Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

838 lines
22 KiB

  1. /*++
  2. Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. REGWORD.C - register word into dictionary of IME
  5. ++*/
  6. #include <windows.h>
  7. #include <immdev.h>
  8. #include "imeattr.h"
  9. #include "imedefs.h"
  10. #include "imerc.h"
  11. #if defined(UNIIME)
  12. #include "uniime.h"
  13. #endif
  14. #if !defined(ROMANIME)
  15. /**********************************************************************/
  16. /* ReadingToPattern */
  17. /* Return Value: */
  18. /* the pattern of the reading (packed sequence code) */
  19. /**********************************************************************/
  20. DWORD PASCAL ReadingToPattern(
  21. #if defined(UNIIME)
  22. LPIMEL lpImeL,
  23. #endif
  24. LPCTSTR lpszReading,
  25. LPBYTE lpbSeq,
  26. BOOL fFinalized)
  27. {
  28. BYTE bSeq[8];
  29. char cIndex;
  30. DWORD dwPattern;
  31. int i;
  32. #if defined(PHON)
  33. char cOldIndex;
  34. #endif
  35. cIndex = 0;
  36. #if defined(PHON)
  37. cOldIndex = -1;
  38. #endif
  39. *(LPDWORD)bSeq = 0;
  40. #if defined(CHAJEI) || defined(QUICK) || defined(WINAR30) || defined(UNIIME)
  41. *(LPDWORD)&bSeq[4] = 0;
  42. #endif
  43. for (; *lpszReading; (LPBYTE)lpszReading += sizeof(WCHAR)) {
  44. int iSeqCode;
  45. for (iSeqCode = lpImeL->nSeqCode; iSeqCode >= 0; iSeqCode--) {
  46. if (lpImeL->wSeq2CompTbl[iSeqCode] == *(LPWORD)lpszReading) {
  47. break;
  48. }
  49. }
  50. if (iSeqCode < 0) {
  51. return (0);
  52. }
  53. #if defined(PHON) // phontic can have space between reading
  54. if (iSeqCode == 0) {
  55. continue;
  56. }
  57. #else
  58. if (iSeqCode == 0) {
  59. break;
  60. }
  61. #endif
  62. #if defined(PHON)
  63. cIndex = cSeq2IndexTbl[iSeqCode];
  64. // the index is conflict with previous reading
  65. if (cIndex <= cOldIndex) {
  66. return (0);
  67. }
  68. #endif
  69. // too many reading
  70. if (cIndex >= lpImeL->nMaxKey) {
  71. return (0);
  72. }
  73. bSeq[cIndex] = (BYTE)iSeqCode;
  74. #if defined(PHON)
  75. if (cIndex == 3 && cOldIndex == -1) {
  76. return (0);
  77. }
  78. cOldIndex = cIndex;
  79. #else
  80. cIndex++;
  81. #endif
  82. }
  83. #if defined(PHON)
  84. // the index of a finalized char must be 3
  85. if (cIndex != 3 && fFinalized) {
  86. return (0);
  87. }
  88. #elif (WINIME)
  89. // internal code must be 4 digits
  90. if (!bSeq[3] && fFinalized) {
  91. return (0);
  92. }
  93. if (bSeq[0]) {
  94. // similar to InternalCodeRange
  95. // 0x8??? - 0xF??? is OK
  96. if (bSeq[0] >= 0x09 && bSeq[0] <= 0x10) {
  97. } else {
  98. // there is no 0x0??? - 0x7???
  99. return (0);
  100. }
  101. }
  102. if (bSeq[1]) {
  103. if (bSeq[0] == (0x08 + 1)) {
  104. if (bSeq[1] <= (0x00 + 1)) {
  105. // there is no 0x80??
  106. return (0);
  107. } else {
  108. }
  109. } else if (bSeq[0] == (0x0F + 1)) {
  110. if (bSeq[1] >= (0x0F + 1)) {
  111. // there is no 0xFF??
  112. return (0);
  113. } else {
  114. }
  115. } else {
  116. }
  117. }
  118. if (bSeq[2]) {
  119. if (bSeq[2] < (0x04 + 1)) {
  120. // there is no 0x??0?, 0x??1?, 0x??2?, 0x??3?
  121. return (0);
  122. } else if (bSeq[2] < (0x08 + 1)) {
  123. } else if (bSeq[2] < (0x0A + 1)) {
  124. // there is no 0x??8?, 0x??9?
  125. return (0);
  126. } else {
  127. }
  128. }
  129. if (bSeq[3]) {
  130. if (bSeq[2] == (0x07 + 1)) {
  131. if (bSeq[3] >= (0x0F + 1)) {
  132. // there is no 0x??7F
  133. return (0);
  134. } else {
  135. }
  136. } else if (bSeq[2] == (0x0A + 1)) {
  137. if (bSeq[3] <= (0x00 + 1)) {
  138. // there is no 0x??A0
  139. return (0);
  140. } else {
  141. }
  142. } else if (bSeq[2] == (0x0F + 1)) {
  143. if (bSeq[3] <= (0x0F + 1)) {
  144. // there is no 0x??FF
  145. return (0);
  146. } else {
  147. }
  148. } else {
  149. }
  150. }
  151. #endif
  152. dwPattern = 0;
  153. for (i = 0; i < lpImeL->nMaxKey; i++) {
  154. dwPattern <<= lpImeL->nSeqBits;
  155. dwPattern |= bSeq[i];
  156. }
  157. if (lpbSeq) {
  158. *(LPDWORD)lpbSeq = *(LPDWORD)bSeq;
  159. #if defined(CHAJEI) || defined(QUICK) || defined(WINAR30) || defined(UNIIME)
  160. *(LPDWORD)&lpbSeq[4] = *(LPDWORD)&bSeq[4];
  161. #endif
  162. }
  163. return (dwPattern);
  164. }
  165. #endif
  166. #if !defined(WINIME) && !defined(UNICDIME) && !defined(ROMANIME)
  167. /**********************************************************************/
  168. /* RegsisterWord */
  169. /* Return Value: */
  170. /* TRUE - successful, FALSE - failure */
  171. /**********************************************************************/
  172. BOOL PASCAL RegisterWord(
  173. #if defined(UNIIME)
  174. LPIMEL lpImeL,
  175. #endif
  176. LPCTSTR lpszReading,
  177. LPCTSTR lpszString,
  178. LPBYTE lpUsrDicStart,
  179. LPBYTE lpCurr)
  180. {
  181. DWORD dwPattern;
  182. DWORD dwWriteByte;
  183. BYTE bBuf[10];
  184. HANDLE hUsrDicFile;
  185. DWORD dwPos;
  186. if (lpCurr > lpUsrDicStart + lpImeL->uUsrDicSize) {
  187. // invalid offset
  188. return (FALSE);
  189. }
  190. dwPattern = ReadingToPattern(
  191. #if defined(UNIIME)
  192. lpImeL,
  193. #endif
  194. lpszReading, &bBuf[4], TRUE);
  195. if (!dwPattern) {
  196. return (FALSE);
  197. }
  198. if (lpCurr == lpUsrDicStart + lpImeL->uUsrDicSize) {
  199. } else if (dwPattern == (*(LPUNADWORD)(lpCurr + sizeof(WORD)) &
  200. lpImeL->dwPatternMask)) {
  201. // the same one as old, don't need update
  202. return (TRUE);
  203. }
  204. *(LPWORD)bBuf = 1; // bank ID
  205. #ifdef UNICODE
  206. *(LPWORD)&bBuf[2] = *(LPWORD)lpszString;
  207. #else
  208. // internal code, reverve the ANSI string
  209. bBuf[2] = *((LPBYTE)lpszString + 1);
  210. bBuf[3] = *((LPBYTE)lpszString);
  211. #endif
  212. // write this word into file
  213. hUsrDicFile = CreateFile(lpImeL->szUsrDic, GENERIC_WRITE,
  214. FILE_SHARE_READ|FILE_SHARE_WRITE,
  215. NULL, OPEN_EXISTING,
  216. FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
  217. if (hUsrDicFile == INVALID_HANDLE_VALUE) {
  218. return (FALSE);
  219. }
  220. dwPos = (DWORD) ((lpCurr - lpUsrDicStart) / (lpImeL->nSeqBytes + 2) *
  221. (lpImeL->nMaxKey + 4) + 256);
  222. SetFilePointer(hUsrDicFile, dwPos, (LPLONG)NULL, FILE_BEGIN);
  223. WriteFile(hUsrDicFile, bBuf, lpImeL->nMaxKey + 4, &dwWriteByte,
  224. NULL);
  225. *(LPUNAWORD)lpCurr = *(LPWORD)&bBuf[2];
  226. CopyMemory((LPBYTE)lpCurr + sizeof(WORD), &dwPattern, lpImeL->nSeqBytes);
  227. if (lpCurr == (lpUsrDicStart + lpImeL->uUsrDicSize)) {
  228. // add new word
  229. lpImeL->uUsrDicSize += lpImeL->nSeqBytes + sizeof(WORD);
  230. *(LPDWORD)bBuf = lpImeL->uUsrDicSize / (lpImeL->nSeqBytes +
  231. sizeof(WORD));
  232. // offset of ulTableCount
  233. SetFilePointer(hUsrDicFile, 0x0C, (LPLONG)NULL, FILE_BEGIN);
  234. // write to ulTableCount
  235. WriteFile(hUsrDicFile, bBuf, sizeof(DWORD), &dwWriteByte,
  236. NULL);
  237. }
  238. CloseHandle(hUsrDicFile);
  239. return (TRUE);
  240. }
  241. #endif
  242. /**********************************************************************/
  243. /* ImeRegsisterWord */
  244. /* Return Value: */
  245. /* TRUE - successful, FALSE - failure */
  246. /**********************************************************************/
  247. #if defined(UNIIME)
  248. BOOL WINAPI UniImeRegisterWord(
  249. LPINSTDATAL lpInstL,
  250. LPIMEL lpImeL,
  251. #else
  252. BOOL WINAPI ImeRegisterWord(
  253. #endif
  254. LPCTSTR lpszReading,
  255. DWORD dwStyle,
  256. LPCTSTR lpszString)
  257. {
  258. #if defined(WINIME) || defined(UNICDIME) || defined(ROMANIME)
  259. return (FALSE);
  260. #else
  261. BOOL fRet, fNeedUnload;
  262. HANDLE hUsrDicMem;
  263. WORD wCode;
  264. LPBYTE lpUsrDicStart, lpCurr, lpUsrDicLimit;
  265. fRet = FALSE;
  266. if (!lpszString) {
  267. return (fRet);
  268. }
  269. if (!lpszReading) {
  270. return (fRet);
  271. }
  272. // only handle word not string now, should consider string later?
  273. if (*(LPCTSTR)((LPBYTE)lpszString + sizeof(WORD)) != '\0') {
  274. return (fRet);
  275. }
  276. if (!lpImeL->szUsrDic[0]) {
  277. if (!UsrDicFileName(
  278. #if defined(UNIIME)
  279. lpInstL, lpImeL,
  280. #endif
  281. NULL)) {
  282. return (fRet);
  283. }
  284. }
  285. if (!lpInstL->hUsrDicMem) {
  286. // we load here, and maybe need to unload
  287. LoadUsrDicFile(lpInstL, lpImeL);
  288. if (!lpInstL->hUsrDicMem) {
  289. return (fRet);
  290. }
  291. }
  292. if (lpInstL->fdwTblLoad == TBL_LOADED) {
  293. fNeedUnload = FALSE;
  294. } else if (lpInstL->fdwTblLoad == TBL_NOTLOADED) {
  295. // we only load dic, we will unload it
  296. fNeedUnload = TRUE;
  297. } else {
  298. return (fRet);
  299. }
  300. hUsrDicMem = OpenFileMapping(FILE_MAP_WRITE, FALSE,
  301. lpImeL->szUsrDicMap);
  302. if (!hUsrDicMem) {
  303. goto RegWordUnloadUsrDic;
  304. }
  305. lpUsrDicStart = MapViewOfFile(hUsrDicMem, FILE_MAP_WRITE,
  306. 0, 0, 0);
  307. if (!lpUsrDicStart) {
  308. goto RegWordUnloadUsrDic;
  309. }
  310. #ifdef UNICODE
  311. wCode = *lpszString;
  312. #else
  313. wCode = ((BYTE)lpszString[0] << 8) | (BYTE)lpszString[1];
  314. #endif
  315. lpUsrDicLimit = lpUsrDicStart + lpImeL->uUsrDicSize;
  316. for (lpCurr = lpUsrDicStart; lpCurr < lpUsrDicLimit;
  317. lpCurr += lpImeL->nSeqBytes + sizeof(WORD)) {
  318. // find the internal code
  319. if (wCode == *(LPUNAWORD)lpCurr) {
  320. break;
  321. }
  322. }
  323. fRet = RegisterWord(
  324. #if defined(UNIIME)
  325. lpImeL,
  326. #endif
  327. lpszReading, lpszString, lpUsrDicStart, lpCurr);
  328. UnmapViewOfFile(lpUsrDicStart);
  329. CloseHandle(hUsrDicMem);
  330. RegWordUnloadUsrDic:
  331. if (fNeedUnload) {
  332. if (lpInstL->hUsrDicMem) {
  333. CloseHandle(lpInstL->hUsrDicMem);
  334. }
  335. lpInstL->hUsrDicMem = (HANDLE)NULL;
  336. }
  337. return (fRet);
  338. #endif
  339. }
  340. #if !defined(WINIME) && !defined(UNICDIME) && !defined(ROMANIME)
  341. /**********************************************************************/
  342. /* UnregsisterWord */
  343. /**********************************************************************/
  344. void PASCAL UnregisterWord(
  345. #if defined(UNIIME)
  346. LPIMEL lpImeL,
  347. #endif
  348. LPBYTE lpUsrDicStart,
  349. LPBYTE lpCurr,
  350. LPBYTE lpUsrDicLimit)
  351. {
  352. LPBYTE lpMem;
  353. HANDLE hUsrDicFile;
  354. DWORD dwPos;
  355. DWORD dwByte;
  356. BOOL retVal;
  357. MoveMemory(lpCurr, lpCurr + lpImeL->nSeqBytes + sizeof(WORD),
  358. lpUsrDicLimit - lpCurr - lpImeL->nSeqBytes - sizeof(WORD));
  359. lpMem = (LPBYTE)GlobalAlloc(GPTR, (LONG)(lpUsrDicLimit - lpCurr) );
  360. if (!lpMem) {
  361. return;
  362. }
  363. // delete this word from file
  364. hUsrDicFile = CreateFile(lpImeL->szUsrDic,
  365. GENERIC_WRITE|GENERIC_READ,
  366. FILE_SHARE_READ, NULL, OPEN_EXISTING,
  367. FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
  368. if (hUsrDicFile == INVALID_HANDLE_VALUE) {
  369. GlobalFree((HGLOBAL)lpMem);
  370. return;
  371. }
  372. dwPos = (DWORD) ((lpCurr - lpUsrDicStart) / (lpImeL->nSeqBytes + 2) *
  373. (lpImeL->nMaxKey + 4) + 256);
  374. SetFilePointer(hUsrDicFile, dwPos + lpImeL->nMaxKey + 4,
  375. (LPLONG)NULL, FILE_BEGIN);
  376. retVal = ReadFile(hUsrDicFile, lpMem,(DWORD)(lpUsrDicLimit-lpCurr-lpImeL->nMaxKey-4),
  377. &dwByte, NULL);
  378. if ( retVal == FALSE )
  379. {
  380. CloseHandle(hUsrDicFile);
  381. GlobalFree((HGLOBAL)lpMem);
  382. return;
  383. }
  384. SetFilePointer(hUsrDicFile, dwPos, (LPLONG)NULL, FILE_BEGIN);
  385. WriteFile(hUsrDicFile,lpMem,(DWORD)(lpUsrDicLimit-lpCurr-lpImeL->nMaxKey-4),
  386. &dwByte, NULL);
  387. SetEndOfFile(hUsrDicFile);
  388. lpImeL->uUsrDicSize -= lpImeL->nSeqBytes + sizeof(WORD);
  389. *(LPDWORD)lpMem = lpImeL->uUsrDicSize / (lpImeL->nSeqBytes +
  390. sizeof(WORD));
  391. // offset of ulTableCount
  392. SetFilePointer(hUsrDicFile, 0x0C, (LPLONG)NULL, FILE_BEGIN);
  393. // write to ulTableCount
  394. WriteFile(hUsrDicFile, lpMem, sizeof(DWORD), &dwByte,
  395. NULL);
  396. CloseHandle(hUsrDicFile);
  397. GlobalFree((HGLOBAL)lpMem);
  398. return;
  399. }
  400. #endif
  401. /**********************************************************************/
  402. /* ImeUnregsisterWord / UniImeUnregisterWord */
  403. /* Return Value: */
  404. /* TRUE - successful, FALSE - failure */
  405. /**********************************************************************/
  406. #if defined(UNIIME)
  407. BOOL WINAPI UniImeUnregisterWord(
  408. LPINSTDATAL lpInstL,
  409. LPIMEL lpImeL,
  410. #else
  411. BOOL WINAPI ImeUnregisterWord(
  412. #endif
  413. LPCTSTR lpszReading,
  414. DWORD dwStyle,
  415. LPCTSTR lpszString)
  416. {
  417. #if defined(WINIME) || defined(UNICDIME) || defined(ROMANIME)
  418. return (FALSE);
  419. #else
  420. BOOL fRet, fNeedUnload;
  421. HANDLE hUsrDicMem;
  422. LPBYTE lpUsrDicStart, lpCurr, lpUsrDicLimit;
  423. DWORD dwPattern;
  424. WORD wCode;
  425. fRet = FALSE;
  426. if (!lpszString) {
  427. return (fRet);
  428. }
  429. if (dwStyle != IME_REGWORD_STYLE_EUDC) {
  430. return (fRet);
  431. }
  432. // only handle word not string now, should consider string later?
  433. if (*(LPCTSTR)((LPBYTE)lpszString + sizeof(WORD)) != '\0') {
  434. return (fRet);
  435. }
  436. if (!lpImeL->szUsrDic[0]) {
  437. return (fRet);
  438. }
  439. if (lpInstL->fdwTblLoad == TBL_LOADED) {
  440. fNeedUnload = FALSE;
  441. } else if (lpInstL->fdwTblLoad == TBL_NOTLOADED) {
  442. LoadUsrDicFile(lpInstL, lpImeL);
  443. if (lpImeL->fdwErrMsg & (ERRMSG_LOAD_USRDIC|ERRMSG_MEM_USRDIC)) {
  444. return (fRet);
  445. }
  446. // we only load dic, we will unload it
  447. fNeedUnload = TRUE;
  448. } else {
  449. return (fRet);
  450. }
  451. hUsrDicMem = OpenFileMapping(FILE_MAP_WRITE, FALSE,
  452. lpImeL->szUsrDicMap);
  453. if (!hUsrDicMem) {
  454. goto IUWUnloadUsrDic;
  455. }
  456. lpUsrDicStart = MapViewOfFile(hUsrDicMem, FILE_MAP_WRITE,
  457. 0, 0, 0);
  458. if (!lpUsrDicStart) {
  459. goto IUWUnloadUsrDic;
  460. }
  461. lpUsrDicLimit = lpUsrDicStart + lpImeL->uUsrDicSize;
  462. dwPattern = ReadingToPattern(
  463. #if defined(UNIIME)
  464. lpImeL,
  465. #endif
  466. lpszReading, NULL, TRUE);
  467. #ifdef UNICODE
  468. wCode = *(LPWORD)lpszString;
  469. #else
  470. wCode = ((BYTE)lpszString[0] << 8) | (BYTE)lpszString[1];
  471. #endif
  472. for (lpCurr = lpUsrDicStart; lpCurr < lpUsrDicLimit;
  473. lpCurr += lpImeL->nSeqBytes + sizeof(WORD)) {
  474. DWORD dwDicPattern;
  475. // find the internal code
  476. if (wCode != *(LPUNAWORD)lpCurr) {
  477. continue;
  478. }
  479. dwDicPattern = *(LPUNADWORD)(lpCurr + sizeof(WORD)) &
  480. lpImeL->dwPatternMask;
  481. if (!lpszReading) {
  482. // no reading, specify internal code only
  483. } else if (dwDicPattern == dwPattern) {
  484. } else {
  485. continue;
  486. }
  487. fRet = TRUE;
  488. UnregisterWord(
  489. #if defined(UNIIME)
  490. lpImeL,
  491. #endif
  492. lpUsrDicStart, lpCurr, lpUsrDicLimit);
  493. break;
  494. }
  495. UnmapViewOfFile(lpUsrDicStart);
  496. CloseHandle(hUsrDicMem);
  497. IUWUnloadUsrDic:
  498. if (fNeedUnload) {
  499. if (lpInstL->hUsrDicMem) {
  500. CloseHandle(lpInstL->hUsrDicMem);
  501. }
  502. lpInstL->hUsrDicMem = (HANDLE)NULL;
  503. }
  504. return (fRet);
  505. #endif
  506. }
  507. /**********************************************************************/
  508. /* ImeGetRegsisterWordStyle / UniImeGetRegsisterWordStyle */
  509. /* Return Value: */
  510. /* number of styles copied/required */
  511. /**********************************************************************/
  512. #if defined(UNIIME)
  513. UINT WINAPI UniImeGetRegisterWordStyle(
  514. LPINSTDATAL lpInstL,
  515. LPIMEL lpImeL,
  516. #else
  517. UINT WINAPI ImeGetRegisterWordStyle(
  518. #endif
  519. UINT nItem,
  520. LPSTYLEBUF lpStyleBuf)
  521. {
  522. #if defined(WINIME) || defined(UNICDIME) || defined(ROMANIME)
  523. return (FALSE);
  524. #else
  525. if (!nItem) {
  526. return (1);
  527. }
  528. // invalid case
  529. if (!lpStyleBuf) {
  530. return (0);
  531. }
  532. lpStyleBuf->dwStyle = IME_REGWORD_STYLE_EUDC;
  533. LoadString(hInst, IDS_EUDC, lpStyleBuf->szDescription,
  534. sizeof(lpStyleBuf->szDescription)/sizeof(TCHAR));
  535. return (1);
  536. #endif
  537. }
  538. #if !defined(ROMANIME)
  539. /**********************************************************************/
  540. /* PatternToReading */
  541. /**********************************************************************/
  542. void PASCAL PatternToReading(
  543. #if defined(UNIIME)
  544. LPIMEL lpImeL,
  545. #endif
  546. DWORD dwPattern,
  547. LPTSTR lpszReading)
  548. {
  549. int i;
  550. i = lpImeL->nMaxKey;
  551. *(LPTSTR)((LPBYTE)lpszReading + sizeof(WCHAR) * i) = '\0';
  552. // delete the ending 0 sequence code
  553. for (i--; i >= 0; i--) {
  554. if (dwPattern & lpImeL->dwSeqMask) {
  555. break;
  556. }
  557. *(LPWSTR)((LPBYTE)lpszReading + sizeof(WCHAR) * i) = '\0';
  558. dwPattern >>= lpImeL->nSeqBits;
  559. }
  560. for (; i >= 0; i--) {
  561. *(LPWORD)((LPBYTE)lpszReading + sizeof(WORD) * i) =
  562. lpImeL->wSeq2CompTbl[dwPattern & lpImeL->dwSeqMask];
  563. dwPattern >>= lpImeL->nSeqBits;
  564. }
  565. return;
  566. }
  567. #endif
  568. /**********************************************************************/
  569. /* ImeEnumRegisterWord */
  570. /* Return Value: */
  571. /* the last value return by the callback function */
  572. /**********************************************************************/
  573. #if defined(UNIIME)
  574. UINT WINAPI UniImeEnumRegisterWord(
  575. LPINSTDATAL lpInstL,
  576. LPIMEL lpImeL,
  577. #else
  578. UINT WINAPI ImeEnumRegisterWord(
  579. #endif
  580. REGISTERWORDENUMPROC lpfnRegisterWordEnumProc,
  581. LPCTSTR lpszReading,
  582. DWORD dwStyle,
  583. LPCTSTR lpszString,
  584. LPVOID lpData)
  585. {
  586. #if defined(WINIME) || defined(UNICDIME) || defined(ROMANIME)
  587. return (FALSE);
  588. #else
  589. HANDLE hUsrDicMem;
  590. WORD wCode;
  591. BOOL fNeedUnload;
  592. LPBYTE lpUsrDicStart, lpCurr, lpUsrDicLimit;
  593. DWORD dwPattern;
  594. UINT uRet;
  595. uRet = 0;
  596. if (!dwStyle) {
  597. } else if (dwStyle == IME_REGWORD_STYLE_EUDC) {
  598. } else {
  599. return (uRet);
  600. }
  601. if (!lpszString) {
  602. } else if (*(LPCTSTR)((LPBYTE)lpszString + sizeof(WORD)) == '\0') {
  603. #ifdef UNICODE
  604. wCode = *(LPWORD)lpszString;
  605. #else
  606. wCode = ((BYTE)lpszString[0] << 8) | (BYTE)lpszString[1];
  607. #endif
  608. } else {
  609. return (uRet);
  610. }
  611. if (lpInstL->fdwTblLoad == TBL_LOADED) {
  612. fNeedUnload = FALSE;
  613. } else if (!lpImeL->szUsrDic[0]) {
  614. return (uRet);
  615. } else if (lpInstL->fdwTblLoad == TBL_NOTLOADED) {
  616. LoadUsrDicFile(lpInstL, lpImeL);
  617. if (lpImeL->fdwErrMsg & (ERRMSG_LOAD_USRDIC|ERRMSG_MEM_USRDIC)) {
  618. return (uRet);
  619. }
  620. // we only load dic, we will unload it
  621. fNeedUnload = TRUE;
  622. } else {
  623. return (uRet);
  624. }
  625. hUsrDicMem = OpenFileMapping(FILE_MAP_READ, FALSE,
  626. lpImeL->szUsrDicMap);
  627. if (!hUsrDicMem) {
  628. goto IERWUnloadUsrDic;
  629. }
  630. lpUsrDicStart = MapViewOfFile(hUsrDicMem, FILE_MAP_READ,
  631. 0, 0, 0);
  632. if (!lpUsrDicStart) {
  633. goto IERWUnloadUsrDic;
  634. }
  635. if (lpszReading) {
  636. dwPattern = ReadingToPattern(
  637. #if defined(UNIIME)
  638. lpImeL,
  639. #endif
  640. lpszReading, NULL, TRUE);
  641. }
  642. lpUsrDicLimit = lpUsrDicStart + lpImeL->uUsrDicSize;
  643. for (lpCurr = lpUsrDicStart; lpCurr < lpUsrDicLimit;
  644. lpCurr += lpImeL->nSeqBytes + sizeof(WORD)) {
  645. DWORD dwDicPattern;
  646. LPTSTR lpszMatchReading, lpszMatchString;
  647. BYTE szBufReading[sizeof(WORD) * 12];
  648. BYTE szBufString[sizeof(WORD) * 2];
  649. // match string
  650. if (!lpszString) {
  651. lpszMatchString = (LPTSTR)szBufString;
  652. *(LPWORD)lpszMatchString = *(LPUNAWORD)lpCurr;
  653. *(LPTSTR)((LPBYTE)lpszMatchString + sizeof(WORD)) = '\0';
  654. #ifndef UNICODE
  655. // reverse it to ANSI string
  656. wCode = szBufString[0];
  657. szBufString[0] = szBufString[1];
  658. szBufString[1] = (BYTE)wCode;
  659. #endif
  660. } else if (wCode == *(LPUNAWORD)lpCurr) {
  661. lpszMatchString = (LPTSTR)lpszString;
  662. } else {
  663. continue; // not matched
  664. }
  665. // match reading
  666. dwDicPattern = *(LPUNADWORD)(lpCurr + sizeof(WORD)) &
  667. lpImeL->dwPatternMask;
  668. if (!lpszReading) {
  669. lpszMatchReading = (LPTSTR)szBufReading;
  670. PatternToReading(
  671. #if defined(UNIIME)
  672. lpImeL,
  673. #endif
  674. dwDicPattern, lpszMatchReading);
  675. } else if (dwDicPattern == dwPattern) {
  676. lpszMatchReading = (LPTSTR)lpszReading;
  677. } else {
  678. continue; // not matched
  679. }
  680. uRet = (*lpfnRegisterWordEnumProc)(lpszMatchReading,
  681. IME_REGWORD_STYLE_EUDC, lpszMatchString, lpData);
  682. if (!uRet) {
  683. break;
  684. }
  685. }
  686. UnmapViewOfFile(lpUsrDicStart);
  687. CloseHandle(hUsrDicMem);
  688. IERWUnloadUsrDic:
  689. if (fNeedUnload) {
  690. if (lpInstL->hUsrDicMem) {
  691. CloseHandle(lpInstL->hUsrDicMem);
  692. }
  693. lpInstL->hUsrDicMem = (HANDLE)NULL;
  694. }
  695. return (uRet);
  696. #endif
  697. }