Alexandre Julliard : user: Defer all ExitWindowsEx processing to wineboot.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Aug 18 05:39:58 CDT 2006


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Aug 17 20:54:21 2006 +0200

user: Defer all ExitWindowsEx processing to wineboot.

---

 dlls/user/user_main.c       |  209 +++++--------------------------------------
 programs/explorer/desktop.c |    7 -
 2 files changed, 23 insertions(+), 193 deletions(-)

diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c
index 743bded..4a2915a 100644
--- a/dlls/user/user_main.c
+++ b/dlls/user/user_main.c
@@ -26,7 +26,6 @@ #include "winbase.h"
 #include "wingdi.h"
 #include "winuser.h"
 #include "winreg.h"
-#include "tlhelp32.h"
 
 #include "controls.h"
 #include "user_private.h"
@@ -284,201 +283,39 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWO
 
 
 /***********************************************************************
- *           USER_GetProcessHandleList(Internal)
- */
-static HANDLE *USER_GetProcessHandleList(void)
-{
-    DWORD count, i, n;
-    HANDLE *list;
-    PROCESSENTRY32 pe;
-    HANDLE hSnapshot;
-    BOOL r;
-
-    hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
-    if (!hSnapshot)
-    {
-        ERR("cannot create snapshot\n");
-        return FALSE;
-    }
-
-    /* count the number of processes plus one */
-    for (count=0; ;count++)
-    {
-        pe.dwSize = sizeof pe;
-        if (count)
-            r = Process32Next( hSnapshot, &pe );
-        else
-            r = Process32First( hSnapshot, &pe );
-        if (!r)
-            break;
-    }
-
-    /* allocate memory make a list of the process handles */
-    list = HeapAlloc( GetProcessHeap(), 0, (count+1)*sizeof(HANDLE) );
-    n=0;
-    for (i=0; i<count; i++)
-    {
-        pe.dwSize = sizeof pe;
-        if (i)
-            r = Process32Next( hSnapshot, &pe );
-        else
-            r = Process32First( hSnapshot, &pe );
-        if (!r)
-            break;
-
-        /* don't kill ourselves */
-        if (GetCurrentProcessId() == pe.th32ProcessID )
-            continue;
-
-        /* open the process so we don't can track it */
-        list[n] = OpenProcess( PROCESS_QUERY_INFORMATION|
-                                  PROCESS_TERMINATE,
-                                  FALSE, pe.th32ProcessID );
-
-        /* check it didn't terminate already */
-        if( list[n] )
-            n++;
-    }
-    list[n]=0;
-    CloseHandle( hSnapshot );
-
-    if (!r)
-        ERR("Error enumerating processes\n");
-
-    TRACE("return %lu processes\n", n);
-
-    return list;
-}
-
-
-/***********************************************************************
- *		USER_KillProcesses (Internal)
- */
-static DWORD USER_KillProcesses(void)
-{
-    DWORD n, r, i;
-    HANDLE *handles;
-    const DWORD dwShutdownTimeout = 10000;
-
-    TRACE("terminating other processes\n");
-
-    /* kill it and add it to our list of object to wait on */
-    handles = USER_GetProcessHandleList();
-    for (n=0; handles && handles[n]; n++)
-        TerminateProcess( handles[n], 0 );
-
-    /* wait for processes to exit */
-    for (i=0; i<n; i+=MAXIMUM_WAIT_OBJECTS)
-    {
-        int n_objs = ((n-i)>MAXIMUM_WAIT_OBJECTS) ? MAXIMUM_WAIT_OBJECTS : (n-i);
-        r = WaitForMultipleObjects( n_objs, &handles[i], TRUE, dwShutdownTimeout );
-        if (r==WAIT_TIMEOUT)
-            ERR("wait failed!\n");
-    }
-
-    /* close the handles */
-    for (i=0; i<n; i++)
-        CloseHandle( handles[i] );
-
-    HeapFree( GetProcessHeap(), 0, handles );
-
-    return n;
-}
-
-
-/***********************************************************************
- *		USER_DoShutdown (Internal)
- */
-static void USER_DoShutdown(void)
-{
-    DWORD i, n;
-    const DWORD nRetries = 10;
-
-    for (i=0; i<nRetries; i++)
-    {
-        n = USER_KillProcesses();
-        TRACE("Killed %ld processes, attempt %ld\n", n, i);
-        if(!n)
-            break;
-    }
-}
-
-
-/***********************************************************************
  *		ExitWindowsEx (USER32.@)
  */
 BOOL WINAPI ExitWindowsEx( UINT flags, DWORD reason )
 {
-    TRACE("(%x,%lx)\n", flags, reason);
-
-    if (!WIN_IsCurrentThread( GetDesktopWindow() ))
-    {
-        BOOL ret = PostMessageW( GetDesktopWindow(), WM_USER + 666,
-                                 MAKEWPARAM( flags, 0xbabe ), reason);
-        if (ret)
-            return TRUE;
-        /* this can happen if explorer hasn't been started or created the
-         * desktop window yet */
-        WARN("PostMessage failed with error %ld\n", GetLastError());
-        /* fall through to doing it in the same process */
-    }
+    static const WCHAR winebootW[]    = { '\\','w','i','n','e','b','o','o','t',0 };
+    static const WCHAR killW[]        = { ' ','-','-','k','i','l','l',0 };
+    static const WCHAR end_sessionW[] = { ' ','-','-','e','n','d','-','s','e','s','s','i','o','n',0 };
+    static const WCHAR forceW[]       = { ' ','-','-','f','o','r','c','e',0 };
+    static const WCHAR shutdownW[]    = { ' ','-','-','s','h','u','t','d','o','w','n',0 };
 
-    if ((flags & EWX_FORCE) == 0)
-    {
-        HWND *list;
+    WCHAR cmdline[MAX_PATH + 64];
+    PROCESS_INFORMATION pi;
+    STARTUPINFOW si;
 
-        /* We have to build a list of all windows first, as in EnumWindows */
-        list = WIN_ListChildren( GetDesktopWindow() );
-        if (list)
-        {
-            HWND *phwnd;
-            UINT send_flags;
-            DWORD_PTR result=1;
-
-            /* Send a WM_QUERYENDSESSION / WM_ENDSESSION message pair to
-             * each window. Note: it might be better to send all the
-             * WM_QUERYENDSESSION messages, aggregate the results and then
-             * send all the WM_ENDSESSION messages with the results but
-             * that's not what Windows does.
-             */
-            send_flags=(flags & EWX_FORCEIFHUNG) ? SMTO_ABORTIFHUNG : SMTO_NORMAL;
-            for (phwnd = list; *phwnd; phwnd++)
-            {
-                /* Make sure that the window still exists */
-                if (!IsWindow( *phwnd )) continue;
-                if (SendMessageTimeoutW( *phwnd, WM_QUERYENDSESSION, 0, 0, send_flags, 0, &result))
-                {
-                    DWORD_PTR dummy;
-                    SendMessageTimeoutW( *phwnd, WM_ENDSESSION, result, 0, send_flags, 0, &dummy );
-                    if (!result) break;
-                }
-            }
-            HeapFree( GetProcessHeap(), 0, list );
+    GetSystemDirectoryW( cmdline, MAX_PATH );
+    lstrcatW( cmdline, winebootW );
 
-            if (!result)
-                return TRUE;
-        }
+    if (flags & EWX_FORCE) lstrcatW( cmdline, killW );
+    else
+    {
+        lstrcatW( cmdline, end_sessionW );
+        if (flags & EWX_FORCEIFHUNG) lstrcatW( cmdline, forceW );
     }
+    if (!(flags & EWX_REBOOT)) lstrcatW( cmdline, shutdownW );
 
-    /* USER_DoShutdown will kill all processes except the current process */
-    USER_DoShutdown();
-
-    if (flags & EWX_REBOOT)
+    memset( &si, 0, sizeof si );
+    si.cb = sizeof si;
+    if (!CreateProcessW( NULL, cmdline, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi ))
     {
-        WCHAR winebootW[] = { 'w','i','n','e','b','o','o','t',0 };
-        PROCESS_INFORMATION pi;
-        STARTUPINFOW si;
-
-        memset( &si, 0, sizeof si );
-        si.cb = sizeof si;
-        if (CreateProcessW( NULL, winebootW, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ))
-        {
-            CloseHandle( pi.hProcess );
-            CloseHandle( pi.hThread );
-        }
-        else
-            MESSAGE("wine: Failed to start wineboot\n");
+        ERR( "Failed to run %s\n", debugstr_w(cmdline) );
+        return FALSE;
     }
-
+    CloseHandle( pi.hProcess );
+    CloseHandle( pi.hThread );
     return TRUE;
 }
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c
index e552599..0b8bfbb 100644
--- a/programs/explorer/desktop.c
+++ b/programs/explorer/desktop.c
@@ -64,13 +64,6 @@ static LRESULT WINAPI desktop_wnd_proc( 
         }
         return 0;
 
-    /* simple check to prevent applications accidentally triggering the
-     * ExitWindowsEx code if they send random messages to the desktop window */
-    case WM_USER + 666:
-        if (HIWORD(wp) == 0xbabe)
-            return ExitWindowsEx( LOWORD(wp), lp );
-        return DefWindowProcW( hwnd, message, wp, lp );
-
     default:
         return DefWindowProcW( hwnd, message, wp, lp );
     }




More information about the wine-cvs mailing list