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 <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "winver.h"
|
#include "winver.h"
|
||||||
|
@ -2040,10 +2041,28 @@ HWND WINAPI GetDesktopWindow(void)
|
||||||
WCHAR windir[MAX_PATH];
|
WCHAR windir[MAX_PATH];
|
||||||
WCHAR app[MAX_PATH + sizeof(explorer)/sizeof(WCHAR)];
|
WCHAR app[MAX_PATH + sizeof(explorer)/sizeof(WCHAR)];
|
||||||
WCHAR cmdline[MAX_PATH + (sizeof(explorer) + sizeof(args))/sizeof(WCHAR)];
|
WCHAR cmdline[MAX_PATH + (sizeof(explorer) + sizeof(args))/sizeof(WCHAR)];
|
||||||
|
WCHAR desktop[MAX_PATH];
|
||||||
void *redir;
|
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) );
|
memset( &si, 0, sizeof(si) );
|
||||||
si.cb = sizeof(si);
|
si.cb = sizeof(si);
|
||||||
|
si.lpDesktop = *desktop ? desktop : NULL;
|
||||||
si.dwFlags = STARTF_USESTDHANDLES;
|
si.dwFlags = STARTF_USESTDHANDLES;
|
||||||
si.hStdInput = 0;
|
si.hStdInput = 0;
|
||||||
si.hStdOutput = 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 )
|
SERVER_START_REQ( set_user_object_info )
|
||||||
{
|
{
|
||||||
req->handle = wine_server_obj_handle( handle );
|
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;
|
req->obj_flags = obj_flags->dwFlags;
|
||||||
ret = !wine_server_call_err( req );
|
ret = !wine_server_call_err( req );
|
||||||
}
|
}
|
||||||
|
|
|
@ -4009,7 +4009,8 @@ struct set_user_object_info_reply
|
||||||
unsigned int old_obj_flags;
|
unsigned int old_obj_flags;
|
||||||
/* VARARG(name,unicode_str); */
|
/* 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;
|
struct terminate_job_reply terminate_job_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 489
|
#define SERVER_PROTOCOL_VERSION 490
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -2840,14 +2840,15 @@ enum coords_relative
|
||||||
/* Get/set information about a user object (window station or desktop) */
|
/* Get/set information about a user object (window station or desktop) */
|
||||||
@REQ(set_user_object_info)
|
@REQ(set_user_object_info)
|
||||||
obj_handle_t handle; /* handle to the object */
|
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 */
|
unsigned int obj_flags; /* new object flags */
|
||||||
@REPLY
|
@REPLY
|
||||||
int is_desktop; /* is object a desktop? */
|
int is_desktop; /* is object a desktop? */
|
||||||
unsigned int old_obj_flags; /* old object flags */
|
unsigned int old_obj_flags; /* old object flags */
|
||||||
VARARG(name,unicode_str); /* object name */
|
VARARG(name,unicode_str); /* object name */
|
||||||
@END
|
@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 */
|
/* Register a hotkey */
|
||||||
|
|
|
@ -424,13 +424,13 @@ void close_thread_desktop( struct thread *thread )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the reply data from the object name */
|
/* 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;
|
data_size_t len;
|
||||||
const WCHAR *ptr, *name = get_object_name( obj, &len );
|
const WCHAR *ptr, *name = get_object_name( obj, &len );
|
||||||
|
|
||||||
/* if there is a backslash return the part of the name after it */
|
/* 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);
|
len -= (ptr + 1 - name) * sizeof(WCHAR);
|
||||||
name = ptr + 1;
|
name = ptr + 1;
|
||||||
|
@ -657,14 +657,14 @@ DECL_HANDLER(set_user_object_info)
|
||||||
struct desktop *desktop = (struct desktop *)obj;
|
struct desktop *desktop = (struct desktop *)obj;
|
||||||
reply->is_desktop = 1;
|
reply->is_desktop = 1;
|
||||||
reply->old_obj_flags = desktop->flags;
|
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)
|
else if (obj->ops == &winstation_ops)
|
||||||
{
|
{
|
||||||
struct winstation *winstation = (struct winstation *)obj;
|
struct winstation *winstation = (struct winstation *)obj;
|
||||||
reply->is_desktop = 0;
|
reply->is_desktop = 0;
|
||||||
reply->old_obj_flags = winstation->flags;
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -672,7 +672,8 @@ DECL_HANDLER(set_user_object_info)
|
||||||
release_object( obj );
|
release_object( obj );
|
||||||
return;
|
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 );
|
release_object( obj );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -688,7 +689,7 @@ DECL_HANDLER(enum_winstation)
|
||||||
unsigned int access = WINSTA_ENUMERATE;
|
unsigned int access = WINSTA_ENUMERATE;
|
||||||
if (req->index > index++) continue;
|
if (req->index > index++) continue;
|
||||||
if (!check_object_access( &winsta->obj, &access )) 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();
|
clear_error();
|
||||||
reply->next = index;
|
reply->next = index;
|
||||||
return;
|
return;
|
||||||
|
@ -714,7 +715,7 @@ DECL_HANDLER(enum_desktop)
|
||||||
if (req->index > index++) continue;
|
if (req->index > index++) continue;
|
||||||
if (!desktop->obj.name) continue;
|
if (!desktop->obj.name) continue;
|
||||||
if (!check_object_access( &desktop->obj, &access )) 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 );
|
release_object( winstation );
|
||||||
clear_error();
|
clear_error();
|
||||||
reply->next = index;
|
reply->next = index;
|
||||||
|
|
Loading…
Reference in New Issue