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.

246 lines
6.8 KiB

  1. //
  2. // Copyright (c) 1997-1999 Microsoft Corporation.
  3. //
  4. #include <windows.h>
  5. #include <imm.h>
  6. #include "resource.h"
  7. #include "imeblink.h"
  8. #define UNICODE_CP 1200
  9. /************************************************************/
  10. /* MatchImeName() */
  11. /************************************************************/
  12. HKL MatchImeName(
  13. LPCTSTR szStr)
  14. {
  15. TCHAR szImeName[MAX_PATH];
  16. int nLayout;
  17. HKL hKL=NULL;
  18. HGLOBAL hMem;
  19. HKL FAR * lpMem;
  20. int i;
  21. if (!szStr)
  22. {
  23. return hKL;
  24. }
  25. nLayout = GetKeyboardLayoutList(0, NULL);
  26. // alloc temp buffer
  27. hMem = GlobalAlloc(GHND, sizeof(HKL) * nLayout);
  28. if (!hMem) {
  29. return (NULL);
  30. }
  31. lpMem = (HKL FAR *)GlobalLock(hMem);
  32. if (!lpMem) {
  33. GlobalFree(hMem);
  34. return (NULL);
  35. }
  36. // get all keyboard layouts, it includes all IMEs
  37. GetKeyboardLayoutList(nLayout, lpMem);
  38. for (i = 0; i < nLayout; i++) {
  39. LRESULT lRet;
  40. hKL = *(lpMem + i);
  41. lRet = ImmEscape(hKL, (HIMC)NULL, IME_ESC_IME_NAME, szImeName);
  42. if (!lRet) { // this hKL can not ask name
  43. continue;
  44. }
  45. if (lstrcmp(szStr, szImeName) == 0) {
  46. goto MatchOvr;
  47. }
  48. }
  49. hKL = NULL;
  50. MatchOvr:
  51. GlobalUnlock(hMem);
  52. GlobalFree(hMem);
  53. return (hKL);
  54. }
  55. /************************************************************/
  56. /* RegisterTable() */
  57. /************************************************************/
  58. HKL RegisterTable(
  59. HWND hWnd,
  60. LPUSRDICIMHDR lpIsvUsrDic,
  61. DWORD dwFileSize,
  62. UINT uCodePage)
  63. {
  64. HKL hKL=NULL;
  65. // HDC hDC;
  66. // SIZE lTextSize;
  67. // RECT rcProcess;
  68. DWORD i;
  69. LPBYTE lpCurr, lpEnd;
  70. BOOL fRet;
  71. TCHAR szStr[ARRAYLEN(lpIsvUsrDic->achMethodName)];
  72. // TCHAR szProcessFmt[32];
  73. // TCHAR szResult[2][32];
  74. // TCHAR szProcessInfo[48];
  75. WORD wInternalCode[256];
  76. WORD wAltInternalCode[256];
  77. if (!lpIsvUsrDic)
  78. {
  79. return hKL;
  80. }
  81. #ifdef UNICODE
  82. if (uCodePage == UNICODE_CP) {
  83. LPUNATSTR lpszMethodName;
  84. lpszMethodName = (LPUNATSTR)lpIsvUsrDic->achMethodName;
  85. for (i = 0; i < sizeof(lpIsvUsrDic->achMethodName) / sizeof(TCHAR); i++) {
  86. szStr[i] = *lpszMethodName++;
  87. }
  88. szStr[i] = '\0';
  89. } else {
  90. UINT uLen;
  91. uLen = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED,
  92. (LPCSTR)lpIsvUsrDic->achMethodName,
  93. sizeof(lpIsvUsrDic->achMethodName),
  94. szStr,
  95. ARRAYLEN(szStr));
  96. if (uLen == 0)
  97. {
  98. uCodePage = CP_ACP;
  99. uLen = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED,
  100. (LPCSTR)lpIsvUsrDic->achMethodName,
  101. sizeof(lpIsvUsrDic->achMethodName),
  102. szStr,
  103. ARRAYLEN(szStr));
  104. }
  105. szStr[uLen] = '\0';
  106. }
  107. #else
  108. for (i = 0; i < sizeof(lpIsvUsrDic->achMethodName); i++) {
  109. szStr[i] = lpIsvUsrDic->achMethodName[i];
  110. }
  111. szStr[i] = '\0';
  112. #endif
  113. hKL = MatchImeName(szStr);
  114. if (!hKL) {
  115. return (hKL);
  116. }
  117. // convert sequence code to internal code
  118. for (i = 0; i < sizeof(wInternalCode) / sizeof(WORD); i++) {
  119. LRESULT lRet;
  120. lRet = ImmEscape(hKL, (HIMC)NULL,
  121. IME_ESC_SEQUENCE_TO_INTERNAL, &i);
  122. if (HIWORD(lRet) == 0xFFFF) {
  123. // This is caused by sign extent in Win9x in the return value of
  124. // ImmEscape, it causes an invalid internal code.
  125. wAltInternalCode[i] = 0;
  126. } else {
  127. wAltInternalCode[i] = HIWORD(lRet);
  128. }
  129. wInternalCode[i] = LOWORD(lRet);
  130. #ifndef UNICODE
  131. if (wAltInternalCode[i] > 0xFF) {
  132. // convert to multi byte string
  133. wAltInternalCode[i] = LOBYTE(wAltInternalCode[i]) << 8 |
  134. HIBYTE(wAltInternalCode[i]);
  135. }
  136. if (wInternalCode[i] > 0xFF) {
  137. // convert to multi byte string
  138. wInternalCode[i] = LOBYTE(wInternalCode[i]) << 8 |
  139. HIBYTE(wInternalCode[i]);
  140. }
  141. #endif
  142. }
  143. // check for each record and register it
  144. // get to the first record and skip the Bank ID
  145. lpCurr = (LPBYTE)(lpIsvUsrDic + 1) + sizeof(WORD);
  146. lpEnd = (LPBYTE)lpIsvUsrDic + dwFileSize;
  147. for (; lpCurr < lpEnd;
  148. // internal code + sequence code + Bank ID of next record
  149. lpCurr += sizeof(WORD) + lpIsvUsrDic->cMethodKeySize + sizeof(WORD)) {
  150. int j;
  151. // quick way to init \0 for the register string
  152. *(LPDWORD)szStr = 0;
  153. #ifdef UNICODE
  154. if (uCodePage == UNICODE_CP) {
  155. szStr[0] = *(LPUNATSTR)lpCurr;
  156. } else {
  157. CHAR szMultiByte[4];
  158. szMultiByte[0] = HIBYTE(*(LPTSTR)lpCurr);
  159. szMultiByte[1] = LOBYTE(*(LPTSTR)lpCurr);
  160. MultiByteToWideChar(uCodePage, MB_PRECOMPOSED,
  161. szMultiByte, 2, szStr, 2);
  162. }
  163. #else
  164. szStr[1] = *lpCurr;
  165. szStr[0] = *(lpCurr + 1);
  166. #endif
  167. for (i = 0, j = 0; i < lpIsvUsrDic->cMethodKeySize; i++) {
  168. if ((*(LPBYTE)(lpCurr + sizeof(WORD) + i) >= ARRAYLEN(wAltInternalCode)) ||
  169. ((4+j) >= ARRAYLEN(szStr)) )
  170. {
  171. return NULL;
  172. }
  173. if (!wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)]) {
  174. } else if (wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)] < 0xFF) {
  175. *(LPTSTR)&szStr[4 + j] = (TCHAR)
  176. wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)];
  177. j += sizeof(TCHAR) / sizeof(TCHAR);
  178. } else {
  179. *(LPWSTR)&szStr[4 + j] = (WCHAR)
  180. wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)];
  181. j += sizeof(WCHAR) / sizeof(TCHAR);
  182. }
  183. if (wInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)] < 0xFF) {
  184. *(LPTSTR)&szStr[4 + j] = (TCHAR)
  185. wInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)];
  186. j += sizeof(TCHAR) / sizeof(TCHAR);
  187. } else {
  188. *(LPWSTR)&szStr[4 + j] = (WCHAR)
  189. wInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)];
  190. j += sizeof(WCHAR) / sizeof(TCHAR);
  191. }
  192. }
  193. if ( (j+4+2) >= ARRAYLEN(szStr))
  194. {
  195. return NULL;
  196. }
  197. szStr[4 + j] = szStr[4 + j + 1] = szStr[4 + j + 2] = '\0';
  198. fRet = ImmRegisterWord(hKL, &szStr[4], IME_REGWORD_STYLE_EUDC,
  199. szStr);
  200. }
  201. return (hKL);
  202. }