From 96ee4509e552a006f8e51b5261359d4cb139b1c3 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Fri, 27 Sep 2019 20:36:34 +0200 Subject: [PATCH] [NTOSKRNL] Implement NtQuerySystemInformation(SystemLogicalProcessorInformation) --- ntoskrnl/ex/sysinfo.c | 86 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/ntoskrnl/ex/sysinfo.c b/ntoskrnl/ex/sysinfo.c index e3c6ece86d6..aa999b2a023 100644 --- a/ntoskrnl/ex/sysinfo.c +++ b/ntoskrnl/ex/sysinfo.c @@ -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),