Alexandre Julliard : server: Implement object name information for registry keys.
Alexandre Julliard
julliard at winehq.org
Tue Sep 22 15:46:41 CDT 2020
Module: wine
Branch: master
Commit: 96dcee64307b63ed3c07d13832fee15c3dc21ff1
URL: https://source.winehq.org/git/wine.git/?a=commit;h=96dcee64307b63ed3c07d13832fee15c3dc21ff1
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Sep 22 16:57:04 2020 +0200
server: Implement object name information for registry keys.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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 15f905330e..d3b932bec1 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 f4386d9bfb..438ec6c6fc 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" );
}
More information about the wine-cvs
mailing list