From: Timo Kreuzer Date: Thu, 20 Dec 2012 14:58:02 +0000 (+0000) Subject: [NTOSKRNL] X-Git-Tag: backups/ros-csrss@60644~104^2~74 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=7d2114ddb1af57657d68564a3711f82ccb470b1f;hp=589a2f3a3cd1c3e7b9c2e8fa6a21eb058f3cb2e7 [NTOSKRNL] - Use 2 seperate SEH blocks in PsSuspendThread(). This way we don't leak the rundown protection, and don't keep a terminating thread suspended, when KeSuspendThread() throws an exception. Also only catch STATUS_SUSPEND_COUNT_EXCEEDED exceptions in the SEH filter. svn path=/trunk/; revision=57958 --- diff --git a/reactos/ntoskrnl/ps/state.c b/reactos/ntoskrnl/ps/state.c index 62664f9cc10..8baeea0b74b 100644 --- a/reactos/ntoskrnl/ps/state.c +++ b/reactos/ntoskrnl/ps/state.c @@ -45,73 +45,78 @@ PsResumeThread(IN PETHREAD Thread, NTSTATUS NTAPI -PsSuspendThread(IN PETHREAD Thread, - OUT PULONG PreviousCount OPTIONAL) +PsSuspendThread( + IN PETHREAD Thread, + OUT PULONG PreviousCount OPTIONAL) { NTSTATUS Status; ULONG OldCount = 0; PAGED_CODE(); - /* Guard with SEH because KeSuspendThread can raise an exception */ - _SEH2_TRY + /* Assume success */ + Status = STATUS_SUCCESS; + + /* Check if we're suspending ourselves */ + if (Thread == PsGetCurrentThread()) { - /* Check if we're suspending ourselves */ - if (Thread == PsGetCurrentThread()) + /* Guard with SEH because KeSuspendThread can raise an exception */ + _SEH2_TRY { /* Do the suspend */ OldCount = KeSuspendThread(&Thread->Tcb); - - /* We are done */ - Status = STATUS_SUCCESS; } - else + _SEH2_EXCEPT(_SEH2_GetExceptionCode() == STATUS_SUSPEND_COUNT_EXCEEDED) { - /* Acquire rundown */ - if (ExAcquireRundownProtection(&Thread->RundownProtect)) + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + else + { + /* Acquire rundown protection */ + if (ExAcquireRundownProtection(&Thread->RundownProtect)) + { + /* Make sure the thread isn't terminating */ + if (Thread->Terminated) { - /* Make sure the thread isn't terminating */ - if (Thread->Terminated) + /* Fail */ + Status = STATUS_THREAD_IS_TERMINATING; + } + else + { + /* Guard with SEH because KeSuspendThread can raise an exception */ + _SEH2_TRY { - /* Fail */ - Status = STATUS_THREAD_IS_TERMINATING; + /* Do the suspend */ + OldCount = KeSuspendThread(&Thread->Tcb); } - else + _SEH2_EXCEPT(_SEH2_GetExceptionCode() == STATUS_SUSPEND_COUNT_EXCEEDED) { - /* Otherwise, do the suspend */ - OldCount = KeSuspendThread(&Thread->Tcb); - - /* Check if it terminated during the suspend */ - if (Thread->Terminated) - { - /* Wake it back up and fail */ - KeForceResumeThread(&Thread->Tcb); - Status = STATUS_THREAD_IS_TERMINATING; - OldCount = 0; - } + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); } + _SEH2_END; - /* Release rundown protection */ - ExReleaseRundownProtection(&Thread->RundownProtect); - - /* We are done */ - Status = STATUS_SUCCESS; - } - else - { - /* Thread is terminating */ - Status = STATUS_THREAD_IS_TERMINATING; + /* Check if it was terminated during the suspend */ + if (Thread->Terminated) + { + /* Wake it back up and fail */ + KeForceResumeThread(&Thread->Tcb); + Status = STATUS_THREAD_IS_TERMINATING; + OldCount = 0; + } } - } - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Get the exception code */ - Status = _SEH2_GetExceptionCode(); - /* Don't fail if we merely couldn't write the handle back */ - if (Status != STATUS_SUSPEND_COUNT_EXCEEDED) Status = STATUS_SUCCESS; + /* Release rundown protection */ + ExReleaseRundownProtection(&Thread->RundownProtect); + } + else + { + /* Thread is terminating */ + Status = STATUS_THREAD_IS_TERMINATING; + } } - _SEH2_END; /* Write back the previous count */ if (PreviousCount) *PreviousCount = OldCount;