Alexandre Julliard : server: Allow lookup_name to distinguish the case of an empty path.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Feb 9 10:46:48 CST 2016


Module: wine
Branch: master
Commit: 7ad32cf56a2ecb23ee81b9f61cb8a240f6cb79bd
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7ad32cf56a2ecb23ee81b9f61cb8a240f6cb79bd

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Feb  9 20:16:27 2016 +0900

server: Allow lookup_name to distinguish the case of an empty path.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 20d68b2..35c9d0d 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 15ace1e..312a845 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 eb3c0a6..262c4f6 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 934b6a3..4dbc0f3 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 2b8b245..2229070 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 bd09d34..048cd5d 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 6cfbf1d..5d20cdc 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 );




More information about the wine-cvs mailing list