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.

468 lines
11 KiB

  1. #include <windows.h>
  2. #include <setupapi.h>
  3. #include "common.h"
  4. #include "cht.h"
  5. extern TCHAR ImeDataDirectory[MAX_PATH];
  6. extern TCHAR szMsgBuf[];
  7. struct {
  8. ULONG PtrLen95;
  9. ULONG PhraseLen95;
  10. HANDLE hPtrBuf95;
  11. HANDLE hPhraseBuf95;
  12. ULONG PtrLenNT;
  13. ULONG PhraseLenNT;
  14. HANDLE hPtrBufNT;
  15. HANDLE hPhraseBufNT;
  16. } LCData = {0,0,0,0,0,0,0,0};
  17. /******************************Public*Routine******************************\
  18. * InitImeDataCht
  19. *
  20. * Get Win95 IME phrase data from system directory.
  21. *
  22. * Arguments:
  23. *
  24. * Return Value:
  25. *
  26. * BOOL: TRUE-Success, FALSE-FAIL.
  27. *
  28. * History:
  29. *
  30. \**************************************************************************/
  31. BOOL InitImeDataCht(void)
  32. {
  33. HFILE hfLCPtr,hfLCPhrase;
  34. TCHAR szLCPtrName[MAX_PATH];
  35. TCHAR szLCPhraseName[MAX_PATH];
  36. UCHAR *szLCPtrBuf,*szLCPhraseBuf;
  37. UINT len;
  38. // Get system directory
  39. lstrcpy(szLCPtrName, ImeDataDirectory);
  40. DebugMsg(("InitImeDataCht, ImeDataDirectory = %s!\r\n",ImeDataDirectory));
  41. len = lstrlen(ImeDataDirectory);
  42. if (szLCPtrName[len - 1] != '\\') { // consider C:\ ;
  43. szLCPtrName[len++] = '\\';
  44. szLCPtrName[len] = 0;
  45. }
  46. lstrcpy(szLCPhraseName, szLCPtrName);
  47. //
  48. // at this step, szLCPhraseName == szLCPtrName
  49. //
  50. lstrcat(szLCPtrName, LCPTRFILE);
  51. lstrcat(szLCPhraseName, LCPHRASEFILE);
  52. DebugMsg(("InitImeDataCht, szLCPtrName = %s!\r\n",szLCPtrName));
  53. DebugMsg(("InitImeDataCht, szLCPhraseName = %s!\r\n",szLCPhraseName));
  54. // Open LC pointer file
  55. hfLCPtr=_lopen(szLCPtrName,OF_READ);
  56. if(hfLCPtr == -1){
  57. DebugMsg(("InitImeDataCht, open %s failed!\r\n",szLCPtrName));
  58. return FALSE;
  59. }
  60. DebugMsg(("InitImeDataCht, open %s OK!\r\n",szLCPtrName));
  61. // Open LC phrase file
  62. hfLCPhrase=_lopen(szLCPhraseName,OF_READ);
  63. if(hfLCPhrase == -1){
  64. DebugMsg(("InitImeDataCht, open %s failed!\r\n",szLCPhraseName));
  65. _lclose(hfLCPtr);
  66. return FALSE;
  67. }
  68. DebugMsg(("InitImeDataCht, open %s OK!\r\n",szLCPhraseName));
  69. // get file length
  70. LCData.PtrLen95 = _llseek(hfLCPtr,0L,2);
  71. // Allocate Memory
  72. LCData.hPtrBuf95 = GlobalAlloc(GMEM_FIXED, LCData.PtrLen95);
  73. if(!LCData.hPtrBuf95) {
  74. _lclose(hfLCPtr);
  75. _lclose(hfLCPhrase);
  76. return FALSE;
  77. }
  78. szLCPtrBuf = GlobalLock(LCData.hPtrBuf95);
  79. //set to beginning
  80. _llseek(hfLCPtr,0L,0);
  81. if(LCData.PtrLen95 != _lread(hfLCPtr,szLCPtrBuf,LCData.PtrLen95)) {
  82. _lclose(hfLCPtr);
  83. _lclose(hfLCPhrase);
  84. return FALSE;
  85. }
  86. //release handle for PTR data
  87. _lclose(hfLCPtr);
  88. GlobalUnlock(LCData.hPtrBuf95);
  89. //get file length
  90. LCData.PhraseLen95=_llseek(hfLCPhrase,0L,2);
  91. // Allocate Memory
  92. LCData.hPhraseBuf95 = GlobalAlloc(GMEM_MOVEABLE, LCData.PhraseLen95);
  93. if(!LCData.hPhraseBuf95) {
  94. _lclose(hfLCPhrase);
  95. return FALSE;
  96. }
  97. szLCPhraseBuf = GlobalLock(LCData.hPhraseBuf95);
  98. _llseek(hfLCPhrase,0L,0); //set to beginning
  99. if(LCData.PhraseLen95 != _lread(hfLCPhrase,szLCPhraseBuf,LCData.PhraseLen95)) {
  100. _lclose(hfLCPhrase);
  101. return FALSE;
  102. }
  103. _lclose(hfLCPhrase);
  104. GlobalUnlock(LCData.hPhraseBuf95);
  105. LCData.hPhraseBufNT = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, LCData.PhraseLen95*2);
  106. if(!LCData.hPhraseBufNT) {
  107. return FALSE;
  108. }
  109. LCData.PtrLenNT = LCData.PtrLen95/PTRRECLEN95*PTRRECLENNT*sizeof(WCHAR);
  110. LCData.hPtrBufNT = GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT, LCData.PtrLenNT);
  111. if(!LCData.hPtrBufNT) {
  112. return FALSE;
  113. }
  114. return TRUE;
  115. }
  116. /******************************Private*Routine******************************\
  117. * PtrDataCompare
  118. *
  119. * Quick sort serve program.
  120. *
  121. * Arguments:
  122. *
  123. * const void * arg1 - element 1
  124. * const void * arg2 - element 2
  125. *
  126. * Return Value:
  127. *
  128. * int: 1 >, -1 <, 0 =.
  129. *
  130. * History:
  131. *
  132. \**************************************************************************/
  133. int __cdecl PtrDataCompare(const void * arg1, const void * arg2)
  134. {
  135. if (*((WORD*)arg1) > *((WORD*)arg2))
  136. return 1;
  137. else
  138. if (*((WORD*)arg1) < *((WORD*)arg2))
  139. return -1;
  140. return 0;
  141. }
  142. /******************************Private*Routine******************************\
  143. * AddPhrase
  144. *
  145. * Add a phrase section to buffer.
  146. *
  147. * Arguments:
  148. *
  149. * WORD wStart - Start address of a LC phrase section
  150. * WORD wEnd - End address of a LC phrase section
  151. *
  152. * Return Value:
  153. *
  154. * int: phrase section count.
  155. *
  156. * History:
  157. *
  158. \**************************************************************************/
  159. int AddPhrase(
  160. WORD wStart,
  161. WORD wEnd
  162. )
  163. {
  164. UINT i,count=0;
  165. WORD wWord;
  166. UCHAR cchar[2], *szPhraseBuf95;
  167. WCHAR *szPhraseBufNT;
  168. szPhraseBuf95 = GlobalLock(LCData.hPhraseBuf95);
  169. szPhraseBufNT = GlobalLock(LCData.hPhraseBufNT);
  170. for(i=wStart; i < wEnd; i++) {
  171. wWord=*((WORD *)&szPhraseBuf95[i*2]);
  172. wWord |= END_PHRASE;
  173. cchar[0]=HIBYTE(wWord);
  174. cchar[1]=LOBYTE(wWord);
  175. MultiByteToWideChar(950, MB_PRECOMPOSED, cchar, 2, (LPWSTR)(szPhraseBufNT+LCData.PhraseLenNT), 1);
  176. LCData.PhraseLenNT++;
  177. count++;
  178. // If end of phrase append zero
  179. if( !( (*((WORD *)&szPhraseBuf95[i*2])) & END_PHRASE) )
  180. {
  181. szPhraseBufNT[LCData.PhraseLenNT]=0;
  182. LCData.PhraseLenNT++;
  183. count++;
  184. }
  185. }
  186. GlobalUnlock(LCData.hPhraseBuf95);
  187. GlobalUnlock(LCData.hPhraseBufNT);
  188. return count;
  189. }
  190. /******************************Private*Routine******************************\
  191. * PtrBinSearch
  192. *
  193. * Search end counter of a phrase section.
  194. *
  195. * Arguments:
  196. *
  197. * WORD wStart - start address of a LC phrase section
  198. *
  199. * Return Value:
  200. *
  201. * WORD: end address of a LC phrase section.
  202. *
  203. * History:
  204. *
  205. \**************************************************************************/
  206. WORD PtrBinSeach(WORD wStart)
  207. {
  208. int mid, low=PTRRECLEN95, high=LCData.PtrLen95;
  209. UCHAR *szPtrBuf95 = GlobalLock(LCData.hPtrBuf95);
  210. while (low <= high)
  211. {
  212. mid = (low+high)/PTRRECLEN95/2*PTRRECLEN95;
  213. if (wStart > *((WORD*)&szPtrBuf95[mid+2]))
  214. low = mid+PTRRECLEN95;
  215. else
  216. if (wStart < *((WORD*)&szPtrBuf95[mid+2]))
  217. high = mid-PTRRECLEN95;
  218. else
  219. {
  220. GlobalUnlock(LCData.hPtrBuf95);
  221. return *((WORD*)&szPtrBuf95[mid+2+PTRRECLEN95]);
  222. }
  223. }
  224. GlobalUnlock(LCData.hPtrBuf95);
  225. return 0;
  226. }
  227. /******************************Public*Routine******************************\
  228. * ImeDataConvertCht
  229. *
  230. * Convert Windows 95 IME phrase data to Windows NT 5.0 phrase data format.
  231. *
  232. * Arguments:
  233. *
  234. * Return Value:
  235. *
  236. * BOOL: TRUE-Success, FALSE-FAIL.
  237. *
  238. * History:
  239. *
  240. \**************************************************************************/
  241. BOOL ImeDataConvertCht(void)
  242. {
  243. WCHAR *szLCPtrBufNT;
  244. UCHAR *szLCPtrBuf95, TmpChar;
  245. UINT i=PTRRECLEN95, j=PTRRECLENNT;
  246. unsigned long count;
  247. szLCPtrBuf95 = GlobalLock(LCData.hPtrBuf95);
  248. szLCPtrBufNT = GlobalLock(LCData.hPtrBufNT);
  249. // Convert PTR data to UNICODE
  250. // Keep offset value unchanged
  251. while (i< LCData.PtrLen95 )
  252. {
  253. TmpChar = *(szLCPtrBuf95+i);
  254. *(szLCPtrBuf95+i) = *(szLCPtrBuf95+i+1);
  255. *(szLCPtrBuf95+i+1) = TmpChar;
  256. MultiByteToWideChar(950, MB_PRECOMPOSED, (LPCSTR)(szLCPtrBuf95+i), 2, (LPWSTR)(szLCPtrBufNT+j), 1);
  257. szLCPtrBufNT[j+1] = *((WORD*)&szLCPtrBuf95[i+2]);
  258. i+=PTRRECLEN95;
  259. j+=PTRRECLENNT;
  260. }
  261. // Sort PTR data - UNICODE, ascending
  262. qsort( (void *)szLCPtrBufNT, (size_t) (LCData.PtrLenNT/sizeof(WCHAR)/PTRRECLENNT), (size_t)PTRRECLENNT*sizeof(WCHAR), PtrDataCompare);
  263. // Get phrase data
  264. i = PTRRECLENNT;
  265. LCData.PhraseLenNT = 0;
  266. while (i < LCData.PtrLenNT/sizeof(WCHAR))
  267. {
  268. count=AddPhrase(szLCPtrBufNT[i+1],PtrBinSeach(szLCPtrBufNT[i+1]));
  269. *((unsigned long *)&szLCPtrBufNT[i+1]) = LCData.PhraseLenNT-count;
  270. i+=PTRRECLENNT;
  271. }
  272. LCData.PhraseLenNT=LCData.PhraseLenNT*sizeof(WCHAR);
  273. GlobalUnlock(LCData.hPtrBuf95);
  274. GlobalUnlock(LCData.hPtrBufNT);
  275. return TRUE;
  276. }
  277. /******************************Public*Routine******************************\
  278. * FreeResCht
  279. *
  280. * Release global data used by IME conversion.
  281. *
  282. * Arguments:
  283. *
  284. * Return Value:
  285. *
  286. *
  287. * History:
  288. *
  289. \**************************************************************************/
  290. void FreeResCht(void)
  291. {
  292. if (LCData.hPtrBuf95) {
  293. GlobalFree(LCData.hPtrBuf95);
  294. LCData.hPtrBuf95 = NULL;
  295. }
  296. if (LCData.hPtrBufNT) {
  297. GlobalFree(LCData.hPtrBufNT);
  298. LCData.hPtrBufNT = NULL;
  299. }
  300. if (LCData.hPhraseBuf95) {
  301. GlobalFree(LCData.hPhraseBuf95);
  302. LCData.hPhraseBuf95 = NULL;
  303. }
  304. if (LCData.hPhraseBufNT) {
  305. LCData.hPhraseBufNT = NULL;
  306. GlobalFree(LCData.hPhraseBufNT);
  307. }
  308. }
  309. // Test above routines.
  310. int ConvertChtImeData(void)
  311. {
  312. LONG fsize;
  313. HANDLE f1;
  314. WCHAR *szLCPtrBufNT, *szLCPhraseBufNT;
  315. UINT len1,len2;
  316. TCHAR FilePath[MAX_PATH];
  317. TCHAR szName[MAX_PATH];
  318. if (!InitImeDataCht())
  319. {
  320. DebugMsg(("ConvertChtImeData, calling InitImeDataCht failed!\r\n"));
  321. FreeResCht();
  322. return 0;
  323. }
  324. if (!ImeDataConvertCht())
  325. {
  326. DebugMsg(("ConvertChtImeData, calling ImeDataConvertCht failed!\r\n"));
  327. FreeResCht();
  328. return 0;
  329. }
  330. szLCPtrBufNT = GlobalLock(LCData.hPtrBufNT);
  331. szLCPhraseBufNT = GlobalLock(LCData.hPhraseBufNT);
  332. len1 = GetSystemDirectory((LPSTR)szName, sizeof(szName));
  333. if (!len1) {
  334. DebugMsg(("ConvertChtImeData, calling GetSystemDirectory failed!\r\n"));
  335. return 0;
  336. }
  337. DebugMsg(("ConvertChtImeData, System directory is %s !\r\n",szName));
  338. if (szName[len1 - 1] != '\\') {
  339. szName[len1++] = '\\';
  340. szName[len1] = 0;
  341. }
  342. DebugMsg(("ConvertChtImeData, Backsplash checking, System directory is %s !\r\n",szName));
  343. len2 = lstrlen(ImeDataDirectory);
  344. lstrcpy(FilePath, ImeDataDirectory);
  345. lstrcat(FilePath, "lcptr.tbl");
  346. lstrcat(szName,"lcptr.tbl");
  347. //_asm {int 3}
  348. f1 = CreateFile(szName, GENERIC_WRITE, 0, NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE, NULL);
  349. DebugMsg(("ConvertChtImeData, CreateFile %s !\r\n",szName));
  350. if (f1 == INVALID_HANDLE_VALUE) {
  351. DebugMsg(("ConvertChtImeData, Create file %s, failed!\r\n",szName));
  352. }
  353. szName[len1]=0;
  354. FilePath[len2]=0;
  355. if (! WriteFile(f1, szLCPtrBufNT, LCData.PtrLenNT, &fsize, NULL) ) {
  356. DebugMsg(("ConvertChtImeData, Write file %s failed!\r\n",szName));
  357. } else {
  358. DebugMsg(("ConvertChtImeData, Write file, %s OK!\r\n",szName));
  359. }
  360. CloseHandle(f1);
  361. lstrcat(FilePath, "lcphrase.tbl");
  362. lstrcat(szName,"lcphrase.tbl");
  363. //_asm {int 3}
  364. f1 = CreateFile(szName, GENERIC_WRITE, 0, NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE, NULL);
  365. DebugMsg(("ConvertChtImeData, CreateFile %s !\r\n",szName));
  366. if (f1 == INVALID_HANDLE_VALUE) {
  367. DebugMsg(("ConvertChtImeData, Create file %s, failed!\r\n",szName));
  368. }
  369. if (! WriteFile(f1, szLCPhraseBufNT, LCData.PhraseLenNT, &fsize, NULL)) {
  370. DebugMsg(("ConvertChtImeData, Write file %s, failed!\r\n",szName));
  371. } else {
  372. DebugMsg(("ConvertChtImeData, Create file %s OK!\r\n",szName));
  373. }
  374. CloseHandle(f1);
  375. GlobalUnlock(LCData.hPtrBufNT);
  376. GlobalUnlock(LCData.hPhraseBufNT);
  377. FreeResCht();
  378. return 1;
  379. }