Author: jimtabor Date: Sun Jul 5 06:21:35 2009 New Revision: 41776
URL: http://svn.reactos.org/svn/reactos?rev=41776&view=rev Log: - Implement the client shutdown procedure. Tested with wine user32 msg undocumented 0x3B tests. Wine tests: msg: 6175 tests executed (0 marked as todo, 937 failures), 5 skipped. - Add missing end session types. - Reference: winproc.c WM_CLIENTSHUTDOWN http://wiki.winprog.org/wiki/Windows_messages
Modified: trunk/reactos/dll/win32/user32/windows/defwnd.c trunk/reactos/include/psdk/winuser.h trunk/reactos/include/reactos/win32k/ntuser.h trunk/reactos/subsystems/win32/win32k/ntuser/defwnd.c
Modified: trunk/reactos/dll/win32/user32/windows/defwnd.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/de... ============================================================================== --- trunk/reactos/dll/win32/user32/windows/defwnd.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/user32/windows/defwnd.c [iso-8859-1] Sun Jul 5 06:21:35 2009 @@ -1463,6 +1463,13 @@ break; }
+ case WM_CLIENTSHUTDOWN: + { + LRESULT lResult; + NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE); + return lResult; + } + case WM_CANCELMODE: { iMenuSysKey = 0;
Modified: trunk/reactos/include/psdk/winuser.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/winuser.h?rev=... ============================================================================== --- trunk/reactos/include/psdk/winuser.h [iso-8859-1] (original) +++ trunk/reactos/include/psdk/winuser.h [iso-8859-1] Sun Jul 5 06:21:35 2009 @@ -2539,6 +2539,8 @@ #endif /* (_WIN32_WINNT >= 0x0400) */ #if (WINVER >= 0x0400) #define ENDSESSION_LOGOFF 0x80000000 +#define ENDSESSION_CRITICAL 0x40000000 +#define ENDSESSION_CLOSEAPP 0x00000001 #endif #if (WINVER >= 0x0500) #define CHILDID_SELF 0
Modified: trunk/reactos/include/reactos/win32k/ntuser.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntus... ============================================================================== --- trunk/reactos/include/reactos/win32k/ntuser.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/win32k/ntuser.h [iso-8859-1] Sun Jul 5 06:21:35 2009 @@ -562,6 +562,7 @@ // // Non SDK Window Message types. // +#define WM_CLIENTSHUTDOWN 59 #define WM_COPYGLOBALDATA 73 #define WM_SYSTIMER 280 #define WM_POPUPSYSTEMMENU 787
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/defwnd.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/defwnd.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/defwnd.c [iso-8859-1] Sun Jul 5 06:21:35 2009 @@ -11,6 +11,91 @@
#define NDEBUG #include <debug.h> + +// Client Shutdown messages +#define MCS_SHUTDOWNTIMERS 1 +#define MCS_QUERYENDSESSION 2 +// Client Shutdown returns +#define MCSR_GOODFORSHUTDOWN 1 +#define MCSR_SHUTDOWNFINISHED 2 +#define MCSR_DONOTSHUTDOWN 3 + +/* + Based on CSRSS and described in pages 1115 - 1118 "Windows Internals, Fifth Edition". + Apparently CSRSS sends out messages to do this w/o going into win32k internals. + */ +static +LRESULT FASTCALL +IntClientShutdown( + PWINDOW_OBJECT pWindow, + WPARAM wParam, + LPARAM lParam +) +{ + LPARAM lParams; + BOOL KillTimers; + INT i; + LRESULT lResult = MCSR_GOODFORSHUTDOWN; + HWND *List; + + lParams = wParam & (ENDSESSION_LOGOFF|ENDSESSION_CRITICAL|ENDSESSION_CLOSEAPP); + KillTimers = wParam & MCS_SHUTDOWNTIMERS ? TRUE : FALSE; +/* + First, send end sessions to children. + */ + List = IntWinListChildren(pWindow); + + if (List) + { + for (i = 0; List[i]; i++) + { + PWINDOW_OBJECT WndChild; + + if (!(WndChild = UserGetWindowObject(List[i])) || !WndChild->Wnd) + continue; + + if (wParam & MCS_QUERYENDSESSION) + { + if (!co_IntSendMessage(WndChild->hSelf, WM_QUERYENDSESSION, 0, lParams)) + { + lResult = MCSR_DONOTSHUTDOWN; + break; + } + } + else + { + co_IntSendMessage(WndChild->hSelf, WM_ENDSESSION, KillTimers, lParams); + if (KillTimers) + { + MsqRemoveTimersWindow(WndChild->MessageQueue, WndChild->hSelf); + } + lResult = MCSR_SHUTDOWNFINISHED; + } + } + ExFreePool(List); + } + if (List && (lResult == MCSR_DONOTSHUTDOWN)) return lResult; +/* + Send to the caller. + */ + if (wParam & MCS_QUERYENDSESSION) + { + if (!co_IntSendMessage(pWindow->hSelf, WM_QUERYENDSESSION, 0, lParams)) + { + lResult = MCSR_DONOTSHUTDOWN; + } + } + else + { + co_IntSendMessage(pWindow->hSelf, WM_ENDSESSION, KillTimers, lParams); + if (KillTimers) + { + MsqRemoveTimersWindow(pWindow->MessageQueue, pWindow->hSelf); + } + lResult = MCSR_SHUTDOWNFINISHED; + } + return lResult; +}
/* Win32k counterpart of User DefWindowProc @@ -35,10 +120,10 @@ { case WM_SYSCOMMAND: { - DPRINT1("hwnd %p WM_SYSCOMMAND %lx %lx\n", Window->hSelf, wParam, lParam ); - if (!ISITHOOKED(WH_CBT)) break; - lResult = co_HOOK_CallHooks(WH_CBT, HCBT_SYSCOMMAND, wParam, lParam); - break; + DPRINT1("hwnd %p WM_SYSCOMMAND %lx %lx\n", Window->hSelf, wParam, lParam ); + if (!ISITHOOKED(WH_CBT)) break; + lResult = co_HOOK_CallHooks(WH_CBT, HCBT_SYSCOMMAND, wParam, lParam); + break; } case WM_SHOWWINDOW: { @@ -59,6 +144,9 @@ } } break; + case WM_CLIENTSHUTDOWN: + return IntClientShutdown(Window, wParam, lParam); + case WM_CBT: { if (!ISITHOOKED(WH_CBT)) break;