Module: wine Branch: master Commit: 19a3f6b5cb956bc4af1455bd624828478e2c0444 URL: http://source.winehq.org/git/wine.git/?a=commit;h=19a3f6b5cb956bc4af1455bd62...
Author: Sebastian Lackner sebastian@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@fds-team.de Signed-off-by: Alexandre Julliard julliard@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;