Sync to trunk head(r38096)
[reactos.git] / reactos / ntoskrnl / ex / sysinfo.c
index cd609fe..748d303 100644 (file)
@@ -1,23 +1,18 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/sysinfo.c
  * PURPOSE:         System information functions
  *
  * PROGRAMMERS:     David Welch (welch@mcmail.com)
- *                  Aleksey Bragin (aleksey@studiocerebral.com)
+ *                  Aleksey Bragin (aleksey@reactos.org)
  */
 
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
 #define NDEBUG
-#include <internal/debug.h>
-
-extern PEPROCESS PsIdleProcess;
-extern ULONG NtGlobalFlag; /* FIXME: it should go in a ddk/?.h */
-ULONGLONG STDCALL KeQueryInterruptTime(VOID);
+#include <debug.h>
 
 VOID MmPrintMemoryStatistic(VOID);
 
@@ -159,10 +154,8 @@ ExGetPreviousMode (VOID)
  * @implemented
  */
 VOID
-STDCALL
-ExGetCurrentProcessorCpuUsage (
-       PULONG  CpuUsage
-       )
+NTAPI
+ExGetCurrentProcessorCpuUsage(PULONG CpuUsage)
 {
        PKPRCB Prcb;
        ULONG TotalTime;
@@ -182,12 +175,10 @@ ExGetCurrentProcessorCpuUsage (
  * @implemented
  */
 VOID
-STDCALL
-ExGetCurrentProcessorCounts (
-       PULONG  ThreadKernelTime,
-       PULONG  TotalCpuTime,
-       PULONG  ProcessorNumber
-       )
+NTAPI
+ExGetCurrentProcessorCounts(PULONG ThreadKernelTime,
+                            PULONG TotalCpuTime,
+                            PULONG ProcessorNumber)
 {
        PKPRCB Prcb;
 
@@ -202,7 +193,7 @@ ExGetCurrentProcessorCounts (
  * @implemented
  */
 BOOLEAN
-STDCALL
+NTAPI
 ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature)
 {
     /* Quick check to see if it exists at all */
@@ -216,14 +207,15 @@ ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature)
  * @implemented
  */
 BOOLEAN
-STDCALL
+NTAPI
 ExVerifySuite(SUITE_TYPE SuiteType)
 {
     if (SuiteType == Personal) return TRUE;
     return FALSE;
 }
 
-NTSTATUS STDCALL
+NTSTATUS
+NTAPI
 NtQuerySystemEnvironmentValue (IN      PUNICODE_STRING VariableName,
                               OUT      PWSTR           ValueBuffer,
                               IN       ULONG           ValueBufferLength,
@@ -244,7 +236,7 @@ NtQuerySystemEnvironmentValue (IN   PUNICODE_STRING VariableName,
 
   if(PreviousMode != KernelMode)
   {
-    _SEH_TRY
+    _SEH2_TRY
     {
       ProbeForRead(VariableName,
                    sizeof(UNICODE_STRING),
@@ -257,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))
     {
@@ -327,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';
@@ -354,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;
     }
 
     /*
@@ -372,7 +364,7 @@ NtQuerySystemEnvironmentValue (IN   PUNICODE_STRING VariableName,
 }
 
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 NtSetSystemEnvironmentValue (IN        PUNICODE_STRING VariableName,
                             IN PUNICODE_STRING Value)
 {
@@ -501,6 +493,7 @@ QSI_DEF(SystemBasicInformation)
        {
                return (STATUS_INFO_LENGTH_MISMATCH);
        }
+       RtlZeroMemory(Sbi, Size);
        Sbi->Reserved = 0;
        Sbi->TimerResolution = KeMaximumIncrement;
        Sbi->PageSize = PAGE_SIZE;
@@ -530,11 +523,11 @@ QSI_DEF(SystemProcessorInformation)
                return (STATUS_INFO_LENGTH_MISMATCH);
        }
        Prcb = KeGetCurrentPrcb();
-       Spi->ProcessorArchitecture = 0; /* Intel Processor */
-       Spi->ProcessorLevel        = Prcb->CpuType;
-       Spi->ProcessorRevision     = Prcb->CpuStep;
+       Spi->ProcessorArchitecture = KeProcessorArchitecture;
+       Spi->ProcessorLevel        = KeProcessorLevel;
+       Spi->ProcessorRevision     = KeProcessorRevision;
        Spi->Reserved              = 0;
-       Spi->ProcessorFeatureBits          = Prcb->FeatureBits;
+       Spi->ProcessorFeatureBits          = KeFeatureBits;
 
        DPRINT("Arch %d Level %d Rev 0x%x\n", Spi->ProcessorArchitecture,
                Spi->ProcessorLevel, Spi->ProcessorRevision);
@@ -545,6 +538,7 @@ QSI_DEF(SystemProcessorInformation)
 /* Class 2 - Performance Information */
 QSI_DEF(SystemPerformanceInformation)
 {
+       ULONG IdleUser, IdleKernel;
        PSYSTEM_PERFORMANCE_INFORMATION Spi
                = (PSYSTEM_PERFORMANCE_INFORMATION) Buffer;
 
@@ -561,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;
@@ -572,7 +566,7 @@ QSI_DEF(SystemPerformanceInformation)
 
        Spi->AvailablePages = MmStats.NrFreePages;
 /*
-        Add up all the used "Commitied" memory + pagefile.
+        Add up all the used "Committed" memory + pagefile.
         Not sure this is right. 8^\
  */
        Spi->CommittedPages = MiMemoryConsumers[MC_PPOOL].PagesUsed +
@@ -706,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 */
 
@@ -720,10 +715,11 @@ 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);
 
-               syspr = PsGetNextProcess(NULL);
+               syspr = PsIdleProcess;
                pr = syspr;
                pCur = (unsigned char *)Spi;
 
@@ -756,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);
@@ -804,9 +798,9 @@ QSI_DEF(SystemProcessInformation)
                                current = CONTAINING_RECORD(current_entry, ETHREAD,
                                                            ThreadListEntry);
 
-                               ThreadInfo->KernelTime.QuadPart = current->Tcb.KernelTime * 100000LL;
-                               ThreadInfo->UserTime.QuadPart = current->Tcb.UserTime * 100000LL;
-//                             SpiCur->TH[i].CreateTime = current->CreateTime;
+                               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;
                                ThreadInfo->ClientId = current->Cid;
@@ -815,10 +809,19 @@ 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;
+
                        pr = PsGetNextProcess(pr);
                        nThreads = 0;
                        if ((pr == syspr) || (pr == NULL))
@@ -834,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;
@@ -885,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 = ((PKPCR)KPCR_BASE)->Prcb;
-       for (i = 0; i < KeNumberProcessors; i++)
-       {
-          Spi->IdleTime.QuadPart = (Prcb->IdleThread->KernelTime + Prcb->IdleThread->UserTime) * 100000LL; // IdleTime
-           Spi->KernelTime.QuadPart =  Prcb->KernelTime * 100000LL; // KernelTime
-           Spi->UserTime.QuadPart = Prcb->UserTime * 100000LL;
-           Spi->DpcTime.QuadPart = Prcb->DpcTime * 100000LL;
-           Spi->InterruptTime.QuadPart = Prcb->InterruptTime * 100000LL;
-           Spi->InterruptCount = Prcb->InterruptCount; // Interrupt Count
-          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 */
@@ -1058,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++;
                }
@@ -1183,6 +1188,7 @@ QSI_DEF(SystemPoolTagInformation)
 QSI_DEF(SystemInterruptInformation)
 {
   PKPRCB Prcb;
+  PKPCR Pcr;
   LONG i;
   ULONG ti;
   PSYSTEM_INTERRUPT_INFORMATION sii = (PSYSTEM_INTERRUPT_INFORMATION)Buffer;
@@ -1194,17 +1200,25 @@ QSI_DEF(SystemInterruptInformation)
 
   ti = KeQueryTimeIncrement();
 
-  Prcb = ((PKPCR)KPCR_BASE)->Prcb;
   for (i = 0; i < KeNumberProcessors; i++)
   {
-    //sii->ContextSwitches = Prcb->KeContextSwitches;
-    sii->DpcCount = 0; /* FIXME */
-    sii->DpcRate = 0; /* FIXME */
+    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;
+#endif
+    sii->DpcCount = Prcb->DpcData[0].DpcCount;
+    sii->DpcRate = Prcb->DpcRequestRate;
     sii->TimeIncrement = ti;
-    sii->DpcBypassCount = 0; /* FIXME */
-    sii->ApcBypassCount = 0; /* FIXME */
+    sii->DpcBypassCount = 0;
+    sii->ApcBypassCount = 0;
     sii++;
-    Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
   }
 
   return STATUS_SUCCESS;
@@ -1264,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;
@@ -1285,7 +1300,7 @@ SSI_DEF(SystemLoadGdiDriverInformation)
                                NULL,
                                NULL,
                                0,
-                               NULL,
+                               (PVOID)&ModuleObject,
                                &ImageBase);
     if (!NT_SUCCESS(Status)) return Status;
 
@@ -1313,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.
@@ -1351,7 +1366,7 @@ SSI_DEF(SystemUnloadGdiDriverInformation)
         DPRINT1("Image 0x%x not found.\n", BaseAddr);
         return STATUS_DLL_NOT_FOUND;
     }
-    
+
 }
 
 /* Class 28 - Time Adjustment Information */
@@ -1791,11 +1806,14 @@ 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
  */
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
                          OUT PVOID SystemInformation,
                          IN ULONG Length,
@@ -1806,28 +1824,25 @@ 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);
         }
 
-      /* Clear user buffer. */
-      RtlZeroMemory(SystemInformation, Length);
-
       /*
        * 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)
@@ -1842,15 +1857,7 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
            {
               if (PreviousMode != KernelMode)
                 {
-                  _SEH_TRY
-                    {
                       *UnsafeResultLength = ResultLength;
-                    }
-                  _SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
-                    {
-                      FStatus = _SEH_GetExceptionCode();
-                    }
-                  _SEH_END;
                 }
               else
                 {
@@ -1859,18 +1866,18 @@ 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);
 }
 
 
 NTSTATUS
-STDCALL
+NTAPI
 NtSetSystemInformation (
        IN      SYSTEM_INFORMATION_CLASS        SystemInformationClass,
        IN      PVOID                           SystemInformation,
@@ -1900,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)
@@ -1920,7 +1927,7 @@ NtSetSystemInformation (
 
 
 NTSTATUS
-STDCALL
+NTAPI
 NtFlushInstructionCache (
        IN      HANDLE  ProcessHandle,
        IN      PVOID   BaseAddress,
@@ -1932,10 +1939,15 @@ NtFlushInstructionCache (
 #if defined(_M_IX86)
     __wbinvd();
 #elif defined(_M_PPC)
-#error Needs to be implemented for PPC architecture!
+    __asm__ __volatile__("tlbsync");
 #elif defined(_M_MIPS)
     DPRINT1("NtFlushInstructionCache() is not implemented\n");
     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
@@ -1950,4 +1962,4 @@ NtGetCurrentProcessorNumber(VOID)
     return KeGetCurrentProcessorNumber();
 }
 
-/* EOF */
+/* EOF */
\ No newline at end of file