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.

403 lines
11 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: chs.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * FEMGRATE, CHS speciific functions
  7. *
  8. \***************************************************************************/
  9. #include "femgrate.h"
  10. #include "resource.h"
  11. /******************************Public*Routine******************************\
  12. * ImeDataConvertChs
  13. *
  14. * Convert Windows NT 351 IME phrase data to Windows NT 5.0.
  15. *
  16. * Arguments:
  17. *
  18. * HANDLE hSource - source file handle.
  19. * HANDLE hTarget - target file handle.
  20. *
  21. * Return Value:
  22. *
  23. * BOOL: TRUE-Success, FALSE-FAIL.
  24. *
  25. * History:
  26. *
  27. \**************************************************************************/
  28. #define MAXWORDLENTH 40
  29. #define MAXCODELENTH 12
  30. #define MAXNUMBER_EMB 1000
  31. #define IMENUM 3
  32. #define MAXIMENAME 15
  33. typedef struct PHRASERECNT{
  34. WCHAR CODE[MAXCODELENTH];
  35. WCHAR PHRASE[MAXWORDLENTH];
  36. } RECNT;
  37. typedef struct PHRASEREC95{
  38. BYTE CODE[MAXCODELENTH];
  39. BYTE PHRASE[MAXWORDLENTH];
  40. } REC95;
  41. BOOL IsSizeReasonable(DWORD dwSize)
  42. {
  43. DWORD dwTemp = (dwSize - sizeof(WORD)) / sizeof(REC95);
  44. if (((dwSize - sizeof(WORD)) - (dwTemp * sizeof(REC95))) == 0) {
  45. return TRUE;
  46. } else {
  47. return FALSE;
  48. }
  49. }
  50. BOOL ImeDataConvertChs(HANDLE hSource, HANDLE hTarget)
  51. {
  52. HANDLE hPhrase95, hPhraseNT;
  53. BYTE *szPhrase95;
  54. WCHAR *szPhraseNT;
  55. BOOL bReturn = TRUE;
  56. int i;
  57. WORD WordCount;
  58. DWORD dwSizeofRead;
  59. hPhrase95 = GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,
  60. sizeof(REC95)*MAXNUMBER_EMB+sizeof(WORD));
  61. hPhraseNT = GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,
  62. sizeof(RECNT)*MAXNUMBER_EMB+sizeof(WORD));
  63. if (!hPhraseNT || !hPhrase95 ) {
  64. bReturn = FALSE;
  65. goto Convert_Finish;
  66. }
  67. szPhrase95 = GlobalLock(hPhrase95);
  68. szPhraseNT = GlobalLock(hPhraseNT);
  69. bReturn = ReadFile(hSource,
  70. szPhrase95,
  71. sizeof(REC95)*MAXNUMBER_EMB+sizeof(WORD),
  72. &dwSizeofRead,
  73. NULL);
  74. if (! bReturn) {
  75. return FALSE;
  76. }
  77. //phrase count
  78. WordCount = *( (WORD*) szPhrase95);
  79. *( (WORD*)szPhraseNT) = *((WORD*)szPhrase95);
  80. DebugMsg((DM_VERBOSE,TEXT("[0] %d !\n"),WordCount));
  81. if (dwSizeofRead != *((WORD*)&szPhrase95[0])*sizeof(REC95)+2)
  82. {
  83. if (IsSizeReasonable(dwSizeofRead)) {
  84. *((WORD *) szPhrase95) = (WORD)((dwSizeofRead - sizeof(WORD)) / sizeof(REC95));
  85. } else {
  86. bReturn = FALSE;
  87. goto Convert_Finish;
  88. }
  89. }
  90. for (i = 0; i < WordCount; i++)
  91. {
  92. MultiByteToWideChar(936,
  93. MB_PRECOMPOSED,
  94. (LPCSTR)(szPhrase95+sizeof(WORD)+i*sizeof(REC95)),
  95. sizeof(REC95),
  96. (LPWSTR)((LPBYTE)szPhraseNT+ sizeof(WORD) + i*sizeof(RECNT)),
  97. sizeof(RECNT));
  98. }
  99. bReturn = WriteFile((HANDLE)hTarget,
  100. (LPBYTE) szPhraseNT,
  101. sizeof(RECNT)*MAXNUMBER_EMB+sizeof(WORD),
  102. &dwSizeofRead,
  103. NULL);
  104. Convert_Finish:
  105. if (hPhrase95) {
  106. GlobalUnlock(hPhrase95);
  107. GlobalFree(hPhrase95);
  108. }
  109. if (hPhraseNT) {
  110. GlobalUnlock(hPhraseNT);
  111. GlobalFree(hPhraseNT);
  112. }
  113. return bReturn;
  114. }
  115. BOOL ConvertChsANSIImeDataWorker(LPCTSTR EMBFile)
  116. {
  117. HANDLE hs, ht;
  118. TCHAR szSrcFile[MAX_PATH];
  119. TCHAR szDstFile[MAX_PATH];
  120. BOOL Result;
  121. //
  122. // Get Winnt System 32 directory
  123. //
  124. GetSystemDirectory(szSrcFile, MAX_PATH);
  125. ConcatenatePaths(szSrcFile,EMBFile,MAX_PATH);
  126. lstrcat(szSrcFile,TEXT(".emb"));
  127. lstrcpy(szDstFile,szSrcFile);
  128. lstrcat(szDstFile,TEXT(".351"));
  129. DebugMsg((DM_VERBOSE,TEXT("[ConvertChsANSIImeDataWorker] Src %s Dst %s !\n"),szSrcFile,szDstFile));
  130. hs = CreateFile(szSrcFile,
  131. GENERIC_READ,
  132. 0,
  133. NULL,
  134. OPEN_EXISTING,
  135. 0, NULL);
  136. if (hs == INVALID_HANDLE_VALUE) {
  137. return FALSE;
  138. }
  139. ht = CreateFile(szDstFile,
  140. GENERIC_WRITE,
  141. 0,
  142. NULL,
  143. CREATE_ALWAYS,
  144. 0, NULL);
  145. if (ht == INVALID_HANDLE_VALUE) {
  146. CloseHandle(hs);
  147. return FALSE;
  148. }
  149. Result = ImeDataConvertChs(hs, ht);
  150. CloseHandle(hs);
  151. CloseHandle(ht);
  152. return Result;
  153. }
  154. BOOL ConvertChsANSIImeData()
  155. {
  156. int i;
  157. TABLELIST IMETableListENG[] = {
  158. {IDS_ENG_TABLE1,TEXT("")},
  159. {IDS_ENG_TABLE2,TEXT("")},
  160. {IDS_ENG_TABLE3,TEXT("")},
  161. {IDS_ENG_TABLE4,TEXT("")}
  162. };
  163. for (i=0; i< sizeof(IMETableListENG) / sizeof(TABLELIST); i++) {
  164. if (!LoadString(ghInst,IMETableListENG[i].nResID,IMETableListENG[i].szIMEName,MAX_PATH)) {
  165. continue;
  166. }
  167. ConvertChsANSIImeDataWorker(IMETableListENG[i].szIMEName);
  168. DebugMsg((DM_VERBOSE,TEXT("[ConvertChsANSIImeData] converting ANSI EMB %s !\n"),IMETableListENG[i].szIMEName));
  169. }
  170. return TRUE;
  171. }
  172. BOOL CopyCHSIMETable(
  173. LPCTSTR lpszIMEName,
  174. LPCTSTR lpszClassPath)
  175. {
  176. TCHAR szNewPath[MAX_PATH];
  177. TCHAR szOrgSrcPath[MAX_PATH];
  178. TCHAR szAltSrcPath[MAX_PATH];
  179. TCHAR sz351EMB[MAX_PATH];
  180. BOOL bRet = FALSE;
  181. DebugMsg((DM_VERBOSE,TEXT("[CopyCHSIMETable] lpszIMEName = %s !\n"),lpszIMEName));
  182. DebugMsg((DM_VERBOSE,TEXT("[CopyCHSIMETable] lpszClassPath = %s !\n"),lpszClassPath));
  183. ExpandEnvironmentStrings(TEXT("%systemroot%"),szOrgSrcPath,sizeof(szOrgSrcPath));
  184. ConcatenatePaths(szOrgSrcPath,TEXT("system32"),MAX_PATH);
  185. ConcatenatePaths(szOrgSrcPath,lpszIMEName,MAX_PATH);
  186. DebugMsg((DM_VERBOSE,TEXT("[UpgradeCHSPerUserIMEData] Old IME %s !\n"),szOrgSrcPath));
  187. lstrcpy(sz351EMB,szOrgSrcPath);
  188. lstrcpy(szAltSrcPath,szOrgSrcPath);
  189. lstrcat(sz351EMB,TEXT(".351"));
  190. if (IsFileExisting(sz351EMB)) {
  191. lstrcpy(szAltSrcPath,sz351EMB);
  192. }
  193. if (IsFileExisting(szAltSrcPath)) {
  194. if (GetNewPath(szNewPath,szOrgSrcPath,lpszClassPath)) {
  195. if (! CopyFile(szAltSrcPath,szNewPath,FALSE)) {
  196. DebugMsg((DM_VERBOSE,TEXT("[UpgradeCHSPerUserIMEData] Copy %s to %s failed ! %d\n"),szAltSrcPath,szNewPath,GetLastError()));
  197. } else {
  198. DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Copy %s to %s OK !\n"),szAltSrcPath,szNewPath));
  199. bRet = TRUE;
  200. }
  201. }
  202. }
  203. return bRet;
  204. }
  205. BOOL UpgradeCHSPerUserIMEData()
  206. {
  207. TABLELIST IMETableListCHS[] = {
  208. {IDS_CHS_TABLE1,TEXT("")},
  209. {IDS_CHS_TABLE2,TEXT("")},
  210. {IDS_CHS_TABLE3,TEXT("")},
  211. {IDS_CHS_TABLE4,TEXT("")}
  212. };
  213. TABLELIST IMETableListENG[] = {
  214. {IDS_ENG_TABLE1,TEXT("")},
  215. {IDS_ENG_TABLE2,TEXT("")},
  216. {IDS_ENG_TABLE3,TEXT("")},
  217. {IDS_ENG_TABLE4,TEXT("")}
  218. };
  219. TCHAR szRegPath[MAX_PATH];
  220. TCHAR szClassPath[MAX_PATH];
  221. TCHAR szIMEName[MAX_PATH];
  222. int i;
  223. LPTSTR lpszRegPathPtr,lpszClassPtr;
  224. for (i=0; i<sizeof(IMETableListCHS) / sizeof(TABLELIST); i++) {
  225. if (!LoadString(ghInst,IMETableListCHS[i].nResID,IMETableListCHS[i].szIMEName,MAX_PATH)) {
  226. DebugMsg((DM_VERBOSE,TEXT("UpgradeCHSPerUserIMEData, load string failed!\r\n")));
  227. return FALSE;
  228. }
  229. else {
  230. DebugMsg((DM_VERBOSE,TEXT("UpgradeCHSPerUserIMEData, load string [%s] !\r\n"),IMETableListCHS[i].szIMEName));
  231. }
  232. }
  233. for (i=0; i<sizeof(IMETableListENG) / sizeof(TABLELIST); i++) {
  234. if (!LoadString(ghInst,IMETableListENG[i].nResID,IMETableListENG[i].szIMEName,MAX_PATH)) {
  235. DebugMsg((DM_VERBOSE,TEXT("UpgradeCHSPerUserIMEData, load string failed!\r\n")));
  236. return FALSE;
  237. }
  238. else {
  239. DebugMsg((DM_VERBOSE,TEXT("UpgradeCHSPerUserIMEData, load string [%s] !\r\n"),IMETableListENG[i].szIMEName));
  240. }
  241. }
  242. lstrcpy(szRegPath,TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\"));
  243. lpszRegPathPtr = szRegPath+lstrlen(szRegPath);
  244. lstrcpy(szClassPath,TEXT("Microsoft\\IME\\"));
  245. lpszClassPtr = szClassPath+lstrlen(szClassPath);
  246. for (i=0; i<sizeof(IMETableListCHS) / sizeof(TABLELIST); i++) {
  247. lstrcat(szRegPath,IMETableListCHS[i].szIMEName);
  248. lstrcat(szClassPath,IMETableListENG[i].szIMEName);
  249. if (!MovePerUserIMEData(HKEY_CURRENT_USER,szRegPath,TEXT("EUDCDictName"),szClassPath,IMETableListENG[i].szIMEName,FALSE)) {
  250. DebugMsg((DM_VERBOSE,TEXT("[UpgradeCHSPerUserIMEData] MovePerUserIMEData failed ! %s ,%s !\n"),szRegPath,szClassPath));
  251. }
  252. lstrcpy(szIMEName,IMETableListENG[i].szIMEName);
  253. lstrcat(szIMEName,TEXT(".emb"));
  254. DebugMsg((DM_VERBOSE,TEXT("[UpgradeCHSPerUserIMEData] IME name %s !\n"),szIMEName));
  255. CopyCHSIMETable(szIMEName,szClassPath);
  256. *lpszRegPathPtr = TEXT('\0');
  257. *lpszClassPtr = TEXT('\0');
  258. }
  259. //
  260. // special case for winabc
  261. //
  262. lstrcpy(szClassPath,TEXT("Microsoft\\IME\\winabc"));
  263. CopyCHSIMETable(TEXT("tmmr.rem"),szClassPath);
  264. CopyCHSIMETable(TEXT("user.rem"),szClassPath);
  265. return TRUE;
  266. }
  267. int WINAPI WinMainCHS(
  268. int nCmd,
  269. HINF hMigrateInf)
  270. {
  271. const UINT nLocale = LOCALE_CHS;
  272. switch(nCmd) {
  273. case FUNC_PatchFEUIFont:
  274. if (FixSchemeProblem(FALSE,hMigrateInf)) {
  275. DebugMsg((DM_VERBOSE,TEXT("FixSchemeProblem OK ! \n")));
  276. }
  277. else {
  278. DebugMsg((DM_VERBOSE,TEXT("FixSchemeProblem Fail ! \n")));
  279. }
  280. break;
  281. case FUNC_PatchInSetup:
  282. if (FixTimeZone(nLocale)) {
  283. DebugMsg((DM_VERBOSE,TEXT("FixTimeZone OK ! \n")));
  284. }
  285. else {
  286. DebugMsg((DM_VERBOSE,TEXT("FixTimeZone failed ! \n")));
  287. }
  288. break;
  289. case FUNC_PatchPreload:
  290. if (PatchPreloadKeyboard(TRUE)) {
  291. DebugMsg((DM_VERBOSE,TEXT("PatchPreloadKeyboard OK ! \n")));
  292. } else {
  293. DebugMsg((DM_VERBOSE,TEXT("PatchPreloadKeyboard Failed ! \n")));
  294. }
  295. break;
  296. case FUNC_PatchInLogon:
  297. if (UpgradeCHSPerUserIMEData()) {
  298. DebugMsg((DM_VERBOSE,TEXT("PatchPreloadKeyboard OK ! \n")));
  299. } else {
  300. DebugMsg((DM_VERBOSE,TEXT("PatchPreloadKeyboard Failed ! \n")));
  301. }
  302. if (RenameRegValueName(hMigrateInf,TRUE)) {
  303. DebugMsg((DM_VERBOSE,TEXT("RenameRegValueName OK ! \n")));
  304. } else {
  305. DebugMsg((DM_VERBOSE,TEXT("RenameRegValueName failed ! \n")));
  306. }
  307. break;
  308. case FUNC_PatchCHSAnsiEMB:
  309. if (ConvertChsANSIImeData()){
  310. DebugMsg((DM_VERBOSE,TEXT("ConvertChsANSIImeData OK ! \n")));
  311. }
  312. else {
  313. DebugMsg((DM_VERBOSE,TEXT("ConvertChsANSIImeData failed ! \n")));
  314. }
  315. case FUNC_PatchTest:
  316. break;
  317. default:
  318. DebugMsg((DM_VERBOSE,TEXT("No such function\n")));
  319. }
  320. return (0);
  321. }