Jacek Caban : winemac: Directly use ntdll for registry access in init_original_display_mode.

Alexandre Julliard julliard at winehq.org
Tue May 17 15:37:22 CDT 2022


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Sun May 15 19:02:54 2022 +0200

winemac: Directly use ntdll for registry access in init_original_display_mode.

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

---

 dlls/winemac.drv/display.c     | 18 +++++-----
 dlls/winemac.drv/macdrv.h      |  5 +++
 dlls/winemac.drv/macdrv_main.c | 79 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 94 insertions(+), 8 deletions(-)

diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c
index 182d5f122a5..7913c5ed7bc 100644
--- a/dlls/winemac.drv/display.c
+++ b/dlls/winemac.drv/display.c
@@ -46,7 +46,8 @@ struct display_mode_descriptor
 
 BOOL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode, LPDEVMODEW devmode, DWORD flags);
 
-static const char initial_mode_key[] = "Initial Display Mode";
+static const WCHAR initial_mode_keyW[] = {'I','n','i','t','i','a','l',' ','D','i','s','p','l','a','y',
+    ' ','M','o','d','e'};
 static const WCHAR pixelencodingW[] = {'P','i','x','e','l','E','n','c','o','d','i','n','g',0};
 
 static CFArrayRef modes;
@@ -301,13 +302,14 @@ static void init_original_display_mode(void)
         return;
 
     /* @@ Wine registry key: HKLM\Software\Wine\Mac Driver */
-    if (RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Mac Driver", 0, NULL,
-                        0, KEY_ALL_ACCESS, NULL, &mac_driver_hkey, NULL))
+    mac_driver_hkey = reg_create_ascii_key(NULL, "\\Registry\\Machine\\Software\\Wine\\Mac Driver",
+                                           0, NULL);
+    if (!mac_driver_hkey)
         return;
 
     /* @@ Wine registry key: HKLM\Software\Wine\Mac Driver\Initial Display Mode */
-    if (RegCreateKeyExA(mac_driver_hkey, initial_mode_key, 0, NULL,
-                        REG_OPTION_VOLATILE, KEY_WRITE, NULL, &parent_hkey, &disposition))
+    if (!(parent_hkey = reg_create_key(mac_driver_hkey, initial_mode_keyW, sizeof(initial_mode_keyW),
+                                       REG_OPTION_VOLATILE, &disposition)))
     {
         parent_hkey = NULL;
         goto fail;
@@ -332,10 +334,10 @@ done:
 
 fail:
     macdrv_free_displays(displays);
-    RegCloseKey(parent_hkey);
+    NtClose(parent_hkey);
     if (!success && parent_hkey)
-        RegDeleteTreeA(mac_driver_hkey, initial_mode_key);
-    RegCloseKey(mac_driver_hkey);
+        reg_delete_tree(mac_driver_hkey, initial_mode_keyW, sizeof(initial_mode_keyW));
+    NtClose(mac_driver_hkey);
     if (success)
         inited_original_display_mode = TRUE;
 }
diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h
index c216cfb994f..922a2df75cb 100644
--- a/dlls/winemac.drv/macdrv.h
+++ b/dlls/winemac.drv/macdrv.h
@@ -297,6 +297,11 @@ extern BOOL query_ime_char_rect(macdrv_query* query) DECLSPEC_HIDDEN;
 
 extern ULONG query_reg_value(HKEY hkey, const WCHAR *name, KEY_VALUE_PARTIAL_INFORMATION *info,
                              ULONG size) DECLSPEC_HIDDEN;
+extern HKEY reg_create_ascii_key(HKEY root, const char *name, DWORD options,
+                                 DWORD *disposition) DECLSPEC_HIDDEN;
+extern HKEY reg_create_key(HKEY root, const WCHAR *name, ULONG name_len,
+                           DWORD options, DWORD *disposition) DECLSPEC_HIDDEN;
+extern BOOL reg_delete_tree(HKEY parent, const WCHAR *name, ULONG name_len) DECLSPEC_HIDDEN;
 extern HKEY reg_open_key(HKEY root, const WCHAR *name, ULONG name_len) DECLSPEC_HIDDEN;
 
 /* string helpers */
diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c
index 134842bbbfb..b168e12439c 100644
--- a/dlls/winemac.drv/macdrv_main.c
+++ b/dlls/winemac.drv/macdrv_main.c
@@ -24,6 +24,8 @@
 #include <Security/AuthSession.h>
 #include <IOKit/pwr_mgt/IOPMLib.h>
 
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
 #include "macdrv.h"
 #include "winuser.h"
 #include "winreg.h"
@@ -152,6 +154,83 @@ static HKEY open_hkcu_key(const char *name)
 }
 
 
+/* wrapper for NtCreateKey that creates the key recursively if necessary */
+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;
+
+    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;
+}
+
+
+HKEY reg_create_ascii_key(HKEY root, const char *name, DWORD options, DWORD *disposition)
+{
+    WCHAR buf[256];
+    return reg_create_key(root, buf, asciiz_to_unicode(buf, name) - sizeof(WCHAR),
+                          options, disposition);
+}
+
+
+BOOL reg_delete_tree(HKEY parent, const WCHAR *name, ULONG name_len)
+{
+    char buffer[4096];
+    KEY_NODE_INFORMATION *key_info = (KEY_NODE_INFORMATION *)buffer;
+    DWORD size;
+    HKEY key;
+    BOOL ret = TRUE;
+
+    if (!(key = reg_open_key(parent, name, name_len))) return FALSE;
+
+    while (ret && !NtEnumerateKey(key, 0, KeyNodeInformation, key_info, sizeof(buffer), &size))
+        ret = reg_delete_tree(key, key_info->Name, key_info->NameLength);
+
+    if (ret) ret = !NtDeleteKey(key);
+    NtClose(key);
+    return ret;
+}
+
+
 ULONG query_reg_value(HKEY hkey, const WCHAR *name, KEY_VALUE_PARTIAL_INFORMATION *info, ULONG size)
 {
     UNICODE_STRING str;




More information about the wine-cvs mailing list