From: chenzhengyong chenzhengyong@uniontech.com
Add a test verifying that subkeys are correctly renamed and enumerated in the expected order after calling NtRenameKey. See merge request !9247.
Signed-off-by: chenzhengyong chenzhengyong@uniontech.com --- dlls/ntdll/tests/reg.c | 94 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index 0e191a125cc..e2cbc3217f1 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -2344,15 +2344,54 @@ static void test_RtlCreateRegistryKey(void) pRtlFreeUnicodeString(&str); }
+/* helper function for test_NtRenameKey */ +static void check_subkeys(HANDLE key, const WCHAR **expected_names, int expected_count) +{ + NTSTATUS status; + DWORD size; + int i; + char buffer[200]; + PKEY_BASIC_INFORMATION info; + BOOL match; + + for (i = 0;; i++) + { + info = (PKEY_BASIC_INFORMATION)buffer; + status = pNtEnumerateKey(key, i, KeyBasicInformation, info, sizeof(buffer), &size); + if (status == STATUS_NO_MORE_ENTRIES) + { + ok(i == expected_count, "Expected %d subkeys, found %d\n", expected_count, i); + break; + } + + ok(!status, "NtEnumerateKey failed, status %#lx\n", status); + + info->Name[info->NameLength / sizeof(WCHAR)] = 0; + + match = FALSE; + for (int j = 0; j < expected_count; j++) + { + if (!wcscmp(info->Name, expected_names[j])) + { + match = TRUE; + break; + } + } + ok(match, "Unexpected subkey name %s.\n", wine_dbgstr_w(info->Name)); + } +} + static void test_NtRenameKey(void) { KEY_NAME_INFORMATION *info = NULL; UNICODE_STRING str, str2; OBJECT_ATTRIBUTES attr; - HANDLE key, subkey; + HANDLE key, subkey, hsub_b, hsub_c, hsub_d; char buffer[200]; NTSTATUS status; DWORD size; + const WCHAR *expected_names[4]; + int expected_count;
status = NtRenameKey(NULL, NULL); ok(status == STATUS_ACCESS_VIOLATION, "Unexpected status %#lx.\n", status); @@ -2391,9 +2430,6 @@ static void test_NtRenameKey(void) status = NtRenameKey(subkey, &str2); ok(!status, "Unexpected status %#lx.\n", status);
- pRtlFreeUnicodeString(&str2); - pRtlFreeUnicodeString(&str); - info = (KEY_NAME_INFORMATION *)buffer; status = pNtQueryKey(subkey, KeyNameInformation, info, sizeof(buffer), &size); ok(!status, "Unexpected status %#lx.\n", status); @@ -2403,6 +2439,56 @@ static void test_NtRenameKey(void) ok(!!wcsstr(info->Name, L"renamed_subkey"), "Unexpected subkey name %s.\n", wine_dbgstr_w(info->Name)); }
+ /* create subkey b, c, d */ + pRtlCreateUnicodeStringFromAsciiz(&str, "b"); + status = pNtCreateKey(&hsub_b, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0); + ok(!status, "Create subkey 'b' failed, status %#lx\n", status); + + pRtlCreateUnicodeStringFromAsciiz(&str, "c"); + status = pNtCreateKey(&hsub_c, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0); + ok(!status, "Create subkey 'c' failed, status %#lx\n", status); + + pRtlCreateUnicodeStringFromAsciiz(&str, "d"); + status = pNtCreateKey(&hsub_d, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0); + ok(!status, "Create subkey 'd' failed, status %#lx\n", status); + + /* rename "b" to "a" */ + pRtlCreateUnicodeStringFromAsciiz(&str2, "a"); + status = NtRenameKey(hsub_b, &str2); + ok(!status, "NtRenameKey failed, status %#lx\n", status); + + /* expected subkeys: a, c, d */ + expected_names[0] = L"a"; + expected_names[1] = L"c"; + expected_names[2] = L"d"; + expected_names[3] = L"renamed_subkey"; + expected_count = ARRAY_SIZE(expected_names); + check_subkeys(key, expected_names, expected_count); + + /* rename "a" -> "b" again */ + pRtlCreateUnicodeStringFromAsciiz(&str2, "b"); + status = NtRenameKey(hsub_b, &str2); + ok(!status, "NtRenameKey failed, status %#lx\n", status); + + /* expected subkeys: b, c, d */ + expected_names[0] = L"b"; + expected_names[1] = L"c"; + expected_names[2] = L"d"; + expected_names[3] = L"renamed_subkey"; + expected_count = ARRAY_SIZE(expected_names); + check_subkeys(key, expected_names, expected_count); + + /* clean */ + pRtlFreeUnicodeString(&str2); + pRtlFreeUnicodeString(&str); + + pNtDeleteKey(hsub_b); + pNtDeleteKey(hsub_c); + pNtDeleteKey(hsub_d); + pNtClose(hsub_b); + pNtClose(hsub_c); + pNtClose(hsub_d); + pNtDeleteKey(subkey); pNtDeleteKey(key); pNtClose(subkey);