ReactOS 0.4.16-dev-109-gf4cb10f
kbdlayout.c File Reference
#include <win32k.h>
#include <immdev.h>
Include dependency graph for kbdlayout.c:

Go to the source code of this file.

Macros

#define CP_ACP   0
 

Typedefs

typedef PVOID(* PFN_KBDLAYERDESCRIPTOR) (VOID)
 

Functions

 DBG_DEFAULT_CHANNEL (UserKbdLayout)
 
PKL FASTCALL IntHKLtoPKL (_Inout_ PTHREADINFO pti, _In_ HKL hKL)
 
static UINT APIENTRY IntGetKeyboardLayoutList (_Inout_ PWINSTATION_OBJECT pWinSta, _In_ ULONG nBuff, _Out_ HKL *pHklBuff)
 
static BOOL UserLoadKbdDll (WCHAR *pwszLayoutPath, HANDLE *phModule, PKBDTABLES *pKbdTables)
 
static PKBDFILE UserLoadKbdFile (PUNICODE_STRING pwszKLID)
 
static PKL co_UserLoadKbdLayout (PUNICODE_STRING pustrKLID, HKL hKL)
 
static VOID UnloadKbdFile (_In_ PKBDFILE pkf)
 
BOOL UserUnloadKbl (PKL pKl)
 
PKL W32kGetDefaultKeyLayout (VOID)
 
PKL NTAPI UserHklToKbl (HKL hKl)
 
VOID FASTCALL IntReorderKeyboardLayouts (_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PKL pNewKL)
 
BOOL NTAPI UserSetDefaultInputLang (HKL hKl)
 
VOID APIENTRY IntImmActivateLayout (_Inout_ PTHREADINFO pti, _Inout_ PKL pKL)
 
static VOID co_IntSetKeyboardLayoutForProcess (PPROCESSINFO ppi, PKL pKL)
 
HKL APIENTRY co_UserActivateKeyboardLayout (_Inout_ PKL pKL, _In_ ULONG uFlags, _In_opt_ PWND pWnd)
 
HKL APIENTRY co_IntActivateKeyboardLayout (_Inout_ PWINSTATION_OBJECT pWinSta, _In_ HKL hKL, _In_ ULONG uFlags, _In_opt_ PWND pWnd)
 
static BOOL APIENTRY co_IntUnloadKeyboardLayoutEx (_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PKL pKL, _In_ DWORD dwFlags)
 
static BOOL APIENTRY IntUnloadKeyboardLayout (_Inout_ PWINSTATION_OBJECT pWinSta, _In_ HKL hKL)
 
PIMEINFOEX FASTCALL co_UserImmLoadLayout (_In_ HKL hKL)
 Invokes imm32!ImmLoadLayout and returns PIMEINFOEX.
 
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)
 
HANDLE FASTCALL IntVerifyKeyboardFileHandle (HANDLE hFile)
 
HKL FASTCALL UserGetKeyboardLayout (DWORD dwThreadId)
 
UINT APIENTRY NtUserGetKeyboardLayoutList (ULONG nBuff, HKL *pHklBuff)
 
BOOL APIENTRY NtUserGetKeyboardLayoutName (_Inout_ PUNICODE_STRING pustrName)
 
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)
 
HKL NTAPI NtUserActivateKeyboardLayout (HKL hKL, ULONG Flags)
 
BOOL APIENTRY NtUserUnloadKeyboardLayout (HKL hKl)
 

Variables

PKL gspklBaseLayout = NULL
 
PKBDFILE gpkfList = NULL
 
DWORD gSystemFS = 0
 
UINT gSystemCPCharSet = 0
 
HKL ghKLSentToShell = NULL
 

Macro Definition Documentation

◆ CP_ACP

#define CP_ACP   0

Definition at line 18 of file kbdlayout.c.

Typedef Documentation

◆ PFN_KBDLAYERDESCRIPTOR

typedef PVOID(* PFN_KBDLAYERDESCRIPTOR) (VOID)

Definition at line 28 of file kbdlayout.c.

Function Documentation

◆ co_IntActivateKeyboardLayout()

HKL APIENTRY co_IntActivateKeyboardLayout ( _Inout_ PWINSTATION_OBJECT  pWinSta,
_In_ HKL  hKL,
_In_ ULONG  uFlags,
_In_opt_ PWND  pWnd 
)

Definition at line 782 of file kbdlayout.c.

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}
#define ERR(fmt,...)
Definition: precomp.h:57
#define NULL
Definition: types.h:112
UINT uFlags
Definition: api.c:59
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
Definition: input.h:27
VOID FASTCALL IntReorderKeyboardLayouts(_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PKL pNewKL)
Definition: kbdlayout.c:558
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
#define KLF_REORDER
Definition: winuser.h:114

Referenced by NtUserActivateKeyboardLayout().

◆ co_IntLoadKeyboardLayoutEx()

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 at line 885 of file kbdlayout.c.

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}
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
DWORD dwKL_Flags
Definition: input.h:31
PIMEINFOEX piiex
Definition: input.h:38
struct tagKL * pklNext
Definition: input.h:29
struct tagKL * pklPrev
Definition: input.h:30
#define KL_UNLOAD
Definition: undocuser.h:179
VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam)
Definition: desktop.c:1709
PKL gspklBaseLayout
Definition: kbdlayout.c:22
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:539
static PKL co_UserLoadKbdLayout(PUNICODE_STRING pustrKLID, HKL hKL)
Definition: kbdlayout.c:375
BOOL UserUnloadKbl(PKL pKl)
Definition: kbdlayout.c:471
PIMEINFOEX FASTCALL co_UserImmLoadLayout(_In_ HKL hKL)
Invokes imm32!ImmLoadLayout and returns PIMEINFOEX.
Definition: kbdlayout.c:864
#define WSS_NOIO
Definition: winsta.h:9
LONG_PTR LPARAM
Definition: windef.h:208
#define KLF_ACTIVATE
Definition: winuser.h:111
#define KLF_NOTELLSHELL
Definition: winuser.h:116
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by NtUserLoadKeyboardLayoutEx().

◆ co_IntSetKeyboardLayoutForProcess()

static VOID co_IntSetKeyboardLayoutForProcess ( PPROCESSINFO  ppi,
PKL  pKL 
)
static

Definition at line 632 of file kbdlayout.c.

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}
unsigned int BOOL
Definition: ntddk_ex.h:94
#define TIF_INCLEANUP
Definition: ntuser.h:263
#define IS_IMM_MODE()
Definition: ntuser.h:1209
USHORT CodePage
Definition: ntuser.h:340
HKL hKL
Definition: ntuser.h:339
PTHREADINFO ptiList
Definition: win32.h:256
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
USHORT CodePage
Definition: input.h:36
HKL hkl
Definition: input.h:32
#define IntDereferenceThreadInfo(pti)
Definition: win32.h:171
#define IntReferenceThreadInfo(pti)
Definition: win32.h:166
VOID APIENTRY IntImmActivateLayout(_Inout_ PTHREADINFO pti, _Inout_ PKL pKL)
Definition: kbdlayout.c:596
PVOID FASTCALL UserAssignmentLock(PVOID *ppvObj, PVOID pvNew)
Definition: object.c:839

Referenced by co_UserActivateKeyboardLayout().

◆ co_IntUnloadKeyboardLayoutEx()

static BOOL APIENTRY co_IntUnloadKeyboardLayoutEx ( _Inout_ PWINSTATION_OBJECT  pWinSta,
_Inout_ PKL  pKL,
_In_ DWORD  dwFlags 
)
static

Definition at line 805 of file kbdlayout.c.

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}
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ISITHOOKED(HookId)
Definition: hook.h:6
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:40
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:27
Definition: object.h:4
#define UKL_NOACTIVATENEXT
Definition: undocuser.h:182
HKL ghKLSentToShell
Definition: kbdlayout.c:26
BOOL FASTCALL UserMarkObjectDestroy(PVOID Object)
Definition: object.c:621
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define WH_SHELL
Definition: winuser.h:40
#define HKL_NEXT
Definition: winuser.h:109

Referenced by IntUnloadKeyboardLayout().

◆ co_UserActivateKeyboardLayout()

HKL APIENTRY co_UserActivateKeyboardLayout ( _Inout_ PKL  pKL,
_In_ ULONG  uFlags,
_In_opt_ PWND  pWnd 
)

Definition at line 667 of file kbdlayout.c.

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}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define IS_IME_HKL(hKL)
Definition: imm32_undoc.h:20
#define IMS_SENDNOTIFICATION
Definition: immdev.h:113
#define TIF_CSRSSTHREAD
Definition: ntuser.h:266
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
struct _THREADINFO * GetW32ThreadInfo(VOID)
Definition: misc.c:807
#define IS_16BIT_MODE()
Definition: ntuser.h:1211
#define IS_CICERO_MODE()
Definition: ntuser.h:1210
CLIENT_DATA ClientInfo
UINT_PTR HKL
Definition: msctf.idl:143
#define UNICODE_NULL
PPROCESSINFO ppi
Definition: win32.h:88
struct _WND * spwndDefaultIme
Definition: win32.h:131
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:89
Definition: ntuser.h:694
#define WM_IME_SYSTEM
Definition: undocuser.h:60
PTHREADINFO gptiForeground
Definition: focus.c:15
static VOID co_IntSetKeyboardLayoutForProcess(PPROCESSINFO ppi, PKL pKL)
Definition: kbdlayout.c:632
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1495
#define KLF_SETFORPROCESS
Definition: winuser.h:117

Referenced by co_IntActivateKeyboardLayout(), co_IntLoadKeyboardLayoutEx(), and co_IntUnloadKeyboardLayoutEx().

◆ co_UserImmLoadLayout()

PIMEINFOEX FASTCALL co_UserImmLoadLayout ( _In_ HKL  hKL)

Invokes imm32!ImmLoadLayout and returns PIMEINFOEX.

Definition at line 864 of file kbdlayout.c.

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}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
BOOL APIENTRY co_ClientImmLoadLayout(_In_ HKL hKL, _Inout_ PIMEINFOEX pImeInfoEx)
Definition: callback.c:1278
#define USERTAG_IME
Definition: tags.h:240

Referenced by co_IntLoadKeyboardLayoutEx().

◆ co_UserLoadKbdLayout()

static PKL co_UserLoadKbdLayout ( PUNICODE_STRING  pustrKLID,
HKL  hKL 
)
static

Definition at line 375 of file kbdlayout.c.

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}
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define cs
Definition: i386-dis.c:442
@ TYPE_KBDLAYOUT
Definition: ntuser.h:53
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
unsigned short USHORT
Definition: pedump.c:61
DWORD LCID
Definition: nls.h:13
#define TRACE(s)
Definition: solgame.cpp:4
DWORD dwFontSigs
Definition: input.h:34
PKBDFILE spkf
Definition: input.h:33
UINT iBaseCharset
Definition: input.h:35
uint32_t * PULONG
Definition: typedefs.h:59
BOOL APIENTRY co_IntGetCharsetInfo(LCID Locale, PCHARSETINFO pCs)
Definition: callback.c:1040
DWORD gSystemFS
Definition: kbdlayout.c:24
UINT gSystemCPCharSet
Definition: kbdlayout.c:25
#define CP_ACP
Definition: kbdlayout.c:18
static PKBDFILE UserLoadKbdFile(PUNICODE_STRING pwszKLID)
Definition: kbdlayout.c:296
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 ANSI_CHARSET
Definition: wingdi.h:383
#define FS_LATIN1
Definition: wingdi.h:560

Referenced by co_IntLoadKeyboardLayoutEx().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserKbdLayout  )

◆ IntGetKeyboardLayoutList()

static UINT APIENTRY IntGetKeyboardLayoutList ( _Inout_ PWINSTATION_OBJECT  pWinSta,
_In_ ULONG  nBuff,
_Out_ HKL pHklBuff 
)
static

Definition at line 96 of file kbdlayout.c.

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}
unsigned int UINT
Definition: ndis.h:50
int ret

Referenced by NtUserGetKeyboardLayoutList().

◆ IntHKLtoPKL()

PKL FASTCALL IntHKLtoPKL ( _Inout_ PTHREADINFO  pti,
_In_ HKL  hKL 
)

Definition at line 36 of file kbdlayout.c.

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}
#define LOWORD(l)
Definition: pedump.c:82
#define HIWORD(l)
Definition: typedefs.h:247
#define HKL_PREV
Definition: winuser.h:110

Referenced by co_IntActivateKeyboardLayout(), co_IntUnloadKeyboardLayoutEx(), and IntUnloadKeyboardLayout().

◆ IntImmActivateLayout()

VOID APIENTRY IntImmActivateLayout ( _Inout_ PTHREADINFO  pti,
_Inout_ PKL  pKL 
)

Definition at line 596 of file kbdlayout.c.

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}
#define IMS_ACTIVATELAYOUT
Definition: immdev.h:110
#define CI_IMMACTIVATE
Definition: ntuser.h:306

Referenced by co_IntSetKeyboardLayoutForProcess(), and co_UserActivateKeyboardLayout().

◆ IntReorderKeyboardLayouts()

VOID FASTCALL IntReorderKeyboardLayouts ( _Inout_ PWINSTATION_OBJECT  pWinSta,
_Inout_ PKL  pNewKL 
)

Definition at line 558 of file kbdlayout.c.

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}

Referenced by co_IntActivateKeyboardLayout(), co_IntLoadKeyboardLayoutEx(), and UserSetDefaultInputLang().

◆ IntUnloadKeyboardLayout()

static BOOL APIENTRY IntUnloadKeyboardLayout ( _Inout_ PWINSTATION_OBJECT  pWinSta,
_In_ HKL  hKL 
)
static

Definition at line 852 of file kbdlayout.c.

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}
static BOOL APIENTRY co_IntUnloadKeyboardLayoutEx(_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PKL pKL, _In_ DWORD dwFlags)
Definition: kbdlayout.c:805

Referenced by NtUserUnloadKeyboardLayout().

◆ IntVerifyKeyboardFileHandle()

HANDLE FASTCALL IntVerifyKeyboardFileHandle ( HANDLE  hFile)

Definition at line 963 of file kbdlayout.c.

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}
LONG NTSTATUS
Definition: precomp.h:26
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
Status
Definition: gdiplustypes.h:25
_In_ HANDLE hFile
Definition: mswsock.h:90
#define UserMode
Definition: asm.h:35
#define FILE_READ_DATA
Definition: nt_native.h:628
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
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by NtUserLoadKeyboardLayoutEx().

◆ NtUserActivateKeyboardLayout()

HKL NTAPI NtUserActivateKeyboardLayout ( HKL  hKL,
ULONG  Flags 
)

Definition at line 1226 of file kbdlayout.c.

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}
PWINSTATION_OBJECT FASTCALL IntGetProcessWindowStation(HWINSTA *phWinSta OPTIONAL)
Definition: winsta.c:400
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:258
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:249
HKL APIENTRY co_IntActivateKeyboardLayout(_Inout_ PWINSTATION_OBJECT pWinSta, _In_ HKL hKL, _In_ ULONG uFlags, _In_opt_ PWND pWnd)
Definition: kbdlayout.c:782

Referenced by User32DefWindowProc().

◆ NtUserGetKeyboardLayoutList()

UINT APIENTRY NtUserGetKeyboardLayoutList ( ULONG  nBuff,
HKL pHklBuff 
)

Definition at line 1038 of file kbdlayout.c.

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}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:242
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define MAXULONG
Definition: typedefs.h:251
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
static UINT APIENTRY IntGetKeyboardLayoutList(_Inout_ PWINSTATION_OBJECT pWinSta, _In_ ULONG nBuff, _Out_ HKL *pHklBuff)
Definition: kbdlayout.c:96

Referenced by CliImmInitializeHotKeys().

◆ NtUserGetKeyboardLayoutName()

BOOL APIENTRY NtUserGetKeyboardLayoutName ( _Inout_ PUNICODE_STRING  pustrName)

Definition at line 1092 of file kbdlayout.c.

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}
#define HandleToUlong(h)
Definition: basetsd.h:79
static void cleanup(void)
Definition: main.c:1335
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString(ULONG Value, ULONG Base, PUNICODE_STRING String)
#define ProbeForWriteUnicodeString(Ptr)
Definition: probe.h:48
USHORT MaximumLength
Definition: env_spec_w32.h:370
WCHAR awchKF[20]
Definition: input.h:19
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22
#define KL_NAMELENGTH
Definition: winuser.h:122
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by GetKeyboardLayoutNameW(), and START_TEST().

◆ NtUserLoadKeyboardLayoutEx()

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 at line 1161 of file kbdlayout.c.

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}
Definition: bufpool.h:45
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
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
HANDLE FASTCALL IntVerifyKeyboardFileHandle(HANDLE hFile)
Definition: kbdlayout.c:963
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
#define KLF_REPLACELANG
Definition: winuser.h:115
#define KLF_SUBSTITUTE_OK
Definition: winuser.h:112
#define KLF_UNLOADPREVIOUS
Definition: winuser.h:113

Referenced by IntLoadKeyboardLayout().

◆ NtUserUnloadKeyboardLayout()

BOOL APIENTRY NtUserUnloadKeyboardLayout ( HKL  hKl)

Definition at line 1251 of file kbdlayout.c.

1253{
1254 BOOL ret;
1255 PWINSTATION_OBJECT pWinSta;
1256
1258
1260 ret = IntUnloadKeyboardLayout(pWinSta, hKl);
1261
1262 UserLeave();
1263 return ret;
1264}
static BOOL APIENTRY IntUnloadKeyboardLayout(_Inout_ PWINSTATION_OBJECT pWinSta, _In_ HKL hKL)
Definition: kbdlayout.c:852

Referenced by UnloadKeyboardLayout().

◆ UnloadKbdFile()

static VOID UnloadKbdFile ( _In_ PKBDFILE  pkf)
static

Definition at line 444 of file kbdlayout.c.

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}
@ TYPE_KBDFILE
Definition: ntuser.h:54
struct tagKBDFILE * pkfNext
Definition: input.h:18
PKBDFILE gpkfList
Definition: kbdlayout.c:23
ENGAPI VOID APIENTRY EngUnloadImage(_In_ HANDLE hModule)
Definition: ldevobj.c:913
#define NT_ASSERT
Definition: rtlfuncs.h:3324

Referenced by UserUnloadKbl().

◆ UserGetKeyboardLayout()

HKL FASTCALL UserGetKeyboardLayout ( DWORD  dwThreadId)

Definition at line 995 of file kbdlayout.c.

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}
DWORD dwThreadId
Definition: fdebug.c:31
HANDLE NTAPI PsGetThreadId(IN PETHREAD Thread)
Definition: thread.c:705
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _DESKTOP * rpdesk
Definition: win32.h:92
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by IntGetActiveKeyboardLayout(), and NtUserCallOneParam().

◆ UserHklToKbl()

PKL NTAPI UserHklToKbl ( HKL  hKl)

Definition at line 539 of file kbdlayout.c.

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}

Referenced by co_IntLoadKeyboardLayoutEx(), NtUserMapVirtualKeyEx(), NtUserSetThreadLayoutHandles(), NtUserToUnicodeEx(), NtUserVkKeyScanEx(), and UserSetDefaultInputLang().

◆ UserLoadKbdDll()

static BOOL UserLoadKbdDll ( WCHAR pwszLayoutPath,
HANDLE phModule,
PKBDTABLES pKbdTables 
)
static

Definition at line 248 of file kbdlayout.c.

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}
PVOID(* PFN_KBDLAYERDESCRIPTOR)(VOID)
Definition: kbdlayout.c:28
ENGAPI PVOID APIENTRY EngFindImageProcAddress(_In_ HANDLE hModule, _In_ LPSTR lpProcName)
Definition: ldevobj.c:927
ENGAPI HANDLE APIENTRY EngLoadImage(_In_ LPWSTR pwszDriver)
Definition: ldevobj.c:904

Referenced by UserLoadKbdFile().

◆ UserLoadKbdFile()

static PKBDFILE UserLoadKbdFile ( PUNICODE_STRING  pwszKLID)
static

Definition at line 296 of file kbdlayout.c.

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}
#define MAX_PATH
Definition: compat.h:34
#define swprintf
Definition: precomp.h:40
FxAutoRegKey hKey
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define REG_SZ
Definition: layer.c:22
NTSTRSAFEAPI RtlStringCbCatW(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:636
#define L(x)
Definition: ntvdm.h:50
HANDLE hBase
Definition: input.h:20
struct _KBDTABLES * pKbdTbl
Definition: input.h:21
uint32_t ULONG
Definition: typedefs.h:59
static BOOL UserLoadKbdDll(WCHAR *pwszLayoutPath, HANDLE *phModule, PKBDTABLES *pKbdTables)
Definition: kbdlayout.c:248
#define RegOpenKey
Definition: winreg.h:519
#define RegQueryValue
Definition: winreg.h:523

Referenced by co_UserLoadKbdLayout().

◆ UserSetDefaultInputLang()

BOOL NTAPI UserSetDefaultInputLang ( HKL  hKl)

Definition at line 583 of file kbdlayout.c.

584{
585 PKL pKl;
586
587 pKl = UserHklToKbl(hKl);
588 if (!pKl)
589 return FALSE;
590
592 return TRUE;
593}

Referenced by SpiGetSet().

◆ UserUnloadKbl()

BOOL UserUnloadKbl ( PKL  pKl)

Definition at line 471 of file kbdlayout.c.

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}
DWORD cLockObj
Definition: ntuser.h:182
HEAD head
Definition: input.h:28
static VOID UnloadKbdFile(_In_ PKBDFILE pkf)
Definition: kbdlayout.c:444

Referenced by co_IntLoadKeyboardLayoutEx().

◆ W32kGetDefaultKeyLayout()

PKL W32kGetDefaultKeyLayout ( VOID  )

Definition at line 512 of file kbdlayout.c.

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}

Referenced by InitThreadCallback(), IntTranslateKbdMessage(), UserProcessKeyboardInput(), and UserSendKeyboardInput().

Variable Documentation

◆ ghKLSentToShell

HKL ghKLSentToShell = NULL

Definition at line 26 of file kbdlayout.c.

Referenced by co_IntUnloadKeyboardLayoutEx(), and co_UserActivateKeyboardLayout().

◆ gpkfList

PKBDFILE gpkfList = NULL

Definition at line 23 of file kbdlayout.c.

Referenced by UnloadKbdFile(), and UserLoadKbdFile().

◆ gspklBaseLayout

◆ gSystemCPCharSet

UINT gSystemCPCharSet = 0

Definition at line 25 of file kbdlayout.c.

Referenced by co_UserLoadKbdLayout().

◆ gSystemFS

DWORD gSystemFS = 0

Definition at line 24 of file kbdlayout.c.

Referenced by co_UserLoadKbdLayout(), IntImmProcessKey(), and IntLanguageToggle().