HANDLE hModuleWin;
-PGDI_HANDLE_TABLE NTAPI GDIOBJ_iAllocHandleTable(OUT PSECTION_OBJECT *SectionObject);
+PGDI_HANDLE_TABLE NTAPI GDIOBJ_iAllocHandleTable(OUT PVOID *SectionObject);
BOOL NTAPI GDI_CleanupForProcess (struct _EPROCESS *Process);
NTSTATUS NTAPI UserDestroyThreadInfo(struct _ETHREAD *Thread);
HANDLE GlobalUserHeap = NULL;
-PSECTION_OBJECT GlobalUserHeapSection = NULL;
+PVOID GlobalUserHeapSection = NULL;
PSERVERINFO gpsi = NULL; // Global User Server Information.
int i;
NTSTATUS Status = STATUS_SUCCESS;
PTEB pTeb;
+ LARGE_INTEGER LargeTickCount;
Process = Thread->ThreadsProcess;
TRACE_CH(UserThread, "Allocated pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread);
/* Initialize the THREADINFO */
+ IntReferenceThreadInfo(ptiCurrent);
InitializeListHead(&ptiCurrent->WindowListHead);
InitializeListHead(&ptiCurrent->W32CallbackListHead);
+ InitializeListHead(&ptiCurrent->PostedMessagesListHead);
+ InitializeListHead(&ptiCurrent->SentMessagesListHead);
+ InitializeListHead(&ptiCurrent->DispatchingMessagesHead);
+ InitializeListHead(&ptiCurrent->LocalDispatchingMessagesHead);
InitializeListHead(&ptiCurrent->PtiLink);
for (i = 0; i < NB_HOOKS; i++)
{
ptiCurrent->ptiSibling = ptiCurrent->ppi->ptiList;
ptiCurrent->ppi->ptiList = ptiCurrent;
ptiCurrent->ppi->cThreads++;
+
+ ptiCurrent->hEventQueueClient = NULL;
+ Status = ZwCreateEvent(&ptiCurrent->hEventQueueClient, EVENT_ALL_ACCESS,
+ NULL, SynchronizationEvent, FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ goto error;
+ }
+ Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0,
+ ExEventObjectType, KernelMode,
+ (PVOID*)&ptiCurrent->pEventQueueServer, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ZwClose(ptiCurrent->hEventQueueClient);
+ ptiCurrent->hEventQueueClient = NULL;
+ goto error;
+ }
+
+ KeQueryTickCount(&LargeTickCount);
+ ptiCurrent->timeLast = LargeTickCount.u.LowPart;
+
ptiCurrent->MessageQueue = MsqCreateMessageQueue(ptiCurrent);
if(ptiCurrent->MessageQueue == NULL)
{
return Status;
}
+/*
+ Called from IntDereferenceThreadInfo.
+ */
+VOID
+FASTCALL
+UserDeleteW32Thread(PTHREADINFO pti)
+{
+ if (!pti->RefCount)
+ {
+ ERR_CH(UserThread,"UserDeleteW32Thread pti 0x%p\n",pti);
+ if (pti->hEventQueueClient != NULL)
+ ZwClose(pti->hEventQueueClient);
+ pti->hEventQueueClient = NULL;
+
+ /* Free the message queue */
+ if (pti->MessageQueue)
+ {
+ MsqDestroyMessageQueue(pti);
+ }
+
+ MsqCleanupThreadMsgs(pti);
+
+ IntSetThreadDesktop(NULL, TRUE);
+
+ PsSetThreadWin32Thread(pti->pEThread, NULL);
+ ExFreePoolWithTag(pti, USERTAG_THREADINFO);
+ }
+}
+
NTSTATUS
NTAPI
UserDestroyThreadInfo(struct _ETHREAD *Thread)
if (ptiCurrent->pqAttach && ptiCurrent->MessageQueue)
{
PTHREADINFO ptiTo;
- ptiTo = PsGetThreadWin32Thread(ptiCurrent->MessageQueue->Thread);
+ ptiTo = ptiCurrent->MessageQueue->ptiOwner;
TRACE_CH(UserThread,"Attached Thread ptiFrom is getting switched!\n");
if (ptiTo) UserAttachThreadInput( ptiCurrent, ptiTo, FALSE);
else
HOOK_DestroyThreadHooks(Thread);
EVENT_DestroyThreadEvents(Thread);
DestroyTimersForThread(ptiCurrent);
- KeSetEvent(ptiCurrent->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
+ KeSetEvent(ptiCurrent->pEventQueueServer, IO_NO_INCREMENT, FALSE);
UnregisterThreadHotKeys(Thread);
/*
if (IsListEmpty(&ptiCurrent->WindowListHead))
}
}
- /* Free the message queue */
- if (ptiCurrent->MessageQueue)
- {
- MsqDestroyMessageQueue(ptiCurrent);
- }
-
/* Find the THREADINFO in the PROCESSINFO's list */
ppti = &ppiCurrent->ptiList;
while (*ppti != NULL && *ppti != ptiCurrent)
TRACE_CH(UserThread,"Freeing pti 0x%p\n", ptiCurrent);
/* Free the THREADINFO */
- PsSetThreadWin32Thread(Thread, NULL);
- ExFreePoolWithTag(ptiCurrent, USERTAG_THREADINFO);
+ IntDereferenceThreadInfo(ptiCurrent);
return STATUS_SUCCESS;
}