Alexandre Julliard : server: Store the desktop object names inside their window station.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Jan 20 10:50:02 CST 2016


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Jan 20 22:27:44 2016 +0900

server: Store the desktop object names inside their window station.

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

---

 dlls/user32/tests/winstation.c |   4 +-
 server/user.h                  |   1 +
 server/winstation.c            | 110 ++++++++++++++++++-----------------------
 3 files changed, 50 insertions(+), 65 deletions(-)

diff --git a/dlls/user32/tests/winstation.c b/dlls/user32/tests/winstation.c
index db82026..21df249 100644
--- a/dlls/user32/tests/winstation.c
+++ b/dlls/user32/tests/winstation.c
@@ -452,8 +452,8 @@ static void test_getuserobjectinformation(void)
     name_info = (OBJECT_NAME_INFORMATION *)buffer;
     status = pNtQueryObject(desk, ObjectNameInformation, name_info, sizeof(buffer), NULL);
     ok(!status, "expected STATUS_SUCCESS, got %08x\n", status);
-    todo_wine ok(lstrcmpW(name_info->Name.Buffer, foobarTestW) == 0,
-                 "expected '\\foobarTest', got %s\n", wine_dbgstr_w(name_info->Name.Buffer));
+    ok(lstrcmpW(name_info->Name.Buffer, foobarTestW) == 0,
+       "expected '\\foobarTest', got %s\n", wine_dbgstr_w(name_info->Name.Buffer));
 
     /** Tests for UOI_TYPE **/
 
diff --git a/server/user.h b/server/user.h
index 08d0959..89646f1 100644
--- a/server/user.h
+++ b/server/user.h
@@ -49,6 +49,7 @@ struct winstation
     struct list        desktops;           /* list of desktops of this winstation */
     struct clipboard  *clipboard;          /* clipboard information */
     struct atom_table *atom_table;         /* global atom table */
+    struct namespace  *desktop_names;      /* namespace for desktops of this winstation */
 };
 
 struct global_cursor
diff --git a/server/winstation.c b/server/winstation.c
index 33e121f..7a6b9fc 100644
--- a/server/winstation.c
+++ b/server/winstation.c
@@ -42,7 +42,6 @@
 
 
 static struct list winstation_list = LIST_INIT(winstation_list);
-static struct namespace *winstation_namespace;
 
 static void winstation_dump( struct object *obj, int verbose );
 static struct object_type *winstation_get_type( struct object *obj );
@@ -104,9 +103,6 @@ static struct winstation *create_winstation( struct directory *root, const struc
 {
     struct winstation *winstation;
 
-    if (!winstation_namespace && !(winstation_namespace = create_namespace( 7 )))
-        return NULL;
-
     if (memchrW( name->str, '\\', name->len / sizeof(WCHAR) ))  /* no backslash allowed in name */
     {
         set_error( STATUS_INVALID_PARAMETER );
@@ -123,6 +119,11 @@ static struct winstation *create_winstation( struct directory *root, const struc
             winstation->atom_table = NULL;
             list_add_tail( &winstation_list, &winstation->entry );
             list_init( &winstation->desktops );
+            if (!(winstation->desktop_names = create_namespace( 7 )))
+            {
+                release_object( winstation );
+                return NULL;
+            }
         }
     }
     return winstation;
@@ -157,6 +158,7 @@ static void winstation_destroy( struct object *obj )
     list_remove( &winstation->entry );
     if (winstation->clipboard) release_object( winstation->clipboard );
     if (winstation->atom_table) release_object( winstation->atom_table );
+    free( winstation->desktop_names );
 }
 
 static unsigned int winstation_map_access( struct object *obj, unsigned int access )
@@ -177,32 +179,6 @@ struct winstation *get_process_winstation( struct process *process, unsigned int
                                                 access, &winstation_ops );
 }
 
-/* build the full name of a desktop object */
-static WCHAR *build_desktop_name( const struct unicode_str *name,
-                                  struct winstation *winstation, struct unicode_str *res )
-{
-    const WCHAR *winstation_name;
-    WCHAR *full_name;
-    data_size_t winstation_len;
-
-    if (memchrW( name->str, '\\', name->len / sizeof(WCHAR) ))
-    {
-        set_error( STATUS_INVALID_PARAMETER );
-        return NULL;
-    }
-
-    if (!(winstation_name = get_object_name( &winstation->obj, &winstation_len )))
-        winstation_len = 0;
-
-    res->len = winstation_len + name->len + sizeof(WCHAR);
-    if (!(full_name = mem_alloc( res->len ))) return NULL;
-    memcpy( full_name, winstation_name, winstation_len );
-    full_name[winstation_len / sizeof(WCHAR)] = '\\';
-    memcpy( full_name + winstation_len / sizeof(WCHAR) + 1, name->str, name->len );
-    res->str = full_name;
-    return full_name;
-}
-
 /* retrieve a pointer to a desktop object */
 struct desktop *get_desktop_obj( struct process *process, obj_handle_t handle, unsigned int access )
 {
@@ -214,12 +190,14 @@ static struct desktop *create_desktop( const struct unicode_str *name, unsigned
                                        unsigned int flags, struct winstation *winstation )
 {
     struct desktop *desktop;
-    struct unicode_str full_str;
-    WCHAR *full_name;
 
-    if (!(full_name = build_desktop_name( name, winstation, &full_str ))) return NULL;
+    if (memchrW( name->str, '\\', name->len / sizeof(WCHAR) ))  /* no backslash allowed in name */
+    {
+        set_error( STATUS_INVALID_PARAMETER );
+        return NULL;
+    }
 
-    if ((desktop = create_named_object( winstation_namespace, &desktop_ops, &full_str, attr )))
+    if ((desktop = create_named_object( winstation->desktop_names, &desktop_ops, name, attr )))
     {
         if (get_error() != STATUS_OBJECT_NAME_EXISTS)
         {
@@ -238,7 +216,6 @@ static struct desktop *create_desktop( const struct unicode_str *name, unsigned
             list_init( &desktop->hotkeys );
         }
     }
-    free( full_name );
     return desktop;
 }
 
@@ -423,21 +400,6 @@ void close_thread_desktop( struct thread *thread )
     if (handle) close_handle( thread->process, handle );
 }
 
-/* set the reply data from the object name */
-static void set_reply_data_obj_name( struct object *obj, int full_name )
-{
-    data_size_t len;
-    const WCHAR *ptr, *name = get_object_name( obj, &len );
-
-    /* if there is a backslash return the part of the name after it */
-    if (name && !full_name && (ptr = memchrW( name, '\\', len/sizeof(WCHAR) )))
-    {
-        len -= (ptr + 1 - name) * sizeof(WCHAR);
-        name = ptr + 1;
-    }
-    if (name) set_reply_data( name, min( len, get_reply_max_size() ));
-}
-
 /* create a window station */
 DECL_HANDLER(create_winstation)
 {
@@ -547,15 +509,8 @@ DECL_HANDLER(open_desktop)
 
     if (winstation)
     {
-        struct unicode_str full_str;
-        WCHAR *full_name;
-
-        if ((full_name = build_desktop_name( &name, winstation, &full_str )))
-        {
-            reply->handle = open_object( winstation_namespace, &full_str, &desktop_ops, req->access,
-                                         req->attributes );
-            free( full_name );
-        }
+        reply->handle = open_object( winstation->desktop_names, &name, &desktop_ops,
+                                     req->access, req->attributes );
         release_object( winstation );
     }
 }
@@ -658,6 +613,7 @@ DECL_HANDLER(set_thread_desktop)
 DECL_HANDLER(set_user_object_info)
 {
     struct object *obj;
+    data_size_t len;
 
     if (!(obj = get_handle_obj( current->process, req->handle, 0, NULL ))) return;
 
@@ -681,8 +637,30 @@ DECL_HANDLER(set_user_object_info)
         release_object( obj );
         return;
     }
-    if (get_reply_max_size())
-        set_reply_data_obj_name( obj, (req->flags & SET_USER_OBJECT_GET_FULL_NAME) != 0 );
+    if (obj->ops == &desktop_ops && get_reply_max_size() && (req->flags & SET_USER_OBJECT_GET_FULL_NAME))
+    {
+        struct desktop *desktop = (struct desktop *)obj;
+        data_size_t winstation_len, desktop_len;
+        const WCHAR *winstation_name = get_object_name( &desktop->winstation->obj, &winstation_len );
+        const WCHAR *desktop_name = get_object_name( obj, &desktop_len );
+        WCHAR *full_name;
+
+        if (!winstation_name) winstation_len = 0;
+        if (!desktop_name) desktop_len = 0;
+        len = winstation_len + desktop_len + sizeof(WCHAR);
+        if ((full_name = mem_alloc( len )))
+        {
+            memcpy( full_name, winstation_name, winstation_len );
+            full_name[winstation_len / sizeof(WCHAR)] = '\\';
+            memcpy( full_name + winstation_len / sizeof(WCHAR) + 1, desktop_name, desktop_len );
+            set_reply_data_ptr( full_name, min( len, get_reply_max_size() ));
+        }
+    }
+    else
+    {
+        const WCHAR *name = get_object_name( obj, &len );
+        if (name) set_reply_data( name, min( len, get_reply_max_size() ));
+    }
     release_object( obj );
 }
 
@@ -692,15 +670,18 @@ DECL_HANDLER(enum_winstation)
 {
     unsigned int index = 0;
     struct winstation *winsta;
+    const WCHAR *name;
+    data_size_t len;
 
     LIST_FOR_EACH_ENTRY( winsta, &winstation_list, struct winstation, entry )
     {
         unsigned int access = WINSTA_ENUMERATE;
         if (req->index > index++) continue;
         if (!check_object_access( &winsta->obj, &access )) continue;
-        set_reply_data_obj_name( &winsta->obj, 0 );
         clear_error();
         reply->next = index;
+        if ((name = get_object_name( &winsta->obj, &len )))
+            set_reply_data( name, min( len, get_reply_max_size() ));
         return;
     }
     set_error( STATUS_NO_MORE_ENTRIES );
@@ -713,6 +694,8 @@ DECL_HANDLER(enum_desktop)
     struct winstation *winstation;
     struct desktop *desktop;
     unsigned int index = 0;
+    const WCHAR *name;
+    data_size_t len;
 
     if (!(winstation = (struct winstation *)get_handle_obj( current->process, req->winstation,
                                                             WINSTA_ENUMDESKTOPS, &winstation_ops )))
@@ -724,7 +707,8 @@ DECL_HANDLER(enum_desktop)
         if (req->index > index++) continue;
         if (!desktop->obj.name) continue;
         if (!check_object_access( &desktop->obj, &access )) continue;
-        set_reply_data_obj_name( &desktop->obj, 0 );
+        if ((name = get_object_name( &desktop->obj, &len )))
+            set_reply_data( name, min( len, get_reply_max_size() ));
         release_object( winstation );
         clear_error();
         reply->next = index;




More information about the wine-cvs mailing list