ReactOS 0.4.15-dev-5884-gab5aff5
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 <ddk/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);
464 UserDeleteObject(pkf->head.h, TYPE_KBDFILE);
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 kyboard 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
654 UserAssignmentLock((PVOID*)&(pti->KeyboardLayout), pKL);
655 pti->pClientInfo->hKL = pKL->hkl;
656}
657
659{
660 PTHREADINFO ptiNode, ptiNext;
661 PCLIENTINFO pClientInfo;
662 BOOL bImmMode = IS_IMM_MODE();
663
664 for (ptiNode = ppi->ptiList; ptiNode; ptiNode = ptiNext)
665 {
666 IntReferenceThreadInfo(ptiNode);
667 ptiNext = ptiNode->ptiSibling;
668
669 /* Skip this thread if its keyboard layout is already the correct one, or if it's dying */
670 if (ptiNode->KeyboardLayout == pKL || (ptiNode->TIF_flags & TIF_INCLEANUP))
671 {
673 continue;
674 }
675
676 if (bImmMode)
677 {
678 IntImmActivateLayout(ptiNode, pKL);
679 }
680 else
681 {
682 UserAssignmentLock((PVOID*)&ptiNode->KeyboardLayout, pKL);
683 pClientInfo = ptiNode->pClientInfo;
684 pClientInfo->CodePage = pKL->CodePage;
685 pClientInfo->hKL = pKL->hkl;
686 }
687
689 }
690}
691
694 _Inout_ PKL pKL,
696 _Inout_ PWND pWnd)
697{
698 HKL hOldKL = NULL;
699 PKL pOldKL = NULL;
701 PWND pTargetWnd, pImeWnd;
702 HWND hTargetWnd, hImeWnd;
703 USER_REFERENCE_ENTRY Ref1, Ref2;
705 BOOL bSetForProcess = !!(uFlags & KLF_SETFORPROCESS);
706
708 ClientInfo = pti->pClientInfo;
709
710 if (pti->KeyboardLayout)
711 {
712 pOldKL = pti->KeyboardLayout;
713 if (pOldKL)
714 hOldKL = pOldKL->hkl;
715 }
716
717 if (uFlags & KLF_RESET)
718 {
719 FIXME("KLF_RESET\n");
720 }
721
722 if (!bSetForProcess && pKL == pti->KeyboardLayout)
723 {
725 return hOldKL;
726 }
727
728 pKL->wchDiacritic = 0;
729
730 if (pOldKL)
731 UserRefObjectCo(pOldKL, &Ref1);
732
733 if (pti->TIF_flags & TIF_CSRSSTHREAD)
734 {
736 ClientInfo->CodePage = pKL->CodePage;
737 ClientInfo->hKL = pKL->hkl;
738 }
739 else if (bSetForProcess)
740 {
742 }
743 else
744 {
745 if (IS_IMM_MODE())
746 IntImmActivateLayout(pti, pKL);
747 else
749
750 ClientInfo->CodePage = pKL->CodePage;
751 ClientInfo->hKL = pKL->hkl;
752 }
753
754 if (gptiForeground && (gptiForeground->ppi == pti->ppi))
755 {
756 /* Send shell message */
757 co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)pKL->hkl);
758 }
759
760 if (pti->MessageQueue)
761 {
762 /* Determine the target window */
763 pTargetWnd = pti->MessageQueue->spwndFocus;
764 if (!pTargetWnd)
765 {
766 pTargetWnd = pti->MessageQueue->spwndActive;
767 if (!pTargetWnd)
768 pTargetWnd = pWnd;
769 }
770
771 /* Send WM_INPUTLANGCHANGE message */
772 if (pTargetWnd)
773 {
774 UserRefObjectCo(pTargetWnd, &Ref2);
775 hTargetWnd = UserHMGetHandle(pTargetWnd);
776 co_IntSendMessage(hTargetWnd, WM_INPUTLANGCHANGE, pKL->iBaseCharset, (LPARAM)pKL->hkl);
777 UserDerefObjectCo(pTargetWnd);
778 }
779 }
780
781 /* Send WM_IME_SYSTEM:IMS_SENDNOTIFICATION message if necessary */
782 if (pti && !(pti->TIF_flags & TIF_CSRSSTHREAD))
783 {
784 if (IS_IME_HKL(pKL->hkl) || IS_CICERO_MODE())
785 {
786 pImeWnd = pti->spwndDefaultIme;
787 if (pImeWnd)
788 {
789 UserRefObjectCo(pImeWnd, &Ref2);
790 hImeWnd = UserHMGetHandle(pImeWnd);
791 co_IntSendMessage(hImeWnd, WM_IME_SYSTEM, IMS_SENDNOTIFICATION, bSetForProcess);
792 UserDerefObjectCo(pImeWnd);
793 }
794 }
795 }
796
797 if (pOldKL)
798 UserDerefObjectCo(pOldKL);
799
801 return hOldKL;
802}
803
804/* Win: xxxActivateKeyboardLayout */
808 _In_ HKL hKL,
810 _Inout_ PWND pWnd)
811{
812 PKL pKL;
814
815 pKL = IntHKLtoPKL(pti, hKL);
816 if (!pKL)
817 {
818 ERR("Invalid HKL %p!\n", hKL);
819 return NULL;
820 }
821
822 if (uFlags & KLF_REORDER)
823 IntReorderKeyboardLayouts(pWinSta, pKL);
824
825 return co_UserActivateKeyboardLayout(pKL, uFlags, pWnd);
826}
827
828// Win: xxxInternalUnloadKeyboardLayout
829static BOOL APIENTRY
832 _Inout_ PKL pKL,
834{
835 PKL pNextKL;
836 USER_REFERENCE_ENTRY Ref1, Ref2;
838
839 if (pKL == gspklBaseLayout && !(dwFlags & 0x80000000))
840 return FALSE;
841
842 UserRefObjectCo(pKL, &Ref1); /* Add reference */
843
844 /* Regard as unloaded */
846 pKL->dwKL_Flags |= KLF_UNLOAD;
847
848 if (!(dwFlags & 0x80000000) && pti->KeyboardLayout == pKL)
849 {
850 pNextKL = IntHKLtoPKL(pti, (HKL)(ULONG_PTR)HKL_NEXT);
851 if (pNextKL)
852 {
853 UserRefObjectCo(pNextKL, &Ref2); /* Add reference */
855 UserDerefObjectCo(pNextKL); /* Release reference */
856 }
857 }
858
859 if (gspklBaseLayout == pKL && pKL != pKL->pklNext)
860 {
861 /* Set next layout as default (FIXME: Use UserAssignmentLock?) */
863 }
864
865 UserDerefObjectCo(pKL); /* Release reference */
866
867 if (pti->pDeskInfo->fsHooks)
868 {
869 co_IntShellHookNotify(HSHELL_LANGUAGE, 0, 0);
871 }
872
873 return TRUE;
874}
875
876// Win: xxxUnloadKeyboardLayout
877static BOOL APIENTRY
879{
880 PKL pKL = IntHKLtoPKL(gptiCurrent, hKL);
881 if (!pKL)
882 {
883 ERR("Invalid HKL %p!\n", hKL);
884 return FALSE;
885 }
886 return co_IntUnloadKeyboardLayoutEx(pWinSta, pKL, 0);
887}
888
890{
891 PIMEINFOEX piiex;
892
893 if (!IS_IME_HKL(hKL) && !IS_CICERO_MODE())
894 return NULL;
895
897 if (!piiex)
898 return NULL;
899
900 if (!co_ClientImmLoadLayout(hKL, piiex))
901 {
903 return NULL;
904 }
905
906 return piiex;
907}
908
911 IN OUT PWINSTATION_OBJECT pWinSta,
912 IN HANDLE hSafeFile,
913 IN HKL hOldKL,
914 IN PUNICODE_STRING puszSafeKLID,
915 IN HKL hNewKL,
916 IN UINT Flags)
917{
918 PKL pOldKL, pNewKL;
919
920 UNREFERENCED_PARAMETER(hSafeFile);
921
922 if (hNewKL == NULL || (pWinSta->Flags & WSS_NOIO))
923 return NULL;
924
925 /* If hOldKL is specified, unload it and load new layput as default */
926 if (hOldKL && hOldKL != hNewKL)
927 {
928 pOldKL = UserHklToKbl(hOldKL);
929 if (pOldKL)
930 UserUnloadKbl(pOldKL);
931 }
932
933 /* FIXME: It seems KLF_RESET is only supported for WINLOGON */
934
935 /* Let's see if layout was already loaded. */
936 pNewKL = UserHklToKbl(hNewKL);
937 if (!pNewKL)
938 {
939 /* It wasn't, so load it. */
940 pNewKL = co_UserLoadKbdLayout(puszSafeKLID, hNewKL);
941 if (!pNewKL)
942 return NULL;
943
944 if (gspklBaseLayout)
945 {
946 /* Find last not unloaded layout */
947 PKL pLastKL = gspklBaseLayout->pklPrev;
948 while (pLastKL != gspklBaseLayout && (pLastKL->dwKL_Flags & KLF_UNLOAD))
949 pLastKL = pLastKL->pklPrev;
950
951 /* Add new layout to the list */
952 pNewKL->pklNext = pLastKL->pklNext;
953 pNewKL->pklPrev = pLastKL;
954 pNewKL->pklNext->pklPrev = pNewKL;
955 pNewKL->pklPrev->pklNext = pNewKL;
956 }
957 else
958 {
959 /* This is the first layout */
960 pNewKL->pklNext = pNewKL;
961 pNewKL->pklPrev = pNewKL;
962 gspklBaseLayout = pNewKL;
963 }
964
965 pNewKL->piiex = co_UserImmLoadLayout(hNewKL);
966 }
967
968 /* If this layout was prepared to unload, undo it */
969 pNewKL->dwKL_Flags &= ~KLF_UNLOAD;
970
971 /* Reorder if necessary */
972 if (Flags & KLF_REORDER)
973 IntReorderKeyboardLayouts(pWinSta, pNewKL);
974
975 /* Activate this layout in current thread */
976 if (Flags & KLF_ACTIVATE)
978
979 /* Send shell message */
980 if (!(Flags & KLF_NOTELLSHELL))
981 co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)hNewKL);
982
983 /* FIXME: KLF_REPLACELANG */
984
985 return hNewKL;
986}
987
989{
992
994 return NULL;
995
997 (PVOID*)&FileObject, NULL);
998 if (!NT_SUCCESS(Status))
999 {
1000 ERR("0x%08X\n", Status);
1001 return NULL;
1002 }
1003
1004 /* FIXME: Is the file in the system directory? */
1005
1006 if (FileObject)
1008
1009 return hFile;
1010}
1011
1012/* EXPORTS *******************************************************************/
1013
1014/*
1015 * UserGetKeyboardLayout
1016 *
1017 * Returns hkl of given thread keyboard layout
1018 */
1022{
1023 PTHREADINFO pti;
1024 PLIST_ENTRY ListEntry;
1025 PKL pKl;
1026
1028
1029 if (!dwThreadId)
1030 {
1031 pKl = pti->KeyboardLayout;
1032 return pKl ? pKl->hkl : NULL;
1033 }
1034
1035 ListEntry = pti->rpdesk->PtiList.Flink;
1036
1037 //
1038 // Search the Desktop Thread list for related Desktop active Threads.
1039 //
1040 while(ListEntry != &pti->rpdesk->PtiList)
1041 {
1042 pti = CONTAINING_RECORD(ListEntry, THREADINFO, PtiLink);
1043
1044 if (PsGetThreadId(pti->pEThread) == UlongToHandle(dwThreadId))
1045 {
1046 pKl = pti->KeyboardLayout;
1047 return pKl ? pKl->hkl : NULL;
1048 }
1049
1050 ListEntry = ListEntry->Flink;
1051 }
1052
1053 return NULL;
1054}
1055
1056/*
1057 * NtUserGetKeyboardLayoutList
1058 *
1059 * Returns list of loaded keyboard layouts in system
1060 */
1061UINT
1064 ULONG nBuff,
1065 HKL *pHklBuff)
1066{
1067 UINT ret = 0;
1068 PWINSTATION_OBJECT pWinSta;
1069
1070 if (!pHklBuff)
1071 nBuff = 0;
1072
1074
1075 if (nBuff > MAXULONG / sizeof(HKL))
1076 {
1078 goto Quit;
1079 }
1080
1081 _SEH2_TRY
1082 {
1083 ProbeForWrite(pHklBuff, nBuff * sizeof(HKL), 1);
1084 }
1086 {
1088 goto Quit;
1089 }
1090 _SEH2_END;
1091
1093
1094 _SEH2_TRY
1095 {
1096 ret = IntGetKeyboardLayoutList(pWinSta, nBuff, pHklBuff);
1097 }
1099 {
1101 goto Quit;
1102 }
1103 _SEH2_END;
1104
1105Quit:
1106 UserLeave();
1107 return ret;
1108}
1109
1110/*
1111 * NtUserGetKeyboardLayoutName
1112 *
1113 * Returns KLID of current thread keyboard layout
1114 */
1115BOOL
1118 _Inout_ PUNICODE_STRING pustrName)
1119{
1120 BOOL bRet = FALSE;
1121 PKL pKl;
1122 PTHREADINFO pti;
1123 UNICODE_STRING ustrNameSafe;
1125
1127
1129 pKl = pti->KeyboardLayout;
1130
1131 if (!pKl)
1132 goto cleanup;
1133
1134 _SEH2_TRY
1135 {
1136 ProbeForWriteUnicodeString(pustrName);
1137 ustrNameSafe = *pustrName;
1138
1139 ProbeForWrite(ustrNameSafe.Buffer, ustrNameSafe.MaximumLength, 1);
1140
1141 if (IS_IME_HKL(pKl->hkl))
1142 {
1143 Status = RtlIntegerToUnicodeString((ULONG)(ULONG_PTR)pKl->hkl, 16, &ustrNameSafe);
1144 }
1145 else
1146 {
1147 if (ustrNameSafe.MaximumLength < KL_NAMELENGTH * sizeof(WCHAR))
1148 {
1150 goto cleanup;
1151 }
1152
1153 /* FIXME: Do not use awchKF */
1154 ustrNameSafe.Length = 0;
1155 Status = RtlAppendUnicodeToString(&ustrNameSafe, pKl->spkf->awchKF);
1156 }
1157
1158 if (NT_SUCCESS(Status))
1159 {
1160 *pustrName = ustrNameSafe;
1161 bRet = TRUE;
1162 }
1163 }
1165 {
1167 }
1168 _SEH2_END;
1169
1170cleanup:
1171 UserLeave();
1172 return bRet;
1173}
1174
1175/*
1176 * NtUserLoadKeyboardLayoutEx
1177 *
1178 * Loads keyboard layout with given locale id
1179 *
1180 * NOTE: We adopt a different design from Microsoft's one due to security reason.
1181 * We don't use the 3rd parameter of NtUserLoadKeyboardLayoutEx.
1182 * See https://bugtraq.securityfocus.com/detail/50056B96.6040306
1183 */
1184HKL
1185NTAPI
1187 IN HANDLE hFile,
1188 IN DWORD offTable,
1189 IN PVOID pTables,
1190 IN HKL hOldKL,
1191 IN PUNICODE_STRING puszKLID,
1192 IN DWORD dwNewKL,
1193 IN UINT Flags)
1194{
1195 HKL hRetKL;
1197 UNICODE_STRING uszSafeKLID;
1198 PWINSTATION_OBJECT pWinSta;
1199 HANDLE hSafeFile;
1200
1201 UNREFERENCED_PARAMETER(offTable);
1202 UNREFERENCED_PARAMETER(pTables);
1203
1206 KLF_RESET|KLF_SHIFTLOCK))
1207 {
1208 ERR("Invalid flags: %x\n", Flags);
1210 return NULL;
1211 }
1212
1213 RtlInitEmptyUnicodeString(&uszSafeKLID, Buffer, sizeof(Buffer));
1214 _SEH2_TRY
1215 {
1216 ProbeForRead(puszKLID, sizeof(*puszKLID), 1);
1217 ProbeForRead(puszKLID->Buffer, sizeof(puszKLID->Length), 1);
1218 RtlCopyUnicodeString(&uszSafeKLID, puszKLID);
1219 }
1221 {
1223 _SEH2_YIELD(return NULL);
1224 }
1225 _SEH2_END;
1226
1228
1229 hSafeFile = (hFile ? IntVerifyKeyboardFileHandle(hFile) : NULL);
1231 hRetKL = co_IntLoadKeyboardLayoutEx(pWinSta,
1232 hSafeFile,
1233 hOldKL,
1234 &uszSafeKLID,
1235 (HKL)(DWORD_PTR)dwNewKL,
1236 Flags);
1237 if (hSafeFile)
1238 ZwClose(hSafeFile);
1239
1240 UserLeave();
1241 return hRetKL;
1242}
1243
1244/*
1245 * NtUserActivateKeyboardLayout
1246 *
1247 * Activates specified layout for thread or process
1248 */
1249HKL
1250NTAPI
1252 HKL hKL,
1253 ULONG Flags)
1254{
1255 PWINSTATION_OBJECT pWinSta;
1256 HKL hOldKL;
1257
1259
1260 /* FIXME */
1261
1263 hOldKL = co_IntActivateKeyboardLayout(pWinSta, hKL, Flags, NULL);
1264 UserLeave();
1265
1266 return hOldKL;
1267}
1268
1269/*
1270 * NtUserUnloadKeyboardLayout
1271 *
1272 * Unloads keyboard layout with specified hkl value
1273 */
1274BOOL
1277 HKL hKl)
1278{
1279 BOOL ret;
1280 PWINSTATION_OBJECT pWinSta;
1281
1283
1285 ret = IntUnloadKeyboardLayout(pWinSta, hKl);
1286
1287 UserLeave();
1288 return ret;
1289}
1290
1291/* 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 IS_IME_HKL(hKL)
Definition: input.h:88
#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:443
#define IMS_ACTIVATELAYOUT
Definition: immdev.h:40
#define IMS_SENDNOTIFICATION
Definition: immdev.h:43
#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:265
#define TIF_INCLEANUP
Definition: ntuser.h:262
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
struct _THREADINFO * GetW32ThreadInfo(VOID)
Definition: misc.c:801
#define IS_IMM_MODE()
Definition: ntuser.h:1232
@ TYPE_KBDFILE
Definition: ntuser.h:54
@ TYPE_KBDLAYOUT
Definition: ntuser.h:53
#define IS_CICERO_MODE()
Definition: ntuser.h:1233
CLIENT_DATA ClientInfo
#define REG_SZ
Definition: layer.c:22
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#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:104
_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:254
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:238
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:245
#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:335
HKL hKL
Definition: ntuser.h:334
DWORD cLockObj
Definition: ntuser.h:182
HANDLE h
Definition: ntuser.h:181
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:689
HANDLE hBase
Definition: input.h:20
struct _KBDTABLES * pKbdTbl
Definition: input.h:21
struct tagKBDFILE * pkfNext
Definition: input.h:18
HEAD head
Definition: input.h:17
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(NTSTATUS Status)
Definition: error.c:37
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:1063
static BOOL APIENTRY co_IntUnloadKeyboardLayoutEx(_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PKL pKL, _In_ DWORD dwFlags)
Definition: kbdlayout.c:830
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:1251
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:806
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:878
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:889
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:910
BOOL APIENTRY NtUserUnloadKeyboardLayout(HKL hKl)
Definition: kbdlayout.c:1276
BOOL APIENTRY NtUserGetKeyboardLayoutName(_Inout_ PUNICODE_STRING pustrName)
Definition: kbdlayout.c:1117
HKL FASTCALL UserGetKeyboardLayout(DWORD dwThreadId)
Definition: kbdlayout.c:1020
static VOID co_IntSetKeyboardLayoutForProcess(PPROCESSINFO ppi, PKL pKL)
Definition: kbdlayout.c:658
PKL W32kGetDefaultKeyLayout(VOID)
Definition: kbdlayout.c:514
HANDLE FASTCALL IntVerifyKeyboardFileHandle(HANDLE hFile)
Definition: kbdlayout.c:988
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:1186
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:693
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1446
BOOL FASTCALL UserMarkObjectDestroy(PVOID Object)
Definition: object.c:621
PVOID FASTCALL UserAssignmentLock(PVOID *ppvObj, PVOID pvNew)
Definition: object.c:840
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:925
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:28
ENGAPI VOID APIENTRY EngUnloadImage(_In_ HANDLE hModule)
Definition: ldevobj.c:911
ENGAPI HANDLE APIENTRY EngLoadImage(_In_ LPWSTR pwszDriver)
Definition: ldevobj.c:902
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