mirror of
https://github.com/reactos/reactos.git
synced 2024-08-14 07:06:23 +00:00
- Fix NtSuspendThread: correct PreviousMode check, return error if thread is terminating, handle KeSuspendThread's possible exception, only attempt to return previous suspend count if asked to.
- Make KeSuspendThread return an exception if the thread has been suspended beyond the limit. This fixes another wine test. svn path=/trunk/; revision=17230
This commit is contained in:
parent
2d51263ec6
commit
4c12530bbc
|
@ -14,10 +14,8 @@
|
|||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#ifndef MUTANT_INCREMENT
|
||||
#define MUTANT_INCREMENT 1
|
||||
#endif
|
||||
|
||||
/* FIXME: NDK */
|
||||
#define MAXIMUM_SUSPEND_COUNT 0x7F
|
||||
#define THREAD_ALERT_INCREMENT 2
|
||||
|
||||
extern EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue];
|
||||
|
@ -599,6 +597,14 @@ KeSuspendThread(PKTHREAD Thread)
|
|||
/* Save the Old Count */
|
||||
PreviousCount = Thread->SuspendCount;
|
||||
|
||||
/* Handle the maximum */
|
||||
if (PreviousCount == MAXIMUM_SUSPEND_COUNT)
|
||||
{
|
||||
/* Raise an exception */
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
ExRaiseStatus(STATUS_SUSPEND_COUNT_EXCEEDED);
|
||||
}
|
||||
|
||||
/* Increment it */
|
||||
Thread->SuspendCount++;
|
||||
|
||||
|
|
|
@ -115,25 +115,22 @@ NtSuspendThread(IN HANDLE ThreadHandle,
|
|||
{
|
||||
PETHREAD Thread;
|
||||
ULONG Prev;
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
PreviousMode = ExGetPreviousMode();
|
||||
|
||||
/* Check buffer validity */
|
||||
if(PreviousSuspendCount && PreviousMode == UserMode) {
|
||||
|
||||
_SEH_TRY {
|
||||
|
||||
if(PreviousSuspendCount && PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForWrite(PreviousSuspendCount,
|
||||
sizeof(ULONG),
|
||||
sizeof(ULONG));
|
||||
} _SEH_HANDLE {
|
||||
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
|
||||
} _SEH_END;
|
||||
|
||||
if(!NT_SUCCESS(Status)) return Status;
|
||||
|
@ -146,30 +143,34 @@ NtSuspendThread(IN HANDLE ThreadHandle,
|
|||
PreviousMode,
|
||||
(PVOID*)&Thread,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
if (!NT_SUCCESS(Status)) return 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 */
|
||||
/* Call the Kernel function */
|
||||
Prev = KeSuspendThread(&Thread->Tcb);
|
||||
|
||||
/* Return it */
|
||||
if(PreviousSuspendCount) {
|
||||
|
||||
_SEH_TRY {
|
||||
|
||||
*PreviousSuspendCount = Prev;
|
||||
|
||||
} _SEH_HANDLE {
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Dereference and Return */
|
||||
ObDereferenceObject((PVOID)Thread);
|
||||
/* Return */
|
||||
ObDereferenceObject(Thread);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue