ReactOS  0.4.15-dev-3182-g7b62228
kbdlayout.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Win32k subsystem
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: win32ss/user/ntuser/kbdlayout.c
5  * PURPOSE: Keyboard layout management
6  * COPYRIGHT: Copyright 2007 Saveliy Tretiakov
7  * Copyright 2008 Colin Finck
8  * Copyright 2011 Rafal Harabien
9  */
10 
11 #include <win32k.h>
12 
13 // Was included only because of CP_ACP and required the
14 // definition of SYSTEMTIME in ndk\rtltypes.h
15 //#include <winnls.h>
16 #define CP_ACP 0
17 
18 DBG_DEFAULT_CHANNEL(UserKbdLayout);
19 
24 
26 
27 
28 /* PRIVATE FUNCTIONS ******************************************************/
29 
30 #if 0 && DBG
31 
32 static VOID
33 DumpKbdLayout(
34  IN PKBDTABLES pKbdTbl)
35 {
36  PVK_TO_BIT pVkToBit;
37  PVK_TO_WCHAR_TABLE pVkToWchTbl;
38  PVSC_VK pVscVk;
39  ULONG i;
40 
41  DbgPrint("Kbd layout: fLocaleFlags %x bMaxVSCtoVK %x\n",
42  pKbdTbl->fLocaleFlags, pKbdTbl->bMaxVSCtoVK);
43  DbgPrint("wMaxModBits %x\n",
44  pKbdTbl->pCharModifiers ? pKbdTbl->pCharModifiers->wMaxModBits
45  : 0);
46 
47  if (pKbdTbl->pCharModifiers)
48  {
49  pVkToBit = pKbdTbl->pCharModifiers->pVkToBit;
50  if (pVkToBit)
51  {
52  for (; pVkToBit->Vk; ++pVkToBit)
53  {
54  DbgPrint("VkToBit %x -> %x\n", pVkToBit->Vk, pVkToBit->ModBits);
55  }
56  }
57 
58  for (i = 0; i <= pKbdTbl->pCharModifiers->wMaxModBits; ++i)
59  {
60  DbgPrint("ModNumber %x -> %x\n", i, pKbdTbl->pCharModifiers->ModNumber[i]);
61  }
62  }
63 
64  pVkToWchTbl = pKbdTbl->pVkToWcharTable;
65  if (pVkToWchTbl)
66  {
67  for (; pVkToWchTbl->pVkToWchars; ++pVkToWchTbl)
68  {
69  PVK_TO_WCHARS1 pVkToWch = pVkToWchTbl->pVkToWchars;
70 
71  DbgPrint("pVkToWchTbl nModifications %x cbSize %x\n",
72  pVkToWchTbl->nModifications, pVkToWchTbl->cbSize);
73  if (pVkToWch)
74  {
75  while (pVkToWch->VirtualKey)
76  {
77  DbgPrint("pVkToWch VirtualKey %x Attributes %x wc { ",
78  pVkToWch->VirtualKey, pVkToWch->Attributes);
79  for (i = 0; i < pVkToWchTbl->nModifications; ++i)
80  {
81  DbgPrint("%x ", pVkToWch->wch[i]);
82  }
83  DbgPrint("}\n");
84  pVkToWch = (PVK_TO_WCHARS1)(((PBYTE)pVkToWch) + pVkToWchTbl->cbSize);
85  }
86  }
87  }
88  }
89 
90 // TODO: DeadKeys, KeyNames, KeyNamesExt, KeyNamesDead
91 
92  DbgPrint("pusVSCtoVK: { ");
93  if (pKbdTbl->pusVSCtoVK)
94  {
95  for (i = 0; i < pKbdTbl->bMaxVSCtoVK; ++i)
96  {
97  DbgPrint("%x -> %x, ", i, pKbdTbl->pusVSCtoVK[i]);
98  }
99  }
100  DbgPrint("}\n");
101 
102  DbgPrint("pVSCtoVK_E0: { ");
103  pVscVk = pKbdTbl->pVSCtoVK_E0;
104  if (pVscVk)
105  {
106  for (; pVscVk->Vsc; ++pVscVk)
107  {
108  DbgPrint("%x -> %x, ", pVscVk->Vsc, pVscVk->Vk);
109  }
110  }
111  DbgPrint("}\n");
112 
113  DbgPrint("pVSCtoVK_E1: { ");
114  pVscVk = pKbdTbl->pVSCtoVK_E1;
115  if (pVscVk)
116  {
117  for (; pVscVk->Vsc; ++pVscVk)
118  {
119  DbgPrint("%x -> %x, ", pVscVk->Vsc, pVscVk->Vk);
120  }
121  }
122  DbgPrint("}\n");
123 
124 // TODO: Ligatures
125 }
126 
127 #endif // DBG
128 
129 
130 /*
131  * UserLoadKbdDll
132  *
133  * Loads keyboard layout DLL and gets address to KbdTables
134  */
135 static BOOL
136 UserLoadKbdDll(WCHAR *pwszLayoutPath,
137  HANDLE *phModule,
138  PKBDTABLES *pKbdTables)
139 {
140  PFN_KBDLAYERDESCRIPTOR pfnKbdLayerDescriptor;
141 
142  /* Load keyboard layout DLL */
143  TRACE("Loading Keyboard DLL %ws\n", pwszLayoutPath);
144  *phModule = EngLoadImage(pwszLayoutPath);
145  if (!(*phModule))
146  {
147  ERR("Failed to load dll %ws\n", pwszLayoutPath);
148  return FALSE;
149  }
150 
151  /* Find KbdLayerDescriptor function and get layout tables */
152  TRACE("Loaded %ws\n", pwszLayoutPath);
153  pfnKbdLayerDescriptor = EngFindImageProcAddress(*phModule, "KbdLayerDescriptor");
154 
155  /* FIXME: Windows reads file instead of executing!
156  It's not safe to kbdlayout DLL in kernel mode! */
157 
158  if (pfnKbdLayerDescriptor)
159  *pKbdTables = pfnKbdLayerDescriptor();
160  else
161  ERR("Error: %ws has no KbdLayerDescriptor()\n", pwszLayoutPath);
162 
163  if (!pfnKbdLayerDescriptor || !*pKbdTables)
164  {
165  ERR("Failed to load the keyboard layout.\n");
166  EngUnloadImage(*phModule);
167  return FALSE;
168  }
169 
170 #if 0 && DBG
171  /* Dump keyboard layout */
172  DumpKbdLayout(*pKbdTables);
173 #endif
174 
175  return TRUE;
176 }
177 
178 /*
179  * UserLoadKbdFile
180  *
181  * Loads keyboard layout DLL and creates KBDFILE object
182  */
183 static PKBDFILE
185 {
186  PKBDFILE pkf, pRet = NULL;
188  ULONG cbSize;
189  HKEY hKey = NULL;
190  WCHAR wszLayoutPath[MAX_PATH] = L"\\SystemRoot\\System32\\";
191  WCHAR wszLayoutRegKey[256] = L"\\REGISTRY\\Machine\\SYSTEM\\CurrentControlSet\\"
192  L"Control\\Keyboard Layouts\\";
193 
194  /* Create keyboard layout file object */
196  if (!pkf)
197  {
198  ERR("Failed to create object!\n");
199  return NULL;
200  }
201 
202  /* Set keyboard layout name */
203  swprintf(pkf->awchKF, L"%wZ", pwszKLID);
204 
205  /* Open layout registry key */
206  RtlStringCbCatW(wszLayoutRegKey, sizeof(wszLayoutRegKey), pkf->awchKF);
207  Status = RegOpenKey(wszLayoutRegKey, &hKey);
208  if (!NT_SUCCESS(Status))
209  {
210  ERR("Failed to open keyboard layouts registry key %ws (%lx)\n", wszLayoutRegKey, Status);
211  goto cleanup;
212  }
213 
214  /* Read filename of layout DLL */
215  cbSize = (ULONG)(sizeof(wszLayoutPath) - wcslen(wszLayoutPath)*sizeof(WCHAR));
217  L"Layout File",
218  REG_SZ,
219  wszLayoutPath + wcslen(wszLayoutPath),
220  &cbSize);
221 
222  if (!NT_SUCCESS(Status))
223  {
224  ERR("Can't get layout filename for %wZ (%lx)\n", pwszKLID, Status);
225  goto cleanup;
226  }
227 
228  /* Load keyboard file now */
229  if (!UserLoadKbdDll(wszLayoutPath, &pkf->hBase, &pkf->pKbdTbl))
230  {
231  ERR("Failed to load %ws dll!\n", wszLayoutPath);
232  goto cleanup;
233  }
234 
235  /* Update next field */
236  pkf->pkfNext = gpkfList;
237  gpkfList = pkf;
238 
239  /* Return keyboard file */
240  pRet = pkf;
241 
242 cleanup:
243  if (hKey)
244  ZwClose(hKey);
245  if (pkf)
246  UserDereferenceObject(pkf); // we dont need ptr anymore
247  if (!pRet)
248  {
249  /* We have failed - destroy created object */
250  if (pkf)
252  }
253 
254  return pRet;
255 }
256 
257 /*
258  * UserLoadKbdLayout
259  *
260  * Loads keyboard layout and creates KL object
261  */
262 static PKL
264 {
265  LCID lCid;
266  CHARSETINFO cs;
267  PKL pKl;
268 
269  /* Create keyboard layout object */
271  if (!pKl)
272  {
273  ERR("Failed to create object!\n");
274  return NULL;
275  }
276 
277  pKl->hkl = hKL;
278  pKl->spkf = UserLoadKbdFile(pustrKLID);
279 
280  /* Dereference keyboard layout */
282 
283  /* If we failed, remove KL object */
284  if (!pKl->spkf)
285  {
286  ERR("UserLoadKbdFile(%wZ) failed!\n", pustrKLID);
288  return NULL;
289  }
290 
291  // Up to Language Identifiers..
292  if (!NT_SUCCESS(RtlUnicodeStringToInteger(pustrKLID, 16, (PULONG)&lCid)))
293  {
294  ERR("RtlUnicodeStringToInteger failed for '%wZ'\n", pustrKLID);
296  return NULL;
297  }
298 
299  TRACE("Language Identifiers %wZ LCID 0x%x\n", pustrKLID, lCid);
300  if (co_IntGetCharsetInfo(lCid, &cs))
301  {
302  pKl->iBaseCharset = cs.ciCharset;
303  pKl->dwFontSigs = cs.fs.fsCsb[0];
304  pKl->CodePage = (USHORT)cs.ciACP;
305  TRACE("Charset %u Font Sig %lu CodePage %u\n",
306  pKl->iBaseCharset, pKl->dwFontSigs, pKl->CodePage);
307  }
308  else
309  {
310  pKl->iBaseCharset = ANSI_CHARSET;
311  pKl->dwFontSigs = FS_LATIN1;
312  pKl->CodePage = CP_ACP;
313  }
314 
315  // Set initial system character set and font signature.
316  if (gSystemFS == 0)
317  {
319  gSystemFS = pKl->dwFontSigs;
320  }
321 
322  return pKl;
323 }
324 
325 /*
326  * UnloadKbdFile
327  *
328  * Destroys specified Keyboard File object
329  */
330 static
331 VOID
333 {
334  PKBDFILE *ppkfLink = &gpkfList;
335  NT_ASSERT(pkf != NULL);
336 
337  /* Find previous object */
338  while (*ppkfLink)
339  {
340  if (*ppkfLink == pkf)
341  break;
342 
343  ppkfLink = &(*ppkfLink)->pkfNext;
344  }
345 
346  if (*ppkfLink == pkf)
347  *ppkfLink = pkf->pkfNext;
348 
349  EngUnloadImage(pkf->hBase);
350  UserDeleteObject(pkf->head.h, TYPE_KBDFILE);
351 }
352 
353 /*
354  * UserUnloadKbl
355  *
356  * Unloads specified Keyboard Layout if possible
357  */
358 BOOL
360 {
361  /* According to msdn, UnloadKeyboardLayout can fail
362  if the keyboard layout identifier was preloaded. */
363  if (pKl == gspklBaseLayout)
364  {
365  if (pKl->pklNext == pKl->pklPrev)
366  {
367  /* There is only one layout */
368  return FALSE;
369  }
370 
371  /* Set next layout as default */
372  gspklBaseLayout = pKl->pklNext;
373  }
374 
375  if (pKl->head.cLockObj > 1)
376  {
377  /* Layout is used by other threads */
378  pKl->dwKL_Flags |= KLF_UNLOAD;
379  return FALSE;
380  }
381 
382  /* Unload the layout */
383  pKl->pklPrev->pklNext = pKl->pklNext;
384  pKl->pklNext->pklPrev = pKl->pklPrev;
385  UnloadKbdFile(pKl->spkf);
387  return TRUE;
388 }
389 
390 /*
391  * W32kGetDefaultKeyLayout
392  *
393  * Returns default layout for new threads
394  */
395 PKL
397 {
398  PKL pKl = gspklBaseLayout;
399 
400  if (!pKl)
401  return NULL;
402 
403  /* Return not unloaded layout */
404  do
405  {
406  if (!(pKl->dwKL_Flags & KLF_UNLOAD))
407  return pKl;
408 
409  pKl = pKl->pklPrev; /* Confirmed on Win2k */
410  } while(pKl != gspklBaseLayout);
411 
412  /* We have not found proper KL */
413  return NULL;
414 }
415 
416 /*
417  * UserHklToKbl
418  *
419  * Gets KL object from hkl value
420  */
421 PKL
422 NTAPI
424 {
425  PKL pKl = gspklBaseLayout;
426 
427  if (!gspklBaseLayout)
428  return NULL;
429 
430  do
431  {
432  if (pKl->hkl == hKl)
433  return pKl;
434 
435  pKl = pKl->pklNext;
436  } while (pKl != gspklBaseLayout);
437 
438  return NULL;
439 }
440 
441 /*
442  * UserSetDefaultInputLang
443  *
444  * Sets default kyboard layout for system. Called from UserSystemParametersInfo.
445  */
446 BOOL
447 NTAPI
449 {
450  PKL pKl;
451 
452  pKl = UserHklToKbl(hKl);
453  if (!pKl)
454  return FALSE;
455 
456  gspklBaseLayout = pKl;
457  return TRUE;
458 }
459 
460 /*
461  * co_UserActivateKbl
462  *
463  * Activates given layout in specified thread
464  */
465 static PKL
467 {
468  PKL pklPrev;
469  PWND pWnd;
470 
471  pklPrev = pti->KeyboardLayout;
472  if (pklPrev)
473  UserDereferenceObject(pklPrev);
474 
475  pti->KeyboardLayout = pKl;
476  pti->pClientInfo->hKL = pKl->hkl;
477  UserReferenceObject(pKl);
478 
479  if (Flags & KLF_SETFORPROCESS)
480  {
481  // FIXME
482  }
483 
484  if (!(pWnd = pti->MessageQueue->spwndFocus))
485  {
486  pWnd = pti->MessageQueue->spwndActive;
487  }
488 
489  // Send WM_INPUTLANGCHANGE to thread's focus window
490  co_IntSendMessage( pWnd ? UserHMGetHandle(pWnd) : 0,
491  WM_INPUTLANGCHANGE,
492  (WPARAM)pKl->iBaseCharset, // FIXME: How to set it?
493  (LPARAM)pKl->hkl); // hkl
494 
495  return pklPrev;
496 }
497 
498 /* EXPORTS *******************************************************************/
499 
500 /*
501  * UserGetKeyboardLayout
502  *
503  * Returns hkl of given thread keyboard layout
504  */
508 {
509  PTHREADINFO pti;
510  PLIST_ENTRY ListEntry;
511  PKL pKl;
512 
514 
515  if (!dwThreadId)
516  {
517  pKl = pti->KeyboardLayout;
518  return pKl ? pKl->hkl : NULL;
519  }
520 
521  ListEntry = pti->rpdesk->PtiList.Flink;
522 
523  //
524  // Search the Desktop Thread list for related Desktop active Threads.
525  //
526  while(ListEntry != &pti->rpdesk->PtiList)
527  {
528  pti = CONTAINING_RECORD(ListEntry, THREADINFO, PtiLink);
529 
530  if (PsGetThreadId(pti->pEThread) == UlongToHandle(dwThreadId))
531  {
532  pKl = pti->KeyboardLayout;
533  return pKl ? pKl->hkl : NULL;
534  }
535 
536  ListEntry = ListEntry->Flink;
537  }
538 
539  return NULL;
540 }
541 
542 /*
543  * NtUserGetKeyboardLayoutList
544  *
545  * Returns list of loaded keyboard layouts in system
546  */
547 UINT
548 APIENTRY
550  ULONG nBuff,
551  HKL *pHklBuff)
552 {
553  UINT uRet = 0;
554  PKL pKl;
555 
556  if (!pHklBuff)
557  nBuff = 0;
558 
559  UserEnterShared();
560 
561  if (!gspklBaseLayout)
562  {
563  UserLeave();
564  return 0;
565  }
566  pKl = gspklBaseLayout;
567 
568  if (nBuff == 0)
569  {
570  do
571  {
572  uRet++;
573  pKl = pKl->pklNext;
574  } while (pKl != gspklBaseLayout);
575  }
576  else
577  {
578  _SEH2_TRY
579  {
580  ProbeForWrite(pHklBuff, nBuff*sizeof(HKL), 4);
581 
582  while (uRet < nBuff)
583  {
584  pHklBuff[uRet] = pKl->hkl;
585  uRet++;
586  pKl = pKl->pklNext;
587  if (pKl == gspklBaseLayout)
588  break;
589  }
590  }
592  {
594  uRet = 0;
595  }
596  _SEH2_END;
597  }
598 
599  UserLeave();
600  return uRet;
601 }
602 
603 /*
604  * NtUserGetKeyboardLayoutName
605  *
606  * Returns KLID of current thread keyboard layout
607  */
608 BOOL
609 APIENTRY
611  LPWSTR pwszName)
612 {
613  BOOL bRet = FALSE;
614  PKL pKl;
615  PTHREADINFO pti;
616 
617  UserEnterShared();
618 
620  pKl = pti->KeyboardLayout;
621 
622  if (!pKl)
623  goto cleanup;
624 
625  _SEH2_TRY
626  {
627  ProbeForWrite(pwszName, KL_NAMELENGTH*sizeof(WCHAR), 1);
628  wcscpy(pwszName, pKl->spkf->awchKF);
629  bRet = TRUE;
630  }
632  {
634  }
635  _SEH2_END;
636 
637 cleanup:
638  UserLeave();
639  return bRet;
640 }
641 
642 /*
643  * NtUserLoadKeyboardLayoutEx
644  *
645  * Loads keyboard layout with given locale id
646  */
647 HKL
648 APIENTRY
650  IN HANDLE Handle, // hFile (See downloads.securityfocus.com/vulnerabilities/exploits/43774.c)
651  IN DWORD offTable, // Offset to KbdTables
652  IN PUNICODE_STRING puszKeyboardName, // Not used?
653  IN HKL hklUnload,
654  IN PUNICODE_STRING pustrKLID,
655  IN DWORD hkl,
656  IN UINT Flags)
657 {
658  HKL hklRet = NULL;
659  PKL pKl = NULL, pklLast;
660  WCHAR Buffer[9];
661  UNICODE_STRING ustrSafeKLID;
662 
665  KLF_RESET|KLF_SHIFTLOCK))
666  {
667  ERR("Invalid flags: %x\n", Flags);
669  return NULL;
670  }
671 
672  /* FIXME: It seems KLF_RESET is only supported for WINLOGON */
673 
674  RtlInitEmptyUnicodeString(&ustrSafeKLID, Buffer, sizeof(Buffer));
675  _SEH2_TRY
676  {
677  ProbeForRead(pustrKLID, sizeof(*pustrKLID), 1);
678  ProbeForRead(pustrKLID->Buffer, sizeof(pustrKLID->Length), 1);
679  RtlCopyUnicodeString(&ustrSafeKLID, pustrKLID);
680  }
682  {
684  _SEH2_YIELD(return NULL);
685  }
686  _SEH2_END;
687 
689 
690  /* If hklUnload is specified, unload it and load new layput as default */
691  if (hklUnload && (hklUnload != UlongToHandle(hkl)))
692  {
693  pKl = UserHklToKbl(hklUnload);
694  if (pKl)
695  UserUnloadKbl(pKl);
696  }
697 
698  /* Let's see if layout was already loaded. */
700  if (!pKl)
701  {
702  /* It wasn't, so load it. */
703  pKl = UserLoadKbdLayout(&ustrSafeKLID, UlongToHandle(hkl));
704  if (!pKl)
705  goto cleanup;
706 
707  if (gspklBaseLayout)
708  {
709  /* Find last not unloaded layout */
710  pklLast = gspklBaseLayout->pklPrev;
711  while (pklLast != gspklBaseLayout && pklLast->dwKL_Flags & KLF_UNLOAD)
712  pklLast = pklLast->pklPrev;
713 
714  /* Add new layout to the list */
715  pKl->pklNext = pklLast->pklNext;
716  pKl->pklPrev = pklLast;
717  pKl->pklNext->pklPrev = pKl;
718  pKl->pklPrev->pklNext = pKl;
719  }
720  else
721  {
722  /* This is the first layout */
723  pKl->pklNext = pKl;
724  pKl->pklPrev = pKl;
725  gspklBaseLayout = pKl;
726  }
727  }
728 
729  /* If this layout was prepared to unload, undo it */
730  pKl->dwKL_Flags &= ~KLF_UNLOAD;
731 
732  /* Activate this layout in current thread */
733  if (Flags & KLF_ACTIVATE)
735 
736  /* Send shell message */
737  if (!(Flags & KLF_NOTELLSHELL))
738  co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)hkl);
739 
740  /* Return hkl on success */
741  hklRet = UlongToHandle(hkl);
742 
743  /* FIXME: KLF_REPLACELANG
744  KLF_REORDER */
745 
746 cleanup:
747  UserLeave();
748  return hklRet;
749 }
750 
751 /*
752  * NtUserActivateKeyboardLayout
753  *
754  * Activates specified layout for thread or process
755  */
756 HKL
757 APIENTRY
759  HKL hKl,
760  ULONG Flags)
761 {
762  PKL pKl = NULL;
763  HKL hkl = NULL;
764  PTHREADINFO pti;
765 
767 
769 
770  /* hKl can have special value HKL_NEXT or HKL_PREV */
771  if (hKl == (HKL)HKL_NEXT)
772  {
773  /* Get next keyboard layout starting with current */
774  if (pti->KeyboardLayout)
775  pKl = pti->KeyboardLayout->pklNext;
776  }
777  else if (hKl == (HKL)HKL_PREV)
778  {
779  /* Get previous keyboard layout starting with current */
780  if (pti->KeyboardLayout)
781  pKl = pti->KeyboardLayout->pklPrev;
782  }
783  else
784  pKl = UserHklToKbl(hKl);
785 
786  if (!pKl)
787  {
788  ERR("Invalid HKL %p!\n", hKl);
789  goto cleanup;
790  }
791 
792  hkl = pKl->hkl;
793 
794  /* FIXME: KLF_RESET
795  KLF_SHIFTLOCK */
796 
797  if (Flags & KLF_REORDER)
798  gspklBaseLayout = pKl;
799 
800  if (pKl != pti->KeyboardLayout)
801  {
802  /* Activate layout for current thread */
803  pKl = co_UserActivateKbl(pti, pKl, Flags);
804 
805  /* Send shell message */
806  if (!(Flags & KLF_NOTELLSHELL))
807  co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)hkl);
808  }
809 
810 cleanup:
811  UserLeave();
812  return hkl;
813 }
814 
815 /*
816  * NtUserUnloadKeyboardLayout
817  *
818  * Unloads keyboard layout with specified hkl value
819  */
820 BOOL
821 APIENTRY
823  HKL hKl)
824 {
825  PKL pKl;
826  BOOL bRet = FALSE;
827 
829 
830  pKl = UserHklToKbl(hKl);
831  if (pKl)
832  bRet = UserUnloadKbl(pKl);
833  else
834  ERR("Invalid HKL %p!\n", hKl);
835 
836  UserLeave();
837  return bRet;
838 }
839 
840 /* EOF */
#define KLF_REORDER
Definition: winuser.h:114
static BOOL UserLoadKbdDll(WCHAR *pwszLayoutPath, HANDLE *phModule, PKBDTABLES *pKbdTables)
Definition: kbdlayout.c:136
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:239
struct tagKL * pklPrev
Definition: input.h:30
PVK_TO_WCHARS1 pVkToWchars
Definition: kbd.h:51
#define IN
Definition: typedefs.h:39
#define KLF_UNLOAD
Definition: input.h:51
DBG_DEFAULT_CHANNEL(UserKbdLayout)
BOOL FASTCALL UserDeleteObject(HANDLE h, HANDLE_TYPE type)
Definition: object.c:683
#define KL_NAMELENGTH
Definition: winuser.h:122
BYTE ModBits
Definition: kbd.h:23
#define DbgPrint
Definition: hal.h:12
BOOL UserUnloadKbl(PKL pKl)
Definition: kbdlayout.c:359
BOOL APIENTRY co_IntGetCharsetInfo(LCID Locale, PCHARSETINFO pCs)
Definition: callback.c:1040
PKL gspklBaseLayout
Definition: kbdlayout.c:20
#define KLF_ACTIVATE
Definition: winuser.h:111
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
HANDLE h
Definition: ntuser.h:173
Definition: kbd.h:21
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
LONG NTSTATUS
Definition: precomp.h:26
BYTE Vsc
Definition: kbd.h:72
#define KLF_NOTELLSHELL
Definition: winuser.h:116
PKBDFILE gpkfList
Definition: kbdlayout.c:21
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:610
HKL APIENTRY NtUserLoadKeyboardLayoutEx(IN HANDLE Handle, IN DWORD offTable, IN PUNICODE_STRING puszKeyboardName, IN HKL hklUnload, IN PUNICODE_STRING pustrKLID, IN DWORD hkl, IN UINT Flags)
Definition: kbdlayout.c:649
DWORD LCID
Definition: nls.h:13
UINT_PTR WPARAM
Definition: windef.h:207
#define swprintf
Definition: precomp.h:40
UINT gSystemCPCharSet
Definition: kbdlayout.c:23
NTSTRSAFEAPI RtlStringCbCatW(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:636
#define FASTCALL
Definition: nt_native.h:50
struct _DESKTOP * rpdesk
Definition: win32.h:93
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
PVOID FASTCALL UserCreateObject(PUSER_HANDLE_TABLE ht, PDESKTOP pDesktop, PTHREADINFO pti, HANDLE *h, HANDLE_TYPE type, ULONG size)
Definition: object.c:535
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
_SEH2_TRY
Definition: create.c:4226
USHORT Vk
Definition: kbd.h:73
BOOL APIENTRY NtUserGetKeyboardLayoutName(LPWSTR pwszName)
Definition: kbdlayout.c:610
uint32_t cs
Definition: isohybrid.c:75
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
DWORD gSystemFS
Definition: kbdlayout.c:22
unsigned int BOOL
Definition: ntddk_ex.h:94
HEAD head
Definition: input.h:28
Definition: input.h:26
#define _In_
Definition: ms_sal.h:308
#define KLF_UNLOADPREVIOUS
Definition: winuser.h:113
LONG_PTR LPARAM
Definition: windef.h:208
Definition: bufpool.h:45
WCHAR awchKF[20]
Definition: input.h:19
BYTE nModifications
Definition: kbd.h:52
UINT iBaseCharset
Definition: input.h:35
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define KLF_SUBSTITUTE_OK
Definition: winuser.h:112
#define CP_ACP
Definition: kbdlayout.c:16
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:245
Status
Definition: gdiplustypes.h:24
#define UserHMGetHandle(obj)
Definition: ntuser.h:213
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TRACE(s)
Definition: solgame.cpp:4
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PKL W32kGetDefaultKeyLayout(VOID)
Definition: kbdlayout.c:396
HKL FASTCALL UserGetKeyboardLayout(DWORD dwThreadId)
Definition: kbdlayout.c:506
USHORT CodePage
Definition: input.h:36
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define UlongToHandle(ul)
Definition: basetsd.h:97
HKL hkl
Definition: input.h:32
#define MAX_PATH
Definition: compat.h:34
Definition: kbd.h:95
struct tagKBDFILE * pkfNext
Definition: input.h:18
BOOL APIENTRY NtUserUnloadKeyboardLayout(HKL hKl)
Definition: kbdlayout.c:822
unsigned long DWORD
Definition: ntddk_ex.h:95
ENGAPI HANDLE APIENTRY EngLoadImage(_In_ LPWSTR pwszDriver)
Definition: ldevobj.c:456
struct _CLIENTINFO * pClientInfo
Definition: win32.h:95
BYTE cbSize
Definition: kbd.h:53
struct _KBDTABLES * pKbdTbl
Definition: input.h:21
DWORD dwThreadId
Definition: fdebug.c:31
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
static const WCHAR L[]
Definition: oid.c:1250
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1446
DWORD dwKL_Flags
Definition: input.h:31
#define VOID
Definition: acefi.h:82
DWORD dwFontSigs
Definition: input.h:34
static PKL co_UserActivateKbl(PTHREADINFO pti, PKL pKl, UINT Flags)
Definition: kbdlayout.c:466
BYTE Vk
Definition: kbd.h:22
DWORD cLockObj
Definition: ntuser.h:174
Definition: typedefs.h:119
HANDLE NTAPI PsGetThreadId(IN PETHREAD Thread)
Definition: thread.c:705
UINT_PTR HKL
Definition: msctf.idl:101
struct tagKL * KeyboardLayout
Definition: win32.h:91
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
Definition: kbd.h:71
struct tagKL * pklNext
Definition: input.h:29
#define KLF_REPLACELANG
Definition: winuser.h:115
HEAD head
Definition: input.h:17
#define ERR(fmt,...)
Definition: debug.h:110
Definition: ntuser.h:663
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:90
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:253
BOOL NTAPI UserSetDefaultInputLang(HKL hKl)
Definition: kbdlayout.c:448
_SEH2_END
Definition: create.c:4400
HKL hkl
Definition: msctf.idl:611
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned short USHORT
Definition: pedump.c:61
FxAutoRegKey hKey
#define HKL_NEXT
Definition: winuser.h:109
#define KLF_SETFORPROCESS
Definition: winuser.h:117
ENGAPI PVOID APIENTRY EngFindImageProcAddress(_In_ HANDLE hModule, _In_ LPSTR lpProcName)
Definition: ldevobj.c:497
HANDLE hBase
Definition: input.h:20
PVOID(* PFN_KBDLAYERDESCRIPTOR)(VOID)
Definition: kbdlayout.c:25
unsigned int * PULONG
Definition: retypes.h:1
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define HKL_PREV
Definition: winuser.h:110
VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam)
Definition: desktop.c:1660
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define FS_LATIN1
Definition: wingdi.h:559
PKBDFILE spkf
Definition: input.h:33
_In_ HANDLE Handle
Definition: extypes.h:390
#define RegQueryValue
Definition: winreg.h:523
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
unsigned int ULONG
Definition: retypes.h:1
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:423
ENGAPI VOID APIENTRY EngUnloadImage(_In_ HANDLE hModule)
Definition: ldevobj.c:465
char * cleanup(char *str)
Definition: wpickclick.c:99
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
static PKBDFILE UserLoadKbdFile(PUNICODE_STRING pwszKLID)
Definition: kbdlayout.c:184
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define ANSI_CHARSET
Definition: wingdi.h:382
static VOID UnloadKbdFile(_In_ PKBDFILE pkf)
Definition: kbdlayout.c:332
WCHAR * LPWSTR
Definition: xmlstorage.h:184
UINT APIENTRY NtUserGetKeyboardLayoutList(ULONG nBuff, HKL *pHklBuff)
Definition: kbdlayout.c:549
#define RegOpenKey
Definition: winreg.h:519
PUSER_HANDLE_TABLE gHandleTable
Definition: object.c:13
BYTE * PBYTE
Definition: pedump.c:66
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
#define APIENTRY
Definition: api.h:79
static PKL UserLoadKbdLayout(PUNICODE_STRING pustrKLID, HKL hKL)
Definition: kbdlayout.c:263
VOID FASTCALL UserReferenceObject(PVOID obj)
Definition: object.c:697
#define NT_ASSERT
Definition: rtlfuncs.h:3310
#define REG_SZ
Definition: layer.c:22
HKL APIENTRY NtUserActivateKeyboardLayout(HKL hKl, ULONG Flags)
Definition: kbdlayout.c:758