NtQuerySystemInformation参数详解

NtQuerySystemInformation函数,其中SystemBasicInformation(0号功能)返回的结果是一个SYSTEM_BASIC_INFORMATION结构,其中的域bKeNumberProcessors将返回系统CPU的个数。

下面是该函数的具体说明:

/×-------------------------------------------------------------
NtQuerySystemInformation is used to check some system informations
avaiable only in KernelMode (above 0x80000000).
All avaiable (or all known) information classes are described
in SYSTEM_INFORMATION_CLASS.
Requirements
Client: Requires Windows XP or Windows 2000 Professional.
Server: Requires Windows 2000 Server.
Header: Declared in Winternl.h.
DLL: Requires Ntdll.dll.
[NtQuerySystemInformation is available for use in Windows 2000 and
Windows XP. It may be altered or unavailable in subsequent versions.
Applications should use the alternate functions listed in this topic.]
*/

注:NtQuerySystemInformation底层使用中写为ZwQuerySystemInformation,两个函数完全相同,只是入口不同。

NTSYSAPI
NTSTATUS
NTAPI
NtQuerySystemInformation(

             //SystemInformationClass
             //[in] One of the values enumerated in SYSTEM_INFORMATION_CLASS,
             //indicating the kind of system information to be retrieved.
             IN SYSTEMINFOCLASS SystemInformationClass,

             // SystemInformation
             // [in, out] Points to a buffer where the requested information is
             // to be returned. The size and structure of this information varies
             // depending on the value of the SystemInformationClass parameter:
             OUT PVOID pSystemInformation,

             //  SystemInformationLength
             //  [in] Size of the buffer pointed to by the SystemInformation parameter,
             //  in bytes.
             IN ULONG uSystemInformationLength,

             //  ReturnLength
             //  [out, optional] Optional pointer to a location where the function
             //  writes the actual size of the information requested.
             //  If that size is less than or equal to the SystemInformationLength
             //  parameter, the function copies the information into the
             //  SystemInformation buffer; otherwise, it returns an NTSTATUS error code
             //  and returns in ReturnLength the size of buffer required to receive
             //  the requested information.
             OUT PULONG puReturnLength OPTIONAL
             );

//  Return Values
//  Returns an NTSTATUS success or error code.
//  The forms and significance of NTSTATUS error codes are listed
//  in the Ntstatus.h header file available in the Windows Device
//  Driver Kit (DDK), and are described in the DDK documentation
//  under Kernel-Mode Driver Architecture / Design Guide / Driver
//  Programming Techniques / Logging Errors.

typedef enum _SYSTEMINFOCLASS
{
    SystemBasicInformation, //0
    SystemProcessorInformation, // 1
    SystemPerformanceInformation, //2
    SystemTimeOfDayInformation, //3
    SystemPathInformation, //4 SystemNotImplemented1
    SystemProcessInformation, //5  per process SystemProcessesAndThreadsInformation
    SystemCallCountInformation, //6  SystemCallInformation
    SystemConfigurationInformation, //7    SystemDeviceInformation
    SystemProcessorPerformanceInformation, //8  per cpu SystemProcessorCounters
    SystemGlobalFlag, //SystemFlagsInformation
    SystemCallTimeInformation, //10
    SystemModuleInformation, //11
    SystemLockInformation, //12
    SystemStackTraceInformation, //13  SystemNotImplemented2
    SystemPagedPoolInformation, //14   checked build only
    SystemNonPagedPoolInformation, //15  checked build only
    SystemHandleInformation, //16
    SystemObjectInformation, //17   SystemObjectTypeInformation
    SystemPageFileInformation, //18  per page file
    SystemVdmInstemulInformation, //19  SystemVdmInstemulInformation
    SystemVdmBopInformation, //20
    SystemFileCacheInformation, //21
    SystemPoolTagInformation, //22
    SystemInterruptInformation, //23
    SystemDpcBehaviorInformation, //24
    SystemFullMemoryInformation, //25  checked build only
    SystemLoadGdiDriverInformation, //26  set mode only
    SystemUnloadGdiDriverInformation, //27  set mode only
    SystemTimeAdjustmentInformation, //28  writeable
    SystemSummaryMemoryInformation, //29  checked build only
    SystemNextEventIdInformation, //30  checked build only
    SystemEventIdsInformation, //31  checked build only
    SystemCrashDumpInformation, //32
    SystemExceptionInformation, //33
    SystemCrashDumpStateInformation, //34
    SystemKernelDebuggerInformation, //35
    SystemContextSwitchInformation, //36
    SystemRegistryQuotaInformation, //37
    SystemExtendServiceTableInformation, //38  set mode only  SystemAddDriver
    SystemPrioritySeperation, //39  set mode only    SystemPrioritySeparationInformation
    SystemPlugPlayBusInformation, //40  not implemented
    SystemDockInformation, //41  not implemented
    SystemPowerInformation, //42  XP only
    SystemProcessorSpeedInformation, //43  XP only
    SystemCurrentTimeZoneInformation, //44
    SystemLookasideInformation, //45
    SystemSetTimeSlipEvent, //46
    SystemCreateSession, // set mode only
    SystemDeleteSession, // set mode only
    SystemInvalidInfoClass1, // invalid info class
    SystemRangeStartInformation, // 0x0004 (fails if size != 4)
    SystemVerifierInformation,
    SystemAddVerifier,
    SystemSessionProcessesInformation, // checked build only
    MaxSystemInfoClass
} SYSTEMINFOCLASS, *PSYSTEMINFOCLASS;

typedef struct _SYSTEM_BASIC_INFORMATION
{
  DWORD dwUnknown1; // 0
  ULONG uKeMaximumIncrement; // x86: 0x0002625A or 0x00018730
  ULONG uPageSize; // bytes
  ULONG uMmNumberOfPhysicalPages;
  ULONG uMmLowestPhysicalPage;
  ULONG uMmHighestPhysicalPage;
  ULONG uAllocationGranularity; // bytes
  PVOID pLowestUserAddress;
  PVOID pMmHighestUserAddress;
  KAFFINITY uKeActiveProcessors;
  BYTE bKeNumberProcessors;
  BYTE bUnknown2;
  WORD wUnknown3;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;

typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
{
  LARGE_INTEGER IdleTime;
  LARGE_INTEGER KernelTime;
  LARGE_INTEGER UserTime;
  LARGE_INTEGER DpcTime;
  LARGE_INTEGER InterruptTime;
  DWORD InterruptCount;
  DWORD dwUnknown1;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION

typedef struct _SYSTEM_PERFORMANCE_INFORMATION
{
  LARGE_INTEGER liIdleTime;
  LARGE_INTEGER IoReadTransferCount;
  LARGE_INTEGER IoWriteTransferCount;
  LARGE_INTEGER IoOtherTransferCount;
  ULONG IoReadOperationCount;
  ULONG IoWriteOperationCount;
  ULONG IoOtherOperationCount;
  ULONG AvailablePages;
  ULONG CommittedPages;
  ULONG CommitLimit;
  ULONG PeakCommitment;
  ULONG PageFaultCount;
  ULONG CopyOnWriteCount;
  ULONG TransitionCount;
  ULONG CacheTransitionCount;
  ULONG DemandZeroCount;
  ULONG PageReadCount;
  ULONG PageReadIoCount;
  ULONG CacheReadCount;
  ULONG CacheIoCount;
  ULONG DirtyPagesWriteCount;
  ULONG DirtyWriteIoCount;
  ULONG MappedPagesWriteCount;
  ULONG MappedWriteIoCount;
  ULONG PagedPoolPages;
  ULONG NonPagedPoolPages;
  ULONG PagedPoolAllocs;
  ULONG PagedPoolFrees;
  ULONG NonPagedPoolAllocs;
  ULONG NonPagedPoolFrees;
  ULONG FreeSystemPtes;
  ULONG ResidentSystemCodePage;
  ULONG TotalSystemDriverPages;
  ULONG TotalSystemCodePages;
  ULONG NonPagedPoolLookasideHits;
  ULONG PagedPoolLookasideHits;
  ULONG Spare3Count;
  ULONG ResidentSystemCachePage;
  ULONG ResidentPagedPoolPage;
  ULONG ResidentSystemDriverPage;
  ULONG CcFastReadNoWait;
  ULONG CcFastReadWait;
  ULONG CcFastReadResourceMiss;
  ULONG CcFastReadNotPossible;
  ULONG CcFastMdlReadNoWait;
  ULONG CcFastMdlReadWait;
  ULONG CcFastMdlReadResourceMiss;
  ULONG CcFastMdlReadNotPossible;
  ULONG CcMapDataNoWait;
  ULONG CcMapDataWait;
  ULONG CcMapDataNoWaitMiss;
  ULONG CcMapDataWaitMiss;
  ULONG CcPinMappedDataCount;
  ULONG CcPinReadNoWait;
  ULONG CcPinReadWait;
  ULONG CcPinReadNoWaitMiss;
  ULONG CcPinReadWaitMiss;
  ULONG CcCopyReadNoWait;
  ULONG CcCopyReadWait;
  ULONG CcCopyReadNoWaitMiss;
  ULONG CcCopyReadWaitMiss;
  ULONG CcMdlReadNoWait;
  ULONG CcMdlReadWait;
  ULONG CcMdlReadNoWaitMiss;
  ULONG CcMdlReadWaitMiss;
  ULONG CcReadAheadIos;
  ULONG CcLazyWriteIos;
  ULONG CcLazyWritePages;
  ULONG CcDataFlushes;
  ULONG CcDataPages;
  ULONG ContextSwitches;
  ULONG FirstLevelTbFills;
  ULONG SecondLevelTbFills;
  ULONG SystemCalls;
}

我们在任务管理器中所见到的所有信息只使用了下面5个调用:
0    SystemBasicInformation
2    SystemPerformanceInformation
5    SystemProcessInformation
8    SystemProcessorPerformanceInformation
21   SystemFileCacheInformation

初始化部分使用了其中的3个调用(0、2、8),这里给出的是任务管理器的初始化部分:

010058D6 InitPerfInfo proc near
010058D6
010058D6 SYSPROCPERFINFO= SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION ptr -76Ch
010058D6 SYSPERFINFO= SYSTEM_PERFORMANCE_INFORMATION ptr -16Ch
010058D6 SYSBASICINFO= SYSTEM_BASIC_INFORMATION ptr -34h
010058D6 pBuf= dword ptr -8
010058D6 i   = dword ptr -4
010058D6
010058D6     push ebp
010058D7     mov ebp, esp
010058D9     sub esp, 76Ch
010058DF     push ebx
010058E0     push esi
010058E1     xor ebx, ebx
010058E3     push edi
010058E4     push ebx                ; puReturnLength
010058E5     lea eax, [ebp+SYSBASICINFO]
010058E8     push 2Ch                ; SizeOf(SYSTEM_BASIC_INFORMATION)
010058EA     push eax                ; pSystemInformation
010058EB     push ebx                ; ebx = 0  SystemBasicInformation
010058EC     call ds:NtQuerySystemInformation
010058F2     cmp eax, ebx
010058F4     jl  Err_CpuNumAbove32
010058FA     mov eax, [ebp+SYSBASICINFO.uPageSize]
010058FD     mov g_PageSize, eax     ; 页面大小
01005902     mov al, [ebp+SYSBASICINFO.bKeNumberProcessors]
01005905     cmp al, 32              ; 32位Windows操作系统最多允许系统有32个CPU
01005907     mov g_cProcessors, al   ; CPU的个数
0100590C     ja  Err_CpuNumAbove32
01005912     mov esi, ds:LocalAlloc
01005918     mov edi, 1F40h
0100591D     test al, al
0100591F     jbe short CpuNumEquOne
01005921
01005921 Loop_for_AllocMem:
01005921     push edi
01005922     push LMEM_ZEROINIT
01005924     call esi ; LocalAlloc
01005926     test eax, eax
01005928     mov g_pCPUHistory[ebx*4], eax
0100592F     jz  Err_CpuNumAbove32
01005935     push edi
01005936     push LMEM_ZEROINIT
01005938     call esi ; LocalAlloc
0100593A     test eax, eax
0100593C     mov g_pKernelHistory[ebx*4], eax
01005943     jz  Err_CpuNumAbove32
01005949     movzx eax, g_cProcessors
01005950     inc ebx
01005951     cmp ebx, eax
01005953     jl  short Loop_for_AllocMem
01005955
01005955 CpuNumEquOne:
01005955     push edi
01005956     push LMEM_ZEROINIT
01005958     call esi ; LocalAlloc
0100595A     test eax, eax
0100595C     mov g_pMEMHistory, eax
01005961     jz  Err_CpuNumAbove32
01005967     push 0                  ; puReturnLength
01005969     lea eax, [ebp+SYSPROCPERFINFO]
0100596F     push 600h               ; 为32个CPU准备空间
0100596F                             ; SizeOf(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)*32
01005974     push eax                ; pSystemInformation
01005975     push SystemProcessorPerformanceInformation ; SystemInformationClass
01005977     call ds:NtQuerySystemInformation
0100597D     test eax, eax
0100597F     jl  Err_CpuNumAbove32
01005985     movzx eax, g_cProcessors
0100598C     and [ebp+i], 0
01005990     test eax, eax
01005992     jle short CpuNumEquOne_1
01005994     lea eax, [ebp+SYSPROCPERFINFO.KernelTime]
0100599A     mov [ebp+pBuf], offset PreviousCPUKernelTime
010059A1
010059A1 Loop_IniCpuAllTime:
010059A1     mov ecx, [ebp+i]
010059A4     mov edx, [eax-8]        ; edx = IdleTime.LowPart
010059A7     mov edi, [eax+8]        ; edi = UserTime.LowPart
010059AA     mov esi, [eax+4]        ; esi = KernelTime.HighPart
010059AD     shl ecx, 3              ; ecx = i X 8
010059B0     mov ebx, [eax+0Ch]      ; ebx = UserTime.HighPart
010059B3     mov dword ptr PreviousCPUIdleTime.LowPart[ecx], edx
010059B9     mov edx, [eax-4]        ; edx = IdleTime.HighPart
010059BC     mov PreviousCPUIdleTime.HighPart[ecx], edx
010059C2     mov edx, [eax]          ; KernelTime.LowPart
010059C4     add edi, edx            ; edi = UserTime.LowPart + KernelTime.LowPart
010059C6     adc ebx, esi            ; 带进位加
010059C6                             ; ebx = UserTime.HighPart + KernelTime.HighPart
010059C8     add edx, [eax-8]        ; edx = KernelTime.LowPart + IdleTime.LowPart
010059CB     mov dword ptr PreviousCPUTotalTime.LowPart[ecx], edi
010059D1     mov PreviousCPUTotalTime.HighPart[ecx], ebx
010059D7     mov ecx, [ebp+pBuf]     ; PreviousCPUKernelTime的指针
010059DA     adc esi, [eax-4]        ; 带进位加
010059DA                             ; esi = KernelTime.HighPart + IdleTime.HighPart
010059DD     add eax, 30h            ; 取下一个CPU的相关数据
010059DD                             ; SizeOf(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)
010059E0     inc [ebp+i]
010059E3     mov [ecx], edx          ; PreviousCPUTotalTime.LowPart = KernelTime.LowPart + IdleTime.LowPart
010059E5     mov [ecx+4], esi        ; PreviousCPUTotalTime.HighPart = KernelTime.HighPart + IdleTime.HighPart
010059E8     add ecx, 8              ; 移动PreviousCPUKernelTime的指针
010059EB     mov [ebp+pBuf], ecx     ; 保存PreviousCPUKernelTime的指针
010059EE     movzx ecx, g_cProcessors
010059F5     cmp [ebp+i], ecx        ; 和Cpu的个数比较
010059F8     jl  short Loop_IniCpuAllTime
010059FA
010059FA CpuNumEquOne_1:             ; puReturnLength
010059FA     push 0
010059FC     lea eax, [ebp+SYSPERFINFO]
01005A02     push 138h               ; SizeOf(SYSTEM_PERFORMANCE_INFORMATION)
01005A07     push eax                ; pSystemInformation
01005A08     push SystemPerformanceInformation ; SystemInformationClass
01005A0A     call ds:NtQuerySystemInformation
01005A10     test eax, eax
01005A12     jge short Init_Exit
01005A14
01005A14 Err_CpuNumAbove32:          ; 如果出错返回 0
01005A14     xor al, al
01005A16     jmp short Exit
01005A18
01005A18 Init_Exit:
01005A18     mov eax, g_PageSize
01005A1D     shr eax, 10
01005A20     imul eax, [ebp+SYSPERFINFO.CommitLimit]
01005A27     mov g_MEMMax, eax
01005A2C     mov al, g_cProcessors   ; 返回Cpu的个数
01005A31
01005A31 Exit:
01005A31     pop edi
01005A32     pop esi
01005A33     pop ebx
01005A34     leave
01005A35     retn
01005A35 InitPerfInfo endp
01005A35

NtQuerySystemInformation非常复杂,其中的结构随着Windows的版本变化会发生变化,这里给出的结构是2K系统的。

你可能感兴趣的:(NtQuerySystemInformation参数详解)