Source code of Windows XP (NT5)
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.

849 lines
21 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. PSECURITY_ATTRIBUTES psa;
  187. if (lpCurr > lpUsrDicStart + lpImeL->uUsrDicSize) {
  188. // invalid offset
  189. return (FALSE);
  190. }
  191. dwPattern = ReadingToPattern(
  192. #if defined(UNIIME)
  193. lpImeL,
  194. #endif
  195. lpszReading, &bBuf[4], TRUE);
  196. if (!dwPattern) {
  197. return (FALSE);
  198. }
  199. if (lpCurr == lpUsrDicStart + lpImeL->uUsrDicSize) {
  200. } else if (dwPattern == (*(LPUNADWORD)(lpCurr + sizeof(WORD)) &
  201. lpImeL->dwPatternMask)) {
  202. // the same one as old, don't need update
  203. return (TRUE);
  204. }
  205. *(LPWORD)bBuf = 1; // bank ID
  206. #ifdef UNICODE
  207. *(LPWORD)&bBuf[2] = *(LPWORD)lpszString;
  208. #else
  209. // internal code, reverve the ANSI string
  210. bBuf[2] = *((LPBYTE)lpszString + 1);
  211. bBuf[3] = *((LPBYTE)lpszString);
  212. #endif
  213. psa = CreateSecurityAttributes();
  214. // write this word into file
  215. hUsrDicFile = CreateFile(lpImeL->szUsrDic, GENERIC_WRITE,
  216. FILE_SHARE_READ|FILE_SHARE_WRITE,
  217. psa, OPEN_EXISTING,
  218. FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
  219. if (hUsrDicFile == INVALID_HANDLE_VALUE) {
  220. FreeSecurityAttributes(psa);
  221. return (FALSE);
  222. }
  223. dwPos = (DWORD) ((lpCurr - lpUsrDicStart) / (lpImeL->nSeqBytes + 2) *
  224. (lpImeL->nMaxKey + 4) + 256);
  225. SetFilePointer(hUsrDicFile, dwPos, (LPLONG)NULL, FILE_BEGIN);
  226. WriteFile(hUsrDicFile, bBuf, lpImeL->nMaxKey + 4, &dwWriteByte,
  227. NULL);
  228. *(LPUNAWORD)lpCurr = *(LPWORD)&bBuf[2];
  229. CopyMemory((LPBYTE)lpCurr + sizeof(WORD), &dwPattern, lpImeL->nSeqBytes);
  230. if (lpCurr == (lpUsrDicStart + lpImeL->uUsrDicSize)) {
  231. // add new word
  232. lpImeL->uUsrDicSize += lpImeL->nSeqBytes + sizeof(WORD);
  233. *(LPDWORD)bBuf = lpImeL->uUsrDicSize / (lpImeL->nSeqBytes +
  234. sizeof(WORD));
  235. // offset of ulTableCount
  236. SetFilePointer(hUsrDicFile, 0x0C, (LPLONG)NULL, FILE_BEGIN);
  237. // write to ulTableCount
  238. WriteFile(hUsrDicFile, bBuf, sizeof(DWORD), &dwWriteByte,
  239. NULL);
  240. }
  241. CloseHandle(hUsrDicFile);
  242. FreeSecurityAttributes(psa);
  243. return (TRUE);
  244. }
  245. #endif
  246. /**********************************************************************/
  247. /* ImeRegsisterWord */
  248. /* Return Value: */
  249. /* TRUE - successful, FALSE - failure */
  250. /**********************************************************************/
  251. #if defined(UNIIME)
  252. BOOL WINAPI UniImeRegisterWord(
  253. LPINSTDATAL lpInstL,
  254. LPIMEL lpImeL,
  255. #else
  256. BOOL WINAPI ImeRegisterWord(
  257. #endif
  258. LPCTSTR lpszReading,
  259. DWORD dwStyle,
  260. LPCTSTR lpszString)
  261. {
  262. #if defined(WINIME) || defined(UNICDIME) || defined(ROMANIME)
  263. return (FALSE);
  264. #else
  265. BOOL fRet, fNeedUnload;
  266. HANDLE hUsrDicMem;
  267. WORD wCode;
  268. LPBYTE lpUsrDicStart, lpCurr, lpUsrDicLimit;
  269. fRet = FALSE;
  270. if (!lpszString) {
  271. return (fRet);
  272. }
  273. if (!lpszReading) {
  274. return (fRet);
  275. }
  276. // only handle word not string now, should consider string later?
  277. if (*(LPCTSTR)((LPBYTE)lpszString + sizeof(WORD)) != '\0') {
  278. return (fRet);
  279. }
  280. if (!lpImeL->szUsrDic[0]) {
  281. if (!UsrDicFileName(
  282. #if defined(UNIIME)
  283. lpInstL, lpImeL,
  284. #endif
  285. NULL)) {
  286. return (fRet);
  287. }
  288. }
  289. if (!lpInstL->hUsrDicMem) {
  290. // we load here, and maybe need to unload
  291. LoadUsrDicFile(lpInstL, lpImeL);
  292. if (!lpInstL->hUsrDicMem) {
  293. return (fRet);
  294. }
  295. }
  296. if (lpInstL->fdwTblLoad == TBL_LOADED) {
  297. fNeedUnload = FALSE;
  298. } else if (lpInstL->fdwTblLoad == TBL_NOTLOADED) {
  299. // we only load dic, we will unload it
  300. fNeedUnload = TRUE;
  301. } else {
  302. return (fRet);
  303. }
  304. hUsrDicMem = OpenFileMapping(FILE_MAP_WRITE, FALSE,
  305. lpImeL->szUsrDicMap);
  306. if (!hUsrDicMem) {
  307. goto RegWordUnloadUsrDic;
  308. }
  309. lpUsrDicStart = MapViewOfFile(hUsrDicMem, FILE_MAP_WRITE,
  310. 0, 0, 0);
  311. if (!lpUsrDicStart) {
  312. goto RegWordUnloadUsrDic;
  313. }
  314. #ifdef UNICODE
  315. wCode = *lpszString;
  316. #else
  317. wCode = ((BYTE)lpszString[0] << 8) | (BYTE)lpszString[1];
  318. #endif
  319. lpUsrDicLimit = lpUsrDicStart + lpImeL->uUsrDicSize;
  320. for (lpCurr = lpUsrDicStart; lpCurr < lpUsrDicLimit;
  321. lpCurr += lpImeL->nSeqBytes + sizeof(WORD)) {
  322. // find the internal code
  323. if (wCode == *(LPUNAWORD)lpCurr) {
  324. break;
  325. }
  326. }
  327. fRet = RegisterWord(
  328. #if defined(UNIIME)
  329. lpImeL,
  330. #endif
  331. lpszReading, lpszString, lpUsrDicStart, lpCurr);
  332. UnmapViewOfFile(lpUsrDicStart);
  333. CloseHandle(hUsrDicMem);
  334. RegWordUnloadUsrDic:
  335. if (fNeedUnload) {
  336. if (lpInstL->hUsrDicMem) {
  337. CloseHandle(lpInstL->hUsrDicMem);
  338. }
  339. lpInstL->hUsrDicMem = (HANDLE)NULL;
  340. }
  341. return (fRet);
  342. #endif
  343. }
  344. #if !defined(WINIME) && !defined(UNICDIME) && !defined(ROMANIME)
  345. /**********************************************************************/
  346. /* UnregsisterWord */
  347. /**********************************************************************/
  348. void PASCAL UnregisterWord(
  349. #if defined(UNIIME)
  350. LPIMEL lpImeL,
  351. #endif
  352. LPBYTE lpUsrDicStart,
  353. LPBYTE lpCurr,
  354. LPBYTE lpUsrDicLimit)
  355. {
  356. LPBYTE lpMem;
  357. HANDLE hUsrDicFile;
  358. DWORD dwPos;
  359. DWORD dwByte;
  360. PSECURITY_ATTRIBUTES psa;
  361. BOOL retVal;
  362. MoveMemory(lpCurr, lpCurr + lpImeL->nSeqBytes + sizeof(WORD),
  363. lpUsrDicLimit - lpCurr - lpImeL->nSeqBytes - sizeof(WORD));
  364. lpMem = (LPBYTE)GlobalAlloc(GPTR, (LONG)(lpUsrDicLimit - lpCurr) );
  365. if (!lpMem) {
  366. return;
  367. }
  368. psa = CreateSecurityAttributes();
  369. // delete this word from file
  370. hUsrDicFile = CreateFile(lpImeL->szUsrDic,
  371. GENERIC_WRITE|GENERIC_READ,
  372. FILE_SHARE_READ, psa, OPEN_EXISTING,
  373. FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
  374. if (hUsrDicFile == INVALID_HANDLE_VALUE) {
  375. FreeSecurityAttributes(psa);
  376. GlobalFree((HGLOBAL)lpMem);
  377. return;
  378. }
  379. dwPos = (DWORD) ((lpCurr - lpUsrDicStart) / (lpImeL->nSeqBytes + 2) *
  380. (lpImeL->nMaxKey + 4) + 256);
  381. SetFilePointer(hUsrDicFile, dwPos + lpImeL->nMaxKey + 4,
  382. (LPLONG)NULL, FILE_BEGIN);
  383. retVal = ReadFile(hUsrDicFile, lpMem,(DWORD)(lpUsrDicLimit-lpCurr-lpImeL->nMaxKey-4),
  384. &dwByte, NULL);
  385. if ( retVal == FALSE )
  386. {
  387. CloseHandle(hUsrDicFile);
  388. FreeSecurityAttributes(psa);
  389. GlobalFree((HGLOBAL)lpMem);
  390. return;
  391. }
  392. SetFilePointer(hUsrDicFile, dwPos, (LPLONG)NULL, FILE_BEGIN);
  393. WriteFile(hUsrDicFile,lpMem,(DWORD)(lpUsrDicLimit-lpCurr-lpImeL->nMaxKey-4),
  394. &dwByte, NULL);
  395. SetEndOfFile(hUsrDicFile);
  396. lpImeL->uUsrDicSize -= lpImeL->nSeqBytes + sizeof(WORD);
  397. *(LPDWORD)lpMem = lpImeL->uUsrDicSize / (lpImeL->nSeqBytes +
  398. sizeof(WORD));
  399. // offset of ulTableCount
  400. SetFilePointer(hUsrDicFile, 0x0C, (LPLONG)NULL, FILE_BEGIN);
  401. // write to ulTableCount
  402. WriteFile(hUsrDicFile, lpMem, sizeof(DWORD), &dwByte,
  403. NULL);
  404. CloseHandle(hUsrDicFile);
  405. FreeSecurityAttributes(psa);
  406. GlobalFree((HGLOBAL)lpMem);
  407. return;
  408. }
  409. #endif
  410. /**********************************************************************/
  411. /* ImeUnregsisterWord / UniImeUnregisterWord */
  412. /* Return Value: */
  413. /* TRUE - successful, FALSE - failure */
  414. /**********************************************************************/
  415. #if defined(UNIIME)
  416. BOOL WINAPI UniImeUnregisterWord(
  417. LPINSTDATAL lpInstL,
  418. LPIMEL lpImeL,
  419. #else
  420. BOOL WINAPI ImeUnregisterWord(
  421. #endif
  422. LPCTSTR lpszReading,
  423. DWORD dwStyle,
  424. LPCTSTR lpszString)
  425. {
  426. #if defined(WINIME) || defined(UNICDIME) || defined(ROMANIME)
  427. return (FALSE);
  428. #else
  429. BOOL fRet, fNeedUnload;
  430. HANDLE hUsrDicMem;
  431. LPBYTE lpUsrDicStart, lpCurr, lpUsrDicLimit;
  432. DWORD dwPattern;
  433. WORD wCode;
  434. fRet = FALSE;
  435. if (!lpszString) {
  436. return (fRet);
  437. }
  438. if (dwStyle != IME_REGWORD_STYLE_EUDC) {
  439. return (fRet);
  440. }
  441. // only handle word not string now, should consider string later?
  442. if (*(LPCTSTR)((LPBYTE)lpszString + sizeof(WORD)) != '\0') {
  443. return (fRet);
  444. }
  445. if (!lpImeL->szUsrDic[0]) {
  446. return (fRet);
  447. }
  448. if (lpInstL->fdwTblLoad == TBL_LOADED) {
  449. fNeedUnload = FALSE;
  450. } else if (lpInstL->fdwTblLoad == TBL_NOTLOADED) {
  451. LoadUsrDicFile(lpInstL, lpImeL);
  452. if (lpImeL->fdwErrMsg & (ERRMSG_LOAD_USRDIC|ERRMSG_MEM_USRDIC)) {
  453. return (fRet);
  454. }
  455. // we only load dic, we will unload it
  456. fNeedUnload = TRUE;
  457. } else {
  458. return (fRet);
  459. }
  460. hUsrDicMem = OpenFileMapping(FILE_MAP_WRITE, FALSE,
  461. lpImeL->szUsrDicMap);
  462. if (!hUsrDicMem) {
  463. goto IUWUnloadUsrDic;
  464. }
  465. lpUsrDicStart = MapViewOfFile(hUsrDicMem, FILE_MAP_WRITE,
  466. 0, 0, 0);
  467. if (!lpUsrDicStart) {
  468. goto IUWUnloadUsrDic;
  469. }
  470. lpUsrDicLimit = lpUsrDicStart + lpImeL->uUsrDicSize;
  471. dwPattern = ReadingToPattern(
  472. #if defined(UNIIME)
  473. lpImeL,
  474. #endif
  475. lpszReading, NULL, TRUE);
  476. #ifdef UNICODE
  477. wCode = *(LPWORD)lpszString;
  478. #else
  479. wCode = ((BYTE)lpszString[0] << 8) | (BYTE)lpszString[1];
  480. #endif
  481. for (lpCurr = lpUsrDicStart; lpCurr < lpUsrDicLimit;
  482. lpCurr += lpImeL->nSeqBytes + sizeof(WORD)) {
  483. DWORD dwDicPattern;
  484. // find the internal code
  485. if (wCode != *(LPUNAWORD)lpCurr) {
  486. continue;
  487. }
  488. dwDicPattern = *(LPUNADWORD)(lpCurr + sizeof(WORD)) &
  489. lpImeL->dwPatternMask;
  490. if (!lpszReading) {
  491. // no reading, specify internal code only
  492. } else if (dwDicPattern == dwPattern) {
  493. } else {
  494. continue;
  495. }
  496. fRet = TRUE;
  497. UnregisterWord(
  498. #if defined(UNIIME)
  499. lpImeL,
  500. #endif
  501. lpUsrDicStart, lpCurr, lpUsrDicLimit);
  502. break;
  503. }
  504. UnmapViewOfFile(lpUsrDicStart);
  505. CloseHandle(hUsrDicMem);
  506. IUWUnloadUsrDic:
  507. if (fNeedUnload) {
  508. if (lpInstL->hUsrDicMem) {
  509. CloseHandle(lpInstL->hUsrDicMem);
  510. }
  511. lpInstL->hUsrDicMem = (HANDLE)NULL;
  512. }
  513. return (fRet);
  514. #endif
  515. }
  516. /**********************************************************************/
  517. /* ImeGetRegsisterWordStyle / UniImeGetRegsisterWordStyle */
  518. /* Return Value: */
  519. /* number of styles copied/required */
  520. /**********************************************************************/
  521. #if defined(UNIIME)
  522. UINT WINAPI UniImeGetRegisterWordStyle(
  523. LPINSTDATAL lpInstL,
  524. LPIMEL lpImeL,
  525. #else
  526. UINT WINAPI ImeGetRegisterWordStyle(
  527. #endif
  528. UINT nItem,
  529. LPSTYLEBUF lpStyleBuf)
  530. {
  531. #if defined(WINIME) || defined(UNICDIME) || defined(ROMANIME)
  532. return (FALSE);
  533. #else
  534. if (!nItem) {
  535. return (1);
  536. }
  537. // invalid case
  538. if (!lpStyleBuf) {
  539. return (0);
  540. }
  541. lpStyleBuf->dwStyle = IME_REGWORD_STYLE_EUDC;
  542. LoadString(hInst, IDS_EUDC, lpStyleBuf->szDescription,
  543. sizeof(lpStyleBuf->szDescription)/sizeof(TCHAR));
  544. return (1);
  545. #endif
  546. }
  547. #if !defined(ROMANIME)
  548. /**********************************************************************/
  549. /* PatternToReading */
  550. /**********************************************************************/
  551. void PASCAL PatternToReading(
  552. #if defined(UNIIME)
  553. LPIMEL lpImeL,
  554. #endif
  555. DWORD dwPattern,
  556. LPTSTR lpszReading)
  557. {
  558. int i;
  559. i = lpImeL->nMaxKey;
  560. *(LPTSTR)((LPBYTE)lpszReading + sizeof(WCHAR) * i) = '\0';
  561. // delete the ending 0 sequence code
  562. for (i--; i >= 0; i--) {
  563. if (dwPattern & lpImeL->dwSeqMask) {
  564. break;
  565. }
  566. *(LPWSTR)((LPBYTE)lpszReading + sizeof(WCHAR) * i) = '\0';
  567. dwPattern >>= lpImeL->nSeqBits;
  568. }
  569. for (; i >= 0; i--) {
  570. *(LPWORD)((LPBYTE)lpszReading + sizeof(WORD) * i) =
  571. lpImeL->wSeq2CompTbl[dwPattern & lpImeL->dwSeqMask];
  572. dwPattern >>= lpImeL->nSeqBits;
  573. }
  574. return;
  575. }
  576. #endif
  577. /**********************************************************************/
  578. /* ImeEnumRegisterWord */
  579. /* Return Value: */
  580. /* the last value return by the callback function */
  581. /**********************************************************************/
  582. #if defined(UNIIME)
  583. UINT WINAPI UniImeEnumRegisterWord(
  584. LPINSTDATAL lpInstL,
  585. LPIMEL lpImeL,
  586. #else
  587. UINT WINAPI ImeEnumRegisterWord(
  588. #endif
  589. REGISTERWORDENUMPROC lpfnRegisterWordEnumProc,
  590. LPCTSTR lpszReading,
  591. DWORD dwStyle,
  592. LPCTSTR lpszString,
  593. LPVOID lpData)
  594. {
  595. #if defined(WINIME) || defined(UNICDIME) || defined(ROMANIME)
  596. return (FALSE);
  597. #else
  598. HANDLE hUsrDicMem;
  599. WORD wCode;
  600. BOOL fNeedUnload;
  601. LPBYTE lpUsrDicStart, lpCurr, lpUsrDicLimit;
  602. DWORD dwPattern;
  603. UINT uRet;
  604. uRet = 0;
  605. if (!dwStyle) {
  606. } else if (dwStyle == IME_REGWORD_STYLE_EUDC) {
  607. } else {
  608. return (uRet);
  609. }
  610. if (!lpszString) {
  611. } else if (*(LPCTSTR)((LPBYTE)lpszString + sizeof(WORD)) == '\0') {
  612. #ifdef UNICODE
  613. wCode = *(LPWORD)lpszString;
  614. #else
  615. wCode = ((BYTE)lpszString[0] << 8) | (BYTE)lpszString[1];
  616. #endif
  617. } else {
  618. return (uRet);
  619. }
  620. if (lpInstL->fdwTblLoad == TBL_LOADED) {
  621. fNeedUnload = FALSE;
  622. } else if (!lpImeL->szUsrDic[0]) {
  623. return (uRet);
  624. } else if (lpInstL->fdwTblLoad == TBL_NOTLOADED) {
  625. LoadUsrDicFile(lpInstL, lpImeL);
  626. if (lpImeL->fdwErrMsg & (ERRMSG_LOAD_USRDIC|ERRMSG_MEM_USRDIC)) {
  627. return (uRet);
  628. }
  629. // we only load dic, we will unload it
  630. fNeedUnload = TRUE;
  631. } else {
  632. return (uRet);
  633. }
  634. hUsrDicMem = OpenFileMapping(FILE_MAP_READ, FALSE,
  635. lpImeL->szUsrDicMap);
  636. if (!hUsrDicMem) {
  637. goto IERWUnloadUsrDic;
  638. }
  639. lpUsrDicStart = MapViewOfFile(hUsrDicMem, FILE_MAP_READ,
  640. 0, 0, 0);
  641. if (!lpUsrDicStart) {
  642. goto IERWUnloadUsrDic;
  643. }
  644. if (lpszReading) {
  645. dwPattern = ReadingToPattern(
  646. #if defined(UNIIME)
  647. lpImeL,
  648. #endif
  649. lpszReading, NULL, TRUE);
  650. }
  651. lpUsrDicLimit = lpUsrDicStart + lpImeL->uUsrDicSize;
  652. for (lpCurr = lpUsrDicStart; lpCurr < lpUsrDicLimit;
  653. lpCurr += lpImeL->nSeqBytes + sizeof(WORD)) {
  654. DWORD dwDicPattern;
  655. LPTSTR lpszMatchReading, lpszMatchString;
  656. BYTE szBufReading[sizeof(WORD) * 12];
  657. BYTE szBufString[sizeof(WORD) * 2];
  658. // match string
  659. if (!lpszString) {
  660. lpszMatchString = (LPTSTR)szBufString;
  661. *(LPWORD)lpszMatchString = *(LPUNAWORD)lpCurr;
  662. *(LPTSTR)((LPBYTE)lpszMatchString + sizeof(WORD)) = '\0';
  663. #ifndef UNICODE
  664. // reverse it to ANSI string
  665. wCode = szBufString[0];
  666. szBufString[0] = szBufString[1];
  667. szBufString[1] = (BYTE)wCode;
  668. #endif
  669. } else if (wCode == *(LPUNAWORD)lpCurr) {
  670. lpszMatchString = (LPTSTR)lpszString;
  671. } else {
  672. continue; // not matched
  673. }
  674. // match reading
  675. dwDicPattern = *(LPUNADWORD)(lpCurr + sizeof(WORD)) &
  676. lpImeL->dwPatternMask;
  677. if (!lpszReading) {
  678. lpszMatchReading = (LPTSTR)szBufReading;
  679. PatternToReading(
  680. #if defined(UNIIME)
  681. lpImeL,
  682. #endif
  683. dwDicPattern, lpszMatchReading);
  684. } else if (dwDicPattern == dwPattern) {
  685. lpszMatchReading = (LPTSTR)lpszReading;
  686. } else {
  687. continue; // not matched
  688. }
  689. uRet = (*lpfnRegisterWordEnumProc)(lpszMatchReading,
  690. IME_REGWORD_STYLE_EUDC, lpszMatchString, lpData);
  691. if (!uRet) {
  692. break;
  693. }
  694. }
  695. UnmapViewOfFile(lpUsrDicStart);
  696. CloseHandle(hUsrDicMem);
  697. IERWUnloadUsrDic:
  698. if (fNeedUnload) {
  699. if (lpInstL->hUsrDicMem) {
  700. CloseHandle(lpInstL->hUsrDicMem);
  701. }
  702. lpInstL->hUsrDicMem = (HANDLE)NULL;
  703. }
  704. return (uRet);
  705. #endif
  706. }