ReactOS 0.4.15-dev-7788-g1ad9096
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)
 
static PKL co_UserActivateKbl (PTHREADINFO pti, PKL pKl, UINT Flags)
 
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, _Inout_ PWND pWnd)
 
HKL APIENTRY co_IntActivateKeyboardLayout (_Inout_ PWINSTATION_OBJECT pWinSta, _In_ HKL hKL, _In_ ULONG uFlags, _Inout_ 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)
 
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
 
DWORD gLCIDSentToShell = 0
 

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,
_Inout_ PWND  pWnd 
)

Definition at line 818 of file kbdlayout.c.

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}
#define ERR(fmt,...)
Definition: debug.h:110
#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:561
PKL FASTCALL IntHKLtoPKL(_Inout_ PTHREADINFO pti, _In_ HKL hKL)
Definition: kbdlayout.c:37
HKL APIENTRY co_UserActivateKeyboardLayout(_Inout_ PKL pKL, _In_ ULONG uFlags, _Inout_ PWND pWnd)
Definition: kbdlayout.c:705
#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 922 of file kbdlayout.c.

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}
#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
VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam)
Definition: desktop.c:1692
#define KLF_UNLOAD
Definition: input.h:51
static PKL co_UserActivateKbl(PTHREADINFO pti, PKL pKl, UINT Flags)
Definition: kbdlayout.c:604
PKL gspklBaseLayout
Definition: kbdlayout.c:22
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:541
static PKL co_UserLoadKbdLayout(PUNICODE_STRING pustrKLID, HKL hKL)
Definition: kbdlayout.c:377
BOOL UserUnloadKbl(PKL pKl)
Definition: kbdlayout.c:473
PIMEINFOEX FASTCALL co_UserImmLoadLayout(_In_ HKL hKL)
Definition: kbdlayout.c:901
#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 670 of file kbdlayout.c.

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}
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:634
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 842 of file kbdlayout.c.

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}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT_PTR HKL
Definition: msctf.idl:143
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
struct _DESKTOPINFO * pDeskInfo
Definition: win32.h:93
Definition: object.h:4
uint32_t ULONG_PTR
Definition: typedefs.h:65
DWORD gLCIDSentToShell
Definition: kbdlayout.c:26
BOOL FASTCALL UserMarkObjectDestroy(PVOID Object)
Definition: object.c:621
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define HKL_NEXT
Definition: winuser.h:109

Referenced by IntUnloadKeyboardLayout().

◆ co_UserActivateKbl()

static PKL co_UserActivateKbl ( PTHREADINFO  pti,
PKL  pKl,
UINT  Flags 
)
static

Definition at line 604 of file kbdlayout.c.

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}
#define FIXME(fmt,...)
Definition: debug.h:111
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:89
Definition: ntuser.h:694
UINT iBaseCharset
Definition: input.h:35
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1445
UINT_PTR WPARAM
Definition: windef.h:207
#define KLF_SETFORPROCESS
Definition: winuser.h:117

Referenced by co_IntLoadKeyboardLayoutEx().

◆ co_UserActivateKeyboardLayout()

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

Definition at line 705 of file kbdlayout.c.

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}
#define IS_IME_HKL(hKL)
Definition: imm32_undoc.h:20
#define IMS_SENDNOTIFICATION
Definition: immdev.h:113
#define TIF_CSRSSTHREAD
Definition: ntuser.h:266
struct _THREADINFO * GetW32ThreadInfo(VOID)
Definition: misc.c:805
#define IS_CICERO_MODE()
Definition: ntuser.h:1210
CLIENT_DATA ClientInfo
PPROCESSINFO ppi
Definition: win32.h:88
struct _WND * spwndDefaultIme
Definition: win32.h:131
#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:670

Referenced by co_IntActivateKeyboardLayout(), and co_IntUnloadKeyboardLayoutEx().

◆ co_UserImmLoadLayout()

PIMEINFOEX FASTCALL co_UserImmLoadLayout ( _In_ HKL  hKL)

Definition at line 901 of file kbdlayout.c.

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}
#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 377 of file kbdlayout.c.

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}
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#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
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:298
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 98 of file kbdlayout.c.

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}
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 37 of file kbdlayout.c.

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}
#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 634 of file kbdlayout.c.

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}
#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 561 of file kbdlayout.c.

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}

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

◆ IntUnloadKeyboardLayout()

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

Definition at line 890 of file kbdlayout.c.

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

Referenced by NtUserUnloadKeyboardLayout().

◆ IntVerifyKeyboardFileHandle()

HANDLE FASTCALL IntVerifyKeyboardFileHandle ( HANDLE  hFile)

Definition at line 1000 of file kbdlayout.c.

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}
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 1263 of file kbdlayout.c.

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

Referenced by User32DefWindowProc().

◆ NtUserGetKeyboardLayoutList()

UINT APIENTRY NtUserGetKeyboardLayoutList ( ULONG  nBuff,
HKL pHklBuff 
)

Definition at line 1075 of file kbdlayout.c.

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}
#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:235
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#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:98

Referenced by CliImmInitializeHotKeys().

◆ NtUserGetKeyboardLayoutName()

BOOL APIENTRY NtUserGetKeyboardLayoutName ( _Inout_ PUNICODE_STRING  pustrName)

Definition at line 1129 of file kbdlayout.c.

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}
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
uint32_t ULONG
Definition: typedefs.h:59
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 1198 of file kbdlayout.c.

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}
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:162
uint32_t DWORD_PTR
Definition: typedefs.h:65
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
HANDLE FASTCALL IntVerifyKeyboardFileHandle(HANDLE hFile)
Definition: kbdlayout.c:1000
#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 1288 of file kbdlayout.c.

1290{
1291 BOOL ret;
1292 PWINSTATION_OBJECT pWinSta;
1293
1295
1297 ret = IntUnloadKeyboardLayout(pWinSta, hKl);
1298
1299 UserLeave();
1300 return ret;
1301}
static BOOL APIENTRY IntUnloadKeyboardLayout(_Inout_ PWINSTATION_OBJECT pWinSta, _In_ HKL hKL)
Definition: kbdlayout.c:890

Referenced by UnloadKeyboardLayout().

◆ UnloadKbdFile()

static VOID UnloadKbdFile ( _In_ PKBDFILE  pkf)
static

Definition at line 446 of file kbdlayout.c.

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}
@ 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:3310

Referenced by UserUnloadKbl().

◆ UserGetKeyboardLayout()

HKL FASTCALL UserGetKeyboardLayout ( DWORD  dwThreadId)

Definition at line 1032 of file kbdlayout.c.

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}
#define UlongToHandle(ul)
Definition: basetsd.h:97
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 541 of file kbdlayout.c.

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}

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

◆ UserLoadKbdDll()

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

Definition at line 250 of file kbdlayout.c.

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}
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 298 of file kbdlayout.c.

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}
#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
static BOOL UserLoadKbdDll(WCHAR *pwszLayoutPath, HANDLE *phModule, PKBDTABLES *pKbdTables)
Definition: kbdlayout.c:250
#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 586 of file kbdlayout.c.

587{
588 PKL pKl;
589
590 pKl = UserHklToKbl(hKl);
591 if (!pKl)
592 return FALSE;
593
595 return TRUE;
596}

Referenced by SpiGetSet().

◆ UserUnloadKbl()

BOOL UserUnloadKbl ( PKL  pKl)

Definition at line 473 of file kbdlayout.c.

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

Referenced by co_IntLoadKeyboardLayoutEx().

◆ W32kGetDefaultKeyLayout()

PKL W32kGetDefaultKeyLayout ( VOID  )

Definition at line 514 of file kbdlayout.c.

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}

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

Variable Documentation

◆ gLCIDSentToShell

DWORD gLCIDSentToShell = 0

Definition at line 26 of file kbdlayout.c.

Referenced by co_IntUnloadKeyboardLayoutEx().

◆ 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().