Author: rharabien
Date: Sun Oct 16 15:39:07 2011
New Revision: 54163
URL:
http://svn.reactos.org/svn/reactos?rev=54163&view=rev
Log:
[WIN32K]
- Remove ReadRegistryValue in kbdlayout.c as we already implement RegQueryValue for
reading from registry in W32k. This function additionally checks value type.
- Rename KBL to KL based on Techwiki
- HKCU\Keyboard Layout\Preload value is REG_SZ (not REG_EXPAND_SZ)
- NtUserLoadKeyboardLayoutEx should set last error if flags are invalid
- Minor keyboard layout code cleanup
Modified:
trunk/reactos/boot/bootdata/livecd.inf
trunk/reactos/subsystems/win32/win32k/include/input.h
trunk/reactos/subsystems/win32/win32k/include/win32.h
trunk/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c
trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c
Modified: trunk/reactos/boot/bootdata/livecd.inf
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/bootdata/livecd.inf?r…
==============================================================================
--- trunk/reactos/boot/bootdata/livecd.inf [iso-8859-1] (original)
+++ trunk/reactos/boot/bootdata/livecd.inf [iso-8859-1] Sun Oct 16 15:39:07 2011
@@ -8,7 +8,7 @@
[AddReg]
; Default locale for the keyboard layout
-HKU,".DEFAULT\Keyboard
Layout\Preload","1",0x00020000,"00000409"
+HKU,".DEFAULT\Keyboard
Layout\Preload","1",0x00000000,"00000409"
; Cdfs (ISO96660) filesystem driver
HKLM,"SYSTEM\CurrentControlSet\Services\Cdfs","Start",0x00010001,0x00000000
Modified: trunk/reactos/subsystems/win32/win32k/include/input.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/input.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/input.h [iso-8859-1] Sun Oct 16 15:39:07
2011
@@ -2,17 +2,17 @@
#include <ndk/kbd.h>
-typedef struct _KBL
+typedef struct _KL
{
LIST_ENTRY List;
DWORD Flags;
WCHAR Name[KL_NAMELENGTH]; // used w GetKeyboardLayoutName same as wszKLID.
- struct _KBDTABLES* KBTables; // KBDTABLES in ndk/kbd.h
+ struct _KBDTABLES *KBTables; // KBDTABLES in ndk/kbd.h
HANDLE hModule;
ULONG RefCount;
HKL hkl;
DWORD klid; // Low word - language id. High word - device id.
-} KBL, *PKBL;
+} KL, *PKL;
typedef struct _ATTACHINFO
{
@@ -39,14 +39,14 @@
INIT_FUNCTION NTSTATUS NTAPI InitInputImpl(VOID);
INIT_FUNCTION NTSTATUS NTAPI InitKeyboardImpl(VOID);
VOID NTAPI UserInitKeyboard(HANDLE hKeyboardDevice);
-PKBL W32kGetDefaultKeyLayout(VOID);
+PKL W32kGetDefaultKeyLayout(VOID);
VOID NTAPI UserProcessKeyboardInput(PKEYBOARD_INPUT_DATA pKeyInput);
BOOL NTAPI UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected);
VOID NTAPI UserProcessMouseInput(PMOUSE_INPUT_DATA Data, ULONG InputCount);
BOOL FASTCALL IntBlockInput(PTHREADINFO W32Thread, BOOL BlockIt);
BOOL FASTCALL IntMouseInput(MOUSEINPUT *mi, BOOL Injected);
BOOL UserInitDefaultKeyboardLayout(VOID);
-PKBL UserHklToKbl(HKL hKl);
+PKL UserHklToKbl(HKL hKl);
VOID NTAPI KeyboardThreadMain(PVOID StartContext);
DWORD NTAPI CreateSystemThreads(UINT Type);
BOOL FASTCALL UserAttachThreadInput(PTHREADINFO,PTHREADINFO,BOOL);
Modified: trunk/reactos/subsystems/win32/win32k/include/win32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/win32.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/win32.h [iso-8859-1] Sun Oct 16 15:39:07
2011
@@ -69,7 +69,7 @@
PTL ptl;
PPROCESSINFO ppi;
struct _USER_MESSAGE_QUEUE* MessageQueue;
- struct _KBL* KeyboardLayout;
+ struct _KL* KeyboardLayout;
PCLIENTTHREADINFO pcti;
struct _DESKTOP* rpdesk;
PDESKTOPINFO pDeskInfo;
@@ -188,7 +188,7 @@
LIST_ENTRY PrivateFontListHead;
FAST_MUTEX DriverObjListLock;
LIST_ENTRY DriverObjListHead;
- struct _KBL* KeyboardLayout; // THREADINFO only
+ struct _KL* KeyboardLayout; // THREADINFO only
W32HEAP_USER_MAPPING HeapMappings;
struct _GDI_POOL *pPoolDcAttr;
struct _GDI_POOL *pPoolBrushAttr;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c [iso-8859-1] Sun Oct 16
15:39:07 2011
@@ -5,251 +5,156 @@
* PURPOSE: Keyboard layout management
* COPYRIGHT: Copyright 2007 Saveliy Tretiakov
* Copyright 2008 Colin Finck
+ * Copyright 2011 Rafal Harabien
*/
#include <win32k.h>
DBG_DEFAULT_CHANNEL(UserKbdLayout);
-PKBL KBLList = NULL; // Keyboard layout list.
-
-typedef PVOID (*KbdLayerDescriptor)(VOID);
+PKL gpklFirst = NULL; // Keyboard layout list.
+
+typedef PVOID (*PFNKBDLAYERDESCRIPTOR)(VOID);
/* PRIVATE FUNCTIONS ******************************************************/
-
-/*
- * Utility function to read a value from the registry more easily.
- *
- * IN PUNICODE_STRING KeyName -> Name of key to open
- * IN PUNICODE_STRING ValueName -> Name of value to open
- * OUT PUNICODE_STRING ReturnedValue -> String contained in registry
- *
- * Returns NTSTATUS
- */
-
-static NTSTATUS APIENTRY ReadRegistryValue( PUNICODE_STRING KeyName,
- PUNICODE_STRING ValueName,
- PUNICODE_STRING ReturnedValue )
+static BOOL
+UserLoadKbdDll(CONST WCHAR *wszKLID,
+ HANDLE *phModule,
+ PKBDTABLES *pKbdTables)
{
NTSTATUS Status;
- HANDLE KeyHandle;
- OBJECT_ATTRIBUTES KeyAttributes;
- PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
- ULONG Length = 0;
- ULONG ResLength = 0;
- PWCHAR ReturnBuffer;
-
- InitializeObjectAttributes(&KeyAttributes, KeyName, OBJ_CASE_INSENSITIVE,
- NULL, NULL);
- Status = ZwOpenKey(&KeyHandle, KEY_READ, &KeyAttributes);
+ HKEY hKey;
+ ULONG cbSize;
+ PFNKBDLAYERDESCRIPTOR pfnKbdLayerDescriptor;
+ WCHAR wszLayoutRegKey[256] =
L"\\REGISTRY\\Machine\\SYSTEM\\CurrentControlSet\\"
+ L"Control\\Keyboard Layouts\\";
+ WCHAR wszLayoutPath[MAX_PATH] = L"\\SystemRoot\\System32\\";
+
+ /* Open layout registry key */
+ RtlStringCbCatW(wszLayoutRegKey, sizeof(wszLayoutRegKey), wszKLID);
+ Status = RegOpenKey(wszLayoutRegKey, &hKey);
if (!NT_SUCCESS(Status))
{
- return Status;
- }
-
- Status = ZwQueryValueKey(KeyHandle, ValueName, KeyValuePartialInformation,
- 0,
- 0,
- &ResLength);
-
- if (Status != STATUS_BUFFER_TOO_SMALL)
- {
- NtClose(KeyHandle);
- return Status;
- }
-
- ResLength += sizeof(*KeyValuePartialInfo);
- KeyValuePartialInfo =
- ExAllocatePoolWithTag(PagedPool, ResLength, TAG_STRING);
- Length = ResLength;
-
- if (!KeyValuePartialInfo)
- {
- NtClose(KeyHandle);
- return STATUS_NO_MEMORY;
- }
-
- Status = ZwQueryValueKey(KeyHandle,
- ValueName,
- KeyValuePartialInformation,
- (PVOID)KeyValuePartialInfo,
- Length,
- &ResLength);
-
+ ERR("Failed to open keyboard layouts registry key %ws (%lx)\n",
wszKLID, Status);
+ return FALSE;
+ }
+
+ /* Read filename of layout DLL and close the key */
+ cbSize = sizeof(wszLayoutPath) - (wcslen(wszLayoutPath) + 1)*sizeof(WCHAR);
+ Status = RegQueryValue(hKey,
+ L"Layout File",
+ REG_SZ,
+ wszLayoutPath + wcslen(wszLayoutPath),
+ &cbSize);
+ ZwClose(hKey);
if (!NT_SUCCESS(Status))
{
- NtClose(KeyHandle);
- ExFreePoolWithTag(KeyValuePartialInfo, TAG_STRING);
- return Status;
- }
-
- /* At this point, KeyValuePartialInfo->Data contains the key data */
- ReturnBuffer = ExAllocatePoolWithTag(PagedPool,
- KeyValuePartialInfo->DataLength,
- TAG_STRING);
-
- if (!ReturnBuffer)
- {
- NtClose(KeyHandle);
- ExFreePoolWithTag(KeyValuePartialInfo, TAG_STRING);
- return STATUS_NO_MEMORY;
- }
-
- RtlCopyMemory(ReturnBuffer,
- KeyValuePartialInfo->Data,
- KeyValuePartialInfo->DataLength);
- RtlInitUnicodeString(ReturnedValue, ReturnBuffer);
-
- ExFreePoolWithTag(KeyValuePartialInfo, TAG_STRING);
- NtClose(KeyHandle);
-
- return Status;
-}
-
-static BOOL UserLoadKbdDll(WCHAR *wsKLID,
- HANDLE *phModule,
- PKBDTABLES *pKbdTables)
-{
- NTSTATUS Status;
- KbdLayerDescriptor layerDescGetFn;
- ANSI_STRING kbdProcedureName;
- UNICODE_STRING LayoutKeyName;
- UNICODE_STRING LayoutValueName;
- UNICODE_STRING LayoutFile;
- UNICODE_STRING FullLayoutPath;
- UNICODE_STRING klid;
- WCHAR LayoutPathBuffer[MAX_PATH] = L"\\SystemRoot\\System32\\";
- WCHAR KeyNameBuffer[MAX_PATH] = L"\\REGISTRY\\Machine\\SYSTEM\\"
- L"CurrentControlSet\\Control\\Keyboard
Layouts\\";
-
- RtlInitUnicodeString(&klid, wsKLID);
- RtlInitUnicodeString(&LayoutValueName, L"Layout File");
- RtlInitUnicodeString(&LayoutKeyName, KeyNameBuffer);
- LayoutKeyName.MaximumLength = sizeof(KeyNameBuffer);
-
- RtlAppendUnicodeStringToString(&LayoutKeyName, &klid);
- Status = ReadRegistryValue(&LayoutKeyName, &LayoutValueName,
&LayoutFile);
-
- if (!NT_SUCCESS(Status))
- {
- TRACE("Can't get layout filename for %wZ. (%08lx)\n", klid,
Status);
+ TRACE("Can't get layout filename for %ws (%lx)\n", wszKLID,
Status);
return FALSE;
}
- TRACE("Read registry and got %wZ\n", &LayoutFile);
- RtlInitUnicodeString(&FullLayoutPath, LayoutPathBuffer);
- FullLayoutPath.MaximumLength = sizeof(LayoutPathBuffer);
- RtlAppendUnicodeStringToString(&FullLayoutPath, &LayoutFile);
- TRACE("Loading Keyboard DLL %wZ\n", &FullLayoutPath);
- ExFreePoolWithTag(LayoutFile.Buffer, TAG_STRING);
-
- *phModule = EngLoadImage(FullLayoutPath.Buffer);
-
- if (*phModule)
- {
- TRACE("Loaded %wZ\n", &FullLayoutPath);
-
- RtlInitAnsiString( &kbdProcedureName, "KbdLayerDescriptor" );
- layerDescGetFn = EngFindImageProcAddress(*phModule,
"KbdLayerDescriptor");
-
- if (layerDescGetFn)
- {
- *pKbdTables = layerDescGetFn();
- }
- else
- {
- ERR("Error: %wZ has no KbdLayerDescriptor()\n",
&FullLayoutPath);
- }
-
- if (!layerDescGetFn || !*pKbdTables)
- {
- ERR("Failed to load the keyboard layout.\n");
- EngUnloadImage(*phModule);
- return FALSE;
- }
+ /* Load keyboard layout DLL */
+ TRACE("Loading Keyboard DLL %ws\n", wszLayoutPath);
+ *phModule = EngLoadImage(wszLayoutPath);
+ if (!(*phModule))
+ {
+ ERR("Failed to load dll %ws\n", wszLayoutPath);
+ return FALSE;
+ }
+
+ /* Find KbdLayerDescriptor function and get layout tables */
+ TRACE("Loaded %ws\n", wszLayoutPath);
+ pfnKbdLayerDescriptor = EngFindImageProcAddress(*phModule,
"KbdLayerDescriptor");
+
+ if (pfnKbdLayerDescriptor)
+ *pKbdTables = pfnKbdLayerDescriptor();
+ else
+ ERR("Error: %ws has no KbdLayerDescriptor()\n", wszLayoutPath);
+
+ if (!pfnKbdLayerDescriptor || !*pKbdTables)
+ {
+ ERR("Failed to load the keyboard layout.\n");
+ EngUnloadImage(*phModule);
+ return FALSE;
+ }
#if 0 // Dump keyboard layout
- {
- unsigned i;
- PVK_TO_BIT pVkToBit = (*pKbdTables)->pCharModifiers->pVkToBit;
- PVK_TO_WCHAR_TABLE pVkToWchTbl = (*pKbdTables)->pVkToWcharTable;
- PVSC_VK pVscVk = (*pKbdTables)->pVSCtoVK_E0;
- DbgPrint("Kbd layout: fLocaleFlags %x bMaxVSCtoVK %x\n",
(*pKbdTables)->fLocaleFlags, (*pKbdTables)->bMaxVSCtoVK);
- DbgPrint("wMaxModBits %x\n",
(*pKbdTables)->pCharModifiers->wMaxModBits);
- while (pVkToBit->Vk)
+ {
+ unsigned i;
+ PVK_TO_BIT pVkToBit = (*pKbdTables)->pCharModifiers->pVkToBit;
+ PVK_TO_WCHAR_TABLE pVkToWchTbl = (*pKbdTables)->pVkToWcharTable;
+ PVSC_VK pVscVk = (*pKbdTables)->pVSCtoVK_E0;
+ DbgPrint("Kbd layout: fLocaleFlags %x bMaxVSCtoVK %x\n",
(*pKbdTables)->fLocaleFlags, (*pKbdTables)->bMaxVSCtoVK);
+ DbgPrint("wMaxModBits %x\n",
(*pKbdTables)->pCharModifiers->wMaxModBits);
+ while (pVkToBit->Vk)
+ {
+ DbgPrint("VkToBit %x -> %x\n", pVkToBit->Vk,
pVkToBit->ModBits);
+ ++pVkToBit;
+ }
+ for (i = 0; i <= (*pKbdTables)->pCharModifiers->wMaxModBits; ++i)
+ DbgPrint("ModNumber %x -> %x\n", i,
(*pKbdTables)->pCharModifiers->ModNumber[i]);
+ while (pVkToWchTbl->pVkToWchars)
+ {
+ PVK_TO_WCHARS1 pVkToWch = pVkToWchTbl->pVkToWchars;
+ DbgPrint("pVkToWchTbl nModifications %x cbSize %x\n",
pVkToWchTbl->nModifications, pVkToWchTbl->cbSize);
+ while (pVkToWch->VirtualKey)
{
- DbgPrint("VkToBit %x -> %x\n", pVkToBit->Vk,
pVkToBit->ModBits);
- ++pVkToBit;
+ DbgPrint("pVkToWch VirtualKey %x Attributes %x wc { ",
pVkToWch->VirtualKey, pVkToWch->Attributes);
+ for (i = 0; i < pVkToWchTbl->nModifications; ++i)
+ DbgPrint("%x ", pVkToWch->wch[i]);
+ DbgPrint("}\n");
+ pVkToWch = (PVK_TO_WCHARS1)(((PBYTE)pVkToWch) + pVkToWchTbl->cbSize);
}
- for (i = 0; i <= (*pKbdTables)->pCharModifiers->wMaxModBits; ++i)
- DbgPrint("ModNumber %x -> %x\n", i,
(*pKbdTables)->pCharModifiers->ModNumber[i]);
- while (pVkToWchTbl->pVkToWchars)
- {
- PVK_TO_WCHARS1 pVkToWch = pVkToWchTbl->pVkToWchars;
- DbgPrint("pVkToWchTbl nModifications %x cbSize %x\n",
pVkToWchTbl->nModifications, pVkToWchTbl->cbSize);
- while (pVkToWch->VirtualKey)
- {
- DbgPrint("pVkToWch VirtualKey %x Attributes %x wc { ",
pVkToWch->VirtualKey, pVkToWch->Attributes);
- for (i = 0; i < pVkToWchTbl->nModifications; ++i)
- DbgPrint("%x ", pVkToWch->wch[i]);
- DbgPrint("}\n");
- pVkToWch = (PVK_TO_WCHARS1)(((PBYTE)pVkToWch) +
pVkToWchTbl->cbSize);
- }
- ++pVkToWchTbl;
- }
- DbgPrint("pusVSCtoVK: { ");
- for (i = 0; i < (*pKbdTables)->bMaxVSCtoVK; ++i)
- DbgPrint("%x -> %x, ", i, (*pKbdTables)->pusVSCtoVK[i]);
- DbgPrint("}\n");
- DbgPrint("pVSCtoVK_E0: { ");
- while (pVscVk->Vsc)
- {
- DbgPrint("%x -> %x, ", pVscVk->Vsc, pVscVk->Vk);
- ++pVscVk;
- }
- DbgPrint("}\n");
- pVscVk = (*pKbdTables)->pVSCtoVK_E1;
- DbgPrint("pVSCtoVK_E1: { ");
- while (pVscVk->Vsc)
- {
- DbgPrint("%x -> %x, ", pVscVk->Vsc, pVscVk->Vk);
- ++pVscVk;
- }
- DbgPrint("}\n");
- }
+ ++pVkToWchTbl;
+ }
+ DbgPrint("pusVSCtoVK: { ");
+ for (i = 0; i < (*pKbdTables)->bMaxVSCtoVK; ++i)
+ DbgPrint("%x -> %x, ", i, (*pKbdTables)->pusVSCtoVK[i]);
+ DbgPrint("}\n");
+ DbgPrint("pVSCtoVK_E0: { ");
+ while (pVscVk->Vsc)
+ {
+ DbgPrint("%x -> %x, ", pVscVk->Vsc, pVscVk->Vk);
+ ++pVscVk;
+ }
+ DbgPrint("}\n");
+ pVscVk = (*pKbdTables)->pVSCtoVK_E1;
+ DbgPrint("pVSCtoVK_E1: { ");
+ while (pVscVk->Vsc)
+ {
+ DbgPrint("%x -> %x, ", pVscVk->Vsc, pVscVk->Vk);
+ ++pVscVk;
+ }
+ DbgPrint("}\n");
DbgBreakPoint();
+ }
#endif
- }
- else
- {
- ERR("Failed to load dll %wZ\n", &FullLayoutPath);
- return FALSE;
- }
return TRUE;
}
-static PKBL UserLoadDllAndCreateKbl(DWORD LocaleId)
-{
- PKBL NewKbl;
+static PKL
+UserLoadDllAndCreateKbl(DWORD LocaleId)
+{
+ PKL pNewKbl;
ULONG hKl;
LANGID langid;
- NewKbl = ExAllocatePoolWithTag(PagedPool, sizeof(KBL), USERTAG_KBDLAYOUT);
-
- if (!NewKbl)
- {
- ERR("%s: Can't allocate memory!\n", __FUNCTION__);
+ pNewKbl = ExAllocatePoolWithTag(PagedPool, sizeof(KL), USERTAG_KBDLAYOUT);
+
+ if (!pNewKbl)
+ {
+ ERR("Can't allocate memory!\n");
return NULL;
}
- swprintf(NewKbl->Name, L"%08lx", LocaleId);
-
- if (!UserLoadKbdDll(NewKbl->Name, &NewKbl->hModule,
&NewKbl->KBTables))
- {
- TRACE("%s: failed to load %x dll!\n", __FUNCTION__, LocaleId);
- ExFreePoolWithTag(NewKbl, USERTAG_KBDLAYOUT);
+ swprintf(pNewKbl->Name, L"%08lx", LocaleId);
+
+ if (!UserLoadKbdDll(pNewKbl->Name, &pNewKbl->hModule,
&pNewKbl->KBTables))
+ {
+ ERR("Failed to load %x dll!\n", LocaleId);
+ ExFreePoolWithTag(pNewKbl, USERTAG_KBDLAYOUT);
return NULL;
}
@@ -265,158 +170,155 @@
hKl |= 0xe001 << 16; /* FIXME */
else hKl |= hKl << 16;
- NewKbl->hkl = (HKL)(ULONG_PTR) hKl;
- NewKbl->klid = LocaleId;
- NewKbl->Flags = 0;
- NewKbl->RefCount = 0;
-
- return NewKbl;
-}
-
-BOOL UserInitDefaultKeyboardLayout()
+ pNewKbl->hkl = (HKL)(ULONG_PTR) hKl;
+ pNewKbl->klid = LocaleId;
+ pNewKbl->Flags = 0;
+ pNewKbl->RefCount = 0;
+
+ return pNewKbl;
+}
+
+BOOL
+UserInitDefaultKeyboardLayout()
{
LCID LocaleId;
NTSTATUS Status;
+ /* Load keyboard layout for default locale */
Status = ZwQueryDefaultLocale(FALSE, &LocaleId);
- if (!NT_SUCCESS(Status))
- {
+ if (NT_SUCCESS(Status))
+ {
+ TRACE("DefaultLocale = %08lx\n", LocaleId);
+ gpklFirst = UserLoadDllAndCreateKbl(LocaleId);
+ }
+ else
ERR("Could not get default locale (%08lx).\n", Status);
- }
- else
- {
- TRACE("DefaultLocale = %08lx\n", LocaleId);
- }
-
- if (!NT_SUCCESS(Status) || !(KBLList = UserLoadDllAndCreateKbl(LocaleId)))
- {
+
+ if (!NT_SUCCESS(Status) || !gpklFirst)
+ {
+ /* If failed load US keyboard layout */
ERR("Trying to load US Keyboard Layout.\n");
LocaleId = 0x409;
- if (!(KBLList = UserLoadDllAndCreateKbl(LocaleId)))
+ if (!(gpklFirst = UserLoadDllAndCreateKbl(LocaleId)))
{
ERR("Failed to load any Keyboard Layout\n");
return FALSE;
}
}
- KBLList->Flags |= KBL_PRELOAD;
-
- InitializeListHead(&KBLList->List);
+ /* Add layout to the list */
+ gpklFirst->Flags |= KBL_PRELOAD;
+ InitializeListHead(&gpklFirst->List);
+
return TRUE;
}
-PKBL W32kGetDefaultKeyLayout(VOID)
-{
- const WCHAR szKeyboardLayoutPath[] = L"\\Keyboard Layout\\Preload";
- const WCHAR szDefaultUserPath[] = L"\\REGISTRY\\USER\\.DEFAULT";
-
- HANDLE KeyHandle;
+PKL
+W32kGetDefaultKeyLayout(VOID)
+{
+ CONST WCHAR wszDefaultUserPath[] = L"\\REGISTRY\\USER\\.DEFAULT";
+ CONST WCHAR wszKeyboardLayoutPath[] = L"\\Keyboard Layout\\Preload";
+ WCHAR wszKbdLayoutKey[256], *pwsz;
+ size_t cbRemaining;
+ HKEY hKey;
+ ULONG cbValue;
LCID LayoutLocaleId = 0;
NTSTATUS Status;
- OBJECT_ATTRIBUTES KeyAttributes;
- PKBL pKbl;
+ PKL pKbl;
UNICODE_STRING CurrentUserPath;
- UNICODE_STRING FullKeyboardLayoutPath;
- UNICODE_STRING LayoutValueName;
- UNICODE_STRING LayoutLocaleIdString;
WCHAR wszBuffer[MAX_PATH];
- // Get the path to HKEY_CURRENT_USER
+ /* Try to get default alayout from HKCU\Keyboard Layout\Preload first */
Status = RtlFormatCurrentUserKeyPath(&CurrentUserPath);
-
if (NT_SUCCESS(Status))
{
- FullKeyboardLayoutPath.Buffer = wszBuffer;
- FullKeyboardLayoutPath.MaximumLength = sizeof(wszBuffer);
-
- // FIXME: Is this 100% correct?
- // We're called very early, so HKEY_CURRENT_USER might not be available yet.
Check this first.
- InitializeObjectAttributes(&KeyAttributes, &CurrentUserPath,
OBJ_CASE_INSENSITIVE, NULL, NULL);
- Status = ZwOpenKey(&KeyHandle, KEY_READ, &KeyAttributes);
-
- if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
- {
- // It is not available, so read it from HKEY_USERS\.DEFAULT
- FullKeyboardLayoutPath.Length = sizeof(szDefaultUserPath) -
sizeof(UNICODE_NULL);
- RtlCopyMemory(wszBuffer, szDefaultUserPath, sizeof(szDefaultUserPath));
- }
+ /* FIXME: We're called very early, so HKEY_CURRENT_USER might not be
+ available yet. Check this first. */
+ RtlStringCbCopyNExW(wszKbdLayoutKey, sizeof(wszKbdLayoutKey),
+ CurrentUserPath.Buffer, CurrentUserPath.Length,
+ &pwsz, &cbRemaining, 0);
+ RtlStringCbCopyW(pwsz, cbRemaining, wszKeyboardLayoutPath);
+ Status = RegOpenKey(wszKbdLayoutKey, &hKey);
+
+ /* Free CurrentUserPath - we dont need it anymore */
+ RtlFreeUnicodeString(&CurrentUserPath);
+ }
+
+ /* If failed try HKU\.DEFAULT\Keyboard Layout\Preload */
+ if (!NT_SUCCESS(Status))
+ {
+ RtlStringCbCopyNExW(wszKbdLayoutKey, sizeof(wszKbdLayoutKey),
+ wszDefaultUserPath, sizeof(wszDefaultUserPath),
+ &pwsz, &cbRemaining, 0);
+ RtlStringCbCopyW(pwsz, cbRemaining, wszKeyboardLayoutPath);
+ Status = RegOpenKey(wszKbdLayoutKey, &hKey);
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ /* Return the first keyboard layout listed there */
+ cbValue = sizeof(wszBuffer);
+ Status = RegQueryValue(hKey, L"1", REG_SZ, wszBuffer, &cbValue);
+ if (NT_SUCCESS(Status))
+ LayoutLocaleId = (LCID)wcstol(wszBuffer, NULL, 16);
else
- {
- // The path is available
- ZwClose(KeyHandle);
- RtlCopyUnicodeString(&FullKeyboardLayoutPath, &CurrentUserPath);
- }
-
- // Free CurrentUserPath - we dont need it anymore
- RtlFreeUnicodeString(&CurrentUserPath);
-
- Status = RtlAppendUnicodeToString(&FullKeyboardLayoutPath,
szKeyboardLayoutPath);
-
- if (NT_SUCCESS(Status))
- {
- // Return the first keyboard layout listed there
- RtlInitUnicodeString(&LayoutValueName, L"1");
-
- Status = ReadRegistryValue(&FullKeyboardLayoutPath, &LayoutValueName,
&LayoutLocaleIdString);
-
- if (NT_SUCCESS(Status))
- {
- RtlUnicodeStringToInteger(&LayoutLocaleIdString, 16,
&LayoutLocaleId);
- ExFreePoolWithTag(LayoutLocaleIdString.Buffer, TAG_STRING);
- }
- else
- ERR("ReadRegistryValue failed! (%08lx).\n", Status);
- }
- else
- ERR("RtlAppendUnicodeToString failed! (%08lx)\n", Status);
+ ERR("RegQueryValue failed (%08lx)\n", Status);
+
+ /* Close the key */
+ ZwClose(hKey);
}
else
- ERR("RtlFormatCurrentUserKeyPath failed! (%08lx)\n", Status);
-
+ ERR("Failed to open keyboard layout preload key (%08lx)\n", Status);
+
+ /* If we failed loading settings from registry use US layout */
if (!LayoutLocaleId)
{
ERR("Assuming default locale for the keyboard layout (0x409 - US)\n");
LayoutLocaleId = 0x409;
}
- pKbl = KBLList;
+ /* Check if layout is already loaded */
+ pKbl = gpklFirst;
do
{
if (pKbl->klid == LayoutLocaleId)
- {
return pKbl;
- }
-
- pKbl = (PKBL) pKbl->List.Flink;
- } while (pKbl != KBLList);
-
+
+ pKbl = CONTAINING_RECORD(pKbl->List.Flink, KL, List);
+ } while (pKbl != gpklFirst);
+
+ /* Load the keyboard layout */
TRACE("Loading new default keyboard layout.\n");
pKbl = UserLoadDllAndCreateKbl(LayoutLocaleId);
-
if (!pKbl)
{
- TRACE("Failed to load %x!!! Returning any availableKL.\n",
LayoutLocaleId);
- return KBLList;
- }
-
- InsertTailList(&KBLList->List, &pKbl->List);
+ ERR("Failed to load %x!!! Returning any available KL.\n",
LayoutLocaleId);
+ return gpklFirst;
+ }
+
+ /* Add loaded layout to the list */
+ InsertTailList(&gpklFirst->List, &pKbl->List);
return pKbl;
}
-PKBL UserHklToKbl(HKL hKl)
-{
- PKBL pKbl = KBLList;
+PKL
+UserHklToKbl(HKL hKl)
+{
+ PKL pKbl = gpklFirst;
do
{
- if (pKbl->hkl == hKl) return pKbl;
- pKbl = (PKBL) pKbl->List.Flink;
- } while (pKbl != KBLList);
+ if (pKbl->hkl == hKl)
+ return pKbl;
+
+ pKbl = CONTAINING_RECORD(pKbl->List.Flink, KL, List);
+ } while (pKbl != gpklFirst);
return NULL;
}
-BOOL UserUnloadKbl(PKBL pKbl)
+BOOL
+UserUnloadKbl(PKL pKbl)
{
/* According to msdn, UnloadKeyboardLayout can fail
if the keyboard layout identifier was preloaded. */
@@ -444,13 +346,14 @@
return TRUE;
}
-static PKBL co_UserActivateKbl(PTHREADINFO w32Thread, PKBL pKbl, UINT Flags)
-{
- PKBL Prev;
-
- Prev = w32Thread->KeyboardLayout;
- Prev->RefCount--;
- w32Thread->KeyboardLayout = pKbl;
+static PKL
+co_UserActivateKbl(PTHREADINFO pti, PKL pKbl, UINT Flags)
+{
+ PKL pklPrev;
+
+ pklPrev = pti->KeyboardLayout;
+ pklPrev->RefCount--;
+ pti->KeyboardLayout = pKbl;
pKbl->RefCount++;
if (Flags & KLF_SETFORPROCESS)
@@ -459,18 +362,18 @@
}
- if (Prev->Flags & KBL_UNLOAD && Prev->RefCount == 0)
- {
- UserUnloadKbl(Prev);
+ if (pklPrev->Flags & KBL_UNLOAD && pklPrev->RefCount == 0)
+ {
+ UserUnloadKbl(pklPrev);
}
// Send WM_INPUTLANGCHANGE to thread's focus window
- co_IntSendMessage(w32Thread->MessageQueue->FocusWindow,
+ co_IntSendMessage(pti->MessageQueue->FocusWindow,
WM_INPUTLANGCHANGE,
0, // FIXME: put charset here (what is this?)
(LPARAM)pKbl->hkl); //klid
- return Prev;
+ return pklPrev;
}
/* EXPORTS *******************************************************************/
@@ -481,13 +384,13 @@
{
NTSTATUS Status;
PETHREAD Thread;
- PTHREADINFO W32Thread;
+ PTHREADINFO pti;
HKL Ret;
if (!dwThreadId)
{
- W32Thread = PsGetCurrentThreadWin32Thread();
- return W32Thread->KeyboardLayout->hkl;
+ pti = PsGetCurrentThreadWin32Thread();
+ return pti->KeyboardLayout->hkl;
}
Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)dwThreadId, &Thread);
@@ -497,8 +400,8 @@
return NULL;
}
- W32Thread = PsGetThreadWin32Thread(Thread);
- Ret = W32Thread->KeyboardLayout->hkl;
+ pti = PsGetThreadWin32Thread(Thread);
+ Ret = pti->KeyboardLayout->hkl;
ObDereferenceObject(Thread);
return Ret;
}
@@ -506,37 +409,41 @@
UINT
APIENTRY
NtUserGetKeyboardLayoutList(
- INT nItems,
+ INT nBuff,
HKL* pHklBuff)
{
- UINT Ret = 0;
- PKBL pKbl;
+ UINT uRet = 0;
+ PKL pKbl;
UserEnterShared();
- pKbl = KBLList;
-
- if (nItems == 0)
+ pKbl = gpklFirst;
+
+ if (!pHklBuff)
+ nBuff = 0;
+
+ if (nBuff == 0)
{
do
{
- Ret++;
- pKbl = (PKBL) pKbl->List.Flink;
- } while (pKbl != KBLList);
+ uRet++;
+ pKbl = CONTAINING_RECORD(pKbl->List.Flink, KL, List);
+ } while (pKbl != gpklFirst);
}
else
{
_SEH2_TRY
{
- ProbeForWrite(pHklBuff, nItems*sizeof(HKL), 4);
-
- while (Ret < nItems)
+ ProbeForWrite(pHklBuff, nBuff*sizeof(HKL), 4);
+
+ while (uRet < nBuff)
{
if (!(pKbl->Flags & KBL_UNLOAD))
{
- pHklBuff[Ret] = pKbl->hkl;
- Ret++;
- pKbl = (PKBL) pKbl->List.Flink;
- if (pKbl == KBLList) break;
+ pHklBuff[uRet] = pKbl->hkl;
+ uRet++;
+ pKbl = CONTAINING_RECORD(pKbl->List.Flink, KL, List);
+ if (pKbl == gpklFirst)
+ break;
}
}
@@ -544,13 +451,13 @@
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastNtError(_SEH2_GetExceptionCode());
- Ret = 0;
+ uRet = 0;
}
_SEH2_END;
}
UserLeave();
- return Ret;
+ return uRet;
}
BOOL
@@ -558,8 +465,8 @@
NtUserGetKeyboardLayoutName(
LPWSTR lpszName)
{
- BOOL ret = FALSE;
- PKBL pKbl;
+ BOOL bRet = FALSE;
+ PKL pKbl;
PTHREADINFO pti;
UserEnterShared();
@@ -569,20 +476,18 @@
ProbeForWrite(lpszName, KL_NAMELENGTH*sizeof(WCHAR), 1);
pti = PsGetCurrentThreadWin32Thread();
pKbl = pti->KeyboardLayout;
- RtlCopyMemory(lpszName, pKbl->Name, KL_NAMELENGTH*sizeof(WCHAR));
- ret = TRUE;
+ RtlCopyMemory(lpszName, pKbl->Name, KL_NAMELENGTH*sizeof(WCHAR));
+ bRet = TRUE;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastNtError(_SEH2_GetExceptionCode());
- ret = FALSE;
}
_SEH2_END;
UserLeave();
- return ret;
-}
-
+ return bRet;
+}
HKL
APIENTRY
@@ -595,24 +500,32 @@
IN DWORD dwKLID,
IN UINT Flags)
{
- HKL Ret = NULL;
- PKBL pKbl = NULL, Cur;
+ HKL hklRet = NULL;
+ PKL pKbl = NULL, pklCur;
+
+ if (Flags & ~(KLF_ACTIVATE|KLF_NOTELLSHELL|KLF_REORDER|KLF_REPLACELANG|
+ KLF_SUBSTITUTE_OK|KLF_SETFORPROCESS|KLF_UNLOADPREVIOUS))
+ {
+ ERR("Invalid flags: %x\n", Flags);
+ EngSetLastError(ERROR_INVALID_FLAGS);
+ return 0;
+ }
UserEnterExclusive();
//Let's see if layout was already loaded.
- Cur = KBLList;
+ pklCur = gpklFirst;
do
{
- if (Cur->klid == dwKLID)
- {
- pKbl = Cur;
+ if (pklCur->klid == dwKLID)
+ {
+ pKbl = pklCur;
pKbl->Flags &= ~KBL_UNLOAD;
break;
}
- Cur = (PKBL) Cur->List.Flink;
- } while (Cur != KBLList);
+ pklCur = CONTAINING_RECORD(pKbl->List.Flink, KL, List);
+ } while (pklCur != gpklFirst);
//It wasn't, so load it.
if (!pKbl)
@@ -621,28 +534,28 @@
if (!pKbl)
{
- goto the_end;
- }
-
- InsertTailList(&KBLList->List, &pKbl->List);
- }
-
- if (Flags & KLF_REORDER) KBLList = pKbl;
+ goto cleanup;
+ }
+
+ InsertTailList(&gpklFirst->List, &pKbl->List);
+ }
+
+ if (Flags & KLF_REORDER) gpklFirst = pKbl;
if (Flags & KLF_ACTIVATE)
{
co_UserActivateKbl(PsGetCurrentThreadWin32Thread(), pKbl, Flags);
}
- Ret = pKbl->hkl;
+ hklRet = pKbl->hkl;
//FIXME: KLF_NOTELLSHELL
// KLF_REPLACELANG
// KLF_SUBSTITUTE_OK
-the_end:
+cleanup:
UserLeave();
- return Ret;
+ return hklRet;
}
HKL
@@ -651,27 +564,27 @@
HKL hKl,
ULONG Flags)
{
- PKBL pKbl;
- HKL Ret = NULL;
- PTHREADINFO pWThread;
+ PKL pKbl;
+ HKL hklRet = NULL;
+ PTHREADINFO pti;
UserEnterExclusive();
- pWThread = PsGetCurrentThreadWin32Thread();
-
- if (pWThread->KeyboardLayout->hkl == hKl)
- {
- Ret = hKl;
- goto the_end;
+ pti = PsGetCurrentThreadWin32Thread();
+
+ if (pti->KeyboardLayout->hkl == hKl)
+ {
+ hklRet = hKl;
+ goto cleanup;
}
if (hKl == (HKL)HKL_NEXT)
{
- pKbl = (PKBL)pWThread->KeyboardLayout->List.Flink;
+ pKbl = CONTAINING_RECORD(pti->KeyboardLayout->List.Flink, KL, List);
}
else if (hKl == (HKL)HKL_PREV)
{
- pKbl = (PKBL)pWThread->KeyboardLayout->List.Blink;
+ pKbl = CONTAINING_RECORD(pti->KeyboardLayout->List.Blink, KL, List);
}
else pKbl = UserHklToKbl(hKl);
@@ -680,16 +593,16 @@
if (pKbl)
{
if (Flags & KLF_REORDER)
- KBLList = pKbl;
-
- if (pKbl == pWThread->KeyboardLayout)
- {
- Ret = pKbl->hkl;
+ gpklFirst = pKbl;
+
+ if (pKbl == pti->KeyboardLayout)
+ {
+ hklRet = pKbl->hkl;
}
else
{
- pKbl = co_UserActivateKbl(pWThread, pKbl, Flags);
- Ret = pKbl->hkl;
+ pKbl = co_UserActivateKbl(pti, pKbl, Flags);
+ hklRet = pKbl->hkl;
}
}
else
@@ -697,9 +610,9 @@
ERR("Invalid HKL %x!\n", hKl);
}
-the_end:
+cleanup:
UserLeave();
- return Ret;
+ return hklRet;
}
BOOL
@@ -707,14 +620,15 @@
NtUserUnloadKeyboardLayout(
HKL hKl)
{
- PKBL pKbl;
- BOOL Ret = FALSE;
+ PKL pKbl;
+ BOOL bRet = FALSE;
UserEnterExclusive();
- if ((pKbl = UserHklToKbl(hKl)))
- {
- Ret = UserUnloadKbl(pKbl);
+ pKbl = UserHklToKbl(hKl);
+ if (pKbl)
+ {
+ bRet = UserUnloadKbl(pKbl);
}
else
{
@@ -722,7 +636,7 @@
}
UserLeave();
- return Ret;
+ return bRet;
}
/* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/keyboard.c [iso-8859-1] Sun Oct 16
15:39:07 2011
@@ -891,7 +891,7 @@
UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
{
WORD wScanCode, wVk;
- PKBL pKbl = NULL;
+ PKL pKbl = NULL;
PKBDTABLES pKbdTbl;
PUSER_MESSAGE_QUEUE pFocusQueue;
struct _ETHREAD *pFocusThread;
@@ -973,7 +973,7 @@
PKEYBOARD_INPUT_DATA pKbdInputData)
{
WORD wScanCode, wVk;
- PKBL pKbl = NULL;
+ PKL pKbl = NULL;
PKBDTABLES pKbdTbl;
PUSER_MESSAGE_QUEUE pFocusQueue;
struct _ETHREAD *pFocusThread;
@@ -1211,7 +1211,7 @@
}
else
{
- PKBL pKbl;
+ PKL pKbl;
pKbl = UserHklToKbl(dwhkl);
if (pKbl)
@@ -1246,7 +1246,7 @@
BYTE afKeyState[256 * 2 / 8] = {0};
PWCHAR pwszBuff = NULL;
INT i, iRet = 0;
- PKBL pKbl = NULL;
+ PKL pKbl = NULL;
TRACE("Enter NtUserSetKeyboardState\n");
@@ -1451,7 +1451,7 @@
PKBDTABLES pKbdTbl;
PVK_TO_WCHAR_TABLE pVkToWchTbl;
PVK_TO_WCHARS10 pVkToWch;
- PKBL pKbl = NULL;
+ PKL pKbl = NULL;
DWORD i, dwModBits = 0, dwModNumber = 0, Ret = (DWORD)-1;
TRACE("NtUserVkKeyScanEx() wch %d, KbdLayout 0x%p\n", wch, dwhkl);