LIST_ENTRY ThreadsToReapHead;
+#define TERMINATE_PROC 0x1
+#define TERMINATE_APC 0x2
+
/* FUNCTIONS *****************************************************************/
VOID
SIZE_T Length = PAGE_SIZE;
PVOID TebBlock;
- KeLowerIrql(PASSIVE_LEVEL);
+ DPRINT("PsTerminateCurrentThread(ExitStatus %x)\n", ExitStatus);
CurrentThread = PsGetCurrentThread();
+
+ oldIrql = KeAcquireDispatcherDatabaseLock();
+ if (CurrentThread->HasTerminated & TERMINATE_PROC)
+ {
+ KeReleaseDispatcherDatabaseLock(oldIrql);
+ return;
+ }
+ CurrentThread->HasTerminated |= TERMINATE_PROC;
+ KeReleaseDispatcherDatabaseLock(oldIrql);
+
+ KeLowerIrql(PASSIVE_LEVEL);
+
CurrentProcess = CurrentThread->ThreadsProcess;
/* Can't terminate a thread if it attached another process */
DPRINT("terminating %x\n",CurrentThread);
- CurrentThread->HasTerminated = TRUE;
CurrentThread->ExitStatus = ExitStatus;
KeQuerySystemTime((PLARGE_INTEGER)&CurrentThread->ExitTime);
PVOID SystemArgument1,
PVOID SystemArgument2)
{
- PETHREAD EThread = PsGetCurrentThread();
- if (EThread->HasTerminated)
- {
- /* Someone else has already called PsTerminateCurrentThread */
- return;
- }
- PsTerminateCurrentThread(PsGetCurrentThread()->ExitStatus);
+ PsTerminateCurrentThread((NTSTATUS)SystemArgument1);
}
VOID
Thread, ExitStatus);
OldIrql = KeAcquireDispatcherDatabaseLock();
- if (Thread->HasTerminated)
+ if (Thread->HasTerminated & TERMINATE_APC)
{
KeReleaseDispatcherDatabaseLock (OldIrql);
return;
}
- Thread->HasTerminated = TRUE;
+ Thread->HasTerminated |= TERMINATE_APC;
KeReleaseDispatcherDatabaseLock (OldIrql);
- Thread->ExitStatus = ExitStatus;
Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG_TERMINATE_APC);
KeInitializeApc(Apc,
&Thread->Tcb,
KernelMode,
NULL);
KeInsertQueueApc(Apc,
- NULL,
+ (PVOID)ExitStatus,
NULL,
IO_NO_INCREMENT);