From 96dcee64307b63ed3c07d13832fee15c3dc21ff1 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 22 Sep 2020 16:57:04 +0200 Subject: [PATCH] server: Implement object name information for registry keys. Signed-off-by: Alexandre Julliard --- dlls/ntdll/tests/om.c | 2 +- server/registry.c | 51 +++++++++++++++++++++++++------------------ 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index 15f905330e2..d3b932bec1d 100644 --- a/dlls/ntdll/tests/om.c +++ b/dlls/ntdll/tests/om.c @@ -1470,7 +1470,7 @@ static void test_query_object(void) status = pNtCreateKey( &handle, KEY_READ, &attr, 0, 0, 0, 0 ); ok( status == STATUS_SUCCESS, "NtCreateKey failed status %x\n", status ); - test_object_name( handle, L"\\REGISTRY\\MACHINE", TRUE ); + test_object_name( handle, L"\\REGISTRY\\MACHINE", FALSE ); test_object_type( handle, L"Key" ); pNtClose( handle ); diff --git a/server/registry.c b/server/registry.c index f4386d9bfb5..438ec6c6fc2 100644 --- a/server/registry.c +++ b/server/registry.c @@ -148,6 +148,7 @@ static void key_dump( struct object *obj, int verbose ); static struct object_type *key_get_type( struct object *obj ); static unsigned int key_map_access( struct object *obj, unsigned int access ); static struct security_descriptor *key_get_sd( struct object *obj ); +static WCHAR *key_get_full_name( struct object *obj, data_size_t *len ); static int key_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); static void key_destroy( struct object *obj ); @@ -165,7 +166,7 @@ static const struct object_ops key_ops = key_map_access, /* map_access */ key_get_sd, /* get_sd */ default_set_sd, /* set_sd */ - no_get_full_name, /* get_full_name */ + key_get_full_name, /* get_full_name */ no_lookup_name, /* lookup_name */ no_link_name, /* link_name */ NULL, /* unlink_name */ @@ -394,6 +395,29 @@ static struct security_descriptor *key_get_sd( struct object *obj ) return key_default_sd; } +static WCHAR *key_get_full_name( struct object *obj, data_size_t *ret_len ) +{ + static const WCHAR backslash = '\\'; + struct key *key = (struct key *) obj; + data_size_t len = sizeof(root_name) - sizeof(WCHAR); + char *ret; + + for (key = (struct key *)obj; key != root_key; key = key->parent) len += key->namelen + sizeof(WCHAR); + if (!(ret = malloc( len ))) return NULL; + + *ret_len = len; + key = (struct key *)obj; + for (key = (struct key *)obj; key != root_key; key = key->parent) + { + memcpy( ret + len - key->namelen, key->name, key->namelen ); + dump_strW( (WCHAR *)(ret + len - key->namelen), key->namelen, stderr, "" ); + len -= key->namelen + sizeof(WCHAR); + memcpy( ret + len, &backslash, sizeof(WCHAR) ); + } + memcpy( ret, root_name, sizeof(root_name) - sizeof(WCHAR) ); + return (WCHAR *)ret; +} + /* close the notification associated with a handle */ static int key_close_handle( struct object *obj, struct process *process, obj_handle_t handle ) { @@ -876,15 +900,13 @@ static struct key *create_key_recursive( struct key *key, const struct unicode_s } /* query information about a key or a subkey */ -static void enum_key( const struct key *key, int index, int info_class, - struct enum_key_reply *reply ) +static void enum_key( 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; + WCHAR *fullname = NULL; char *data; if (index != -1) /* -1 means use the specified key directly */ @@ -903,11 +925,7 @@ static void enum_key( const struct key *key, int index, int info_class, switch(info_class) { 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); + if (!(fullname = key->obj.ops->get_full_name( &key->obj, &namelen ))) return; /* fall through */ case KeyBasicInformation: classlen = 0; /* only return the name */ @@ -959,18 +977,8 @@ static void enum_key( const struct key *key, int index, int info_class, } 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 + pos, k->name, - min( k->namelen, len - pos ) ); - pos -= sizeof(backslash); - if (pos < len) memcpy( data + pos, backslash, - min( sizeof(backslash), len - pos ) ); - } - memcpy( data, root_name, min( sizeof(root_name) - sizeof(backslash), len ) ); + memcpy( data, fullname, namelen ); } else { @@ -978,6 +986,7 @@ static void enum_key( const struct key *key, int index, int info_class, memcpy( data, key->name, len ); } } + free( fullname ); if (debug_level > 1) dump_operation( key, NULL, "Enum" ); }