From: Santino Mazza smazza@codeweavers.com
Signed-off-by: Santino Mazza smazza@codweavers.com --- dlls/advapi32/tests/registry.c | 6 +-- dlls/kernelbase/registry.c | 70 ++++++++++++++++++++++++++++------ 2 files changed, 61 insertions(+), 15 deletions(-)
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index e2707504c4f..555cc72451e 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -1615,8 +1615,8 @@ static void test_reg_load_app_key(void)
/* Test with non existant file */ ret = RegLoadAppKeyA("saved_app_key", &key1, KEY_READ, 0, 0); - ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); - ok(key1 != NULL, "got a null key\n"); + todo_wine ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + todo_wine ok(key1 != NULL, "got a null key\n");
ret = GetFileAttributesA("saved_app_key"); todo_wine ok(ret != -1, "hive file didn't got created.\n"); @@ -1674,7 +1674,7 @@ static void test_reg_load_app_key(void) ok(key1 != NULL, "got a null key\n");
ret = RegCreateKeyA(key1, "testkey", &childkey); - todo_wine ok(ret == ERROR_SUCCESS || broken(ret == ERROR_INVALID_HANDLE) /* win7 */, "error when creating testkey. %ld\n", ret); + ok(ret == ERROR_SUCCESS || broken(ret == ERROR_INVALID_HANDLE) /* win7 */, "error when creating testkey. %ld\n", ret); RegCloseKey(key1);
hivefile = CreateFileA("saved_app_key", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, diff --git a/dlls/kernelbase/registry.c b/dlls/kernelbase/registry.c index 91462d80e06..a0fa81118b9 100644 --- a/dlls/kernelbase/registry.c +++ b/dlls/kernelbase/registry.c @@ -3080,35 +3080,81 @@ cleanup: return ret; }
+static void generate_string_uuid(WCHAR *out, DWORD out_size) +{ + UUID uuid; + LARGE_INTEGER ft; + ULONG seed; + + NtQuerySystemTime(&ft); + seed = ft.LowPart; + for (int i = 0; i < sizeof(uuid); ++i) + ((UCHAR*)&uuid)[i] = (UCHAR)RtlRandom(&seed); + + + uuid.Data3 &= 0x0fff; + uuid.Data3 |= (4 << 12); + uuid.Data4[0] &= 0x3f; + uuid.Data4[0] |= 0x80; + + swprintf(out, out_size, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", uuid.Data1, + uuid.Data2, uuid.Data3, uuid.Data4[0], uuid.Data4[1], uuid.Data4[2], uuid.Data4[3], + uuid.Data4[4], uuid.Data4[5], uuid.Data4[6], uuid.Data4[7]); +}
/****************************************************************************** * RegLoadAppKeyA (kernelbase.@) * */ -LSTATUS WINAPI RegLoadAppKeyA(const char *file, HKEY *result, REGSAM sam, DWORD options, DWORD reserved) +LSTATUS WINAPI RegLoadAppKeyA(const char *filename, HKEY *result, REGSAM sam, DWORD options, DWORD reserved) { - FIXME("%s %p %lu %lu %lu: stub\n", wine_dbgstr_a(file), result, sam, options, reserved); + UNICODE_STRING filenameW; + LSTATUS status; + FIXME("%s %p %lu %lu %lu: stub\n", wine_dbgstr_a(filename), result, sam, options, reserved);
- if (!file || reserved) - return ERROR_INVALID_PARAMETER; - - *result = (HKEY)0xdeadbeef; - return ERROR_SUCCESS; + RtlCreateUnicodeStringFromAsciiz(&filenameW, filename); + status = RegLoadAppKeyW(filenameW.Buffer, result, sam, options, reserved); + RtlFreeUnicodeString(&filenameW); + return status; }
/****************************************************************************** * RegLoadAppKeyW (kernelbase.@) * */ -LSTATUS WINAPI RegLoadAppKeyW(const WCHAR *file, HKEY *result, REGSAM sam, DWORD options, DWORD reserved) +LSTATUS WINAPI RegLoadAppKeyW(const WCHAR *filename, HKEY *result, REGSAM sam, DWORD options, DWORD reserved) { - FIXME("%s %p %lu %lu %lu: stub\n", wine_dbgstr_w(file), result, sam, options, reserved); + NTSTATUS status; + WCHAR application_root[13] = L"\REGISTRY\A\"; + WCHAR rootguid_str[39]; + WCHAR *destkey_path_tmp; + UNICODE_STRING destkey_path, filenameW; + OBJECT_ATTRIBUTES destkey, file; + + TRACE("%s %p %lu %lu %lu\n", wine_dbgstr_w(filename), result, sam, options, reserved);
- if (!file || reserved) + if (!filename || reserved) return ERROR_INVALID_PARAMETER;
- *result = (HKEY)0xdeadbeef; - return ERROR_SUCCESS; + InitializeObjectAttributes(&destkey, &destkey_path, 0, 0, 0); + RtlDosPathNameToNtPathName_U(filename, &filenameW, NULL, NULL); + InitializeObjectAttributes(&file, &filenameW, 0, 0, 0); + + generate_string_uuid(rootguid_str, sizeof(rootguid_str)); + + destkey_path_tmp = heap_alloc_zero(sizeof(application_root) + sizeof(rootguid_str)); + wcscat(destkey_path_tmp, application_root); + wcscat(destkey_path_tmp, rootguid_str); + + RtlCreateUnicodeString(&destkey_path, destkey_path_tmp); + heap_free(destkey_path_tmp); + + status = NtLoadKeyEx(&destkey, &file, 0x10 /* LOAD_APP_KEY flag */, 0, 0, sam, (HANDLE *)result, 0); + + RtlFreeUnicodeString(&destkey_path); + RtlFreeUnicodeString(&filenameW); + + return RtlNtStatusToDosError(status); }