Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

layime.c

Go to the documentation of this file.
00001 /**************************************************************************\ 00002 * Module Name: layout.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * IMM User Mode Routines 00007 * 00008 * History: 00009 * 03-Jan-1996 wkwok Created 00010 \**************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 00015 00016 #define VERSION_DLL TEXT("version.dll") 00017 #define VER_FILE_VERSION TEXT("FileVersion") 00018 00019 #define SZ_BACKSLASH TEXT("\\") 00020 00021 #define WCHAR_BACKSLASH L'\\' 00022 #define WCHAR_NULL L'\0' 00023 00024 #define VERSION_GetFileVersionInfoW "GetFileVersionInfoW" 00025 #define VERSION_GetFileVersionInfoSizeW "GetFileVersionInfoSizeW" 00026 #define VERSION_VerQueryValueW "VerQueryValueW" 00027 00028 typedef BOOL (WINAPI *LPFNGETFILEVERSIONINFOW)(PWSTR, DWORD, DWORD, LPVOID); 00029 typedef DWORD (WINAPI *LPFNGETFILEVERSIONINFOSIZEW)(PWSTR, LPDWORD); 00030 typedef BOOL (WINAPI *LPFNVERQUERYVALUEW)(const LPVOID, PWSTR, LPVOID*, LPDWORD); 00031 typedef VS_FIXEDFILEINFO *PFIXEDFILEINFO; 00032 00033 static LPFNGETFILEVERSIONINFOW pfnGetFileVersionInfoW; 00034 static LPFNGETFILEVERSIONINFOSIZEW pfnGetFileVersionInfoSizeW; 00035 static LPFNVERQUERYVALUEW pfnVerQueryValueW; 00036 00037 00038 BOOL ImmLoadLayout( 00039 HKL hKL, 00040 PIMEINFOEX piiex) 00041 { 00042 UNICODE_STRING strIme; 00043 WCHAR wszIme[MAX_PATH]; 00044 HKEY hKeyKbdLayout, hKeyIme; 00045 NTSTATUS Status; 00046 DWORD dwTmp; 00047 LONG lRet; 00048 00049 strIme.Buffer = wszIme; 00050 strIme.MaximumLength = sizeof(wszIme); 00051 00052 Status = RtlIntegerToUnicodeString(HandleToUlong(hKL), 16, &strIme); 00053 if (!NT_SUCCESS(Status)) { 00054 return(FALSE); 00055 } 00056 00057 lRet = RegOpenKey(HKEY_LOCAL_MACHINE, gszRegKbdLayout, &hKeyKbdLayout); 00058 if ( lRet != ERROR_SUCCESS ) { 00059 return(FALSE); 00060 } 00061 00062 lRet = RegOpenKey(hKeyKbdLayout, strIme.Buffer, &hKeyIme); 00063 if ( lRet != ERROR_SUCCESS ) { 00064 RegCloseKey(hKeyKbdLayout); 00065 return(FALSE); 00066 } 00067 00068 dwTmp = IM_FILE_SIZE; 00069 lRet = RegQueryValueEx(hKeyIme, 00070 gszValImeFile, 00071 NULL, 00072 NULL, 00073 (LPBYTE)piiex->wszImeFile, 00074 &dwTmp); 00075 00076 if ( lRet != ERROR_SUCCESS ) { 00077 RegCloseKey(hKeyIme); 00078 RegCloseKey(hKeyKbdLayout); 00079 return(FALSE); 00080 } 00081 00082 piiex->wszImeFile[IM_FILE_SIZE - 1] = L'\0'; 00083 00084 RegCloseKey(hKeyIme); 00085 RegCloseKey(hKeyKbdLayout); 00086 00087 piiex->hkl = hKL; 00088 piiex->fLoadFlag = IMEF_NONLOAD; 00089 00090 return LoadVersionInfo(piiex); 00091 } 00092 00093 // GetSystemPathName() 00094 // create "%windir%\system32\%filename" 00095 VOID GetSystemPathName(PWSTR /*OUT*/ pwszPath, PWSTR pwszFileName, UINT maxChar) 00096 { 00097 UINT fnLen = wcslen(pwszFileName); 00098 UINT i = GetSystemDirectoryW(pwszPath, maxChar); 00099 00100 UserAssert(fnLen + 1 < maxChar); 00101 // avoid error condition 00102 if (fnLen + 1 >= maxChar) { 00103 *pwszPath = L'\0'; 00104 return; 00105 } 00106 if (i > 0 || i < maxChar - fnLen - 1) { 00107 pwszPath += i; 00108 if (pwszPath[-1] != L'\\') 00109 *pwszPath++ = L'\\'; 00110 } 00111 wcscpy(pwszPath, pwszFileName); 00112 } 00113 00114 INT 00115 ExtractColumn( 00116 LPWSTR lpSrc, 00117 WCHAR cSeparator, 00118 UINT uiColumn 00119 ) 00120 00121 /*++ 00122 00123 Routine Description: 00124 00125 00126 Arguments: 00127 00128 lpSrc - "YYYY.MM.DD" or "HH:MM:SS" or "MM.NN" pointer 00129 00130 Return Value: 00131 00132 packed int 00133 00134 --*/ 00135 00136 { 00137 UNICODE_STRING uStr; 00138 WCHAR *pSep, *pStr; 00139 INT i; 00140 00141 if (!lpSrc) { 00142 return 0; 00143 } 00144 00145 pStr = pSep = NULL; 00146 00147 while (uiColumn--) { 00148 pStr = lpSrc; 00149 00150 while (*lpSrc && *lpSrc != cSeparator) { 00151 lpSrc++; 00152 } 00153 00154 if (*lpSrc == cSeparator) { 00155 pSep = lpSrc; 00156 lpSrc++; 00157 } 00158 } 00159 00160 if (pStr) { 00161 if (pSep) { 00162 *pSep = TEXT('\0'); 00163 uStr.Length = (USHORT)((pSep - pStr) * sizeof(WCHAR)); 00164 } 00165 else { 00166 uStr.Length = (USHORT)(((lpSrc - pStr) + 1) * sizeof(WCHAR)); 00167 } 00168 uStr.Buffer = pStr; 00169 uStr.MaximumLength = (USHORT)(uStr.Length + sizeof(WCHAR)); 00170 RtlUnicodeStringToInteger(&uStr, 0, &i); 00171 if (pSep) { 00172 *pSep = cSeparator; 00173 } 00174 } else { 00175 i = 0; 00176 } 00177 00178 return i; 00179 } 00180 00181 00182 PWSTR GetVersionDatum( 00183 PWSTR pszVersionBuffer, 00184 PWSTR pszVersionKey, 00185 PWSTR pszName) 00186 { 00187 ULONG ulSize; 00188 DWORD cbValue = 0; 00189 PWSTR pValue; 00190 00191 ulSize = wcslen(pszVersionKey); 00192 wcscat(pszVersionKey, pszName); 00193 00194 (*pfnVerQueryValueW)(pszVersionBuffer, 00195 pszVersionKey, 00196 (LPVOID*)&pValue, 00197 &cbValue); 00198 00199 pszVersionKey[ulSize] = L'\0'; 00200 return (cbValue != 0) ? pValue : (PWSTR)NULL; 00201 } 00202 00203 00204 BOOL LoadFixVersionInfo( 00205 PIMEINFOEX piiex, 00206 PWSTR pszVersionBuffer) 00207 { 00208 PFIXEDFILEINFO pFixedVersionInfo; 00209 BOOL fResult; 00210 DWORD cbValue; 00211 00212 fResult = (*pfnVerQueryValueW)(pszVersionBuffer, 00213 SZ_BACKSLASH, 00214 &pFixedVersionInfo, 00215 &cbValue); 00216 00217 if (!fResult || cbValue == 0) 00218 return FALSE; 00219 00220 /* 00221 * Check for IME file type. 00222 */ 00223 if (pFixedVersionInfo->dwFileType != VFT_DRV || 00224 pFixedVersionInfo->dwFileSubtype != VFT2_DRV_INPUTMETHOD) { 00225 return FALSE; 00226 } 00227 00228 piiex->dwProdVersion = pFixedVersionInfo->dwProductVersionMS; 00229 00230 /* 00231 * Currently, we only support 4.0 DLL based IME. 00232 */ 00233 piiex->dwImeWinVersion = IMEVER_0400; 00234 00235 return TRUE; 00236 } 00237 00238 BOOL LoadVarVersionInfo( 00239 PIMEINFOEX piiex, 00240 PWSTR pszVersionBuffer) 00241 { 00242 PWSTR pDescription; 00243 WORD wLangId; 00244 BOOL fResult; 00245 PUSHORT puXlate; 00246 DWORD cbValue; 00247 WCHAR szVersionKey[80]; 00248 00249 fResult = (*pfnVerQueryValueW)(pszVersionBuffer, 00250 L"\\VarFileInfo\\Translation", 00251 (LPVOID *)&puXlate, 00252 &cbValue); 00253 00254 if (!fResult || cbValue == 0) 00255 return FALSE; 00256 00257 wLangId = *puXlate; 00258 00259 if (piiex->hkl == 0) { 00260 /* 00261 * A newly installed IME, its HKL is not assigned yet. 00262 */ 00263 piiex->hkl = (HKL)LongToHandle( MAKELONG(wLangId, 0) ); 00264 } 00265 #if 0 // let unlocalized IME to work. 00266 else if (LOWORD(HandleToUlong(piiex->hkl)) != wLangId){ 00267 /* 00268 * Mismatch in Lang ID, blow out 00269 */ 00270 return FALSE; 00271 } 00272 #endif 00273 00274 /* 00275 * First try the language we are currently in. 00276 */ 00277 wsprintf(szVersionKey, L"\\StringFileInfo\\%04X04B0\\", 00278 LANGIDFROMLCID(GetThreadLocale())); 00279 00280 pDescription = GetVersionDatum(pszVersionBuffer, szVersionKey, 00281 L"FileDescription"); 00282 00283 if (pDescription == NULL) { 00284 /* 00285 * Now try the first translation specified in IME 00286 */ 00287 wsprintf(szVersionKey, L"\\StringFileInfo\\%04X%04X\\", 00288 *puXlate, *(puXlate+1)); 00289 00290 pDescription = GetVersionDatum(pszVersionBuffer, szVersionKey, 00291 L"FileDescription"); 00292 } 00293 00294 if (pDescription != NULL) { 00295 wcscpy(piiex->wszImeDescription, pDescription); 00296 } 00297 else { 00298 piiex->wszImeDescription[0] = L'\0'; 00299 } 00300 00301 return TRUE; 00302 } 00303 00304 00305 BOOL LoadVersionInfo( 00306 PIMEINFOEX piiex) 00307 { 00308 WCHAR szPath[MAX_PATH]; 00309 PWSTR pszVersionBuffer; 00310 HANDLE hVersion; 00311 DWORD dwVersionSize; 00312 DWORD dwHandle = 0; 00313 BOOL fUnload, fReturn = FALSE; 00314 00315 hVersion = GetModuleHandle(VERSION_DLL); 00316 if (hVersion != NULL) { 00317 fUnload = FALSE; 00318 } 00319 else { 00320 hVersion = LoadLibrary(VERSION_DLL); 00321 if (hVersion == NULL) { 00322 return FALSE; 00323 } 00324 fUnload = TRUE; 00325 } 00326 00327 #define GET_PROC(x) \ 00328 if (!(pfn##x = (PVOID) GetProcAddress(hVersion, VERSION_##x))) { \ 00329 goto LoadVerInfoUnload; } 00330 00331 GET_PROC(GetFileVersionInfoW); 00332 GET_PROC(GetFileVersionInfoSizeW); 00333 GET_PROC(VerQueryValueW); 00334 00335 #undef GET_PROC 00336 00337 // szPath = fully qualified IME file name 00338 GetSystemPathName(szPath, piiex->wszImeFile, ARRAY_SIZE(szPath)); 00339 00340 dwVersionSize = (*pfnGetFileVersionInfoSizeW)(szPath, &dwHandle); 00341 00342 if (dwVersionSize == 0L) 00343 goto LoadVerInfoUnload; 00344 00345 pszVersionBuffer = (PWSTR)ImmLocalAlloc(0, dwVersionSize); 00346 00347 if (pszVersionBuffer == NULL) // can't get memory for version info, blow out 00348 goto LoadVerInfoUnload; 00349 00350 if (!(*pfnGetFileVersionInfoW)(szPath, dwHandle, dwVersionSize, pszVersionBuffer)) 00351 goto LoadVerInfoFree; 00352 00353 /* 00354 * Get the fixed block version information. 00355 */ 00356 if (LoadFixVersionInfo(piiex, pszVersionBuffer)) { 00357 /* 00358 * Get the variable block version information. 00359 */ 00360 fReturn = LoadVarVersionInfo(piiex, pszVersionBuffer); 00361 } 00362 00363 LoadVerInfoFree: 00364 ImmLocalFree((HLOCAL)pszVersionBuffer); 00365 00366 LoadVerInfoUnload: 00367 if (fUnload) 00368 FreeLibrary(hVersion); 00369 00370 return fReturn; 00371 }

Generated on Sat May 15 19:40:36 2004 for test by doxygen 1.3.7