Gabriel Ivăncescu : gdi32: Create the registry keys recursively, if needed.

Alexandre Julliard julliard at winehq.org
Tue Oct 5 15:51:41 CDT 2021


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

Author: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Date:   Tue Oct  5 17:16:45 2021 +0300

gdi32: Create the registry keys recursively, if needed.

Fixes a regression introduced by 1cdc74b2d62d1c94005c46f9c8f4b566aa8bdcbd
when creating new prefixes, as NtCreateKey does not recursively create keys.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdi32/font.c | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index c6bc3a716be..8cc60d5a16f 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -31,6 +31,8 @@
 #include <assert.h>
 #include <pthread.h>
 
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
 #include "winerror.h"
 #include "windef.h"
 #include "winbase.h"
@@ -564,11 +566,13 @@ static HKEY reg_open_key( HKEY root, const WCHAR *name, ULONG name_len )
     return 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;
 
     attr.Length = sizeof(attr);
@@ -578,7 +582,34 @@ static HKEY reg_create_key( HKEY root, const WCHAR *name, ULONG name_len,
     attr.SecurityDescriptor = NULL;
     attr.SecurityQualityOfService = NULL;
 
-    if (NtCreateKey( &ret, MAXIMUM_ALLOWED, &attr, 0, NULL, options, disposition )) return 0;
+    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 (;;)
+        {
+            nameW.Buffer = (WCHAR *)name + pos;
+            nameW.Length = (i - pos) * sizeof(WCHAR);
+            status = NtCreateKey( &ret, MAXIMUM_ALLOWED, &attr, 0, NULL, 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;
 }
 




More information about the wine-cvs mailing list