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.

292 lines
8.5 KiB

  1. /****************************************************************************
  2. HANJA.CPP
  3. Owner: cslim
  4. Copyright (c) 1997-1999 Microsoft Corporation
  5. Hanja conversion and dictionary lookup functions. Dictionary index is
  6. stored as globally shared memory.
  7. History:
  8. 26-APR-1999 cslim Modified for Multibox Applet Tooltip display
  9. 14-JUL-1999 cslim Copied from IME98 source tree
  10. *****************************************************************************/
  11. #include <windows.h>
  12. #include <windowsx.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include "hwxobj.h"
  16. #include "lexheader.h"
  17. #include "hanja.h"
  18. #include "common.h"
  19. #include "immsec.h"
  20. #include "dbg.h"
  21. // NT5 Globally shared memory.
  22. const TCHAR IMEKR_LEX_SHAREDDATA_MUTEX_NAME[] = TEXT("ImeKrLex.Mutex");
  23. const TCHAR IMEKR_LEX_SHAREDDATA_NAME[] = TEXT("ImeKrLexHanjaToHangul.SharedMemory");
  24. UINT vuNumofK0=0, vuNumofK1=0;
  25. WCHAR vwcHangul=0;
  26. // Private data
  27. static BOOL vfLexOpen = FALSE;
  28. static HANDLE vhLex=0;
  29. static HANDLE vhLexIndexTbl=0;
  30. static UINT vuNumOfHanjaEntry=0;
  31. static DWORD viBufferStart=0; // seek point
  32. // Private functions
  33. static BOOL OpenLex();
  34. //static VOID ClearHanjaSenseArray();
  35. static INT SearchHanjaIndex(WCHAR wHChar, HanjaToHangulIndex *pLexIndexTbl);
  36. BOOL EnsureHanjaLexLoaded()
  37. {
  38. _DictHeader *pLexHeader;
  39. HKEY hKey;
  40. DWORD dwReadBytes;
  41. CHAR szLexFileName[MAX_PATH], szLexPathExpanded[MAX_PATH];
  42. DWORD dwCb, dwType;
  43. if (vfLexOpen)
  44. return TRUE;
  45. // Get Lex file path
  46. szLexFileName[0] = 0;
  47. szLexPathExpanded[0] = 0;
  48. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_szIMERootKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
  49. {
  50. dwCb = sizeof(szLexFileName);
  51. dwType = REG_SZ;
  52. if (RegQueryValueEx(hKey, g_szDictionary, NULL, &dwType, (LPBYTE)szLexFileName, &dwCb) == ERROR_SUCCESS)
  53. ExpandEnvironmentStrings(szLexFileName, szLexPathExpanded, sizeof(szLexPathExpanded));
  54. RegCloseKey(hKey);
  55. }
  56. DBGAssert(szLexPathExpanded[0] != 0);
  57. if (szLexPathExpanded[0] == 0)
  58. return FALSE;
  59. vhLex = CreateFile(szLexPathExpanded, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
  60. if (vhLex==INVALID_HANDLE_VALUE)
  61. {
  62. DBGAssert(0);
  63. return FALSE;
  64. }
  65. pLexHeader = new _DictHeader;
  66. if (!pLexHeader)
  67. return FALSE;
  68. if (ReadFile(vhLex, pLexHeader, sizeof(_DictHeader), &dwReadBytes, 0) == 0 || (dwReadBytes != sizeof(_DictHeader)))
  69. {
  70. DBGAssert(0);
  71. return FALSE;
  72. }
  73. // Set member vars
  74. vuNumOfHanjaEntry = pLexHeader->uiNumofHanja;
  75. viBufferStart = pLexHeader->iBufferStart;
  76. if (pLexHeader->Version < LEX_VERSION || pLexHeader->Version > LEX_COMPATIBLE_VERSION_LIMIT )
  77. {
  78. delete pLexHeader;
  79. DBGAssert(0);
  80. return FALSE;
  81. }
  82. if (lstrcmpA(pLexHeader->COPYRIGHT_HEADER, COPYRIGHT_STR))
  83. {
  84. delete pLexHeader;
  85. DBGAssert(0);
  86. return FALSE;
  87. }
  88. // Read Index table
  89. SetFilePointer(vhLex, pLexHeader->iHanjaToHangulIndex, 0, FILE_BEGIN);
  90. delete pLexHeader;
  91. return OpenLex();
  92. }
  93. __inline BOOL DoEnterCriticalSection(HANDLE hMutex)
  94. {
  95. if(WAIT_FAILED==WaitForSingleObject(hMutex, 3000)) // Wait 3 seconds
  96. return(FALSE);
  97. return(TRUE);
  98. }
  99. BOOL OpenLex()
  100. {
  101. BOOL fRet = FALSE;
  102. HanjaToHangulIndex* pHanjaToHangulIndex;
  103. HANDLE hMutex;
  104. DWORD dwReadBytes;
  105. ///////////////////////////////////////////////////////////////////////////
  106. // Mapping Lex file
  107. // The dictionary index is shared data between all IME instance
  108. hMutex=CreateMutex(GetIMESecurityAttributes(), FALSE, IMEKR_LEX_SHAREDDATA_MUTEX_NAME);
  109. if (hMutex != NULL)
  110. {
  111. if (DoEnterCriticalSection(hMutex) == FALSE)
  112. goto ExitOpenLexCritSection;
  113. vhLexIndexTbl = OpenFileMapping(FILE_MAP_READ, TRUE, IMEKR_LEX_SHAREDDATA_NAME);
  114. if(vhLexIndexTbl)
  115. {
  116. Dbg(("CHanja::OpenLex() - File mapping already exists"));
  117. fRet = TRUE;
  118. }
  119. else
  120. {
  121. // if no file mapping exist
  122. vhLexIndexTbl = CreateFileMapping(INVALID_HANDLE_VALUE,
  123. GetIMESecurityAttributes(),
  124. PAGE_READWRITE,
  125. 0,
  126. sizeof(HanjaToHangulIndex)*(vuNumOfHanjaEntry),
  127. IMEKR_LEX_SHAREDDATA_NAME);
  128. if (vhLexIndexTbl)
  129. {
  130. Dbg(("CHanja::OpenLex() - File mapping Created"));
  131. pHanjaToHangulIndex = (HanjaToHangulIndex*)MapViewOfFile(vhLexIndexTbl, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
  132. if (!pHanjaToHangulIndex)
  133. goto ExitOpenLexCritSection;
  134. if (ReadFile(vhLex, pHanjaToHangulIndex, sizeof(HanjaToHangulIndex)*(vuNumOfHanjaEntry), &dwReadBytes, 0) != 0 &&
  135. dwReadBytes == sizeof(HanjaToHangulIndex)*(vuNumOfHanjaEntry))
  136. {
  137. fRet = TRUE;
  138. }
  139. else
  140. {
  141. fRet = FALSE;
  142. }
  143. UnmapViewOfFile(pHanjaToHangulIndex);
  144. }
  145. #ifdef _DEBUG
  146. else
  147. DBGAssert(0);
  148. #endif
  149. }
  150. ExitOpenLexCritSection:
  151. ReleaseMutex(hMutex);
  152. CloseHandle(hMutex);
  153. }
  154. FreeIMESecurityAttributes();
  155. vfLexOpen = fRet;
  156. return fRet;
  157. }
  158. BOOL CloseLex()
  159. {
  160. //ClearHanjaSenseArray();
  161. if (vhLexIndexTbl)
  162. {
  163. CloseHandle(vhLexIndexTbl);
  164. vhLexIndexTbl = 0;
  165. }
  166. if (vhLex)
  167. {
  168. CloseHandle(vhLex);
  169. vhLex = 0;
  170. }
  171. vfLexOpen = FALSE;
  172. return TRUE;
  173. }
  174. BOOL GetMeaningAndProunc(WCHAR wch, LPWSTR lpwstrTip, INT cchMax)
  175. {
  176. HanjaToHangulIndex* pHanjaToHangulIndex;
  177. INT iMapHanjaInfo;
  178. WCHAR wcHanja;
  179. BYTE cchMeaning = 0;
  180. WCHAR wszMeaning[MAX_SENSE_LENGTH];
  181. DWORD dwReadBytes;
  182. BOOL fRet = FALSE;
  183. Dbg(("GetMeaningAndProunc"));
  184. if (!EnsureHanjaLexLoaded())
  185. return FALSE;
  186. pHanjaToHangulIndex = (HanjaToHangulIndex*)MapViewOfFile(vhLexIndexTbl, FILE_MAP_READ, 0, 0, 0);
  187. if (!pHanjaToHangulIndex)
  188. {
  189. DBGAssert(0);
  190. return FALSE;
  191. }
  192. // Search index
  193. if ((iMapHanjaInfo = SearchHanjaIndex(wch, pHanjaToHangulIndex)) >= 0)
  194. {
  195. // Seek to mapping Hanja
  196. SetFilePointer(vhLex, viBufferStart + pHanjaToHangulIndex[iMapHanjaInfo].iOffset, 0, FILE_BEGIN);
  197. // Read Hanja Info
  198. if (ReadFile(vhLex, &wcHanja, sizeof(WCHAR), &dwReadBytes, 0) == 0)
  199. {
  200. goto GetMeaningAndProuncExit;
  201. }
  202. DBGAssert(wch == wcHanja);
  203. if (ReadFile(vhLex, &cchMeaning, sizeof(BYTE), &dwReadBytes, 0) == 0)
  204. {
  205. goto GetMeaningAndProuncExit;
  206. }
  207. if (cchMeaning)
  208. {
  209. if (ReadFile(vhLex, wszMeaning, cchMeaning, &dwReadBytes, 0) == 0)
  210. {
  211. goto GetMeaningAndProuncExit;
  212. }
  213. }
  214. wszMeaning[cchMeaning>>1] = L'\0';
  215. swprintf(lpwstrTip, L"%s %c\nU+%04X", wszMeaning, pHanjaToHangulIndex[iMapHanjaInfo].wchHangul, wch);
  216. fRet = TRUE;
  217. }
  218. GetMeaningAndProuncExit:
  219. UnmapViewOfFile(pHanjaToHangulIndex);
  220. return fRet;
  221. }
  222. INT SearchHanjaIndex(WCHAR wHChar, HanjaToHangulIndex *pLexIndexTbl)
  223. {
  224. int iHead = 0, iTail = vuNumOfHanjaEntry-1, iMid;
  225. while (iHead <= iTail)
  226. {
  227. iMid = (iHead + iTail) >> 1;
  228. Dbg(("SearchHanjaIndex iMid=%d, pLexIndexTbl[iMid].wchHanja = 0x%04X", iMid, pLexIndexTbl[iMid].wchHanja));
  229. if (pLexIndexTbl[iMid].wchHanja > wHChar)
  230. iTail = iMid - 1;
  231. else
  232. if (pLexIndexTbl[iMid].wchHanja < wHChar)
  233. iHead = iMid + 1;
  234. else
  235. return (iMid);
  236. }
  237. return (-1);
  238. }