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?re... ============================================================================== --- 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/inc... ============================================================================== --- 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/inc... ============================================================================== --- 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/ntu... ============================================================================== --- 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/ntu... ============================================================================== --- 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);