Geoff Chappell, Software Analyst
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).
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.
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.
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, which allows WOW64.DLL, executing 64-bit code for a 32-bit process, to get processor information that’s suited to its 32-bit caller.
With attention restricted just to x86 and x64 builds, the ProcessorArchitecture can be:
These are the native values produced for SystemBasicInformation on 32-bit and 64-bit Windows, respectively. For SystemEmulationBasicInformation, the ProcessorArchitecture is 0 even for 64-bit Windows.
The ProcessorLevel is what Intel’s literature refers to as the family. For each processor, the family is saved in the KPRCB as the CpuType. What goes into the structure is the numerically lowest family for all processors.
The ProcessorRevision combines the model and stepping, as saved in the KPRCB as CpuStep.
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.
The ProcessorFeatureBits are retrieved directly from an internal variable in which the kernel accumulates its record of which features are identified for use on all processors. This variable is widened to 64 bits in 64-bit Windows 8.1 and 32-bit Windows 10, but this structure continues to produce just the low 32 bits. The variable’s whole value is produced in the new structure SYSTEM_PROCESSOR_FEATURES_INFORMATION for the information class SystemProcessorFeaturesInformation (0x9A).
Interpretation of the SYSTEM_PROCESSOR_INFORMATION is known to be different before version 3.51. The output buffer must be large enough for an array of these structures, one per processor, though only the first is filled in and only then incompletely.
The only member that is filled in is the dword at the start. It is 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”. Documented values are:
These are computed by taking the CpuType from the corresponding KPRCB, multiplying by 100 and adding 86, and would therefore continue to an undocumented 686, etc., on almost any x86 computer made since the late 90s.
In these early versions, the user-mode SYSTEM_INFO also is different. In place of the later wProcessorArchitecture is a 32bit dwOemId obtained from the Reserved member of the SYSTEM_BASIC_INFORMATION. Its wProcessorLevel and wProcessorRevision are both zero.