diff --git a/reactos/ntoskrnl/ps/query.c b/reactos/ntoskrnl/ps/query.c index b5ac9dabb86..87d2fda3e90 100644 --- a/reactos/ntoskrnl/ps/query.c +++ b/reactos/ntoskrnl/ps/query.c @@ -2412,6 +2412,7 @@ NtQueryInformationThread(IN HANDLE ThreadHandle, (PTHREAD_BASIC_INFORMATION)ThreadInformation; PKERNEL_USER_TIMES ThreadTime = (PKERNEL_USER_TIMES)ThreadInformation; KIRQL OldIrql; + ULONG ThreadTerminated; PAGED_CODE(); /* Check if we were called from user mode */ @@ -2661,6 +2662,31 @@ NtQueryInformationThread(IN HANDLE ThreadHandle, _SEH2_END; break; + case ThreadIsTerminated: + + /* Set the return length*/ + Length = sizeof(ThreadTerminated); + + if (ThreadInformationLength != Length) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + ThreadTerminated = PsIsThreadTerminating(Thread); + + _SEH2_TRY + { + *(PULONG)ThreadInformation = ThreadTerminated ? 1 : 0; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + break; + /* Anything else */ default: diff --git a/reactos/subsystems/win32/csrsrv/api.h b/reactos/subsystems/win32/csrsrv/api.h index e03cc89089f..6bf294475ff 100644 --- a/reactos/subsystems/win32/csrsrv/api.h +++ b/reactos/subsystems/win32/csrsrv/api.h @@ -137,11 +137,15 @@ BOOLEAN NTAPI UnProtectHandle(IN HANDLE ObjectHandle); -VOID +NTSTATUS NTAPI CsrInsertThread(IN PCSR_PROCESS Process, IN PCSR_THREAD Thread); +VOID +NTAPI +CsrDeallocateThread(IN PCSR_THREAD CsrThread); + VOID NTAPI CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess); diff --git a/reactos/subsystems/win32/csrsrv/procsup.c b/reactos/subsystems/win32/csrsrv/procsup.c index 2dc5c116598..def775e8025 100644 --- a/reactos/subsystems/win32/csrsrv/procsup.c +++ b/reactos/subsystems/win32/csrsrv/procsup.c @@ -690,7 +690,15 @@ CsrCreateProcess(IN HANDLE hProcess, CsrThread->Flags = 0; /* Insert the Thread into the Process */ - CsrInsertThread(CsrProcess, CsrThread); + Status = CsrInsertThread(CsrProcess, CsrThread); + if (!NT_SUCCESS(Status)) + { + /* Bail out */ + CsrDeallocateProcess(CsrProcess); + CsrDeallocateThread(CsrThread); + CsrReleaseProcessLock(); + return Status; + } /* Reference the session */ CsrReferenceNtSession(NtSession); diff --git a/reactos/subsystems/win32/csrsrv/session.c b/reactos/subsystems/win32/csrsrv/session.c index 79702903a62..f2d1ccde9ec 100644 --- a/reactos/subsystems/win32/csrsrv/session.c +++ b/reactos/subsystems/win32/csrsrv/session.c @@ -289,7 +289,15 @@ CsrSbCreateSession(IN PSB_API_MSG ApiMessage) CsrThread->Flags = 0; /* Insert it into the Process List */ - CsrInsertThread(CsrProcess, CsrThread); + Status = CsrInsertThread(CsrProcess, CsrThread); + if (!NT_SUCCESS(Status)) + { + /* Bail out */ + CsrDeallocateProcess(CsrProcess); + CsrDeallocateThread(CsrThread); + CsrReleaseProcessLock(); + return Status; + } /* Setup Process Data */ CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId; diff --git a/reactos/subsystems/win32/csrsrv/thredsup.c b/reactos/subsystems/win32/csrsrv/thredsup.c index 26b5bb12b86..b4063c6b7aa 100644 --- a/reactos/subsystems/win32/csrsrv/thredsup.c +++ b/reactos/subsystems/win32/csrsrv/thredsup.c @@ -292,14 +292,25 @@ CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL, * @remarks None. * *--*/ -VOID +NTSTATUS NTAPI CsrInsertThread(IN PCSR_PROCESS Process, IN PCSR_THREAD Thread) { ULONG i; + NTSTATUS Status; + ULONG ThreadInfo; // ASSERT(ProcessStructureListLocked()); + /* Make sure the thread isn't already dead by the time we got this */ + Status = NtQueryInformationThread(Thread->ThreadHandle, + ThreadIsTerminated, + &ThreadInfo, + sizeof(ThreadInfo), + NULL); + if (!NT_SUCCESS(Status)) return Status; + if (ThreadInfo == TRUE) return STATUS_THREAD_IS_TERMINATING; + /* Insert it into the Regular List */ InsertTailList(&Process->ThreadList, &Thread->Link); @@ -311,6 +322,7 @@ CsrInsertThread(IN PCSR_PROCESS Process, /* Insert it there too */ InsertHeadList(&CsrThreadHashTable[i], &Thread->HashLinks); + return STATUS_SUCCESS; } /*++ @@ -623,7 +635,15 @@ CsrCreateRemoteThread(IN HANDLE hThread, CsrThread->Flags = 0; /* Insert the Thread into the Process */ - CsrInsertThread(CsrProcess, CsrThread); + Status = CsrInsertThread(CsrProcess, CsrThread); + if (!NT_SUCCESS(Status)) + { + /* Bail out */ + if (CsrThread->ThreadHandle != hThread) NtClose(CsrThread->ThreadHandle); + CsrUnlockProcess(CsrProcess); + CsrDeallocateThread(CsrThread); + return Status; + } /* Release the lock and return */ CsrUnlockProcess(CsrProcess); @@ -720,7 +740,14 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess, CsrThread->Flags = 0; /* Insert the Thread into the Process */ - CsrInsertThread(CsrProcess, CsrThread); + Status = CsrInsertThread(CsrProcess, CsrThread); + if (!NT_SUCCESS(Status)) + { + /* Bail out */ + CsrUnlockProcess(CsrProcess); + CsrDeallocateThread(CsrThread); + return Status; + } /* Release the lock and return */ CsrReleaseProcessLock();