Jacek Caban : winex11: Directly use ntdll for registry access in setup_options.

Alexandre Julliard julliard at winehq.org
Mon Apr 11 15:54:59 CDT 2022


Module: wine
Branch: master
Commit: a3ebf88ad5da03a78b74b2a5a756b36eb29b6cb3
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=a3ebf88ad5da03a78b74b2a5a756b36eb29b6cb3

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Apr  8 13:29:16 2022 +0200

winex11: Directly use ntdll for registry access in setup_options.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winex11.drv/x11drv.h      |  16 +++++-
 dlls/winex11.drv/x11drv_main.c | 118 ++++++++++++++++++++++++++++++++++-------
 dlls/winex11.drv/xim.c         |  13 +++--
 3 files changed, 124 insertions(+), 23 deletions(-)

diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index f22b7f4f25e..252505f80e6 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -823,7 +823,7 @@ extern void X11DRV_DisplayDevices_Update(BOOL) DECLSPEC_HIDDEN;
 extern struct x11drv_display_device_handler desktop_handler DECLSPEC_HIDDEN;
 
 /* XIM support */
-extern BOOL X11DRV_InitXIM( const char *input_style ) DECLSPEC_HIDDEN;
+extern BOOL X11DRV_InitXIM( const WCHAR *input_style ) DECLSPEC_HIDDEN;
 extern XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data) DECLSPEC_HIDDEN;
 extern void X11DRV_SetupXIM(void) DECLSPEC_HIDDEN;
 extern void X11DRV_XIMLookupChars( const char *str, DWORD count ) DECLSPEC_HIDDEN;
@@ -841,4 +841,18 @@ static inline BOOL is_window_rect_mapped( const RECT *rect )
             max( rect->bottom, rect->top + 1 ) > virtual_rect.top);
 }
 
+/* string helpers */
+
+static inline void ascii_to_unicode( WCHAR *dst, const char *src, size_t len )
+{
+    while (len--) *dst++ = (unsigned char)*src++;
+}
+
+static inline UINT asciiz_to_unicode( WCHAR *dst, const char *src )
+{
+    WCHAR *p = dst;
+    while ((*p++ = *src++));
+    return (p - dst) * sizeof(WCHAR);
+}
+
 #endif  /* __WINE_X11DRV_H */
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index f52e504f468..df3c672708e 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -93,7 +93,7 @@ static int err_callback_result;              /* error callback result */
 static unsigned long err_serial;             /* serial number of first request */
 static int (*old_error_handler)( Display *, XErrorEvent * );
 static BOOL use_xim = TRUE;
-static char input_style[20];
+static WCHAR input_style[20];
 
 static CRITICAL_SECTION x11drv_section;
 static CRITICAL_SECTION_DEBUG critsect_debug =
@@ -336,16 +336,99 @@ static void init_pixmap_formats( Display *display )
 }
 
 
+static HKEY reg_open_key( HKEY root, const WCHAR *name, ULONG name_len )
+{
+    UNICODE_STRING nameW = { name_len, name_len, (WCHAR *)name };
+    OBJECT_ATTRIBUTES attr;
+    HANDLE ret;
+
+    attr.Length = sizeof(attr);
+    attr.RootDirectory = root;
+    attr.ObjectName = &nameW;
+    attr.Attributes = 0;
+    attr.SecurityDescriptor = NULL;
+    attr.SecurityQualityOfService = NULL;
+
+    return NtOpenKeyEx( &ret, MAXIMUM_ALLOWED, &attr, 0 ) ? 0 : ret;
+}
+
+
+static HKEY open_hkcu_key( const char *name )
+{
+    WCHAR bufferW[256];
+    static HKEY hkcu;
+
+    if (!hkcu)
+    {
+        char buffer[256];
+        DWORD_PTR sid_data[(sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE) / sizeof(DWORD_PTR)];
+        DWORD i, len = sizeof(sid_data);
+        SID *sid;
+
+        if (NtQueryInformationToken( GetCurrentThreadEffectiveToken(), TokenUser, sid_data, len, &len ))
+            return 0;
+
+        sid = ((TOKEN_USER *)sid_data)->User.Sid;
+        len = sprintf( buffer, "\\Registry\\User\\S-%u-%u", sid->Revision,
+                       MAKELONG( MAKEWORD( sid->IdentifierAuthority.Value[5],
+                                           sid->IdentifierAuthority.Value[4] ),
+                                 MAKEWORD( sid->IdentifierAuthority.Value[3],
+                                           sid->IdentifierAuthority.Value[2] )));
+        for (i = 0; i < sid->SubAuthorityCount; i++)
+            len += sprintf( buffer + len, "-%u", sid->SubAuthority[i] );
+
+        ascii_to_unicode( bufferW, buffer, len );
+        hkcu = reg_open_key( NULL, bufferW, len * sizeof(WCHAR) );
+    }
+
+    return reg_open_key( hkcu, bufferW, asciiz_to_unicode( bufferW, name ) - sizeof(WCHAR) );
+}
+
+
+static ULONG query_reg_value( HKEY hkey, const WCHAR *name,
+                              KEY_VALUE_PARTIAL_INFORMATION *info, ULONG size )
+{
+    unsigned int name_size = name ? lstrlenW( name ) * sizeof(WCHAR) : 0;
+    UNICODE_STRING nameW = { name_size, name_size, (WCHAR *)name };
+
+    if (NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation,
+                         info, size, &size ))
+        return 0;
+
+    return size - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
+}
+
+
 /***********************************************************************
  *		get_config_key
  *
  * Get a config key from either the app-specific or the default config
  */
 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
-                                    char *buffer, DWORD size )
+                                    WCHAR *buffer, DWORD size )
 {
-    if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
-    if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
+    WCHAR nameW[128];
+    char buf[2048];
+    KEY_VALUE_PARTIAL_INFORMATION *info = (void *)buf;
+
+    asciiz_to_unicode( nameW, name );
+
+    if (appkey && query_reg_value( appkey, nameW, info, sizeof(buf) ))
+    {
+        size = min( info->DataLength, size - sizeof(WCHAR) );
+        memcpy( buffer, info->Data, size );
+        buffer[size / sizeof(WCHAR)] = 0;
+        return 0;
+    }
+
+    if (defkey && query_reg_value( defkey, nameW, info, sizeof(buf) ))
+    {
+        size = min( info->DataLength, size - sizeof(WCHAR) );
+        memcpy( buffer, info->Data, size );
+        buffer[size / sizeof(WCHAR)] = 0;
+        return 0;
+    }
+
     return ERROR_FILE_NOT_FOUND;
 }
 
@@ -358,21 +441,20 @@ static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
 static void setup_options(void)
 {
     static const WCHAR x11driverW[] = {'\\','X','1','1',' ','D','r','i','v','e','r',0};
-    char buffer[64];
-    WCHAR bufferW[MAX_PATH+16];
+    WCHAR buffer[MAX_PATH+16];
     HKEY hkey, appkey = 0;
     DWORD len;
 
     /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */
-    if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0;
+    hkey = open_hkcu_key( "Software\\Wine\\X11 Driver" );
 
     /* open the app-specific key */
 
-    len = (GetModuleFileNameW( 0, bufferW, MAX_PATH ));
+    len = GetModuleFileNameW( 0, buffer, MAX_PATH );
     if (len && len < MAX_PATH)
     {
         HKEY tmpkey;
-        WCHAR *p, *appname = bufferW;
+        WCHAR *p, *appname = buffer;
         if ((p = strrchrW( appname, '/' ))) appname = p + 1;
         if ((p = strrchrW( appname, '\\' ))) appname = p + 1;
         CharLowerW(appname);
@@ -381,10 +463,10 @@ static void setup_options(void)
             WideCharToMultiByte( CP_UNIXCP, 0, appname, -1, process_name, len, NULL, NULL );
         strcatW( appname, x11driverW );
         /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */
-        if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
+        if ((tmpkey = open_hkcu_key( "Software\\Wine\\AppDefaults" )))
         {
-            if (RegOpenKeyW( tmpkey, appname, &appkey )) appkey = 0;
-            RegCloseKey( tmpkey );
+            appkey = reg_open_key( tmpkey, appname, lstrlenW( appname ) * sizeof(WCHAR) );
+            NtClose( tmpkey );
         }
     }
 
@@ -419,7 +501,7 @@ static void setup_options(void)
         grab_fullscreen = IS_OPTION_TRUE( buffer[0] );
 
     if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
-        default_visual.depth = atoi(buffer);
+        default_visual.depth = strtolW( buffer, NULL, 0 );
 
     if (!get_config_key( hkey, appkey, "ClientSideGraphics", buffer, sizeof(buffer) ))
         client_side_graphics = IS_OPTION_TRUE( buffer[0] );
@@ -437,18 +519,18 @@ static void setup_options(void)
         private_color_map = IS_OPTION_TRUE( buffer[0] );
 
     if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
-        primary_monitor = atoi( buffer );
+        primary_monitor = strtolW( buffer, NULL, 0 );
 
     if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
-        copy_default_colors = atoi(buffer);
+        copy_default_colors = strtolW( buffer, NULL, 0 );
 
     if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
-        alloc_system_colors = atoi(buffer);
+        alloc_system_colors = strtolW( buffer, NULL, 0 );
 
     get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
 
-    if (appkey) RegCloseKey( appkey );
-    if (hkey) RegCloseKey( hkey );
+    NtClose( appkey );
+    NtClose( hkey );
 }
 
 #ifdef SONAME_LIBXCOMPOSITE
diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c
index 3994c2106cc..6adf2475de7 100644
--- a/dlls/winex11.drv/xim.c
+++ b/dlls/winex11.drv/xim.c
@@ -30,6 +30,7 @@
 #include "x11drv.h"
 #include "imm.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(xim);
 
@@ -290,13 +291,17 @@ void X11DRV_SetPreeditState(HWND hwnd, BOOL fOpen)
  *
  * Process-wide XIM initialization.
  */
-BOOL X11DRV_InitXIM( const char *input_style )
+BOOL X11DRV_InitXIM( const WCHAR *input_style )
 {
-    if (!_strnicmp(input_style, "offthespot", -1))
+    static const WCHAR offthespotW[] = {'o','f','f','t','h','e','s','p','o','t',0};
+    static const WCHAR overthespotW[] = {'o','v','e','r','t','h','e','s','p','o','t',0};
+    static const WCHAR rootW[] = {'r','o','o','t',0};
+
+    if (!strcmpiW(input_style, offthespotW))
         ximStyleRequest = STYLE_OFFTHESPOT;
-    else if (!_strnicmp(input_style, "overthespot", -1))
+    else if (!strcmpiW(input_style, overthespotW))
         ximStyleRequest = STYLE_OVERTHESPOT;
-    else if (!_strnicmp(input_style, "root", -1))
+    else if (!strcmpiW(input_style, rootW))
         ximStyleRequest = STYLE_ROOT;
 
     if (!XSupportsLocale())




More information about the wine-cvs mailing list