By now you must be wondering how the data is structured. We have a nifty table at the end of this section detailing the contents of each of the performance data structures, and the structures are defined in excruciating detail in the WINPERF.H header file supplied with the Windows NT SDK.
The structure of the data retrieved by RegQueryValueEx begins with a single header structure, PERF_DATA_BLOCK. The PERF_DATA_BLOCK structure is followed by the data for the various object types returning data. For each object type defined on the system there is a PERF_OBJECT_TYPE structure and the accompanying data for that object.
Figure 12.3 Basic structure of performance data
The PERF_DATA_BLOCK structure describes the system and the performance data. Each PERF_OBJECT_TYPE structure describes the performance data for one type of object.
Following the PERF_OBJECT_TYPE structure for each object is a list of PERF_COUNTER_DEFINITION structures, one for each counter defined for the object.
How the performance data for each object is structured depends on whether the object has instances. You'll remember from earlier in this book that some objects, such as memory, do not have instances. Objects such as thread, disk, and processor do have one or more instances. For example, each thread in the system is an instance of the thread object type.
For an object with no instances, the data following the PERF_COUNTER_DEFINITION structures consists of a single PERF_COUNTER_BLOCK structure, followed by the data for each counter.
Figure 12.4 Performance data structure of an object with no instances
For an object type with one or more instances, the list of counter definitions is followed by a PERF_INSTANCE_DEFINITION structure and a PERF_COUNTER_BLOCK structure for each instance.
Figure 12.5 Performance data structure of an object with one or more instances
Table 12.1 Performance Data Structures
Data structure | Contents |
PERF_DATA_BLOCK | Length of the entire data block, including all objects and their counters. |
Offset to the Unicode system name and its length. | |
Time stamp. | |
Size of entire data structure. | |
Number of object type definitions contained in this data. | |
Offset of the first object type definition. | |
PERF_OBJECT_TYPE | Size of the structure and the accompanying data for this object type. |
Number of counters defined for the object type. | |
Number of instances of this object type. | |
Parent of this object (if any). | |
Level of expertise required by the user to understand this object's data. | |
Offsets to the first definition counter under this object, and to the next PERF_OBJECT_TYPE structure. | |
Indexes to the object name and Explain text in the title database. | |
PERF_COUNTER_DEFINITION | Type of counter. |
Offset to the counter and its size. | |
The level of expertise required by the user to understand this counter. | |
Indexes to counter name and Explain text. | |
PERF_COUNTER_BLOCK | Length of the PERF_COUNTER_BLOCK structure and the data that follows it. |
PERF_INSTANCE_DEFINITION | Offset to instance name, and its length. |
Index to parent instance (if any). | |
Unique identifier (if any). |