[win32k]
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / msgqueue.c
index ec866f5..1bba2a1 100644 (file)
@@ -28,7 +28,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -171,11 +171,14 @@ MsqInitializeImpl(VOID)
 VOID FASTCALL
 MsqInsertSystemMessage(MSG* Msg)
 {
-   LARGE_INTEGER LargeTickCount;
    KIRQL OldIrql;
    ULONG Prev;
-   EVENTMSG Event;
 
+   /*
+    * If we got WM_MOUSEMOVE and there are already messages in the
+    * system message queue, check if the last message is mouse move
+    * and if it is then just overwrite it.
+    */
    IntLockSystemMessageQueue(OldIrql);
 
    /*
@@ -189,22 +192,6 @@ MsqInsertSystemMessage(MSG* Msg)
       return;
    }
 
-   KeQueryTickCount(&LargeTickCount);
-   Msg->time = MsqCalculateMessageTime(&LargeTickCount);
-
-   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);
-
-   /*
-    * If we got WM_MOUSEMOVE and there are already messages in the
-    * system message queue, check if the last message is mouse move
-    * and if it is then just overwrite it.
-    */
-
    if (Msg->message == WM_MOUSEMOVE && SystemMessageQueueCount)
    {
       if (SystemMessageQueueTail == 0)
@@ -240,7 +227,7 @@ MsqIsClkLck(LPMSG Msg, BOOL Remove)
    BOOL Res = FALSE;
 
    pti = PsGetCurrentThreadWin32Thread();
-   if (pti->Desktop == NULL)
+   if (pti->rpdesk == NULL)
    {
       return FALSE;
    }
@@ -281,7 +268,7 @@ MsqIsDblClk(LPMSG Msg, BOOL Remove)
    BOOL Res;
 
    pti = PsGetCurrentThreadWin32Thread();
-   if (pti->Desktop == NULL)
+   if (pti->rpdesk == NULL)
    {
       return FALSE;
    }
@@ -623,7 +610,6 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Windo
    {
       PUSER_MESSAGE UserMsg;
       MSG Msg;
-      BOOL ProcessMessage;
 
       ASSERT(SystemMessageQueueHead < SYSTEM_MESSAGE_QUEUE_SIZE);
       Msg = SystemMessageQueue[SystemMessageQueueHead];
@@ -631,48 +617,14 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Windo
          (SystemMessageQueueHead + 1) % SYSTEM_MESSAGE_QUEUE_SIZE;
       SystemMessageQueueCount--;
       IntUnLockSystemMessageQueue(OldIrql);
-      if (WM_MOUSEFIRST <= Msg.message && Msg.message <= WM_MOUSELAST)
-      {
-         MSLLHOOKSTRUCT MouseHookData;
 
-         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;
-         ProcessMessage = (0 == co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION,
-                           Msg.message, (LPARAM) &MouseHookData));
-      }
-      else
-      {
-         ProcessMessage = TRUE;
-      }
-      if (ProcessMessage)
-      {
-         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);
-      }
+      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);
+
       IntLockSystemMessageQueue(OldIrql);
    }
    HardwareMessageQueueStamp++;
@@ -767,7 +719,6 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    MSG Msg;
    LARGE_INTEGER LargeTickCount;
    KBDLLHOOKSTRUCT KbdHookData;
-   EVENTMSG Event;
    BOOLEAN Entered = FALSE;
 
    DPRINT("MsqPostKeyboardMessage(uMsg 0x%x, wParam 0x%x, lParam 0x%x)\n",
@@ -795,14 +746,6 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    KeQueryTickCount(&LargeTickCount);
    Msg.time = MsqCalculateMessageTime(&LargeTickCount);
 
-   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);
-
    /* We can't get the Msg.pt point here since we don't know thread
       (and thus the window station) the message will end up in yet. */
 
@@ -951,7 +894,6 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
    PLIST_ENTRY Entry;
    LRESULT Result;
    BOOL SenderReturned;
-   PUSER_SENT_MESSAGE_NOTIFY NotifyMessage;
 
    if (IsListEmpty(&MessageQueue->SentMessagesListHead))
    {
@@ -994,12 +936,15 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
       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);
+      SenderReturned = (Message->DispatchingListEntry.Flink == NULL);
+      if (!SenderReturned)
+      {
+         /* 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) */
@@ -1010,39 +955,37 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
       *Message->Result = Result;
    }
 
+   if (Message->HasPackedLParam == TRUE)
+   {
+      if (Message->Msg.lParam)
+         ExFreePool((PVOID)Message->Msg.lParam);
+   }
+
    /* Notify the sender. */
    if (Message->CompletionEvent != NULL)
    {
       KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE);
    }
 
-   /* Notify the sender if they specified a callback. */
+   /* Call the callback if the message was sent with SendMessageCallback */
    if (!SenderReturned && Message->CompletionCallback != NULL)
    {
-      if(!(NotifyMessage = ExAllocatePoolWithTag(NonPagedPool,
-                           sizeof(USER_SENT_MESSAGE_NOTIFY), TAG_USRMSG)))
-      {
-         DPRINT1("MsqDispatchOneSentMessage(): Not enough memory to create a callback notify message\n");
-         goto Notified;
-      }
-      NotifyMessage->CompletionCallback =
-         Message->CompletionCallback;
-      NotifyMessage->CompletionCallbackContext =
-         Message->CompletionCallbackContext;
-      NotifyMessage->Result = Result;
-      NotifyMessage->hWnd = Message->Msg.hwnd;
-      NotifyMessage->Msg = Message->Msg.message;
-      MsqSendNotifyMessage(Message->SenderQueue, NotifyMessage);
+      co_IntCallSentMessageCallback(Message->CompletionCallback,
+                                    Message->Msg.hwnd,
+                                    Message->Msg.message,
+                                    Message->CompletionCallbackContext,
+                                    Result);
    }
 
-Notified:
-
-   /* dereference both sender and our queue */
-   IntDereferenceMessageQueue(MessageQueue);
-   IntDereferenceMessageQueue(Message->SenderQueue);
+   /* Only if it is not a no wait message */
+   if (!(Message->HookMessage & MSQ_SENTNOWAIT))
+   {
+      IntDereferenceMessageQueue(Message->SenderQueue);
+      IntDereferenceMessageQueue(MessageQueue);
+   }
 
    /* free the message */
-   ExFreePool(Message);
+   ExFreePoolWithTag(Message, TAG_USRMSG);
    return(TRUE);
 }
 
@@ -1090,10 +1033,11 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
       {
          DPRINT("Notify the sender and remove a message from the queue that had not been dispatched\n");
 
-        RemoveEntryList(&SentMessage->ListEntry);
+         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);
          }
@@ -1104,12 +1048,22 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
             KeSetEvent(SentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE);
          }
 
-         /* dereference our and the sender's message queue */
-         IntDereferenceMessageQueue(MessageQueue);
-         IntDereferenceMessageQueue(SentMessage->SenderQueue);
+         if (SentMessage->HasPackedLParam == TRUE)
+         {
+            if (SentMessage->Msg.lParam)
+               ExFreePool((PVOID)SentMessage->Msg.lParam);
+         }
+
+         /* Only if it is not a no wait message */
+         if (!(SentMessage->HookMessage & MSQ_SENTNOWAIT))
+         {
+            /* dereference our and the sender's message queue */
+            IntDereferenceMessageQueue(MessageQueue);
+            IntDereferenceMessageQueue(SentMessage->SenderQueue);
+         }
 
          /* free the message */
-         ExFreePool(SentMessage);
+         ExFreePoolWithTag(SentMessage, TAG_USRMSG);
 
          CurrentEntry = MessageQueue->SentMessagesListHead.Flink;
       }
@@ -1174,6 +1128,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
    IntReferenceMessageQueue(ThreadQueue);
    Message->CompletionCallback = NULL;
    Message->HookMessage = HookMessage;
+   Message->HasPackedLParam = FALSE;
 
    IntReferenceMessageQueue(MessageQueue);
 
@@ -1403,19 +1358,8 @@ co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT WndFil
                          UINT MsgFilterMin, UINT MsgFilterMax)
 {
    PVOID WaitObjects[2] = {MessageQueue->NewMessages, &HardwareMessageEvent};
-   LARGE_INTEGER TimerExpiry;
-   PLARGE_INTEGER Timeout;
    NTSTATUS ret;
 
-   if (MsqGetFirstTimerExpiry(MessageQueue, WndFilter, MsgFilterMin, MsgFilterMax, &TimerExpiry))
-   {
-      Timeout = &TimerExpiry;
-   }
-   else
-   {
-      Timeout = NULL;
-   }
-
    IdlePing(); // Going to wait so send Idle ping.
 
    UserLeaveCo();
@@ -1426,11 +1370,9 @@ co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT WndFil
                                   Executive,
                                   UserMode,
                                   FALSE,
-                                  Timeout,
+                                  NULL,
                                   NULL);
-
    UserEnterCo();
-
    return ret;
 }
 
@@ -1514,8 +1456,9 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
 
       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);
       }
@@ -1526,9 +1469,19 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
          KeSetEvent(CurrentSentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE);
       }
 
-      /* dereference our and the sender's message queue */
-      IntDereferenceMessageQueue(MessageQueue);
-      IntDereferenceMessageQueue(CurrentSentMessage->SenderQueue);
+      if (CurrentSentMessage->HasPackedLParam == TRUE)
+      {
+         if (CurrentSentMessage->Msg.lParam)
+            ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
+      }
+
+      /* Only if it is not a no wait message */
+      if (!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT))
+      {
+         /* dereference our and the sender's message queue */
+         IntDereferenceMessageQueue(MessageQueue);
+         IntDereferenceMessageQueue(CurrentSentMessage->SenderQueue);
+      }
 
       /* free the message */
       ExFreePool(CurrentSentMessage);
@@ -1564,9 +1517,19 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
          KeSetEvent(CurrentSentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE);
       }
 
-      /* dereference our and the sender's message queue */
-      IntDereferenceMessageQueue(MessageQueue);
-      IntDereferenceMessageQueue(CurrentSentMessage->SenderQueue);
+      if (CurrentSentMessage->HasPackedLParam == TRUE)
+      {
+         if (CurrentSentMessage->Msg.lParam)
+            ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
+      }
+
+      /* Only if it is not a no wait message */
+      if (!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT))
+      {
+         /* dereference our and the sender's message queue */
+         IntDereferenceMessageQueue(MessageQueue);
+         IntDereferenceMessageQueue(CurrentSentMessage->SenderQueue);
+      }
 
       /* free the message */
       ExFreePool(CurrentSentMessage);