[NTOSKRNL / RTL]
authorEric Kohl <eric.kohl@reactos.org>
Sat, 29 May 2010 18:22:47 +0000 (18:22 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 29 May 2010 18:22:47 +0000 (18:22 +0000)
- Implement BreakOnTermination case for NtQueryInformationProcess and NtSetInformationProcess.
- Implement RtlSetProcessIsCritical.

svn path=/trunk/; revision=47423

reactos/include/ndk/rtlfuncs.h
reactos/lib/rtl/process.c
reactos/ntoskrnl/include/internal/ps_i.h
reactos/ntoskrnl/ps/query.c

index 18aa474..d0f3f06 100644 (file)
@@ -2042,12 +2042,12 @@ RtlRemoteCall(
 );
 
 NTSYSAPI
-VOID
+NTSTATUS
 NTAPI
 RtlSetProcessIsCritical(
     IN BOOLEAN NewValue,
     OUT PBOOLEAN OldValue OPTIONAL,
-    IN BOOLEAN IsWinlogon
+    IN BOOLEAN NeedBreaks
 );
 
 NTSYSAPI
index b8585b0..5d6c689 100644 (file)
@@ -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
index 75a4994..13251f8 100644 (file)
@@ -249,9 +249,9 @@ static const INFORMATION_CLASS_INFO PsProcessInfoClass[] =
     /* ProcessBreakOnTermination */
     IQS_SAME
     (
-        UCHAR,
-        UCHAR,
-        0
+        ULONG,
+        ULONG,
+        ICIF_QUERY | ICIF_SET
     ),
 
     /* ProcessDebugObjectHandle */
index b4c2aba..c919c41 100644 (file)
@@ -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: