Patch from Art Yerkes:

1. I removed the global keyboard pointer, and instead acquire a new copy of
the pointer for each thread that needs it.  This makes a lock unnecessary,
but is probably less efficient than it could be.

2. Keyboard DLL names are read from the registry in the same way as on win2k.
The (Default) value is taken from HKLM\System\currentcontrolset\nls\locale,
and used to form the key HKLM\System\currentcontrolset\<8-digit-locale>
And get the layout file from the "Layout File" value.  I added the entries
for kbdus in hivesys.inf.  When others make keyboard layouts, they should be
added here.

svn path=/trunk/; revision=6362
This commit is contained in:
Vizzini 2003-10-18 20:41:10 +00:00
parent db03a52a68
commit e6bdd2efdb
3 changed files with 216 additions and 21 deletions

View file

@ -1,5 +1,5 @@
#ifndef __WIN32K_MOUSE_H
#define __WIN32K_MOUSE_H
#ifndef __WIN32K_INPUT_H
#define __WIN32K_INPUT_H
#include <internal/kbd.h>
@ -9,4 +9,4 @@ PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue(VOID);
PKBDTABLES W32kGetDefaultKeyLayout(VOID);
VOID FASTCALL W32kKeyProcessMessage(LPMSG Msg, PKBDTABLES KeyLayout);
#endif /* __WIN32K_MOUSE_H */
#endif /* __WIN32K_INPUT_H */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: input.c,v 1.14 2003/10/09 06:13:04 gvg Exp $
/* $Id: input.c,v 1.15 2003/10/18 20:41:10 vizzini Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -38,6 +38,7 @@
#include <include/msgqueue.h>
#include <ddk/ntddmou.h>
#include <include/mouse.h>
#include <include/input.h>
#define NDEBUG
#include <debug.h>
@ -291,6 +292,9 @@ InitInputImpl(VOID)
NtClose(MouseDeviceHandle);
return STATUS_SUCCESS;
}
/* Initialize the default keyboard layout */
(VOID)W32kGetDefaultKeyLayout();
return STATUS_SUCCESS;
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: keyboard.c,v 1.10 2003/10/09 06:13:04 gvg Exp $
/* $Id: keyboard.c,v 1.11 2003/10/18 20:41:10 vizzini Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -44,8 +44,9 @@
#define NDEBUG
#include <debug.h>
#define SYSTEMROOT_DIR L"\\SystemRoot\\System32\\"
BYTE QueueKeyStateTable[256];
PKBDTABLES pkKeyboardLayout = 0;
/* arty -- These should be phased out for the general kbdxx.dll tables */
@ -393,6 +394,114 @@ int STDCALL ToUnicode( UINT wVirtKey,
0 );
}
/*
* Utility to copy and append two unicode strings.
*
* IN OUT PUNICODE_STRING ResultFirst -> First string and result
* IN PUNICODE_STRING Second -> Second string to append
* IN BOOL Deallocate -> TRUE: Deallocate First string before
* overwriting.
*
* Returns NTSTATUS.
*/
static NTSTATUS ReallyAppendUnicodeString(PUNICODE_STRING ResultFirst,
PUNICODE_STRING Second,
BOOL Deallocate) {
NTSTATUS Status;
PWSTR new_string =
ExAllocatePool(PagedPool,
(ResultFirst->Length + Second->Length + sizeof(WCHAR)));
if( !new_string ) {
return STATUS_NO_MEMORY;
}
memcpy( new_string, ResultFirst->Buffer,
ResultFirst->Length );
memcpy( new_string + ResultFirst->Length / sizeof(WCHAR),
Second->Buffer,
Second->Length );
if( Deallocate ) RtlFreeUnicodeString(ResultFirst);
ResultFirst->Length += Second->Length;
ResultFirst->MaximumLength = ResultFirst->Length;
new_string[ResultFirst->Length / sizeof(WCHAR)] = 0;
Status = RtlCreateUnicodeString(ResultFirst,new_string) ?
STATUS_SUCCESS : STATUS_NO_MEMORY;
ExFreePool(new_string);
return Status;
}
/*
* 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 ReadRegistryValue( PUNICODE_STRING KeyName,
PUNICODE_STRING ValueName,
PUNICODE_STRING ReturnedValue ) {
NTSTATUS Status;
HANDLE KeyHandle;
OBJECT_ATTRIBUTES KeyAttributes;
PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
ULONG Length = 0;
ULONG ResLength = 0;
UNICODE_STRING Temp;
InitializeObjectAttributes(&KeyAttributes, KeyName, OBJ_CASE_INSENSITIVE,
NULL, NULL);
Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &KeyAttributes);
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 =
ExAllocatePool(PagedPool, ResLength);
Length = ResLength;
if( !KeyValuePartialInfo ) {
NtClose(KeyHandle);
return STATUS_NO_MEMORY;
}
Status = ZwQueryValueKey(KeyHandle, ValueName, KeyValuePartialInformation,
(PVOID)KeyValuePartialInfo,
Length,
&ResLength);
if( !NT_SUCCESS(Status) ) {
NtClose(KeyHandle);
ExFreePool(KeyValuePartialInfo);
return Status;
}
Temp.Length = Temp.MaximumLength = KeyValuePartialInfo->DataLength;
Temp.Buffer = (PWCHAR)KeyValuePartialInfo->Data;
/* At this point, KeyValuePartialInfo->Data contains the key data */
RtlInitUnicodeString(ReturnedValue,L"");
ReallyAppendUnicodeString(ReturnedValue,&Temp,FALSE);
ExFreePool(KeyValuePartialInfo);
NtClose(KeyHandle);
return Status;
}
typedef PVOID (*KbdLayerDescriptor)(VOID);
NTSTATUS STDCALL LdrGetProcedureAddress(PVOID module,
PANSI_STRING import_name,
@ -400,31 +509,113 @@ NTSTATUS STDCALL LdrGetProcedureAddress(PVOID module,
PVOID *func_addr);
void InitKbdLayout( PVOID *pkKeyboardLayout ) {
UNICODE_STRING KeyName;
UNICODE_STRING ValueName;
UNICODE_STRING LayoutKeyName;
UNICODE_STRING LayoutValueName;
UNICODE_STRING DefaultLocale;
UNICODE_STRING LayoutFile;
UNICODE_STRING FullLayoutPath;
PWCHAR KeyboardLayoutWSTR;
HMODULE kbModule = 0;
NTSTATUS Status;
ANSI_STRING kbdProcedureName;
//NTSTATUS Status;
KbdLayerDescriptor layerDescGetFn;
kbModule = EngLoadImage(L"\\SystemRoot\\system32\\kbdus.dll");
#define XX_STATUS(x) if (!NT_SUCCESS(Status = (x))) continue;
if( !kbModule ) {
DbgPrint( "Foo: No kbdus.dll\n" );
return;
do {
RtlInitUnicodeString(&KeyName,
L"\\REGISTRY\\Machine\\SYSTEM\\CurrentControlSet"
L"\\Control\\Nls\\Locale");
RtlInitUnicodeString(&ValueName,
L"(Default)");
DPRINT("KeyName = %wZ, ValueName = %wZ\n", &KeyName, &ValueName);
Status = ReadRegistryValue(&KeyName,&ValueName,&DefaultLocale);
if( !NT_SUCCESS(Status) ) {
DbgPrint( "Could not get default locale (%08x).\n", Status );
return;
}
DPRINT( "DefaultLocale = %wZ\n", &DefaultLocale );
RtlInitUnicodeString(&LayoutKeyName,
L"\\REGISTRY\\Machine\\SYSTEM\\CurrentControlSet"
L"\\Control\\KeyboardLayouts\\");
ReallyAppendUnicodeString(&LayoutKeyName,&DefaultLocale,FALSE);
RtlFreeUnicodeString(&DefaultLocale);
RtlInitUnicodeString(&LayoutValueName,L"Layout File");
Status = ReadRegistryValue(&LayoutKeyName,&LayoutValueName,&LayoutFile);
if( !NT_SUCCESS(Status) ) {
DbgPrint("Got default locale but not layout file. (%08x)\n",
Status);
return;
}
DPRINT("Read registry and got %wZ\n", &LayoutFile);
RtlFreeUnicodeString(&LayoutKeyName);
RtlInitUnicodeString(&FullLayoutPath,SYSTEMROOT_DIR);
ReallyAppendUnicodeString(&FullLayoutPath,&LayoutFile,FALSE);
DPRINT("Loading Keyboard DLL %wZ\n", &FullLayoutPath);
RtlFreeUnicodeString(&LayoutFile);
KeyboardLayoutWSTR = ExAllocatePool(PagedPool,
(FullLayoutPath.Length + 1) *
sizeof(WCHAR));
if( !KeyboardLayoutWSTR ) {
DbgPrint("Couldn't allocate a string for the keyboard layout name.\n");
RtlFreeUnicodeString(&FullLayoutPath);
return;
}
memcpy(KeyboardLayoutWSTR,FullLayoutPath.Buffer,
(FullLayoutPath.Length + 1) * sizeof(WCHAR));
KeyboardLayoutWSTR[FullLayoutPath.Length] = 0;
kbModule = EngLoadImage(KeyboardLayoutWSTR);
DPRINT( "Load Keyboard Layout: %S\n", KeyboardLayoutWSTR );
if( !kbModule ) {
DbgPrint( "Load Keyboard Layout: No %wZ\n", &FullLayoutPath );
RtlFreeUnicodeString(&FullLayoutPath);
return;
}
RtlFreeUnicodeString(&FullLayoutPath);
RtlInitAnsiString( &kbdProcedureName, "KbdLayerDescriptor" );
LdrGetProcedureAddress((PVOID)kbModule,
&kbdProcedureName,
0,
(PVOID*)&layerDescGetFn);
if( layerDescGetFn ) {
*pkKeyboardLayout = layerDescGetFn();
}
} while (FALSE);
if( !*pkKeyboardLayout ) {
DbgPrint("Failed to load the keyboard layout.\n");
}
RtlInitAnsiString( &kbdProcedureName, "KbdLayerDescriptor" );
LdrGetProcedureAddress((PVOID)kbModule,
&kbdProcedureName,
0,
(PVOID*)&layerDescGetFn);
if( layerDescGetFn ) {
*pkKeyboardLayout = layerDescGetFn();
}
#undef XX_STATUS
}
PKBDTABLES W32kGetDefaultKeyLayout() {
if( !pkKeyboardLayout ) InitKbdLayout( (PVOID) &pkKeyboardLayout );
PKBDTABLES pkKeyboardLayout = 0;
InitKbdLayout( (PVOID) &pkKeyboardLayout );
return pkKeyboardLayout;
}