[PATCH v5] gdi32: Create the registry keys recursively, if needed.
Gabriel Ivăncescu
gabrielopcode at gmail.com
Mon Oct 4 13:27:43 CDT 2021
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>
---
v5: Fix memcmp size...
dlls/gdi32/font.c | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 98c70a6..4784c1d 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -29,6 +29,8 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
@@ -569,11 +571,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);
@@ -583,7 +587,32 @@ 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 > 10 && !memcmp( name, registry_rootW, 10 * sizeof(WCHAR) )) i += 10;
+
+ 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;
}
--
2.31.1
More information about the wine-devel
mailing list