Don't set Message->DispatchingListEntry.Flink to NULL / compare against NULL, but use InitializeListHead and IsListEmpty. Make sure the list entry is properly initialize, when the item is removed Fixes list corruption.

svn path=/trunk/; revision=66661
This commit is contained in:
Timo Kreuzer 2015-03-10 10:27:00 +00:00
parent e5c8124164
commit 3ea483bc85
2 changed files with 17 additions and 11 deletions

View file

@ -1698,7 +1698,8 @@ co_IntSendMessageWithCallBack( HWND hWnd,
Message->ptiReceiver = ptiSendTo; Message->ptiReceiver = ptiSendTo;
Message->ptiSender = NULL; // mjmartin, you are right! This is null. Message->ptiSender = NULL; // mjmartin, you are right! This is null.
Message->ptiCallBackSender = Win32Thread; Message->ptiCallBackSender = Win32Thread;
Message->DispatchingListEntry.Flink = NULL; InitializeListHead(&Message->DispatchingListEntry);
//Message->DispatchingListEntry.Flink = NULL;
Message->CompletionCallback = CompletionCallback; Message->CompletionCallback = CompletionCallback;
Message->CompletionCallbackContext = CompletionCallbackContext; Message->CompletionCallbackContext = CompletionCallbackContext;
Message->HookMessage = MSQ_NORMAL; Message->HookMessage = MSQ_NORMAL;

View file

@ -840,15 +840,16 @@ co_MsqDispatchOneSentMessage(
/* remove the message from the dispatching list if needed, so lock the sender's message queue */ /* remove the message from the dispatching list if needed, so lock the sender's message queue */
if (Message->ptiSender && !(Message->ptiSender->TIF_flags & TIF_INCLEANUP)) if (Message->ptiSender && !(Message->ptiSender->TIF_flags & TIF_INCLEANUP))
{ {
if (Message->DispatchingListEntry.Flink != NULL) if (!IsListEmpty(&Message->DispatchingListEntry))
{ {
/* only remove it from the dispatching list if not already removed by a timeout */ /* only remove it from the dispatching list if not already removed by a timeout */
RemoveEntryList(&Message->DispatchingListEntry); RemoveEntryList(&Message->DispatchingListEntry);
InitializeListHead(&Message->DispatchingListEntry);
} }
} }
/* still keep the sender's message queue locked, so the sender can't exit the /* still keep the sender's message queue locked, so the sender can't exit the
MsqSendMessage() function (if timed out) */ MsqSendMessage() function (if timed out) */
if (Message->QS_Flags & QS_SMRESULT) if (Message->QS_Flags & QS_SMRESULT)
{ {
Result = Message->lResult; Result = Message->lResult;
@ -935,10 +936,11 @@ MsqRemoveWindowMessagesFromQueue(PWND Window)
ClearMsgBitsMask(pti, SentMessage->QS_Flags); ClearMsgBitsMask(pti, SentMessage->QS_Flags);
/* Only if the message has a sender was the queue referenced */ /* Only if the message has a sender was the queue referenced */
if ((SentMessage->ptiSender) if ((SentMessage->ptiSender) &&
&& (SentMessage->DispatchingListEntry.Flink != NULL)) (!IsListEmpty(&SentMessage->DispatchingListEntry)))
{ {
RemoveEntryList(&SentMessage->DispatchingListEntry); RemoveEntryList(&SentMessage->DispatchingListEntry);
InitializeListHead(&SentMessage->DispatchingListEntry);
} }
/* wake the sender's thread */ /* wake the sender's thread */
@ -998,7 +1000,7 @@ co_MsqSendMessageAsync(PTHREADINFO ptiReceiver,
Message->ptiReceiver = ptiReceiver; Message->ptiReceiver = ptiReceiver;
Message->ptiSender = NULL; Message->ptiSender = NULL;
Message->ptiCallBackSender = ptiSender; Message->ptiCallBackSender = ptiSender;
Message->DispatchingListEntry.Flink = NULL; InitializeListHead(&Message->DispatchingListEntry);
Message->CompletionCallback = CompletionCallback; Message->CompletionCallback = CompletionCallback;
Message->CompletionCallbackContext = CompletionCallbackContext; Message->CompletionCallbackContext = CompletionCallbackContext;
Message->HookMessage = HookMessage; Message->HookMessage = HookMessage;
@ -1180,7 +1182,7 @@ co_MsqSendMessage(PTHREADINFO ptirec,
Message->CompletionEvent = NULL; Message->CompletionEvent = NULL;
Message->Result = NULL; Message->Result = NULL;
RemoveEntryList(&Message->DispatchingListEntry); RemoveEntryList(&Message->DispatchingListEntry);
Message->DispatchingListEntry.Flink = NULL; InitializeListHead(&Message->DispatchingListEntry);
break; break;
} }
Entry = Entry->Flink; Entry = Entry->Flink;
@ -1221,6 +1223,7 @@ co_MsqSendMessage(PTHREADINFO ptirec,
Message->Result = NULL; Message->Result = NULL;
RemoveEntryList(&Message->ListEntry); RemoveEntryList(&Message->ListEntry);
RemoveEntryList(&Message->DispatchingListEntry); RemoveEntryList(&Message->DispatchingListEntry);
InitializeListHead(&Message->DispatchingListEntry);
ClearMsgBitsMask(ptirec, Message->QS_Flags); ClearMsgBitsMask(ptirec, Message->QS_Flags);
ExFreePoolWithTag(Message, TAG_USRMSG); ExFreePoolWithTag(Message, TAG_USRMSG);
break; break;
@ -1244,7 +1247,7 @@ co_MsqSendMessage(PTHREADINFO ptirec,
Message->CompletionEvent = NULL; Message->CompletionEvent = NULL;
Message->Result = NULL; Message->Result = NULL;
RemoveEntryList(&Message->DispatchingListEntry); RemoveEntryList(&Message->DispatchingListEntry);
Message->DispatchingListEntry.Flink = NULL; InitializeListHead(&Message->DispatchingListEntry);
break; break;
} }
Entry = Entry->Flink; Entry = Entry->Flink;
@ -2062,10 +2065,11 @@ MsqCleanupThreadMsgs(PTHREADINFO pti)
TRACE("Notify the sender and remove a message from the queue that had not been dispatched\n"); TRACE("Notify the sender and remove a message from the queue that had not been dispatched\n");
/* Only if the message has a sender was the message in the DispatchingList */ /* Only if the message has a sender was the message in the DispatchingList */
if ((CurrentSentMessage->ptiSender) if ((CurrentSentMessage->ptiSender) &&
&& (CurrentSentMessage->DispatchingListEntry.Flink != NULL)) (!IsListEmpty(&CurrentSentMessage->DispatchingListEntry)))
{ {
RemoveEntryList(&CurrentSentMessage->DispatchingListEntry); RemoveEntryList(&CurrentSentMessage->DispatchingListEntry);
InitializeListHead(&CurrentSentMessage->DispatchingListEntry);
} }
/* wake the sender's thread */ /* wake the sender's thread */
@ -2092,9 +2096,10 @@ MsqCleanupThreadMsgs(PTHREADINFO pti)
CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry); CurrentSentMessage = CONTAINING_RECORD(CurrentEntry, USER_SENT_MESSAGE, ListEntry);
/* remove the message from the dispatching list */ /* remove the message from the dispatching list */
if(CurrentSentMessage->DispatchingListEntry.Flink != NULL) if (!IsListEmpty(&CurrentSentMessage->DispatchingListEntry))
{ {
RemoveEntryList(&CurrentSentMessage->DispatchingListEntry); RemoveEntryList(&CurrentSentMessage->DispatchingListEntry);
InitializeListHead(&CurrentSentMessage->DispatchingListEntry);
} }
TRACE("Notify the sender, the thread has been terminated while dispatching a message!\n"); TRACE("Notify the sender, the thread has been terminated while dispatching a message!\n");