[3/5] wineboot: Notify explorer when the session ends.

Vincent Povirk madewokherd at gmail.com
Tue Feb 18 17:03:56 CST 2014


This is a bit complicated because wineboot can't destroy the desktop
window, and explorer can't do it either while wineboot is running.
-------------- next part --------------
From 1eb2fb2552b020631b9748519c23c27ad4692e8e Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Tue, 18 Feb 2014 16:17:02 -0600
Subject: [PATCH 3/6] wineboot: Notify explorer when the session ends.

---
 programs/explorer/desktop.c  | 44 +++++++++++++++++++++++++++++++++++++++++++-
 programs/wineboot/wineboot.c |  7 ++++++-
 2 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c
index 7afc8d9..199c938 100644
--- a/programs/explorer/desktop.c
+++ b/programs/explorer/desktop.c
@@ -64,6 +64,11 @@ static int desktop_width, launcher_size, launchers_per_row;
 static struct launcher **launchers;
 static unsigned int nb_launchers, nb_allocated;
 
+#define END_SESSION_TIMER      1
+
+HANDLE endsession_handle;
+int endsession_tries;
+
 static RECT get_icon_rect( unsigned int index )
 {
     RECT rect;
@@ -511,9 +516,46 @@ static LRESULT WINAPI desktop_wnd_proc( HWND hwnd, UINT message, WPARAM wp, LPAR
         return 0;
 
     case WM_CLOSE:
-        DestroyWindow( hwnd );
+        if (wp)
+        {
+            /* Message from wineboot */
+            HANDLE hprocess = OpenProcess( SYNCHRONIZE, FALSE, (DWORD)wp );
+            if (hprocess)
+            {
+                CloseHandle(endsession_handle);
+                endsession_handle = hprocess;
+                endsession_tries = 20;
+                SetTimer( hwnd, END_SESSION_TIMER, 100, NULL );
+            }
+        }
+        else
+            DestroyWindow( hwnd );
         return 0;
 
+    case WM_TIMER:
+        if (wp == END_SESSION_TIMER)
+        {
+            if (WaitForSingleObject( endsession_handle, 0 ) == WAIT_OBJECT_0)
+            {
+                CloseHandle( endsession_handle );
+                endsession_handle = NULL;
+                if (!DestroyWindow( hwnd ))
+                {
+                    WINE_WARN( "processes left over after wineboot quit\n" );
+                    KillTimer( hwnd, END_SESSION_TIMER );
+                }
+            }
+            else if (!--endsession_tries)
+            {
+                WINE_FIXME( "timed out waiting for wineboot to quit\n" );
+                KillTimer( hwnd, END_SESSION_TIMER );
+                CloseHandle( endsession_handle );
+                endsession_handle = NULL;
+            }
+            return 0;
+        }
+        break;
+
     case WM_DESTROY:
         PostQuitMessage(0);
         return 0;
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c
index a20b4e1..2d2b4c7 100644
--- a/programs/wineboot/wineboot.c
+++ b/programs/wineboot/wineboot.c
@@ -1212,7 +1212,12 @@ int main( int argc, char *argv[] )
         {
             if (!shutdown_all_desktops( force )) return 1;
         }
-        else if (!shutdown_close_windows( force )) return 1;
+        else
+        {
+            if (!shutdown_close_windows( force )) return 1;
+            if (shutdown)
+                SendMessageW( GetDesktopWindow(), WM_CLOSE, GetCurrentProcessId(), 0 );
+        }
     }
 
     if (kill) kill_processes( shutdown );
-- 
1.8.3.2



More information about the wine-patches mailing list