Fixes a regression introduced by 1cdc74b2d62d1c94005c46f9c8f4b566aa8bdcbd when creating new prefixes, as NtCreateKey does not recursively create keys.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
Most of the code is taken from kernelbase's create_key, but simplified to gdi32's cases only.
dlls/gdi32/font.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index 98c70a6..d54f9a5 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,28 @@ 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) + { + DWORD pos = 0, i = 0, len = name_len / sizeof(WCHAR); + + 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; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=99264
Your paranoid android.
=== debiant2 (32 bit report) ===
gdi32: font.c:1234: Test failed: GetCharABCWidthsW should have failed font.c:1681: Test failed: GetGlyphIndicesW should have returned a 001f not 0000 font.c:4387: Test failed: info[0] = 3 for the system font font.c:5033: Test failed: Unexpected first glyph L":" font.c:5060: Test failed: Unexpected first glyph L":" font.c:7484: Test failed: expected 0, got -1 font.c:7485: Test failed: expected 0, got -6 metafile.c:5106: Test failed: expected 0, got 150 metafile.c:5180: Test failed: expected 0, got 150
=== debiant2 (32 bit Chinese:China report) ===
gdi32: font.c:1234: Test failed: GetCharABCWidthsW should have failed font.c:1681: Test failed: GetGlyphIndicesW should have returned a 001f not 0000 font.c:4387: Test failed: info[0] = 3 for the system font font.c:5033: Test failed: Unexpected first glyph L"8" font.c:5060: Test failed: Unexpected first glyph L"8" font.c:7484: Test failed: expected 0, got -11 font.c:7485: Test failed: expected 0, got -6 metafile.c:5106: Test failed: expected 0, got 178 metafile.c:5180: Test failed: expected 0, got 178
=== debiant2 (32 bit WoW report) ===
gdi32: font.c:1234: Test failed: GetCharABCWidthsW should have failed font.c:1681: Test failed: GetGlyphIndicesW should have returned a 001f not 0000 font.c:4387: Test failed: info[0] = 3 for the system font font.c:5033: Test failed: Unexpected first glyph L":" font.c:5060: Test failed: Unexpected first glyph L":" font.c:7484: Test failed: expected 0, got -1 font.c:7485: Test failed: expected 0, got -6 metafile.c:5106: Test failed: expected 0, got 150 metafile.c:5180: Test failed: expected 0, got 150
=== debiant2 (64 bit WoW report) ===
gdi32: font.c:1234: Test failed: GetCharABCWidthsW should have failed font.c:1681: Test failed: GetGlyphIndicesW should have returned a 001f not 0000 font.c:4387: Test failed: info[0] = 3 for the system font font.c:5033: Test failed: Unexpected first glyph L":" font.c:5060: Test failed: Unexpected first glyph L":" font.c:7484: Test failed: expected 0, got -1 font.c:7485: Test failed: expected 0, got -6 metafile.c:5106: Test failed: expected 0, got 150 metafile.c:5180: Test failed: expected 0, got 150