- co_IntSendMessageWithCallBack is called for two reasons; for messages that originate from win32k and from user mode when using Callbacks.
For both cases do not do anything with the sendqueue member of message struct and do not add the message to the senders dispatch message list.
- In msgqueue related functions, check if the message is a nowait messages before attempting to remove and entry from the dispatch message list as it doesnt exist.
- Fixes a NonPagedPool corruption that was occurring on regtest bootcd. Thanks Caemyr for testing.

svn path=/trunk/; revision=47849
This commit is contained in:
Michael Martin 2010-06-26 09:15:32 +00:00
parent 5b46128dfb
commit bc5e79f42d
2 changed files with 17 additions and 14 deletions

View file

@ -1646,8 +1646,8 @@ co_IntSendMessageWithCallBack( HWND hWnd,
Message->Msg.lParam = lParamPacked;
Message->CompletionEvent = NULL;
Message->Result = 0;
Message->SenderQueue = Win32Thread->MessageQueue;
IntReferenceMessageQueue(Message->SenderQueue);
Message->SenderQueue = NULL; //Win32Thread->MessageQueue;
IntReferenceMessageQueue(Window->pti->MessageQueue);
Message->CompletionCallback = CompletionCallback;
Message->CompletionCallbackContext = CompletionCallbackContext;
@ -1655,9 +1655,7 @@ co_IntSendMessageWithCallBack( HWND hWnd,
Message->HasPackedLParam = (lParamBufferSize > 0);
InsertTailList(&Window->pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
InsertTailList(&Win32Thread->MessageQueue->DispatchingMessagesHead, &Message->DispatchingListEntry);
IntDereferenceMessageQueue(Window->pti->MessageQueue);
IntDereferenceMessageQueue(Message->SenderQueue);
RETURN(TRUE);

View file

@ -936,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) */
@ -974,7 +977,6 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
Result);
}
/* Only if it is not a no wait message */
if (!(Message->HookMessage & MSQ_SENTNOWAIT))
{
@ -1033,8 +1035,9 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
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);
}
@ -1453,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,6 +1530,7 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
IntDereferenceMessageQueue(MessageQueue);
IntDereferenceMessageQueue(CurrentSentMessage->SenderQueue);
}
/* free the message */
ExFreePool(CurrentSentMessage);
}