mirror of
https://github.com/reactos/reactos.git
synced 2024-09-30 14:37:45 +00:00
[AUDIT] - State.c is clean, it is merely a collection of trivial ~10 line wrappers around the actual kernel (Ke) functions which do the work.
- Rename suspend.c to state.c (since it also had resume APIs) and add alert APIs from kthread to it too. - Fix a bug in one of the alert APIs which was probing for a valid pointer even if the caller had given NULL (which is valid if the caller doesn't want the previous state returned). svn path=/trunk/; revision=23146
This commit is contained in:
parent
d9f7a999cf
commit
9170a29ef7
|
@ -310,6 +310,25 @@ KeStartThread(
|
||||||
IN OUT PKTHREAD Thread
|
IN OUT PKTHREAD Thread
|
||||||
);
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
KeAlertThread(
|
||||||
|
IN PKTHREAD Thread,
|
||||||
|
IN KPROCESSOR_MODE AlertMode
|
||||||
|
);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
KeAlertResumeThread(
|
||||||
|
IN PKTHREAD Thread
|
||||||
|
);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
KeResumeThread(
|
||||||
|
IN PKTHREAD Thread
|
||||||
|
);
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KeSwitchKernelStack(
|
KeSwitchKernelStack(
|
||||||
|
|
|
@ -443,8 +443,8 @@ KeRundownThread(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
STDCALL
|
NTAPI
|
||||||
KeResumeThread(PKTHREAD Thread)
|
KeResumeThread(IN PKTHREAD Thread)
|
||||||
{
|
{
|
||||||
ULONG PreviousCount;
|
ULONG PreviousCount;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
@ -624,7 +624,7 @@ KeForceResumeThread(IN PKTHREAD Thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
STDCALL
|
NTAPI
|
||||||
KeAlertResumeThread(IN PKTHREAD Thread)
|
KeAlertResumeThread(IN PKTHREAD Thread)
|
||||||
{
|
{
|
||||||
ULONG PreviousCount;
|
ULONG PreviousCount;
|
||||||
|
@ -674,9 +674,9 @@ KeAlertResumeThread(IN PKTHREAD Thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
STDCALL
|
NTAPI
|
||||||
KeAlertThread(PKTHREAD Thread,
|
KeAlertThread(IN PKTHREAD Thread,
|
||||||
KPROCESSOR_MODE AlertMode)
|
IN KPROCESSOR_MODE AlertMode)
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
BOOLEAN PreviousState;
|
BOOLEAN PreviousState;
|
||||||
|
@ -1550,109 +1550,6 @@ KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
|
||||||
return OldState;
|
return OldState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* NOT EXPORTED
|
|
||||||
*/
|
|
||||||
NTSTATUS
|
|
||||||
STDCALL
|
|
||||||
NtAlertResumeThread(IN HANDLE ThreadHandle,
|
|
||||||
OUT PULONG SuspendCount)
|
|
||||||
{
|
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
|
||||||
PETHREAD Thread;
|
|
||||||
NTSTATUS Status;
|
|
||||||
ULONG PreviousState;
|
|
||||||
|
|
||||||
/* Check if parameters are valid */
|
|
||||||
if(PreviousMode != KernelMode) {
|
|
||||||
|
|
||||||
_SEH_TRY {
|
|
||||||
|
|
||||||
ProbeForWriteUlong(SuspendCount);
|
|
||||||
|
|
||||||
} _SEH_HANDLE {
|
|
||||||
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
|
|
||||||
} _SEH_END;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reference the Object */
|
|
||||||
Status = ObReferenceObjectByHandle(ThreadHandle,
|
|
||||||
THREAD_SUSPEND_RESUME,
|
|
||||||
PsThreadType,
|
|
||||||
PreviousMode,
|
|
||||||
(PVOID*)&Thread,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
/* Check for Success */
|
|
||||||
if (NT_SUCCESS(Status)) {
|
|
||||||
|
|
||||||
/* Call the Kernel Function */
|
|
||||||
PreviousState = KeAlertResumeThread(&Thread->Tcb);
|
|
||||||
|
|
||||||
/* Dereference Object */
|
|
||||||
ObDereferenceObject(Thread);
|
|
||||||
|
|
||||||
if (SuspendCount) {
|
|
||||||
|
|
||||||
_SEH_TRY {
|
|
||||||
|
|
||||||
*SuspendCount = PreviousState;
|
|
||||||
|
|
||||||
} _SEH_HANDLE {
|
|
||||||
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
|
|
||||||
} _SEH_END;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return status */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*
|
|
||||||
* EXPORTED
|
|
||||||
*/
|
|
||||||
NTSTATUS
|
|
||||||
STDCALL
|
|
||||||
NtAlertThread (IN HANDLE ThreadHandle)
|
|
||||||
{
|
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
|
||||||
PETHREAD Thread;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
/* Reference the Object */
|
|
||||||
Status = ObReferenceObjectByHandle(ThreadHandle,
|
|
||||||
THREAD_SUSPEND_RESUME,
|
|
||||||
PsThreadType,
|
|
||||||
PreviousMode,
|
|
||||||
(PVOID*)&Thread,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
/* Check for Success */
|
|
||||||
if (NT_SUCCESS(Status)) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do an alert depending on the processor mode. If some kmode code wants to
|
|
||||||
* enforce a umode alert it should call KeAlertThread() directly. If kmode
|
|
||||||
* code wants to do a kmode alert it's sufficient to call it with Zw or just
|
|
||||||
* use KeAlertThread() directly
|
|
||||||
*/
|
|
||||||
KeAlertThread(&Thread->Tcb, PreviousMode);
|
|
||||||
|
|
||||||
/* Dereference Object */
|
|
||||||
ObDereferenceObject(Thread);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return status */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtDelayExecution(IN BOOLEAN Alertable,
|
NtDelayExecution(IN BOOLEAN Alertable,
|
||||||
|
|
|
@ -295,7 +295,7 @@
|
||||||
<file>query.c</file>
|
<file>query.c</file>
|
||||||
<file>quota.c</file>
|
<file>quota.c</file>
|
||||||
<file>security.c</file>
|
<file>security.c</file>
|
||||||
<file>suspend.c</file>
|
<file>state.c</file>
|
||||||
<file>thread.c</file>
|
<file>thread.c</file>
|
||||||
<file>win32.c</file>
|
<file>win32.c</file>
|
||||||
</directory>
|
</directory>
|
||||||
|
|
321
reactos/ntoskrnl/ps/state.c
Normal file
321
reactos/ntoskrnl/ps/state.c
Normal file
|
@ -0,0 +1,321 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Kernel
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: ntoskrnl/ps/state.c
|
||||||
|
* PURPOSE: Process Manager: Process/Thread State Control
|
||||||
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
|
* Thomas Weidenmueller (w3seek@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include <ntoskrnl.h>
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
NtAlertThread(IN HANDLE ThreadHandle)
|
||||||
|
{
|
||||||
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
|
PETHREAD Thread;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Reference the Object */
|
||||||
|
Status = ObReferenceObjectByHandle(ThreadHandle,
|
||||||
|
THREAD_SUSPEND_RESUME,
|
||||||
|
PsThreadType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID*)&Thread,
|
||||||
|
NULL);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Do an alert depending on the processor mode. If some kmode code wants to
|
||||||
|
* enforce a umode alert it should call KeAlertThread() directly. If kmode
|
||||||
|
* code wants to do a kmode alert it's sufficient to call it with Zw or just
|
||||||
|
* use KeAlertThread() directly
|
||||||
|
*/
|
||||||
|
KeAlertThread(&Thread->Tcb, PreviousMode);
|
||||||
|
|
||||||
|
/* Dereference Object */
|
||||||
|
ObDereferenceObject(Thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return status */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
NtAlertResumeThread(IN HANDLE ThreadHandle,
|
||||||
|
OUT PULONG SuspendCount)
|
||||||
|
{
|
||||||
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
|
PETHREAD Thread;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
ULONG PreviousState;
|
||||||
|
|
||||||
|
/* Check if we came from user mode with a suspend count */
|
||||||
|
if ((SuspendCount) && (PreviousMode != KernelMode))
|
||||||
|
{
|
||||||
|
/* Enter SEH for probing */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Probe the count */
|
||||||
|
ProbeForWriteUlong(SuspendCount);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
/* Get the exception code */
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
/* Fail on exception */
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reference the Object */
|
||||||
|
Status = ObReferenceObjectByHandle(ThreadHandle,
|
||||||
|
THREAD_SUSPEND_RESUME,
|
||||||
|
PsThreadType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID*)&Thread,
|
||||||
|
NULL);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Call the Kernel Function */
|
||||||
|
PreviousState = KeAlertResumeThread(&Thread->Tcb);
|
||||||
|
|
||||||
|
/* Dereference Object */
|
||||||
|
ObDereferenceObject(Thread);
|
||||||
|
|
||||||
|
/* Check if the caller gave a suspend count */
|
||||||
|
if (SuspendCount)
|
||||||
|
{
|
||||||
|
/* Enter SEH for write */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Write state back */
|
||||||
|
*SuspendCount = PreviousState;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
/* Get exception code */
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return status */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
NtResumeThread(IN HANDLE ThreadHandle,
|
||||||
|
OUT PULONG SuspendCount OPTIONAL)
|
||||||
|
{
|
||||||
|
PETHREAD Thread;
|
||||||
|
ULONG Prev;
|
||||||
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Check if caller gave a suspend count from user mode */
|
||||||
|
if ((SuspendCount) && (PreviousMode != KernelMode))
|
||||||
|
{
|
||||||
|
/* Enter SEH for probing */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Probe the count */
|
||||||
|
ProbeForWriteUlong(SuspendCount);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
/* Get the exception code */
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
/* Fail on exception */
|
||||||
|
if(!NT_SUCCESS(Status)) return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the Thread Object */
|
||||||
|
Status = ObReferenceObjectByHandle(ThreadHandle,
|
||||||
|
THREAD_SUSPEND_RESUME,
|
||||||
|
PsThreadType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID*)&Thread,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
/* Call the Kernel Function */
|
||||||
|
Prev = KeResumeThread(&Thread->Tcb);
|
||||||
|
|
||||||
|
/* Check if the caller wanted the count back */
|
||||||
|
if (SuspendCount)
|
||||||
|
{
|
||||||
|
/* Enter SEH for write back */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Write the count */
|
||||||
|
*SuspendCount = Prev;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
/* Get the exception code */
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dereference and return */
|
||||||
|
ObDereferenceObject(Thread);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
NtSuspendThread(IN HANDLE ThreadHandle,
|
||||||
|
OUT PULONG PreviousSuspendCount OPTIONAL)
|
||||||
|
{
|
||||||
|
PETHREAD Thread;
|
||||||
|
ULONG Prev;
|
||||||
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Check if caller gave a suspend count from user mode */
|
||||||
|
if ((PreviousSuspendCount) && (PreviousMode != KernelMode))
|
||||||
|
{
|
||||||
|
/* Enter SEH for probing */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Probe the count */
|
||||||
|
ProbeForWriteUlong(PreviousSuspendCount);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
/* Get the exception code */
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
/* Fail on exception */
|
||||||
|
if(!NT_SUCCESS(Status)) return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the Thread Object */
|
||||||
|
Status = ObReferenceObjectByHandle(ThreadHandle,
|
||||||
|
THREAD_SUSPEND_RESUME,
|
||||||
|
PsThreadType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID*)&Thread,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
/* Guard with SEH because KeSuspendThread can raise an exception */
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Make sure the thread isn't terminating */
|
||||||
|
if ((Thread != PsGetCurrentThread()) && (Thread->Terminated))
|
||||||
|
{
|
||||||
|
ObDereferenceObject(Thread);
|
||||||
|
return STATUS_THREAD_IS_TERMINATING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call the Kernel function */
|
||||||
|
Prev = KeSuspendThread(&Thread->Tcb);
|
||||||
|
|
||||||
|
/* Return the Previous Count */
|
||||||
|
if (PreviousSuspendCount) *PreviousSuspendCount = Prev;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
|
||||||
|
/* Don't fail if we merely couldn't write the handle back */
|
||||||
|
if (Status != STATUS_SUSPEND_COUNT_EXCEEDED) Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
/* Return */
|
||||||
|
ObDereferenceObject(Thread);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
NtSuspendProcess(IN HANDLE ProcessHandle)
|
||||||
|
{
|
||||||
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
|
PEPROCESS Process;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Reference the process */
|
||||||
|
Status = ObReferenceObjectByHandle(ProcessHandle,
|
||||||
|
PROCESS_SUSPEND_RESUME,
|
||||||
|
PsProcessType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID*)&Process,
|
||||||
|
NULL);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* FIXME */
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
DPRINT1("NtSuspendProcess not yet implemented!\n");
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return status */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
NtResumeProcess(IN HANDLE ProcessHandle)
|
||||||
|
{
|
||||||
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
|
PEPROCESS Process;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Reference the process */
|
||||||
|
Status = ObReferenceObjectByHandle(ProcessHandle,
|
||||||
|
PROCESS_SUSPEND_RESUME,
|
||||||
|
PsProcessType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID*)&Process,
|
||||||
|
NULL);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* FIXME */
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
DPRINT1("NtResumeProcess not yet implemented!\n");
|
||||||
|
ObDereferenceObject(Process);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return status */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
NtTestAlert(VOID)
|
||||||
|
{
|
||||||
|
/* Check and Alert Thread if needed */
|
||||||
|
return KeTestAlertThread(ExGetPreviousMode()) ?
|
||||||
|
STATUS_ALERTED : STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -1,241 +0,0 @@
|
||||||
/* $Id$
|
|
||||||
*
|
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
|
||||||
* PROJECT: ReactOS kernel
|
|
||||||
* FILE: ntoskrnl/ps/suspend.c
|
|
||||||
* PURPOSE: Thread managment
|
|
||||||
*
|
|
||||||
* PROGRAMMERS: David Welch (welch@mcmail.com)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
|
||||||
|
|
||||||
#include <ntoskrnl.h>
|
|
||||||
#define NDEBUG
|
|
||||||
#include <internal/debug.h>
|
|
||||||
|
|
||||||
ULONG
|
|
||||||
STDCALL
|
|
||||||
KeResumeThread(PKTHREAD Thread);
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FUNCTION: Decrements a thread's resume count
|
|
||||||
* ARGUMENTS:
|
|
||||||
* ThreadHandle = Handle to the thread that should be resumed
|
|
||||||
* ResumeCount = The resulting resume count.
|
|
||||||
* RETURNS: Status
|
|
||||||
*/
|
|
||||||
NTSTATUS
|
|
||||||
STDCALL
|
|
||||||
NtResumeThread(IN HANDLE ThreadHandle,
|
|
||||||
IN PULONG SuspendCount OPTIONAL)
|
|
||||||
{
|
|
||||||
PETHREAD Thread;
|
|
||||||
ULONG Prev;
|
|
||||||
KPROCESSOR_MODE PreviousMode;
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
PreviousMode = ExGetPreviousMode();
|
|
||||||
|
|
||||||
DPRINT("NtResumeThead(ThreadHandle %lx SuspendCount %p)\n",
|
|
||||||
ThreadHandle, SuspendCount);
|
|
||||||
|
|
||||||
/* Check buffer validity */
|
|
||||||
if(SuspendCount && PreviousMode != KernelMode) {
|
|
||||||
|
|
||||||
_SEH_TRY {
|
|
||||||
|
|
||||||
ProbeForWriteUlong(SuspendCount);
|
|
||||||
} _SEH_HANDLE {
|
|
||||||
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
|
|
||||||
} _SEH_END;
|
|
||||||
|
|
||||||
if(!NT_SUCCESS(Status)) return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the Thread Object */
|
|
||||||
Status = ObReferenceObjectByHandle(ThreadHandle,
|
|
||||||
THREAD_SUSPEND_RESUME,
|
|
||||||
PsThreadType,
|
|
||||||
PreviousMode,
|
|
||||||
(PVOID*)&Thread,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status)) {
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call the Kernel Function */
|
|
||||||
Prev = KeResumeThread(&Thread->Tcb);
|
|
||||||
|
|
||||||
/* Return it */
|
|
||||||
if(SuspendCount) {
|
|
||||||
|
|
||||||
_SEH_TRY {
|
|
||||||
|
|
||||||
*SuspendCount = Prev;
|
|
||||||
|
|
||||||
} _SEH_HANDLE {
|
|
||||||
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
|
|
||||||
} _SEH_END;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dereference and Return */
|
|
||||||
ObDereferenceObject ((PVOID)Thread);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FUNCTION: Increments a thread's suspend count
|
|
||||||
* ARGUMENTS:
|
|
||||||
* ThreadHandle = Handle to the thread that should be resumed
|
|
||||||
* PreviousSuspendCount = The resulting/previous suspend count.
|
|
||||||
* REMARK:
|
|
||||||
* A thread will be suspended if its suspend count is greater than 0.
|
|
||||||
* This procedure maps to the win32 SuspendThread function. (
|
|
||||||
* documentation about the the suspend count can be found here aswell )
|
|
||||||
* The suspend count is not increased if it is greater than
|
|
||||||
* MAXIMUM_SUSPEND_COUNT.
|
|
||||||
* RETURNS: Status
|
|
||||||
*/
|
|
||||||
NTSTATUS
|
|
||||||
STDCALL
|
|
||||||
NtSuspendThread(IN HANDLE ThreadHandle,
|
|
||||||
IN PULONG PreviousSuspendCount OPTIONAL)
|
|
||||||
{
|
|
||||||
PETHREAD Thread;
|
|
||||||
ULONG Prev;
|
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
/* Check buffer validity */
|
|
||||||
if(PreviousSuspendCount && PreviousMode != KernelMode)
|
|
||||||
{
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
ProbeForWriteUlong(PreviousSuspendCount);
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
} _SEH_END;
|
|
||||||
|
|
||||||
if(!NT_SUCCESS(Status)) return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the Thread Object */
|
|
||||||
Status = ObReferenceObjectByHandle(ThreadHandle,
|
|
||||||
THREAD_SUSPEND_RESUME,
|
|
||||||
PsThreadType,
|
|
||||||
PreviousMode,
|
|
||||||
(PVOID*)&Thread,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status)) return Status;
|
|
||||||
|
|
||||||
/* Guard with SEH because KeSuspendThread can raise an exception */
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
/* Make sure the thread isn't terminating */
|
|
||||||
if ((Thread != PsGetCurrentThread()) && (Thread->Terminated))
|
|
||||||
{
|
|
||||||
ObDereferenceObject(Thread);
|
|
||||||
return STATUS_THREAD_IS_TERMINATING;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call the Kernel function */
|
|
||||||
Prev = KeSuspendThread(&Thread->Tcb);
|
|
||||||
|
|
||||||
/* Return the Previous Count */
|
|
||||||
if (PreviousSuspendCount) *PreviousSuspendCount = Prev;
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
|
|
||||||
/* Don't fail if we merely couldn't write the handle back */
|
|
||||||
if (Status != STATUS_SUSPEND_COUNT_EXCEEDED) Status = STATUS_SUCCESS;
|
|
||||||
} _SEH_END;
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
ObDereferenceObject(Thread);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @unimplemented
|
|
||||||
*/
|
|
||||||
NTSTATUS
|
|
||||||
STDCALL
|
|
||||||
NtSuspendProcess(IN HANDLE ProcessHandle)
|
|
||||||
{
|
|
||||||
KPROCESSOR_MODE PreviousMode;
|
|
||||||
PEPROCESS Process;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
PreviousMode = ExGetPreviousMode();
|
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(ProcessHandle,
|
|
||||||
PROCESS_SUSPEND_RESUME,
|
|
||||||
PsProcessType,
|
|
||||||
PreviousMode,
|
|
||||||
(PVOID*)&Process,
|
|
||||||
NULL);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
/* FIXME */
|
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
|
||||||
DPRINT1("NtSuspendProcess not yet implemented!\n");
|
|
||||||
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @unimplemented
|
|
||||||
*/
|
|
||||||
NTSTATUS
|
|
||||||
STDCALL
|
|
||||||
NtResumeProcess(IN HANDLE ProcessHandle)
|
|
||||||
{
|
|
||||||
KPROCESSOR_MODE PreviousMode;
|
|
||||||
PEPROCESS Process;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
PreviousMode = ExGetPreviousMode();
|
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(ProcessHandle,
|
|
||||||
PROCESS_SUSPEND_RESUME,
|
|
||||||
PsProcessType,
|
|
||||||
PreviousMode,
|
|
||||||
(PVOID*)&Process,
|
|
||||||
NULL);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
/* FIXME */
|
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
|
||||||
DPRINT1("NtResumeProcess not yet implemented!\n");
|
|
||||||
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* EOF */
|
|
|
@ -840,14 +840,6 @@ NtYieldExecution(VOID)
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
NtTestAlert(VOID)
|
|
||||||
{
|
|
||||||
/* Check and Alert Thread if needed */
|
|
||||||
return KeTestAlertThread(ExGetPreviousMode()) ? STATUS_ALERTED : STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue