From aaf641d620b28cd7fa6ae0ccbfbf678497dfcb21 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Wed, 10 Jul 2002 15:17:35 +0000 Subject: [PATCH] Implemented the ability to create suspended threads. svn path=/trunk/; revision=3206 --- reactos/ntoskrnl/ps/create.c | 157 +++++++++++++++++++--------------- reactos/ntoskrnl/ps/suspend.c | 152 ++++++++++++++++---------------- 2 files changed, 168 insertions(+), 141 deletions(-) diff --git a/reactos/ntoskrnl/ps/create.c b/reactos/ntoskrnl/ps/create.c index 14dc4220fb6..cb57039bbaa 100644 --- a/reactos/ntoskrnl/ps/create.c +++ b/reactos/ntoskrnl/ps/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.46 2002/03/05 00:20:54 ekohl Exp $ +/* $Id: create.c,v 1.47 2002/07/10 15:17:34 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -546,77 +546,96 @@ PsCreateTeb(HANDLE ProcessHandle, NTSTATUS STDCALL -NtCreateThread (PHANDLE ThreadHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes, - HANDLE ProcessHandle, - PCLIENT_ID Client, - PCONTEXT ThreadContext, - PINITIAL_TEB InitialTeb, - BOOLEAN CreateSuspended) +NtCreateThread(PHANDLE ThreadHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + HANDLE ProcessHandle, + PCLIENT_ID Client, + PCONTEXT ThreadContext, + PINITIAL_TEB InitialTeb, + BOOLEAN CreateSuspended) { - PETHREAD Thread; - PTEB TebBase; - NTSTATUS Status; - - DPRINT("NtCreateThread(ThreadHandle %x, PCONTEXT %x)\n", - ThreadHandle,ThreadContext); - - Status = PsInitializeThread(ProcessHandle, - &Thread, - ThreadHandle, - DesiredAccess, - ObjectAttributes, - FALSE); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - Status = Ke386InitThreadWithContext(&Thread->Tcb, - ThreadContext); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - Status = PsCreateTeb(ProcessHandle, - &TebBase, - Thread, - InitialTeb); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - /* Attention: TebBase is in user memory space */ - Thread->Tcb.Teb = TebBase; + PETHREAD Thread; + PTEB TebBase; + NTSTATUS Status; - Thread->StartAddress=NULL; + DPRINT("NtCreateThread(ThreadHandle %x, PCONTEXT %x)\n", + ThreadHandle,ThreadContext); - if (Client != NULL) - { - *Client=Thread->Cid; - } - - /* - * Maybe send a message to the process's debugger - */ - DbgkCreateThread((PVOID)ThreadContext->Eip); - - /* - * Start the thread running - */ - if (!CreateSuspended) - { - DPRINT("Not creating suspended\n"); - PsUnblockThread(Thread, NULL); - } - else - { - KeBugCheck(0); - } - return(STATUS_SUCCESS); + Status = PsInitializeThread(ProcessHandle, + &Thread, + ThreadHandle, + DesiredAccess, + ObjectAttributes, + FALSE); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + Status = Ke386InitThreadWithContext(&Thread->Tcb, + ThreadContext); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + Status = PsCreateTeb(ProcessHandle, + &TebBase, + Thread, + InitialTeb); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + /* Attention: TebBase is in user memory space */ + Thread->Tcb.Teb = TebBase; + + Thread->StartAddress=NULL; + + if (Client != NULL) + { + *Client=Thread->Cid; + } + + /* + * Maybe send a message to the process's debugger + */ + DbgkCreateThread((PVOID)ThreadContext->Eip); + + /* + * Start the thread running + */ + if (!CreateSuspended) + { + DPRINT("Not creating suspended\n"); + PsUnblockThread(Thread, NULL); + } + else + { + DPRINT("Creating suspended\n"); + + /* + * Simulate a call to NtWaitForSingleObject() upon thread startup + */ + + /* Increment the suspend counter */ + Thread->Tcb.SuspendCount++; + + /* Add one wait-block for suspend semaphore */ + Thread->Tcb.WaitStatus = STATUS_UNSUCCESSFUL; + Thread->Tcb.WaitBlockList = &Thread->Tcb.WaitBlock[0]; + Thread->Tcb.WaitBlock[0].Object = (POBJECT)&Thread->Tcb.SuspendSemaphore; + Thread->Tcb.WaitBlock[0].Thread = &Thread->Tcb; + Thread->Tcb.WaitBlock[0].WaitKey = STATUS_WAIT_0; + Thread->Tcb.WaitBlock[0].WaitType = WaitAny; + Thread->Tcb.WaitBlock[0].NextWaitBlock = NULL; + InsertTailList(&Thread->Tcb.SuspendSemaphore.Header.WaitListHead, + &Thread->Tcb.WaitBlock[0].WaitListEntry); + } + + return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/ps/suspend.c b/reactos/ntoskrnl/ps/suspend.c index 98fa5978067..86effe3518d 100644 --- a/reactos/ntoskrnl/ps/suspend.c +++ b/reactos/ntoskrnl/ps/suspend.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: suspend.c,v 1.6 2001/08/27 01:22:22 ekohl Exp $ +/* $Id: suspend.c,v 1.7 2002/07/10 15:17:35 ekohl Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ps/suspend.c @@ -46,6 +46,7 @@ PiSuspendThreadRundownRoutine(PKAPC Apc) { } + VOID STDCALL PiSuspendThreadKernelRoutine(PKAPC Apc, PKNORMAL_ROUTINE* NormalRoutine, @@ -55,48 +56,55 @@ PiSuspendThreadKernelRoutine(PKAPC Apc, { } + VOID STDCALL PiSuspendThreadNormalRoutine(PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2) { - KeWaitForSingleObject(&PsGetCurrentThread()->Tcb.SuspendSemaphore, - 0, - UserMode, - TRUE, - NULL); + KeWaitForSingleObject(&PsGetCurrentThread()->Tcb.SuspendSemaphore, + 0, + UserMode, + TRUE, + NULL); } + NTSTATUS PsResumeThread(PETHREAD Thread, PULONG SuspendCount) { + *SuspendCount = InterlockedDecrement((PULONG)&Thread->Tcb.SuspendCount); KeReleaseSemaphore(&Thread->Tcb.SuspendSemaphore, IO_NO_INCREMENT, 1, FALSE); + return(STATUS_SUCCESS); } -NTSTATUS + +NTSTATUS PsSuspendThread(PETHREAD Thread, PULONG PreviousSuspendCount) { - ULONG OldValue; + ULONG OldValue; - OldValue = InterlockedIncrement((PULONG)&Thread->Tcb.SuspendCount); - if (OldValue == 0) - { - KeInsertQueueApc(&Thread->Tcb.SuspendApc, - NULL, - NULL, - 0); - } - else - { - InterlockedDecrement(&Thread->Tcb.SuspendSemaphore.Header.SignalState); - } - return(STATUS_SUCCESS); + OldValue = InterlockedIncrement((PULONG)&Thread->Tcb.SuspendCount); + if (OldValue == 0) + { + KeInsertQueueApc(&Thread->Tcb.SuspendApc, + NULL, + NULL, + 0); + } + else + { + InterlockedDecrement(&Thread->Tcb.SuspendSemaphore.Header.SignalState); + } + + return(STATUS_SUCCESS); } -NTSTATUS STDCALL -NtResumeThread (IN HANDLE ThreadHandle, - IN PULONG SuspendCount) + +NTSTATUS STDCALL +NtResumeThread(IN HANDLE ThreadHandle, + IN PULONG SuspendCount) /* * FUNCTION: Decrements a thread's resume count * ARGUMENTS: @@ -105,36 +113,39 @@ NtResumeThread (IN HANDLE ThreadHandle, * RETURNS: Status */ { - PETHREAD Thread; - NTSTATUS Status; - ULONG Count; + PETHREAD Thread; + NTSTATUS Status; + ULONG Count; - Status = ObReferenceObjectByHandle(ThreadHandle, - THREAD_SUSPEND_RESUME, - PsThreadType, - UserMode, - (PVOID*)&Thread, - NULL); - if (!NT_SUCCESS(Status)) - { - return(Status); - } + DPRINT("NtResumeThead(ThreadHandle %lx SuspendCount %p)\n", + ThreadHandle, SuspendCount); - Status = PsResumeThread(Thread, &Count); - if (SuspendCount != NULL) - { - *SuspendCount = Count; - } + Status = ObReferenceObjectByHandle(ThreadHandle, + THREAD_SUSPEND_RESUME, + PsThreadType, + UserMode, + (PVOID*)&Thread, + NULL); + if (!NT_SUCCESS(Status)) + { + return(Status); + } - ObDereferenceObject((PVOID)Thread); + Status = PsResumeThread(Thread, &Count); + if (SuspendCount != NULL) + { + *SuspendCount = Count; + } - return STATUS_SUCCESS; + ObDereferenceObject((PVOID)Thread); + + return(STATUS_SUCCESS); } -NTSTATUS STDCALL -NtSuspendThread (IN HANDLE ThreadHandle, - IN PULONG PreviousSuspendCount) +NTSTATUS STDCALL +NtSuspendThread(IN HANDLE ThreadHandle, + IN PULONG PreviousSuspendCount) /* * FUNCTION: Increments a thread's suspend count * ARGUMENTS: @@ -147,35 +158,32 @@ NtSuspendThread (IN HANDLE ThreadHandle, * The suspend count is not increased if it is greater than * MAXIMUM_SUSPEND_COUNT. * RETURNS: Status - */ + */ { - PETHREAD Thread; - NTSTATUS Status; - ULONG Count; + PETHREAD Thread; + NTSTATUS Status; + ULONG Count; - Status = ObReferenceObjectByHandle(ThreadHandle, - THREAD_SUSPEND_RESUME, - PsThreadType, - UserMode, - (PVOID*)&Thread, - NULL); - if (!NT_SUCCESS(Status)) - { - return(Status); - } + Status = ObReferenceObjectByHandle(ThreadHandle, + THREAD_SUSPEND_RESUME, + PsThreadType, + UserMode, + (PVOID*)&Thread, + NULL); + if (!NT_SUCCESS(Status)) + { + return(Status); + } - Status = PsSuspendThread(Thread, &Count); - if (PreviousSuspendCount != NULL) - { - *PreviousSuspendCount = Count; - } + Status = PsSuspendThread(Thread, &Count); + if (PreviousSuspendCount != NULL) + { + *PreviousSuspendCount = Count; + } - ObDereferenceObject((PVOID)Thread); + ObDereferenceObject((PVOID)Thread); - return STATUS_SUCCESS; + return(STATUS_SUCCESS); } - - - - +/* EOF */