mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-01 18:58:29 +00:00
ntdll: Fix handling of non-string types with RTL_QUERY_REGISTRY_DIRECT.
This commit is contained in:
parent
802a52cb1b
commit
867af68b17
|
@ -341,17 +341,16 @@ static NTSTATUS RTL_ReportRegistryValue(PKEY_VALUE_FULL_INFORMATION pInfo,
|
|||
pInfo->DataLength);
|
||||
else
|
||||
{
|
||||
if (bin[0] <= sizeof(ULONG))
|
||||
if (bin[0] < 0)
|
||||
{
|
||||
memcpy(&bin[1], ((CHAR*)pInfo) + pInfo->DataOffset,
|
||||
min(-bin[0], pInfo->DataLength));
|
||||
if (pInfo->DataLength <= -bin[0])
|
||||
memcpy(bin, (char*)pInfo + pInfo->DataOffset, pInfo->DataLength);
|
||||
}
|
||||
else
|
||||
else if (pInfo->DataLength <= bin[0])
|
||||
{
|
||||
len = min(bin[0], pInfo->DataLength);
|
||||
bin[1] = len;
|
||||
bin[2] = pInfo->Type;
|
||||
memcpy(&bin[3], ((CHAR*)pInfo) + pInfo->DataOffset, len);
|
||||
bin[0] = len;
|
||||
bin[1] = pInfo->Type;
|
||||
memcpy(bin + 2, (char*)pInfo + pInfo->DataOffset, len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -2553,6 +2553,7 @@ struct query_reg_values_test
|
|||
ULONG expected_type;
|
||||
const WCHAR *expected_data;
|
||||
ULONG expected_data_size;
|
||||
ULONG size_limit;
|
||||
};
|
||||
|
||||
static unsigned int query_routine_calls;
|
||||
|
@ -2625,6 +2626,23 @@ static NTSTATUS WINAPI query_routine(const WCHAR *value_name, ULONG value_type,
|
|||
|
||||
static UNICODE_STRING query_reg_values_direct_str;
|
||||
|
||||
static ULONG query_reg_values_direct_int;
|
||||
|
||||
static union
|
||||
{
|
||||
ULONG size;
|
||||
char data[16];
|
||||
}
|
||||
query_reg_values_direct_sized;
|
||||
|
||||
static struct
|
||||
{
|
||||
ULONG size;
|
||||
ULONG type;
|
||||
char data[16];
|
||||
}
|
||||
query_reg_values_direct_typed;
|
||||
|
||||
static struct query_reg_values_test query_reg_values_tests[] =
|
||||
{
|
||||
/* Empty table */
|
||||
|
@ -2644,7 +2662,7 @@ static struct query_reg_values_test query_reg_values_tests[] =
|
|||
/* The query routine is called for every value in current key */
|
||||
{
|
||||
{{ query_routine }},
|
||||
STATUS_SUCCESS, 4, SKIP_NAME_CHECK | SKIP_DATA_CHECK
|
||||
STATUS_SUCCESS, 6, SKIP_NAME_CHECK | SKIP_DATA_CHECK
|
||||
},
|
||||
/* NOVALUE is ignored when the name is not null */
|
||||
{
|
||||
|
@ -2678,6 +2696,26 @@ static struct query_reg_values_test query_reg_values_tests[] =
|
|||
&query_reg_values_direct_str }},
|
||||
STATUS_SUCCESS, 0, 0, REG_SZ, L"%SYSTEMDRIVE%"
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"MeaningOfLife32", &query_reg_values_direct_int }},
|
||||
STATUS_SUCCESS, 0, 0, REG_DWORD, (WCHAR*)42
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"MeaningOfLife64", &query_reg_values_direct_sized }},
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, L"\x2a\0\0", sizeof(UINT64)
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"MeaningOfLife64", &query_reg_values_direct_sized }},
|
||||
STATUS_SUCCESS, 0, 0, REG_NONE, L"\xff", 1, 1
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"MeaningOfLife64", &query_reg_values_direct_typed }},
|
||||
STATUS_SUCCESS, 0, 0, REG_QWORD, L"\x2a\0\0", sizeof(UINT64)
|
||||
},
|
||||
{
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"MeaningOfLife64", &query_reg_values_direct_typed }},
|
||||
STATUS_SUCCESS, 0, 0, 0x23, L"\x23", 1, 1
|
||||
},
|
||||
/* DIRECT on a multi-string crashes on Windows without NOEXPAND */
|
||||
/* {
|
||||
{{ NULL, RTL_QUERY_REGISTRY_DIRECT, (WCHAR*)L"CapitalsOfEurope", &query_reg_values_direct_str }},
|
||||
|
@ -2783,8 +2821,8 @@ static struct query_reg_values_test query_reg_values_tests[] =
|
|||
/* 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
|
||||
&query_reg_values_direct_int, REG_DWORD, (WCHAR*)0xdeadbeef }},
|
||||
STATUS_SUCCESS, 0
|
||||
},
|
||||
/* REQUIRED fails if the value doesn't exist and there is no default */
|
||||
{
|
||||
|
@ -2821,8 +2859,16 @@ static void test_RtlQueryRegistryValues(void)
|
|||
L"Brussels\0Paris\0%PATH%", sizeof(L"Brussels\0Paris\0%PATH%"));
|
||||
ok(status == ERROR_SUCCESS, "Failed to create registry value CapitalsOfEurope: %lu\n", status);
|
||||
|
||||
status = RegSetKeyValueW(HKEY_CURRENT_USER, L"WineTest", L"MeaningOfLife32", REG_DWORD,
|
||||
L"\x2a", sizeof(DWORD));
|
||||
ok(status == ERROR_SUCCESS, "Failed to create registry value MeaningOfLife32: %lu\n", status);
|
||||
|
||||
status = RegSetKeyValueW(HKEY_CURRENT_USER, L"WineTest", L"MeaningOfLife64", REG_QWORD,
|
||||
L"\x2a\0\0", sizeof(UINT64));
|
||||
ok(status == ERROR_SUCCESS, "Failed to create registry value MeaningOfLife64: %lu\n", status);
|
||||
|
||||
status = RegSetKeyValueW(HKEY_CURRENT_USER, L"WineTest\\subkey", L"Color", REG_SZ,
|
||||
(void*)L"Yellow", sizeof(L"Yellow"));
|
||||
L"Yellow", sizeof(L"Yellow"));
|
||||
ok(status == ERROR_SUCCESS, "Failed to create registry value Color: %lu\n", status);
|
||||
|
||||
query_reg_values_direct_str.MaximumLength = 32 * sizeof(WCHAR);
|
||||
|
@ -2846,10 +2892,22 @@ static void test_RtlQueryRegistryValues(void)
|
|||
}
|
||||
|
||||
query_routine_calls = 0;
|
||||
|
||||
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;
|
||||
|
||||
query_reg_values_direct_int = 1;
|
||||
|
||||
memset(query_reg_values_direct_sized.data, 0x23, sizeof(query_reg_values_direct_sized));
|
||||
query_reg_values_direct_sized.size = test->size_limit ? -test->size_limit
|
||||
: -(LONG)sizeof(query_reg_values_direct_sized);
|
||||
|
||||
query_reg_values_direct_typed.size = test->size_limit ? test->size_limit
|
||||
: sizeof(query_reg_values_direct_typed.data);
|
||||
query_reg_values_direct_typed.type = 0x23;
|
||||
memset(query_reg_values_direct_typed.data, 0x23, sizeof(query_reg_values_direct_typed.data));
|
||||
|
||||
status = pRtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, winetestpath.Buffer, test->query_table, test, NULL);
|
||||
|
||||
todo_wine_if(test->flags & WINE_TODO_RET)
|
||||
|
@ -2877,7 +2935,9 @@ static void test_RtlQueryRegistryValues(void)
|
|||
expected_size = test->expected_data_size;
|
||||
}
|
||||
|
||||
if (!expected_size && expected_data && (expected_type == REG_SZ || expected_type == REG_EXPAND_SZ))
|
||||
if (query->EntryContext == &query_reg_values_direct_str)
|
||||
{
|
||||
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;
|
||||
|
@ -2895,6 +2955,36 @@ static void test_RtlQueryRegistryValues(void)
|
|||
debugstr_w(query_reg_values_direct_str.Buffer));
|
||||
}
|
||||
}
|
||||
else if (query->EntryContext == &query_reg_values_direct_int)
|
||||
{
|
||||
if (expected_data)
|
||||
{
|
||||
ok(!memcmp(&query_reg_values_direct_int, &expected_data, expected_size),
|
||||
"Data does not match\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
- ok(query_reg_values_direct_int == 1,
|
||||
"Expected data to not change, got %lu\n", query_reg_values_direct_int);
|
||||
}
|
||||
}
|
||||
else if (query->EntryContext == &query_reg_values_direct_sized)
|
||||
{
|
||||
ok(!memcmp(query_reg_values_direct_sized.data, expected_data, expected_size),
|
||||
"Data does not match\n");
|
||||
}
|
||||
else if (query->EntryContext == &query_reg_values_direct_typed)
|
||||
{
|
||||
ok(query_reg_values_direct_typed.size == expected_size,
|
||||
"Expected size %lu, got %lu\n", expected_size, query_reg_values_direct_typed.size);
|
||||
|
||||
ok(query_reg_values_direct_typed.type == expected_type,
|
||||
"Expected type %lu, got %lu\n", expected_type, query_reg_values_direct_typed.type);
|
||||
|
||||
ok(!memcmp(query_reg_values_direct_typed.data, expected_data, expected_size),
|
||||
"Data does not match\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
winetest_pop_context();
|
||||
|
|
Loading…
Reference in a new issue