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.
This commit is contained in:
Francois Gouget 2006-02-24 12:58:16 +01:00 committed by Alexandre Julliard
parent ec6744490d
commit 6edd77228d
1 changed files with 13 additions and 11 deletions

View File

@ -374,23 +374,25 @@ BOOL WINAPI ExitWindowsEx( UINT flags, DWORD reason )
{ {
HWND *phwnd; HWND *phwnd;
UINT send_flags; 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; send_flags=(flags & EWX_FORCEIFHUNG) ? SMTO_ABORTIFHUNG : SMTO_NORMAL;
for (phwnd = list; *phwnd; phwnd++) for (phwnd = list; *phwnd; phwnd++)
{ {
/* Make sure that the window still exists */ /* Make sure that the window still exists */
if (!IsWindow( *phwnd )) continue; if (!IsWindow( *phwnd )) continue;
if (SendMessageTimeoutW( *phwnd, WM_QUERYENDSESSION, 0, 0, send_flags, INFINITE, &result) && !result) break; if (SendMessageTimeoutW( *phwnd, WM_QUERYENDSESSION, 0, 0, send_flags, 0, &result))
} {
result = (*phwnd == NULL); DWORD_PTR dummy;
SendMessageTimeoutW( *phwnd, WM_ENDSESSION, result, 0, send_flags, 0, &dummy );
/* Now notify all windows that got a WM_QUERYENDSESSION of the result */ if (!result) break;
for (phwnd = list; *phwnd; phwnd++) }
{
if (!IsWindow( *phwnd )) continue;
SendMessageW( *phwnd, WM_ENDSESSION, result, 0 );
} }
HeapFree( GetProcessHeap(), 0, list ); HeapFree( GetProcessHeap(), 0, list );