[NTOS/PS]
[reactos.git] / reactos / ntoskrnl / ps / query.c
index 308e983..b370191 100644 (file)
@@ -17,9 +17,6 @@
 /* FIXME: From winbase.h... what to do? */
 #define SEM_NOALIGNMENTFAULTEXCEPT 0x04
 
-/* Include Information Class Tables */
-#include "internal/ps_i.h"
-
 /* Debugging Level */
 ULONG PspTraceLevel = 0;
 
@@ -108,7 +105,8 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
         _SEH2_END;
     }
 
-    if((ProcessInformationClass == ProcessCookie) &&
+    if (((ProcessInformationClass == ProcessCookie) ||
+         (ProcessInformationClass == ProcessImageInformation)) &&
         (ProcessHandle != NtCurrentProcess()))
     {
         /*
@@ -153,7 +151,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 ProcessBasicInfo->UniqueProcessId = (ULONG_PTR)Process->
                                                     UniqueProcessId;
                 ProcessBasicInfo->InheritedFromUniqueProcessId =
-                    (ULONG)Process->InheritedFromUniqueProcessId;
+                    (ULONG_PTR)Process->InheritedFromUniqueProcessId;
                 ProcessBasicInfo->BasePriority = Process->Pcb.BasePriority;
 
             }
@@ -421,7 +419,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
             _SEH2_TRY
             {
                 /* Write back the Session ID */
-                SessionInfo->SessionId = PtrToUlong(PsGetProcessSessionId(Process));
+                SessionInfo->SessionId = PsGetProcessSessionId(Process);
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
@@ -470,8 +468,8 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 VmCounters->PagefileUsage = Process->QuotaUsage[2] << PAGE_SHIFT;
                 VmCounters->PeakPagefileUsage = Process->QuotaPeak[2] << PAGE_SHIFT;
                 //VmCounters->PrivateUsage = Process->CommitCharge << PAGE_SHIFT;
-                // 
-                
+                //
+
                 /* Set the return length */
                 Length = ProcessInformationLength;
             }
@@ -699,7 +697,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 }
 
                 /* Free the image path */
-                ExFreePool(ImageName);
+                ExFreePoolWithTag(ImageName, TAG_SEPA);
             }
             /* Dereference the process */
             ObDereferenceObject(Process);
@@ -823,8 +821,30 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
             break;
 
         case ProcessImageInformation:
-            DPRINT1("Image Information Query Not implemented: %lx\n", ProcessInformationClass);
-            Status = STATUS_NOT_IMPLEMENTED;
+
+            /* Set the length required and validate it */
+            Length = sizeof(SECTION_IMAGE_INFORMATION);
+            if (ProcessInformationLength != Length)
+            {
+                /* Break out */
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
+            /* Enter SEH to protect write */
+            _SEH2_TRY
+            {
+                MmGetImageInformation((PSECTION_IMAGE_INFORMATION)ProcessInformation);
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                /* Get the exception code */
+                Status = _SEH2_GetExceptionCode();
+            }
+            _SEH2_END;
+
+            /* Indicate success */
+            Status = STATUS_SUCCESS;
             break;
 
         case ProcessDebugObjectHandle:
@@ -880,10 +900,10 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
-            
+
             /* Indicate success */
             Status = STATUS_SUCCESS;
-            
+
             /* Protect write in SEH */
             _SEH2_TRY
             {
@@ -958,14 +978,14 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
             {
                 /* Get the WOW64 process structure */
 #ifdef _WIN64
-                Wow64 = Process->Wow64Process;
+                Wow64 = (ULONG_PTR)Process->Wow64Process;
 #else
                 Wow64 = 0;
 #endif
                 /* Release the lock */
                 ExReleaseRundownProtection(&Process->RundownProtect);
             }
-            
+
             /* Protect write with SEH */
             _SEH2_TRY
             {
@@ -982,9 +1002,9 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
             /* Dereference the process */
             ObDereferenceObject(Process);
             break;
-            
+
         case ProcessExecuteFlags:
-        
+
             /* Set return length */
             Length = sizeof(ULONG);
             if (ProcessInformationLength != Length)
@@ -1149,7 +1169,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             /* Getting VDM powers requires the SeTcbPrivilege */
             if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
             {
-                /* Bail out */
+                /* We don't hold the privilege, bail out */
                 Status = STATUS_PRIVILEGE_NOT_HELD;
                 DPRINT1("Need TCB privilege\n");
                 break;
@@ -1193,7 +1213,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             /* Setting the error port requires the SeTcbPrivilege */
             if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
             {
-                /* Can't set the session ID, bail out. */
+                /* We don't hold the privilege, bail out */
                 Status = STATUS_PRIVILEGE_NOT_HELD;
                 break;
             }
@@ -1312,17 +1332,19 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             /* Setting the session id requires the SeTcbPrivilege */
             if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
             {
-                /* Can't set the session ID, bail out. */
+                /* We don't hold the privilege, bail out */
                 Status = STATUS_PRIVILEGE_NOT_HELD;
                 break;
             }
 
+#if 0 // OLD AND DEPRECATED CODE!!!!
+
             /* FIXME - update the session id for the process token */
             //Status = PsLockProcess(Process, FALSE);
             if (!NT_SUCCESS(Status)) break;
 
             /* Write the session ID in the EPROCESS */
-            Process->Session = SessionInfo.SessionId;
+            Process->Session = UlongToPtr(SessionInfo.SessionId); // HACK!!!
 
             /* Check if the process also has a PEB */
             if (Process->Peb)
@@ -1352,6 +1374,27 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
 
             /* Unlock the process */
             //PsUnlockProcess(Process);
+
+#endif
+
+            /*
+             * Since we cannot change the session ID of the given
+             * process anymore because it is set once and for all
+             * at process creation time and because it is stored
+             * inside the Process->Session structure managed by MM,
+             * we fake changing it: we just return success if the
+             * user-defined value is the same as the session ID of
+             * the process, and otherwise we fail.
+             */
+            if (SessionInfo.SessionId == PsGetProcessSessionId(Process))
+            {
+                Status = STATUS_SUCCESS;
+            }
+            else
+            {
+                Status = STATUS_ACCESS_DENIED;
+            }
+
             break;
 
         case ProcessPriorityClass:
@@ -1592,6 +1635,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             /* Setting 'break on termination' requires the SeDebugPrivilege */
             if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode))
             {
+                /* We don't hold the privilege, bail out */
                 Status = STATUS_PRIVILEGE_NOT_HELD;
                 break;
             }
@@ -1811,13 +1855,13 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             KeSetAutoAlignmentProcess(&Process->Pcb, FALSE);
             Status = STATUS_SUCCESS;
             break;
-            
+
         case ProcessUserModeIOPL:
 
             /* Only TCB can do this */
-            if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode)) 
+            if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
             {
-                /* Fail */
+                /* We don't hold the privilege, bail out */
                 DPRINT1("Need TCB to set IOPL\n");
                 Status = STATUS_PRIVILEGE_NOT_HELD;
                 break;
@@ -1863,7 +1907,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             /* Call Mm for the update */
             Status = MmSetExecuteOptions(NoExecute);
             break;
-                
+
         /* We currently don't implement any of these */
         case ProcessLdtInformation:
         case ProcessLdtSize:
@@ -1873,9 +1917,12 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
              break;
 
         case ProcessQuotaLimits:
-            DPRINT1("Quota Limits not implemented\n");
-            Status = STATUS_NOT_IMPLEMENTED;
-            break;
+
+            return PspSetQuotaLimits(ProcessHandle,
+                                     1,
+                                     ProcessInformation,
+                                     ProcessInformationLength,
+                                     PreviousMode);
 
         case ProcessWorkingSetWatch:
             DPRINT1("WS watch not implemented\n");
@@ -2319,7 +2366,7 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
 
             /* All done */
             break;
-            
+
         case ThreadBreakOnTermination:
 
             /* Check buffer length */
@@ -2346,6 +2393,7 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
             /* Setting 'break on termination' requires the SeDebugPrivilege */
             if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode))
             {
+                /* We don't hold the privilege, bail out */
                 Status = STATUS_PRIVILEGE_NOT_HELD;
                 break;
             }
@@ -2392,6 +2440,7 @@ NtQueryInformationThread(IN HANDLE ThreadHandle,
         (PTHREAD_BASIC_INFORMATION)ThreadInformation;
     PKERNEL_USER_TIMES ThreadTime = (PKERNEL_USER_TIMES)ThreadInformation;
     KIRQL OldIrql;
+    ULONG ThreadTerminated;
     PAGED_CODE();
 
     /* Check if we were called from user mode */
@@ -2641,6 +2690,31 @@ NtQueryInformationThread(IN HANDLE ThreadHandle,
             _SEH2_END;
             break;
 
+        case ThreadIsTerminated:
+
+            /* Set the return length*/
+            Length = sizeof(ThreadTerminated);
+
+            if (ThreadInformationLength != Length)
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
+            ThreadTerminated = PsIsThreadTerminating(Thread);
+
+            _SEH2_TRY
+            {
+                *(PULONG)ThreadInformation = ThreadTerminated ? 1 : 0;
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                Status = _SEH2_GetExceptionCode();
+            }
+            _SEH2_END;
+
+            break;
+
         /* Anything else */
         default: