Index: win32ss/user/ntuser/input.c =================================================================== --- win32ss/user/ntuser/input.c (revision 57054) +++ win32ss/user/ntuser/input.c (working copy) @@ -446,7 +446,10 @@ ERR("Attach Allocated! ptiFrom 0x%p ptiTo 0x%p\n",ptiFrom,ptiTo); ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel; - ptiFrom->pqAttach = ptiFrom->MessageQueue; + + /* Keep the original queue in pqAttach (ie do not trash it in a second attachment) */ + if(ptiFrom->pqAttach == NULL) + ptiFrom->pqAttach = ptiFrom->MessageQueue; ptiFrom->MessageQueue = ptiTo->MessageQueue; // FIXME: conditions? if (ptiFrom->pqAttach == gpqForeground) @@ -478,12 +481,32 @@ if (!pai) return FALSE; + ASSERT(ptiFrom->pqAttach); + if (paiprev) paiprev->paiNext = pai->paiNext; else if (!pai->paiNext) gpai = NULL; - + else if (gpai == pai) gpai = pai->paiNext; + ExFreePoolWithTag(pai, USERTAG_ATTACHINFO); ERR("Attach Free! ptiFrom 0x%p ptiTo 0x%p\n",ptiFrom,ptiTo); + /* Search list and check if the thread is attached one more time */ + pai = gpai; + while(pai) + { + /* If the thread is attached again , we are done */ + if (pai->pti1 == ptiFrom) + { + /* Use the message queue of the last attachment */ + ptiFrom->MessageQueue = pai->pti2->MessageQueue; + ptiFrom->MessageQueue->CursorObject = NULL; + ptiFrom->MessageQueue->spwndActive = NULL; + ptiFrom->MessageQueue->spwndFocus = NULL; + return TRUE; + } + pai = pai->paiNext; + } + ptiFrom->MessageQueue = ptiFrom->pqAttach; // FIXME: conditions? ptiFrom->MessageQueue->CursorObject = NULL;