server: Add a helper function for splitting a path into individual elements.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-03-24 12:47:31 +01:00
parent 2a5160c4f2
commit 7b41b7510f
4 changed files with 24 additions and 17 deletions

View File

@ -142,30 +142,28 @@ static struct object *directory_lookup_name( struct object *obj, struct unicode_
struct directory *dir = (struct directory *)obj; struct directory *dir = (struct directory *)obj;
struct object *found; struct object *found;
struct unicode_str tmp; struct unicode_str tmp;
const WCHAR *p;
assert( obj->ops == &directory_ops ); assert( obj->ops == &directory_ops );
if (!name) return NULL; /* open the directory itself */ if (!name) return NULL; /* open the directory itself */
if (!(p = memchrW( name->str, '\\', name->len / sizeof(WCHAR) )))
/* Last element in the path name */
tmp.len = name->len;
else
tmp.len = (p - name->str) * sizeof(WCHAR);
tmp.str = name->str; tmp.str = name->str;
tmp.len = get_path_element( name->str, name->len );
if ((found = find_object( dir->entries, &tmp, attr ))) if ((found = find_object( dir->entries, &tmp, attr )))
{ {
/* Skip trailing \\ */ /* Skip trailing \\ and move to the next element */
if (p) if (tmp.len < name->len)
{ {
p++;
tmp.len += sizeof(WCHAR); tmp.len += sizeof(WCHAR);
name->str += tmp.len / sizeof(WCHAR);
name->len -= tmp.len;
}
else
{
name->str = NULL;
name->len = 0;
} }
/* Move to the next element*/
name->str = p;
name->len -= tmp.len;
return found; return found;
} }
@ -173,7 +171,7 @@ static struct object *directory_lookup_name( struct object *obj, struct unicode_
{ {
if (tmp.len == 0) /* Double backslash */ if (tmp.len == 0) /* Double backslash */
set_error( STATUS_OBJECT_NAME_INVALID ); set_error( STATUS_OBJECT_NAME_INVALID );
else if (p) /* Path still has backslashes */ else if (tmp.len < name->len) /* Path still has backslashes */
set_error( STATUS_OBJECT_PATH_NOT_FOUND ); set_error( STATUS_OBJECT_PATH_NOT_FOUND );
} }
return NULL; return NULL;

View File

@ -276,6 +276,15 @@ struct object *lookup_named_object( struct object *root, const struct unicode_st
return parent; return parent;
} }
/* return length of first path element in name */
data_size_t get_path_element( const WCHAR *name, data_size_t len )
{
data_size_t i;
for (i = 0; i < len / sizeof(WCHAR); i++) if (name[i] == '\\') break;
return i * sizeof(WCHAR);
}
static struct object *create_object( struct object *parent, const struct object_ops *ops, static struct object *create_object( struct object *parent, const struct object_ops *ops,
const struct unicode_str *name, const struct security_descriptor *sd ) const struct unicode_str *name, const struct security_descriptor *sd )
{ {

View File

@ -135,6 +135,7 @@ extern WCHAR *get_object_full_name( struct object *obj, data_size_t *ret_len );
extern void dump_object_name( struct object *obj ); extern void dump_object_name( struct object *obj );
extern struct object *lookup_named_object( struct object *root, const struct unicode_str *name, extern struct object *lookup_named_object( struct object *root, const struct unicode_str *name,
unsigned int attr, struct unicode_str *name_left ); unsigned int attr, struct unicode_str *name_left );
extern data_size_t get_path_element( const WCHAR *name, data_size_t len );
extern void *create_named_object( struct object *parent, const struct object_ops *ops, extern void *create_named_object( struct object *parent, const struct object_ops *ops,
const struct unicode_str *name, unsigned int attributes, const struct unicode_str *name, unsigned int attributes,
const struct security_descriptor *sd ); const struct security_descriptor *sd );

View File

@ -38,7 +38,6 @@
#include "user.h" #include "user.h"
#include "file.h" #include "file.h"
#include "security.h" #include "security.h"
#include "wine/unicode.h"
static struct list winstation_list = LIST_INIT(winstation_list); static struct list winstation_list = LIST_INIT(winstation_list);
@ -163,7 +162,7 @@ static struct object *winstation_lookup_name( struct object *obj, struct unicode
if (!name) return NULL; /* open the winstation itself */ if (!name) return NULL; /* open the winstation itself */
if (memchrW( name->str, '\\', name->len / sizeof(WCHAR) )) /* no backslash allowed in name */ if (get_path_element( name->str, name->len ) < name->len) /* no backslash allowed in name */
{ {
set_error( STATUS_OBJECT_PATH_SYNTAX_BAD ); set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
return NULL; return NULL;
@ -262,7 +261,7 @@ static int desktop_link_name( struct object *obj, struct object_name *name, stru
set_error( STATUS_OBJECT_TYPE_MISMATCH ); set_error( STATUS_OBJECT_TYPE_MISMATCH );
return 0; return 0;
} }
if (memchrW( name->name, '\\', name->len / sizeof(WCHAR) )) /* no backslash allowed in name */ if (get_path_element( name->name, name->len ) < name->len) /* no backslash allowed in name */
{ {
set_error( STATUS_OBJECT_PATH_SYNTAX_BAD ); set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
return 0; return 0;