winemac: Directly use ntdll for registry access in init_original_display_mode.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2022-05-15 19:02:54 +02:00 committed by Alexandre Julliard
parent 9b66a5397a
commit 6045ad5bcf
3 changed files with 94 additions and 8 deletions

View File

@ -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;
}

View File

@ -297,6 +297,11 @@ extern void macdrv_process_text_input(UINT vkey, UINT scan, UINT repeat, const B
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 */

View File

@ -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;