- 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

svn path=/trunk/; revision=41776
This commit is contained in:
James Tabor 2009-07-05 02:21:35 +00:00
parent 3c12bab49c
commit 3df7c8cf6a
4 changed files with 102 additions and 4 deletions

View file

@ -1463,6 +1463,13 @@ User32DefWindowProc(HWND hWnd,
break;
}
case WM_CLIENTSHUTDOWN:
{
LRESULT lResult;
NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
return lResult;
}
case WM_CANCELMODE:
{
iMenuSysKey = 0;

View file

@ -2539,6 +2539,8 @@ extern "C" {
#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

View file

@ -562,6 +562,7 @@ typedef struct _USERCONNECT
//
// Non SDK Window Message types.
//
#define WM_CLIENTSHUTDOWN 59
#define WM_COPYGLOBALDATA 73
#define WM_SYSTIMER 280
#define WM_POPUPSYSTEMMENU 787

View file

@ -12,6 +12,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 @@ IntDefWindowProc(
{
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 @@ IntDefWindowProc(
}
}
break;
case WM_CLIENTSHUTDOWN:
return IntClientShutdown(Window, wParam, lParam);
case WM_CBT:
{
if (!ISITHOOKED(WH_CBT)) break;