SYSTEM_PERFORMANCE_INFORMATION

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).

Documentation Status

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.

Layout

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.