mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 17:14:41 +00:00
Implemented the ability to create suspended threads.
svn path=/trunk/; revision=3206
This commit is contained in:
parent
cae7cd6a6c
commit
aaf641d620
2 changed files with 168 additions and 141 deletions
|
@ -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;
|
||||
PETHREAD Thread;
|
||||
PTEB TebBase;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("NtCreateThread(ThreadHandle %x, PCONTEXT %x)\n",
|
||||
ThreadHandle,ThreadContext);
|
||||
DPRINT("NtCreateThread(ThreadHandle %x, PCONTEXT %x)\n",
|
||||
ThreadHandle,ThreadContext);
|
||||
|
||||
Status = PsInitializeThread(ProcessHandle,
|
||||
&Thread,
|
||||
ThreadHandle,
|
||||
DesiredAccess,
|
||||
ObjectAttributes,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
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 = Ke386InitThreadWithContext(&Thread->Tcb,
|
||||
ThreadContext);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
Status = PsCreateTeb(ProcessHandle,
|
||||
&TebBase,
|
||||
Thread,
|
||||
InitialTeb);
|
||||
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;
|
||||
/* Attention: TebBase is in user memory space */
|
||||
Thread->Tcb.Teb = TebBase;
|
||||
|
||||
Thread->StartAddress=NULL;
|
||||
Thread->StartAddress=NULL;
|
||||
|
||||
if (Client != NULL)
|
||||
{
|
||||
*Client=Thread->Cid;
|
||||
}
|
||||
if (Client != NULL)
|
||||
{
|
||||
*Client=Thread->Cid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Maybe send a message to the process's debugger
|
||||
*/
|
||||
DbgkCreateThread((PVOID)ThreadContext->Eip);
|
||||
/*
|
||||
* 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);
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
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)
|
||||
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)
|
||||
NtSuspendThread(IN HANDLE ThreadHandle,
|
||||
IN PULONG PreviousSuspendCount)
|
||||
/*
|
||||
* FUNCTION: Increments a thread's suspend count
|
||||
* ARGUMENTS:
|
||||
|
@ -149,33 +160,30 @@ NtSuspendThread (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);
|
||||
}
|
||||
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 */
|
||||
|
|
Loading…
Reference in a new issue