[NTOS]: Fix Implementation of BreakOnTermination -- Process Flags should be accessed...
[reactos.git] / reactos / ntoskrnl / ps / query.c
index b4c2aba..342c818 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,42 @@ 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:
 
@@ -831,6 +868,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
     PROCESS_SESSION_INFORMATION SessionInfo = {0};
     PROCESS_PRIORITY_CLASS PriorityClass = {0};
     PVOID ExceptionPort;
+    ULONG Break;
     PAGED_CODE();
 
     /* Verify Information Class validity */
@@ -887,8 +925,9 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Return the exception code */
-                _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                /* Get the exception code */
+                Status = _SEH2_GetExceptionCode();
+                _SEH2_YIELD(break);
             }
             _SEH2_END;
 
@@ -931,8 +970,9 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Return the exception code */
-                _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                /* Get the exception code */
+                Status = _SEH2_GetExceptionCode();
+                _SEH2_YIELD(break);
             }
             _SEH2_END;
 
@@ -983,8 +1023,9 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Return the exception code */
-                _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                /* Get the exception code */
+                Status = _SEH2_GetExceptionCode();
+                _SEH2_YIELD(break);
             }
             _SEH2_END;
 
@@ -1051,7 +1092,8 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
                 /* Return the exception code */
-                _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                Status = _SEH2_GetExceptionCode();
+                _SEH2_YIELD(break);
             }
             _SEH2_END;
 
@@ -1146,6 +1188,48 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             Status = STATUS_NOT_IMPLEMENTED;
             break;
 
+        case ProcessBreakOnTermination:
+
+            /* Check buffer length */
+            if (ProcessInformationLength != sizeof(ULONG))
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
+            /* Enter SEH for direct buffer read */
+            _SEH2_TRY
+            {
+                Break = *(PULONG)ProcessInformation;
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                /* Get exception code */
+                Break = 0;
+                Status = _SEH2_GetExceptionCode();
+                _SEH2_YIELD(break);
+            }
+            _SEH2_END;
+            
+            /* Setting 'break on termination' requires the SeDebugPrivilege */
+            if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode))
+            {
+                Status = STATUS_PRIVILEGE_NOT_HELD;
+                break;
+            }
+            
+            /* Set or clear the flag */
+            if (Break)
+            {
+                PspSetProcessFlag(Process, PSF_BREAK_ON_TERMINATION_BIT);
+            }
+            else
+            {
+                PspClearProcessFlag(Process, PSF_BREAK_ON_TERMINATION_BIT);
+            }
+
+            break;
+
         /* We currently don't implement any of these */
         case ProcessLdtInformation:
         case ProcessLdtSize:
@@ -1221,7 +1305,7 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
         Access = THREAD_SET_THREAD_TOKEN;
     }
 
-    /* Reference the process */
+    /* Reference the thread */
     Status = ObReferenceObjectByHandle(ThreadHandle,
                                        Access,
                                        PsThreadType,
@@ -1251,8 +1335,9 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Return the exception code */
-                _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                /* Get the exception code */
+                Status = _SEH2_GetExceptionCode();
+                _SEH2_YIELD(break);
             }
             _SEH2_END;
 
@@ -1286,8 +1371,9 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Return the exception code */
-                _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                /* Get the exception code */
+                Status = _SEH2_GetExceptionCode();
+                _SEH2_YIELD(break);
             }
             _SEH2_END;
 
@@ -1331,8 +1417,8 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Return the exception code */
-                _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                /* Get the exception code */
+                Status = _SEH2_GetExceptionCode();
             }
             _SEH2_END;
 
@@ -1398,8 +1484,9 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Return the exception code */
-                _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                /* Get the exception code */
+                Status = _SEH2_GetExceptionCode();
+                _SEH2_YIELD(break);
             }
             _SEH2_END;
 
@@ -1424,8 +1511,9 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Return the exception code */
-                _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                /* Get the exception code */
+                Status = _SEH2_GetExceptionCode();
+                _SEH2_YIELD(break);
             }
             _SEH2_END;
 
@@ -1450,8 +1538,9 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Return the exception code */
-                _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                /* Get the exception code */
+                Status = _SEH2_GetExceptionCode();
+                _SEH2_YIELD(break);
             }
             _SEH2_END;
 
@@ -1497,8 +1586,9 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Return the exception code */
-                _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                /* Get the exception code */
+                Status = _SEH2_GetExceptionCode();
+                _SEH2_YIELD(break);
             }
             _SEH2_END;
 
@@ -1523,8 +1613,9 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
-                /* Return the exception code */
-                _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                /* Get the exception code */
+                Status = _SEH2_GetExceptionCode();
+                _SEH2_YIELD(break);
             }
             _SEH2_END;