-/*
- * ReactOS W32 Subsystem
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/* INCLUDES ******************************************************************/
-#include <w32k.h>
+#include <win32k.h>
#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)
+
typedef struct
{
UINT uFlags;
Size = sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData;
break;
+ case WM_COPYGLOBALDATA:
+ Size = wParam;
+ break;
+
default:
- assert(FALSE);
+ ASSERT(FALSE);
Size = 0;
break;
}
}
static NTSTATUS
-PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
+PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL NonPagedPoolNeeded)
{
NCCALCSIZE_PARAMS *UnpackedNcCalcsize;
NCCALCSIZE_PARAMS *PackedNcCalcsize;
CREATESTRUCTW *UnpackedCs;
CREATESTRUCTW *PackedCs;
- PUNICODE_STRING WindowName;
+ PLARGE_STRING WindowName;
PUNICODE_STRING ClassName;
+ POOL_TYPE PoolType;
UINT Size;
PCHAR CsData;
*lParamPacked = lParam;
+
+ if (NonPagedPoolNeeded)
+ PoolType = NonPagedPool;
+ else
+ PoolType = PagedPool;
+
if (WM_NCCALCSIZE == Msg && wParam)
{
+
UnpackedNcCalcsize = (NCCALCSIZE_PARAMS *) lParam;
- if (UnpackedNcCalcsize->lppos != (PWINDOWPOS) (UnpackedNcCalcsize + 1))
+ PackedNcCalcsize = ExAllocatePoolWithTag(PoolType,
+ sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS),
+ TAG_MSG);
+
+ if (NULL == PackedNcCalcsize)
{
- PackedNcCalcsize = ExAllocatePoolWithTag(PagedPool,
- sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS),
- TAG_MSG);
- if (NULL == PackedNcCalcsize)
- {
- DPRINT1("Not enough memory to pack lParam\n");
- return STATUS_NO_MEMORY;
- }
- RtlCopyMemory(PackedNcCalcsize, UnpackedNcCalcsize, sizeof(NCCALCSIZE_PARAMS));
- PackedNcCalcsize->lppos = (PWINDOWPOS) (PackedNcCalcsize + 1);
- RtlCopyMemory(PackedNcCalcsize->lppos, UnpackedNcCalcsize->lppos, sizeof(WINDOWPOS));
- *lParamPacked = (LPARAM) PackedNcCalcsize;
+ 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 = (PUNICODE_STRING) UnpackedCs->lpszName;
+ 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) + ClassName->Length + sizeof(WCHAR);
}
- PackedCs = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
+ PackedCs = ExAllocatePoolWithTag(PoolType, Size, TAG_MSG);
if (NULL == PackedCs)
{
DPRINT1("Not enough memory to pack lParam\n");
*lParamPacked = (LPARAM) PackedCs;
}
+ else if (PoolType == NonPagedPool)
+ {
+ PMSGMEMORY MsgMemoryEntry;
+ PVOID PackedData;
+
+ 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;
+ }
+
return STATUS_SUCCESS;
}
static NTSTATUS
-UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam)
+UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL NonPagedPoolUsed)
{
NCCALCSIZE_PARAMS *UnpackedParams;
NCCALCSIZE_PARAMS *PackedParams;
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;
+ }
ASSERT(FALSE);
{
BOOL SameThread = FALSE;
- if (Window->ti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->ThreadInfo)
+ if (Window->pti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread()))
SameThread = TRUE;
- if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROC))) ||
+ if ((!SameThread && (Window->pti->fsHooks & HOOKID_TO_FLAG(WH_CALLWNDPROC))) ||
(SameThread && ISITHOOKED(WH_CALLWNDPROC)) )
{
CWPSTRUCT CWP;
co_HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, SameThread, (LPARAM)&CWP );
}
}
+
static
VOID
FASTCALL
{
BOOL SameThread = FALSE;
- if (Window->ti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->ThreadInfo)
+ if (Window->pti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread()))
SameThread = TRUE;
- if ((!SameThread && (Window->ti->Hooks & HOOKID_TO_FLAG(WH_CALLWNDPROCRET))) ||
+ if ((!SameThread && (Window->pti->fsHooks & HOOKID_TO_FLAG(WH_CALLWNDPROCRET))) ||
(SameThread && ISITHOOKED(WH_CALLWNDPROCRET)) )
{
CWPRETSTRUCT CWPR;
LARGE_INTEGER TickCount;
LONG Time;
LRESULT retval;
+ PMSGMEMORY MsgMemoryEntry;
+ INT lParamBufferSize;
+ LPARAM lParamPacked;
PWINDOW_OBJECT Window = NULL;
if (pMsg->hwnd)
}
}
// Need a window!
- if (!Window) return 0;
-
- retval = co_IntPostOrSendMessage(pMsg->hwnd, pMsg->message, pMsg->wParam, pMsg->lParam);
+ if ( !Window || !Window->Wnd ) return 0;
- if (pMsg->message == WM_PAINT)
+ /* See if this message type is present in the table */
+ MsgMemoryEntry = FindMsgMemory(pMsg->message);
+ if ( !MsgMemoryEntry )
{
- /* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
- HRGN hrgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
- co_UserGetUpdateRgn( Window, hrgn, TRUE );
- GreDeleteObject( hrgn );
+ lParamBufferSize = -1;
}
- return retval;
-}
-
-
-BOOL
-APIENTRY
-NtUserCallMsgFilter(
- LPMSG lpmsg,
- INT code)
-{
- BOOL BadChk = FALSE, Ret = TRUE;
- 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);
-
- if (!co_HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)&Msg))
- {
- Ret = co_HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)&Msg);
- }
-
- _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)
-
-CLEANUP:
- DPRINT("Leave NtUserCallMsgFilter. ret=%i\n", _ret_);
- UserLeave();
- END_CLEANUP;
-}
-
-LRESULT APIENTRY
-NtUserDispatchMessage(PMSG UnsafeMsgInfo)
-{
- LRESULT Res = 0;
- BOOL Hit = FALSE;
- MSG SafeMsg;
-
- UserEnterExclusive();
- _SEH2_TRY
+ else
{
- ProbeForRead(UnsafeMsgInfo, sizeof(MSG), 1);
- RtlCopyMemory(&SafeMsg, UnsafeMsgInfo, sizeof(MSG));
+ lParamBufferSize = MsgMemorySize(MsgMemoryEntry, pMsg->wParam, pMsg->lParam);
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+
+ if (! NT_SUCCESS(PackParam(&lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam, FALSE)))
{
- SetLastNtError(_SEH2_GetExceptionCode());
- Hit = TRUE;
+ DPRINT1("Failed to pack message parameters\n");
+ return 0;
}
- _SEH2_END;
-
- if (!Hit) Res = IntDispatchMessage(&SafeMsg);
-
- UserLeave();
- return Res;
-}
-
-
-BOOL APIENTRY
-NtUserTranslateMessage(LPMSG lpMsg,
- HKL dwhkl)
-{
- NTSTATUS Status;
- MSG SafeMsg;
- DECLARE_RETURN(BOOL);
-
- DPRINT("Enter NtUserTranslateMessage\n");
- UserEnterExclusive();
- Status = MmCopyFromCaller(&SafeMsg, lpMsg, sizeof(MSG));
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( FALSE);
- }
+ retval = co_IntCallWindowProc( Window->Wnd->lpfnWndProc,
+ !Window->Wnd->Unicode,
+ pMsg->hwnd,
+ pMsg->message,
+ pMsg->wParam,
+ lParamPacked,
+ lParamBufferSize);
- RETURN( IntTranslateKbdMessage(&SafeMsg, dwhkl));
+ if (! NT_SUCCESS(UnpackParam(lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam, FALSE)))
+ {
+ DPRINT1("Failed to unpack message parameters\n");
+ }
-CLEANUP:
- DPRINT("Leave NtUserTranslateMessage: ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ 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)
{
{
WPARAM wParam;
PSYSTEM_CURSORINFO CurInfo;
+ CurInfo = IntGetSysCursorInfo();
- if(!IntGetWindowStationObject(InputWindowStation))
- {
- break;
- }
- CurInfo = IntGetSysCursorInfo(InputWindowStation);
wParam = (WPARAM)(CurInfo->ButtonsDown);
- ObDereferenceObject(InputWindowStation);
co_IntSendMessage(Msg->hwnd, WM_MOUSEMOVE, wParam, Msg->lParam);
co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(HTCLIENT, Msg->message));
}
BOOL FASTCALL
-co_IntActivateWindowMouse(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, PWINDOW_OBJECT MsgWindow,
- USHORT *HitTest)
+co_IntActivateWindowMouse(
+ PUSER_MESSAGE_QUEUE ThreadQueue,
+ LPMSG Msg,
+ PWINDOW_OBJECT MsgWindow,
+ USHORT *HitTest)
{
ULONG Result;
PWINDOW_OBJECT Parent;
}
BOOL FASTCALL
-co_IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *HitTest, BOOL Remove)
+co_IntTranslateMouseMessage(
+ PUSER_MESSAGE_QUEUE ThreadQueue,
+ LPMSG Msg,
+ USHORT *HitTest,
+ BOOL Remove)
{
PWINDOW_OBJECT Window;
USER_REFERENCE_ENTRY Ref, DesktopRef;
UserRefObjectCo(Window, &Ref);
- if(ThreadQueue == Window->MessageQueue &&
- ThreadQueue->CaptureWindow != Window->hSelf)
+ if ( ThreadQueue == Window->pti->MessageQueue &&
+ ThreadQueue->CaptureWindow != Window->hSelf)
{
/* only send WM_NCHITTEST messages if we're not capturing the window! */
*HitTest = co_IntSendMessage(Window->hSelf, WM_NCHITTEST, 0,
MAKELONG(Msg->pt.x, Msg->pt.y));
- if(*HitTest == (USHORT)HTTRANSPARENT)
+ if (*HitTest == (USHORT)HTTRANSPARENT)
{
PWINDOW_OBJECT DesktopWindow;
HWND hDesktop = IntGetDesktopWindow();
- if((DesktopWindow = UserGetWindowObject(hDesktop)))
+ if ((DesktopWindow = UserGetWindowObject(hDesktop)))
{
PWINDOW_OBJECT Wnd;
UserRefObjectCo(DesktopWindow, &DesktopRef);
- co_WinPosWindowFromPoint(DesktopWindow, Window->MessageQueue, &Msg->pt, &Wnd);
- if(Wnd)
+ co_WinPosWindowFromPoint(DesktopWindow, Window->pti->MessageQueue, &Msg->pt, &Wnd);
+ if (Wnd)
{
- if(Wnd != Window)
+ if (Wnd != Window)
{
/* post the message to the other window */
Msg->hwnd = Wnd->hSelf;
- if(!(Wnd->Status & WINDOWSTATUS_DESTROYING))
+ if(!(Wnd->state & WINDOWSTATUS_DESTROYING))
{
- MsqPostMessage(Wnd->MessageQueue, Msg, FALSE,
+ MsqPostMessage(Wnd->pti->MessageQueue, Msg, FALSE,
Msg->message == WM_MOUSEMOVE ? QS_MOUSEMOVE :
QS_MOUSEBUTTON);
}
*HitTest = HTCLIENT;
}
- if(IS_BTN_MESSAGE(Msg->message, DOWN))
+ if ( gspv.bMouseClickLock &&
+ ( (Msg->message == WM_LBUTTONUP) ||
+ (Msg->message == WM_LBUTTONDOWN) ) )
+ {
+ if (MsqIsClkLck(Msg, Remove))
+ {
+ // FIXME: drop the message, hack: use WM_NULL
+ Msg->message = WM_NULL;
+ }
+ }
+
+ if (IS_BTN_MESSAGE(Msg->message, DOWN))
{
/* generate double click messages, if necessary */
if ((((*HitTest) != HTCLIENT) ||
- (Window->Wnd->Class->Style & CS_DBLCLKS)) &&
+ (Window->Wnd->pcls->style & CS_DBLCLKS)) &&
MsqIsDblClk(Msg, Remove))
{
Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;
if ((*HitTest) != HTCLIENT)
{
Msg->message += WM_NCMOUSEMOVE - WM_MOUSEMOVE;
- if((Msg->message == WM_NCRBUTTONUP) &&
- (((*HitTest) == HTCAPTION) || ((*HitTest) == HTSYSMENU)))
+ if ( (Msg->message == WM_NCRBUTTONUP) &&
+ (((*HitTest) == HTCAPTION) || ((*HitTest) == HTSYSMENU)) )
{
Msg->message = WM_CONTEXTMENU;
Msg->wParam = (WPARAM)Window->hSelf;
}
Msg->lParam = MAKELONG(Msg->pt.x, Msg->pt.y);
}
- else if(ThreadQueue->MoveSize == NULL &&
- ThreadQueue->MenuOwner == NULL)
+ 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->ClientRect.left,
- Msg->pt.y - (WORD)Window->Wnd->ClientRect.top);
+ Msg->pt.x - (WORD)Window->Wnd->rcClient.left,
+ Msg->pt.y - (WORD)Window->Wnd->rcClient.top);
}
}
return FALSE;
}
+BOOL ProcessMouseMessage(MSG* Msg, USHORT HitTest, UINT RemoveMsg)
+{
+ 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;
+ }
+
+ return TRUE;
+}
+BOOL ProcessKeyboardMessage(MSG* Msg, UINT RemoveMsg)
+{
+ EVENTMSG Event;
+
+ 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 (co_HOOK_CallHooks( WH_KEYBOARD,
+ RemoveMsg ? HC_ACTION : HC_NOREMOVE,
+ LOWORD(Msg->wParam),
+ Msg->lParam))
+ {
+ if (ISITHOOKED(WH_CBT))
+ {
+ /* skip this message */
+ co_HOOK_CallHooks( WH_CBT,
+ HCBT_KEYSKIPPED,
+ LOWORD(Msg->wParam),
+ Msg->lParam );
+ }
+ return FALSE;
+ }
+ return TRUE;
+}
/*
* Internal version of PeekMessage() doing all the work
*/
BOOL FASTCALL
-co_IntPeekMessage(PUSER_MESSAGE Msg,
- HWND hWnd,
- UINT MsgFilterMin,
- UINT MsgFilterMax,
- UINT RemoveMsg)
+co_IntPeekMessage( PUSER_MESSAGE Msg,
+ PWINDOW_OBJECT Window,
+ UINT MsgFilterMin,
+ UINT MsgFilterMax,
+ UINT RemoveMsg )
{
PTHREADINFO pti;
LARGE_INTEGER LargeTickCount;
BOOL Present, RemoveMessages;
USER_REFERENCE_ENTRY Ref;
USHORT HitTest;
- MOUSEHOOKSTRUCT MHook;
/* The queues and order in which they are checked are documented in the MSDN
article on GetMessage() */
ThreadQueue = pti->MessageQueue;
/* Inspect RemoveMsg flags */
- /* FIXME: The only flag we process is PM_REMOVE - processing of others must still be implemented */
+ /* 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;
+/*
+ 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:
Present = FALSE;
}
/* Now check for normal messages. */
- Present = co_MsqFindMessage(ThreadQueue,
- FALSE,
- RemoveMessages,
- hWnd,
- MsgFilterMin,
- MsgFilterMax,
- &Message);
+ Present = co_MsqFindMessage( ThreadQueue,
+ FALSE,
+ RemoveMessages,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ &Message );
if (Present)
{
RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
}
/* Check for hardware events. */
- Present = co_MsqFindMessage(ThreadQueue,
- TRUE,
- RemoveMessages,
- hWnd,
- MsgFilterMin,
- MsgFilterMax,
- &Message);
+ Present = co_MsqFindMessage( ThreadQueue,
+ TRUE,
+ RemoveMessages,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ &Message );
if (Present)
{
RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
;
/* Check for paint messages. */
- if (IntGetPaintMessage(hWnd, MsgFilterMin, MsgFilterMax, pti, &Msg->Msg, RemoveMessages))
+ if ( IntGetPaintMessage( Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ pti,
+ &Msg->Msg,
+ RemoveMessages))
{
Msg->FreeLParam = FALSE;
goto MsgExit;
}
- if (ThreadQueue->WakeMask & QS_TIMER)
- if (PostTimerMessages(hWnd)) // If there are timers ready,
- goto CheckMessages; // go back and process them.
-
- // LOL! Polling Timer Queue? How much time is spent doing this?
- /* Check for WM_(SYS)TIMER messages */
- Present = MsqGetTimerMessage(ThreadQueue, hWnd, MsgFilterMin, MsgFilterMax,
- &Msg->Msg, RemoveMessages);
- if (Present)
- {
- Msg->FreeLParam = FALSE;
- goto MessageFound;
- }
+ if (PostTimerMessages(Window))
+ goto CheckMessages;
if(Present)
{
{
PWINDOW_OBJECT MsgWindow = NULL;
- if(Msg->Msg.hwnd && (MsgWindow = UserGetWindowObject(Msg->Msg.hwnd)) &&
- Msg->Msg.message >= WM_MOUSEFIRST && Msg->Msg.message <= WM_MOUSELAST)
+ /* 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 */
+ 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 */
if(ThreadQueue->CaptureWindow == NULL)
{
co_IntSendHitTestMessages(ThreadQueue, &Msg->Msg);
- if((Msg->Msg.message != WM_MOUSEMOVE && Msg->Msg.message != WM_NCMOUSEMOVE) &&
+
+ 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))
+ co_IntActivateWindowMouse(ThreadQueue, &Msg->Msg, MsgWindow, &HitTest) )
{
UserDerefObjectCo(MsgWindow);
/* eat the message, search again */
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 */
+ 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) &&
- Msg->Msg.message >= WM_MOUSEFIRST &&
- Msg->Msg.message <= WM_MOUSELAST )
- {
- MHook.pt = Msg->Msg.pt;
- MHook.hwnd = Msg->Msg.hwnd;
- MHook.wHitTestCode = HitTest;
- MHook.dwExtraInfo = 0;
- if (co_HOOK_CallHooks( WH_MOUSE,
- RemoveMsg ? HC_ACTION : HC_NOREMOVE,
- Msg->Msg.message,
- (LPARAM)&MHook ))
- {
- if (ISITHOOKED(WH_CBT))
- {
- MHook.pt = Msg->Msg.pt;
- MHook.hwnd = Msg->Msg.hwnd;
- MHook.wHitTestCode = HitTest;
- MHook.dwExtraInfo = 0;
- co_HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED,
- Msg->Msg.message, (LPARAM)&MHook);
- }
- return FALSE;
- }
- }
- if ( ISITHOOKED(WH_KEYBOARD) &&
- (Msg->Msg.message == WM_KEYDOWN || Msg->Msg.message == WM_KEYUP) )
+ if ( ISITHOOKED(WH_MOUSE) && IS_MOUSE_MESSAGE(Msg->Msg.message))
{
- if (co_HOOK_CallHooks( WH_KEYBOARD,
- RemoveMsg ? HC_ACTION : HC_NOREMOVE,
- LOWORD(Msg->Msg.wParam),
- Msg->Msg.lParam))
- {
- if (ISITHOOKED(WH_CBT))
- {
- /* skip this message */
- co_HOOK_CallHooks( WH_CBT, HCBT_KEYSKIPPED,
- LOWORD(Msg->Msg.wParam), Msg->Msg.lParam );
- }
- return FALSE;
- }
+ 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.
return Present;
}
-BOOL APIENTRY
-NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
- HWND hWnd,
- UINT MsgFilterMin,
- UINT MsgFilterMax,
- UINT RemoveMsg)
+static NTSTATUS FASTCALL
+CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg, PMSGMEMORY MsgMemoryEntry)
{
NTSTATUS Status;
- BOOL Present;
- NTUSERGETMESSAGEINFO Info;
- PWINDOW_OBJECT Window;
- PMSGMEMORY MsgMemoryEntry;
- PVOID UserMem;
+
+ PVOID KernelMem;
UINT Size;
- USER_MESSAGE Msg;
- DECLARE_RETURN(BOOL);
- DPRINT("Enter NtUserPeekMessage\n");
- UserEnterExclusive();
+ *KernelModeMsg = *UserModeMsg;
- /* Validate input */
- if (hWnd && hWnd != INVALID_HANDLE_VALUE)
+ /* See if this message type is present in the table */
+ if (NULL == MsgMemoryEntry)
{
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- RETURN(-1);
- }
+ /* Not present, no copying needed */
+ return STATUS_SUCCESS;
}
- if (MsgFilterMax < MsgFilterMin)
- {
- MsgFilterMin = 0;
- MsgFilterMax = 0;
- }
+ /* Determine required size */
+ Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
- Present = co_IntPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg);
- if (Present)
+ if (0 != Size)
{
-
- Info.Msg = Msg.Msg;
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
- if (NULL == MsgMemoryEntry)
+ /* Allocate kernel mem */
+ KernelMem = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
+ if (NULL == KernelMem)
{
- /* Not present, no copying needed */
- Info.LParamSize = 0;
+ DPRINT1("Not enough memory to copy message to kernel mem\n");
+ return STATUS_NO_MEMORY;
}
- else
+ KernelModeMsg->lParam = (LPARAM) KernelMem;
+
+ /* Copy data if required */
+ if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_READ))
{
- /* 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);
+ Status = MmCopyFromCaller(KernelMem, (PVOID) UserModeMsg->lParam, Size);
if (! NT_SUCCESS(Status))
{
- ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
- &Info.LParamSize, MEM_RELEASE);
- SetLastNtError(Status);
- RETURN( (BOOL) -1);
+ DPRINT1("Failed to copy message to kernel: invalid usermode buffer\n");
+ ExFreePoolWithTag(KernelMem, TAG_MSG);
+ return Status;
}
- Info.Msg.lParam = (LPARAM) UserMem;
}
- if (RemoveMsg && Msg.FreeLParam && 0 != Msg.Msg.lParam)
+ else
{
- ExFreePool((void *) Msg.Msg.lParam);
+ /* Make sure we don't pass any secrets to usermode */
+ RtlZeroMemory(KernelMem, Size);
}
- Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
- if (! NT_SUCCESS(Status))
+ }
+ else
+ {
+ KernelModeMsg->lParam = 0;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS FASTCALL
+CopyMsgToUserMem(MSG *UserModeMsg, MSG *KernelModeMsg)
+{
+ NTSTATUS Status;
+ PMSGMEMORY MsgMemoryEntry;
+ UINT Size;
+
+ /* 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;
+ }
+
+ /* Determine required size */
+ Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
+
+ if (0 != Size)
+ {
+ /* Copy data if required */
+ if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_WRITE))
{
- SetLastNtError(Status);
- RETURN( (BOOL) -1);
+ 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;
+ }
}
- }
- RETURN( Present);
+ ExFreePool((PVOID) KernelModeMsg->lParam);
+ }
-CLEANUP:
- DPRINT("Leave NtUserPeekMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ return STATUS_SUCCESS;
}
static BOOL FASTCALL
-co_IntWaitMessage(HWND Wnd,
- UINT MsgFilterMin,
- UINT MsgFilterMax)
+co_IntWaitMessage( PWINDOW_OBJECT Window,
+ UINT MsgFilterMin,
+ UINT MsgFilterMax )
{
PTHREADINFO pti;
PUSER_MESSAGE_QUEUE ThreadQueue;
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
USER_MESSAGE Msg;
pti = PsGetCurrentThreadWin32Thread();
do
{
- if (co_IntPeekMessage(&Msg, Wnd, MsgFilterMin, MsgFilterMax, PM_NOREMOVE))
+ if ( co_IntPeekMessage( &Msg,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ PM_NOREMOVE))
{
return TRUE;
}
-
/* Nothing found. Wait for new messages. */
- Status = co_MsqWaitForNewMessages(ThreadQueue, Wnd, MsgFilterMin, MsgFilterMax);
+ Status = co_MsqWaitForNewMessages( ThreadQueue,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax);
}
- while ((STATUS_WAIT_0 <= Status && Status <= STATUS_WAIT_63) || STATUS_TIMEOUT == Status);
+ while ( (STATUS_WAIT_0 <= Status && Status <= STATUS_WAIT_63) ||
+ STATUS_TIMEOUT == Status );
- SetLastNtError(Status);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ DPRINT1("Exit co_IntWaitMessage on error!\n");
+ }
return FALSE;
}
-BOOL APIENTRY
-NtUserGetMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
- 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 FASTCALL
+co_IntGetPeekMessage( PMSG pMsg,
+ HWND hWnd,
+ UINT MsgFilterMin,
+ UINT MsgFilterMax,
+ UINT RemoveMsg,
+ BOOL bGMSG )
{
- 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;
+ BOOL Present;
+ PWINDOW_OBJECT Window;
USER_MESSAGE Msg;
- DECLARE_RETURN(BOOL);
-// USER_REFERENCE_ENTRY Ref;
- DPRINT("Enter NtUserGetMessage\n");
- UserEnterExclusive();
+ if ( hWnd == HWND_TOPMOST ||
+ hWnd == HWND_BROADCAST )
+ hWnd = HWND_BOTTOM;
/* Validate input */
- if (hWnd && !(Window = UserGetWindowObject(hWnd)))
+ if (hWnd && hWnd != HWND_BOTTOM)
{
- RETURN(-1);
+ if (!(Window = UserGetWindowObject(hWnd)))
+ {
+ if (bGMSG)
+ return -1;
+ else
+ return FALSE;
+ }
+ }
+ else
+ {
+ Window = (PWINDOW_OBJECT)hWnd;
}
-
-// if (Window) UserRefObjectCo(Window, &Ref);
if (MsgFilterMax < MsgFilterMin)
{
do
{
- GotMessage = co_IntPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE);
- if (GotMessage)
+ Present = co_IntPeekMessage( &Msg,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
+ RemoveMsg );
+ if (Present)
{
- 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;
- }
+ RtlCopyMemory( pMsg, &Msg.Msg, sizeof(MSG));
+
+ if (bGMSG)
+ return (WM_QUIT != pMsg->message);
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);
+ return TRUE;
+ }
- 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);
- }
+ if ( bGMSG && !co_IntWaitMessage(Window, MsgFilterMin, MsgFilterMax) )
+ {
+ return -1;
}
- else if (! co_IntWaitMessage(hWnd, MsgFilterMin, MsgFilterMax))
+ else
{
- RETURN( (BOOL) -1);
+ if (!(RemoveMsg & PM_NOYIELD))
+ {
+ // Yield this thread!
+ UserLeave();
+ ZwYieldExecution();
+ UserEnterExclusive();
+ // Fall through to fail.
+ }
}
}
- while (! GotMessage);
-
- RETURN( WM_QUIT != Info.Msg.message);
+ while( bGMSG && !Present );
-CLEANUP:
-// if (Window) UserDerefObjectCo(Window);
-
- DPRINT("Leave NtUserGetMessage\n");
- UserLeave();
- END_CLEANUP;
+ return FALSE;
}
-
-static NTSTATUS FASTCALL
-CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg, PMSGMEMORY MsgMemoryEntry)
+BOOL FASTCALL
+UserPostThreadMessage( DWORD idThread,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam )
{
+ MSG Message;
+ PETHREAD peThread;
+ PTHREADINFO pThread;
+ LARGE_INTEGER LargeTickCount;
NTSTATUS Status;
- PVOID KernelMem;
- UINT Size;
-
- *KernelModeMsg = *UserModeMsg;
+ DPRINT1("UserPostThreadMessage wParam 0x%x lParam 0x%x\n", wParam,lParam);
- /* See if this message type is present in the table */
- if (NULL == MsgMemoryEntry)
+ if (FindMsgMemory(Msg) != 0)
{
- /* Not present, no copying needed */
- return STATUS_SUCCESS;
+ SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
+ return FALSE;
}
- /* Determine required size */
- Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
+ Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
- if (0 != Size)
+ if( Status == STATUS_SUCCESS )
{
- /* Allocate kernel mem */
- KernelMem = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
- if (NULL == KernelMem)
+ pThread = (PTHREADINFO)peThread->Tcb.Win32Thread;
+ if( !pThread ||
+ !pThread->MessageQueue ||
+ (pThread->TIF_flags & TIF_INCLEANUP))
{
- DPRINT1("Not enough memory to copy message to kernel mem\n");
- return STATUS_NO_MEMORY;
+ ObDereferenceObject( peThread );
+ return FALSE;
}
- 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);
- }
+ 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
{
- KernelModeMsg->lParam = 0;
+ SetLastNtError( Status );
}
-
- return STATUS_SUCCESS;
+ return FALSE;
}
-static NTSTATUS FASTCALL
-CopyMsgToUserMem(MSG *UserModeMsg, MSG *KernelModeMsg)
+BOOL FASTCALL
+UserPostMessage( HWND Wnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam )
{
- NTSTATUS Status;
- PMSGMEMORY MsgMemoryEntry;
- UINT Size;
+ PTHREADINFO pti;
+ MSG Message;
+ LARGE_INTEGER LargeTickCount;
- /* See if this message type is present in the table */
- MsgMemoryEntry = FindMsgMemory(UserModeMsg->message);
- if (NULL == MsgMemoryEntry)
+ if (FindMsgMemory(Msg) != 0)
{
- /* Not present, no copying needed */
- return STATUS_SUCCESS;
- }
-
- /* Determine required size */
- Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
-
- 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;
- }
- }
-
- ExFreePool((PVOID) KernelModeMsg->lParam);
+ SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
+ return FALSE;
}
- return STATUS_SUCCESS;
-}
-
-BOOL FASTCALL
-UserPostMessage(HWND Wnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
-{
- PTHREADINFO pti;
- MSG UserModeMsg, KernelModeMsg;
- LARGE_INTEGER LargeTickCount;
- NTSTATUS Status;
- PMSGMEMORY MsgMemoryEntry;
+ if (!Wnd)
+ return UserPostThreadMessage( PtrToInt(PsGetCurrentThreadId()),
+ Msg,
+ wParam,
+ lParam);
- pti = PsGetCurrentThreadWin32Thread();
- if (WM_QUIT == Msg)
- {
- MsqPostQuitMessage(pti->MessageQueue, wParam);
- }
- else if (Wnd == HWND_BROADCAST)
+ if (Wnd == HWND_BROADCAST)
{
HWND *List;
PWINDOW_OBJECT DesktopWindow;
PWINDOW_OBJECT Window;
Window = UserGetWindowObject(Wnd);
- if (NULL == Window)
+ if ( !Window || !Window->Wnd )
{
return FALSE;
}
- if(Window->Status & WINDOWSTATUS_DESTROYING)
+
+ pti = Window->Wnd->head.pti;
+ if ( pti->TIF_flags & TIF_INCLEANUP )
{
- DPRINT1("Attempted to post message to window 0x%x that is being destroyed!\n", Wnd);
- /* FIXME - last error code? */
+ DPRINT1("Attempted to post message to window 0x%x when the thread is in cleanup!\n", Wnd);
return FALSE;
}
- UserModeMsg.hwnd = Wnd;
- UserModeMsg.message = Msg;
- UserModeMsg.wParam = wParam;
- UserModeMsg.lParam = lParam;
- MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
- Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
- if (! NT_SUCCESS(Status))
+ if ( Window->state & WINDOWSTATUS_DESTROYING )
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ DPRINT1("Attempted to post message to window 0x%x that is being destroyed!\n", Wnd);
+ /* FIXME - last error code? */
return FALSE;
}
- IntGetCursorLocation(pti->Desktop->WindowStation,
- &KernelModeMsg.pt);
- KeQueryTickCount(&LargeTickCount);
- KernelModeMsg.time = MsqCalculateMessageTime(&LargeTickCount);
- MsqPostMessage(Window->MessageQueue, &KernelModeMsg,
- NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam,
- QS_POSTMESSAGE);
- }
-
- return TRUE;
-}
-
-
-BOOL APIENTRY
-NtUserPostMessage(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
-{
- DECLARE_RETURN(BOOL);
-
- DPRINT("Enter NtUserPostMessage\n");
- UserEnterExclusive();
-
- RETURN(UserPostMessage(hWnd, Msg, wParam, lParam));
-CLEANUP:
- DPRINT("Leave NtUserPostMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
-
-
-
-BOOL APIENTRY
-NtUserPostThreadMessage(DWORD idThread,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
-{
- MSG UserModeMsg, KernelModeMsg;
- PETHREAD peThread;
- PTHREADINFO pThread;
- NTSTATUS Status;
- PMSGMEMORY MsgMemoryEntry;
- DECLARE_RETURN(BOOL);
-
- DPRINT("Enter NtUserPostThreadMessage\n");
- UserEnterExclusive();
-
- Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
-
- if( Status == STATUS_SUCCESS )
- {
- pThread = (PTHREADINFO)peThread->Tcb.Win32Thread;
- if( !pThread || !pThread->MessageQueue )
+ if (WM_QUIT == Msg)
{
- ObDereferenceObject( peThread );
- RETURN( FALSE);
+ MsqPostQuitMessage(Window->pti->MessageQueue, wParam);
}
-
- UserModeMsg.hwnd = NULL;
- UserModeMsg.message = Msg;
- UserModeMsg.wParam = wParam;
- UserModeMsg.lParam = lParam;
- MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
- Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
- if (! NT_SUCCESS(Status))
+ else
{
- ObDereferenceObject( peThread );
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN( FALSE);
+ 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);
}
- MsqPostMessage(pThread->MessageQueue, &KernelModeMsg,
- NULL != MsgMemoryEntry && 0 != KernelModeMsg.lParam,
- QS_POSTMESSAGE);
- ObDereferenceObject( peThread );
- RETURN( TRUE);
- }
- else
- {
- SetLastNtError( Status );
- RETURN( FALSE);
}
-
-CLEANUP:
- DPRINT("Leave NtUserPostThreadMessage, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ return TRUE;
}
-DWORD APIENTRY
-NtUserQuerySendMessage(DWORD Unknown0)
-{
- UNIMPLEMENTED;
-
- return 0;
-}
LRESULT FASTCALL
-co_IntSendMessage(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
+co_IntSendMessage( HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam )
{
ULONG_PTR Result = 0;
if(co_IntSendMessageTimeout(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result))
static
LRESULT FASTCALL
-co_IntSendMessageTimeoutSingle(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam,
- UINT uFlags,
- UINT uTimeout,
- ULONG_PTR *uResult)
+co_IntSendMessageTimeoutSingle( HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ UINT uFlags,
+ UINT uTimeout,
+ ULONG_PTR *uResult )
{
ULONG_PTR Result;
NTSTATUS Status;
IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
- if (NULL != Win32Thread &&
- Window->MessageQueue == Win32Thread->MessageQueue)
+ if ( NULL != Win32Thread &&
+ Window->pti->MessageQueue == Win32Thread->MessageQueue)
{
- if (Win32Thread->IsExiting)
+ if (Win32Thread->TIF_flags & TIF_INCLEANUP)
{
/* Never send messages to exiting threads */
RETURN( FALSE);
lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
}
- if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam)))
+ 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->WndProc, !Window->Wnd->Unicode, hWnd, Msg, wParam,
- lParamPacked,lParamBufferSize);
-
+ 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);
- if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam)))
+ if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
{
DPRINT1("Failed to unpack message parameters\n");
RETURN( TRUE);
RETURN( TRUE);
}
- if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->MessageQueue))
+ if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->pti->MessageQueue))
{
/* FIXME - Set a LastError? */
RETURN( FALSE);
}
- if (Window->Status & WINDOWSTATUS_DESTROYING)
+ if (Window->state & WINDOWSTATUS_DESTROYING)
{
/* FIXME - last error? */
DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
do
{
- Status = co_MsqSendMessage( Window->MessageQueue,
- hWnd,
- Msg,
- wParam,
- lParam,
- uTimeout,
- (uFlags & SMTO_BLOCK),
- MSQ_NORMAL,
- uResult);
+ 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->MessageQueue));
+ !MsqIsHung(Window->pti->MessageQueue));
IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
}
LRESULT FASTCALL
-co_IntSendMessageTimeout(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam,
- UINT uFlags,
- UINT uTimeout,
- ULONG_PTR *uResult)
+co_IntSendMessageTimeout( HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ UINT uFlags,
+ UINT uTimeout,
+ ULONG_PTR *uResult )
{
PWINDOW_OBJECT DesktopWindow;
HWND *Children;
return (LRESULT) TRUE;
}
+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;
+}
+
+LRESULT FASTCALL
+co_IntSendMessageWithCallBack( HWND hWnd,
+ 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);
+ }
+
+ 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);
+ }
+
+ Win32Thread = PsGetCurrentThreadWin32Thread();
+
+ IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
+
+ if (Win32Thread == NULL)
+ {
+ ASSERT(FALSE);
+ 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);
+ }
+
+ if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->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))
+ {
+
+ 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);
+
+ 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;
+ }
+
+ 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->pti->MessageQueue);
+ Message->CompletionCallback = CompletionCallback;
+ Message->CompletionCallbackContext = CompletionCallbackContext;
+ Message->HookMessage = MSQ_NORMAL | MSQ_SENTNOWAIT;
+ Message->HasPackedLParam = (lParamBufferSize > 0);
+
+ InsertTailList(&Window->pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
+ IntDereferenceMessageQueue(Window->pti->MessageQueue);
+
+ RETURN(TRUE);
+
+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! */
LRESULT FASTCALL
-co_IntPostOrSendMessage(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
+co_IntPostOrSendMessage( HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam )
{
ULONG_PTR Result;
PTHREADINFO pti;
PWINDOW_OBJECT Window;
- if(hWnd == HWND_BROADCAST)
+ if ( hWnd == HWND_BROADCAST )
{
return 0;
}
}
pti = PsGetCurrentThreadWin32Thread();
- if(Window->MessageQueue != pti->MessageQueue)
+
+ 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)) {
+ if ( !co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result) )
+ {
Result = 0;
}
}
}
LRESULT FASTCALL
-co_IntDoSendMessage(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam,
- PDOSENDMESSAGE dsm,
- PNTUSERSENDMESSAGEINFO UnsafeInfo)
+co_IntDoSendMessage( HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ PDOSENDMESSAGE dsm,
+ PNTUSERSENDMESSAGEINFO UnsafeInfo )
{
PTHREADINFO pti;
LRESULT Result = TRUE;
if (HWND_BROADCAST != hWnd)
{
Window = UserGetWindowObject(hWnd);
- if (NULL == Window)
+ if ( !Window || !Window->Wnd )
{
/* Tell usermode to not touch this one */
Info.HandledByKernel = TRUE;
MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
return 0;
}
- if (!Window->Wnd)
- return 0;
}
- /* FIXME: Check for an exiting window. */
+ /* 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();
- if (HWND_BROADCAST != hWnd && NULL != pti &&
- Window->MessageQueue == pti->MessageQueue)
+
+ // 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;
Info.Ansi = ! Window->Wnd->Unicode;
}
- IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
-
- if (Window->Wnd->IsSystem)
- {
- Info.Proc = (!Info.Ansi ? Window->Wnd->WndProc : Window->Wnd->WndProcExtra);
- }
- else
- {
- Info.Ansi = !Window->Wnd->Unicode;
- Info.Proc = Window->Wnd->WndProc;
- }
-
- IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, &Result);
-
+ Info.Ansi = !Window->Wnd->Unicode;
+ Info.Proc = Window->Wnd->lpfnWndProc;
}
else
{
UserModeMsg.wParam = wParam;
UserModeMsg.lParam = lParam;
MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
+
Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
if (! NT_SUCCESS(Status))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return (dsm ? 0 : -1);
}
+
if(!dsm)
{
- Result = co_IntSendMessage(KernelModeMsg.hwnd, KernelModeMsg.message,
- KernelModeMsg.wParam, KernelModeMsg.lParam);
+ 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);
+ Result = co_IntSendMessageTimeout( KernelModeMsg.hwnd,
+ KernelModeMsg.message,
+ KernelModeMsg.wParam,
+ KernelModeMsg.lParam,
+ dsm->uFlags,
+ dsm->uTimeout,
+ &dsm->Result );
}
+
Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
if (! NT_SUCCESS(Status))
{
return (LRESULT)Result;
}
-LRESULT APIENTRY
-NtUserSendMessageTimeout(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam,
- UINT uFlags,
- UINT uTimeout,
- ULONG_PTR *uResult,
- PNTUSERSENDMESSAGEINFO UnsafeInfo)
-{
- DOSENDMESSAGE dsm;
- LRESULT Result;
- DECLARE_RETURN(BOOL);
- DPRINT("Enter NtUserSendMessageTimeout\n");
- UserEnterExclusive();
+BOOL FASTCALL
+UserSendNotifyMessage( HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam )
+{
+ BOOL Result = TRUE;
- dsm.uFlags = uFlags;
- dsm.uTimeout = uTimeout;
- Result = co_IntDoSendMessage(hWnd, Msg, wParam, lParam, &dsm, UnsafeInfo);
- if(uResult != NULL && Result != 0)
+ 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;
+
+ 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 ( !(Window = UserGetWindowObject(hWnd)) ) return FALSE;
+
+ pti = PsGetCurrentThreadWin32Thread();
+
+ 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;
+}
+
+
+DWORD APIENTRY
+IntGetQueueStatus(BOOL ClearChanges)
+{
+ PTHREADINFO pti;
+ PUSER_MESSAGE_QUEUE Queue;
+ DWORD Result;
+ DECLARE_RETURN(DWORD);
+
+ DPRINT("Enter IntGetQueueStatus\n");
+
+ pti = PsGetCurrentThreadWin32Thread();
+ Queue = pti->MessageQueue;
+
+ Result = MAKELONG(Queue->QueueBits, Queue->ChangedBits);
+ if (ClearChanges)
+ {
+ Queue->ChangedBits = 0;
+ }
+
+ RETURN(Result);
+
+CLEANUP:
+ DPRINT("Leave IntGetQueueStatus, ret=%i\n",_ret_);
+ END_CLEANUP;
+}
+
+BOOL APIENTRY
+IntInitMessagePumpHook()
+{
+ if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti)
+ {
+ ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->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;
+}
+
+/** Functions ******************************************************************/
+
+BOOL APIENTRY
+NtUserPostMessage(HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ DECLARE_RETURN(BOOL);
+
+ DPRINT("Enter NtUserPostMessage\n");
+ UserEnterExclusive();
+
+ RETURN( UserPostMessage(hWnd, Msg, wParam, lParam));
+
+CLEANUP:
+ DPRINT("Leave NtUserPostMessage, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+
+BOOL APIENTRY
+NtUserPostThreadMessage(DWORD idThread,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ DECLARE_RETURN(BOOL);
+
+ DPRINT("Enter NtUserPostThreadMessage\n");
+ UserEnterExclusive();
+
+ RETURN( UserPostThreadMessage( idThread,
+ Msg,
+ wParam,
+ lParam));
+
+CLEANUP:
+ DPRINT("Leave NtUserPostThreadMessage, 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 )
+{
+ DOSENDMESSAGE dsm;
+ LRESULT Result;
+ DECLARE_RETURN(BOOL);
+
+ DPRINT("Enter NtUserSendMessageTimeout\n");
+ UserEnterExclusive();
+
+ dsm.uFlags = uFlags;
+ dsm.uTimeout = uTimeout;
+ Result = co_IntDoSendMessage(hWnd, Msg, wParam, lParam, &dsm, UnsafeInfo);
+ if(uResult != NULL && Result != 0)
{
NTSTATUS Status;
}
LRESULT APIENTRY
-NtUserSendMessage(HWND Wnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam,
- PNTUSERSENDMESSAGEINFO UnsafeInfo)
+NtUserSendMessage( HWND Wnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ PNTUSERSENDMESSAGEINFO UnsafeInfo )
{
DECLARE_RETURN(BOOL);
UserLeave();
END_CLEANUP;
}
+//////////
+BOOL APIENTRY
+NtUserWaitMessage(VOID)
+{
+ DECLARE_RETURN(BOOL);
-BOOL FASTCALL
-UserSendNotifyMessage(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
+ DPRINT("EnterNtUserWaitMessage\n");
+ UserEnterExclusive();
+
+ RETURN(co_IntWaitMessage(NULL, 0, 0));
+
+CLEANUP:
+ DPRINT("Leave NtUserWaitMessage, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+
+
+BOOL APIENTRY
+NtUserGetMessage( PNTUSERGETMESSAGEINFO UnsafeInfo,
+ 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 Result = TRUE;
- // Basicly the same as IntPostOrSendMessage
- if (hWnd == HWND_BROADCAST) //Handle Broadcast
+ 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)))
{
- HWND *List;
- PWINDOW_OBJECT DesktopWindow;
- ULONG i;
+ RETURN(-1);
+ }
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
- List = IntWinListChildren(DesktopWindow);
+// if (Window) UserRefObjectCo(Window, &Ref);
- if (List != NULL)
+ 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;
+}
+
+
+BOOL
+APIENTRY
+NtUserGetMessageX(
+ PMSG pMsg,
+ HWND hWnd,
+ UINT MsgFilterMin,
+ UINT MsgFilterMax)
+{
+ MSG Msg;
+ BOOL Ret = FALSE;
+ DECLARE_RETURN(BOOL);
+
+ DPRINT("Enter NtUserGetMessage\n");
+ UserEnterExclusive();
+
+ if ( (MsgFilterMin|MsgFilterMax) & ~WM_MAXIMUM )
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ RETURN( Ret);
+ }
+
+ RtlZeroMemory(&Msg, sizeof(MSG));
+
+ Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE, TRUE);
+
+ 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);
+
+CLEANUP:
+ DPRINT("Leave NtUserGetMessage\n");
+ UserLeave();
+ END_CLEANUP;
+}
+
+BOOL APIENTRY
+NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
+ 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)))
{
- for (i = 0; List[i]; i++)
- {
- UserSendNotifyMessage(List[i], Msg, wParam, lParam);
- }
- ExFreePool(List);
+ RETURN(-1);
}
}
else
{
- ULONG_PTR PResult;
- PTHREADINFO pti;
- PWINDOW_OBJECT Window;
- NTSTATUS Status;
- MSG UserModeMsg;
- MSG KernelModeMsg;
- PMSGMEMORY MsgMemoryEntry;
+ Window = (PWINDOW_OBJECT)hWnd;
+ }
+
+ if (MsgFilterMax < MsgFilterMin)
+ {
+ MsgFilterMin = 0;
+ MsgFilterMax = 0;
+ }
- if(!(Window = UserGetWindowObject(hWnd))) return FALSE;
+ Present = co_IntPeekMessage(&Msg, Window, MsgFilterMin, MsgFilterMax, RemoveMsg);
+ if (Present)
+ {
- pti = PsGetCurrentThreadWin32Thread();
- if(Window->MessageQueue != pti->MessageQueue)
- { // Send message w/o waiting for it.
- Result = UserPostMessage(hWnd, Msg, wParam, lParam);
+ 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
- { // Handle message and callback.
- UserModeMsg.hwnd = hWnd;
- UserModeMsg.message = Msg;
- UserModeMsg.wParam = wParam;
- UserModeMsg.lParam = lParam;
- MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
- Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
+ {
+ /* 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))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
+ SetLastNtError(Status);
+ RETURN( (BOOL) -1);
}
- Result = co_IntSendMessageTimeoutSingle(
- KernelModeMsg.hwnd, KernelModeMsg.message,
- KernelModeMsg.wParam, KernelModeMsg.lParam,
- SMTO_NORMAL, 0, &PResult);
-
- Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
+ /* Transfer lParam data to user-mode mem */
+ Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Size);
if (! NT_SUCCESS(Status))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
+ 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);
}
}
- return Result;
-}
-
-BOOL APIENTRY
-NtUserSendNotifyMessage(HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam)
-{
- DECLARE_RETURN(BOOL);
-
- DPRINT("EnterNtUserSendNotifyMessage\n");
- UserEnterExclusive();
-
- RETURN(UserSendNotifyMessage(hWnd, Msg, wParam, lParam));
+ RETURN( Present);
CLEANUP:
- DPRINT("Leave NtUserSendNotifyMessage, ret=%i\n",_ret_);
+ DPRINT("Leave NtUserPeekMessage, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
-
}
-
-BOOL APIENTRY
-NtUserWaitMessage(VOID)
+BOOL
+APIENTRY
+NtUserPeekMessageX(
+ PMSG pMsg,
+ HWND hWnd,
+ UINT MsgFilterMin,
+ UINT MsgFilterMax,
+ UINT RemoveMsg)
{
+ MSG Msg;
+ BOOL Ret = FALSE;
DECLARE_RETURN(BOOL);
- DPRINT("EnterNtUserWaitMessage\n");
+ DPRINT("Enter NtUserPeekMessage\n");
UserEnterExclusive();
- RETURN(co_IntWaitMessage(NULL, 0, 0));
+ if ( RemoveMsg & PM_BADMSGFLAGS )
+ {
+ SetLastWin32Error(ERROR_INVALID_FLAGS);
+ RETURN( Ret);
+ }
+
+ RtlZeroMemory(&Msg, sizeof(MSG));
+
+ Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg, FALSE);
+
+ 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);
CLEANUP:
- DPRINT("Leave NtUserWaitMessage, ret=%i\n",_ret_);
+ DPRINT("Leave NtUserPeekMessage, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
-DWORD APIENTRY
-IntGetQueueStatus(BOOL ClearChanges)
+BOOL
+APIENTRY
+NtUserCallMsgFilter(
+ LPMSG lpmsg,
+ INT code)
{
- PTHREADINFO pti;
- PUSER_MESSAGE_QUEUE Queue;
- DWORD Result;
- DECLARE_RETURN(DWORD);
+ BOOL BadChk = FALSE, Ret = FALSE;
+ MSG Msg;
+ DECLARE_RETURN(BOOL);
- DPRINT("Enter IntGetQueueStatus\n");
+ 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);
- pti = PsGetCurrentThreadWin32Thread();
- Queue = pti->MessageQueue;
+ if (BadChk) RETURN( FALSE);
- Result = MAKELONG(Queue->QueueBits, Queue->ChangedBits);
- if (ClearChanges)
+ if ( ISITHOOKED(WH_SYSMSGFILTER) &&
+ co_HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)&Msg))
{
- Queue->ChangedBits = 0;
+ Ret = TRUE;
+ }
+ else
+ {
+ if ( ISITHOOKED(WH_MSGFILTER) )
+ {
+ Ret = co_HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)&Msg);
+ }
}
- RETURN(Result);
+ _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)
CLEANUP:
- DPRINT("Leave IntGetQueueStatus, ret=%i\n",_ret_);
+ DPRINT("Leave NtUserCallMsgFilter. ret=%i\n", _ret_);
+ UserLeave();
END_CLEANUP;
}
-BOOL APIENTRY
-IntInitMessagePumpHook()
+LRESULT APIENTRY
+NtUserDispatchMessage(PMSG UnsafeMsgInfo)
{
- if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo)
- {
- ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook++;
- return TRUE;
- }
- return FALSE;
+ 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;
}
+
BOOL APIENTRY
-IntUninitMessagePumpHook()
+NtUserTranslateMessage(LPMSG lpMsg,
+ UINT flags)
{
- if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo)
+ NTSTATUS Status;
+ MSG SafeMsg;
+ DECLARE_RETURN(BOOL);
+
+ DPRINT("Enter NtUserTranslateMessage\n");
+ UserEnterExclusive();
+
+ Status = MmCopyFromCaller(&SafeMsg, lpMsg, sizeof(MSG));
+ if(!NT_SUCCESS(Status))
{
- if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook <= 0)
- {
- return FALSE;
- }
- ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->ThreadInfo->ClientThreadInfo.dwcPumpHook--;
- return TRUE;
+ SetLastNtError(Status);
+ RETURN( FALSE);
}
- return FALSE;
-}
+ RETURN( IntTranslateKbdMessage(&SafeMsg, flags));
-LRESULT APIENTRY
+CLEANUP:
+ DPRINT("Leave NtUserTranslateMessage: ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+
+BOOL APIENTRY
NtUserMessageCall(
HWND hWnd,
UINT Msg,
BOOL Ansi)
{
LRESULT lResult = 0;
+ BOOL Ret = FALSE;
+ BOOL BadChk = FALSE;
PWINDOW_OBJECT Window = NULL;
USER_REFERENCE_ENTRY Ref;
/* Validate input */
if (hWnd && (hWnd != INVALID_HANDLE_VALUE) && !(Window = UserGetWindowObject(hWnd)))
{
- return 0;
+ 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:
{
- PBROADCASTPARM parm;
- BOOL BadChk = FALSE;
+ BROADCASTPARM parm;
DWORD_PTR RetVal = 0;
- lResult = -1;
if (ResultInfo)
{
ProbeForWrite((PVOID)ResultInfo,
sizeof(BROADCASTPARM),
1);
- parm = (PBROADCASTPARM)ResultInfo;
+ RtlCopyMemory(&parm, (PVOID)ResultInfo, sizeof(BROADCASTPARM));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
else
break;
- if ( parm->recipients & BSM_ALLDESKTOPS ||
- parm->recipients == BSM_ALLCOMPONENTS )
+ if ( parm.recipients & BSM_ALLDESKTOPS ||
+ parm.recipients == BSM_ALLCOMPONENTS )
{
}
- else if (parm->recipients & BSM_APPLICATIONS)
+ else if (parm.recipients & BSM_APPLICATIONS)
{
- if (parm->flags & BSF_QUERY)
+ if (parm.flags & BSF_QUERY)
{
- if (parm->flags & BSF_FORCEIFHUNG || parm->flags & BSF_NOHANG)
+ if (parm.flags & BSF_FORCEIFHUNG || parm.flags & BSF_NOHANG)
{
co_IntSendMessageTimeout( HWND_BROADCAST,
Msg,
2000,
&RetVal);
}
- else if (parm->flags & BSF_NOTIMEOUTIFNOTHUNG)
+ else if (parm.flags & BSF_NOTIMEOUTIFNOTHUNG)
{
co_IntSendMessageTimeout( HWND_BROADCAST,
Msg,
&RetVal);
}
}
- else if (parm->flags & BSF_POSTMESSAGE)
+ else if (parm.flags & BSF_POSTMESSAGE)
{
- lResult = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam);
+ Ret = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam);
}
- else if ( parm->flags & BSF_SENDNOTIFYMESSAGE)
+ else if ( parm.flags & BSF_SENDNOTIFYMESSAGE)
{
- lResult = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam);
+ Ret = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam);
}
}
}
break;
case FNID_SENDMESSAGECALLBACK:
+ {
+ PCALL_BACK_INFO CallBackInfo = (PCALL_BACK_INFO)ResultInfo;
+
+ if (!CallBackInfo)
+ break;
+
+ if (!co_IntSendMessageWithCallBack(hWnd, Msg, wParam, lParam,
+ CallBackInfo->CallBack, CallBackInfo->Context, NULL))
+ {
+ DPRINT1("Callback failure!\n");
+ }
+ }
break;
// CallNextHook bypass.
case FNID_CALLWNDPROC:
}
break;
}
+
+ switch(dwType)
+ {
+ case FNID_DEFWINDOWPROC:
+ case FNID_CALLWNDPROC:
+ case FNID_CALLWNDPROCRET:
+ if (ResultInfo)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite((PVOID)ResultInfo, sizeof(LRESULT), 1);
+ RtlCopyMemory((PVOID)ResultInfo, &lResult, sizeof(LRESULT));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ BadChk = TRUE;
+ }
+ _SEH2_END;
+ }
+ break;
+ default:
+ break;
+ }
+
UserLeave();
- return lResult;
+
+ return BadChk ? FALSE : Ret;
}
#define INFINITE 0xFFFFFFFF
IN BOOL Unknown2)
{
PEPROCESS Process;
- PW32PROCESS W32Process;
+ PPROCESSINFO W32Process;
NTSTATUS Status;
HANDLE Handles[2];
LARGE_INTEGER Timeout;
return WAIT_FAILED;
}
- W32Process = (PW32PROCESS)Process->Win32Process;
+ W32Process = (PPROCESSINFO)Process->Win32Process;
if (!W32Process)
{
ObDereferenceObject(Process);
WaitExit:
if (W32Process->InputIdleEvent)
{
- EngDeleteEvent((PEVENT)W32Process->InputIdleEvent);
+ EngFreeMem((PVOID)W32Process->InputIdleEvent);
W32Process->InputIdleEvent = NULL;
}
ObDereferenceObject(Process);