Commit e94d2e04 authored by Akihiro Sagawa's avatar Akihiro Sagawa Committed by Alexandre Julliard

server: KeyNameInformation returns the full name of the key.

parent 617f668f
...@@ -1285,7 +1285,7 @@ static void test_NtQueryKey(void) ...@@ -1285,7 +1285,7 @@ static void test_NtQueryKey(void)
HANDLE key; HANDLE key;
NTSTATUS status; NTSTATUS status;
OBJECT_ATTRIBUTES attr; OBJECT_ATTRIBUTES attr;
ULONG len; ULONG length, len;
KEY_NAME_INFORMATION *info = NULL; KEY_NAME_INFORMATION *info = NULL;
UNICODE_STRING str; UNICODE_STRING str;
...@@ -1293,21 +1293,30 @@ static void test_NtQueryKey(void) ...@@ -1293,21 +1293,30 @@ static void test_NtQueryKey(void)
status = pNtOpenKey(&key, KEY_READ, &attr); status = pNtOpenKey(&key, KEY_READ, &attr);
ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08x\n", status); 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) { if (status == STATUS_INVALID_PARAMETER) {
win_skip("KeyNameInformation is not supported\n"); win_skip("KeyNameInformation is not supported\n");
pNtClose(key); pNtClose(key);
return; return;
} }
todo_wine ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryKey Failed: 0x%08x\n", status); todo_wine ok(status == STATUS_BUFFER_TOO_SMALL, "NtQueryKey Failed: 0x%08x\n", status);
info = HeapAlloc(GetProcessHeap(), 0, length);
info = HeapAlloc(GetProcessHeap(), 0, len); /* non-zero buffer size, but insufficient */
status = pNtQueryKey(key, KeyNameInformation, info, len, &len); 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(status == STATUS_SUCCESS, "NtQueryKey Failed: 0x%08x\n", status);
ok(length == len, "got %d, expected %d\n", len, length);
str.Buffer = info->Name; str.Buffer = info->Name;
str.Length = info->NameLength; str.Length = info->NameLength;
todo_wine ok(pRtlCompareUnicodeString(&winetestpath, &str, TRUE) == 0, ok(pRtlCompareUnicodeString(&winetestpath, &str, TRUE) == 0,
"got %s, expected %s\n", "got %s, expected %s\n",
wine_dbgstr_wn(str.Buffer, str.Length/sizeof(WCHAR)), wine_dbgstr_wn(str.Buffer, str.Length/sizeof(WCHAR)),
wine_dbgstr_wn(winetestpath.Buffer, winetestpath.Length/sizeof(WCHAR))); wine_dbgstr_wn(winetestpath.Buffer, winetestpath.Length/sizeof(WCHAR)));
......
...@@ -864,10 +864,12 @@ static struct key *create_key_recursive( struct key *key, const struct unicode_s ...@@ -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, static void enum_key( const struct key *key, int index, int info_class,
struct enum_key_reply *reply ) struct enum_key_reply *reply )
{ {
static const WCHAR backslash[] = { '\\' };
int i; int i;
data_size_t len, namelen, classlen; data_size_t len, namelen, classlen;
data_size_t max_subkey = 0, max_class = 0; data_size_t max_subkey = 0, max_class = 0;
data_size_t max_value = 0, max_data = 0; data_size_t max_value = 0, max_data = 0;
const struct key *k;
char *data; char *data;
if (index != -1) /* -1 means use the specified key directly */ 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, ...@@ -885,8 +887,14 @@ static void enum_key( const struct key *key, int index, int info_class,
switch(info_class) switch(info_class)
{ {
case KeyBasicInformation:
case KeyNameInformation: 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 */ classlen = 0; /* only return the name */
/* fall through */ /* fall through */
case KeyNodeInformation: case KeyNodeInformation:
...@@ -935,6 +943,21 @@ static void enum_key( const struct key *key, int index, int info_class, ...@@ -935,6 +943,21 @@ static void enum_key( const struct key *key, int index, int info_class,
memcpy( data, key->name, namelen ); memcpy( data, key->name, namelen );
memcpy( data + namelen, key->class, len - 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 else
{ {
reply->namelen = len; reply->namelen = len;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment