2003-05-18 17:16:18 +00:00
|
|
|
/*
|
|
|
|
* ReactOS W32 Subsystem
|
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
2008-07-11 11:22:16 +00:00
|
|
|
/*
|
2001-06-12 17:51:51 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* PURPOSE: Messages
|
|
|
|
* FILE: subsys/win32k/ntuser/message.c
|
|
|
|
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
|
|
|
* REVISION HISTORY:
|
|
|
|
* 06-06-2001 CSH Created
|
|
|
|
*/
|
2002-01-13 22:52:08 +00:00
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2004-05-10 17:07:20 +00:00
|
|
|
#include <w32k.h>
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2003-05-04 15:42:21 +00:00
|
|
|
#define NDEBUG
|
2001-06-12 17:51:51 +00:00
|
|
|
#include <debug.h>
|
|
|
|
|
2004-03-11 14:47:44 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT uFlags;
|
|
|
|
UINT uTimeout;
|
|
|
|
ULONG_PTR Result;
|
|
|
|
}
|
|
|
|
DOSENDMESSAGE, *PDOSENDMESSAGE;
|
2004-03-11 14:47:44 +00:00
|
|
|
|
2002-01-13 22:52:08 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
NTSTATUS FASTCALL
|
2003-08-19 11:48:50 +00:00
|
|
|
IntInitMessageImpl(VOID)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
return STATUS_SUCCESS;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
NTSTATUS FASTCALL
|
2003-08-19 11:48:50 +00:00
|
|
|
IntCleanupMessageImpl(VOID)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
return STATUS_SUCCESS;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2004-04-29 21:13:16 +00:00
|
|
|
#define MMS_SIZE_WPARAM -1
|
|
|
|
#define MMS_SIZE_WPARAMWCHAR -2
|
|
|
|
#define MMS_SIZE_LPARAMSZ -3
|
|
|
|
#define MMS_SIZE_SPECIAL -4
|
|
|
|
#define MMS_FLAG_READ 0x01
|
|
|
|
#define MMS_FLAG_WRITE 0x02
|
|
|
|
#define MMS_FLAG_READWRITE (MMS_FLAG_READ | MMS_FLAG_WRITE)
|
|
|
|
typedef struct tagMSGMEMORY
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
UINT Message;
|
|
|
|
UINT Size;
|
|
|
|
INT Flags;
|
|
|
|
}
|
|
|
|
MSGMEMORY, *PMSGMEMORY;
|
2004-04-29 21:13:16 +00:00
|
|
|
|
|
|
|
static MSGMEMORY MsgMemory[] =
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
{ WM_CREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
|
|
|
|
{ WM_DDE_ACK, sizeof(KMDDELPARAM), MMS_FLAG_READ },
|
|
|
|
{ WM_DDE_EXECUTE, MMS_SIZE_WPARAM, MMS_FLAG_READ },
|
|
|
|
{ WM_GETMINMAXINFO, sizeof(MINMAXINFO), MMS_FLAG_READWRITE },
|
|
|
|
{ WM_GETTEXT, MMS_SIZE_WPARAMWCHAR, MMS_FLAG_WRITE },
|
|
|
|
{ WM_NCCALCSIZE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
|
|
|
|
{ WM_NCCREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
|
|
|
|
{ WM_SETTEXT, MMS_SIZE_LPARAMSZ, MMS_FLAG_READ },
|
|
|
|
{ WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ },
|
|
|
|
{ WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE },
|
|
|
|
{ WM_COPYDATA, MMS_SIZE_SPECIAL, MMS_FLAG_READ },
|
|
|
|
{ WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
|
|
|
|
{ WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
|
|
|
|
};
|
2004-04-29 21:13:16 +00:00
|
|
|
|
|
|
|
static PMSGMEMORY FASTCALL
|
|
|
|
FindMsgMemory(UINT Msg)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
PMSGMEMORY MsgMemoryEntry;
|
|
|
|
|
|
|
|
/* See if this message type is present in the table */
|
|
|
|
for (MsgMemoryEntry = MsgMemory;
|
|
|
|
MsgMemoryEntry < MsgMemory + sizeof(MsgMemory) / sizeof(MSGMEMORY);
|
|
|
|
MsgMemoryEntry++)
|
|
|
|
{
|
2004-04-29 21:13:16 +00:00
|
|
|
if (Msg == MsgMemoryEntry->Message)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
return MsgMemoryEntry;
|
|
|
|
}
|
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return NULL;
|
2004-04-29 21:13:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static UINT FASTCALL
|
|
|
|
MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
CREATESTRUCTW *Cs;
|
|
|
|
PUNICODE_STRING WindowName;
|
|
|
|
PUNICODE_STRING ClassName;
|
2005-11-23 21:59:34 +00:00
|
|
|
UINT Size = 0;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2007-10-19 23:21:45 +00:00
|
|
|
_SEH_TRY
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-11-23 21:59:34 +00:00
|
|
|
if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size)
|
|
|
|
{
|
|
|
|
Size = (UINT)wParam;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
else if (MMS_SIZE_WPARAMWCHAR == MsgMemoryEntry->Size)
|
2005-11-23 21:59:34 +00:00
|
|
|
{
|
|
|
|
Size = (UINT) (wParam * sizeof(WCHAR));
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
else if (MMS_SIZE_LPARAMSZ == MsgMemoryEntry->Size)
|
2005-11-23 21:59:34 +00:00
|
|
|
{
|
|
|
|
Size = (UINT) ((wcslen((PWSTR) lParam) + 1) * sizeof(WCHAR));
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
else if (MMS_SIZE_SPECIAL == MsgMemoryEntry->Size)
|
2005-11-23 21:59:34 +00:00
|
|
|
{
|
|
|
|
switch(MsgMemoryEntry->Message)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
case WM_CREATE:
|
|
|
|
case WM_NCCREATE:
|
|
|
|
Cs = (CREATESTRUCTW *) lParam;
|
|
|
|
WindowName = (PUNICODE_STRING) Cs->lpszName;
|
|
|
|
ClassName = (PUNICODE_STRING) Cs->lpszClass;
|
|
|
|
Size = sizeof(CREATESTRUCTW) + WindowName->Length + sizeof(WCHAR);
|
|
|
|
if (IS_ATOM(ClassName->Buffer))
|
|
|
|
{
|
|
|
|
Size += sizeof(WCHAR) + sizeof(ATOM);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_NCCALCSIZE:
|
2005-11-23 21:59:34 +00:00
|
|
|
Size = wParam ? sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS) : sizeof(RECT);
|
2005-09-07 21:25:42 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_COPYDATA:
|
2005-11-23 21:59:34 +00:00
|
|
|
Size = sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData;
|
|
|
|
break;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
assert(FALSE);
|
2005-11-23 21:59:34 +00:00
|
|
|
Size = 0;
|
2005-09-07 21:25:42 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-11-23 21:59:34 +00:00
|
|
|
Size = MsgMemoryEntry->Size;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
}
|
|
|
|
_SEH_HANDLE
|
2005-11-23 21:59:34 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT1("Exception caught in MsgMemorySize()! Status: 0x%x\n", _SEH_GetExceptionCode());
|
2005-11-23 21:59:34 +00:00
|
|
|
Size = 0;
|
2007-10-19 23:21:45 +00:00
|
|
|
}
|
2005-11-23 21:59:34 +00:00
|
|
|
_SEH_END;
|
|
|
|
return Size;
|
2004-04-29 21:13:16 +00:00
|
|
|
}
|
2002-01-27 01:11:24 +00:00
|
|
|
|
2006-01-08 23:26:03 +00:00
|
|
|
static NTSTATUS
|
2004-04-29 21:13:16 +00:00
|
|
|
PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
NCCALCSIZE_PARAMS *UnpackedNcCalcsize;
|
|
|
|
NCCALCSIZE_PARAMS *PackedNcCalcsize;
|
|
|
|
CREATESTRUCTW *UnpackedCs;
|
|
|
|
CREATESTRUCTW *PackedCs;
|
|
|
|
PUNICODE_STRING WindowName;
|
|
|
|
PUNICODE_STRING ClassName;
|
|
|
|
UINT Size;
|
|
|
|
PCHAR CsData;
|
|
|
|
|
|
|
|
*lParamPacked = lParam;
|
|
|
|
if (WM_NCCALCSIZE == Msg && wParam)
|
|
|
|
{
|
2004-06-16 06:09:40 +00:00
|
|
|
UnpackedNcCalcsize = (NCCALCSIZE_PARAMS *) lParam;
|
|
|
|
if (UnpackedNcCalcsize->lppos != (PWINDOWPOS) (UnpackedNcCalcsize + 1))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
PackedNcCalcsize = ExAllocatePoolWithTag(PagedPool,
|
|
|
|
sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS),
|
|
|
|
TAG_MSG);
|
|
|
|
if (NULL == PackedNcCalcsize)
|
|
|
|
{
|
|
|
|
DPRINT1("Not enough memory to pack lParam\n");
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
RtlCopyMemory(PackedNcCalcsize, UnpackedNcCalcsize, sizeof(NCCALCSIZE_PARAMS));
|
|
|
|
PackedNcCalcsize->lppos = (PWINDOWPOS) (PackedNcCalcsize + 1);
|
|
|
|
RtlCopyMemory(PackedNcCalcsize->lppos, UnpackedNcCalcsize->lppos, sizeof(WINDOWPOS));
|
|
|
|
*lParamPacked = (LPARAM) PackedNcCalcsize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
|
|
|
|
{
|
2004-06-16 06:09:40 +00:00
|
|
|
UnpackedCs = (CREATESTRUCTW *) lParam;
|
|
|
|
WindowName = (PUNICODE_STRING) UnpackedCs->lpszName;
|
|
|
|
ClassName = (PUNICODE_STRING) UnpackedCs->lpszClass;
|
|
|
|
Size = sizeof(CREATESTRUCTW) + WindowName->Length + sizeof(WCHAR);
|
|
|
|
if (IS_ATOM(ClassName->Buffer))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
Size += sizeof(WCHAR) + sizeof(ATOM);
|
|
|
|
}
|
2004-06-16 06:09:40 +00:00
|
|
|
else
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR);
|
|
|
|
}
|
2004-06-16 06:09:40 +00:00
|
|
|
PackedCs = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
|
|
|
|
if (NULL == PackedCs)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
DPRINT1("Not enough memory to pack lParam\n");
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
2004-06-16 06:09:40 +00:00
|
|
|
RtlCopyMemory(PackedCs, UnpackedCs, sizeof(CREATESTRUCTW));
|
|
|
|
CsData = (PCHAR) (PackedCs + 1);
|
|
|
|
PackedCs->lpszName = (LPCWSTR) (CsData - (PCHAR) PackedCs);
|
|
|
|
RtlCopyMemory(CsData, WindowName->Buffer, WindowName->Length);
|
|
|
|
CsData += WindowName->Length;
|
|
|
|
*((WCHAR *) CsData) = L'\0';
|
|
|
|
CsData += sizeof(WCHAR);
|
|
|
|
PackedCs->lpszClass = (LPCWSTR) (CsData - (PCHAR) PackedCs);
|
|
|
|
if (IS_ATOM(ClassName->Buffer))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
*((WCHAR *) CsData) = L'A';
|
|
|
|
CsData += sizeof(WCHAR);
|
|
|
|
*((ATOM *) CsData) = (ATOM)(DWORD_PTR) ClassName->Buffer;
|
|
|
|
CsData += sizeof(ATOM);
|
|
|
|
}
|
2004-06-16 06:09:40 +00:00
|
|
|
else
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
*((WCHAR *) CsData) = L'S';
|
|
|
|
CsData += sizeof(WCHAR);
|
|
|
|
RtlCopyMemory(CsData, ClassName->Buffer, ClassName->Length);
|
|
|
|
CsData += ClassName->Length;
|
|
|
|
*((WCHAR *) CsData) = L'\0';
|
|
|
|
CsData += sizeof(WCHAR);
|
|
|
|
}
|
2004-06-16 06:09:40 +00:00
|
|
|
ASSERT(CsData == (PCHAR) PackedCs + Size);
|
|
|
|
*lParamPacked = (LPARAM) PackedCs;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2002-07-04 19:56:38 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-04-29 21:13:16 +00:00
|
|
|
}
|
|
|
|
|
2006-01-08 23:26:03 +00:00
|
|
|
static NTSTATUS
|
2004-04-29 21:13:16 +00:00
|
|
|
UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
NCCALCSIZE_PARAMS *UnpackedParams;
|
|
|
|
NCCALCSIZE_PARAMS *PackedParams;
|
|
|
|
PWINDOWPOS UnpackedWindowPos;
|
2004-04-29 21:13:16 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if (lParamPacked == lParam)
|
|
|
|
{
|
2004-04-29 21:13:16 +00:00
|
|
|
return STATUS_SUCCESS;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if (WM_NCCALCSIZE == Msg && wParam)
|
|
|
|
{
|
2004-04-29 21:13:16 +00:00
|
|
|
PackedParams = (NCCALCSIZE_PARAMS *) lParamPacked;
|
|
|
|
UnpackedParams = (NCCALCSIZE_PARAMS *) lParam;
|
|
|
|
UnpackedWindowPos = UnpackedParams->lppos;
|
|
|
|
RtlCopyMemory(UnpackedParams, PackedParams, sizeof(NCCALCSIZE_PARAMS));
|
|
|
|
UnpackedParams->lppos = UnpackedWindowPos;
|
|
|
|
RtlCopyMemory(UnpackedWindowPos, PackedParams + 1, sizeof(WINDOWPOS));
|
|
|
|
ExFreePool((PVOID) lParamPacked);
|
|
|
|
|
2004-06-16 06:09:40 +00:00
|
|
|
return STATUS_SUCCESS;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
|
|
|
|
{
|
2004-06-16 06:09:40 +00:00
|
|
|
ExFreePool((PVOID) lParamPacked);
|
|
|
|
|
2004-04-29 21:13:16 +00:00
|
|
|
return STATUS_SUCCESS;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
ASSERT(FALSE);
|
2004-04-29 21:13:16 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2008-07-29 00:35:05 +00:00
|
|
|
static
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
IntCallWndProc
|
|
|
|
( PWINDOW_OBJECT Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
BOOL SameThread = FALSE;
|
|
|
|
|
|
|
|
if (Window->ti == PsGetCurrentThreadWin32Thread()->ThreadInfo)
|
|
|
|
SameThread = TRUE;
|
|
|
|
|
|
|
|
if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROC))) ||
|
|
|
|
(SameThread && ISITHOOKED(WH_CALLWNDPROC)) )
|
|
|
|
{
|
|
|
|
CWPSTRUCT CWP;
|
|
|
|
CWP.hwnd = hWnd;
|
|
|
|
CWP.message = Msg;
|
|
|
|
CWP.wParam = wParam;
|
|
|
|
CWP.lParam = lParam;
|
|
|
|
co_HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, SameThread, (LPARAM)&CWP );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
static
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
IntCallWndProcRet
|
|
|
|
( PWINDOW_OBJECT Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *uResult)
|
|
|
|
{
|
|
|
|
BOOL SameThread = FALSE;
|
|
|
|
|
|
|
|
if (Window->ti == PsGetCurrentThreadWin32Thread()->ThreadInfo)
|
|
|
|
SameThread = TRUE;
|
|
|
|
|
|
|
|
if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROCRET))) ||
|
|
|
|
(SameThread && ISITHOOKED(WH_CALLWNDPROCRET)) )
|
|
|
|
{
|
|
|
|
CWPRETSTRUCT CWPR;
|
|
|
|
CWPR.hwnd = hWnd;
|
|
|
|
CWPR.message = Msg;
|
|
|
|
CWPR.wParam = wParam;
|
|
|
|
CWPR.lParam = lParam;
|
|
|
|
CWPR.lResult = *uResult;
|
|
|
|
co_HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, SameThread, (LPARAM)&CWPR );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-06-16 20:46:39 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL
|
|
|
|
NtUserCallMsgFilter(
|
2008-07-25 23:08:50 +00:00
|
|
|
LPMSG lpmsg,
|
2005-09-07 21:25:42 +00:00
|
|
|
INT code)
|
2005-06-16 20:46:39 +00:00
|
|
|
{
|
2008-07-26 00:25:42 +00:00
|
|
|
BOOL BadChk = FALSE, Ret = TRUE;
|
2008-07-25 23:08:50 +00:00
|
|
|
MSG Msg;
|
2005-09-07 21:25:42 +00:00
|
|
|
DECLARE_RETURN(BOOL);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserCallMsgFilter\n");
|
|
|
|
UserEnterExclusive();
|
2008-07-25 23:08:50 +00:00
|
|
|
if (lpmsg)
|
|
|
|
{
|
|
|
|
_SEH_TRY
|
|
|
|
{
|
|
|
|
ProbeForRead((PVOID)lpmsg,
|
|
|
|
sizeof(MSG),
|
|
|
|
1);
|
|
|
|
RtlCopyMemory( &Msg,
|
|
|
|
(PVOID)lpmsg,
|
|
|
|
sizeof(MSG));
|
|
|
|
}
|
|
|
|
_SEH_HANDLE
|
|
|
|
{
|
|
|
|
BadChk = TRUE;
|
|
|
|
}
|
|
|
|
_SEH_END;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
RETURN( FALSE);
|
|
|
|
|
|
|
|
if (BadChk) RETURN( FALSE);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2008-07-25 23:08:50 +00:00
|
|
|
if (!co_HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)&Msg))
|
|
|
|
{
|
2008-07-26 00:25:42 +00:00
|
|
|
Ret = co_HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)&Msg);
|
2008-07-25 23:08:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_SEH_TRY
|
|
|
|
{
|
|
|
|
ProbeForWrite((PVOID)lpmsg,
|
|
|
|
sizeof(MSG),
|
|
|
|
1);
|
|
|
|
RtlCopyMemory((PVOID)lpmsg,
|
|
|
|
&Msg,
|
|
|
|
sizeof(MSG));
|
|
|
|
}
|
|
|
|
_SEH_HANDLE
|
|
|
|
{
|
|
|
|
BadChk = TRUE;
|
|
|
|
}
|
|
|
|
_SEH_END;
|
|
|
|
if (BadChk) RETURN( FALSE);
|
2008-07-26 00:25:42 +00:00
|
|
|
RETURN( Ret)
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserCallMsgFilter. ret=%i\n", _ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2005-06-16 20:46:39 +00:00
|
|
|
}
|
2003-12-28 13:53:14 +00:00
|
|
|
|
|
|
|
LRESULT STDCALL
|
2004-04-29 21:13:16 +00:00
|
|
|
NtUserDispatchMessage(PNTUSERDISPATCHMESSAGEINFO UnsafeMsgInfo)
|
2003-12-28 13:53:14 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
NTUSERDISPATCHMESSAGEINFO MsgInfo;
|
|
|
|
LRESULT Result = TRUE;
|
|
|
|
DECLARE_RETURN(LRESULT);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserDispatchMessage\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
|
|
|
Status = MmCopyFromCaller(&MsgInfo, UnsafeMsgInfo, sizeof(NTUSERDISPATCHMESSAGEINFO));
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2004-04-29 21:13:16 +00:00
|
|
|
SetLastNtError(Status);
|
2005-09-05 21:19:23 +00:00
|
|
|
RETURN( 0);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
/* Process timer messages. */
|
|
|
|
if (WM_TIMER == MsgInfo.Msg.message && 0 != MsgInfo.Msg.lParam)
|
|
|
|
{
|
2004-04-29 21:13:16 +00:00
|
|
|
LARGE_INTEGER LargeTickCount;
|
|
|
|
/* FIXME: Call hooks. */
|
|
|
|
|
|
|
|
/* FIXME: Check for continuing validity of timer. */
|
|
|
|
|
|
|
|
MsgInfo.HandledByKernel = FALSE;
|
|
|
|
KeQueryTickCount(&LargeTickCount);
|
|
|
|
MsgInfo.Proc = (WNDPROC) MsgInfo.Msg.lParam;
|
|
|
|
MsgInfo.Msg.lParam = (LPARAM)LargeTickCount.u.LowPart;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
else if (NULL == MsgInfo.Msg.hwnd)
|
|
|
|
{
|
2004-04-29 21:13:16 +00:00
|
|
|
MsgInfo.HandledByKernel = TRUE;
|
|
|
|
Result = 0;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-09-11 14:48:32 +00:00
|
|
|
PWINDOW_OBJECT Window;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2004-04-29 21:13:16 +00:00
|
|
|
/* Get the window object. */
|
2005-09-11 14:48:32 +00:00
|
|
|
Window = UserGetWindowObject(MsgInfo.Msg.hwnd);
|
|
|
|
if (NULL == Window)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
MsgInfo.HandledByKernel = TRUE;
|
|
|
|
Result = 0;
|
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
else
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-11 14:48:32 +00:00
|
|
|
if (Window->OwnerThread != PsGetCurrentThread())
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
DPRINT1("Window doesn't belong to the calling thread!\n");
|
|
|
|
MsgInfo.HandledByKernel = TRUE;
|
|
|
|
Result = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* FIXME: Call hook procedures. */
|
|
|
|
|
|
|
|
MsgInfo.HandledByKernel = FALSE;
|
|
|
|
Result = 0;
|
2006-04-05 08:05:55 +00:00
|
|
|
|
2007-11-17 00:40:22 +00:00
|
|
|
if (Window->Wnd->IsSystem)
|
2006-05-03 10:35:11 +00:00
|
|
|
{
|
2007-11-17 00:40:22 +00:00
|
|
|
MsgInfo.Proc = (!MsgInfo.Ansi ? Window->Wnd->WndProc : Window->Wnd->WndProcExtra);
|
2006-05-03 10:35:11 +00:00
|
|
|
}
|
2006-04-14 18:23:11 +00:00
|
|
|
else
|
2006-05-03 10:35:11 +00:00
|
|
|
{
|
2007-11-16 09:03:51 +00:00
|
|
|
MsgInfo.Ansi = !Window->Wnd->Unicode;
|
2007-11-17 00:40:22 +00:00
|
|
|
MsgInfo.Proc = Window->Wnd->WndProc;
|
2006-05-03 10:35:11 +00:00
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Status = MmCopyToCaller(UnsafeMsgInfo, &MsgInfo, sizeof(NTUSERDISPATCHMESSAGEINFO));
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2004-04-29 21:13:16 +00:00
|
|
|
SetLastNtError(Status);
|
2005-09-05 21:19:23 +00:00
|
|
|
RETURN( 0);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
RETURN( Result);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserDispatchMessage. ret=%i\n", _ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-12-28 13:53:14 +00:00
|
|
|
}
|
|
|
|
|
2003-12-28 14:21:03 +00:00
|
|
|
|
|
|
|
BOOL STDCALL
|
|
|
|
NtUserTranslateMessage(LPMSG lpMsg,
|
2005-09-07 21:25:42 +00:00
|
|
|
HKL dwhkl)
|
2003-12-28 14:21:03 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
MSG SafeMsg;
|
|
|
|
DECLARE_RETURN(BOOL);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserTranslateMessage\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
|
|
|
Status = MmCopyFromCaller(&SafeMsg, lpMsg, sizeof(MSG));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
RETURN( IntTranslateKbdMessage(&SafeMsg, dwhkl));
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserTranslateMessage: ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-12-28 14:21:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-20 21:45:14 +00:00
|
|
|
VOID FASTCALL
|
2005-09-05 21:19:23 +00:00
|
|
|
co_IntSendHitTestMessages(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg)
|
2003-12-20 21:45:14 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
if(!Msg->hwnd || ThreadQueue->CaptureWindow)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(Msg->message)
|
|
|
|
{
|
|
|
|
case WM_MOUSEMOVE:
|
|
|
|
{
|
|
|
|
co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(HTCLIENT, Msg->message));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case WM_NCMOUSEMOVE:
|
|
|
|
{
|
|
|
|
co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(Msg->wParam, Msg->message));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case WM_LBUTTONDOWN:
|
|
|
|
case WM_MBUTTONDOWN:
|
|
|
|
case WM_RBUTTONDOWN:
|
|
|
|
case WM_XBUTTONDOWN:
|
|
|
|
case WM_LBUTTONDBLCLK:
|
|
|
|
case WM_MBUTTONDBLCLK:
|
|
|
|
case WM_RBUTTONDBLCLK:
|
|
|
|
case WM_XBUTTONDBLCLK:
|
|
|
|
{
|
|
|
|
WPARAM wParam;
|
|
|
|
PSYSTEM_CURSORINFO CurInfo;
|
|
|
|
|
|
|
|
if(!IntGetWindowStationObject(InputWindowStation))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
CurInfo = IntGetSysCursorInfo(InputWindowStation);
|
|
|
|
wParam = (WPARAM)(CurInfo->ButtonsDown);
|
|
|
|
ObDereferenceObject(InputWindowStation);
|
|
|
|
|
|
|
|
co_IntSendMessage(Msg->hwnd, WM_MOUSEMOVE, wParam, Msg->lParam);
|
|
|
|
co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(HTCLIENT, Msg->message));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case WM_NCLBUTTONDOWN:
|
|
|
|
case WM_NCMBUTTONDOWN:
|
|
|
|
case WM_NCRBUTTONDOWN:
|
|
|
|
case WM_NCXBUTTONDOWN:
|
|
|
|
case WM_NCLBUTTONDBLCLK:
|
|
|
|
case WM_NCMBUTTONDBLCLK:
|
|
|
|
case WM_NCRBUTTONDBLCLK:
|
|
|
|
case WM_NCXBUTTONDBLCLK:
|
|
|
|
{
|
|
|
|
co_IntSendMessage(Msg->hwnd, WM_NCMOUSEMOVE, (WPARAM)Msg->wParam, Msg->lParam);
|
|
|
|
co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(Msg->wParam, Msg->message));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2003-12-20 21:45:14 +00:00
|
|
|
}
|
|
|
|
|
2004-04-15 23:36:03 +00:00
|
|
|
BOOL FASTCALL
|
2005-09-05 21:19:23 +00:00
|
|
|
co_IntActivateWindowMouse(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, PWINDOW_OBJECT MsgWindow,
|
2005-09-07 21:25:42 +00:00
|
|
|
USHORT *HitTest)
|
2004-04-15 23:36:03 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
ULONG Result;
|
|
|
|
PWINDOW_OBJECT Parent;
|
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
ASSERT_REFS_CO(MsgWindow);
|
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if(*HitTest == (USHORT)HTTRANSPARENT)
|
|
|
|
{
|
|
|
|
/* eat the message, search again! */
|
2004-04-15 23:36:03 +00:00
|
|
|
return TRUE;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
Parent = IntGetParent(MsgWindow);//fixme: deref retval?
|
2005-09-07 21:25:42 +00:00
|
|
|
/* fixme: abort if no parent ? */
|
|
|
|
Result = co_IntSendMessage(MsgWindow->hSelf,
|
|
|
|
WM_MOUSEACTIVATE,
|
|
|
|
(WPARAM) (Parent ? Parent->hSelf : NULL),
|
|
|
|
(LPARAM)MAKELONG(*HitTest, Msg->message)
|
|
|
|
);
|
|
|
|
|
|
|
|
switch (Result)
|
|
|
|
{
|
|
|
|
case MA_NOACTIVATEANDEAT:
|
|
|
|
return TRUE;
|
|
|
|
case MA_NOACTIVATE:
|
|
|
|
break;
|
|
|
|
case MA_ACTIVATEANDEAT:
|
|
|
|
co_IntMouseActivateWindow(MsgWindow);
|
|
|
|
return TRUE;
|
|
|
|
default:
|
|
|
|
/* MA_ACTIVATE */
|
|
|
|
co_IntMouseActivateWindow(MsgWindow);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
2004-04-15 23:36:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOL FASTCALL
|
2005-09-05 21:19:23 +00:00
|
|
|
co_IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *HitTest, BOOL Remove)
|
2004-04-15 23:36:03 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
PWINDOW_OBJECT Window;
|
2005-10-15 13:22:13 +00:00
|
|
|
USER_REFERENCE_ENTRY Ref, DesktopRef;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
if(!(Window = UserGetWindowObject(Msg->hwnd)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
/* let's just eat the message?! */
|
|
|
|
return TRUE;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-10-15 13:22:13 +00:00
|
|
|
UserRefObjectCo(Window, &Ref);
|
2005-09-11 14:48:32 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if(ThreadQueue == Window->MessageQueue &&
|
|
|
|
ThreadQueue->CaptureWindow != Window->hSelf)
|
|
|
|
{
|
|
|
|
/* only send WM_NCHITTEST messages if we're not capturing the window! */
|
|
|
|
*HitTest = co_IntSendMessage(Window->hSelf, WM_NCHITTEST, 0,
|
|
|
|
MAKELONG(Msg->pt.x, Msg->pt.y));
|
|
|
|
|
|
|
|
if(*HitTest == (USHORT)HTTRANSPARENT)
|
2004-05-05 22:13:17 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
PWINDOW_OBJECT DesktopWindow;
|
|
|
|
HWND hDesktop = IntGetDesktopWindow();
|
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
if((DesktopWindow = UserGetWindowObject(hDesktop)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
PWINDOW_OBJECT Wnd;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-10-15 13:22:13 +00:00
|
|
|
UserRefObjectCo(DesktopWindow, &DesktopRef);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
co_WinPosWindowFromPoint(DesktopWindow, Window->MessageQueue, &Msg->pt, &Wnd);
|
|
|
|
if(Wnd)
|
2004-12-11 19:39:18 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
if(Wnd != Window)
|
|
|
|
{
|
|
|
|
/* post the message to the other window */
|
|
|
|
Msg->hwnd = Wnd->hSelf;
|
|
|
|
if(!(Wnd->Status & WINDOWSTATUS_DESTROYING))
|
|
|
|
{
|
|
|
|
MsqPostMessage(Wnd->MessageQueue, Msg, FALSE,
|
|
|
|
Msg->message == WM_MOUSEMOVE ? QS_MOUSEMOVE :
|
|
|
|
QS_MOUSEBUTTON);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* eat the message */
|
2008-02-13 00:46:23 +00:00
|
|
|
UserDereferenceObject(Wnd);
|
2005-09-11 14:48:32 +00:00
|
|
|
UserDerefObjectCo(DesktopWindow);
|
|
|
|
UserDerefObjectCo(Window);
|
2005-09-07 21:25:42 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
2008-02-13 00:46:23 +00:00
|
|
|
UserDereferenceObject(Wnd);
|
2004-12-11 19:39:18 +00:00
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
UserDerefObjectCo(DesktopWindow);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*HitTest = HTCLIENT;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if(IS_BTN_MESSAGE(Msg->message, DOWN))
|
|
|
|
{
|
|
|
|
/* generate double click messages, if necessary */
|
|
|
|
if ((((*HitTest) != HTCLIENT) ||
|
2007-11-16 02:37:14 +00:00
|
|
|
(Window->Wnd->Class->Style & CS_DBLCLKS)) &&
|
2005-09-07 21:25:42 +00:00
|
|
|
MsqIsDblClk(Msg, Remove))
|
|
|
|
{
|
|
|
|
Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;
|
2004-05-05 22:13:17 +00:00
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(Msg->message != WM_MOUSEWHEEL)
|
|
|
|
{
|
|
|
|
|
|
|
|
if ((*HitTest) != HTCLIENT)
|
2004-04-15 23:36:03 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
Msg->message += WM_NCMOUSEMOVE - WM_MOUSEMOVE;
|
|
|
|
if((Msg->message == WM_NCRBUTTONUP) &&
|
|
|
|
(((*HitTest) == HTCAPTION) || ((*HitTest) == HTSYSMENU)))
|
|
|
|
{
|
|
|
|
Msg->message = WM_CONTEXTMENU;
|
|
|
|
Msg->wParam = (WPARAM)Window->hSelf;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Msg->wParam = *HitTest;
|
|
|
|
}
|
|
|
|
Msg->lParam = MAKELONG(Msg->pt.x, Msg->pt.y);
|
2004-04-15 23:36:03 +00:00
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
else if(ThreadQueue->MoveSize == NULL &&
|
|
|
|
ThreadQueue->MenuOwner == NULL)
|
2004-04-15 23:36:03 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
/* NOTE: Msg->pt should remain in screen coordinates. -- FiN */
|
|
|
|
Msg->lParam = MAKELONG(
|
2007-11-15 19:42:41 +00:00
|
|
|
Msg->pt.x - (WORD)Window->Wnd->ClientRect.left,
|
|
|
|
Msg->pt.y - (WORD)Window->Wnd->ClientRect.top);
|
2004-04-15 23:36:03 +00:00
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
UserDerefObjectCo(Window);
|
2005-09-07 21:25:42 +00:00
|
|
|
return FALSE;
|
2004-04-15 23:36:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-01-13 22:52:08 +00:00
|
|
|
/*
|
2003-05-21 22:58:43 +00:00
|
|
|
* Internal version of PeekMessage() doing all the work
|
2002-01-13 22:52:08 +00:00
|
|
|
*/
|
2004-04-15 23:36:03 +00:00
|
|
|
BOOL FASTCALL
|
2005-09-05 21:19:23 +00:00
|
|
|
co_IntPeekMessage(PUSER_MESSAGE Msg,
|
2005-09-11 14:48:32 +00:00
|
|
|
HWND hWnd,
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT MsgFilterMin,
|
|
|
|
UINT MsgFilterMax,
|
|
|
|
UINT RemoveMsg)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
LARGE_INTEGER LargeTickCount;
|
|
|
|
PUSER_MESSAGE_QUEUE ThreadQueue;
|
|
|
|
PUSER_MESSAGE Message;
|
|
|
|
BOOL Present, RemoveMessages;
|
2005-10-15 13:22:13 +00:00
|
|
|
USER_REFERENCE_ENTRY Ref;
|
2006-01-08 23:26:03 +00:00
|
|
|
USHORT HitTest;
|
2008-07-24 11:38:08 +00:00
|
|
|
MOUSEHOOKSTRUCT MHook;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
/* The queues and order in which they are checked are documented in the MSDN
|
|
|
|
article on GetMessage() */
|
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetCurrentThreadWin32Thread()->MessageQueue;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
/* Inspect RemoveMsg flags */
|
|
|
|
/* FIXME: The only flag we process is PM_REMOVE - processing of others must still be implemented */
|
|
|
|
RemoveMessages = RemoveMsg & PM_REMOVE;
|
|
|
|
|
|
|
|
CheckMessages:
|
|
|
|
|
|
|
|
Present = FALSE;
|
|
|
|
|
|
|
|
KeQueryTickCount(&LargeTickCount);
|
|
|
|
ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
|
|
|
|
|
|
|
|
/* Dispatch sent messages here. */
|
|
|
|
while (co_MsqDispatchOneSentMessage(ThreadQueue))
|
|
|
|
;
|
|
|
|
|
|
|
|
/* Now look for a quit message. */
|
|
|
|
|
|
|
|
if (ThreadQueue->QuitPosted)
|
|
|
|
{
|
|
|
|
/* According to the PSDK, WM_QUIT messages are always returned, regardless
|
|
|
|
of the filter specified */
|
|
|
|
Msg->Msg.hwnd = NULL;
|
|
|
|
Msg->Msg.message = WM_QUIT;
|
|
|
|
Msg->Msg.wParam = ThreadQueue->QuitExitCode;
|
|
|
|
Msg->Msg.lParam = 0;
|
|
|
|
Msg->FreeLParam = FALSE;
|
|
|
|
if (RemoveMessages)
|
2004-04-15 23:36:03 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
ThreadQueue->QuitPosted = FALSE;
|
2004-04-15 23:36:03 +00:00
|
|
|
}
|
2008-07-22 04:54:53 +00:00
|
|
|
goto MsgExit;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Now check for normal messages. */
|
|
|
|
Present = co_MsqFindMessage(ThreadQueue,
|
|
|
|
FALSE,
|
|
|
|
RemoveMessages,
|
2005-09-11 14:48:32 +00:00
|
|
|
hWnd,
|
2005-09-07 21:25:42 +00:00
|
|
|
MsgFilterMin,
|
|
|
|
MsgFilterMax,
|
|
|
|
&Message);
|
|
|
|
if (Present)
|
|
|
|
{
|
|
|
|
RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
|
|
|
|
if (RemoveMessages)
|
2004-04-15 23:36:03 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
MsqDestroyMessage(Message);
|
2004-04-15 23:36:03 +00:00
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
goto MessageFound;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
/* Check for hardware events. */
|
|
|
|
Present = co_MsqFindMessage(ThreadQueue,
|
|
|
|
TRUE,
|
|
|
|
RemoveMessages,
|
2005-09-11 14:48:32 +00:00
|
|
|
hWnd,
|
2005-09-07 21:25:42 +00:00
|
|
|
MsgFilterMin,
|
|
|
|
MsgFilterMax,
|
|
|
|
&Message);
|
|
|
|
if (Present)
|
|
|
|
{
|
|
|
|
RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
|
|
|
|
if (RemoveMessages)
|
2004-04-15 23:36:03 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
MsqDestroyMessage(Message);
|
2004-04-15 23:36:03 +00:00
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
goto MessageFound;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for sent messages again. */
|
|
|
|
while (co_MsqDispatchOneSentMessage(ThreadQueue))
|
|
|
|
;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
/* Check for paint messages. */
|
2006-07-20 14:53:47 +00:00
|
|
|
if (IntGetPaintMessage(hWnd, MsgFilterMin, MsgFilterMax, PsGetCurrentThreadWin32Thread(), &Msg->Msg, RemoveMessages))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
Msg->FreeLParam = FALSE;
|
2008-07-22 04:54:53 +00:00
|
|
|
goto MsgExit;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for WM_(SYS)TIMER messages */
|
2005-09-11 14:48:32 +00:00
|
|
|
Present = MsqGetTimerMessage(ThreadQueue, hWnd, MsgFilterMin, MsgFilterMax,
|
2005-09-07 21:25:42 +00:00
|
|
|
&Msg->Msg, RemoveMessages);
|
|
|
|
if (Present)
|
|
|
|
{
|
|
|
|
Msg->FreeLParam = FALSE;
|
|
|
|
goto MessageFound;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(Present)
|
|
|
|
{
|
|
|
|
MessageFound:
|
|
|
|
|
|
|
|
if(RemoveMessages)
|
|
|
|
{
|
|
|
|
PWINDOW_OBJECT MsgWindow = NULL;
|
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
if(Msg->Msg.hwnd && (MsgWindow = UserGetWindowObject(Msg->Msg.hwnd)) &&
|
2005-09-07 21:25:42 +00:00
|
|
|
Msg->Msg.message >= WM_MOUSEFIRST && Msg->Msg.message <= WM_MOUSELAST)
|
|
|
|
{
|
|
|
|
USHORT HitTest;
|
|
|
|
|
2005-10-15 13:22:13 +00:00
|
|
|
UserRefObjectCo(MsgWindow, &Ref);
|
2005-09-11 21:05:32 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if(co_IntTranslateMouseMessage(ThreadQueue, &Msg->Msg, &HitTest, TRUE))
|
|
|
|
/* FIXME - check message filter again, if the message doesn't match anymore,
|
|
|
|
search again */
|
|
|
|
{
|
2005-09-11 14:48:32 +00:00
|
|
|
UserDerefObjectCo(MsgWindow);
|
2005-09-07 21:25:42 +00:00
|
|
|
/* eat the message, search again */
|
|
|
|
goto CheckMessages;
|
|
|
|
}
|
2005-09-11 21:05:32 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if(ThreadQueue->CaptureWindow == NULL)
|
|
|
|
{
|
|
|
|
co_IntSendHitTestMessages(ThreadQueue, &Msg->Msg);
|
|
|
|
if((Msg->Msg.message != WM_MOUSEMOVE && Msg->Msg.message != WM_NCMOUSEMOVE) &&
|
|
|
|
IS_BTN_MESSAGE(Msg->Msg.message, DOWN) &&
|
|
|
|
co_IntActivateWindowMouse(ThreadQueue, &Msg->Msg, MsgWindow, &HitTest))
|
|
|
|
{
|
2005-09-11 14:48:32 +00:00
|
|
|
UserDerefObjectCo(MsgWindow);
|
2005-09-07 21:25:42 +00:00
|
|
|
/* eat the message, search again */
|
|
|
|
goto CheckMessages;
|
|
|
|
}
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
UserDerefObjectCo(MsgWindow);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
co_IntSendHitTestMessages(ThreadQueue, &Msg->Msg);
|
|
|
|
}
|
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
// if(MsgWindow)
|
|
|
|
// {
|
2008-02-13 00:46:23 +00:00
|
|
|
// UserDereferenceObject(MsgWindow);
|
2005-09-11 14:48:32 +00:00
|
|
|
// }
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2008-07-22 04:54:53 +00:00
|
|
|
goto MsgExit;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if((Msg->Msg.hwnd && Msg->Msg.message >= WM_MOUSEFIRST && Msg->Msg.message <= WM_MOUSELAST) &&
|
|
|
|
co_IntTranslateMouseMessage(ThreadQueue, &Msg->Msg, &HitTest, FALSE))
|
|
|
|
/* FIXME - check message filter again, if the message doesn't match anymore,
|
|
|
|
search again */
|
|
|
|
{
|
|
|
|
/* eat the message, search again */
|
|
|
|
goto CheckMessages;
|
|
|
|
}
|
2008-07-22 04:54:53 +00:00
|
|
|
MsgExit:
|
2008-07-24 11:38:08 +00:00
|
|
|
if ( ISITHOOKED(WH_MOUSE) &&
|
|
|
|
Msg->Msg.message >= WM_MOUSEFIRST &&
|
|
|
|
Msg->Msg.message <= WM_MOUSELAST )
|
|
|
|
{
|
|
|
|
MHook.pt = Msg->Msg.pt;
|
|
|
|
MHook.hwnd = Msg->Msg.hwnd;
|
|
|
|
MHook.wHitTestCode = HitTest;
|
|
|
|
MHook.dwExtraInfo = 0;
|
|
|
|
if (co_HOOK_CallHooks( WH_MOUSE,
|
|
|
|
RemoveMsg ? HC_ACTION : HC_NOREMOVE,
|
|
|
|
Msg->Msg.message,
|
|
|
|
(LPARAM)&MHook ))
|
|
|
|
{
|
|
|
|
if (ISITHOOKED(WH_CBT))
|
|
|
|
{
|
|
|
|
MHook.pt = Msg->Msg.pt;
|
|
|
|
MHook.hwnd = Msg->Msg.hwnd;
|
|
|
|
MHook.wHitTestCode = HitTest;
|
|
|
|
MHook.dwExtraInfo = 0;
|
|
|
|
co_HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED,
|
|
|
|
Msg->Msg.message, (LPARAM)&MHook);
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( ISITHOOKED(WH_KEYBOARD) &&
|
|
|
|
(Msg->Msg.message == WM_KEYDOWN || Msg->Msg.message == WM_KEYUP) )
|
|
|
|
{
|
|
|
|
if (co_HOOK_CallHooks( WH_KEYBOARD,
|
|
|
|
RemoveMsg ? HC_ACTION : HC_NOREMOVE,
|
|
|
|
LOWORD(Msg->Msg.wParam),
|
|
|
|
Msg->Msg.lParam))
|
|
|
|
{
|
|
|
|
if (ISITHOOKED(WH_CBT))
|
|
|
|
{
|
|
|
|
/* skip this message */
|
|
|
|
co_HOOK_CallHooks( WH_CBT, HCBT_KEYSKIPPED,
|
|
|
|
LOWORD(Msg->Msg.wParam), Msg->Msg.lParam );
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
2008-07-22 04:54:53 +00:00
|
|
|
// The WH_GETMESSAGE hook enables an application to monitor messages about to
|
|
|
|
// be returned by the GetMessage or PeekMessage function.
|
2008-07-24 11:38:08 +00:00
|
|
|
if (ISITHOOKED(WH_GETMESSAGE))
|
2008-07-22 04:54:53 +00:00
|
|
|
{
|
2008-07-22 23:46:31 +00:00
|
|
|
//DPRINT1("Peek WH_GETMESSAGE -> %x\n",&Msg);
|
|
|
|
co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)&Msg->Msg);
|
2008-07-22 04:54:53 +00:00
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Present;
|
2003-05-21 22:58:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOL STDCALL
|
2004-04-29 21:13:16 +00:00
|
|
|
NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
|
2005-09-11 14:48:32 +00:00
|
|
|
HWND hWnd,
|
2003-05-21 22:58:43 +00:00
|
|
|
UINT MsgFilterMin,
|
|
|
|
UINT MsgFilterMax,
|
|
|
|
UINT RemoveMsg)
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
BOOL Present;
|
|
|
|
NTUSERGETMESSAGEINFO Info;
|
|
|
|
PWINDOW_OBJECT Window;
|
|
|
|
PMSGMEMORY MsgMemoryEntry;
|
|
|
|
PVOID UserMem;
|
|
|
|
UINT Size;
|
|
|
|
USER_MESSAGE Msg;
|
|
|
|
DECLARE_RETURN(BOOL);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserPeekMessage\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
|
|
|
/* Validate input */
|
2005-09-11 14:48:32 +00:00
|
|
|
if (hWnd && hWnd != INVALID_HANDLE_VALUE)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-11 14:48:32 +00:00
|
|
|
if (!(Window = UserGetWindowObject(hWnd)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-11 14:48:32 +00:00
|
|
|
RETURN(-1);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if (MsgFilterMax < MsgFilterMin)
|
|
|
|
{
|
2003-05-21 22:58:43 +00:00
|
|
|
MsgFilterMin = 0;
|
|
|
|
MsgFilterMax = 0;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2003-05-21 22:58:43 +00:00
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
Present = co_IntPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg);
|
2005-09-07 21:25:42 +00:00
|
|
|
if (Present)
|
|
|
|
{
|
2008-07-22 04:54:53 +00:00
|
|
|
|
2004-04-29 21:13:16 +00:00
|
|
|
Info.Msg = Msg.Msg;
|
|
|
|
/* See if this message type is present in the table */
|
|
|
|
MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
|
|
|
|
if (NULL == MsgMemoryEntry)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
/* Not present, no copying needed */
|
|
|
|
Info.LParamSize = 0;
|
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
else
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
/* Determine required size */
|
|
|
|
Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam,
|
|
|
|
Info.Msg.lParam);
|
|
|
|
/* Allocate required amount of user-mode memory */
|
|
|
|
Info.LParamSize = Size;
|
|
|
|
UserMem = NULL;
|
|
|
|
Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
|
|
|
|
&Info.LParamSize, MEM_COMMIT, PAGE_READWRITE);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
RETURN( (BOOL) -1);
|
|
|
|
}
|
|
|
|
/* Transfer lParam data to user-mode mem */
|
|
|
|
Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Size);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
|
2007-11-18 23:59:48 +00:00
|
|
|
&Info.LParamSize, MEM_RELEASE);
|
2005-09-07 21:25:42 +00:00
|
|
|
SetLastNtError(Status);
|
|
|
|
RETURN( (BOOL) -1);
|
|
|
|
}
|
|
|
|
Info.Msg.lParam = (LPARAM) UserMem;
|
|
|
|
}
|
2005-01-04 21:25:20 +00:00
|
|
|
if (RemoveMsg && Msg.FreeLParam && 0 != Msg.Msg.lParam)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
ExFreePool((void *) Msg.Msg.lParam);
|
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
|
2003-05-21 22:58:43 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
RETURN( (BOOL) -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RETURN( Present);
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserPeekMessage, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-05-21 22:58:43 +00:00
|
|
|
}
|
|
|
|
|
2004-04-13 13:50:31 +00:00
|
|
|
static BOOL FASTCALL
|
2005-09-05 21:19:23 +00:00
|
|
|
co_IntWaitMessage(HWND Wnd,
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT MsgFilterMin,
|
|
|
|
UINT MsgFilterMax)
|
2003-05-21 22:58:43 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
PUSER_MESSAGE_QUEUE ThreadQueue;
|
|
|
|
NTSTATUS Status;
|
|
|
|
USER_MESSAGE Msg;
|
2003-05-21 22:58:43 +00:00
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetCurrentThreadWin32Thread()->MessageQueue;
|
2003-05-21 22:58:43 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
do
|
|
|
|
{
|
2005-09-05 21:19:23 +00:00
|
|
|
if (co_IntPeekMessage(&Msg, Wnd, MsgFilterMin, MsgFilterMax, PM_NOREMOVE))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
2003-05-21 22:58:43 +00:00
|
|
|
|
|
|
|
/* Nothing found. Wait for new messages. */
|
2005-09-05 21:19:23 +00:00
|
|
|
Status = co_MsqWaitForNewMessages(ThreadQueue, Wnd, MsgFilterMin, MsgFilterMax);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
while ((STATUS_WAIT_0 <= Status && Status <= STATUS_WAIT_63) || STATUS_TIMEOUT == Status);
|
2003-05-21 22:58:43 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
SetLastNtError(Status);
|
2003-05-21 22:58:43 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return FALSE;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-05-21 22:58:43 +00:00
|
|
|
BOOL STDCALL
|
2004-04-29 21:13:16 +00:00
|
|
|
NtUserGetMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
|
2005-09-11 14:48:32 +00:00
|
|
|
HWND hWnd,
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT MsgFilterMin,
|
|
|
|
UINT MsgFilterMax)
|
2003-05-21 22:58:43 +00:00
|
|
|
/*
|
|
|
|
* FUNCTION: Get a message from the calling thread's message queue.
|
|
|
|
* ARGUMENTS:
|
|
|
|
* UnsafeMsg - Pointer to the structure which receives the returned message.
|
|
|
|
* Wnd - Window whose messages are to be retrieved.
|
|
|
|
* MsgFilterMin - Integer value of the lowest message value to be
|
|
|
|
* retrieved.
|
|
|
|
* MsgFilterMax - Integer value of the highest message value to be
|
|
|
|
* retrieved.
|
|
|
|
*/
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
BOOL GotMessage;
|
|
|
|
NTUSERGETMESSAGEINFO Info;
|
|
|
|
NTSTATUS Status;
|
2005-09-11 14:48:32 +00:00
|
|
|
PWINDOW_OBJECT Window = NULL;
|
2005-09-07 21:25:42 +00:00
|
|
|
PMSGMEMORY MsgMemoryEntry;
|
|
|
|
PVOID UserMem;
|
|
|
|
UINT Size;
|
|
|
|
USER_MESSAGE Msg;
|
|
|
|
DECLARE_RETURN(BOOL);
|
2005-10-15 13:22:13 +00:00
|
|
|
// USER_REFERENCE_ENTRY Ref;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
DPRINT("Enter NtUserGetMessage\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
|
|
|
/* Validate input */
|
2005-09-11 14:48:32 +00:00
|
|
|
if (hWnd && !(Window = UserGetWindowObject(hWnd)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-11 14:48:32 +00:00
|
|
|
RETURN(-1);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-10-15 13:22:13 +00:00
|
|
|
// if (Window) UserRefObjectCo(Window, &Ref);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if (MsgFilterMax < MsgFilterMin)
|
|
|
|
{
|
2003-05-21 22:58:43 +00:00
|
|
|
MsgFilterMin = 0;
|
|
|
|
MsgFilterMax = 0;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2003-05-21 22:58:43 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
do
|
|
|
|
{
|
2005-09-11 14:48:32 +00:00
|
|
|
GotMessage = co_IntPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE);
|
2003-05-21 22:58:43 +00:00
|
|
|
if (GotMessage)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
Info.Msg = Msg.Msg;
|
|
|
|
/* See if this message type is present in the table */
|
|
|
|
MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
|
|
|
|
if (NULL == MsgMemoryEntry)
|
|
|
|
{
|
|
|
|
/* Not present, no copying needed */
|
|
|
|
Info.LParamSize = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Determine required size */
|
|
|
|
Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam,
|
|
|
|
Info.Msg.lParam);
|
|
|
|
/* Allocate required amount of user-mode memory */
|
|
|
|
Info.LParamSize = Size;
|
|
|
|
UserMem = NULL;
|
|
|
|
Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
|
|
|
|
&Info.LParamSize, MEM_COMMIT, PAGE_READWRITE);
|
|
|
|
|
|
|
|
if (! NT_SUCCESS(Status))
|
2004-04-29 21:13:16 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
SetLastNtError(Status);
|
|
|
|
RETURN( (BOOL) -1);
|
2004-04-29 21:13:16 +00:00
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
/* Transfer lParam data to user-mode mem */
|
|
|
|
Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Size);
|
|
|
|
if (! NT_SUCCESS(Status))
|
2004-04-29 21:13:16 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
|
|
|
|
&Info.LParamSize, MEM_DECOMMIT);
|
|
|
|
SetLastNtError(Status);
|
|
|
|
RETURN( (BOOL) -1);
|
2004-04-29 21:13:16 +00:00
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
Info.Msg.lParam = (LPARAM) UserMem;
|
|
|
|
}
|
|
|
|
if (Msg.FreeLParam && 0 != Msg.Msg.lParam)
|
|
|
|
{
|
|
|
|
ExFreePool((void *) Msg.Msg.lParam);
|
|
|
|
}
|
|
|
|
Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
RETURN( (BOOL) -1);
|
|
|
|
}
|
|
|
|
}
|
2005-09-11 14:48:32 +00:00
|
|
|
else if (! co_IntWaitMessage(hWnd, MsgFilterMin, MsgFilterMax))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
RETURN( (BOOL) -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (! GotMessage);
|
|
|
|
|
|
|
|
RETURN( WM_QUIT != Info.Msg.message);
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-11 14:48:32 +00:00
|
|
|
// if (Window) UserDerefObjectCo(Window);
|
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserGetMessage\n");
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-05-21 22:58:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-04-29 21:13:16 +00:00
|
|
|
static NTSTATUS FASTCALL
|
|
|
|
CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg, PMSGMEMORY MsgMemoryEntry)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
NTSTATUS Status;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
PVOID KernelMem;
|
|
|
|
UINT Size;
|
2003-03-06 23:57:03 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
*KernelModeMsg = *UserModeMsg;
|
2004-04-29 21:13:16 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
/* See if this message type is present in the table */
|
|
|
|
if (NULL == MsgMemoryEntry)
|
|
|
|
{
|
2004-04-29 21:13:16 +00:00
|
|
|
/* Not present, no copying needed */
|
|
|
|
return STATUS_SUCCESS;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2003-12-24 10:23:13 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
/* Determine required size */
|
|
|
|
Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
|
2004-04-29 21:13:16 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if (0 != Size)
|
|
|
|
{
|
2004-04-29 21:13:16 +00:00
|
|
|
/* Allocate kernel mem */
|
|
|
|
KernelMem = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
|
|
|
|
if (NULL == KernelMem)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
DPRINT1("Not enough memory to copy message to kernel mem\n");
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
KernelModeMsg->lParam = (LPARAM) KernelMem;
|
|
|
|
|
|
|
|
/* Copy data if required */
|
|
|
|
if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_READ))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2006-08-12 15:55:03 +00:00
|
|
|
Status = MmCopyFromCaller(KernelMem, (PVOID) UserModeMsg->lParam, Size);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to copy message to kernel: invalid usermode buffer\n");
|
|
|
|
ExFreePool(KernelMem);
|
|
|
|
return Status;
|
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
else
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
/* Make sure we don't pass any secrets to usermode */
|
|
|
|
RtlZeroMemory(KernelMem, Size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-04-29 21:13:16 +00:00
|
|
|
KernelModeMsg->lParam = 0;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-04-29 21:13:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static NTSTATUS FASTCALL
|
|
|
|
CopyMsgToUserMem(MSG *UserModeMsg, MSG *KernelModeMsg)
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PMSGMEMORY MsgMemoryEntry;
|
|
|
|
UINT Size;
|
|
|
|
|
|
|
|
/* See if this message type is present in the table */
|
|
|
|
MsgMemoryEntry = FindMsgMemory(UserModeMsg->message);
|
|
|
|
if (NULL == MsgMemoryEntry)
|
|
|
|
{
|
2004-04-29 21:13:16 +00:00
|
|
|
/* Not present, no copying needed */
|
|
|
|
return STATUS_SUCCESS;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
/* Determine required size */
|
|
|
|
Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
|
2004-04-29 21:13:16 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if (0 != Size)
|
|
|
|
{
|
2004-04-29 21:13:16 +00:00
|
|
|
/* Copy data if required */
|
|
|
|
if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_WRITE))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
Status = MmCopyToCaller((PVOID) UserModeMsg->lParam, (PVOID) KernelModeMsg->lParam, Size);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to copy message from kernel: invalid usermode buffer\n");
|
|
|
|
ExFreePool((PVOID) KernelModeMsg->lParam);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
|
|
|
|
ExFreePool((PVOID) KernelModeMsg->lParam);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-04-29 21:13:16 +00:00
|
|
|
}
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
BOOL FASTCALL
|
|
|
|
UserPostMessage(HWND Wnd,
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT Msg,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam)
|
2004-04-29 21:13:16 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
MSG UserModeMsg, KernelModeMsg;
|
|
|
|
LARGE_INTEGER LargeTickCount;
|
|
|
|
NTSTATUS Status;
|
|
|
|
PMSGMEMORY MsgMemoryEntry;
|
|
|
|
|
|
|
|
if (WM_QUIT == Msg)
|
|
|
|
{
|
2006-07-20 14:53:47 +00:00
|
|
|
MsqPostQuitMessage(PsGetCurrentThreadWin32Thread()->MessageQueue, wParam);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
else if (Wnd == HWND_BROADCAST)
|
|
|
|
{
|
2004-04-29 21:13:16 +00:00
|
|
|
HWND *List;
|
|
|
|
PWINDOW_OBJECT DesktopWindow;
|
|
|
|
ULONG i;
|
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
|
2004-04-29 21:13:16 +00:00
|
|
|
List = IntWinListChildren(DesktopWindow);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2003-12-24 10:23:13 +00:00
|
|
|
if (List != NULL)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
for (i = 0; List[i]; i++)
|
2005-09-05 21:19:23 +00:00
|
|
|
UserPostMessage(List[i], Msg, wParam, lParam);
|
2005-09-07 21:25:42 +00:00
|
|
|
ExFreePool(List);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-09-11 14:48:32 +00:00
|
|
|
PWINDOW_OBJECT Window;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
Window = UserGetWindowObject(Wnd);
|
2004-04-29 21:13:16 +00:00
|
|
|
if (NULL == Window)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2004-12-11 19:39:18 +00:00
|
|
|
if(Window->Status & WINDOWSTATUS_DESTROYING)
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT1("Attempted to post message to window 0x%x that is being destroyed!\n", Wnd);
|
|
|
|
/* FIXME - last error code? */
|
|
|
|
return FALSE;
|
2004-12-11 19:39:18 +00:00
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
|
|
|
|
UserModeMsg.hwnd = Wnd;
|
|
|
|
UserModeMsg.message = Msg;
|
|
|
|
UserModeMsg.wParam = wParam;
|
|
|
|
UserModeMsg.lParam = lParam;
|
|
|
|
MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
|
|
|
|
Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
|
|
|
|
if (! NT_SUCCESS(Status))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2006-07-20 14:53:47 +00:00
|
|
|
IntGetCursorLocation(PsGetCurrentThreadWin32Thread()->Desktop->WindowStation,
|
2005-01-27 00:49:24 +00:00
|
|
|
&KernelModeMsg.pt);
|
2003-09-27 15:41:54 +00:00
|
|
|
KeQueryTickCount(&LargeTickCount);
|
2007-07-28 17:16:51 +00:00
|
|
|
KernelModeMsg.time = MsqCalculateMessageTime(&LargeTickCount);
|
2004-04-29 21:13:16 +00:00
|
|
|
MsqPostMessage(Window->MessageQueue, &KernelModeMsg,
|
2004-12-25 22:59:10 +00:00
|
|
|
NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam,
|
|
|
|
QS_POSTMESSAGE);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2003-03-06 23:57:03 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return TRUE;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
|
|
|
|
BOOL STDCALL
|
|
|
|
NtUserPostMessage(HWND hWnd,
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT Msg,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam)
|
2005-09-05 21:19:23 +00:00
|
|
|
{
|
|
|
|
DECLARE_RETURN(BOOL);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserPostMessage\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
|
|
|
RETURN(UserPostMessage(hWnd, Msg, wParam, lParam));
|
|
|
|
|
|
|
|
CLEANUP:
|
|
|
|
DPRINT("Leave NtUserPostMessage, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2002-01-13 22:52:08 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
NtUserPostThreadMessage(DWORD idThread,
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT Msg,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
MSG UserModeMsg, KernelModeMsg;
|
|
|
|
PETHREAD peThread;
|
|
|
|
PW32THREAD pThread;
|
|
|
|
NTSTATUS Status;
|
|
|
|
PMSGMEMORY MsgMemoryEntry;
|
|
|
|
DECLARE_RETURN(BOOL);
|
2005-09-05 21:19:23 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Enter NtUserPostThreadMessage\n");
|
|
|
|
UserEnterExclusive();
|
2003-07-23 17:00:55 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if( Status == STATUS_SUCCESS )
|
|
|
|
{
|
2005-11-08 08:56:41 +00:00
|
|
|
pThread = (PW32THREAD)peThread->Tcb.Win32Thread;
|
2005-09-07 21:25:42 +00:00
|
|
|
if( !pThread || !pThread->MessageQueue )
|
2003-07-24 05:51:26 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
ObDereferenceObject( peThread );
|
|
|
|
RETURN( FALSE);
|
2003-07-24 05:51:26 +00:00
|
|
|
}
|
2004-04-29 21:13:16 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
UserModeMsg.hwnd = NULL;
|
|
|
|
UserModeMsg.message = Msg;
|
|
|
|
UserModeMsg.wParam = wParam;
|
|
|
|
UserModeMsg.lParam = lParam;
|
|
|
|
MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
|
|
|
|
Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
|
|
|
|
if (! NT_SUCCESS(Status))
|
2004-04-29 21:13:16 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
ObDereferenceObject( peThread );
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
RETURN( FALSE);
|
2004-04-29 21:13:16 +00:00
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
MsqPostMessage(pThread->MessageQueue, &KernelModeMsg,
|
|
|
|
NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam,
|
|
|
|
QS_POSTMESSAGE);
|
|
|
|
ObDereferenceObject( peThread );
|
|
|
|
RETURN( TRUE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetLastNtError( Status );
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserPostThreadMessage, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2002-01-13 22:52:08 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserQuerySendMessage(DWORD Unknown0)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
UNIMPLEMENTED;
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return 0;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2004-04-13 13:50:31 +00:00
|
|
|
LRESULT FASTCALL
|
2005-09-05 21:19:23 +00:00
|
|
|
co_IntSendMessage(HWND hWnd,
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT Msg,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam)
|
2004-03-11 14:47:44 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
ULONG_PTR Result = 0;
|
|
|
|
if(co_IntSendMessageTimeout(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result))
|
|
|
|
{
|
|
|
|
return (LRESULT)Result;
|
|
|
|
}
|
|
|
|
return 0;
|
2004-03-11 14:47:44 +00:00
|
|
|
}
|
|
|
|
|
2007-10-19 23:21:45 +00:00
|
|
|
static
|
2005-09-11 14:48:32 +00:00
|
|
|
LRESULT FASTCALL
|
2005-09-05 21:19:23 +00:00
|
|
|
co_IntSendMessageTimeoutSingle(HWND hWnd,
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT Msg,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam,
|
|
|
|
UINT uFlags,
|
|
|
|
UINT uTimeout,
|
|
|
|
ULONG_PTR *uResult)
|
2002-05-06 22:20:32 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
ULONG_PTR Result;
|
|
|
|
NTSTATUS Status;
|
2005-09-11 14:48:32 +00:00
|
|
|
PWINDOW_OBJECT Window = NULL;
|
2005-09-07 21:25:42 +00:00
|
|
|
PMSGMEMORY MsgMemoryEntry;
|
|
|
|
INT lParamBufferSize;
|
|
|
|
LPARAM lParamPacked;
|
|
|
|
PW32THREAD Win32Thread;
|
2005-09-11 14:48:32 +00:00
|
|
|
DECLARE_RETURN(LRESULT);
|
2005-10-15 13:22:13 +00:00
|
|
|
USER_REFERENCE_ENTRY Ref;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
if (!(Window = UserGetWindowObject(hWnd)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-11 14:48:32 +00:00
|
|
|
RETURN( FALSE);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-10-15 13:22:13 +00:00
|
|
|
UserRefObjectCo(Window, &Ref);
|
2002-07-04 19:56:38 +00:00
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
Win32Thread = PsGetCurrentThreadWin32Thread();
|
2008-07-25 12:31:59 +00:00
|
|
|
|
2008-07-29 00:35:05 +00:00
|
|
|
IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
|
2008-07-25 12:31:59 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if (NULL != Win32Thread &&
|
2008-07-25 12:31:59 +00:00
|
|
|
Window->MessageQueue == Win32Thread->MessageQueue)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2004-02-05 20:09:10 +00:00
|
|
|
if (Win32Thread->IsExiting)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
/* Never send messages to exiting threads */
|
2005-09-11 14:48:32 +00:00
|
|
|
RETURN( FALSE);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2004-02-05 20:09:10 +00:00
|
|
|
|
2003-12-26 22:52:12 +00:00
|
|
|
/* See if this message type is present in the table */
|
|
|
|
MsgMemoryEntry = FindMsgMemory(Msg);
|
|
|
|
if (NULL == MsgMemoryEntry)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
lParamBufferSize = -1;
|
|
|
|
}
|
2002-07-17 21:04:57 +00:00
|
|
|
else
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
|
|
|
|
}
|
2003-12-26 22:52:12 +00:00
|
|
|
|
|
|
|
if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2008-07-25 12:31:59 +00:00
|
|
|
DPRINT1("Failed to pack message parameters\n");
|
2005-09-11 14:48:32 +00:00
|
|
|
RETURN( FALSE);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2006-04-05 08:05:55 +00:00
|
|
|
|
2007-11-17 00:40:22 +00:00
|
|
|
Result = (ULONG_PTR)co_IntCallWindowProc(Window->Wnd->WndProc, !Window->Wnd->Unicode, hWnd, Msg, wParam,
|
2006-04-05 08:05:55 +00:00
|
|
|
lParamPacked,lParamBufferSize);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-05-22 09:22:41 +00:00
|
|
|
if(uResult)
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
*uResult = Result;
|
2004-05-22 09:22:41 +00:00
|
|
|
}
|
2008-07-25 12:31:59 +00:00
|
|
|
|
2008-07-29 00:35:05 +00:00
|
|
|
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-26 22:52:12 +00:00
|
|
|
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
DPRINT1("Failed to unpack message parameters\n");
|
2008-07-25 12:31:59 +00:00
|
|
|
RETURN( TRUE);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2003-12-26 22:52:12 +00:00
|
|
|
|
2008-07-25 12:31:59 +00:00
|
|
|
RETURN( TRUE);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
2008-07-25 12:31:59 +00:00
|
|
|
if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->MessageQueue))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
/* FIXME - Set a LastError? */
|
2008-07-25 12:31:59 +00:00
|
|
|
RETURN( FALSE);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
2008-07-25 12:31:59 +00:00
|
|
|
if (Window->Status & WINDOWSTATUS_DESTROYING)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
/* FIXME - last error? */
|
|
|
|
DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
|
2008-07-25 12:31:59 +00:00
|
|
|
RETURN( FALSE);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
2008-07-25 12:31:59 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
Status = co_MsqSendMessage( Window->MessageQueue,
|
|
|
|
hWnd,
|
|
|
|
Msg,
|
|
|
|
wParam,
|
|
|
|
lParam,
|
|
|
|
uTimeout,
|
|
|
|
(uFlags & SMTO_BLOCK),
|
2008-07-31 23:48:35 +00:00
|
|
|
MSQ_NORMAL,
|
2008-07-25 12:31:59 +00:00
|
|
|
uResult);
|
|
|
|
}
|
|
|
|
while ((STATUS_TIMEOUT == Status) &&
|
|
|
|
(uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
|
|
|
|
!MsqIsHung(Window->MessageQueue));
|
2005-09-11 14:48:32 +00:00
|
|
|
|
2008-07-29 00:35:05 +00:00
|
|
|
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
|
2005-09-11 14:48:32 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if (STATUS_TIMEOUT == Status)
|
|
|
|
{
|
2008-07-25 12:31:59 +00:00
|
|
|
/*
|
|
|
|
MSDN says:
|
|
|
|
Microsoft Windows 2000: If GetLastError returns zero, then the function
|
|
|
|
timed out.
|
|
|
|
XP+ : If the function fails or times out, the return value is zero.
|
|
|
|
To get extended error information, call GetLastError. If GetLastError
|
|
|
|
returns ERROR_TIMEOUT, then the function timed out.
|
|
|
|
*/
|
|
|
|
SetLastWin32Error(ERROR_TIMEOUT);
|
|
|
|
RETURN( FALSE);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
else if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2004-08-26 12:29:37 +00:00
|
|
|
SetLastNtError(Status);
|
2008-07-25 12:31:59 +00:00
|
|
|
RETURN( FALSE);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2004-08-26 12:29:37 +00:00
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
RETURN( TRUE);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
CLEANUP:
|
|
|
|
if (Window) UserDerefObjectCo(Window);
|
|
|
|
END_CLEANUP;
|
2003-12-26 22:52:12 +00:00
|
|
|
}
|
|
|
|
|
2004-04-13 13:50:31 +00:00
|
|
|
LRESULT FASTCALL
|
2005-09-05 21:19:23 +00:00
|
|
|
co_IntSendMessageTimeout(HWND hWnd,
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT Msg,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam,
|
|
|
|
UINT uFlags,
|
|
|
|
UINT uTimeout,
|
|
|
|
ULONG_PTR *uResult)
|
2004-04-07 17:52:32 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
PWINDOW_OBJECT DesktopWindow;
|
|
|
|
HWND *Children;
|
|
|
|
HWND *Child;
|
2004-04-07 17:52:32 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if (HWND_BROADCAST != hWnd)
|
|
|
|
{
|
2005-09-05 21:19:23 +00:00
|
|
|
return co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, uFlags, uTimeout, uResult);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2004-04-07 17:52:32 +00:00
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
|
2005-09-07 21:25:42 +00:00
|
|
|
if (NULL == DesktopWindow)
|
|
|
|
{
|
2004-04-07 17:52:32 +00:00
|
|
|
SetLastWin32Error(ERROR_INTERNAL_ERROR);
|
|
|
|
return 0;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2005-09-11 14:48:32 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
Children = IntWinListChildren(DesktopWindow);
|
|
|
|
if (NULL == Children)
|
|
|
|
{
|
2004-04-07 17:52:32 +00:00
|
|
|
return 0;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2004-04-07 17:52:32 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
for (Child = Children; NULL != *Child; Child++)
|
|
|
|
{
|
2005-09-05 21:19:23 +00:00
|
|
|
co_IntSendMessageTimeoutSingle(*Child, Msg, wParam, lParam, uFlags, uTimeout, uResult);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2004-04-07 17:52:32 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
ExFreePool(Children);
|
2004-04-07 21:12:40 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return (LRESULT) TRUE;
|
2004-04-07 17:52:32 +00:00
|
|
|
}
|
|
|
|
|
2003-12-26 22:52:12 +00:00
|
|
|
|
2004-04-13 13:50:31 +00:00
|
|
|
/* This function posts a message if the destination's message queue belongs to
|
|
|
|
another thread, otherwise it sends the message. It does not support broadcast
|
|
|
|
messages! */
|
|
|
|
LRESULT FASTCALL
|
2005-09-05 21:19:23 +00:00
|
|
|
co_IntPostOrSendMessage(HWND hWnd,
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT Msg,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam)
|
2004-04-13 13:50:31 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
ULONG_PTR Result;
|
|
|
|
PWINDOW_OBJECT Window;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if(hWnd == HWND_BROADCAST)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-09-11 14:48:32 +00:00
|
|
|
if(!(Window = UserGetWindowObject(hWnd)))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
if(Window->MessageQueue != PsGetCurrentThreadWin32Thread()->MessageQueue)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
Result = UserPostMessage(hWnd, Msg, wParam, lParam);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-07-24 11:38:08 +00:00
|
|
|
if(!co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result)) {
|
2005-09-07 21:25:42 +00:00
|
|
|
Result = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (LRESULT)Result;
|
2004-04-13 13:50:31 +00:00
|
|
|
}
|
|
|
|
|
2004-03-11 14:47:44 +00:00
|
|
|
LRESULT FASTCALL
|
2005-09-11 14:48:32 +00:00
|
|
|
co_IntDoSendMessage(HWND hWnd,
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT Msg,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam,
|
|
|
|
PDOSENDMESSAGE dsm,
|
|
|
|
PNTUSERSENDMESSAGEINFO UnsafeInfo)
|
2002-07-17 21:04:57 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
LRESULT Result = TRUE;
|
|
|
|
NTSTATUS Status;
|
|
|
|
PWINDOW_OBJECT Window;
|
|
|
|
NTUSERSENDMESSAGEINFO Info;
|
|
|
|
MSG UserModeMsg;
|
|
|
|
MSG KernelModeMsg;
|
|
|
|
PMSGMEMORY MsgMemoryEntry;
|
|
|
|
|
|
|
|
RtlZeroMemory(&Info, sizeof(NTUSERSENDMESSAGEINFO));
|
|
|
|
|
|
|
|
/* FIXME: Call hooks. */
|
2005-09-11 14:48:32 +00:00
|
|
|
if (HWND_BROADCAST != hWnd)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2005-09-11 14:48:32 +00:00
|
|
|
Window = UserGetWindowObject(hWnd);
|
2004-04-07 17:52:32 +00:00
|
|
|
if (NULL == Window)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
/* Tell usermode to not touch this one */
|
|
|
|
Info.HandledByKernel = TRUE;
|
|
|
|
MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
|
|
|
|
return 0;
|
|
|
|
}
|
2008-07-05 09:19:56 +00:00
|
|
|
if (!Window->Wnd)
|
|
|
|
return 0;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: Check for an exiting window. */
|
|
|
|
|
|
|
|
/* See if the current thread can handle the message */
|
2006-07-20 14:53:47 +00:00
|
|
|
if (HWND_BROADCAST != hWnd && NULL != PsGetCurrentThreadWin32Thread() &&
|
|
|
|
Window->MessageQueue == PsGetCurrentThreadWin32Thread()->MessageQueue)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2003-12-14 11:36:43 +00:00
|
|
|
/* Gather the information usermode needs to call the window proc directly */
|
|
|
|
Info.HandledByKernel = FALSE;
|
2006-04-05 08:05:55 +00:00
|
|
|
|
|
|
|
Status = MmCopyFromCaller(&(Info.Ansi), &(UnsafeInfo->Ansi),
|
|
|
|
sizeof(BOOL));
|
|
|
|
if (! NT_SUCCESS(Status))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2007-11-16 09:03:51 +00:00
|
|
|
Info.Ansi = ! Window->Wnd->Unicode;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2006-04-05 08:05:55 +00:00
|
|
|
|
2008-07-29 00:35:05 +00:00
|
|
|
IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
|
|
|
|
|
2007-11-17 00:40:22 +00:00
|
|
|
if (Window->Wnd->IsSystem)
|
2006-05-03 10:35:11 +00:00
|
|
|
{
|
2007-11-17 00:40:22 +00:00
|
|
|
Info.Proc = (!Info.Ansi ? Window->Wnd->WndProc : Window->Wnd->WndProcExtra);
|
2006-05-03 10:35:11 +00:00
|
|
|
}
|
2006-04-14 18:23:11 +00:00
|
|
|
else
|
2006-05-03 10:35:11 +00:00
|
|
|
{
|
2007-11-16 09:03:51 +00:00
|
|
|
Info.Ansi = !Window->Wnd->Unicode;
|
2007-11-17 00:40:22 +00:00
|
|
|
Info.Proc = Window->Wnd->WndProc;
|
2006-05-03 10:35:11 +00:00
|
|
|
}
|
2008-07-29 00:35:05 +00:00
|
|
|
|
|
|
|
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, &Result);
|
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-12-14 11:36:43 +00:00
|
|
|
/* Must be handled by other thread */
|
2005-09-11 14:48:32 +00:00
|
|
|
// if (HWND_BROADCAST != hWnd)
|
|
|
|
// {
|
2008-02-13 00:46:23 +00:00
|
|
|
// UserDereferenceObject(Window);
|
2005-09-11 14:48:32 +00:00
|
|
|
// }
|
2003-12-14 11:36:43 +00:00
|
|
|
Info.HandledByKernel = TRUE;
|
2005-09-11 14:48:32 +00:00
|
|
|
UserModeMsg.hwnd = hWnd;
|
2003-12-26 22:52:12 +00:00
|
|
|
UserModeMsg.message = Msg;
|
|
|
|
UserModeMsg.wParam = wParam;
|
|
|
|
UserModeMsg.lParam = lParam;
|
2004-04-29 21:13:16 +00:00
|
|
|
MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
|
|
|
|
Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
|
2003-12-26 22:52:12 +00:00
|
|
|
if (! NT_SUCCESS(Status))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return (dsm ? 0 : -1);
|
|
|
|
}
|
2004-03-11 14:47:44 +00:00
|
|
|
if(!dsm)
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
Result = co_IntSendMessage(KernelModeMsg.hwnd, KernelModeMsg.message,
|
|
|
|
KernelModeMsg.wParam, KernelModeMsg.lParam);
|
2004-03-11 14:47:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
Result = co_IntSendMessageTimeout(KernelModeMsg.hwnd, KernelModeMsg.message,
|
|
|
|
KernelModeMsg.wParam, KernelModeMsg.lParam,
|
|
|
|
dsm->uFlags, dsm->uTimeout, &dsm->Result);
|
2004-03-11 14:47:44 +00:00
|
|
|
}
|
2003-12-26 22:52:12 +00:00
|
|
|
Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
|
|
|
|
if (! NT_SUCCESS(Status))
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
|
|
|
MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return(dsm ? 0 : -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
2003-12-14 11:36:43 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2003-12-14 11:36:43 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return (LRESULT)Result;
|
2002-07-17 21:04:57 +00:00
|
|
|
}
|
|
|
|
|
2004-03-11 14:47:44 +00:00
|
|
|
LRESULT STDCALL
|
|
|
|
NtUserSendMessageTimeout(HWND hWnd,
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT Msg,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam,
|
|
|
|
UINT uFlags,
|
|
|
|
UINT uTimeout,
|
|
|
|
ULONG_PTR *uResult,
|
|
|
|
PNTUSERSENDMESSAGEINFO UnsafeInfo)
|
2004-03-11 14:47:44 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
DOSENDMESSAGE dsm;
|
|
|
|
LRESULT Result;
|
|
|
|
DECLARE_RETURN(BOOL);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserSendMessageTimeout\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
|
|
|
dsm.uFlags = uFlags;
|
|
|
|
dsm.uTimeout = uTimeout;
|
|
|
|
Result = co_IntDoSendMessage(hWnd, Msg, wParam, lParam, &dsm, UnsafeInfo);
|
|
|
|
if(uResult != NULL && Result != 0)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = MmCopyToCaller(uResult, &dsm.Result, sizeof(ULONG_PTR));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
RETURN( Result);
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserSendMessageTimeout, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2004-03-11 14:47:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT STDCALL
|
|
|
|
NtUserSendMessage(HWND Wnd,
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT Msg,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam,
|
2004-03-11 14:47:44 +00:00
|
|
|
PNTUSERSENDMESSAGEINFO UnsafeInfo)
|
|
|
|
{
|
2005-09-05 21:19:23 +00:00
|
|
|
DECLARE_RETURN(BOOL);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserSendMessage\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
|
|
|
RETURN(co_IntDoSendMessage(Wnd, Msg, wParam, lParam, NULL, UnsafeInfo));
|
|
|
|
|
|
|
|
CLEANUP:
|
|
|
|
DPRINT("Leave NtUserSendMessage, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
2005-09-07 21:25:42 +00:00
|
|
|
END_CLEANUP;
|
2004-03-11 14:47:44 +00:00
|
|
|
}
|
|
|
|
|
2006-08-12 15:50:45 +00:00
|
|
|
|
|
|
|
BOOL FASTCALL
|
|
|
|
UserSendNotifyMessage(HWND hWnd,
|
|
|
|
UINT Msg,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam)
|
|
|
|
{
|
|
|
|
BOOL Result = TRUE;
|
|
|
|
// Basicly the same as IntPostOrSendMessage
|
|
|
|
if (hWnd == HWND_BROADCAST) //Handle Broadcast
|
|
|
|
{
|
|
|
|
HWND *List;
|
|
|
|
PWINDOW_OBJECT DesktopWindow;
|
|
|
|
ULONG i;
|
|
|
|
|
|
|
|
DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
|
|
|
|
List = IntWinListChildren(DesktopWindow);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2006-08-12 15:50:45 +00:00
|
|
|
if (List != NULL)
|
|
|
|
{
|
|
|
|
for (i = 0; List[i]; i++)
|
|
|
|
{
|
|
|
|
UserSendNotifyMessage(List[i], Msg, wParam, lParam);
|
|
|
|
}
|
|
|
|
ExFreePool(List);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ULONG_PTR PResult;
|
|
|
|
PWINDOW_OBJECT Window;
|
|
|
|
NTSTATUS Status;
|
|
|
|
MSG UserModeMsg;
|
|
|
|
MSG KernelModeMsg;
|
|
|
|
PMSGMEMORY MsgMemoryEntry;
|
|
|
|
|
|
|
|
if(!(Window = UserGetWindowObject(hWnd))) return FALSE;
|
|
|
|
|
|
|
|
if(Window->MessageQueue != PsGetCurrentThreadWin32Thread()->MessageQueue)
|
|
|
|
{ // Send message w/o waiting for it.
|
|
|
|
Result = UserPostMessage(hWnd, Msg, wParam, lParam);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // Handle message and callback.
|
|
|
|
UserModeMsg.hwnd = hWnd;
|
|
|
|
UserModeMsg.message = Msg;
|
|
|
|
UserModeMsg.wParam = wParam;
|
|
|
|
UserModeMsg.lParam = lParam;
|
|
|
|
MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
|
|
|
|
Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
Result = co_IntSendMessageTimeoutSingle(
|
|
|
|
KernelModeMsg.hwnd, KernelModeMsg.message,
|
|
|
|
KernelModeMsg.wParam, KernelModeMsg.lParam,
|
|
|
|
SMTO_NORMAL, 0, &PResult);
|
|
|
|
|
|
|
|
Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-01-13 22:52:08 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
NtUserSendNotifyMessage(HWND hWnd,
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT Msg,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2006-08-12 15:50:45 +00:00
|
|
|
DECLARE_RETURN(BOOL);
|
|
|
|
|
|
|
|
DPRINT("EnterNtUserSendNotifyMessage\n");
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
|
|
|
RETURN(UserSendNotifyMessage(hWnd, Msg, wParam, lParam));
|
|
|
|
|
|
|
|
CLEANUP:
|
|
|
|
DPRINT("Leave NtUserSendNotifyMessage, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2001-06-12 17:51:51 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-08-12 15:50:45 +00:00
|
|
|
|
2002-01-13 22:52:08 +00:00
|
|
|
BOOL STDCALL
|
2001-06-12 17:51:51 +00:00
|
|
|
NtUserWaitMessage(VOID)
|
|
|
|
{
|
2005-09-05 21:19:23 +00:00
|
|
|
DECLARE_RETURN(BOOL);
|
|
|
|
|
|
|
|
DPRINT("EnterNtUserWaitMessage\n");
|
|
|
|
UserEnterExclusive();
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
RETURN(co_IntWaitMessage(NULL, 0, 0));
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
|
|
|
DPRINT("Leave NtUserWaitMessage, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-08-02 16:53:08 +00:00
|
|
|
DWORD STDCALL
|
Patch by Stefan Ginsberg (stefan__100__ AT hotmail DOT com):
- remove NtUserEnumClipboardFormats, use ->ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMAT insetad
- remove NtUserRegisterClipboardFormat, use NtUserRegisterWIndowsMessage instead
- remove NtUserKillSystemTimer, use HWNDPARAM_ROUTINE_KILLSYSTEMTIMER instead
- remove NtUserInsertMenuItem, use NtUserThunkedMenuItemInfo instead
- remove NtUserGetCapture, use THREADSTATE_CAPTUREWINDOW instead
- remove NtUserGetActiveWindow, use THREADSTATE_ACTIVEWINDOW instead
- remove NtUserGetQueueStatus, use ONEPARAM_ROUTIME_GETQUEUESTATUS instead
- remove NtUserGetLastActivePopup, wasn't implemented
- remove NtUserRealizePalette from ntuser.h, it's not implemented
- remove duplicate NtUserGetLastInputInfo from ntuser.h
- remove PrivateCsrssRergisterPrimitive from user32, it was unused and unimplemented
- remove NtUserDereferenceWndprocHandle, it was unused
- move WNDPROC_INFO structure from ntuser.h to win32k/include/class.h, as it's not used in usermode anymore
tested with AbiWord and FF on VMWare
svn path=/trunk/; revision=32825
2008-04-03 02:13:34 +00:00
|
|
|
IntGetQueueStatus(BOOL ClearChanges)
|
2003-08-02 16:53:08 +00:00
|
|
|
{
|
|
|
|
PUSER_MESSAGE_QUEUE Queue;
|
|
|
|
DWORD Result;
|
2005-09-05 21:19:23 +00:00
|
|
|
DECLARE_RETURN(DWORD);
|
|
|
|
|
Patch by Stefan Ginsberg (stefan__100__ AT hotmail DOT com):
- remove NtUserEnumClipboardFormats, use ->ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMAT insetad
- remove NtUserRegisterClipboardFormat, use NtUserRegisterWIndowsMessage instead
- remove NtUserKillSystemTimer, use HWNDPARAM_ROUTINE_KILLSYSTEMTIMER instead
- remove NtUserInsertMenuItem, use NtUserThunkedMenuItemInfo instead
- remove NtUserGetCapture, use THREADSTATE_CAPTUREWINDOW instead
- remove NtUserGetActiveWindow, use THREADSTATE_ACTIVEWINDOW instead
- remove NtUserGetQueueStatus, use ONEPARAM_ROUTIME_GETQUEUESTATUS instead
- remove NtUserGetLastActivePopup, wasn't implemented
- remove NtUserRealizePalette from ntuser.h, it's not implemented
- remove duplicate NtUserGetLastInputInfo from ntuser.h
- remove PrivateCsrssRergisterPrimitive from user32, it was unused and unimplemented
- remove NtUserDereferenceWndprocHandle, it was unused
- move WNDPROC_INFO structure from ntuser.h to win32k/include/class.h, as it's not used in usermode anymore
tested with AbiWord and FF on VMWare
svn path=/trunk/; revision=32825
2008-04-03 02:13:34 +00:00
|
|
|
DPRINT("Enter IntGetQueueStatus\n");
|
2003-08-02 16:53:08 +00:00
|
|
|
|
2006-07-20 14:53:47 +00:00
|
|
|
Queue = PsGetCurrentThreadWin32Thread()->MessageQueue;
|
2003-08-02 16:53:08 +00:00
|
|
|
|
2004-12-25 22:59:10 +00:00
|
|
|
Result = MAKELONG(Queue->QueueBits, Queue->ChangedBits);
|
2003-08-02 16:53:08 +00:00
|
|
|
if (ClearChanges)
|
|
|
|
{
|
|
|
|
Queue->ChangedBits = 0;
|
|
|
|
}
|
|
|
|
|
Patch by Stefan Ginsberg (stefan__100__ AT hotmail DOT com):
- remove NtUserEnumClipboardFormats, use ->ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMAT insetad
- remove NtUserRegisterClipboardFormat, use NtUserRegisterWIndowsMessage instead
- remove NtUserKillSystemTimer, use HWNDPARAM_ROUTINE_KILLSYSTEMTIMER instead
- remove NtUserInsertMenuItem, use NtUserThunkedMenuItemInfo instead
- remove NtUserGetCapture, use THREADSTATE_CAPTUREWINDOW instead
- remove NtUserGetActiveWindow, use THREADSTATE_ACTIVEWINDOW instead
- remove NtUserGetQueueStatus, use ONEPARAM_ROUTIME_GETQUEUESTATUS instead
- remove NtUserGetLastActivePopup, wasn't implemented
- remove NtUserRealizePalette from ntuser.h, it's not implemented
- remove duplicate NtUserGetLastInputInfo from ntuser.h
- remove PrivateCsrssRergisterPrimitive from user32, it was unused and unimplemented
- remove NtUserDereferenceWndprocHandle, it was unused
- move WNDPROC_INFO structure from ntuser.h to win32k/include/class.h, as it's not used in usermode anymore
tested with AbiWord and FF on VMWare
svn path=/trunk/; revision=32825
2008-04-03 02:13:34 +00:00
|
|
|
RETURN(Result);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
Patch by Stefan Ginsberg (stefan__100__ AT hotmail DOT com):
- remove NtUserEnumClipboardFormats, use ->ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMAT insetad
- remove NtUserRegisterClipboardFormat, use NtUserRegisterWIndowsMessage instead
- remove NtUserKillSystemTimer, use HWNDPARAM_ROUTINE_KILLSYSTEMTIMER instead
- remove NtUserInsertMenuItem, use NtUserThunkedMenuItemInfo instead
- remove NtUserGetCapture, use THREADSTATE_CAPTUREWINDOW instead
- remove NtUserGetActiveWindow, use THREADSTATE_ACTIVEWINDOW instead
- remove NtUserGetQueueStatus, use ONEPARAM_ROUTIME_GETQUEUESTATUS instead
- remove NtUserGetLastActivePopup, wasn't implemented
- remove NtUserRealizePalette from ntuser.h, it's not implemented
- remove duplicate NtUserGetLastInputInfo from ntuser.h
- remove PrivateCsrssRergisterPrimitive from user32, it was unused and unimplemented
- remove NtUserDereferenceWndprocHandle, it was unused
- move WNDPROC_INFO structure from ntuser.h to win32k/include/class.h, as it's not used in usermode anymore
tested with AbiWord and FF on VMWare
svn path=/trunk/; revision=32825
2008-04-03 02:13:34 +00:00
|
|
|
DPRINT("Leave IntGetQueueStatus, ret=%i\n",_ret_);
|
2005-09-07 21:25:42 +00:00
|
|
|
END_CLEANUP;
|
2003-08-02 16:53:08 +00:00
|
|
|
}
|
|
|
|
|
2003-11-19 13:19:40 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
IntInitMessagePumpHook()
|
|
|
|
{
|
2008-04-07 19:02:21 +00:00
|
|
|
if (((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo)
|
|
|
|
{
|
|
|
|
((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook++;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
2003-11-19 13:19:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOL STDCALL
|
|
|
|
IntUninitMessagePumpHook()
|
|
|
|
{
|
2008-04-07 19:02:21 +00:00
|
|
|
if (((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo)
|
2005-09-07 21:25:42 +00:00
|
|
|
{
|
2008-04-07 19:02:21 +00:00
|
|
|
if (((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook <= 0)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook--;
|
|
|
|
return TRUE;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2008-04-07 19:02:21 +00:00
|
|
|
return FALSE;
|
2003-11-19 13:19:40 +00:00
|
|
|
}
|
|
|
|
|
2008-07-13 00:24:05 +00:00
|
|
|
|
|
|
|
LRESULT STDCALL
|
|
|
|
NtUserMessageCall(
|
|
|
|
HWND hWnd,
|
|
|
|
UINT Msg,
|
|
|
|
WPARAM wParam,
|
|
|
|
LPARAM lParam,
|
|
|
|
ULONG_PTR ResultInfo,
|
|
|
|
DWORD dwType, // fnID?
|
|
|
|
BOOL Ansi)
|
|
|
|
{
|
|
|
|
LRESULT lResult = 0;
|
|
|
|
PWINDOW_OBJECT Window = NULL;
|
2008-07-14 07:26:13 +00:00
|
|
|
USER_REFERENCE_ENTRY Ref;
|
2008-07-13 00:24:05 +00:00
|
|
|
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
|
|
|
/* Validate input */
|
|
|
|
if (hWnd && (hWnd != INVALID_HANDLE_VALUE) && !(Window = UserGetWindowObject(hWnd)))
|
|
|
|
{
|
|
|
|
return 0;
|
2008-07-14 07:26:13 +00:00
|
|
|
}
|
2008-07-13 00:24:05 +00:00
|
|
|
switch(dwType)
|
|
|
|
{
|
2008-07-19 03:49:48 +00:00
|
|
|
case FNID_DEFWINDOWPROC:
|
2008-07-24 11:38:08 +00:00
|
|
|
UserRefObjectCo(Window, &Ref);
|
2008-07-22 04:54:53 +00:00
|
|
|
lResult = IntDefWindowProc(Window, Msg, wParam, lParam, Ansi);
|
2008-07-24 11:38:08 +00:00
|
|
|
UserDerefObjectCo(Window);
|
|
|
|
break;
|
|
|
|
case FNID_BROADCASTSYSTEMMESSAGE:
|
|
|
|
{
|
|
|
|
PBROADCASTPARM parm;
|
|
|
|
BOOL BadChk = FALSE;
|
|
|
|
DWORD_PTR RetVal = 0;
|
|
|
|
lResult = -1;
|
|
|
|
|
|
|
|
if (ResultInfo)
|
|
|
|
{
|
|
|
|
_SEH_TRY
|
|
|
|
{
|
|
|
|
ProbeForWrite((PVOID)ResultInfo,
|
|
|
|
sizeof(BROADCASTPARM),
|
|
|
|
1);
|
|
|
|
parm = (PBROADCASTPARM)ResultInfo;
|
|
|
|
}
|
|
|
|
_SEH_HANDLE
|
|
|
|
{
|
|
|
|
BadChk = TRUE;
|
|
|
|
}
|
|
|
|
_SEH_END;
|
|
|
|
if (BadChk) break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
|
|
|
|
if ( parm->recipients & BSM_ALLDESKTOPS ||
|
|
|
|
parm->recipients == BSM_ALLCOMPONENTS )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
else if (parm->recipients & BSM_APPLICATIONS)
|
|
|
|
{
|
|
|
|
if (parm->flags & BSF_QUERY)
|
|
|
|
{
|
|
|
|
if (parm->flags & BSF_FORCEIFHUNG || parm->flags & BSF_NOHANG)
|
|
|
|
{
|
|
|
|
co_IntSendMessageTimeout( HWND_BROADCAST,
|
|
|
|
Msg,
|
|
|
|
wParam,
|
|
|
|
lParam,
|
|
|
|
SMTO_ABORTIFHUNG,
|
|
|
|
2000,
|
|
|
|
&RetVal);
|
|
|
|
}
|
|
|
|
else if (parm->flags & BSF_NOTIMEOUTIFNOTHUNG)
|
|
|
|
{
|
|
|
|
co_IntSendMessageTimeout( HWND_BROADCAST,
|
|
|
|
Msg,
|
|
|
|
wParam,
|
|
|
|
lParam,
|
|
|
|
SMTO_NOTIMEOUTIFNOTHUNG,
|
|
|
|
2000,
|
|
|
|
&RetVal);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
co_IntSendMessageTimeout( HWND_BROADCAST,
|
|
|
|
Msg,
|
|
|
|
wParam,
|
|
|
|
lParam,
|
|
|
|
SMTO_NORMAL,
|
|
|
|
2000,
|
|
|
|
&RetVal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (parm->flags & BSF_POSTMESSAGE)
|
|
|
|
{
|
|
|
|
lResult = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam);
|
|
|
|
}
|
|
|
|
else if ( parm->flags & BSF_SENDNOTIFYMESSAGE)
|
|
|
|
{
|
|
|
|
lResult = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case FNID_SENDMESSAGECALLBACK:
|
2008-07-13 00:24:05 +00:00
|
|
|
break;
|
2008-07-26 12:27:40 +00:00
|
|
|
// CallNextHook bypass.
|
2008-07-24 21:39:00 +00:00
|
|
|
case FNID_CALLWNDPROC:
|
|
|
|
case FNID_CALLWNDPROCRET:
|
|
|
|
{
|
2008-10-14 21:03:20 +00:00
|
|
|
PCLIENTINFO ClientInfo = GetWin32ClientInfo();
|
2008-07-26 12:27:40 +00:00
|
|
|
PHOOK NextObj, Hook = ClientInfo->phkCurrent;
|
|
|
|
|
|
|
|
if (!ClientInfo || !Hook) break;
|
|
|
|
|
|
|
|
UserReferenceObject(Hook);
|
|
|
|
|
|
|
|
if (Hook->Thread && (Hook->Thread != PsGetCurrentThread()))
|
|
|
|
{
|
|
|
|
UserDereferenceObject(Hook);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
NextObj = IntGetNextHook(Hook);
|
|
|
|
ClientInfo->phkCurrent = NextObj;
|
|
|
|
|
|
|
|
if ( Hook->HookId == WH_CALLWNDPROC)
|
|
|
|
{
|
|
|
|
CWPSTRUCT CWP;
|
|
|
|
CWP.hwnd = hWnd;
|
|
|
|
CWP.message = Msg;
|
|
|
|
CWP.wParam = wParam;
|
|
|
|
CWP.lParam = lParam;
|
2008-07-27 00:56:18 +00:00
|
|
|
DPRINT("WH_CALLWNDPROC: Hook %x NextHook %x\n", Hook, NextObj );
|
2008-07-26 12:27:40 +00:00
|
|
|
|
|
|
|
lResult = co_IntCallHookProc( Hook->HookId,
|
|
|
|
HC_ACTION,
|
|
|
|
((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
|
|
|
|
(LPARAM)&CWP,
|
|
|
|
Hook->Proc,
|
|
|
|
Hook->Ansi,
|
|
|
|
&Hook->ModuleName);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CWPRETSTRUCT CWPR;
|
|
|
|
CWPR.hwnd = hWnd;
|
|
|
|
CWPR.message = Msg;
|
|
|
|
CWPR.wParam = wParam;
|
|
|
|
CWPR.lParam = lParam;
|
|
|
|
CWPR.lResult = ClientInfo->dwHookData;
|
|
|
|
|
|
|
|
lResult = co_IntCallHookProc( Hook->HookId,
|
|
|
|
HC_ACTION,
|
|
|
|
((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
|
|
|
|
(LPARAM)&CWPR,
|
|
|
|
Hook->Proc,
|
|
|
|
Hook->Ansi,
|
|
|
|
&Hook->ModuleName);
|
|
|
|
}
|
|
|
|
UserDereferenceObject(Hook);
|
|
|
|
lResult = (LRESULT) NextObj;
|
2008-07-24 21:39:00 +00:00
|
|
|
}
|
|
|
|
break;
|
2008-07-13 00:24:05 +00:00
|
|
|
}
|
|
|
|
UserLeave();
|
|
|
|
return lResult;
|
|
|
|
}
|
|
|
|
|
2008-07-11 11:22:16 +00:00
|
|
|
#define INFINITE 0xFFFFFFFF
|
|
|
|
#define WAIT_FAILED ((DWORD)0xFFFFFFFF)
|
|
|
|
|
2008-07-10 23:51:24 +00:00
|
|
|
DWORD
|
|
|
|
NTAPI
|
|
|
|
NtUserWaitForInputIdle(
|
|
|
|
IN HANDLE hProcess,
|
|
|
|
IN DWORD dwMilliseconds,
|
|
|
|
IN BOOL Unknown2)
|
|
|
|
{
|
2008-07-11 01:24:47 +00:00
|
|
|
PEPROCESS Process;
|
|
|
|
PW32PROCESS W32Process;
|
|
|
|
NTSTATUS Status;
|
2008-07-11 11:22:16 +00:00
|
|
|
HANDLE Handles[2];
|
|
|
|
LARGE_INTEGER Timeout;
|
|
|
|
ULONGLONG StartTime, Run, Elapsed = 0;
|
2008-07-11 01:02:28 +00:00
|
|
|
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
2008-07-11 01:24:47 +00:00
|
|
|
Status = ObReferenceObjectByHandle(hProcess,
|
|
|
|
PROCESS_QUERY_INFORMATION,
|
|
|
|
PsProcessType,
|
|
|
|
UserMode,
|
|
|
|
(PVOID*)&Process,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2008-07-15 14:00:37 +00:00
|
|
|
UserLeave();
|
2008-07-11 01:24:47 +00:00
|
|
|
SetLastNtError(Status);
|
2008-07-11 11:22:16 +00:00
|
|
|
return WAIT_FAILED;
|
2008-07-11 01:24:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
W32Process = (PW32PROCESS)Process->Win32Process;
|
|
|
|
if (!W32Process)
|
|
|
|
{
|
|
|
|
ObDereferenceObject(Process);
|
2008-07-15 14:00:37 +00:00
|
|
|
UserLeave();
|
2008-07-11 01:24:47 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
2008-07-11 11:22:16 +00:00
|
|
|
return WAIT_FAILED;
|
2008-07-11 01:24:47 +00:00
|
|
|
}
|
|
|
|
|
2008-07-11 11:22:16 +00:00
|
|
|
EngCreateEvent((PEVENT *)&W32Process->InputIdleEvent);
|
|
|
|
|
2008-07-15 14:00:37 +00:00
|
|
|
Handles[0] = Process;
|
2008-07-11 11:22:16 +00:00
|
|
|
Handles[1] = W32Process->InputIdleEvent;
|
2008-07-11 01:02:28 +00:00
|
|
|
|
2008-07-15 14:00:37 +00:00
|
|
|
if (!Handles[1])
|
|
|
|
{
|
|
|
|
ObDereferenceObject(Process);
|
|
|
|
UserLeave();
|
|
|
|
return STATUS_SUCCESS; /* no event to wait on */
|
|
|
|
}
|
2008-07-11 01:02:28 +00:00
|
|
|
|
2008-07-11 11:22:16 +00:00
|
|
|
StartTime = ((ULONGLONG)SharedUserData->TickCountLowDeprecated *
|
|
|
|
SharedUserData->TickCountMultiplier / 16777216);
|
2008-07-11 01:02:28 +00:00
|
|
|
|
2008-07-11 11:22:16 +00:00
|
|
|
Run = dwMilliseconds;
|
|
|
|
|
|
|
|
DPRINT("WFII: waiting for %p\n", Handles[1] );
|
2008-07-11 01:02:28 +00:00
|
|
|
do
|
|
|
|
{
|
2008-07-11 11:22:16 +00:00
|
|
|
Timeout.QuadPart = Run - Elapsed;
|
2008-07-11 01:02:28 +00:00
|
|
|
UserLeave();
|
2008-07-11 11:22:16 +00:00
|
|
|
Status = KeWaitForMultipleObjects( 2,
|
|
|
|
Handles,
|
|
|
|
WaitAny,
|
|
|
|
UserRequest,
|
|
|
|
UserMode,
|
|
|
|
FALSE,
|
|
|
|
dwMilliseconds == INFINITE ? NULL : &Timeout,
|
|
|
|
NULL);
|
2008-07-11 01:02:28 +00:00
|
|
|
UserEnterExclusive();
|
|
|
|
|
2008-07-11 11:22:16 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2008-07-11 01:02:28 +00:00
|
|
|
{
|
2008-07-11 11:22:16 +00:00
|
|
|
SetLastNtError(Status);
|
|
|
|
Status = WAIT_FAILED;
|
|
|
|
goto WaitExit;
|
2008-07-11 01:02:28 +00:00
|
|
|
}
|
2008-07-11 11:22:16 +00:00
|
|
|
|
|
|
|
switch (Status)
|
|
|
|
{
|
|
|
|
case STATUS_WAIT_0:
|
|
|
|
Status = WAIT_FAILED;
|
|
|
|
goto WaitExit;
|
|
|
|
|
|
|
|
case STATUS_WAIT_2:
|
|
|
|
{
|
|
|
|
USER_MESSAGE Msg;
|
|
|
|
co_IntPeekMessage( &Msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case STATUS_USER_APC:
|
|
|
|
case STATUS_ALERTED:
|
|
|
|
case STATUS_TIMEOUT:
|
|
|
|
DPRINT1("WFII: timeout\n");
|
|
|
|
Status = STATUS_TIMEOUT;
|
|
|
|
goto WaitExit;
|
|
|
|
|
|
|
|
default:
|
|
|
|
DPRINT1("WFII: finished\n");
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
goto WaitExit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dwMilliseconds != INFINITE)
|
2008-07-11 01:02:28 +00:00
|
|
|
{
|
2008-07-11 11:22:16 +00:00
|
|
|
Elapsed = ((ULONGLONG)SharedUserData->TickCountLowDeprecated *
|
|
|
|
SharedUserData->TickCountMultiplier / 16777216)
|
|
|
|
- StartTime;
|
2008-07-11 01:02:28 +00:00
|
|
|
|
2008-07-11 11:22:16 +00:00
|
|
|
if (Elapsed > Run)
|
|
|
|
Status = STATUS_TIMEOUT;
|
2008-07-11 01:02:28 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (1);
|
2008-07-11 11:22:16 +00:00
|
|
|
|
2008-07-11 01:02:28 +00:00
|
|
|
WaitExit:
|
2008-07-11 11:22:16 +00:00
|
|
|
if (W32Process->InputIdleEvent)
|
|
|
|
{
|
|
|
|
EngDeleteEvent((PEVENT)W32Process->InputIdleEvent);
|
|
|
|
W32Process->InputIdleEvent = NULL;
|
|
|
|
}
|
2008-07-11 01:24:47 +00:00
|
|
|
ObDereferenceObject(Process);
|
2008-07-11 01:02:28 +00:00
|
|
|
UserLeave();
|
2008-07-11 11:22:16 +00:00
|
|
|
return Status;
|
2008-07-10 23:51:24 +00:00
|
|
|
}
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
/* EOF */
|