server: Implement object name information for registry keys.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
bdb2fe0cad
commit
96dcee6430
|
@ -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 );
|
||||
|
|
|
@ -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" );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue