fix uninitialized variable
[reactos.git] / reactos / ntoskrnl / ex / sysinfo.c
index 7f391db..4546b75 100644 (file)
@@ -4,12 +4,9 @@
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/sysinfo.c
  * PURPOSE:         System information functions
- * PROGRAMMER:      David Welch (welch@mcmail.com)
- * UPDATE HISTORY:
- *                  Created 22/05/98
- *                  20/03/2003: implemented querying SystemProcessInformation,
- *                              no more copying to-from the caller (Aleksey
- *                              Bragin <aleksey@studiocerebral.com>)
+ * 
+ * PROGRAMMERS:     David Welch (welch@mcmail.com)
+ *                  Aleksey Bragin (aleksey@studiocerebral.com)
  */
 
 /* INCLUDES *****************************************************************/
@@ -18,6 +15,7 @@
 #define NDEBUG
 #include <internal/debug.h>
 
+extern PEPROCESS PsIdleProcess;
 extern ULONG NtGlobalFlag; /* FIXME: it should go in a ddk/?.h */
 ULONGLONG STDCALL KeQueryInterruptTime(VOID);
 
@@ -49,17 +47,18 @@ ExGetCurrentProcessorCpuUsage (
        PULONG  CpuUsage
        )
 {
-       PKPCR Pcr;
+       PKPRCB Prcb;
        ULONG TotalTime;
-       ULONG PercentTime = 0;
        ULONGLONG ScaledIdle;
 
-       Pcr = KeGetCurrentKPCR();
+       Prcb = KeGetCurrentPrcb();
 
-       ScaledIdle = Pcr->PrcbData.IdleThread->KernelTime * 100;
-       TotalTime = Pcr->PrcbData.KernelTime + Pcr->PrcbData.UserTime;
-       if (TotalTime) PercentTime = 100 - (ScaledIdle / TotalTime);
-       CpuUsage = &PercentTime;
+       ScaledIdle = Prcb->IdleThread->KernelTime * 100;
+       TotalTime = Prcb->KernelTime + Prcb->UserTime;
+       if (TotalTime != 0)
+               *CpuUsage = 100 - (ScaledIdle / TotalTime);
+       else
+               *CpuUsage = 0;
 }
 
 /*
@@ -73,20 +72,27 @@ ExGetCurrentProcessorCounts (
        PULONG  ProcessorNumber
        )
 {
-       PKPCR Pcr;
-       ULONG TotalTime;
-       ULONG ThreadTime;
-       ULONG ProcNumber;
+       PKPRCB Prcb;
+
+       Prcb = KeGetCurrentPrcb();
 
-       Pcr = KeGetCurrentKPCR();
+       *ThreadKernelTime = Prcb->KernelTime + Prcb->UserTime;
+       *TotalCpuTime = Prcb->CurrentThread->KernelTime;
+       *ProcessorNumber = KeGetCurrentKPCR()->ProcessorNumber;
+}
 
-       TotalTime = Pcr->PrcbData.KernelTime + Pcr->PrcbData.UserTime;
-       ThreadTime = Pcr->PrcbData.CurrentThread->KernelTime;
-       ProcNumber = Pcr->ProcessorNumber;
+/*
+ * @implemented
+ */
+BOOLEAN 
+STDCALL
+ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature)
+{
+    /* Quick check to see if it exists at all */
+    if (ProcessorFeature >= PROCESSOR_FEATURE_MAX) return(FALSE);
 
-       ThreadKernelTime = &ThreadTime;
-       TotalCpuTime = &TotalTime;
-       ProcessorNumber = &ProcNumber;
+    /* Return our support for it */
+    return(SharedUserData->ProcessorFeatures[ProcessorFeature]);
 }
 
 NTSTATUS STDCALL
@@ -104,6 +110,8 @@ NtQuerySystemEnvironmentValue (IN   PUNICODE_STRING VariableName,
   KPROCESSOR_MODE PreviousMode;
   NTSTATUS Status = STATUS_SUCCESS;
   
+  PAGED_CODE();
+  
   PreviousMode = ExGetPreviousMode();
   
   if(PreviousMode != KernelMode)
@@ -154,6 +162,7 @@ NtQuerySystemEnvironmentValue (IN   PUNICODE_STRING VariableName,
       RtlReleaseCapturedUnicodeString(&WName,
                                      PreviousMode,
                                      FALSE);
+      DPRINT1("NtQuerySystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
       return STATUS_PRIVILEGE_NOT_HELD;
     }
     
@@ -247,6 +256,8 @@ NtSetSystemEnvironmentValue (IN     PUNICODE_STRING VariableName,
   ANSI_STRING AName, AValue;
   KPROCESSOR_MODE PreviousMode;
   NTSTATUS Status;
+  
+  PAGED_CODE();
 
   PreviousMode = ExGetPreviousMode();
   
@@ -295,6 +306,7 @@ NtSetSystemEnvironmentValue (IN     PUNICODE_STRING VariableName,
       }
       else
       {
+        DPRINT1("NtSetSystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
         Status = STATUS_PRIVILEGE_NOT_HELD;
       }
       
@@ -360,7 +372,7 @@ QSI_DEF(SystemProcessorInformation)
 {
        PSYSTEM_PROCESSOR_INFORMATION Spi 
                = (PSYSTEM_PROCESSOR_INFORMATION) Buffer;
-       PKPCR Pcr;
+       PKPRCB Prcb;
        *ReqSize = sizeof (SYSTEM_PROCESSOR_INFORMATION);
        /*
         * Check user buffer's size 
@@ -369,12 +381,12 @@ QSI_DEF(SystemProcessorInformation)
        {
                return (STATUS_INFO_LENGTH_MISMATCH);
        }
-       Pcr = KeGetCurrentKPCR();
+       Prcb = KeGetCurrentPrcb();
        Spi->ProcessorArchitecture = 0; /* Intel Processor */
-       Spi->ProcessorLevel        = Pcr->PrcbData.CpuType;
-       Spi->ProcessorRevision     = Pcr->PrcbData.CpuStep;
+       Spi->ProcessorLevel        = Prcb->CpuType;
+       Spi->ProcessorRevision     = Prcb->CpuStep;
        Spi->Unknown               = 0;
-       Spi->FeatureBits           = Pcr->PrcbData.FeatureBits;
+       Spi->FeatureBits           = Prcb->FeatureBits;
 
        DPRINT("Arch %d Level %d Rev 0x%x\n", Spi->ProcessorArchitecture,
                Spi->ProcessorLevel, Spi->ProcessorRevision);
@@ -399,7 +411,7 @@ QSI_DEF(SystemPerformanceInformation)
                return (STATUS_INFO_LENGTH_MISMATCH);
        }
        
-       PsLookupProcessByProcessId((PVOID) 1, &TheIdleProcess);
+       TheIdleProcess = PsIdleProcess;
        
        Spi->IdleTime.QuadPart = TheIdleProcess->Pcb.KernelTime * 100000LL;
 
@@ -503,8 +515,6 @@ QSI_DEF(SystemPerformanceInformation)
        Spi->SecondLevelTbFills = 0; /* FIXME */
        Spi->SystemCalls = 0; /* FIXME */
 
-       ObDereferenceObject(TheIdleProcess);
-
        return (STATUS_SUCCESS);
 }
 
@@ -552,12 +562,12 @@ QSI_DEF(SystemProcessInformation)
 
        /* scan the process list */
 
-       PSYSTEM_PROCESSES Spi
-               = (PSYSTEM_PROCESSES) Buffer;
+       PSYSTEM_PROCESS_INFORMATION Spi
+               = (PSYSTEM_PROCESS_INFORMATION) Buffer;
 
-       *ReqSize = sizeof(SYSTEM_PROCESSES);
+       *ReqSize = sizeof(SYSTEM_PROCESS_INFORMATION);
 
-       if (Size < sizeof(SYSTEM_PROCESSES))
+       if (Size < sizeof(SYSTEM_PROCESS_INFORMATION))
        {
                return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
        }
@@ -568,19 +578,25 @@ QSI_DEF(SystemProcessInformation)
 
        do
        {
-               PSYSTEM_PROCESSES SpiCur;
+               PSYSTEM_PROCESS_INFORMATION SpiCur;
                int curSize, i = 0;
                ANSI_STRING     imgName;
                int inLen=32; // image name len in bytes
                PLIST_ENTRY current_entry;
                PETHREAD current;
 
-               SpiCur = (PSYSTEM_PROCESSES)pCur;
+               SpiCur = (PSYSTEM_PROCESS_INFORMATION)pCur;
+
+               nThreads = 0;
+               current_entry = pr->ThreadListHead.Flink;
+               while (current_entry != &pr->ThreadListHead)
+               {
+                       nThreads++;
+                       current_entry = current_entry->Flink;
+               }
 
-               nThreads = PsEnumThreadsByProcess(pr);
-               
                // size of the structure for every process
-               curSize = sizeof(SYSTEM_PROCESSES)-sizeof(SYSTEM_THREADS)+sizeof(SYSTEM_THREADS)*nThreads;
+               curSize = sizeof(SYSTEM_PROCESS_INFORMATION)-sizeof(SYSTEM_THREAD_INFORMATION)+sizeof(SYSTEM_THREAD_INFORMATION)*nThreads;
                ovlSize += curSize+inLen;
 
                if (ovlSize > Size)
@@ -592,38 +608,45 @@ QSI_DEF(SystemProcessInformation)
                }
 
                // fill system information
-               SpiCur->NextEntryDelta = curSize+inLen; // relative offset to the beginnnig of the next structure
-               SpiCur->ThreadCount = nThreads;
+               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->ProcessName.Length = strlen(pr->ImageFileName) * sizeof(WCHAR);
-               SpiCur->ProcessName.MaximumLength = inLen;
-               SpiCur->ProcessName.Buffer = (void*)(pCur+curSize);
+               SpiCur->ImageName.Length = strlen(pr->ImageFileName) * sizeof(WCHAR);
+               SpiCur->ImageName.MaximumLength = inLen;
+               SpiCur->ImageName.Buffer = (void*)(pCur+curSize);
 
                // copy name to the end of the struct
-               RtlInitAnsiString(&imgName, pr->ImageFileName);
-               RtlAnsiStringToUnicodeString(&SpiCur->ProcessName, &imgName, FALSE);
+               if(pr != PsIdleProcess)
+               {
+                 RtlInitAnsiString(&imgName, pr->ImageFileName);
+                 RtlAnsiStringToUnicodeString(&SpiCur->ImageName, &imgName, FALSE);
+               }
+               else
+               {
+                  RtlInitUnicodeString(&SpiCur->ImageName, NULL);
+               }
 
                SpiCur->BasePriority = pr->Pcb.BasePriority;
-               SpiCur->ProcessId = pr->UniqueProcessId;
-               SpiCur->InheritedFromProcessId = (DWORD)(pr->InheritedFromUniqueProcessId);
-               SpiCur->HandleCount = ObpGetHandleCountByHandleTable(&pr->HandleTable);
-               SpiCur->VmCounters.PeakVirtualSize = pr->PeakVirtualSize;
-               SpiCur->VmCounters.VirtualSize = pr->VirtualSize.QuadPart;
-               SpiCur->VmCounters.PageFaultCount = pr->LastFaultCount;
-               SpiCur->VmCounters.PeakWorkingSetSize = pr->Vm.PeakWorkingSetSize; // Is this right using ->Vm. here ?
-               SpiCur->VmCounters.WorkingSetSize = pr->Vm.WorkingSetSize; // Is this right using ->Vm. here ?
-               SpiCur->VmCounters.QuotaPeakPagedPoolUsage =
+               SpiCur->UniqueProcessId = pr->UniqueProcessId;
+               SpiCur->InheritedFromUniqueProcessId = pr->InheritedFromUniqueProcessId;
+               SpiCur->HandleCount = (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0);
+               SpiCur->PeakVirtualSize = pr->PeakVirtualSize;
+               SpiCur->VirtualSize = pr->VirtualSize.QuadPart;
+               SpiCur->PageFaultCount = pr->LastFaultCount;
+               SpiCur->PeakWorkingSetSize = pr->Vm.PeakWorkingSetSize; // Is this right using ->Vm. here ?
+               SpiCur->WorkingSetSize = pr->Vm.WorkingSetSize; // Is this right using ->Vm. here ?
+               SpiCur->QuotaPeakPagedPoolUsage =
                                        pr->QuotaPeakPoolUsage[0];
-               SpiCur->VmCounters.QuotaPagedPoolUsage =
+               SpiCur->QuotaPagedPoolUsage =
                                        pr->QuotaPoolUsage[0];
-               SpiCur->VmCounters.QuotaPeakNonPagedPoolUsage =
+               SpiCur->QuotaPeakNonPagedPoolUsage =
                                        pr->QuotaPeakPoolUsage[1];
-               SpiCur->VmCounters.QuotaNonPagedPoolUsage =
+               SpiCur->QuotaNonPagedPoolUsage =
                                        pr->QuotaPoolUsage[1];
-               SpiCur->VmCounters.PagefileUsage = pr->PagefileUsage; // FIXME
-               SpiCur->VmCounters.PeakPagefileUsage = pr->PeakPagefileUsage;
+               SpiCur->PagefileUsage = pr->PagefileUsage; // FIXME
+               SpiCur->PeakPagefileUsage = pr->PeakPagefileUsage;
                // KJK::Hyperion: I don't know what does this mean. VM_COUNTERS
                // doesn't seem to contain any equivalent field
                //SpiCur->TotalPrivateBytes = pr->NumberOfPrivatePages; //FIXME: bytes != pages
@@ -634,37 +657,38 @@ QSI_DEF(SystemProcessInformation)
                  current = CONTAINING_RECORD(current_entry, ETHREAD,
                                              ThreadListEntry);
 
-                 SpiCur->Threads[i].KernelTime.QuadPart = current->Tcb.KernelTime * 100000LL;
-                 SpiCur->Threads[i].UserTime.QuadPart = current->Tcb.UserTime * 100000LL;
-//                 SpiCur->Threads[i].CreateTime = current->CreateTime;
-                 SpiCur->Threads[i].WaitTime = current->Tcb.WaitTime;
-                 SpiCur->Threads[i].StartAddress = (PVOID) current->StartAddress;
-                 SpiCur->Threads[i].ClientId = current->Cid;
-                 SpiCur->Threads[i].Priority = current->Tcb.Priority;
-                 SpiCur->Threads[i].BasePriority = current->Tcb.BasePriority;
-                 SpiCur->Threads[i].ContextSwitchCount = current->Tcb.ContextSwitches;
-                 SpiCur->Threads[i].State = current->Tcb.State;
-                 SpiCur->Threads[i].WaitReason = current->Tcb.WaitReason;
+                 SpiCur->TH[i].KernelTime.QuadPart = current->Tcb.KernelTime * 100000LL;
+                 SpiCur->TH[i].UserTime.QuadPart = current->Tcb.UserTime * 100000LL;
+//                 SpiCur->TH[i].CreateTime = current->CreateTime;
+                 SpiCur->TH[i].WaitTime = current->Tcb.WaitTime;
+                 SpiCur->TH[i].StartAddress = (PVOID) current->StartAddress;
+                 SpiCur->TH[i].ClientId = current->Cid;
+                 SpiCur->TH[i].Priority = current->Tcb.Priority;
+                 SpiCur->TH[i].BasePriority = current->Tcb.BasePriority;
+                 SpiCur->TH[i].ContextSwitches = current->Tcb.ContextSwitches;
+                 SpiCur->TH[i].ThreadState = current->Tcb.State;
+                 SpiCur->TH[i].WaitReason = current->Tcb.WaitReason;
                  i++;
                  current_entry = current_entry->Flink;
                }
-
+               
                pr = PsGetNextProcess(pr);
-
+        nThreads = 0;
                if ((pr == syspr) || (pr == NULL))
                {
-                       SpiCur->NextEntryDelta = 0;
+                       SpiCur->NextEntryOffset = 0;
                        break;
                }
                else
                        pCur = pCur + curSize + inLen;
        }  while ((pr != syspr) && (pr != NULL));
+       
+       if(pr != NULL)
+       {
+          ObDereferenceObject(pr);
+       }
 
        *ReqSize = ovlSize;
-       if (pr != NULL)
-         {
-           ObDereferenceObject(pr);
-         }
        return (STATUS_SUCCESS);
 }
 
@@ -707,38 +731,36 @@ QSI_DEF(SystemDeviceInformation)
 /* Class 8 - Processor Performance Information */
 QSI_DEF(SystemProcessorPerformanceInformation)
 {
-       PSYSTEM_PROCESSORTIME_INFO Spi
-               = (PSYSTEM_PROCESSORTIME_INFO) Buffer;
+       PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION Spi
+               = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) Buffer;
 
         ULONG i;
        LARGE_INTEGER CurrentTime;
-       PKPCR Pcr;
+       PKPRCB Prcb;
 
-       *ReqSize = KeNumberProcessors * sizeof (SYSTEM_PROCESSORTIME_INFO);
+       *ReqSize = KeNumberProcessors * sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
        /*
-        * Check user buffer's size 
+        * Check user buffer's size
         */
-       if (Size < KeNumberProcessors * sizeof(SYSTEM_PROCESSORTIME_INFO))
+       if (Size < KeNumberProcessors * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION))
        {
                return (STATUS_INFO_LENGTH_MISMATCH);
        }
 
        CurrentTime.QuadPart = KeQueryInterruptTime();
-       Pcr = (PKPCR)KPCR_BASE;   
+       Prcb = ((PKPCR)KPCR_BASE)->Prcb;
        for (i = 0; i < KeNumberProcessors; i++)
        {
-
-          Spi->TotalProcessorRunTime.QuadPart = (Pcr->PrcbData.IdleThread->KernelTime + Pcr->PrcbData.IdleThread->UserTime) * 100000LL; // IdleTime
-           Spi->TotalProcessorTime.QuadPart =  Pcr->PrcbData.KernelTime * 100000LL; // KernelTime
-           Spi->TotalProcessorUserTime.QuadPart = Pcr->PrcbData.UserTime * 100000LL;
-           Spi->TotalDPCTime.QuadPart = Pcr->PrcbData.DpcTime * 100000LL;
-           Spi->TotalInterruptTime.QuadPart = Pcr->PrcbData.InterruptTime * 100000LL;
-           Spi->TotalInterrupts = Pcr->PrcbData.InterruptCount; // Interrupt Count
+          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++;
-//        Pcr++;
-          Pcr = (PKPCR)((ULONG_PTR)Pcr + PAGE_SIZE);
+          Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
        }
-     
+
        return (STATUS_SUCCESS);
 }
 
@@ -810,13 +832,105 @@ QSI_DEF(SystemNonPagedPoolInformation)
        return (STATUS_NOT_IMPLEMENTED);
 }
 
+
+VOID
+ObpGetNextHandleByProcessCount(PSYSTEM_HANDLE_TABLE_ENTRY_INFO pshi,
+                               PEPROCESS Process,
+                               int Count);
+
 /* Class 16 - Handle Information */
 QSI_DEF(SystemHandleInformation)
 {
-       /* FIXME */
-       DPRINT1("NtQuerySystemInformation - SystemHandleInformation not implemented\n");
-       return (STATUS_NOT_IMPLEMENTED);
+        PSYSTEM_HANDLE_INFORMATION Shi = 
+               (PSYSTEM_HANDLE_INFORMATION) Buffer;
+
+        DPRINT("NtQuerySystemInformation - SystemHandleInformation\n");
+
+       if (Size < sizeof (SYSTEM_HANDLE_INFORMATION))
+        {
+               * ReqSize = sizeof (SYSTEM_HANDLE_INFORMATION);
+               return (STATUS_INFO_LENGTH_MISMATCH);
+       }
+
+       DPRINT("SystemHandleInformation 1\n");
+
+       PEPROCESS pr, syspr;
+       int curSize, i = 0;
+       ULONG hCount = 0;
+               
+        /* First Calc Size from Count. */
+        syspr = PsGetNextProcess(NULL);
+       pr = syspr;
+
+        do
+         {
+            hCount = hCount + (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0);
+            pr = PsGetNextProcess(pr);
+
+           if ((pr == syspr) || (pr == NULL))
+               break;
+        } while ((pr != syspr) && (pr != NULL));
+        
+       if(pr != NULL)
+       {
+          ObDereferenceObject(pr);
+       }
+
+       DPRINT("SystemHandleInformation 2\n");
+
+        curSize = sizeof(SYSTEM_HANDLE_INFORMATION)+
+                  (  (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) * hCount) - 
+                     (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) ));
+
+        Shi->NumberOfHandles = hCount;
+
+        if (curSize > Size)
+          {
+            *ReqSize = curSize;
+             return (STATUS_INFO_LENGTH_MISMATCH);
+          }
+
+       DPRINT("SystemHandleInformation 3\n");
+
+        /* Now get Handles from all processs. */
+        syspr = PsGetNextProcess(NULL);
+       pr = syspr;
+
+        do
+         {
+            int Count = 0, HandleCount;
+
+            HandleCount = (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0);
+
+            for (Count = 0; HandleCount > 0 ; HandleCount--)
+               {
+                 ObpGetNextHandleByProcessCount( &Shi->Handles[i], pr, Count);
+                 Count++;
+                 i++;
+               }
+
+           pr = PsGetNextProcess(pr);
+
+           if ((pr == syspr) || (pr == NULL))
+               break;
+          } while ((pr != syspr) && (pr != NULL));
+
+       if(pr != NULL)
+       {
+          ObDereferenceObject(pr);
+       }
+
+       DPRINT("SystemHandleInformation 4\n");
+       return (STATUS_SUCCESS);
+
 }
+/*
+SSI_DEF(SystemHandleInformation)
+{
+       
+       return (STATUS_SUCCESS);
+}
+*/
 
 /* Class 17 -  Information */
 QSI_DEF(SystemObjectInformation)
@@ -909,12 +1023,35 @@ QSI_DEF(SystemPoolTagInformation)
        return (STATUS_NOT_IMPLEMENTED);
 }
 
-/* Class 23 - Interrupt Information */
+/* Class 23 - Interrupt Information for all processors */
 QSI_DEF(SystemInterruptInformation)
 {
-       /* FIXME */
-       DPRINT1("NtQuerySystemInformation - SystemInterruptInformation not implemented\n");
-       return (STATUS_NOT_IMPLEMENTED);
+  PKPRCB Prcb;
+  UINT i;
+  ULONG ti;
+  PSYSTEM_INTERRUPT_INFORMATION sii = (PSYSTEM_INTERRUPT_INFORMATION)Buffer;
+  
+  if(Size < KeNumberProcessors * sizeof(SYSTEM_INTERRUPT_INFORMATION))
+  {
+    return (STATUS_INFO_LENGTH_MISMATCH);
+  }
+  
+  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 */
+    sii->TimeIncrement = ti;
+    sii->DpcBypassCount = 0; /* FIXME */
+    sii->ApcBypassCount = 0; /* FIXME */
+    sii++;
+    Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
+  }
+  
+  return STATUS_SUCCESS;
 }
 
 /* Class 24 - DPC Behaviour Information */
@@ -947,7 +1084,7 @@ QSI_DEF(SystemFullMemoryInformation)
        }
        DPRINT("SystemFullMemoryInformation\n");
 
-       PsLookupProcessByProcessId((PVOID) 1, &TheIdleProcess);
+       TheIdleProcess = PsIdleProcess;
 
         DPRINT("PID: %d, KernelTime: %u PFFree: %d PFUsed: %d\n",
                TheIdleProcess->UniqueProcessId,
@@ -961,8 +1098,6 @@ QSI_DEF(SystemFullMemoryInformation)
        
        *Spi = MiMemoryConsumers[MC_USER].PagesUsed;
 
-       ObDereferenceObject(TheIdleProcess);
-
        return (STATUS_SUCCESS);
 }
 
@@ -1376,6 +1511,8 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
   PVOID SystemInformation;
   NTSTATUS Status;
   NTSTATUS FStatus;
+  
+  PAGED_CODE();
 
 /*     DPRINT("NtQuerySystemInformation Start. Class:%d\n",
                                        SystemInformationClass );
@@ -1453,6 +1590,8 @@ NtSetSystemInformation (
        IN      ULONG                           SystemInformationLength
        )
 {
+        PAGED_CODE();
+        
        /*
         * If called from user mode, check 
         * possible unsafe arguments.
@@ -1501,6 +1640,8 @@ NtFlushInstructionCache (
        IN      UINT    NumberOfBytesToFlush
        )
 {
+        PAGED_CODE();
+        
        __asm__("wbinvd\n");
        return STATUS_SUCCESS;
 }