ReactOS 0.4.16-dev-2528-g7139e57
install.c File Reference
#include "precomp.h"
Include dependency graph for install.c:

Go to the source code of this file.

Classes

struct  tagREG_IME_LAYOUT
 

Macros

#define MIN_SYSTEM_IMM_IME_ID   0xE000
 
#define MAX_SYSTEM_IMM_IME_ID   0xE0FF
 
#define MIN_USER_IMM_IME_ID   0xE020
 
#define MAX_USER_IMM_IME_ID   MAX_SYSTEM_IMM_IME_ID
 
#define MAX_PRELOAD   0x400
 
#define GET_FN(name)
 
#define GET_FN(name)
 

Typedefs

typedef struct tagREG_IME_LAYOUT REG_IME_LAYOUT
 
typedef struct tagREG_IME_LAYOUTPREG_IME_LAYOUT
 
typedef BOOL(WINAPIFN_GetFileVersionInfoW) (LPCWSTR, DWORD, DWORD, LPVOID)
 
typedef DWORD(WINAPIFN_GetFileVersionInfoSizeW) (LPCWSTR, LPDWORD)
 
typedef BOOL(WINAPIFN_VerQueryValueW) (LPCVOID, LPCWSTR, LPVOID *, PUINT)
 
typedef INT(WINAPIFN_LZOpenFileW) (LPWSTR, LPOFSTRUCT, WORD)
 
typedef LONG(WINAPIFN_LZCopy) (INT, INT)
 
typedef VOID(WINAPIFN_LZClose) (INT)
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (imm)
 
static LPWSTR Imm32GetVerInfoValue (_In_reads_bytes_(cbVerInfo) LPCVOID pVerInfo, _In_ DWORD cbVerInfo, _Inout_ PWSTR pszKey, _In_ DWORD cchKey, _In_ PCWSTR pszName)
 
static BOOL Imm32LoadImeLangAndDesc (_Inout_ PIMEINFOEX pInfoEx, _In_reads_bytes_(cbVerInfo) LPCVOID pVerInfo, _In_ DWORD cbVerInfo)
 
static BOOL Imm32LoadImeFixedInfo (_Out_ PIMEINFOEX pInfoEx, _In_reads_bytes_(cbVerInfo) LPCVOID pVerInfo, _In_ DWORD cbVerInfo)
 
static HKL Imm32AssignNewLayout (_In_ UINT cKLs, _In_reads_(cKLs) const REG_IME_LAYOUT *pLayouts, _In_ LANGID wLangID)
 
static UINT Imm32GetImeLayoutList (_Out_writes_opt_(cLayouts) PREG_IME_LAYOUT pLayouts, _In_ UINT cLayouts)
 
static BOOL Imm32WriteImeLayout (_In_ HKL hKL, _In_ PCWSTR pchFileTitle, _In_ PCWSTR pszLayoutText)
 
static BOOL Imm32CopyImeFile (_In_ PCWSTR pszOldFile, _In_ PCWSTR pszNewFile)
 
BOOL Imm32LoadImeVerInfo (_Inout_ PIMEINFOEX pImeInfoEx)
 
HKL WINAPI ImmInstallIMEA (_In_ LPCSTR lpszIMEFileName, _In_ LPCSTR lpszLayoutText)
 
HKL WINAPI ImmInstallIMEW (_In_ LPCWSTR lpszIMEFileName, _In_ LPCWSTR lpszLayoutText)
 

Variables

static FN_GetFileVersionInfoW s_fnGetFileVersionInfoW = NULL
 
static FN_GetFileVersionInfoSizeW s_fnGetFileVersionInfoSizeW = NULL
 
static FN_VerQueryValueW s_fnVerQueryValueW = NULL
 

Macro Definition Documentation

◆ GET_FN [1/2]

#define GET_FN (   name)
Value:
do { \
fn##name = (FN_##name)GetProcAddress(hinstLZ32, #name); \
if (!fn##name) goto Quit; \
} while (0)
#define GetProcAddress(x, y)
Definition: compat.h:753
Definition: name.c:39
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159

◆ GET_FN [2/2]

#define GET_FN (   name)
Value:
do { \
s_fn##name = (FN_##name)GetProcAddress(hinstVersion, #name); \
if (!s_fn##name) goto Quit; \
} while (0)

◆ MAX_PRELOAD

#define MAX_PRELOAD   0x400

◆ MAX_SYSTEM_IMM_IME_ID

#define MAX_SYSTEM_IMM_IME_ID   0xE0FF

◆ MAX_USER_IMM_IME_ID

#define MAX_USER_IMM_IME_ID   MAX_SYSTEM_IMM_IME_ID

◆ MIN_SYSTEM_IMM_IME_ID

#define MIN_SYSTEM_IMM_IME_ID   0xE000

◆ MIN_USER_IMM_IME_ID

#define MIN_USER_IMM_IME_ID   0xE020

Typedef Documentation

◆ FN_GetFileVersionInfoSizeW

typedef DWORD(WINAPI * FN_GetFileVersionInfoSizeW) (LPCWSTR, LPDWORD)

Definition at line 22 of file install.c.

◆ FN_GetFileVersionInfoW

typedef BOOL(WINAPI * FN_GetFileVersionInfoW) (LPCWSTR, DWORD, DWORD, LPVOID)

Definition at line 21 of file install.c.

◆ FN_LZClose

typedef VOID(WINAPI * FN_LZClose) (INT)

Definition at line 32 of file install.c.

◆ FN_LZCopy

typedef LONG(WINAPI * FN_LZCopy) (INT, INT)

Definition at line 31 of file install.c.

◆ FN_LZOpenFileW

typedef INT(WINAPI * FN_LZOpenFileW) (LPWSTR, LPOFSTRUCT, WORD)

Definition at line 30 of file install.c.

◆ FN_VerQueryValueW

typedef BOOL(WINAPI * FN_VerQueryValueW) (LPCVOID, LPCWSTR, LPVOID *, PUINT)

Definition at line 23 of file install.c.

◆ PREG_IME_LAYOUT

◆ REG_IME_LAYOUT

Function Documentation

◆ Imm32AssignNewLayout()

static HKL Imm32AssignNewLayout ( _In_ UINT  cKLs,
_In_reads_(cKLs) const REG_IME_LAYOUT pLayouts,
_In_ LANGID  wLangID 
)
static

Definition at line 132 of file install.c.

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 UlongToHandle(MAKELONG(wLangID, nID));
179}
#define ERR(fmt,...)
Definition: precomp.h:57
#define LongToHandle(h)
Definition: basetsd.h:76
#define UlongToHandle(ul)
Definition: basetsd.h:91
#define NULL
Definition: types.h:112
#define min(a, b)
Definition: monoChain.cc:55
UINT_PTR HKL
Definition: msctf.idl:125
unsigned int UINT
Definition: ndis.h:50
#define max(a, b)
Definition: svc.c:63
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define HIWORD(l)
Definition: typedefs.h:247
#define MAX_USER_IMM_IME_ID
#define MIN_SYSTEM_IMM_IME_ID
#define MIN_USER_IMM_IME_ID
#define MAX_SYSTEM_IMM_IME_ID

Referenced by ImmInstallIMEW().

◆ Imm32CopyImeFile()

static BOOL Imm32CopyImeFile ( _In_ PCWSTR  pszOldFile,
_In_ PCWSTR  pszNewFile 
)
static

Definition at line 354 of file install.c.

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}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#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
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
int WINAPI _lclose(HFILE hFile)
Definition: lfile.c:138
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
#define ANSI_NULL
#define _countof(array)
Definition: sndvol32.h:70
uint16_t * PWSTR
Definition: typedefs.h:56
INT(WINAPI * FN_LZOpenFileW)(LPWSTR, LPOFSTRUCT, WORD)
Definition: install.c:30
#define GET_FN(name)
LONG(WINAPI * FN_LZCopy)(INT, INT)
Definition: install.c:31
VOID(WINAPI * FN_LZClose)(INT)
Definition: install.c:32
BOOL Imm32GetSystemLibraryPath(LPWSTR pszPath, DWORD cchPath, LPCWSTR pszFileName)
Definition: utils.c:152
#define IS_NULL_UNEXPECTEDLY(p)
Definition: precomp.h:67
#define HFILE_ERROR
Definition: winbase.h:113
#define OF_READ
Definition: winbase.h:118
#define OF_CREATE
Definition: winbase.h:127
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175

Referenced by ImmInstallIMEW().

◆ Imm32GetImeLayoutList()

static UINT Imm32GetImeLayoutList ( _Out_writes_opt_(cLayouts) PREG_IME_LAYOUT  pLayouts,
_In_ UINT  cLayouts 
)
static

Definition at line 182 of file install.c.

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}
#define WARN(fmt,...)
Definition: precomp.h:61
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
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
_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
unsigned long DWORD
Definition: ntddk_ex.h:95
#define IS_IME_HKL(hKL)
Definition: imm32_undoc.h:21
#define debugstr_w
Definition: kernel32.h:32
#define UNICODE_NULL
_In_opt_ _In_opt_ _In_ _In_ DWORD cbData
Definition: shlwapi.h:761
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
unsigned char * LPBYTE
Definition: typedefs.h:53
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define REGKEY_KEYBOARD_LAYOUTS
Definition: precomp.h:82
#define IS_ERROR_UNEXPECTEDLY(x)
Definition: precomp.h:70
HRESULT Imm32StrToUInt(_In_ PCWSTR pszText, _Out_ PDWORD pdwValue, _In_ ULONG nBase)
Definition: utils.c:40
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by ImmInstallIMEW().

◆ Imm32GetVerInfoValue()

static LPWSTR Imm32GetVerInfoValue ( _In_reads_bytes_(cbVerInfo) LPCVOID  pVerInfo,
_In_ DWORD  cbVerInfo,
_Inout_ PWSTR  pszKey,
_In_ DWORD  cchKey,
_In_ PCWSTR  pszName 
)
static

Definition at line 36 of file install.c.

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}
#define ASSERT(a)
Definition: mode.c:44
_In_opt_ LPCSTR _In_opt_ LPCSTR pszValue
Definition: shlwapi.h:783
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
STRSAFEAPI StringCchLengthW(STRSAFE_LPCWSTR psz, size_t cchMax, size_t *pcchLength)
Definition: strsafe.h:842
static FN_VerQueryValueW s_fnVerQueryValueW
Definition: install.c:27
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by Imm32LoadImeLangAndDesc().

◆ Imm32LoadImeFixedInfo()

static BOOL Imm32LoadImeFixedInfo ( _Out_ PIMEINFOEX  pInfoEx,
_In_reads_bytes_(cbVerInfo) LPCVOID  pVerInfo,
_In_ DWORD  cbVerInfo 
)
static

Definition at line 103 of file install.c.

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}
#define IMEVER_0400
Definition: imm.h:243
#define VFT_DRV
Definition: verrsrc.h:77
#define VFT2_DRV_INPUTMETHOD
Definition: verrsrc.h:95

Referenced by Imm32LoadImeVerInfo().

◆ Imm32LoadImeLangAndDesc()

static BOOL Imm32LoadImeLangAndDesc ( _Inout_ PIMEINFOEX  pInfoEx,
_In_reads_bytes_(cbVerInfo) LPCVOID  pVerInfo,
_In_ DWORD  cbVerInfo 
)
static

Definition at line 60 of file install.c.

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}
LCID WINAPI GetThreadLocale(void)
Definition: locale.c:2803
USHORT LANGID
Definition: mui.h:9
#define LANGIDFROMLCID(l)
Definition: nls.h:18
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
uint16_t * LPWORD
Definition: typedefs.h:56
_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 LPWSTR Imm32GetVerInfoValue(_In_reads_bytes_(cbVerInfo) LPCVOID pVerInfo, _In_ DWORD cbVerInfo, _Inout_ PWSTR pszKey, _In_ DWORD cchKey, _In_ PCWSTR pszName)
Definition: install.c:36

Referenced by Imm32LoadImeVerInfo().

◆ Imm32LoadImeVerInfo()

BOOL Imm32LoadImeVerInfo ( _Inout_ PIMEINFOEX  pImeInfoEx)

Definition at line 413 of file install.c.

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}
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
LPCWSTR szPath
Definition: env.c:37
#define TRACE(s)
Definition: solgame.cpp:4
static BOOL Imm32LoadImeLangAndDesc(_Inout_ PIMEINFOEX pInfoEx, _In_reads_bytes_(cbVerInfo) LPCVOID pVerInfo, _In_ DWORD cbVerInfo)
Definition: install.c:60
static FN_GetFileVersionInfoW s_fnGetFileVersionInfoW
Definition: install.c:25
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
#define IS_ZERO_UNEXPECTEDLY(p)
Definition: precomp.h:68
#define ImmLocalFree(lpData)
Definition: precomp.h:102
LPVOID ImmLocalAlloc(_In_ DWORD dwFlags, _In_ DWORD dwBytes)
Definition: utils.c:275

Referenced by ImmInstallIMEW(), and ImmLoadLayout().

◆ Imm32WriteImeLayout()

static BOOL Imm32WriteImeLayout ( _In_ HKL  hKL,
_In_ PCWSTR  pchFileTitle,
_In_ PCWSTR  pszLayoutText 
)
static

Definition at line 257 of file install.c.

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}
#define HandleToUlong(h)
Definition: basetsd.h:73
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 RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:159
#define LOBYTE(W)
Definition: jmemdos.c:487
#define REG_SZ
Definition: layer.c:22
#define LOWORD(l)
Definition: pedump.c:82
long LONG
Definition: pedump.c:60
#define LANG_JAPANESE
Definition: nls.h:76
#define LANG_KOREAN
Definition: nls.h:84
#define MAX_PRELOAD
HRESULT Imm32UIntToStr(_In_ DWORD dwValue, _In_ ULONG nBase, _Out_ PWSTR pszBuff, _In_ USHORT cchBuff)
Definition: utils.c:56
#define HKEY_CURRENT_USER
Definition: winreg.h:11
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by ImmInstallIMEW().

◆ ImmInstallIMEA()

HKL WINAPI ImmInstallIMEA ( _In_ LPCSTR  lpszIMEFileName,
_In_ LPCSTR  lpszLayoutText 
)

Definition at line 473 of file install.c.

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}
#define debugstr_a
Definition: kernel32.h:31
HKL WINAPI ImmInstallIMEW(_In_ LPCWSTR lpszIMEFileName, _In_ LPCWSTR lpszLayoutText)
Definition: install.c:502
LPWSTR Imm32WideFromAnsi(UINT uCodePage, LPCSTR pszA)
Definition: utils.c:96

Referenced by ActiveIMMApp_InstallIMEA().

◆ ImmInstallIMEW()

HKL WINAPI ImmInstallIMEW ( _In_ LPCWSTR  lpszIMEFileName,
_In_ LPCWSTR  lpszLayoutText 
)

Definition at line 502 of file install.c.

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}
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
unsigned short WORD
Definition: ntddk_ex.h:93
BOOL WINAPI ImmGetImeInfoEx(_Out_ PIMEINFOEX pImeInfoEx, _In_ IMEINFOEXCLASS SearchType, _In_ PVOID pvSearchKey)
@ ImeInfoExImeFileName
Definition: imm32_undoc.h:84
WCHAR wszImeFile[80]
Definition: imm32_undoc.h:71
static HKL Imm32AssignNewLayout(_In_ UINT cKLs, _In_reads_(cKLs) const REG_IME_LAYOUT *pLayouts, _In_ LANGID wLangID)
Definition: install.c:132
static UINT Imm32GetImeLayoutList(_Out_writes_opt_(cLayouts) PREG_IME_LAYOUT pLayouts, _In_ UINT cLayouts)
Definition: install.c:182
BOOL Imm32LoadImeVerInfo(_Inout_ PIMEINFOEX pImeInfoEx)
Definition: install.c:413
static BOOL Imm32CopyImeFile(_In_ PCWSTR pszOldFile, _In_ PCWSTR pszNewFile)
Definition: install.c:354
static BOOL Imm32WriteImeLayout(_In_ HKL hKL, _In_ PCWSTR pchFileTitle, _In_ PCWSTR pszLayoutText)
Definition: install.c:257
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
BOOL WINAPI UnloadKeyboardLayout(_In_ HKL)
#define KLF_REPLACELANG
Definition: winuser.h:115
HKL WINAPI LoadKeyboardLayoutW(_In_ LPCWSTR, _In_ UINT)

Referenced by ActiveIMMApp_InstallIMEW(), and ImmInstallIMEA().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( imm  )

Variable Documentation

◆ s_fnGetFileVersionInfoSizeW

FN_GetFileVersionInfoSizeW s_fnGetFileVersionInfoSizeW = NULL
static

Definition at line 26 of file install.c.

Referenced by Imm32LoadImeVerInfo().

◆ s_fnGetFileVersionInfoW

FN_GetFileVersionInfoW s_fnGetFileVersionInfoW = NULL
static

Definition at line 25 of file install.c.

Referenced by Imm32LoadImeVerInfo().

◆ s_fnVerQueryValueW

FN_VerQueryValueW s_fnVerQueryValueW = NULL
static

Definition at line 27 of file install.c.

Referenced by Imm32GetVerInfoValue(), Imm32LoadImeFixedInfo(), and Imm32LoadImeLangAndDesc().