SYSTEM_PROCESSOR_INFORMATION

The SYSTEM_PROCESSOR_INFORMATION structure is what a successful call to ZwQuerySystemInformation or NtQuerySystemInformation produces in its output buffer when given the information classes SystemProcessorInformation (0x01) or SystemEmulationProcessorInformation (0x3F).

Not that anyone is at all likely to be troubled by this nowadays, but beware that before version 3.51 this information class produces an array of these structures—well, of some structure that’s the same size—one per processor.

Usage

The primary use of the SystemProcessorInformation case of NtQuerySystemInformation is to support the KERNEL32 function GetSystemInfo, specifically to obtain values for the following members of that function’s SYSTEM_INFO structure:

If these are all that is wanted, then use GetSystemInfo instead.

Documentation Status

The SYSTEM_PROCESSOR_INFORMATION structure is not documented.

Microsoft does publish the practical equivalent of a C-language definition as type information in public symbol files, though not for the kernel, where the structure is prepared, nor even for low-level user-mode DLLs that interpret the structure, but for various higher-level user-mode DLLs such as URLMON.DLL and only then starting with version 6.2.

Two earlier disclosures of type information are known, though not in symbol files but in statically linked libraries: GDISRVL.LIB from the Device Driver Kit (DDK) for Windows NT 3.51; and SHELL32.LIB from the DDK for Windows NT 4.0.

Layout

The SYSTEM_PROCESSOR_INFORMATION is 0x0C bytes in both 32-bit and 64-bit Windows in version 3.51 and higher.

Offset Definition Versions
0x00
USHORT ProcessorArchitecture;
3.51 and higher
0x02
USHORT ProcessorLevel;
3.51 and higher
0x04
USHORT ProcessorRevision;
3.51 and higher
0x06
USHORT Reserved;
3.51 to 6.1
USHORT MaximumProcessors;
6.2 and higher
0x08
ULONG ProcessorFeatureBits;
3.51 and higher

In 32-bit Windows, the structure is filled exactly the same for both information classes. The x64 builds treat SystemEmulationBasicInformation differently, specifically to force ProcessorArchitecture to PROCESSOR_ARCHITECTURE_INTEL (0). This allows WOW64.DLL, executing 64-bit code in a 32-bit process, to get processor information that’s suited to the 32-bit caller.

Not until Windows 8 does the kernel compute a value for MaximumProcessors. Earlier versions set it to zero. Type information from libraries for versions 3.51 and 4.0 confirm that this member started as formally reserved. When it became formally defined is not known.

Archaeology

Interpretation of the SYSTEM_PROCESSOR_INFORMATION is known to be different before version 3.51. The only member that is filled in is the first and it is then a dword. It is set to 386, 486, 586, etc, according to whether the CpuType in the corresponding KPRCB is 3, 4, 5, etc. It was perhaps named ProcessorType for it is the immediate origin of the dwProcessorType that is documented for the user-mode SYSTEM_INFO structure as an “obsolete member that is retained for compatibility”.

In these early versions, the user-mode SYSTEM_INFO has no wProcessorArchitecture, instead overlaying with a 32bit dwOemId obtained from the Reserved member of the SYSTEM_BASIC_INFORMATION, and wProcessorLevel and wProcessorRevision are zero.