ohmu
·
2026-10-15
1#pragma once
2
3#include <windows.h>
4#include <perflib.h>
5
6// Missing from <perflib.h> of MinGW-w64 SDK
7
8#define PERF_WILDCARD_COUNTER 0xFFFFFFFF
9#define PERF_WILDCARD_INSTANCE L"*"
10#define PERF_AGGREGATE_INSTANCE L"_Total"
11#define PERF_MAX_INSTANCE_NAME 1024
12
13typedef struct _PERF_INSTANCE_HEADER {
14 ULONG Size; // = sizeof(PERF_INSTANCE_HEADER) + sizeof(InstanceName) + sizeof(Padding)
15 ULONG InstanceId; // Instance ID.
16 // Followed by:
17 // WCHAR InstanceName[]; // Nul-terminated.
18 // WCHAR Padding[]; // Pad to a multiple of 8 bytes
19} PERF_INSTANCE_HEADER, *PPERF_INSTANCE_HEADER;
20
21typedef struct _PERF_COUNTER_IDENTIFIER {
22 GUID CounterSetGuid; // The GUID of the counterset.
23 ULONG Status; // Win32 error code indicating success/failure of the add/delete operation.
24 ULONG Size; // sizeof(PERF_COUNTER_IDENTIFIER) + sizeof(InstanceName) + sizeof(Padding)
25 ULONG CounterId; // CounterId, or PERF_WILDCARD_COUNTER for all counters.
26 ULONG InstanceId; // InstanceId, or 0xFFFFFFFF to not filter on instance ID.
27 ULONG Index; // Set by PerfQueryCounterInfo to the position in which the corresponding counter data is returned.
28 ULONG Reserved; // Reserved.
29 // Followed by:
30 // WCHAR InstanceName[];
31 // WCHAR Padding[];
32} PERF_COUNTER_IDENTIFIER, *PPERF_COUNTER_IDENTIFIER;
33
34typedef struct _PERF_DATA_HEADER {
35 ULONG dwTotalSize; // = sizeof(PERF_DATA_HEADER) + sizeof(PERF_COUNTER_HEADER blocks...)
36 ULONG dwNumCounters; // The number of PERF_COUNTER_HEADER blocks.
37 LONGLONG PerfTimeStamp; // Timestamp from a high-resolution clock.
38 LONGLONG PerfTime100NSec; // The number of 100 nanosecond intervals since January 1, 1601, in Coordinated Universal Time (UTC).
39 LONGLONG PerfFreq; // The frequency of a high-resolution clock.
40 SYSTEMTIME SystemTime; // The time at which data is collected on the provider side.
41 // Followed by:
42 // PERF_COUNTER_HEADER blocks...;
43} PERF_DATA_HEADER, *PPERF_DATA_HEADER;
44
45typedef enum _PerfCounterDataType {
46 PERF_ERROR_RETURN = 0, /* An error occurred when the performance counter value was queried. */
47 PERF_SINGLE_COUNTER = 1, /* Query returned a single counter from a single-instance. */
48 PERF_MULTIPLE_COUNTERS = 2, /* Query returned multiple counters from a single instance. */
49 PERF_MULTIPLE_INSTANCES = 4, /* Query returned a single counter from each of multiple instances. */
50 PERF_COUNTERSET = 6 /* Query returned multiple counters from each of multiple instances. */
51} PerfCounterDataType;
52
53typedef struct _PERF_COUNTER_HEADER {
54 ULONG dwStatus; // Win32 error code indicating success/failure of the query operation.
55 PerfCounterDataType dwType; // Result type - error, single/single, multi/single, single/multi, multi/multi.
56 ULONG dwSize; // = sizeof(PERF_COUNTER_HEADER) + sizeof(Additional data)
57 ULONG Reserved; // Reserved.
58 // Followed by additional data:
59 // If dwType == PERF_ERROR_RETURN: nothing.
60 // If dwType == PERF_SINGLE_COUNTER: PERF_COUNTER_DATA block.
61 // If dwType == PERF_MULTIPLE_COUNTERS: PERF_MULTI_COUNTERS block + PERF_COUNTER_DATA blocks.
62 // If dwType == PERF_MULTIPLE_INSTANCES: PERF_MULTI_INSTANCES block.
63 // If dwType == PERF_COUNTERSET: PERF_MULTI_COUNTERS block + PERF_MULTI_INSTANCES block.
64} PERF_COUNTER_HEADER, *PPERF_COUNTER_HEADER;
65
66typedef struct _PERF_MULTI_INSTANCES {
67 ULONG dwTotalSize; // = sizeof(PERF_MULTI_INSTANCES) + sizeof(instance data blocks...)
68 ULONG dwInstances; // Number of instance data blocks.
69 // Followed by:
70 // Instance data blocks...;
71} PERF_MULTI_INSTANCES, *PPERF_MULTI_INSTANCES;
72
73typedef struct _PERF_MULTI_COUNTERS {
74 ULONG dwSize; // sizeof(PERF_MULTI_COUNTERS) + sizeof(CounterIds)
75 ULONG dwCounters; // Number of counter ids.
76 // Followed by:
77 // DWORD CounterIds[dwCounters];
78} PERF_MULTI_COUNTERS, *PPERF_MULTI_COUNTERS;
79
80typedef struct _PERF_COUNTER_DATA {
81 ULONG dwDataSize; // Size of the counter data, in bytes.
82 ULONG dwSize; // = sizeof(PERF_COUNTER_DATA) + sizeof(Data) + sizeof(Padding)
83 // Followed by:
84 // BYTE Data[dwDataSize];
85 // BYTE Padding[];
86} PERF_COUNTER_DATA, *PPERF_COUNTER_DATA;
87
88_Success_(return == ERROR_SUCCESS)
89 ULONG
90 WINAPI
91 PerfEnumerateCounterSetInstances(
92 _In_opt_z_ LPCWSTR szMachine,
93 _In_ LPCGUID pCounterSetId,
94 _Out_opt_bytecap_post_bytecount_(cbInstances, *pcbInstancesActual) PPERF_INSTANCE_HEADER pInstances,
95 DWORD cbInstances,
96 _Out_ LPDWORD pcbInstancesActual);
97
98_Success_(return == ERROR_SUCCESS)
99 ULONG
100 WINAPI
101 PerfOpenQueryHandle(
102 _In_opt_z_ LPCWSTR szMachine,
103 _Out_ HANDLE* phQuery);
104
105_Success_(return == ERROR_SUCCESS)
106 ULONG
107 WINAPI
108 PerfCloseQueryHandle(
109 _In_ HANDLE hQuery);
110
111_Success_(return == ERROR_SUCCESS)
112 ULONG
113 WINAPI
114 PerfAddCounters(
115 _In_ HANDLE hQuery,
116 _Inout_bytecount_(cbCounters) PPERF_COUNTER_IDENTIFIER pCounters,
117 DWORD cbCounters);
118
119_Success_(return == ERROR_SUCCESS)
120 ULONG
121 WINAPI
122 PerfDeleteCounters(
123 _In_ HANDLE hQuery,
124 _Inout_bytecount_(cbCounters) PPERF_COUNTER_IDENTIFIER pCounters,
125 DWORD cbCounters);
126
127_Success_(return == ERROR_SUCCESS)
128 ULONG
129 WINAPI
130 PerfQueryCounterData(
131 _In_ HANDLE hQuery,
132 _Out_opt_bytecap_post_bytecount_(cbCounterBlock, *pcbCounterBlockActual) PPERF_DATA_HEADER pCounterBlock,
133 DWORD cbCounterBlock,
134 _Out_ LPDWORD pcbCounterBlockActual);