From 9170a29ef71faa0cad0b5847c736bddf6ef3c1f2 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 18 Jul 2006 14:34:06 +0000 Subject: [PATCH] [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 --- reactos/ntoskrnl/include/internal/ke.h | 19 ++ reactos/ntoskrnl/ke/kthread.c | 115 +-------- reactos/ntoskrnl/ntoskrnl.rbuild | 2 +- reactos/ntoskrnl/ps/state.c | 321 +++++++++++++++++++++++++ reactos/ntoskrnl/ps/suspend.c | 241 ------------------- reactos/ntoskrnl/ps/thread.c | 8 - 6 files changed, 347 insertions(+), 359 deletions(-) create mode 100644 reactos/ntoskrnl/ps/state.c delete mode 100644 reactos/ntoskrnl/ps/suspend.c diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index c61331a4675..5a657eaf0d7 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -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( diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index c94bb51a0e8..de2a37af2d2 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.c @@ -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, diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 3daae508c59..5b031e23711 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -295,7 +295,7 @@ query.c quota.c security.c - suspend.c + state.c thread.c win32.c diff --git a/reactos/ntoskrnl/ps/state.c b/reactos/ntoskrnl/ps/state.c new file mode 100644 index 00000000000..5aae747c307 --- /dev/null +++ b/reactos/ntoskrnl/ps/state.c @@ -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 +#define NDEBUG +#include + +/* 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 */ diff --git a/reactos/ntoskrnl/ps/suspend.c b/reactos/ntoskrnl/ps/suspend.c deleted file mode 100644 index a2afe674525..00000000000 --- a/reactos/ntoskrnl/ps/suspend.c +++ /dev/null @@ -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 -#define NDEBUG -#include - -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 */ diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index c6517857eb7..3d36a13be17 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -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 */