server: Check winstation visibility in server to avoid race-conditions.

GetDesktopWindow incorrectly assumes, that the process window station is
still the same one, which was used earlier when changing the desktop.
By moving the visibility check to wineserver we can also avoid
wineserver roundtrip for invisible desktops.

Signed-off-by: Sebastian Lackner <sebastian@fds-team.de>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Sebastian Lackner 2015-12-04 01:17:50 +01:00 committed by Alexandre Julliard
parent 71bbd8da87
commit 6bfa3896fc
2 changed files with 37 additions and 39 deletions

View File

@ -2033,45 +2033,39 @@ HWND WINAPI GetDesktopWindow(void)
if (!thread_info->top_window)
{
USEROBJECTFLAGS flags;
if (!GetUserObjectInformationW( GetProcessWindowStation(), UOI_FLAGS, &flags,
sizeof(flags), NULL ) || (flags.dwFlags & WSF_VISIBLE))
static const WCHAR explorer[] = {'\\','e','x','p','l','o','r','e','r','.','e','x','e',0};
static const WCHAR args[] = {' ','/','d','e','s','k','t','o','p',0};
STARTUPINFOW si;
PROCESS_INFORMATION pi;
WCHAR windir[MAX_PATH];
WCHAR app[MAX_PATH + sizeof(explorer)/sizeof(WCHAR)];
WCHAR cmdline[MAX_PATH + (sizeof(explorer) + sizeof(args))/sizeof(WCHAR)];
void *redir;
memset( &si, 0, sizeof(si) );
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = 0;
si.hStdOutput = 0;
si.hStdError = GetStdHandle( STD_ERROR_HANDLE );
GetSystemDirectoryW( windir, MAX_PATH );
strcpyW( app, windir );
strcatW( app, explorer );
strcpyW( cmdline, app );
strcatW( cmdline, args );
Wow64DisableWow64FsRedirection( &redir );
if (CreateProcessW( app, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS,
NULL, windir, &si, &pi ))
{
static const WCHAR explorer[] = {'\\','e','x','p','l','o','r','e','r','.','e','x','e',0};
static const WCHAR args[] = {' ','/','d','e','s','k','t','o','p',0};
STARTUPINFOW si;
PROCESS_INFORMATION pi;
WCHAR windir[MAX_PATH];
WCHAR app[MAX_PATH + sizeof(explorer)/sizeof(WCHAR)];
WCHAR cmdline[MAX_PATH + (sizeof(explorer) + sizeof(args))/sizeof(WCHAR)];
void *redir;
memset( &si, 0, sizeof(si) );
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = 0;
si.hStdOutput = 0;
si.hStdError = GetStdHandle( STD_ERROR_HANDLE );
GetSystemDirectoryW( windir, MAX_PATH );
strcpyW( app, windir );
strcatW( app, explorer );
strcpyW( cmdline, app );
strcatW( cmdline, args );
Wow64DisableWow64FsRedirection( &redir );
if (CreateProcessW( app, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS,
NULL, windir, &si, &pi ))
{
TRACE( "started explorer pid %04x tid %04x\n", pi.dwProcessId, pi.dwThreadId );
WaitForInputIdle( pi.hProcess, 10000 );
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
}
else WARN( "failed to start explorer, err %d\n", GetLastError() );
Wow64RevertWow64FsRedirection( redir );
TRACE( "started explorer pid %04x tid %04x\n", pi.dwProcessId, pi.dwThreadId );
WaitForInputIdle( pi.hProcess, 10000 );
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
}
else TRACE( "not starting explorer since winstation is not visible\n" );
else WARN( "failed to start explorer, err %d\n", GetLastError() );
Wow64RevertWow64FsRedirection( redir );
SERVER_START_REQ( get_desktop_window )
{

View File

@ -1953,10 +1953,14 @@ DECL_HANDLER(destroy_window)
DECL_HANDLER(get_desktop_window)
{
struct desktop *desktop = get_thread_desktop( current, 0 );
int force;
if (!desktop) return;
if (!desktop->top_window && req->force) /* create it */
/* if winstation is invisible, then avoid roundtrip */
force = req->force || !(desktop->winstation->flags & WSF_VISIBLE);
if (!desktop->top_window && force) /* create it */
{
if ((desktop->top_window = create_window( NULL, NULL, DESKTOP_ATOM, 0 )))
{
@ -1965,7 +1969,7 @@ DECL_HANDLER(get_desktop_window)
}
}
if (!desktop->msg_window && req->force) /* create it */
if (!desktop->msg_window && force) /* create it */
{
static const WCHAR messageW[] = {'M','e','s','s','a','g','e'};
static const struct unicode_str name = { messageW, sizeof(messageW) };