/*
- * 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
- */
+* COPYRIGHT: See COPYING in the top level directory
+* PROJECT: ReactOS kernel
+* PURPOSE: Messages
+* FILE: subsystems/win32/win32k/ntuser/message.c
+* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+* REVISION HISTORY:
+* 06-06-2001 CSH Created
+*/
/* INCLUDES ******************************************************************/
#define NDEBUG
#include <debug.h>
-#define PM_BADMSGFLAGS ~((QS_RAWINPUT << 16)|PM_QS_SENDMESSAGE|PM_QS_PAINT|PM_QS_POSTMESSAGE|PM_QS_INPUT|PM_NOYIELD|PM_REMOVE)
+BOOLEAN NTAPI PsGetProcessExitProcessCalled(PEPROCESS Process);
+HWND FASTCALL co_UserSetCapture(HWND hWnd);
-typedef struct
-{
- UINT uFlags;
- UINT uTimeout;
- ULONG_PTR Result;
-}
-DOSENDMESSAGE, *PDOSENDMESSAGE;
+#define PM_BADMSGFLAGS ~((QS_RAWINPUT << 16)|PM_QS_SENDMESSAGE|PM_QS_PAINT|PM_QS_POSTMESSAGE|PM_QS_INPUT|PM_NOYIELD|PM_REMOVE)
/* FUNCTIONS *****************************************************************/
NTSTATUS FASTCALL
IntInitMessageImpl(VOID)
{
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
NTSTATUS FASTCALL
IntCleanupMessageImpl(VOID)
{
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
+}
+
+/* From wine: */
+/* flag for messages that contain pointers */
+/* 32 messages per entry, messages 0..31 map to bits 0..31 */
+
+#define SET(msg) (1 << ((msg) & 31))
+
+static const unsigned int message_pointer_flags[] =
+{
+ /* 0x00 - 0x1f */
+ SET(WM_CREATE) | SET(WM_SETTEXT) | SET(WM_GETTEXT) |
+ SET(WM_WININICHANGE) | SET(WM_DEVMODECHANGE),
+ /* 0x20 - 0x3f */
+ SET(WM_GETMINMAXINFO) | SET(WM_DRAWITEM) | SET(WM_MEASUREITEM) | SET(WM_DELETEITEM) |
+ SET(WM_COMPAREITEM),
+ /* 0x40 - 0x5f */
+ SET(WM_WINDOWPOSCHANGING) | SET(WM_WINDOWPOSCHANGED) | SET(WM_COPYDATA) |
+ SET(WM_COPYGLOBALDATA) | SET(WM_NOTIFY) | SET(WM_HELP),
+ /* 0x60 - 0x7f */
+ SET(WM_STYLECHANGING) | SET(WM_STYLECHANGED),
+ /* 0x80 - 0x9f */
+ SET(WM_NCCREATE) | SET(WM_NCCALCSIZE) | SET(WM_GETDLGCODE),
+ /* 0xa0 - 0xbf */
+ SET(EM_GETSEL) | SET(EM_GETRECT) | SET(EM_SETRECT) | SET(EM_SETRECTNP),
+ /* 0xc0 - 0xdf */
+ SET(EM_REPLACESEL) | SET(EM_GETLINE) | SET(EM_SETTABSTOPS),
+ /* 0xe0 - 0xff */
+ SET(SBM_GETRANGE) | SET(SBM_SETSCROLLINFO) | SET(SBM_GETSCROLLINFO) | SET(SBM_GETSCROLLBARINFO),
+ /* 0x100 - 0x11f */
+ 0,
+ /* 0x120 - 0x13f */
+ 0,
+ /* 0x140 - 0x15f */
+ SET(CB_GETEDITSEL) | SET(CB_ADDSTRING) | SET(CB_DIR) | SET(CB_GETLBTEXT) |
+ SET(CB_INSERTSTRING) | SET(CB_FINDSTRING) | SET(CB_SELECTSTRING) |
+ SET(CB_GETDROPPEDCONTROLRECT) | SET(CB_FINDSTRINGEXACT),
+ /* 0x160 - 0x17f */
+ 0,
+ /* 0x180 - 0x19f */
+ SET(LB_ADDSTRING) | SET(LB_INSERTSTRING) | SET(LB_GETTEXT) | SET(LB_SELECTSTRING) |
+ SET(LB_DIR) | SET(LB_FINDSTRING) |
+ SET(LB_GETSELITEMS) | SET(LB_SETTABSTOPS) | SET(LB_ADDFILE) | SET(LB_GETITEMRECT),
+ /* 0x1a0 - 0x1bf */
+ SET(LB_FINDSTRINGEXACT),
+ /* 0x1c0 - 0x1df */
+ 0,
+ /* 0x1e0 - 0x1ff */
+ 0,
+ /* 0x200 - 0x21f */
+ SET(WM_NEXTMENU) | SET(WM_SIZING) | SET(WM_MOVING) | SET(WM_DEVICECHANGE),
+ /* 0x220 - 0x23f */
+ SET(WM_MDICREATE) | SET(WM_MDIGETACTIVE) | SET(WM_DROPOBJECT) |
+ SET(WM_QUERYDROPOBJECT) | SET(WM_DRAGLOOP) | SET(WM_DRAGSELECT) | SET(WM_DRAGMOVE),
+ /* 0x240 - 0x25f */
+ 0,
+ /* 0x260 - 0x27f */
+ 0,
+ /* 0x280 - 0x29f */
+ 0,
+ /* 0x2a0 - 0x2bf */
+ 0,
+ /* 0x2c0 - 0x2df */
+ 0,
+ /* 0x2e0 - 0x2ff */
+ 0,
+ /* 0x300 - 0x31f */
+ SET(WM_ASKCBFORMATNAME)
+};
+
+/* check whether a given message type includes pointers */
+static inline int is_pointer_message( UINT message )
+{
+ if (message >= 8*sizeof(message_pointer_flags)) return FALSE;
+ return (message_pointer_flags[message / 32] & SET(message)) != 0;
}
#define MMS_SIZE_WPARAM -1
#define MMS_FLAG_READWRITE (MMS_FLAG_READ | MMS_FLAG_WRITE)
typedef struct tagMSGMEMORY
{
- UINT Message;
- UINT Size;
- INT Flags;
+ UINT Message;
+ UINT Size;
+ INT Flags;
}
MSGMEMORY, *PMSGMEMORY;
static MSGMEMORY MsgMemory[] =
- {
- { 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 },
- };
+{
+ { 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_COPYGLOBALDATA, MMS_SIZE_WPARAM, MMS_FLAG_READ },
+ { WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
+ { WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
+};
static PMSGMEMORY FASTCALL
FindMsgMemory(UINT Msg)
{
- PMSGMEMORY MsgMemoryEntry;
+ PMSGMEMORY MsgMemoryEntry;
- /* See if this message type is present in the table */
- for (MsgMemoryEntry = MsgMemory;
- MsgMemoryEntry < MsgMemory + sizeof(MsgMemory) / sizeof(MSGMEMORY);
- MsgMemoryEntry++)
- {
- if (Msg == MsgMemoryEntry->Message)
- {
- return MsgMemoryEntry;
- }
- }
+ /* See if this message type is present in the table */
+ for (MsgMemoryEntry = MsgMemory;
+ MsgMemoryEntry < MsgMemory + sizeof(MsgMemory) / sizeof(MSGMEMORY);
+ MsgMemoryEntry++)
+ {
+ if (Msg == MsgMemoryEntry->Message)
+ {
+ return MsgMemoryEntry;
+ }
+ }
- return NULL;
+ return NULL;
}
static UINT FASTCALL
MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
{
- CREATESTRUCTW *Cs;
- PUNICODE_STRING WindowName;
- PUNICODE_STRING ClassName;
- UINT Size = 0;
+ CREATESTRUCTW *Cs;
+ PUNICODE_STRING WindowName;
+ PUNICODE_STRING ClassName;
+ UINT Size = 0;
- _SEH2_TRY
- {
- if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size)
- {
- Size = (UINT)wParam;
- }
- else if (MMS_SIZE_WPARAMWCHAR == MsgMemoryEntry->Size)
- {
- Size = (UINT) (wParam * sizeof(WCHAR));
- }
- else if (MMS_SIZE_LPARAMSZ == MsgMemoryEntry->Size)
- {
- Size = (UINT) ((wcslen((PWSTR) lParam) + 1) * sizeof(WCHAR));
- }
- else if (MMS_SIZE_SPECIAL == MsgMemoryEntry->Size)
- {
- switch(MsgMemoryEntry->Message)
- {
+ _SEH2_TRY
+ {
+ if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size)
+ {
+ Size = (UINT)wParam;
+ }
+ else if (MMS_SIZE_WPARAMWCHAR == MsgMemoryEntry->Size)
+ {
+ Size = (UINT) (wParam * sizeof(WCHAR));
+ }
+ else if (MMS_SIZE_LPARAMSZ == MsgMemoryEntry->Size)
+ {
+ Size = (UINT) ((wcslen((PWSTR) lParam) + 1) * sizeof(WCHAR));
+ }
+ else if (MMS_SIZE_SPECIAL == MsgMemoryEntry->Size)
+ {
+ switch(MsgMemoryEntry->Message)
+ {
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;
+ 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:
- Size = wParam ? sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS) : sizeof(RECT);
- break;
+ Size = wParam ? sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS) : sizeof(RECT);
+ break;
case WM_COPYDATA:
- Size = sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData;
- break;
-
- case WM_COPYGLOBALDATA:
- Size = wParam;
- break;
+ Size = sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData;
+ break;
default:
- ASSERT(FALSE);
- Size = 0;
- break;
- }
- }
- else
- {
- Size = MsgMemoryEntry->Size;
- }
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- DPRINT1("Exception caught in MsgMemorySize()! Status: 0x%x\n", _SEH2_GetExceptionCode());
- Size = 0;
- }
- _SEH2_END;
- return Size;
+ ASSERT(FALSE);
+ Size = 0;
+ break;
+ }
+ }
+ else
+ {
+ Size = MsgMemoryEntry->Size;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DPRINT1("Exception caught in MsgMemorySize()! Status: 0x%x\n", _SEH2_GetExceptionCode());
+ Size = 0;
+ }
+ _SEH2_END;
+ return Size;
}
static NTSTATUS
PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL NonPagedPoolNeeded)
{
- NCCALCSIZE_PARAMS *UnpackedNcCalcsize;
- NCCALCSIZE_PARAMS *PackedNcCalcsize;
- CREATESTRUCTW *UnpackedCs;
- CREATESTRUCTW *PackedCs;
- PLARGE_STRING WindowName;
- PUNICODE_STRING ClassName;
- POOL_TYPE PoolType;
- UINT Size;
- PCHAR CsData;
-
- *lParamPacked = lParam;
+ NCCALCSIZE_PARAMS *UnpackedNcCalcsize;
+ NCCALCSIZE_PARAMS *PackedNcCalcsize;
+ CREATESTRUCTW *UnpackedCs;
+ CREATESTRUCTW *PackedCs;
+ PLARGE_STRING WindowName;
+ PUNICODE_STRING ClassName;
+ POOL_TYPE PoolType;
+ UINT Size;
+ PCHAR CsData;
+
+ *lParamPacked = lParam;
if (NonPagedPoolNeeded)
- PoolType = NonPagedPool;
+ PoolType = NonPagedPool;
else
- PoolType = PagedPool;
-
- if (WM_NCCALCSIZE == Msg && wParam)
- {
+ PoolType = PagedPool;
- UnpackedNcCalcsize = (NCCALCSIZE_PARAMS *) lParam;
- PackedNcCalcsize = ExAllocatePoolWithTag(PoolType,
- sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS),
- TAG_MSG);
+ if (WM_NCCALCSIZE == Msg && wParam)
+ {
- 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)
- {
- UnpackedCs = (CREATESTRUCTW *) lParam;
- WindowName = (PLARGE_STRING) UnpackedCs->lpszName;
- ClassName = (PUNICODE_STRING) UnpackedCs->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);
- }
- PackedCs = ExAllocatePoolWithTag(PoolType, Size, TAG_MSG);
- if (NULL == PackedCs)
- {
- DPRINT1("Not enough memory to pack lParam\n");
- return STATUS_NO_MEMORY;
- }
- 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))
- {
- *((WCHAR *) CsData) = L'A';
- CsData += sizeof(WCHAR);
- *((ATOM *) CsData) = (ATOM)(DWORD_PTR) ClassName->Buffer;
- CsData += sizeof(ATOM);
- }
- else
- {
- *((WCHAR *) CsData) = L'S';
- CsData += sizeof(WCHAR);
- RtlCopyMemory(CsData, ClassName->Buffer, ClassName->Length);
- CsData += ClassName->Length;
- *((WCHAR *) CsData) = L'\0';
- CsData += sizeof(WCHAR);
- }
- ASSERT(CsData == (PCHAR) PackedCs + Size);
- *lParamPacked = (LPARAM) PackedCs;
- }
+ UnpackedNcCalcsize = (NCCALCSIZE_PARAMS *) lParam;
+ PackedNcCalcsize = ExAllocatePoolWithTag(PoolType,
+ sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS),
+ TAG_MSG);
- else if (PoolType == NonPagedPool)
- {
- PMSGMEMORY MsgMemoryEntry;
- PVOID PackedData;
+ 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)
+ {
+ UnpackedCs = (CREATESTRUCTW *) lParam;
+ WindowName = (PLARGE_STRING) UnpackedCs->lpszName;
+ ClassName = (PUNICODE_STRING) UnpackedCs->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);
+ }
+ PackedCs = ExAllocatePoolWithTag(PoolType, Size, TAG_MSG);
+ if (NULL == PackedCs)
+ {
+ DPRINT1("Not enough memory to pack lParam\n");
+ return STATUS_NO_MEMORY;
+ }
+ 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))
+ {
+ *((WCHAR *) CsData) = L'A';
+ CsData += sizeof(WCHAR);
+ *((ATOM *) CsData) = (ATOM)(DWORD_PTR) ClassName->Buffer;
+ CsData += sizeof(ATOM);
+ }
+ else
+ {
+ *((WCHAR *) CsData) = L'S';
+ CsData += sizeof(WCHAR);
+ RtlCopyMemory(CsData, ClassName->Buffer, ClassName->Length);
+ CsData += ClassName->Length;
+ *((WCHAR *) CsData) = L'\0';
+ CsData += sizeof(WCHAR);
+ }
+ ASSERT(CsData == (PCHAR) PackedCs + Size);
+ *lParamPacked = (LPARAM) PackedCs;
+ }
+ else if (PoolType == NonPagedPool)
+ {
+ PMSGMEMORY MsgMemoryEntry;
+ PVOID PackedData;
- MsgMemoryEntry = FindMsgMemory(Msg);
+ MsgMemoryEntry = FindMsgMemory(Msg);
- if ((!MsgMemoryEntry) || (MsgMemoryEntry->Size < 0))
- {
- /* Keep previous behavior */
- return STATUS_SUCCESS;
- }
- PackedData = ExAllocatePoolWithTag(NonPagedPool, MsgMemorySize(MsgMemoryEntry, wParam, lParam), TAG_MSG);
- RtlCopyMemory(PackedData, (PVOID)lParam, MsgMemorySize(MsgMemoryEntry, wParam, lParam));
- *lParamPacked = (LPARAM)PackedData;
- }
+ if ((!MsgMemoryEntry) || (MsgMemoryEntry->Size < 0))
+ {
+ /* Keep previous behavior */
+ return STATUS_SUCCESS;
+ }
+ PackedData = ExAllocatePoolWithTag(NonPagedPool, MsgMemorySize(MsgMemoryEntry, wParam, lParam), TAG_MSG);
+ RtlCopyMemory(PackedData, (PVOID)lParam, MsgMemorySize(MsgMemoryEntry, wParam, lParam));
+ *lParamPacked = (LPARAM)PackedData;
+ }
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
static NTSTATUS
UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL NonPagedPoolUsed)
{
- NCCALCSIZE_PARAMS *UnpackedParams;
- NCCALCSIZE_PARAMS *PackedParams;
- PWINDOWPOS UnpackedWindowPos;
+ NCCALCSIZE_PARAMS *UnpackedParams;
+ NCCALCSIZE_PARAMS *PackedParams;
+ PWINDOWPOS UnpackedWindowPos;
- if (lParamPacked == lParam)
- {
- return STATUS_SUCCESS;
- }
+ if (lParamPacked == lParam)
+ {
+ return STATUS_SUCCESS;
+ }
- if (WM_NCCALCSIZE == Msg && wParam)
- {
- 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);
-
- return STATUS_SUCCESS;
- }
- else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
- {
- ExFreePool((PVOID) lParamPacked);
+ if (WM_NCCALCSIZE == Msg && wParam)
+ {
+ 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);
+
+ return STATUS_SUCCESS;
+ }
+ else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
+ {
+ ExFreePool((PVOID) lParamPacked);
- return STATUS_SUCCESS;
- }
- else if (NonPagedPoolUsed)
- {
- PMSGMEMORY MsgMemoryEntry;
- MsgMemoryEntry = FindMsgMemory(Msg);
- if (MsgMemoryEntry->Size < 0)
- {
- /* Keep previous behavior */
- return STATUS_INVALID_PARAMETER;
- }
+ return STATUS_SUCCESS;
+ }
+ else if (NonPagedPoolUsed)
+ {
+ PMSGMEMORY MsgMemoryEntry;
+ MsgMemoryEntry = FindMsgMemory(Msg);
+ if (MsgMemoryEntry->Size < 0)
+ {
+ /* Keep previous behavior */
+ return STATUS_INVALID_PARAMETER;
+ }
- if (MsgMemory->Flags == MMS_FLAG_READWRITE)
- {
- //RtlCopyMemory((PVOID)lParam, (PVOID)lParamPacked, MsgMemory->Size);
- }
- ExFreePool((PVOID) lParamPacked);
- return STATUS_SUCCESS;
- }
+ if (MsgMemory->Flags == MMS_FLAG_READWRITE)
+ {
+ //RtlCopyMemory((PVOID)lParam, (PVOID)lParamPacked, MsgMemory->Size);
+ }
+ ExFreePool((PVOID) lParamPacked);
+ return STATUS_SUCCESS;
+ }
- ASSERT(FALSE);
+ ASSERT(FALSE);
- return STATUS_INVALID_PARAMETER;
+ return STATUS_INVALID_PARAMETER;
}
-static
-VOID
-FASTCALL
-IntCallWndProc
-( PWINDOW_OBJECT Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
+static NTSTATUS FASTCALL
+CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg, PMSGMEMORY MsgMemoryEntry)
{
- BOOL SameThread = FALSE;
-
- if (Window->pti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread()))
- SameThread = TRUE;
+ NTSTATUS Status;
- if ((!SameThread && (Window->pti->fsHooks & 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 );
- }
-}
+ PVOID KernelMem;
+ UINT Size;
-static
-VOID
-FASTCALL
-IntCallWndProcRet
-( PWINDOW_OBJECT Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *uResult)
-{
- BOOL SameThread = FALSE;
+ *KernelModeMsg = *UserModeMsg;
- if (Window->pti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread()))
- SameThread = TRUE;
+ /* See if this message type is present in the table */
+ if (NULL == MsgMemoryEntry)
+ {
+ /* Not present, no copying needed */
+ return STATUS_SUCCESS;
+ }
- if ((!SameThread && (Window->pti->fsHooks & 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 );
- }
-}
+ /* Determine required size */
+ Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
-LRESULT
-FASTCALL
-IntDispatchMessage(PMSG pMsg)
-{
- LARGE_INTEGER TickCount;
- LONG Time;
- LRESULT retval;
- PMSGMEMORY MsgMemoryEntry;
- INT lParamBufferSize;
- LPARAM lParamPacked;
- PWINDOW_OBJECT Window = NULL;
-
- if (pMsg->hwnd)
- {
- Window = UserGetWindowObject(pMsg->hwnd);
- if (!Window || !Window->Wnd) return 0;
- }
-
- if (((pMsg->message == WM_SYSTIMER) ||
- (pMsg->message == WM_TIMER)) &&
- (pMsg->lParam) )
- {
- if (pMsg->message == WM_TIMER)
- {
- if (ValidateTimerCallback(PsGetCurrentThreadWin32Thread(),Window,pMsg->wParam,pMsg->lParam))
- {
- KeQueryTickCount(&TickCount);
- Time = MsqCalculateMessageTime(&TickCount);
- return co_IntCallWindowProc((WNDPROC)pMsg->lParam,
- TRUE,
- pMsg->hwnd,
- WM_TIMER,
- pMsg->wParam,
- (LPARAM)Time,
- sizeof(LPARAM));
- }
- return 0;
- }
- else
- {
- PTIMER pTimer = FindSystemTimer(pMsg);
- if (pTimer && pTimer->pfn)
- {
- KeQueryTickCount(&TickCount);
- Time = MsqCalculateMessageTime(&TickCount);
- pTimer->pfn(pMsg->hwnd, WM_SYSTIMER, (UINT)pMsg->wParam, Time);
+ if (0 != Size)
+ {
+ /* Allocate kernel mem */
+ KernelMem = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
+ if (NULL == KernelMem)
+ {
+ DPRINT1("Not enough memory to copy message to kernel mem\n");
+ return STATUS_NO_MEMORY;
}
- return 0;
- }
- }
- // Need a window!
- if ( !Window || !Window->Wnd ) return 0;
-
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(pMsg->message);
- if ( !MsgMemoryEntry )
- {
- lParamBufferSize = -1;
- }
- else
- {
- lParamBufferSize = MsgMemorySize(MsgMemoryEntry, pMsg->wParam, pMsg->lParam);
- }
-
- if (! NT_SUCCESS(PackParam(&lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam, FALSE)))
- {
- DPRINT1("Failed to pack message parameters\n");
- return 0;
- }
-
- retval = co_IntCallWindowProc( Window->Wnd->lpfnWndProc,
- !Window->Wnd->Unicode,
- pMsg->hwnd,
- pMsg->message,
- pMsg->wParam,
- lParamPacked,
- lParamBufferSize);
-
- if (! NT_SUCCESS(UnpackParam(lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam, FALSE)))
- {
- DPRINT1("Failed to unpack message parameters\n");
- }
-
- if (pMsg->message == WM_PAINT)
- {
- /* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
- HRGN hrgn = IntSysCreateRectRgn( 0, 0, 0, 0 );
- co_UserGetUpdateRgn( Window, hrgn, TRUE );
- REGION_FreeRgnByHandle( hrgn );
- }
- return retval;
-}
-
-VOID FASTCALL
-co_IntSendHitTestMessages(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg)
-{
- 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;
- CurInfo = IntGetSysCursorInfo();
+ KernelModeMsg->lParam = (LPARAM) KernelMem;
- wParam = (WPARAM)(CurInfo->ButtonsDown);
+ /* Copy data if required */
+ if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_READ))
+ {
+ Status = MmCopyFromCaller(KernelMem, (PVOID) UserModeMsg->lParam, Size);
+ if (! NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to copy message to kernel: invalid usermode buffer\n");
+ ExFreePoolWithTag(KernelMem, TAG_MSG);
+ return Status;
+ }
+ }
+ else
+ {
+ /* Make sure we don't pass any secrets to usermode */
+ RtlZeroMemory(KernelMem, Size);
+ }
+ }
+ else
+ {
+ KernelModeMsg->lParam = 0;
+ }
- 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;
- }
- }
+ return STATUS_SUCCESS;
}
-BOOL FASTCALL
-co_IntActivateWindowMouse(
- PUSER_MESSAGE_QUEUE ThreadQueue,
- LPMSG Msg,
- PWINDOW_OBJECT MsgWindow,
- USHORT *HitTest)
+static NTSTATUS FASTCALL
+CopyMsgToUserMem(MSG *UserModeMsg, MSG *KernelModeMsg)
{
- ULONG Result;
- PWINDOW_OBJECT Parent;
-
- ASSERT_REFS_CO(MsgWindow);
+ NTSTATUS Status;
+ PMSGMEMORY MsgMemoryEntry;
+ UINT Size;
- if(*HitTest == (USHORT)HTTRANSPARENT)
- {
- /* eat the message, search again! */
- return TRUE;
- }
+ /* See if this message type is present in the table */
+ MsgMemoryEntry = FindMsgMemory(UserModeMsg->message);
+ if (NULL == MsgMemoryEntry)
+ {
+ /* Not present, no copying needed */
+ return STATUS_SUCCESS;
+ }
- Parent = IntGetParent(MsgWindow);//fixme: deref retval?
+ /* Determine required size */
+ Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
- /* If no parent window, pass MsgWindows HWND as wParam. Fixes bug #3111 */
- Result = co_IntSendMessage(MsgWindow->hSelf,
- WM_MOUSEACTIVATE,
- (WPARAM) (Parent ? Parent->hSelf : MsgWindow->hSelf),
- (LPARAM)MAKELONG(*HitTest, Msg->message)
- );
+ if (0 != Size)
+ {
+ /* Copy data if required */
+ if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_WRITE))
+ {
+ 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;
+ }
+ }
- 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;
- }
+ ExFreePool((PVOID) KernelModeMsg->lParam);
+ }
- return FALSE;
+ return STATUS_SUCCESS;
}
-BOOL FASTCALL
-co_IntTranslateMouseMessage(
- PUSER_MESSAGE_QUEUE ThreadQueue,
- LPMSG Msg,
- USHORT *HitTest,
- BOOL Remove)
+//
+// Wakeup any thread/process waiting on idle input.
+//
+VOID FASTCALL
+IdlePing(VOID)
{
- PWINDOW_OBJECT Window;
- USER_REFERENCE_ENTRY Ref, DesktopRef;
+ PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
+ PUSER_MESSAGE_QUEUE ForegroundQueue;
+ PTHREADINFO pti, ptiForeground = NULL;
- if(!(Window = UserGetWindowObject(Msg->hwnd)))
- {
- /* let's just eat the message?! */
- return TRUE;
- }
+ ForegroundQueue = IntGetFocusMessageQueue();
- *HitTest = HTCLIENT;
+ if (ForegroundQueue)
+ ptiForeground = ForegroundQueue->Thread->Tcb.Win32Thread;
- UserRefObjectCo(Window, &Ref);
+ pti = PsGetCurrentThreadWin32Thread();
- if ( ThreadQueue == Window->pti->MessageQueue &&
- ThreadQueue->CaptureWindow != Window->hSelf)
+ if ( pti )
{
- /* only send WM_NCHITTEST messages if we're not capturing the window! */
- if (Remove )
- {
- *HitTest = co_IntSendMessage(Window->hSelf, WM_NCHITTEST, 0,
- MAKELONG(Msg->pt.x, Msg->pt.y));
- }
- /* else we are going to see this message again, but then with Remove == TRUE */
+ pti->pClientInfo->cSpins = 0; // Reset spins.
- if (*HitTest == (USHORT)HTTRANSPARENT)
+ if ( pti->pDeskInfo && pti == ptiForeground )
{
- PWINDOW_OBJECT DesktopWindow;
- HWND hDesktop = IntGetDesktopWindow();
-
- if ((DesktopWindow = UserGetWindowObject(hDesktop)))
+ if ( pti->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) ||
+ pti->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) )
{
- PWINDOW_OBJECT Wnd;
-
- UserRefObjectCo(DesktopWindow, &DesktopRef);
-
- co_WinPosWindowFromPoint(DesktopWindow, Window->pti->MessageQueue, &Msg->pt, &Wnd);
- if (Wnd)
- {
- if (Wnd != Window)
- {
- /* post the message to the other window */
- Msg->hwnd = Wnd->hSelf;
- if(!(Wnd->state & WINDOWSTATUS_DESTROYING))
- {
- MsqPostMessage(Wnd->pti->MessageQueue, Msg, FALSE,
- Msg->message == WM_MOUSEMOVE ? QS_MOUSEMOVE :
- QS_MOUSEBUTTON);
- }
-
- /* eat the message */
- UserDereferenceObject(Wnd);
- UserDerefObjectCo(DesktopWindow);
- UserDerefObjectCo(Window);
- return TRUE;
- }
- UserDereferenceObject(Wnd);
- }
-
- UserDerefObjectCo(DesktopWindow);
+ co_HOOK_CallHooks(WH_FOREGROUNDIDLE,HC_ACTION,0,0);
}
}
}
- if ( gspv.bMouseClickLock &&
- ( (Msg->message == WM_LBUTTONUP) ||
- (Msg->message == WM_LBUTTONDOWN) ) )
+ DPRINT("IdlePing ppi 0x%x\n",ppi);
+ if ( ppi && ppi->InputIdleEvent )
{
- if (MsqIsClkLck(Msg, Remove))
- {
- // FIXME: drop the message, hack: use WM_NULL
- Msg->message = WM_NULL;
- }
+ DPRINT("InputIdleEvent\n");
+ KeSetEvent( ppi->InputIdleEvent, IO_NO_INCREMENT, FALSE);
}
+}
- if (IS_BTN_MESSAGE(Msg->message, DOWN))
+VOID FASTCALL
+IdlePong(VOID)
+{
+ PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
+
+ DPRINT("IdlePong ppi 0x%x\n",ppi);
+ if ( ppi && ppi->InputIdleEvent )
{
- /* generate double click messages, if necessary */
- if ((((*HitTest) != HTCLIENT) ||
- (Window->Wnd->pcls->style & CS_DBLCLKS)) &&
- MsqIsDblClk(Msg, Remove))
- {
- Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;
- }
+ KeClearEvent(ppi->InputIdleEvent);
}
+}
- if(Msg->message != WM_MOUSEWHEEL)
- {
+UINT FASTCALL
+GetWakeMask(UINT first, UINT last )
+{
+ UINT mask = QS_POSTMESSAGE | QS_SENDMESSAGE; /* Always selected */
- if ((*HitTest) != HTCLIENT)
- {
- 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);
- }
- else if ( ThreadQueue->MoveSize == NULL &&
- ThreadQueue->MenuOwner == NULL )
- {
- /* NOTE: Msg->pt should remain in screen coordinates. -- FiN */
- Msg->lParam = MAKELONG(
- Msg->pt.x - (WORD)Window->Wnd->rcClient.left,
- Msg->pt.y - (WORD)Window->Wnd->rcClient.top);
- }
- }
+ if (first || last)
+ {
+ if ((first <= WM_KEYLAST) && (last >= WM_KEYFIRST)) mask |= QS_KEY;
+ if ( ((first <= WM_MOUSELAST) && (last >= WM_MOUSEFIRST)) ||
+ ((first <= WM_NCMOUSELAST) && (last >= WM_NCMOUSEFIRST)) ) mask |= QS_MOUSE;
+ if ((first <= WM_TIMER) && (last >= WM_TIMER)) mask |= QS_TIMER;
+ if ((first <= WM_SYSTIMER) && (last >= WM_SYSTIMER)) mask |= QS_TIMER;
+ if ((first <= WM_PAINT) && (last >= WM_PAINT)) mask |= QS_PAINT;
+ }
+ else mask = QS_ALLINPUT;
- UserDerefObjectCo(Window);
- return FALSE;
+ return mask;
}
-BOOL ProcessMouseMessage(MSG* Msg, USHORT HitTest, UINT RemoveMsg)
+static VOID FASTCALL
+IntCallWndProc( PWND Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
- MOUSEHOOKSTRUCT MHook;
- EVENTMSG Event;
-
- Event.message = Msg->message;
- Event.time = Msg->time;
- Event.hwnd = Msg->hwnd;
- Event.paramL = Msg->pt.x;
- Event.paramH = Msg->pt.y;
- co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
-
-
- MHook.pt = Msg->pt;
- MHook.hwnd = Msg->hwnd;
- MHook.wHitTestCode = HitTest;
- MHook.dwExtraInfo = 0;
- if (co_HOOK_CallHooks( WH_MOUSE,
- RemoveMsg ? HC_ACTION : HC_NOREMOVE,
- Msg->message,
- (LPARAM)&MHook ))
- {
- if (ISITHOOKED(WH_CBT))
- {
- MHook.pt = Msg->pt;
- MHook.hwnd = Msg->hwnd;
- MHook.wHitTestCode = HitTest;
- MHook.dwExtraInfo = 0;
- co_HOOK_CallHooks( WH_CBT,
- HCBT_CLICKSKIPPED,
- Msg->message,
- (LPARAM)&MHook);
- }
- return FALSE;
- }
+ BOOL SameThread = FALSE;
+ CWPSTRUCT CWP;
+
+ if (Window->head.pti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread()))
+ SameThread = TRUE;
+
+ CWP.hwnd = hWnd;
+ CWP.message = Msg;
+ CWP.wParam = wParam;
+ CWP.lParam = lParam;
+ co_HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, SameThread, (LPARAM)&CWP );
+}
- return TRUE;
+static VOID FASTCALL
+IntCallWndProcRet ( PWND Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *uResult)
+{
+ BOOL SameThread = FALSE;
+ CWPRETSTRUCT CWPR;
+
+ if (Window->head.pti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread()))
+ SameThread = TRUE;
+
+ 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 );
}
-BOOL ProcessKeyboardMessage(MSG* Msg, UINT RemoveMsg)
+LRESULT FASTCALL
+IntDispatchMessage(PMSG pMsg)
{
- EVENTMSG Event;
+ LARGE_INTEGER TickCount;
+ LONG Time;
+ LRESULT retval = 0;
+ PTHREADINFO pti;
+ PWND Window = NULL;
+
+ if (pMsg->hwnd)
+ {
+ Window = UserGetWindowObject(pMsg->hwnd);
+ if (!Window) return 0;
+ }
+
+ pti = PsGetCurrentThreadWin32Thread();
- Event.message = Msg->message;
- Event.hwnd = Msg->hwnd;
- Event.time = Msg->time;
- Event.paramL = (Msg->wParam & 0xFF) | (HIWORD(Msg->lParam) << 8);
- Event.paramH = Msg->lParam & 0x7FFF;
- if (HIWORD(Msg->lParam) & 0x0100) Event.paramH |= 0x8000;
- co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
+ if ( Window->head.pti != pti)
+ {
+ EngSetLastError( ERROR_MESSAGE_SYNC_ONLY );
+ return 0;
+ }
- if (co_HOOK_CallHooks( WH_KEYBOARD,
- RemoveMsg ? HC_ACTION : HC_NOREMOVE,
- LOWORD(Msg->wParam),
- Msg->lParam))
+ if (((pMsg->message == WM_SYSTIMER) ||
+ (pMsg->message == WM_TIMER)) &&
+ (pMsg->lParam) )
{
- if (ISITHOOKED(WH_CBT))
+ if (pMsg->message == WM_TIMER)
{
- /* skip this message */
- co_HOOK_CallHooks( WH_CBT,
- HCBT_KEYSKIPPED,
- LOWORD(Msg->wParam),
- Msg->lParam );
+ if (ValidateTimerCallback(pti,pMsg->lParam))
+ {
+ KeQueryTickCount(&TickCount);
+ Time = MsqCalculateMessageTime(&TickCount);
+ retval = co_IntCallWindowProc((WNDPROC)pMsg->lParam,
+ TRUE,
+ pMsg->hwnd,
+ WM_TIMER,
+ pMsg->wParam,
+ (LPARAM)Time,
+ 0);
+ }
+ return retval;
}
- return FALSE;
+ else
+ {
+ PTIMER pTimer = FindSystemTimer(pMsg);
+ if (pTimer && pTimer->pfn)
+ {
+ KeQueryTickCount(&TickCount);
+ Time = MsqCalculateMessageTime(&TickCount);
+ pTimer->pfn(pMsg->hwnd, WM_SYSTIMER, (UINT)pMsg->wParam, Time);
+ }
+ return 0;
+ }
+ }
+ // Need a window!
+ if ( !Window ) return 0;
+
+ /* Since we are doing a callback on the same thread right away, there is
+ no need to copy the lparam to kernel mode and then back to usermode.
+ We just pretend it isn't a pointer */
+
+ retval = co_IntCallWindowProc( Window->lpfnWndProc,
+ !Window->Unicode,
+ pMsg->hwnd,
+ pMsg->message,
+ pMsg->wParam,
+ pMsg->lParam,
+ 0);
+
+ if (pMsg->message == WM_PAINT)
+ {
+ /* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
+ HRGN hrgn = IntSysCreateRectRgn( 0, 0, 0, 0 );
+ co_UserGetUpdateRgn( Window, hrgn, TRUE );
+ REGION_FreeRgnByHandle( hrgn );
}
- return TRUE;
+
+ return retval;
}
+
/*
* Internal version of PeekMessage() doing all the work
*/
BOOL FASTCALL
-co_IntPeekMessage( PUSER_MESSAGE Msg,
- PWINDOW_OBJECT Window,
+co_IntPeekMessage( PMSG Msg,
+ PWND Window,
UINT MsgFilterMin,
UINT MsgFilterMax,
- UINT RemoveMsg )
+ UINT RemoveMsg,
+ BOOL bGMSG )
{
- PTHREADINFO pti;
- LARGE_INTEGER LargeTickCount;
- PUSER_MESSAGE_QUEUE ThreadQueue;
- PUSER_MESSAGE Message;
- BOOL Present, RemoveMessages;
- USER_REFERENCE_ENTRY Ref;
- USHORT HitTest;
+ PTHREADINFO pti;
+ PCLIENTINFO pci;
+ LARGE_INTEGER LargeTickCount;
+ PUSER_MESSAGE_QUEUE ThreadQueue;
+ BOOL RemoveMessages;
+ UINT ProcessMask;
+ BOOL Hit = FALSE;
- /* The queues and order in which they are checked are documented in the MSDN
- article on GetMessage() */
+ pti = PsGetCurrentThreadWin32Thread();
+ ThreadQueue = pti->MessageQueue;
+ pci = pti->pClientInfo;
- pti = PsGetCurrentThreadWin32Thread();
- ThreadQueue = pti->MessageQueue;
-
- /* Inspect RemoveMsg flags */
- /* Note:
- The only flag we process is PM_REMOVE.
- Processing (High word) PM_QS_Xx Is needed. This and MsgFilterXxx can result
- with QS_Xx flags to be used to isolate which message check to test for.
- ATM, we look at all messages and the filters are sent to co_MsqFindMessage
- and there, it is cross checked.
- Example: Wine server/queue.c is_keyboard_msg, check_msg_filter and
- filter_contains_hw_range.
- */
- RemoveMessages = RemoveMsg & PM_REMOVE;
+ RemoveMessages = RemoveMsg & PM_REMOVE;
+ ProcessMask = HIWORD(RemoveMsg);
-/*
- If no filter is specified, messages are processed in the following order:
-
- * Sent messages
- * Posted messages
- * Input (hardware) messages and system internal events
- * Sent messages (again)
- * WM_PAINT messages
- * WM_TIMER messages
- */
-CheckMessages:
+ /* Hint, "If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage returns
+ all available messages (that is, no range filtering is performed)". */
+ if (!ProcessMask) ProcessMask = (QS_ALLPOSTMESSAGE|QS_ALLINPUT);
- HitTest = HTNOWHERE;
+ IdlePong();
- Present = FALSE;
+ do
+ {
+ KeQueryTickCount(&LargeTickCount);
+ ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
+ pti->pcti->tickLastMsgChecked = LargeTickCount.u.LowPart;
- KeQueryTickCount(&LargeTickCount);
- ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
+ /* Dispatch sent messages here. */
+ while ( co_MsqDispatchOneSentMessage(ThreadQueue) )
+ {
+ /* if some PM_QS* flags were specified, only handle sent messages from now on */
+ if (HIWORD(RemoveMsg) && !bGMSG) Hit = TRUE; // wine does this; ProcessMask = QS_SENDMESSAGE;
+ }
+ if (Hit) return FALSE;
- /* Dispatch sent messages here. */
- while (co_MsqDispatchOneSentMessage(ThreadQueue))
- ;
+ /* Clear changed bits so we can wait on them if we don't find a message */
+ if (ProcessMask & QS_POSTMESSAGE)
+ {
+ pti->pcti->fsChangeBits &= ~(QS_POSTMESSAGE | QS_HOTKEY | QS_TIMER);
+ if (MsgFilterMin == 0 && MsgFilterMax == 0) // wine hack does this; ~0U)
+ {
+ pti->pcti->fsChangeBits &= ~QS_ALLPOSTMESSAGE;
+ }
+ }
- /* Now look for a quit message. */
+ if (ProcessMask & QS_INPUT)
+ {
+ pti->pcti->fsChangeBits &= ~QS_INPUT;
+ }
- 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)
- {
- ThreadQueue->QuitPosted = FALSE;
- }
- goto MsgExit;
- }
-
- /* Now check for normal messages. */
- Present = co_MsqFindMessage( ThreadQueue,
- FALSE,
- RemoveMessages,
- Window,
- MsgFilterMin,
- MsgFilterMax,
- &Message );
- if (Present)
- {
- RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
- if (RemoveMessages)
- {
- MsqDestroyMessage(Message);
- }
- goto MessageFound;
- }
-
- /* Check for hardware events. */
- Present = co_MsqFindMessage( ThreadQueue,
- TRUE,
- RemoveMessages,
- Window,
- MsgFilterMin,
- MsgFilterMax,
- &Message );
- if (Present)
- {
- RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
- if (RemoveMessages)
- {
- MsqDestroyMessage(Message);
- }
- goto MessageFound;
- }
-
- /* Check for sent messages again. */
- while (co_MsqDispatchOneSentMessage(ThreadQueue))
- ;
-
- /* Check for paint messages. */
- if ( IntGetPaintMessage( Window,
+ /* Now check for normal messages. */
+ if ((ProcessMask & QS_POSTMESSAGE) &&
+ MsqPeekMessage( ThreadQueue,
+ RemoveMessages,
+ Window,
MsgFilterMin,
MsgFilterMax,
- pti,
- &Msg->Msg,
- RemoveMessages))
- {
- Msg->FreeLParam = FALSE;
- goto MsgExit;
- }
-
- if (PostTimerMessages(Window))
- goto CheckMessages;
-
- if(Present)
- {
-MessageFound:
-
- if(RemoveMessages)
- {
- PWINDOW_OBJECT MsgWindow = NULL;
-
- /* Mouse message process */
-
- if( Msg->Msg.hwnd &&
- ( MsgWindow = UserGetWindowObject(Msg->Msg.hwnd) ) &&
- Msg->Msg.message >= WM_MOUSEFIRST &&
- Msg->Msg.message <= WM_MOUSELAST )
- {
- USHORT HitTest;
-
- UserRefObjectCo(MsgWindow, &Ref);
-
- if ( co_IntTranslateMouseMessage( ThreadQueue,
- &Msg->Msg,
- &HitTest,
- TRUE))
- /* FIXME - check message filter again, if the message doesn't match anymore,
- search again */
- {
- UserDerefObjectCo(MsgWindow);
- /* eat the message, search again */
- goto CheckMessages;
- }
+ ProcessMask,
+ Msg ))
+ {
+ return TRUE;
+ }
- if(ThreadQueue->CaptureWindow == NULL)
+ /* 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->hwnd = NULL;
+ Msg->message = WM_QUIT;
+ Msg->wParam = ThreadQueue->QuitExitCode;
+ Msg->lParam = 0;
+ if (RemoveMessages)
{
- 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) )
- {
- UserDerefObjectCo(MsgWindow);
- /* eat the message, search again */
- goto CheckMessages;
- }
+ ThreadQueue->QuitPosted = FALSE;
+ ClearMsgBitsMask(ThreadQueue, QS_POSTMESSAGE);
+ pti->pcti->fsWakeBits &= ~QS_ALLPOSTMESSAGE;
+ pti->pcti->fsChangeBits &= ~QS_ALLPOSTMESSAGE;
}
+ return TRUE;
+ }
- UserDerefObjectCo(MsgWindow);
- }
- else
- {
- co_IntSendHitTestMessages(ThreadQueue, &Msg->Msg);
- }
-
-// if(MsgWindow)
-// {
-// UserDereferenceObject(MsgWindow);
-// }
-
- goto MsgExit;
- }
-
- 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;
- }
-
-MsgExit:
- if ( ISITHOOKED(WH_MOUSE) && IS_MOUSE_MESSAGE(Msg->Msg.message))
- {
- if(!ProcessMouseMessage(&Msg->Msg, HitTest, RemoveMsg))
- {
- return FALSE;
- }
- }
-
- if ( ISITHOOKED(WH_KEYBOARD) && IS_KBD_MESSAGE(Msg->Msg.message))
- {
- if(!ProcessKeyboardMessage(&Msg->Msg, RemoveMsg))
- {
- return FALSE;
- }
- }
- // The WH_GETMESSAGE hook enables an application to monitor messages about to
- // be returned by the GetMessage or PeekMessage function.
- if (ISITHOOKED(WH_GETMESSAGE))
- {
- //DPRINT1("Peek WH_GETMESSAGE -> %x\n",&Msg);
- co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)&Msg->Msg);
- }
- return TRUE;
- }
-
- return Present;
-}
-
-static NTSTATUS FASTCALL
-CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg, PMSGMEMORY MsgMemoryEntry)
-{
- NTSTATUS Status;
-
- PVOID KernelMem;
- UINT Size;
-
- *KernelModeMsg = *UserModeMsg;
-
- /* See if this message type is present in the table */
- if (NULL == MsgMemoryEntry)
- {
- /* Not present, no copying needed */
- return STATUS_SUCCESS;
- }
-
- /* Determine required size */
- Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
-
- if (0 != Size)
- {
- /* Allocate kernel mem */
- KernelMem = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
- if (NULL == KernelMem)
- {
- DPRINT1("Not enough memory to copy message to kernel mem\n");
- return STATUS_NO_MEMORY;
- }
- KernelModeMsg->lParam = (LPARAM) KernelMem;
-
- /* Copy data if required */
- if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_READ))
- {
- Status = MmCopyFromCaller(KernelMem, (PVOID) UserModeMsg->lParam, Size);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("Failed to copy message to kernel: invalid usermode buffer\n");
- ExFreePoolWithTag(KernelMem, TAG_MSG);
- return Status;
- }
- }
- else
- {
- /* Make sure we don't pass any secrets to usermode */
- RtlZeroMemory(KernelMem, Size);
- }
- }
- else
- {
- KernelModeMsg->lParam = 0;
- }
-
- return STATUS_SUCCESS;
-}
+ /* Check for hardware events. */
+ if ((ProcessMask & QS_MOUSE) &&
+ co_MsqPeekMouseMove( ThreadQueue,
+ RemoveMessages,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ Msg ))
+ {
+ return TRUE;
+ }
-static NTSTATUS FASTCALL
-CopyMsgToUserMem(MSG *UserModeMsg, MSG *KernelModeMsg)
-{
- NTSTATUS Status;
- PMSGMEMORY MsgMemoryEntry;
- UINT Size;
+ if ((ProcessMask & QS_INPUT) &&
+ co_MsqPeekHardwareMessage( ThreadQueue,
+ RemoveMessages,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ ProcessMask,
+ Msg))
+ {
+ return TRUE;
+ }
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(UserModeMsg->message);
- if (NULL == MsgMemoryEntry)
- {
- /* Not present, no copying needed */
- return STATUS_SUCCESS;
- }
+ /* Check for sent messages again. */
+ while ( co_MsqDispatchOneSentMessage(ThreadQueue) )
+ {
+ if (HIWORD(RemoveMsg) && !bGMSG) Hit = TRUE;
+ }
+ if (Hit) return FALSE;
- /* Determine required size */
- Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
+ /* Check for paint messages. */
+ if ((ProcessMask & QS_PAINT) &&
+ pti->cPaintsReady &&
+ IntGetPaintMessage( Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ pti,
+ Msg,
+ RemoveMessages))
+ {
+ return TRUE;
+ }
- if (0 != Size)
- {
- /* Copy data if required */
- if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_WRITE))
- {
- 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;
- }
- }
+ /* This is correct, check for the current threads timers waiting to be
+ posted to this threads message queue. If any we loop again.
+ */
+ if ((ProcessMask & QS_TIMER) &&
+ PostTimerMessages(Window))
+ {
+ continue;
+ }
- ExFreePool((PVOID) KernelModeMsg->lParam);
- }
+ return FALSE;
+ }
+ while (TRUE);
- return STATUS_SUCCESS;
+ return TRUE;
}
static BOOL FASTCALL
-co_IntWaitMessage( PWINDOW_OBJECT Window,
+co_IntWaitMessage( PWND Window,
UINT MsgFilterMin,
UINT MsgFilterMax )
{
- PTHREADINFO pti;
- PUSER_MESSAGE_QUEUE ThreadQueue;
- NTSTATUS Status = STATUS_SUCCESS;
- USER_MESSAGE Msg;
+ PTHREADINFO pti;
+ PUSER_MESSAGE_QUEUE ThreadQueue;
+ NTSTATUS Status = STATUS_SUCCESS;
+ MSG Msg;
- pti = PsGetCurrentThreadWin32Thread();
- ThreadQueue = pti->MessageQueue;
+ pti = PsGetCurrentThreadWin32Thread();
+ ThreadQueue = pti->MessageQueue;
- do
- {
- if ( co_IntPeekMessage( &Msg,
- Window,
- MsgFilterMin,
- MsgFilterMax,
- PM_NOREMOVE))
- {
- return TRUE;
- }
- /* Nothing found. Wait for new messages. */
- Status = co_MsqWaitForNewMessages( ThreadQueue,
- Window,
- MsgFilterMin,
- MsgFilterMax);
- }
- while ( (STATUS_WAIT_0 <= Status && Status <= STATUS_WAIT_63) ||
- STATUS_TIMEOUT == Status );
+ do
+ {
+ if ( co_IntPeekMessage( &Msg, // Dont reenter!
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ MAKELONG( PM_NOREMOVE, GetWakeMask( MsgFilterMin, MsgFilterMax)),
+ TRUE ) ) // act like GetMessage.
+ {
+ return TRUE;
+ }
- if (!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- DPRINT1("Exit co_IntWaitMessage on error!\n");
- }
+ /* Nothing found. Wait for new messages. */
+ Status = co_MsqWaitForNewMessages( ThreadQueue,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax);
+ }
+ while ( (STATUS_WAIT_0 <= Status && Status <= STATUS_WAIT_63) ||
+ STATUS_TIMEOUT == Status );
+
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ DPRINT1("Exit co_IntWaitMessage on error!\n");
+ }
- return FALSE;
+ return FALSE;
}
BOOL FASTCALL
UINT RemoveMsg,
BOOL bGMSG )
{
- BOOL Present;
- PWINDOW_OBJECT Window;
- USER_MESSAGE Msg;
+ PWND Window;
+ PTHREADINFO pti;
+ BOOL Present = FALSE;
- if ( hWnd == HWND_TOPMOST ||
- hWnd == HWND_BROADCAST )
- hWnd = HWND_BOTTOM;
+ if ( hWnd == HWND_TOPMOST || hWnd == HWND_BROADCAST )
+ hWnd = HWND_BOTTOM;
- /* Validate input */
- if (hWnd && hWnd != HWND_BOTTOM)
- {
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- if (bGMSG)
- return -1;
- else
- return FALSE;
- }
- }
- else
- {
- Window = (PWINDOW_OBJECT)hWnd;
- }
+ /* Validate input */
+ if (hWnd && hWnd != HWND_BOTTOM)
+ {
+ if (!(Window = UserGetWindowObject(hWnd)))
+ {
+ if (bGMSG)
+ return -1;
+ else
+ return FALSE;
+ }
+ }
+ else
+ {
+ Window = (PWND)hWnd;
+ }
- if (MsgFilterMax < MsgFilterMin)
- {
- MsgFilterMin = 0;
- MsgFilterMax = 0;
- }
+ if (MsgFilterMax < MsgFilterMin)
+ {
+ MsgFilterMin = 0;
+ MsgFilterMax = 0;
+ }
- do
- {
- Present = co_IntPeekMessage( &Msg,
- Window,
- MsgFilterMin,
- MsgFilterMax,
- RemoveMsg );
- if (Present)
- {
- RtlCopyMemory( pMsg, &Msg.Msg, sizeof(MSG));
+ if (bGMSG)
+ {
+ RemoveMsg |= ((GetWakeMask( MsgFilterMin, MsgFilterMax ))<< 16);
+ }
- if (bGMSG)
- return (WM_QUIT != pMsg->message);
- else
- return TRUE;
- }
+ pti = PsGetCurrentThreadWin32Thread();
+ pti->pClientInfo->cSpins++; // Bump up the spin count.
- if ( bGMSG && !co_IntWaitMessage(Window, MsgFilterMin, MsgFilterMax) )
- {
- return -1;
- }
- else
- {
- if (!(RemoveMsg & PM_NOYIELD))
- {
- // Yield this thread!
- UserLeave();
- ZwYieldExecution();
- UserEnterExclusive();
- // Fall through to fail.
- }
- }
- }
- while( bGMSG && !Present );
+ do
+ {
+ Present = co_IntPeekMessage( pMsg,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ RemoveMsg,
+ bGMSG );
+ if (Present)
+ {
+ /* GetMessage or PostMessage must never get messages that contain pointers */
+ ASSERT(FindMsgMemory(pMsg->message) == NULL);
+
+ if (pMsg->message != WM_PAINT && pMsg->message != WM_QUIT)
+ {
+ pti->timeLast = pMsg->time;
+ pti->ptLast = pMsg->pt;
+ }
- return FALSE;
+ // The WH_GETMESSAGE hook enables an application to monitor messages about to
+ // be returned by the GetMessage or PeekMessage function.
+
+ co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)pMsg);
+
+ if ( bGMSG )
+ {
+ Present = (WM_QUIT != pMsg->message);
+ break;
+ }
+ }
+
+ if ( bGMSG )
+ {
+ if ( !co_IntWaitMessage(Window, MsgFilterMin, MsgFilterMax) )
+ {
+ Present = -1;
+ break;
+ }
+ }
+ else
+ {
+ if (!(RemoveMsg & PM_NOYIELD))
+ {
+ IdlePing();
+ // Yield this thread!
+ UserLeave();
+ ZwYieldExecution();
+ UserEnterExclusive();
+ // Fall through to exit.
+ IdlePong();
+ }
+ break;
+ }
+ }
+ while( bGMSG && !Present );
+
+ // Been spinning, time to swap vinyl...
+ if (pti->pClientInfo->cSpins >= 100)
+ {
+ // Clear the spin cycle to fix the mix.
+ pti->pClientInfo->cSpins = 0;
+ //if (!(pti->TIF_flags & TIF_SPINNING)) FIXME need to swap vinyl..
+ }
+ return Present;
}
BOOL FASTCALL
WPARAM wParam,
LPARAM lParam )
{
- MSG Message;
- PETHREAD peThread;
- PTHREADINFO pThread;
- LARGE_INTEGER LargeTickCount;
- NTSTATUS Status;
-
- DPRINT1("UserPostThreadMessage wParam 0x%x lParam 0x%x\n", wParam,lParam);
+ MSG Message;
+ PETHREAD peThread;
+ PTHREADINFO pThread;
+ LARGE_INTEGER LargeTickCount;
+ NTSTATUS Status;
- if (FindMsgMemory(Msg) != 0)
- {
- SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
- return FALSE;
- }
+ if (is_pointer_message(Msg))
+ {
+ EngSetLastError(ERROR_MESSAGE_SYNC_ONLY );
+ return FALSE;
+ }
- Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
+ Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
- if( Status == STATUS_SUCCESS )
- {
- pThread = (PTHREADINFO)peThread->Tcb.Win32Thread;
- if( !pThread ||
- !pThread->MessageQueue ||
- (pThread->TIF_flags & TIF_INCLEANUP))
- {
- ObDereferenceObject( peThread );
- return FALSE;
- }
+ if( Status == STATUS_SUCCESS )
+ {
+ pThread = (PTHREADINFO)peThread->Tcb.Win32Thread;
+ if( !pThread ||
+ !pThread->MessageQueue ||
+ (pThread->TIF_flags & TIF_INCLEANUP))
+ {
+ ObDereferenceObject( peThread );
+ return FALSE;
+ }
- Message.hwnd = NULL;
- Message.message = Msg;
- Message.wParam = wParam;
- Message.lParam = lParam;
- Message.pt = gpsi->ptCursor;
-
- KeQueryTickCount(&LargeTickCount);
- pThread->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
- MsqPostMessage(pThread->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
- ObDereferenceObject( peThread );
- return TRUE;
- }
- else
- {
- SetLastNtError( Status );
- }
- return FALSE;
+ Message.hwnd = NULL;
+ Message.message = Msg;
+ Message.wParam = wParam;
+ Message.lParam = lParam;
+ Message.pt = gpsi->ptCursor;
+
+ KeQueryTickCount(&LargeTickCount);
+ Message.time = MsqCalculateMessageTime(&LargeTickCount);
+ MsqPostMessage(pThread->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
+ ObDereferenceObject( peThread );
+ return TRUE;
+ }
+ else
+ {
+ SetLastNtError( Status );
+ }
+ return FALSE;
}
BOOL FASTCALL
WPARAM wParam,
LPARAM lParam )
{
- PTHREADINFO pti;
- MSG Message;
- LARGE_INTEGER LargeTickCount;
+ PTHREADINFO pti;
+ MSG Message, KernelModeMsg;
+ LARGE_INTEGER LargeTickCount;
+ PMSGMEMORY MsgMemoryEntry;
+
+ Message.hwnd = Wnd;
+ Message.message = Msg;
+ Message.wParam = wParam;
+ Message.lParam = lParam;
+ Message.pt = gpsi->ptCursor;
+ KeQueryTickCount(&LargeTickCount);
+ Message.time = MsqCalculateMessageTime(&LargeTickCount);
+
+ MsgMemoryEntry = FindMsgMemory(Message.message);
+
+ if( Msg >= WM_DDE_FIRST && Msg <= WM_DDE_LAST )
+ {
+ NTSTATUS Status;
- if (FindMsgMemory(Msg) != 0)
- {
- SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
- return FALSE;
- }
+ Status = CopyMsgToKernelMem(&KernelModeMsg, &Message, MsgMemoryEntry);
+ if (! NT_SUCCESS(Status))
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ co_IntSendMessageNoWait(KernelModeMsg.hwnd,
+ KernelModeMsg.message,
+ KernelModeMsg.wParam,
+ KernelModeMsg.lParam);
- if (!Wnd)
- return UserPostThreadMessage( PtrToInt(PsGetCurrentThreadId()),
- Msg,
- wParam,
- lParam);
+ if (MsgMemoryEntry && KernelModeMsg.lParam)
+ ExFreePool((PVOID) KernelModeMsg.lParam);
- if (Wnd == HWND_BROADCAST)
- {
- HWND *List;
- PWINDOW_OBJECT DesktopWindow;
- ULONG i;
+ return TRUE;
+ }
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
- List = IntWinListChildren(DesktopWindow);
+ if (is_pointer_message(Message.message))
+ {
+ EngSetLastError(ERROR_MESSAGE_SYNC_ONLY );
+ return FALSE;
+ }
- if (List != NULL)
- {
- for (i = 0; List[i]; i++)
- UserPostMessage(List[i], Msg, wParam, lParam);
- ExFreePool(List);
- }
- }
- else
- {
- PWINDOW_OBJECT Window;
+ if (!Wnd)
+ {
+ return UserPostThreadMessage( PtrToInt(PsGetCurrentThreadId()),
+ Msg,
+ wParam,
+ lParam);
+ }
+ if (Wnd == HWND_BROADCAST)
+ {
+ HWND *List;
+ PWND DesktopWindow;
+ ULONG i;
- Window = UserGetWindowObject(Wnd);
- if ( !Window || !Window->Wnd )
- {
- return FALSE;
- }
+ DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ List = IntWinListChildren(DesktopWindow);
- pti = Window->Wnd->head.pti;
- if ( pti->TIF_flags & TIF_INCLEANUP )
- {
- DPRINT1("Attempted to post message to window 0x%x when the thread is in cleanup!\n", Wnd);
- return FALSE;
- }
+ if (List != NULL)
+ {
+ UserPostMessage(DesktopWindow->head.h, Msg, wParam, lParam);
+ for (i = 0; List[i]; i++)
+ {
+ UserPostMessage(List[i], Msg, wParam, lParam);
+ }
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
+ }
+ }
+ else
+ {
+ PWND Window;
- if ( Window->state & WINDOWSTATUS_DESTROYING )
- {
- DPRINT1("Attempted to post message to window 0x%x that is being destroyed!\n", Wnd);
- /* FIXME - last error code? */
- return FALSE;
- }
+ Window = UserGetWindowObject(Wnd);
+ if ( !Window )
+ {
+ return FALSE;
+ }
- if (WM_QUIT == Msg)
- {
- MsqPostQuitMessage(Window->pti->MessageQueue, wParam);
- }
- else
- {
- Message.hwnd = Wnd;
- Message.message = Msg;
- Message.wParam = wParam;
- Message.lParam = lParam;
- Message.pt = gpsi->ptCursor;
- KeQueryTickCount(&LargeTickCount);
- pti->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
- MsqPostMessage(Window->pti->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
- }
- }
- return TRUE;
+ pti = Window->head.pti;
+ if ( pti->TIF_flags & TIF_INCLEANUP )
+ {
+ DPRINT1("Attempted to post message to window 0x%x when the thread is in cleanup!\n", Wnd);
+ return FALSE;
+ }
+
+ if ( Window->state & WNDS_DESTROYED )
+ {
+ DPRINT1("Attempted to post message to window 0x%x that is being destroyed!\n", Wnd);
+ /* FIXME - last error code? */
+ return FALSE;
+ }
+
+ if (WM_QUIT == Msg)
+ {
+ MsqPostQuitMessage(Window->head.pti->MessageQueue, wParam);
+ }
+ else
+ {
+ MsqPostMessage(Window->head.pti->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
+ }
+ }
+ return TRUE;
}
WPARAM wParam,
LPARAM lParam )
{
- ULONG_PTR Result = 0;
- if(co_IntSendMessageTimeout(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result))
- {
- return (LRESULT)Result;
- }
- return 0;
+ ULONG_PTR Result = 0;
+ if(co_IntSendMessageTimeout(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result))
+ {
+ return (LRESULT)Result;
+ }
+ return 0;
}
-static
-LRESULT FASTCALL
+static LRESULT FASTCALL
co_IntSendMessageTimeoutSingle( HWND hWnd,
UINT Msg,
WPARAM wParam,
UINT uTimeout,
ULONG_PTR *uResult )
{
- ULONG_PTR Result;
- NTSTATUS Status;
- PWINDOW_OBJECT Window = NULL;
- PMSGMEMORY MsgMemoryEntry;
- INT lParamBufferSize;
- LPARAM lParamPacked;
- PTHREADINFO Win32Thread;
- DECLARE_RETURN(LRESULT);
- USER_REFERENCE_ENTRY Ref;
-
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- RETURN( FALSE);
- }
+ NTSTATUS Status;
+ PWND Window = NULL;
+ PMSGMEMORY MsgMemoryEntry;
+ INT lParamBufferSize;
+ LPARAM lParamPacked;
+ PTHREADINFO Win32Thread;
+ ULONG_PTR Result = 0;
+ DECLARE_RETURN(LRESULT);
+ USER_REFERENCE_ENTRY Ref;
+
+ if (!(Window = UserGetWindowObject(hWnd)))
+ {
+ RETURN( FALSE);
+ }
- UserRefObjectCo(Window, &Ref);
+ UserRefObjectCo(Window, &Ref);
- Win32Thread = PsGetCurrentThreadWin32Thread();
+ Win32Thread = PsGetCurrentThreadWin32Thread();
- IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
+ IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
- if ( NULL != Win32Thread &&
- Window->pti->MessageQueue == Win32Thread->MessageQueue)
- {
- if (Win32Thread->TIF_flags & TIF_INCLEANUP)
- {
- /* Never send messages to exiting threads */
- RETURN( FALSE);
- }
+ if ( NULL != Win32Thread &&
+ Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
+ {
+ if (Win32Thread->TIF_flags & TIF_INCLEANUP)
+ {
+ /* Never send messages to exiting threads */
+ RETURN( FALSE);
+ }
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(Msg);
- if (NULL == MsgMemoryEntry)
- {
- lParamBufferSize = -1;
- }
- else
- {
- lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
- }
+ /* See if this message type is present in the table */
+ MsgMemoryEntry = FindMsgMemory(Msg);
+ if (NULL == MsgMemoryEntry)
+ {
+ lParamBufferSize = -1;
+ }
+ else
+ {
+ lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
+ }
- if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, FALSE)))
- {
- DPRINT1("Failed to pack message parameters\n");
- RETURN( FALSE);
- }
+ if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, FALSE)))
+ {
+ DPRINT1("Failed to pack message parameters\n");
+ RETURN( FALSE);
+ }
- Result = (ULONG_PTR)co_IntCallWindowProc( Window->Wnd->lpfnWndProc,
- !Window->Wnd->Unicode,
- hWnd,
- Msg,
- wParam,
- lParamPacked,
- lParamBufferSize );
- if(uResult)
- {
- *uResult = Result;
- }
+ ObReferenceObject(Win32Thread->pEThread);
+ Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
+ !Window->Unicode,
+ hWnd,
+ Msg,
+ wParam,
+ lParamPacked,
+ lParamBufferSize );
+ if(uResult)
+ {
+ *uResult = Result;
+ }
- IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
+ ObDereferenceObject(Win32Thread->pEThread);
- if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
- {
- DPRINT1("Failed to unpack message parameters\n");
- RETURN( TRUE);
- }
+ IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
- RETURN( TRUE);
- }
+ if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
+ {
+ DPRINT1("Failed to unpack message parameters\n");
+ RETURN( TRUE);
+ }
- if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->pti->MessageQueue))
- {
- /* FIXME - Set a LastError? */
- RETURN( FALSE);
- }
+ RETURN( TRUE);
+ }
- if (Window->state & WINDOWSTATUS_DESTROYING)
- {
- /* FIXME - last error? */
- DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
- RETURN( FALSE);
- }
+ if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->head.pti->MessageQueue))
+ {
+ /* FIXME - Set a LastError? */
+ RETURN( FALSE);
+ }
- do
- {
- Status = co_MsqSendMessage( Window->pti->MessageQueue,
- hWnd,
- Msg,
- wParam,
- lParam,
- uTimeout,
- (uFlags & SMTO_BLOCK),
- MSQ_NORMAL,
- uResult );
- }
- while ((STATUS_TIMEOUT == Status) &&
- (uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
- !MsqIsHung(Window->pti->MessageQueue));
+ if (Window->state & WNDS_DESTROYED)
+ {
+ /* FIXME - last error? */
+ DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
+ RETURN( FALSE);
+ }
+
+ do
+ {
+ Status = co_MsqSendMessage( Window->head.pti->MessageQueue,
+ hWnd,
+ Msg,
+ wParam,
+ lParam,
+ uTimeout,
+ (uFlags & SMTO_BLOCK),
+ MSQ_NORMAL,
+ uResult );
+ }
+ while ((STATUS_TIMEOUT == Status) &&
+ (uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
+ !MsqIsHung(Window->head.pti->MessageQueue));
- IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
+ IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
- if (STATUS_TIMEOUT == Status)
- {
-/*
- 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);
- }
- else if (! NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( FALSE);
- }
+ if (STATUS_TIMEOUT == Status)
+ {
+ /*
+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.
+*/
+ EngSetLastError(ERROR_TIMEOUT);
+ RETURN( FALSE);
+ }
+ else if (! NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ RETURN( FALSE);
+ }
- RETURN( TRUE);
+ RETURN( TRUE);
CLEANUP:
- if (Window) UserDerefObjectCo(Window);
- END_CLEANUP;
+ if (Window) UserDerefObjectCo(Window);
+ END_CLEANUP;
}
LRESULT FASTCALL
UINT uTimeout,
ULONG_PTR *uResult )
{
- PWINDOW_OBJECT DesktopWindow;
- HWND *Children;
- HWND *Child;
+ PWND DesktopWindow;
+ HWND *Children;
+ HWND *Child;
- if (HWND_BROADCAST != hWnd)
- {
- return co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, uFlags, uTimeout, uResult);
- }
+ if (HWND_BROADCAST != hWnd)
+ {
+ return co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, uFlags, uTimeout, uResult);
+ }
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
- if (NULL == DesktopWindow)
- {
- SetLastWin32Error(ERROR_INTERNAL_ERROR);
- return 0;
- }
+ DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ if (NULL == DesktopWindow)
+ {
+ EngSetLastError(ERROR_INTERNAL_ERROR);
+ return 0;
+ }
- Children = IntWinListChildren(DesktopWindow);
- if (NULL == Children)
- {
- return 0;
- }
+ /* Send message to the desktop window too! */
+ co_IntSendMessageTimeoutSingle(DesktopWindow->head.h, Msg, wParam, lParam, uFlags, uTimeout, uResult);
- for (Child = Children; NULL != *Child; Child++)
- {
- co_IntSendMessageTimeoutSingle(*Child, Msg, wParam, lParam, uFlags, uTimeout, uResult);
- }
+ Children = IntWinListChildren(DesktopWindow);
+ if (NULL == Children)
+ {
+ return 0;
+ }
+
+ for (Child = Children; NULL != *Child; Child++)
+ {
+ co_IntSendMessageTimeoutSingle(*Child, Msg, wParam, lParam, uFlags, uTimeout, uResult);
+ }
- ExFreePool(Children);
+ ExFreePool(Children);
- return (LRESULT) TRUE;
+ return (LRESULT) TRUE;
}
-LRESULT FASTCALL co_IntSendMessageNoWait(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
+LRESULT FASTCALL
+co_IntSendMessageNoWait(HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam)
{
- ULONG_PTR Result = 0;
- co_IntSendMessageWithCallBack(hWnd,
- Msg,
- wParam,
- lParam,
- NULL,
- 0,
- &Result);
- return Result;
+ ULONG_PTR Result = 0;
+ co_IntSendMessageWithCallBack(hWnd,
+ Msg,
+ wParam,
+ lParam,
+ NULL,
+ 0,
+ &Result);
+ return Result;
}
LRESULT FASTCALL
co_IntSendMessageWithCallBack( HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam,
- SENDASYNCPROC CompletionCallback,
- ULONG_PTR CompletionCallbackContext,
- ULONG_PTR *uResult)
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ SENDASYNCPROC CompletionCallback,
+ ULONG_PTR CompletionCallbackContext,
+ ULONG_PTR *uResult)
{
- ULONG_PTR Result;
- PWINDOW_OBJECT Window = NULL;
- PMSGMEMORY MsgMemoryEntry;
- INT lParamBufferSize;
- LPARAM lParamPacked;
- PTHREADINFO Win32Thread;
- DECLARE_RETURN(LRESULT);
- USER_REFERENCE_ENTRY Ref;
- PUSER_SENT_MESSAGE Message;
-
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- RETURN(FALSE);
- }
+ ULONG_PTR Result;
+ PWND Window = NULL;
+ PMSGMEMORY MsgMemoryEntry;
+ INT lParamBufferSize;
+ LPARAM lParamPacked;
+ PTHREADINFO Win32Thread;
+ DECLARE_RETURN(LRESULT);
+ USER_REFERENCE_ENTRY Ref;
+ PUSER_SENT_MESSAGE Message;
+
+ if (!(Window = UserGetWindowObject(hWnd)))
+ {
+ RETURN(FALSE);
+ }
- UserRefObjectCo(Window, &Ref);
+ UserRefObjectCo(Window, &Ref);
- if (Window->state & WINDOWSTATUS_DESTROYING)
- {
- /* FIXME - last error? */
- DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
- RETURN(FALSE);
- }
+ if (Window->state & WNDS_DESTROYED)
+ {
+ /* FIXME - last error? */
+ DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
+ RETURN(FALSE);
+ }
- Win32Thread = PsGetCurrentThreadWin32Thread();
+ Win32Thread = PsGetCurrentThreadWin32Thread();
- IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
+ IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
- if (Win32Thread == NULL)
- {
- ASSERT(FALSE);
- RETURN(FALSE);
- }
+ if (Win32Thread == NULL)
+ {
+ ASSERT(FALSE);
+ RETURN(FALSE);
+ }
- if (Win32Thread->TIF_flags & TIF_INCLEANUP)
- {
- /* Never send messages to exiting threads */
- RETURN(FALSE);
- }
+ if (Win32Thread->TIF_flags & TIF_INCLEANUP)
+ {
+ /* Never send messages to exiting threads */
+ RETURN(FALSE);
+ }
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(Msg);
- if (NULL == MsgMemoryEntry)
- {
- lParamBufferSize = -1;
- }
- else
- {
- lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
- }
+ /* See if this message type is present in the table */
+ MsgMemoryEntry = FindMsgMemory(Msg);
+ if (NULL == MsgMemoryEntry)
+ {
+ lParamBufferSize = -1;
+ }
+ else
+ {
+ lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
+ }
- if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->pti->MessageQueue != Win32Thread->MessageQueue)))
- {
- DPRINT1("Failed to pack message parameters\n");
- RETURN( FALSE);
- }
+ if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->head.pti->MessageQueue != Win32Thread->MessageQueue)))
+ {
+ DPRINT1("Failed to pack message parameters\n");
+ RETURN( FALSE);
+ }
- /* If this is not a callback and it can be sent now, then send it. */
- if ((Window->pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
- {
+ /* If this is not a callback and it can be sent now, then send it. */
+ if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
+ {
+ ObReferenceObject(Win32Thread->pEThread);
+ Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
+ !Window->Unicode,
+ hWnd,
+ Msg,
+ wParam,
+ lParamPacked,
+ lParamBufferSize );
+ if(uResult)
+ {
+ *uResult = Result;
+ }
+ ObDereferenceObject(Win32Thread->pEThread);
+ }
- Result = (ULONG_PTR)co_IntCallWindowProc( Window->Wnd->lpfnWndProc,
- !Window->Wnd->Unicode,
- hWnd,
- Msg,
- wParam,
- lParamPacked,
- lParamBufferSize );
- if(uResult)
- {
- *uResult = Result;
- }
- }
+ IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
- IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
+ if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
+ {
+ if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
+ {
+ DPRINT1("Failed to unpack message parameters\n");
+ }
+ RETURN(TRUE);
+ }
- if ((Window->pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
- {
- if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
- {
- DPRINT1("Failed to unpack message parameters\n");
- }
- RETURN(TRUE);
- }
+ if(!(Message = ExAllocatePoolWithTag(NonPagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG)))
+ {
+ DPRINT1("MsqSendMessage(): Not enough memory to allocate a message");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
- if(!(Message = ExAllocatePoolWithTag(NonPagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG)))
- {
- DPRINT1("MsqSendMessage(): Not enough memory to allocate a message");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ Message->Msg.hwnd = hWnd;
+ Message->Msg.message = Msg;
+ Message->Msg.wParam = wParam;
+ Message->Msg.lParam = lParamPacked;
+ Message->CompletionEvent = NULL;
+ Message->Result = 0;
+ Message->lResult = 0;
+ Message->QS_Flags = 0;
+ Message->SenderQueue = NULL; // mjmartin, you are right! This is null.
+ Message->CallBackSenderQueue = Win32Thread->MessageQueue;
- Message->Msg.hwnd = hWnd;
- Message->Msg.message = Msg;
- Message->Msg.wParam = wParam;
- Message->Msg.lParam = lParamPacked;
- Message->CompletionEvent = NULL;
- Message->Result = 0;
- Message->SenderQueue = NULL; //Win32Thread->MessageQueue;
+ IntReferenceMessageQueue(Window->head.pti->MessageQueue);
+ Message->CompletionCallback = CompletionCallback;
+ Message->CompletionCallbackContext = CompletionCallbackContext;
+ Message->HookMessage = MSQ_NORMAL | MSQ_SENTNOWAIT;
+ Message->HasPackedLParam = (lParamBufferSize > 0);
- IntReferenceMessageQueue(Window->pti->MessageQueue);
- Message->CompletionCallback = CompletionCallback;
- Message->CompletionCallbackContext = CompletionCallbackContext;
- Message->HookMessage = MSQ_NORMAL | MSQ_SENTNOWAIT;
- Message->HasPackedLParam = (lParamBufferSize > 0);
+ Message->QS_Flags = QS_SENDMESSAGE;
+ MsqWakeQueue(Window->head.pti->MessageQueue, QS_SENDMESSAGE, FALSE);
- InsertTailList(&Window->pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
- IntDereferenceMessageQueue(Window->pti->MessageQueue);
+ InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
+ IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
- RETURN(TRUE);
+ RETURN(TRUE);
CLEANUP:
- if (Window) UserDerefObjectCo(Window);
- END_CLEANUP;
+ if (Window) UserDerefObjectCo(Window);
+ END_CLEANUP;
}
/* 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! */
+another thread, otherwise it sends the message. It does not support broadcast
+messages! */
LRESULT FASTCALL
co_IntPostOrSendMessage( HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam )
{
- ULONG_PTR Result;
- PTHREADINFO pti;
- PWINDOW_OBJECT Window;
+ ULONG_PTR Result;
+ PTHREADINFO pti;
+ PWND Window;
- if ( hWnd == HWND_BROADCAST )
- {
- return 0;
- }
+ if ( hWnd == HWND_BROADCAST )
+ {
+ return 0;
+ }
- if(!(Window = UserGetWindowObject(hWnd)))
- {
- return 0;
- }
+ if(!(Window = UserGetWindowObject(hWnd)))
+ {
+ return 0;
+ }
- pti = PsGetCurrentThreadWin32Thread();
+ pti = PsGetCurrentThreadWin32Thread();
- if ( Window->pti->MessageQueue != pti->MessageQueue &&
- FindMsgMemory(Msg) == 0 )
- {
- Result = UserPostMessage(hWnd, Msg, wParam, lParam);
- }
- else
- {
- if ( !co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result) )
- {
- Result = 0;
- }
- }
+ if ( Window->head.pti->MessageQueue != pti->MessageQueue &&
+ FindMsgMemory(Msg) == 0 )
+ {
+ Result = UserPostMessage(hWnd, Msg, wParam, lParam);
+ }
+ else
+ {
+ if ( !co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result) )
+ {
+ Result = 0;
+ }
+ }
- return (LRESULT)Result;
+ return (LRESULT)Result;
}
LRESULT FASTCALL
UINT Msg,
WPARAM wParam,
LPARAM lParam,
- PDOSENDMESSAGE dsm,
- PNTUSERSENDMESSAGEINFO UnsafeInfo )
+ PDOSENDMESSAGE dsm)
{
- PTHREADINFO pti;
- LRESULT Result = TRUE;
- NTSTATUS Status;
- PWINDOW_OBJECT Window = NULL;
- NTUSERSENDMESSAGEINFO Info;
- MSG UserModeMsg;
- MSG KernelModeMsg;
- PMSGMEMORY MsgMemoryEntry;
-
- RtlZeroMemory(&Info, sizeof(NTUSERSENDMESSAGEINFO));
-
- /* FIXME: Call hooks. */
- if (HWND_BROADCAST != hWnd)
- {
- Window = UserGetWindowObject(hWnd);
- if ( !Window || !Window->Wnd )
- {
- /* Tell usermode to not touch this one */
- Info.HandledByKernel = TRUE;
- MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
- return 0;
- }
- }
-
- /* Check for an exiting window. */
- if (Window && Window->state & WINDOWSTATUS_DESTROYING)
- {
- DPRINT1("co_IntDoSendMessage Window Exiting!\n");
- }
-
- /* See if the current thread can handle the message */
- pti = PsGetCurrentThreadWin32Thread();
+ PTHREADINFO pti;
+ LRESULT Result = TRUE;
+ NTSTATUS Status;
+ PWND Window = NULL;
+ MSG UserModeMsg;
+ MSG KernelModeMsg;
+ PMSGMEMORY MsgMemoryEntry;
+
+ if (HWND_BROADCAST != hWnd)
+ {
+ Window = UserGetWindowObject(hWnd);
+ if ( !Window )
+ {
+ return 0;
+ }
+ }
- // This is checked in user mode!!!!!!!
- if ( HWND_BROADCAST != hWnd &&
- NULL != pti &&
- Window->pti->MessageQueue == pti->MessageQueue &&
- !ISITHOOKED(WH_CALLWNDPROC) &&
- !ISITHOOKED(WH_CALLWNDPROCRET) &&
- ( Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST ) )
- {
- /* Gather the information usermode needs to call the window proc directly */
- Info.HandledByKernel = FALSE;
+ /* Check for an exiting window. */
+ if (Window && Window->state & WNDS_DESTROYED)
+ {
+ DPRINT1("co_IntDoSendMessage Window Exiting!\n");
+ }
- Status = MmCopyFromCaller(&(Info.Ansi), &(UnsafeInfo->Ansi),
- sizeof(BOOL));
- if (! NT_SUCCESS(Status))
- {
- Info.Ansi = ! Window->Wnd->Unicode;
- }
+ /* See if the current thread can handle the message */
+ pti = PsGetCurrentThreadWin32Thread();
- Info.Ansi = !Window->Wnd->Unicode;
- Info.Proc = Window->Wnd->lpfnWndProc;
- }
- else
- {
- /* Must be handled by other thread */
-// if (HWND_BROADCAST != hWnd)
-// {
-// UserDereferenceObject(Window);
-// }
- Info.HandledByKernel = TRUE;
- 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))
- {
- MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return (dsm ? 0 : -1);
- }
+ UserModeMsg.hwnd = hWnd;
+ UserModeMsg.message = Msg;
+ UserModeMsg.wParam = wParam;
+ UserModeMsg.lParam = lParam;
+ MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
- if(!dsm)
- {
- Result = co_IntSendMessage( KernelModeMsg.hwnd,
- KernelModeMsg.message,
- KernelModeMsg.wParam,
- KernelModeMsg.lParam );
- }
- else
- {
- Result = co_IntSendMessageTimeout( KernelModeMsg.hwnd,
- KernelModeMsg.message,
- KernelModeMsg.wParam,
- KernelModeMsg.lParam,
- dsm->uFlags,
- dsm->uTimeout,
- &dsm->Result );
- }
+ Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
+ if (! NT_SUCCESS(Status))
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return (dsm ? 0 : -1);
+ }
- Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
- if (! NT_SUCCESS(Status))
- {
- MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return(dsm ? 0 : -1);
- }
- }
+ if (!dsm)
+ {
+ Result = co_IntSendMessage( KernelModeMsg.hwnd,
+ KernelModeMsg.message,
+ KernelModeMsg.wParam,
+ KernelModeMsg.lParam );
+ }
+ else
+ {
+ Result = co_IntSendMessageTimeout( KernelModeMsg.hwnd,
+ KernelModeMsg.message,
+ KernelModeMsg.wParam,
+ KernelModeMsg.lParam,
+ dsm->uFlags,
+ dsm->uTimeout,
+ &dsm->Result );
+ }
- Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
- if (! NT_SUCCESS(Status))
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- }
+ Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
+ if (! NT_SUCCESS(Status))
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return(dsm ? 0 : -1);
+ }
- return (LRESULT)Result;
+ return (LRESULT)Result;
}
-
BOOL FASTCALL
UserSendNotifyMessage( HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam )
{
- BOOL Result = TRUE;
-
- if (FindMsgMemory(Msg) != 0)
- {
- SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
- return FALSE;
- }
-
- // Basicly the same as IntPostOrSendMessage
- if (hWnd == HWND_BROADCAST) //Handle Broadcast
- {
- HWND *List;
- PWINDOW_OBJECT DesktopWindow;
- ULONG i;
+ BOOL Ret = TRUE;
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
- List = IntWinListChildren(DesktopWindow);
-
- if (List != NULL)
- {
- for (i = 0; List[i]; i++)
- {
- UserSendNotifyMessage(List[i], Msg, wParam, lParam);
- }
- ExFreePool(List);
- }
- }
- else
- {
- ULONG_PTR PResult;
- PTHREADINFO pti;
- PWINDOW_OBJECT Window;
- MSG Message;
+ if (is_pointer_message(Msg))
+ {
+ EngSetLastError(ERROR_MESSAGE_SYNC_ONLY );
+ return FALSE;
+ }
- if ( !(Window = UserGetWindowObject(hWnd)) ) return FALSE;
+ // Basicly the same as IntPostOrSendMessage
+ if (hWnd == HWND_BROADCAST) //Handle Broadcast
+ {
+ HWND *List;
+ PWND DesktopWindow;
+ ULONG i;
- pti = PsGetCurrentThreadWin32Thread();
+ DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ List = IntWinListChildren(DesktopWindow);
- if (Window->pti->MessageQueue != pti->MessageQueue)
- { // Send message w/o waiting for it.
- Result = UserPostMessage(hWnd, Msg, wParam, lParam);
- }
- else
- { // Handle message and callback.
- Message.hwnd = hWnd;
- Message.message = Msg;
- Message.wParam = wParam;
- Message.lParam = lParam;
-
- Result = co_IntSendMessageTimeoutSingle( hWnd,
- Msg,
- wParam,
- lParam,
- SMTO_NORMAL,
- 0,
- &PResult );
- }
- }
- return Result;
+ if (List != NULL)
+ {
+ UserSendNotifyMessage(DesktopWindow->head.h, Msg, wParam, lParam);
+ for (i = 0; List[i]; i++)
+ {
+ Ret = UserSendNotifyMessage(List[i], Msg, wParam, lParam);
+ }
+ ExFreePool(List);
+ }
+ }
+ else
+ {
+ ULONG_PTR lResult = 0;
+ Ret = co_IntSendMessageWithCallBack( hWnd,
+ Msg,
+ wParam,
+ lParam,
+ NULL,
+ 0,
+ &lResult);
+ }
+ return Ret;
}
DWORD APIENTRY
-IntGetQueueStatus(BOOL ClearChanges)
+IntGetQueueStatus(DWORD Changes)
{
- PTHREADINFO pti;
- PUSER_MESSAGE_QUEUE Queue;
- DWORD Result;
- DECLARE_RETURN(DWORD);
+ PTHREADINFO pti;
+ PUSER_MESSAGE_QUEUE Queue;
+ DWORD Result;
- DPRINT("Enter IntGetQueueStatus\n");
-
- pti = PsGetCurrentThreadWin32Thread();
- Queue = pti->MessageQueue;
+ pti = PsGetCurrentThreadWin32Thread();
+ Queue = pti->MessageQueue;
+// wine:
+ Changes &= (QS_ALLINPUT|QS_ALLPOSTMESSAGE|QS_SMRESULT);
- Result = MAKELONG(Queue->QueueBits, Queue->ChangedBits);
- if (ClearChanges)
- {
- Queue->ChangedBits = 0;
- }
+ /* High word, types of messages currently in the queue.
+ Low word, types of messages that have been added to the queue and that
+ are still in the queue
+ */
+ Result = MAKELONG(pti->pcti->fsChangeBits & Changes, pti->pcti->fsWakeBits & Changes);
- RETURN(Result);
+ pti->pcti->fsChangeBits &= ~Changes;
-CLEANUP:
- DPRINT("Leave IntGetQueueStatus, ret=%i\n",_ret_);
- END_CLEANUP;
+ return Result;
}
BOOL APIENTRY
IntInitMessagePumpHook()
{
- if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti)
- {
- ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti->dwcPumpHook++;
- return TRUE;
- }
- return FALSE;
+ PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
+
+ if (pti->pcti)
+ {
+ pti->pcti->dwcPumpHook++;
+ return TRUE;
+ }
+ return FALSE;
}
BOOL APIENTRY
IntUninitMessagePumpHook()
{
- if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti)
- {
- if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti->dwcPumpHook <= 0)
- {
- return FALSE;
- }
- ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti->dwcPumpHook--;
- return TRUE;
- }
- return FALSE;
+ PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
+
+ if (pti->pcti)
+ {
+ if (pti->pcti->dwcPumpHook <= 0)
+ {
+ return FALSE;
+ }
+ pti->pcti->dwcPumpHook--;
+ return TRUE;
+ }
+ return FALSE;
}
/** Functions ******************************************************************/
-BOOL APIENTRY
-NtUserPostMessage(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
+BOOL
+APIENTRY
+NtUserDragDetect(
+ HWND hWnd,
+ POINT pt) // Just like the User call.
{
- DECLARE_RETURN(BOOL);
+ MSG msg;
+ RECT rect;
+ WORD wDragWidth, wDragHeight;
+ DECLARE_RETURN(BOOL);
- DPRINT("Enter NtUserPostMessage\n");
- UserEnterExclusive();
+ DPRINT("Enter NtUserDragDetect(%x)\n", hWnd);
+ UserEnterExclusive();
- RETURN( UserPostMessage(hWnd, Msg, wParam, lParam));
+ wDragWidth = UserGetSystemMetrics(SM_CXDRAG);
+ wDragHeight= UserGetSystemMetrics(SM_CYDRAG);
-CLEANUP:
- DPRINT("Leave NtUserPostMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
+ rect.left = pt.x - wDragWidth;
+ rect.right = pt.x + wDragWidth;
-BOOL APIENTRY
-NtUserPostThreadMessage(DWORD idThread,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
-{
- DECLARE_RETURN(BOOL);
+ rect.top = pt.y - wDragHeight;
+ rect.bottom = pt.y + wDragHeight;
- DPRINT("Enter NtUserPostThreadMessage\n");
- UserEnterExclusive();
+ co_UserSetCapture(hWnd);
- RETURN( UserPostThreadMessage( idThread,
- Msg,
- wParam,
- lParam));
+ for (;;)
+ {
+ while (co_IntGetPeekMessage( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE, FALSE ) ||
+ co_IntGetPeekMessage( &msg, 0, WM_QUEUESYNC, WM_QUEUESYNC, PM_REMOVE, FALSE ) ||
+ co_IntGetPeekMessage( &msg, 0, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE, FALSE ) )
+ {
+ if ( msg.message == WM_LBUTTONUP )
+ {
+ co_UserSetCapture(NULL);
+ RETURN( FALSE);
+ }
+ if ( msg.message == WM_MOUSEMOVE )
+ {
+ POINT tmp;
+ tmp.x = (short)LOWORD(msg.lParam);
+ tmp.y = (short)HIWORD(msg.lParam);
+ if( !IntPtInRect( &rect, tmp ) )
+ {
+ co_UserSetCapture(NULL);
+ RETURN( TRUE);
+ }
+ }
+ if ( msg.message == WM_KEYDOWN )
+ {
+ if ( msg.wParam == VK_ESCAPE )
+ {
+ co_UserSetCapture(NULL);
+ RETURN( TRUE);
+ }
+ }
+ if ( msg.message == WM_QUEUESYNC )
+ {
+ co_HOOK_CallHooks( WH_CBT, HCBT_QS, 0, 0 );
+ }
+ }
+ co_IntWaitMessage(NULL, 0, 0);
+ }
+ RETURN( FALSE);
CLEANUP:
- DPRINT("Leave NtUserPostThreadMessage, ret=%i\n",_ret_);
+ DPRINT("Leave NtUserDragDetect, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
-DWORD APIENTRY
-NtUserQuerySendMessage(DWORD Unknown0)
-{
- UNIMPLEMENTED;
-
- return 0;
-}
-
-
-////////// API on the way out!
-LRESULT APIENTRY
-NtUserSendMessageTimeout( HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam,
- UINT uFlags,
- UINT uTimeout,
- ULONG_PTR *uResult,
- PNTUSERSENDMESSAGEINFO UnsafeInfo )
+BOOL APIENTRY
+NtUserPostMessage(HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam)
{
- DOSENDMESSAGE dsm;
- LRESULT Result;
- DECLARE_RETURN(BOOL);
+ BOOL ret;
- DPRINT("Enter NtUserSendMessageTimeout\n");
- UserEnterExclusive();
+ UserEnterExclusive();
- dsm.uFlags = uFlags;
- dsm.uTimeout = uTimeout;
- Result = co_IntDoSendMessage(hWnd, Msg, wParam, lParam, &dsm, UnsafeInfo);
- if(uResult != NULL && Result != 0)
- {
- NTSTATUS Status;
+ ret = UserPostMessage(hWnd, Msg, wParam, lParam);
- Status = MmCopyToCaller(uResult, &dsm.Result, sizeof(ULONG_PTR));
- if(!NT_SUCCESS(Status))
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN( FALSE);
- }
- }
- RETURN( Result);
+ UserLeave();
-CLEANUP:
- DPRINT("Leave NtUserSendMessageTimeout, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ return ret;
}
-LRESULT APIENTRY
-NtUserSendMessage( HWND Wnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam,
- PNTUSERSENDMESSAGEINFO UnsafeInfo )
+BOOL APIENTRY
+NtUserPostThreadMessage(DWORD idThread,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam)
{
- DECLARE_RETURN(BOOL);
+ BOOL ret;
- DPRINT("Enter NtUserSendMessage\n");
- UserEnterExclusive();
+ UserEnterExclusive();
- RETURN(co_IntDoSendMessage(Wnd, Msg, wParam, lParam, NULL, UnsafeInfo));
+ ret = UserPostThreadMessage( idThread, Msg, wParam, lParam);
-CLEANUP:
- DPRINT("Leave NtUserSendMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ UserLeave();
+
+ return ret;
}
-//////////
BOOL APIENTRY
NtUserWaitMessage(VOID)
{
- DECLARE_RETURN(BOOL);
+ BOOL ret;
- DPRINT("EnterNtUserWaitMessage\n");
- UserEnterExclusive();
+ UserEnterExclusive();
+ DPRINT("NtUserWaitMessage Enter\n");
+ ret = co_IntWaitMessage(NULL, 0, 0);
+ DPRINT("NtUserWaitMessage Leave\n");
+ UserLeave();
- RETURN(co_IntWaitMessage(NULL, 0, 0));
-
-CLEANUP:
- DPRINT("Leave NtUserWaitMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ return ret;
}
-
BOOL APIENTRY
-NtUserGetMessage( PNTUSERGETMESSAGEINFO UnsafeInfo,
+NtUserGetMessage(PMSG pMsg,
HWND hWnd,
UINT MsgFilterMin,
UINT MsgFilterMax )
-/*
- * 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.
- */
{
- BOOL GotMessage;
- NTUSERGETMESSAGEINFO Info;
- NTSTATUS Status;
- /* FIXME: if initialization is removed, gcc complains that this may be used before initialization. Please review */
- PWINDOW_OBJECT Window = NULL;
- PMSGMEMORY MsgMemoryEntry;
- PVOID UserMem;
- UINT Size;
- USER_MESSAGE Msg;
- DECLARE_RETURN(BOOL);
-// USER_REFERENCE_ENTRY Ref;
-
- DPRINT("Enter NtUserGetMessage\n");
- UserEnterExclusive();
-
- /* Validate input */
- if (hWnd && !(Window = UserGetWindowObject(hWnd)))
- {
- RETURN(-1);
- }
-
-// if (Window) UserRefObjectCo(Window, &Ref);
-
- if (MsgFilterMax < MsgFilterMin)
- {
- MsgFilterMin = 0;
- MsgFilterMax = 0;
- }
-
- do
- {
- GotMessage = co_IntPeekMessage(&Msg, Window, MsgFilterMin, MsgFilterMax, PM_REMOVE);
- if (GotMessage)
- {
- 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))
- {
- 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,
- &Info.LParamSize, MEM_DECOMMIT);
- SetLastNtError(Status);
- RETURN( (BOOL) -1);
- }
- 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);
- }
- }
- else if (! co_IntWaitMessage(Window, MsgFilterMin, MsgFilterMax))
- {
- RETURN( (BOOL) -1);
- }
- }
- while (! GotMessage);
-
- RETURN( WM_QUIT != Info.Msg.message);
-
-CLEANUP:
-// if (Window) UserDerefObjectCo(Window);
-
- DPRINT("Leave NtUserGetMessage\n");
- UserLeave();
- END_CLEANUP;
-}
-
+ MSG Msg;
+ BOOL Ret;
-BOOL
-APIENTRY
-NtUserGetMessageX(
- PMSG pMsg,
- HWND hWnd,
- UINT MsgFilterMin,
- UINT MsgFilterMax)
-{
- MSG Msg;
- BOOL Ret = FALSE;
- DECLARE_RETURN(BOOL);
+ if ( (MsgFilterMin|MsgFilterMax) & ~WM_MAXIMUM )
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
- DPRINT("Enter NtUserGetMessage\n");
- UserEnterExclusive();
+ UserEnterExclusive();
- if ( (MsgFilterMin|MsgFilterMax) & ~WM_MAXIMUM )
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN( Ret);
- }
+ RtlZeroMemory(&Msg, sizeof(MSG));
- RtlZeroMemory(&Msg, sizeof(MSG));
+ Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE, TRUE);
- Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE, TRUE);
+ UserLeave();
- if (Ret)
- {
- _SEH2_TRY
- {
- ProbeForWrite(pMsg, sizeof(MSG), 1);
- RtlCopyMemory(pMsg, &Msg, sizeof(MSG));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastNtError(_SEH2_GetExceptionCode());
- Ret = FALSE;
- }
- _SEH2_END;
- }
- RETURN( Ret);
+ if (Ret)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite(pMsg, sizeof(MSG), 1);
+ RtlCopyMemory(pMsg, &Msg, sizeof(MSG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Ret = FALSE;
+ }
+ _SEH2_END;
+ }
-CLEANUP:
- DPRINT("Leave NtUserGetMessage\n");
- UserLeave();
- END_CLEANUP;
+ return Ret;
}
BOOL APIENTRY
-NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
+NtUserPeekMessage( PMSG pMsg,
HWND hWnd,
UINT MsgFilterMin,
UINT MsgFilterMax,
UINT RemoveMsg)
{
- 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();
-
- if (hWnd == (HWND)-1 || hWnd == (HWND)0x0000FFFF || hWnd == (HWND)0xFFFFFFFF)
- hWnd = (HWND)1;
-
- /* Validate input */
- if (hWnd && hWnd != (HWND)1)
- {
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- RETURN(-1);
- }
- }
- else
- {
- Window = (PWINDOW_OBJECT)hWnd;
- }
+ MSG Msg;
+ BOOL Ret;
- if (MsgFilterMax < MsgFilterMin)
- {
- MsgFilterMin = 0;
- MsgFilterMax = 0;
- }
+ if ( RemoveMsg & PM_BADMSGFLAGS )
+ {
+ EngSetLastError(ERROR_INVALID_FLAGS);
+ return FALSE;
+ }
- Present = co_IntPeekMessage(&Msg, Window, MsgFilterMin, MsgFilterMax, RemoveMsg);
- if (Present)
- {
+ UserEnterExclusive();
- 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))
- {
- 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,
- &Info.LParamSize, MEM_RELEASE);
- SetLastNtError(Status);
- RETURN( (BOOL) -1);
- }
- Info.Msg.lParam = (LPARAM) UserMem;
- }
- if (RemoveMsg && 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);
- }
- }
+ RtlZeroMemory(&Msg, sizeof(MSG));
- RETURN( Present);
+ Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg, FALSE);
-CLEANUP:
- DPRINT("Leave NtUserPeekMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ UserLeave();
+
+ if (Ret)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite(pMsg, sizeof(MSG), 1);
+ RtlCopyMemory(pMsg, &Msg, sizeof(MSG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Ret = FALSE;
+ }
+ _SEH2_END;
+ }
+
+ return Ret;
}
-BOOL
-APIENTRY
-NtUserPeekMessageX(
- PMSG pMsg,
- HWND hWnd,
- UINT MsgFilterMin,
- UINT MsgFilterMax,
- UINT RemoveMsg)
+BOOL APIENTRY
+NtUserCallMsgFilter( LPMSG lpmsg, INT code)
{
- MSG Msg;
- BOOL Ret = FALSE;
- DECLARE_RETURN(BOOL);
+ BOOL Ret = FALSE;
+ MSG Msg;
- DPRINT("Enter NtUserPeekMessage\n");
- UserEnterExclusive();
+ _SEH2_TRY
+ {
+ ProbeForRead(lpmsg, sizeof(MSG), 1);
+ RtlCopyMemory( &Msg, lpmsg, sizeof(MSG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return FALSE);
+ }
+ _SEH2_END;
- if ( RemoveMsg & PM_BADMSGFLAGS )
- {
- SetLastWin32Error(ERROR_INVALID_FLAGS);
- RETURN( Ret);
- }
+ UserEnterExclusive();
- RtlZeroMemory(&Msg, sizeof(MSG));
+ if ( co_HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)&Msg))
+ {
+ Ret = TRUE;
+ }
+ else
+ {
+ Ret = co_HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)&Msg);
+ }
- Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg, FALSE);
+ UserLeave();
- if (Ret)
- {
- _SEH2_TRY
- {
- ProbeForWrite(pMsg, sizeof(MSG), 1);
- RtlCopyMemory(pMsg, &Msg, sizeof(MSG));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastNtError(_SEH2_GetExceptionCode());
- Ret = FALSE;
- }
- _SEH2_END;
- }
- RETURN( Ret);
+ _SEH2_TRY
+ {
+ ProbeForWrite(lpmsg, sizeof(MSG), 1);
+ RtlCopyMemory(lpmsg, &Msg, sizeof(MSG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Ret = FALSE;
+ }
+ _SEH2_END;
-CLEANUP:
- DPRINT("Leave NtUserPeekMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ return Ret;
}
-BOOL
-APIENTRY
-NtUserCallMsgFilter(
- LPMSG lpmsg,
- INT code)
+LRESULT APIENTRY
+NtUserDispatchMessage(PMSG UnsafeMsgInfo)
{
- BOOL BadChk = FALSE, Ret = FALSE;
- MSG Msg;
- DECLARE_RETURN(BOOL);
-
- DPRINT("Enter NtUserCallMsgFilter\n");
- UserEnterExclusive();
- if (lpmsg)
- {
- _SEH2_TRY
- {
- ProbeForRead((PVOID)lpmsg,
- sizeof(MSG),
- 1);
- RtlCopyMemory( &Msg,
- (PVOID)lpmsg,
- sizeof(MSG));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- BadChk = TRUE;
- }
- _SEH2_END;
- }
- else
- RETURN( FALSE);
-
- if (BadChk) RETURN( FALSE);
+ LRESULT Res = 0;
+ MSG SafeMsg;
- if ( ISITHOOKED(WH_SYSMSGFILTER) &&
- co_HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)&Msg))
- {
- Ret = TRUE;
- }
- else
- {
- if ( ISITHOOKED(WH_MSGFILTER) )
- {
- Ret = co_HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)&Msg);
- }
- }
+ _SEH2_TRY
+ {
+ ProbeForRead(UnsafeMsgInfo, sizeof(MSG), 1);
+ RtlCopyMemory(&SafeMsg, UnsafeMsgInfo, sizeof(MSG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(return FALSE);
+ }
+ _SEH2_END;
- _SEH2_TRY
- {
- ProbeForWrite((PVOID)lpmsg,
- sizeof(MSG),
- 1);
- RtlCopyMemory((PVOID)lpmsg,
- &Msg,
- sizeof(MSG));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- BadChk = TRUE;
- }
- _SEH2_END;
- if (BadChk) RETURN( FALSE);
- RETURN( Ret)
+ UserEnterExclusive();
-CLEANUP:
- DPRINT("Leave NtUserCallMsgFilter. ret=%i\n", _ret_);
- UserLeave();
- END_CLEANUP;
-}
+ Res = IntDispatchMessage(&SafeMsg);
-LRESULT APIENTRY
-NtUserDispatchMessage(PMSG UnsafeMsgInfo)
-{
- LRESULT Res = 0;
- BOOL Hit = FALSE;
- MSG SafeMsg;
-
- UserEnterExclusive();
- _SEH2_TRY
- {
- ProbeForRead(UnsafeMsgInfo, sizeof(MSG), 1);
- RtlCopyMemory(&SafeMsg, UnsafeMsgInfo, sizeof(MSG));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastNtError(_SEH2_GetExceptionCode());
- Hit = TRUE;
- }
- _SEH2_END;
-
- if (!Hit) Res = IntDispatchMessage(&SafeMsg);
-
- UserLeave();
- return Res;
+ UserLeave();
+ return Res;
}
BOOL APIENTRY
-NtUserTranslateMessage(LPMSG lpMsg,
- UINT flags)
+NtUserTranslateMessage(LPMSG lpMsg, UINT flags)
{
- NTSTATUS Status;
- MSG SafeMsg;
- DECLARE_RETURN(BOOL);
+ MSG SafeMsg;
+ BOOL Ret;
- DPRINT("Enter NtUserTranslateMessage\n");
- UserEnterExclusive();
+ _SEH2_TRY
+ {
+ ProbeForRead(lpMsg, sizeof(MSG), 1);
+ RtlCopyMemory(&SafeMsg, lpMsg, sizeof(MSG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(return FALSE);
+ }
+ _SEH2_END;
- Status = MmCopyFromCaller(&SafeMsg, lpMsg, sizeof(MSG));
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( FALSE);
- }
+ UserEnterExclusive();
- RETURN( IntTranslateKbdMessage(&SafeMsg, flags));
+ Ret = IntTranslateKbdMessage(&SafeMsg, flags);
-CLEANUP:
- DPRINT("Leave NtUserTranslateMessage: ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ UserLeave();
+
+ return Ret;
}
BOOL APIENTRY
-NtUserMessageCall(
- HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam,
- ULONG_PTR ResultInfo,
- DWORD dwType, // fnID?
- BOOL Ansi)
+NtUserMessageCall( HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ ULONG_PTR ResultInfo,
+ DWORD dwType, // fnID?
+ BOOL Ansi)
{
- LRESULT lResult = 0;
- BOOL Ret = FALSE;
- BOOL BadChk = FALSE;
- PWINDOW_OBJECT Window = NULL;
- USER_REFERENCE_ENTRY Ref;
+ LRESULT lResult = 0;
+ BOOL Ret = FALSE;
+ PWND Window = NULL;
+ USER_REFERENCE_ENTRY Ref;
- UserEnterExclusive();
+ UserEnterExclusive();
- /* Validate input */
- if (hWnd && (hWnd != INVALID_HANDLE_VALUE) && !(Window = UserGetWindowObject(hWnd)))
- {
- UserLeave();
- return FALSE;
- }
- switch(dwType)
- {
- case FNID_DEFWINDOWPROC:
- UserRefObjectCo(Window, &Ref);
- lResult = IntDefWindowProc(Window, Msg, wParam, lParam, Ansi);
- Ret = TRUE;
- UserDerefObjectCo(Window);
- break;
- case FNID_SENDNOTIFYMESSAGE:
- Ret = UserSendNotifyMessage(hWnd, Msg, wParam, lParam);
- break;
- case FNID_BROADCASTSYSTEMMESSAGE:
- {
- BROADCASTPARM parm;
- DWORD_PTR RetVal = 0;
+ /* Validate input */
+ if (hWnd && (hWnd != INVALID_HANDLE_VALUE))
+ {
+ Window = UserGetWindowObject(hWnd);
+ if (!Window)
+ {
+ UserLeave();
+ return FALSE;
+ }
+ }
+
+ switch(dwType)
+ {
+ case FNID_DEFWINDOWPROC:
+ if (Window) UserRefObjectCo(Window, &Ref);
+ lResult = IntDefWindowProc(Window, Msg, wParam, lParam, Ansi);
+ Ret = TRUE;
+ if (Window) UserDerefObjectCo(Window);
+ break;
+ case FNID_SENDNOTIFYMESSAGE:
+ Ret = UserSendNotifyMessage(hWnd, Msg, wParam, lParam);
+ break;
+ case FNID_BROADCASTSYSTEMMESSAGE:
+ {
+ BROADCASTPARM parm;
+ DWORD_PTR RetVal = 0;
+
+ if (ResultInfo)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite((PVOID)ResultInfo, sizeof(BROADCASTPARM), 1);
+ RtlCopyMemory(&parm, (PVOID)ResultInfo, sizeof(BROADCASTPARM));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Ret = FALSE;
+ _SEH2_YIELD(break);
+ }
+ _SEH2_END;
+ }
+ 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);
+ }
+ Ret = RetVal;
+ }
+ else if (parm.flags & BSF_POSTMESSAGE)
+ {
+ Ret = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam);
+ }
+ else //Everything else,,,, if ( parm.flags & BSF_SENDNOTIFYMESSAGE)
+ {
+ Ret = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam);
+ }
+ }
+ }
+ break;
+ case FNID_SENDMESSAGECALLBACK:
+ {
+ CALL_BACK_INFO CallBackInfo;
+ ULONG_PTR uResult;
- if (ResultInfo)
- {
_SEH2_TRY
{
- ProbeForWrite((PVOID)ResultInfo,
- sizeof(BROADCASTPARM),
- 1);
- RtlCopyMemory(&parm, (PVOID)ResultInfo, sizeof(BROADCASTPARM));
+ ProbeForRead((PVOID)ResultInfo, sizeof(CALL_BACK_INFO), 1);
+ RtlCopyMemory(&CallBackInfo, (PVOID)ResultInfo, sizeof(CALL_BACK_INFO));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- BadChk = TRUE;
+ Ret = FALSE;
+ _SEH2_YIELD(break);
}
_SEH2_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 (!co_IntSendMessageWithCallBack(hWnd, Msg, wParam, lParam,
+ CallBackInfo.CallBack, CallBackInfo.Context, &uResult))
{
- 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);
- }
+ DPRINT1("Callback failure!\n");
}
- else if (parm.flags & BSF_POSTMESSAGE)
+ }
+ break;
+ case FNID_SENDMESSAGE:
+ {
+ Ret = co_IntDoSendMessage(hWnd, Msg, wParam, lParam, 0);
+
+ if (ResultInfo)
{
- Ret = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam);
+ _SEH2_TRY
+ {
+ ProbeForWrite((PVOID)ResultInfo, sizeof(ULONG_PTR), 1);
+ RtlCopyMemory((PVOID)ResultInfo, &Ret, sizeof(ULONG_PTR));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Ret = FALSE;
+ _SEH2_YIELD(break);
+ }
+ _SEH2_END;
}
- else if ( parm.flags & BSF_SENDNOTIFYMESSAGE)
+ break;
+ }
+ case FNID_SENDMESSAGETIMEOUT:
+ {
+ DOSENDMESSAGE dsm, *pdsm = (PDOSENDMESSAGE)ResultInfo;
+ if (ResultInfo)
{
- Ret = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam);
+ _SEH2_TRY
+ {
+ ProbeForRead(pdsm, sizeof(DOSENDMESSAGE), 1);
+ RtlCopyMemory(&dsm, pdsm, sizeof(DOSENDMESSAGE));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Ret = FALSE;
+ _SEH2_YIELD(break);
+ }
+ _SEH2_END;
}
- }
- }
- break;
- case FNID_SENDMESSAGECALLBACK:
- {
- PCALL_BACK_INFO CallBackInfo = (PCALL_BACK_INFO)ResultInfo;
- if (!CallBackInfo)
+ Ret = co_IntDoSendMessage( hWnd, Msg, wParam, lParam, &dsm );
+
+ if (pdsm)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite(pdsm, sizeof(DOSENDMESSAGE), 1);
+ RtlCopyMemory(pdsm, &dsm, sizeof(DOSENDMESSAGE));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Ret = FALSE;
+ _SEH2_YIELD(break);
+ }
+ _SEH2_END;
+ }
break;
+ }
+ // CallNextHook bypass.
+ case FNID_CALLWNDPROC:
+ case FNID_CALLWNDPROCRET:
+ {
+ PTHREADINFO pti;
+ PCLIENTINFO ClientInfo;
+ PHOOK NextObj, Hook;
- if (!co_IntSendMessageWithCallBack(hWnd, Msg, wParam, lParam,
- CallBackInfo->CallBack, CallBackInfo->Context, NULL))
- {
- DPRINT1("Callback failure!\n");
- }
- }
- break;
- // CallNextHook bypass.
- case FNID_CALLWNDPROC:
- case FNID_CALLWNDPROCRET:
- {
- PCLIENTINFO ClientInfo = GetWin32ClientInfo();
- PHOOK NextObj, Hook = ClientInfo->phkCurrent;
+ pti = GetW32ThreadInfo();
- if (!ClientInfo || !Hook) break;
+ Hook = pti->sphkCurrent;
- UserReferenceObject(Hook);
+ if (!Hook) break;
- if (Hook->Thread && (Hook->Thread != PsGetCurrentThread()))
- {
- UserDereferenceObject(Hook);
- break;
- }
+ NextObj = Hook->phkNext;
+ ClientInfo = pti->pClientInfo;
+ _SEH2_TRY
+ {
+ ClientInfo->phkCurrent = NextObj;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ClientInfo = NULL;
+ }
+ _SEH2_END;
- NextObj = IntGetNextHook(Hook);
- ClientInfo->phkCurrent = NextObj;
+ if (!ClientInfo || !NextObj) break;
- if ( Hook->HookId == WH_CALLWNDPROC)
- {
- CWPSTRUCT CWP;
- CWP.hwnd = hWnd;
- CWP.message = Msg;
- CWP.wParam = wParam;
- CWP.lParam = lParam;
- DPRINT("WH_CALLWNDPROC: Hook %x NextHook %x\n", Hook, NextObj );
-
- 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;
- }
- break;
- }
+ NextObj->phkNext = IntGetNextHook(NextObj);
- switch(dwType)
- {
- case FNID_DEFWINDOWPROC:
- case FNID_CALLWNDPROC:
- case FNID_CALLWNDPROCRET:
- if (ResultInfo)
- {
+ if ( Hook->HookId == WH_CALLWNDPROC)
+ {
+ CWPSTRUCT CWP;
+ CWP.hwnd = hWnd;
+ CWP.message = Msg;
+ CWP.wParam = wParam;
+ CWP.lParam = lParam;
+ DPRINT("WH_CALLWNDPROC: Hook %x NextHook %x\n", Hook, NextObj );
+
+ 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);
+ }
+ }
+ break;
+ }
+
+ switch(dwType)
+ {
+ case FNID_DEFWINDOWPROC:
+ case FNID_CALLWNDPROC:
+ case FNID_CALLWNDPROCRET:
+ if (ResultInfo)
+ {
_SEH2_TRY
{
ProbeForWrite((PVOID)ResultInfo, sizeof(LRESULT), 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- BadChk = TRUE;
+ Ret = FALSE;
}
- _SEH2_END;
- }
- break;
- default:
- break;
- }
+ _SEH2_END;
+ }
+ break;
+ default:
+ break;
+ }
- UserLeave();
+ UserLeave();
- return BadChk ? FALSE : Ret;
+ return Ret;
}
#define INFINITE 0xFFFFFFFF
DWORD
APIENTRY
-NtUserWaitForInputIdle(
- IN HANDLE hProcess,
- IN DWORD dwMilliseconds,
- IN BOOL Unknown2)
+NtUserWaitForInputIdle( IN HANDLE hProcess,
+ IN DWORD dwMilliseconds,
+ IN BOOL Unknown2)
{
- PEPROCESS Process;
- PPROCESSINFO W32Process;
- NTSTATUS Status;
- HANDLE Handles[2];
- LARGE_INTEGER Timeout;
- ULONGLONG StartTime, Run, Elapsed = 0;
-
- UserEnterExclusive();
-
- Status = ObReferenceObjectByHandle(hProcess,
- PROCESS_QUERY_INFORMATION,
- PsProcessType,
- UserMode,
- (PVOID*)&Process,
- NULL);
-
- if (!NT_SUCCESS(Status))
- {
- UserLeave();
- SetLastNtError(Status);
- return WAIT_FAILED;
- }
-
- W32Process = (PPROCESSINFO)Process->Win32Process;
- if (!W32Process)
- {
- ObDereferenceObject(Process);
- UserLeave();
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return WAIT_FAILED;
- }
-
- EngCreateEvent((PEVENT *)&W32Process->InputIdleEvent);
-
- Handles[0] = Process;
- Handles[1] = W32Process->InputIdleEvent;
-
- if (!Handles[1])
- {
- ObDereferenceObject(Process);
- UserLeave();
- return STATUS_SUCCESS; /* no event to wait on */
- }
-
- StartTime = EngGetTickCount();
-
- Run = dwMilliseconds;
-
- DPRINT("WFII: waiting for %p\n", Handles[1] );
- do
- {
- Timeout.QuadPart = Run - Elapsed;
- UserLeave();
- Status = KeWaitForMultipleObjects( 2,
- Handles,
- WaitAny,
- UserRequest,
- UserMode,
- FALSE,
- dwMilliseconds == INFINITE ? NULL : &Timeout,
- NULL);
- UserEnterExclusive();
-
- if (!NT_SUCCESS(Status))
- {
+ PEPROCESS Process;
+ PPROCESSINFO W32Process;
+ PTHREADINFO pti;
+ NTSTATUS Status;
+ HANDLE Handles[3];
+ LARGE_INTEGER Timeout;
+
+ UserEnterExclusive();
+
+ Status = ObReferenceObjectByHandle(hProcess,
+ PROCESS_QUERY_INFORMATION,
+ PsProcessType,
+ UserMode,
+ (PVOID*)&Process,
+ NULL);
+
+ if (!NT_SUCCESS(Status))
+ {
+ UserLeave();
SetLastNtError(Status);
- Status = WAIT_FAILED;
- goto WaitExit;
- }
+ return WAIT_FAILED;
+ }
- switch (Status)
- {
- case STATUS_WAIT_0:
- Status = WAIT_FAILED;
- goto WaitExit;
+ pti = PsGetCurrentThreadWin32Thread();
- case STATUS_WAIT_2:
+ W32Process = (PPROCESSINFO)Process->Win32Process;
+
+ if ( PsGetProcessExitProcessCalled(Process) ||
+ !W32Process ||
+ pti->ppi == W32Process)
+ {
+ ObDereferenceObject(Process);
+ UserLeave();
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return WAIT_FAILED;
+ }
+
+ Handles[0] = Process;
+ Handles[1] = W32Process->InputIdleEvent;
+ Handles[2] = pti->MessageQueue->NewMessages; // pEventQueueServer; IntMsqSetWakeMask returns hEventQueueClient
+
+ if (!Handles[1])
+ {
+ ObDereferenceObject(Process);
+ UserLeave();
+ return STATUS_SUCCESS; /* no event to wait on */
+ }
+
+ if (dwMilliseconds != INFINITE)
+ Timeout.QuadPart = (LONGLONG) dwMilliseconds * (LONGLONG) -10000;
+
+ W32Process->W32PF_flags |= W32PF_WAITFORINPUTIDLE;
+ for (pti = W32Process->ptiList; pti; pti = pti->ptiSibling)
+ {
+ pti->TIF_flags |= TIF_WAITFORINPUTIDLE;
+ pti->pClientInfo->dwTIFlags = pti->TIF_flags;
+ }
+
+ DPRINT("WFII: ppi 0x%x\n",W32Process);
+ DPRINT("WFII: waiting for %p\n", Handles[1] );
+ do
+ {
+ UserLeave();
+ Status = KeWaitForMultipleObjects( 3,
+ Handles,
+ WaitAny,
+ UserRequest,
+ UserMode,
+ FALSE,
+ dwMilliseconds == INFINITE ? NULL : &Timeout,
+ NULL);
+ UserEnterExclusive();
+
+ if (!NT_SUCCESS(Status))
{
- USER_MESSAGE Msg;
- co_IntPeekMessage( &Msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE );
- break;
+ SetLastNtError(Status);
+ Status = WAIT_FAILED;
+ goto WaitExit;
}
- case STATUS_USER_APC:
- case STATUS_ALERTED:
- case STATUS_TIMEOUT:
- DPRINT1("WFII: timeout\n");
- Status = STATUS_TIMEOUT;
- goto WaitExit;
+ switch (Status)
+ {
+ case STATUS_WAIT_0:
+ goto WaitExit;
- default:
- DPRINT1("WFII: finished\n");
- Status = STATUS_SUCCESS;
- goto WaitExit;
- }
+ case STATUS_WAIT_2:
+ {
+ MSG Msg;
+ co_IntGetPeekMessage( &Msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE, FALSE);
+ DPRINT1("WFII: WAIT 2\n");
+ }
+ break;
- if (dwMilliseconds != INFINITE)
- {
- Elapsed = EngGetTickCount() - StartTime;
+ case STATUS_TIMEOUT:
+ DPRINT1("WFII: timeout\n");
+ case WAIT_FAILED:
+ goto WaitExit;
- if (Elapsed > Run)
- Status = STATUS_TIMEOUT;
- break;
- }
- }
- while (1);
+ default:
+ DPRINT1("WFII: finished\n");
+ Status = STATUS_SUCCESS;
+ goto WaitExit;
+ }
+ }
+ while (TRUE);
WaitExit:
- if (W32Process->InputIdleEvent)
- {
- EngFreeMem((PVOID)W32Process->InputIdleEvent);
- W32Process->InputIdleEvent = NULL;
- }
- ObDereferenceObject(Process);
- UserLeave();
- return Status;
+ for (pti = W32Process->ptiList; pti; pti = pti->ptiSibling)
+ {
+ pti->TIF_flags &= ~TIF_WAITFORINPUTIDLE;
+ pti->pClientInfo->dwTIFlags = pti->TIF_flags;
+ }
+ W32Process->W32PF_flags &= ~W32PF_WAITFORINPUTIDLE;
+ ObDereferenceObject(Process);
+ UserLeave();
+ return Status;
}
/* EOF */