ReactOS 0.4.15-dev-7942-gd23573b
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 * Win: HKLtoPKL
36 */
38{
39 PKL pFirstKL, pKL;
40
41 pFirstKL = pti->KeyboardLayout;
42 if (!pFirstKL)
43 return NULL;
44
45 pKL = pFirstKL;
46
47 /* hKL can have special value HKL_NEXT or HKL_PREV */
48 if (hKL == (HKL)(ULONG_PTR)HKL_NEXT) /* Looking forward */
49 {
50 do
51 {
52 pKL = pKL->pklNext;
53 if (!(pKL->dwKL_Flags & KLF_UNLOAD))
54 return pKL;
55 } while (pKL != pFirstKL);
56 }
57 else if (hKL == (HKL)(ULONG_PTR)HKL_PREV) /* Looking backward */
58 {
59 do
60 {
61 pKL = pKL->pklPrev;
62 if (!(pKL->dwKL_Flags & KLF_UNLOAD))
63 return pKL;
64 } while (pKL != pFirstKL);
65 }
66 else if (HIWORD(hKL)) /* hKL is a full input locale identifier */
67 {
68 /* No KLF_UNLOAD check */
69 do
70 {
71 if (pKL->hkl == hKL)
72 return pKL;
73
74 pKL = pKL->pklNext;
75 } while (pKL != pFirstKL);
76 }
77 else /* Language only specified */
78 {
79 /* No KLF_UNLOAD check */
80 do
81 {
82 if (LOWORD(pKL->hkl) == LOWORD(hKL)) /* Low word is language ID */
83 return pKL;
84
85 pKL = pKL->pklNext;
86 } while (pKL != pFirstKL);
87 }
88
89 return NULL;
90}
91
92/*
93 * A helper function for NtUserGetKeyboardLayoutList.
94 * @implemented
95 * Win: _GetKeyboardLayoutList
96 */
97static UINT APIENTRY
100 _In_ ULONG nBuff,
101 _Out_ HKL *pHklBuff)
102{
103 UINT ret = 0;
104 PKL pKL, pFirstKL;
105
106 pFirstKL = gspklBaseLayout; /* FIXME: Use pWinSta->spklList instead */
107 if (!pWinSta || !pFirstKL)
108 return 0;
109
110 pKL = pFirstKL;
111
112 if (nBuff == 0)
113 {
114 /* Count the effective PKLs */
115 do
116 {
117 if (!(pKL->dwKL_Flags & KLF_UNLOAD))
118 ++ret;
119 pKL = pKL->pklNext;
120 } while (pKL != pFirstKL);
121 }
122 else
123 {
124 /* Copy the effective HKLs to pHklBuff */
125 do
126 {
127 if (!(pKL->dwKL_Flags & KLF_UNLOAD))
128 {
129 *pHklBuff = pKL->hkl;
130 ++pHklBuff;
131 ++ret;
132 --nBuff;
133
134 if (nBuff == 0)
135 break;
136 }
137 pKL = pKL->pklNext;
138 } while (pKL != pFirstKL);
139 }
140
141 return ret;
142}
143
144#if 0 && DBG
145
146static VOID
147DumpKbdLayout(
148 IN PKBDTABLES pKbdTbl)
149{
150 PVK_TO_BIT pVkToBit;
151 PVK_TO_WCHAR_TABLE pVkToWchTbl;
152 PVSC_VK pVscVk;
153 ULONG i;
154
155 DbgPrint("Kbd layout: fLocaleFlags %x bMaxVSCtoVK %x\n",
156 pKbdTbl->fLocaleFlags, pKbdTbl->bMaxVSCtoVK);
157 DbgPrint("wMaxModBits %x\n",
158 pKbdTbl->pCharModifiers ? pKbdTbl->pCharModifiers->wMaxModBits
159 : 0);
160
161 if (pKbdTbl->pCharModifiers)
162 {
163 pVkToBit = pKbdTbl->pCharModifiers->pVkToBit;
164 if (pVkToBit)
165 {
166 for (; pVkToBit->Vk; ++pVkToBit)
167 {
168 DbgPrint("VkToBit %x -> %x\n", pVkToBit->Vk, pVkToBit->ModBits);
169 }
170 }
171
172 for (i = 0; i <= pKbdTbl->pCharModifiers->wMaxModBits; ++i)
173 {
174 DbgPrint("ModNumber %x -> %x\n", i, pKbdTbl->pCharModifiers->ModNumber[i]);
175 }
176 }
177
178 pVkToWchTbl = pKbdTbl->pVkToWcharTable;
179 if (pVkToWchTbl)
180 {
181 for (; pVkToWchTbl->pVkToWchars; ++pVkToWchTbl)
182 {
183 PVK_TO_WCHARS1 pVkToWch = pVkToWchTbl->pVkToWchars;
184
185 DbgPrint("pVkToWchTbl nModifications %x cbSize %x\n",
186 pVkToWchTbl->nModifications, pVkToWchTbl->cbSize);
187 if (pVkToWch)
188 {
189 while (pVkToWch->VirtualKey)
190 {
191 DbgPrint("pVkToWch VirtualKey %x Attributes %x wc { ",
192 pVkToWch->VirtualKey, pVkToWch->Attributes);
193 for (i = 0; i < pVkToWchTbl->nModifications; ++i)
194 {
195 DbgPrint("%x ", pVkToWch->wch[i]);
196 }
197 DbgPrint("}\n");
198 pVkToWch = (PVK_TO_WCHARS1)(((PBYTE)pVkToWch) + pVkToWchTbl->cbSize);
199 }
200 }
201 }
202 }
203
204// TODO: DeadKeys, KeyNames, KeyNamesExt, KeyNamesDead
205
206 DbgPrint("pusVSCtoVK: { ");
207 if (pKbdTbl->pusVSCtoVK)
208 {
209 for (i = 0; i < pKbdTbl->bMaxVSCtoVK; ++i)
210 {
211 DbgPrint("%x -> %x, ", i, pKbdTbl->pusVSCtoVK[i]);
212 }
213 }
214 DbgPrint("}\n");
215
216 DbgPrint("pVSCtoVK_E0: { ");
217 pVscVk = pKbdTbl->pVSCtoVK_E0;
218 if (pVscVk)
219 {
220 for (; pVscVk->Vsc; ++pVscVk)
221 {
222 DbgPrint("%x -> %x, ", pVscVk->Vsc, pVscVk->Vk);
223 }
224 }
225 DbgPrint("}\n");
226
227 DbgPrint("pVSCtoVK_E1: { ");
228 pVscVk = pKbdTbl->pVSCtoVK_E1;
229 if (pVscVk)
230 {
231 for (; pVscVk->Vsc; ++pVscVk)
232 {
233 DbgPrint("%x -> %x, ", pVscVk->Vsc, pVscVk->Vk);
234 }
235 }
236 DbgPrint("}\n");
237
238// TODO: Ligatures
239}
240
241#endif // DBG
242
243
244/*
245 * UserLoadKbdDll
246 *
247 * Loads keyboard layout DLL and gets address to KbdTables
248 */
249static BOOL
250UserLoadKbdDll(WCHAR *pwszLayoutPath,
251 HANDLE *phModule,
252 PKBDTABLES *pKbdTables)
253{
254 PFN_KBDLAYERDESCRIPTOR pfnKbdLayerDescriptor;
255
256 /* Load keyboard layout DLL */
257 TRACE("Loading Keyboard DLL %ws\n", pwszLayoutPath);
258 *phModule = EngLoadImage(pwszLayoutPath);
259 if (!(*phModule))
260 {
261 ERR("Failed to load dll %ws\n", pwszLayoutPath);
262 return FALSE;
263 }
264
265 /* Find KbdLayerDescriptor function and get layout tables */
266 TRACE("Loaded %ws\n", pwszLayoutPath);
267 pfnKbdLayerDescriptor = EngFindImageProcAddress(*phModule, "KbdLayerDescriptor");
268
269 /* FIXME: Windows reads file instead of executing!
270 It's not safe to kbdlayout DLL in kernel mode! */
271
272 if (pfnKbdLayerDescriptor)
273 *pKbdTables = pfnKbdLayerDescriptor();
274 else
275 ERR("Error: %ws has no KbdLayerDescriptor()\n", pwszLayoutPath);
276
277 if (!pfnKbdLayerDescriptor || !*pKbdTables)
278 {
279 ERR("Failed to load the keyboard layout.\n");
280 EngUnloadImage(*phModule);
281 return FALSE;
282 }
283
284#if 0 && DBG
285 /* Dump keyboard layout */
286 DumpKbdLayout(*pKbdTables);
287#endif
288
289 return TRUE;
290}
291
292/*
293 * UserLoadKbdFile
294 *
295 * Loads keyboard layout DLL and creates KBDFILE object
296 */
297static PKBDFILE
299{
300 PKBDFILE pkf, pRet = NULL;
302 ULONG cbSize;
303 HKEY hKey = NULL;
304 WCHAR wszLayoutPath[MAX_PATH] = L"\\SystemRoot\\System32\\";
305 WCHAR wszLayoutRegKey[256] = L"\\REGISTRY\\Machine\\SYSTEM\\CurrentControlSet\\"
306 L"Control\\Keyboard Layouts\\";
307
308 /* Create keyboard layout file object */
310 if (!pkf)
311 {
312 ERR("Failed to create object!\n");
313 return NULL;
314 }
315
316 /* Set keyboard layout name */
317 swprintf(pkf->awchKF, L"%wZ", pwszKLID);
318
319 /* Open layout registry key */
320 RtlStringCbCatW(wszLayoutRegKey, sizeof(wszLayoutRegKey), pkf->awchKF);
321 Status = RegOpenKey(wszLayoutRegKey, &hKey);
322 if (!NT_SUCCESS(Status))
323 {
324 ERR("Failed to open keyboard layouts registry key %ws (%lx)\n", wszLayoutRegKey, Status);
325 goto cleanup;
326 }
327
328 /* Read filename of layout DLL */
329 cbSize = (ULONG)(sizeof(wszLayoutPath) - wcslen(wszLayoutPath)*sizeof(WCHAR));
331 L"Layout File",
332 REG_SZ,
333 wszLayoutPath + wcslen(wszLayoutPath),
334 &cbSize);
335
336 if (!NT_SUCCESS(Status))
337 {
338 ERR("Can't get layout filename for %wZ (%lx)\n", pwszKLID, Status);
339 goto cleanup;
340 }
341
342 /* Load keyboard file now */
343 if (!UserLoadKbdDll(wszLayoutPath, &pkf->hBase, &pkf->pKbdTbl))
344 {
345 ERR("Failed to load %ws dll!\n", wszLayoutPath);
346 goto cleanup;
347 }
348
349 /* Update next field */
350 pkf->pkfNext = gpkfList;
351 gpkfList = pkf;
352
353 /* Return keyboard file */
354 pRet = pkf;
355
356cleanup:
357 if (hKey)
358 ZwClose(hKey);
359 if (pkf)
360 UserDereferenceObject(pkf); // we dont need ptr anymore
361 if (!pRet)
362 {
363 /* We have failed - destroy created object */
364 if (pkf)
366 }
367
368 return pRet;
369}
370
371/*
372 * co_UserLoadKbdLayout
373 *
374 * Loads keyboard layout and creates KL object
375 */
376static PKL
378{
379 LCID lCid;
381 PKL pKl;
382
383 /* Create keyboard layout object */
385 if (!pKl)
386 {
387 ERR("Failed to create object!\n");
388 return NULL;
389 }
390
391 pKl->hkl = hKL;
392 pKl->spkf = UserLoadKbdFile(pustrKLID);
393
394 /* Dereference keyboard layout */
396
397 /* If we failed, remove KL object */
398 if (!pKl->spkf)
399 {
400 ERR("UserLoadKbdFile(%wZ) failed!\n", pustrKLID);
402 return NULL;
403 }
404
405 // Up to Language Identifiers..
406 if (!NT_SUCCESS(RtlUnicodeStringToInteger(pustrKLID, 16, (PULONG)&lCid)))
407 {
408 ERR("RtlUnicodeStringToInteger failed for '%wZ'\n", pustrKLID);
410 return NULL;
411 }
412
413 TRACE("Language Identifiers %wZ LCID 0x%x\n", pustrKLID, lCid);
414 if (co_IntGetCharsetInfo(lCid, &cs))
415 {
416 pKl->iBaseCharset = cs.ciCharset;
417 pKl->dwFontSigs = cs.fs.fsCsb[0];
418 pKl->CodePage = (USHORT)cs.ciACP;
419 TRACE("Charset %u Font Sig %lu CodePage %u\n",
420 pKl->iBaseCharset, pKl->dwFontSigs, pKl->CodePage);
421 }
422 else
423 {
425 pKl->dwFontSigs = FS_LATIN1;
426 pKl->CodePage = CP_ACP;
427 }
428
429 // Set initial system character set and font signature.
430 if (gSystemFS == 0)
431 {
433 gSystemFS = pKl->dwFontSigs;
434 }
435
436 return pKl;
437}
438
439/*
440 * UnloadKbdFile
441 *
442 * Destroys specified Keyboard File object
443 */
444static
445VOID
447{
448 PKBDFILE *ppkfLink = &gpkfList;
449 NT_ASSERT(pkf != NULL);
450
451 /* Find previous object */
452 while (*ppkfLink)
453 {
454 if (*ppkfLink == pkf)
455 break;
456
457 ppkfLink = &(*ppkfLink)->pkfNext;
458 }
459
460 if (*ppkfLink == pkf)
461 *ppkfLink = pkf->pkfNext;
462
463 EngUnloadImage(pkf->hBase);
465}
466
467/*
468 * UserUnloadKbl
469 *
470 * Unloads specified Keyboard Layout if possible
471 */
472BOOL
474{
475 /* According to msdn, UnloadKeyboardLayout can fail
476 if the keyboard layout identifier was preloaded. */
477 if (pKl == gspklBaseLayout)
478 {
479 if (pKl->pklNext == pKl->pklPrev)
480 {
481 /* There is only one layout */
482 return FALSE;
483 }
484
485 /* Set next layout as default */
487 }
488
489 if (pKl->head.cLockObj > 1)
490 {
491 /* Layout is used by other threads */
492 pKl->dwKL_Flags |= KLF_UNLOAD;
493 return FALSE;
494 }
495
496 /* Unload the layout */
497 pKl->pklPrev->pklNext = pKl->pklNext;
498 pKl->pklNext->pklPrev = pKl->pklPrev;
499 UnloadKbdFile(pKl->spkf);
500 if (pKl->piiex)
501 {
503 }
505 return TRUE;
506}
507
508/*
509 * W32kGetDefaultKeyLayout
510 *
511 * Returns default layout for new threads
512 */
513PKL
515{
516 PKL pKl = gspklBaseLayout;
517
518 if (!pKl)
519 return NULL;
520
521 /* Return not unloaded layout */
522 do
523 {
524 if (!(pKl->dwKL_Flags & KLF_UNLOAD))
525 return pKl;
526
527 pKl = pKl->pklPrev; /* Confirmed on Win2k */
528 } while(pKl != gspklBaseLayout);
529
530 /* We have not found proper KL */
531 return NULL;
532}
533
534/*
535 * UserHklToKbl
536 *
537 * Gets KL object from hkl value
538 */
539PKL
540NTAPI
542{
543 PKL pKl = gspklBaseLayout;
544
545 if (!gspklBaseLayout)
546 return NULL;
547
548 do
549 {
550 if (pKl->hkl == hKl)
551 return pKl;
552
553 pKl = pKl->pklNext;
554 } while (pKl != gspklBaseLayout);
555
556 return NULL;
557}
558
559// Win: ReorderKeyboardLayouts
563 _Inout_ PKL pNewKL)
564{
565 PKL pOldKL = gspklBaseLayout;
566
567 if ((pWinSta->Flags & WSS_NOIO) || pNewKL == pOldKL)
568 return;
569
570 pNewKL->pklPrev->pklNext = pNewKL->pklNext;
571 pNewKL->pklNext->pklPrev = pNewKL->pklPrev;
572 pNewKL->pklNext = pOldKL;
573 pNewKL->pklPrev = pOldKL->pklPrev;
574 pOldKL->pklPrev->pklNext = pNewKL;
575 pOldKL->pklPrev = pNewKL;
576 gspklBaseLayout = pNewKL; /* Should we use UserAssignmentLock? */
577}
578
579/*
580 * UserSetDefaultInputLang
581 *
582 * Sets default keyboard layout for system. Called from UserSystemParametersInfo.
583 */
584BOOL
585NTAPI
587{
588 PKL pKl;
589
590 pKl = UserHklToKbl(hKl);
591 if (!pKl)
592 return FALSE;
593
595 return TRUE;
596}
597
598/*
599 * co_UserActivateKbl
600 *
601 * Activates given layout in specified thread
602 */
603static PKL
605{
606 PKL pklPrev;
607 PWND pWnd;
608
609 pklPrev = pti->KeyboardLayout;
610
612 pti->pClientInfo->hKL = pKl->hkl;
613
615 {
616 FIXME("KLF_SETFORPROCESS\n");
617 }
618
619 if (!(pWnd = pti->MessageQueue->spwndFocus))
620 {
621 pWnd = pti->MessageQueue->spwndActive;
622 }
623
624 // Send WM_INPUTLANGCHANGE to thread's focus window
625 co_IntSendMessage( pWnd ? UserHMGetHandle(pWnd) : 0,
626 WM_INPUTLANGCHANGE,
627 (WPARAM)pKl->iBaseCharset, // FIXME: How to set it?
628 (LPARAM)pKl->hkl); // hkl
629
630 return pklPrev;
631}
632
636 _Inout_ PKL pKL)
637{
638 PWND pImeWnd;
639 HWND hImeWnd;
641
642 if (pti->KeyboardLayout == pKL)
643 return;
644
645 pImeWnd = pti->spwndDefaultIme;
646 if (pImeWnd)
647 {
648 UserRefObjectCo(pImeWnd, &Ref);
649 hImeWnd = UserHMGetHandle(pImeWnd);
651 UserDerefObjectCo(pImeWnd);
652 }
653 else
654 {
655 /* Remember old keyboard layout to switch back for Chinese IMEs */
656 pti->hklPrev = pti->KeyboardLayout->hkl;
657
658 if (pti->spDefaultImc)
659 {
660 /* IME Activation is needed */
661 pti->pClientInfo->CI_flags |= CI_IMMACTIVATE;
662 }
663 }
664
665 UserAssignmentLock((PVOID*)&(pti->KeyboardLayout), pKL);
666 pti->pClientInfo->hKL = pKL->hkl;
667 pti->pClientInfo->CodePage = pKL->CodePage;
668}
669
671{
672 PTHREADINFO ptiNode, ptiNext;
673 PCLIENTINFO pClientInfo;
674 BOOL bImmMode = IS_IMM_MODE();
675
676 for (ptiNode = ppi->ptiList; ptiNode; ptiNode = ptiNext)
677 {
678 IntReferenceThreadInfo(ptiNode);
679 ptiNext = ptiNode->ptiSibling;
680
681 /* Skip this thread if its keyboard layout is already the correct one, or if it's dying */
682 if (ptiNode->KeyboardLayout == pKL || (ptiNode->TIF_flags & TIF_INCLEANUP))
683 {
685 continue;
686 }
687
688 if (bImmMode)
689 {
690 IntImmActivateLayout(ptiNode, pKL);
691 }
692 else
693 {
694 UserAssignmentLock((PVOID*)&ptiNode->KeyboardLayout, pKL);
695 pClientInfo = ptiNode->pClientInfo;
696 pClientInfo->CodePage = pKL->CodePage;
697 pClientInfo->hKL = pKL->hkl;
698 }
699
701 }
702}
703
706 _Inout_ PKL pKL,
708 _Inout_ PWND pWnd)
709{
710 HKL hOldKL = NULL;
711 PKL pOldKL = NULL;
713 PWND pTargetWnd, pImeWnd;
714 HWND hTargetWnd, hImeWnd;
715 USER_REFERENCE_ENTRY Ref1, Ref2;
717 BOOL bSetForProcess = !!(uFlags & KLF_SETFORPROCESS);
718
720 ClientInfo = pti->pClientInfo;
721
722 if (pti->KeyboardLayout)
723 {
724 pOldKL = pti->KeyboardLayout;
725 if (pOldKL)
726 hOldKL = pOldKL->hkl;
727 }
728
729 if (uFlags & KLF_RESET)
730 {
731 FIXME("KLF_RESET\n");
732 }
733
734 if (!bSetForProcess && pKL == pti->KeyboardLayout)
735 {
737 return hOldKL;
738 }
739
740 pKL->wchDiacritic = 0;
741
742 if (pOldKL)
743 UserRefObjectCo(pOldKL, &Ref1);
744
745 if (pti->TIF_flags & TIF_CSRSSTHREAD)
746 {
748 ClientInfo->CodePage = pKL->CodePage;
749 ClientInfo->hKL = pKL->hkl;
750 }
751 else if (bSetForProcess)
752 {
754 }
755 else
756 {
757 if (IS_IMM_MODE())
758 IntImmActivateLayout(pti, pKL);
759 else
761
762 ClientInfo->CodePage = pKL->CodePage;
763 ClientInfo->hKL = pKL->hkl;
764 }
765
766 if (gptiForeground && (gptiForeground->ppi == pti->ppi))
767 {
768 /* Send shell message */
769 co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)pKL->hkl);
770 }
771
772 if (pti->MessageQueue)
773 {
774 /* Determine the target window */
775 pTargetWnd = pti->MessageQueue->spwndFocus;
776 if (!pTargetWnd)
777 {
778 pTargetWnd = pti->MessageQueue->spwndActive;
779 if (!pTargetWnd)
780 pTargetWnd = pWnd;
781 }
782
783 /* Send WM_INPUTLANGCHANGE message */
784 if (pTargetWnd)
785 {
786 UserRefObjectCo(pTargetWnd, &Ref2);
787 hTargetWnd = UserHMGetHandle(pTargetWnd);
788 co_IntSendMessage(hTargetWnd, WM_INPUTLANGCHANGE, pKL->iBaseCharset, (LPARAM)pKL->hkl);
789 UserDerefObjectCo(pTargetWnd);
790 }
791 }
792
793 /* Send WM_IME_SYSTEM:IMS_SENDNOTIFICATION message if necessary */
794 if (pti && !(pti->TIF_flags & TIF_CSRSSTHREAD))
795 {
796 if (IS_IME_HKL(pKL->hkl) || IS_CICERO_MODE())
797 {
798 pImeWnd = pti->spwndDefaultIme;
799 if (pImeWnd)
800 {
801 UserRefObjectCo(pImeWnd, &Ref2);
802 hImeWnd = UserHMGetHandle(pImeWnd);
803 co_IntSendMessage(hImeWnd, WM_IME_SYSTEM, IMS_SENDNOTIFICATION, bSetForProcess);
804 UserDerefObjectCo(pImeWnd);
805 }
806 }
807 }
808
809 if (pOldKL)
810 UserDerefObjectCo(pOldKL);
811
813 return hOldKL;
814}
815
816/* Win: xxxActivateKeyboardLayout */
820 _In_ HKL hKL,
822 _Inout_ PWND pWnd)
823{
824 PKL pKL;
826
827 pKL = IntHKLtoPKL(pti, hKL);
828 if (!pKL)
829 {
830 ERR("Invalid HKL %p!\n", hKL);
831 return NULL;
832 }
833
834 if (uFlags & KLF_REORDER)
835 IntReorderKeyboardLayouts(pWinSta, pKL);
836
837 return co_UserActivateKeyboardLayout(pKL, uFlags, pWnd);
838}
839
840// Win: xxxInternalUnloadKeyboardLayout
841static BOOL APIENTRY
844 _Inout_ PKL pKL,
846{
847 PKL pNextKL;
848 USER_REFERENCE_ENTRY Ref1, Ref2;
850
851 if (pKL == gspklBaseLayout && !(dwFlags & 0x80000000))
852 return FALSE;
853
854 UserRefObjectCo(pKL, &Ref1); /* Add reference */
855
856 /* Regard as unloaded */
858 pKL->dwKL_Flags |= KLF_UNLOAD;
859
860 if (!(dwFlags & 0x80000000) && pti->KeyboardLayout == pKL)
861 {
862 pNextKL = IntHKLtoPKL(pti, (HKL)(ULONG_PTR)HKL_NEXT);
863 if (pNextKL)
864 {
865 UserRefObjectCo(pNextKL, &Ref2); /* Add reference */
867 UserDerefObjectCo(pNextKL); /* Release reference */
868 }
869 }
870
871 if (gspklBaseLayout == pKL && pKL != pKL->pklNext)
872 {
873 /* Set next layout as default (FIXME: Use UserAssignmentLock?) */
875 }
876
877 UserDerefObjectCo(pKL); /* Release reference */
878
879 if (pti->pDeskInfo->fsHooks)
880 {
881 co_IntShellHookNotify(HSHELL_LANGUAGE, 0, 0);
883 }
884
885 return TRUE;
886}
887
888// Win: xxxUnloadKeyboardLayout
889static BOOL APIENTRY
891{
892 PKL pKL = IntHKLtoPKL(gptiCurrent, hKL);
893 if (!pKL)
894 {
895 ERR("Invalid HKL %p!\n", hKL);
896 return FALSE;
897 }
898 return co_IntUnloadKeyboardLayoutEx(pWinSta, pKL, 0);
899}
900
902{
903 PIMEINFOEX piiex;
904
905 if (!IS_IME_HKL(hKL) && !IS_CICERO_MODE())
906 return NULL;
907
909 if (!piiex)
910 return NULL;
911
912 if (!co_ClientImmLoadLayout(hKL, piiex))
913 {
915 return NULL;
916 }
917
918 return piiex;
919}
920
923 IN OUT PWINSTATION_OBJECT pWinSta,
924 IN HANDLE hSafeFile,
925 IN HKL hOldKL,
926 IN PUNICODE_STRING puszSafeKLID,
927 IN HKL hNewKL,
928 IN UINT Flags)
929{
930 PKL pOldKL, pNewKL;
931
932 UNREFERENCED_PARAMETER(hSafeFile);
933
934 if (hNewKL == NULL || (pWinSta->Flags & WSS_NOIO))
935 return NULL;
936
937 /* If hOldKL is specified, unload it and load new layput as default */
938 if (hOldKL && hOldKL != hNewKL)
939 {
940 pOldKL = UserHklToKbl(hOldKL);
941 if (pOldKL)
942 UserUnloadKbl(pOldKL);
943 }
944
945 /* FIXME: It seems KLF_RESET is only supported for WINLOGON */
946
947 /* Let's see if layout was already loaded. */
948 pNewKL = UserHklToKbl(hNewKL);
949 if (!pNewKL)
950 {
951 /* It wasn't, so load it. */
952 pNewKL = co_UserLoadKbdLayout(puszSafeKLID, hNewKL);
953 if (!pNewKL)
954 return NULL;
955
956 if (gspklBaseLayout)
957 {
958 /* Find last not unloaded layout */
959 PKL pLastKL = gspklBaseLayout->pklPrev;
960 while (pLastKL != gspklBaseLayout && (pLastKL->dwKL_Flags & KLF_UNLOAD))
961 pLastKL = pLastKL->pklPrev;
962
963 /* Add new layout to the list */
964 pNewKL->pklNext = pLastKL->pklNext;
965 pNewKL->pklPrev = pLastKL;
966 pNewKL->pklNext->pklPrev = pNewKL;
967 pNewKL->pklPrev->pklNext = pNewKL;
968 }
969 else
970 {
971 /* This is the first layout */
972 pNewKL->pklNext = pNewKL;
973 pNewKL->pklPrev = pNewKL;
974 gspklBaseLayout = pNewKL;
975 }
976
977 pNewKL->piiex = co_UserImmLoadLayout(hNewKL);
978 }
979
980 /* If this layout was prepared to unload, undo it */
981 pNewKL->dwKL_Flags &= ~KLF_UNLOAD;
982
983 /* Reorder if necessary */
984 if (Flags & KLF_REORDER)
985 IntReorderKeyboardLayouts(pWinSta, pNewKL);
986
987 /* Activate this layout in current thread */
988 if (Flags & KLF_ACTIVATE)
990
991 /* Send shell message */
992 if (!(Flags & KLF_NOTELLSHELL))
993 co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)hNewKL);
994
995 /* FIXME: KLF_REPLACELANG */
996
997 return hNewKL;
998}
999
1001{
1004
1006 return NULL;
1007
1009 (PVOID*)&FileObject, NULL);
1010 if (!NT_SUCCESS(Status))
1011 {
1012 ERR("0x%08X\n", Status);
1013 return NULL;
1014 }
1015
1016 /* FIXME: Is the file in the system directory? */
1017
1018 if (FileObject)
1020
1021 return hFile;
1022}
1023
1024/* EXPORTS *******************************************************************/
1025
1026/*
1027 * UserGetKeyboardLayout
1028 *
1029 * Returns hkl of given thread keyboard layout
1030 */
1034{
1035 PTHREADINFO pti;
1036 PLIST_ENTRY ListEntry;
1037 PKL pKl;
1038
1040
1041 if (!dwThreadId)
1042 {
1043 pKl = pti->KeyboardLayout;
1044 return pKl ? pKl->hkl : NULL;
1045 }
1046
1047 ListEntry = pti->rpdesk->PtiList.Flink;
1048
1049 //
1050 // Search the Desktop Thread list for related Desktop active Threads.
1051 //
1052 while(ListEntry != &pti->rpdesk->PtiList)
1053 {
1054 pti = CONTAINING_RECORD(ListEntry, THREADINFO, PtiLink);
1055
1056 if (PsGetThreadId(pti->pEThread) == UlongToHandle(dwThreadId))
1057 {
1058 pKl = pti->KeyboardLayout;
1059 return pKl ? pKl->hkl : NULL;
1060 }
1061
1062 ListEntry = ListEntry->Flink;
1063 }
1064
1065 return NULL;
1066}
1067
1068/*
1069 * NtUserGetKeyboardLayoutList
1070 *
1071 * Returns list of loaded keyboard layouts in system
1072 */
1073UINT
1076 ULONG nBuff,
1077 HKL *pHklBuff)
1078{
1079 UINT ret = 0;
1080 PWINSTATION_OBJECT pWinSta;
1081
1082 if (!pHklBuff)
1083 nBuff = 0;
1084
1086
1087 if (nBuff > MAXULONG / sizeof(HKL))
1088 {
1090 goto Quit;
1091 }
1092
1093 _SEH2_TRY
1094 {
1095 ProbeForWrite(pHklBuff, nBuff * sizeof(HKL), 1);
1096 }
1098 {
1100 goto Quit;
1101 }
1102 _SEH2_END;
1103
1105
1106 _SEH2_TRY
1107 {
1108 ret = IntGetKeyboardLayoutList(pWinSta, nBuff, pHklBuff);
1109 }
1111 {
1113 goto Quit;
1114 }
1115 _SEH2_END;
1116
1117Quit:
1118 UserLeave();
1119 return ret;
1120}
1121
1122/*
1123 * NtUserGetKeyboardLayoutName
1124 *
1125 * Returns KLID of current thread keyboard layout
1126 */
1127BOOL
1130 _Inout_ PUNICODE_STRING pustrName)
1131{
1132 BOOL bRet = FALSE;
1133 PKL pKl;
1134 PTHREADINFO pti;
1135 UNICODE_STRING ustrNameSafe;
1137
1139
1141 pKl = pti->KeyboardLayout;
1142
1143 if (!pKl)
1144 goto cleanup;
1145
1146 _SEH2_TRY
1147 {
1148 ProbeForWriteUnicodeString(pustrName);
1149 ustrNameSafe = *pustrName;
1150
1151 ProbeForWrite(ustrNameSafe.Buffer, ustrNameSafe.MaximumLength, 1);
1152
1153 if (IS_IME_HKL(pKl->hkl))
1154 {
1155 Status = RtlIntegerToUnicodeString((ULONG)(ULONG_PTR)pKl->hkl, 16, &ustrNameSafe);
1156 }
1157 else
1158 {
1159 if (ustrNameSafe.MaximumLength < KL_NAMELENGTH * sizeof(WCHAR))
1160 {
1162 goto cleanup;
1163 }
1164
1165 /* FIXME: Do not use awchKF */
1166 ustrNameSafe.Length = 0;
1167 Status = RtlAppendUnicodeToString(&ustrNameSafe, pKl->spkf->awchKF);
1168 }
1169
1170 if (NT_SUCCESS(Status))
1171 {
1172 *pustrName = ustrNameSafe;
1173 bRet = TRUE;
1174 }
1175 }
1177 {
1179 }
1180 _SEH2_END;
1181
1182cleanup:
1183 UserLeave();
1184 return bRet;
1185}
1186
1187/*
1188 * NtUserLoadKeyboardLayoutEx
1189 *
1190 * Loads keyboard layout with given locale id
1191 *
1192 * NOTE: We adopt a different design from Microsoft's one due to security reason.
1193 * We don't use the 3rd parameter of NtUserLoadKeyboardLayoutEx.
1194 * See https://bugtraq.securityfocus.com/detail/50056B96.6040306
1195 */
1196HKL
1197NTAPI
1199 IN HANDLE hFile,
1200 IN DWORD offTable,
1201 IN PVOID pTables,
1202 IN HKL hOldKL,
1203 IN PUNICODE_STRING puszKLID,
1204 IN DWORD dwNewKL,
1205 IN UINT Flags)
1206{
1207 HKL hRetKL;
1209 UNICODE_STRING uszSafeKLID;
1210 PWINSTATION_OBJECT pWinSta;
1211 HANDLE hSafeFile;
1212
1213 UNREFERENCED_PARAMETER(offTable);
1214 UNREFERENCED_PARAMETER(pTables);
1215
1218 KLF_RESET|KLF_SHIFTLOCK))
1219 {
1220 ERR("Invalid flags: %x\n", Flags);
1222 return NULL;
1223 }
1224
1225 RtlInitEmptyUnicodeString(&uszSafeKLID, Buffer, sizeof(Buffer));
1226 _SEH2_TRY
1227 {
1228 ProbeForRead(puszKLID, sizeof(*puszKLID), 1);
1229 ProbeForRead(puszKLID->Buffer, sizeof(puszKLID->Length), 1);
1230 RtlCopyUnicodeString(&uszSafeKLID, puszKLID);
1231 }
1233 {
1235 _SEH2_YIELD(return NULL);
1236 }
1237 _SEH2_END;
1238
1240
1241 hSafeFile = (hFile ? IntVerifyKeyboardFileHandle(hFile) : NULL);
1243 hRetKL = co_IntLoadKeyboardLayoutEx(pWinSta,
1244 hSafeFile,
1245 hOldKL,
1246 &uszSafeKLID,
1247 (HKL)(DWORD_PTR)dwNewKL,
1248 Flags);
1249 if (hSafeFile)
1250 ZwClose(hSafeFile);
1251
1252 UserLeave();
1253 return hRetKL;
1254}
1255
1256/*
1257 * NtUserActivateKeyboardLayout
1258 *
1259 * Activates specified layout for thread or process
1260 */
1261HKL
1262NTAPI
1264 HKL hKL,
1265 ULONG Flags)
1266{
1267 PWINSTATION_OBJECT pWinSta;
1268 HKL hOldKL;
1269
1271
1272 /* FIXME */
1273
1275 hOldKL = co_IntActivateKeyboardLayout(pWinSta, hKL, Flags, NULL);
1276 UserLeave();
1277
1278 return hOldKL;
1279}
1280
1281/*
1282 * NtUserUnloadKeyboardLayout
1283 *
1284 * Unloads keyboard layout with specified hkl value
1285 */
1286BOOL
1289 HKL hKl)
1290{
1291 BOOL ret;
1292 PWINSTATION_OBJECT pWinSta;
1293
1295
1297 ret = IntUnloadKeyboardLayout(pWinSta, hKl);
1298
1299 UserLeave();
1300 return ret;
1301}
1302
1303/* EOF */
#define VOID
Definition: acefi.h:82
LONG NTSTATUS
Definition: precomp.h:26
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:103
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:32
#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 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:805
#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_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
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 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:251
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:235
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:242
#define L(x)
Definition: ntvdm.h:50
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:40
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:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
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:256
PPROCESSINFO ppi
Definition: win32.h:88
struct _DESKTOPINFO * pDeskInfo
Definition: win32.h:93
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
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#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 WM_IME_SYSTEM
Definition: undocuser.h:60
int ret
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
#define IntDereferenceThreadInfo(pti)
Definition: win32.h:171
#define IntReferenceThreadInfo(pti)
Definition: win32.h:166
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:1692
PTHREADINFO gptiForeground
Definition: focus.c:15
#define KLF_UNLOAD
Definition: input.h:51
DWORD gLCIDSentToShell
Definition: kbdlayout.c:26
UINT APIENTRY NtUserGetKeyboardLayoutList(ULONG nBuff, HKL *pHklBuff)
Definition: kbdlayout.c:1075
static BOOL APIENTRY co_IntUnloadKeyboardLayoutEx(_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PKL pKL, _In_ DWORD dwFlags)
Definition: kbdlayout.c:842
static UINT APIENTRY IntGetKeyboardLayoutList(_Inout_ PWINSTATION_OBJECT pWinSta, _In_ ULONG nBuff, _Out_ HKL *pHklBuff)
Definition: kbdlayout.c:98
HKL NTAPI NtUserActivateKeyboardLayout(HKL hKL, ULONG Flags)
Definition: kbdlayout.c:1263
static BOOL UserLoadKbdDll(WCHAR *pwszLayoutPath, HANDLE *phModule, PKBDTABLES *pKbdTables)
Definition: kbdlayout.c:250
static PKL co_UserActivateKbl(PTHREADINFO pti, PKL pKl, UINT Flags)
Definition: kbdlayout.c:604
VOID FASTCALL IntReorderKeyboardLayouts(_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PKL pNewKL)
Definition: kbdlayout.c:561
HKL APIENTRY co_IntActivateKeyboardLayout(_Inout_ PWINSTATION_OBJECT pWinSta, _In_ HKL hKL, _In_ ULONG uFlags, _Inout_ PWND pWnd)
Definition: kbdlayout.c:818
VOID APIENTRY IntImmActivateLayout(_Inout_ PTHREADINFO pti, _Inout_ PKL pKL)
Definition: kbdlayout.c:634
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:890
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:541
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:37
static PKL co_UserLoadKbdLayout(PUNICODE_STRING pustrKLID, HKL hKL)
Definition: kbdlayout.c:377
BOOL UserUnloadKbl(PKL pKl)
Definition: kbdlayout.c:473
PKBDFILE gpkfList
Definition: kbdlayout.c:23
PVOID(* PFN_KBDLAYERDESCRIPTOR)(VOID)
Definition: kbdlayout.c:28
PIMEINFOEX FASTCALL co_UserImmLoadLayout(_In_ HKL hKL)
Definition: kbdlayout.c:901
static VOID UnloadKbdFile(_In_ PKBDFILE pkf)
Definition: kbdlayout.c:446
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:922
BOOL APIENTRY NtUserUnloadKeyboardLayout(HKL hKl)
Definition: kbdlayout.c:1288
BOOL APIENTRY NtUserGetKeyboardLayoutName(_Inout_ PUNICODE_STRING pustrName)
Definition: kbdlayout.c:1129
HKL FASTCALL UserGetKeyboardLayout(DWORD dwThreadId)
Definition: kbdlayout.c:1032
static VOID co_IntSetKeyboardLayoutForProcess(PPROCESSINFO ppi, PKL pKL)
Definition: kbdlayout.c:670
PKL W32kGetDefaultKeyLayout(VOID)
Definition: kbdlayout.c:514
HANDLE FASTCALL IntVerifyKeyboardFileHandle(HANDLE hFile)
Definition: kbdlayout.c:1000
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:1198
BOOL NTAPI UserSetDefaultInputLang(HKL hKl)
Definition: kbdlayout.c:586
static PKBDFILE UserLoadKbdFile(PUNICODE_STRING pwszKLID)
Definition: kbdlayout.c:298
HKL APIENTRY co_UserActivateKeyboardLayout(_Inout_ PKL pKL, _In_ ULONG uFlags, _Inout_ PWND pWnd)
Definition: kbdlayout.c:705
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1445
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
UINT_PTR WPARAM
Definition: windef.h:207
#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 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:3310
__wchar_t WCHAR
Definition: xmlstorage.h:180