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 );
|
status = pNtCreateKey( &handle, KEY_READ, &attr, 0, 0, 0, 0 );
|
||||||
ok( status == STATUS_SUCCESS, "NtCreateKey failed status %x\n", status );
|
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" );
|
test_object_type( handle, L"Key" );
|
||||||
|
|
||||||
pNtClose( handle );
|
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 struct object_type *key_get_type( struct object *obj );
|
||||||
static unsigned int key_map_access( struct object *obj, unsigned int access );
|
static unsigned int key_map_access( struct object *obj, unsigned int access );
|
||||||
static struct security_descriptor *key_get_sd( struct object *obj );
|
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 int key_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
|
||||||
static void key_destroy( struct object *obj );
|
static void key_destroy( struct object *obj );
|
||||||
|
|
||||||
|
@ -165,7 +166,7 @@ static const struct object_ops key_ops =
|
||||||
key_map_access, /* map_access */
|
key_map_access, /* map_access */
|
||||||
key_get_sd, /* get_sd */
|
key_get_sd, /* get_sd */
|
||||||
default_set_sd, /* set_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_lookup_name, /* lookup_name */
|
||||||
no_link_name, /* link_name */
|
no_link_name, /* link_name */
|
||||||
NULL, /* unlink_name */
|
NULL, /* unlink_name */
|
||||||
|
@ -394,6 +395,29 @@ static struct security_descriptor *key_get_sd( struct object *obj )
|
||||||
return key_default_sd;
|
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 */
|
/* close the notification associated with a handle */
|
||||||
static int key_close_handle( struct object *obj, struct process *process, obj_handle_t 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 */
|
/* query information about a key or a subkey */
|
||||||
static void enum_key( const struct key *key, int index, int info_class,
|
static void enum_key( struct key *key, int index, int info_class, struct enum_key_reply *reply )
|
||||||
struct enum_key_reply *reply )
|
|
||||||
{
|
{
|
||||||
static const WCHAR backslash[] = { '\\' };
|
|
||||||
int i;
|
int i;
|
||||||
data_size_t len, namelen, classlen;
|
data_size_t len, namelen, classlen;
|
||||||
data_size_t max_subkey = 0, max_class = 0;
|
data_size_t max_subkey = 0, max_class = 0;
|
||||||
data_size_t max_value = 0, max_data = 0;
|
data_size_t max_value = 0, max_data = 0;
|
||||||
const struct key *k;
|
WCHAR *fullname = NULL;
|
||||||
char *data;
|
char *data;
|
||||||
|
|
||||||
if (index != -1) /* -1 means use the specified key directly */
|
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)
|
switch(info_class)
|
||||||
{
|
{
|
||||||
case KeyNameInformation:
|
case KeyNameInformation:
|
||||||
namelen = 0;
|
if (!(fullname = key->obj.ops->get_full_name( &key->obj, &namelen ))) return;
|
||||||
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 */
|
/* fall through */
|
||||||
case KeyBasicInformation:
|
case KeyBasicInformation:
|
||||||
classlen = 0; /* only return the name */
|
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)
|
else if (info_class == KeyNameInformation)
|
||||||
{
|
{
|
||||||
data_size_t pos = namelen;
|
|
||||||
reply->namelen = namelen;
|
reply->namelen = namelen;
|
||||||
for (k = key; k != root_key; k = k->parent)
|
memcpy( data, fullname, namelen );
|
||||||
{
|
|
||||||
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 ) );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -978,6 +986,7 @@ static void enum_key( const struct key *key, int index, int info_class,
|
||||||
memcpy( data, key->name, len );
|
memcpy( data, key->name, len );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free( fullname );
|
||||||
if (debug_level > 1) dump_operation( key, NULL, "Enum" );
|
if (debug_level > 1) dump_operation( key, NULL, "Enum" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue