Author: jimtabor
Date: Sat Aug 18 22:13:38 2012
New Revision: 57103
URL:
http://svn.reactos.org/svn/reactos?rev=57103&view=rev
Log:
[Win32k]
- AttachThreadInput, this should fix the crash. Original crash patch by Giannis
Adamopoulos. See bug 7225.
- WARNING: This code should be turned off until the restructuring is finished. Please read
bug 7225!
Modified:
trunk/reactos/win32ss/user/ntuser/input.c
trunk/reactos/win32ss/user/ntuser/input.h
trunk/reactos/win32ss/user/ntuser/main.c
trunk/reactos/win32ss/user/ntuser/ntstubs.c
Modified: trunk/reactos/win32ss/user/ntuser/input.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/input.…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/input.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/input.c [iso-8859-1] Sat Aug 18 22:13:38 2012
@@ -17,6 +17,7 @@
PTHREADINFO ptiMouse;
PKTIMER MasterTimer = NULL;
PATTACHINFO gpai = NULL;
+INT paiCount = 0;
HANDLE ghKeyboardDevice;
static DWORD LastInputTick = 0;
@@ -414,20 +415,20 @@
return pai->pti1;
}
-BOOL FASTCALL
+NTSTATUS FASTCALL
UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach)
{
MSG msg;
PATTACHINFO pai;
/* Can not be the same thread. */
- if (ptiFrom == ptiTo) return FALSE;
+ if (ptiFrom == ptiTo) return STATUS_INVALID_PARAMETER;
/* Do not attach to system threads or between different desktops. */
if (ptiFrom->TIF_flags & TIF_DONTATTACHQUEUE ||
- ptiTo->TIF_flags & TIF_DONTATTACHQUEUE ||
- ptiFrom->rpdesk != ptiTo->rpdesk)
- return FALSE;
+ ptiTo->TIF_flags & TIF_DONTATTACHQUEUE ||
+ ptiFrom->rpdesk != ptiTo->rpdesk)
+ return STATUS_ACCESS_DENIED;
/* MSDN Note:
Keyboard and mouse events received by both threads are processed by the thread
specified by the idAttachTo.
@@ -437,20 +438,34 @@
if (fAttach)
{
pai = ExAllocatePoolWithTag(PagedPool, sizeof(ATTACHINFO), USERTAG_ATTACHINFO);
- if (!pai) return FALSE;
+ if (!pai) return STATUS_NO_MEMORY;
pai->paiNext = gpai;
pai->pti1 = ptiFrom;
pai->pti2 = ptiTo;
gpai = pai;
- ERR("Attach Allocated! ptiFrom 0x%p ptiTo 0x%p\n",ptiFrom,ptiTo);
+ paiCount++;
+ ERR("Attach Allocated! ptiFrom 0x%p ptiTo 0x%p paiCount
%d\n",ptiFrom,ptiTo,paiCount);
+
+ if (ptiTo->MessageQueue == ptiFrom->MessageQueue)
+ {
+ ERR("Attach Threads are already associated!\n");
+ }
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;
+
+ ptiFrom->MessageQueue->cThreads++;
+ ERR("ptiTo S Share count %d\n",
ptiFrom->MessageQueue->cThreads);
+
// FIXME: conditions?
if (ptiFrom->pqAttach == gpqForeground)
{
+ ERR("ptiFrom is Foreground\n");
ptiFrom->MessageQueue->spwndActive = ptiFrom->pqAttach->spwndActive;
ptiFrom->MessageQueue->spwndFocus = ptiFrom->pqAttach->spwndFocus;
ptiFrom->MessageQueue->CursorObject =
ptiFrom->pqAttach->CursorObject;
@@ -458,31 +473,71 @@
ptiFrom->MessageQueue->QF_flags ^= ((ptiFrom->MessageQueue->QF_flags
^ ptiFrom->pqAttach->QF_flags) & QF_CAPTURELOCKED);
ptiFrom->MessageQueue->CaretInfo = ptiFrom->pqAttach->CaretInfo;
}
+ else
+ {
+ ERR("ptiFrom NOT Foreground\n");
+ }
+ if (ptiTo->MessageQueue == gpqForeground)
+ {
+ ERR("ptiTo is Foreground\n");
+ }
+ else
+ {
+ ERR("ptiTo NOT Foreground\n");
+ }
}
else /* If clear, unlink and free it. */
{
- PATTACHINFO paiprev = NULL;
-
- if (!gpai) return FALSE;
-
+ BOOL Hit = FALSE;
+ PATTACHINFO *ppai;
+
+ if (!gpai) return STATUS_INVALID_PARAMETER;
+
+ /* Search list and free if found or return false. */
+ ppai = &gpai;
+ while (*ppai != NULL)
+ {
+ if ( (*ppai)->pti2 == ptiTo && (*ppai)->pti1 == ptiFrom )
+ {
+ pai = *ppai;
+ /* Remove it from the list */
+ *ppai = (*ppai)->paiNext;
+ ExFreePoolWithTag(pai, USERTAG_ATTACHINFO);
+ paiCount--;
+ Hit = TRUE;
+ break;
+ }
+ ppai = &((*ppai)->paiNext);
+ }
+
+ if (!Hit) return STATUS_INVALID_PARAMETER;
+
+ ASSERT(ptiFrom->pqAttach);
+
+ ERR("Attach Free! ptiFrom 0x%p ptiTo 0x%p paiCount
%d\n",ptiFrom,ptiTo,paiCount);
+
+ /* Search list and check if the thread is attached one more time */
pai = gpai;
-
- /* Search list and free if found or return false. */
- do
- {
- if (pai->pti2 == ptiTo && pai->pti1 == ptiFrom) break;
- paiprev = pai;
+ while(pai)
+ {
+ /* If the thread is attached again , we are done */
+ if (pai->pti1 == ptiFrom)
+ {
+ ptiFrom->MessageQueue->cThreads--;
+ ERR("ptiTo L Share count %d\n",
ptiFrom->MessageQueue->cThreads);
+ /* 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;
+ ptiFrom->MessageQueue->spwndCapture = NULL;
+ return STATUS_SUCCESS;
+ }
pai = pai->paiNext;
- } while (pai);
-
- if (!pai) return FALSE;
-
- if (paiprev) paiprev->paiNext = pai->paiNext;
- else if (!pai->paiNext) gpai = NULL;
-
- ExFreePoolWithTag(pai, USERTAG_ATTACHINFO);
- ERR("Attach Free! ptiFrom 0x%p ptiTo 0x%p\n",ptiFrom,ptiTo);
-
+ }
+
+ ptiFrom->MessageQueue->cThreads--;
+ ERR("ptiTo E Share count %d\n",
ptiFrom->MessageQueue->cThreads);
ptiFrom->MessageQueue = ptiFrom->pqAttach;
// FIXME: conditions?
ptiFrom->MessageQueue->CursorObject = NULL;
@@ -505,7 +560,7 @@
msg.pt = gpsi->ptCursor;
co_MsqInsertMouseMessage(&msg, 0, 0, TRUE);
- return TRUE;
+ return STATUS_SUCCESS;
}
/*
Modified: trunk/reactos/win32ss/user/ntuser/input.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/input.…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/input.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/input.h [iso-8859-1] Sat Aug 18 22:13:38 2012
@@ -62,7 +62,7 @@
INIT_FUNCTION NTSTATUS NTAPI InitInputImpl(VOID);
BOOL FASTCALL IntBlockInput(PTHREADINFO W32Thread, BOOL BlockIt);
DWORD NTAPI CreateSystemThreads(UINT Type);
-BOOL FASTCALL UserAttachThreadInput(PTHREADINFO,PTHREADINFO,BOOL);
+NTSTATUS FASTCALL UserAttachThreadInput(PTHREADINFO,PTHREADINFO,BOOL);
PTHREADINFO FASTCALL IsThreadAttach(PTHREADINFO);
VOID FASTCALL DoTheScreenSaver(VOID);
#define ThreadHasInputAccess(W32Thread) (TRUE)
Modified: trunk/reactos/win32ss/user/ntuser/main.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/main.c…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/main.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/main.c [iso-8859-1] Sat Aug 18 22:13:38 2012
@@ -401,6 +401,28 @@
ppiCurrent = ptiCurrent->ppi;
ASSERT(ppiCurrent);
+ // ptiTo
+ if (IsThreadAttach(ptiCurrent))
+ {
+ PTHREADINFO ptiFrom = IsThreadAttach(ptiCurrent);
+ TRACE_CH(UserThread,"Attached Thread ptiTo is getting switched!\n");
+ UserAttachThreadInput(ptiFrom, ptiCurrent, FALSE);
+ }
+
+ // ptiFrom
+ if (ptiCurrent->pqAttach && ptiCurrent->MessageQueue)
+ {
+ PTHREADINFO ptiTo;
+ ptiTo = PsGetThreadWin32Thread(ptiCurrent->MessageQueue->Thread);
+ TRACE_CH(UserThread,"Attached Thread ptiFrom is getting switched!\n");
+ if (ptiTo) UserAttachThreadInput( ptiCurrent, ptiTo, FALSE);
+ else
+ {
+ // eThread maybe okay but Win32Thread already made NULL!
+ ERR_CH(UserThread,"Attached Thread ptiFrom did not switch due to ptiTo is
NULL!\n");
+ }
+ }
+
/* Decrement thread count and check if its 0 */
ppiCurrent->cThreads--;
@@ -470,23 +492,6 @@
psle = PopEntryList(&ptiCurrent->ReferencesList);
}
- }
-
- // ptiTo
- if (IsThreadAttach(ptiCurrent))
- {
- PTHREADINFO ptiFrom = IsThreadAttach(ptiCurrent);
- TRACE_CH(UserThread,"Attached Thread ptiTo is getting switched!\n");
- UserAttachThreadInput(ptiFrom, ptiCurrent, FALSE);
- }
-
- // ptiFrom
- if (ptiCurrent->pqAttach && ptiCurrent->MessageQueue)
- {
- PTHREADINFO ptiTo;
- ptiTo = PsGetThreadWin32Thread(ptiCurrent->MessageQueue->Thread);
- TRACE_CH(UserThread,"Attached Thread ptiFrom is getting switched!\n");
- UserAttachThreadInput( ptiCurrent, ptiTo, FALSE);
}
/* Free the message queue */
Modified: trunk/reactos/win32ss/user/ntuser/ntstubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/ntstub…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/ntstubs.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/ntstubs.c [iso-8859-1] Sat Aug 18 22:13:38 2012
@@ -34,6 +34,7 @@
BOOL Ret = FALSE;
UserEnterExclusive();
+ ERR("Enter NtUserAttachThreadInput %s\n",(fAttach ? "TRUE" :
"FALSE" ));
Status = PsLookupThreadByThreadId((HANDLE)idAttach, &Thread);
if (!NT_SUCCESS(Status))
{
@@ -53,9 +54,15 @@
ObDereferenceObject(Thread);
ObDereferenceObject(ThreadTo);
- Ret = UserAttachThreadInput( pti, ptiTo, fAttach);
+ Status = UserAttachThreadInput( pti, ptiTo, fAttach);
+ if (!NT_SUCCESS(Status))
+ {
+ EngSetLastError(RtlNtStatusToDosError(Status));
+ }
+ else Ret = TRUE;
Exit:
+ ERR("Leave NtUserAttachThreadInput, ret=%d\n",Ret);
UserLeave();
return Ret;
}