From 00fbba2fb4e16e0708b4c4f18400591acf11b5aa Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 29 May 2010 18:22:47 +0000 Subject: [PATCH] [NTOSKRNL / RTL] - Implement BreakOnTermination case for NtQueryInformationProcess and NtSetInformationProcess. - Implement RtlSetProcessIsCritical. svn path=/trunk/; revision=47423 --- reactos/include/ndk/rtlfuncs.h | 4 +- reactos/lib/rtl/process.c | 46 ++++++++++++---- reactos/ntoskrnl/include/internal/ps_i.h | 6 +-- reactos/ntoskrnl/ps/query.c | 67 ++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 14 deletions(-) diff --git a/reactos/include/ndk/rtlfuncs.h b/reactos/include/ndk/rtlfuncs.h index 18aa4749ad4..d0f3f06d701 100644 --- a/reactos/include/ndk/rtlfuncs.h +++ b/reactos/include/ndk/rtlfuncs.h @@ -2042,12 +2042,12 @@ RtlRemoteCall( ); NTSYSAPI -VOID +NTSTATUS NTAPI RtlSetProcessIsCritical( IN BOOLEAN NewValue, OUT PBOOLEAN OldValue OPTIONAL, - IN BOOLEAN IsWinlogon + IN BOOLEAN NeedBreaks ); NTSYSAPI diff --git a/reactos/lib/rtl/process.c b/reactos/lib/rtl/process.c index b8585b0fe6f..5d6c6896a04 100644 --- a/reactos/lib/rtl/process.c +++ b/reactos/lib/rtl/process.c @@ -5,6 +5,7 @@ * PURPOSE: Process functions * PROGRAMMER: Alex Ionescu (alex@relsoft.net) * Ariadne (ariadne@xs4all.nl) + * Eric Kohl */ /* INCLUDES ****************************************************************/ @@ -351,18 +352,45 @@ RtlEncodeSystemPointer(IN PVOID Pointer) } /* - * @unimplemented + * @implemented + * + * NOTES: + * Implementation based on the documentation from: + * http://www.geoffchappell.com/studies/windows/win32/ntdll/api/rtl/peb/setprocessiscritical.htm */ -NTSYSAPI -VOID +NTSTATUS NTAPI -RtlSetProcessIsCritical( - IN BOOLEAN NewValue, - OUT PBOOLEAN OldValue OPTIONAL, - IN BOOLEAN IsWinlogon) +RtlSetProcessIsCritical(IN BOOLEAN NewValue, + OUT PBOOLEAN OldValue OPTIONAL, + IN BOOLEAN NeedBreaks) { - //TODO - UNIMPLEMENTED; + ULONG BreakOnTermination = FALSE; + + if (OldValue) + *OldValue = FALSE; + + /* Fail, if the critical breaks flag is required but is not set */ + if (NeedBreaks == TRUE && + !(NtCurrentPeb()->NtGlobalFlag & FLG_ENABLE_SYSTEM_CRIT_BREAKS)) + return STATUS_UNSUCCESSFUL; + + if (OldValue) + { + /* Query and return the old break on termination flag for the process */ + ZwQueryInformationProcess(NtCurrentProcess(), + ProcessBreakOnTermination, + &BreakOnTermination, + sizeof(ULONG), + NULL); + *OldValue = (BOOLEAN)BreakOnTermination; + } + + /* Set the break on termination flag for the process */ + BreakOnTermination = NewValue; + return ZwSetInformationProcess(NtCurrentProcess(), + ProcessBreakOnTermination, + &BreakOnTermination, + sizeof(ULONG)); } ULONG diff --git a/reactos/ntoskrnl/include/internal/ps_i.h b/reactos/ntoskrnl/include/internal/ps_i.h index 75a4994f24a..13251f8e901 100644 --- a/reactos/ntoskrnl/include/internal/ps_i.h +++ b/reactos/ntoskrnl/include/internal/ps_i.h @@ -249,9 +249,9 @@ static const INFORMATION_CLASS_INFO PsProcessInfoClass[] = /* ProcessBreakOnTermination */ IQS_SAME ( - UCHAR, - UCHAR, - 0 + ULONG, + ULONG, + ICIF_QUERY | ICIF_SET ), /* ProcessDebugObjectHandle */ diff --git a/reactos/ntoskrnl/ps/query.c b/reactos/ntoskrnl/ps/query.c index b4c2abaefea..c919c419931 100644 --- a/reactos/ntoskrnl/ps/query.c +++ b/reactos/ntoskrnl/ps/query.c @@ -5,6 +5,7 @@ * PURPOSE: Process Manager: Thread/Process Query/Set Information * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * Thomas Weidenmueller (w3seek@reactos.org) + * Eric Kohl */ /* INCLUDES ******************************************************************/ @@ -735,6 +736,43 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle, ObDereferenceObject(Process); break; + case ProcessBreakOnTermination: + + /* Set the return length*/ + Length = sizeof(ULONG); + if (ProcessInformationLength != Length) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + /* Reference the process */ + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_QUERY_INFORMATION, + PsProcessType, + PreviousMode, + (PVOID*)&Process, + NULL); + if (!NT_SUCCESS(Status)) + break; + + /* Enter SEH for writing back data */ + _SEH2_TRY + { + /* Return the BreakOnTermination state */ + *(PULONG)ProcessInformation = Process->BreakOnTermination; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get the exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + /* Dereference the process */ + ObDereferenceObject(Process); + break; + /* Per-process security cookie */ case ProcessCookie: @@ -1146,6 +1184,35 @@ NtSetInformationProcess(IN HANDLE ProcessHandle, Status = STATUS_NOT_IMPLEMENTED; break; + case ProcessBreakOnTermination: + + /* Check buffer length */ + if (ProcessInformationLength != sizeof(ULONG)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + /* Setting 'break on termination' requires the SeDebugPrivilege */ + if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode)) + { + Status = STATUS_PRIVILEGE_NOT_HELD; + break; + } + + /* Enter SEH for direct buffer read */ + _SEH2_TRY + { + Process->BreakOnTermination = *(PULONG)ProcessInformation; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get exception code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + break; + /* We currently don't implement any of these */ case ProcessLdtInformation: case ProcessLdtSize: -- 2.17.1