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

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


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

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

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 at fds-team.de>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/user32/win.c | 72 +++++++++++++++++++++++++------------------------------
 server/window.c   |  8 +++++--
 2 files changed, 39 insertions(+), 41 deletions(-)

diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index b81c22d..360834e 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -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 ))
-            {
-                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 );
-        }
-        else TRACE( "not starting explorer since winstation is not visible\n" );
+        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 );
 
         SERVER_START_REQ( get_desktop_window )
         {
diff --git a/server/window.c b/server/window.c
index d089149..5f32f1e 100644
--- a/server/window.c
+++ b/server/window.c
@@ -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) };




More information about the wine-cvs mailing list