Sebastian Lackner : user32: Make sure explorer.exe process is spawned for the correct desktop.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Dec 4 08:19:27 CST 2015


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

Author: Sebastian Lackner <sebastian at fds-team.de>
Date:   Fri Dec  4 01:19:58 2015 +0100

user32: Make sure explorer.exe process is spawned for the correct desktop.

If an invalid combination of winstation/desktop is active for the
current process, the handle inheritance doesn't work, and no desktop is
created.

Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/user32/win.c              | 19 +++++++++++++++++++
 dlls/user32/winstation.c       |  2 +-
 include/wine/server_protocol.h |  5 +++--
 server/protocol.def            |  5 +++--
 server/winstation.c            | 15 ++++++++-------
 5 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 360834e..1a3cd49 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -25,6 +25,7 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
+
 #include "windef.h"
 #include "winbase.h"
 #include "winver.h"
@@ -2040,10 +2041,28 @@ HWND WINAPI GetDesktopWindow(void)
         WCHAR windir[MAX_PATH];
         WCHAR app[MAX_PATH + sizeof(explorer)/sizeof(WCHAR)];
         WCHAR cmdline[MAX_PATH + (sizeof(explorer) + sizeof(args))/sizeof(WCHAR)];
+        WCHAR desktop[MAX_PATH];
         void *redir;
 
+        SERVER_START_REQ( set_user_object_info )
+        {
+            req->handle = wine_server_obj_handle( GetThreadDesktop(GetCurrentThreadId()) );
+            req->flags  = SET_USER_OBJECT_GET_FULL_NAME;
+            wine_server_set_reply( req, desktop, sizeof(desktop) - sizeof(WCHAR) );
+            if (!wine_server_call( req ))
+            {
+                size_t size = wine_server_reply_size( reply );
+                desktop[size / sizeof(WCHAR)] = 0;
+                TRACE( "starting explorer for desktop %s\n", debugstr_w(desktop) );
+            }
+            else
+                desktop[0] = 0;
+        }
+        SERVER_END_REQ;
+
         memset( &si, 0, sizeof(si) );
         si.cb = sizeof(si);
+        si.lpDesktop = *desktop ? desktop : NULL;
         si.dwFlags = STARTF_USESTDHANDLES;
         si.hStdInput  = 0;
         si.hStdOutput = 0;
diff --git a/dlls/user32/winstation.c b/dlls/user32/winstation.c
index d1353b4..ae1d6ad 100644
--- a/dlls/user32/winstation.c
+++ b/dlls/user32/winstation.c
@@ -632,7 +632,7 @@ BOOL WINAPI SetUserObjectInformationW( HANDLE handle, INT index, LPVOID info, DW
     SERVER_START_REQ( set_user_object_info )
     {
         req->handle    = wine_server_obj_handle( handle );
-        req->flags     = SET_USER_OBJECT_FLAGS;
+        req->flags     = SET_USER_OBJECT_SET_FLAGS;
         req->obj_flags = obj_flags->dwFlags;
         ret = !wine_server_call_err( req );
     }
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 64f02a0..4e33260 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -4009,7 +4009,8 @@ struct set_user_object_info_reply
     unsigned int old_obj_flags;
     /* VARARG(name,unicode_str); */
 };
-#define SET_USER_OBJECT_FLAGS 1
+#define SET_USER_OBJECT_SET_FLAGS       1
+#define SET_USER_OBJECT_GET_FULL_NAME   2
 
 
 
@@ -6152,6 +6153,6 @@ union generic_reply
     struct terminate_job_reply terminate_job_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 489
+#define SERVER_PROTOCOL_VERSION 490
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index aa37c66..04814c9 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2840,14 +2840,15 @@ enum coords_relative
 /* Get/set information about a user object (window station or desktop) */
 @REQ(set_user_object_info)
     obj_handle_t handle;          /* handle to the object */
-    unsigned int flags;           /* information to set */
+    unsigned int flags;           /* information to set/get */
     unsigned int obj_flags;       /* new object flags */
 @REPLY
     int          is_desktop;      /* is object a desktop? */
     unsigned int old_obj_flags;   /* old object flags */
     VARARG(name,unicode_str);     /* object name */
 @END
-#define SET_USER_OBJECT_FLAGS 1
+#define SET_USER_OBJECT_SET_FLAGS       1
+#define SET_USER_OBJECT_GET_FULL_NAME   2
 
 
 /* Register a hotkey */
diff --git a/server/winstation.c b/server/winstation.c
index 08389bb..5016184 100644
--- a/server/winstation.c
+++ b/server/winstation.c
@@ -424,13 +424,13 @@ void close_thread_desktop( struct thread *thread )
 }
 
 /* set the reply data from the object name */
-static void set_reply_data_obj_name( struct object *obj )
+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 && (ptr = memchrW( name, '\\', len/sizeof(WCHAR) )))
+    if (name && !full_name && (ptr = memchrW( name, '\\', len/sizeof(WCHAR) )))
     {
         len -= (ptr + 1 - name) * sizeof(WCHAR);
         name = ptr + 1;
@@ -657,14 +657,14 @@ DECL_HANDLER(set_user_object_info)
         struct desktop *desktop = (struct desktop *)obj;
         reply->is_desktop = 1;
         reply->old_obj_flags = desktop->flags;
-        if (req->flags & SET_USER_OBJECT_FLAGS) desktop->flags = req->obj_flags;
+        if (req->flags & SET_USER_OBJECT_SET_FLAGS) desktop->flags = req->obj_flags;
     }
     else if (obj->ops == &winstation_ops)
     {
         struct winstation *winstation = (struct winstation *)obj;
         reply->is_desktop = 0;
         reply->old_obj_flags = winstation->flags;
-        if (req->flags & SET_USER_OBJECT_FLAGS) winstation->flags = req->obj_flags;
+        if (req->flags & SET_USER_OBJECT_SET_FLAGS) winstation->flags = req->obj_flags;
     }
     else
     {
@@ -672,7 +672,8 @@ DECL_HANDLER(set_user_object_info)
         release_object( obj );
         return;
     }
-    if (get_reply_max_size()) set_reply_data_obj_name( obj );
+    if (get_reply_max_size())
+        set_reply_data_obj_name( obj, (req->flags & SET_USER_OBJECT_GET_FULL_NAME) != 0 );
     release_object( obj );
 }
 
@@ -688,7 +689,7 @@ DECL_HANDLER(enum_winstation)
         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 );
+        set_reply_data_obj_name( &winsta->obj, 0 );
         clear_error();
         reply->next = index;
         return;
@@ -714,7 +715,7 @@ 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 );
+        set_reply_data_obj_name( &desktop->obj, 0 );
         release_object( winstation );
         clear_error();
         reply->next = index;




More information about the wine-cvs mailing list