static KEVENT HardwareMessageEvent;
static PAGED_LOOKASIDE_LIST MessageLookasideList;
-static PAGED_LOOKASIDE_LIST TimerLookasideList;
#define IntLockSystemMessageQueue(OldIrql) \
KeAcquireSpinLock(&SystemMessageQueueLock, &OldIrql)
/* FUNCTIONS *****************************************************************/
-//
-// Wakeup any thread/process waiting on idle input.
-//
-static VOID FASTCALL
-IdlePing(VOID)
-{
- HWND hWnd;
- PWINDOW_OBJECT Window;
- PPROCESSINFO W32d = PsGetCurrentProcessWin32Process();
-
- hWnd = UserGetForegroundWindow();
-
- Window = UserGetWindowObject(hWnd);
-
- if (Window && Window->pti)
- {
- if (Window->pti->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE))
- {
- co_HOOK_CallHooks(WH_FOREGROUNDIDLE,HC_ACTION,0,0);
- }
- }
-
- if (W32d && W32d->InputIdleEvent)
- KePulseEvent( W32d->InputIdleEvent, EVENT_INCREMENT, TRUE);
-}
-
HANDLE FASTCALL
IntMsqSetWakeMask(DWORD WakeMask)
{
}
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
MsqInitializeImpl(VOID)
{
/*CurrentFocusMessageQueue = NULL;*/
sizeof(USER_MESSAGE),
TAG_USRMSG,
256);
- ExInitializePagedLookasideList(&TimerLookasideList,
- NULL,
- NULL,
- 0,
- sizeof(TIMER_ENTRY),
- TAG_TIMER,
- 64);
return(STATUS_SUCCESS);
}
VOID FASTCALL
-MsqInsertSystemMessage(MSG* Msg)
+MsqInsertMouseMessage(MSG* Msg)
{
+ LARGE_INTEGER LargeTickCount;
KIRQL OldIrql;
ULONG Prev;
+ MSLLHOOKSTRUCT MouseHookData;
+
+ KeQueryTickCount(&LargeTickCount);
+ Msg->time = MsqCalculateMessageTime(&LargeTickCount);
+
+ MouseHookData.pt.x = LOWORD(Msg->lParam);
+ MouseHookData.pt.y = HIWORD(Msg->lParam);
+ switch(Msg->message)
+ {
+ case WM_MOUSEWHEEL:
+ MouseHookData.mouseData = MAKELONG(0, GET_WHEEL_DELTA_WPARAM(Msg->wParam));
+ break;
+ case WM_XBUTTONDOWN:
+ case WM_XBUTTONUP:
+ case WM_XBUTTONDBLCLK:
+ case WM_NCXBUTTONDOWN:
+ case WM_NCXBUTTONUP:
+ case WM_NCXBUTTONDBLCLK:
+ MouseHookData.mouseData = MAKELONG(0, HIWORD(Msg->wParam));
+ break;
+ default:
+ MouseHookData.mouseData = 0;
+ break;
+ }
+
+ MouseHookData.flags = 0;
+ MouseHookData.time = Msg->time;
+ MouseHookData.dwExtraInfo = 0;
+
+ /* If the hook procedure returned non zero, dont send the message */
+ if (co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION, Msg->message, (LPARAM) &MouseHookData))
+ return;
/*
* If we got WM_MOUSEMOVE and there are already messages in the
}
static BOOL APIENTRY
-co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Window, UINT FilterLow, UINT FilterHigh,
+co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWND Window, UINT FilterLow, UINT FilterHigh,
PUSER_MESSAGE Message, BOOL Remove, PBOOL Freed,
- PWINDOW_OBJECT ScopeWin, PPOINT ScreenPoint, BOOL FromGlobalQueue, PLIST_ENTRY *Next)
+ PWND ScopeWin, PPOINT ScreenPoint, BOOL FromGlobalQueue, PLIST_ENTRY *Next)
{
USHORT Msg = Message->Msg.message;
- PWINDOW_OBJECT CaptureWindow = NULL;
+ PWND CaptureWindow = NULL;
HWND hCaptureWin;
+ /* FIXME: Mouse message can be sent before the Desktop is up and running in which case ScopeWin (Desktop) is 0.
+ Is this the best fix? */
+ if (ScopeWin == 0) return FALSE;
+
ASSERT_REFS_CO(ScopeWin);
/*
return(FALSE);
}
- if (CaptureWindow->pti->MessageQueue != MessageQueue)
+ if (CaptureWindow->head.pti->MessageQueue != MessageQueue)
{
if (! FromGlobalQueue)
{
/* lock the destination message queue, so we don't get in trouble with other
threads, messing with it at the same time */
- IntLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
- InsertTailList(&CaptureWindow->pti->MessageQueue->HardwareMessagesListHead,
+ IntLockHardwareMessageQueue(CaptureWindow->head.pti->MessageQueue);
+ InsertTailList(&CaptureWindow->head.pti->MessageQueue->HardwareMessagesListHead,
&Message->ListEntry);
if(Message->Msg.message == WM_MOUSEMOVE)
{
- if(CaptureWindow->pti->MessageQueue->MouseMoveMsg)
+ if(CaptureWindow->head.pti->MessageQueue->MouseMoveMsg)
{
/* remove the old WM_MOUSEMOVE message, we're processing a more recent
one */
- RemoveEntryList(&CaptureWindow->pti->MessageQueue->MouseMoveMsg->ListEntry);
- ExFreePool(CaptureWindow->pti->MessageQueue->MouseMoveMsg);
+ RemoveEntryList(&CaptureWindow->head.pti->MessageQueue->MouseMoveMsg->ListEntry);
+ ExFreePool(CaptureWindow->head.pti->MessageQueue->MouseMoveMsg);
}
/* save the pointer to the WM_MOUSEMOVE message in the new queue */
- CaptureWindow->pti->MessageQueue->MouseMoveMsg = Message;
+ CaptureWindow->head.pti->MessageQueue->MouseMoveMsg = Message;
- CaptureWindow->pti->MessageQueue->QueueBits |= QS_MOUSEMOVE;
- CaptureWindow->pti->MessageQueue->ChangedBits |= QS_MOUSEMOVE;
- if (CaptureWindow->pti->MessageQueue->WakeMask & QS_MOUSEMOVE)
- KeSetEvent(CaptureWindow->pti->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
+ CaptureWindow->head.pti->MessageQueue->QueueBits |= QS_MOUSEMOVE;
+ CaptureWindow->head.pti->MessageQueue->ChangedBits |= QS_MOUSEMOVE;
+ if (CaptureWindow->head.pti->MessageQueue->WakeMask & QS_MOUSEMOVE)
+ KeSetEvent(CaptureWindow->head.pti->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
}
else
{
- CaptureWindow->pti->MessageQueue->QueueBits |= QS_MOUSEBUTTON;
- CaptureWindow->pti->MessageQueue->ChangedBits |= QS_MOUSEBUTTON;
- if (CaptureWindow->pti->MessageQueue->WakeMask & QS_MOUSEBUTTON)
- KeSetEvent(CaptureWindow->pti->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
+ CaptureWindow->head.pti->MessageQueue->QueueBits |= QS_MOUSEBUTTON;
+ CaptureWindow->head.pti->MessageQueue->ChangedBits |= QS_MOUSEBUTTON;
+ if (CaptureWindow->head.pti->MessageQueue->WakeMask & QS_MOUSEBUTTON)
+ KeSetEvent(CaptureWindow->head.pti->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
}
- IntUnLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
+ IntUnLockHardwareMessageQueue(CaptureWindow->head.pti->MessageQueue);
*Freed = FALSE;
UserDereferenceObject(CaptureWindow);
*ScreenPoint = Message->Msg.pt;
- if((Window != NULL && PtrToInt(Window) != 1 && CaptureWindow->hSelf != Window->hSelf) ||
+ if((Window != NULL && PtrToInt(Window) != 1 && CaptureWindow->head.h != Window->head.h) ||
((FilterLow != 0 || FilterHigh != 0) && (Msg < FilterLow || Msg > FilterHigh)))
{
/* Reject the message because it doesn't match the filter */
/* Lock the message queue so no other thread can mess with it.
Our own message queue is not locked while fetching from the global
queue, so we have to make sure nothing interferes! */
- IntLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
+ IntLockHardwareMessageQueue(CaptureWindow->head.pti->MessageQueue);
/* if we're from the global queue, we need to add our message to our
private queue so we don't loose it! */
- InsertTailList(&CaptureWindow->pti->MessageQueue->HardwareMessagesListHead,
+ InsertTailList(&CaptureWindow->head.pti->MessageQueue->HardwareMessagesListHead,
&Message->ListEntry);
}
if (Message->Msg.message == WM_MOUSEMOVE)
{
- if(CaptureWindow->pti->MessageQueue->MouseMoveMsg &&
- (CaptureWindow->pti->MessageQueue->MouseMoveMsg != Message))
+ if(CaptureWindow->head.pti->MessageQueue->MouseMoveMsg &&
+ (CaptureWindow->head.pti->MessageQueue->MouseMoveMsg != Message))
{
/* delete the old message */
- RemoveEntryList(&CaptureWindow->pti->MessageQueue->MouseMoveMsg->ListEntry);
- ExFreePool(CaptureWindow->pti->MessageQueue->MouseMoveMsg);
+ RemoveEntryList(&CaptureWindow->head.pti->MessageQueue->MouseMoveMsg->ListEntry);
+ ExFreePool(CaptureWindow->head.pti->MessageQueue->MouseMoveMsg);
if (!FromGlobalQueue)
{
// We might have deleted the next one in our queue, so fix next
}
/* always save a pointer to this WM_MOUSEMOVE message here because we're
sure that the message is in the private queue */
- CaptureWindow->pti->MessageQueue->MouseMoveMsg = Message;
+ CaptureWindow->head.pti->MessageQueue->MouseMoveMsg = Message;
}
if(FromGlobalQueue)
{
- IntUnLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
+ IntUnLockHardwareMessageQueue(CaptureWindow->head.pti->MessageQueue);
}
UserDereferenceObject(CaptureWindow);
}
/* FIXME - only assign if removing? */
- Message->Msg.hwnd = CaptureWindow->hSelf;
+ Message->Msg.hwnd = CaptureWindow->head.h;
Message->Msg.message = Msg;
Message->Msg.lParam = MAKELONG(Message->Msg.pt.x, Message->Msg.pt.y);
/* Lock the message queue so no other thread can mess with it.
Our own message queue is not locked while fetching from the global
queue, so we have to make sure nothing interferes! */
- IntLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
- if(CaptureWindow->pti->MessageQueue->MouseMoveMsg)
+ IntLockHardwareMessageQueue(CaptureWindow->head.pti->MessageQueue);
+ if(CaptureWindow->head.pti->MessageQueue->MouseMoveMsg)
{
/* delete the WM_(NC)MOUSEMOVE message in the private queue, we're dealing
with one that's been sent later */
- RemoveEntryList(&CaptureWindow->pti->MessageQueue->MouseMoveMsg->ListEntry);
- ExFreePool(CaptureWindow->pti->MessageQueue->MouseMoveMsg);
+ RemoveEntryList(&CaptureWindow->head.pti->MessageQueue->MouseMoveMsg->ListEntry);
+ ExFreePool(CaptureWindow->head.pti->MessageQueue->MouseMoveMsg);
/* our message is not in the private queue so we can remove the pointer
instead of setting it to the current message we're processing */
- CaptureWindow->pti->MessageQueue->MouseMoveMsg = NULL;
+ CaptureWindow->head.pti->MessageQueue->MouseMoveMsg = NULL;
}
- IntUnLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
+ IntUnLockHardwareMessageQueue(CaptureWindow->head.pti->MessageQueue);
}
- else if (CaptureWindow->pti->MessageQueue->MouseMoveMsg == Message)
+ else if (CaptureWindow->head.pti->MessageQueue->MouseMoveMsg == Message)
{
- CaptureWindow->pti->MessageQueue->MouseMoveMsg = NULL;
+ CaptureWindow->head.pti->MessageQueue->MouseMoveMsg = NULL;
}
}
}
BOOL APIENTRY
-co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Window,
+co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWND Window,
UINT FilterLow, UINT FilterHigh, BOOL Remove,
- PUSER_MESSAGE* Message)
+ PMSG Message)
{
KIRQL OldIrql;
POINT ScreenPoint;
BOOL Accept, Freed;
PLIST_ENTRY CurrentEntry;
- PWINDOW_OBJECT DesktopWindow = NULL;
+ PWND DesktopWindow = NULL;
PVOID WaitObjects[2];
NTSTATUS WaitStatus;
DECLARE_RETURN(BOOL);
WaitObjects[0] = &HardwareMessageQueueLock;
do
{
- IdlePing();
-
UserLeaveCo();
WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest,
if (DesktopWindow)
{
- UserRefObjectCo(DesktopWindow, &Ref);//can DesktopWindow be NULL?
- Desk = DesktopWindow->pti->pDeskInfo;
+ UserRefObjectCo(DesktopWindow, &Ref);
+ Desk = DesktopWindow->head.pti->pDeskInfo;
}
/* Process messages in the message queue itself. */
DesktopWindow, &ScreenPoint, FALSE, &CurrentEntry);
if (Accept)
{
+ *Message = Current->Msg;
if (Remove)
{
RemoveEntryList(&Current->ListEntry);
+ MsqDestroyMessage(Current);
}
IntUnLockHardwareMessageQueue(MessageQueue);
IntUnLockSystemHardwareMessageQueueLock(FALSE);
- *Message = Current;
-
+
if (Desk)
Desk->LastInputWasKbd = FALSE;
}
}
+ else
+ {
+ *Message = Current->Msg;
+ if (Remove)
+ {
+ RemoveEntryList(&Current->ListEntry);
+ MsqDestroyMessage(Current);
+ }
+ IntUnLockHardwareMessageQueue(MessageQueue);
+ IntUnLockSystemHardwareMessageQueueLock(FALSE);
+
+ RETURN(TRUE);
+ }
}
IntUnLockHardwareMessageQueue(MessageQueue);
UserMsg = ExAllocateFromPagedLookasideList(&MessageLookasideList);
/* What to do if out of memory? For now we just panic a bit in debug */
ASSERT(UserMsg);
- UserMsg->FreeLParam = FALSE;
UserMsg->Msg = Msg;
InsertTailList(&HardwareMessageQueueHead, &UserMsg->ListEntry);
IntUnLockHardwareMessageQueue(MessageQueue);
}
IntUnLockSystemHardwareMessageQueueLock(FALSE);
- *Message = Current;
+ *Message = Current->Msg;
+
+ if (Remove)
+ {
+ MsqDestroyMessage(Current);
+ }
RETURN(TRUE);
}
KbdHookData.dwExtraInfo = 0;
if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData))
{
- DPRINT("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
+ DPRINT1("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
Msg.message, Msg.wParam, Msg.lParam);
if (Entered) UserLeave();
return;
FocusMessageQueue->Desktop->pDeskInfo->LastInputWasKbd = TRUE;
Msg.pt = gpsi->ptCursor;
- MsqPostMessage(FocusMessageQueue, &Msg, FALSE, QS_KEY);
+ MsqPostMessage(FocusMessageQueue, &Msg, TRUE, QS_KEY);
}
else
{
VOID FASTCALL
MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam)
{
- PWINDOW_OBJECT Window;
+ PWND Window;
PTHREADINFO Win32Thread;
MSG Mesg;
LARGE_INTEGER LargeTickCount;
KeQueryTickCount(&LargeTickCount);
Mesg.time = MsqCalculateMessageTime(&LargeTickCount);
Mesg.pt = gpsi->ptCursor;
- MsqPostMessage(Window->pti->MessageQueue, &Mesg, FALSE, QS_HOTKEY);
+ MsqPostMessage(Window->head.pti->MessageQueue, &Mesg, FALSE, QS_HOTKEY);
UserDereferenceObject(Window);
ObDereferenceObject (Thread);
}
PUSER_MESSAGE FASTCALL
-MsqCreateMessage(LPMSG Msg, BOOLEAN FreeLParam)
+MsqCreateMessage(LPMSG Msg)
{
PUSER_MESSAGE Message;
return NULL;
}
- Message->FreeLParam = FreeLParam;
RtlMoveMemory(&Message->Msg, Msg, sizeof(MSG));
return Message;
PUSER_SENT_MESSAGE Message;
PLIST_ENTRY Entry;
LRESULT Result;
- BOOL SenderReturned;
if (IsListEmpty(&MessageQueue->SentMessagesListHead))
{
&Message->ListEntry);
if (Message->HookMessage == MSQ_ISHOOK)
- {
- Result = co_HOOK_CallHooks(Message->Msg.message,
- (INT)(INT_PTR)Message->Msg.hwnd,
- Message->Msg.wParam,
- Message->Msg.lParam);
+ { // Direct Hook Call processor
+ Result = co_CallHook( Message->Msg.message, // HookId
+ (INT)(INT_PTR)Message->Msg.hwnd, // Code
+ Message->Msg.wParam,
+ Message->Msg.lParam);
}
else if (Message->HookMessage == MSQ_ISEVENT)
- {
+ { // Direct Event Call processor
Result = co_EVENT_CallEvents( Message->Msg.message,
Message->Msg.hwnd,
Message->Msg.wParam,
- Message->Msg.lParam);
+ Message->Msg.lParam);
}
else
- {
- /* Call the window procedure. */
- Result = co_IntSendMessage(Message->Msg.hwnd,
- Message->Msg.message,
- Message->Msg.wParam,
- Message->Msg.lParam);
+ { /* Call the window procedure. */
+ Result = co_IntSendMessage( Message->Msg.hwnd,
+ Message->Msg.message,
+ Message->Msg.wParam,
+ Message->Msg.lParam);
}
/* remove the message from the local dispatching list, because it doesn't need
to be cleaned up on thread termination anymore */
RemoveEntryList(&Message->ListEntry);
- /* remove the message from the dispatching list, so lock the sender's message queue */
- SenderReturned = (Message->DispatchingListEntry.Flink == NULL);
- if (!SenderReturned)
+ /* remove the message from the dispatching list if needed, so lock the sender's message queue */
+ if (!(Message->HookMessage & MSQ_SENTNOWAIT))
{
- /* only remove it from the dispatching list if not already removed by a timeout */
- RemoveEntryList(&Message->DispatchingListEntry);
+ if (Message->DispatchingListEntry.Flink != NULL)
+ {
+ /* only remove it from the dispatching list if not already removed by a timeout */
+ RemoveEntryList(&Message->DispatchingListEntry);
+ }
}
/* still keep the sender's message queue locked, so the sender can't exit the
MsqSendMessage() function (if timed out) */
}
/* Call the callback if the message was sent with SendMessageCallback */
- if (!SenderReturned && Message->CompletionCallback != NULL)
+ if (Message->CompletionCallback != NULL)
{
co_IntCallSentMessageCallback(Message->CompletionCallback,
Message->Msg.hwnd,
Result);
}
-
/* Only if it is not a no wait message */
if (!(Message->HookMessage & MSQ_SENTNOWAIT))
{
PUSER_MESSAGE PostedMessage;
PUSER_MESSAGE_QUEUE MessageQueue;
PLIST_ENTRY CurrentEntry, ListHead;
- PWINDOW_OBJECT Window = pWindow;
+ PWND Window = pWindow;
ASSERT(Window);
- MessageQueue = Window->pti->MessageQueue;
+ MessageQueue = Window->head.pti->MessageQueue;
ASSERT(MessageQueue);
/* remove the posted messages for this window */
{
PostedMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
ListEntry);
- if (PostedMessage->Msg.hwnd == Window->hSelf)
+ if (PostedMessage->Msg.hwnd == Window->head.h)
{
RemoveEntryList(&PostedMessage->ListEntry);
MsqDestroyMessage(PostedMessage);
{
SentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE,
ListEntry);
- if(SentMessage->Msg.hwnd == Window->hSelf)
+ if(SentMessage->Msg.hwnd == Window->head.h)
{
DPRINT("Notify the sender and remove a message from the queue that had not been dispatched\n");
RemoveEntryList(&SentMessage->ListEntry);
- /* remove the message from the dispatching list */
- if(SentMessage->DispatchingListEntry.Flink != NULL)
+ /* remove the message from the dispatching list if neede */
+ if ((!(SentMessage->HookMessage & MSQ_SENTNOWAIT))
+ && (SentMessage->DispatchingListEntry.Flink != NULL))
{
RemoveEntryList(&SentMessage->DispatchingListEntry);
}
PUSER_SENT_MESSAGE Message;
KEVENT CompletionEvent;
NTSTATUS WaitStatus;
- LRESULT Result;
PUSER_MESSAGE_QUEUE ThreadQueue;
LARGE_INTEGER Timeout;
PLIST_ENTRY Entry;
+ LRESULT Result = 0; //// Result could be trashed. ////
if(!(Message = ExAllocatePoolWithTag(PagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG)))
{
/* FIXME - increase reference counter of sender's message queue here */
- Result = 0;
Message->Msg.hwnd = Wnd;
Message->Msg.message = Msg;
Message->Msg.wParam = wParam;
Message->SenderQueue = ThreadQueue;
IntReferenceMessageQueue(ThreadQueue);
Message->CompletionCallback = NULL;
+ Message->CompletionCallbackContext = 0;
Message->HookMessage = HookMessage;
Message->HasPackedLParam = FALSE;
if(Block)
{
- IdlePing();
-
UserLeaveCo();
/* don't process messages sent to the thread */
WaitObjects[1] = ThreadQueue->NewMessages;
do
{
- IdlePing();
-
UserLeaveCo();
WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest,
}
VOID FASTCALL
-MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN FreeLParam,
+MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MSG* Msg, BOOLEAN HardwareMessage,
DWORD MessageBits)
{
PUSER_MESSAGE Message;
- if(!(Message = MsqCreateMessage(Msg, FreeLParam)))
+ if(!(Message = MsqCreateMessage(Msg)))
{
return;
}
- InsertTailList(&MessageQueue->PostedMessagesListHead,
- &Message->ListEntry);
+
+ if(!HardwareMessage)
+ {
+ InsertTailList(&MessageQueue->PostedMessagesListHead,
+ &Message->ListEntry);
+ }
+ else
+ {
+ InsertTailList(&MessageQueue->HardwareMessagesListHead,
+ &Message->ListEntry);
+ }
MessageQueue->QueueBits |= MessageBits;
MessageQueue->ChangedBits |= MessageBits;
if (MessageQueue->WakeMask & MessageBits)
co_MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
IN BOOLEAN Hardware,
IN BOOLEAN Remove,
- IN PWINDOW_OBJECT Window,
+ IN PWND Window,
IN UINT MsgFilterLow,
IN UINT MsgFilterHigh,
- OUT PUSER_MESSAGE* Message)
+ OUT PMSG Message)
{
PLIST_ENTRY CurrentEntry;
PUSER_MESSAGE CurrentMessage;
ListEntry);
if ( ( !Window ||
PtrToInt(Window) == 1 ||
- Window->hSelf == CurrentMessage->Msg.hwnd ) &&
+ Window->head.h == CurrentMessage->Msg.hwnd ) &&
( (MsgFilterLow == 0 && MsgFilterHigh == 0) ||
( MsgFilterLow <= CurrentMessage->Msg.message &&
MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
RemoveEntryList(&CurrentMessage->ListEntry);
}
- *Message = CurrentMessage;
+ *Message= CurrentMessage->Msg;
+
+ if (Remove)
+ {
+ MsqDestroyMessage(CurrentMessage);
+ }
+
return(TRUE);
}
CurrentEntry = CurrentEntry->Flink;
}
NTSTATUS FASTCALL
-co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT WndFilter,
+co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWND WndFilter,
UINT MsgFilterMin, UINT MsgFilterMax)
{
PVOID WaitObjects[2] = {MessageQueue->NewMessages, &HardwareMessageEvent};
NTSTATUS ret;
- IdlePing(); // Going to wait so send Idle ping.
-
UserLeaveCo();
ret = KeWaitForMultipleObjects(2,
InitializeListHead(&MessageQueue->PostedMessagesListHead);
InitializeListHead(&MessageQueue->SentMessagesListHead);
InitializeListHead(&MessageQueue->HardwareMessagesListHead);
- InitializeListHead(&MessageQueue->TimerListHead);
InitializeListHead(&MessageQueue->DispatchingMessagesHead);
InitializeListHead(&MessageQueue->LocalDispatchingMessagesHead);
KeInitializeMutex(&MessageQueue->HardwareLock, 0);
{
PLIST_ENTRY CurrentEntry;
PUSER_MESSAGE CurrentMessage;
- PTIMER_ENTRY CurrentTimer;
PUSER_SENT_MESSAGE CurrentSentMessage;
/* cleanup posted messages */
DPRINT("Notify the sender and remove a message from the queue that had not been dispatched\n");
- /* remove the message from the dispatching list */
- if(CurrentSentMessage->DispatchingListEntry.Flink != NULL)
+ /* remove the message from the dispatching list if needed */
+ if ((!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT))
+ && (CurrentSentMessage->DispatchingListEntry.Flink != NULL))
{
RemoveEntryList(&CurrentSentMessage->DispatchingListEntry);
}
ExFreePool(CurrentSentMessage);
}
- /* cleanup timers */
- while (! IsListEmpty(&MessageQueue->TimerListHead))
- {
- CurrentEntry = RemoveHeadList(&MessageQueue->TimerListHead);
- CurrentTimer = CONTAINING_RECORD(CurrentEntry, TIMER_ENTRY, ListEntry);
- ExFreeToPagedLookasideList(&TimerLookasideList, CurrentTimer);
- }
-
/* notify senders of dispatching messages. This needs to be cleaned up if e.g.
ExitThread() was called in a SendMessage() umode callback */
while (!IsListEmpty(&MessageQueue->LocalDispatchingMessagesHead))
IntDereferenceMessageQueue(MessageQueue);
IntDereferenceMessageQueue(CurrentSentMessage->SenderQueue);
}
+
/* free the message */
ExFreePool(CurrentSentMessage);
}
IntDereferenceMessageQueue(MessageQueue);
}
-PHOOKTABLE FASTCALL
-MsqGetHooks(PUSER_MESSAGE_QUEUE Queue)
-{
- return Queue->Hooks;
-}
-
-VOID FASTCALL
-MsqSetHooks(PUSER_MESSAGE_QUEUE Queue, PHOOKTABLE Hooks)
-{
- Queue->Hooks = Hooks;
-}
-
LPARAM FASTCALL
MsqSetMessageExtraInfo(LPARAM lParam)
{
return NULL;
}
-#ifndef NDEBUG
-static VOID FASTCALL
-DumpTimerList(PUSER_MESSAGE_QUEUE MessageQueue)
-{
- PLIST_ENTRY Current;
- PTIMER_ENTRY Timer;
-
- Current = MessageQueue->TimerListHead.Flink;
- if (Current == &MessageQueue->TimerListHead)
- {
- DPRINT("timer list is empty for queue %p\n", MessageQueue);
- }
- while (Current != &MessageQueue->TimerListHead)
- {
- Timer = CONTAINING_RECORD(Current, TIMER_ENTRY, ListEntry);
- DPRINT("queue %p timer %p expiry %I64d wnd %x id %p period %u timerproc %p msg %u\n",
- MessageQueue, Timer, Timer->ExpiryTime.QuadPart, Timer->Wnd, Timer->IDEvent,
- Timer->Period, Timer->TimerFunc, Timer->Msg);
- Current = Current->Flink;
- }
-}
-#endif /* ! defined(NDEBUG) */
-
-/* Must have the message queue locked while calling this */
-static VOID FASTCALL
-InsertTimer(PUSER_MESSAGE_QUEUE MessageQueue, PTIMER_ENTRY NewTimer)
-{
- PLIST_ENTRY Current;
-
- Current = MessageQueue->TimerListHead.Flink;
- while (Current != &MessageQueue->TimerListHead)
- {
- if (NewTimer->ExpiryTime.QuadPart <
- CONTAINING_RECORD(Current, TIMER_ENTRY, ListEntry)->ExpiryTime.QuadPart)
- {
- break;
- }
- Current = Current->Flink;
- }
-
- InsertTailList(Current, &NewTimer->ListEntry);
-}
-
-/* Must have the message queue locked while calling this */
-static PTIMER_ENTRY FASTCALL
-RemoveTimer(PUSER_MESSAGE_QUEUE MessageQueue, HWND Wnd, UINT_PTR IDEvent, UINT Msg)
-{
- PTIMER_ENTRY Timer;
- PLIST_ENTRY EnumEntry;
-
- /* Remove timer if already in the queue */
- EnumEntry = MessageQueue->TimerListHead.Flink;
- while (EnumEntry != &MessageQueue->TimerListHead)
- {
- Timer = CONTAINING_RECORD(EnumEntry, TIMER_ENTRY, ListEntry);
- EnumEntry = EnumEntry->Flink;
-
- if (Timer->Wnd == Wnd &&
- Timer->IDEvent == IDEvent &&
- Timer->Msg == Msg)
- {
- RemoveEntryList(&Timer->ListEntry);
- return Timer;
- }
- }
-
- return NULL;
-}
-
-BOOLEAN FASTCALL
-MsqSetTimer(PUSER_MESSAGE_QUEUE MessageQueue, HWND Wnd,
- UINT_PTR IDEvent, UINT Period, TIMERPROC TimerFunc,
- UINT Msg)
-{
- PTIMER_ENTRY Timer;
- LARGE_INTEGER CurrentTime;
-
- DPRINT("MsqSetTimer queue %p wnd %x id %p period %u timerproc %p msg %d\n",
- MessageQueue, Wnd, IDEvent, Period, TimerFunc, Msg);
-
- Timer = RemoveTimer(MessageQueue, Wnd, IDEvent, Msg);
- if (NULL == Timer)
- {
- Timer = ExAllocateFromPagedLookasideList(&TimerLookasideList);
- if (NULL == Timer)
- {
- DPRINT1("Failed to allocate timer entry\n");
- return FALSE;
- }
- DPRINT("Allocated new timer entry %p\n", Timer);
- Timer->Wnd = Wnd;
- Timer->IDEvent = IDEvent;
- Timer->Msg = Msg;
- }
- else
- {
- DPRINT("Updating existing timer entry %p\n", Timer);
- }
-
- KeQuerySystemTime(&CurrentTime);
- Timer->ExpiryTime.QuadPart = CurrentTime.QuadPart +
- (ULONGLONG) Period * (ULONGLONG) 10000;
- Timer->Period = Period;
- Timer->TimerFunc = TimerFunc;
- DPRINT("Insert timer now %I64d expiry %I64d\n", CurrentTime.QuadPart,
- Timer->ExpiryTime.QuadPart);
-
- InsertTimer(MessageQueue, Timer);
-
-#ifndef NDEBUG
-
- DumpTimerList(MessageQueue);
-#endif /* ! defined(NDEBUG) */
-
- return TRUE;
-}
-
-BOOLEAN FASTCALL
-MsqKillTimer(PUSER_MESSAGE_QUEUE MessageQueue, HWND Wnd,
- UINT_PTR IDEvent, UINT Msg)
-{
- PTIMER_ENTRY Timer;
-
- DPRINT("MsqKillTimer queue %p wnd %x id %p msg %d\n",
- MessageQueue, Wnd, IDEvent, Msg);
-
- Timer = RemoveTimer(MessageQueue, Wnd, IDEvent, Msg);
-
- if (NULL == Timer)
- {
- DPRINT("Failed to remove timer from list, not found\n");
- }
- else
- {
- ExFreeToPagedLookasideList(&TimerLookasideList, Timer);
- }
-
-#ifndef NDEBUG
- DumpTimerList(MessageQueue);
-#endif /* ! defined(NDEBUG) */
-
- return NULL != Timer;
-}
-
-BOOLEAN FASTCALL
-MsqGetTimerMessage(PUSER_MESSAGE_QUEUE MessageQueue,
- PWINDOW_OBJECT WindowFilter, UINT MsgFilterMin, UINT MsgFilterMax,
- MSG *Msg, BOOLEAN Restart)
-{
- PTIMER_ENTRY Timer;
- LARGE_INTEGER CurrentTime;
- LARGE_INTEGER LargeTickCount;
- PLIST_ENTRY EnumEntry;
- BOOLEAN GotMessage;
-
- DPRINT("MsqGetTimerMessage queue %p msg %p restart %s\n",
- MessageQueue, Msg, Restart ? "TRUE" : "FALSE");
-
- KeQuerySystemTime(&CurrentTime);
- DPRINT("Current time %I64d\n", CurrentTime.QuadPart);
- EnumEntry = MessageQueue->TimerListHead.Flink;
- GotMessage = FALSE;
- while (EnumEntry != &MessageQueue->TimerListHead)
- {
- Timer = CONTAINING_RECORD(MessageQueue->TimerListHead.Flink,
- TIMER_ENTRY, ListEntry);
- DPRINT("Checking timer %p wnd %x expiry %I64d\n", Timer, Timer->Wnd,
- Timer->ExpiryTime.QuadPart);
- EnumEntry = EnumEntry->Flink;
- if ((NULL == WindowFilter || Timer->Wnd == WindowFilter->hSelf) &&
- ((MsgFilterMin == 0 && MsgFilterMax == 0) ||
- (MsgFilterMin <= Timer->Msg &&
- Timer->Msg <= MsgFilterMax)))
- {
- if (Timer->ExpiryTime.QuadPart <= CurrentTime.QuadPart)
- {
- DPRINT("Timer is expired\n");
- GotMessage = TRUE;
- break;
- }
- else
- {
- DPRINT("No need to check later timers\n");
- break;
- }
- }
- else
- {
- DPRINT("timer %p (wnd %x msg %d) failed filter wnd %x msgmin %d msgmax %d\n",
- Timer, Timer->Wnd, Timer->Msg, WindowFilter->hSelf, MsgFilterMin, MsgFilterMax);
- }
- }
-
- if (! GotMessage)
- {
- DPRINT("No timer pending\n");
- return FALSE;
- }
-
- Msg->hwnd = Timer->Wnd;
- Msg->message = Timer->Msg;
- Msg->wParam = (WPARAM) Timer->IDEvent;
- Msg->lParam = (LPARAM) Timer->TimerFunc;
- KeQueryTickCount(&LargeTickCount);
- Msg->time = MsqCalculateMessageTime(&LargeTickCount);
- Msg->pt = gpsi->ptCursor;
-
- if (Restart)
- {
- RemoveEntryList(&Timer->ListEntry);
- Timer->ExpiryTime.QuadPart = CurrentTime.QuadPart +
- (ULONGLONG) Timer->Period * (ULONGLONG) 10000;
- DPRINT("Restarting timer %p expires %I64d\n", Timer, Timer->ExpiryTime.QuadPart);
- InsertTimer(MessageQueue, Timer);
-
-#ifndef NDEBUG
-
- DumpTimerList(MessageQueue);
-#endif /* ! defined(NDEBUG) */
-
- }
-
- DPRINT("Created message wnd %x msg %d wParam %u lParam %u\n", Msg->hwnd, Msg->message,
- Msg->wParam, Msg->lParam);
-
- return TRUE;
-}
-
-VOID FASTCALL
-MsqRemoveTimersWindow(PUSER_MESSAGE_QUEUE MessageQueue, HWND Wnd)
-{
- PTIMER_ENTRY Timer;
- PLIST_ENTRY EnumEntry;
-
- DPRINT("MsqRemoveTimersWindow queue %p wnd %x\n", MessageQueue, Wnd);
-
- EnumEntry = MessageQueue->TimerListHead.Flink;
- while (EnumEntry != &MessageQueue->TimerListHead)
- {
- Timer = CONTAINING_RECORD(EnumEntry, TIMER_ENTRY, ListEntry);
- EnumEntry = EnumEntry->Flink;
- if (Timer->Wnd == Wnd)
- {
- DPRINT("Removing timer %p because its window is going away\n", Timer);
- RemoveEntryList(&Timer->ListEntry);
- ExFreeToPagedLookasideList(&TimerLookasideList, Timer);
- }
- }
-
-#ifndef NDEBUG
- DumpTimerList(MessageQueue);
-#endif /* ! defined(NDEBUG) */
-
-}
-
-BOOLEAN FASTCALL
-MsqGetFirstTimerExpiry(PUSER_MESSAGE_QUEUE MessageQueue,
- PWINDOW_OBJECT WndFilter, UINT MsgFilterMin, UINT MsgFilterMax,
- PLARGE_INTEGER FirstTimerExpiry)
-{
- PTIMER_ENTRY Timer;
- PLIST_ENTRY EnumEntry;
-
- DPRINT("MsqGetFirstTimerExpiry queue %p wndfilter %x msgfiltermin %d msgfiltermax %d expiry %p\n",
- MessageQueue, WndFilter, MsgFilterMin, MsgFilterMax, FirstTimerExpiry);
-
- EnumEntry = MessageQueue->TimerListHead.Flink;
- while (EnumEntry != &MessageQueue->TimerListHead)
- {
- Timer = CONTAINING_RECORD(MessageQueue->TimerListHead.Flink,
- TIMER_ENTRY, ListEntry);
- EnumEntry = EnumEntry->Flink;
- if ((NULL == WndFilter || PtrToInt(WndFilter) == 1 || Timer->Wnd == WndFilter->hSelf) &&
- ((MsgFilterMin == 0 && MsgFilterMax == 0) ||
- (MsgFilterMin <= Timer->Msg &&
- Timer->Msg <= MsgFilterMax)))
- {
- *FirstTimerExpiry = Timer->ExpiryTime;
- DPRINT("First timer expires %I64d\n", Timer->ExpiryTime);
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
/* EOF */