Alexandre Julliard : server: Implement link_name() for registry keys.
Alexandre Julliard
julliard at winehq.org
Thu Jul 7 17:03:25 CDT 2022
Module: wine
Branch: master
Commit: 6a7a7bbe97b210af5c5983fd09a707c33538073c
URL: https://source.winehq.org/git/wine.git/?a=commit;h=6a7a7bbe97b210af5c5983fd09a707c33538073c
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Jul 7 11:49:50 2022 +0200
server: Implement link_name() for registry keys.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
server/registry.c | 78 +++++++++++++++++++++++++++++++++----------------------
1 file changed, 47 insertions(+), 31 deletions(-)
diff --git a/server/registry.c b/server/registry.c
index c7b56344bae..2c52ec85d29 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -164,6 +164,7 @@ static void key_dump( struct object *obj, int verbose );
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_link_name( struct object *obj, struct object_name *name, struct object *parent );
static void key_unlink_name( struct object *obj, struct object_name *name );
static int key_close_handle( struct object *obj, struct process *process, obj_handle_t handle );
static void key_destroy( struct object *obj );
@@ -184,7 +185,7 @@ static const struct object_ops key_ops =
default_set_sd, /* set_sd */
key_get_full_name, /* get_full_name */
no_lookup_name, /* lookup_name */
- no_link_name, /* link_name */
+ key_link_name, /* link_name */
key_unlink_name, /* unlink_name */
no_open_file, /* open_file */
no_kernel_obj_list, /* get_kernel_obj_list */
@@ -202,6 +203,7 @@ static inline struct key *get_parent( const struct key *key )
{
struct object *parent = key->obj.name->parent;
+ if (!parent || parent->ops != &key_ops) return NULL;
return (struct key *)parent;
}
@@ -483,6 +485,40 @@ static WCHAR *key_get_full_name( struct object *obj, data_size_t *ret_len )
return (WCHAR *)ret;
}
+static int key_link_name( struct object *obj, struct object_name *name, struct object *parent )
+{
+ struct key *key = (struct key *)obj;
+ struct key *parent_key = (struct key *)parent;
+ struct unicode_str tmp;
+ int i, index;
+
+ if (parent->ops != &key_ops)
+ {
+ /* only the root key can be created inside a normal directory */
+ if (!root_key) return directory_link_name( obj, name, parent );
+ set_error( STATUS_OBJECT_NAME_NOT_FOUND );
+ return 0;
+ }
+
+ if (parent_key->last_subkey + 1 == parent_key->nb_subkeys)
+ {
+ /* need to grow the array */
+ if (!grow_subkeys( parent_key )) return 0;
+ }
+ tmp.str = name->name;
+ tmp.len = name->len;
+ find_subkey( parent_key, &tmp, &index );
+
+ for (i = ++parent_key->last_subkey; i > index; i--)
+ parent_key->subkeys[i] = parent_key->subkeys[i - 1];
+ parent_key->subkeys[index] = (struct key *)grab_object( key );
+ if (is_wow6432node( name->name, name->len ) &&
+ !is_wow6432node( parent_key->obj.name->name, parent_key->obj.name->len ))
+ parent_key->wow6432node = key;
+ name->parent = parent;
+ return 1;
+}
+
static void key_unlink_name( struct object *obj, struct object_name *name )
{
struct key *key = (struct key *)obj;
@@ -676,33 +712,14 @@ static void touch_key( struct key *key, unsigned int change )
}
/* allocate a subkey for a given key, and return its index */
-static struct key *alloc_subkey( struct key *parent, const struct unicode_str *name,
- int index, timeout_t modif )
+static struct key *alloc_subkey( struct key *parent, const struct unicode_str *name, timeout_t modif )
{
struct key *key;
- int i;
- if (name->len > MAX_NAME_LEN * sizeof(WCHAR))
- {
- set_error( STATUS_INVALID_PARAMETER );
- return NULL;
- }
- if (parent->last_subkey + 1 == parent->nb_subkeys)
- {
- /* need to grow the array */
- if (!grow_subkeys( parent )) return NULL;
- }
- if ((key = alloc_key( name, modif )) != NULL)
- {
- key->obj.name->parent = &parent->obj;
- for (i = ++parent->last_subkey; i > index; i--)
- parent->subkeys[i] = parent->subkeys[i-1];
- parent->subkeys[index] = key;
- if (is_wow6432node( key->obj.name->name, key->obj.name->len ) &&
- !is_wow6432node( parent->obj.name->name, parent->obj.name->len ))
- parent->wow6432node = key;
- }
- return key;
+ if (!(key = alloc_key( name, modif ))) return NULL;
+ if (key_link_name( &key->obj, key->obj.name, &parent->obj )) return key;
+ release_object( key );
+ return NULL;
}
/* return the wow64 variant of the key, or the key itself if none */
@@ -850,7 +867,7 @@ static struct key *create_key( struct key *key, const struct unicode_str *name,
return NULL;
}
make_dirty( key );
- if (!(key = alloc_subkey( key, &token, index, current_time ))) return NULL;
+ if (!(key = alloc_subkey( key, &token, current_time ))) return NULL;
if (options & REG_OPTION_CREATE_LINK) key->flags |= KEY_SYMLINK;
if (options & REG_OPTION_VOLATILE) key->flags |= KEY_VOLATILE;
@@ -895,14 +912,13 @@ static struct key *create_key_recursive( struct key *key, const struct unicode_s
if (token.len)
{
- if (!(key = alloc_subkey( key, &token, index, modif ))) return NULL;
+ if (!(key = alloc_subkey( key, &token, modif ))) return NULL;
base = key;
for (;;)
{
get_path_token( name, &token );
if (!token.len) break;
- /* we know the index is always 0 in a new key */
- if (!(key = alloc_subkey( key, &token, 0, modif )))
+ if (!(key = alloc_subkey( key, &token, modif )))
{
unlink_named_object( &base->obj );
return NULL;
@@ -1076,11 +1092,11 @@ static int rename_key( struct key *key, const struct unicode_str *new_name )
/* delete a key and its values */
static int delete_key( struct key *key, int recurse )
{
- struct key *parent = get_parent( key );
+ struct key *parent;
if (key->flags & KEY_DELETED) return 1;
- if (!parent)
+ if (!(parent = get_parent( key )))
{
set_error( STATUS_ACCESS_DENIED );
return 0;
More information about the wine-cvs
mailing list