Fix ExitWindows()
Francois Gouget
fgouget at codeweavers.com
Fri Feb 24 05:58:16 CST 2006
There was a bunch of bugs in ExitWindows():
1) SendMessageTimeoutW() now behaves like on NT, so now 0 means an
infinite timeout, not -1 (which was the Win9x behavior).
2) it used a standard SendMessage() to send the WM_ENDSESSION
messages, which means it would get stuck if one of the processes was hung
3) only windows that received a WM_QUERYENDSESSION are supposed to
receive a WM_ENDSESSION, but ExitWindows() would send the latter to all
windows regardless
Also, Windows is really not so sophisticated: it sends the
WM_QUERYENDSESSION and WM_ENDSESSION, messages in pairs, rather than
first sending all the WM_QUERYENDSESSION messages and then all the
WM_ENDSESSION messages with the result of the 'poll'. It's simpler to do
it the Windows way if we want to avoid bug 3 so I've changed it so.
Changelog:
* dlls/user/user_main.c
Francois Gouget <fgouget at codeweavers.com>
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.
--
Francois Gouget
fgouget at codeweavers.com
-------------- next part --------------
Index: dlls/user/user_main.c
===================================================================
RCS file: /home/wine/wine/dlls/user/user_main.c,v
retrieving revision 1.97
diff -u -p -r1.97 user_main.c
--- dlls/user/user_main.c 17 Sep 2005 14:28:44 -0000 1.97
+++ dlls/user/user_main.c 24 Feb 2006 10:57:09 -0000
@@ -374,23 +374,25 @@ BOOL WINAPI ExitWindowsEx( UINT flags, D
{
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 );
More information about the wine-patches
mailing list