From de078e7357eacd7a1e862a00db6568e2bc40785d Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 27 Apr 2011 23:49:09 +0000 Subject: [PATCH] [WIN32K] Don't send messages from or to a thread in cleanup. Fixes possible deadlock. svn path=/trunk/; revision=51469 --- .../subsystems/win32/win32k/ntuser/msgqueue.c | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index e7371277601..cd57a5082a5 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -64,7 +64,7 @@ static void set_input_key_state( PUSER_MESSAGE_QUEUE MessageQueue, UCHAR key, BO { if (down) { - if (!(MessageQueue->KeyState[key] & KS_DOWN_BIT)) + if (!(MessageQueue->KeyState[key] & KS_DOWN_BIT)) { MessageQueue->KeyState[key] ^= KS_LOCK_BIT; } @@ -106,9 +106,9 @@ static void update_input_key_state( PUSER_MESSAGE_QUEUE MessageQueue, MSG* msg ) down = 1; /* fall through */ case WM_XBUTTONUP: - if (msg->wParam == XBUTTON1) + if (msg->wParam == XBUTTON1) set_input_key_state( MessageQueue, VK_XBUTTON1, down ); - else if (msg->wParam == XBUTTON2) + else if (msg->wParam == XBUTTON2) set_input_key_state( MessageQueue, VK_XBUTTON2, down ); break; case WM_KEYDOWN: @@ -223,7 +223,7 @@ ClearMsgBitsMask(PUSER_MESSAGE_QUEUE Queue, UINT MessageBits) pti = Queue->Thread->Tcb.Win32Thread; if (MessageBits & QS_KEY) - { + { if (--Queue->nCntsQBits[QSRosKey] == 0) ClrMask |= QS_KEY; } if (MessageBits & QS_MOUSEMOVE) // ReactOS hard coded. @@ -347,7 +347,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook if(Msg->hwnd != NULL) { pwnd = UserGetWindowObject(Msg->hwnd); - if ((pwnd->style & WS_VISIBLE) && + if ((pwnd->style & WS_VISIBLE) && IntPtInWindow(pwnd, Msg->pt.x, Msg->pt.y)) { pDesk->htEx = HTCLIENT; @@ -367,7 +367,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook continue; } - if((pwnd->style & WS_VISIBLE) && + if((pwnd->style & WS_VISIBLE) && IntPtInWindow(pwnd, Msg->pt.x, Msg->pt.y)) { Msg->hwnd = pwnd->head.h; @@ -817,7 +817,14 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, ptirec = MessageQueue->Thread->Tcb.Win32Thread; ASSERT(ThreadQueue != MessageQueue); ASSERT(ptirec->pcti); // Send must have a client side to receive it!!!! - + + /* Don't send from or to a dying thread */ + if (pti->TIF_flags & TIF_INCLEANUP || ptirec->TIF_flags & TIF_INCLEANUP) + { + *uResult = -1; + return STATUS_TIMEOUT; + } + Timeout.QuadPart = (LONGLONG) uTimeout * (LONGLONG) -10000; /* FIXME - increase reference counter of sender's message queue here */ @@ -1034,7 +1041,7 @@ static void MsqSendParentNotify( PWND pwnd, WORD event, WORD idChild, POINT pt ) if (pwndParent == pwndDesktop) break; pt.x += pwnd->rcClient.left - pwndParent->rcClient.left; pt.y += pwnd->rcClient.top - pwndParent->rcClient.top; - + pwnd = pwndParent; co_IntSendMessage( UserHMGetHandle(pwnd), WM_PARENTNOTIFY, MAKEWPARAM( event, idChild ), MAKELPARAM( pt.x, pt.y ) ); @@ -1076,7 +1083,7 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT } DPRINT("Got mouse message for 0x%x, hittest: 0x%x\n", msg->hwnd, hittest ); - + if (pwndMsg == NULL || pwndMsg->head.pti != pti) { /* Remove and ignore the message */ @@ -1146,7 +1153,7 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT } } - if (!((first == 0 && last == 0) || (message >= first || message <= last))) + if (!((first == 0 && last == 0) || (message >= first || message <= last))) { DPRINT("Message out of range!!!\n"); RETURN(FALSE); @@ -1267,8 +1274,8 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT if (pwndTop && pwndTop != pwndDesktop) { - LONG ret = co_IntSendMessage( msg->hwnd, - WM_MOUSEACTIVATE, + LONG ret = co_IntSendMessage( msg->hwnd, + WM_MOUSEACTIVATE, (WPARAM)UserHMGetHandle(pwndTop), MAKELONG( hittest, msg->message)); switch(ret) @@ -1443,7 +1450,7 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue, CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry); - do + do { if (IsListEmpty(CurrentEntry)) break; if (!CurrentMessage) break; @@ -1490,7 +1497,7 @@ MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue, PLIST_ENTRY CurrentEntry; PUSER_MESSAGE CurrentMessage; PLIST_ENTRY ListHead; - + CurrentEntry = MessageQueue->PostedMessagesListHead.Flink; ListHead = &MessageQueue->PostedMessagesListHead; @@ -1542,7 +1549,7 @@ co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWND WndFilter, ret = KeWaitForSingleObject( MessageQueue->NewMessages, UserRequest, UserMode, - FALSE, + FALSE, NULL ); UserEnterCo(); return ret; @@ -1614,7 +1621,7 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue) PUSER_MESSAGE CurrentMessage; PUSER_SENT_MESSAGE CurrentSentMessage; PTHREADINFO pti; - + pti = MessageQueue->Thread->Tcb.Win32Thread; @@ -1642,7 +1649,7 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue) DPRINT("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 */ - if ((CurrentSentMessage->SenderQueue) + if ((CurrentSentMessage->SenderQueue) && (CurrentSentMessage->DispatchingListEntry.Flink != NULL)) { RemoveEntryList(&CurrentSentMessage->DispatchingListEntry);