server: Implement object name information for registry keys.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-09-22 16:57:04 +02:00
parent bdb2fe0cad
commit 96dcee6430
2 changed files with 31 additions and 22 deletions

View File

@ -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 );

View File

@ -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" );
}