From 9b1c1240b270142564a8ef9350720c92004efcc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Fri, 6 Jan 2023 11:22:10 +0100 Subject: [PATCH 2/9] winex11: Always create the HKCU configuration registry key. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=30984 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45605 --- dlls/winex11.drv/x11drv_main.c | 67 ++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 797e4f92d38..e04bdedd43a 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -356,11 +356,61 @@ HKEY reg_open_key( HKEY root, const WCHAR *name, ULONG name_len ) return NtOpenKeyEx( &ret, MAXIMUM_ALLOWED, &attr, 0 ) ? 0 : ret; } +/* wrapper for NtCreateKey that creates the key recursively if necessary */ +static HKEY reg_create_key( HKEY root, const WCHAR *name, ULONG name_len, + DWORD options, DWORD *disposition ) +{ + UNICODE_STRING nameW = { name_len, name_len, (WCHAR *)name }; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + HANDLE ret; -HKEY open_hkcu_key( const char *name ) + attr.Length = sizeof(attr); + attr.RootDirectory = root; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + status = NtCreateKey( &ret, MAXIMUM_ALLOWED, &attr, 0, NULL, options, disposition ); + if (status == STATUS_OBJECT_NAME_NOT_FOUND) + { + static const WCHAR registry_rootW[] = { '\\','R','e','g','i','s','t','r','y','\\' }; + DWORD pos = 0, i = 0, len = name_len / sizeof(WCHAR); + + /* don't try to create registry root */ + if (!root && len > ARRAY_SIZE(registry_rootW) && + !memcmp( name, registry_rootW, sizeof(registry_rootW) )) + i += ARRAY_SIZE(registry_rootW); + + while (i < len && name[i] != '\\') i++; + if (i == len) return 0; + for (;;) + { + unsigned int subkey_options = options; + if (i < len) subkey_options &= ~(REG_OPTION_CREATE_LINK | REG_OPTION_OPEN_LINK); + nameW.Buffer = (WCHAR *)name + pos; + nameW.Length = (i - pos) * sizeof(WCHAR); + status = NtCreateKey( &ret, MAXIMUM_ALLOWED, &attr, 0, NULL, subkey_options, disposition ); + + if (attr.RootDirectory != root) NtClose( attr.RootDirectory ); + if (!NT_SUCCESS(status)) return 0; + if (i == len) break; + attr.RootDirectory = ret; + while (i < len && name[i] == '\\') i++; + pos = i; + while (i < len && name[i] != '\\') i++; + } + } + return ret; +} + +static HKEY reg_open_hkcu_key( const char *name, BOOL create ) { WCHAR bufferW[256]; static HKEY hkcu; + DWORD disp; + HKEY key; if (!hkcu) { @@ -385,7 +435,18 @@ HKEY open_hkcu_key( const char *name ) hkcu = reg_open_key( NULL, bufferW, len * sizeof(WCHAR) ); } - return reg_open_key( hkcu, bufferW, asciiz_to_unicode( bufferW, name ) - sizeof(WCHAR) ); + if ((key = reg_open_key( hkcu, bufferW, asciiz_to_unicode( bufferW, name ) - sizeof(WCHAR) )) || !create) return key; + return reg_create_key( hkcu, bufferW, asciiz_to_unicode( bufferW, name ) - sizeof(WCHAR), 0, &disp ); +} + +HKEY open_hkcu_key( const char *name ) +{ + return reg_open_hkcu_key( name, FALSE ); +} + +static HKEY create_hkcu_key( const char *name ) +{ + return reg_open_hkcu_key( name, TRUE ); } @@ -449,7 +510,7 @@ static void setup_options(void) DWORD len; /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */ - hkey = open_hkcu_key( "Software\\Wine\\X11 Driver" ); + hkey = create_hkcu_key( "Software\\Wine\\X11 Driver" ); /* open the app-specific key */ -- 2.39.1