[NTOSKRNL] Add a raw implementation of !irpfind in kdbg
[reactos.git] / ntoskrnl / ps / query.c
index b370191..1f605be 100644 (file)
@@ -14,9 +14,6 @@
 #define NDEBUG
 #include <debug.h>
 
-/* FIXME: From winbase.h... what to do? */
-#define SEM_NOALIGNMENTFAULTEXCEPT 0x04
-
 /* Debugging Level */
 ULONG PspTraceLevel = 0;
 
@@ -31,7 +28,10 @@ PsReferenceProcessFilePointer(IN PEPROCESS Process,
     PAGED_CODE();
 
     /* Lock the process */
-    ExAcquireRundownProtection(&Process->RundownProtect);
+    if (!ExAcquireRundownProtection(&Process->RundownProtect))
+    {
+        return STATUS_PROCESS_IS_TERMINATING;
+    }
 
     /* Get the section */
     Section = Process->SectionObject;
@@ -70,6 +70,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
     PPROCESS_BASIC_INFORMATION ProcessBasicInfo =
         (PPROCESS_BASIC_INFORMATION)ProcessInformation;
     PKERNEL_USER_TIMES ProcessTime = (PKERNEL_USER_TIMES)ProcessInformation;
+    ULONG UserTime, KernelTime;
     PPROCESS_PRIORITY_CLASS PsPriorityClass = (PPROCESS_PRIORITY_CLASS)ProcessInformation;
     ULONG HandleCount;
     PPROCESS_SESSION_INFORMATION SessionInfo =
@@ -81,6 +82,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
     PUNICODE_STRING ImageName;
     ULONG Cookie, ExecuteOptions = 0;
     ULONG_PTR Wow64 = 0;
+    PROCESS_VALUES ProcessValues;
     PAGED_CODE();
 
     /* Check for user-mode caller */
@@ -90,9 +92,9 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
         _SEH2_TRY
         {
             /* Probe the buffer */
-            ProbeForWrite(ProcessInformation,
-                          ProcessInformationLength,
-                          sizeof(ULONG));
+            ProbeForRead(ProcessInformation,
+                         ProcessInformationLength,
+                         sizeof(ULONG));
 
             /* Probe the return length if required */
             if (ReturnLength) ProbeForWriteUlong(ReturnLength);
@@ -110,8 +112,8 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
         (ProcessHandle != NtCurrentProcess()))
     {
         /*
-         * Retreiving the process cookie is only allowed for the calling process
-         * itself! XP only allowes NtCurrentProcess() as process handles even if
+         * Retrieving the process cookie is only allowed for the calling process
+         * itself! XP only allows NtCurrentProcess() as process handles even if
          * a real handle actually represents the current process.
          */
         return STATUS_INVALID_PARAMETER;
@@ -123,15 +125,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
         /* Basic process information */
         case ProcessBasicInformation:
 
-            /* Set return length */
-            Length = sizeof(PROCESS_BASIC_INFORMATION);
-
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(PROCESS_BASIC_INFORMATION))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            /* Set return length */
+            Length = sizeof(PROCESS_BASIC_INFORMATION);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -169,13 +171,14 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
         /* Process quota limits */
         case ProcessQuotaLimits:
 
-            Length = sizeof(QUOTA_LIMITS);
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(QUOTA_LIMITS))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            Length = sizeof(QUOTA_LIMITS);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -232,13 +235,14 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
 
         case ProcessIoCounters:
 
-            Length = sizeof(IO_COUNTERS);
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(IO_COUNTERS))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            Length = sizeof(IO_COUNTERS);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -248,15 +252,12 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                                                NULL);
             if (!NT_SUCCESS(Status)) break;
 
+            /* Query IO counters from the process */
+            KeQueryValuesProcess(&Process->Pcb, &ProcessValues);
+
             _SEH2_TRY
             {
-                /* FIXME: Call KeQueryValuesProcess */
-                IoCounters->ReadOperationCount = Process->ReadOperationCount.QuadPart;
-                IoCounters->ReadTransferCount = Process->ReadTransferCount.QuadPart;
-                IoCounters->WriteOperationCount = Process->WriteOperationCount.QuadPart;
-                IoCounters->WriteTransferCount = Process->WriteTransferCount.QuadPart;
-                IoCounters->OtherOperationCount = Process->OtherOperationCount.QuadPart;
-                IoCounters->OtherTransferCount = Process->OtherTransferCount.QuadPart;
+                RtlCopyMemory(IoCounters, &ProcessValues.IoInfo, sizeof(IO_COUNTERS));
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             {
@@ -275,14 +276,14 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
         case ProcessTimes:
 
             /* Set the return length */
-            Length = sizeof(KERNEL_USER_TIMES);
-
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(KERNEL_USER_TIMES))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            Length = sizeof(KERNEL_USER_TIMES);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -296,12 +297,10 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
             _SEH2_TRY
             {
                 /* Copy time information from EPROCESS/KPROCESS */
-                /* FIXME: Call KeQueryRuntimeProcess */
+                KernelTime = KeQueryRuntimeProcess(&Process->Pcb, &UserTime);
                 ProcessTime->CreateTime = Process->CreateTime;
-                ProcessTime->UserTime.QuadPart = Process->Pcb.UserTime *
-                                                 KeMaximumIncrement;
-                ProcessTime->KernelTime.QuadPart = Process->Pcb.KernelTime *
-                                                   KeMaximumIncrement;
+                ProcessTime->UserTime.QuadPart = (LONGLONG)UserTime * KeMaximumIncrement;
+                ProcessTime->KernelTime.QuadPart = (LONGLONG)KernelTime * KeMaximumIncrement;
                 ProcessTime->ExitTime = Process->ExitTime;
             }
             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@@ -318,15 +317,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
         /* Process Debug Port */
         case ProcessDebugPort:
 
-            /* Set return length */
-            Length = sizeof(HANDLE);
-
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(HANDLE))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            /* Set return length */
+            Length = sizeof(HANDLE);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -356,15 +355,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
 
         case ProcessHandleCount:
 
-            /* Set the return length*/
-            Length = sizeof(ULONG);
-
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(ULONG))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            /* Set the return length*/
+            Length = sizeof(ULONG);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -397,15 +396,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
         /* Session ID for the process */
         case ProcessSessionInformation:
 
-            /* Set the return length*/
-            Length = sizeof(PROCESS_SESSION_INFORMATION);
-
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            /* Set the return length*/
+            Length = sizeof(PROCESS_SESSION_INFORMATION);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -487,15 +486,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
         /* Hard Error Processing Mode */
         case ProcessDefaultHardErrorMode:
 
-            /* Set the return length*/
-            Length = sizeof(ULONG);
-
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(ULONG))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            /* Set the return length*/
+            Length = sizeof(ULONG);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -526,15 +525,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
         /* Priority Boosting status */
         case ProcessPriorityBoost:
 
-            /* Set the return length */
-            Length = sizeof(ULONG);
-
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(ULONG))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            /* Set the return length */
+            Length = sizeof(ULONG);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -565,10 +564,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
         /* DOS Device Map */
         case ProcessDeviceMap:
 
-            /* Set the return length */
-            Length = sizeof(PROCESS_DEVICEMAP_INFORMATION);
-
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != RTL_FIELD_SIZE(PROCESS_DEVICEMAP_INFORMATION, Query))
             {
                 if (ProcessInformationLength == sizeof(PROCESS_DEVICEMAP_INFORMATION_EX))
                 {
@@ -582,6 +578,9 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
                 break;
             }
 
+            /* Set the return length */
+            Length = sizeof(PROCESS_DEVICEMAP_INFORMATION);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -613,15 +612,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
         /* Priority class */
         case ProcessPriorityClass:
 
-            /* Set the return length*/
-            Length = sizeof(PROCESS_PRIORITY_CLASS);
-
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            /* Set the return length*/
+            Length = sizeof(PROCESS_PRIORITY_CLASS);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -705,14 +704,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
 
         case ProcessDebugFlags:
 
-            /* Set the return length*/
-            Length = sizeof(ULONG);
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(ULONG))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            /* Set the return length*/
+            Length = sizeof(ULONG);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -741,14 +741,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
 
         case ProcessBreakOnTermination:
 
-            /* Set the return length*/
-            Length = sizeof(ULONG);
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(ULONG))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            /* Set the return length */
+            Length = sizeof(ULONG);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -822,15 +823,16 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
 
         case ProcessImageInformation:
 
-            /* Set the length required and validate it */
-            Length = sizeof(SECTION_IMAGE_INFORMATION);
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(SECTION_IMAGE_INFORMATION))
             {
                 /* Break out */
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            /* Set the length required and validate it */
+            Length = sizeof(SECTION_IMAGE_INFORMATION);
+
             /* Enter SEH to protect write */
             _SEH2_TRY
             {
@@ -849,14 +851,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
 
         case ProcessDebugObjectHandle:
 
-            /* Set the return length */
-            Length = sizeof(HANDLE);
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(HANDLE))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            /* Set the return length */
+            Length = sizeof(HANDLE);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -893,14 +896,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
 
         case ProcessLUIDDeviceMapsEnabled:
 
-            /* Set the return length */
-            Length = sizeof(ULONG);
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(ULONG))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            /* Set the return length */
+            Length = sizeof(ULONG);
+
             /* Indicate success */
             Status = STATUS_SUCCESS;
 
@@ -920,14 +924,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
 
         case ProcessWx86Information:
 
-            /* Set the return length */
-            Length = sizeof(ULONG);
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(ULONG))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            /* Set the return length */
+            Length = sizeof(ULONG);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -956,14 +961,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
 
         case ProcessWow64Information:
 
-            /* Set return length */
-            Length = sizeof(ULONG_PTR);
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(ULONG_PTR))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            /* Set return length */
+            Length = sizeof(ULONG_PTR);
+
             /* Reference the process */
             Status = ObReferenceObjectByHandle(ProcessHandle,
                                                PROCESS_QUERY_INFORMATION,
@@ -1005,14 +1011,15 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
 
         case ProcessExecuteFlags:
 
-            /* Set return length */
-            Length = sizeof(ULONG);
-            if (ProcessInformationLength != Length)
+            if (ProcessInformationLength != sizeof(ULONG))
             {
                 Status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
 
+            /* Set return length */
+            Length = sizeof(ULONG);
+
             if (ProcessHandle != NtCurrentProcess())
             {
                 return STATUS_INVALID_PARAMETER;
@@ -1528,6 +1535,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             /* Validate the number */
             if ((BasePriority > HIGH_PRIORITY) || (BasePriority <= LOW_PRIORITY))
             {
+                ObDereferenceObject(Process);
                 return STATUS_INVALID_PARAMETER;
             }
 
@@ -1918,11 +1926,12 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
 
         case ProcessQuotaLimits:
 
-            return PspSetQuotaLimits(ProcessHandle,
+            Status = PspSetQuotaLimits(Process,
                                      1,
                                      ProcessInformation,
                                      ProcessInformationLength,
                                      PreviousMode);
+            break;
 
         case ProcessWorkingSetWatch:
             DPRINT1("WS watch not implemented\n");
@@ -2409,6 +2418,19 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
             }
             break;
 
+        case ThreadHideFromDebugger:
+
+            /* Check buffer length */
+            if (ThreadInformationLength != 0)
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+                break;
+            }
+
+            /* Set the flag */
+            PspSetCrossThreadFlag(Thread, CT_HIDE_FROM_DEBUGGER_BIT);
+            break;
+
         default:
             /* We don't implement it yet */
             DPRINT1("Not implemented: %d\n", ThreadInformationClass);