[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / ps / query.c
index 8f18912..d27ff3e 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 ******************************************************************/
@@ -147,7 +148,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 ProcessBasicInfo->UniqueProcessId = (ULONG_PTR)Process->
                                                     UniqueProcessId;
                 ProcessBasicInfo->InheritedFromUniqueProcessId =
-                    (ULONG_PTR)Process->InheritedFromUniqueProcessId;
+                    (ULONG)Process->InheritedFromUniqueProcessId;
                 ProcessBasicInfo->BasePriority = Process->Pcb.BasePriority;
 
             }
@@ -434,7 +435,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
             _SEH2_TRY
             {
                 /* Write back the Session ID */
-                SessionInfo->SessionId = PtrToUlong(Process->Session);
+                SessionInfo->SessionId = Process->Session;
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
@@ -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:
 
@@ -887,11 +925,13 @@ 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_END;
 
+            if (!NT_SUCCESS(Status)) break;
+
             /* Get the LPC Port */
             Status = ObReferenceObjectByHandle(PortHandle,
                                                0,
@@ -931,11 +971,13 @@ 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_END;
 
+            if (!NT_SUCCESS(Status)) break;
+
             /* Assign the actual token */
             Status = PspSetPrimaryToken(Process, TokenHandle, NULL);
             break;
@@ -983,11 +1025,13 @@ 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_END;
 
+            if (!NT_SUCCESS(Status)) break;
+
             /* Setting the session id requires the SeTcbPrivilege */
             if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
             {
@@ -1001,7 +1045,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             if (!NT_SUCCESS(Status)) break;
 
             /* Write the session ID in the EPROCESS */
-            Process->Session = (PVOID)(ULONG_PTR)SessionInfo.SessionId;
+            Process->Session = SessionInfo.SessionId;
 
             /* Check if the process also has a PEB */
             if (Process->Peb)
@@ -1051,10 +1095,12 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
                 /* Return the exception code */
-                _SEH2_YIELD(return _SEH2_GetExceptionCode());
+                Status = _SEH2_GetExceptionCode();
             }
             _SEH2_END;
 
+            if (!NT_SUCCESS(Status)) break;
+
             /* Check for invalid PriorityClass value */
             if (PriorityClass.PriorityClass > PROCESS_PRIORITY_CLASS_ABOVE_NORMAL)
             {
@@ -1146,6 +1192,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:
@@ -1221,7 +1296,7 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
         Access = THREAD_SET_THREAD_TOKEN;
     }
 
-    /* Reference the process */
+    /* Reference the thread */
     Status = ObReferenceObjectByHandle(ThreadHandle,
                                        Access,
                                        PsThreadType,
@@ -1251,11 +1326,13 @@ 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;
 
+            if (!NT_SUCCESS(Status)) break;
+
             /* Validate it */
             if ((Priority > HIGH_PRIORITY) ||
                 (Priority <= LOW_PRIORITY))
@@ -1286,11 +1363,13 @@ 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;
 
+            if (!NT_SUCCESS(Status)) break;
+
             /* Validate it */
             if ((Priority > THREAD_BASE_PRIORITY_MAX) ||
                 (Priority < THREAD_BASE_PRIORITY_MIN))
@@ -1331,8 +1410,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,11 +1477,13 @@ 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;
 
+            if (!NT_SUCCESS(Status)) break;
+
             /* Assign the actual token */
             Status = PsAssignImpersonationToken(Thread, TokenHandle);
             break;
@@ -1424,11 +1505,13 @@ 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;
 
+            if (!NT_SUCCESS(Status)) break;
+
             /* Set the address */
             Thread->Win32StartAddress = Address;
             break;
@@ -1450,11 +1533,13 @@ 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;
 
+            if (!NT_SUCCESS(Status)) break;
+
             /* Validate it */
             if (IdealProcessor > MAXIMUM_PROCESSORS)
             {
@@ -1497,11 +1582,13 @@ 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;
 
+            if (!NT_SUCCESS(Status)) break;
+
             /* Call the kernel */
             KeSetDisableBoostThread(&Thread->Tcb, (BOOLEAN)DisableBoost);
             break;
@@ -1523,11 +1610,13 @@ 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;
 
+            if (!NT_SUCCESS(Status)) break;
+
             /* This is only valid for the current thread */
             if (Thread != PsGetCurrentThread())
             {