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>
This commit is contained in:
parent
8c4a785daf
commit
19a3f6b5cb
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue