ReactOS  0.4.15-dev-345-g5d88487
kbdlayout.c File Reference
#include <win32k.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)
 
static BOOL UserLoadKbdDll (WCHAR *pwszLayoutPath, HANDLE *phModule, PKBDTABLES *pKbdTables)
 
static PKBDFILE UserLoadKbdFile (PUNICODE_STRING pwszKLID)
 
static PKL UserLoadKbdLayout (PUNICODE_STRING pustrKLID, HKL hKL)
 
static VOID UnloadKbdFile (_In_ PKBDFILE pkf)
 
BOOL UserUnloadKbl (PKL pKl)
 
PKL W32kGetDefaultKeyLayout (VOID)
 
PKL NTAPI UserHklToKbl (HKL hKl)
 
BOOL NTAPI UserSetDefaultInputLang (HKL hKl)
 
static PKL co_UserActivateKbl (PTHREADINFO pti, PKL pKl, UINT Flags)
 
HKL FASTCALL UserGetKeyboardLayout (DWORD dwThreadId)
 
UINT APIENTRY NtUserGetKeyboardLayoutList (ULONG nBuff, HKL *pHklBuff)
 
BOOL APIENTRY NtUserGetKeyboardLayoutName (LPWSTR pwszName)
 
HKL APIENTRY NtUserLoadKeyboardLayoutEx (IN HANDLE Handle, IN DWORD offTable, IN PUNICODE_STRING puszKeyboardName, IN HKL hklUnload, IN PUNICODE_STRING pustrKLID, IN DWORD hkl, IN UINT Flags)
 
HKL APIENTRY NtUserActivateKeyboardLayout (HKL hKl, ULONG Flags)
 
BOOL APIENTRY NtUserUnloadKeyboardLayout (HKL hKl)
 

Variables

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

Macro Definition Documentation

◆ CP_ACP

#define CP_ACP   0

Definition at line 16 of file kbdlayout.c.

Typedef Documentation

◆ PFN_KBDLAYERDESCRIPTOR

typedef PVOID(* PFN_KBDLAYERDESCRIPTOR) (VOID)

Definition at line 25 of file kbdlayout.c.

Function Documentation

◆ co_UserActivateKbl()

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

Definition at line 413 of file kbdlayout.c.

414 {
415  PKL pklPrev;
416  PWND pWnd;
417 
418  pklPrev = pti->KeyboardLayout;
419  if (pklPrev)
420  UserDereferenceObject(pklPrev);
421 
422  pti->KeyboardLayout = pKl;
423  pti->pClientInfo->hKL = pKl->hkl;
424  UserReferenceObject(pKl);
425 
426  if (Flags & KLF_SETFORPROCESS)
427  {
428  // FIXME
429  }
430 
431  if (!(pWnd = pti->MessageQueue->spwndFocus))
432  {
433  pWnd = pti->MessageQueue->spwndActive;
434  }
435 
436  // Send WM_INPUTLANGCHANGE to thread's focus window
437  co_IntSendMessage( pWnd ? UserHMGetHandle(pWnd) : 0,
438  WM_INPUTLANGCHANGE,
439  (WPARAM)pKl->iBaseCharset, // FIXME: How to set it?
440  (LPARAM)pKl->hkl); // hkl
441 
442  return pklPrev;
443 }
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:610
UINT_PTR WPARAM
Definition: windef.h:207
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
Definition: input.h:26
LONG_PTR LPARAM
Definition: windef.h:208
UINT iBaseCharset
Definition: input.h:35
#define UserHMGetHandle(obj)
Definition: ntuser.h:208
HKL hkl
Definition: input.h:32
struct _CLIENTINFO * pClientInfo
Definition: win32.h:93
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1446
struct tagKL * KeyboardLayout
Definition: win32.h:89
Definition: ntuser.h:657
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:88
#define KLF_SETFORPROCESS
Definition: winuser.h:117
VOID FASTCALL UserReferenceObject(PVOID obj)
Definition: object.c:697

Referenced by NtUserActivateKeyboardLayout(), and NtUserLoadKeyboardLayoutEx().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserKbdLayout  )

◆ NtUserActivateKeyboardLayout()

HKL APIENTRY NtUserActivateKeyboardLayout ( HKL  hKl,
ULONG  Flags 
)

Definition at line 705 of file kbdlayout.c.

708 {
709  PKL pKl = NULL;
710  HKL hkl = NULL;
711  PTHREADINFO pti;
712 
714 
716 
717  /* hKl can have special value HKL_NEXT or HKL_PREV */
718  if (hKl == (HKL)HKL_NEXT)
719  {
720  /* Get next keyboard layout starting with current */
721  if (pti->KeyboardLayout)
722  pKl = pti->KeyboardLayout->pklNext;
723  }
724  else if (hKl == (HKL)HKL_PREV)
725  {
726  /* Get previous keyboard layout starting with current */
727  if (pti->KeyboardLayout)
728  pKl = pti->KeyboardLayout->pklPrev;
729  }
730  else
731  pKl = UserHklToKbl(hKl);
732 
733  if (!pKl)
734  {
735  ERR("Invalid HKL %p!\n", hKl);
736  goto cleanup;
737  }
738 
739  hkl = pKl->hkl;
740 
741  /* FIXME: KLF_RESET
742  KLF_SHIFTLOCK */
743 
744  if (Flags & KLF_REORDER)
745  gspklBaseLayout = pKl;
746 
747  if (pKl != pti->KeyboardLayout)
748  {
749  /* Activate layout for current thread */
750  pKl = co_UserActivateKbl(pti, pKl, Flags);
751 
752  /* Send shell message */
753  if (!(Flags & KLF_NOTELLSHELL))
754  co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)hkl);
755  }
756 
757 cleanup:
758  UserLeave();
759  return hkl;
760 }
#define KLF_REORDER
Definition: winuser.h:114
PKL gspklBaseLayout
Definition: kbdlayout.c:20
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
#define KLF_NOTELLSHELL
Definition: winuser.h:116
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
smooth NULL
Definition: ftsmooth.c:416
Definition: input.h:26
LONG_PTR LPARAM
Definition: windef.h:208
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
HKL hkl
Definition: input.h:32
static PKL co_UserActivateKbl(PTHREADINFO pti, PKL pKl, UINT Flags)
Definition: kbdlayout.c:413
UINT_PTR HKL
Definition: msctf.idl:101
struct tagKL * KeyboardLayout
Definition: win32.h:89
#define ERR(fmt,...)
Definition: debug.h:110
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
HKL hkl
Definition: msctf.idl:611
#define HKL_NEXT
Definition: winuser.h:109
#define HKL_PREV
Definition: winuser.h:110
VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam)
Definition: desktop.c:1656
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:370
char * cleanup(char *str)
Definition: wpickclick.c:99

Referenced by User32DefWindowProc().

◆ NtUserGetKeyboardLayoutList()

UINT APIENTRY NtUserGetKeyboardLayoutList ( ULONG  nBuff,
HKL pHklBuff 
)

Definition at line 496 of file kbdlayout.c.

499 {
500  UINT uRet = 0;
501  PKL pKl;
502 
503  if (!pHklBuff)
504  nBuff = 0;
505 
506  UserEnterShared();
507 
508  if (!gspklBaseLayout)
509  {
510  UserLeave();
511  return 0;
512  }
513  pKl = gspklBaseLayout;
514 
515  if (nBuff == 0)
516  {
517  do
518  {
519  uRet++;
520  pKl = pKl->pklNext;
521  } while (pKl != gspklBaseLayout);
522  }
523  else
524  {
525  _SEH2_TRY
526  {
527  ProbeForWrite(pHklBuff, nBuff*sizeof(HKL), 4);
528 
529  while (uRet < nBuff)
530  {
531  pHklBuff[uRet] = pKl->hkl;
532  uRet++;
533  pKl = pKl->pklNext;
534  if (pKl == gspklBaseLayout)
535  break;
536  }
537  }
539  {
541  uRet = 0;
542  }
543  _SEH2_END;
544  }
545 
546  UserLeave();
547  return uRet;
548 }
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:241
PKL gspklBaseLayout
Definition: kbdlayout.c:20
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_SEH2_TRY
Definition: create.c:4250
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
Definition: input.h:26
HKL hkl
Definition: input.h:32
UINT_PTR HKL
Definition: msctf.idl:101
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
struct tagKL * pklNext
Definition: input.h:29
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
_SEH2_END
Definition: create.c:4424
unsigned int UINT
Definition: ndis.h:50
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12

◆ NtUserGetKeyboardLayoutName()

BOOL APIENTRY NtUserGetKeyboardLayoutName ( LPWSTR  pwszName)

Definition at line 557 of file kbdlayout.c.

559 {
560  BOOL bRet = FALSE;
561  PKL pKl;
562  PTHREADINFO pti;
563 
564  UserEnterShared();
565 
567  pKl = pti->KeyboardLayout;
568 
569  if (!pKl)
570  goto cleanup;
571 
572  _SEH2_TRY
573  {
574  ProbeForWrite(pwszName, KL_NAMELENGTH*sizeof(WCHAR), 1);
575  wcscpy(pwszName, pKl->spkf->awchKF);
576  bRet = TRUE;
577  }
579  {
581  }
582  _SEH2_END;
583 
584 cleanup:
585  UserLeave();
586  return bRet;
587 }
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:241
#define TRUE
Definition: types.h:120
#define KL_NAMELENGTH
Definition: winuser.h:122
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_SEH2_TRY
Definition: create.c:4250
unsigned int BOOL
Definition: ntddk_ex.h:94
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
Definition: input.h:26
WCHAR awchKF[20]
Definition: input.h:19
__wchar_t WCHAR
Definition: xmlstorage.h:180
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
struct tagKL * KeyboardLayout
Definition: win32.h:89
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
_SEH2_END
Definition: create.c:4424
PKBDFILE spkf
Definition: input.h:33
char * cleanup(char *str)
Definition: wpickclick.c:99
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12

Referenced by GetKeyboardLayoutNameW().

◆ NtUserLoadKeyboardLayoutEx()

HKL APIENTRY NtUserLoadKeyboardLayoutEx ( IN HANDLE  Handle,
IN DWORD  offTable,
IN PUNICODE_STRING  puszKeyboardName,
IN HKL  hklUnload,
IN PUNICODE_STRING  pustrKLID,
IN DWORD  hkl,
IN UINT  Flags 
)

Definition at line 596 of file kbdlayout.c.

604 {
605  HKL hklRet = NULL;
606  PKL pKl = NULL, pklLast;
607  WCHAR Buffer[9];
608  UNICODE_STRING ustrSafeKLID;
609 
612  KLF_RESET|KLF_SHIFTLOCK))
613  {
614  ERR("Invalid flags: %x\n", Flags);
616  return NULL;
617  }
618 
619  /* FIXME: It seems KLF_RESET is only supported for WINLOGON */
620 
621  RtlInitEmptyUnicodeString(&ustrSafeKLID, Buffer, sizeof(Buffer));
622  _SEH2_TRY
623  {
624  ProbeForRead(pustrKLID, sizeof(*pustrKLID), 1);
625  ProbeForRead(pustrKLID->Buffer, sizeof(pustrKLID->Length), 1);
626  RtlCopyUnicodeString(&ustrSafeKLID, pustrKLID);
627  }
629  {
631  _SEH2_YIELD(return NULL);
632  }
633  _SEH2_END;
634 
636 
637  /* If hklUnload is specified, unload it and load new layput as default */
638  if (hklUnload && (hklUnload != UlongToHandle(hkl)))
639  {
640  pKl = UserHklToKbl(hklUnload);
641  if (pKl)
642  UserUnloadKbl(pKl);
643  }
644 
645  /* Let's see if layout was already loaded. */
647  if (!pKl)
648  {
649  /* It wasn't, so load it. */
650  pKl = UserLoadKbdLayout(&ustrSafeKLID, UlongToHandle(hkl));
651  if (!pKl)
652  goto cleanup;
653 
654  if (gspklBaseLayout)
655  {
656  /* Find last not unloaded layout */
657  pklLast = gspklBaseLayout->pklPrev;
658  while (pklLast != gspklBaseLayout && pklLast->dwKL_Flags & KLF_UNLOAD)
659  pklLast = pklLast->pklPrev;
660 
661  /* Add new layout to the list */
662  pKl->pklNext = pklLast->pklNext;
663  pKl->pklPrev = pklLast;
664  pKl->pklNext->pklPrev = pKl;
665  pKl->pklPrev->pklNext = pKl;
666  }
667  else
668  {
669  /* This is the first layout */
670  pKl->pklNext = pKl;
671  pKl->pklPrev = pKl;
672  gspklBaseLayout = pKl;
673  }
674  }
675 
676  /* If this layout was prepared to unload, undo it */
677  pKl->dwKL_Flags &= ~KLF_UNLOAD;
678 
679  /* Activate this layout in current thread */
680  if (Flags & KLF_ACTIVATE)
682 
683  /* Send shell message */
684  if (!(Flags & KLF_NOTELLSHELL))
685  co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)hkl);
686 
687  /* Return hkl on success */
688  hklRet = UlongToHandle(hkl);
689 
690  /* FIXME: KLF_REPLACELANG
691  KLF_REORDER */
692 
693 cleanup:
694  UserLeave();
695  return hklRet;
696 }
#define KLF_REORDER
Definition: winuser.h:114
struct tagKL * pklPrev
Definition: input.h:30
#define KLF_UNLOAD
Definition: input.h:51
BOOL UserUnloadKbl(PKL pKl)
Definition: kbdlayout.c:306
PKL gspklBaseLayout
Definition: kbdlayout.c:20
#define KLF_ACTIVATE
Definition: winuser.h:111
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
#define KLF_NOTELLSHELL
Definition: winuser.h:116
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
_SEH2_TRY
Definition: create.c:4250
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
Definition: input.h:26
#define KLF_UNLOADPREVIOUS
Definition: winuser.h:113
LONG_PTR LPARAM
Definition: windef.h:208
Definition: bufpool.h:45
#define KLF_SUBSTITUTE_OK
Definition: winuser.h:112
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define UlongToHandle(ul)
Definition: basetsd.h:97
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
DWORD dwKL_Flags
Definition: input.h:31
static PKL co_UserActivateKbl(PTHREADINFO pti, PKL pKl, UINT Flags)
Definition: kbdlayout.c:413
UINT_PTR HKL
Definition: msctf.idl:101
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
struct tagKL * pklNext
Definition: input.h:29
#define KLF_REPLACELANG
Definition: winuser.h:115
#define ERR(fmt,...)
Definition: debug.h:110
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
_SEH2_END
Definition: create.c:4424
HKL hkl
Definition: msctf.idl:611
#define KLF_SETFORPROCESS
Definition: winuser.h:117
VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam)
Definition: desktop.c:1656
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:370
char * cleanup(char *str)
Definition: wpickclick.c:99
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
static PKL UserLoadKbdLayout(PUNICODE_STRING pustrKLID, HKL hKL)
Definition: kbdlayout.c:210

Referenced by LoadKeyboardLayoutW().

◆ NtUserUnloadKeyboardLayout()

BOOL APIENTRY NtUserUnloadKeyboardLayout ( HKL  hKl)

Definition at line 769 of file kbdlayout.c.

771 {
772  PKL pKl;
773  BOOL bRet = FALSE;
774 
776 
777  pKl = UserHklToKbl(hKl);
778  if (pKl)
779  bRet = UserUnloadKbl(pKl);
780  else
781  ERR("Invalid HKL %p!\n", hKl);
782 
783  UserLeave();
784  return bRet;
785 }
BOOL UserUnloadKbl(PKL pKl)
Definition: kbdlayout.c:306
unsigned int BOOL
Definition: ntddk_ex.h:94
Definition: input.h:26
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
#define ERR(fmt,...)
Definition: debug.h:110
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:370

◆ UnloadKbdFile()

static VOID UnloadKbdFile ( _In_ PKBDFILE  pkf)
static

Definition at line 279 of file kbdlayout.c.

280 {
281  PKBDFILE *ppkfLink = &gpkfList;
282  NT_ASSERT(pkf != NULL);
283 
284  /* Find previous object */
285  while (*ppkfLink)
286  {
287  if (*ppkfLink == pkf)
288  break;
289 
290  ppkfLink = &(*ppkfLink)->pkfNext;
291  }
292 
293  if (*ppkfLink == pkf)
294  *ppkfLink = pkf->pkfNext;
295 
296  EngUnloadImage(pkf->hBase);
297  UserDeleteObject(pkf->head.h, TYPE_KBDFILE);
298 }
BOOL FASTCALL UserDeleteObject(HANDLE h, HANDLE_TYPE type)
Definition: object.c:683
PKBDFILE gpkfList
Definition: kbdlayout.c:21
smooth NULL
Definition: ftsmooth.c:416
struct tagKBDFILE * pkfNext
Definition: input.h:18
ENGAPI VOID APIENTRY EngUnloadImage(_In_ HANDLE hModule)
Definition: ldevobj.c:465
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by UserUnloadKbl().

◆ UserGetKeyboardLayout()

HKL FASTCALL UserGetKeyboardLayout ( DWORD  dwThreadId)

Definition at line 453 of file kbdlayout.c.

455 {
456  PTHREADINFO pti;
457  PLIST_ENTRY ListEntry;
458  PKL pKl;
459 
461 
462  if (!dwThreadId)
463  {
464  pKl = pti->KeyboardLayout;
465  return pKl ? pKl->hkl : NULL;
466  }
467 
468  ListEntry = pti->rpdesk->PtiList.Flink;
469 
470  //
471  // Search the Desktop Thread list for related Desktop active Threads.
472  //
473  while(ListEntry != &pti->rpdesk->PtiList)
474  {
475  pti = CONTAINING_RECORD(ListEntry, THREADINFO, PtiLink);
476 
477  if (PsGetThreadId(pti->pEThread) == UlongToHandle(dwThreadId))
478  {
479  pKl = pti->KeyboardLayout;
480  return pKl ? pKl->hkl : NULL;
481  }
482 
483  ListEntry = ListEntry->Flink;
484  }
485 
486  return NULL;
487 }
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
struct _DESKTOP * rpdesk
Definition: win32.h:91
smooth NULL
Definition: ftsmooth.c:416
Definition: input.h:26
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
#define UlongToHandle(ul)
Definition: basetsd.h:97
HKL hkl
Definition: input.h:32
DWORD dwThreadId
Definition: fdebug.c:31
Definition: typedefs.h:118
HANDLE NTAPI PsGetThreadId(IN PETHREAD Thread)
Definition: thread.c:705
struct tagKL * KeyboardLayout
Definition: win32.h:89

Referenced by NtUserCallOneParam().

◆ UserHklToKbl()

PKL NTAPI UserHklToKbl ( HKL  hKl)

Definition at line 370 of file kbdlayout.c.

371 {
372  PKL pKl = gspklBaseLayout;
373 
374  if (!gspklBaseLayout)
375  return NULL;
376 
377  do
378  {
379  if (pKl->hkl == hKl)
380  return pKl;
381 
382  pKl = pKl->pklNext;
383  } while (pKl != gspklBaseLayout);
384 
385  return NULL;
386 }
PKL gspklBaseLayout
Definition: kbdlayout.c:20
smooth NULL
Definition: ftsmooth.c:416
Definition: input.h:26
HKL hkl
Definition: input.h:32
struct tagKL * pklNext
Definition: input.h:29

Referenced by NtUserActivateKeyboardLayout(), NtUserLoadKeyboardLayoutEx(), NtUserMapVirtualKeyEx(), NtUserToUnicodeEx(), NtUserUnloadKeyboardLayout(), NtUserVkKeyScanEx(), and UserSetDefaultInputLang().

◆ UserLoadKbdDll()

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

Definition at line 36 of file kbdlayout.c.

39 {
40  PFN_KBDLAYERDESCRIPTOR pfnKbdLayerDescriptor;
41 
42  /* Load keyboard layout DLL */
43  TRACE("Loading Keyboard DLL %ws\n", pwszLayoutPath);
44  *phModule = EngLoadImage(pwszLayoutPath);
45  if (!(*phModule))
46  {
47  ERR("Failed to load dll %ws\n", pwszLayoutPath);
48  return FALSE;
49  }
50 
51  /* Find KbdLayerDescriptor function and get layout tables */
52  TRACE("Loaded %ws\n", pwszLayoutPath);
53  pfnKbdLayerDescriptor = EngFindImageProcAddress(*phModule, "KbdLayerDescriptor");
54 
55  /* FIXME: Windows reads file instead of executing!
56  It's not safe to kbdlayout DLL in kernel mode! */
57 
58  if (pfnKbdLayerDescriptor)
59  *pKbdTables = pfnKbdLayerDescriptor();
60  else
61  ERR("Error: %ws has no KbdLayerDescriptor()\n", pwszLayoutPath);
62 
63  if (!pfnKbdLayerDescriptor || !*pKbdTables)
64  {
65  ERR("Failed to load the keyboard layout.\n");
66  EngUnloadImage(*phModule);
67  return FALSE;
68  }
69 
70 #if 0 /* Dump keyboard layout */
71  {
72  unsigned i;
73  PVK_TO_BIT pVkToBit = (*pKbdTables)->pCharModifiers->pVkToBit;
74  PVK_TO_WCHAR_TABLE pVkToWchTbl = (*pKbdTables)->pVkToWcharTable;
75  PVSC_VK pVscVk = (*pKbdTables)->pVSCtoVK_E0;
76  DbgPrint("Kbd layout: fLocaleFlags %x bMaxVSCtoVK %x\n", (*pKbdTables)->fLocaleFlags, (*pKbdTables)->bMaxVSCtoVK);
77  DbgPrint("wMaxModBits %x\n", (*pKbdTables)->pCharModifiers->wMaxModBits);
78  while (pVkToBit->Vk)
79  {
80  DbgPrint("VkToBit %x -> %x\n", pVkToBit->Vk, pVkToBit->ModBits);
81  ++pVkToBit;
82  }
83  for (i = 0; i <= (*pKbdTables)->pCharModifiers->wMaxModBits; ++i)
84  DbgPrint("ModNumber %x -> %x\n", i, (*pKbdTables)->pCharModifiers->ModNumber[i]);
85  while (pVkToWchTbl->pVkToWchars)
86  {
87  PVK_TO_WCHARS1 pVkToWch = pVkToWchTbl->pVkToWchars;
88  DbgPrint("pVkToWchTbl nModifications %x cbSize %x\n", pVkToWchTbl->nModifications, pVkToWchTbl->cbSize);
89  while (pVkToWch->VirtualKey)
90  {
91  DbgPrint("pVkToWch VirtualKey %x Attributes %x wc { ", pVkToWch->VirtualKey, pVkToWch->Attributes);
92  for (i = 0; i < pVkToWchTbl->nModifications; ++i)
93  DbgPrint("%x ", pVkToWch->wch[i]);
94  DbgPrint("}\n");
95  pVkToWch = (PVK_TO_WCHARS1)(((PBYTE)pVkToWch) + pVkToWchTbl->cbSize);
96  }
97  ++pVkToWchTbl;
98  }
99  DbgPrint("pusVSCtoVK: { ");
100  for (i = 0; i < (*pKbdTables)->bMaxVSCtoVK; ++i)
101  DbgPrint("%x -> %x, ", i, (*pKbdTables)->pusVSCtoVK[i]);
102  DbgPrint("}\n");
103  DbgPrint("pVSCtoVK_E0: { ");
104  while (pVscVk->Vsc)
105  {
106  DbgPrint("%x -> %x, ", pVscVk->Vsc, pVscVk->Vk);
107  ++pVscVk;
108  }
109  DbgPrint("}\n");
110  pVscVk = (*pKbdTables)->pVSCtoVK_E1;
111  DbgPrint("pVSCtoVK_E1: { ");
112  while (pVscVk->Vsc)
113  {
114  DbgPrint("%x -> %x, ", pVscVk->Vsc, pVscVk->Vk);
115  ++pVscVk;
116  }
117  DbgPrint("}\n");
118  DbgBreakPoint();
119  }
120 #endif
121 
122  return TRUE;
123 }
PVK_TO_WCHARS1 pVkToWchars
Definition: kbd.h:51
#define TRUE
Definition: types.h:120
BYTE ModBits
Definition: kbd.h:23
#define DbgPrint
Definition: loader.c:25
Definition: kbd.h:21
BYTE Vsc
Definition: kbd.h:72
void DbgBreakPoint()
Definition: mach.c:553
USHORT Vk
Definition: kbd.h:73
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
BYTE nModifications
Definition: kbd.h:52
#define TRACE(s)
Definition: solgame.cpp:4
ENGAPI HANDLE APIENTRY EngLoadImage(_In_ LPWSTR pwszDriver)
Definition: ldevobj.c:456
BYTE cbSize
Definition: kbd.h:53
BYTE Vk
Definition: kbd.h:22
Definition: kbd.h:71
#define ERR(fmt,...)
Definition: debug.h:110
ENGAPI PVOID APIENTRY EngFindImageProcAddress(_In_ HANDLE hModule, _In_ LPSTR lpProcName)
Definition: ldevobj.c:497
PVOID(* PFN_KBDLAYERDESCRIPTOR)(VOID)
Definition: kbdlayout.c:25
ENGAPI VOID APIENTRY EngUnloadImage(_In_ HANDLE hModule)
Definition: ldevobj.c:465
BYTE * PBYTE
Definition: pedump.c:66

Referenced by UserLoadKbdFile().

◆ UserLoadKbdFile()

static PKBDFILE UserLoadKbdFile ( PUNICODE_STRING  pwszKLID)
static

Definition at line 131 of file kbdlayout.c.

132 {
133  PKBDFILE pkf, pRet = NULL;
135  ULONG cbSize;
136  HKEY hKey = NULL;
137  WCHAR wszLayoutPath[MAX_PATH] = L"\\SystemRoot\\System32\\";
138  WCHAR wszLayoutRegKey[256] = L"\\REGISTRY\\Machine\\SYSTEM\\CurrentControlSet\\"
139  L"Control\\Keyboard Layouts\\";
140 
141  /* Create keyboard layout file object */
143  if (!pkf)
144  {
145  ERR("Failed to create object!\n");
146  return NULL;
147  }
148 
149  /* Set keyboard layout name */
150  swprintf(pkf->awchKF, L"%wZ", pwszKLID);
151 
152  /* Open layout registry key */
153  RtlStringCbCatW(wszLayoutRegKey, sizeof(wszLayoutRegKey), pkf->awchKF);
154  Status = RegOpenKey(wszLayoutRegKey, &hKey);
155  if (!NT_SUCCESS(Status))
156  {
157  ERR("Failed to open keyboard layouts registry key %ws (%lx)\n", wszLayoutRegKey, Status);
158  goto cleanup;
159  }
160 
161  /* Read filename of layout DLL */
162  cbSize = (ULONG)(sizeof(wszLayoutPath) - wcslen(wszLayoutPath)*sizeof(WCHAR));
163  Status = RegQueryValue(hKey,
164  L"Layout File",
165  REG_SZ,
166  wszLayoutPath + wcslen(wszLayoutPath),
167  &cbSize);
168 
169  if (!NT_SUCCESS(Status))
170  {
171  ERR("Can't get layout filename for %wZ (%lx)\n", pwszKLID, Status);
172  goto cleanup;
173  }
174 
175  /* Load keyboard file now */
176  if (!UserLoadKbdDll(wszLayoutPath, &pkf->hBase, &pkf->pKbdTbl))
177  {
178  ERR("Failed to load %ws dll!\n", wszLayoutPath);
179  goto cleanup;
180  }
181 
182  /* Update next field */
183  pkf->pkfNext = gpkfList;
184  gpkfList = pkf;
185 
186  /* Return keyboard file */
187  pRet = pkf;
188 
189 cleanup:
190  if (hKey)
191  ZwClose(hKey);
192  if (pkf)
193  UserDereferenceObject(pkf); // we dont need ptr anymore
194  if (!pRet)
195  {
196  /* We have failed - destroy created object */
197  if (pkf)
199  }
200 
201  return pRet;
202 }
static BOOL UserLoadKbdDll(WCHAR *pwszLayoutPath, HANDLE *phModule, PKBDTABLES *pKbdTables)
Definition: kbdlayout.c:36
BOOL FASTCALL UserDeleteObject(HANDLE h, HANDLE_TYPE type)
Definition: object.c:683
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
HANDLE h
Definition: ntuser.h:176
LONG NTSTATUS
Definition: precomp.h:26
PKBDFILE gpkfList
Definition: kbdlayout.c:21
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:610
NTSTRSAFEAPI RtlStringCbCatW(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:636
PVOID FASTCALL UserCreateObject(PUSER_HANDLE_TABLE ht, PDESKTOP pDesktop, PTHREADINFO pti, HANDLE *h, HANDLE_TYPE type, ULONG size)
Definition: object.c:535
smooth NULL
Definition: ftsmooth.c:416
WCHAR awchKF[20]
Definition: input.h:19
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:26
#define swprintf(buf, format,...)
Definition: sprintf.c:56
struct tagKBDFILE * pkfNext
Definition: input.h:18
struct _KBDTABLES * pKbdTbl
Definition: input.h:21
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
HEAD head
Definition: input.h:17
#define ERR(fmt,...)
Definition: debug.h:110
HANDLE hBase
Definition: input.h:20
#define RegQueryValue
Definition: winreg.h:523
unsigned int ULONG
Definition: retypes.h:1
char * cleanup(char *str)
Definition: wpickclick.c:99
#define RegOpenKey
Definition: winreg.h:519
PUSER_HANDLE_TABLE gHandleTable
Definition: object.c:13
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define REG_SZ
Definition: layer.c:22

Referenced by UserLoadKbdLayout().

◆ UserLoadKbdLayout()

static PKL UserLoadKbdLayout ( PUNICODE_STRING  pustrKLID,
HKL  hKL 
)
static

Definition at line 210 of file kbdlayout.c.

211 {
212  LCID lCid;
213  CHARSETINFO cs;
214  PKL pKl;
215 
216  /* Create keyboard layout object */
218  if (!pKl)
219  {
220  ERR("Failed to create object!\n");
221  return NULL;
222  }
223 
224  pKl->hkl = hKL;
225  pKl->spkf = UserLoadKbdFile(pustrKLID);
226 
227  /* Dereference keyboard layout */
229 
230  /* If we failed, remove KL object */
231  if (!pKl->spkf)
232  {
233  ERR("UserLoadKbdFile(%wZ) failed!\n", pustrKLID);
235  return NULL;
236  }
237 
238  // Up to Language Identifiers..
239  if (!NT_SUCCESS(RtlUnicodeStringToInteger(pustrKLID, 16, (PULONG)&lCid)))
240  {
241  ERR("RtlUnicodeStringToInteger failed for '%wZ'\n", pustrKLID);
243  return NULL;
244  }
245 
246  TRACE("Language Identifiers %wZ LCID 0x%x\n", pustrKLID, lCid);
247  if (co_IntGetCharsetInfo(lCid, &cs))
248  {
249  pKl->iBaseCharset = cs.ciCharset;
250  pKl->dwFontSigs = cs.fs.fsCsb[0];
251  pKl->CodePage = (USHORT)cs.ciACP;
252  TRACE("Charset %u Font Sig %lu CodePage %u\n",
253  pKl->iBaseCharset, pKl->dwFontSigs, pKl->CodePage);
254  }
255  else
256  {
257  pKl->iBaseCharset = ANSI_CHARSET;
258  pKl->dwFontSigs = FS_LATIN1;
259  pKl->CodePage = CP_ACP;
260  }
261 
262  // Set initial system character set and font signature.
263  if (gSystemFS == 0)
264  {
266  gSystemFS = pKl->dwFontSigs;
267  }
268 
269  return pKl;
270 }
BOOL FASTCALL UserDeleteObject(HANDLE h, HANDLE_TYPE type)
Definition: object.c:683
BOOL APIENTRY co_IntGetCharsetInfo(LCID Locale, PCHARSETINFO pCs)
Definition: callback.c:1051
HANDLE h
Definition: ntuser.h:176
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:610
DWORD LCID
Definition: nls.h:13
UINT gSystemCPCharSet
Definition: kbdlayout.c:23
PVOID FASTCALL UserCreateObject(PUSER_HANDLE_TABLE ht, PDESKTOP pDesktop, PTHREADINFO pti, HANDLE *h, HANDLE_TYPE type, ULONG size)
Definition: object.c:535
uint32_t cs
Definition: isohybrid.c:75
DWORD gSystemFS
Definition: kbdlayout.c:22
HEAD head
Definition: input.h:28
smooth NULL
Definition: ftsmooth.c:416
Definition: input.h:26
UINT iBaseCharset
Definition: input.h:35
#define CP_ACP
Definition: kbdlayout.c:16
#define TRACE(s)
Definition: solgame.cpp:4
USHORT CodePage
Definition: input.h:36
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
HKL hkl
Definition: input.h:32
DWORD dwFontSigs
Definition: input.h:34
#define ERR(fmt,...)
Definition: debug.h:110
unsigned short USHORT
Definition: pedump.c:61
unsigned int * PULONG
Definition: retypes.h:1
#define FS_LATIN1
Definition: wingdi.h:559
PKBDFILE spkf
Definition: input.h:33
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
static PKBDFILE UserLoadKbdFile(PUNICODE_STRING pwszKLID)
Definition: kbdlayout.c:131
#define ANSI_CHARSET
Definition: wingdi.h:382
PUSER_HANDLE_TABLE gHandleTable
Definition: object.c:13

Referenced by NtUserLoadKeyboardLayoutEx().

◆ UserSetDefaultInputLang()

BOOL NTAPI UserSetDefaultInputLang ( HKL  hKl)

Definition at line 395 of file kbdlayout.c.

396 {
397  PKL pKl;
398 
399  pKl = UserHklToKbl(hKl);
400  if (!pKl)
401  return FALSE;
402 
403  gspklBaseLayout = pKl;
404  return TRUE;
405 }
#define TRUE
Definition: types.h:120
PKL gspklBaseLayout
Definition: kbdlayout.c:20
Definition: input.h:26
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:370

Referenced by SpiGetSet().

◆ UserUnloadKbl()

BOOL UserUnloadKbl ( PKL  pKl)

Definition at line 306 of file kbdlayout.c.

307 {
308  /* According to msdn, UnloadKeyboardLayout can fail
309  if the keyboard layout identifier was preloaded. */
310  if (pKl == gspklBaseLayout)
311  {
312  if (pKl->pklNext == pKl->pklPrev)
313  {
314  /* There is only one layout */
315  return FALSE;
316  }
317 
318  /* Set next layout as default */
319  gspklBaseLayout = pKl->pklNext;
320  }
321 
322  if (pKl->head.cLockObj > 1)
323  {
324  /* Layout is used by other threads */
325  pKl->dwKL_Flags |= KLF_UNLOAD;
326  return FALSE;
327  }
328 
329  /* Unload the layout */
330  pKl->pklPrev->pklNext = pKl->pklNext;
331  pKl->pklNext->pklPrev = pKl->pklPrev;
332  UnloadKbdFile(pKl->spkf);
334  return TRUE;
335 }
struct tagKL * pklPrev
Definition: input.h:30
#define KLF_UNLOAD
Definition: input.h:51
BOOL FASTCALL UserDeleteObject(HANDLE h, HANDLE_TYPE type)
Definition: object.c:683
#define TRUE
Definition: types.h:120
PKL gspklBaseLayout
Definition: kbdlayout.c:20
HANDLE h
Definition: ntuser.h:176
HEAD head
Definition: input.h:28
DWORD dwKL_Flags
Definition: input.h:31
DWORD cLockObj
Definition: ntuser.h:177
struct tagKL * pklNext
Definition: input.h:29
PKBDFILE spkf
Definition: input.h:33
static VOID UnloadKbdFile(_In_ PKBDFILE pkf)
Definition: kbdlayout.c:279

Referenced by NtUserLoadKeyboardLayoutEx(), and NtUserUnloadKeyboardLayout().

◆ W32kGetDefaultKeyLayout()

PKL W32kGetDefaultKeyLayout ( VOID  )

Definition at line 343 of file kbdlayout.c.

344 {
345  PKL pKl = gspklBaseLayout;
346 
347  if (!pKl)
348  return NULL;
349 
350  /* Return not unloaded layout */
351  do
352  {
353  if (!(pKl->dwKL_Flags & KLF_UNLOAD))
354  return pKl;
355 
356  pKl = pKl->pklPrev; /* Confirmed on Win2k */
357  } while(pKl != gspklBaseLayout);
358 
359  /* We have not found proper KL */
360  return NULL;
361 }
struct tagKL * pklPrev
Definition: input.h:30
#define KLF_UNLOAD
Definition: input.h:51
PKL gspklBaseLayout
Definition: kbdlayout.c:20
smooth NULL
Definition: ftsmooth.c:416
Definition: input.h:26
DWORD dwKL_Flags
Definition: input.h:31

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

Variable Documentation

◆ gpkfList

PKBDFILE gpkfList = NULL

Definition at line 21 of file kbdlayout.c.

Referenced by UnloadKbdFile(), and UserLoadKbdFile().

◆ gspklBaseLayout

◆ gSystemCPCharSet

UINT gSystemCPCharSet = 0

Definition at line 23 of file kbdlayout.c.

Referenced by UserLoadKbdLayout().

◆ gSystemFS

DWORD gSystemFS = 0

Definition at line 22 of file kbdlayout.c.

Referenced by co_IntProcessKeyboardMessage(), and UserLoadKbdLayout().