From 6edd77228dd18f013fb64a22abaaa4da14fde707 Mon Sep 17 00:00:00 2001 From: Francois Gouget Date: Fri, 24 Feb 2006 12:58:16 +0100 Subject: [PATCH] user: Fix ExitWindows(). - Use 0 to get an infinite timeout with SendMessageTimeoutW(). - Use SendMessageTimeoutW() to send the WM_ENDSESSION messages too so we don't get stuck if a process is hung. - Only send WM_ENDSESSION to windows that received a WM_QUERYENDSESSION message. Also better mimick the Windows behavior. --- dlls/user/user_main.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c index 7cca47c43e9..0e2d830f74e 100644 --- a/dlls/user/user_main.c +++ b/dlls/user/user_main.c @@ -374,23 +374,25 @@ BOOL WINAPI ExitWindowsEx( UINT flags, DWORD reason ) { HWND *phwnd; UINT send_flags; - DWORD_PTR result; + DWORD_PTR result=1; - /* Send a WM_QUERYENDSESSION message to every window */ + /* 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, INFINITE, &result) && !result) break; - } - result = (*phwnd == NULL); - - /* Now notify all windows that got a WM_QUERYENDSESSION of the result */ - for (phwnd = list; *phwnd; phwnd++) - { - if (!IsWindow( *phwnd )) continue; - SendMessageW( *phwnd, WM_ENDSESSION, result, 0 ); + 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 );