- /* Check for hardware events. */
- Present = co_MsqFindMessage( ThreadQueue,
- TRUE,
- RemoveMessages,
- Window,
- MsgFilterMin,
- MsgFilterMax,
- &Message );
- if (Present)
- {
- RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
- if (RemoveMessages)
- {
- MsqDestroyMessage(Message);
- }
- goto MessageFound;
- }
-
- /* Check for sent messages again. */
- while (co_MsqDispatchOneSentMessage(ThreadQueue))
- ;
-
- /* Check for paint messages. */
- if ( IntGetPaintMessage( Window,
- MsgFilterMin,
- MsgFilterMax,
- pti,
- &Msg->Msg,
- RemoveMessages))
- {
- Msg->FreeLParam = 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(Present)
- {
-MessageFound:
-
- if(RemoveMessages)
- {
- PWINDOW_OBJECT MsgWindow = NULL;
-
- /* Mouse message process */
-
- if( Msg->Msg.hwnd &&
- ( MsgWindow = UserGetWindowObject(Msg->Msg.hwnd) ) &&
- Msg->Msg.message >= WM_MOUSEFIRST &&
- Msg->Msg.message <= WM_MOUSELAST )
- {
- USHORT HitTest;
-
- UserRefObjectCo(MsgWindow, &Ref);
-
- if ( co_IntTranslateMouseMessage( ThreadQueue,
- &Msg->Msg,
- &HitTest,
- TRUE))
- /* FIXME - check message filter again, if the message doesn't match anymore,
- search again */
- {
- UserDerefObjectCo(MsgWindow);
- /* eat the message, search again */
- goto CheckMessages;
- }
-
- if(ThreadQueue->CaptureWindow == NULL)
- {
- co_IntSendHitTestMessages(ThreadQueue, &Msg->Msg);
-
- if ( ( Msg->Msg.message != WM_MOUSEMOVE &&
- Msg->Msg.message != WM_NCMOUSEMOVE ) &&
- IS_BTN_MESSAGE(Msg->Msg.message, DOWN) &&
- co_IntActivateWindowMouse(ThreadQueue, &Msg->Msg, MsgWindow, &HitTest) )
- {
- UserDerefObjectCo(MsgWindow);
- /* eat the message, search again */
- goto CheckMessages;
- }
- }
-
- UserDerefObjectCo(MsgWindow);
- }
- else
- {
- co_IntSendHitTestMessages(ThreadQueue, &Msg->Msg);
- }
-
-// if(MsgWindow)
-// {
-// UserDereferenceObject(MsgWindow);
-// }
-
- goto MsgExit;
- }
-
- if ( ( Msg->Msg.hwnd &&
- Msg->Msg.message >= WM_MOUSEFIRST &&
- Msg->Msg.message <= WM_MOUSELAST ) &&
- co_IntTranslateMouseMessage( ThreadQueue,
- &Msg->Msg,
- &HitTest,
- FALSE) )
- /* FIXME - check message filter again, if the message doesn't match anymore,
- search again */
- {
- /* eat the message, search again */
- goto CheckMessages;
- }
-
-MsgExit:
- if ( ISITHOOKED(WH_MOUSE) &&
- Msg->Msg.message >= WM_MOUSEFIRST &&
- Msg->Msg.message <= WM_MOUSELAST )
- {
- MHook.pt = Msg->Msg.pt;
- MHook.hwnd = Msg->Msg.hwnd;
- MHook.wHitTestCode = HitTest;
- MHook.dwExtraInfo = 0;
- if (co_HOOK_CallHooks( WH_MOUSE,
- RemoveMsg ? HC_ACTION : HC_NOREMOVE,
- Msg->Msg.message,
- (LPARAM)&MHook ))
- {
- if (ISITHOOKED(WH_CBT))
- {
- MHook.pt = Msg->Msg.pt;
- MHook.hwnd = Msg->Msg.hwnd;
- MHook.wHitTestCode = HitTest;
- MHook.dwExtraInfo = 0;
- co_HOOK_CallHooks( WH_CBT,
- HCBT_CLICKSKIPPED,
- Msg->Msg.message,
- (LPARAM)&MHook);
- }
- return FALSE;
- }
- }
-
- if ( ISITHOOKED(WH_KEYBOARD) &&
- (Msg->Msg.message == WM_KEYDOWN || Msg->Msg.message == WM_KEYUP) )
- {
- if (co_HOOK_CallHooks( WH_KEYBOARD,
- RemoveMsg ? HC_ACTION : HC_NOREMOVE,
- LOWORD(Msg->Msg.wParam),
- Msg->Msg.lParam))
- {
- if (ISITHOOKED(WH_CBT))
- {
- /* skip this message */
- co_HOOK_CallHooks( WH_CBT,
- HCBT_KEYSKIPPED,
- LOWORD(Msg->Msg.wParam),
- Msg->Msg.lParam );
- }
- return FALSE;
- }
- }
- // The WH_GETMESSAGE hook enables an application to monitor messages about to
- // be returned by the GetMessage or PeekMessage function.
- if (ISITHOOKED(WH_GETMESSAGE))
- {
- //DPRINT1("Peek WH_GETMESSAGE -> %x\n",&Msg);
- co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)&Msg->Msg);
- }
- return TRUE;
- }
-
- return Present;
-}
-
-static NTSTATUS FASTCALL
-CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg, PMSGMEMORY MsgMemoryEntry)
-{
- NTSTATUS Status;
-
- PVOID KernelMem;
- UINT Size;
-
- *KernelModeMsg = *UserModeMsg;
-
- /* See if this message type is present in the table */
- if (NULL == MsgMemoryEntry)
- {
- /* Not present, no copying needed */
- return STATUS_SUCCESS;
- }
-
- /* Determine required size */
- Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
-
- if (0 != Size)
- {
- /* Allocate kernel mem */
- KernelMem = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
- if (NULL == KernelMem)
- {
- DPRINT1("Not enough memory to copy message to kernel mem\n");
- return STATUS_NO_MEMORY;
- }
- KernelModeMsg->lParam = (LPARAM) KernelMem;
-
- /* Copy data if required */
- if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_READ))
- {
- Status = MmCopyFromCaller(KernelMem, (PVOID) UserModeMsg->lParam, Size);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("Failed to copy message to kernel: invalid usermode buffer\n");
- ExFreePoolWithTag(KernelMem, TAG_MSG);
- return Status;
- }
- }
- else
- {
- /* Make sure we don't pass any secrets to usermode */
- RtlZeroMemory(KernelMem, Size);
- }
- }
- else
- {
- KernelModeMsg->lParam = 0;
- }
-
- return STATUS_SUCCESS;
-}
-
-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))
- {
- 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;
- }
- }