From 786f5a19d7bb470d3c3eb05343d3ba2c04af2bc6 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Sun, 9 May 2010 12:27:57 +0000 Subject: [PATCH] [win32k] - When message are sent without waiting a reply (non-queued messages) the message queues are referenced and dereferenced in the call. Message removal and cleanup functions for queues expected a reference on the queue. Add checks to determine if the message is a non-queued message and if so release memory for those that had pointers and more importantly skip dereferencing the queues. Possibly fixes random crashes and memory leaks. svn path=/trunk/; revision=47142 --- .../subsystems/win32/win32k/ntuser/msgqueue.c | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index 4b45bac5c21..5bfe414b5ed 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -1072,7 +1072,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) @@ -1086,9 +1086,19 @@ 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); @@ -1509,9 +1519,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); @@ -1547,10 +1567,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); }