From: Alex Henrie alexhenrie24@gmail.com
--- dlls/ntdll/reg.c | 5 +++++ dlls/ntdll/tests/reg.c | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/reg.c b/dlls/ntdll/reg.c index 9be75649cc3..271abb03768 100644 --- a/dlls/ntdll/reg.c +++ b/dlls/ntdll/reg.c @@ -261,6 +261,8 @@ static NTSTATUS RTL_ReportRegistryValue(PKEY_VALUE_FULL_INFORMATION pInfo,
if (pQuery->Flags & RTL_QUERY_REGISTRY_DIRECT) { + if (pQuery->QueryRoutine) + return STATUS_INVALID_PARAMETER; if (str->MaximumLength < default_size) return STATUS_BUFFER_TOO_SMALL; memcpy(str->Buffer, pQuery->DefaultData, default_size); @@ -277,6 +279,9 @@ static NTSTATUS RTL_ReportRegistryValue(PKEY_VALUE_FULL_INFORMATION pInfo,
if (pQuery->Flags & RTL_QUERY_REGISTRY_DIRECT) { + if (pQuery->QueryRoutine) + return STATUS_INVALID_PARAMETER; + switch(pInfo->Type) { case REG_EXPAND_SZ: diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index 9449cd2f904..eda20c35e9f 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -2662,7 +2662,12 @@ static struct query_reg_values_test query_reg_values_tests[] = /* DIRECT doesn't call the query routine and reads directly into a buffer */ { {{ query_routine, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"WindowsDrive", &query_reg_values_direct_str }}, - STATUS_INVALID_PARAMETER, 0, WINE_TODO_RET | WINE_TODO_NAME | WINE_TODO_TYPE | WINE_TODO_SIZE | WINE_TODO_DATA + STATUS_INVALID_PARAMETER, 0 + }, + { + {{ query_routine, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist", + &query_reg_values_direct_str, REG_SZ, (WCHAR*)L"Some default" }}, + STATUS_INVALID_PARAMETER, 0 }, { {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"WindowsDrive", &query_reg_values_direct_str }},
From: Alex Henrie alexhenrie24@gmail.com
--- dlls/ntdll/reg.c | 1 + dlls/ntdll/tests/reg.c | 29 +++++++++++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/dlls/ntdll/reg.c b/dlls/ntdll/reg.c index 271abb03768..df8763835ad 100644 --- a/dlls/ntdll/reg.c +++ b/dlls/ntdll/reg.c @@ -266,6 +266,7 @@ static NTSTATUS RTL_ReportRegistryValue(PKEY_VALUE_FULL_INFORMATION pInfo, if (str->MaximumLength < default_size) return STATUS_BUFFER_TOO_SMALL; memcpy(str->Buffer, pQuery->DefaultData, default_size); + str->Length = default_size - sizeof(WCHAR); return STATUS_SUCCESS; } else if (pQuery->QueryRoutine) diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index eda20c35e9f..d569f1f4d19 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -2662,12 +2662,12 @@ static struct query_reg_values_test query_reg_values_tests[] = /* DIRECT doesn't call the query routine and reads directly into a buffer */ { {{ query_routine, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"WindowsDrive", &query_reg_values_direct_str }}, - STATUS_INVALID_PARAMETER, 0 + STATUS_INVALID_PARAMETER, 0, 0, REG_NONE, NULL, -1 }, { {{ query_routine, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist", &query_reg_values_direct_str, REG_SZ, (WCHAR*)L"Some default" }}, - STATUS_INVALID_PARAMETER, 0 + STATUS_INVALID_PARAMETER, 0, 0, REG_NONE, NULL, -1 }, { {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"WindowsDrive", &query_reg_values_direct_str }}, @@ -2681,7 +2681,7 @@ static struct query_reg_values_test query_reg_values_tests[] = { {{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, (WCHAR*)L"CapitalsOfEurope", &query_reg_values_direct_str }}, - STATUS_SUCCESS, 0, 0, REG_SZ, L"Brussels\0Paris\0Madrid", sizeof(L"Brussels\0Paris\0Madrid") + STATUS_SUCCESS, 0, WINE_TODO_DATA, REG_SZ, L"Brussels\0Paris\0Madrid\0", sizeof(L"Brussels\0Paris\0Madrid\0") }, /* DIRECT with a null buffer crashes on Windows */ /* { @@ -2744,7 +2744,7 @@ static struct query_reg_values_test query_reg_values_tests[] = { {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist", &query_reg_values_direct_str, REG_EXPAND_SZ, (WCHAR*)L"%SYSTEMDRIVE%" }}, - STATUS_SUCCESS, 0, WINE_TODO_DATA, REG_EXPAND_SZ, L"C:" + STATUS_SUCCESS, 0, WINE_TODO_SIZE | WINE_TODO_DATA, REG_EXPAND_SZ, L"C:" }, /* DIRECT with a multi-string default value crashes on Windows */ /* { @@ -2764,12 +2764,12 @@ static struct query_reg_values_test query_reg_values_tests[] = { {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist", &query_reg_values_direct_str, REG_SZ }}, - STATUS_DATA_OVERRUN, 0, WINE_TODO_RET + STATUS_DATA_OVERRUN, 0, WINE_TODO_RET | WINE_TODO_SIZE, REG_NONE, NULL, -1 }, { {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist", &query_reg_values_direct_str, REG_NONE, (WCHAR*)L"Some default" }}, - STATUS_SUCCESS, 0 + STATUS_SUCCESS, 0, WINE_TODO_SIZE, REG_NONE, NULL, -1 }, /* REQUIRED fails if the value doesn't exist and there is no default */ { @@ -2830,7 +2830,9 @@ static void test_RtlQueryRegistryValues(void) }
query_routine_calls = 0; - wcscpy(query_reg_values_direct_str.Buffer, L"###"); + query_reg_values_direct_str.Length = query_reg_values_direct_str.MaximumLength - sizeof(WCHAR); + memset(query_reg_values_direct_str.Buffer, 0x23, query_reg_values_direct_str.Length); + query_reg_values_direct_str.Buffer[query_reg_values_direct_str.Length] = 0;
status = pRtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, winetestpath.Buffer, test->query_table, test, NULL);
@@ -2857,11 +2859,18 @@ static void test_RtlQueryRegistryValues(void) expected_size = test->expected_data_size; }
+ if (!expected_size && expected_data) + expected_size = (wcslen(expected_data) + 1) * sizeof(WCHAR); + else if (expected_size == -1) + expected_size = query_reg_values_direct_str.MaximumLength; + + todo_wine_if(test->flags & WINE_TODO_SIZE) + ok(query_reg_values_direct_str.Length + sizeof(WCHAR) == expected_size, + "Expected size %lu, got %Iu\n", expected_size, + query_reg_values_direct_str.Length + sizeof(WCHAR)); + if (expected_data) { - if (!expected_size) - expected_size = (wcslen(expected_data) + 1) * sizeof(WCHAR); - todo_wine_if(test->flags & WINE_TODO_DATA) ok(!memcmp(query_reg_values_direct_str.Buffer, expected_data, expected_size), "Expected data %s, got %s\n", debugstr_w(expected_data),
From: Alex Henrie alexhenrie24@gmail.com
--- dlls/ntdll/reg.c | 16 ++++++++++++---- dlls/ntdll/tests/reg.c | 27 ++++++++++++++++++++------- 2 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/dlls/ntdll/reg.c b/dlls/ntdll/reg.c index df8763835ad..044bf32f460 100644 --- a/dlls/ntdll/reg.c +++ b/dlls/ntdll/reg.c @@ -263,10 +263,18 @@ static NTSTATUS RTL_ReportRegistryValue(PKEY_VALUE_FULL_INFORMATION pInfo, { if (pQuery->QueryRoutine) return STATUS_INVALID_PARAMETER; - if (str->MaximumLength < default_size) - return STATUS_BUFFER_TOO_SMALL; - memcpy(str->Buffer, pQuery->DefaultData, default_size); - str->Length = default_size - sizeof(WCHAR); + + if (pQuery->DefaultType == REG_SZ || pQuery->DefaultType == REG_EXPAND_SZ || + pQuery->DefaultType == REG_MULTI_SZ || pQuery->DefaultType == REG_LINK) + { + if (!pQuery->DefaultData) + return STATUS_DATA_OVERRUN; + if (str->MaximumLength < default_size) + return STATUS_BUFFER_TOO_SMALL; + memcpy(str->Buffer, pQuery->DefaultData, default_size); + str->Length = default_size - sizeof(WCHAR); + } + return STATUS_SUCCESS; } else if (pQuery->QueryRoutine) diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index d569f1f4d19..b6763e6e1d2 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -2601,7 +2601,7 @@ static NTSTATUS WINAPI query_routine(const WCHAR *value_name, ULONG value_type, expected_size = 0; }
- if (!expected_size && expected_data) + if (!expected_size && expected_data && (expected_type == REG_SZ || expected_type == REG_EXPAND_SZ)) expected_size = (wcslen(expected_data) + 1) * sizeof(WCHAR);
todo_wine_if(test->flags & WINE_TODO_TYPE) @@ -2611,11 +2611,11 @@ static NTSTATUS WINAPI query_routine(const WCHAR *value_name, ULONG value_type, ok(value_data_size == expected_size, "Expected size %lu, got %lu\n", expected_size, value_data_size);
todo_wine_if(test->flags & WINE_TODO_DATA && !(test->flags & SPLIT_MULTI && query_routine_calls == 0)) - if (expected_data) + if (expected_data == query->DefaultData || expected_data == NULL) + ok(value_data == expected_data, "Expected data %p, got %p\n", expected_data, value_data); + else ok(!memcmp(value_data, expected_data, value_data_size), "Expected data %s, got %s\n", debugstr_w(expected_data), debugstr_w(value_data)); - else - ok(!value_data, "Expected null data\n"); }
query_routine_calls++; @@ -2731,6 +2731,10 @@ static struct query_reg_values_test query_reg_values_tests[] = {{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_MULTI_SZ, (WCHAR*)L"Brussels\0Paris\0Madrid\0" }}, STATUS_SUCCESS, 3, EXPECT_DEFAULT_DATA | SPLIT_MULTI | WINE_TODO_CALLS | WINE_TODO_TYPE | WINE_TODO_SIZE }, + { + {{ query_routine, 0, (WCHAR*)L"I don't exist", NULL, REG_DWORD, (WCHAR*)0xdeadbeef }}, + STATUS_SUCCESS, 1, EXPECT_DEFAULT_DATA + }, { {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist", &query_reg_values_direct_str, REG_SZ, (WCHAR*)L"Some default", 4 * sizeof(WCHAR) }}, @@ -2764,12 +2768,18 @@ static struct query_reg_values_test query_reg_values_tests[] = { {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist", &query_reg_values_direct_str, REG_SZ }}, - STATUS_DATA_OVERRUN, 0, WINE_TODO_RET | WINE_TODO_SIZE, REG_NONE, NULL, -1 + STATUS_DATA_OVERRUN, 0, 0, REG_NONE, NULL, -1 }, { {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist", &query_reg_values_direct_str, REG_NONE, (WCHAR*)L"Some default" }}, - STATUS_SUCCESS, 0, WINE_TODO_SIZE, REG_NONE, NULL, -1 + STATUS_SUCCESS, 0, 0, REG_NONE, NULL, -1 + }, + /* DIRECT additionally requires the default value to be a string */ + { + {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"I don't exist", + &query_reg_values_direct_str, REG_DWORD, (WCHAR*)0xdeadbeef }}, + STATUS_SUCCESS, 0, 0, REG_NONE, NULL, -1 }, /* REQUIRED fails if the value doesn't exist and there is no default */ { @@ -2820,6 +2830,7 @@ static void test_RtlQueryRegistryValues(void) RTL_QUERY_REGISTRY_TABLE *query; const WCHAR *expected_data; ULONG expected_size; + ULONG expected_type;
winetest_push_context("%u/%Iu", i, ARRAY_SIZE(query_reg_values_tests) - 1);
@@ -2850,16 +2861,18 @@ static void test_RtlQueryRegistryValues(void) { if (test->flags & EXPECT_DEFAULT_DATA) { + expected_type = query->DefaultType; expected_data = query->DefaultData; expected_size = query->DefaultLength; } else { + expected_type = test->expected_type; expected_data = test->expected_data; expected_size = test->expected_data_size; }
- if (!expected_size && expected_data) + if (!expected_size && expected_data && (expected_type == REG_SZ || expected_type == REG_EXPAND_SZ)) expected_size = (wcslen(expected_data) + 1) * sizeof(WCHAR); else if (expected_size == -1) expected_size = query_reg_values_direct_str.MaximumLength;
From: Alex Henrie alexhenrie24@gmail.com
--- dlls/ntdll/reg.c | 7 ++++++- dlls/ntdll/tests/reg.c | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/reg.c b/dlls/ntdll/reg.c index 044bf32f460..3cbd055f367 100644 --- a/dlls/ntdll/reg.c +++ b/dlls/ntdll/reg.c @@ -311,7 +311,12 @@ static NTSTATUS RTL_ReportRegistryValue(PKEY_VALUE_FULL_INFORMATION pInfo, if (str->Buffer == NULL) RtlCreateUnicodeString(str, (WCHAR*)(((CHAR*)pInfo) + pInfo->DataOffset)); else - RtlAppendUnicodeToString(str, (WCHAR*)(((CHAR*)pInfo) + pInfo->DataOffset)); + { + if (str->MaximumLength < len) + return STATUS_BUFFER_TOO_SMALL; + memcpy(str->Buffer, (char*)pInfo + pInfo->DataOffset, len); + str->Length = len - sizeof(WCHAR); + } break;
case REG_MULTI_SZ: diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index b6763e6e1d2..14227db755c 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -2673,6 +2673,11 @@ static struct query_reg_values_test query_reg_values_tests[] = {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"WindowsDrive", &query_reg_values_direct_str }}, STATUS_SUCCESS, 0, 0, REG_SZ, L"C:" }, + { + {{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND, (WCHAR*)L"WindowsDrive", + &query_reg_values_direct_str }}, + STATUS_SUCCESS, 0, 0, REG_SZ, L"%SYSTEMDRIVE%" + }, /* DIRECT on a multi-string crashes on Windows without NOEXPAND */ /* { {{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"CapitalsOfEurope", &query_reg_values_direct_str }},