mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 01:42:30 +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
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KeAlertThread(
|
||||
IN PKTHREAD Thread,
|
||||
IN KPROCESSOR_MODE AlertMode
|
||||
);
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
KeAlertResumeThread(
|
||||
IN PKTHREAD Thread
|
||||
);
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
KeResumeThread(
|
||||
IN PKTHREAD Thread
|
||||
);
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
KeSwitchKernelStack(
|
||||
|
|
|
@ -443,8 +443,8 @@ KeRundownThread(VOID)
|
|||
}
|
||||
|
||||
ULONG
|
||||
STDCALL
|
||||
KeResumeThread(PKTHREAD Thread)
|
||||
NTAPI
|
||||
KeResumeThread(IN PKTHREAD Thread)
|
||||
{
|
||||
ULONG PreviousCount;
|
||||
KIRQL OldIrql;
|
||||
|
@ -624,7 +624,7 @@ KeForceResumeThread(IN PKTHREAD Thread)
|
|||
}
|
||||
|
||||
ULONG
|
||||
STDCALL
|
||||
NTAPI
|
||||
KeAlertResumeThread(IN PKTHREAD Thread)
|
||||
{
|
||||
ULONG PreviousCount;
|
||||
|
@ -674,9 +674,9 @@ KeAlertResumeThread(IN PKTHREAD Thread)
|
|||
}
|
||||
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
KeAlertThread(PKTHREAD Thread,
|
||||
KPROCESSOR_MODE AlertMode)
|
||||
NTAPI
|
||||
KeAlertThread(IN PKTHREAD Thread,
|
||||
IN KPROCESSOR_MODE AlertMode)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
BOOLEAN PreviousState;
|
||||
|
@ -1550,109 +1550,6 @@ KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
|
|||
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
|
||||
STDCALL
|
||||
NtDelayExecution(IN BOOLEAN Alertable,
|
||||
|
|
|
@ -295,7 +295,7 @@
|
|||
<file>query.c</file>
|
||||
<file>quota.c</file>
|
||||
<file>security.c</file>
|
||||
<file>suspend.c</file>
|
||||
<file>state.c</file>
|
||||
<file>thread.c</file>
|
||||
<file>win32.c</file>
|
||||
</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);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtTestAlert(VOID)
|
||||
{
|
||||
/* Check and Alert Thread if needed */
|
||||
return KeTestAlertThread(ExGetPreviousMode()) ? STATUS_ALERTED : STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue