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