Geoff Chappell, Software Analyst
The SYSTEM_PERFORMANCE_INFORMATION structure is what a successful call to ZwQuerySystemInformation or NtQuerySystemInformation produces in its output buffer when given the information class SystemPerformanceInformation (0x02).
The SYSTEM_PERFORMANCE_INFORMATION structure is defined in WINTERNL.H from the Software Development Kit (SDK). The definition there has the whole structure as one array of 0x0138 bytes, named Reserved1. Documentation of NtQuerySystemInformation describes the structure as “opaque” and suggests that whatever is produced in it for the SystemPerformanceInformation case “can be used to generate an unpredictable seed for a random number generator.”
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_PERFORMANCE_INFORMATION is the same in both 32-bit and 64-bit Windows. The structure exists in three sizes:
Except for some reuse of members in the ealiest versions, the structure has changed only by extension. Early forms of the structure are supported in later versions simply by allowing callers to ask just for an old size.
Offset | Definition or Description | Versions | Remarks |
---|---|---|---|
0x00 |
LARGE_INTEGER IdleProcessTime; |
3.10 and higher | |
0x08 |
LARGE_INTEGER IoReadTransferCount; |
3.10 and higher | |
0x10 |
LARGE_INTEGER IoWriteTransferCount; |
3.10 and higher | |
0x18 |
LARGE_INTEGER IoOtherTransferCount; |
3.10 and higher | |
0x20 |
ULONG IoReadOperationCount; |
3.10 and higher | |
0x24 |
ULONG IoWriteOperationCount; |
3.10 and higher | |
0x28 |
ULONG IoOtherOperationCount; |
3.10 and higher | |
0x2C |
ULONG AvailablePages; |
3.10 and higher | |
0x30 |
ULONG CommittedPages; |
3.10 and higher | |
0x34 |
ULONG CommitLimit; |
3.10 and higher | |
0x38 |
ULONG PeakCommitment; |
3.10 and higher | |
0x3C |
ULONG PageFaultCount; |
3.10 and higher | |
0x40 |
ULONG CopyOnWriteCount; |
3.10 and higher | |
0x44 |
ULONG TransitionCount; |
3.10 and higher | |
0x48 |
ULONG CacheTransitionCount; |
3.10 and higher | |
0x4C |
ULONG DemandZeroCount; |
3.10 and higher | |
0x50 |
ULONG PageReadCount; |
3.10 and higher | |
0x54 |
ULONG PageReadIoCount; |
3.10 and higher | |
0x58 |
ULONG CacheReadCount; |
3.10 and higher | |
0x5C |
ULONG CacheIoCount; |
3.10 and higher | |
0x60 |
ULONG DirtyPagesWriteCount; |
3.10 and higher | |
0x64 |
ULONG DirtyWriteIoCount; |
3.10 and higher | |
0x68 |
ULONG MappedPagesWriteCount; |
3.10 and higher | |
0x6C |
ULONG MappedWriteIoCount; |
3.10 and higher | |
0x70 |
ULONG PagedPoolPages; |
3.10 and higher | |
0x74 |
ULONG NonPagedPoolPages; |
3.10 and higher | |
0x78 |
ULONG PagedPoolAllocs; |
3.10 and higher | |
0x7C |
ULONG PagedPoolFrees; |
3.10 and higher | |
0x80 |
ULONG NonPagedPoolAllocs; |
3.10 and higher | |
0x84 |
ULONG NonPagedPoolFrees; |
3.10 and higher | |
0x88 |
ULONG FreeSystemPtes; |
3.10 and higher | |
0x8C | unaccounted dword | 3.10 only | |
ULONG ResidentSystemCodePage; |
3.50 and higher | ||
0x90 | unaccounted dword | 3.10 only | |
ULONG TotalSystemDriverPages; |
3.50 and higher | ||
0x94 | unaccounted dword | 3.10 only | |
ULONG TotalSystemCodePages; |
3.50 and higher | ||
0x98 | unknown dword | 3.10 to 3.50 | |
ULONG Spare0Count; |
3.51 only | ||
ULONG NonPagedPoolLookasideHits; |
4.0 and higher | ||
0x9C | unknown dword | 3.10 to 3.50 | |
ULONG Spare1Count; |
3.51 only | ||
ULONG PagedPoolLookasideHits; |
4.0 and higher | ||
0xA0 | unknown dword | 3.10 to 3.50 | |
ULONG Spare3Count; |
3.51 to 5.0 | ||
ULONG AvailablePagedPoolPages; |
5.1 and higher | ||
0xA4 | unknown dword | 3.10 only | |
ULONG ResidentSystemCachePage; |
3.50 and higher | ||
0xA8 | unknown dword | 3.10 only | |
ULONG ResidentPagedPoolPage; |
3.50 and higher | ||
0xAC | unknown dword | 3.10 only | |
ULONG ResidentSystemDriverPage; |
3.50 and higher | ||
0xB0 |
ULONG CcFastReadNoWait; |
3.10 and higher | |
0xB4 |
ULONG CcFastReadWait; |
3.10 and higher | |
0xB8 |
ULONG CcFastReadResourceMiss; |
3.10 and higher | |
0xBC |
ULONG CcFastReadNotPossible; |
3.10 and higher | |
0xC0 |
ULONG CcFastMdlReadNoWait; |
3.10 and higher | |
0xC4 |
ULONG CcFastMdlReadWait; |
3.10 and higher | |
0xC8 |
ULONG CcFastMdlReadResourceMiss; |
3.10 and higher | |
0xCC |
ULONG CcFastMdlReadNotPossible; |
3.10 and higher | |
0xD0 |
ULONG CcMapDataNoWait; |
3.10 and higher | |
0xD4 |
ULONG CcMapDataWait; |
3.10 and higher | |
0xD8 |
ULONG CcMapDataNoWaitMiss; |
3.10 and higher | |
0xDC |
ULONG CcMapDataWaitMiss; |
3.10 and higher | |
0xE0 |
ULONG CcPinMappedDataCount; |
3.10 and higher | |
0xE4 |
ULONG CcPinReadNoWait; |
3.10 and higher | |
0xE8 |
ULONG CcPinReadWait; |
3.10 and higher | |
0xEC |
ULONG CcPinReadNoWaitMiss; |
3.10 and higher | |
0xF0 |
ULONG CcPinReadWaitMiss; |
3.10 and higher | |
0xF4 |
ULONG CcCopyReadNoWait; |
3.10 and higher | |
0xF8 |
ULONG CcCopyReadWait; |
3.10 and higher | |
0xFC |
ULONG CcCopyReadNoWaitMiss; |
3.10 and higher | |
0x0100 |
ULONG CcCopyReadWaitMiss; |
3.10 and higher | |
0x0104 |
ULONG CcMdlReadNoWait; |
3.10 and higher | |
0x0108 |
ULONG CcMdlReadWait; |
3.10 and higher | |
0x010C |
ULONG CcMdlReadNoWaitMiss; |
3.10 and higher | |
0x0110 |
ULONG CcMdlReadWaitMiss; |
3.10 and higher | |
0x0114 |
ULONG CcReadAheadIos; |
3.10 and higher | |
0x0118 |
ULONG CcLazyWriteIos; |
3.10 and higher | |
0x011C |
ULONG CcLazyWritePages; |
3.10 and higher | |
0x0120 |
ULONG CcDataFlushes; |
3.10 and higher | |
0x0124 |
ULONG CcDataPages; |
3.10 and higher | |
0x0128 |
ULONG ContextSwitches; |
3.10 and higher | |
0x012C |
ULONG FirstLevelTbFills; |
3.10 and higher | |
0x0130 |
ULONG SecondLevelTbFills; |
3.10 and higher | |
0x0134 |
ULONG SystemCalls; |
3.10 and higher | last member in 3.10 to 6.0 |
0x0138 |
ULONGLONG CcTotalDirtyPages; |
6.1 and higher | |
0x0140 |
ULONGLONG CcDirtyPageThreshold; |
6.1 and higher | last member in 6.1 |
0x0148 |
LONGLONG ResidentAvailablePages; |
6.2 and higher | |
0x0150 |
ULONGLONG SharedCommittedPages; |
6.2 and higher |
No use is known in version 3.10 of the three members at offsets 0x8C to 0x94. In contrast, at offsets 0x98 to 0xAC version 3.10 keeps four counters that the earliest known type information, for version 3.51, explicitly labels spare and two more that are used differently as early as version 3.50. Microsoft’s names may never be known. What the early versions count at offsets 0x98 to 0xA4 are waits for which the given reason is respectively WrLpcReceive, WrLpcReply, WrQueue or WrSpare0 (which was in those days defined as WrEventPair). Offsets 0xA8 and 0xAC in version 3.50 count times that the high and low events in an event pair get set.
It is not known how the sequence from Spare0Count to Spare3Count ever had a Spare2Count.