[NTOS:EX]
[reactos.git] / reactos / ntoskrnl / ex / sysinfo.c
index 06aca9a..b9fed78 100644 (file)
@@ -17,6 +17,9 @@
 /* The maximum size of an environment value (in bytes) */
 #define MAX_ENVVAL_SIZE 1024
 
+extern LIST_ENTRY HandleTableListHead;
+extern EX_PUSH_LOCK HandleTableListLock;
+
 FAST_MUTEX ExpEnvironmentLock;
 ERESOURCE ExpFirmwareTableResource;
 LIST_ENTRY ExpFirmwareTableProviderListHead;
@@ -219,7 +222,7 @@ ExLockUserBuffer(
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
         ExFreePoolWithTag(Mdl, TAG_MDL);
-        return _SEH2_GetExceptionCode();
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
     }
     _SEH2_END;
 
@@ -499,7 +502,10 @@ NtQuerySystemEnvironmentValueEx(IN PUNICODE_STRING VariableName,
 NTSTATUS
 NTAPI
 NtSetSystemEnvironmentValueEx(IN PUNICODE_STRING VariableName,
-                              IN LPGUID VendorGuid)
+                              IN LPGUID VendorGuid,
+                              IN PVOID Value,
+                              IN OUT PULONG ReturnLength,
+                              IN OUT PULONG Attributes)
 {
     UNIMPLEMENTED;
     return STATUS_NOT_IMPLEMENTED;
@@ -806,6 +812,10 @@ QSI_DEF(SystemProcessInformation)
         {
             SpiCurrent = (PSYSTEM_PROCESS_INFORMATION) Current;
 
+            /* Lock the Process */
+            KeEnterCriticalRegion();
+            ExAcquirePushLockShared(&Process->ProcessLock);
+
             if ((Process->ProcessExiting) &&
                 (Process->Pcb.Header.SignalState) &&
                 !(Process->ActiveThreads) &&
@@ -815,6 +825,10 @@ QSI_DEF(SystemProcessInformation)
                         Process, Process->ImageFileName, Process->UniqueProcessId);
                 CurrentSize = 0;
                 ImageNameMaximumLength = 0;
+
+                /* Unlock the Process */
+                ExReleasePushLockShared(&Process->ProcessLock);
+                KeLeaveCriticalRegion();
                 goto Skip;
             }
 
@@ -949,6 +963,10 @@ QSI_DEF(SystemProcessInformation)
                 ProcessImageName = NULL;
             }
 
+            /* Unlock the Process */
+            ExReleasePushLockShared(&Process->ProcessLock);
+            KeLeaveCriticalRegion();
+
             /* Handle idle process entry */
 Skip:
             if (Process == PsIdleProcess) Process = NULL;
@@ -1065,12 +1083,20 @@ QSI_DEF(SystemProcessorPerformanceInformation)
 /* Class 9 - Flags Information */
 QSI_DEF(SystemFlagsInformation)
 {
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+    *ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION);
+#endif
+
     if (sizeof(SYSTEM_FLAGS_INFORMATION) != Size)
     {
-        *ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION);
-        return (STATUS_INFO_LENGTH_MISMATCH);
+        return STATUS_INFO_LENGTH_MISMATCH;
     }
+
     ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags = NtGlobalFlag;
+#if (NTDDI_VERSION < NTDDI_VISTA)
+    *ReqSize = sizeof(SYSTEM_FLAGS_INFORMATION);
+#endif
+
     return STATUS_SUCCESS;
 }
 
@@ -1080,6 +1106,12 @@ SSI_DEF(SystemFlagsInformation)
     {
         return STATUS_INFO_LENGTH_MISMATCH;
     }
+
+    if (!SeSinglePrivilegeCheck(SeDebugPrivilege, ExGetPreviousMode()))
+    {
+        return STATUS_ACCESS_DENIED;
+    }
+
     NtGlobalFlag = ((PSYSTEM_FLAGS_INFORMATION) Buffer)->Flags;
     return STATUS_SUCCESS;
 }
@@ -1150,93 +1182,131 @@ QSI_DEF(SystemNonPagedPoolInformation)
 /* Class 16 - Handle Information */
 QSI_DEF(SystemHandleInformation)
 {
-    PEPROCESS pr, syspr;
-    ULONG curSize, i = 0;
-    ULONG hCount = 0;
-
-    PSYSTEM_HANDLE_INFORMATION Shi =
-        (PSYSTEM_HANDLE_INFORMATION) Buffer;
+    PSYSTEM_HANDLE_INFORMATION HandleInformation;
+    PLIST_ENTRY NextTableEntry;
+    PHANDLE_TABLE HandleTable;
+    PHANDLE_TABLE_ENTRY HandleTableEntry;
+    EXHANDLE Handle;
+    ULONG Index = 0;
+    NTSTATUS Status;
+    PMDL Mdl;
+    PAGED_CODE();
 
     DPRINT("NtQuerySystemInformation - SystemHandleInformation\n");
 
-    if (Size < sizeof(SYSTEM_HANDLE_INFORMATION))
+    /* Set initial required buffer size */
+    *ReqSize = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION, Handles);
+
+    /* Check user's buffer size */
+    if (Size < *ReqSize)
     {
-        *ReqSize = sizeof(SYSTEM_HANDLE_INFORMATION);
         return STATUS_INFO_LENGTH_MISMATCH;
     }
 
-    DPRINT("SystemHandleInformation 1\n");
+    /* We need to lock down the memory */
+    Status = ExLockUserBuffer(Buffer,
+                              Size,
+                              ExGetPreviousMode(),
+                              IoWriteAccess,
+                              (PVOID*)&HandleInformation,
+                              &Mdl);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to lock the user buffer: 0x%lx\n", Status);
+        return Status;
+    }
 
-    /* First Calc Size from Count. */
-    syspr = PsGetNextProcess(NULL);
-    pr = syspr;
+    /* Reset of count of handles */
+    HandleInformation->NumberOfHandles = 0;
 
-    do
-    {
-        hCount = hCount + ObGetProcessHandleCount(pr);
-        pr = PsGetNextProcess(pr);
+    /* Enter a critical region */
+    KeEnterCriticalRegion();
 
-        if ((pr == syspr) || (pr == NULL)) break;
-    }
-    while ((pr != syspr) && (pr != NULL));
+    /* Acquire the handle table lock */
+    ExAcquirePushLockShared(&HandleTableListLock);
 
-    if(pr != NULL)
+    /* Enumerate all system handles */
+    for (NextTableEntry = HandleTableListHead.Flink;
+         NextTableEntry != &HandleTableListHead;
+         NextTableEntry = NextTableEntry->Flink)
     {
-        ObDereferenceObject(pr);
-    }
+        /* Get current handle table */
+        HandleTable = CONTAINING_RECORD(NextTableEntry, HANDLE_TABLE, HandleTableList);
 
-    DPRINT("SystemHandleInformation 2\n");
+        /* Set the initial value and loop the entries */
+        Handle.Value = 0;
+        while ((HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle)))
+        {
+            /* Validate the entry */
+            if ((HandleTableEntry->Object) &&
+                (HandleTableEntry->NextFreeTableEntry != -2))
+            {
+                /* Increase of count of handles */
+                ++HandleInformation->NumberOfHandles;
 
-    curSize = sizeof(SYSTEM_HANDLE_INFORMATION) +
-                     ((sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) * hCount) -
-                     (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO)));
+                /* Lock the entry */
+                if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry))
+                {
+                    /* Increase required buffer size */
+                    *ReqSize += sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO);
 
-    Shi->NumberOfHandles = hCount;
+                    /* Check user's buffer size */
+                    if (*ReqSize > Size)
+                    {
+                        Status = STATUS_INFO_LENGTH_MISMATCH;
+                    }
+                    else
+                    {
+                        POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry);
 
-    if (curSize > Size)
-    {
-        *ReqSize = curSize;
-        return (STATUS_INFO_LENGTH_MISMATCH);
-    }
+                        /* Filling handle information */
+                        HandleInformation->Handles[Index].UniqueProcessId =
+                            (USHORT)(ULONG_PTR) HandleTable->UniqueProcessId;
 
-    DPRINT("SystemHandleInformation 3\n");
+                        HandleInformation->Handles[Index].CreatorBackTraceIndex = 0;
 
-    /* Now get Handles from all processes. */
-    syspr = PsGetNextProcess(NULL);
-    pr = syspr;
+#if 0 /* FIXME!!! Type field currupted */
+                        HandleInformation->Handles[Index].ObjectTypeIndex =
+                            (UCHAR) ObjectHeader->Type->Index;
+#else
+                        HandleInformation->Handles[Index].ObjectTypeIndex = 0;
+#endif
 
-    do
-    {
-        int Count = 0, HandleCount;
+                        HandleInformation->Handles[Index].HandleAttributes =
+                            HandleTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
 
-        HandleCount = ObGetProcessHandleCount(pr);
+                        HandleInformation->Handles[Index].HandleValue =
+                            (USHORT)(ULONG_PTR) Handle.GenericHandleOverlay;
 
-        for (Count = 0; HandleCount > 0 ; HandleCount--)
-        {
-            Shi->Handles[i].UniqueProcessId = (USHORT)(ULONG_PTR)pr->UniqueProcessId;
-            Count++;
-            i++;
-        }
+                        HandleInformation->Handles[Index].Object = &ObjectHeader->Body;
+
+                        HandleInformation->Handles[Index].GrantedAccess =
+                            HandleTableEntry->GrantedAccess;
+
+                        ++Index;
+                    }
 
-        pr = PsGetNextProcess(pr);
+                    /* Unlock it */
+                    ExUnlockHandleTableEntry(HandleTable, HandleTableEntry);
+                }
+            }
 
-        if ((pr == syspr) || (pr == NULL)) break;
+            /* Go to the next entry */
+            Handle.Value += sizeof(HANDLE);
+        }
     }
-    while ((pr != syspr) && (pr != NULL));
 
-    if(pr != NULL) ObDereferenceObject(pr);
+    /* Release the lock */
+    ExReleasePushLockShared(&HandleTableListLock);
 
-    DPRINT("SystemHandleInformation 4\n");
-    return STATUS_SUCCESS;
+    /* Leave the critical region */
+    KeLeaveCriticalRegion();
 
-}
-/*
-SSI_DEF(SystemHandleInformation)
-{
+    /* Release the locked user buffer */
+    ExUnlockUserBuffer(Mdl);
 
-    return STATUS_SUCCESS;
+    return Status;
 }
-*/
 
 /* Class 17 -  Information */
 QSI_DEF(SystemObjectInformation)
@@ -1559,11 +1629,11 @@ QSI_DEF(SystemNextEventIdInformation)
     return STATUS_NOT_IMPLEMENTED;
 }
 
-/* Class 31 - Event Ids Information */
-QSI_DEF(SystemEventIdsInformation)
+/* Class 31 */
+QSI_DEF(SystemPerformanceTraceInformation)
 {
     /* FIXME */
-    DPRINT1("NtQuerySystemInformation - SystemEventIdsInformation not implemented\n");
+    DPRINT1("NtQuerySystemInformation - SystemPerformanceTraceInformation not implemented\n");
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -1625,7 +1695,10 @@ QSI_DEF(SystemKernelDebuggerInformation)
 {
     PSYSTEM_KERNEL_DEBUGGER_INFORMATION skdi = (PSYSTEM_KERNEL_DEBUGGER_INFORMATION) Buffer;
 
+#if (NTDDI_VERSION >= NTDDI_VISTA)
     *ReqSize = sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION);
+#endif
+
     if (Size < sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION))
     {
         return STATUS_INFO_LENGTH_MISMATCH;
@@ -1634,6 +1707,10 @@ QSI_DEF(SystemKernelDebuggerInformation)
     skdi->KernelDebuggerEnabled = KD_DEBUGGER_ENABLED;
     skdi->KernelDebuggerNotPresent = KD_DEBUGGER_NOT_PRESENT;
 
+#if (NTDDI_VERSION < NTDDI_VISTA)
+    *ReqSize = sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION);
+#endif
+
     return STATUS_SUCCESS;
 }
 
@@ -1820,24 +1897,24 @@ SSI_DEF(SystemPrioritySeperation)
     return STATUS_SUCCESS;
 }
 
-/* Class 40 - Plug Play Bus Information */
-QSI_DEF(SystemPlugPlayBusInformation)
+/* Class 40 */
+QSI_DEF(SystemVerifierAddDriverInformation)
 {
     /* FIXME */
-    DPRINT1("NtQuerySystemInformation - SystemPlugPlayBusInformation not implemented\n");
+    DPRINT1("NtQuerySystemInformation - SystemVerifierAddDriverInformation not implemented\n");
     return STATUS_NOT_IMPLEMENTED;
 }
 
-/* Class 41 - Dock Information */
-QSI_DEF(SystemDockInformation)
+/* Class 41 */
+QSI_DEF(SystemVerifierRemoveDriverInformation)
 {
     /* FIXME */
-    DPRINT1("NtQuerySystemInformation - SystemDockInformation not implemented\n");
+    DPRINT1("NtQuerySystemInformation - SystemVerifierRemoveDriverInformation not implemented\n");
     return STATUS_NOT_IMPLEMENTED;
 }
 
 /* Class 42 - Power Information */
-QSI_DEF(SystemPowerInformation)
+QSI_DEF(SystemProcessorIdleInformation)
 {
     *ReqSize = sizeof(PROCESSOR_POWER_INFORMATION) * KeNumberProcessors;
 
@@ -1851,11 +1928,11 @@ QSI_DEF(SystemPowerInformation)
     return STATUS_NOT_IMPLEMENTED;
 }
 
-/* Class 43 - Processor Speed Information */
-QSI_DEF(SystemProcessorSpeedInformation)
+/* Class 43 */
+QSI_DEF(SystemLegacyDriverInformation)
 {
     /* FIXME */
-    DPRINT1("NtQuerySystemInformation - SystemProcessorSpeedInformation not implemented\n");
+    DPRINT1("NtQuerySystemInformation - SystemLegacyDriverInformation not implemented\n");
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -2038,10 +2115,10 @@ Leave:
 
 
 /* Class 46 - Set time slip event */
-SSI_DEF(SystemSetTimeSlipEvent)
+SSI_DEF(SystemTimeSlipNotification)
 {
     /* FIXME */
-    DPRINT1("NtSetSystemInformation - SystemSetTimSlipEvent not implemented\n");
+    DPRINT1("NtSetSystemInformation - SystemTimeSlipNotification not implemented\n");
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -2054,7 +2131,7 @@ NTAPI
 MmSessionDelete(IN ULONG SessionId);
 
 /* Class 47 - Create a new session (TSE) */
-SSI_DEF(SystemCreateSession)
+SSI_DEF(SystemSessionCreate)
 {
     ULONG SessionId;
     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
@@ -2068,6 +2145,8 @@ SSI_DEF(SystemCreateSession)
         {
             return STATUS_PRIVILEGE_NOT_HELD;
         }
+
+        ProbeForWriteUlong(Buffer);
     }
 
     Status = MmSessionCreate(&SessionId);
@@ -2078,7 +2157,7 @@ SSI_DEF(SystemCreateSession)
 
 
 /* Class 48 - Delete an existing session (TSE) */
-SSI_DEF(SystemDeleteSession)
+SSI_DEF(SystemSessionDetach)
 {
     ULONG SessionId;
     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
@@ -2100,10 +2179,10 @@ SSI_DEF(SystemDeleteSession)
 
 
 /* Class 49 - UNKNOWN */
-QSI_DEF(SystemInvalidInfoClass4)
+QSI_DEF(SystemSessionInformation)
 {
     /* FIXME */
-    DPRINT1("NtQuerySystemInformation - SystemInvalidInfoClass4 not implemented\n");
+    DPRINT1("NtQuerySystemInformation - SystemSessionInformation not implemented\n");
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -2138,11 +2217,11 @@ SSI_DEF(SystemVerifierInformation)
 }
 
 
-/* Class 52 - Add a driver verifier */
-SSI_DEF(SystemAddVerifier)
+/* Class 52 */
+SSI_DEF(SystemVerifierThunkExtend)
 {
     /* FIXME */
-    DPRINT1("NtSetSystemInformation - SystemAddVerifier not implemented\n");
+    DPRINT1("NtSetSystemInformation - SystemVerifierThunkExtend not implemented\n");
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -2300,7 +2379,6 @@ struct _QSSI_CALLS
 {
     NTSTATUS (* Query) (PVOID,ULONG,PULONG);
     NTSTATUS (* Set) (PVOID,ULONG);
-
 } QSSI_CALLS;
 
 // QS    Query & Set
@@ -2322,54 +2400,54 @@ CallQS [] =
     SI_QX(SystemPerformanceInformation),
     SI_QX(SystemTimeOfDayInformation),
     SI_QX(SystemPathInformation), /* should be SI_XX */
-    SI_QX(SystemProcessInformation),  // aka SystemProcessesAndThreadsInformation
-    SI_QX(SystemCallCountInformation), // aka SystemCallCounts
-    SI_QX(SystemDeviceInformation), // aka SystemConfigurationInformation
-    SI_QX(SystemProcessorPerformanceInformation), // aka SystemProcessorTimes
-    SI_QS(SystemFlagsInformation), // aka SystemGlobalFlag
+    SI_QX(SystemProcessInformation),
+    SI_QX(SystemCallCountInformation),
+    SI_QX(SystemDeviceInformation),
+    SI_QX(SystemProcessorPerformanceInformation),
+    SI_QS(SystemFlagsInformation),
     SI_QX(SystemCallTimeInformation), /* should be SI_XX */
     SI_QX(SystemModuleInformation),
-    SI_QX(SystemLocksInformation), // aka SystemLockInformation
+    SI_QX(SystemLocksInformation),
     SI_QX(SystemStackTraceInformation), /* should be SI_XX */
     SI_QX(SystemPagedPoolInformation), /* should be SI_XX */
     SI_QX(SystemNonPagedPoolInformation), /* should be SI_XX */
     SI_QX(SystemHandleInformation),
     SI_QX(SystemObjectInformation),
-    SI_QX(SystemPageFileInformation), // aka SystemPagefileInformation
-    SI_QX(SystemVdmInstemulInformation), // aka SystemInstructionEmulationCounts
+    SI_QX(SystemPageFileInformation),
+    SI_QX(SystemVdmInstemulInformation),
     SI_QX(SystemVdmBopInformation), /* it should be SI_XX */
-    SI_QS(SystemFileCacheInformation), // aka SystemCacheInformation
+    SI_QS(SystemFileCacheInformation),
     SI_QX(SystemPoolTagInformation),
-    SI_QX(SystemInterruptInformation), // aka SystemProcessorStatistics
-    SI_QS(SystemDpcBehaviourInformation), // aka SystemDpcInformation
+    SI_QX(SystemInterruptInformation),
+    SI_QS(SystemDpcBehaviourInformation),
     SI_QX(SystemFullMemoryInformation), /* it should be SI_XX */
-    SI_XS(SystemLoadGdiDriverInformation), // correct: SystemLoadImage
-    SI_XS(SystemUnloadGdiDriverInformation), // correct: SystemUnloadImage
-    SI_QS(SystemTimeAdjustmentInformation), // aka SystemTimeAdjustment
+    SI_XS(SystemLoadGdiDriverInformation),
+    SI_XS(SystemUnloadGdiDriverInformation),
+    SI_QS(SystemTimeAdjustmentInformation),
     SI_QX(SystemSummaryMemoryInformation), /* it should be SI_XX */
     SI_QX(SystemNextEventIdInformation), /* it should be SI_XX */
-    SI_QX(SystemEventIdsInformation), /* it should be SI_XX */ // SystemPerformanceTraceInformation
+    SI_QX(SystemPerformanceTraceInformation), /* it should be SI_XX */
     SI_QX(SystemCrashDumpInformation),
     SI_QX(SystemExceptionInformation),
     SI_QX(SystemCrashDumpStateInformation),
     SI_QX(SystemKernelDebuggerInformation),
     SI_QX(SystemContextSwitchInformation),
     SI_QS(SystemRegistryQuotaInformation),
-    SI_XS(SystemExtendServiceTableInformation), // correct: SystemLoadAndCallImage
+    SI_XS(SystemExtendServiceTableInformation),
     SI_XS(SystemPrioritySeperation),
-    SI_QX(SystemPlugPlayBusInformation), /* it should be SI_XX */
-    SI_QX(SystemDockInformation), /* it should be SI_XX */
-    SI_QX(SystemPowerInformation), /* it should be SI_XX */ // SystemPowerInformationNative? SystemInvalidInfoClass2
-    SI_QX(SystemProcessorSpeedInformation), /* it should be SI_XX */
-    SI_QS(SystemCurrentTimeZoneInformation), /* it should be SI_QX */ // aka SystemTimeZoneInformation
+    SI_QX(SystemVerifierAddDriverInformation), /* it should be SI_XX */
+    SI_QX(SystemVerifierRemoveDriverInformation), /* it should be SI_XX */
+    SI_QX(SystemProcessorIdleInformation), /* it should be SI_XX */
+    SI_QX(SystemLegacyDriverInformation), /* it should be SI_XX */
+    SI_QS(SystemCurrentTimeZoneInformation), /* it should be SI_QX */
     SI_QX(SystemLookasideInformation),
-    SI_XS(SystemSetTimeSlipEvent),
-    SI_XS(SystemCreateSession),
-    SI_XS(SystemDeleteSession),
-    SI_QX(SystemInvalidInfoClass4), /* it should be SI_XX */ // SystemSessionInformation?
+    SI_XS(SystemTimeSlipNotification),
+    SI_XS(SystemSessionCreate),
+    SI_XS(SystemSessionDetach),
+    SI_QX(SystemSessionInformation), /* it should be SI_XX */
     SI_QX(SystemRangeStartInformation),
     SI_QS(SystemVerifierInformation),
-    SI_XS(SystemAddVerifier),
+    SI_XS(SystemVerifierThunkExtend),
     SI_QX(SystemSessionProcessesInformation),
     SI_XS(SystemLoadGdiDriverInSystemSpaceInformation),
     SI_QX(SystemNumaProcessorMap),
@@ -2395,6 +2473,7 @@ NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
 {
     KPROCESSOR_MODE PreviousMode;
     ULONG ResultLength = 0;
+    ULONG Alignment = TYPE_ALIGNMENT(ULONG);
     NTSTATUS FStatus = STATUS_NOT_IMPLEMENTED;
 
     PAGED_CODE();
@@ -2403,10 +2482,23 @@ NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
 
     _SEH2_TRY
     {
+#if (NTDDI_VERSION >= NTDDI_VISTA)
+        /*
+         * Check if the request is valid.
+         */
+        if (SystemInformationClass >= MAX_SYSTEM_INFO_CLASS)
+        {
+            _SEH2_YIELD(return STATUS_INVALID_INFO_CLASS);
+        }
+#endif
+
         if (PreviousMode != KernelMode)
         {
             /* SystemKernelDebuggerInformation needs only BOOLEAN alignment */
-            ProbeForWrite(SystemInformation, Length, 1);
+            if (SystemInformationClass == SystemKernelDebuggerInformation)
+                Alignment = TYPE_ALIGNMENT(BOOLEAN);
+
+            ProbeForWrite(SystemInformation, Length, Alignment);
             if (UnsafeResultLength != NULL)
                 ProbeForWriteUlong(UnsafeResultLength);
         }
@@ -2414,6 +2506,7 @@ NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
         if (UnsafeResultLength)
             *UnsafeResultLength = 0;
 
+#if (NTDDI_VERSION < NTDDI_VISTA)
         /*
          * Check if the request is valid.
          */
@@ -2421,6 +2514,7 @@ NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
         {
             _SEH2_YIELD(return STATUS_INVALID_INFO_CLASS);
         }
+#endif
 
         if (NULL != CallQS [SystemInformationClass].Query)
         {
@@ -2452,137 +2546,62 @@ NtSetSystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
                         IN PVOID SystemInformation,
                         IN ULONG SystemInformationLength)
 {
-    PAGED_CODE();
-
-    /*
-     * If called from user mode, check
-     * possible unsafe arguments.
-     */
-#if 0
-    if (KernelMode != KeGetPreviousMode())
-    {
-        // Check arguments
-        //ProbeForWrite(
-        //    SystemInformation,
-        //    Length
-        //    );
-        //ProbeForWrite(
-        //    ResultLength,
-        //    sizeof (ULONG)
-        //    );
-    }
-#endif
-    /*
-     * Check the request is valid.
-     */
-    if ((SystemInformationClass >= MIN_SYSTEM_INFO_CLASS) &&
-        (SystemInformationClass < MAX_SYSTEM_INFO_CLASS))
-    {
-        if (NULL != CallQS [SystemInformationClass].Set)
-        {
-            /*
-             * Hand the request to a subhandler.
-             */
-            return CallQS [SystemInformationClass].Set(SystemInformation,
-                                                       SystemInformationLength);
-        }
-    }
-
-    return STATUS_INVALID_INFO_CLASS;
-}
+    NTSTATUS Status = STATUS_INVALID_INFO_CLASS;
+    KPROCESSOR_MODE PreviousMode;
 
-NTSTATUS
-NTAPI
-NtFlushInstructionCache(
-    _In_ HANDLE ProcessHandle,
-    _In_opt_ PVOID BaseAddress,
-    _In_ ULONG FlushSize)
-{
-    KAPC_STATE ApcState;
-    PKPROCESS Process;
-    NTSTATUS Status;
     PAGED_CODE();
 
-    /* Is a base address given? */
-    if (BaseAddress != NULL)
+    PreviousMode = ExGetPreviousMode();
+
+    _SEH2_TRY
     {
-        /* If the requested size is 0, there is nothing to do */
-        if (FlushSize == 0)
+        /*
+         * If called from user mode, check
+         * possible unsafe arguments.
+         */
+        if (PreviousMode != KernelMode)
         {
-            return STATUS_SUCCESS;
+            ProbeForRead(SystemInformation, SystemInformationLength, sizeof(ULONG));
         }
 
-        /* Is this a user mode call? */
-        if (KeGetPreviousMode() != KernelMode)
+        /*
+         * Check the request is valid.
+         */
+        if ((SystemInformationClass >= MIN_SYSTEM_INFO_CLASS) &&
+            (SystemInformationClass < MAX_SYSTEM_INFO_CLASS))
         {
-            /* Make sure the base address is in user space */
-            if (BaseAddress > MmHighestUserAddress)
+            if (NULL != CallQS [SystemInformationClass].Set)
             {
-                DPRINT1("Invalid BaseAddress 0x%p\n", BaseAddress);
-                return STATUS_ACCESS_VIOLATION;
+                /*
+                 * Hand the request to a subhandler.
+                 */
+                Status = CallQS [SystemInformationClass].Set(SystemInformation,
+                                                             SystemInformationLength);
             }
         }
     }
-
-    /* Is another process requested? */
-    if (ProcessHandle != NtCurrentProcess())
-    {
-        /* Reference the process */
-        Status = ObReferenceObjectByHandle(ProcessHandle,
-                                           PROCESS_VM_WRITE,
-                                           PsProcessType,
-                                           KeGetPreviousMode(),
-                                           (PVOID*)&Process,
-                                           NULL);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("Failed to reference the process %p\n", ProcessHandle);
-            return Status;
-        }
-
-        /* Attach to the process */
-        KeStackAttachProcess(Process, &ApcState);
-    }
-
-    /* FIXME: don't flush everything if a range is requested */
-#if defined(_M_IX86) || defined(_M_AMD64)
-    __wbinvd();
-#elif defined(_M_PPC)
-    __asm__ __volatile__("tlbsync");
-#elif defined(_M_MIPS)
-    DPRINT1("NtFlushInstructionCache() is not implemented\n");
-    DbgBreakPoint();
-#elif defined(_M_ARM)
-    _MoveToCoprocessor(0, CP15_ICIALLU);
-#else
-#error Unknown architecture
-#endif
-
-    /* Check if we attached */
-    if (ProcessHandle != NtCurrentProcess())
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        /* Detach from the process */
-        KeUnstackDetachProcess(&ApcState);
+        Status = _SEH2_GetExceptionCode();
     }
+    _SEH2_END;
 
-    return STATUS_SUCCESS;
+    return Status;
 }
 
 ULONG
 NTAPI
 NtGetCurrentProcessorNumber(VOID)
 {
-    /* Just return the CPU */
+    /* Just use Ke */
     return KeGetCurrentProcessorNumber();
 }
 
-/*
- * @implemented
- */
 #undef ExGetPreviousMode
 KPROCESSOR_MODE
 NTAPI
-ExGetPreviousMode (VOID)
+ExGetPreviousMode(VOID)
 {
+    /* Just use Ke */
     return KeGetPreviousMode();
 }