/* INCLUDES ******************************************************************/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
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);
lParamBufferSize = MsgMemorySize(MsgMemoryEntry, pMsg->wParam, pMsg->lParam);
}
- if (! NT_SUCCESS(PackParam(&lParamPacked, pMsg->message, 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;
lParamPacked,
lParamBufferSize);
- if (! NT_SUCCESS(UnpackParam(lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam)))
+ 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 = NtGdiCreateRectRgn( 0, 0, 0, 0 );
+ HRGN hrgn = IntSysCreateRectRgn( 0, 0, 0, 0 );
co_UserGetUpdateRgn( Window, hrgn, TRUE );
- GreDeleteObject( hrgn );
+ REGION_FreeRgnByHandle( hrgn );
}
return retval;
}
UserRefObjectCo(Window, &Ref);
- if ( ThreadQueue == Window->MessageQueue &&
+ if ( ThreadQueue == Window->pti->MessageQueue &&
ThreadQueue->CaptureWindow != Window->hSelf)
{
/* only send WM_NCHITTEST messages if we're not capturing the window! */
UserRefObjectCo(DesktopWindow, &DesktopRef);
- co_WinPosWindowFromPoint(DesktopWindow, Window->MessageQueue, &Msg->pt, &Wnd);
+ co_WinPosWindowFromPoint(DesktopWindow, Window->pti->MessageQueue, &Msg->pt, &Wnd);
if (Wnd)
{
if (Wnd != Window)
Msg->hwnd = Wnd->hSelf;
if(!(Wnd->state & WINDOWSTATUS_DESTROYING))
{
- MsqPostMessage(Wnd->MessageQueue, Msg, FALSE,
+ MsqPostMessage(Wnd->pti->MessageQueue, Msg, FALSE,
Msg->message == WM_MOUSEMOVE ? QS_MOUSEMOVE :
QS_MOUSEBUTTON);
}
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 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;
goto MsgExit;
}
- if (ThreadQueue->WakeMask & QS_TIMER)
- if (PostTimerMessages(Window)) // 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,
- Window,
- MsgFilterMin,
- MsgFilterMax,
- &Msg->Msg,
- RemoveMessages);
- if (Present)
- {
- Msg->FreeLParam = FALSE;
- goto MessageFound;
- }
+ if (PostTimerMessages(Window))
+ goto CheckMessages;
if(Present)
{
goto MsgExit;
}
- if ( ( Msg->Msg.hwnd && Msg->Msg.message >= WM_MOUSEFIRST &&
+ if ( ( Msg->Msg.hwnd &&
+ Msg->Msg.message >= WM_MOUSEFIRST &&
Msg->Msg.message <= WM_MOUSELAST ) &&
co_IntTranslateMouseMessage( ThreadQueue,
&Msg->Msg,
}
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_MOUSE) && IS_MOUSE_MESSAGE(Msg->Msg.message))
+ {
+ if(!ProcessMouseMessage(&Msg->Msg, HitTest, RemoveMsg))
+ {
+ return FALSE;
+ }
+ }
- if ( ISITHOOKED(WH_KEYBOARD) &&
- (Msg->Msg.message == WM_KEYDOWN || Msg->Msg.message == WM_KEYUP) )
+ if ( ISITHOOKED(WH_KEYBOARD) && IS_KBD_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(!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 FASTCALL
-co_IntGetPeekMessage( PMSG pMsg,
- HWND hWnd,
- UINT MsgFilterMin,
- UINT MsgFilterMax,
- UINT RemoveMsg,
- BOOL bGMSG )
-{
- return FALSE;
-}
-
-
-static BOOL FASTCALL
-co_IntWaitMessage( PWINDOW_OBJECT Window,
- UINT MsgFilterMin,
- UINT MsgFilterMax )
-{
- PTHREADINFO pti;
- PUSER_MESSAGE_QUEUE ThreadQueue;
- NTSTATUS Status = STATUS_SUCCESS;
- USER_MESSAGE Msg;
-
- 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 );
-
- SetLastNtError(Status);
-
- DPRINT1("Exit co_IntWaitMessage on error!\n");
-
- return FALSE;
-}
-
-
static NTSTATUS FASTCALL
CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg, PMSGMEMORY MsgMemoryEntry)
{
return STATUS_SUCCESS;
}
+static BOOL FASTCALL
+co_IntWaitMessage( PWINDOW_OBJECT Window,
+ UINT MsgFilterMin,
+ UINT MsgFilterMax )
+{
+ PTHREADINFO pti;
+ PUSER_MESSAGE_QUEUE ThreadQueue;
+ NTSTATUS Status = STATUS_SUCCESS;
+ USER_MESSAGE Msg;
+
+ 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 );
+
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ DPRINT1("Exit co_IntWaitMessage on error!\n");
+ }
+
+ return FALSE;
+}
+
+BOOL FASTCALL
+co_IntGetPeekMessage( PMSG pMsg,
+ HWND hWnd,
+ UINT MsgFilterMin,
+ UINT MsgFilterMax,
+ UINT RemoveMsg,
+ BOOL bGMSG )
+{
+ BOOL Present;
+ PWINDOW_OBJECT Window;
+ USER_MESSAGE Msg;
+
+ 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;
+ }
+
+ 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)
+ return (WM_QUIT != pMsg->message);
+ else
+ return TRUE;
+ }
+
+ 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 );
+
+ return FALSE;
+}
+
BOOL FASTCALL
UserPostThreadMessage( DWORD idThread,
UINT Msg,
if( Status == STATUS_SUCCESS )
{
pThread = (PTHREADINFO)peThread->Tcb.Win32Thread;
- if( !pThread || !pThread->MessageQueue || (pThread->TIF_flags & TIF_INCLEANUP))
+ if( !pThread ||
+ !pThread->MessageQueue ||
+ (pThread->TIF_flags & TIF_INCLEANUP))
{
ObDereferenceObject( peThread );
return FALSE;
if (WM_QUIT == Msg)
{
- MsqPostQuitMessage(Window->MessageQueue, wParam);
+ MsqPostQuitMessage(Window->pti->MessageQueue, wParam);
}
else
{
Message.pt = gpsi->ptCursor;
KeQueryTickCount(&LargeTickCount);
pti->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
- MsqPostMessage(Window->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
+ MsqPostMessage(Window->pti->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
}
}
return TRUE;
IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
if ( NULL != Win32Thread &&
- Window->MessageQueue == Win32Thread->MessageQueue)
+ Window->pti->MessageQueue == Win32Thread->MessageQueue)
{
if (Win32Thread->TIF_flags & TIF_INCLEANUP)
{
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);
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);
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);
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
pti = PsGetCurrentThreadWin32Thread();
- if ( Window->MessageQueue != pti->MessageQueue &&
+ if ( Window->pti->MessageQueue != pti->MessageQueue &&
FindMsgMemory(Msg) == 0 )
{
Result = UserPostMessage(hWnd, Msg, wParam, lParam);
// This is checked in user mode!!!!!!!
if ( HWND_BROADCAST != hWnd &&
NULL != pti &&
- Window->MessageQueue == pti->MessageQueue &&
+ Window->pti->MessageQueue == pti->MessageQueue &&
!ISITHOOKED(WH_CALLWNDPROC) &&
!ISITHOOKED(WH_CALLWNDPROCRET) &&
( Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST ) )
pti = PsGetCurrentThreadWin32Thread();
- if (Window->MessageQueue != pti->MessageQueue)
+ if (Window->pti->MessageQueue != pti->MessageQueue)
{ // Send message w/o waiting for it.
Result = UserPostMessage(hWnd, Msg, wParam, lParam);
}
RETURN( Ret);
}
+ RtlZeroMemory(&Msg, sizeof(MSG));
+
Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE, TRUE);
if (Ret)
RETURN( Ret);
}
+ RtlZeroMemory(&Msg, sizeof(MSG));
+
Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg, FALSE);
if (Ret)
}
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:
WaitExit:
if (W32Process->InputIdleEvent)
{
- EngDeleteEvent((PEVENT)W32Process->InputIdleEvent);
+ EngFreeMem((PVOID)W32Process->InputIdleEvent);
W32Process->InputIdleEvent = NULL;
}
ObDereferenceObject(Process);