winemac: Directly use ntdll in setup_options.

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-13 14:23:14 +02:00 committed by Alexandre Julliard
parent 56d9ed83c1
commit 718db04398
2 changed files with 125 additions and 19 deletions

View File

@ -293,4 +293,21 @@ extern void macdrv_process_text_input(UINT vkey, UINT scan, UINT repeat, const B
extern void macdrv_sent_text_input(const macdrv_event *event) DECLSPEC_HIDDEN;
extern BOOL query_ime_char_rect(macdrv_query* query) DECLSPEC_HIDDEN;
/* 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);
}
/* FIXME: remove once we use unixlib */
#define wcsrchr strrchrW
#endif /* __WINE_MACDRV_H */

View File

@ -28,6 +28,7 @@
#include "winuser.h"
#include "winreg.h"
#include "wine/server.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(macdrv);
@ -102,16 +103,97 @@ const char* debugstr_cf(CFTypeRef t)
}
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)
{
UNICODE_STRING str;
RtlInitUnicodeString(&str, name);
if (NtQueryValueKey(hkey, &str, 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;
}
@ -123,36 +205,41 @@ static inline DWORD get_config_key(HKEY defkey, HKEY appkey, const char *name,
*/
static void setup_options(void)
{
char buffer[MAX_PATH + 16];
static const WCHAR macdriverW[] = {'\\','M','a','c',' ','D','r','i','v','e','r',0};
WCHAR buffer[MAX_PATH + 16], *p, *appname;
HKEY hkey, appkey = 0;
DWORD len;
/* @@ Wine registry key: HKCU\Software\Wine\Mac Driver */
if (RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Mac Driver", &hkey)) hkey = 0;
hkey = open_hkcu_key("Software\\Wine\\Mac Driver");
/* open the app-specific key */
len = GetModuleFileNameA(0, buffer, MAX_PATH);
appname = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer;
if ((p = wcsrchr(appname, '/'))) appname = p + 1;
if ((p = wcsrchr(appname, '\\'))) appname = p + 1;
len = lstrlenW(appname);
if (len && len < MAX_PATH)
{
HKEY tmpkey;
char *p, *appname = buffer;
if ((p = strrchr(appname, '/'))) appname = p + 1;
if ((p = strrchr(appname, '\\'))) appname = p + 1;
strcat(appname, "\\Mac Driver");
memcpy(buffer, appname, len * sizeof(WCHAR));
memcpy(buffer + len, macdriverW, sizeof(macdriverW));
/* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\Mac Driver */
if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey))
if ((tmpkey = open_hkcu_key("Software\\Wine\\AppDefaults")))
{
if (RegOpenKeyA(tmpkey, appname, &appkey)) appkey = 0;
RegCloseKey(tmpkey);
appkey = reg_open_key(tmpkey, buffer, lstrlenW(buffer) * sizeof(WCHAR));
NtClose(tmpkey);
}
}
if (!get_config_key(hkey, appkey, "WindowsFloatWhenInactive", buffer, sizeof(buffer)))
{
if (!strcmp(buffer, "none"))
static const WCHAR noneW[] = {'n','o','n','e',0};
static const WCHAR allW[] = {'a','l','l',0};
if (!lstrcmpW(buffer, noneW))
topmost_float_inactive = TOPMOST_FLOAT_INACTIVE_NONE;
else if (!strcmp(buffer, "all"))
else if (!lstrcmpW(buffer, allW))
topmost_float_inactive = TOPMOST_FLOAT_INACTIVE_ALL;
else
topmost_float_inactive = TOPMOST_FLOAT_INACTIVE_NONFULLSCREEN;
@ -206,9 +293,11 @@ static void setup_options(void)
if (!get_config_key(hkey, appkey, "OpenGLSurfaceMode", buffer, sizeof(buffer)))
{
if (!strcmp(buffer, "transparent"))
static const WCHAR transparentW[] = {'t','r','a','n','s','p','a','r','e','n','t',0};
static const WCHAR behindW[] = {'b','e','h','i','n','d',0};
if (!lstrcmpW(buffer, transparentW))
gl_surface_mode = GL_SURFACE_IN_FRONT_TRANSPARENT;
else if (!strcmp(buffer, "behind"))
else if (!lstrcmpW(buffer, behindW))
gl_surface_mode = GL_SURFACE_BEHIND;
else
gl_surface_mode = GL_SURFACE_IN_FRONT_OPAQUE;
@ -222,8 +311,8 @@ static void setup_options(void)
if (!get_config_key(hkey, NULL, "RetinaMode", buffer, sizeof(buffer)))
retina_enabled = IS_OPTION_TRUE(buffer[0]);
if (appkey) RegCloseKey(appkey);
if (hkey) RegCloseKey(hkey);
if (appkey) NtClose(appkey);
if (hkey) NtClose(hkey);
}