diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 7349d865f01..08a00c0e647 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -114,25 +114,6 @@ static HKL get_locale_kbd_layout(void) } -/********************************************************************** - * keyboard_init - */ -void keyboard_init(void) -{ - WCHAR layout[KL_NAMELENGTH]; - HKEY hkey; - - if (RegCreateKeyExW( HKEY_CURRENT_USER, L"Keyboard Layout\\Preload", 0, NULL, 0, - KEY_ALL_ACCESS, NULL, &hkey, NULL )) - return; - - if (GetKeyboardLayoutNameW( layout )) - RegSetValueExW( hkey, L"1", 0, REG_SZ, (const BYTE *)layout, sizeof(layout) ); - - RegCloseKey( hkey ); -} - - /********************************************************************** * set_capture_window */ @@ -754,66 +735,11 @@ BOOL WINAPI GetKeyboardLayoutNameA(LPSTR pszKLID) { WCHAR buf[KL_NAMELENGTH]; - if (GetKeyboardLayoutNameW(buf)) + if (NtUserGetKeyboardLayoutName( buf )) return WideCharToMultiByte( CP_ACP, 0, buf, -1, pszKLID, KL_NAMELENGTH, NULL, NULL ) != 0; return FALSE; } -/**************************************************************************** - * GetKeyboardLayoutNameW (USER32.@) - */ -BOOL WINAPI GetKeyboardLayoutNameW( WCHAR *name ) -{ - struct user_thread_info *info = get_user_thread_info(); - WCHAR klid[KL_NAMELENGTH], value[5]; - DWORD value_size, tmp, i = 0; - HKEY hkey; - HKL layout; - - TRACE_(keyboard)( "name %p\n", name ); - - if (!name) - { - SetLastError( ERROR_NOACCESS ); - return FALSE; - } - - if (info->kbd_layout_id) - { - swprintf( name, KL_NAMELENGTH, L"%08X", info->kbd_layout_id ); - return TRUE; - } - - layout = NtUserGetKeyboardLayout( 0 ); - tmp = HandleToUlong( layout ); - if (HIWORD( tmp ) == LOWORD( tmp )) tmp = LOWORD( tmp ); - swprintf( name, KL_NAMELENGTH, L"%08X", tmp ); - - if (!RegOpenKeyW( HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\Keyboard Layouts", &hkey )) - { - while (!RegEnumKeyW( hkey, i++, klid, ARRAY_SIZE(klid) )) - { - value_size = sizeof(value); - if (!RegGetValueW( hkey, klid, L"Layout Id", RRF_RT_REG_SZ, NULL, (void *)&value, &value_size )) - tmp = 0xf000 | (wcstoul( value, NULL, 16 ) & 0xfff); - else - tmp = wcstoul( klid, NULL, 16 ); - - if (HIWORD( layout ) == tmp) - { - lstrcpynW( name, klid, KL_NAMELENGTH ); - break; - } - } - RegCloseKey( hkey ); - } - - info->kbd_layout_id = wcstoul( name, NULL, 16 ); - - TRACE_(keyboard)( "ret %s\n", debugstr_w( name ) ); - return TRUE; -} - /**************************************************************************** * GetKeyNameTextA (USER32.@) */ diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index 8b8dcb611f9..20d89c14a84 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -320,7 +320,7 @@ @ stdcall GetKeyboardLayout(long) NtUserGetKeyboardLayout @ stdcall GetKeyboardLayoutList(long ptr) NtUserGetKeyboardLayoutList @ stdcall GetKeyboardLayoutNameA(ptr) -@ stdcall GetKeyboardLayoutNameW(ptr) +@ stdcall GetKeyboardLayoutNameW(ptr) NtUserGetKeyboardLayoutName @ stdcall -import GetKeyboardState(ptr) NtUserGetKeyboardState @ stdcall GetKeyboardType(long) @ stdcall GetLastActivePopup(long) diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 20d3d386871..e489bcda17a 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -236,7 +236,6 @@ static BOOL process_attach(void) /* Setup palette function pointers */ palette_init(); - keyboard_init(); return TRUE; } diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 79e8b3fd3eb..c2152900a9b 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -161,7 +161,6 @@ extern BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hard extern BOOL rawinput_device_get_usages(HANDLE handle, USAGE *usage_page, USAGE *usage); extern struct rawinput_thread_data *rawinput_thread_data(void); -extern void keyboard_init(void) DECLSPEC_HIDDEN; extern void create_offscreen_window_surface( const RECT *visible_rect, struct window_surface **surface ) DECLSPEC_HIDDEN; extern void CLIPBOARD_ReleaseOwner( HWND hwnd ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index 40467bb82f5..2be3122961b 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -49,7 +49,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(font); static HKEY wine_fonts_key; static HKEY wine_fonts_cache_key; -static HKEY hkcu_key; +HKEY hkcu_key; struct font_physdev { diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index bc3cd17a29e..90a77639d1a 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -33,6 +33,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(win); WINE_DECLARE_DEBUG_CHANNEL(keyboard); +static const WCHAR keyboard_layouts_keyW[] = +{ + '\\','R','e','g','i','s','t','r','y', + '\\','M','a','c','h','i','n','e', + '\\','S','y','s','t','e','m', + '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t', + '\\','C','o','n','t','r','o','l', + '\\','K','e','y','b','o','a','r','d',' ','L','a','y','o','u','t','s' +}; + /********************************************************************** * NtUserAttachThreadInput (win32u.@) @@ -618,16 +628,6 @@ UINT WINAPI NtUserGetKeyboardLayoutList( INT size, HKL *layouts ) HKEY hkey, subkey; HKL layout; - static const WCHAR keyboard_layouts_keyW[] = - { - '\\','R','e','g','i','s','t','r','y', - '\\','M','a','c','h','i','n','e', - '\\','S','y','s','t','e','m', - '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t', - '\\','C','o','n','t','r','o','l', - '\\','K','e','y','b','o','a','r','d',' ','L','a','y','o','u','t','s' - }; - TRACE_(keyboard)( "size %d, layouts %p.\n", size, layouts ); if ((count = user_driver->pGetKeyboardLayoutList( size, layouts )) != ~0) return count; @@ -671,6 +671,71 @@ UINT WINAPI NtUserGetKeyboardLayoutList( INT size, HKL *layouts ) return count; } +/**************************************************************************** + * NtUserGetKeyboardLayoutName (win32u.@) + */ +BOOL WINAPI NtUserGetKeyboardLayoutName( WCHAR *name ) +{ + struct user_thread_info *info = get_user_thread_info(); + char buffer[4096]; + KEY_NODE_INFORMATION *key = (KEY_NODE_INFORMATION *)buffer; + KEY_VALUE_PARTIAL_INFORMATION *value = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; + WCHAR klid[KL_NAMELENGTH]; + DWORD tmp, i = 0; + HKEY hkey, subkey; + HKL layout; + + TRACE_(keyboard)( "name %p\n", name ); + + if (!name) + { + SetLastError( ERROR_NOACCESS ); + return FALSE; + } + + if (info->kbd_layout_id) + { + sprintf( buffer, "%08X", info->kbd_layout_id ); + asciiz_to_unicode( name, buffer ); + return TRUE; + } + + layout = NtUserGetKeyboardLayout( 0 ); + tmp = HandleToUlong( layout ); + if (HIWORD( tmp ) == LOWORD( tmp )) tmp = LOWORD( tmp ); + sprintf( buffer, "%08X", tmp ); + asciiz_to_unicode( name, buffer ); + + if ((hkey = reg_open_key( NULL, keyboard_layouts_keyW, sizeof(keyboard_layouts_keyW) ))) + { + while (!NtEnumerateKey( hkey, i++, KeyNodeInformation, key, + sizeof(buffer) - sizeof(WCHAR), &tmp )) + { + if (!(subkey = reg_open_key( hkey, key->Name, key->NameLength ))) continue; + memcpy( klid, key->Name, key->NameLength ); + klid[key->NameLength / sizeof(WCHAR)] = 0; + if (query_reg_ascii_value( subkey, "Layout Id", value, sizeof(buffer) ) && + value->Type == REG_SZ) + tmp = 0xf000 | (wcstoul( (const WCHAR *)value->Data, NULL, 16 ) & 0xfff); + else + tmp = wcstoul( klid, NULL, 16 ); + NtClose( subkey ); + + if (HIWORD( layout ) == tmp) + { + lstrcpynW( name, klid, KL_NAMELENGTH ); + break; + } + } + NtClose( hkey ); + } + + info->kbd_layout_id = wcstoul( name, NULL, 16 ); + + TRACE_(keyboard)( "ret %s\n", debugstr_w( name ) ); + return TRUE; +} + /*********************************************************************** * NtUserUnregisterHotKey (win32u.@) */ diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index c8f08e3c2a6..2f24bcf5f65 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -114,6 +114,7 @@ static void * const syscalls[] = NtUserGetCursor, NtUserGetKeyState, NtUserGetKeyboardLayout, + NtUserGetKeyboardLayoutName, NtUserGetKeyboardState, NtUserGetLayeredWindowAttributes, NtUserGetMouseMovePointsEx, @@ -150,6 +151,7 @@ static NTSTATUS init( void *dispatcher ) if ((status = ntdll_init_syscalls( 1, &syscall_table, dispatcher ))) return status; if ((status = gdi_init())) return status; winstation_init(); + sysparams_init(); return STATUS_SUCCESS; } diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index d2406672ee6..e0de4edc6e5 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1636,6 +1636,27 @@ static BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info ) return FALSE; } +/********************************************************************** + * sysparams_init + */ +void sysparams_init(void) +{ + WCHAR layout[KL_NAMELENGTH]; + HKEY hkey; + + static const WCHAR oneW[] = {'1',0}; + static const WCHAR kl_preloadW[] = + {'K','e','y','b','o','a','r','d',' ','L','a','y','o','u','t','\\','P','r','e','l','o','a','d'}; + + if ((hkey = reg_create_key( hkcu_key, kl_preloadW, sizeof(kl_preloadW), 0, NULL ))) + { + if (NtUserGetKeyboardLayoutName( layout )) + set_reg_value( hkey, oneW, REG_SZ, (const BYTE *)layout, + (lstrlenW(layout) + 1) * sizeof(WCHAR) ); + NtClose( hkey ); + } +} + ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code ) { switch(code) diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 7d3421efbcc..8499d52e32c 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -948,7 +948,7 @@ @ stdcall -syscall NtUserGetKeyState(long) @ stdcall -syscall NtUserGetKeyboardLayout(long) @ stdcall NtUserGetKeyboardLayoutList(long ptr) -@ stub NtUserGetKeyboardLayoutName +@ stdcall -syscall NtUserGetKeyboardLayoutName(ptr) @ stdcall -syscall NtUserGetKeyboardState(ptr) @ stdcall -syscall NtUserGetLayeredWindowAttributes(long ptr ptr ptr) @ stub NtUserGetListBoxInfo diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index c8b5e0f4246..7fbc92cde7b 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -250,6 +250,7 @@ extern void wrappers_init( unixlib_handle_t handle ) DECLSPEC_HIDDEN; extern NTSTATUS gdi_init(void) DECLSPEC_HIDDEN; extern NTSTATUS callbacks_init( void *args ) DECLSPEC_HIDDEN; extern void winstation_init(void) DECLSPEC_HIDDEN; +extern void sysparams_init(void) DECLSPEC_HIDDEN; extern HKEY reg_create_key( HKEY root, const WCHAR *name, ULONG name_len, DWORD options, DWORD *disposition ) DECLSPEC_HIDDEN; @@ -264,6 +265,8 @@ extern void set_reg_value( HKEY hkey, const WCHAR *name, UINT type, const void * DWORD count ) DECLSPEC_HIDDEN; extern BOOL reg_delete_tree( HKEY parent, const WCHAR *name, ULONG name_len ) DECLSPEC_HIDDEN; +extern HKEY hkcu_key DECLSPEC_HIDDEN; + static inline struct user_thread_info *get_user_thread_info(void) { return (struct user_thread_info *)NtCurrentTeb()->Win32ClientInfo; diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h index 7a148935444..99ed465cbc3 100644 --- a/dlls/wow64win/syscall.h +++ b/dlls/wow64win/syscall.h @@ -101,6 +101,7 @@ SYSCALL_ENTRY( NtUserGetCursor ) \ SYSCALL_ENTRY( NtUserGetKeyState ) \ SYSCALL_ENTRY( NtUserGetKeyboardLayout ) \ + SYSCALL_ENTRY( NtUserGetKeyboardLayoutName ) \ SYSCALL_ENTRY( NtUserGetKeyboardState ) \ SYSCALL_ENTRY( NtUserGetLayeredWindowAttributes ) \ SYSCALL_ENTRY( NtUserGetMouseMovePointsEx ) \ diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index eea3879b9b5..9962b0b442a 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -262,6 +262,13 @@ NTSTATUS WINAPI wow64_NtUserGetKeyboardLayout( UINT *args ) return HandleToUlong( NtUserGetKeyboardLayout( tid )); } +NTSTATUS WINAPI wow64_NtUserGetKeyboardLayoutName( UINT *args ) +{ + WCHAR *name = get_ptr( &args ); + + return NtUserGetKeyboardLayoutName( name ); +} + NTSTATUS WINAPI wow64_NtUserGetKeyboardState( UINT *args ) { BYTE *state = get_ptr( &args ); diff --git a/include/ntuser.h b/include/ntuser.h index e962c5b3fa2..3904daf5a82 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -105,6 +105,7 @@ INT WINAPI NtUserGetKeyNameText( LONG lparam, WCHAR *buffer, INT size ); SHORT WINAPI NtUserGetKeyState( INT vkey ); HKL WINAPI NtUserGetKeyboardLayout( DWORD thread_id ); UINT WINAPI NtUserGetKeyboardLayoutList( INT size, HKL *layouts ); +BOOL WINAPI NtUserGetKeyboardLayoutName( WCHAR *name ); BOOL WINAPI NtUserGetKeyboardState( BYTE *state ); BOOL WINAPI NtUserGetLayeredWindowAttributes( HWND hwnd, COLORREF *key, BYTE *alpha, DWORD *flags ); int WINAPI NtUserGetMouseMovePointsEx( UINT size, MOUSEMOVEPOINT *ptin, MOUSEMOVEPOINT *ptout,