ReactOS 0.4.16-dev-1457-g02ea0aa
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_ WORD 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_ WORD  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, wLow = MAX_USER_IMM_IME_ID, wHigh = MIN_USER_IMM_IME_ID;
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 UINT wNextImeId = 0;
150 if (wHigh < MAX_SYSTEM_IMM_IME_ID)
151 {
152 wNextImeId = wHigh + 1;
153 }
154 else if (wLow > MIN_SYSTEM_IMM_IME_ID)
155 {
156 wNextImeId = wLow - 1;
157 }
158 else
159 {
160 UINT wID;
161 for (wID = MIN_USER_IMM_IME_ID; wID <= MAX_USER_IMM_IME_ID; ++wID)
162 {
163 for (iKL = 0; iKL < cKLs; ++iKL)
164 {
165 if (LOWORD(pLayouts[iKL].hKL) == wLangID && HIWORD(pLayouts[iKL].hKL) == wID)
166 break;
167 }
168
169 if (iKL >= cKLs)
170 break;
171 }
172
173 if (wID <= MAX_SYSTEM_IMM_IME_ID)
174 wNextImeId = wID;
175 }
176
177 if (!wNextImeId)
178 {
179 ERR("No next IMM IME ID\n");
180 return NULL;
181 }
182
183 return UlongToHandle(MAKELONG(wLangID, wNextImeId));
184}
#define ERR(fmt,...)
Definition: precomp.h:57
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define NULL
Definition: types.h:112
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define LOWORD(l)
Definition: pedump.c:82
#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 359 of file install.c.

362{
363 BOOL ret = FALSE, bLoaded = FALSE;
364
365 /* Load LZ32.dll for copying/decompressing file */
366 WCHAR szLZ32Path[MAX_PATH];
367 Imm32GetSystemLibraryPath(szLZ32Path, _countof(szLZ32Path), L"LZ32");
368 HMODULE hinstLZ32 = GetModuleHandleW(szLZ32Path);
369 if (!hinstLZ32)
370 {
371 hinstLZ32 = LoadLibraryW(szLZ32Path);
372 if (IS_NULL_UNEXPECTEDLY(hinstLZ32))
373 return FALSE;
374 bLoaded = TRUE;
375 }
376
377 FN_LZOpenFileW fnLZOpenFileW;
378 FN_LZCopy fnLZCopy;
379 FN_LZClose fnLZClose;
380#define GET_FN(name) do { \
381 fn##name = (FN_##name)GetProcAddress(hinstLZ32, #name); \
382 if (!fn##name) goto Quit; \
383} while (0)
385 GET_FN(LZCopy);
387#undef GET_FN
388
389 CHAR szDestA[MAX_PATH];
390 HFILE hfDest, hfSrc;
391 OFSTRUCT OFStruct;
392
393 if (!WideCharToMultiByte(CP_ACP, 0, pszNewFile, -1, szDestA, _countof(szDestA), NULL, NULL))
394 goto Quit;
395 szDestA[_countof(szDestA) - 1] = ANSI_NULL; /* Avoid buffer overrun */
396
397 hfSrc = fnLZOpenFileW((PWSTR)pszOldFile, &OFStruct, OF_READ);
398 if (hfSrc < 0)
399 goto Quit;
400
401 hfDest = OpenFile(szDestA, &OFStruct, OF_CREATE);
402 if (hfDest != HFILE_ERROR)
403 {
404 ret = (fnLZCopy(hfSrc, hfDest) >= 0);
405 _lclose(hfDest);
406 }
407
408 fnLZClose(hfSrc);
409
410Quit:
411 if (bLoaded)
412 FreeLibrary(hinstLZ32);
413 return ret;
414}
#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
#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:66
#define HFILE_ERROR
Definition: winbase.h:119
#define OF_READ
Definition: winbase.h:124
#define OF_CREATE
Definition: winbase.h:133
int HFILE
Definition: windef.h:298
__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 187 of file install.c.

190{
191 /* Open the registry keyboard layouts */
192 HKEY hkeyLayouts;
194 if (IS_ERROR_UNEXPECTEDLY(lError))
195 return 0;
196
197 UINT iKey, nCount;
198 WCHAR szImeFileName[80], szImeKey[20];
199 DWORD cbData, Value;
200 HKL hKL;
201 for (iKey = nCount = 0; ; ++iKey)
202 {
203 /* Get the key name */
204 lError = RegEnumKeyW(hkeyLayouts, iKey, szImeKey, _countof(szImeKey));
205 if (lError != ERROR_SUCCESS)
206 break;
207
208 if (szImeKey[0] != L'E' && szImeKey[0] != L'e')
209 continue; /* Not an IME layout */
210
211 if (pLayouts == NULL) /* for counting only */
212 {
213 ++nCount;
214 continue;
215 }
216
217 if (cLayouts <= nCount)
218 break;
219
220 HKEY hkeyIME;
221 lError = RegOpenKeyW(hkeyLayouts, szImeKey, &hkeyIME); /* Open the IME key */
222 if (IS_ERROR_UNEXPECTEDLY(lError))
223 continue;
224
225 /* Load the "Ime File" value */
226 szImeFileName[0] = UNICODE_NULL;
227 cbData = sizeof(szImeFileName);
228 RegQueryValueExW(hkeyIME, L"Ime File", NULL, NULL, (LPBYTE)szImeFileName, &cbData);
229 szImeFileName[_countof(szImeFileName) - 1] = UNICODE_NULL; /* Avoid buffer overrun */
230
231 RegCloseKey(hkeyIME);
232
233 /* We don't allow the invalid "IME File" values for security reason */
234 if (!szImeFileName[0] || wcscspn(szImeFileName, L":\\/") != wcslen(szImeFileName))
235 {
236 WARN("Invalid IME Filename (%s)\n", debugstr_w(szImeFileName));
237 continue;
238 }
239
240 Imm32StrToUInt(szImeKey, &Value, 16);
241 hKL = UlongToHandle(Value);
242 if (!IS_IME_HKL(hKL)) /* Not an IMM IME */
243 {
244 WARN("Not IMM IME HKL: %p\n", hKL);
245 continue;
246 }
247
248 /* Store the IME key and the IME filename */
249 pLayouts[nCount].hKL = hKL;
250 StringCchCopyW(pLayouts[nCount].szImeKey, _countof(pLayouts[nCount].szImeKey), szImeKey);
251 StringCchCopyW(pLayouts[nCount].szFileName, _countof(pLayouts[nCount].szFileName),
252 szImeFileName);
253 ++nCount;
254 }
255
256 RegCloseKey(hkeyLayouts);
257 return nCount;
258}
#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
unsigned long DWORD
Definition: ntddk_ex.h:95
#define IS_IME_HKL(hKL)
Definition: imm32_undoc.h:21
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define debugstr_w
Definition: kernel32.h:32
UINT_PTR HKL
Definition: msctf.idl:125
#define UNICODE_NULL
_Check_return_ _CRTIMP size_t __cdecl wcscspn(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_Control)
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:85
#define IS_ERROR_UNEXPECTEDLY(x)
Definition: precomp.h:69
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;
44 LPWSTR pszValue;
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
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;
67 UINT cbData;
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 418 of file install.c.

419{
420 HINSTANCE hinstVersion;
421 BOOL ret = FALSE, bLoaded = FALSE;
423 LPVOID pVerInfo;
424 DWORD cbVerInfo, dwHandle;
425
426 /* Load version.dll to use the version info API */
428 hinstVersion = GetModuleHandleW(szPath);
429 if (!hinstVersion)
430 {
431 hinstVersion = LoadLibraryW(szPath);
432 if (IS_NULL_UNEXPECTEDLY(hinstVersion))
433 return FALSE;
434
435 bLoaded = TRUE;
436 }
437
438#define GET_FN(name) do { \
439 s_fn##name = (FN_##name)GetProcAddress(hinstVersion, #name); \
440 if (!s_fn##name) goto Quit; \
441} while (0)
445#undef GET_FN
446
447 /* The path of the IME module */
448 Imm32GetSystemLibraryPath(szPath, _countof(szPath), pImeInfoEx->wszImeFile);
449
450 cbVerInfo = s_fnGetFileVersionInfoSizeW(szPath, &dwHandle);
451 if (IS_ZERO_UNEXPECTEDLY(cbVerInfo))
452 goto Quit;
453
454 pVerInfo = ImmLocalAlloc(0, cbVerInfo);
455 if (IS_NULL_UNEXPECTEDLY(pVerInfo))
456 goto Quit;
457
458 /* Load the version info of the IME module */
459 if (s_fnGetFileVersionInfoW(szPath, dwHandle, cbVerInfo, pVerInfo) &&
460 Imm32LoadImeFixedInfo(pImeInfoEx, pVerInfo, cbVerInfo))
461 {
462 ret = Imm32LoadImeLangAndDesc(pImeInfoEx, pVerInfo, cbVerInfo);
463 }
464
465 ImmLocalFree(pVerInfo);
466
467Quit:
468 if (bLoaded)
469 FreeLibrary(hinstVersion);
470 TRACE("ret: %d\n", ret);
471 return ret;
472}
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:67
#define ImmLocalFree(lpData)
Definition: precomp.h:105
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 262 of file install.c.

266{
267 UINT iPreload;
268 HKEY hkeyLayouts, hkeyIME, hkeyPreload;
269 WCHAR szImeKey[20], szPreloadNumber[20], szPreloadKey[20];
270 DWORD cbData;
272 LONG lError;
273 LPCWSTR pszLayoutFile;
274
275 /* Open the registry keyboard layouts */
277 if (IS_ERROR_UNEXPECTEDLY(lError))
278 return FALSE;
279
280 /* Get the IME key from hKL */
281 StringCchPrintfW(szImeKey, _countof(szImeKey), L"%08X", HandleToUlong(hKL));
282
283 /* Create a registry IME key */
284 lError = RegCreateKeyW(hkeyLayouts, szImeKey, &hkeyIME);
285 if (IS_ERROR_UNEXPECTEDLY(lError))
286 goto Failure;
287
288 /* Write "Ime File" */
289 cbData = (wcslen(pchFileTitle) + 1) * sizeof(WCHAR);
290 lError = RegSetValueExW(hkeyIME, L"Ime File", 0, REG_SZ, (LPBYTE)pchFileTitle, cbData);
291 if (IS_ERROR_UNEXPECTEDLY(lError))
292 goto Failure;
293
294 /* Write "Layout Text" */
295 cbData = (wcslen(pszLayoutText) + 1) * sizeof(WCHAR);
296 lError = RegSetValueExW(hkeyIME, L"Layout Text", 0, REG_SZ, (LPBYTE)pszLayoutText, cbData);
297 if (IS_ERROR_UNEXPECTEDLY(lError))
298 goto Failure;
299
300 /* Choose "Layout File" from hKL */
301 LangID = LOWORD(hKL);
302 switch (LOBYTE(LangID))
303 {
304 case LANG_JAPANESE: pszLayoutFile = L"kbdjpn.dll"; break;
305 case LANG_KOREAN: pszLayoutFile = L"kbdkor.dll"; break;
306 default: pszLayoutFile = L"kbdus.dll"; break;
307 }
308
309 /* Write "Layout File" */
310 cbData = (wcslen(pszLayoutFile) + 1) * sizeof(WCHAR);
311 lError = RegSetValueExW(hkeyIME, L"Layout File", 0, REG_SZ, (LPBYTE)pszLayoutFile, cbData);
312 if (IS_ERROR_UNEXPECTEDLY(lError))
313 goto Failure;
314
315 RegCloseKey(hkeyIME);
316 RegCloseKey(hkeyLayouts);
317
318 /* Create "Preload" key */
319 RegCreateKeyW(HKEY_CURRENT_USER, L"Keyboard Layout\\Preload", &hkeyPreload);
320
321#define MAX_PRELOAD 0x400
322 for (iPreload = 1; iPreload < MAX_PRELOAD; ++iPreload)
323 {
324 Imm32UIntToStr(iPreload, 10, szPreloadNumber, _countof(szPreloadNumber));
325
326 /* Load the key of the preload number */
327 cbData = sizeof(szPreloadKey);
328 lError = RegQueryValueExW(hkeyPreload, szPreloadNumber, NULL, NULL,
329 (LPBYTE)szPreloadKey, &cbData);
330 szPreloadKey[_countof(szPreloadKey) - 1] = UNICODE_NULL; /* Avoid buffer overrun */
331
332 if (lError != ERROR_SUCCESS || _wcsicmp(szImeKey, szPreloadKey) == 0)
333 break; /* Found an empty room or the same key */
334 }
335
336 if (iPreload >= MAX_PRELOAD) /* Not found */
337 {
338 ERR("iPreload: %u\n", iPreload);
339 RegCloseKey(hkeyPreload);
340 return FALSE;
341 }
342#undef MAX_PRELOAD
343
344 /* Write the IME key to the preload number */
345 cbData = (wcslen(szImeKey) + 1) * sizeof(WCHAR);
346 lError = RegSetValueExW(hkeyPreload, szPreloadNumber, 0, REG_SZ, (LPBYTE)szImeKey, cbData);
347 RegCloseKey(hkeyPreload);
348 return lError == ERROR_SUCCESS;
349
350Failure:
351 RegCloseKey(hkeyIME);
352 RegDeleteKeyW(hkeyLayouts, szImeKey);
353 RegCloseKey(hkeyLayouts);
354 return FALSE;
355}
#define HandleToUlong(h)
Definition: basetsd.h:79
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
#define LOBYTE(W)
Definition: jmemdos.c:487
#define REG_SZ
Definition: layer.c:22
long LONG
Definition: pedump.c:60
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#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 478 of file install.c.

481{
482 HKL hKL = NULL;
483 LPWSTR pszFileNameW = NULL, pszLayoutTextW = NULL;
484
485 TRACE("(%s, %s)\n", debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText));
486
487 pszFileNameW = Imm32WideFromAnsi(CP_ACP, lpszIMEFileName);
488 if (IS_NULL_UNEXPECTEDLY(pszFileNameW))
489 goto Quit;
490
491 pszLayoutTextW = Imm32WideFromAnsi(CP_ACP, lpszLayoutText);
492 if (IS_NULL_UNEXPECTEDLY(pszLayoutTextW))
493 goto Quit;
494
495 hKL = ImmInstallIMEW(pszFileNameW, pszLayoutTextW);
496
497Quit:
498 ImmLocalFree(pszFileNameW);
499 ImmLocalFree(pszLayoutTextW);
500 return hKL;
501}
#define debugstr_a
Definition: kernel32.h:31
HKL WINAPI ImmInstallIMEW(_In_ LPCWSTR lpszIMEFileName, _In_ LPCWSTR lpszLayoutText)
Definition: install.c:507
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 507 of file install.c.

510{
511 TRACE("(%s, %s)\n", debugstr_w(lpszIMEFileName), debugstr_w(lpszLayoutText));
512
513 /* Get full pathname and file title */
514 WCHAR szImeFileName[MAX_PATH];
515 PWSTR pchFileTitle;
516 GetFullPathNameW(lpszIMEFileName, _countof(szImeFileName), szImeFileName, &pchFileTitle);
517 if (IS_NULL_UNEXPECTEDLY(pchFileTitle))
518 return NULL;
519
520 /* Load the IME version info */
521 IMEINFOEX InfoEx;
522 HKL hNewKL;
523 InfoEx.hkl = hNewKL = NULL;
524 StringCchCopyW(InfoEx.wszImeFile, _countof(InfoEx.wszImeFile), pchFileTitle);
525 if (!Imm32LoadImeVerInfo(&InfoEx) || !InfoEx.hkl)
526 {
527 ERR("Can't get version info (error: %lu)\n", GetLastError());
528 return NULL;
529 }
530 WORD wLangID = LOWORD(InfoEx.hkl);
531
532 /* Get the IME layouts from registry */
533 PREG_IME_LAYOUT pLayouts = NULL;
534 UINT iLayout, cLayouts = Imm32GetImeLayoutList(NULL, 0);
535 if (cLayouts)
536 {
537 pLayouts = ImmLocalAlloc(0, cLayouts * sizeof(REG_IME_LAYOUT));
538 if (IS_NULL_UNEXPECTEDLY(pLayouts))
539 return NULL;
540
541 if (!Imm32GetImeLayoutList(pLayouts, cLayouts))
542 {
543 ERR("Can't get IME layouts\n");
544 ImmLocalFree(pLayouts);
545 return NULL;
546 }
547
548 for (iLayout = 0; iLayout < cLayouts; ++iLayout)
549 {
550 if (_wcsicmp(pLayouts[iLayout].szFileName, pchFileTitle) == 0)
551 {
552 if (wLangID != LOWORD(pLayouts[iLayout].hKL))
553 {
554 ERR("The language is mismatched\n");
555 goto Quit;
556 }
557
558 hNewKL = pLayouts[iLayout].hKL; /* Found */
559 break;
560 }
561 }
562 }
563
564 /* If the IME for the specified filename is already loaded, then unload it now */
565 if (ImmGetImeInfoEx(&InfoEx, ImeInfoExImeFileName, pchFileTitle) &&
566 !UnloadKeyboardLayout(InfoEx.hkl))
567 {
568 ERR("Can't unload laybout\n");
569 hNewKL = NULL;
570 goto Quit;
571 }
572
573 WCHAR szImeDestPath[MAX_PATH], szImeKey[20];
574 Imm32GetSystemLibraryPath(szImeDestPath, _countof(szImeDestPath), pchFileTitle);
575
576 /* If the source and the destination pathnames were different, then copy the IME file */
577 if (_wcsicmp(szImeFileName, szImeDestPath) != 0 &&
578 !Imm32CopyImeFile(szImeFileName, szImeDestPath))
579 {
580 ERR("Can't copy file (%s -> %s)\n", debugstr_w(szImeFileName), debugstr_w(szImeDestPath));
581 hNewKL = NULL;
582 goto Quit;
583 }
584
585 if (hNewKL == NULL)
586 hNewKL = Imm32AssignNewLayout(cLayouts, pLayouts, wLangID);
587
588 if (hNewKL)
589 {
590 /* Write the IME layout to registry */
591 if (Imm32WriteImeLayout(hNewKL, pchFileTitle, lpszLayoutText))
592 {
593 /* Replace the current keyboard layout */
594 StringCchPrintfW(szImeKey, _countof(szImeKey), L"%08X", HandleToUlong(hNewKL));
595 hNewKL = LoadKeyboardLayoutW(szImeKey, KLF_REPLACELANG);
596 }
597 else
598 {
599 ERR("Can't write IME layout to registry\n");
600 hNewKL = NULL;
601 }
602 }
603
604Quit:
605 ImmLocalFree(pLayouts);
606 return hNewKL;
607}
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:82
WCHAR wszImeFile[80]
Definition: imm32_undoc.h:69
static HKL Imm32AssignNewLayout(_In_ UINT cKLs, _In_reads_(cKLs) const REG_IME_LAYOUT *pLayouts, _In_ WORD wLangID)
Definition: install.c:132
static UINT Imm32GetImeLayoutList(_Out_writes_opt_(cLayouts) PREG_IME_LAYOUT pLayouts, _In_ UINT cLayouts)
Definition: install.c:187
BOOL Imm32LoadImeVerInfo(_Inout_ PIMEINFOEX pImeInfoEx)
Definition: install.c:418
static BOOL Imm32CopyImeFile(_In_ PCWSTR pszOldFile, _In_ PCWSTR pszNewFile)
Definition: install.c:359
static BOOL Imm32WriteImeLayout(_In_ HKL hKL, _In_ PCWSTR pchFileTitle, _In_ PCWSTR pszLayoutText)
Definition: install.c:262
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().