diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index 22048f98e21..08af73e1710 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -1285,7 +1285,7 @@ static void test_NtQueryKey(void) HANDLE key; NTSTATUS status; OBJECT_ATTRIBUTES attr; - ULONG len; + ULONG length, len; KEY_NAME_INFORMATION *info = NULL; UNICODE_STRING str; @@ -1293,21 +1293,30 @@ static void test_NtQueryKey(void) status = pNtOpenKey(&key, KEY_READ, &attr); ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08x\n", status); - status = pNtQueryKey(key, KeyNameInformation, NULL, 0, &len); + status = pNtQueryKey(key, KeyNameInformation, NULL, 0, &length); if (status == STATUS_INVALID_PARAMETER) { win_skip("KeyNameInformation is not supported\n"); pNtClose(key); return; } todo_wine ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryKey Failed: 0x%08x\n", status); + info = HeapAlloc(GetProcessHeap(), 0, length); - info = HeapAlloc(GetProcessHeap(), 0, len); - status = pNtQueryKey(key, KeyNameInformation, info, len, &len); + /* non-zero buffer size, but insufficient */ + status = pNtQueryKey(key, KeyNameInformation, info, sizeof(*info), &len); + ok(status == STATUS_BUFFER_OVERFLOW, "NtQueryKey Failed: 0x%08x\n", status); + ok(length == len, "got %d, expected %d\n", len, length); + ok(info->NameLength == winetestpath.Length, "got %d, expected %d\n", + info->NameLength, winetestpath.Length); + + /* correct buffer size */ + status = pNtQueryKey(key, KeyNameInformation, info, length, &len); ok(status == STATUS_SUCCESS, "NtQueryKey Failed: 0x%08x\n", status); + ok(length == len, "got %d, expected %d\n", len, length); str.Buffer = info->Name; str.Length = info->NameLength; - todo_wine ok(pRtlCompareUnicodeString(&winetestpath, &str, TRUE) == 0, + ok(pRtlCompareUnicodeString(&winetestpath, &str, TRUE) == 0, "got %s, expected %s\n", wine_dbgstr_wn(str.Buffer, str.Length/sizeof(WCHAR)), wine_dbgstr_wn(winetestpath.Buffer, winetestpath.Length/sizeof(WCHAR))); diff --git a/server/registry.c b/server/registry.c index 1436bfeba53..4aaaf03235e 100644 --- a/server/registry.c +++ b/server/registry.c @@ -864,10 +864,12 @@ static struct key *create_key_recursive( struct key *key, const struct unicode_s static void enum_key( const struct key *key, int index, int info_class, struct enum_key_reply *reply ) { + static const WCHAR backslash[] = { '\\' }; int i; data_size_t len, namelen, classlen; data_size_t max_subkey = 0, max_class = 0; data_size_t max_value = 0, max_data = 0; + const struct key *k; char *data; if (index != -1) /* -1 means use the specified key directly */ @@ -885,8 +887,14 @@ static void enum_key( const struct key *key, int index, int info_class, switch(info_class) { - case KeyBasicInformation: case KeyNameInformation: + namelen = 0; + for (k = key; k != root_key; k = k->parent) + namelen += k->namelen + sizeof(backslash); + if (!namelen) return; + namelen += sizeof(root_name) - sizeof(backslash); + /* fall through */ + case KeyBasicInformation: classlen = 0; /* only return the name */ /* fall through */ case KeyNodeInformation: @@ -935,6 +943,21 @@ static void enum_key( const struct key *key, int index, int info_class, memcpy( data, key->name, namelen ); memcpy( data + namelen, key->class, len - namelen ); } + else if (info_class == KeyNameInformation) + { + data_size_t pos = namelen; + reply->namelen = namelen; + for (k = key; k != root_key; k = k->parent) + { + pos -= k->namelen; + if (pos < len) memcpy( data + namelen, k->name, + min( k->namelen, len - pos ) ); + pos -= sizeof(backslash); + if (pos < len) memcpy( data + namelen, backslash, + min( sizeof(backslash), len - pos ) ); + } + memcpy( data, root_name, min( sizeof(root_name) - sizeof(backslash), len ) ); + } else { reply->namelen = len;