Akihiro Sagawa : server: KeyNameInformation returns the full name of the key.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Oct 15 11:37:25 CDT 2014
Module: wine
Branch: master
Commit: e94d2e045960978f8c48c4e9527f88f1229bf4be
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e94d2e045960978f8c48c4e9527f88f1229bf4be
Author: Akihiro Sagawa <sagawa.aki at gmail.com>
Date: Tue Oct 14 00:25:00 2014 +0900
server: KeyNameInformation returns the full name of the key.
---
dlls/ntdll/tests/reg.c | 19 ++++++++++++++-----
server/registry.c | 25 ++++++++++++++++++++++++-
2 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c
index 22048f9..08af73e 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 1436bfe..4aaaf03 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;
More information about the wine-cvs
mailing list