From 7ad32cf56a2ecb23ee81b9f61cb8a240f6cb79bd Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 9 Feb 2016 20:16:27 +0900 Subject: [PATCH] server: Allow lookup_name to distinguish the case of an empty path. Signed-off-by: Alexandre Julliard --- dlls/user32/tests/winstation.c | 1 - server/directory.c | 6 +++--- server/mailslot.c | 2 ++ server/named_pipe.c | 2 ++ server/object.c | 10 ++++++---- server/symlink.c | 4 +++- server/winstation.c | 8 ++------ 7 files changed, 18 insertions(+), 15 deletions(-) diff --git a/dlls/user32/tests/winstation.c b/dlls/user32/tests/winstation.c index 20d68b28a0c..35c9d0d1d1d 100644 --- a/dlls/user32/tests/winstation.c +++ b/dlls/user32/tests/winstation.c @@ -225,7 +225,6 @@ static void test_handles(void) SetLastError( 0xdeadbeef ); w2 = CreateWindowStationA( "foo\\bar", 0, WINSTA_ALL_ACCESS, NULL ); ok( !w2, "create station succeeded\n" ); - todo_wine ok( GetLastError() == ERROR_PATH_NOT_FOUND || GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() ); diff --git a/server/directory.c b/server/directory.c index 15ace1e1a1c..312a8456f48 100644 --- a/server/directory.c +++ b/server/directory.c @@ -144,6 +144,8 @@ static struct object *directory_lookup_name( struct object *obj, struct unicode_ assert( obj->ops == &directory_ops ); + 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; @@ -165,14 +167,12 @@ static struct object *directory_lookup_name( struct object *obj, struct unicode_ return found; } - if (name->str) + if (name->str) /* not the last element */ { if (tmp.len == 0) /* Double backslash */ set_error( STATUS_OBJECT_NAME_INVALID ); else if (p) /* Path still has backslashes */ set_error( STATUS_OBJECT_PATH_NOT_FOUND ); - else - clear_error(); } return NULL; } diff --git a/server/mailslot.c b/server/mailslot.c index eb3c0a69d5d..262c4f66629 100644 --- a/server/mailslot.c +++ b/server/mailslot.c @@ -370,6 +370,8 @@ static struct object *mailslot_device_lookup_name( struct object *obj, struct un assert( obj->ops == &mailslot_device_ops ); + if (!name) return NULL; /* open the device itself */ + if ((found = find_object( device->mailslots, name, attr | OBJ_CASE_INSENSITIVE ))) name->len = 0; diff --git a/server/named_pipe.c b/server/named_pipe.c index 934b6a3a1ab..4dbc0f35a0e 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -473,6 +473,8 @@ static struct object *named_pipe_device_lookup_name( struct object *obj, struct assert( obj->ops == &named_pipe_device_ops ); assert( device->pipes ); + if (!name) return NULL; /* open the device itself */ + if ((found = find_object( device->pipes, name, attr | OBJ_CASE_INSENSITIVE ))) name->len = 0; diff --git a/server/object.c b/server/object.c index 2b8b245c406..22290700f08 100644 --- a/server/object.c +++ b/server/object.c @@ -217,7 +217,7 @@ struct object *lookup_named_object( struct object *root, const struct unicode_st unsigned int attr, struct unicode_str *name_left ) { struct object *obj, *parent; - struct unicode_str name_tmp = *name; + struct unicode_str name_tmp = *name, *ptr = &name_tmp; if (root) { @@ -242,9 +242,11 @@ struct object *lookup_named_object( struct object *root, const struct unicode_st parent = get_root_directory(); } - if (!name_tmp.len) goto done; + if (!name_tmp.len) ptr = NULL; /* special case for empty path */ - while ((obj = parent->ops->lookup_name( parent, &name_tmp, attr ))) + clear_error(); + + while ((obj = parent->ops->lookup_name( parent, ptr, attr ))) { /* move to the next element */ release_object ( parent ); @@ -256,7 +258,6 @@ struct object *lookup_named_object( struct object *root, const struct unicode_st return NULL; } - done: if (name_left) *name_left = name_tmp; return parent; } @@ -617,6 +618,7 @@ int default_set_sd( struct object *obj, const struct security_descriptor *sd, struct object *no_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attr ) { + if (!name) set_error( STATUS_OBJECT_TYPE_MISMATCH ); return NULL; } diff --git a/server/symlink.c b/server/symlink.c index bd09d34a8c4..048cd5d230d 100644 --- a/server/symlink.c +++ b/server/symlink.c @@ -99,11 +99,13 @@ static struct object *symlink_lookup_name( struct object *obj, struct unicode_st struct object *target; assert( obj->ops == &symlink_ops ); + + if (!name) return NULL; if (!name->len && (attr & OBJ_OPENLINK)) return NULL; target_str.str = symlink->target; target_str.len = symlink->len; - if ((target = find_object_dir( NULL, &target_str, attr, &name_left ))) + if ((target = lookup_named_object( NULL, &target_str, attr, &name_left ))) { if (name_left.len) { diff --git a/server/winstation.c b/server/winstation.c index 6cfbf1dc5db..5d20cdc9881 100644 --- a/server/winstation.c +++ b/server/winstation.c @@ -110,12 +110,6 @@ static struct winstation *create_winstation( struct directory *root, const struc { struct winstation *winstation; - if (memchrW( name->str, '\\', name->len / sizeof(WCHAR) )) /* no backslash allowed in name */ - { - set_error( STATUS_INVALID_PARAMETER ); - return NULL; - } - if ((winstation = create_named_object_dir( root, name, attr, &winstation_ops ))) { if (get_error() != STATUS_OBJECT_NAME_EXISTS) @@ -165,6 +159,8 @@ static struct object *winstation_lookup_name( struct object *obj, struct unicode assert( obj->ops == &winstation_ops ); + if (!name) return NULL; /* open the winstation itself */ + if (memchrW( name->str, '\\', name->len / sizeof(WCHAR) )) /* no backslash allowed in name */ { set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );