ReactOS 0.4.16-dev-2491-g3dc6630
install.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS IMM32
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Implementing IME installation
5 * COPYRIGHT: Copyright 2020-2025 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#include "precomp.h"
9
11
12/* An IME layout entry in registry */
13typedef struct tagREG_IME_LAYOUT
14{
16 WCHAR szImeKey[20]; /* "E0XXYYYY": "E0XX" is the device handle. "YYYY" is a LANGID. */
17 WCHAR szFileName[80]; /* The IME module filename */
19
20/* For using version.dll */
24
28
29/* Used in Imm32CopyImeFile */
33
34/* Gets a version information entry by using version!VerQueryValueW */
35static LPWSTR
37 _In_reads_bytes_(cbVerInfo) LPCVOID pVerInfo,
38 _In_ DWORD cbVerInfo,
39 _Inout_ PWSTR pszKey,
40 _In_ DWORD cchKey,
41 _In_ PCWSTR pszName)
42{
43 size_t cchExtra;
45 UINT cbValue = 0;
46
47 StringCchLengthW(pszKey, cchKey, &cchExtra);
48
49 StringCchCatW(pszKey, cchKey, pszName);
50 s_fnVerQueryValueW(pVerInfo, pszKey, (LPVOID *)&pszValue, &cbValue);
51 pszKey[cchExtra] = UNICODE_NULL; /* Avoid buffer overrun */
52
53 ASSERT(cbValue <= cbVerInfo);
54
55 return (cbValue ? pszValue : NULL);
56}
57
58/* Gets the language and description of an IME */
59static BOOL
61 _Inout_ PIMEINFOEX pInfoEx,
62 _In_reads_bytes_(cbVerInfo) LPCVOID pVerInfo,
63 _In_ DWORD cbVerInfo)
64{
65 /* Getting the version info. See VerQueryValue */
66 LPWORD pw;
68 BOOL ret = s_fnVerQueryValueW(pVerInfo, L"\\VarFileInfo\\Translation", (LPVOID *)&pw, &cbData);
69 if (!ret || !cbData)
70 {
71 ERR("Translation not available\n");
72 return FALSE;
73 }
74
75 ASSERT(cbData <= cbVerInfo);
76
77 if (pInfoEx->hkl == NULL)
78 pInfoEx->hkl = UlongToHandle(*pw);
79
80 /* Try the current language and the Unicode codepage (0x04B0) */
82 WCHAR szKey[80];
83 StringCchPrintfW(szKey, _countof(szKey), L"\\StringFileInfo\\%04X04B0\\", LangID);
84 LPWSTR pszDesc = Imm32GetVerInfoValue(pVerInfo, cbVerInfo, szKey, _countof(szKey), L"FileDescription");
85 if (!pszDesc)
86 {
87 /* Retry the language and codepage of the IME module */
88 StringCchPrintfW(szKey, _countof(szKey), L"\\StringFileInfo\\%04X%04X\\", pw[0], pw[1]);
89 pszDesc = Imm32GetVerInfoValue(pVerInfo, cbVerInfo, szKey, _countof(szKey), L"FileDescription");
90 }
91
92 /* The description */
93 if (pszDesc)
94 StringCchCopyW(pInfoEx->wszImeDescription, _countof(pInfoEx->wszImeDescription), pszDesc);
95 else
96 pInfoEx->wszImeDescription[0] = UNICODE_NULL;
97
98 return TRUE;
99}
100
101/* Gets the fixed version info from IME */
102static BOOL
104 _Out_ PIMEINFOEX pInfoEx,
105 _In_reads_bytes_(cbVerInfo) LPCVOID pVerInfo,
106 _In_ DWORD cbVerInfo)
107{
108 UINT cbFixed = 0;
109 VS_FIXEDFILEINFO *pFixed;
110 if (!s_fnVerQueryValueW(pVerInfo, L"\\", (LPVOID *)&pFixed, &cbFixed) || !cbFixed)
111 {
112 ERR("Fixed version info not available\n");
113 return FALSE;
114 }
115
116 ASSERT(cbFixed <= cbVerInfo);
117
118 /* NOTE: The IME module must contain a version info of input method driver. */
119 if (pFixed->dwFileType != VFT_DRV || pFixed->dwFileSubtype != VFT2_DRV_INPUTMETHOD)
120 {
121 ERR("DLL '%s' is not an IME\n", debugstr_w(pInfoEx->wszImeFile));
122 return FALSE;
123 }
124
125 pInfoEx->dwProdVersion = pFixed->dwProductVersionMS;
126 pInfoEx->dwImeWinVersion = IMEVER_0400;
127 return TRUE;
128}
129
130/* Generates a new IMM IME HKL (0xE0XXYYYY) */
131static HKL
133 _In_ UINT cKLs,
134 _In_reads_(cKLs) const REG_IME_LAYOUT *pLayouts,
135 _In_ LANGID wLangID)
136{
137#define MIN_SYSTEM_IMM_IME_ID 0xE000
138#define MAX_SYSTEM_IMM_IME_ID 0xE0FF
139#define MIN_USER_IMM_IME_ID 0xE020
140#define MAX_USER_IMM_IME_ID MAX_SYSTEM_IMM_IME_ID
141 UINT iKL, nID, wLow = MAX_USER_IMM_IME_ID, wHigh = MIN_USER_IMM_IME_ID - 1;
142
143 for (iKL = 0; iKL < cKLs; ++iKL)
144 {
145 wHigh = max(wHigh, HIWORD(pLayouts[iKL].hKL));
146 wLow = min(wLow, HIWORD(pLayouts[iKL].hKL));
147 }
148
149 if (!cKLs || wHigh + 1 <= MAX_SYSTEM_IMM_IME_ID)
150 {
151 nID = wHigh + 1;
152 }
153 else if (wLow - 1 > MIN_SYSTEM_IMM_IME_ID)
154 {
155 nID = wLow - 1;
156 }
157 else
158 {
159 for (nID = MIN_USER_IMM_IME_ID; nID <= MAX_USER_IMM_IME_ID; ++nID)
160 {
161 HKL hKL = LongToHandle(MAKELONG(wLangID, nID));
162 for (iKL = 0; iKL < cKLs; ++iKL)
163 {
164 if (pLayouts[iKL].hKL == hKL)
165 break;
166 }
167 if (iKL >= cKLs)
168 break;
169 }
170
171 if (nID > MAX_USER_IMM_IME_ID)
172 {
173 ERR("No empty room for new IME HKL\n");
174 return NULL;
175 }
176 }
177
178 return (HKL)LongToHandle(MAKELONG(wLangID, nID));
179}
180
181static UINT
183 _Out_writes_opt_(cLayouts) PREG_IME_LAYOUT pLayouts,
184 _In_ UINT cLayouts)
185{
186 /* Open the registry keyboard layouts */
187 HKEY hkeyLayouts;
189 if (IS_ERROR_UNEXPECTEDLY(lError))
190 return 0;
191
192 UINT iKey, nCount;
193 WCHAR szImeFileName[80], szImeKey[20];
195 HKL hKL;
196 for (iKey = nCount = 0; ; ++iKey)
197 {
198 /* Get the key name */
199 lError = RegEnumKeyW(hkeyLayouts, iKey, szImeKey, _countof(szImeKey));
200 if (lError != ERROR_SUCCESS)
201 break;
202
203 if (szImeKey[0] != L'E' && szImeKey[0] != L'e')
204 continue; /* Not an IME layout */
205
206 if (pLayouts == NULL) /* for counting only */
207 {
208 ++nCount;
209 continue;
210 }
211
212 if (cLayouts <= nCount)
213 break;
214
215 HKEY hkeyIME;
216 lError = RegOpenKeyW(hkeyLayouts, szImeKey, &hkeyIME); /* Open the IME key */
217 if (IS_ERROR_UNEXPECTEDLY(lError))
218 continue;
219
220 /* Load the "Ime File" value */
221 szImeFileName[0] = UNICODE_NULL;
222 cbData = sizeof(szImeFileName);
223 RegQueryValueExW(hkeyIME, L"Ime File", NULL, NULL, (LPBYTE)szImeFileName, &cbData);
224 szImeFileName[_countof(szImeFileName) - 1] = UNICODE_NULL; /* Avoid buffer overrun */
225
226 RegCloseKey(hkeyIME);
227
228 /* We don't allow the invalid "IME File" values for security reason */
229 if (!szImeFileName[0] || wcscspn(szImeFileName, L":\\/") != wcslen(szImeFileName))
230 {
231 WARN("Invalid IME Filename (%s)\n", debugstr_w(szImeFileName));
232 continue;
233 }
234
235 Imm32StrToUInt(szImeKey, &Value, 16);
236 hKL = UlongToHandle(Value);
237 if (!IS_IME_HKL(hKL)) /* Not an IMM IME */
238 {
239 WARN("Not IMM IME HKL: %p\n", hKL);
240 continue;
241 }
242
243 /* Store the IME key and the IME filename */
244 pLayouts[nCount].hKL = hKL;
245 StringCchCopyW(pLayouts[nCount].szImeKey, _countof(pLayouts[nCount].szImeKey), szImeKey);
246 StringCchCopyW(pLayouts[nCount].szFileName, _countof(pLayouts[nCount].szFileName),
247 szImeFileName);
248 ++nCount;
249 }
250
251 RegCloseKey(hkeyLayouts);
252 return nCount;
253}
254
255/* Write an IME layout to registry */
256static BOOL
258 _In_ HKL hKL,
259 _In_ PCWSTR pchFileTitle,
260 _In_ PCWSTR pszLayoutText)
261{
262 UINT iPreload;
263 HKEY hkeyLayouts, hkeyIME, hkeyPreload;
264 WCHAR szImeKey[20], szPreloadNumber[20], szPreloadKey[20];
267 LONG lError;
268 LPCWSTR pszLayoutFile;
269
270 /* Open the registry keyboard layouts */
272 if (IS_ERROR_UNEXPECTEDLY(lError))
273 return FALSE;
274
275 /* Get the IME key from hKL */
276 StringCchPrintfW(szImeKey, _countof(szImeKey), L"%08X", HandleToUlong(hKL));
277
278 /* Create a registry IME key */
279 lError = RegCreateKeyW(hkeyLayouts, szImeKey, &hkeyIME);
280 if (IS_ERROR_UNEXPECTEDLY(lError))
281 goto Failure;
282
283 /* Write "Ime File" */
284 cbData = (wcslen(pchFileTitle) + 1) * sizeof(WCHAR);
285 lError = RegSetValueExW(hkeyIME, L"Ime File", 0, REG_SZ, (LPBYTE)pchFileTitle, cbData);
286 if (IS_ERROR_UNEXPECTEDLY(lError))
287 goto Failure;
288
289 /* Write "Layout Text" */
290 cbData = (wcslen(pszLayoutText) + 1) * sizeof(WCHAR);
291 lError = RegSetValueExW(hkeyIME, L"Layout Text", 0, REG_SZ, (LPBYTE)pszLayoutText, cbData);
292 if (IS_ERROR_UNEXPECTEDLY(lError))
293 goto Failure;
294
295 /* Choose "Layout File" from hKL */
296 LangID = LOWORD(hKL);
297 switch (LOBYTE(LangID))
298 {
299 case LANG_JAPANESE: pszLayoutFile = L"kbdjpn.dll"; break;
300 case LANG_KOREAN: pszLayoutFile = L"kbdkor.dll"; break;
301 default: pszLayoutFile = L"kbdus.dll"; break;
302 }
303
304 /* Write "Layout File" */
305 cbData = (wcslen(pszLayoutFile) + 1) * sizeof(WCHAR);
306 lError = RegSetValueExW(hkeyIME, L"Layout File", 0, REG_SZ, (LPBYTE)pszLayoutFile, cbData);
307 if (IS_ERROR_UNEXPECTEDLY(lError))
308 goto Failure;
309
310 RegCloseKey(hkeyIME);
311 RegCloseKey(hkeyLayouts);
312
313 /* Create "Preload" key */
314 RegCreateKeyW(HKEY_CURRENT_USER, L"Keyboard Layout\\Preload", &hkeyPreload);
315
316#define MAX_PRELOAD 0x400
317 for (iPreload = 1; iPreload < MAX_PRELOAD; ++iPreload)
318 {
319 Imm32UIntToStr(iPreload, 10, szPreloadNumber, _countof(szPreloadNumber));
320
321 /* Load the key of the preload number */
322 cbData = sizeof(szPreloadKey);
323 lError = RegQueryValueExW(hkeyPreload, szPreloadNumber, NULL, NULL,
324 (LPBYTE)szPreloadKey, &cbData);
325 szPreloadKey[_countof(szPreloadKey) - 1] = UNICODE_NULL; /* Avoid buffer overrun */
326
327 if (lError != ERROR_SUCCESS || _wcsicmp(szImeKey, szPreloadKey) == 0)
328 break; /* Found an empty room or the same key */
329 }
330
331 if (iPreload >= MAX_PRELOAD) /* Not found */
332 {
333 ERR("iPreload: %u\n", iPreload);
334 RegCloseKey(hkeyPreload);
335 return FALSE;
336 }
337#undef MAX_PRELOAD
338
339 /* Write the IME key to the preload number */
340 cbData = (wcslen(szImeKey) + 1) * sizeof(WCHAR);
341 lError = RegSetValueExW(hkeyPreload, szPreloadNumber, 0, REG_SZ, (LPBYTE)szImeKey, cbData);
342 RegCloseKey(hkeyPreload);
343 return lError == ERROR_SUCCESS;
344
345Failure:
346 RegCloseKey(hkeyIME);
347 RegDeleteKeyW(hkeyLayouts, szImeKey);
348 RegCloseKey(hkeyLayouts);
349 return FALSE;
350}
351
352/* Copy an IME file with using LZ decompression */
353static BOOL
355 _In_ PCWSTR pszOldFile,
356 _In_ PCWSTR pszNewFile)
357{
358 BOOL ret = FALSE, bLoaded = FALSE;
359
360 /* Load LZ32.dll for copying/decompressing file */
361 WCHAR szLZ32Path[MAX_PATH];
362 Imm32GetSystemLibraryPath(szLZ32Path, _countof(szLZ32Path), L"LZ32");
363 HMODULE hinstLZ32 = GetModuleHandleW(szLZ32Path);
364 if (!hinstLZ32)
365 {
366 hinstLZ32 = LoadLibraryW(szLZ32Path);
367 if (IS_NULL_UNEXPECTEDLY(hinstLZ32))
368 return FALSE;
369 bLoaded = TRUE;
370 }
371
372 FN_LZOpenFileW fnLZOpenFileW;
373 FN_LZCopy fnLZCopy;
374 FN_LZClose fnLZClose;
375#define GET_FN(name) do { \
376 fn##name = (FN_##name)GetProcAddress(hinstLZ32, #name); \
377 if (!fn##name) goto Quit; \
378} while (0)
380 GET_FN(LZCopy);
382#undef GET_FN
383
384 CHAR szDestA[MAX_PATH];
385 HFILE hfDest, hfSrc;
386 OFSTRUCT OFStruct;
387
388 if (!WideCharToMultiByte(CP_ACP, 0, pszNewFile, -1, szDestA, _countof(szDestA), NULL, NULL))
389 goto Quit;
390 szDestA[_countof(szDestA) - 1] = ANSI_NULL; /* Avoid buffer overrun */
391
392 hfSrc = fnLZOpenFileW((PWSTR)pszOldFile, &OFStruct, OF_READ);
393 if (hfSrc < 0)
394 goto Quit;
395
396 hfDest = OpenFile(szDestA, &OFStruct, OF_CREATE);
397 if (hfDest != HFILE_ERROR)
398 {
399 ret = (fnLZCopy(hfSrc, hfDest) >= 0);
400 _lclose(hfDest);
401 }
402
403 fnLZClose(hfSrc);
404
405Quit:
406 if (bLoaded)
407 FreeLibrary(hinstLZ32);
408 return ret;
409}
410
411/* Loads version info of an IME by using version!{GetFileVersionInfo,VerQueryValue} etc. */
412BOOL
414{
415 HINSTANCE hinstVersion;
416 BOOL ret = FALSE, bLoaded = FALSE;
418 LPVOID pVerInfo;
419 DWORD cbVerInfo, dwHandle;
420
421 /* Load version.dll to use the version info API */
423 hinstVersion = GetModuleHandleW(szPath);
424 if (!hinstVersion)
425 {
426 hinstVersion = LoadLibraryW(szPath);
427 if (IS_NULL_UNEXPECTEDLY(hinstVersion))
428 return FALSE;
429
430 bLoaded = TRUE;
431 }
432
433#define GET_FN(name) do { \
434 s_fn##name = (FN_##name)GetProcAddress(hinstVersion, #name); \
435 if (!s_fn##name) goto Quit; \
436} while (0)
440#undef GET_FN
441
442 /* The path of the IME module */
443 Imm32GetSystemLibraryPath(szPath, _countof(szPath), pImeInfoEx->wszImeFile);
444
445 cbVerInfo = s_fnGetFileVersionInfoSizeW(szPath, &dwHandle);
446 if (IS_ZERO_UNEXPECTEDLY(cbVerInfo))
447 goto Quit;
448
449 pVerInfo = ImmLocalAlloc(0, cbVerInfo);
450 if (IS_NULL_UNEXPECTEDLY(pVerInfo))
451 goto Quit;
452
453 /* Load the version info of the IME module */
454 if (s_fnGetFileVersionInfoW(szPath, dwHandle, cbVerInfo, pVerInfo) &&
455 Imm32LoadImeFixedInfo(pImeInfoEx, pVerInfo, cbVerInfo))
456 {
457 ret = Imm32LoadImeLangAndDesc(pImeInfoEx, pVerInfo, cbVerInfo);
458 }
459
460 ImmLocalFree(pVerInfo);
461
462Quit:
463 if (bLoaded)
464 FreeLibrary(hinstVersion);
465 TRACE("ret: %d\n", ret);
466 return ret;
467}
468
469/***********************************************************************
470 * ImmInstallIMEA (IMM32.@)
471 */
474 _In_ LPCSTR lpszIMEFileName,
475 _In_ LPCSTR lpszLayoutText)
476{
477 HKL hKL = NULL;
478 LPWSTR pszFileNameW = NULL, pszLayoutTextW = NULL;
479
480 TRACE("(%s, %s)\n", debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText));
481
482 pszFileNameW = Imm32WideFromAnsi(CP_ACP, lpszIMEFileName);
483 if (IS_NULL_UNEXPECTEDLY(pszFileNameW))
484 goto Quit;
485
486 pszLayoutTextW = Imm32WideFromAnsi(CP_ACP, lpszLayoutText);
487 if (IS_NULL_UNEXPECTEDLY(pszLayoutTextW))
488 goto Quit;
489
490 hKL = ImmInstallIMEW(pszFileNameW, pszLayoutTextW);
491
492Quit:
493 ImmLocalFree(pszFileNameW);
494 ImmLocalFree(pszLayoutTextW);
495 return hKL;
496}
497
498/***********************************************************************
499 * ImmInstallIMEW (IMM32.@)
500 */
503 _In_ LPCWSTR lpszIMEFileName,
504 _In_ LPCWSTR lpszLayoutText)
505{
506 TRACE("(%s, %s)\n", debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText));
507
508 /* Get full pathname and file title */
509 WCHAR szImeFileName[MAX_PATH];
510 PWSTR pchFileTitle;
511 GetFullPathNameW(lpszIMEFileName, _countof(szImeFileName), szImeFileName, &pchFileTitle);
512 if (IS_NULL_UNEXPECTEDLY(pchFileTitle))
513 return NULL;
514
515 /* Load the IME version info */
516 IMEINFOEX InfoEx;
517 HKL hNewKL;
518 InfoEx.hkl = hNewKL = NULL;
519 StringCchCopyW(InfoEx.wszImeFile, _countof(InfoEx.wszImeFile), pchFileTitle);
520 if (!Imm32LoadImeVerInfo(&InfoEx) || !InfoEx.hkl)
521 {
522 ERR("Can't get version info (error: %lu)\n", GetLastError());
523 return NULL;
524 }
525 WORD wLangID = LOWORD(InfoEx.hkl);
526
527 /* Get the IME layouts from registry */
528 PREG_IME_LAYOUT pLayouts = NULL;
529 UINT iLayout, cLayouts = Imm32GetImeLayoutList(NULL, 0);
530 if (cLayouts)
531 {
532 pLayouts = ImmLocalAlloc(0, cLayouts * sizeof(REG_IME_LAYOUT));
533 if (IS_NULL_UNEXPECTEDLY(pLayouts))
534 return NULL;
535
536 if (!Imm32GetImeLayoutList(pLayouts, cLayouts))
537 {
538 ERR("Can't get IME layouts\n");
539 ImmLocalFree(pLayouts);
540 return NULL;
541 }
542
543 for (iLayout = 0; iLayout < cLayouts; ++iLayout)
544 {
545 if (_wcsicmp(pLayouts[iLayout].szFileName, pchFileTitle) == 0)
546 {
547 if (wLangID != LOWORD(pLayouts[iLayout].hKL))
548 {
549 ERR("The language is mismatched\n");
550 goto Quit;
551 }
552
553 hNewKL = pLayouts[iLayout].hKL; /* Found */
554 break;
555 }
556 }
557 }
558
559 /* If the IME for the specified filename is already loaded, then unload it now */
560 if (ImmGetImeInfoEx(&InfoEx, ImeInfoExImeFileName, pchFileTitle) &&
561 !UnloadKeyboardLayout(InfoEx.hkl))
562 {
563 ERR("Can't unload laybout\n");
564 hNewKL = NULL;
565 goto Quit;
566 }
567
568 WCHAR szImeDestPath[MAX_PATH], szImeKey[20];
569 Imm32GetSystemLibraryPath(szImeDestPath, _countof(szImeDestPath), pchFileTitle);
570
571 /* If the source and the destination pathnames were different, then copy the IME file */
572 if (_wcsicmp(szImeFileName, szImeDestPath) != 0 &&
573 !Imm32CopyImeFile(szImeFileName, szImeDestPath))
574 {
575 ERR("Can't copy file (%s -> %s)\n", debugstr_w(szImeFileName), debugstr_w(szImeDestPath));
576 hNewKL = NULL;
577 goto Quit;
578 }
579
580 if (hNewKL == NULL)
581 hNewKL = Imm32AssignNewLayout(cLayouts, pLayouts, wLangID);
582
583 if (hNewKL)
584 {
585 /* Write the IME layout to registry */
586 if (Imm32WriteImeLayout(hNewKL, pchFileTitle, lpszLayoutText))
587 {
588 /* Replace the current keyboard layout */
589 StringCchPrintfW(szImeKey, _countof(szImeKey), L"%08X", HandleToUlong(hNewKL));
590 hNewKL = LoadKeyboardLayoutW(szImeKey, KLF_REPLACELANG);
591 }
592 else
593 {
594 ERR("Can't write IME layout to registry\n");
595 hNewKL = NULL;
596 }
597 }
598
599Quit:
600 ImmLocalFree(pLayouts);
601 return hNewKL;
602}
#define VOID
Definition: acefi.h:82
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define LongToHandle(h)
Definition: basetsd.h:76
#define UlongToHandle(ul)
Definition: basetsd.h:91
#define HandleToUlong(h)
Definition: basetsd.h:73
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
LONG WINAPI RegEnumKeyW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, DWORD cbName)
Definition: reg.c:2393
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
#define CP_ACP
Definition: compat.h:109
#define FreeLibrary(x)
Definition: compat.h:748
#define MAX_PATH
Definition: compat.h:34
#define WideCharToMultiByte
Definition: compat.h:111
#define LoadLibraryW(x)
Definition: compat.h:747
HFILE WINAPI OpenFile(LPCSTR lpFileName, LPOFSTRUCT lpReOpenBuff, UINT uStyle)
Definition: create.c:368
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
LCID WINAPI GetThreadLocale(void)
Definition: locale.c:2803
BOOL WINAPI GetFileVersionInfoW(LPCWSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:967
BOOL WINAPI VerQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen)
Definition: version.c:1171
DWORD WINAPI GetFileVersionInfoSizeW(LPCWSTR filename, LPDWORD handle)
Definition: version.c:738
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:159
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
_ACRTIMP size_t __cdecl wcscspn(const wchar_t *, const wchar_t *)
Definition: wcs.c:498
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define IS_IME_HKL(hKL)
Definition: imm32_undoc.h:21
BOOL WINAPI ImmGetImeInfoEx(_Out_ PIMEINFOEX pImeInfoEx, _In_ IMEINFOEXCLASS SearchType, _In_ PVOID pvSearchKey)
@ ImeInfoExImeFileName
Definition: imm32_undoc.h:84
#define IMEVER_0400
Definition: imm.h:243
#define LOBYTE(W)
Definition: jmemdos.c:487
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define REG_SZ
Definition: layer.c:22
int WINAPI _lclose(HFILE hFile)
Definition: lfile.c:138
USHORT LANGID
Definition: mui.h:9
HFILE WINAPI LZOpenFileW(LPWSTR fn, LPOFSTRUCT ofs, WORD mode)
Definition: lzexpand.c:580
LONG WINAPI LZCopy(HFILE src, HFILE dest)
Definition: lzexpand.c:467
void WINAPI LZClose(HFILE fd)
Definition: lzexpand.c:595
int HFILE
Definition: minwindef.h:222
CONST void * LPCVOID
Definition: minwindef.h:164
#define ASSERT(a)
Definition: mode.c:44
LPCWSTR szPath
Definition: env.c:37
static HANDLE LPVOID
Definition: install.c:28
static INT
Definition: install.c:29
#define min(a, b)
Definition: monoChain.cc:55
UINT_PTR HKL
Definition: msctf.idl:125
unsigned int * PUINT
Definition: ndis.h:50
unsigned int UINT
Definition: ndis.h:50
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Inout_
Definition: no_sal2.h:162
#define _Out_writes_opt_(s)
Definition: no_sal2.h:226
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define LPDWORD
Definition: nt_native.h:46
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
#define UNICODE_NULL
#define ANSI_NULL
#define LOWORD(l)
Definition: pedump.c:82
long LONG
Definition: pedump.c:60
_In_opt_ _In_opt_ _In_ _In_ DWORD cbData
Definition: shlwapi.h:761
_In_opt_ LPCSTR _In_opt_ LPCSTR pszValue
Definition: shlwapi.h:783
#define LANGIDFROMLCID(l)
Definition: nls.h:18
#define LANG_JAPANESE
Definition: nls.h:76
#define LANG_KOREAN
Definition: nls.h:84
#define _countof(array)
Definition: sndvol32.h:70
#define TRACE(s)
Definition: solgame.cpp:4
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
STRSAFEAPI StringCchLengthW(STRSAFE_LPCWSTR psz, size_t cchMax, size_t *pcchLength)
Definition: strsafe.h:842
WCHAR wszImeFile[80]
Definition: imm32_undoc.h:71
WCHAR szFileName[80]
Definition: install.c:17
WCHAR szImeKey[20]
Definition: install.c:16
DWORD dwProductVersionMS
Definition: compat.h:904
DWORD dwFileSubtype
Definition: compat.h:910
#define max(a, b)
Definition: svc.c:63
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWORD
Definition: typedefs.h:56
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define HIWORD(l)
Definition: typedefs.h:247
#define VFT_DRV
Definition: verrsrc.h:77
#define VFT2_DRV_INPUTMETHOD
Definition: verrsrc.h:95
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT _In_ UCHAR _In_opt_ USHORT LangID
Definition: wdfusb.h:1083
static BOOL Imm32LoadImeLangAndDesc(_Inout_ PIMEINFOEX pInfoEx, _In_reads_bytes_(cbVerInfo) LPCVOID pVerInfo, _In_ DWORD cbVerInfo)
Definition: install.c:60
#define MAX_USER_IMM_IME_ID
INT(WINAPI * FN_LZOpenFileW)(LPWSTR, LPOFSTRUCT, WORD)
Definition: install.c:30
static HKL Imm32AssignNewLayout(_In_ UINT cKLs, _In_reads_(cKLs) const REG_IME_LAYOUT *pLayouts, _In_ LANGID wLangID)
Definition: install.c:132
static FN_GetFileVersionInfoW s_fnGetFileVersionInfoW
Definition: install.c:25
#define MIN_SYSTEM_IMM_IME_ID
struct tagREG_IME_LAYOUT REG_IME_LAYOUT
#define MIN_USER_IMM_IME_ID
#define GET_FN(name)
static UINT Imm32GetImeLayoutList(_Out_writes_opt_(cLayouts) PREG_IME_LAYOUT pLayouts, _In_ UINT cLayouts)
Definition: install.c:182
BOOL(WINAPI * FN_VerQueryValueW)(LPCVOID, LPCWSTR, LPVOID *, PUINT)
Definition: install.c:23
LONG(WINAPI * FN_LZCopy)(INT, INT)
Definition: install.c:31
#define MAX_SYSTEM_IMM_IME_ID
BOOL Imm32LoadImeVerInfo(_Inout_ PIMEINFOEX pImeInfoEx)
Definition: install.c:413
static BOOL Imm32CopyImeFile(_In_ PCWSTR pszOldFile, _In_ PCWSTR pszNewFile)
Definition: install.c:354
DWORD(WINAPI * FN_GetFileVersionInfoSizeW)(LPCWSTR, LPDWORD)
Definition: install.c:22
static LPWSTR Imm32GetVerInfoValue(_In_reads_bytes_(cbVerInfo) LPCVOID pVerInfo, _In_ DWORD cbVerInfo, _Inout_ PWSTR pszKey, _In_ DWORD cchKey, _In_ PCWSTR pszName)
Definition: install.c:36
static BOOL Imm32LoadImeFixedInfo(_Out_ PIMEINFOEX pInfoEx, _In_reads_bytes_(cbVerInfo) LPCVOID pVerInfo, _In_ DWORD cbVerInfo)
Definition: install.c:103
static FN_GetFileVersionInfoSizeW s_fnGetFileVersionInfoSizeW
Definition: install.c:26
static BOOL Imm32WriteImeLayout(_In_ HKL hKL, _In_ PCWSTR pchFileTitle, _In_ PCWSTR pszLayoutText)
Definition: install.c:257
struct tagREG_IME_LAYOUT * PREG_IME_LAYOUT
BOOL(WINAPI * FN_GetFileVersionInfoW)(LPCWSTR, DWORD, DWORD, LPVOID)
Definition: install.c:21
HKL WINAPI ImmInstallIMEW(_In_ LPCWSTR lpszIMEFileName, _In_ LPCWSTR lpszLayoutText)
Definition: install.c:502
VOID(WINAPI * FN_LZClose)(INT)
Definition: install.c:32
static FN_VerQueryValueW s_fnVerQueryValueW
Definition: install.c:27
#define MAX_PRELOAD
HKL WINAPI ImmInstallIMEA(_In_ LPCSTR lpszIMEFileName, _In_ LPCSTR lpszLayoutText)
Definition: install.c:473
#define IS_ZERO_UNEXPECTEDLY(p)
Definition: precomp.h:68
#define ImmLocalFree(lpData)
Definition: precomp.h:102
LPWSTR Imm32WideFromAnsi(UINT uCodePage, LPCSTR pszA)
Definition: utils.c:96
#define REGKEY_KEYBOARD_LAYOUTS
Definition: precomp.h:82
#define IS_ERROR_UNEXPECTEDLY(x)
Definition: precomp.h:70
BOOL Imm32GetSystemLibraryPath(LPWSTR pszPath, DWORD cchPath, LPCWSTR pszFileName)
Definition: utils.c:152
HRESULT Imm32UIntToStr(_In_ DWORD dwValue, _In_ ULONG nBase, _Out_ PWSTR pszBuff, _In_ USHORT cchBuff)
Definition: utils.c:56
#define IS_NULL_UNEXPECTEDLY(p)
Definition: precomp.h:67
LPVOID ImmLocalAlloc(_In_ DWORD dwFlags, _In_ DWORD dwBytes)
Definition: utils.c:275
HRESULT Imm32StrToUInt(_In_ PCWSTR pszText, _Out_ PDWORD pdwValue, _In_ ULONG nBase)
Definition: utils.c:40
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
struct _OFSTRUCT * LPOFSTRUCT
#define HFILE_ERROR
Definition: winbase.h:113
#define OF_READ
Definition: winbase.h:118
#define OF_CREATE
Definition: winbase.h:127
#define WINAPI
Definition: msvc.h:6
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
BOOL WINAPI UnloadKeyboardLayout(_In_ HKL)
#define KLF_REPLACELANG
Definition: winuser.h:115
HKL WINAPI LoadKeyboardLayoutW(_In_ LPCWSTR, _In_ UINT)
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char CHAR
Definition: xmlstorage.h:175