server: Add a function to lookup an object by name inside any parent, not only directories.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2016-02-08 14:09:36 +09:00
parent a090eff243
commit bfd0dff215
3 changed files with 59 additions and 49 deletions

View File

@ -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. */

View File

@ -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;

View File

@ -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 );