Implemented the ability to create suspended threads.

svn path=/trunk/; revision=3206
This commit is contained in:
Eric Kohl 2002-07-10 15:17:35 +00:00
parent cae7cd6a6c
commit aaf641d620
2 changed files with 168 additions and 141 deletions

View file

@ -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);
}

View file

@ -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 */