ReactOS 0.4.16-dev-197-g92996da
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 * Copyright 2022 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
10 */
11
12#include <win32k.h>
13#include <immdev.h>
14
15// Was included only because of CP_ACP and required the
16// definition of SYSTEMTIME in ndk\rtltypes.h
17//#include <winnls.h>
18#define CP_ACP 0
19
20DBG_DEFAULT_CHANNEL(UserKbdLayout);
21
22PKL gspklBaseLayout = NULL; /* FIXME: Please move this to pWinSta->spklList */
27
29
30/* PRIVATE FUNCTIONS ******************************************************/
31
32/*
33 * Retrieves a PKL by an input locale identifier (HKL).
34 * @implemented
35 */
37{
38 PKL pFirstKL, pKL;
39
40 pFirstKL = pti->KeyboardLayout;
41 if (!pFirstKL)
42 return NULL;
43
44 pKL = pFirstKL;
45
46 /* hKL can have special value HKL_NEXT or HKL_PREV */
47 if (hKL == UlongToHandle(HKL_NEXT)) /* Looking forward */
48 {
49 do
50 {
51 pKL = pKL->pklNext;
52 if (!(pKL->dwKL_Flags & KL_UNLOAD))
53 return pKL;
54 } while (pKL != pFirstKL);
55 }
56 else if (hKL == UlongToHandle(HKL_PREV)) /* Looking backward */
57 {
58 do
59 {
60 pKL = pKL->pklPrev;
61 if (!(pKL->dwKL_Flags & KL_UNLOAD))
62 return pKL;
63 } while (pKL != pFirstKL);
64 }
65 else if (HIWORD(hKL)) /* hKL is a full input locale identifier */
66 {
67 /* No KL_UNLOAD check */
68 do
69 {
70 if (pKL->hkl == hKL)
71 return pKL;
72
73 pKL = pKL->pklNext;
74 } while (pKL != pFirstKL);
75 }
76 else /* Language only specified */
77 {
78 /* No KL_UNLOAD check */
79 do
80 {
81 if (LOWORD(pKL->hkl) == LOWORD(hKL)) /* Low word is language ID */
82 return pKL;
83
84 pKL = pKL->pklNext;
85 } while (pKL != pFirstKL);
86 }
87
88 return NULL;
89}
90
91/*
92 * A helper function for NtUserGetKeyboardLayoutList.
93 * @implemented
94 */
95static UINT APIENTRY
98 _In_ ULONG nBuff,
99 _Out_ HKL *pHklBuff)
100{
101 UINT ret = 0;
102 PKL pKL, pFirstKL;
103
104 pFirstKL = gspklBaseLayout; /* FIXME: Use pWinSta->spklList instead */
105 if (!pWinSta || !pFirstKL)
106 return 0;
107
108 pKL = pFirstKL;
109
110 if (nBuff == 0)
111 {
112 /* Count the effective PKLs */
113 do
114 {
115 if (!(pKL->dwKL_Flags & KL_UNLOAD))
116 ++ret;
117 pKL = pKL->pklNext;
118 } while (pKL != pFirstKL);
119 }
120 else
121 {
122 /* Copy the effective HKLs to pHklBuff */
123 do
124 {
125 if (!(pKL->dwKL_Flags & KL_UNLOAD))
126 {
127 *pHklBuff = pKL->hkl;
128 ++pHklBuff;
129 ++ret;
130 --nBuff;
131
132 if (nBuff == 0)
133 break;
134 }
135 pKL = pKL->pklNext;
136 } while (pKL != pFirstKL);
137 }
138
139 return ret;
140}
141
142#if 0 && DBG
143
144static VOID
145DumpKbdLayout(
146 IN PKBDTABLES pKbdTbl)
147{
148 PVK_TO_BIT pVkToBit;
149 PVK_TO_WCHAR_TABLE pVkToWchTbl;
150 PVSC_VK pVscVk;
151 ULONG i;
152
153 DbgPrint("Kbd layout: fLocaleFlags %x bMaxVSCtoVK %x\n",
154 pKbdTbl->fLocaleFlags, pKbdTbl->bMaxVSCtoVK);
155 DbgPrint("wMaxModBits %x\n",
156 pKbdTbl->pCharModifiers ? pKbdTbl->pCharModifiers->wMaxModBits
157 : 0);
158
159 if (pKbdTbl->pCharModifiers)
160 {
161 pVkToBit = pKbdTbl->pCharModifiers->pVkToBit;
162 if (pVkToBit)
163 {
164 for (; pVkToBit->Vk; ++pVkToBit)
165 {
166 DbgPrint("VkToBit %x -> %x\n", pVkToBit->Vk, pVkToBit->ModBits);
167 }
168 }
169
170 for (i = 0; i <= pKbdTbl->pCharModifiers->wMaxModBits; ++i)
171 {
172 DbgPrint("ModNumber %x -> %x\n", i, pKbdTbl->pCharModifiers->ModNumber[i]);
173 }
174 }
175
176 pVkToWchTbl = pKbdTbl->pVkToWcharTable;
177 if (pVkToWchTbl)
178 {
179 for (; pVkToWchTbl->pVkToWchars; ++pVkToWchTbl)
180 {
181 PVK_TO_WCHARS1 pVkToWch = pVkToWchTbl->pVkToWchars;
182
183 DbgPrint("pVkToWchTbl nModifications %x cbSize %x\n",
184 pVkToWchTbl->nModifications, pVkToWchTbl->cbSize);
185 if (pVkToWch)
186 {
187 while (pVkToWch->VirtualKey)
188 {
189 DbgPrint("pVkToWch VirtualKey %x Attributes %x wc { ",
190 pVkToWch->VirtualKey, pVkToWch->Attributes);
191 for (i = 0; i < pVkToWchTbl->nModifications; ++i)
192 {
193 DbgPrint("%x ", pVkToWch->wch[i]);
194 }
195 DbgPrint("}\n");
196 pVkToWch = (PVK_TO_WCHARS1)(((PBYTE)pVkToWch) + pVkToWchTbl->cbSize);
197 }
198 }
199 }
200 }
201
202// TODO: DeadKeys, KeyNames, KeyNamesExt, KeyNamesDead
203
204 DbgPrint("pusVSCtoVK: { ");
205 if (pKbdTbl->pusVSCtoVK)
206 {
207 for (i = 0; i < pKbdTbl->bMaxVSCtoVK; ++i)
208 {
209 DbgPrint("%x -> %x, ", i, pKbdTbl->pusVSCtoVK[i]);
210 }
211 }
212 DbgPrint("}\n");
213
214 DbgPrint("pVSCtoVK_E0: { ");
215 pVscVk = pKbdTbl->pVSCtoVK_E0;
216 if (pVscVk)
217 {
218 for (; pVscVk->Vsc; ++pVscVk)
219 {
220 DbgPrint("%x -> %x, ", pVscVk->Vsc, pVscVk->Vk);
221 }
222 }
223 DbgPrint("}\n");
224
225 DbgPrint("pVSCtoVK_E1: { ");
226 pVscVk = pKbdTbl->pVSCtoVK_E1;
227 if (pVscVk)
228 {
229 for (; pVscVk->Vsc; ++pVscVk)
230 {
231 DbgPrint("%x -> %x, ", pVscVk->Vsc, pVscVk->Vk);
232 }
233 }
234 DbgPrint("}\n");
235
236// TODO: Ligatures
237}
238
239#endif // DBG
240
241
242/*
243 * UserLoadKbdDll
244 *
245 * Loads keyboard layout DLL and gets address to KbdTables
246 */
247static BOOL
248UserLoadKbdDll(WCHAR *pwszLayoutPath,
249 HANDLE *phModule,
250 PKBDTABLES *pKbdTables)
251{
252 PFN_KBDLAYERDESCRIPTOR pfnKbdLayerDescriptor;
253
254 /* Load keyboard layout DLL */
255 TRACE("Loading Keyboard DLL %ws\n", pwszLayoutPath);
256 *phModule = EngLoadImage(pwszLayoutPath);
257 if (!(*phModule))
258 {
259 ERR("Failed to load dll %ws\n", pwszLayoutPath);
260 return FALSE;
261 }
262
263 /* Find KbdLayerDescriptor function and get layout tables */
264 TRACE("Loaded %ws\n", pwszLayoutPath);
265 pfnKbdLayerDescriptor = EngFindImageProcAddress(*phModule, "KbdLayerDescriptor");
266
267 /* FIXME: Windows reads file instead of executing!
268 It's not safe to kbdlayout DLL in kernel mode! */
269
270 if (pfnKbdLayerDescriptor)
271 *pKbdTables = pfnKbdLayerDescriptor();
272 else
273 ERR("Error: %ws has no KbdLayerDescriptor()\n", pwszLayoutPath);
274
275 if (!pfnKbdLayerDescriptor || !*pKbdTables)
276 {
277 ERR("Failed to load the keyboard layout.\n");
278 EngUnloadImage(*phModule);
279 return FALSE;
280 }
281
282#if 0 && DBG
283 /* Dump keyboard layout */
284 DumpKbdLayout(*pKbdTables);
285#endif
286
287 return TRUE;
288}
289
290/*
291 * UserLoadKbdFile
292 *
293 * Loads keyboard layout DLL and creates KBDFILE object
294 */
295static PKBDFILE
297{
298 PKBDFILE pkf, pRet = NULL;
300 ULONG cbSize;
301 HKEY hKey = NULL;
302 WCHAR wszLayoutPath[MAX_PATH] = L"\\SystemRoot\\System32\\";
303 WCHAR wszLayoutRegKey[256] = L"\\REGISTRY\\Machine\\SYSTEM\\CurrentControlSet\\"
304 L"Control\\Keyboard Layouts\\";
305
306 /* Create keyboard layout file object */
308 if (!pkf)
309 {
310 ERR("Failed to create object!\n");
311 return NULL;
312 }
313
314 /* Set keyboard layout name */
315 swprintf(pkf->awchKF, L"%wZ", pwszKLID);
316
317 /* Open layout registry key */
318 RtlStringCbCatW(wszLayoutRegKey, sizeof(wszLayoutRegKey), pkf->awchKF);
319 Status = RegOpenKey(wszLayoutRegKey, &hKey);
320 if (!NT_SUCCESS(Status))
321 {
322 ERR("Failed to open keyboard layouts registry key %ws (%lx)\n", wszLayoutRegKey, Status);
323 goto cleanup;
324 }
325
326 /* Read filename of layout DLL */
327 cbSize = (ULONG)(sizeof(wszLayoutPath) - wcslen(wszLayoutPath)*sizeof(WCHAR));
329 L"Layout File",
330 REG_SZ,
331 wszLayoutPath + wcslen(wszLayoutPath),
332 &cbSize);
333
334 if (!NT_SUCCESS(Status))
335 {
336 ERR("Can't get layout filename for %wZ (%lx)\n", pwszKLID, Status);
337 goto cleanup;
338 }
339
340 /* Load keyboard file now */
341 if (!UserLoadKbdDll(wszLayoutPath, &pkf->hBase, &pkf->pKbdTbl))
342 {
343 ERR("Failed to load %ws dll!\n", wszLayoutPath);
344 goto cleanup;
345 }
346
347 /* Update next field */
348 pkf->pkfNext = gpkfList;
349 gpkfList = pkf;
350
351 /* Return keyboard file */
352 pRet = pkf;
353
354cleanup:
355 if (hKey)
356 ZwClose(hKey);
357 if (pkf)
358 UserDereferenceObject(pkf); // we dont need ptr anymore
359 if (!pRet)
360 {
361 /* We have failed - destroy created object */
362 if (pkf)
364 }
365
366 return pRet;
367}
368
369/*
370 * co_UserLoadKbdLayout
371 *
372 * Loads keyboard layout and creates KL object
373 */
374static PKL
376{
377 LCID lCid;
379 PKL pKl;
380
381 /* Create keyboard layout object */
383 if (!pKl)
384 {
385 ERR("Failed to create object!\n");
386 return NULL;
387 }
388
389 pKl->hkl = hKL;
390 pKl->spkf = UserLoadKbdFile(pustrKLID);
391
392 /* Dereference keyboard layout */
394
395 /* If we failed, remove KL object */
396 if (!pKl->spkf)
397 {
398 ERR("UserLoadKbdFile(%wZ) failed!\n", pustrKLID);
400 return NULL;
401 }
402
403 // Up to Language Identifiers..
404 if (!NT_SUCCESS(RtlUnicodeStringToInteger(pustrKLID, 16, (PULONG)&lCid)))
405 {
406 ERR("RtlUnicodeStringToInteger failed for '%wZ'\n", pustrKLID);
408 return NULL;
409 }
410
411 TRACE("Language Identifiers %wZ LCID 0x%x\n", pustrKLID, lCid);
412 if (co_IntGetCharsetInfo(lCid, &cs))
413 {
414 pKl->iBaseCharset = cs.ciCharset;
415 pKl->dwFontSigs = cs.fs.fsCsb[0];
416 pKl->CodePage = (USHORT)cs.ciACP;
417 TRACE("Charset %u Font Sig %lu CodePage %u\n",
418 pKl->iBaseCharset, pKl->dwFontSigs, pKl->CodePage);
419 }
420 else
421 {
423 pKl->dwFontSigs = FS_LATIN1;
424 pKl->CodePage = CP_ACP;
425 }
426
427 // Set initial system character set and font signature.
428 if (gSystemFS == 0)
429 {
431 gSystemFS = pKl->dwFontSigs;
432 }
433
434 return pKl;
435}
436
437/*
438 * UnloadKbdFile
439 *
440 * Destroys specified Keyboard File object
441 */
442static
443VOID
445{
446 PKBDFILE *ppkfLink = &gpkfList;
447 NT_ASSERT(pkf != NULL);
448
449 /* Find previous object */
450 while (*ppkfLink)
451 {
452 if (*ppkfLink == pkf)
453 break;
454
455 ppkfLink = &(*ppkfLink)->pkfNext;
456 }
457
458 if (*ppkfLink == pkf)
459 *ppkfLink = pkf->pkfNext;
460
461 EngUnloadImage(pkf->hBase);
463}
464
465/*
466 * UserUnloadKbl
467 *
468 * Unloads specified Keyboard Layout if possible
469 */
470BOOL
472{
473 /* According to msdn, UnloadKeyboardLayout can fail
474 if the keyboard layout identifier was preloaded. */
475 if (pKl == gspklBaseLayout)
476 {
477 if (pKl->pklNext == pKl->pklPrev)
478 {
479 /* There is only one layout */
480 return FALSE;
481 }
482
483 /* Set next layout as default */
485 }
486
487 if (pKl->head.cLockObj > 1)
488 {
489 /* Layout is used by other threads */
490 pKl->dwKL_Flags |= KL_UNLOAD;
491 return FALSE;
492 }
493
494 /* Unload the layout */
495 pKl->pklPrev->pklNext = pKl->pklNext;
496 pKl->pklNext->pklPrev = pKl->pklPrev;
497 UnloadKbdFile(pKl->spkf);
498 if (pKl->piiex)
499 {
501 }
503 return TRUE;
504}
505
506/*
507 * W32kGetDefaultKeyLayout
508 *
509 * Returns default layout for new threads
510 */
511PKL
513{
514 PKL pKl = gspklBaseLayout;
515
516 if (!pKl)
517 return NULL;
518
519 /* Return not unloaded layout */
520 do
521 {
522 if (!(pKl->dwKL_Flags & KL_UNLOAD))
523 return pKl;
524
525 pKl = pKl->pklPrev; /* Confirmed on Win2k */
526 } while(pKl != gspklBaseLayout);
527
528 /* We have not found proper KL */
529 return NULL;
530}
531
532/*
533 * UserHklToKbl
534 *
535 * Gets KL object from hkl value
536 */
537PKL
538NTAPI
540{
541 PKL pKl = gspklBaseLayout;
542
543 if (!gspklBaseLayout)
544 return NULL;
545
546 do
547 {
548 if (pKl->hkl == hKl)
549 return pKl;
550
551 pKl = pKl->pklNext;
552 } while (pKl != gspklBaseLayout);
553
554 return NULL;
555}
556
560 _Inout_ PKL pNewKL)
561{
562 PKL pOldKL = gspklBaseLayout;
563
564 if ((pWinSta->Flags & WSS_NOIO) || pNewKL == pOldKL)
565 return;
566
567 pNewKL->pklPrev->pklNext = pNewKL->pklNext;
568 pNewKL->pklNext->pklPrev = pNewKL->pklPrev;
569 pNewKL->pklNext = pOldKL;
570 pNewKL->pklPrev = pOldKL->pklPrev;
571 pOldKL->pklPrev->pklNext = pNewKL;
572 pOldKL->pklPrev = pNewKL;
573 gspklBaseLayout = pNewKL; /* Should we use UserAssignmentLock? */
574}
575
576/*
577 * UserSetDefaultInputLang
578 *
579 * Sets default keyboard layout for system. Called from UserSystemParametersInfo.
580 */
581BOOL
582NTAPI
584{
585 PKL pKl;
586
587 pKl = UserHklToKbl(hKl);
588 if (!pKl)
589 return FALSE;
590
592 return TRUE;
593}
594
598 _Inout_ PKL pKL)
599{
600 PWND pImeWnd;
601 HWND hImeWnd;
603
604 if (pti->KeyboardLayout == pKL)
605 return;
606
607 pImeWnd = pti->spwndDefaultIme;
608 if (pImeWnd)
609 {
610 UserRefObjectCo(pImeWnd, &Ref);
611 hImeWnd = UserHMGetHandle(pImeWnd);
613 UserDerefObjectCo(pImeWnd);
614 }
615 else
616 {
617 /* Remember old keyboard layout to switch back for Chinese IMEs */
618 pti->hklPrev = pti->KeyboardLayout->hkl;
619
620 if (pti->spDefaultImc)
621 {
622 /* IME Activation is needed */
623 pti->pClientInfo->CI_flags |= CI_IMMACTIVATE;
624 }
625 }
626
627 UserAssignmentLock((PVOID*)&(pti->KeyboardLayout), pKL);
628 pti->pClientInfo->hKL = pKL->hkl;
629 pti->pClientInfo->CodePage = pKL->CodePage;
630}
631
633{
634 PTHREADINFO ptiNode, ptiNext;
635 PCLIENTINFO pClientInfo;
636 BOOL bImmMode = IS_IMM_MODE();
637
638 for (ptiNode = ppi->ptiList; ptiNode; ptiNode = ptiNext)
639 {
640 IntReferenceThreadInfo(ptiNode);
641 ptiNext = ptiNode->ptiSibling;
642
643 /* Skip this thread if its keyboard layout is already the correct one, or if it's dying */
644 if (ptiNode->KeyboardLayout == pKL || (ptiNode->TIF_flags & TIF_INCLEANUP))
645 {
647 continue;
648 }
649
650 if (bImmMode)
651 {
652 IntImmActivateLayout(ptiNode, pKL);
653 }
654 else
655 {
656 UserAssignmentLock((PVOID*)&ptiNode->KeyboardLayout, pKL);
657 pClientInfo = ptiNode->pClientInfo;
658 pClientInfo->CodePage = pKL->CodePage;
659 pClientInfo->hKL = pKL->hkl;
660 }
661
663 }
664}
665
668 _Inout_ PKL pKL,
670 _In_opt_ PWND pWnd)
671{
672 HKL hOldKL = NULL;
673 PKL pOldKL;
675 PWND pTargetWnd, pImeWnd;
676 HWND hTargetWnd, hImeWnd;
677 USER_REFERENCE_ENTRY Ref1, Ref2;
679 BOOL bSetForProcess = !!(uFlags & KLF_SETFORPROCESS);
680
682 ClientInfo = pti->pClientInfo;
683
684 pOldKL = pti->KeyboardLayout;
685 if (pOldKL)
686 hOldKL = pOldKL->hkl;
687
688 if (uFlags & KLF_RESET)
689 {
690 FIXME("KLF_RESET\n");
691 }
692
693 if (!bSetForProcess && pKL == pti->KeyboardLayout)
694 {
696 return hOldKL;
697 }
698
699 pKL->wchDiacritic = UNICODE_NULL;
700
701 if (pOldKL)
702 UserRefObjectCo(pOldKL, &Ref1);
703
704 if (pti->TIF_flags & TIF_CSRSSTHREAD)
705 {
707 ClientInfo->CodePage = pKL->CodePage;
708 ClientInfo->hKL = pKL->hkl;
709 }
710 else if (bSetForProcess)
711 {
713 }
714 else
715 {
716 if (IS_IMM_MODE())
717 IntImmActivateLayout(pti, pKL);
718 else
720
721 ClientInfo->CodePage = pKL->CodePage;
722 ClientInfo->hKL = pKL->hkl;
723 }
724
725 /* Send shell message if necessary */
727 {
728 /* Send the HKL if needed and remember it */
729 if (ghKLSentToShell != pKL->hkl)
730 {
731 co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)pKL->hkl);
732 ghKLSentToShell = pKL->hkl;
733 }
734 }
735
736 if (pti->MessageQueue)
737 {
738 /* Determine the target window */
739 pTargetWnd = pti->MessageQueue->spwndFocus;
740 if (!pTargetWnd)
741 {
742 pTargetWnd = pti->MessageQueue->spwndActive;
743 if (!pTargetWnd)
744 pTargetWnd = pWnd;
745 }
746
747 /* Send WM_INPUTLANGCHANGE message */
748 if (pTargetWnd)
749 {
750 UserRefObjectCo(pTargetWnd, &Ref2);
751 hTargetWnd = UserHMGetHandle(pTargetWnd);
752 co_IntSendMessage(hTargetWnd, WM_INPUTLANGCHANGE, pKL->iBaseCharset, (LPARAM)pKL->hkl);
753 UserDerefObjectCo(pTargetWnd);
754 }
755 }
756
757 // Refresh IME UI via WM_IME_SYSTEM:IMS_SENDNOTIFICATION messaging
758 if (!(pti->TIF_flags & TIF_CSRSSTHREAD))
759 {
760 if (IS_IME_HKL(pKL->hkl) || (IS_CICERO_MODE() && !IS_16BIT_MODE()))
761 {
762 pImeWnd = pti->spwndDefaultIme;
763 if (pImeWnd)
764 {
765 bSetForProcess &= !IS_16BIT_MODE();
766 UserRefObjectCo(pImeWnd, &Ref2);
767 hImeWnd = UserHMGetHandle(pImeWnd);
768 co_IntSendMessage(hImeWnd, WM_IME_SYSTEM, IMS_SENDNOTIFICATION, bSetForProcess);
769 UserDerefObjectCo(pImeWnd);
770 }
771 }
772 }
773
774 if (pOldKL)
775 UserDerefObjectCo(pOldKL);
776
778 return hOldKL;
779}
780
784 _In_ HKL hKL,
786 _In_opt_ PWND pWnd)
787{
788 PKL pKL;
790
791 pKL = IntHKLtoPKL(pti, hKL);
792 if (!pKL)
793 {
794 ERR("Invalid HKL %p!\n", hKL);
795 return NULL;
796 }
797
798 if (uFlags & KLF_REORDER)
799 IntReorderKeyboardLayouts(pWinSta, pKL);
800
801 return co_UserActivateKeyboardLayout(pKL, uFlags, pWnd);
802}
803
804static BOOL APIENTRY
807 _Inout_ PKL pKL,
809{
810 PKL pNextKL;
811 USER_REFERENCE_ENTRY Ref1, Ref2;
813
814 if (pKL == gspklBaseLayout && !(dwFlags & UKL_NOACTIVATENEXT))
815 return FALSE;
816
817 UserRefObjectCo(pKL, &Ref1); /* Add reference */
818
819 /* Regard as unloaded */
821 pKL->dwKL_Flags |= KL_UNLOAD;
822
823 if (!(dwFlags & UKL_NOACTIVATENEXT) && pti->KeyboardLayout == pKL)
824 {
825 pNextKL = IntHKLtoPKL(pti, UlongToHandle(HKL_NEXT));
826 if (pNextKL)
827 {
828 UserRefObjectCo(pNextKL, &Ref2); /* Add reference */
830 UserDerefObjectCo(pNextKL); /* Release reference */
831 }
832 }
833
834 if (gspklBaseLayout == pKL && pKL != pKL->pklNext)
835 {
836 /* Set next layout as default (FIXME: Use UserAssignmentLock?) */
838 }
839
840 UserDerefObjectCo(pKL); /* Release reference */
841
842 if (ISITHOOKED(WH_SHELL))
843 {
844 co_IntShellHookNotify(HSHELL_LANGUAGE, 0, 0);
846 }
847
848 return TRUE;
849}
850
851static BOOL APIENTRY
853{
854 PKL pKL = IntHKLtoPKL(gptiCurrent, hKL);
855 if (!pKL)
856 {
857 ERR("Invalid HKL %p!\n", hKL);
858 return FALSE;
859 }
860 return co_IntUnloadKeyboardLayoutEx(pWinSta, pKL, 0);
861}
862
865{
866 PIMEINFOEX piiex;
867
868 if (!IS_IME_HKL(hKL) && !IS_CICERO_MODE())
869 return NULL;
870
872 if (!piiex)
873 return NULL;
874
875 if (!co_ClientImmLoadLayout(hKL, piiex))
876 {
878 return NULL;
879 }
880
881 return piiex;
882}
883
886 IN OUT PWINSTATION_OBJECT pWinSta,
887 IN HANDLE hSafeFile,
888 IN HKL hOldKL,
889 IN PUNICODE_STRING puszSafeKLID,
890 IN HKL hNewKL,
891 IN UINT Flags)
892{
893 PKL pOldKL, pNewKL;
894
895 UNREFERENCED_PARAMETER(hSafeFile);
896
897 if (hNewKL == NULL || (pWinSta->Flags & WSS_NOIO))
898 return NULL;
899
900 /* If hOldKL is specified, unload it and load new layput as default */
901 if (hOldKL && hOldKL != hNewKL)
902 {
903 pOldKL = UserHklToKbl(hOldKL);
904 if (pOldKL)
905 UserUnloadKbl(pOldKL);
906 }
907
908 /* FIXME: It seems KLF_RESET is only supported for WINLOGON */
909
910 /* Let's see if layout was already loaded. */
911 pNewKL = UserHklToKbl(hNewKL);
912 if (!pNewKL)
913 {
914 /* It wasn't, so load it. */
915 pNewKL = co_UserLoadKbdLayout(puszSafeKLID, hNewKL);
916 if (!pNewKL)
917 return NULL;
918
919 if (gspklBaseLayout)
920 {
921 /* Find last not unloaded layout */
922 PKL pLastKL = gspklBaseLayout->pklPrev;
923 while (pLastKL != gspklBaseLayout && (pLastKL->dwKL_Flags & KL_UNLOAD))
924 pLastKL = pLastKL->pklPrev;
925
926 /* Add new layout to the list */
927 pNewKL->pklNext = pLastKL->pklNext;
928 pNewKL->pklPrev = pLastKL;
929 pNewKL->pklNext->pklPrev = pNewKL;
930 pNewKL->pklPrev->pklNext = pNewKL;
931 }
932 else
933 {
934 /* This is the first layout */
935 pNewKL->pklNext = pNewKL;
936 pNewKL->pklPrev = pNewKL;
937 gspklBaseLayout = pNewKL;
938 }
939
940 pNewKL->piiex = co_UserImmLoadLayout(hNewKL);
941 }
942
943 /* If this layout was prepared to unload, undo it */
944 pNewKL->dwKL_Flags &= ~KL_UNLOAD;
945
946 /* Reorder if necessary */
947 if (Flags & KLF_REORDER)
948 IntReorderKeyboardLayouts(pWinSta, pNewKL);
949
950 /* Activate this layout in current thread */
951 if (Flags & KLF_ACTIVATE)
953
954 /* Send shell message */
955 if (!(Flags & KLF_NOTELLSHELL))
956 co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)hNewKL);
957
958 /* FIXME: KLF_REPLACELANG */
959
960 return hNewKL;
961}
962
964{
967
969 return NULL;
970
972 (PVOID*)&FileObject, NULL);
973 if (!NT_SUCCESS(Status))
974 {
975 ERR("0x%08X\n", Status);
976 return NULL;
977 }
978
979 /* FIXME: Is the file in the system directory? */
980
981 if (FileObject)
983
984 return hFile;
985}
986
987/* EXPORTS *******************************************************************/
988
989/*
990 * UserGetKeyboardLayout
991 *
992 * Returns hkl of given thread keyboard layout
993 */
997{
998 PTHREADINFO pti;
999 PLIST_ENTRY ListEntry;
1000 PKL pKl;
1001
1003
1004 if (!dwThreadId)
1005 {
1006 pKl = pti->KeyboardLayout;
1007 return pKl ? pKl->hkl : NULL;
1008 }
1009
1010 ListEntry = pti->rpdesk->PtiList.Flink;
1011
1012 //
1013 // Search the Desktop Thread list for related Desktop active Threads.
1014 //
1015 while(ListEntry != &pti->rpdesk->PtiList)
1016 {
1017 pti = CONTAINING_RECORD(ListEntry, THREADINFO, PtiLink);
1018
1019 if (PsGetThreadId(pti->pEThread) == UlongToHandle(dwThreadId))
1020 {
1021 pKl = pti->KeyboardLayout;
1022 return pKl ? pKl->hkl : NULL;
1023 }
1024
1025 ListEntry = ListEntry->Flink;
1026 }
1027
1028 return NULL;
1029}
1030
1031/*
1032 * NtUserGetKeyboardLayoutList
1033 *
1034 * Returns list of loaded keyboard layouts in system
1035 */
1036UINT
1039 ULONG nBuff,
1040 HKL *pHklBuff)
1041{
1042 UINT ret = 0;
1043 PWINSTATION_OBJECT pWinSta;
1044
1045 if (!pHklBuff)
1046 nBuff = 0;
1047
1049
1050 if (nBuff > MAXULONG / sizeof(HKL))
1051 {
1053 goto Quit;
1054 }
1055
1056 _SEH2_TRY
1057 {
1058 ProbeForWrite(pHklBuff, nBuff * sizeof(HKL), 1);
1059 }
1061 {
1063 goto Quit;
1064 }
1065 _SEH2_END;
1066
1068
1069 _SEH2_TRY
1070 {
1071 ret = IntGetKeyboardLayoutList(pWinSta, nBuff, pHklBuff);
1072 }
1074 {
1076 goto Quit;
1077 }
1078 _SEH2_END;
1079
1080Quit:
1081 UserLeave();
1082 return ret;
1083}
1084
1085/*
1086 * NtUserGetKeyboardLayoutName
1087 *
1088 * Returns KLID of current thread keyboard layout
1089 */
1090BOOL
1093 _Inout_ PUNICODE_STRING pustrName)
1094{
1095 BOOL bRet = FALSE;
1096 PKL pKl;
1097 PTHREADINFO pti;
1098 UNICODE_STRING ustrNameSafe;
1100
1102
1104 pKl = pti->KeyboardLayout;
1105
1106 if (!pKl)
1107 goto cleanup;
1108
1109 _SEH2_TRY
1110 {
1111 ProbeForWriteUnicodeString(pustrName);
1112 ustrNameSafe = *pustrName;
1113
1114 ProbeForWrite(ustrNameSafe.Buffer, ustrNameSafe.MaximumLength, 1);
1115
1116 if (IS_IME_HKL(pKl->hkl))
1117 {
1118 Status = RtlIntegerToUnicodeString(HandleToUlong(pKl->hkl), 16, &ustrNameSafe);
1119 }
1120 else
1121 {
1122 if (ustrNameSafe.MaximumLength < KL_NAMELENGTH * sizeof(WCHAR))
1123 {
1125 goto cleanup;
1126 }
1127
1128 /* FIXME: Do not use awchKF */
1129 ustrNameSafe.Length = 0;
1130 Status = RtlAppendUnicodeToString(&ustrNameSafe, pKl->spkf->awchKF);
1131 }
1132
1133 if (NT_SUCCESS(Status))
1134 {
1135 *pustrName = ustrNameSafe;
1136 bRet = TRUE;
1137 }
1138 }
1140 {
1142 }
1143 _SEH2_END;
1144
1145cleanup:
1146 UserLeave();
1147 return bRet;
1148}
1149
1150/*
1151 * NtUserLoadKeyboardLayoutEx
1152 *
1153 * Loads keyboard layout with given locale id
1154 *
1155 * NOTE: We adopt a different design from Microsoft's one due to security reason.
1156 * We don't use the 3rd parameter of NtUserLoadKeyboardLayoutEx.
1157 * See https://bugtraq.securityfocus.com/detail/50056B96.6040306
1158 */
1159HKL
1160NTAPI
1162 IN HANDLE hFile,
1163 IN DWORD offTable,
1164 IN PVOID pTables,
1165 IN HKL hOldKL,
1166 IN PUNICODE_STRING puszKLID,
1167 IN DWORD dwNewKL,
1168 IN UINT Flags)
1169{
1170 HKL hRetKL;
1172 UNICODE_STRING uszSafeKLID;
1173 PWINSTATION_OBJECT pWinSta;
1174 HANDLE hSafeFile;
1175
1176 UNREFERENCED_PARAMETER(offTable);
1177 UNREFERENCED_PARAMETER(pTables);
1178
1181 KLF_RESET|KLF_SHIFTLOCK))
1182 {
1183 ERR("Invalid flags: %x\n", Flags);
1185 return NULL;
1186 }
1187
1188 RtlInitEmptyUnicodeString(&uszSafeKLID, Buffer, sizeof(Buffer));
1189 _SEH2_TRY
1190 {
1191 ProbeForRead(puszKLID, sizeof(*puszKLID), 1);
1192 ProbeForRead(puszKLID->Buffer, sizeof(puszKLID->Length), 1);
1193 RtlCopyUnicodeString(&uszSafeKLID, puszKLID);
1194 }
1196 {
1198 _SEH2_YIELD(return NULL);
1199 }
1200 _SEH2_END;
1201
1203
1204 hSafeFile = (hFile ? IntVerifyKeyboardFileHandle(hFile) : NULL);
1206 hRetKL = co_IntLoadKeyboardLayoutEx(pWinSta,
1207 hSafeFile,
1208 hOldKL,
1209 &uszSafeKLID,
1210 UlongToHandle(dwNewKL),
1211 Flags);
1212 if (hSafeFile)
1213 ZwClose(hSafeFile);
1214
1215 UserLeave();
1216 return hRetKL;
1217}
1218
1219/*
1220 * NtUserActivateKeyboardLayout
1221 *
1222 * Activates specified layout for thread or process
1223 */
1224HKL
1225NTAPI
1227 HKL hKL,
1228 ULONG Flags)
1229{
1230 PWINSTATION_OBJECT pWinSta;
1231 HKL hOldKL;
1232
1234
1235 /* FIXME */
1236
1238 hOldKL = co_IntActivateKeyboardLayout(pWinSta, hKL, Flags, NULL);
1239 UserLeave();
1240
1241 return hOldKL;
1242}
1243
1244/*
1245 * NtUserUnloadKeyboardLayout
1246 *
1247 * Unloads keyboard layout with specified hkl value
1248 */
1249BOOL
1252 HKL hKl)
1253{
1254 BOOL ret;
1255 PWINSTATION_OBJECT pWinSta;
1256
1258
1260 ret = IntUnloadKeyboardLayout(pWinSta, hKl);
1261
1262 UserLeave();
1263 return ret;
1264}
1265
1266/* EOF */
#define VOID
Definition: acefi.h:82
LONG NTSTATUS
Definition: precomp.h:26
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define HandleToUlong(h)
Definition: basetsd.h:79
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define APIENTRY
Definition: api.h:79
UINT uFlags
Definition: api.c:59
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
static void cleanup(void)
Definition: main.c:1335
#define swprintf
Definition: precomp.h:40
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define PagedPool
Definition: env_spec_w32.h:308
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
DWORD dwThreadId
Definition: fdebug.c:31
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
Status
Definition: gdiplustypes.h:25
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
#define DbgPrint
Definition: hal.h:12
#define ISITHOOKED(HookId)
Definition: hook.h:6
#define cs
Definition: i386-dis.c:442
#define IS_IME_HKL(hKL)
Definition: imm32_undoc.h:20
#define IMS_ACTIVATELAYOUT
Definition: immdev.h:110
#define IMS_SENDNOTIFICATION
Definition: immdev.h:113
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define TIF_CSRSSTHREAD
Definition: ntuser.h:266
#define TIF_INCLEANUP
Definition: ntuser.h:263
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
struct _THREADINFO * GetW32ThreadInfo(VOID)
Definition: misc.c:807
#define CI_IMMACTIVATE
Definition: ntuser.h:306
#define IS_IMM_MODE()
Definition: ntuser.h:1209
@ TYPE_KBDFILE
Definition: ntuser.h:54
@ TYPE_KBDLAYOUT
Definition: ntuser.h:53
#define IS_16BIT_MODE()
Definition: ntuser.h:1211
#define IS_CICERO_MODE()
Definition: ntuser.h:1210
CLIENT_DATA ClientInfo
#define REG_SZ
Definition: layer.c:22
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define _Inout_
Definition: ms_sal.h:378
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
UINT_PTR HKL
Definition: msctf.idl:143
_In_ HANDLE hFile
Definition: mswsock.h:90
unsigned int UINT
Definition: ndis.h:50
#define UserMode
Definition: asm.h:35
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FASTCALL
Definition: nt_native.h:50
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString(ULONG Value, ULONG Base, PUNICODE_STRING String)
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
HANDLE NTAPI PsGetThreadId(IN PETHREAD Thread)
Definition: thread.c:705
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
NTSTRSAFEAPI RtlStringCbCatW(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:636
PWINSTATION_OBJECT FASTCALL IntGetProcessWindowStation(HWINSTA *phWinSta OPTIONAL)
Definition: winsta.c:400
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:258
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:242
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:249
#define L(x)
Definition: ntvdm.h:50
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:43
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:27
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define LOWORD(l)
Definition: pedump.c:82
BYTE * PBYTE
Definition: pedump.c:66
unsigned short USHORT
Definition: pedump.c:61
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
DWORD LCID
Definition: nls.h:13
#define ProbeForWriteUnicodeString(Ptr)
Definition: probe.h:48
#define TRACE(s)
Definition: solgame.cpp:4
USHORT CodePage
Definition: ntuser.h:340
HKL hKL
Definition: ntuser.h:339
DWORD cLockObj
Definition: ntuser.h:182
Definition: kbd.h:95
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PTHREADINFO ptiList
Definition: win32.h:257
PPROCESSINFO ppi
Definition: win32.h:88
PTHREADINFO ptiSibling
Definition: win32.h:116
struct _CLIENTINFO * pClientInfo
Definition: win32.h:94
struct tagKL * KeyboardLayout
Definition: win32.h:90
FLONG TIF_flags
Definition: win32.h:95
struct _DESKTOP * rpdesk
Definition: win32.h:92
struct _WND * spwndDefaultIme
Definition: win32.h:131
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:89
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: object.h:4
Definition: kbd.h:21
BYTE ModBits
Definition: kbd.h:23
BYTE Vk
Definition: kbd.h:22
BYTE cbSize
Definition: kbd.h:53
PVK_TO_WCHARS1 pVkToWchars
Definition: kbd.h:51
BYTE nModifications
Definition: kbd.h:52
Definition: kbd.h:71
USHORT Vk
Definition: kbd.h:73
BYTE Vsc
Definition: kbd.h:72
Definition: ntuser.h:694
HANDLE hBase
Definition: input.h:20
struct _KBDTABLES * pKbdTbl
Definition: input.h:21
struct tagKBDFILE * pkfNext
Definition: input.h:18
WCHAR awchKF[20]
Definition: input.h:19
Definition: input.h:27
DWORD dwKL_Flags
Definition: input.h:31
USHORT CodePage
Definition: input.h:36
PIMEINFOEX piiex
Definition: input.h:38
DWORD dwFontSigs
Definition: input.h:34
PKBDFILE spkf
Definition: input.h:33
HEAD head
Definition: input.h:28
HKL hkl
Definition: input.h:32
struct tagKL * pklNext
Definition: input.h:29
UINT iBaseCharset
Definition: input.h:35
struct tagKL * pklPrev
Definition: input.h:30
#define MAXULONG
Definition: typedefs.h:251
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
#define OUT
Definition: typedefs.h:40
#define UKL_NOACTIVATENEXT
Definition: undocuser.h:182
#define KL_UNLOAD
Definition: undocuser.h:179
#define WM_IME_SYSTEM
Definition: undocuser.h:60
int ret
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
#define IntDereferenceThreadInfo(pti)
Definition: win32.h:172
#define IntReferenceThreadInfo(pti)
Definition: win32.h:167
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
BOOL APIENTRY co_IntGetCharsetInfo(LCID Locale, PCHARSETINFO pCs)
Definition: callback.c:1040
BOOL APIENTRY co_ClientImmLoadLayout(_In_ HKL hKL, _Inout_ PIMEINFOEX pImeInfoEx)
Definition: callback.c:1278
VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam)
Definition: desktop.c:1709
PTHREADINFO gptiForeground
Definition: focus.c:15
UINT APIENTRY NtUserGetKeyboardLayoutList(ULONG nBuff, HKL *pHklBuff)
Definition: kbdlayout.c:1038
static BOOL APIENTRY co_IntUnloadKeyboardLayoutEx(_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PKL pKL, _In_ DWORD dwFlags)
Definition: kbdlayout.c:805
static UINT APIENTRY IntGetKeyboardLayoutList(_Inout_ PWINSTATION_OBJECT pWinSta, _In_ ULONG nBuff, _Out_ HKL *pHklBuff)
Definition: kbdlayout.c:96
HKL NTAPI NtUserActivateKeyboardLayout(HKL hKL, ULONG Flags)
Definition: kbdlayout.c:1226
static BOOL UserLoadKbdDll(WCHAR *pwszLayoutPath, HANDLE *phModule, PKBDTABLES *pKbdTables)
Definition: kbdlayout.c:248
VOID FASTCALL IntReorderKeyboardLayouts(_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PKL pNewKL)
Definition: kbdlayout.c:558
VOID APIENTRY IntImmActivateLayout(_Inout_ PTHREADINFO pti, _Inout_ PKL pKL)
Definition: kbdlayout.c:596
DWORD gSystemFS
Definition: kbdlayout.c:24
PKL gspklBaseLayout
Definition: kbdlayout.c:22
static BOOL APIENTRY IntUnloadKeyboardLayout(_Inout_ PWINSTATION_OBJECT pWinSta, _In_ HKL hKL)
Definition: kbdlayout.c:852
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:539
UINT gSystemCPCharSet
Definition: kbdlayout.c:25
#define CP_ACP
Definition: kbdlayout.c:18
PKL FASTCALL IntHKLtoPKL(_Inout_ PTHREADINFO pti, _In_ HKL hKL)
Definition: kbdlayout.c:36
HKL APIENTRY co_UserActivateKeyboardLayout(_Inout_ PKL pKL, _In_ ULONG uFlags, _In_opt_ PWND pWnd)
Definition: kbdlayout.c:667
static PKL co_UserLoadKbdLayout(PUNICODE_STRING pustrKLID, HKL hKL)
Definition: kbdlayout.c:375
BOOL UserUnloadKbl(PKL pKl)
Definition: kbdlayout.c:471
PKBDFILE gpkfList
Definition: kbdlayout.c:23
PVOID(* PFN_KBDLAYERDESCRIPTOR)(VOID)
Definition: kbdlayout.c:28
PIMEINFOEX FASTCALL co_UserImmLoadLayout(_In_ HKL hKL)
Invokes imm32!ImmLoadLayout and returns PIMEINFOEX.
Definition: kbdlayout.c:864
HKL ghKLSentToShell
Definition: kbdlayout.c:26
static VOID UnloadKbdFile(_In_ PKBDFILE pkf)
Definition: kbdlayout.c:444
HKL APIENTRY co_IntLoadKeyboardLayoutEx(IN OUT PWINSTATION_OBJECT pWinSta, IN HANDLE hSafeFile, IN HKL hOldKL, IN PUNICODE_STRING puszSafeKLID, IN HKL hNewKL, IN UINT Flags)
Definition: kbdlayout.c:885
HKL APIENTRY co_IntActivateKeyboardLayout(_Inout_ PWINSTATION_OBJECT pWinSta, _In_ HKL hKL, _In_ ULONG uFlags, _In_opt_ PWND pWnd)
Definition: kbdlayout.c:782
BOOL APIENTRY NtUserUnloadKeyboardLayout(HKL hKl)
Definition: kbdlayout.c:1251
BOOL APIENTRY NtUserGetKeyboardLayoutName(_Inout_ PUNICODE_STRING pustrName)
Definition: kbdlayout.c:1092
HKL FASTCALL UserGetKeyboardLayout(DWORD dwThreadId)
Definition: kbdlayout.c:995
static VOID co_IntSetKeyboardLayoutForProcess(PPROCESSINFO ppi, PKL pKL)
Definition: kbdlayout.c:632
PKL W32kGetDefaultKeyLayout(VOID)
Definition: kbdlayout.c:512
HANDLE FASTCALL IntVerifyKeyboardFileHandle(HANDLE hFile)
Definition: kbdlayout.c:963
HKL NTAPI NtUserLoadKeyboardLayoutEx(IN HANDLE hFile, IN DWORD offTable, IN PVOID pTables, IN HKL hOldKL, IN PUNICODE_STRING puszKLID, IN DWORD dwNewKL, IN UINT Flags)
Definition: kbdlayout.c:1161
BOOL NTAPI UserSetDefaultInputLang(HKL hKl)
Definition: kbdlayout.c:583
static PKBDFILE UserLoadKbdFile(PUNICODE_STRING pwszKLID)
Definition: kbdlayout.c:296
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1495
BOOL FASTCALL UserMarkObjectDestroy(PVOID Object)
Definition: object.c:621
PVOID FASTCALL UserAssignmentLock(PVOID *ppvObj, PVOID pvNew)
Definition: object.c:839
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:644
BOOL FASTCALL UserDeleteObject(HANDLE h, HANDLE_TYPE type)
Definition: object.c:717
PUSER_HANDLE_TABLE gHandleTable
Definition: object.c:13
PVOID FASTCALL UserCreateObject(PUSER_HANDLE_TABLE ht, PDESKTOP pDesktop, PTHREADINFO pti, HANDLE *h, HANDLE_TYPE type, ULONG size)
Definition: object.c:568
#define USERTAG_IME
Definition: tags.h:240
#define WSS_NOIO
Definition: winsta.h:9
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
ENGAPI PVOID APIENTRY EngFindImageProcAddress(_In_ HANDLE hModule, _In_ LPSTR lpProcName)
Definition: ldevobj.c:927
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22
ENGAPI VOID APIENTRY EngUnloadImage(_In_ HANDLE hModule)
Definition: ldevobj.c:913
ENGAPI HANDLE APIENTRY EngLoadImage(_In_ LPWSTR pwszDriver)
Definition: ldevobj.c:904
LONG_PTR LPARAM
Definition: windef.h:208
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
#define ANSI_CHARSET
Definition: wingdi.h:383
#define FS_LATIN1
Definition: wingdi.h:560
#define RegOpenKey
Definition: winreg.h:519
#define RegQueryValue
Definition: winreg.h:523
#define KLF_SETFORPROCESS
Definition: winuser.h:117
#define KL_NAMELENGTH
Definition: winuser.h:122
#define KLF_REPLACELANG
Definition: winuser.h:115
#define KLF_ACTIVATE
Definition: winuser.h:111
#define HKL_PREV
Definition: winuser.h:110
#define KLF_REORDER
Definition: winuser.h:114
#define WH_SHELL
Definition: winuser.h:40
#define HKL_NEXT
Definition: winuser.h:109
#define KLF_SUBSTITUTE_OK
Definition: winuser.h:112
#define KLF_NOTELLSHELL
Definition: winuser.h:116
#define KLF_UNLOADPREVIOUS
Definition: winuser.h:113
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObDereferenceObject
Definition: obfuncs.h:203
#define NT_ASSERT
Definition: rtlfuncs.h:3324
__wchar_t WCHAR
Definition: xmlstorage.h:180