Alexandre Julliard : server: Implement lookup_name() for registry keys.
Alexandre Julliard
julliard at winehq.org
Thu Jul 7 17:03:25 CDT 2022
Module: wine
Branch: master
Commit: b79ff648ef6b18ac49c87571a3f78f731af78d25
URL: https://source.winehq.org/git/wine.git/?a=commit;h=b79ff648ef6b18ac49c87571a3f78f731af78d25
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Jul 7 11:52:59 2022 +0200
server: Implement lookup_name() for registry keys.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
server/registry.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 86 insertions(+), 1 deletion(-)
diff --git a/server/registry.c b/server/registry.c
index 2c52ec85d29..f800bcd842c 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -164,6 +164,8 @@ 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 struct object *key_lookup_name( struct object *obj, struct unicode_str *name,
+ unsigned int attr, struct object *root );
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 );
@@ -184,7 +186,7 @@ static const struct object_ops key_ops =
key_get_sd, /* get_sd */
default_set_sd, /* set_sd */
key_get_full_name, /* get_full_name */
- no_lookup_name, /* lookup_name */
+ key_lookup_name, /* lookup_name */
key_link_name, /* link_name */
key_unlink_name, /* unlink_name */
no_open_file, /* open_file */
@@ -485,6 +487,89 @@ static WCHAR *key_get_full_name( struct object *obj, data_size_t *ret_len )
return (WCHAR *)ret;
}
+static struct object *key_lookup_name( struct object *obj, struct unicode_str *name,
+ unsigned int attr, struct object *root )
+{
+ struct key *found, *key = (struct key *)obj;
+ struct unicode_str tmp;
+ data_size_t next;
+ int index;
+
+ assert( obj->ops == &key_ops );
+
+ if (!name) return NULL; /* open the key itself */
+
+ if (key->flags & KEY_DELETED)
+ {
+ set_error( STATUS_KEY_DELETED );
+ return NULL;
+ }
+
+ if (key->flags & KEY_SYMLINK)
+ {
+ struct unicode_str name_left;
+ struct key_value *value;
+
+ if (!name->len && (attr & OBJ_OPENLINK)) return NULL;
+
+ if (!(value = find_value( key, &symlink_str, &index )) ||
+ value->len < sizeof(WCHAR) || *(WCHAR *)value->data != '\\')
+ {
+ set_error( STATUS_OBJECT_NAME_NOT_FOUND );
+ return NULL;
+ }
+ tmp.str = value->data;
+ tmp.len = (value->len / sizeof(WCHAR)) * sizeof(WCHAR);
+ if ((obj = lookup_named_object( NULL, &tmp, OBJ_CASE_INSENSITIVE, &name_left )))
+ {
+ if (!name->len) *name = name_left; /* symlink destination can be created if missing */
+ else if (name_left.len) /* symlink must have been resolved completely */
+ {
+ release_object( obj );
+ obj = NULL;
+ set_error( STATUS_OBJECT_NAME_NOT_FOUND );
+ }
+ }
+ return obj;
+ }
+
+ if (!name->str) return NULL;
+
+ tmp.str = name->str;
+ tmp.len = get_path_element( name->str, name->len );
+
+ if (tmp.len > MAX_NAME_LEN * sizeof(WCHAR))
+ {
+ set_error( STATUS_INVALID_PARAMETER );
+ return 0;
+ }
+
+ /* skip trailing backslashes */
+ for (next = tmp.len; next < name->len; next += sizeof(WCHAR))
+ if (name->str[next / sizeof(WCHAR)] != '\\') break;
+
+ if (!(found = find_subkey( key, &tmp, &index )))
+ {
+ if (next < name->len) /* path still has elements */
+ set_error( STATUS_OBJECT_NAME_NOT_FOUND );
+ else /* only trailing backslashes */
+ name->len = tmp.len;
+ return NULL;
+ }
+
+ if (next < name->len) /* move to the next element */
+ {
+ name->str += next / sizeof(WCHAR);
+ name->len -= next;
+ }
+ else
+ {
+ name->str = NULL;
+ name->len = 0;
+ }
+ return grab_object( found );
+}
+
static int key_link_name( struct object *obj, struct object_name *name, struct object *parent )
{
struct key *key = (struct key *)obj;
More information about the wine-cvs
mailing list