00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
#include <nt.h>
00011
#include <ntrtl.h>
00012
#include <nturtl.h>
00013
#include <windows.h>
00014
#include <kbd.h>
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#if 0 // FYI: old explanation
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
#endif
00049
00050
00051
#if defined(HIRO_DBG)
00052
#define TRACE(x) DbgPrint x
00053
#else
00054 #define TRACE(x)
00055
#endif
00056
00057
00058
00059
00060 #define MAXBUF_CSIZE (256)
00061
00062
00063
00064
00065
00066
00067
00068 __inline LPWSTR
MakeString(PKEY_VALUE_FULL_INFORMATION pKey, size_t limit)
00069 {
00070 LPWSTR pwszHead = (LPWSTR)((LPBYTE)pKey + pKey->DataOffset);
00071 LPWSTR pwszTail = (LPWSTR)((LPBYTE)pwszHead + pKey->DataLength);
00072
00073
ASSERT((LPBYTE)pwszTail - (LPBYTE)pKey < (
int)limit );
00074 *pwszTail =
L'\0';
00075
00076 UNREFERENCED_PARAMETER(limit);
00077
00078
return pwszHead;
00079 }
00080
00081
#if 0 // not needed any more
00082
00083
00084
00085
00086
00087
00088
00089
00090 WCHAR* FindServices(WCHAR* str)
00091 {
00092 CONST WCHAR wszServices[] =
L"\\services";
00093
00094
while (*str) {
00095 CONST WCHAR* p1;
00096 CONST WCHAR* p2;
00097
for (p1 = str, p2 = wszServices; *p1 && *p2; ++p1, ++p2) {
00098
00099
if (*p2 !=
L'\\') {
00100
if ((*p1 != *p2) && (*p1 + (
L'a' -
L'A') != *p2)) {
00101
break;
00102 }
00103 }
00104
else if (*p1 !=
L'\\') {
00105
break;
00106 }
00107 }
00108
if (*p2 == 0) {
00109
00110
return str;
00111 }
00112 ++str;
00113 }
00114
return NULL;
00115 }
00116
#endif
00117
00118 BOOL GetRealDllFileNameWorker(CONST WCHAR* pwszKeyName, WCHAR* RealDllName)
00119 {
00120
NTSTATUS Status;
00121 HANDLE handleService;
00122
BOOL fRet =
FALSE;
00123 UNICODE_STRING servicePath;
00124 OBJECT_ATTRIBUTES servicePathObjectAttributes;
00125 WCHAR serviceRegistryPath[
MAXBUF_CSIZE];
00126
00127 servicePath.Buffer = serviceRegistryPath;
00128 servicePath.Length = 0;
00129 servicePath.MaximumLength =
sizeof serviceRegistryPath;
00130
00131
RtlAppendUnicodeToString(&servicePath,
00132
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\i8042prt\\Parameters");
00133
00134 InitializeObjectAttributes(&servicePathObjectAttributes,
00135 &servicePath,
00136 OBJ_CASE_INSENSITIVE,
00137
NULL,
00138
NULL);
00139
00140
TRACE((
"Open -> '%ws'\n",servicePath.Buffer));
00141
00142
Status =
NtOpenKey(&handleService, KEY_READ, &servicePathObjectAttributes);
00143
00144
if (
NT_SUCCESS(
Status)) {
00145
00146 UNICODE_STRING layerName;
00147 WCHAR LayerDllName[
MAXBUF_CSIZE];
00148 ULONG cbStringSize;
00149
00150
RtlInitUnicodeString(&layerName, pwszKeyName);
00151
TRACE((
"Entry name -> '%ws'\n", layerName.Buffer));
00152
00153
00154
00155
00156
Status =
NtQueryValueKey(handleService,
00157 &layerName,
00158 KeyValueFullInformation,
00159 LayerDllName,
00160
sizeof LayerDllName -
sizeof(WCHAR),
00161 &cbStringSize);
00162
00163
if (
NT_SUCCESS(
Status)) {
00164 LPWSTR pwszStr =
MakeString((PKEY_VALUE_FULL_INFORMATION)LayerDllName,
00165
sizeof LayerDllName);
00166
00167 wcscpy(RealDllName, pwszStr);
00168
00169
TRACE((
"Real Dll name -> '%ws'\n", RealDllName));
00170
00171
00172
00173
00174 fRet =
TRUE;
00175 }
00176
NtClose(handleService);
00177 }
00178
00179
return fRet;
00180 }
00181
00183
00184
00186
00187 BOOL KbdLayerRealDllFileNT4(WCHAR *RealDllName)
00188 {
00189
TRACE((
"KbdLayerRealDllFile():\n"));
00190
return GetRealDllFileNameWorker(
L"LayerDriver", RealDllName);
00191 }
00192
00194
00195
00196
00198
00199 BOOL KbdLayerRealDllFileForWBT(HKL hkl, WCHAR *realDllName, PCLIENTKEYBOARDTYPE pClientKbdType, LPVOID reserve)
00200 {
00201 HANDLE hkRegistry =
NULL;
00202 UNICODE_STRING deviceMapPath;
00203 OBJECT_ATTRIBUTES deviceMapObjectAttributes;
00204
NTSTATUS Status;
00205 HANDLE handleMap;
00206 HANDLE handleService;
00207 ULONG cbStringSize;
00208 PWCHAR pwszReg;
00209
00210 UNREFERENCED_PARAMETER(reserve);
00211
00212
ASSERT(pClientKbdType !=
NULL);
00213
00214
00215
00216
if (PRIMARYLANGID(LOWORD(hkl)) == LANG_JAPANESE) {
00217 wcscpy(realDllName,
L"kbd101.dll");
00218 pwszReg =
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Terminal Server\\KeyboardType Mapping\\JPN";
00219 }
00220
else if (PRIMARYLANGID(LOWORD(hkl)) == LANG_KOREAN) {
00221 wcscpy(realDllName,
L"kbd101a.dll");
00222 pwszReg =
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Terminal Server\\KeyboardType Mapping\\KOR";
00223 }
00224
else {
00225
ASSERT(
FALSE);
00226 }
00227
00228
00229
00230
00231
00232
RtlInitUnicodeString(&deviceMapPath, pwszReg);
00233
00234 InitializeObjectAttributes(&deviceMapObjectAttributes,
00235 &deviceMapPath,
00236 OBJ_CASE_INSENSITIVE,
00237
NULL,
00238
NULL);
00239
00240
00241
00242
Status =
NtOpenKey(&handleMap, KEY_READ, &deviceMapObjectAttributes);
00243
00244
if (
NT_SUCCESS(
Status)) {
00245 WCHAR SubKbdBuffer[16];
00246 WCHAR FuncKeyBuffer[16];
00247 WCHAR SubKbdAndFuncKeyBuffer[32];
00248 UNICODE_STRING SubKbd = {
00249 0,
sizeof SubKbdBuffer, SubKbdBuffer,
00250 };
00251 UNICODE_STRING FuncKbd = {
00252 0,
sizeof FuncKeyBuffer, FuncKeyBuffer,
00253 };
00254 UNICODE_STRING SubKbdAndFuncKey = {
00255 0,
sizeof SubKbdAndFuncKeyBuffer, SubKbdAndFuncKeyBuffer,
00256 };
00257 UCHAR AnsiBuffer[16];
00258 ANSI_STRING AnsiString;
00259 WCHAR LayerDriverName[256];
00260
00261
00262
00263
00264 RtlZeroMemory(AnsiBuffer,
sizeof(AnsiBuffer));
00265
Status =
RtlIntegerToChar(pClientKbdType->SubType, 16
L,
00266 -8,
00267 AnsiBuffer);
00268
if (
NT_SUCCESS(
Status)) {
00269
00270
00271
00272 AnsiString.Buffer = AnsiBuffer;
00273 AnsiString.MaximumLength =
sizeof AnsiBuffer;
00274 AnsiString.Length = (
USHORT)
strlen(AnsiBuffer);
00275
Status =
RtlAnsiStringToUnicodeString(&SubKbd, &AnsiString,
FALSE);
00276 }
00277
ASSERT(
NT_SUCCESS(
Status));
00278
00279
00280
00281
00282 RtlZeroMemory(AnsiBuffer,
sizeof(AnsiBuffer));
00283
Status =
RtlIntegerToChar(pClientKbdType->FunctionKey, 10
L,
00284 -4,
00285 AnsiBuffer);
00286
if (
NT_SUCCESS(
Status)) {
00287
00288
00289
00290 AnsiString.Buffer = AnsiBuffer;
00291 AnsiString.MaximumLength =
sizeof AnsiBuffer;
00292 AnsiString.Length = (
USHORT)
strlen(AnsiBuffer);
00293
Status =
RtlAnsiStringToUnicodeString(&FuncKbd, &AnsiString,
FALSE);
00294 }
00295
ASSERT(
NT_SUCCESS(
Status));
00296
00297
00298
00299
00300
00301
RtlCopyUnicodeString(&SubKbdAndFuncKey, &SubKbd);
00302
RtlAppendUnicodeStringToString(&SubKbdAndFuncKey, &FuncKbd);
00303
Status =
NtQueryValueKey(handleMap,
00304 &SubKbdAndFuncKey,
00305 KeyValueFullInformation,
00306 LayerDriverName,
00307
sizeof(LayerDriverName),
00308 &cbStringSize);
00309
00310
if (
NT_SUCCESS(
Status)) {
00311
00312 LayerDriverName[cbStringSize /
sizeof(WCHAR)] =
L'\0';
00313
00314 wcscpy(realDllName,
00315 (LPWSTR)((PUCHAR)LayerDriverName +
00316 ((PKEY_VALUE_FULL_INFORMATION)LayerDriverName)->DataOffset));
00317
00318
00319 }
00320
else {
00321
00322
00323
00324
Status =
NtQueryValueKey(handleMap,
00325 &SubKbd,
00326 KeyValueFullInformation,
00327 LayerDriverName,
00328
sizeof(LayerDriverName),
00329 &cbStringSize);
00330
00331
if (
NT_SUCCESS(
Status)) {
00332
00333 LayerDriverName[cbStringSize /
sizeof(WCHAR)] =
L'\0';
00334
00335 wcscpy(realDllName,
00336 (LPWSTR)((PUCHAR)LayerDriverName +
00337 ((PKEY_VALUE_FULL_INFORMATION)LayerDriverName)->DataOffset));
00338
00339
00340 }
00341 }
00342
00343
NtClose(handleMap);
00344 }
00345
00346
return TRUE;
00347 }
00348
00349
00350 __inline WCHAR*
wszcpy(WCHAR* target, CONST WCHAR* src)
00351 {
00352
while (*target++ = *src++);
00353
return target - 1;
00354 }
00355
00356
00358
00359
00360
00361
00363
00364 BOOL KbdLayerRealDllFile(HKL hkl, WCHAR *realDllName, PCLIENTKEYBOARDTYPE pClientKbdType, LPVOID reserve)
00365 {
00366 WCHAR pwszBuff[32];
00367 WCHAR* pwszTail;
00368 LPCWSTR pwsz;
00369
00370
ASSERT(PRIMARYLANGID(LOWORD(hkl)) == LANG_JAPANESE ||
00371 PRIMARYLANGID(LOWORD(hkl)) == LANG_KOREAN);
00372
00373
if (pClientKbdType !=
NULL) {
00374
00375
00376
00377
return KbdLayerRealDllFileForWBT(hkl, realDllName, pClientKbdType, reserve);
00378 }
00379
00380
if (PRIMARYLANGID(LOWORD(hkl)) == LANG_JAPANESE) {
00381 pwsz =
L" JPN";
00382 }
00383
else if (PRIMARYLANGID(LOWORD(hkl)) == LANG_KOREAN) {
00384 pwsz =
L" KOR";
00385 }
00386
else {
00387 pwsz =
L"";
00388 }
00389
00390 pwszTail =
wszcpy(pwszBuff,
L"LayerDriver");
00391
if (*pwsz) {
00392
wszcpy(pwszTail, pwsz);
00393 }
00394
00395
TRACE((
"KbdLayerRealDllFileEx: fetching '%S'\n", pwszBuff));
00396
00397
return GetRealDllFileNameWorker(pwszBuff, realDllName);
00398 }
00399
00400