Author: jimtabor
Date: Mon Oct 30 22:38:37 2006
New Revision: 24683
URL:
http://svn.reactos.org/svn/reactos?rev=24683&view=rev
Log:
Part of the Win32k User32 Compatibility Project.
- Create IntLoadKeyboardLayout
- Code assimilated from win32k ntuser keyboard.c and Wine.
- Process and load a new keyboard layout.
- Creates the HKL for processing in NtUserLoadKeyboardLayoutEx.
- Load and computes module offset so NtUserLoadKeyboardLayoutEx can process it (read it
in), load (EngLoadImage) and set the table entry point. This data is saved in a new
structure connected to a list of keyboard layouts that was created during win32k init.
Modified:
trunk/reactos/dll/win32/user32/windows/input.c
Modified: trunk/reactos/dll/win32/user32/windows/input.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/i…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/input.c (original)
+++ trunk/reactos/dll/win32/user32/windows/input.c Mon Oct 30 22:38:37 2006
@@ -32,8 +32,12 @@
#include <wine/debug.h>
+
+/* Directory to load key layouts from */
+#define SYSTEMROOT_DIR L"\\SystemRoot\\System32\\"
+
+
/* GLOBALS *******************************************************************/
-
typedef struct __TRACKINGLIST {
TRACKMOUSEEVENT tme;
@@ -44,6 +48,209 @@
static _TRACKINGLIST tracking_info;
static UINT_PTR timer;
static const INT iTimerInterval = 50; /* msec for timer interval */
+
+
+/* LOCALE 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 FASTCALL
+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 = LocalAlloc(LMEM_ZEROINIT, 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);
+ LocalFree(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"");
+ RtlAppendUnicodeStringToString(ReturnedValue,&Temp);
+
+ LocalFree(KeyValuePartialInfo);
+ NtClose(KeyHandle);
+
+ return Status;
+}
+
+
+static
+HKL FASTCALL
+IntLoadKeyboardLayout( LPCWSTR pwszKLID,
+ UINT Flags)
+{
+ HANDLE Handle;
+ HINSTANCE KBModule = 0;
+ FARPROC pAddr = 0;
+ DWORD offTable = 0;
+ HKL hKL;
+ NTSTATUS Status;
+ WCHAR LocaleBuffer[16];
+ UNICODE_STRING LayoutKeyName;
+ UNICODE_STRING LayoutValueName;
+ UNICODE_STRING DefaultLocale;
+ UNICODE_STRING LayoutFile;
+ UNICODE_STRING FullLayoutPath;
+ LCID LocaleId;
+ PWCHAR KeyboardLayoutWSTR;
+ ULONG_PTR layout;
+ LANGID langid;
+
+ layout = (ULONG_PTR) wcstoul(pwszKLID, NULL, 16);
+
+// LocaleId = GetSystemDefaultLCID();
+
+ LocaleId = (LCID) layout;
+
+ /* Create the HKL to be used by NtUserLoadKeyboardLayoutEx*/
+ /*
+ * Microsoft Office expects this value to be something specific
+ * for Japanese and Korean Windows with an IME the value is 0xe001
+ * We should probably check to see if an IME exists and if so then
+ * set this word properly.
+ */
+ langid = PRIMARYLANGID(LANGIDFROMLCID(layout));
+ if (langid == LANG_CHINESE || langid == LANG_JAPANESE || langid == LANG_KOREAN)
+ layout |= 0xe001 << 16; /* FIXME */
+ else
+ layout |= layout << 16;
+
+ DPRINT("Input = %S\n", pwszKLID );
+
+ DPRINT("DefaultLocale = %lx\n", LocaleId);
+
+ swprintf(LocaleBuffer, L"%08lx", LocaleId);
+
+ DPRINT("DefaultLocale = %S\n", LocaleBuffer);
+ RtlInitUnicodeString(&DefaultLocale, LocaleBuffer);
+
+ RtlInitUnicodeString(&LayoutKeyName,
+ L"\\REGISTRY\\Machine\\SYSTEM\\CurrentControlSet"
+ L"\\Control\\KeyboardLayouts\\");
+
+ RtlAppendUnicodeStringToString(&LayoutKeyName,&DefaultLocale);
+
+ RtlInitUnicodeString(&LayoutValueName,L"Layout File");
+
+ Status = ReadRegistryValue(&LayoutKeyName,&LayoutValueName,&LayoutFile);
+
+ RtlFreeUnicodeString(&LayoutKeyName);
+
+ DPRINT("Read registry and got %wZ\n", &LayoutFile);
+
+ RtlInitUnicodeString(&FullLayoutPath,SYSTEMROOT_DIR);
+ RtlAppendUnicodeStringToString(&FullLayoutPath,&LayoutFile);
+
+ DPRINT("Loading Keyboard DLL %wZ\n", &FullLayoutPath);
+
+ RtlFreeUnicodeString(&LayoutFile);
+
+ KeyboardLayoutWSTR = LocalAlloc(LMEM_ZEROINIT,
+ FullLayoutPath.Length + sizeof(WCHAR));
+
+ if( !KeyboardLayoutWSTR )
+ {
+ DPRINT1("Couldn't allocate a string for the keyboard layout
name.\n");
+ RtlFreeUnicodeString(&FullLayoutPath);
+ return NULL;
+ }
+ memcpy(KeyboardLayoutWSTR,FullLayoutPath.Buffer, FullLayoutPath.Length);
+
+ KeyboardLayoutWSTR[FullLayoutPath.Length / sizeof(WCHAR)] = 0;
+
+ KBModule = LoadLibraryW(KeyboardLayoutWSTR);
+
+ DPRINT( "Load Keyboard Layout: %S\n", KeyboardLayoutWSTR );
+
+ if( !KBModule )
+ DPRINT1( "Load Keyboard Layout: No %wZ\n", &FullLayoutPath );
+
+ pAddr = GetProcAddress( KBModule, (LPCSTR) 1);
+ offTable = (DWORD) pAddr - (DWORD) KBModule; // Weeks to figure this out!
+
+ DPRINT( "Load Keyboard Module Offset: %x\n", offTable );
+
+ FreeLibrary(KBModule);
+
+ Handle = CreateFileW( KeyboardLayoutWSTR,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+
+ hKL = NtUserLoadKeyboardLayoutEx( Handle,
+ offTable,
+ (HKL) layout,
+ &DefaultLocale,
+ (UINT) layout,
+ Flags);
+
+ NtClose(Handle);
+
+ LocalFree(KeyboardLayoutWSTR);
+ RtlFreeUnicodeString(&FullLayoutPath);
+
+ return hKL;
+}
/* FUNCTIONS *****************************************************************/
@@ -315,19 +522,17 @@
ret = LoadKeyboardLayoutW(pwszKLIDW.Buffer, Flags);
RtlFreeUnicodeString(&pwszKLIDW);
return ret;
-
-}
-
-
-/*
- * @unimplemented
+}
+
+
+/*
+ * @implemented
*/
HKL STDCALL
LoadKeyboardLayoutW(LPCWSTR pwszKLID,
UINT Flags)
{
- UNIMPLEMENTED;
- return (HKL)0;
+ return IntLoadKeyboardLayout( pwszKLID, Flags);
}