[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:
Alex Ionescu 2006-07-18 14:34:06 +00:00
parent d9f7a999cf
commit 9170a29ef7
6 changed files with 347 additions and 359 deletions

View file

@ -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(

View file

@ -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,

View file

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

View file

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

View file

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