Alexandre Julliard : server: Add a function to lookup an object by name inside any parent, not only directories.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Feb 8 10:09:20 CST 2016
Module: wine
Branch: master
Commit: bfd0dff215a954dace516b74430c55c6cb7abeba
URL: http://source.winehq.org/git/wine.git/?a=commit;h=bfd0dff215a954dace516b74430c55c6cb7abeba
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Feb 8 14:09:36 2016 +0900
server: Add a function to lookup an object by name inside any parent, not only directories.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
server/directory.c | 55 ++++++------------------------------------------------
server/object.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++
server/object.h | 3 +++
3 files changed, 59 insertions(+), 49 deletions(-)
diff --git a/server/directory.c b/server/directory.c
index 45683b9..cba3a35 100644
--- a/server/directory.c
+++ b/server/directory.c
@@ -218,6 +218,11 @@ static struct directory *create_directory( struct directory *root, const struct
return dir;
}
+struct object *get_root_directory(void)
+{
+ return grab_object( root_directory );
+}
+
struct directory *get_directory_obj( struct process *process, obj_handle_t handle, unsigned int access )
{
return (struct directory *)get_handle_obj( process, handle, access, &directory_ops );
@@ -242,55 +247,7 @@ struct directory *get_directory_obj( struct process *process, obj_handle_t handl
struct object *find_object_dir( struct directory *root, const struct unicode_str *name,
unsigned int attr, struct unicode_str *name_left )
{
- struct object *obj, *parent;
- struct unicode_str name_tmp;
-
- if (name) name_tmp = *name;
- else name_tmp.len = 0;
-
- /* Arguments check:
- * - Either rootdir or name have to be specified
- * - If root is specified path shouldn't start with backslash */
- if (root)
- {
- if (name_tmp.len && name_tmp.str[0] == '\\')
- {
- set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
- return NULL;
- }
- parent = grab_object( root );
- }
- else
- {
- if (!name_tmp.len || name_tmp.str[0] != '\\')
- {
- set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
- return NULL;
- }
- parent = grab_object( &root_directory->obj );
- /* skip leading backslash */
- name_tmp.str++;
- name_tmp.len -= sizeof(WCHAR);
- }
-
- /* Special case for opening RootDirectory */
- if (!name_tmp.len) goto done;
-
- while ((obj = parent->ops->lookup_name( parent, &name_tmp, attr )))
- {
- /* move to the next element */
- release_object ( parent );
- parent = obj;
- }
- if (get_error())
- {
- release_object( parent );
- return NULL;
- }
-
- done:
- if (name_left) *name_left = name_tmp;
- return parent;
+ return lookup_named_object( &root->obj, name, attr, name_left );
}
/* create a named (if name is present) or unnamed object. */
diff --git a/server/object.c b/server/object.c
index c8098ca..297a5b3 100644
--- a/server/object.c
+++ b/server/object.c
@@ -211,6 +211,56 @@ void free_object( struct object *obj )
free( obj );
}
+/* find an object by name starting from the specified root */
+/* if it doesn't exist, its parent is returned, and name_left contains the remaining name */
+struct object *lookup_named_object( struct object *root, const struct unicode_str *name,
+ unsigned int attr, struct unicode_str *name_left )
+{
+ struct object *obj, *parent;
+ struct unicode_str name_tmp = *name;
+
+ if (root)
+ {
+ /* if root is specified path shouldn't start with backslash */
+ if (name_tmp.len && name_tmp.str[0] == '\\')
+ {
+ set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
+ return NULL;
+ }
+ parent = grab_object( root );
+ }
+ else
+ {
+ if (!name_tmp.len || name_tmp.str[0] != '\\')
+ {
+ set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
+ return NULL;
+ }
+ /* skip leading backslash */
+ name_tmp.str++;
+ name_tmp.len -= sizeof(WCHAR);
+ parent = get_root_directory();
+ }
+
+ if (!name_tmp.len) goto done;
+
+ while ((obj = parent->ops->lookup_name( parent, &name_tmp, attr )))
+ {
+ /* move to the next element */
+ release_object ( parent );
+ parent = obj;
+ }
+ if (get_error())
+ {
+ release_object( parent );
+ return NULL;
+ }
+
+ done:
+ if (name_left) *name_left = name_tmp;
+ return parent;
+}
+
void *create_object( struct object *parent, const struct object_ops *ops, const struct unicode_str *name )
{
struct object *obj;
diff --git a/server/object.h b/server/object.h
index c4bc40b..90112d7 100644
--- a/server/object.h
+++ b/server/object.h
@@ -132,6 +132,8 @@ extern void namespace_add( struct namespace *namespace, struct object_name *ptr
extern const WCHAR *get_object_name( struct object *obj, data_size_t *len );
extern WCHAR *get_object_full_name( struct object *obj, data_size_t *ret_len );
extern void dump_object_name( struct object *obj );
+extern struct object *lookup_named_object( struct object *root, const struct unicode_str *name,
+ unsigned int attr, struct unicode_str *name_left );
extern void *create_object( struct object *parent, const struct object_ops *ops,
const struct unicode_str *name );
extern void *create_named_object( struct object *parent, struct namespace *namespace, const struct object_ops *ops,
@@ -225,6 +227,7 @@ extern void release_global_atom( struct winstation *winstation, atom_t atom );
/* directory functions */
+extern struct object *get_root_directory(void);
extern struct directory *get_directory_obj( struct process *process, obj_handle_t handle, unsigned int access );
extern struct object *find_object_dir( struct directory *root, const struct unicode_str *name,
unsigned int attr, struct unicode_str *name_left );
More information about the wine-cvs
mailing list