[WIN32K] Free allocations with the tag that was used to allocate them
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / msgqueue.c
index b7f3c4b..33b8119 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;
    }
@@ -395,7 +382,7 @@ co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Win
       return(FALSE);
    }
 
-   if (CaptureWindow->MessageQueue != MessageQueue)
+   if (CaptureWindow->pti->MessageQueue != MessageQueue)
    {
       if (! FromGlobalQueue)
       {
@@ -418,34 +405,34 @@ co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Win
 
       /* lock the destination message queue, so we don't get in trouble with other
          threads, messing with it at the same time */
-      IntLockHardwareMessageQueue(CaptureWindow->MessageQueue);
-      InsertTailList(&CaptureWindow->MessageQueue->HardwareMessagesListHead,
+      IntLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
+      InsertTailList(&CaptureWindow->pti->MessageQueue->HardwareMessagesListHead,
                      &Message->ListEntry);
       if(Message->Msg.message == WM_MOUSEMOVE)
       {
-         if(CaptureWindow->MessageQueue->MouseMoveMsg)
+         if(CaptureWindow->pti->MessageQueue->MouseMoveMsg)
          {
             /* remove the old WM_MOUSEMOVE message, we're processing a more recent
                one */
-            RemoveEntryList(&CaptureWindow->MessageQueue->MouseMoveMsg->ListEntry);
-            ExFreePool(CaptureWindow->MessageQueue->MouseMoveMsg);
+            RemoveEntryList(&CaptureWindow->pti->MessageQueue->MouseMoveMsg->ListEntry);
+            ExFreePool(CaptureWindow->pti->MessageQueue->MouseMoveMsg);
          }
          /* save the pointer to the WM_MOUSEMOVE message in the new queue */
-         CaptureWindow->MessageQueue->MouseMoveMsg = Message;
+         CaptureWindow->pti->MessageQueue->MouseMoveMsg = Message;
 
-         CaptureWindow->MessageQueue->QueueBits |= QS_MOUSEMOVE;
-         CaptureWindow->MessageQueue->ChangedBits |= QS_MOUSEMOVE;
-         if (CaptureWindow->MessageQueue->WakeMask & QS_MOUSEMOVE)
-            KeSetEvent(CaptureWindow->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
+         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);
       }
       else
       {
-         CaptureWindow->MessageQueue->QueueBits |= QS_MOUSEBUTTON;
-         CaptureWindow->MessageQueue->ChangedBits |= QS_MOUSEBUTTON;
-         if (CaptureWindow->MessageQueue->WakeMask & QS_MOUSEBUTTON)
-            KeSetEvent(CaptureWindow->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
+         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);
       }
-      IntUnLockHardwareMessageQueue(CaptureWindow->MessageQueue);
+      IntUnLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
 
       *Freed = FALSE;
       UserDereferenceObject(CaptureWindow);
@@ -466,21 +453,21 @@ co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Win
          /* 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->MessageQueue);
+         IntLockHardwareMessageQueue(CaptureWindow->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->MessageQueue->HardwareMessagesListHead,
+         InsertTailList(&CaptureWindow->pti->MessageQueue->HardwareMessagesListHead,
                         &Message->ListEntry);
       }
 
       if (Message->Msg.message == WM_MOUSEMOVE)
       {
-         if(CaptureWindow->MessageQueue->MouseMoveMsg &&
-               (CaptureWindow->MessageQueue->MouseMoveMsg != Message))
+         if(CaptureWindow->pti->MessageQueue->MouseMoveMsg &&
+               (CaptureWindow->pti->MessageQueue->MouseMoveMsg != Message))
          {
             /* delete the old message */
-            RemoveEntryList(&CaptureWindow->MessageQueue->MouseMoveMsg->ListEntry);
-            ExFreePool(CaptureWindow->MessageQueue->MouseMoveMsg);
+            RemoveEntryList(&CaptureWindow->pti->MessageQueue->MouseMoveMsg->ListEntry);
+            ExFreePool(CaptureWindow->pti->MessageQueue->MouseMoveMsg);
             if (!FromGlobalQueue)
             {
                // We might have deleted the next one in our queue, so fix next
@@ -489,11 +476,11 @@ co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Win
          }
          /* always save a pointer to this WM_MOUSEMOVE message here because we're
             sure that the message is in the private queue */
-         CaptureWindow->MessageQueue->MouseMoveMsg = Message;
+         CaptureWindow->pti->MessageQueue->MouseMoveMsg = Message;
       }
       if(FromGlobalQueue)
       {
-         IntUnLockHardwareMessageQueue(CaptureWindow->MessageQueue);
+         IntUnLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
       }
 
       UserDereferenceObject(CaptureWindow);
@@ -516,22 +503,22 @@ co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Win
          /* 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->MessageQueue);
-         if(CaptureWindow->MessageQueue->MouseMoveMsg)
+         IntLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
+         if(CaptureWindow->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->MessageQueue->MouseMoveMsg->ListEntry);
-            ExFreePool(CaptureWindow->MessageQueue->MouseMoveMsg);
+            RemoveEntryList(&CaptureWindow->pti->MessageQueue->MouseMoveMsg->ListEntry);
+            ExFreePool(CaptureWindow->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->MessageQueue->MouseMoveMsg = NULL;
+            CaptureWindow->pti->MessageQueue->MouseMoveMsg = NULL;
          }
-         IntUnLockHardwareMessageQueue(CaptureWindow->MessageQueue);
+         IntUnLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
       }
-      else if (CaptureWindow->MessageQueue->MouseMoveMsg == Message)
+      else if (CaptureWindow->pti->MessageQueue->MouseMoveMsg == Message)
       {
-         CaptureWindow->MessageQueue->MouseMoveMsg = NULL;
+         CaptureWindow->pti->MessageQueue->MouseMoveMsg = NULL;
       }
    }
 
@@ -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. */
 
@@ -884,7 +827,7 @@ MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam)
    KeQueryTickCount(&LargeTickCount);
    Mesg.time = MsqCalculateMessageTime(&LargeTickCount);
    Mesg.pt = gpsi->ptCursor;
-   MsqPostMessage(Window->MessageQueue, &Mesg, FALSE, QS_HOTKEY);
+   MsqPostMessage(Window->pti->MessageQueue, &Mesg, FALSE, QS_HOTKEY);
    UserDereferenceObject(Window);
    ObDereferenceObject (Thread);
 
@@ -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))
    {
@@ -996,7 +938,7 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
 
    /* remove the message from the dispatching list, so lock the sender's message queue */
    SenderReturned = (Message->DispatchingListEntry.Flink == NULL);
-   if(!SenderReturned)
+   if (!SenderReturned)
    {
       /* only remove it from the dispatching list if not already removed by a timeout */
       RemoveEntryList(&Message->DispatchingListEntry);
@@ -1010,39 +952,38 @@ 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);
 }
 
@@ -1057,7 +998,7 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
 
    ASSERT(Window);
 
-   MessageQueue = Window->MessageQueue;
+   MessageQueue = Window->pti->MessageQueue;
    ASSERT(MessageQueue);
 
    /* remove the posted messages for this window */
@@ -1090,7 +1031,7 @@ 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)
@@ -1104,12 +1045,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 +1125,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
    IntReferenceMessageQueue(ThreadQueue);
    Message->CompletionCallback = NULL;
    Message->HookMessage = HookMessage;
+   Message->HasPackedLParam = FALSE;
 
    IntReferenceMessageQueue(MessageQueue);
 
@@ -1363,9 +1315,12 @@ co_MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
 
    if (Hardware)
    {
-      return(co_MsqPeekHardwareMessage(MessageQueue, Window,
-                                       MsgFilterLow, MsgFilterHigh,
-                                       Remove, Message));
+      return(co_MsqPeekHardwareMessage( MessageQueue,
+                                        Window,
+                                        MsgFilterLow,
+                                        MsgFilterHigh,
+                                        Remove,
+                                        Message));
    }
 
    CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
@@ -1374,10 +1329,12 @@ co_MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
    {
       CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
                                          ListEntry);
-      if ((!Window || PtrToInt(Window) == 1 || Window->hSelf == CurrentMessage->Msg.hwnd) &&
-            ((MsgFilterLow == 0 && MsgFilterHigh == 0) ||
-             (MsgFilterLow <= CurrentMessage->Msg.message &&
-              MsgFilterHigh >= CurrentMessage->Msg.message)))
+      if ( ( !Window ||
+            PtrToInt(Window) == 1 ||
+            Window->hSelf == CurrentMessage->Msg.hwnd ) &&
+            ( (MsgFilterLow == 0 && MsgFilterHigh == 0) ||
+              ( MsgFilterLow <= CurrentMessage->Msg.message &&
+                MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
       {
          if (Remove)
          {
@@ -1398,19 +1355,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();
@@ -1421,11 +1367,9 @@ co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT WndFil
                                   Executive,
                                   UserMode,
                                   FALSE,
-                                  Timeout,
+                                  NULL,
                                   NULL);
-
    UserEnterCo();
-
    return ret;
 }
 
@@ -1521,9 +1465,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);
@@ -1559,10 +1513,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);
    }