[NTOSKRNL] Implement NtQuerySystemInformation(SystemLogicalProcessorInformation)
[reactos.git] / ntoskrnl / ex / sysinfo.c
index e3c6ece..aa999b2 100644 (file)
@@ -2631,6 +2631,90 @@ QSI_DEF(SystemObjectSecurityMode)
     return STATUS_SUCCESS;
 }
 
+/* Class 73 - Logical processor information  */
+QSI_DEF(SystemLogicalProcessorInformation)
+{
+    LONG i;
+    PKPRCB Prcb;
+    KAFFINITY CurrentProc;
+    NTSTATUS Status = STATUS_SUCCESS;
+    ULONG DataSize = 0, ProcessorFlags;
+    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION CurrentInfo;
+
+    /* First, browse active processors, thanks to the map */
+    i = 0;
+    CurrentInfo = Buffer;
+    CurrentProc = KeActiveProcessors;
+    do
+    {
+        /* If current processor is active and is main in case of HT/MC, return it */
+        Prcb = KiProcessorBlock[i];
+        if ((CurrentProc & 1) &&
+            Prcb == Prcb->MultiThreadSetMaster)
+        {
+            /* Assume processor can do HT or multicore */
+            ProcessorFlags = 1;
+
+            /* If set is the same for PRCB and multithread, then
+             * actually, the processor is single core
+             */
+            if (Prcb->SetMember == Prcb->MultiThreadProcessorSet)
+            {
+                ProcessorFlags = 0;
+            }
+
+            /* Check we have enough room to return */
+            DataSize += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
+            if (DataSize > Size)
+            {
+                Status = STATUS_INFO_LENGTH_MISMATCH;
+            }
+            else
+            {
+                /* Zero output and return */
+                RtlZeroMemory(CurrentInfo, sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
+                CurrentInfo->ProcessorMask = Prcb->MultiThreadProcessorSet;
+
+                /* Processor core needs 1 if HT/MC is supported */
+                CurrentInfo->Relationship = RelationProcessorCore;
+                CurrentInfo->ProcessorCore.Flags = ProcessorFlags;
+                ++CurrentInfo;
+            }
+        }
+
+        /* Move to the next proc */
+        CurrentProc >>= 1;
+        ++i;
+    /* Loop while there's someone in the bitmask */
+    } while (CurrentProc != 0);
+
+    /* Now, return the NUMA nodes */
+    for (i = 0; i < KeNumberNodes; ++i)
+    {
+        /* Check we have enough room to return */
+        DataSize += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
+        if (DataSize > Size)
+        {
+            Status = STATUS_INFO_LENGTH_MISMATCH;
+        }
+        else
+        {
+            /* Zero output and return */
+            RtlZeroMemory(CurrentInfo, sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
+            CurrentInfo->ProcessorMask = KeActiveProcessors;
+
+            /* NUMA node needs its ID */
+            CurrentInfo->Relationship = RelationNumaNode;
+            CurrentInfo->NumaNode.NodeNumber = i;
+            ++CurrentInfo;
+        }
+    }
+
+    *ReqSize = DataSize;
+
+    return Status;
+}
+
 /* Class 76 - System firmware table information  */
 QSI_DEF(SystemFirmwareTableInformation)
 {
@@ -2826,7 +2910,7 @@ CallQS [] =
     SI_QX(SystemObjectSecurityMode),
     SI_XX(SystemWatchdogTimerHandler), /* FIXME: not implemented */
     SI_XX(SystemWatchdogTimerInformation), /* FIXME: not implemented */
-    SI_XX(SystemLogicalProcessorInformation), /* FIXME: not implemented */
+    SI_QX(SystemLogicalProcessorInformation),
     SI_XX(SystemWow64SharedInformation), /* FIXME: not implemented */
     SI_XX(SystemRegisterFirmwareTableInformationHandler), /* FIXME: not implemented */
     SI_QX(SystemFirmwareTableInformation),