Sync to trunk head(r38096)
[reactos.git] / reactos / ntoskrnl / ex / sysinfo.c
index f650930..748d303 100644 (file)
@@ -236,7 +236,7 @@ NtQuerySystemEnvironmentValue (IN   PUNICODE_STRING VariableName,
 
   if(PreviousMode != KernelMode)
   {
-    _SEH_TRY
+    _SEH2_TRY
     {
       ProbeForRead(VariableName,
                    sizeof(UNICODE_STRING),
@@ -249,11 +249,11 @@ NtQuerySystemEnvironmentValue (IN PUNICODE_STRING VariableName,
         ProbeForWriteUlong(ReturnLength);
       }
     }
-    _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+    _SEH2_EXCEPT(ExSystemExceptionFilter())
     {
-      Status = _SEH_GetExceptionCode();
+      Status = _SEH2_GetExceptionCode();
     }
-    _SEH_END;
+    _SEH2_END;
 
     if(!NT_SUCCESS(Status))
     {
@@ -319,23 +319,23 @@ NtQuerySystemEnvironmentValue (IN PUNICODE_STRING VariableName,
      * Convert the result to UNICODE, protect with SEH in case the value buffer
      * isn't NULL-terminated!
      */
-    _SEH_TRY
+    _SEH2_TRY
     {
       RtlInitAnsiString(&AValue, Value);
       Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, TRUE);
     }
-    _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+    _SEH2_EXCEPT(ExSystemExceptionFilter())
     {
-      Status = _SEH_GetExceptionCode();
+      Status = _SEH2_GetExceptionCode();
     }
-    _SEH_END;
+    _SEH2_END;
 
     if(NT_SUCCESS(Status))
     {
       /*
        * Copy the result back to the caller.
        */
-      _SEH_TRY
+      _SEH2_TRY
       {
         RtlCopyMemory(ValueBuffer, WValue.Buffer, WValue.Length);
         ValueBuffer[WValue.Length / sizeof(WCHAR)] = L'\0';
@@ -346,11 +346,11 @@ NtQuerySystemEnvironmentValue (IN PUNICODE_STRING VariableName,
 
         Status = STATUS_SUCCESS;
       }
-      _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+      _SEH2_EXCEPT(ExSystemExceptionFilter())
       {
-        Status = _SEH_GetExceptionCode();
+        Status = _SEH2_GetExceptionCode();
       }
-      _SEH_END;
+      _SEH2_END;
     }
 
     /*
@@ -538,6 +538,7 @@ QSI_DEF(SystemProcessorInformation)
 /* Class 2 - Performance Information */
 QSI_DEF(SystemPerformanceInformation)
 {
+       ULONG IdleUser, IdleKernel;
        PSYSTEM_PERFORMANCE_INFORMATION Spi
                = (PSYSTEM_PERFORMANCE_INFORMATION) Buffer;
 
@@ -554,8 +555,8 @@ QSI_DEF(SystemPerformanceInformation)
 
        TheIdleProcess = PsIdleProcess;
 
-       Spi->IdleProcessTime.QuadPart = TheIdleProcess->Pcb.KernelTime * 100000LL;
-
+       IdleKernel = KeQueryRuntimeProcess(&TheIdleProcess->Pcb, &IdleUser);
+       Spi->IdleProcessTime.QuadPart = UInt32x32To64(IdleKernel, KeMaximumIncrement);
        Spi->IoReadTransferCount = IoReadTransferCount;
        Spi->IoWriteTransferCount = IoWriteTransferCount;
        Spi->IoOtherTransferCount = IoOtherTransferCount;
@@ -699,10 +700,11 @@ QSI_DEF(SystemProcessInformation)
 {
        ULONG ovlSize = 0, nThreads;
        PEPROCESS pr = NULL, syspr;
-       unsigned char *pCur;
+       PUCHAR pCur;
+       ULONG TotalUser, TotalKernel;
        NTSTATUS Status = STATUS_SUCCESS;
 
-       _SEH_TRY
+       _SEH2_TRY
        {
                /* scan the process list */
 
@@ -713,7 +715,7 @@ QSI_DEF(SystemProcessInformation)
 
                if (Size < sizeof(SYSTEM_PROCESS_INFORMATION))
                {
-                       _SEH_YIELD(return STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
+                       _SEH2_YIELD(return STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
                }
                RtlZeroMemory(Spi, Size);
 
@@ -750,15 +752,13 @@ QSI_DEF(SystemProcessInformation)
                                *ReqSize = ovlSize;
                                ObDereferenceObject(pr);
 
-                               _SEH_YIELD(return STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
+                               _SEH2_YIELD(return STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
                        }
 
                        // fill system information
                        SpiCur->NextEntryOffset = curSize+inLen; // relative offset to the beginnnig of the next structure
                        SpiCur->NumberOfThreads = nThreads;
                        SpiCur->CreateTime = pr->CreateTime;
-                       SpiCur->UserTime.QuadPart = pr->Pcb.UserTime * 100000LL;
-                       SpiCur->KernelTime.QuadPart = pr->Pcb.KernelTime * 100000LL;
                        SpiCur->ImageName.Length = strlen(pr->ImageFileName) * sizeof(WCHAR);
                        SpiCur->ImageName.MaximumLength = (USHORT)inLen;
                        SpiCur->ImageName.Buffer = (void*)(pCur+curSize);
@@ -798,8 +798,8 @@ QSI_DEF(SystemProcessInformation)
                                current = CONTAINING_RECORD(current_entry, ETHREAD,
                                                            ThreadListEntry);
 
-                               ThreadInfo->KernelTime.QuadPart = current->Tcb.KernelTime * 100000LL;
-                               ThreadInfo->UserTime.QuadPart = current->Tcb.UserTime * 100000LL;
+                               ThreadInfo->KernelTime.QuadPart = UInt32x32To64(current->Tcb.KernelTime, KeMaximumIncrement);
+                               ThreadInfo->UserTime.QuadPart = UInt32x32To64(current->Tcb.UserTime, KeMaximumIncrement);
                                ThreadInfo->CreateTime.QuadPart = current->CreateTime.QuadPart;
                                ThreadInfo->WaitTime = current->Tcb.WaitTime;
                                ThreadInfo->StartAddress = (PVOID) current->StartAddress;
@@ -809,10 +809,16 @@ QSI_DEF(SystemProcessInformation)
                                ThreadInfo->ContextSwitches = current->Tcb.ContextSwitches;
                                ThreadInfo->ThreadState = current->Tcb.State;
                                ThreadInfo->WaitReason = current->Tcb.WaitReason;
+
                                ThreadInfo++;
                                current_entry = current_entry->Flink;
                        }
 
+                       /* Query total user/kernel times of a process */
+                       TotalKernel = KeQueryRuntimeProcess(&pr->Pcb, &TotalUser);
+                       SpiCur->UserTime.QuadPart = UInt32x32To64(TotalUser, KeMaximumIncrement);
+                       SpiCur->KernelTime.QuadPart = UInt32x32To64(TotalKernel, KeMaximumIncrement);
+
                        /* Handle idle process entry */
                        if (pr == PsIdleProcess) pr = NULL;
 
@@ -831,13 +837,13 @@ QSI_DEF(SystemProcessInformation)
                        ObDereferenceObject(pr);
                Status = STATUS_SUCCESS;
        }
-       _SEH_HANDLE
+       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
                if(pr != NULL)
                        ObDereferenceObject(pr);
-               Status = _SEH_GetExceptionCode();
+               Status = _SEH2_GetExceptionCode();
        }
-       _SEH_END
+       _SEH2_END
 
        *ReqSize = ovlSize;
        return Status;
@@ -882,37 +888,39 @@ QSI_DEF(SystemDeviceInformation)
 /* Class 8 - Processor Performance Information */
 QSI_DEF(SystemProcessorPerformanceInformation)
 {
-       PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION Spi
-               = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) Buffer;
+    PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION Spi
+        = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) Buffer;
 
-        LONG i;
-       LARGE_INTEGER CurrentTime;
-       PKPRCB Prcb;
+    LONG i;
+    ULONG TotalTime;
+    LARGE_INTEGER CurrentTime;
+    PKPRCB Prcb;
 
-       *ReqSize = KeNumberProcessors * sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
-       /*
-        * Check user buffer's size
-        */
-       if (Size < KeNumberProcessors * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION))
-       {
-               return (STATUS_INFO_LENGTH_MISMATCH);
-       }
+    *ReqSize = KeNumberProcessors * sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
 
-       CurrentTime.QuadPart = KeQueryInterruptTime();
-       Prcb = KeGetPcr()->Prcb;
-       for (i = 0; i < KeNumberProcessors; i++)
-       {
-          Spi->IdleTime.QuadPart = (Prcb->IdleThread->KernelTime + Prcb->IdleThread->UserTime) * 100000LL;
-           Spi->KernelTime.QuadPart =  Prcb->KernelTime * 100000LL;
-           Spi->UserTime.QuadPart = Prcb->UserTime * 100000LL;
-           Spi->DpcTime.QuadPart = Prcb->DpcTime * 100000LL;
-           Spi->InterruptTime.QuadPart = Prcb->InterruptTime * 100000LL;
-           Spi->InterruptCount = Prcb->InterruptCount;
-          Spi++;
-          Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
-       }
+    /* Check user buffer's size */
+    if (Size < *ReqSize)
+    {
+        return STATUS_INFO_LENGTH_MISMATCH;
+    }
 
-       return (STATUS_SUCCESS);
+    CurrentTime.QuadPart = KeQueryInterruptTime();
+    Prcb = KeGetPcr()->Prcb;
+    for (i = 0; i < KeNumberProcessors; i++)
+    {
+        /* Calculate total user and kernel times */
+        TotalTime = Prcb->IdleThread->KernelTime + Prcb->IdleThread->UserTime;
+        Spi->IdleTime.QuadPart = UInt32x32To64(TotalTime, KeMaximumIncrement);
+        Spi->KernelTime.QuadPart =  UInt32x32To64(Prcb->KernelTime, KeMaximumIncrement);
+        Spi->UserTime.QuadPart = UInt32x32To64(Prcb->UserTime, KeMaximumIncrement);
+        Spi->DpcTime.QuadPart = UInt32x32To64(Prcb->DpcTime, KeMaximumIncrement);
+        Spi->InterruptTime.QuadPart = UInt32x32To64(Prcb->InterruptTime, KeMaximumIncrement);
+        Spi->InterruptCount = Prcb->InterruptCount;
+        Spi++;
+        Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
+    }
+
+    return STATUS_SUCCESS;
 }
 
 /* Class 9 - Flags Information */
@@ -1055,7 +1063,7 @@ QSI_DEF(SystemHandleInformation)
 
             for (Count = 0; HandleCount > 0 ; HandleCount--)
                {
-                 Shi->Handles[i].UniqueProcessId = (USHORT)(ULONG)pr->UniqueProcessId;
+                 Shi->Handles[i].UniqueProcessId = (USHORT)(ULONG_PTR)pr->UniqueProcessId;
                  Count++;
                  i++;
                }
@@ -1195,11 +1203,15 @@ QSI_DEF(SystemInterruptInformation)
   for (i = 0; i < KeNumberProcessors; i++)
   {
     Prcb = KiProcessorBlock[i];
+#ifdef _M_AMD64
+    Pcr = CONTAINING_RECORD(Prcb, KPCR, CurrentPrcb);
+#else
     Pcr = CONTAINING_RECORD(Prcb, KPCR, Prcb);
+#endif
 #ifdef _M_ARM // This code should probably be done differently
     sii->ContextSwitches = Pcr->ContextSwitches;
 #else
-    sii->ContextSwitches = ((PKIPCR)Pcr)->ContextSwitches;      
+    sii->ContextSwitches = ((PKIPCR)Pcr)->ContextSwitches;
 #endif
     sii->DpcCount = Prcb->DpcData[0].DpcCount;
     sii->DpcRate = Prcb->DpcRequestRate;
@@ -1266,6 +1278,7 @@ SSI_DEF(SystemLoadGdiDriverInformation)
     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
     UNICODE_STRING ImageName;
     PVOID ImageBase;
+    PLDR_DATA_TABLE_ENTRY ModuleObject;
     ULONG_PTR EntryPoint;
     NTSTATUS Status;
     ULONG DirSize;
@@ -1287,7 +1300,7 @@ SSI_DEF(SystemLoadGdiDriverInformation)
                                NULL,
                                NULL,
                                0,
-                               NULL,
+                               (PVOID)&ModuleObject,
                                &ImageBase);
     if (!NT_SUCCESS(Status)) return Status;
 
@@ -1315,25 +1328,25 @@ SSI_DEF(SystemLoadGdiDriverInformation)
 
 /* Class 27 - Unload Image */
 SSI_DEF(SystemUnloadGdiDriverInformation)
-{  
+{
     PLDR_DATA_TABLE_ENTRY LdrEntry;
     PLIST_ENTRY NextEntry;
     PVOID BaseAddr = *((PVOID*)Buffer);
-     
-    if(Size != sizeof(PVOID)) 
+
+    if(Size != sizeof(PVOID))
         return STATUS_INFO_LENGTH_MISMATCH;
-   
-    if(KeGetPreviousMode() != KernelMode) 
+
+    if(KeGetPreviousMode() != KernelMode)
         return STATUS_PRIVILEGE_NOT_HELD;
-    
-    // Scan the module list 
+
+    // Scan the module list
     NextEntry = PsLoadedModuleList.Flink;
     while(NextEntry != &PsLoadedModuleList)
     {
         LdrEntry = CONTAINING_RECORD(NextEntry,
                                      LDR_DATA_TABLE_ENTRY,
                                      InLoadOrderLinks);
-        
+
         if (LdrEntry->DllBase == BaseAddr)
         {
             // Found it.
@@ -1353,7 +1366,7 @@ SSI_DEF(SystemUnloadGdiDriverInformation)
         DPRINT1("Image 0x%x not found.\n", BaseAddr);
         return STATUS_DLL_NOT_FOUND;
     }
-    
+
 }
 
 /* Class 28 - Time Adjustment Information */
@@ -1793,6 +1806,9 @@ CallQS [] =
        SI_QX(SystemSessionProcessesInformation)
 };
 
+C_ASSERT(SystemBasicInformation == 0);
+#define MIN_SYSTEM_INFO_CLASS (SystemBasicInformation)
+#define MAX_SYSTEM_INFO_CLASS (sizeof(CallQS) / sizeof(CallQS[0]))
 
 /*
  * @implemented
@@ -1808,15 +1824,15 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
   NTSTATUS FStatus = STATUS_NOT_IMPLEMENTED;
 
   PAGED_CODE();
-  
+
   PreviousMode = ExGetPreviousMode();
-  
-  _SEH_TRY
+
+  _SEH2_TRY
     {
       if (PreviousMode != KernelMode)
         {
           /* SystemKernelDebuggerInformation needs only BOOLEAN alignment */
-          ProbeForWrite(SystemInformation, Length, 1); 
+          ProbeForWrite(SystemInformation, Length, 1);
           if (UnsafeResultLength != NULL)
             ProbeForWriteUlong(UnsafeResultLength);
         }
@@ -1824,9 +1840,9 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
       /*
        * Check the request is valid.
        */
-      if (SystemInformationClass >= MaxSystemInfoClass)
+      if (SystemInformationClass >= MAX_SYSTEM_INFO_CLASS)
         {
-          _SEH_YIELD(return STATUS_INVALID_INFO_CLASS);
+          _SEH2_YIELD(return STATUS_INVALID_INFO_CLASS);
         }
 
       if (NULL != CallQS [SystemInformationClass].Query)
@@ -1850,11 +1866,11 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
            }
        }
     }
-  _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
+  _SEH2_EXCEPT(ExSystemExceptionFilter())
     {
-      FStatus = _SEH_GetExceptionCode();
+      FStatus = _SEH2_GetExceptionCode();
     }
-  _SEH_END;
+  _SEH2_END;
 
   return (FStatus);
 }
@@ -1891,8 +1907,8 @@ NtSetSystemInformation (
        /*
         * Check the request is valid.
         */
-       if (    (SystemInformationClass >= SystemBasicInformation)
-               && (SystemInformationClass < MaxSystemInfoClass)
+       if (    (SystemInformationClass >= MIN_SYSTEM_INFO_CLASS)
+               && (SystemInformationClass < MAX_SYSTEM_INFO_CLASS)
                )
        {
                if (NULL != CallQS [SystemInformationClass].Set)
@@ -1929,6 +1945,9 @@ NtFlushInstructionCache (
     for (;;);
 #elif defined(_M_ARM)
     __asm__ __volatile__("mov r1, #0; mcr p15, 0, r1, c7, c5, 0");
+#elif defined(_M_AMD64)
+    DPRINT1("NtFlushInstructionCache() is not implemented\n");
+    for (;;);
 #else
 #error Unknown architecture
 #endif
@@ -1943,4 +1962,4 @@ NtGetCurrentProcessorNumber(VOID)
     return KeGetCurrentProcessorNumber();
 }
 
-/* EOF */
+/* EOF */
\ No newline at end of file