Performance Monitoring

Performance monitoring is the process of capturing and analyzing the performance data that applications, services, and drivers provide to determine system bottlenecks and fine-tune system and application performance. You can do this either by writing a program that calls the registry interface or the Performance Data Helper (PDH) interface, or by using applications provided with Windows NT and Windows 2000. The method you choose will typically depend on how much data you want to monitor and what kind of analysis you want to perform on the data.

  • About Performance Monitoring
  • Using Performance Monitoring
  • Performance Monitoring Reference
Microsoft Platform SDK, February 2001 Edition.
This content last built on Thursday, February 01, 2001.


About Performance Monitoring

The areas covered in this section are the following:

  • Performance Data Collection
  • Performance Monitoring Architecture
  • Performance Registry Interface
  • Performance Data Helper


Performance Data Collection

The following means of collecting performance data are provided in Windows NT or Windows 2000:

  • Performance-monitoring applications. These applications present selected performance data to the user. They include the Windows NT Performance Monitor (Perfmon.exe), the Windows 2000 Performance Monitor (the ActiveX® control), and custom applications. The Windows NT Performance Monitor is not included with Windows 2000. For more information, see Performance Monitor.
  • Custom performance-monitoring applications. You can create a custom performance-monitoring application that obtains counter information using one of two supported programming interfaces. For more information, see Performance Data Helper and Performance Registry Interface.
  • Performance extension DLLs. These DLLs retrieve information from the object on behalf on the programming interfaces. For more information, see Creating a Performance Extension DLL.

Among other things, the Windows 2000 Performance Monitor allows you to define a set of performance data that will be retrieved from the system. You can then graph this data according to your specifications, or write it to a file for archiving and further analysis. Refer to the help pages in the Windows 2000 Performance Monitor for more information on how to use it. You can control the behavior of the Windows 2000 Performance Monitor from Visual Basic® programs and ActiveX®-compliant containers, such as Microsoft® Office 97 applications, through the Windows 2000 Performance Monitor automation programming interface. This interface cannot be used with the Windows NT Performance Monitor. Refer to the System Monitor automation programming interface specification for more information.

Note In this document, use of the Windows 2000 Performance Monitor is emphasized, and a distinction between the Windows 2000 Performance Monitor and the Windows NT Performance Monitor is made only where the functionality of the two differs.


Performance Monitoring Architecture

The following topics contain diagrams that illustrate how performance monitoring applications, the registry and PDH interfaces, and the performance extension DLLs work together in both Windows NT and Windows 2000.

  • Windows 2000 Performance Monitoring
  • Windows NT 4.0 Performance Monitoring


Windows 2000 Performance Monitoring

The following diagram illustrates the performance-monitoring architecture in Windows 2000 and Whistler.

Custom application A uses the registry interface to obtain counter information. Custom application B and the Performance Monitor use the PDH interface to obtain counter information. In turn, the PDH interface functions can use either the registry interface or WMI. PDH functions obtain performance data provided by WMI through providers that use performance extension DLLs or the high-performance data provider object.

The extension DLLs expose the Open, Collect, and Close functions. For more information, see Creating a Performance Extension DLL.

For more information on creating and using WMI providers, refer to the WMI SDK documentation.


Windows NT 4.0 Performance Monitoring

The following diagram illustrates the performance-monitoring architecture in Windows NT 4.0

The Windows NT Performance Monitor and custom application B use the registry interface to obtain counter information. Custom application A uses the PDH interface to obtain counter information. PDH in turn uses the registry interface. The extension DLLs expose the Open, Collect, and Close functions. For more information, see Creating a Performance Extension DLL.


Performance Registry Interface

The registry interface to the performance data is older than the PDH interface and has more extensive functionality. However, the PDH interface is easier to use for most performance data collection tasks. The PDH interface is essentially a higher-level abstraction of the functionality that the registry interface provides, oriented more towards operations on single counters rather than groups of counters.

For an overview of the registry interface, see the following topics:

  • Performance Data Format
  • The HKEY_PERFORMANCE_DATA Key

For information on obtaining performance data through calls to registry functions, refer to Using the Registry Interface.

For information on PDH, see Performance Data Helper.


Performance Data Format

The format of the data retrieved by the RegQueryValueEx function begins with a fixed-length header structure, PERF_DATA_BLOCK. The PERF_DATA_BLOCK structure describes the system and the performance data. The PERF_DATA_BLOCK structure is followed by variable number of variable-length object data items. The header of the object contains the offset of the next object in the list. The following diagram shows the basic performance data structure.

There are two formats for the object data items: one that supports multiple instances, and the other that does not support multiple instances.

Each object information block contains a PERF_OBJECT_TYPE structure, which describes the performance data for the object. The PERF_OBJECT_TYPE structure is followed by a list of PERF_COUNTER_DEFINITION structures, one for each counter defined for the object. For an object with only one instance, the list of PERF_COUNTER_DEFINITION structures is followed by a single PERF_COUNTER_BLOCK structure, followed by the counter data. Each PERF_COUNTER_DEFINITION structure contains the offset from the start of the PERF_COUNTER_BLOCK structure to the corresponding counter data. The following diagram shows the structure of a performance object that does not support multiple instances.

For an object type that supports multiple instances, the list of PERF_COUNTER_DEFINITION structures is followed by a list of instance information blocks (one for each instance). Each instance information block contains a PERF_INSTANCE_DEFINITION structure, the name of the instance, and a PERF_COUNTER_BLOCK structure. The following diagram shows the structure of a performance object that supports two instances.


The HKEY_PERFORMANCE_DATA Key

The performance data is accessed through the registry key HKEY_PEFORMANCE_DATA. Each software component creates keys for its objects and counters when it is installed and writes counter data while it is executing. You can access this data as you would access any other registry data, using the registry functions. However, although you use the registry to collect performance data, the data is not stored in the registry database. Instead, calling the registry functions with the HKEY_PEFORMANCE_DATA key causes the system to collect the data from the appropriate system object managers.

To obtain performance data from the local system, use the RegQueryValueEx function, with the HKEY_PERFORMANCE_DATA key. The first call opens the key; you do not need to explicitly open the key first. However, be sure to use the RegCloseKey function to close the handle to the key when you are finished obtaining performance data. The user cannot install or remove a software component while its performance data is in use.

To obtain performance data from a remote system, you must use the RegConnectRegistry function, with the computer name of the remote system and the HKEY_PERFORMANCE_DATA key. This call retrieves a key representing the performance data for the remote system. To retrieve the data, call RegQueryValueEx using this key, rather than the HKEY_PERFORMANCE_DATA key.


Performance Data Helper

The performance data helper (PDH) interface calls the registry interface to retrieve performance data.

  • Performance Objects and Counters
  • PDH Queries
  • Performance Data Sources
  • Log Files

For information on the PDH functions used to collect performance data, and the order in which to call them, refer to Using the PDH Interface.


Performance Objects and Counters

The mechanism by which performance data is collected is the counter. A counter is a performance data item whose name is stored in the registry. Each counter is related to a specific area of system functionality. Examples include a processor's busy time, memory usage, or the number of bytes received over a network connection. Each counter is uniquely identified through its name and its path, or location. In the same way that a file path includes drives, directories, subdirectories, and file names, a counter path consists of four elements: the machine, the object, the object instance, and the counter name. The syntax of a counter path is:

\\Machine\PerfObject(ParentInstance/ObjectInstance#InstanceIndex)\Counter

Most performance counters in Windows NT and Windows 2000 increment and are never reset to zero. Therefore, to obtain performance data, perform the following steps.

  • Take a snapshot of the relevant performance counters at the beginning of a time interval.
  • Take a snapshot of the same performance counters at the end of the time interval.
  • Find the difference between the counter values in the snapshots and apply the appropriate calculation function.

The machine specification is the network name of the computer where the counter resides. This specification can be omitted if the counter is located on the local machine; therefore, a single path string without the machine specification can be used on any computer the counter is located on.

A machine's performance objects include physical components, such as processors, disks, and memory. There are also system objects, such as processes and threads. Each object is related to a functional element within the computer and has a set of standard counters assigned to it. These objects are listed in the PDH browse dialog box (see PdhBrowseCounters) and in the Add Counters dialog box in the Windows 2000 Performance Monitor, and you must include them in the counter path. Performance data is grouped by the performance object to which is it related. For a list of the system performance objects and performance counters, refer to the counter list contained in the Counters.chm file provided with the Windows 2000 Resource Kit documentation. The Counters.chm file is located in the ResourceKit folder when the Resource Kit is installed.

In certain cases, there may be several copies of the same object. For example, several processes and threads run simultaneously, and some computers contain more than one processor. These object copies are called object instances. Each object instance has a set of standard counters assigned to it. If an object can have more than one instance, an instance specification must be included in the counter path.

The format of the instance specification depends on the object type. If the object has simple instances, then the format is only the instance name enclosed in parentheses. For example:

(Explorer)

If the instance of this object also requires a parent instance name, the parent instance name must come before the object instance and be separated by a forward slash character. For example:

(Explorer/0)

If the object has multiple instances that have the same name string, they can be indexed sequentially by specifying the instance index prefixed by a pound sign. Instance indexes are 0-based, so all instances have an implicit index of "0". For example:

(Explorer/0#1)

The \Counter component is required; it specifies the performance counter. The counter names are displayed in the PDH browse dialog box and in the Add Counter dialog box in the Windows 2000 Performance Monitor. The counters associated with the selected object are displayed.

The following are two common counters in the PDH counter path format:

\Processor(0)\% Processor Time
\System\% Total Processor Time

For more information on counters, see Adding Counters to a Query and Working with Counters, Performance Objects, and Machines.


PDH Queries

PDH functions work with queries and counters. A query is a set of performance counters that are grouped together so that you can collect their data at the same time. A query can contain one or more counters, and a counter can be contained in more than one query.

For information on how to create and run queries, refer to Working with Queries.


Performance Data Sources

Many PDH functions collect data from one of two types of sources: real-time data sources or log files.

A real-time data source provides data that describes the current performance activity in the system. The term current activity is also used to describe this kind of data source. Note that this usage of the term "real time" is not the standard use. While the PDH interface generally provides the data in a real-time fashion, threads with a higher priority of execution can postpone delivery of the data.

Currently, there are two real-time data sources: the registry interface and WMI providers. Refer to the WMI documentation for more information on WMI providers.


Log Files

Performance log files are binary or text files that contain performance data values along with the time stamp of each value and the name of the counter that provided the values. Optionally, they can also contain annotations and a log file catalog that indexes the data. Several log file formats are supported.


Log File Formats

Performance data can be stored in four formats: comma-separated-value (CSV), tab-separated-value (TSV), binary, and Perfmon format.

The fields of a record within a CSV log file are delimited by double-quotes and commas. The fields of a record within a TSV log file are delimited by double-quotes and tab characters.

The first line of CSV-format and TSV-format log files serves as the header, providing information about the format of the file, the version of the PDH interface used to create the log file, and the names and paths of each of the counters to the PDH.

Both the Perfmon and binary log file formats are proprietary formats developed at Microsoft. The Perfmon format is the format the Performance Monitor uses when it writes counter data to a log file. The binary format provides all of the information contained in the Perfmon format, but in a more space-efficient manner. The Windows 2000 Performance Monitor uses the binary format by default.

Be aware that the PDH library can open a log file in the Perfmon format only for reading.


Log File Catalog

The performance log file catalog is an index of all of the data values in a binary performance log file. This can speed access to particular values in large performance log files while it increases the size of the file slightly. By default, performance log files are created without a catalog.

You can choose to create a catalog in a log file when it is created, or create a catalog in an existing log file that does not have one. Catalogs should be updated when the performance data collection session is ended and the query has been closed. They can be updated at any time, but updating the catalog while collecting data will slow the data collection.

Performance log files in the CSV, TSV, and Perfmon format cannot contain catalogs.


Using Performance Monitoring

  • Using the PDH Interface
  • Using the Registry Interface
  • Creating a Performance Extension DLL


Using the PDH Interface

The basic process of using the PDH interface to collect performance data consists of the following steps.

  1. Create a query.
  2. Add counters to the query.
  3. Collect the performance data.
  4. Process the performance data.
  5. Close the query.

You can use this process to collect performance data from either real-time sources or log files. The collected data can be written to log files or displayed. Refer to Working with Log Files for more information on how to write performance data to log files.

You can obtain Information about specific counters and the performance data values they provide through PDH interface functions. Working with Counters, Performance Objects, and Machines describes how to obtain and set this information.

You can also use the PDH interface to obtain information about specific queries. Refer to Working with Queries for more on this topic.

The user can be prompted for both the data source and the name and location of the counters added to the query in Step 2 of the preceding list. Refer to Browsing Counters for information on how to do this.

You can also access counters on remote machines. Refer to Accessing Counters on Remote Machines for information on how to do this.

The following are useful things you can do with the PDH library that are adjuncts to the basic data collection procedure.

  • Determining the Version of the Currently Installed PDH DLL
  • Checking PDH Interface Return Values
  • Examples


Determining the Version of the Currently Installed PDH DLL

You may need to determine the version of the PDH DLL that is currently installed on your system to know whether some of the more recently included functionality, like log file creation and access, is available to you.

The PdhGetDllVersion function provides an easy way to get this information.


Accessing Counters on Remote Machines

By default, PDH functions access counters on the machine the PDH library is installed on. If you want to access counters located on another machine, call the PdhConnectMachine function with the name of that machine before accessing them. This establishes a connection to the specified machine for subsequent accesses of counters on that machine. You can call PdhConnectMachine many times to access counters on many machines.

The other way the access counters on remote machines is to specify the machine name in the counter path passed to a call to PdhAddCounter. For more information on adding counters with PdhAddCounter, refer to Adding Counters to a Query.


Browsing Counters

You can call the PdhBrowseCounters function to display the following dialog box, which lets you browse and select performance counters.

You control the configuration of the dialog box by setting members of the PDH_BROWSE_DLG_CONFIG structure that you pass to PdhBrowseCounters. The szReturnPathBuffer member contains a pointer to a buffer you allocate. The cchReturnPathLength member contains the size of the buffer you allocated. This buffer provides a communication link between your application and the dialog box. If you want to define a callback function to process the counter names returned by the browser, use the CounterPathCallback function.

When the dialog box is first displayed, the default performance object and the default counter will be automatically selected if the data source is specified as current activity. Default performance objects and default counters are not supported if the data source is a log file. To obtain these settings through the PDH interface, call the PdhGetDefaultPerfObject and PdhGetDefaultPerfCounter functions. The default object and counter settings can be retrieved, and not set, through the PDH and registry interfaces.

By calling the PdhSelectDataSource function, you can display a dialog box prompting the user to select whether the data source is real-time or a log file, and, if it is a log file, its name. The following data source dialog is displayed first.

If the user knows the name of the log file, he or she can enter it in the following dialog box. If the log file name is not known, the user can click the ellipsis button in the dialog box to display the following file browser.

If you do not want the data source dialog to be displayed, you can call PdhSelectDataSource to display only the file browser catalog. To do this, specify PDH_FLAGS_FILE_BROWSER_ONLY as the second parameter of the call to PdhSelectDataSource.

You can use PdhSelectDataSource in conjunction with PdhBrowseCounters to allow the user even more performance data input options.


Collecting Performance Data

After you create a query and add counters to it, call the PdhCollectQueryData function to retrieve the current raw data for all counters in the query. Read the counter values by calling PdhCollectQueryData for each performance data sample you want to read.

The one exception where you would not use PdhCollectQueryData to collect performance data is when performance data is to be written to a log file. Refer to Opening a Log File for Writing and Writing to the Log File for more information on this procedure.

Many counters, such as rate counters, require two data samples to calculate a formatted data value. Do the following to collect these samples.

  • To provide a starting value, call PdhCollectQueryData.
  • To get the ending value, call PdhCollectQueryData again after a set period of time. Call Sleep to implement this waiting period.

Performance data collection can create and trigger a user-defined event. One example of when you may want this to happen is when sampling real-time data at regular intervals. Use the PdhCollectQueryDataEx function to do this. The process of calling PdhCollectQueryDataEx is the following.

  • Create an event by calling the CreateEvent function.
  • Pass the event handle into the call to PdhCollectQueryDataEx.

PdhCollectQueryDataEx will return immediately and create a timing thread. This timing thread will wait the specified interval of time and then collect a sample of performance data and set the event. When set, this event signals the main thread that performance data is available.


Displaying Performance Data

The raw value of many counters may not be useful for you—you might need to format the values for display. To get the information in the form described by most counter names, you need to compute the displayable value based on this raw data. Pdh functions can do this for you. For example, the Page Faults/Sec counter simply counts page faults, so if you view the raw data, you see a running total of page faults. To get the rate implied by the counter name, page faults per second, you need to call the PdhGetFormattedCounterValue function. In this case, the function divides the difference between two samples by the time between the samples. The PdhGetFormattedCounterValue function performs its computations on the sample returned by the last call to PdhCollectQueryData.

You can retrieve raw counter data with the PdhGetRawCounterValue function. If the raw data will be formatted later, store the raw data, and call the PdhFormatFromRawValue function to perform the calculation on the stored data. For time-based counter values, call PdhGetCounterTimeBase before PdhFormatFromRawValue to get the counter's time base.

Note The PdhCalculateCounterFromRawValue function incorporates the functionality of PdhGetCounterTimeBase and PdhFormatFromRawValue into one function.

PdhGetFormattedCounterValue and PdhGetRawCounterValue are used to get single counter values. In situations where you may want to retrieve more than one counter value, the PdhGetFormattedCounterArray and PdhGetRawCounterArray functions are provided. PdhGetFormattedCounterArray and PdhGetRawCounterArray accept only counter handle (hCounter) values that have been created with PdhAddCounter where the wildcard characters in the counter name string were specified for instance names, not performance object or counter names. For example, a counter handle created with the counter name string "\Explorer(*)\ID Process" is valid for use with PdhGetFormattedCounterArray and PdhGetRawCounterArray. A counter handle created with the counter name string "\Processor\* Bypasses/sec" is not.

In both of these functions, the counter values are returned in a buffered set of PDH_RAW_COUNTER_ITEM structures in the case of PdhGetRawCounterArray and PDH_FMT_COUNTERVALUE_ITEM structures in the case of PdhGetFormattedCounterArray.

Note that there are no links between the structures; therefore, the read pointer must be moved forward the number of bytes corresponding to the size of a structure to get the next counter value in the array. When you have retrieved an array of raw counter values, the PdhComputeCounterStatistics function will take the buffered counter values and compute the minimum, maximum, and mean values. It returns the statistical values in a PDH_STATISTICS structure. An example of when this would be done is in compressing a log file. To compress a log file, call PdhComputeCounterStatistics to compute the mean of a number of raw counter values and then write the mean to an output log file as a log file record.

Remember to check the CStatus member of the PDH_RAW_COUNTER structure (contained in the PDH_RAW_COUNTER_ITEM structure you pass into PdhComputeCounterStatistics) for a value of PDH_CSTATUS_NEW_DATA or PDH_CSTATUS_VALID_DATA before reading the values from the structure. If the value of CStatus is anything other than PDH_CSTATUS_NEW_DATA or PDH_CSTATUS_VALID_DATA, the counter values are not valid.


Working with Queries

  • Creating a Query
  • Adding Counters to a Query
  • Removing a Counter from a Query
  • Closing the Query
  • Setting a Time Range for a Query
  • Determining Whether a Query is Reading from a Real-time Data Source


Creating a Query

To create a new query, call the PdhOpenQuery function. The function returns a handle to the query to be used in other PDH function calls. You can create more than one query to be used in your program by calling PdhOpenQuery for each query.

When reading performance data from a real-time source, specify NULL as the first parameter of the PdhOpenQuery call. When reading performance data from a log file, specify the name of the log file as the first parameter.


Adding Counters to a Query

After you create a query, call the PdhAddCounter function to add a counter to the query. Call PdhAddCounter for each counter to be added to the query. You can use one of the following methods to provide PdhAddCounter with a fully qualified counter string.

  • Define the counter path as a static string and pass it into PdhAddCounter. Use this method if you always monitor the same counter, and if you are familiar with the correct syntax of a counter path. Refer to Performance Objects and Counters for a description of this syntax. Keep in mind that you can specify wildcard characters in your counter string.
  • Initialize a PDH_COUNTER_PATH_ELEMENTS structure with the names of the machine, object, counter, and instance, then pass this structure into a call to PdhMakeCounterPath. Given a counter name and the name of its object, PdhMakeCounterPath will return a string containing the specified performance object elements in the counter path syntax described in Performance Objects and Counters. Use this method if the syntax of the fully qualified counter path is not determined at run time.
  • Call PdhExpandCounterPath to get a list of counter names that match the wildcard characters in the counter name you passed in. Then scan through the returned array of counter names and add the counters you want from this array with PdhAddCounter. PdhExpandWildCardPath can also be used for this purpose if you want to use a log file as the source of the counter name list, or if you have wildcard characters in the counter and instance names and want to expand either the counter or the instance name, or you want to expand the names of counters that reside on remote machines.
  • Call the PdhBrowseCounters function to display the PDH browse dialog box. The dialog box allows the user to browse and select performance counters. For more information, refer to Browsing Counters.

If you're returning performance data from a log file, you can also define a time range within which the query collects performance data. For more information on how to set and get query-time ranges, refer to the following sections.

  • Setting a Time Range for a Query
  • Getting the Time Range of a Performance Data Set in a Log File


Removing a Counter from a Query

You can call the PdhRemoveCounter function to remove a counter from a query at any time after the counter has been added to the query and the query is closed.


Closing the Query

After you finish collecting data for a query, call the PdhCloseQuery function to close the query and release all allocated system resources. PdhCloseQuery closes all counter handles associated with the query.


Setting a Time Range for a Query

If your data source is a log file, you have the option of defining a time range for a query, which will determine the period of time during which performance data will be collected from the log file. You use the PdhSetQueryTimeRange function to do this. PdhSetQueryTimeRange is not used for queries that collect performance data from real-time data sources.

PdhSetQueryTimeRange sets the start and stop times for the query to the 64-bit (LONGLONG) beginning and ending time values in the PDH_TIME_INFO structure passed in as the second parameter. The standard method for creating these LONGLONG time range values is the following.

  1. Allocate a SYSTEMTIME structure and initialize the fields with the desired time value.
  2. Convert the SYSTEMTIME structure time values to FILETIME structure time values by calling SystemTimeToFileTime.
  3. Cast the FILETIME structure as a LONGLONG value, keeping in mind the structure member padding conventions of your platform and compiler.
  4. Copy the LONGLONG value to the appropriate field in the PDH_TIME_INFO structure.

If you want to obtain the time range of all of the performance data contained in a log file, use the PdhGetDataSourceTimeRange function. PdhGetDataSourceTimeRange returns this information in a PDH_TIME_INFO structure.


Determining Whether a Query is Reading from a Real-time Data Source

When an application opens multiple queries, you may need to determine from within the program what kind of data source a particular query is reading from. While a specific query is open, you can call the PdhIsRealTimeQuery function to determine this.


Working with Counters, Performance Objects, and Machines

  • Getting Counter Information
  • Determining Whether a Counter Is Located on a Machine
  • Setting the Scale Factor of a Counter
  • Getting the Time Base of a Counter
  • Converting Raw Counter Values to a Specified Format
  • Enumerating Performance Objects
  • Enumerating Machines
  • Obtaining Counter Path Elements from a Counter Path
  • Determining a Counter's Name or Index
  • Determining a Counter's Path Based on a Wildcard String


Getting Counter Information

The PDH library of functions provides a way to obtain information about the path and value of a particular counter.

To obtain counter information using a counter handle returned by PdhAddCounter, call the PdhGetCounterInfo function. The counter information is returned as a PDH_COUNTER_INFO structure. You can call PdhGetCounterInfo at any time between the opening and closing of the counter.

Refer to Adding Counters to a Query for more information on PdhAddCounter.


Determining Whether a Counter Is Located on a Machine

To determine whether a counter is installed on a particular machine, pass the fully qualified counter path into a call to the PdhValidatePath function. If the counter is located on the specified machine, ERROR_SUCCESS will be returned. PdhValidatePath validates the entire path; therefore, if any object in the path doesn't exist, the return value of the function will identify it.

PdhValidatePath verifies the specified counter path in this order: machine, performance object, instance, and counter.


Setting the Scale Factor of a Counter

Often a counter value must be scaled up or down by a certain factor for a calculation, or to be displayed. The PdhSetCounterScaleFactor function allows you to do this for all values returned by a particular counter. Counter values can be scaled by a power of ten from a factor of -7 to 7.


Getting the Time Base of a Counter

Each counter that returns time-based performance data has a time base defined for it. The time base of a counter is the number of times a counter samples data per second. To determine this time base for a specific counter, call the PdhGetCounterTimeBase function. If a non-time-based counter is used, PDH_INVALID_ARGUMENT will be returned.

The PdhFormatFromRawValue function requires the time base returned by PdhGetCounterTimeBase for its performance data value calculations.


Converting Raw Counter Values to a Specified Format

Use PdhCalculateCounterFromRawValue to convert raw counter values to a format you specify. PdhCalculateCounterFromRawValue can also convert two raw counter values for time-based calculations that require two samples.


Enumerating Performance Objects

PdhEnumObjects returns a list of all of the performance objects that exist on the specified machine. PdhEnumObjectItems returns a list of all of the counters and instances contained within a specified performance object. You can also use PdhEnumObjectItems to identify the objects and counters that provided the performance data contained in a log file. Keep in mind that repeated calls to PdhEnumObjectItems will return the same list of counters and instances unless you call PdhEnumObjects to refresh the list of performance objects first. Refer to the reference page for PdhEnumObjectItems for more information.

An example of when you would use PdhEnumObjects and PdhEnumObjectItems is when you want to read a log file with unknown counter data.

Refer to Enumerating Process Objects for a code example that uses PdhEnumObjects and PdhEnumObjectItems.


Enumerating Machines

The PDH library maintains a list of machines that have been connected to by calls to the PdhConnectMachine function. PdhEnumMachines retrieves this list of machines into a buffer of MULTI_SZ strings.


Obtaining Counter Path Elements from a Counter Path

PdhParseCounterPath performs the converse operation of PdhMakeCounterPath. While PdhMakeCounterPath creates a string containing a fully qualified counter path from the counter path element names specified in a PDH_COUNTER_PATH_ELEMENTS structure, PdhParseCounterPath parses a string containing a fully qualified counter path and extracts the performance object names into a PDH_COUNTER_PATH_ELEMENTS structure.

You can perform a similar process for counter instances when the instance name is complex and has a parent instance and instance index. Given a string containing information about an instance, the PdhParseInstanceName function will extract and return details about the instance name, its parent counter, and its index number. An example of when PdhParseInstanceName would be used is when the index number of a particular instance of a process—for example, an Internet Explorer root process—must be obtained.


Determining a Counter's Name or Index

For each object and counter in the registry, there is a corresponding numeric index. The purpose of a counter index is to facilitate searches for a particular counter name and description. For more information on counter indexes, refer to Retrieving Counter Names and Explanations. For example code that compiles a list of all counter indexes in the registry using the registry interface, refer to Displaying Object, Instance, and Counter Names.

The counter name and index provide two ways to access a particular counter; however, you must know either the name or the index to do so. If you know the index of a counter and want to obtain the name, call the PdhLookupPerfNameByIndex function. If you know the name of a counter and want to find the index, call the PdhLookupPerfIndexByName function.

With both functions, the machine name can be expressed as a DNS name or an IP address, depending on which network protocols you have installed.


Determining a Counter's Path Based on a Wildcard String

Given a string containing a counter path with wildcard characters, the PdhExpandCounterPath function returns all counter paths that match the specified path. The list of matching counter paths are returned as one string, and you must allocate sufficient memory space for this string. Each counter path is terminated by a NULL character. You can allocate this memory in blocks at run time by calling PdhExpandCounterPath repeatedly and checking for a PDH_MORE_DATA return value.


Working with Log Files

Two PDH functions open log files: PdhOpenQuery and PdhOpenLog. The function you use to open a log file depends on whether you are opening the log file for a read or a write operation.

  • Opening a Log File for Reading
  • Opening a Log File for Writing and Writing to the Log File
  • Getting the Size of a Log File
  • Getting the Time Range of a Performance Data Set in a Log File
  • Closing a Log File


Opening a Log File for Reading

Open a log file for reading by calling PdhOpenQuery. PdhOpenQuery can only be used to open a log file for a read operation.

Refer to Creating a Query for more information on how to use PdhOpenQuery.


Opening a Log File for Writing and Writing to the Log File

Open a log file for writing by calling PdhOpenLog and specifying a log file name as the szDataSource parameter. PdhOpenLog is used only to open a log file for a write operation.

Do the following to write to a log file:

  1. Call PdhOpenQuery to establish the source of the performance data that will be written to the log file. This can be either a real-time source or a log file.
  2. Call PdhOpenLog, passing in the handle to the query object created by the earlier call to PdhOpenQuery.
  3. Update the query and collect the performance data from the data source by calling PdhUpdateLog.


Getting the Size of a Log File

PdhGetLogFileSize returns the size, in bytes, of the specified log file. Use this function when you need to allocate memory for a buffer you will be writing the contents of a log file into.


Getting the Time Range of a Performance Data Set in a Log File

The time range of a performance data set stored in a log file can be obtained by calling the PdhGetDataSourceTimeRange function. PdhGetDataSourceTimeRange returns the time range information in a PDH_TIME_INFO structure.

If PdhGetDataSourceTimeRange is called with the data source specified as anything other than a log file, the function will leave the PDH_TIME_INFO structure uninitialized and return PDH_DATA_SOURCE_IS_REAL_TIME.


Closing a Log File

You can call either PdhCloseQuery or PdhCloseLog to close a log file. Which function you use depends on which function you used to open the log file.

  • If you used PdhOpenQuery to open the log file for reading, call PdhCloseQuery to close it. You would do this if, for example, the data in one log file is converted to another format and written to another log file.
  • If you used PdhOpenLog to open the log file for writing, call PdhCloseLog to close it.

PdhCloseQuery and PdhCloseLog close both local counters and counters located on other machines.


Checking PDH Interface Return Values

The return value of PDH functions indicates the success or error of the function call, which is distinct from the status of the counter data. Always check the CStatus member of a counter value returned in the PDH structures to ensure that the data returned is valid before you use it. If the value of the CStatus member does not indicate success, do not use the data. The following are the possible status values for counters:

Value | Meaning
PDH_CSTATUS_NO_MACHINE | PDH was unable to connect to the machine specified in the counter path. If this status is returned when the counter is being added, the counter is not completely initialized. Each time the query is updated, PDH retries the connection. When the connection is established, normal data collection resumes.
PDH_CSTATUS_NO_OBJECT | The specified machine was found, but no matching performance object was found on that machine. If this status is returned when the counter is being added, the specified counter is not included in the query. If this status is returned by an active counter, the data for that counter is invalid. Each time the data is requested, PDH tries to obtain this counter data.
PDH_CSTATUS_NO_INSTANCE | The specified instance was not found in the object. If this status is returned while the counter is being added to the query, the counter is successfully added to the query, but no data is available until the specific instance appears and a successful status is returned.
PDH_CSTATUS_NO_COUNTER | The specified counter was not found in the specified object. If this status is returned when the counter is being added, then the counter is not added to the query. If this status is returned after a data update, the data for that counter is invalid. Each time the data is requested, PDH tries to obtain this counter data.
PDH_CSTATUS_INVALID_DATA | The counter was successfully found, but the data returned is not valid. One possible cause for this value is when the data of a normally increasing counter is less than the previous value. Another possible cause is a system timer that is not correct.
PDH_CSTATUS_VALID_DATA | The data for the counter was returned successfully, but is unchanged from the last time the counter was read.
PDH_CSTATUS_NEW_DATA | The data for the counter was returned successfully and is different from the last time the counter was read. PDH_CSTATUS_NEW_DATA can be returned on a rate counter even if the resulting rate is the same as the last sample. This is because the raw data value that is used in the determination of this status value has changed, not the computed rate.
PDH_MORE_DATA | The supplied buffer was not large enough to store all of the counter data. Allocate a larger buffer and execute the function again.
PDH_CSTATUS_ITEM_NOT_VALIDATED | The counter has been added to the query, but has not been validated nor accessed. No additional status information on this counter is available.
PDH_CSTATUS_NO_COUNTERNAME | No counter name was specified in the query.
PDH_CSTATUS_NO_COUNTER | The specified counter name could not be found.
PDH_CSTATUS_NO_OBJECT | The specified performance object could not be found.
PDH_CALC_NEGATIVE_DENOMINATOR | A counter has a negative denominator value.
PDH_CALC_NEGATIVE_TIMEBASE | A counter has a negative timebase value.
PDH_CALC_NEGATIVE_VALUE | A counter has a negative value.
PDH_CSTATUS_NO_COUNTERNAME | No counter path was specified.
PDH_CSTATUS_BAD_COUNTERNAME | The counter path format is incorrect.


Examples

  • Enumerating Process Objects
  • Browsing Performance Counters
  • Reading Performance Data from a Log File
  • Writing Performance Data to a Log File
  • Transferring Data from a Perfmon-format Log File to a CSV-format Log File


Enumerating Process Objects

The example in this topic uses the PDH interface to enumerate the process objects on the system.

#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE  1
#endif
#define tmain     wmain
#else
#define tmain     main
#endif

// This program needs only the essential Windows header files.
#define WIN32_LEAN_AND_MEAN 1

#include <windows.h>
#include <winperf.h>
#include <malloc.h>
#include <stdio.h>
#include <tchar.h>
#include <pdh.h>

int
tmain ()
{
    PDH_STATUS  pdhStatus               = ERROR_SUCCESS;
    LPTSTR      szCounterListBuffer     = NULL;
    DWORD       dwCounterListSize       = 0;
    LPTSTR      szInstanceListBuffer    = NULL;
    DWORD       dwInstanceListSize      = 0;
    LPTSTR      szThisInstance          = NULL;

// Determine the required buffer size for the data.

    pdhStatus = PdhEnumObjectItems (
        NULL,                   // reserved
        NULL,                   // local machine
        TEXT("Process"),        // object to enumerate
        szCounterListBuffer,    // pass in NULL buffers
        &dwCounterListSize,     // an 0 length to get
        szInstanceListBuffer,   // required size
        &dwInstanceListSize,    // of the buffers in chars
        PERF_DETAIL_WIZARD,     // counter detail level
        0);

    if (pdhStatus == ERROR_SUCCESS)
    {
    // Allocate the buffers and try the call again.
        szCounterListBuffer = (LPTSTR)malloc (
            (dwCounterListSize * sizeof (TCHAR)));
        szInstanceListBuffer = (LPTSTR)malloc (
            (dwInstanceListSize * sizeof (TCHAR)));
        if ((szCounterListBuffer != NULL) &&
            (szInstanceListBuffer != NULL))
        {
            pdhStatus = PdhEnumObjectItems (
                NULL,   // reserved
                NULL,   // local machine
                TEXT("Process"), // object to enumerate
                szCounterListBuffer,    // passing in NULL buffers
                &dwCounterListSize,     // passing in 0
                szInstanceListBuffer,
                &dwInstanceListSize,
                PERF_DETAIL_WIZARD,     // counter detail level
                0);
            if (pdhStatus == ERROR_SUCCESS)
            {
                _tprintf (TEXT("\nRunning Processes:"));
            // Walk the return instance list.
                for (szThisInstance = szInstanceListBuffer;
                     *szThisInstance != 0;
                     szThisInstance += lstrlen(szThisInstance) + 1)
                {
                     _tprintf (TEXT("\n  %s"), szThisInstance);
                }
            }
        }
        else
        {
            _tprintf (TEXT("\nPROCLIST: unable to allocate buffers"));
        }

        if (szCounterListBuffer != NULL)
            free (szCounterListBuffer);

        if (szInstanceListBuffer != NULL)
            free (szInstanceListBuffer);
    }
    else
    {
        _tprintf(TEXT("\nUnable to determine required buffer size."));
    }
    return 0;
}


Browsing Performance Counters

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <pdh.h>

#define SAMPLE_INTERVAL_MS  1000
#define MAXPATH 80

int __cdecl _tmain (int argc, TCHAR **argv)
{

   HQUERY          hQuery;
   HCOUNTER        *pCounterHandle;
   PDH_STATUS      pdhStatus;
   PDH_FMT_COUNTERVALUE   fmtValue;
   DWORD           ctrType;
   SYSTEMTIME      stSampleTime;
   PDH_BROWSE_DLG_CONFIG  BrowseDlgData;
   CHAR            szPathBuffer[MAXPATH];
   int             nRetCode = 0;

   // Open the query object.
   pdhStatus = PdhOpenQuery (0, 0, &hQuery);

   // Allocate the counter handle array. Allocate room for
   //  one handle per command line arg, not including the
   //  executable file name.
   pCounterHandle = (HCOUNTER *)GlobalAlloc(GPTR, sizeof(HCOUNTER));

   // Zero the contents of the structure.
   memset (&BrowseDlgData, 0, sizeof(PDH_BROWSE_DLG_CONFIG));

   // Initialize the browser dialog window settings.
   BrowseDlgData.bIncludeInstanceIndex = FALSE;
   BrowseDlgData.bSingleCounterPerAdd = TRUE;
   BrowseDlgData.bSingleCounterPerDialog = TRUE;
   BrowseDlgData.bLocalCountersOnly = FALSE;
   BrowseDlgData.bWildCardInstances = TRUE;
   BrowseDlgData.bHideDetailBox = TRUE;
   BrowseDlgData.bInitializePath = FALSE;
   BrowseDlgData.bDisableMachineSelection = FALSE;
   BrowseDlgData.bIncludeCostlyObjects = FALSE;
   BrowseDlgData.bReserved = TRUE;
   BrowseDlgData.hWndOwner = NULL;
   BrowseDlgData.bReserved = FALSE;
   BrowseDlgData.szReturnPathBuffer = szPathBuffer;
   BrowseDlgData.cchReturnPathLength = MAXPATH;;
   BrowseDlgData.pCallBack = NULL;
   BrowseDlgData.dwCallBackArg = 0;
   BrowseDlgData.CallBackStatus = ERROR_SUCCESS;
   BrowseDlgData.dwDefaultDetailLevel = PERF_DETAIL_WIZARD;
   BrowseDlgData.szDialogBoxCaption = "Select a counter to monitor.";

   // Display the counter browser window.
   pdhStatus = PdhBrowseCounters (&BrowseDlgData);

   pdhStatus = PdhAddCounter (hQuery,
                              szPathBuffer,
                              0,
                              pCounterHandle);

   // "Prime" counters that need two values to display a
   //   formatted value.
   pdhStatus = PdhCollectQueryData (hQuery);

   // Print counter values until a key is pressed.
   while (!_kbhit()) {

     // Wait one interval.
     Sleep(SAMPLE_INTERVAL_MS);

     // Get the sample time.
     GetLocalTime (&stSampleTime);

     // Get the current data values.
     pdhStatus = PdhCollectQueryData (hQuery);

     // Print the time stamp for the sample.
     _tprintf (TEXT("\n
                    \"%2.2d/%2.2d/%4.4d %2.2d:%2.2d:%2.2d.%3.3d\""),
               stSampleTime.wMonth,
               stSampleTime.wDay,
               stSampleTime.wYear,
               stSampleTime.wHour,
               stSampleTime.wMinute,
               stSampleTime.wSecond,
               stSampleTime.wMilliseconds);

     // Get the current value of this counter.
     pdhStatus = PdhGetFormattedCounterValue (*pCounterHandle,
                                              PDH_FMT_DOUBLE,
                                              &ctrType,
                                              &fmtValue);

     if (pdhStatus == ERROR_SUCCESS) {
         _tprintf (TEXT(",\"%.20g\""), fmtValue.doubleValue);
     } else {

         // Print the error value.
         _tprintf (TEXT(".\"-1\""));
     }
   }

   // Close the query.
   pdhStatus = PdhCloseQuery (hQuery);

   return nRetCode;
}


Reading Performance Data from a Log File

#define UNICODE
#define _UNICODE

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <pdh.h>
#include <pdhmsg.h>

void
DisplayCommandLineHelp ()
{
   _tprintf (TEXT("\nA valid log name must be specified as the"));
   _tprintf (TEXT("\ncommand line argument. The log file must be"));
   _tprintf (TEXT("\nin the CSV file format."));
   return;
}

int __cdecl _tmain (int argc, TCHAR **argv)
{

   HQUERY          hQuery;
   PDH_STATUS      pdhStatus;
   DWORD           dwFormat = PDH_FMT_DOUBLE;
   PDH_FMT_COUNTERVALUE  *lpItemBuffer;
   HCOUNTER        hCounter;
   CHAR            szCounterPath[45] =
                     TEXT("\\Processor(0)\\% Processor Time");

   if (argc != 2) {
      DisplayCommandLineHelp ();
      return -1;
   }

   // Open a query object.
   pdhStatus = PdhOpenQuery (argv[1],
                             0,
                             &hQuery);

   // Add the counter that created the data in the log file.
   pdhStatus = PdhAddCounter (hQuery,
                              szCounterPath,
                              0,
                              &hCounter);

   // Allocate the counter value structure.
   lpItemBuffer = (PDH_FMT_COUNTERVALUE *) GlobalAlloc
                   (GPTR, sizeof(PDH_FMT_COUNTERVALUE));

   // Read the performance data records.
   pdhStatus = PdhCollectQueryData(hQuery);
   while (pdhStatus == ERROR_SUCCESS) {

       // Format the performance data record.
       pdhStatus = PdhGetFormattedCounterValue (hCounter,
                                               dwFormat,
                                               (LPDWORD)NULL,
                                               lpItemBuffer);

       // Print the performance data record.
       _tprintf(TEXT("\nLog Record Value = %4.8f\n"),
                     lpItemBuffer->doubleValue);

       // Read the next record
       pdhStatus = PdhCollectQueryData(hQuery);

   }

   // Close the query and the log file.
   pdhStatus = PdhCloseQuery(hQuery);

   return 0;

}


Writing Performance Data to a Log File

#define UNICODE
#define _UNICODE

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <pdh.h>
#include <pdhmsg.h>

void
DisplayCommandLineHelp ()
{
   _tprintf (TEXT("\n\nOne or more valid log names must be"));
   _tprintf (TEXT("specified as a command line argument. The"));
   _tprintf (TEXT("\nlog file will be in the CSV log file format."));
   return;
}

int __cdecl _tmain (int argc, TCHAR **argv)
{

   HQUERY          hQuery;
   HLOG            hLog;
   PDH_STATUS      pdhStatus;
   DWORD           dwLogType = PDH_LOG_TYPE_CSV;
   HCOUNTER        hCounter;
   CHAR            szCounterPath[45] =
                    TEXT("\\Processor(0)\\% Processor Time");
   DWORD           dwCount;

   if (argc != 2) {
      DisplayCommandLineHelp ();
      return -1;
   }

   // Open a query object.
   pdhStatus = PdhOpenQuery (0,
                             0,
                             &hQuery);

   // Add one counter that will provide the data.
   pdhStatus = PdhAddCounter (hQuery,
                              szCounterPath,
                              0,
                              &hCounter);

   // Open the log file for write access.
   pdhStatus = PdhOpenLog (argv[1],
                           PDH_LOG_WRITE_ACCESS |
                           PDH_LOG_CREATE_ALWAYS,
                           &dwLogType,
                           hQuery,
                           0,
                           NULL,
                           &hLog);

   // Write 50 records to the log file.
   for (dwCount = 0; dwCount <= 50; dwCount++) {
       pdhStatus = PdhUpdateLog (hLog, TEXT("This is a comment."));
       Sleep(1000);      // Wait one second between samples for
                         //  the counter to be updated.
   }

   // Close the query object.
   pdhStatus = PdhCloseQuery (hQuery);

   // Close the log file.
   pdhStatus = PdhCloseLog (hLog,
                            PDH_FLAGS_CLOSE_QUERY);

   return 0;
}


Transferring Data from a Perfmon-format Log File to a CSV-format Log File

#define UNICODE
#define _UNICODE

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <pdh.h>
#include <pdhmsg.h>

void
DisplayCommandLineHelp ()
{
   _tprintf (TEXT("\nOne or more valid log names must be specified"));
   _tprintf (TEXT("\nas a command line argument. The input log"));
   _tprintf (TEXT("\nfile must be in the Perfmon file format. The"));
   _tprintf (TEXT("\noutput log file will be in the CSV file"));
   _tprintf (TEXT("\nformat."));
   _tprintf (TEXT("\nSyntax: convertlog <input file name>"));
   _tprintf (TEXT("          <output file name>"));
   return;
}

int __cdecl _tmain (int argc, TCHAR **argv)
{

   HQUERY          hQuery;
   HLOG            hOutputLog;
   PDH_STATUS      pdhStatus;
   BOOLEAN         bStatus = FALSE;
   DWORD           dwNumEntries;
   DWORD           dwInputLogType = PDH_LOG_TYPE_PERFMON;
   DWORD           dwOutputLogType = PDH_LOG_TYPE_CSV;
   PDH_TIME_INFO   TimeRange;
   DWORD           dwCount;
   DWORD           dwFormat = PDH_FMT_DOUBLE;
   PDH_FMT_COUNTERVALUE  *lpItemBuffer;
   HCOUNTER        hCounter;
   CHAR            szCounterPath[45] =
                         TEXT("\\Processor(0)\\% Processor Time");
   DWORD           dwBufferSize;
   DWORD           dwFormattedDataSize = 0;

   if (argc != 3)
   {
      DisplayCommandLineHelp ();
      return -1;
   }

   // Open the query object and open the input log file.
   pdhStatus = PdhOpenQuery (argv[1],
                             0,
                             &hQuery);

   // Add the counter to the query object.
   pdhStatus = PdhAddCounter (hQuery,
                              szCounterPath,
                              0,
                              &hCounter);

   // Get the time range of the input log data.
   pdhStatus = PdhGetDataSourceTimeRange(argv[1],
                                         &dwNumEntries,
                                         &TimeRange,
                                         &dwBufferSize);

   // Create and open the output log file.
   pdhStatus = PdhOpenLog (argv[2],
                           PDH_LOG_WRITE_ACCESS |
                           PDH_LOG_CREATE_ALWAYS,
                           &dwOutputLogType,
                           hQuery,
                           0,
                           NULL,
                           &hOutputLog);

   // Allocate space for the counter value.
   lpItemBuffer = (PDH_FMT_COUNTERVALUE *) GlobalAlloc (GPTR,
                             sizeof(PDH_FMT_COUNTERVALUE));

   // Transfer the values from the input log file to the output
   //  log file.
   for (dwCount = 0; dwCount < TimeRange.SampleCount; dwCount++) {
       pdhStatus = PdhUpdateLog (hOutputLog,
                                 TEXT("This is a comment."));
   }

   // Close the output log file.
   pdhStatus = PdhCloseLog (hOutputLog, 0);

   // Close the query object and input log file.
   pdhStatus = PdhCloseQuery (hQuery);

   return 0;
}


Using the Registry Interface

The following topics discuss the registry interface for retrieving performance data.

  • Retrieving Counter Names and Explanations
  • Retrieving Selected Data
  • Calculations for Raw Counter Data
  • Displaying Object, Instance, and Counter Names
  • Adding Performance Counters


Retrieving Counter Names and Explanations

Object type names, counter names, object explanations, and counter explanations are not made directly available in the performance data structures. Instead, the performance data structures contain indexes you can use to locate where the names and explanations for each object and counter can be found. The ObjectNameTitleIndex and ObjectHelpTitleIndex members of the PERF_OBJECT_TYPE structure contain the indexes to the object name and explanation, respectively. The CounterNameTitleIndex and CounterHelpTitleIndex members of the PERF_COUNTER_DEFINITION structure contain the indexes to the counter name and explanation, respectively.

To access the names and explanations, read the Counter and Help values in the following registry key.

HKEY_LOCAL_MACHINE\
 SOFTWARE\
 Microsoft\
 Windows NT\
 CurrentVersion\
 Perflib\
 langid

The langid is the ASCII representation of the 3-digit hexadecimal language identifier. For example, the U.S. English langid is 009. In a non-English version of Windows NT/Windows 2000, counters are stored in both the native language of the system and in English.

The data is stored as MULTI_SZ strings. This data type consists of a list of Unicode strings, each terminated with UNICODE_NULL. The last string is followed by an additional UNICODE_NULL. The strings are listed in pairs. The first string of each pair is the Unicode string of the index, and the second string is the actual name of the index. The Counter data uses only even-numbered indexes, while the Help data has odd-numbered indexes. For example, the Counter data contains the following object and counter name strings.

2    System
4    Memory
6    % Processor Time

The Help data contains the following counter explanations.

3    The System object type includes those counters that ...
5    The Memory object type includes those counters that ...
7    Processor Time is expressed as a percentage of the ...

To retrieve a name or explanation for an object type or counter, given its index, an application should perform the following steps.

  1. If the system is remote, call the RegConnectRegistry function.
  2. Use the RegOpenKeyEx function to open the registry key containing the name and explanation text.
  3. Use the RegQueryValueEx function, specifying either Counter or Help as the name of the value to query.
  4. Convert the index into Unicode or ASCII, depending on whether your application is Unicode or ASCII.
  5. Search the MULTI_SZ data for the appropriate index.
  6. Retrieve the string following the matching index. The string contains the name or explanation.

If you are going to be looking up a number of counters, you should build a table for faster and easier lookup. For an example, see Displaying Object, Instance, and Counter Names.


Retrieving Selected Data

Retrieving the performance data is not without cost to the system, especially in terms of processor and memory requirements. In cases where your application does not need all the performance data, you can use the lpszValueName parameter of the RegQueryValueEx function to indicate the amount of information to retrieve. The following table lists the values you can specify for lpszValueName. Note that the value strings are case-sensitive, and if a string includes more than one word, your words must be separated by a space.

Value | Description
Global | The function returns all data for counters on the local computer, except those included in the Costly category.
nnn xx yyy | Each of these is a Unicode string representing the decimal value for an object name index. The function only returns data about the specified object types on the local computer. For example, if your program were to use "2 4", the System and Memory objects would be retrieved. Note that more object types can be returned than are requested. This occurs when the requested object type depends on another object type. For example, processes are needed to identify threads, so information for the Process object is also returned when you request information for the Thread object.
Foreign ssss | The string ssss is the name of a foreign computer, such as a Novell NetWare server or a UNIX system. If your system is capable of collecting data from a foreign computer, the function returns all data for counters on the foreign computer. Try this approach if the RegConnectRegistry function fails to connect to a foreign computer.
Foreign ssss nnn xx yyy | This format combines Foreign ssss and nnn xx yyy.
Costly | The function returns data for object types whose data is expensive to collect in terms of processor time or memory usage. Start a worker thread if your application needs to respond to the user during this lengthy data collection.


Calculations for Raw Counter Data

This section lists the calculations Windows 2000 Performance Monitor uses to convert raw data to the information you would expect from the counter name. The counter types and data structures are defined in Winperf.h..

For information on the calculations, see the following topics:

  • Performance Counter Key
  • Predefined Counter Types
  • Performance Counter Bases
  • Calculating Averages


Performance Counter Key

The table for each performance data time describes the components and formula used to perform the calculation. The following elements are used in the description.

Element | Meaning
X | Many of the calculations use two data components, such as the raw data and the performance frequency. This describes one component.
Y | If a calculation is based on the raw data and another component, such as the performance frequency, this describes the second component
Data Size | The number of bytes of the raw data
Display Suffix | The result of the calculations may be displayed with a suffix that describes the formatted data units. Possible suffixes are as follows: /Sec % Sec No suffix
Time base | If used in the calculation, the time base converts to units of seconds. If not, it indicates the units.
Calculation | Formula that describes how to convert the raw data and other components, such as performance frequency, to result in the formatted counter value.

To help describe the calculations, the following symbols are used.

Symbol | Definition
TB | Time base. If TB is not used in the calculation, then it indicates the units of the raw data.
B | The base value used for calculating performance data types that require base. See Performance Counter Bases.
0,1,n | Subscript notation used when calculating with multiple samplings. A 0 refers to the oldest sampling, 1 refers to the more recent sampling, and n refers to the latest sampling. In the case of two data samplings, X1-X0 means to subtract the oldest data sampling value from the more recent data sampling. The symbol, n, may be used alone to indicate the number of samplings. For example, a raw count average is described as the sum of the values divided by the number of samplings, or (X0+X1+…+Xn)/n.

The tables below also include a reference of the performance data value correlating to a symbol. The following table describes the values.

Value | Comment
CounterData | The raw performance data value.
CounterTime | The time base defined by the counter.
100Ns | The calculation result is in 100-nanosecond units.
100NsTime | The performance data sampling time in 100-nanosecond units. This is extracted from the PerfTime100nSec member of the PERF_DATA_BLOCK structure.
ObjectTime | The performance data sampling time defined by the performance object.
ObjectSpecific | The time base specific to the performance object.
PerfTime | The sampling time of data collection. This value is taken from the PerfTime member of the PERF_DATA_BLOCK structure. However, if the performance data object is of type PERF_OBJECT_TIMER, then PerfTime is used.
PerfFreq | The sampling frequency performance data collection. It is used to convert PerfTime to seconds; for example, PerfTime/PerfFreq = seconds. This value is taken from the PerfFreq member of the PERF_DATA_BLOCK structure. However, if the performance data object is of type PERF_OBJECT_TIMER, then the PerfFreq member is used.

Note The only performance data type that is of type PERF_OBJECT_TIMER is PERF_ELAPSED_TIME.


Predefined Counter Types

The following is a list of the predefined counter types defined in Winperf.h:

  • PERF_100NSEC_MULTI_TIMER
  • PERF_100NSEC_MULTI_TIMER_INV
  • PERF_100NSEC_TIMER
  • PERF_100NSEC_TIMER_INV
  • PERF_AVERAGE_BASE
  • PERF_AVERAGE_BULK
  • PERF_AVERAGE_TIMER
  • PERF_COUNTER_100NS_QUEUELEN_TYPE
  • PERF_COUNTER_BULK_COUNT
  • PERF_COUNTER_COUNTER
  • PERF_COUNTER_DELTA
  • PERF_COUNTER_LARGE_DELTA
  • PERF_COUNTER_LARGE_QUEUELEN_TYPE
  • PERF_COUNTER_LARGE_RAWCOUNT
  • PERF_COUNTER_LARGE_RAWCOUNT_HEX
  • PERF_COUNTER_MULTI_BASE
  • PERF_COUNTER_MULTI_TIMER
  • PERF_COUNTER_MULTI_TIMER_INV
  • PERF_COUNTER_NODATA
  • PERF_COUNTER_QUEUELEN_TYPE
  • PERF_COUNTER_RAWCOUNT
  • PERF_COUNTER_RAWCOUNT_HEX
  • PERF_COUNTER_TEXT
  • PERF_COUNTER_TIMER
  • PERF_COUNTER_TIMER_INV
  • PERF_ELAPSED_TIME
  • PERF_LARGE_RAW_BASE
  • PERF_OBJ_TIME_TIMER
  • PERF_PRECISION_100NS_TIMER
  • PERF_PRECISION_OBJECT_TIMER
  • PERF_PRECISION_SYSTEM_TIMER
  • PERF_RAW_BASE
  • PERF_RAW_FRACTION
  • PERF_SAMPLE_BASE
  • PERF_SAMPLE_COUNTER
  • PERF_SAMPLE_FRACTION


Performance Counter Bases

Some performance data types rely on an accompanying counter base used as a denominator in the calculations. The counter base is stored in a performance counter that immediately follows the subject performance counter with an index that is one greater than the index of the subject performance counter. For example, if the index of a counter of type PERF_RAW_FRACTION is 2018, the base value will be in a counter of type PERF_RAW_BASE at index 2019.

The following table lists the performance data types for each base type.

Base Type and Definition | Corresponding Counter Types
PERF_AVERAGE_BASE Stores the denominator for calculating a counter to present "time per operation" or "count per operation". | PERF_AVERAGE_BULK PERF_AVERAGE_TIMER
PERF_COUNTER_MULTI_BASE When taking timings of multiple items, this base indicates the number of items sampled. It is used as the denominator in calculations to get an average from the items sampled. | PERF_100NSEC_MULTI_TIMER PERF_100NSEC_MULTI_TIMER_INV PERF_COUNTER_MULTI_TIMER PERF_COUNTER_MULTI_TIMER_INV
PERF_RAW_BASE Stores the denominator of a counter that presents a general arithmetic fraction. | PERF_RAW_FRACTION
PERF_SAMPLE_BASE Stores the number of sampling interrupts taken and is used as a denominator in the sampling fraction. The sampling fraction is the number of samples that were 1 (or TRUE) for a sample interrupt. | PERF_SAMPLE_FRACTION


Calculating Averages

A statistical average is calculated by taking the sum of the formatted counter values divided by the number of samplings taken. For example, PERF_COUNTER_LARGE_RAWCOUNT exposes data that is fairly random from sample to sample. Using the notation, an average calculation would be (X0+X1+…+Xn)/n.

For rate counters, where rates increase as a resources are used, a fast calculation of the average is ((Xn-X0)/(Yn-Y0))/TB where X is the CounterData and Y is the time the sampling was taken. The result is the average usage per second.


PERF_100NSEC_MULTI_TIMER

Timer sampling of multiple but similar items. Result is an average sampling among the items. The number of items is in the base data.

Element | Value
X | CounterData
Y | 100NsTime
Time base | 100Ns
Data Size | 8 Bytes
Display Suffix | %
Calculation | 100*((X1-X0)/(Y1-Y0))/B1


PERF_100NSEC_MULTI_TIMER_INV

The inverse of the timer for multiple but similar items. Used when the objects are not in use.

Element | Value
X | CounterData
Y | 100NsTime
Time base | 100Ns
Data Size | 8 Bytes
Display Suffix | %
Calculation | 100* (B1-((X1-X0)/(Y1-Y0)))/B1


PERF_100NSEC_TIMER

Timer for when the object is in use.

Element | Value
X | CounterData
Y | 100NsTime
Time base | 100Ns
Data Size | 8 Bytes
Display Suffix | %
Calculation | 100*(X1-X0)/(Y1-Y0)


PERF_100NSEC_TIMER_INV

The inverse of the timer. Used when the object is not in use.

Element | Value
X | CounterData
Y | 100NsTime
Data Size | 8 Bytes
Display Suffix | %
Time base | 100Ns
Calculation | 100*(1-(X1-X0)/(Y1-Y0))


PERF_AVERAGE_BASE

Used as the base data in the computation of time or count averages. See PERF_AVERAGE_TIMER and PERF_AVERAGE_BULK.

Element | Value
X | N/A
Y | N/A
Time base | N/A
Data Size | 4 Bytes
Display Suffix | N/A
Calculation | N/A


PERF_AVERAGE_BULK

A count that usually gives the bytes per operation when divided by the number of operations.

Element | Value
X | CounterData
Y | N/A
Time base | N/A
Data Size | 8 Bytes
Display Suffix | No suffix
Calculation | (X1-X0)/(B1-BO)


PERF_AVERAGE_TIMER

A timer that usually gives time per operation when divided by the number of operations.

Element | Value
X | CounterData
Y | N/A
Time base | PerfFreq
Data Size | 4 Bytes
Display Suffix | Sec
Calculation | ((X1-X0)/TB)/(B1-B0)


PERF_COUNTER_100NS_QUEUELEN_TYPE

Queue-length space-time product using a 100-nanosecond time base.

Element | Value
X | CounterData
Y | PerfTime
Time base | PerfFreq
Data Size | 8 Bytes
Display Suffix | No suffix
Calculation | (TB(X1-X0))/(Y1-Y0)


PERF_COUNTER_BULK_COUNT

Used to count byte transmission rates.

Element | Value
X | CounterData
Y | PerfTime
Time base | PerfFreq
Data Size | 8 Bytes
Display Suffix | /Sec
Calculation | (X1-X0)/((Y1-Y0)/TB)


PERF_COUNTER_COUNTER

Rate of counts. This is the most common counter.

Element | Value
X | CounterData
Y | PerfTime
Time base | PerfFreq
Data Size | 4 Bytes
Display Suffix | /Sec
Calculation | (X1-X0)/((Y1-Y0)/TB)


PERF_COUNTER_DELTA

Windows NT 4.0 and later: Difference between two counters.

Element | Value
X | CounterData
Y | N/A
Time base | N/A
Data Size | 4 Bytes
Display Suffix | No suffix
Calculation | X1-X0


PERF_COUNTER_LARGE_DELTA

Windows NT 4.0 and later: Difference between two counters.

Element | Value
X | CounterData
Y | N/A
Time base | N/A
Data Size | 8 Bytes
Display Suffix | No suffix
Calculation | X1-X0


PERF_COUNTER_LARGE_QUEUELEN_TYPE

Windows NT 4.0 and later: Count per time interval. Typically used to track number of items queued or waiting.

Element | Value
X | CounterData
Y | PerfTime
Time base | PerfFreq
Data Size | 8 Bytes
Display Suffix | No suffix
Calculation | (X1-X0)/(Y1-Y0)


PERF_COUNTER_LARGE_RAWCOUNT

Instantaneous counter value.

Element | Value
X | CounterData
Y | N/A
Time base | N/A
Data Size | 8 Bytes
Display Suffix | No suffix
Calculation | X


PERF_COUNTER_LARGE_RAWCOUNT_HEX

Instantaneous counter value intended to be displayed as a hexadecimal number.

Element | Value
X | CounterData
Y | N/A
Time base | N/A
Data Size | 8 Bytes
Display Suffix | No suffix
Calculation | X


PERF_COUNTER_MULTI_BASE

Used as the base data for the MULTI counters. It defines the number of similar items sampled. See PERF_COUNTER_MULTI_TIMER, PERF_COUNTER_MULTI_TIMER_INV, PERF_100NSEC_MULTI_TIMER, and PERF_100NSEC_MULTI_TIMER_INV.

Element | Value
X | N/A
Y | N/A
Time base | N/A
Data Size | 8 Bytes
Display Suffix | N/A
Calculation | N/A


PERF_COUNTER_MULTI_TIMER

Timer sampling of multiple but similar items. Result is an average sampling among the items. The number of items is in the base data.

Element | Value
X | CounterData
Y | PerfTime
Time base | PerfFreq
Data Size | 8 Bytes
Display Suffix | %
Calculation | 100*((X1-X0)/((Y1-Y0)/TB))/B1


PERF_COUNTER_MULTI_TIMER_INV

The inverse of the timer for multiple but similar items. Used when the objects are not in use.

Element | Value
X | CounterData
Y | PerfTime
Time base | PerfFreq
Data Size | 8 Bytes
Display Suffix | %
Calculation | 100*(B1-((X1-X0)/((Y1-Y0)/TB)))/B1


PERF_COUNTER_NODATA

There is no data for this counter.

Element | Value
X | 0
Y | N/A
Time base | N/A
Data Size | 0 Bytes
Display Suffix | N/A
Calculation | 0


PERF_COUNTER_OBJECT_TIME_QUEUELEN_TYPE

Queue-length space-time product using an object-specific time base.

Element | Value
X | CounterData
Y | ObjectTime
Time base | ObjectSpecific
Data Size | 8 Bytes
Display Suffix | No suffix
Calculation | (X1-X0)/(Y1-Y0)


PERF_COUNTER_QUEUELEN_TYPE

Count per time interval. Typically used to track number of items queued or waiting.

Element | Value
X | CounterData
Y | PerfTime
Time base | PerfFreq
Data Size | 4 Bytes
Display Suffix | No suffix
Calculation | (X1-X0)/(Y1-Y0)


PERF_COUNTER_RAWCOUNT

Instantaneous counter value.

Element | Value
X | CounterData
Y | N/A
Time base | N/A
Data Size | 4 Bytes
Display Suffix | No suffix
Calculation | X


PERF_COUNTER_RAWCOUNT_HEX

Instantaneous counter value intended to be displayed as a hexadecimal number.

Element | Value
X | CounterData
Y | N/A
Time base | N/A
Data Size | 4 Bytes
Display Suffix | No suffix
Calculation | X


PERF_COUNTER_TEXT

Indicates the data is not a counter, but is Unicode text.

Element | Value
X | N/A
Y | N/A
Time base | N/A
Data Size | Variable length of bytes in the Unicode string. The length is the first DWORD in the counter data and immediately following that in memory is the Unicode string.
Display Suffix | N/A
Calculation | N/A


PERF_COUNTER_TIMER

The most common timer.

Element | Value
X | CounterData
Y | PerfTime
Time base | PerfFreq
Data Size | 8 Bytes
Display Suffix | %
Calculation | 100*(X1-X0)/(Y1-Y0)


PERF_COUNTER_TIMER_INV

The inverse of the timer. Used when the object is not in use.

Element | Value
X | CounterData
Y | PerfTime
Time base | PerfFreq
Data Size | 8 Bytes
Display Suffix | %
Calculation | 100*(1-((X1-X0)/(Y1-Y0)))


PERF_ELAPSED_TIME

The data is the start time of the item being measured. For display, subtract the start time from the snapshot time to yield the elapsed time. The PerfTime member of the PERF_OBJECT_TYPE structure contains the sample time. Use the PerfFreq member of the PERF_OBJECT_TYPE structure to convert the time into seconds.

Element | Value
X | CounterData
Y | PerfTime
Time base | PerfFreq
Data Size | 8 Bytes
Display Suffix | Sec
Calculation | (Y-X)/TB


PERF_LARGE_RAW_BASE

Used as a base data for PERF_RAW_FRACTION. The CounterData holds the denominator of the fraction value. Check that this value is greater than zero before dividing.

Element | Value
X | N/A
Y | N/A
Time base | N/A
Data Size | 8 Bytes
Display Suffix | N/A
Calculation | N/A


PERF_OBJ_TIME_TIMER

64-bit timer in object-specific units.

Element | Value
X | CounterData
Y | PerfTime
Time base | ObjectSpecific
Data Size | 8 Bytes
Display Suffix | %
Calculation | (X1-X0)/(Y1-Y0)


PERF_PRECISION_100NS_TIMER

100-nanosecond timer used where the standard system timers are not precise enough for accurate readings. It is assumed that the service providing the data also provides a timestamp. This will eliminate any error that may occur as a small and variable amount of time elapses between the time the system timestamp is captured and the time when the data is collected from the performance DLL.

Element | Value
X | CounterData
Y | 100NsTime
Time base | 100Ns
Data Size | 8 Bytes
Display Suffix | %
Calculation | 100*(X1-X0)/(Y1-Y0)


PERF_PRECISION_OBJECT_TIMER

Object timer used where the standard system timers are not precise enough for accurate readings. It is assumed that the service providing the data also provides a timestamp. This will eliminate any error that may occur as a small and variable amount of time elapses between the time the system timestamp is captured and the time when the data is collected from the performance DLL.

Element | Value
X | CounterData
Y | PerfData
Time base | PerfFreq
Data Size | 8 Bytes
Display Suffix | %
Calculation | (TB(X1-X0))/(Y1-Y0)


PERF_PRECISION_SYSTEM_TIMER

System timer used where the standard system timers are not precise enough for accurate readings. This timer is the same as PERF_COUNTER_TIMER except that it uses a counter-defined time base instead of a timestamp.

Element | Value
X | CounterData
Y | ClockTime
Time base | CounterTime
Data Size | 8 Bytes
Display Suffix | %
Calculation | 100*(X1-X0)/(Y1-Y0)


PERF_RAW_BASE

Used as a base data for PERF_RAW_FRACTION. The CounterData holds the denominator of the fraction value. Check that this value is greater than zero before dividing.

Element | Value
X | N/A
Y | N/A
Time base | N/A
Data Size | 4 Bytes
Display Suffix | N/A
Calculation | N/A


PERF_RAW_FRACTION

Instantaneous value, to be divided by the base data. See PERF_RAW_BASE.

Element | Value
X | CounterData
Y | N/A
Time base | N/A
Data Size | 4 Bytes
Display Suffix | %
Calculation | 100*X/B


PERF_SAMPLE_BASE

Used as a base data for PERF_SAMPLE_COUNTER and PERF_SAMPLE_FRACTION. Check that this value is greater than zero before dividing.

Element | Value
X | N/A
Y | N/A
Time base | N/A
Data Size | 4 Bytes
Display Suffix | N/A
Calculation | N/A


PERF_SAMPLE_COUNTER

A count that is either 1 or 0 on each sampling interrupt. The CounterData is the counter of 1s sampled.

Element | Value
X | CounterData
Y | N/A
Time base | N/A
Data Size | 4 Bytes
Display Suffix | No suffix
Calculation | (X1-X0)/(B1-B0)


PERF_SAMPLE_FRACTION

A count that is either 1 or 0 on each sampling interrupt. The CounterData is the counter of 1s sampled. For display in terms of a percentage.

Element | Value
X | CounterData
Y | N/A
Time base | N/A
Data Size | 4 Bytes
Display Suffix | %
Calculation | 100*(X1-X0)/(B1-B0)


Displaying Object, Instance, and Counter Names

The performance data contains information for a variable number of object types, instances per object, and counters per object type. Therefore, the number and size of blocks in the performance data varies. To ensure that your application correctly receives the performance data, you must use the offsets included in the performance structures to navigate through the data. Every offset is a count of bytes relative to the structure containing it.

Note The reason the system uses offsets instead of pointers is that pointers are not valid across process boundaries. The addresses that the process that installs the counters would store would not be valid for the process that reads the counters.

The following example displays the index and name of each object, along with the indexes and names of its counters.

The object and counter names are stored in the registry, by index. This example creates a function, GetNameStrings, to load the indexes and names of each object and counter from the registry into an array, so that they can be easily accessed. GetNameStrings uses the following standard registry functions to access the data: RegOpenKey, RegCloseKey, RegQueryInfoKey, and RegQueryValueEx.

This example creates the following functions for navigating the performance data: FirstObject, FirstInstance, FirstCounter, NextCounter, NextInstance, and NextCounter. These functions navigate the performance data by using the offsets stored in the performance structures.

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>

#define TOTALBYTES    8192
#define BYTEINCREMENT 1024

LPSTR lpNameStrings;
LPSTR *lpNamesArray;

/*****************************************************************
 *                                                               *
 * Functions used to navigate through the performance data.      *
 *                                                               *
 *****************************************************************/

PPERF_OBJECT_TYPE FirstObject( PPERF_DATA_BLOCK PerfData )
{
    return( (PPERF_OBJECT_TYPE)((PBYTE)PerfData +
        PerfData->HeaderLength) );
}

PPERF_OBJECT_TYPE NextObject( PPERF_OBJECT_TYPE PerfObj )
{
    return( (PPERF_OBJECT_TYPE)((PBYTE)PerfObj +
        PerfObj->TotalByteLength) );
}

PPERF_INSTANCE_DEFINITION FirstInstance( PPERF_OBJECT_TYPE PerfObj )
{
    return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfObj +
        PerfObj->DefinitionLength) );
}

PPERF_INSTANCE_DEFINITION NextInstance(
    PPERF_INSTANCE_DEFINITION PerfInst )
{
    PPERF_COUNTER_BLOCK PerfCntrBlk;

    PerfCntrBlk = (PPERF_COUNTER_BLOCK)((PBYTE)PerfInst +
        PerfInst->ByteLength);

    return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfCntrBlk +
        PerfCntrBlk->ByteLength) );
}

PPERF_COUNTER_DEFINITION FirstCounter( PPERF_OBJECT_TYPE PerfObj )
{
    return( (PPERF_COUNTER_DEFINITION) ((PBYTE)PerfObj +
        PerfObj->HeaderLength) );
}

PPERF_COUNTER_DEFINITION NextCounter(
    PPERF_COUNTER_DEFINITION PerfCntr )
{
    return( (PPERF_COUNTER_DEFINITION)((PBYTE)PerfCntr +
        PerfCntr->ByteLength) );
}

/*****************************************************************
 *                                                               *
 * Load the counter and object names from the registry to the    *
 * global variable lpNamesArray.                                 *
 *                                                               *
 *****************************************************************/

void GetNameStrings( )
{
    HKEY hKeyPerflib;      // handle to registry key
    HKEY hKeyPerflib009;   // handle to registry key
    DWORD dwMaxValueLen;   // maximum size of key values
    DWORD dwBuffer;        // bytes to allocate for buffers
    DWORD dwBufferSize;    // size of dwBuffer
    LPSTR lpCurrentString; // pointer for enumerating data strings
    DWORD dwCounter;       // current counter index

// Get the number of Counter items.

    RegOpenKeyEx( HKEY_LOCAL_MACHINE,
        "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib",
        0,
        KEY_READ,
        &hKeyPerflib);

    dwBufferSize = sizeof(dwBuffer);

    RegQueryValueEx( hKeyPerflib,
        "Last Counter",
        NULL,
        NULL,
        (LPBYTE) &dwBuffer,
        &dwBufferSize );

    RegCloseKey( hKeyPerflib );

// Allocate memory for the names array.

    lpNamesArray = malloc( (dwBuffer+1) * sizeof(LPSTR) );

// Open the key containing the counter and object names.

    RegOpenKeyEx( HKEY_LOCAL_MACHINE,
    "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009",
        0,
        KEY_READ,
        &hKeyPerflib009);

// Get the size of the largest value in the key (Counter or Help).

    RegQueryInfoKey( hKeyPerflib009,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        &dwMaxValueLen,
        NULL,
        NULL);

// Allocate memory for the counter and object names.

    dwBuffer = dwMaxValueLen + 1;

    lpNameStrings = malloc( dwBuffer * sizeof(CHAR) );

// Read the Counter value.

    RegQueryValueEx( hKeyPerflib009,
        "Counter",
        NULL,
        NULL,
        lpNameStrings, &dwBuffer );

// Load names into an array, by index.

    for( lpCurrentString = lpNameStrings; *lpCurrentString;
         lpCurrentString += (lstrlen(lpCurrentString)+1) )
    {
        dwCounter = atol( lpCurrentString );

        lpCurrentString += (lstrlen(lpCurrentString)+1);

        lpNamesArray[dwCounter] = (LPSTR) lpCurrentString;
    }
}

/*****************************************************************
 *                                                               *
 * Display the indexes and/or names for all performance objects, *
 * instances, and counters.                                      *
 *                                                               *
 *****************************************************************/

void main()
{
    PPERF_DATA_BLOCK PerfData = NULL;
    PPERF_OBJECT_TYPE PerfObj;
    PPERF_INSTANCE_DEFINITION PerfInst;
    PPERF_COUNTER_DEFINITION PerfCntr, CurCntr;
    PPERF_COUNTER_BLOCK PtrToCntr;
    DWORD BufferSize = TOTALBYTES;
    DWORD i, j, k;

// Get the name strings through the registry.

    GetNameStrings( );

// Allocate the buffer for the performance data.

    PerfData = (PPERF_DATA_BLOCK) malloc( BufferSize );

    while( RegQueryValueEx( HKEY_PERFORMANCE_DATA,
                               "Global",
                               NULL,
                               NULL,
                               (LPBYTE) PerfData,
                               &BufferSize ) == ERROR_MORE_DATA )
    {
    // Get a buffer that is big enough.

        BufferSize += BYTEINCREMENT;
        PerfData = (PPERF_DATA_BLOCK) realloc( PerfData, BufferSize );
    }

// Get the first object type.

    PerfObj = FirstObject( PerfData );

// Process all objects.

    for( i=0; i < PerfData->NumObjectTypes; i++ )
    {
    // Display the object by index and name.

        printf( "\nObject %ld: %s\n", PerfObj->ObjectNameTitleIndex,
            lpNamesArray[PerfObj->ObjectNameTitleIndex] );

    // Get the first counter.

        PerfCntr = FirstCounter( PerfObj );

        if( PerfObj->NumInstances > 0 )
        {
        // Get the first instance.

            PerfInst = FirstInstance( PerfObj );

        // Retrieve all instances.

            for( k=0; k < PerfObj->NumInstances; k++ )
            {
            // Display the instance by name.

                printf( "\n\tInstance %S: \n",
                    (char *)((PBYTE)PerfInst + PerfInst->NameOffset));
                CurCntr = PerfCntr;

            // Retrieve all counters.

                for( j=0; j < PerfObj->NumCounters; j++ )
                {
                // Display the counter by index and name.

                    printf("\t\tCounter %ld: %s\n",
                        CurCntr->CounterNameTitleIndex,
                        lpNamesArray[CurCntr->CounterNameTitleIndex]);

                // Get the next counter.

                    CurCntr = NextCounter( CurCntr );
                }

            // Get the next instance.

                PerfInst = NextInstance( PerfInst );
            }
        }
        else
        {
        // Get the counter block.

            PtrToCntr = (PPERF_COUNTER_BLOCK) ((PBYTE)PerfObj +
                            PerfObj->DefinitionLength );

        // Retrieve all counters.

            for( j=0; j < PerfObj->NumCounters; j++ )
            {
            // Display the counter by index and name.

                printf( "\tCounter %ld: %s\n", PerfCntr->CounterNameTitleIndex,
                    lpNamesArray[PerfCntr->CounterNameTitleIndex] );

            // Get the next counter.

                PerfCntr = NextCounter( PerfCntr );
            }
        }

    // Get the next object type.

        PerfObj = NextObject( PerfObj );
    }
}


Adding Performance Counters

Windows NT/Windows 2000 provides a mechanism for you to add performance objects and counters for your application and other software components. Performance counters specific to your application can help you tune performance while you develop and debug the application. After your application is complete and installed on target systems, the counters can help system administrators adjust configurable settings for your application.

To add an extended object and its counters, use the following steps.

  1. Design the object types and counters for the application. See Object and Counter Design.
  2. Create an initialization (.ini) file containing the names and descriptions of the counter objects and counters. See Adding Counter Names and Descriptions to the Registry.
  3. Create a header (.h) file containing the relative offsets at which the counter objects and counters will be installed in the registry. See Adding Counter Names and Descriptions to the Registry.
  4. Set up the necessary performance monitoring entries in the registry. This includes the following steps.
    1. Create a registry key in the Services key for the application. If you do not have such a node, create it under the following registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services. See Creating the Application's Performance Key.
    2. Use the lodctr utility with the .ini and .h files to install the information in the registry. This utility succeeds only if a performance key exists in the Services key for the application. See Adding Counter Names and Descriptions to the Registry.
  5. Create a performance DLL containing a set of exported functions that provide the link between the application and a performance monitoring application. See Creating a Performance Extension DLL.
  6. Modify the application's setup file to automate adding information to the registry (as described in step 4) and move your performance DLL to the system directory at setup.

To view an extended object, its functions, and its counter, use the extensible counter list utility (Exctrlst.exe). For more information, see ExCtrLst.

For information about additional registry entries, see Creating Other Registry Entries.


Object and Counter Design

A performance object is an entity for which performance data is available. Performance counters define the type of data that is available for a counter object. An application can provide information for multiple performance objects, each with one or more counters.

An application can also define objects that have multiple instances. For example, a SCSI application could use a single set of counter definitions to define a drive object with two counters, such as Bytes Read and Bytes Written. The performance DLL for the application could report performance data for each drive controlled by the application.

The Windows 2000 Performance Monitor can show some counters as rates, such as Page Faults/sec, as well as a raw count. This gives context to the users, so they do not have to compare data from different time intervals. However, you do not have to take this into account when you design a counter. You increment the counter and let the monitor application do the work of converting raw counts to a rate.

The method you use to collect the data can be as simple as incrementing a counter each time a particular routine in the application is called, or it can involve time-consuming calculations. Counters and timers should increment and never be cleared. Counters can wrap, as long as they do not wrap twice between snapshots. Your application can collect and store data during its normal execution, as long as it does not affect the its performance.

For some types of data, it may be more efficient or appropriate to collect the data on demand. In this situation, the performance DLL must communicate to the application that the data has been requested. For data that is expensive to collect (in terms of processor time or memory usage), consider collecting data only when the performance monitoring program requests Costly data. This allows a custom performance monitoring program to routinely request data for all counters that are not costly. The data can be requested only when needed. The Windows 2000 Performance Monitor does not collect Costly data.


Adding Counter Names and Descriptions to the Registry

The names and descriptions of all performance objects and their counters are stored using the registry. You must add this information for the objects and counters you add to the system.

The following example shows the registry location where performance counter names and descriptions are stored.

HKEY_LOCAL_MACHINE
\SOFTWARE
\Microsoft
\Windows NT
\CurrentVersion
\Perflib
Last Counter = highest counter index
Last Help = highest help index
\009
Counter = 2 System 4 Memory ...
Help = 3 The System object type ...
\supported language, other than U.S. English
Counter = ...
Help = ...

To add names and descriptions of the objects and counters for your application, use the lodctr utility included with the operating system. The lodctr utility takes strings from an .ini file and adds them to the Counter and Help values under the appropriate language subkeys. It also updates the Last Counter and Last Help values. In addition to adding values under the PerfLib key, the lodctr utility also adds the following value entries to the Services node for the application.

\HKEY_LOCAL_MACHINE
\SYSTEM
\CurrentControlSet
\Services
\Application_Name
\Performance
First Counter = lowest counter index
First Help = lowest help index
Last Counter = highest counter index
Last Help = highest help index

Using lodctr

The command-line syntax for lodctr is:

lodctr [\\remote computer name] MyApplication.ini

The remote computer name argument is the name of the remote computer, if one is used. If a remote computer name is not specified, the local machine is the default.

Initialization (.INI) File

The .INI file used by lodctr has the following format:

[info]
drivername=Application_Name
symbolfile=SymbolFile

// One key (value optional) for each language supported
[languages]
langid=
 .
 .
 .

// Name and description for each counter or counter object
[text]
offset_langid_NAME=Name         // Counter name string
offset_langid_HELP=Description  // Help description string
 .
 .
 .

The .INI file entries are variables with the following meanings:

Variable | Description
DriverName | The name of the performance key created under the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services key.
SymbolFile | An .h file containing symbolic offsets of counters. The performance DLL also uses the offsets in this file along with the First Counter and First Help registry values to determine the indexes of the various counters and counter objects.
Langid | An ID corresponding to the language subkey in the registry (for example, 009 for U.S. English).
Offset | A symbolic constant defined in SymbolFile. Offsets must be consecutive, even numbers beginning with zero. These offsets determine the order in which the counters are installed in the Counter and Help values in the registry.

The following is an example SymbolFile.

// SYMFILE.H

#define OBJECT_1    0
#define DEVICE_COUNTER_1    2
#define DEVICE_COUNTER_2    4

The following is an example .ini file.

// begin .ini file example
[info]
drivername=MyApplication
symbolfile=symfile.h

[languages]
009=English
011=OtherLanguage

[text]
OBJECT_1_009_NAME=Device Name
OBJECT_1_009_HELP=Displays performance statistics on Device Name
OBJECT_1_011_NAME=Device Name in other language
OBJECT_1_011_HELP=Displays performance of Device Name in other language

DEVICE_COUNTER_1_009_NAME=Counter A
DEVICE_COUNTER_1_009_HELP=Displays the current value of Counter A
DEVICE_COUNTER_1_011_NAME=Counter A in other language
DEVICE_COUNTER_1_011_HELP=Displays the value of Counter A in other language

DEVICE_COUNTER_2_009_NAME=Counter B
DEVICE_COUNTER_2_009_HELP=Displays the current rate of Device B
DEVICE_COUNTER_2_011_NAME=Counter B in other language
DEVICE_COUNTER_2_011_HELP=Displays the rate of Device B in other language

If you run lodctr to add counters for an application and the application does not have a Services key, lodctr returns without modifying the Perflib values.

Note The loading function of lodctr, LoadPerfCounterTextStrings, is declared in Loadperf.h and exported from Loadperf.dll. This allows you to call this function directly from your install program. The syntax for this function is as follows:

LONG LoadPerfCounterTextStrings(
 LPSTR lpCommandLine,
BOOL bQuietModeArg
);

where lpCommandLine is the name of your initialization file and bQuietModeArg is a Boolean parameter that indicates whether to display output during the loading of the counter text strings. If the function succeeds, the return value is ERROR_SUCCESS. If the function fails, the return value is a nonzero error code defined in Winerror.h.


Creating the Application's Performance Key

An application that supports performance counters must have a Performance key under the Services key. The following example shows the values you should include for this key.

HKEY_LOCAL_MACHINE
\SYSTEM
\CurrentControlSet
\Services
\Application_Name
\Performance
Library = DLL_Name
Open = Open_Function_Name
Collect = Collect_Function_Name
Close = Close_Function_Name

The Library value provides the name of the performance DLL, and the Open, Collect, and Close values provide the names of the functions exported from the performance DLL. When a performance monitoring application requests performance data, the system uses these values to determine which performance DLLs to load and which DLL functions to call.


Creating Other Registry Entries

To obtain the performance data for some applications (those that return counters using the DeviceIoControl function), it is necessary to use the CreateFile function to open the device associated with the application. In this case, the name specified in CreateFile must also be installed in the DOS Devices node of the registry, as shown here:

HKEY_LOCAL_MACHINE
\SYSTEM
\CurrentControlSet
\Control
\Session Manager
\DOS Devices

Applications that manage multiple device instances with performance data for each device must put a Linkage key in its Services key. The Linkage key contains an Export value whose data is a list of the device names. For example, a system with two Etherlink cards could have the following registry entries:

HKEY_LOCAL_MACHINE
\SYSTEM
\CurrentControlSet
\Services
\Elnkii
\Linkage
Export = "\Device\Elnk01" "\Device\Elnk02"
\Performance
Library = "ElnkStat.dll"
Open = "OpenElnkStats"
Collect = "GetElnkStats"
Close = "CloseElnkStats"
\Elnk01
\Linkage
\Parameters
\Elnk02
\Linkage
\Parameters

When the system calls the Open function in an application's performance DLL, its argument is a string containing the list of device names from the application's Export value, if it is present. The Open function can then use these names to determine the devices for which to collect performance data.


Deleting Performance Counters

The following steps are necessary to completely uninstall a performance counter. Note that these steps must be performed in the specified order.

  1. Use the unlodctr utility with the .ini and .h files to uninstall the counter information in the registry. This utility succeeds only if a performance key exists in the Services key for the application. See Removing Counter Names and Descriptions from the Registry.
  2. Delete the registry key in the Services key corresponding to the application. See Deleting the Application's Performance Key.


Removing Counter Names and Descriptions from the Registry

The unlodctr utility removes the registry entries created by lodctr.

Using unlodctr

The command-line syntax for unlodctr is:

unlodctr Application_Name

The unlodctr utility looks up the First Counter and Last Counter values in the application's Performance key to determine the indexes of the counter objects to remove. Using these indexes, it makes the following changes to the Perflib key.

HKEY_LOCAL_MACHINE
\SOFTWARE
\Microsoft
\Windows NT
\CurrentVersion
\Perflib
Last Counter = updated if changed
Last Help = updated if changed
\009
Counter = application text removed
Help = application text removed
\supported language, other than U.S. English
Counter = application text removed
Help = application text removed

The unlodctr utility also removes the First Counter, First Help, Last Counter, and Last Help values from the application's Performance key.

Note The unloading function of unlodctr, UnloadPerfCounterTextStrings, is declared in Loadperf.h and exported from Loadperf.dll. This allows you to call this function directly from your uninstall program. The syntax for this function is as follows:

LONG UnloadPerfCounterTextStrings(
 LPSTR lpCommandLine,
BOOL bQuietModeArg
);

where lpCommandLine is the name of your application and bQuietModeArg is a Boolean parameter that indicates whether to display output during the unloading of the counter text strings. If the function succeeds, the return value is ERROR_SUCCESS. If the function fails, the return value is a nonzero error code defined in Winerror.h.


Deleting the Application's Performance Key

The performance key created when the performance DLL was installed can be deleted either by using the Regedt32.exe utility or by calling RegDeleteKey. You must run the unlodctr utility to remove the counter names and descriptions from the registry before deleting the performance key. Refer to Removing Counter Names and Descriptions from the Registry for information on how to do this.

To delete the performance key with Regedt32.exe, do the following.

  1. Click the Start key, then select Run.
  2. Type "regedt32" in the Open field, then click OK.
  3. Within the HKEY_LOCAL_MACHINE window, click the SYSTEM key, then click the CurrentControlSet key, then click the Services key.
  4. Click the key with the name corresponding to the service name of the application that supports the counters you want to delete. Click the Performance subkey of this key.
  5. Select Delete in the Edit menu. The performance key will be deleted from the registry.

To delete the performance key using RegDeleteKey, use the following function call syntax.

RegDeleteKey(HKEY_LOCAL_MACHINE, "<service name of the application>/Performance");

<service name of the application> refers to the service name mentioned in Step 4 in the preceding list.


Creating a Performance Extension DLL

Your application's extension DLL defines the counter and object data structures that it uses to pass performance data to performance monitoring applications. Your DLL also provides the following exported functions that are called by the system in response to requests for performance data.

Function | Description
Open | Initializes performance monitoring for the application.
Collect | Reports performance data when requested.
Close | Closes performance monitoring.

The prototypes for these functions, and the structures and constants used to define counters and counter objects, are defined in the Winperf.h file distributed with the Platform SDK.

Communication between an application and its performance DLL differs for user-mode and privileged-mode applications. The application's performance DLL executes in user mode. Because of this, user-mode applications, such as print and display applications, can use any technique for interprocess communication, such as named pipes, file mapping, or RPC. However, privileged-mode applications must provide an IOCTL interface that returns the performance data to the performance DLL.

Warning Do not use COM as the IPC mechanism. The system cannot guarantee the COM initialization state of the thread calling the interface. Therefore, the DLL may not be able to successfully initialize COM and collect the data.


How the DLL Interfaces with a Performance Monitor Application

An application retrieves performance data by specifying HKEY_PERFORMANCE_DATA in a call to the RegQueryValueEx function. If successful, RegQueryValueEx fills a buffer of the application with the requested performance data.

The first time an application calls RegQueryValueEx, or if the application uses the RegOpenKey function to open HKEY_PERFORMANCE_DATA, the system calls the Open function for each application with the correct registry entries. This gives each performance DLL an opportunity to initialize its performance data structures. Then, if the Open function returns successfully (or if there is no Open function), the system calls the Collect function. Subsequent calls to RegQueryValueEx cause the system to call the Collect function.

When the application has finished collecting performance data, it specifies HKEY_PERFORMANCE_DATA in a call to the RegCloseKey function. This causes the system to call the Close function for each application. The performance DLLs are then unloaded.

Note It is possible for multiple programs to collect performance data at the same time. The system calls Open and Close functions only once for each application requesting performance data. For remote measurement, the system limits access to these routines to one thread at a time, so synchronization is not a problem. However, for local measurement, because multiple processes may be making simultaneous calls, you must prevent any conflicts from multiple concurrent requests for data.

When coding calls to functions within a performance DLL, remember that ExitProcess, ExitThread, CreateThread, CreateRemoteThread, and a process that is starting (as the result of a call by CreateProcess) are serialized between each other within a process. Only one of these events at a time can happen in an address space, and the following restrictions apply.

  • During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is finished for the process.
  • Only one thread at a time can be in a DLL initialization or detach routine.
  • The ExitProcess function does not return until no threads are in their DLL initialization or detach routines.


The Open Function

The system calls the Open function whenever an application first connects to the registry to collect performance data. This function performs the initialization required for the application to provide performance data.

Use the following function prototype for your Open function.

DWORD CALLBACK OpenPerformanceData(LPWSTR lpDeviceNames);

The name OpenPerformanceData is a placeholder for an application-defined name. The lpDeviceNames argument points to a buffer containing the Unicode strings stored in the Export value in the following registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
Application_Name\Linkage

The strings are REG_MULTI_SZ strings, separated by a UNICODE_NULL, and terminated by two UNICODE_NULL characters. If this entry does not exist, lpDeviceNames should be NULL. The strings are the names of the devices managed by this application. The Open function should call the CreateFile function to open a handle to each device named. If CreateFile fails, the Open function should return the error code returned by the GetLastError function; otherwise, it should return ERROR_SUCCESS.

The Open function initializes the data structures it returns to the performance monitor application. In particular, it examines the registry to get the Counter and Help indexes of the objects and counters supported by the application. It then stores these indexes in the appropriate members of the PERF_OBJECT_TYPE and PERF_COUNTER_DEFINITION structures.

Other initialization tasks that might be performed by the Open function include the following:

  • Open and map a file mapping object used by the program to store performance data. Create a mutex to prevent the application from changing a value while the performance DLL is reading it. This is one way to communicate performance data from the application to the performance DLL. If you are using another form of interprocess communication, substitute the appropriate steps to initialize that mechanism.
  • Initialize event logging, if the DLL uses event logging to report errors. This is the only way for the performance DLL to report error conditions to the user, other than through a debugger. For more information, see Event Logging.
  • Initialize the object and counter indexes. This must be done each time the performance DLL is loaded, because the indexes vary from machine to machine.
  • Perform other initialization tasks necessary for the Collect function to collect performance data efficiently.

The Open function should write in the system event log any error that prevents the function from completing successfully.


The Collect Function

The system calls each application's Collect function whenever a performance monitor program calls the RegQueryValueEx function to collect performance data. This function returns the application's performance data.

Use the following function prototype for your Collect function.

DWORD WINAPI CollectPerformanceData(
  LPWSTR lpwszValue,
  LPVOID *lppData,
  LPDWORD lpcbBytes,
  LPDWORD lpcObjectTypes
);

The name CollectPerformanceData is a placeholder for an application-defined name.

Argument | Description
lpwszValue | Pointer to a string specified by the performance monitor program in a call to the RegQueryValueEx function. The string uses one of the formats described in Retrieving Selected Data.
LppData | On input, points to a pointer to the location where the data is to be placed. On successful exit, set *lppData to the next byte in the buffer available for data, such as one byte past the last byte of your data. The data returned must be a multiple of a DWORD in length. It must conform to the PERF_OBJECT_TYPE structure, unless this is a collection from a foreign computer. If foreign, any PERF_OBJECT_TYPE structures returned must be preceded by a PERF_DATA_BLOCK structure for the foreign computer. If the Collect function fails for any reason, leave *lppData unchanged.
LpcbBytes | On input, points to a 32-bit value that specifies the size, in bytes, of the lppData buffer. On successful exit, set *lpcbBytes to the size, in bytes, of the data written to the lppData buffer. This must be a multiple of sizeof(DWORD) (a multiple of 4). If the Collect function fails for any reason, set *lpcbBytes to zero.
lpcObjectTypes | On successful exit, set *lpcObjectTypes to the number of object type definitions being returned. If the Collect function fails for any reason, it should set *lpcObjectTypes to zero.

If the requested data specified by lpwszValue does not correspond to any of the object indexes or foreign computers supported by your program, leave *lppData unchanged, and set *lpcbBytes and *lpcObjectTypes both to zero. This indicates that no data is returned. If your data collection is time-consuming, you should respond only to specific requests and Costly requests. You should also lower the priority of the thread collecting the data, so that it does not adversely affect system performance.

The Collect function must return one of the values shown in the following table.

Return value | Description
ERROR_MORE_DATA | Indicates that the size of the lppData buffer as specified by *lpcbBytes is not large enough to store the data to be returned. In this case, leave *lppData unchanged, and set *lpcbBytes and *lpcObjectTypes to zero. No attempt is made to indicate the required buffer size, because this may change before the next call.
ERROR_SUCCESS | Return this value in all other cases, even if no data is returned or an error occurs. To report errors other than insufficient buffer size, use the system event log, but do not flood the event log with errors on every data collection operation.

To provide more information to the user, the Collect function should write any error that prevents the function from completing successfully in the system event log. For more information, see Event Logging.

If the application collecting the data is running on another machine (remotely), then the extensible counter functions are called in the context of the Winlogon process, which handles the server side of the remote connection. This distinction is important when troubleshooting problems that only occur remotely. The Winlogon process may access the functions using multiple threads, usually one per remote connection. This means that the Open function can be called more than once. You should handle this in your code accordingly, so that initialization tasks are not performed more than necessary. The Collect function may also be called concurrently by multiple threads, so you should be careful how you initialize and use temporary data. Static variables should be used only if the data is intended to be shared across threads.

The connection to the machine providing the data should be tested each time data is requested. If the connection cannot be made, you need to return some sort of indication. One suggestion is to provide a Status counter for the object that indicates whether a valid connection exists. When the connection does not exist, set the Status counter and return the last set of valid data.

For foreign computer interfaces, the opening of a channel to the foreign computer must be done in the Collect function because the computer name is not provided to the Open function. The performance DLL should save a handle to the foreign computer to avoid reconnecting on each data collection call, which would significantly slow down system performance.

Once you get the data for a foreign computer, construct a PERF_DATA_BLOCK as the first thing in *lppData, so that your application can return the data. If the system you are measuring does not provide the requested information, provide a reasonable value. You should use values from the local system for time and counter frequency if they are not provided remotely. You may need to use the PerfTime and .PerfFreq members of the PERF_OBJECT_TYPE structure for some counters as well.

Other things that you might do in the Collect function include:

  • Validate the shared memory pointer and check that the Open function had successfully completed. If the Open function failed, it should have already logged an event, so the Collect function need not report this error.
  • Determine the data request type, as described in Retrieving Selected Data. If the request is for Foreign data, it is ignored and the Collect function should return no data. If the request is for a specific object or list of objects, search for its index in the list of object and counter indexes. If you do not find a match, the data from this object is not desired, so the function should return no data.
  • Request ownership of the mutex for the shared memory object. Wait to get access to the data in the shared memory block.
  • Estimate the size of the data to make sure there is enough room for the data in the buffer. If the estimated size is larger than the available size, return a status of ERROR_MORE_DATA. The system passes this error to the thread that issued the call to RegQueryValueEx to request the data.
  • Copy the performance data from the shared memory to the performance data structure to be returned.
  • When all data has been transferred from the shared memory file to the performance data buffer, release the shared memory mutex and update the pointers and counter fields. The updating of the pointers and counter fields is very important, to prevent an access violation from the application, monitor, or system due to misleading buffer length information.

After the Collect function returns successfully, the system performs the following tests to try to catch logic errors. The first test to fail will generate an event log message and, in most cases, the data is discarded to prevent any further problems due to invalid pointers. These tests are normally enabled though they can be disabled by changing a registry variable value as described below:

HKEY_LOCAL_MACHINE
\Software
\Microsoft
\Windows NT
\CurrentVersion
\Perflib
ExtCounterTestLevel = Test_Level

The Test_Level is a REG_DWORD that specifies the test level. Test level 1 requests all tests. Test level 2 requests basic tests. Test level 3 requests no tests. The default is test level 1.

The basic tests performed on the data buffer are as follows:

  • Is the BytesLeft return value consistent with the returned pointer? The returned value of the BytesLeft argument to the Collect function is compared to the returned buffer pointer. If all is consistent, the BytesLeft value added to the original buffer pointer passed in to the Collect function should be the same as the buffer pointer returned by the function. If they are not the same, a warning message is logged and the BytesLeft parameter is replaced by the value computed by finding the difference between the buffer pointer after the function call and the buffer pointer before the function call. This is somewhat risky, in that it assumes the BytesLeft value is assumed to be the incorrect one, when in fact it could be that the buffer pointer is the incorrect one.
  • Has the returned buffer pointer exceeded the allocated buffer extent? The actual buffer passed to the collect function is allocated specifically for that function call by the performance library and contains a 1K Guard Page above and below the size indicated by the remaining size of the user's buffer. A separate buffer is used to allow testing of the extensible counter DLL's returned data without corrupting the caller's buffer. If the returned buffer pointer (the pointer to the next byte after this object's data) exceeds the size of this buffer (not including guard pages) then the buffer is assumed to be invalid and discarded since it is too large to be copied into the caller's buffer. This test consists of two parts. If the buffer pointer exceeds the end of the buffer, but not the end of the guard page, then a buffer overrun error is logged. If the buffer pointer is past the end of the guard page, then a heap error is logged because the heap that the buffer was allocated from could have been corrupted, causing other memory errors.
  • Are the guard pages corrupted? The 1K Guard Pages above and below the block of memory passed to the collect procedure are initialized with a data pattern before the Collect function is called. This data pattern is checked after the collect procedure returns. If any discrepancy is detected, a buffer overrun or other memory error is assumed and the buffer is discarded.

The following tests are performed only if test level 1 is used.

  • Test object TotalByteLength field consistency. This test walks the object(s) returned by the extensible counter to see if the sum of the length of all the objects returned is the same as the value of the size of the returned buffer. Because the Collect function generally returns one or more object structures (including the instance definitions, and counter definitions and data), the sum of each object's length should be the same as the bytes returned. A failure here can indicate the object is not computing the value of the TotalByteLength field correctly. This can cause an application program using the data to fail by having it get lost in the data structures.
  • Test Instance ByteLength field consistency. This test is similar to the test above. The test walks the list of instances in each object that returns multiple instances, to see if the next object or end of buffer follows the last instance. As above, if an inconsistency is detected, the buffer is discarded to prevent the application program from crashing due to a lost pointer.


The Close Function

The system calls each application's Close function when an application calls the RegCloseKey function to close the HKEY_PERFORMANCE_DATA key. This function performs any cleanup required by the application's performance data collection mechanism. For example, the function could close device handles opened by the CreateFile function, or close a handle to a file mapping object.

Use the following function prototype for your Close function.

DWORD WINAPI ClosePerformanceData();

The name ClosePerformanceData is a placeholder for an application-defined name.

The function should return ERROR_SUCCESS.


Error Handling in the DLL

Use event logging to record errors that occur during any of the functions in the performance DLL. Logging error events aids in troubleshooting applications providing performance data during development and after installation. Be careful not to log error events on every call to the Collect function, however, because data collection can be frequent.

The performance library logs the following errors to the event log if the performance library has problems with the Open function. If one of the errors listed below occurs, then the performance library makes no further calls to this performance DLL. Instead, the DLL is unloaded and data for the object provided by the performance DLL is not returned with the performance data.

  • PERFLIB_OPEN_PROC_NOT_FOUND—Logged when the procedure name defined in the registry could not be found in the DLL as an exported function. This usually occurs when the performance counter DLL or the service is not installed correctly or the function name has been renamed without updating the installation procedure.
  • PERFLIB_OPEN_PROC_FAILURE—Logged when the open procedure returned an error status other than ERROR_SUCCESS. This usually occurs when an expected error condition has occurred in the open procedure. Should this happen, the Counter DLL should have also entered an event log entry describing the conditions that caused the failure.
  • PERFLIB_OPEN_PROC_EXCEPTION—Logged when the open procedure encounters an unhandled exception. This is usually due to an unexpected error condition encountered by the open procedure.


Performance DLL Samples

The Platform SDK contains three sample performance DLL projects. These projects are located in the Samples\WinBase\WinNT\PerfTool\PerfDllS directory. The root of this path is the base installation directory of the Platform SDK.

The projects contained in this directory are:

  • AppMem—Provides counterparts of the GlobalAlloc, GlobalReAlloc, and GlobalFree functions that report performance information. Performance counters in the registry and the Performance Monitor can read the performance information.
  • LeakyBin—Demonstrates the use of application performance counters.
  • PerfGen—Provides three waveforms at five different periods for use with the Performance Monitor to provide data at a known rate and value. This can be useful in testing applications that use performance data and need predictable values to test against.


Performance Monitoring Reference

The following elements are supported for working with performance data.

  • Performance Monitoring Types
  • Performance Monitoring Functions
  • Performance Monitoring Functions for Visual Basic
  • Performance Monitoring Structures


Performance Monitoring Types

All PDH string structures are shown as type TCHAR, meaning that both Unicode and ANSI string structures are supported. Internally, the native or preferred code path inside the PDH is the Unicode string format, because it is built only for Windows NT/Windows 2000. An ANSI version of each function is provided for those functions that have string arguments. They are, however, slightly less efficient because they must convert the ANSI string arguments to Unicode arguments before calling the Unicode version of the function.

The string data types expected are determined by the Unicode symbol when the application is compiled. If Unicode is defined, then the Unicode or wide character strings are expected. If the symbol is undefined, then the 8-bit or ANSI character strings are expected.

Data type | Description
HQUERY | Handle to a query (HANDLE).
HCOUNTER | Handle to a counter. PDH maintains the linkage between counters and queries.
PDH_STATUS | LONG status value.

Unless otherwise specified, all functions return a Win32 status value of ERROR_SUCCESS if the function completes successfully or a PDH error status value defined in the PDHMsg.h header file.

For data collection and formatting functions it is important to remember that the return value of the function indicates the success or error of the function call and not necessarily that of the counter data. Always check the CStatus member of the counter value returned to ensure that the data returned is valid before you use it. If the value of the CStatus member does not indicate success, do not use the data.


Performance Monitoring Functions

The following functions are supported for working with performance data.

CounterPathCallBack
PdhAddCounter
PdhBrowseCounters
PdhCalculateCounterFromRawValue
PdhCloseLog
PdhCloseQuery
PdhCollectQueryData
PdhCollectQueryDataEx
PdhComputeCounterStatistics
PdhConnectMachine
PdhEnumMachines
PdhEnumObjectItems
PdhEnumObjects
PdhExpandCounterPath
PdhExpandWildCardPath
PdhFormatFromRawValue
PdhGetCounterInfo
PdhGetCounterTimeBase
PdhGetDataSourceTimeRange
PdhGetDefaultPerfCounter
PdhGetDefaultPerfObject
PdhGetDllVersion
PdhGetFormattedCounterArray
PdhGetFormattedCounterValue
PdhGetLogFileSize
PdhGetRawCounterArray
PdhGetRawCounterValue
PdhIsRealTimeQuery
PdhLookupPerfIndexByName
PdhLookupPerfNameByIndex
PdhMakeCounterPath
PdhOpenLog
PdhOpenQuery
PdhParseCounterPath
PdhParseInstanceName
PdhReadRawLogRecord
PdhRemoveCounter
PdhSelectDataSource
PdhSetCounterScaleFactor
PdhSetDefaultRealTimeDataSource
PdhSetQueryTimeRange
PdhUpdateLog
PdhUpdateLogFileCatalog
PdhValidatePath


CounterPathCallBack

The CounterPathCallback function is an application-defined callback function that processes the counter path strings read from the szReturnPathBuffer member of the PDH_BROWSE_DLG_CONFIG structure.

PDH_STATUS __stdcall CounterPathCallBack(
  DWORD_PTR dwArg
);

Parameters

dwArg
[in] The user-defined value passed to the callback function by the browser dialog box. This value is the dwCallBackArg member of the PDH_BROWSE_DLG_CONFIG structure.

Remarks

The following members of the PDH_BROWSE_DLG_CONFIG structure are used to communicate with the callback function:

szReturnPathBuffer
Contains the counter path strings currently selected by the user.
cchReturnPathLength
Contains the current maximum size of the szReturnPathBuffer member. If the callback function reallocates a new buffer, it must also update this value.
CallBackStatus
On entry to the callback function, this member contains the status of the path buffer. On exit, the callback function sets the status value resulting from processing.

If the buffer is too small to load the current selection, the browser will set this value to PDH_MORE_DATA. If the browser sets this member to ERROR_SUCCESS, then the szReturnPathBuffer member contains a valid counter path or counter path list.

If the callback function reallocates a new buffer, it should set this member to PDH_RETRY so that the browser will try to load the buffer with the selected paths and call the callback function again.

If some other error occurred, then the callback function should return the appropriate PDH error status value.

Return Values

If the function succeeds (processes the buffer and does not need to be called again), it returns ERROR_SUCCESS.

If the function fails (an error occurs and the function needs to be called again to retry the processing), it returns PDH_RETRY. This is usually the result of insufficient memory.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.

See Also

PdhBrowseCounters, PDH_BROWSE_DLG_CONFIG


PdhAddCounter

The PdhAddCounter function initializes a counter structure for the specified counter in the specified query.

PDH_STATUS PdhAddCounter(
  HQUERY hQuery,
  LPCTSTR szFullCounterPath,
  DWORD_PTR dwUserData,
  HCOUNTER *phCounter
);

Parameters

hQuery
[in] Handle of the query to which the new counter will be added.
szFullCounterPath
[in] A pointer to the fully qualified and resolved path of the counter to create. This path can contain wildcard characters. See PDH_COUNTER_PATH_ELEMENTS.
dwUserData
[in] A user-defined value, typically, a pointer or index to the user's counter structure.
phCounter
[out] A pointer to the buffer that receives a handle to the created counter.

Remarks

If a wildcard character is specified in the szFullCounterPath parameter, all counter names matching the wildcard character are added to the query.

Return Values

If the function succeeds, it returns ERROR_SUCCESS, creates a new counter, and returns a handle to the counter in the buffer pointed to by phCounter.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_CSTATUS_BAD_COUNTERNAME | The counter name path string could not be parsed or interpreted.
PDH_CSTATUS_NO_COUNTER | The specified counter was not found.
PDH_CSTATUS_NO_COUNTERNAME | An empty counter name path string was passed in.
PDH_CSTATUS_NO_MACHINE | A machine entry could not be created.
PDH_CSTATUS_NO_OBJECT | The specified object could not be found.
PDH_FUNCTION_NOT_FOUND | The calculation function for this counter could not be determined.
PDH_INVALID_ARGUMENT | One or more arguments are invalid.
PDH_INVALID_HANDLE | The query handle is not valid.
PDH_MEMORY_ALLOCATION_FAILURE | A memory buffer could not be allocated.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

PdhRemoveCounter, PDH_COUNTER_PATH_ELEMENTS


PdhBrowseCounters

The PdhBrowseCounters function displays the counter browsing dialog box so that the user can select the counters to be returned to the caller.

PDH_STATUS PdhBrowseCounters(
  PPDH_BROWSE_DLG_CONFIG pBrowseDlgData
);

Parameters

pBrowseDlgData
[in] A pointer to a PDH_BROWSE_DLG_CONFIG structure that specifies the behavior of the dialog box that receives the counter path strings.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

CounterPathCallback, PDH_BROWSE_DLG_CONFIG


PdhCalculateCounterFromRawValue

The PdhCalculateCounterFromRawValue function computes the current value of a counter as referenced by the hCounter parameter, using the raw counter data passed in the parameter list.

PDH_STATUS PdhCalculateCounterFromRawValue(
  HCOUNTER hCounter,
  DWORD dwFormat,
  PPDH_RAW_COUNTER rawValue1,
  PPDH_RAW_COUNTER rawValue2,
  PPDH_FMT_COUNTERVALUE fmtValue
);

Parameters

hCounter
[in] A handle to the counter used for the computation. This determines how the data will be computed.
dwFormat
[in] The format code can be one of the following values.
Value | Meaning
PDH_FMT_DOUBLE | Return the calculated value as a double-precision floating point real.
PDH_FMT_LARGE | Return the calculated value as a 64-bit integer.
PDH_FMT_LONG | Return the calculated value as a long integer.

The value selected from the previous table can be combined using the OR operator with one of the following scaling flags.
Flag | Meaning
PDH_FMT_NOSCALE | Do not apply the counter's scaling factors in the calculation.
PDH_FMT_NOCAP100 | Counter values above 100 (for example, counter values measuring the processor load on multiprocessor machines) will not be reset to 100. The default behavior is that counter values are capped at a value of 100.
PDH_FMT_1000 | Multiply the final value by 1000.

rawValue1
[in] A pointer to the raw counter value used to compute the counter value. Some counters (for example, rate counters) require two raw values for a calculation. The format of the buffer depends on the type of counter to be processed. See PDH_RAW_COUNTER.
rawValue2
[in] A pointer to the raw counter value used in computations for counters that require two raw values (for example, rate counters). This value must be the older of the two raw values.
fmtValue
[out] A pointer to the PDH_FMT_COUNTERVALUE structure that receives the calculated counter value.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.
PDH_INVALID_HANDLE | The counter handle is not valid.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

PDH_FMT_COUNTERVALUE, PDH_RAW_COUNTER, PdhGetFormattedCounterValue, PdhGetRawCounterValue, PdhSetCounterScaleFactor


PdhCloseLog

The PdhCloseLog function closes the specified log file.

PDH_STATUS PdhCloseLog(
  HLOG hLog,
  DWORD dwFlags
);

Parameters

hLog
[in] A handle to the log file to be closed.
dwFlags
[in] This parameter can be the following value.
Value | Meaning
PDH_FLAGS_CLOSE_QUERY | Closes the query associated with the specified log file handle.

Return Values

If the function succeeds, it returns ERROR_SUCCESS and closes and deletes the query.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following is a possible error value.

Error value | Description
PDH_INVALID_HANDLE | An invalid log file handle was specified.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

PdhOpenQuery, PdhUpdateLog, PdhUpdateLogFileCatalog, PdhGetLogFileSize


PdhCloseQuery

The PdhCloseQuery function closes all counters contained in the specified query, closes all handles related to the query, and frees all memory associated with the query.

[C++]
PDH_STATUS PdhCloseQuery(
  HQUERY hQuery
);
[Visual Basic]
PdhCloseQuery(
  ByVal QueryHandle as Long
)
as Long

Parameters

[C++] hQuery
[in] A handle to the query to close and delete.
[Visual Basic] QueryHandle
[in] The ID of the query to close and delete. Closing a query closes all the counters associated with the query.

Return Values

If the function succeeds, it returns ERROR_SUCCESS and closes and deletes the query. Otherwise, the function returns a PDH error value.

The following is the possible PDH error value.

Error value | Description
PDH_INVALID_HANDLE | The query handle is not valid.

[C++] PDH error values are defined in PDHMsg.h.

[Visual Basic] PDH error values are defined in PDHDef.txt.

Remarks

The handles added to this query should be deleted or zeroed and not used after the query they belong to is deleted.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h (C/C++).
Library: Use Pdh.lib.

See Also

PdhOpenQuery


PdhCollectQueryData

The PdhCollectQueryData function collects the current raw data value for all counters in the specified query and updates the status code of each counter.

[C++]
PDH_STATUS PdhCollectQueryData(
  HQUERY hQuery
);
[Visual Basic]
PdhCollectQueryData(
  ByVal QueryHandle as Long
)
as Long

Parameters

[C++] hQuery
[in] A handle to the query from which to collect data.
[Visual Basic] QueryHandle
[in] The ID of the query to update. This must be a value returned by a call to PdhOpenQuery.

Return Values

If the function succeeds, it returns ERROR_SUCCESS. Otherwise, the function returns a PDH error value.

The following are possible PDH error values.

Error value | Description
PDH_INVALID_HANDLE | The query handle is not valid.
PDH_NO_DATA | The query does not currently have any counters.

[C++] PDH error values are defined in PDHMsg.h.

[Visual Basic] PDH error values are defined in PDHDefs.txt.

Remarks

The PdhCollectQueryData function can succeed, but may not have collected data for all counters. Always check the status code of each counter in the query before using the data.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h (C/C++).
Library: Use Pdh.lib.

See Also

PdhOpenQuery


PdhCollectQueryDataEx

The PdhCollectQueryDataEx function samples the current raw data value for all counters in the specified query according to the specified time interval, and updates the status code of the counter. After the time interval has expired, the specified event is signaled.

PDH_STATUS PdhCollectQueryDataEx(
  HQUERY hQuery,
  DWORD dwIntervalTime,
  HANDLE hNewDataEvent
);

Parameters

hQuery
[in] A handle to the query.
dwIntervalTime
[in] The time interval, in seconds, between samplings of the input performance data. A value of 0 or less will terminate all current data collection threads.
hNewDataEvent
[in] A handle to the event to be set when performance data is present. If you do not want to receive this notification, you must set the value of this parameter to NULL.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_HANDLE | The query handle is not valid.
PDH_NO_DATA | The query does not currently have any counters.

Remarks

This function is designed to return successfully while no data is available. For this reason, check the event specified by the value of hNewDataEvent to ensure that a value exists for all of the counters in the query.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

Synchronization Functions, PdhCollectQueryData, CreateEvent


PdhComputeCounterStatistics

The PdhComputeCounterStatistics function computes statistics for a counter from an array of raw values.

PDH_STATUS PdhComputeCounterStatistics(
  HCOUNTER hCounter,
  DWORD dwFormat,
  DWORD dwFirstEntry,
  DWORD dwNumEntries,
  PPDH_RAW_COUNTER lpRawValueArray,
  PPDH_STATISTICS data
);

Parameters

hCounter
[in] A handle to the counter used for the computation. This determines how the data will be computed.
dwFormat
[in] Formatting information sent by the caller to indicate how the calculated value should be returned. This parameter can be one of the following values.
Value | Meaning
PDH_FMT_DOUBLE | Return the calculated value as a double-precision floating point real.
PDH_FMT_LARGE | Return the calculated value as a 64-bit integer.
PDH_FMT_LONG | Return the calculated value as a long integer.

The value selected from the previous table can be combined using the OR operator with one of the following scaling flags.
Value | Meaning
PDH_FMT_NOSCALE | Do not apply the counter's scaling factors in the calculation.
PDH_FMT_NOCAP100 | Counter values above 100 (for example, counter values measuring the processor load on multiprocessor machines) will not be reset to 100. The default behavior is that counter values are capped at a value of 100.
PDH_FMT_1000 | Multiply the final value by 1000.

dwFirstEntry
[in] The zero-based index of the first raw counter buffer to look at. This value must point to the oldest entry in the buffer. The PdhComputeCounterStatistics function starts at this entry and scans through the buffer, wrapping at the last entry back to the beginning of the buffer and up to the dwFirstEntry-1 entry, which is assumed to be the newest or most recent data.
dwNumEntries
[in] The number of raw counter entries in the lpRawValueArray buffer.
lpRawValueArray
[in] A pointer to the raw counter value or values used to compute the counter value. Some counters (for example, rate counters) require two values for a calculation. The format of the buffer is assumed to be an array of PDH_RAW_COUNTER structures that contain dwNumEntries entries.
data
[out] A pointer to a PDH_STATISTICS structure that receives the counter statistics.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.
PDH_INVALID_HANDLE | The counter handle is not valid.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

PdhCalculateCounterFromRawValue, PdhGetRawCounterValue, PDH_RAW_COUNTER, PdhSetCounterScaleFactor, PDH_STATISTICS


PdhConnectMachine

The PdhConnectMachine function connects to the specified machine, and creates and initializes a machine entry in the PDH DLL.

PDH_STATUS PdhConnectMachine(
  LPCTSTR szMachineName
);

Parameters

szMachineName
[in] A pointer to a null-terminated string containing the name of the machine to browse. If the value of this parameter is NULL, the connection is established to the local machine.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_CSTATUS_NO_MACHINE | Unable to connect to the specified machine. Could be caused by the machine not being on, not running Windows NT/Windows 2000, not being connected to the network, or having the permissions set on the registry to not allow remote connections or remote performance monitoring by the user.
PDH_MEMORY_ALLOCATION_FAILURE | Unable to allocate a dynamic memory block. Occurs when there is a serious memory shortage in the system due to too many applications running on the system or an insufficient memory paging file.

Remarks

An application can call PdhConnectMachine to establish a connection to a remote machine at a more convenient time than when the application opens a query and adds counters.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

PdhEnumMachines


PdhEnumMachines

The PdhEnumMachines function returns a list of the names of the machines that have been opened previously by the PDH DLL. The machines listed include those that are currently connected and online, as well as those that are offline or not returning performance data. For information about how to connect to a machine, see PdhConnectMachine.

PDH_STATUS PdhEnumMachines(
  LPCTSTR szDataSource,
  LPTSTR mszMachineNameList,
  LPDWORD pcchBufferLength
);

Parameters

szDataSource
Windows 2000 or later: [in] A pointer to a null-terminated string containing either the name of a log file or the null termination only. If you specify the name of a log file, performance data will be taken from that log file. If this parameter contains a null string, performance data will be collected from a real-time data source.

Windows NT 4.0: [in] Reserved. Must be NULL.

mszMachineNameList
[out] A pointer to a null-terminated string containing the name of the buffer, allocated by the calling function, that receives the list of MULTI_SZ strings of machines to which the PDH DLL is currently connected. This parameter may be NULL if the value referenced by pcchBufferLength is zero.
pcchBufferLength
[in/out] A pointer to a variable containing the size, in characters, of the available buffer on entry and the size of the returned buffer on exit. If the buffer size on entry is zero, then no data is returned in the mszMachineNameList buffer (and the pointer may be NULL), and the size of the buffer required, in characters, is returned in the variable pointed to by pcchBufferLength. The size returned includes both terminating NULL characters of the MULTI_SZ string.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_MORE_DATA | More data is available then the current buffer can hold. Some entries may be returned in the mszMachinenameList buffer.
PDH_INSUFFICIENT_BUFFER | The buffer provided is not large enough to contain any data.
PDH_INVALID_ARGUMENT | A required argument is invalid or a reserved argument is not NULL.

Remarks

The term real-time as used in the description of this function does not imply the standard meaning of the term real-time. Instead, it describes the collection of performance data from a source providing current information (for example, the registry or a WMI provider) rather than from a log file.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

PdhConnectMachine


PdhEnumObjectItems

The PdhEnumObjectItems function returns the available counters and instances provided by the specified object on the specified machine.

PDH_STATUS PdhEnumObjectItems(
  LPCTSTR szDataSource,
  LPCTSTR szMachineName,
  LPCTSTR szObjectName,
  LPTSTR mszCounterList,
  LPDWORD pcchCounterListLength,
  LPTSTR mszInstanceList,
  LPDWORD pcchInstanceListLength,
  DWORD dwDetailLevel,
  DWORD dwFlags
);

Parameters

szDataSource
Windows 2000 or later: [in] A pointer to a null-terminated string containing either the name of a log file or the null termination only. If you specify the name of a log file, performance data will be taken from that log file. If this parameter contains a null string, performance data will be collected from a real-time data source.

Windows NT 4.0: [in] Reserved. Must be NULL.

szMachineName
[in] A pointer to a null-terminated string containing the name of the machine on which to list the object items. If the machine specified is not in the list of currently connected machines, the PDH will try to connect to it.
szObjectName
[in] A pointer to a null-terminated string containing the name of the object on the specified machine from which the items are to be listed.
mszCounterList
[out] A pointer to a null-terminated string containing the name of the buffer allocated by the calling function that receives the MULTI_SZ list of performance counters provided by the specified object on the specified machine. This parameter can be NULL if the value of the variable referenced by pcchCounterListLength is zero.
pcchCounterListLength
[in/out] A pointer to a DWORD that on input contains the size, in characters, of the available buffer. On output, it receives the size of the buffer used. If the buffer size is zero on input, no data is returned in the mszCounterList buffer, and the size of the buffer required is returned in the variable referenced by pcchCounterListLength. The size returned includes both terminating NULL characters of the MULTI_SZ string.
mszInstanceList
[out] A pointer to a null-terminated string containing the name of the buffer allocated by the calling function that receives the MULTI_SZ list of the instances of the specified object on the specified machine. This argument can be NULL if the value of the variable pointed to by pcchCounterListLength is zero.
pcchInstanceListLength
[in/out] A pointer to a variable that on input contains the size, in characters, of the available buffer. On output, it receives the size of the buffer used. If the buffer size is zero on input, no data is returned in the mszInstanceList buffer, and the size of the buffer required is returned in the variable pointed to by pcchInstanceListLength. The size returned includes both terminating NULL characters of the MULTI_SZ string. If the specified object does not support variable instances, then the returned value will be 0. If the specified object does support variable instances, but does not currently have any instances, then the value returned is 2, which is the size, in characters, of an empty MULTI_SZ list string.
dwDetailLevel
[in] The detail level of the performance items to return. All items that are of the specified detail level or less will be returned. This parameter can be one of the following values.
Value | Meaning
PERF_LEVEL_NOVICE | Novice user level of detail.
PERF_LEVEL_ADVANCE | Advanced user level of detail. Includes the novice level of detail.
PERF_DETAIL_EXPERT | Expert user level of detail. Includes the novice and advanced levels of detail.
PERF_DETAIL_WIZARD | System designer level of detail. Includes all levels of detail.

dwFlags
This parameter must be zero.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_MORE_DATA | There are more entries available to return than there is room in the buffer. Some entries might be returned in the buffer, however.
PDH_INSUFFICIENT_BUFFER | The buffer provided is not large enough to contain any data.
PDH_INVALID_ARGUMENT | A required argument is invalid or a reserved argument is not NULL.
PDH_MEMORY_ALLOCATION_FAILURE | A required temporary buffer could not be allocated.
PDH_CSTATUS_NO_MACHINE | The specified machine is offline or unavailable.
PDH_CSTATUS_NO_OBJECT | The specified object could not be found on the specified machine.

Remarks

Consecutive calls to this function will return identical lists of counters and instances, because PdhEnumObjectItems will always query the list of performance objects defined by the last call to PdhEnumObjects. To refresh the list of performance objects, call PdhEnumObjects with a bRefresh flag value of TRUE before calling PdhEnumObjectItems again.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

PdhConnectMachine, PdhEnumObjects


PdhEnumObjects

The PdhEnumObjects function returns a list of objects available on the specified machine.

PDH_STATUS PdhEnumObjects(
  LPCTSTR szDataSource,
  LPCTSTR szMachineName,
  LPTSTR mszObjectList,
  LPDWORD pcchBufferLength,
  DWORD dwDetailLevel,
  BOOL bRefresh
);

Parameters

szDataSource
Windows 2000 or later: [in] A pointer to a null-terminated string containing either the name of a log file or a null string. If you specify the name of a log file, performance data will be taken from that log file. If this parameter contains a null string, performance data will be collected from a real-time data source.

Windows NT 4.0: [in] Reserved. Must be NULL.

szMachineName
[in] A pointer to a null-terminated string containing the name of the machine on which to list the objects. If the machine specified is not in the list of currently connected machines, the PDH will try to connect to the machine and add it to the list.
mszObjectList
[out] A pointer to a null-terminated string containing the name of a buffer, allocated by the calling function, that receives the MULTI_SZ list of objects available on the specified machine. Each object name in this list is terminated by a NULL character. This parameter may be NULL if the value of the variable pointed to by pcchBufferLength is zero.
pcchBufferLength
[in/out] A pointer to a variable containing the size, in characters, of the available buffer on input and the size of the returned buffer on output. If the buffer size is zero on input, no data is returned in the mszObjectList buffer, and the parameter can be NULL. However, the size of the buffer required, in characters, is returned in the variable pointed to by pcchBufferLength. The size returned includes both terminating NULL characters of the MULTI_SZ string.
dwDetailLevel
[in] The detail level of the performance items to return. All items that are of the specified detail level or less will be returned. This parameter can be one of the following values.
Value | Meaning
PERF_DETAIL_NOVICE | Novice user level of detail.
PERF_DETAIL_ADVANCED | Advanced user level of detail. Includes the novice level of detail.
PERF_DETAIL_EXPERT | Expert user level of detail. Includes the novice and advanced levels of detail.
PERF_DETAIL_WIZARD | System designer level of detail. Includes all levels of detail.

bRefresh
[in] Indicates whether a new list of objects will be obtained from the specified machine. If the machine is not currently connected by the PDH, then this flag is ignored and the list is refreshed automatically. This parameter can be one of the following values.
Value | Meaning
TRUE | A new performance data buffer for this machine will be cached before the objects are returned.
FALSE | A new performance data buffer for this machine will not be cached; the object list will be returned from currently cached performance data buffer.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_MORE_DATA | There are more entries available to return than there is room in the buffer. Some entries might be returned in the buffer, however.
PDH_INSUFFICIENT_BUFFER | The buffer provided is not large enough to contain any data.
PDH_CSTATUS_NO_MACHINE | The machine is unavailable.
PDH_CSTATUS_NO_OBJECT | The specified object could not be found on the machine.
PDH_INVALID_ARGUMENT | A required argument is invalid or a reserved argument is not NULL.

Remarks

When you request a required buffer size, the bRefresh flag should be FALSE for all subsequent calls to this function. Otherwise, the size might not be valid.

The term real-time as used in the description of this function does not imply the standard meaning of the term real-time. Instead, it describes the collection of performance data from a source providing current information (for example, the registry or a WMI provider) rather than from a log file.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

PdhConnectMachine, PdhEnumMachines


PdhExpandCounterPath

The PdhExpandCounterPath function examines the specified machine (or local machine if none is specified) for counters and instances of counters that match the wildcard strings in the counter path.

PDH_STATUS PdhExpandCounterPath(
  LPCTSTR szWildCardPath,
  LPTSTR mszExpandedPathList,
  LPDWORD pcchPathListLength
);

Parameters

szWildCardPath
[in] A pointer to a null-terminated string containing the name of the counter path to expand.
mszExpandedPathList
[out] A pointer to a null-terminated string containing the name of the buffer that receives the list of counter path names that match the wildcard specification in the szWildCardPath buffer. Each counter path in this list is terminated by a NULL character. You must allocate the memory for this buffer before calling PdhExpandCounterPath.
pcchPathListLength
[in/out] A pointer to a DWORD that specifies the size of the mszExpandedPathList buffer, in characters. On output, receives the length actually used by the returned path strings.

If the mszExpandedPathList buffer is too small to receive the entire list, PdhExpandCounterPath returns PDH_MORE_DATA. The pcchPathListLength variable receives the length required for the returned path strings.

Return Values

If the function succeeds, it returns PDH_CSTATUS_VALID_DATA.

If the function fails, the return value is a PDH error status defined in PDHMsg.h.

Remarks

The general counter path format is as follows:

\\machine\object(parent/instance#index)\counter

The parent, instance, index, and counter components of the format may contain either a valid name or a wildcard character. The machine, parent, instance, and index components are not necessary for all counters.

The counter paths you must use is determined by the counter itself. For example, the LogicalDisk object has an instance index, so you must provide the #index, or a wildcard. Therefore, you could use the following format:

\LogicalDisk(*/*#*)\*

In comparison, the Process object does not require an instance index. Therefore, you could use the following format:

\Process(*)\ID Process

The following is a list of the possible formats:

  • \\machine\object(parent/instance#index)\counter
  • \\machine\object(parent/instance)\counter
  • \\machine\object(instance#index)\counter
  • \\machine\object(instance)\counter
  • \\machine\object\counter
  • \object(parent/instance#index)\counter
  • \object(parent/instance)\counter
  • \object(instance#index)\counter
  • \object(instance)\counter
  • \object\counter

Example

The following example demonstrates how to use PdhExpandCounterPath.

#include <pdh.h>
#include <pdhmsg.h>
#include <stdio.h>

#define INITIALPATHSIZE 1000

LPSTR  szCtrPath = NULL;
char   szWildCardPath[256] = "\000";
DWORD  dwCtrPathSize = 0;

PDH_STATUS  pdhStatus;
HQUERY      hQuery;

void main()
{
    pdhStatus = PdhOpenQuery(0,0, &hQuery);

// Use the counter path format without specifying the machine.
//    \object(parent/instance#index)\counter

    sprintf(szWildCardPath, "\\LogicalDisk(*/*#*)\\*");

// First try with an initial buffer size.
    szCtrPath = (LPSTR) GlobalAlloc(GPTR, INITIALPATHSIZE);
    dwCtrPathSize = INITIALPATHSIZE;

    pdhStatus = PdhExpandCounterPath(szWildCardPath, szCtrPath,
                    &dwCtrPathSize);

// Check for a too small buffer.
    if (pdhStatus == PDH_MORE_DATA)
    {
        // dwCtrPathSize has the required length, minus the last NULL
        dwCtrPathSize++;
        GlobalFree(szCtrPath);
        szCtrPath = GlobalAlloc(GPTR, dwCtrPathSize);
        pdhStatus = PdhExpandCounterPath(szWildCardPath, szCtrPath,
                        &dwCtrPathSize);
    }

// Upon success, print all counter path names.
    if (pdhStatus == PDH_CSTATUS_VALID_DATA)
    {
        LPTSTR ptr;

        ptr = szCtrPath;
        while (*ptr)
        {
            printf("%s\n", ptr);
            ptr += strlen(ptr);
            ptr++;
        }
    }
    else printf("PdhExpandCounterPath failed: %d\n", pdhStatus);
}

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

PdhMakeCounterPath, PdhExpandWildCardPath


PdhExpandWildCardPath

The PdhExpandWildCardPath function expands any wildcard characters in the specified counter path string and returns the matching counter paths.

PDH_STATUS PdhExpandWildCardPath(
  LPCTSTR szDataSource,
  LPCTSTR szWildCardPath,
  LPTSTR mszExpandedPathList,
  LPDWORD pcchPathListLength,
  DWORD dwFlags
);

Parameters

szDataSource
Windows 2000 or later: [in] A pointer to a null-terminated string containing either the name of a log file or a null string. If you specify the name of a log file, performance data will be taken from that log file. If this parameter contains a null string, performance data will be collected from a real-time data source.

Windows NT 4.0: [in] Reserved. Must be NULL.

szWildCardPath
[in] A pointer to a null-terminated string containing the name of the counter path to expand.
mszExpandedPathList
[out] A pointer to a null-terminated string containing the name of the buffer that receives the list of counter path names that match the wildcard specification in the buffer that szWildCardPath points to. Each counter path in this list is terminated by a NULL character. You must allocate the memory for this buffer before calling PdhExpandWildCardPath.
pcchPathListLength
[in/out] A pointer to a DWORD that specifies the size, in characters, of the buffer that mszExpandedPathList points to. On output, receives the length actually used by the returned path strings.

If the buffer that mszExpandedPathList points to is too small to receive the entire list, PdhExpandWildCardPath returns PDH_MORE_DATA. The pcchPathListLength parameter receives the length required for the returned path strings.

dwFlags
[in] Flags determining which wildcard characters in the counter path string are to be expanded.
Value | Meaning
PDH_NOEXPANDCOUNTERS | Wildcard characters in the counter names specified in the counter path list are not expanded.
PDH_NOEXPANDINSTANCES | Wildcard characters in the instance names specified in the counter path list are not expanded.

Return Values

If the function succeeds, it returns PDH_CSTATUS_VALID_DATA.

If the function fails, the return value is a PDH error status defined in PDHMsg.h.

Remarks

PdhExpandWildCardPath differs from PdhExpandCounterPath in three ways:

  1. PdhExpandWildCardPath can expand only the wildcard characters in the counter or instance names according to the value of the dwFlags parameter, or it can expand all of them. PdhExpandCounterPath expands only the wildcard characters in the counter path string.
  2. The contents of a log file can be used as the source of counter names. In this case, PdhExpandWildCardPath will filter the counters listed in the log file according to the values of szWildCardPath and dwFlags.
  3. PdhExpandWildCardPath expands counter paths that include the machine to also include the machine and a connection will be made to the specified machine to resolve the wildcard matches. Counter paths that do not contain a machine name will use the local machine to resolve wildcard matches.

The general counter path format is as follows:

\\machine\object(parent/instance#index)\counter

The parent, instance, index, and counter components of the format may contain either a valid name or a wildcard character. The machine, parent, instance, and index components are not necessary for all counters.

You determine the counter paths to use based on the counter itself. For example, the LogicalDisk object has an instance index, so you must provide the #index or a wildcard. Therefore, you could use the following format:

\LogicalDisk(*/*#*)\*

In comparison, the Process object does not require an instance index. Therefore, you could use the following format:

\Process(*)\ID Process

The following is a list of the possible formats:

  • \\machine\object(parent/instance#index)\counter
  • \\machine\object(parent/instance)\counter
  • \\machine\object(instance#index)\counter
  • \\machine\object(instance)\counter
  • \\machine\object\counter
  • \object(parent/instance#index)\counter
  • \object(parent/instance)\counter
  • \object(instance#index)\counter
  • \object(instance)\counter
  • \object\counter

If a wildcard character is specified in the parent name, all instances of the specified object that match the specified instance and counter fields will be returned.

If a wildcard character is specified in the instance name, all instances of the specified object and parent object will be returned if all instance names corresponding to the specified index match the wildcard character.

If a wildcard character is specified in the counter name, all counters of the specified object are returned.

Partial counter path string matches (for example, "pro*") are not supported.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

PdhExpandCounterPath


PdhFormatFromRawValue

The PdhFormatFromRawValue function converts one raw performance data value to the specified format, or two raw performance data values if the format conversion is time-based.

PDH_FUNCTION PdhFormatFromRawValue(
  DWORD dwCounterType,
  DWORD dwFormat,
  LONGLONG *pTimeBase,
  PPDH_RAW_COUNTER pRawValue1,
  PPDH_RAW_COUNTER pRawValue2,
  PPDH_FMT_COUNTERVALUE pFmtValue
);

Parameters

dwCounterType
[in] The type of counter. This parameter can be one of the counter types defined in Winperf.h, except for PERF_LARGE_RAW_FRACTION and PERF_LARGE_RAW_BASE. Refer to the counter list contained in the Counters.chm file provided with the Windows 2000 Resource Kit for a description of the counter type defined in Winperf.h. The Counters.chm file is located in the ResourceKit folder when the Resource Kit is installed.
dwFormat
[in] The format to which the raw performance data is to be converted. This parameter can be one of the following values.
Value | Meaning
PDH_FMT_DOUBLE | Return the calculated value as a double-precision floating point real.
PDH_FMT_LARGE | Return the calculated value as a 64-bit integer.
PDH_FMT_LONG | Return the calculated value as a long integer.

The value selected from the previous table can be combined using the OR operator with one of the following scaling flags.
Flag | Meaning
PDH_FMT_NOSCALE | Do not apply the counter's scaling factors in the calculation.
PDH_FMT_1000 | Multiply the final value by 1000.

pTimeBase
[in] A pointer to the time base, if necessary for the format conversion. If time base information is not necessary for the format conversion, the value of this parameter is ignored.
pRawValue1
[in] A pointer to a PDH_RAW_COUNTER structure containing a raw performance value.
pRawValue2
[in] A pointer to a PDH_RAW_COUNTER structure containing a second raw performance value, if necessary for the format conversion. If a second raw performance value is not necessary, this parameter should be NULL.
pFmtValue
[out] A pointer to a PDH_FMT_COUNTERVALUE structure that receives the formatted performance value.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.
PDH_INVALID_HANDLE | The counter handle is not valid.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

PDH_FMT_COUNTERVALUE, PDH_RAW_COUNTER, PdhReadRawLogRecord, PdhGetRawCounterArray, PdhGetCounterTimeBase


PdhGetCounterInfo

The PdhGetCounterInfo function retrieves information about a counter, such as data size, counter type, path, and user-supplied data values.

PDH_STATUS PdhGetCounterInfo(
  HQUERY hCounter,
  BOOLEAN bRetrieveExplainText,
  LPDWORD pdwBufferSize,
  PPDH_COUNTER_INFO lpBuffer
);

Parameters

hCounter
[in] A handle to the counter from which to retrieve the information.
bRetrieveExplainText
[in] Determines whether explain text is retrieved. If you set this parameter to TRUE, then the explain text for the counter is retrieved. If you set this parameter to FALSE, the field in the returned buffer is NULL.
pdwBufferSize
[in/out] A pointer to a DWORD containing the size, in bytes, of the buffer passed in lpBuffer. If the counter requires a buffer larger than is indicated by pdwBufferSize, then PdhGetCounterInfo returns the required buffer size in this parameter. If the function succeeds, this parameter contains the size of the data returned in lpBuffer. If this parameter is zero on input, the function does not return data in the buffer (in fact, lpBuffer can be NULL); it returns the required size, in bytes.
lpBuffer
[out] A pointer to a PDH_COUNTER_INFO structure that receives the counter information. The structure returned is variable-length, because the string data is appended to the end of the fixed-format portion of the structure. This is done so that all data is returned in a single buffer allocated by the caller.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.
PDH_INVALID_HANDLE | The counter handle is not valid.
PDH_MORE_DATA | The buffer supplied is not large enough to receive the requested data.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

PDH_COUNTER_INFO


PdhGetCounterTimeBase

The PdhGetCounterTimeBase function returns the time base of the specified counter.

PDH_STATUS PdhGetCounterTimeBase(
  HCOUNTER hCounter,
  LONGLONG *pTimeBase
);

Parameters

hCounter
[in] A handle to the counter.
pTimeBase
[out] A pointer to a variable that receives the time base. The time base is the number of performance values a counter samples per second.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.
PDH_INVALID_HANDLE | The counter handle is not valid.

Remarks

This function can be used to get the time base for a subsequent call to the PdhFormatFromRawValue function.

If a non-time-based counter is specified, PDH_INVALID_ARGUMENT will be returned.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

PdhFormatFromRawValue


PdhGetDataSourceTimeRange

The PdhGetDataSourceTimeRange function determines the time range, number of entries and, if applicable, the size of the buffer containing the performance data from the specified input source.

PDH_STATUS PdhGetDataSourceTimeRange(
  LPCTSTR szDataSource,
  LPDWORD pdwNumEntries,
  PPDH_TIME_INFO pInfo,
  LPDWORD dwBufferSize
);

Parameters

szDataSource
[in] A pointer to a null-terminated string containing the name of a log file that performance data will be taken from.
pdwNumEntries
[out] A pointer to a DWORD that receives the number of performance data collection sessions. The value of this parameter is always 1. This means that only one group of performance data can be collected for each call to PdhGetDataSourceTimeRange.
pInfo
[out] A pointer to a PDH_TIME_INFO structure that receives the time range.
dwBufferSize
[in] A pointer to a DWORD containing the size, in bytes, of the pInfo buffer.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.
PDH_INVALID_HANDLE | The counter handle is not valid.

The following are possible non-error return values.

Value | Description
PDH_DATA_SOURCE_IS_REAL_TIME | The current data source is a real-time data source.

Remarks

If the current data source is a real-time data source, a PDH_DATA_SOURCE_IS_REAL_TIME value is returned and no action is performed by this function.

The SampleCount member of the PDH_TIME_INFO structure, which the pInfo parameter points to, contains the number of samples collected during the time interval.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

PdhSetQueryTimeRange


PdhGetDefaultPerfCounter

The PdhGetDefaultPerfCounter function retrieves the name of the default counter for the specified object. This name can be used to set the initial selection of the counter browser list/combo box.

PDH_STATUS PdhGetDefaultPerfCounter(
  LPCTSTR szDataSource,
  LPCTSTR szMachineName,
  LPCTSTR szObjectName,
  LPTSTR szDefaultCounterName,
  LPDWORD pcchBufferSize
);

Parameters

szDataSource
Windows 2000 or later: [in] A pointer to a null-terminated string containing either the name of a log file or a null string. If you specify the name of a log file, performance data will be taken from that log file. If this parameter contains only a null string, performance data will be taken from a real-time data source.

Windows NT 4.0: Reserved. Must be NULL.

szMachineName
[in] A pointer to a null-terminated string containing the name of the machine to query.
szObjectName
[in] A pointer to a null-terminated string containing the name of the object in szMachineName to query.
szDefaultCounterName
[out] A pointer to a null-terminated string containing the name of the buffer that receives the default counter name for the specified object. This parameter can be NULL if the value of the variable referenced by pcchBufferSize is zero.
pcchBufferSize
[in/out] A pointer to a DWORD containing the size of the szDefaultCounterName buffer, in characters, when called, and the size of the counter name returned on return. If the value in the variable pointed to by this parameter is 0, then the required buffer size, in characters, for this object name is returned in the variable and no data is copied to the buffer.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INSUFFICIENT_BUFFER | The buffer provided is not large enough for the available data.
PDH_INVALID_ARGUMENT | A required argument is invalid or a reserved argument is not NULL.
PDH_MEMORY_ALLOCATION_FAILURE | A required temporary buffer could not be allocated.
PDH_CSTATUS_NO_MACHINE | The specified machine is offline or unavailable.
PDH_CSTATUS_NO_COUNTERNAME | The default object name cannot be read or found.
PDH_CSTATUS_NO_OBJECT | The specified object could not be found on the specified machine.
PDH_CSTATUS_NO_COUNTER | The default counter was not found in the specified object.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

PdhGetDefaultPerfObject


PdhGetDefaultPerfObject

The PdhGetDefaultPerfObject function retrieves the name of the default performance object. This name can be used to select the default entry in the object browser list box.

PDH_STATUS PdhGetDefaultPerfObject(
  LPCTSTR szDataSource,
  LPCTSTR szMachineName,
  LPTSTR szDefaultObjectName,
  LPDWORD pcchBufferSize
);

Parameters

szDataSource
Windows 2000 or later: [in] A pointer to a null-terminated string containing either the name of a log file or a null string. If you specify the name of a log file, performance data will be taken from that log file. If this parameter contains a null string, performance data will be taken from a real-time data source.

Windows NT 4.0: Reserved. Must be NULL.

szMachineName
[in] A pointer to a null-terminated string containing the name of the machine to query. If this value of this parameter is NULL, the local machine is queried.
szDefaultObjectName
[out] A pointer to a null-terminated string containing the name of the buffer that receives the fully qualified default object name. This parameter can be NULL if the value of the variable referenced by pcchBufferSize is zero.
pcchBufferSize
[in/out] A pointer to a DWORD containing the size of the szDefaultObjectName buffer, in characters, on input and the size of the returned object name on output. If the value in the variable referenced by this parameter is zero, the required buffer size, in characters, for this object name is returned in the variable and no data is copied to the buffer.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INSUFFICIENT_BUFFER | The buffer provided is not large enough for the available data.
PDH_INVALID_ARGUMENT | A required argument is invalid or a reserved argument is not NULL.
PDH_MEMORY_ALLOCATION_FAILURE | A required temporary buffer could not be allocated.
PDH_CSTATUS_NO_MACHINE | The specified machine is offline or unavailable.
PDH_CSTATUS_NO_COUNTERNAME | The default object name cannot be read or found.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

PdhGetDefaultPerfCounter


PdhGetDllVersion

The PdhGetDllVersion function returns the version of the currently installed Pdh.dll file.

PDH_FUNCTION PdhGetDllVersion(
  LPDWORD lpdwVersion
);

Parameters

lpdwVersion
[out] A pointer to a DWORD that receives the version of Pdh.dll. This parameter can be one of the following values.
Value | Description
PDH_CVERSION_WIN40 | The file version is Windows NT 4.0.
PDH_CVERSION_WIN50 | The file version is Windows 2000.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.

Remarks

This function is used to help in determining the functionality the currently installed version of Pdh.dll supports.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.


PdhGetFormattedCounterArray

The PdhGetFormattedCounterArray function returns an array of values of the specified counter in the format requested by the caller.

PDH_STATUS PdhGetFormattedCounterArray(
  HCOUNTER hCounter,
  DWORD dwFormat,
  LPDWORD lpdwBufferSize,
  LPDWORD lpdwBufferCount,
  PPDH_FMT_COUNTERVALUE_ITEM ItemBuffer
);

Parameters

hCounter
[in] A handle to the counter whose current value is to be formatted and returned.
dwFormat
[in] The formatting information sent by the caller to indicate how the data should be returned. This parameter can be one of the following values.
Value | Meaning
PDH_FMT_DOUBLE | Return data as a double-precision floating point real.
PDH_FMT_LARGE | Return data as a 64-bit integer.
PDH_FMT_LONG | Return data as a long integer.

The value selected from the previous table can optionally be combined using the OR operator with one of the following scaling flags.
Value | Meaning
PDH_FMT_NOSCALE | Do not apply the default scaling factor.
PDH_FMT_NOCAP100 | Counter values above 100 (for example, counter values measuring the processor load on multiprocessor machines) will not be reset to 100. The default behavior is that counter values are capped at a value of 100.
PDH_FMT_1000 | Multiply the actual value by 1000.

lpdwBufferSize
[in/out] A pointer to a DWORD that contains the size, in bytes, of the buffer pointed to by ItemBuffer.
lpdwBufferCount
[out] A pointer to a DWORD that contains the number of counter values in the buffer pointed to by ItemBuffer.
ItemBuffer
[out] A pointer to an array of PDH_FMT_COUNTERVALUE_ITEM structures that receives the counter values.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.
PDH_INVALID_HANDLE | The counter handle is not valid.

Remarks

The data for the counter is locked for the duration of the call to PdhGetFormattedCounterArray to prevent any changes during the processing of the call.

The value of hCounter can be obtained by a call to PdhAddCounter, with a wildcard specified for the instance name.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

PdhGetFormattedCounterValue, PdhGetRawCounterValue, PdhGetRawCounterArray, PDH_FMT_COUNTERVALUE_ITEM, PdhAddCounter


PdhGetFormattedCounterValue

The PdhGetFormattedCounterValue function returns the current value of a specified counter in the format requested by the caller.

PDH_STATUS PdhGetFormattedCounterValue(
  HCOUNTER hCounter,
  DWORD dwFormat,
  LPDWORD lpdwType,
  PPDH_FMT_COUNTERVALUE pValue
);

Parameters

hCounter
[in] A handle to the counter whose current value is to be formatted and returned.
dwFormat
[in] The formatting information sent by the caller to indicate how the data should be returned. This parameter can be one of the following values.
Value | Meaning
PDH_FMT_DOUBLE | Return data as a double-precision floating point real.
PDH_FMT_LARGE | Return data as a 64-bit integer.
PDH_FMT_LONG | Return data as a long integer.

The value selected from the previous table can be combined using the OR operator with one of the following scaling flags.
Value | Meaning
PDH_FMT_NOSCALE | Do not apply the default scaling factor.
PDH_FMT_NOCAP100 | Counter values above 100 (for example, counter values measuring the processor load on multiprocessor machines) will not be reset to 100. The default behavior is that counter values are capped at a value of 100.
PDH_FMT_1000 | Multiply the actual value by 1000.

lpdwType
[out] A pointer to a DWORD that receives the counter type. The possible counter types are described in WINPERF.H. This parameter is optional.
pValue
[out] A pointer to a PDH_FMT_COUNTERVALUE structure that receives the counter value.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.
PDH_INVALID_DATA | The specified counter does not contain valid data or a successful status code.
PDH_INVALID_HANDLE | The counter handle is not valid.

Remarks

The data for the counter is locked (protected) for the duration of the call to PdhGetFormattedCounterValue to prevent any changes during the processing of the call. Reading the data (calling this function successfully) clears the data-changed flag for the counter.

Obtaining the value of rate counters such as Page faults/sec requires that PdhCollectQueryData be called twice, with a specific time interval between the two calls, before calling PdhGetFormattedCounterValue. Call Sleep to implement the waiting period between the two calls to PdhCollectQueryData.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

PdhGetRawCounterValue, PdhSetCounterScaleFactor, PdhCollectQueryData


PdhGetLogFileSize

The PdhGetLogFileSize function returns the size, in bytes, of the specified log file.

PDH_STATUS PdhGetLogFileSize(
  HLOG hLog,
  LONGLONG *llSize
);

Parameters

hLog
[in] A handle to the log file. This handle is returned by the PdhOpenLog function.
llSize
[out] A pointer to a variable that receives the length of the log file.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_LOG_FILE_OPEN_ERROR | An error occurred during the attempt to open the log file.
PDH_INVALID_HANDLE | An invalid log file handle was specified.
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

PdhOpenLog


PdhGetRawCounterArray

The PdhGetRawCounterArray function returns an array of raw values from the specified counter.

PDH_STATUS PdhGetRawCounterArray(
  HCOUNTER hCounter,
  LPDWORD lpdwBufferSize,
  LPDWORD lpdwItemCount,
  PPDH_RAW_COUNTER_ITEM ItemBuffer
);

Parameters

hCounter
[in] A handle to the counter from which to retrieve the current raw values.
lpdwBufferSize
[in/out] A pointer to a DWORD that contains the size, in bytes, of the buffer pointed to by ItemBuffer.
lpdwItemCount
[out] A pointer to a DWORD that contains the number of values in the buffer pointed to by ItemBuffer.
ItemBuffer
[out] A pointer to an array of PDH_RAW_COUNTER_ITEM structures that receives the counter values.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.
PDH_MORE_DATA | The buffer was not large enough to contain the counter data.
PDH_INVALID_HANDLE | The counter handle is not valid.

Remarks

The data for the counter is locked for the duration of the call to PdhGetRawCounterArray to prevent any changes during processing of the call.

The value of hCounter can be obtained by a call to PdhAddCounter, with a wildcard specified for the instance name.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

PdhGetFormattedCounterValue, PdhGetFormattedCounterArray, PdhCalculateCounterFromRawValue, PDH_RAW_COUNTER_ITEM, PdhAddCounter


PdhGetRawCounterValue

The PdhGetRawCounterValue function returns the current raw value of the counter.

PDH_STATUS PdhGetRawCounterValue(
  HCOUNTER hCounter,
  LPDWORD lpdwType,
  PPDH_RAW_COUNTER pValue
);

Parameters

hCounter
[in] A handle to the counter from which to retrieve the current raw value.
lpdwType
[out] A pointer to a DWORD that receives the counter type. The possible counter types are described in WINPERF.H. This parameter is optional.
pValue
[out] A pointer to a PDH_RAW_COUNTER structure that receives the counter value.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.
PDH_INVALID_HANDLE | The counter handle is not valid.

Remarks

The data for the counter is locked (protected) for the duration of the call to PdhGetRawCounterValue to prevent any changes during processing of the call.

Obtaining the value of rate counters such as Page faults/sec requires that PdhCollectQueryData be called twice, with a specific time interval between the two calls, before calling PdhGetRawCounterValue. Call Sleep to implement the waiting period between the two calls to PdhCollectQueryData.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

PdhGetFormattedCounterValue, PdhCalculateCounterFromRawValue, PdhCollectQueryData


PdhIsRealTimeQuery

The PdhIsRealTimeQuery function determines if the specified query is a real-time query.

BOOL PdhIsRealTimeQuery(
  HWND hQuery
);

Parameters

hQuery
[in] A handle to the query.

Return Values

If the query is a real-time query, the return value is TRUE.

If the query is not a real-time query, the return value is FALSE.

Remarks

The term real-time as used in the description of this function does not imply the standard meaning of the term real-time. Instead, it describes the collection of performance data from a source providing current information (for example, the registry or a WMI provider) rather than from a log file.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

PdhSelectDataSource


PdhLookupPerfIndexByName

The PdhLookupPerfIndexByName function returns the counter index corresponding to the specified counter name.

PDH_FUNCTION PdhLookupPerfIndexByName(
  LPCTSTR *szMachineName,
  LPCTSTR szNameBuffer,
  LPDWORD pdwIndex
);

Parameters

szMachineName
[in] A pointer to a null-terminated string containing the name of a buffer that contains the name of the machine where the specified counter is located. The machine name can be specified by the DNS name or the IP address.
szNameBuffer
[in] A pointer to a null-terminated string containing the name of a buffer that contains the full name of the counter.
pdwIndex
[out] A pointer to a DWORD that receives the index of the counter.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.

Remarks

The general counter path format is as follows:

\\machine\object(parent/instance#index)\counter

The parent, instance, index, and counter components of the format may contain either a valid name or a wildcard character. The machine, parent, instance, and index components are not necessary for all counters.

The counter paths you must use is determined by the counter itself. For example, the LogicalDisk object has an instance index, so you must provide the #index, or a wildcard. Therefore, you could use the following format:

\LogicalDisk(*/*#*)\*

In comparison, the Process object does not require an instance index. Therefore, you could use the following format:

\Process(*)\ID Process

The following is a list of the possible formats:

  • \\machine\object(parent/instance#index)\counter
  • \\machine\object(parent/instance)\counter
  • \\machine\object(instance#index)\counter
  • \\machine\object(instance)\counter
  • \\machine\object\counter
  • \object(parent/instance#index)\counter
  • \object(parent/instance)\counter
  • \object(instance#index)\counter
  • \object(instance)\counter
  • \object\counter

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

PdhLookupPerfNameByIndex


PdhLookupPerfNameByIndex

The PdhLookupPerfNameByIndex function returns the performance object name corresponding to the specified index.

PDH_STATUS PdhLookupPerfNameByIndex(
  LPCTSTR *szMachineName,
  DWORD dwNameIndex,
  LPTSTR szNameBuffer,
  LPDWORD pcchNameBufferSize
);

Parameters

szMachineName
[in] A pointer to a null-terminated string containing the name of a buffer that contains the name of the machine where the specified performance object is located. The machine name can be specified by the DNS name or the IP address.
dwNameIndex
[in] The index of the performance object.
szNameBuffer
[out] A pointer to a null-terminated string containing the name of the buffer that receives the name of the performance object.
pcchNameBufferSize
[in] A pointer to a DWORD containing the size, in bytes, of the szNameBuffer buffer.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INSUFFICIENT_BUFFER | The buffer is not large enough to contain any data.
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

PdhLookupPerfIndexByName


PdhMakeCounterPath

The PdhMakeCounterPath function creates a full counter path using the members specified in the structure passed in the parameter list.

PDH_STATUS PdhMakeCounterPath(
  PDH_COUNTER_PATH_ELEMENTS *pCounterPathElements,
  LPTSTR szFullPathBuffer,
  LPDWORD pcchBufferSize,
  DWORD dwFlags
);

Parameters

pCounterPathElements
[in] A pointer to a PDH_COUNTER_PATH_ELEMENTS structure that contains the individual members that are to make up the path. The following table indicates which members are required and which are optional.
Member | Required or optional
szMachineName | optional
szObjectName | required
szInstanceName | optional
szParentInstance | optional
dwInstanceIndex optional
((DWORD)–1 if no index)
szCounterName | required

If a required member is not present, then no path string will be constructed. If the szMachineName member is NULL, then no machine name will be included in the path (a generic path will be created). If the instance name argument is NULL, then no instance reference will be inserted into the path string and the szParentInstance and the dwInstanceIndex members will be ignored.

szFullPathBuffer
[out] A pointer to a null-terminated string containing the name of the buffer allocated by the caller that receives the full path string.
pcchBufferSize
[in/out] A pointer to a DWORD containing the size, in bytes, of the available buffer on input. On output, receives the size of the buffer used. If the buffer size on input is zero, then no data is returned in the szFullPathBuffer buffer, however, the size of the buffer required is returned in the variable. The size returned includes the terminating NULL character of the string.
dwFlags
[in] The format of the input and output counter values. This parameter can be one of the following values.
Value | Description
PDH_PATH_WBEM_RESULT | Windows 2000 or later: The path is returned as in WMI format.
PDH_PATH_WBEM_INPUT | Windows 2000 or later: The input is assumed to be in WMI format.
0 | The path is returned as a list of registry path items.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INSUFFICIENT_BUFFER | The buffer is not large enough to contain any data.
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

PDH_COUNTER_PATH_ELEMENTS, PdhParseCounterPath


PdhObjectHasInstances

The PdhObjectHasInstances function determines whether the specified object contains instances.

PDH_FUNCTION PdhObjectHasInstances(
  LPCTSTR szDataSource,
  LPCTSTR szMachineName,
  LPCTSTR szObjectName,
  LPDWORD pdwFlags
);

Parameters

szDataSource
Windows 2000 or later: [in] A pointer to a null-terminated string containing either the name of a log file or the null termination only. If you specify the name of a log file, performance data will be taken from that log file. If this parameter contains only a NULL, performance data will be taken from a real-time data source.

Windows NT 4.0: Reserved. Must be NULL.

szMachineName
[in] A pointer to a null-terminated string containing the name of the machine where the performance object is located. If the value of this parameter is NULL, the connection is established to the local machine.
szObjectName
[in] A pointer to a null-terminated string containing the name of the performance object on the specified machine.
pdwFlags
[out] Indicates whether the specified object contains instances. This parameter can be one of the following values.
Value | Meaning
0 | The object does not have instances.
PDH_OBJECT_HAS_INSTANCES | The object does have instances.

Return Values

If the specified performance object has instances, PdhObjectHasInstances returns TRUE. Otherwise, the function returns FALSE.

Remarks

"Process" is an example of a performance object that contains instances, and "Browser" is an example of a performance object that does not.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

PdhBrowseCounters, PdhParseInstanceName, PdhMakeCounterPath


PdhOpenLog

The PdhOpenLog function opens the specified log file for reading or writing.

PDH_STATUS PdhOpenLog(
  LPCTSTR szLogFileName,
  DWORD dwAccessFlags,
  LPDWORD lpdwLogType,
  HQUERY hQuery,
  DWORD dwMaxSize,
  LPCTSTR szUserCaption,
  HLOG *phLog
);

Parameters

szLogFileName
[in] A pointer to a null-terminated string containing the name of the buffer that contains the name of the log file to be opened.
dwAccessFlags
[in] The type of access to be specified when the log file is opened. This parameter can be one of the following values.
Value | Meaning
PDH_LOG_READ_ACCESS | A new log file is opened for a read operation.
PDH_LOG_WRITE_ACCESS | A new log file is opened for a write operation.
PDH_LOG_UPDATE_ACCESS | An existing log file is opened for a write operation.

The value selected from the previous table can be combined using the OR operator with one of the following create access flags.
Value | Meaning
PDH_LOG_CREATE_NEW | A new log file with the specified name is created.
PDH_LOG_CREATE_ALWAYS | A new log file with the specified name is created and any existing log file with the same name is erased.
PDH_LOG_OPEN_EXISTING | An existing log file with the specified name is opened. If a log file with the specified name does not exist, this is equal to PDH_LOG_CREATE_NEW.
PDH_LOG_OPEN_ALWAYS | An existing log file with the specified name is opened or a new log file with the specified name is created.

lpdwLogType
[in] A pointer to a DWORD that indicates the type of log file to be opened. This parameter can be one of the following values.
Value | Meaning
PDH_LOG_TYPE_UNDEFINED | Undefined log file format.
PDH_LOG_TYPE_CSV | Text files containing column headers in the first line, and individual data samples in each subsequent line.
PDH_LOG_TYPE_TSV | Same as PDH_LOG_TYPE_CSV.
PDH_LOG_TYPE_BINARY | Binary log file format. Includes circular log files.
PDH_LOG_TYPE_PERFMON | Perfmon log file format.

hQuery
[in] A buffer containing the query handle. The value can be NULL if the log file is to be opened for reading.
dwMaxSize
[in] The maximum size of the log file, if the log file is a limited-size or circular log file.
szUserCaption
[in] A pointer to a null-terminated string containing the name of the buffer that contains the user-defined caption of the log file. A log file caption generally describes the contents of the log file. When an existing log file is opened, the value of this parameter is ignored.
phLog
[out] A pointer to a buffer that receives a handle to the opened log file.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.

Remarks

When using this function to write performance data to a log file, a query must first be opened using PdhOpenQuery.

There must be a currently opened query, and the desired counters must be added to it, before this function is called.

Note that log files in the Perfmon format can only be opened for reading.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

PdhOpenQuery, PdhUpdateLog, PdhUpdateLogFileCatalog,PdhGetLogFileSize


PdhOpenQuery

The PdhOpenQuery function creates and initializes a unique query structure that is used to manage the collection of performance data.

PDH_STATUS PdhOpenQuery(
  LPCTSTR szDataSource,
  DWORD_PTR dwUserData,
  HQUERY *phQuery
);

Parameters

szDataSource
Windows 2000 or later: [in] A pointer to a null-terminated string containing either the name of a log file or the null termination only. If you specify the name of a log file, performance data will be taken from that log file. If this parameter contains only a NULL, performance data will be taken from a real-time data source.

Windows NT 4.0: Reserved. Must be NULL.

dwUserData
[in] A user-defined value that is to be associated with this query.
phQuery
[out] A pointer to the buffer that receives a handle to the query that is created.

Return Values

If the function succeeds, it returns ERROR_SUCCESS, creates a new query, and returns a handle to the query in the buffer pointed to by phQuery.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | One or more arguments are invalid.
PDH_MEMORY_ALLOCATION_FAILURE | A memory buffer could not be allocated.

Remarks

You can call PdhGetCounterInfo to retrieve the user data value set by dwUserData.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

PdhCloseQuery, PdhGetCounterInfo


PdhParseCounterPath

The PdhParseCounterPath function parses the elements of the counter path and stores the results in the structure passed by the caller.

PDH_STATUS PdhParseCounterPath(
  LPCTSTR szFullPathBuffer,
  PDH_COUNTER_PATH_ELEMENTS *pCounterPathElements,
  LPDWORD pdwBufferSize,
  DWORD dwFlags
);

Parameters

szFullPathBuffer
[in] A pointer to a null-terminated string containing the name of the buffer that contains the counter path to parse.
pCounterPathElements
[out] A pointer to a PDH_COUNTER_PATH_ELEMENTS structure that receives the individual components of the path referenced by the szFullPathBuffer parameter. The buffer space allocated for this should be large enough for the structure and the strings that will be referenced by the members in this structure. As this function parses the elements in the path, they are stored in the buffer after the PDH_COUNTER_PATH_ELEMENTS structure. This allows the calling function to allocate, and eventually free, only a single block of memory for this structure and the strings referenced by the members of this structure, rather than having the calling function allocate the structure and the string buffers separately.
pdwBufferSize
[in/out] A pointer to a DWORD containing the size, in bytes, of the buffer referenced by pCounterPathElements on input. On output, it receives the size of the buffer used. If the buffer size on input is zero, then no data is returned in the pCounterPathElements buffer, however, the size of the buffer required is returned in the variable referenced by this pointer.
dwFlags
Reserved. Must be zero.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An argument is incorrect, or this function does not have the necessary access to that argument.
PDH_INSUFFICIENT_BUFFER | The buffer supplied is not large enough to accept the resulting data.
PDH_INVALID_PATH | The path is not formatted correctly and cannot be parsed.
PDH_MEMORY_ALLOCATION_FAILURE | A temporary buffer cannot be allocated.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

PDH_COUNTER_PATH_ELEMENTS, PdhMakeCounterPath


PdhParseInstanceName

The PdhParseInstanceName function parses the elements of an instance string and returns them in the buffers supplied by the caller.

PDH_STATUS PdhParseInstanceName(
  LPCTSTR szInstanceString,
  LPTSTR szInstanceName,
  LPDWORD pcchInstanceNameLength,
  LPTSTR szParentName,
  LPDWORD pcchParentNameLength,
  LPDWORD lpIndex
);

Parameters

szInstanceString
[in] A pointer to a null-terminated string containing the instance substring to parse into individual components. This string can contain the following formats, and is less than MAX_PATH characters in length:

instance
instance#index
parent/instance
parent/instance#index

szInstanceName
[out] A pointer to a null-terminated string containing the name of the buffer that receives the instance name parsed from the instance string. This pointer can be NULL if the variable referenced by the pcchInstanceNameLength parameter is zero.
pcchInstanceNameLength
[in] A pointer to a DWORD that contains the length of the szInstanceName buffer. If the value of this variable is zero, the buffer size required to hold the instance name will be returned.
szParentName
[out] A pointer to a null-terminated string containing the name of a buffer that receives the name of the parent index if one is specified. This parameter can be NULL if the value of the variable referenced by the pcchParentNameLength parameter is zero.
pcchParentNameLength
[in/out] A pointer to a DWORD that contains the length of the szParentName buffer. If the value of this variable is zero, the buffer size required to hold the instance name is returned.
lpIndex
[out] A pointer to a DWORD that receives the index value of the instance. If an index entry is not present in the string, then this value is zero. This parameter can be NULL.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An argument is invalid or incorrect.
PDH_INSUFFICIENT_BUFFER | One or both of the string buffers supplied is not large enough for the strings to be returned.
PDH_INVALID_INSTANCE | The instance string is incorrectly formatted, exceeds MAX_PATH characters in length, or cannot be parsed.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

PdhMakeCounterPath


PdhReadRawLogRecord

The PdhReadRawLogRecord function reads the information in the specified binary trace log file.

PDH_STATUS PdhReadRawLogRecord(
  HLOG hLog,
  FILETIME ftRecord,
  PPDH_RAW_LOG_RECORD pRawLogRecord,
  LPDWORD pdwBufferLength
);

Parameters

hLog
[in] A handle to the log file.
ftRecord
[in] The timestamp of the record to be read.
pRawLogRecord
[out] A pointer to a PDH_RAW_LOG_RECORD structure that receives the log file record information.
pdwBufferLength
[in] A pointer to a DWORD that receives the length of the pRawLogRecord buffer.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h.

Remarks

This function is intended to be used only with binary trace log files and is not to be used when reading CSV, TSV, Perfmon, and binary log files created by either the Windows NT System Monitor, the Windows NT and Windows 2000 Performance Monitors, or PDH interface functions. Use the PdhCollectQueryData function to do this.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

PDH_RAW_LOG_RECORD, PdhFormatFromRawValue,PdhCollectQueryData


PdhRemoveCounter

The PdhRemoveCounter function removes a counter from a query.

[C++]
PDH_STATUS PdhRemoveCounter(
  HCOUNTER hCounter
);
[Visual Basic]
PdhRemoveCounter(
  ByVal CounterHandle as Long
)
as Long

Parameters

[C++] hCounter
[in] A handle to the counter to remove from its query.
[Visual Basic] CounterHandle
[in] The ID of the counter returned by the PdhAddCounter function.

Return Values

If the function succeeds, it returns ERROR_SUCCESS and removes the specified counter from its query. Otherwise, the function returns a PDH error value.

The following is the possible PDH error value.

Value | Meaning
PDH_INVALID_HANDLE | The counter handle is not valid.

[C++] PDH error values are defined in PDHMsg.h.

[Visual Basic] PDH error values are defined in PDHDefs.txt.

Remarks

After you remove a counter, any references to it using a handle passed in hCounter will be invalid and will return an error.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h (C/C++).
Library: Use Pdh.lib.

See Also

PdhAddCounter, PdhOpenQuery


PdhSelectDataSource

The PdhSelectDataSource function displays a dialog window that prompts the user to specify where the performance data will be collected.

PDH_STATUS PdhSelectDataSource(
  HWND hWndOwner,
  DWORD dwFlags,
  LPTSTR szDataSource,
  LPDWORD pcchBufferLength
);

Parameters

hWndOwner
[in] The owner of the dialog window that is displayed. This can be NULL if there is no owner.
dwFlags
[in] The dialog windows that will be displayed to prompt for the data source. This parameter can be one of the following values.
Value | Meaning
PDH_FLAGS_FILE_BROWSER_ONLY | Display the file browser only.
0 | Display the data source selection dialog containing a button that can be clicked to display the file browser.

This function can prompt for the data source in two ways. If the value of this parameter is zero, then a dialog is displayed prompting the user to select performance data input from either a log file or a real-time source. If the user specified that data is to be collected from a log file, a file browser is displayed for the user to specify the name and location of the log file.

If the value of this parameter is PDH_FLAGS_FILE_BROWSER_ONLY, the file browser only will be displayed. This flag would be set when this function is used solely to prompt for the name and location of a log file.

szDataSource
[out] A pointer to a buffer that receives the description of the data source. The value of the parameter will be either a null-terminated string containing either the name of a log file containing the performance data, or NULL if the performance data is taken from a real-time data source.
pcchBufferLength
[in/out] The maximum length, in characters, of the szDataSource buffer.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is an error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | The length of the buffer passed in the pcchBufferLength is not equal to the actual length of the szDataSource parameter.
PDH_MEMORY_ALLOCATION_FAILURE | A zero-length buffer was passed in the szDataSource parameter.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

PdhIsRealTimeQuery


PdhSetCounterScaleFactor

The PdhSetCounterScaleFactor function sets the scale factor that is applied to the calculated value of the specified counter when you request the formatted counter value. If the PDH_FMT_NOSCALE flag is set, then this scale factor is ignored.

PDH_STATUS PdhSetCounterScaleFactor(
  HCOUNTER hCounter,
  LONG lFactor
);

Parameters

hCounter
[in] A handle to the counter to receive the scale factor.
lFactor
[in] The power of ten by which to multiply the calculated value before returning it. The valid range of this parameter is PDH_MIN_SCALE (–7) (the returned value is the actual value times 10–7) to PDH_MAX_SCALE (+7) (the returned value is the actual value times 10+7). A value of zero will set the scale to one, so that the actual value is returned.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is an error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | The scale value is out of range.
PDH_INVALID_HANDLE | The counter handle is not valid.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

PdhCalculateCounterFromRawValue, PdhComputeCounterStatistics, PdhGetFormattedCounterValue


PdhSetDefaultRealTimeDataSource

The PdhSetDefaultRealTimeDataSource function specifies the source of the real-time data to be collected.

PDH_FUNCTION PdhSetDefaultRealTimeDataSource(
  DWORD dwDataSourceId
);

Parameters

dwDataSourceId
[in] The source of the performance data. This parameter can be one of the following values.
Value | Meaning
DATA_SOURCE_REGISTRY | The data source is the registry interface.
DATA_SOURCE_WBEM | The data source is a real-time source.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | An invalid argument was specified.

Remarks

The term real-time as used in the description of this function does not imply the standard meaning of the term real-time. Instead, it describes the collection of performance data from a source providing current information (for example, the registry or a WMI provider) rather than from a log file.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

PdhSelectDataSource


PdhSetQueryTimeRange

The PdhSetQueryTimeRange function specifies the timeframe performance data will be collected for the specified query. This query refers to a log file that has been opened for reading.

PDH_STATUS PdhSetQueryTimeRange(
  HQUERY hQuery,
  PPDH_TIME_INFO pInfo
);

Parameters

hQuery
[in] A handle to the query.
pInfo
[in] A pointer to a PDH_TIME_INFO structure containing the time range.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_HANDLE | An invalid handle was specified.
PDH_INVALID_ARGUMENT | A time earlier than the starting time range value was specified as the ending time range value.

Remarks

When the end of the specified time range or the end of the log file is reached, the PdhCollectQueryData function will return PDH_NO_MORE_DATA.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

PdhGetDataSourceTimeRange, PdhCollectQueryData


PdhUpdateLog

The PdhUpdateLog function updates the current query and writes new data to the log file.

PDH_STATUS PdhUpdateLog(
  HLOG hLog,
  LPCTSTR szUserString
);

Parameters

hLog
[in] A handle to the log file to be updated.
szUserString
[in] A pointer to a null-terminated string containing the data to be added to the log file. This is generally used for comments within the log file.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_INVALID_HANDLE | An invalid log file handle was specified.
PDH_INVALID_ARGUMENT | A null string was passed in the szUserString parameter.

Remarks

There must be a currently opened query, and the desired counters must be added to it before this function is called. The query handle (hQuery) from PdhOpenQuery is passed to the call to PdhOpenLog before PdhUpdateLog is called.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

PdhUpdateLogFileCatalog, PdhGetLogFileSize, PdhOpenQuery, PdhOpenLog


PdhUpdateLogFileCatalog

The PdhUpdateLogFileCatalog function synchronizes the information in the log file catalog with the performance data in the log file.

PDH_STATUS PdhUpdateLogFileCatalog(
  HLOG hLog
);

Parameters

hLog
[in] A handle to the log file containing the file catalog to be updated.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_NOT_IMPLEMENTED | A handle to a CSV or TSV log file was specified. These log file types do not have catalogs.
PDH_UNKNOWN_LOG_FORMAT | A handle to a log file with an unknown format was specified.
PDH_INVALID_HANDLE | An invalid handle was specified.

Remarks

The log file catalog serves as an index to the performance data records in the log file, providing for faster searches for individual records in the file.

Catalogs should be updated when the data collection process is complete and the log file has been closed. The catalog can be updated during data collection, but doing this may disrupt the process of logging the performance data because updating the catalogs can be time consuming.

Perfmon, CSV, and TSV log files do not have catalogs. Specifying a handle to these log file types will result in a return value of PDH_NOT_IMPLEMENTED.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.

See Also

PdhUpdateLog, PdhGetLogFileSize


PdhValidatePath

The PdhValidatePath function validates that the specified counter is present on the machine specified in the counter path.

PDH_STATUS PdhValidatePath(
  LPCTSTR szFullCounterPath
);

Parameters

szFullCounterPath
[in] A pointer to a null-terminated string containing the counter path to validate.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHMsg.h. The following are possible error values.

Error value | Description
PDH_CSTATUS_NO_INSTANCE | The specified instance of the performance object was not found.
PDH_CSTATUS_NO_COUNTER | The specified counter was not found in the performance object.
PDH_CSTATUS_NO_OBJECT | The specified performance object was not found on the machine.
PDH_CSTATUS_NO_MACHINE | The specified machine could not be found or connected to.
PDH_CSTATUS_BAD_COUNTERNAME | The counter path string could not be parsed.
PDH_MEMORY_ALLOCATION_FAILURE | The function is unable to allocate a required temporary buffer.

Remarks

PdhValidatePath verifies the specified counter path in this order: machine, performance object, instance, and counter.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Library: Use Pdh.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

PdhMakeCounterPath


Performance Monitoring Functions for Visual Basic

The following functions are supported for working with performance data in Visual Basic.

PdhCloseQuery
PdhCollectQueryData
PdhRemoveCounter
PdhVbAddCounter
PdhVbCreateCounterPathList
PdhVbGetCounterPathElements
PdhVbGetCounterPathFromList
PdhVbGetDoubleCounterValue
PdhVbGetOneCounterPath
PdhVbIsGoodStatus
PdhVbOpenQuery


PdhVbAddCounter

The PdhVbAddCounter function creates a counter entry in the specified query object, and returns a handle to that counter upon successful completion.

PdhVbAddCounter(
  ByVal QueryHandle as Long,
  ByVal CounterPath as String,
  ByRef CounterHandle as Long
) as Long

Parameters

QueryHandle
The ID of the query to assign this counter to. This must be a value returned by a successful call to PdhVbOpenQuery.
CounterPath
The text string containing the name of the counter path to add to the query. The contents of this string must be a valid counter path, as obtained from the counter browser or other source.
CounterHandle
The unique reference that identifies this counter in the query. This variable must be initialized to zero before the function is called. It contains a valid value on return only if the function completes successfully.

Return Values

If the function succeeds, it returns a Long integer equal to ERROR_SUCCESS and a new handle in the CounterHandle variable.

If the function fails, the return value is a PDH error status defined in PDHDefs.txt. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | One or more of the arguments is invalid or incorrect.
PDH_MEMORY_ALLOCATION_FAILURE | A memory buffer could not be allocated.
PDH_INVALID_HANDLE | The query handle is not valid.
PDH_CSTATUS_NO_COUNTER | The specified counter was not found.
PDH_CSTATUS_NO_OBJECT | The specified object could not be found.
PDH_CSTATUS_NO_MACHINE | A machine entry could not be created.
PDH_CSTATUS_BAD_COUNTERNAME | An empty counter name path string was passed in.
PDH_FUNCTION_NOT_FOUND | The calculation function for this counter could not be determined.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Library: Use Pdh.lib.

See Also

PdhVbOpenQuery


PdhVbCreateCounterPathList

The PdhVbCreateCounterPathList function displays the performance counter browsing dialog box, which lets the user select several performance counters. Each selected counter path must then be read using the PdhVbGetCounterPathFromList function.

PdhVbCreateCounterPathList(
  ByVal DetailLevel as Long,
  ByVal CaptionString as String
) as Long

Parameters

DetailLevel
One of the following values defined in PDHDefs.txt. The selected value indicates the types of counters to be displayed in the dialog box:
Value | Counters displayed
PERF_DETAIL_NOVICE | Only counters that the novice user is likely to understand.
PERF_DETAIL_ADVANCED | Counters that the advanced user is likely to understand, in addition to the novice-user counters.
PERF_DETAIL_EXPERT | Counters that the expert user and software developer is likely to understand, in addition to the counters for the novice and advanced users.
PERF_DETAIL_WIZARD | All counters in the system.

CaptionString
A string variable that contains the text that will be displayed in the caption bar of the dialog box.

Return Values

The function returns the number of counter paths that the user selected.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Library: Use Pdh.lib.

See Also

PdhVbGetCounterPathFromList


PdhVbGetCounterPathElements

The PdhVbGetCounterPathElements function parses a fully qualified performance counter path string into its individual elements. Each of the string variables must be the same size (BufferSize) and dimensioned and initialized before it is used in this function.

PdhVbGetCounterPathElements(
  ByVal PathString as String,
  ByVal MachineName as String,
  ByVal ObjectName as String,
  ByVal InstanceName as String,
  ByVal ParentInstance as String,
  ByVal CounterName as String,
  ByVal BufferSize as Long
) as Long

Parameters

PathString
The counter path string that is to be broken up into its individual elements.
MachineName
The string to receive the Machine name element of the counter path specified in PathString.
ObjectName
The string to receive the Object element of the counter path specified in PathString.
InstanceName
The string to receive the Instance name element, if used, of the counter path specified in PathString.
ParentInstance
The string to receive the Parent Instance element, if used, of the counter path specified in PathString.
CounterName
The string to receive the Machine name element of the counter path specified in PathString.
BufferSize
The maximum size of each string variable used as a parameter to this function call.

Return Values

If the function succeeds, it returns a Long integer equal to ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in PDHDefs.txt. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | One or more of the string buffers is not the correct size.
PDH_INSUFFICIENT_BUFFER | One or more of the counter path elements is too large for the return buffer length.
PDH_MEMORY_ALLOCATION_FAILURE | A temporary memory buffer could not be allocated.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Library: Use Pdh.lib.


PdhVbGetCounterPathFromList

The PdhVbGetCounterPathFromList function copies the counter path referenced by the Index parameter from a counter path list created by the user from the most recent call to the PdhVbCreateCounterPathList function.

PdhVbGetCounterPathFromList(
  ByVal Index as Long,
  ByVal Buffer as String,
  ByVal BufferLength as Long
) as Long

Parameters

Index
The index of the counter path to retrieve. This must be a value that is greater than or equal to 1, and less than or equal to the value returned by the PdhVbCreateCounterPathList function.
Buffer
A dimensioned and initialized string that will receive the counter path that corresponds to the value of the Index parameter.
BufferLength
The maximum number of characters that will fit in the string referenced by Buffer.

Return Values

The function returns the number of characters copied to Buffer.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Library: Use Pdh.lib.

See Also

PdhVbCreateCounterPathList


PdhVbGetDoubleCounterValue

The PdhVbGetDoubleCounterValue function returns the current value of the specified counter as a double-precision floating point value. You should check CounterStatus before using the returned number, because the counter may not be valid when it is read. To check the counter status, call the PdhVbIsGoodStatus function.

PdhVbGetDoubleCounterValue(
  ByVal CounterHandle as Long,
  ByRef CounterStatus as Long
) as Double

Parameters

CounterHandle
The ID of the counter whose current value is to be read.
CounterStatus
The variable in which the current status of the counter value is returned to the caller. The returned data value is valid if and only if the value returned in CounterStatus is PDH_CSTATUS_VALID_DATA or PDH_CSTATUS_NEW_DATA (defined in PDHDefs.txt). If the value returned in CounterStatus is any other value, do not use the data.

Return Values

The function returns the double-precision floating point value of the current counter, computed and formatted as defined by the counter type.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Library: Use Pdh.lib.

See Also

PdhVbIsGoodStatus


PdhVbGetOneCounterPath

The PdhVbGetOneCounterPath function displays a dialog box that lets the user browse the available performance counters on a Windows NT/Windows 2000 system and select one counter. The counter selected is returned in the PathString variable. The PathString variable must be dimensioned and initialized before this function is called, and the dimensioned size must be indicated by the PathLength variable.

PdhVbGetOneCounterPath(
  ByVal PathString as String,
  ByVal PathLength as Long,
  ByVal DetailLevel as Long,
  ByVal CaptionString as String
) as Long

Parameters

PathString
The initialized string variable used to receive the counter path selected by the user.
PathLength
The length of the initialized PathString.
DetailLevel
One of the following values defined in PDHDefs.txt. The selected value indicates the types of counters to be displayed in the dialog box:
Value | Counters displayed
PERF_DETAIL_NOVICE | Only counters that the novice user is likely to understand.
PERF_DETAIL_ADVANCED | Counters that the advanced user is likely to understand, in addition to the novice-user counters.
PERF_DETAIL_EXPERT | Counters that the expert user and software developer is likely to understand, in addition to the counters for the novice and advanced users.
PERF_DETAIL_WIZARD | All counters in the system.

CaptionString
A string variable that contains the text that will be displayed in the caption bar of the dialog box.

Return Values

The function returns the number of characters written to the PathString buffer.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Library: Use Pdh.lib.


PdhVbIsGoodStatus

The PdhVbIsGoodStatus function tests a status value to determine if it is a success or failure code. If the status value is a successful one, then the return value will be nonzero. If it is a failure status code, the return value will be zero.

PdhVbIsGoodStatus(
  ByVal StatusValue as Long
) as Long

Parameters

StatusValue
The PDH status value returned by another PDH function that is to be tested.

Return Values

The function returns zero if the status code is a failure status code. It returns nonzero if the status code is a success status code.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Library: Use Pdh.lib.


PdhVbOpenQuery

The PdhVbOpenQuery function creates and initializes a unique query structure that is used to manage the collection of performance data.

PdhVbOpenQuery(
  ByRef QueryHandle as Long
) as Long

Parameters

QueryHandle
A variable that is cleared (equals 0) before the function is called and, if the function is successful, contains the unique ID of the query that is created and opened. This handle is used in the subsequent calls to other PDH functions to identify the query.

Return Values

If the function succeeds, it returns a Long integer equal to ERROR_SUCCESS and a new handle in the QueryHandle variable.

If the function fails, the return value is a PDH error status defined in PDHDefs.txt. The following are possible error values.

Error value | Description
PDH_INVALID_ARGUMENT | The argument is invalid or incorrect.
PDH_MEMORY_ALLOCATION_FAILURE | A temporary memory buffer could not be allocated.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Library: Use Pdh.lib.


Performance Monitoring Structures

The following structures are supported for working with performance data.

PDH Interface

Structure | Description
PDH_BROWSE_DLG_CONFIG | Used by the PdhBrowseCounters function to configure the PDH Browse Counters dialog box.
PDH_COUNTER_INFO | Contains information describing the properties of a counter.
PDH_COUNTER_PATH_ELEMENTS | Contains the parsed elements of a fully qualified counter path.
PDH_DATA_ITEM_PATH_ELEMENTS | Contains the path elements of a specific data item.
PDH_FMT_COUNTERVALUE | Contains the value of a counter.
PDH_FMT_COUNTERVALUE_ITEM | Contains the name of, and information about, a specific counter value.
PDH_RAW_COUNTER | Contains raw counter data as it was collected from the provider.
PDH_RAW_COUNTER_ITEM | Contains the name of, and information about, a specific raw counter value.
PDH_RAW_LOG_RECORD | Stores information about a record contained in a binary trace log file.
PDH_STATISTICS | Contains statistics on the values in an array of raw counters.
PDH_TIME_INFO | Contains information describing a time interval.

Registry Interface

Structure | Description
PERF_COUNTER_BLOCK | Contains the length of the performance-counter data.
PERF_COUNTER_DEFINITION | Contains a description of a performance counter.
PERF_DATA_BLOCK | Contains a description of the performance data provided by a counter.
PERF_INSTANCE_DEFINITION | Contains instance-specific information for a block of performance data.
PERF_OBJECT_TYPE | Contains object-specific performance information.


PDH_BROWSE_DLG_CONFIG

The PDH_BROWSE_DLG_CONFIG structure is used by the PdhBrowseCounters function to configure the PDH Browse Counters dialog box.

typedef struct _BrowseDlgConfig {
  // Configuration flags
  DWORD   bIncludeInstanceIndex:1,
          bSingleCounterPerAdd:1,
          bSingleCounterPerDialog:1,
          bLocalCountersOnly:1,
          bWildCardInstances:1,
          bHideDetailBox:1,
          bInitializePath:1,
          bDisableMachineSelection:1,
          bIncludeCostlyObjects:1,
          bShowObjectBrowser:1,
          bReserved:23;

  HWND                hWndOwner;
  LPTSTR              szDataSource;
  LPTSTR              szReturnPathBuffer;
  DWORD               cchReturnPathLength;
  CounterPathCallBack pCallBack;
  DWORD_PTR           dwCallBackArg;
  PDH_STATUS          CallBackStatus;
  DWORD               dwDefaultDetailLevel;
  LPTSTR              szDialogBoxCaption;
} PDH_BROWSE_DLG_CONFIG, *PPDH_BROWSE_DLG_CONFIG;

Members

bIncludeInstanceIndex
If this flag is TRUE, the returned counter path will include the instance index for the instance. If this flag is FALSE, the returned counter path will not contain an instance number.
bSingleCounterPerAdd
If this flag is TRUE, multiple and wildcard selections are permitted. Selected counters are returned as a MULTI_SZ string each time the Add button is clicked. If this flag is FALSE, multiple selections are not permitted. Only one counter will be returned each time the Add button is clicked.
bSingleCounterPerDialog
If this flag is TRUE, the dialog box is closed after the Add button is clicked the first time. Therefore, you can only add a single counter. If this flag is FALSE, the dialog box is not closed until the Close button is clicked. The Add button can be clicked multiple times.
bLocalCountersOnly
If this flag is TRUE, the machine name will not prefix the counter path in the returned string. If this flag is FALSE, the machine name will prefix the counter path unless the user selects the Local Counters Only radio button.
bWildCardInstances
If this flag is TRUE and a wildcard instance (for example, ALL) is selected, the returned counter path will include the wild-card syntax (for example, "*") for the instance field.

If this flag is FALSE, and All Instances has been selected, all the instances currently found for that object will be returned in a MULTI_SZ string.

bHideDetailBox
If this flag is TRUE, this removes the Detail Level combo box from the dialog box so the user cannot change the detail level of the counters displayed in the dialog box. The detail level will be fixed to the value of the dwDefaultDetailLevel member.

If this flag is FALSE, this displays the Detail Level combo box in the dialog box, allowing the user to change the detail level of the counters displayed.

Note that the counters displayed will be those whose detail level is less than or equal to the current detail level selection. Selecting a detail level of Wizard will display all counters and objects.

bInitializePath
If this flag is TRUE, the counter and object are selected based on the first counter path contained in the szReturnPathBuffer member when the dialog box is first displayed, instead of using the default counter and object specified by the machine.

If this flag is FALSE, this selects the initial counter and object using the default counter and object information returned by the machine.

bDisableMachineSelection
If this flag is TRUE, the Computer drop-down list cannot be selected.

If this flag is FALSE, the Computer drop-down list can be selected. This is the default value.

bIncludeCostlyObjects
If this flag is TRUE, performance objects returning costly data—that is, data that requires a relatively large amount of processor time or memory overhead to collect—are listed for selection.

If this flag is FALSE, performance objects returning costly data are not listed for selection. This is the default value.

bShowObjectBrowser
If this flag is TRUE, a browser window will be displayed containing only a list of performance objects. When an object is selected, PdhBrowseCounters returns a wildcard string identifying the counters in the object. For example, if the "Process" object is selected, PdhBrowseCounters returns the string "\Process(*)\*".
hWndOwner
A handle to the calling function's window.
szDataSource
A pointer to a null-terminated string containing either the name of a log file or the null termination only. If you specify the name of a log file, performance data will be taken from that log file. If this parameter contains a null string, performance data will be collected from a real-time data source.
szReturnPathBuffer
A pointer to a null-terminated string containing the name of the buffer, allocated by the caller, that is used to initialize the first selection in the list boxes (bInitializePath == TRUE) and to return the selected counters to the calling function or the callback procedure.
cchReturnPathLength
The current maximum size, in characters, of the buffer referenced by the szReturnPathBuffer member. If the callback function reallocates a new buffer, it must also update this value.
pCallBack
The address of the callback function used to update application buffers and controls when a multiple-selection dialog box is configured. For more information, see CounterPathCallback.
dwCallBackArg
User-defined argument that is passed as the only argument to the callback function when it is called by the dialog box.
CallBackStatus
On entry to the callback function, this member contains the status of the path buffer. On exit, the callback function sets the status value resulting from processing.

If the buffer is too small to load the current selection, the browser will set this value to PDH_MORE_DATA. If the browser sets this member to ERROR_SUCCESS, then the szReturnPathBuffer member contains a valid counter path or counter path list.

If the callback function reallocates a new buffer, it should set this member to PDH_RETRY so that the browser will try to load the buffer with the selected paths and call the callback function again.

If some other error occurred, then the callback function should return the appropriate PDH error status value.

dwDefaultDetailLevel
The default detail level to show on startup in the Detail Level combo box. If the Detail Level combo box is not shown, this is the detail level to use in filtering the displayed performance counters and objects.
szDialogBoxCaption
A pointer to a null-terminated string containing the optional caption to be displayed in the caption bar of the PDH Browse Counters dialog box. If this member is NULL, the caption will be Browse Performance Counters.

Remarks

Each time the Add button is clicked, the szReturnPathBuffer buffer contains the selected counter and the pCallBack callback function is called. The callback function should call the PdhAddCounter function for each counter in the buffer.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Unicode: Declared as Unicode and ANSI structures.

See Also

CounterPathCallback, PdhAddCounter, PdhBrowseCounters


PDH_COUNTER_INFO

The PDH_COUNTER_INFO structure contains information describing the properties of a counter. This information also includes the counter path. The format of this buffer is to have the structure described below followed by a variable-length buffer containing the string information referenced by the string pointers in the structure (szFullPath, szMachineName, szObjectName, szInstanceName, szParentInstance, szCounterName, and szExplainText).

typedef struct _PDH_COUNTER_INFO {
  DWORD      dwLength;
  DWORD      dwType;
  DWORD      CVersion;
  DWORD      CStatus;
  LONG       lScale;
  LONG       lDefaultScale;
  DWORD_PTR  dwUserData;
  DWORD_PTR  dwQueryUserData;
  LPTSTR     szFullPath;
  union   {
      PDH_DATA_ITEM_PATH_ELEMENTS DataItemPath;
      PDH_COUNTER_PATH_ELEMENTS CounterPath;
      struct {
          LPTSTR   szMachineName;
          LPTSTR   szObjectName;
          LPTSTR   szInstanceName;
          LPTSTR   szParentInstance;
          DWORD    dwInstanceIndex;
          LPTSTR   szCounterName;
      };
  };
  LPTSTR  szExplainText;
  DWORD   DataBuffer[1];
} PDH_COUNTER_INFO, *PPDH_COUNTER_INFO;

Members

dwLength
The length of the structure, including strings.
dwType
The counter type.
CVersion
The counter version information.
CStatus
The current counter status. For more information, see Checking PDH Interface Return Values.
lScale
The current scale factor.
lDefaultScale
The recommended scale factor.
dwUserData
The value of the counter's User Data field.
dwQueryUserData
The value of the User Data field for the query to which the counter belongs.
szFullPath
A pointer to a null-terminated string containing the full counter path.
DataItemPath
A PDH_DATA_ITEM_PATH_ELEMENTS structure.
CounterPath
A PDH_COUNTER_PATH_ELEMENTS structure.
szExplainText
The explain text for this counter.
DataBuffer[1]
The first byte of string data appended to the structure.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Unicode: Declared as Unicode and ANSI structures.

See Also

PDH_COUNTER_PATH_ELEMENTS, PdhGetCounterInfo, PDH_DATA_ITEM_PATH_ELEMENTS


PDH_COUNTER_PATH_ELEMENTS

The PDH_COUNTER_PATH_ELEMENTS structure contains the parsed elements of a fully qualified counter path. The main purpose of this structure is to provide formatted text to the calling application for display.

typedef struct _PDH_COUNTER_PATH_ELEMENTS {
  LPTSTR  szMachineName;
  LPTSTR  szObjectName;
  LPTSTR  szInstanceName;
  LPTSTR  szParentInstance;
  DWORD   dwInstanceIndex;
  LPTSTR  szCounterName;
} PDH_COUNTER_PATH_ELEMENTS, *PPDH_COUNTER_PATH_ELEMENTS;

Members

szMachineName
A pointer to a null-terminated string containing the machine name, parsed from the counter path.
szObjectName
A pointer to a null-terminated string containing the object name, parsed from the counter path.
szInstanceName
A pointer to a null-terminated string containing the instance name, parsed from counter path.
szParentInstance
A pointer to a null-terminated string containing the parent instance name, parsed from counter path.
dwInstanceIndex
The index of duplicate instance names.
szCounterName
A pointer to a null-terminated string containing the counter name.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.
Unicode: Declared as Unicode and ANSI structures.

See Also

PdhMakeCounterPath, PdhParseCounterPath


PDH_DATA_ITEM_PATH_ELEMENTS

The PDH_DATA_ITEM_PATH_ELEMENTS structure contains the path elements of a specific data item.

typedef struct _PDH_DATA_ITEM_PATH_ELEMENTS
  LPTSTR  szMachineName;
  GUID    ObjectGUID;
  DWORD   dwItemId;
  LPTSTR  szInstanceName;
} PDH_DATA_ITEM_PATH_ELEMENTS, *PPDH_DATA_ITEM_PATH_ELEMENTS;

Members

szMachineName
A pointer to a null-terminated string containing the name of the machine where the data item resides.
ObjectGUID
The GUID of the object where the data item resides.
dwItemId
The identifier of the data item.
szInstanceName
A pointer to a null-terminated string containing the name of the data item instance.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Unicode: Declared as Unicode and ANSI structures.

See Also

PDH_COUNTER_INFO


PDH_FMT_COUNTERVALUE

The PDH_FMT_COUNTERVALUE structure is the most commonly used method of reading the data from within an application. The data type of the data returned (member of the union that will have meaningful data) is specified by the caller when requesting the data. The CStatus member provides the status of the counter. Check this member before using the data in a calculation or display. The counter, and therefore the data, could be invalid.

typedef struct _PDH_FMT_COUNTERVALUE {
  DWORD    CStatus;
  union {
      LONG        longValue;
      double      doubleValue;
      LONGLONG    largeValue;
      LPCSTR      AnsiStringValue;
      LPCWSTR     WideStringValue;
  };
} PDH_FMT_COUNTERVALUE, *PPDH_FMT_COUNTERVALUE;

Members

CStatus
The status of last collection operation for this counter. For more information, see Checking PDH Interface Return Values.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.

See Also

PdhCalculateCounterFromRawValue, PdhGetFormattedCounterValue


PDH_FMT_COUNTERVALUE_ITEM

The PDH_FMT_COUNTERVALUE_ITEM structure contains the name of, and information about, a specific counter value.

typedef struct _PDH_FMT_COUNTERVALUE_ITEM
  LPTSTR                szName;
  PDH_FMT_COUNTERVALUE  FmtValue;
} PDH_FMT_COUNTERVALUE_ITEM, *PPDH_FMT_COUNTERVALUE_ITEM;

Members

szName
A pointer to a null-terminated string containing the name of the counter.
FmtValue
A PDH_FMT_COUNTERVALUE structure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Unicode: Declared as Unicode and ANSI structures.

See Also

PdhGetFormattedCounterArray, PDH_FMT_COUNTERVALUE


PDH_RAW_COUNTER

The PDH_RAW_COUNTER structure returns the data as it was collected from the counter provider. No translation, formatting, or other interpretation is performed on the data.

typedef struct _PDH_RAW_COUNTER {
  DWORD       CStatus;
  FILETIME    TimeStamp;
  LONGLONG    FirstValue;
  LONGLONG    SecondValue;
  DWORD       MultiCount;
} PDH_RAW_COUNTER, *PPDH_RAW_COUNTER;

Members

CStatus
The status of the last collection operation for this counter. For more information, see Checking PDH Interface Return Values.
TimeStamp
The local time this data was collected, in FILETIME format.
FirstValue
The first raw counter value.
SecondValue
The second (if necessary) raw counter value.
MultiCount
The multi count (normally 1).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.

See Also

PdhCalculateCounterFromRawValue, PdhComputeCounterStatistics, PdhGetRawCounterValue


PDH_RAW_COUNTER_ITEM

The PDH_RAW_COUNTER_ITEM structure contains the name of, and information about, a specific raw counter value.

typedef struct _PDH_RAW_COUNTER_ITEM
  LPTSTR           szName;
  PDH_RAW_COUNTER  RawValue;
} PDH_RAW_COUNTER_ITEM, *PPDH_RAW_COUNTER_ITEM;

Members

szName
A pointer to a null-terminated string containing the name of the raw counter.
RawValue
A PDH_RAW_COUNTER structure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.
Unicode: Declared as Unicode and ANSI structures.

See Also

PdhGetRawCounterArray, PDH_RAW_COUNTER


PDH_RAW_LOG_RECORD

The PDH_RAW_LOG_RECORD structure stores information about a record contained in a binary trace log file.

typedef struct _PDH_RAW_LOG_RECORD
  DWORD  dwStructureSize;
  DWORD  dwRecordType;
  DWORD  dwItems;
  UCHAR  RawBytes[1];
} PDH_RAW_LOG_RECORD, *PPDH_RAW_LOG_RECORD;

Members

dwStructureSize
The size, in bytes, of this structure.
dwRecordType
The type of record.
Value | Meaning
PDH_LOG_TYPE_TSV | A tab-separated-value format record.
PDH_LOG_TYPE_CSV | A comma-separated-value format record.
PDH_LOG_TYPE_BINARY | A binary trace format record.
PDH_LOG_TYPE_PERFMON | A Perfmon format record.

dwItems
The number of items in the record.
RawBytes
The raw binary data that makes up the trace log record. Memory space for this structure member is dynamically allocated.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.

See Also

PdhReadRawLogRecord


PDH_STATISTICS

The PDH_STATISTICS structure is used to return the statistics of the values in an array of raw counters managed by the application program. The format of the data in the PDH_FMT_COUNTERVALUE structure is described in the dwFormat member.

typedef struct _PDH_STATISTICS {
  DWORD                   dwFormat;
  DWORD                   count;
  PDH_FMT_COUNTERVALUE    min;
  PDH_FMT_COUNTERVALUE    max;
  PDH_FMT_COUNTERVALUE    mean;
} PDH_STATISTICS, *PPDH_STATISTICS;

Members

dwFormat
The format of the data.
count
The number of values in the array.
min
The minimum of the values.
max
The maximum of the values.
mean
The mean of the values.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Pdh.h.

See Also

PdhComputeCounterStatistics, PDH_FMT_COUNTERVALUE


PDH_TIME_INFO

The PDH_TIME_INFO structure contains information on time intervals as applied to the sampling of performance data.

typedef struct _PDH_TIME_INFO {
  LONGLONG  StartTime;
  LONGLONG  EndTime;
  DWORD     SampleCount;
} PDH_TIME_INFO, *PPDH_TIME_INFO;

Members

StartTime
The starting time of the sample interval.
EndTime
The ending time of the sample interval.
SampleCount
The number of samples collected during the interval.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Pdh.h.

See Also

PdhSetQueryTimeRange


PERF_COUNTER_BLOCK

The PERF_COUNTER_BLOCK structure contains the length, in bytes, of the performance-counter data. This structure is followed by data for the number of counters specified in the PERF_OBJECT_TYPE structure.

typedef struct _PERF_COUNTER_BLOCK {
  DWORD ByteLength;
} PERF_COUNTER_BLOCK;

Members

ByteLength
Specifies the length, in bytes, of this structure, including the counters that follow.

Remarks

This structure is part of the performance data provided by the RegQueryValueEx function when the HKEY_PERFORMANCE_DATA key is used.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winperf.h; include Windows.h.

See Also

PERF_OBJECT_TYPE, RegQueryValueEx


PERF_COUNTER_DEFINITION

The PERF_COUNTER_DEFINITION structure describes a performance counter. The Unicode names in this structure must appear in a message file.

typedef struct _PERF_COUNTER_DEFINITION {
  DWORD  ByteLength;
  DWORD  CounterNameTitleIndex;
  LPWSTR CounterNameTitle;
  DWORD  CounterHelpTitleIndex;
  LPWSTR CounterHelpTitle;
  DWORD  DefaultScale;
  DWORD  DetailLevel;
  DWORD  CounterType;
  DWORD  CounterSize;
  DWORD  CounterOffset;
} PERF_COUNTER_DEFINITION;

Members

ByteLength
Contains the length, in bytes, of this structure.
CounterNameTitleIndex
Contains the index of the counter name in the title database of the registry.
CounterNameTitle
A pointer to a null-terminated string containing the name of the counter. This member contains NULL, initially, but it can contain a pointer to the actual string once the string is located.
CounterHelpTitleIndex
Contains the index to the counter's Help title in the title database of the registry.
CounterHelpTitle
A pointer to a null-terminated string containing the title of Help. This member contains NULL, initially, but it can contain a pointer to the actual string once the string is located.
DefaultScale
Specifies the power of 10 by which to scale a chart line, assuming the vertical axis is 100. If this value is zero, the scale value is 1; if this value is 1, the scale value is 10; if this value is –1, the scale value is .10; and so on.
DetailLevel
Specifies the level of detail for the counter. Applications use this value to control display complexity. This member can be one of the following values.
Value | Meaning
PERF_DETAIL_NOVICE | The data can be understood by the uninformed user.
PERF_DETAIL_ADVANCED | The data is designed for the advanced user.
PERF_DETAIL_EXPERT | The data is designed for the expert user.
PERF_DETAIL_WIZARD | The data is designed for the system designer.

CounterType
Specifies the type of counter. For a list of predefined counter types, see Calculations for Raw Counter Data. Each of the predefined counter types is a combination of the values from the following tables.

These values indicate the counter's data size.
Value | Meaning
PERF_SIZE_DWORD | The counter data is a DWORD.
PERF_SIZE_LARGE | The counter data is a large integer.
PERF_SIZE_ZERO | The counter data is a zero-length field.
PERF_SIZE_VARIABLE_LEN | The size of the counter data is in the CounterSize member.

These values indicate the additional contents of this member.
Value | Meaning
PERF_TYPE_NUMBER | The counter data is a number value but not a counter.
PERF_TYPE_COUNTER | The counter data is an increasing numeric value.
PERF_TYPE_TEXT | The counter data is a text field.
PERF_TYPE_ZERO | The counter data is always zero.

If PERF_TYPE_NUMBER is specified, one of these values is also specified to indicate the format of the number.
Value | Meaning
PERF_NUMBER_HEX | The counter data should be displayed as a hexadecimal value.
PERF_NUMBER_DECIMAL | The counter data should be displayed as a decimal value.
PERF_NUMBER_DEC_1000 | The counter data should be divided by 1000 and displayed as a decimal value.

If PERF_TYPE_COUNTER is specified, one of these values is also specified to indicate the type of counter.
Value | Meaning
PERF_COUNTER_VALUE | The counter value is valid without additional calculation; that is, it should be displayed as is.
PERF_COUNTER_RATE | The counter value should be divided by the elapsed time.
PERF_COUNTER_FRACTION | The counter value should be divided by the base value indicated by the next counter if it is of type PERF_COUNTER_BASE or by the value of the counter subtype.
PERF_COUNTER_BASE | The counter value is the base value to use in fractions.
PERF_COUNTER_ELAPSED | The counter value is a start time to be subtracted from the current time.
PERF_COUNTER_QUEUELEN | The performance application should use the Queuelen counter — that is, the Queue Length Space-Time Product formula. The next counter is the number currently in the queue. Multiply it by the current time (units specified by this counter's subtype). Add the product to the original value of the counter. To obtain the average queue length, divide the result of the addition by the delta time.
PERF_COUNTER_HISTOGRAM | The counter value begins or ends a histogram.

If PERF_TYPE_COUNTER is specified, one of these values is also specified to indicate the subtype of counter.
Value | Meaning
PERF_TIMER_TICK | The frequency of the high-resolution performance counter should be used as the base.
PERF_TIMER_100NS | The time base units of the 100-nanosecond timer should be used as the base.
PERF_OBJECT_TIMER | The object-timer frequency should be used as the base unit. This value is system-defined in this counter's PERF_OBJECT_TYPE definition.

If PERF_TYPE_TEXT is specified, one of these values is also specified to indicate the type of text.
Value | Meaning
PERF_TEXT_UNICODE | The counter data contains Unicode text.
PERF_TEXT_ASCII | The counter data contains ASCII text.

These values indicate how to use the counter data in a calculation.
Value | Meaning
PERF_DELTA_COUNTER | The difference between the previous counter value and the current counter value is computed before proceeding.
PERF_DELTA_BASE | The difference between the previous base value and the current base value is computed before proceeding.
PERF_INVERSE_COUNTER | After other calculations, the counter should be inverted before displaying or converting to a percentage.
PERF_MULTI_COUNTER | This value is a sum of counters from several sources, the number of which is indicated by the next counter.

These values indicate the display suffix of the counter data.
Value | Meaning
PERF_DISPLAY_NO_SUFFIX | There is no display suffix.
PERF_DISPLAY_PER_SEC | The display suffix is '/sec'.
PERF_DISPLAY_PERCENT | The display suffix is '%'.
PERF_DISPLAY_SECONDS | The display suffix is 'secs'.
PERF_DISPLAY_NOSHOW | The counter value should not be displayed.

CounterSize
Specifies the counter size, in bytes.
CounterOffset
Specifies the offset from the start of the PERF_COUNTER_BLOCK structure to the first byte of this counter.

Remarks

This structure is part of the performance data provided by the RegQueryValueEx function when the HKEY_PERFORMANCE_DATA key is used.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winperf.h; include Windows.h.

See Also

RegQueryValueEx


PERF_DATA_BLOCK

The PERF_DATA_BLOCK structure describes the performance data provided by RegQueryValueEx function. The data starts with a PERF_DATA_BLOCK structure and is followed by a PERF_OBJECT_TYPE structure and other object-specific data for each type of object monitored.

typedef struct _PERF_DATA_BLOCK {
  WCHAR         Signature[4];
  DWORD         LittleEndian;
  DWORD         Version;
  DWORD         Revision;
  DWORD         TotalByteLength;
  DWORD         HeaderLength;
  DWORD         NumObjectTypes;
  DWORD         DefaultObject;
  SYSTEMTIME    SystemTime;
  LARGE_INTEGER PerfTime;
  LARGE_INTEGER PerfFreq;
  LARGE_INTEGER PerfTime100nSec;
  DWORD         SystemNameLength;
  DWORD         SystemNameOffset;
} PERF_DATA_BLOCK;

Members

Signature
Contains the Unicode string PERF.
LittleEndian
Contains zero if the processor is big endian and one if it is little endian.
Version
Contains the version of the performance (PERF_) structures. This member is greater than or equal to one.
Revision
Contains the revision of the performance (PERF_) structures. This member is greater than or equal to zero.
TotalByteLength
Contains the total length, in bytes, of the performance data.
HeaderLength
Contains the length, in bytes, of this structure.
NumObjectTypes
Contains the number of object types being monitored.
DefaultObject
Contains the object title index of the default object whose performance data is to be displayed. This member can be –1 to indicate that no data is to be displayed.
SystemTime
Contains the time when the system is monitored. This member is in Coordinated Universal Time (UTC) format.
PerfTime
Contains the performance-counter value, in counts, for the system being monitored.
PerfFreq
Contains the performance-counter frequency, in counts per second, for the system being monitored.
PerfTime100nSec
Contains the performance-counter value, in 100 nanosecond units, for the system being monitored.
SystemNameLength
Contains the length, in bytes, of the system name.
SystemNameOffset
Contains the offset from the beginning of this structure to the name of the system being monitored.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winperf.h; include Windows.h.

See Also

PERF_OBJECT_TYPE, RegQueryValueEx


PERF_INSTANCE_DEFINITION

The PERF_INSTANCE_DEFINITION structure contains the instance-specific information for a block of performance data. There is one PERF_INSTANCE_DEFINITION structure for each instance specified in the PERF_OBJECT_TYPE structure.

typedef struct _PERF_INSTANCE_DEFINITION {
  DWORD ByteLength;
  DWORD ParentObjectTitleIndex;
  DWORD ParentObjectInstance;
  DWORD UniqueID;
  DWORD NameOffset;
  DWORD NameLength;
} PERF_INSTANCE_DEFINITION;

Members

ByteLength
Specifies the length, in bytes, of this structure, including the subsequent name.
ParentObjectTitleIndex
Specifies the index of the name of the "parent" object in the title database. For example, if the object is a thread, the parent object type is a process, or if the object is a logical drive, the parent is a physical drive.
ParentObjectInstance
Specifies the index to an instance of the parent object type that is the parent of this instance. This member may be zero or greater.
UniqueID
Specifies the unique identifier used instead of the instance name. This member is PERF_NO_UNIQUE_ID if there is no such identifier.
NameOffset
Specifies the offset from the beginning of this structure to the Unicode name of this instance.
NameLength
Specifies the length, in bytes, of the instance name. This member is zero if the instance does not have a name.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winperf.h; include Windows.h.

See Also

PERF_OBJECT_TYPE


PERF_OBJECT_TYPE

The PERF_OBJECT_TYPE structure describes object-specific performance information. This structure is followed by a list of PERF_COUNTER_DEFINITION structures, one for each counter defined for the type of object.

typedef struct _PERF_OBJECT_TYPE {
  DWORD  TotalByteLength;
  DWORD  DefinitionLength;
  DWORD  HeaderLength;
  DWORD  ObjectNameTitleIndex;
  LPWSTR ObjectNameTitle;
  DWORD  ObjectHelpTitleIndex;
  LPWSTR ObjectHelpTitle;
  DWORD  DetailLevel;
  DWORD  NumCounters;
  DWORD  DefaultCounter;
  DWORD  NumInstances;
  DWORD  CodePage;
  LARGE_INTEGER PerfTime;
  LARGE_INTEGER PerfFreq;
} PERF_OBJECT_TYPE;

Members

TotalByteLength
Contains the length, in bytes, of the object-specific data. This value includes this structure, the PERF_COUNTER_DEFINITION structures, and the PERF_INSTANCE_DEFINITION and PERF_COUNTER_BLOCK structures for each instance. This member specifies the offset from the beginning of this structure to the next PERF_OBJECT_TYPE structure if one exists.
DefinitionLength
Contains the length, in bytes, of the object-specific data. This value includes this structure and the PERF_COUNTER_DEFINITION structures for this object. This member is the offset from the beginning of the PERF_OBJECT_TYPE structure to the first PERF_INSTANCE_DEFINITION structure or to the PERF_COUNTER_DEFINITION structures if there is no instance data.
HeaderLength
Contains the length, in bytes, of this structure. This member is the offset to the first PERF_COUNTER_DEFINITION structure for this object.
ObjectNameTitleIndex
Contains the index to the object's name in the title database.
ObjectNameTitle
A pointer to a null-terminated string containing the name of the object. This member initially contains NULL, but it can contain a pointer to the actual string once the string is located.
ObjectHelpTitleIndex
Contains the index to the object's Help title in the title database.
ObjectHelpTitle
A pointer to a null-terminated string containing the title of Help. This member initially contains NULL, but it can contain a pointer to the actual string once the string is located.
DetailLevel
Specifies the level of detail. Applications use this value to control display complexity. This value is the minimum detail level of all the counters for a given object. This member can be one of the following values.
Detail level | Meaning
PERF_DETAIL_NOVICE | No technical ability is required to understand the counter data.
PERF_DETAIL_ADVANCED | The counter data is provided for advanced users.
PERF_DETAIL_EXPERT | The counter data is provided for expert users.
PERF_DETAIL_WIZARD | The counter data is provided for system designers.

NumCounters
Specifies the number of counters in each counter block. There is one counter block per instance.
DefaultCounter
Specifies the default counter whose information is to be displayed when this object is selected. This member is typically greater than or equal to zero. However, this member may be –1 to indicate that there is no default.
NumInstances
Specifies the number of object instances for which counters are being provided. If the object can have zero or more instances, but has none at present, this value should be zero. If the object cannot have multiple instances, this value should be PERF_NO_INSTANCES.
CodePage
Specifies the code page. This member is zero if the instance strings are in Unicode. Otherwise, this member is the code-page identifier of the instance names.
PerfTime
Specifies the current value, in counts, of the high-resolution performance counter.
PerfFreq
Specifies the current frequency, in counts per second, of the high-resolution performance counter.

Remarks

If there is only one instance of the object type, the counter definitions are followed by a single PERF_COUNTER_BLOCK structure. This structure is followed by data for each counter. (The PERF_COUNTER_BLOCK structure contains the total length of the structure and the counter data that follows it.)

If there is more than one instance of the object type, the list of counter definitions is followed by a PERF_INSTANCE_DEFINITION structure and a PERF_COUNTER_BLOCK structure for each instance. The PERF_INSTANCE_DEFINITION structure includes the name, the identifier, and the name of the parent of the instance.

Following the counter data, there is a PERF_INSTANCE_DEFINITION structure and a PERF_COUNTER_BLOCK structure for each instance specified in the PERF_DATA_BLOCK structure that begins the performance-data area.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winperf.h; include Windows.h.

See Also

PERF_COUNTER_BLOCK, PERF_COUNTER_DEFINITION, PERF_INSTANCE_DEFINITION


Process Status Helper

The process status helper functions make it easier for you to obtain information about processes and device drivers running on Microsoft® Windows NT®/Windows® 2000. These functions are available in PSAPI.DLL, which is distributed in the Microsoft® Platform Software Development Kit (SDK). The same information is generally available through the performance data in the registry, but it is more difficult to get to it. For more information, see Performance Monitoring.

  • About PSAPI
  • Using PSAPI
  • PSAPI Reference


About PSAPI

The process status API (PSAPI) provides sets of functions for retrieving the following information:

  • Process Information
  • Module Information
  • Device Driver Information
  • Process Memory Usage Information
  • Working Set Information
  • Memory-Mapped File Information


Process Information

The system maintains a list of running processes. You can retrieve the identifiers for these processes by calling the EnumProcesses function. This function fills an array of DWORD values with the identifiers of all processes in the system.

Many functions in PSAPI and the Win32 API require a process handle. To obtain a process handle for a running process, pass its process identifier (obtained from EnumProcesses) to the OpenProcess function. Remember to call the CloseHandle function when you are finished with the process handle.


Module Information

A module is an executable file or DLL. Each process consists of one or more modules. You can retrieve the list of module handles for a process by calling the EnumProcessModules function. This function fills an array of HMODULE values with the module handles for the specified process. The first module is the executable file. Remember that these module handles are most likely from some other process, so you cannot use them with Win32 functions such as GetModuleFileName. However, you can use PSAPI functions to obtain information about a module from another process.

To obtain module information

  1. Call the GetModuleBaseName function. This function takes a process handle and a module handle as input and fills in a buffer with the base name of a module (for example, KERNEL32.DLL). A related function, GetModuleFileNameEx, takes the same parameters as input but returns the full path to the module (for example, C:\WINNT\SYSTEM32\KERNEL32.DLL).
  2. Call the GetModuleInformation function. This function takes a process handle and a module handle and fills a MODULEINFO structure with the load address of the module, the size of the linear address space it occupies, and a pointer to its entry point.


Device Driver Information

Device drivers and modules are similar in that they are both based on PE files. However, while each process has its own private list of loaded modules, device drivers have modules that are global to the system. Therefore, PSAPI has specific functions for obtaining the list of device drivers and their names.

You can retrieve the load address for each device driver by calling the EnumDeviceDrivers function. This function fills an array of LPVOID values with the load addresses of all device drivers in the system.

The GetDeviceDriverBaseName function takes a driver load address as input and fills in a buffer with the base name of the driver (for example, WIN32K.SYS). A related function, GetDeviceDriverFileName, takes the same parameters and returns the full path to the device driver (for example, C:\WINNT\SYSTEM32\WIN32K.SYS).


Process Memory Usage Information

The GetProcessMemoryInfo function takes a process handle as input and fills a PROCESS_MEMORY_COUNTERS structure with information about the memory statistics for the process. The cb member receives the size of the structure. The PageFaultCount member receives the number of page faults. The remaining members receive the current and peak memory usage in the following categories:

  • working set
  • paged pool
  • nonpaged pool
  • pagefile

The working set is the amount of memory physically mapped to the process context at a given time. Memory in the paged pool is system memory that can be transferred to the paging file on disk (paged) when it is not being used. Memory in the nonpaged pool is system memory that cannot be paged to disk as long as the corresponding objects are allocated. The pagefile usage represents how much memory is set aside for the process in the system paging file. When memory usage is too high, the virtual memory manager pages selected memory to disk. When a thread needs a page that is not in memory, the memory manager reloads it from the paging file.


Working Set Information

The working set of a process is the amount of memory physically mapped to its process context. PSAPI enables you to take snapshots of the working set or to monitor the working set.

The QueryWorkingSet function fills a buffer with a snapshot of the information for every page in the current working set of the specified process. The function reports only those pages that are physically present at the exact moment it is called.

You can use working set monitoring to find out how much additional RAM a particular operation takes (for example, saving a file). To begin monitoring the working set, call the InitializeProcessForWsWatch function. Not all processes let you read their working set information, so be sure that the function returns a nonzero value before you continue. Next, call the GetWsChanges function. This function reports only the pages that have been loaded in memory since you began monitoring the working set. The function returns data in an array of PSAPI_WS_WATCH_INFORMATION structures, one structure for each new page added to the working set of the process. The structure tells you which pages are in memory, and what caused the system to page them in.

The EmptyWorkingSet function takes a process handle. It removes as many pages as possible from the process working set. This operation is useful primarily for testing and tuning. Note that the SetProcessWorkingSetSize function does the same thing if you pass it -1 for the minimum and maximum sizes.


Memory-Mapped File Information

A memory-mapped file (or file mapping) is the result of associating a file's contents with a portion of the virtual address space of a process. It can be used to share a file or memory between two or more processes.

The GetMappedFileName function receives a process handle and a pointer to an address as input. If the address is within a memory-mapped file in the virtual address space of the process, the function returns the name of the memory-mapped file. The file names returned by GetMappedFileName use device form, rather than drive letters. For example, the file name c:\winnt\system32\ctype.nls would look like this in device form:

\Device\Harddisk0\Partition1\WINNT\System32\ctype.nls

For more information about memory-mapped files, see File Mapping.


Using PSAPI

The following examples show you how to use the PSAPI functions:

  • Enumerating all processes
  • Enumerating all modules for a process
  • Collecting memory usage information for a process


Enumerating All Processes

Task Manager is an example of a program that enumerates all running processes on Windows NT/Windows 2000. It is implemented using data from the performance registry. The following sample code uses the EnumProcesses function to enumerate the current processes in the system. This method is easier than using the performance registry.

#include <windows.h>
#include <stdio.h>
#include "psapi.h"

void PrintProcessNameAndID( DWORD processID )
{
    char szProcessName[MAX_PATH] = "unknown";

    // Get a handle to the process.

    HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                   PROCESS_VM_READ,
                                   FALSE, processID );

    // Get the process name.

    if ( hProcess )
    {
        HMODULE hMod;
        DWORD cbNeeded;

        if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
             &cbNeeded) )
        {
            GetModuleBaseName( hProcess, hMod, szProcessName,
                               sizeof(szProcessName) );
        }
    }

    // Print the process name and identifier.

    printf( "%s (Process ID: %u)\n", szProcessName, processID );

    CloseHandle( hProcess );
}

void main( )
{
    // Get the list of process identifiers.

    DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return;

    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the name and process identifier for each process.

    for ( i = 0; i < cProcesses; i++ )
        PrintProcessNameAndID( aProcesses[i] );
}

The main function obtains a list of processes by using the EnumProcesses function. For each process, main calls the PrintProcessNameAndID function, passing it the process identifier. PrintProcessNameAndID in turn calls the OpenProcess function to obtain the process handle. If OpenProcess fails, the output shows only the process identifier. For example, OpenProcess fails for the Idle and CSRSS processes because their access restrictions prevent user-level code from opening them. Next, PrintProcessNameAndID calls the EnumProcessModules function to obtain the module handles. Finally, PrintProcessNameAndID calls the GetModuleBaseName function to obtain the name of the executable file.


Enumerating All Modules For a Process

To determine which processes have loaded a particular DLL, you must enumerate the modules for each process. The following sample code uses the EnumProcessModules function to enumerate the modules of current processes in the system.

#include <windows.h>
#include <stdio.h>
#include "psapi.h"

void PrintModules( DWORD processID )
{
    HMODULE hMods[1024];
    HANDLE hProcess;
    DWORD cbNeeded;
    unsigned int i;

    // Print the process identifier.

    printf( "\nProcess ID: %u\n", processID );

    // Get a list of all the modules in this process.

    hProcess = OpenProcess(  PROCESS_QUERY_INFORMATION |
                                    PROCESS_VM_READ,
                                    FALSE, processID );

    if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
    {
        for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
        {
            char szModName[MAX_PATH];

            // Get the full path to the module's file.

            if ( GetModuleFileNameEx( hProcess, hMods[i], szModName,
                                      sizeof(szModName)))
            {
                // Print the module name and handle value.

                printf("\t%s (0x%08X)\n", szModName, hMods[i] );
            }
        }
    }

    CloseHandle( hProcess );
}

void main( )
{
    // Get the list of process identifiers.

    DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return;

    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the name of the modules for each process.

    for ( i = 0; i < cProcesses; i++ )
        PrintModules( aProcesses[i] );
}

The main function obtains a list of processes by using the EnumProcesses function. For each process, the main function calls the PrintModules function, passing it the process identifier. PrintModules in turn calls the OpenProcess function to obtain the process handle. If OpenProcess fails, the output shows only the process identifier. For example, OpenProcess fails for the Idle and CSRSS processes because their access restrictions prevent user-level code from opening them. Next, PrintModules calls the EnumProcessModules function to obtain the module handles function. Finally, PrintModules calls the GetModuleFileNameEx function, once for each module, to obtain the module names.


Collecting Memory Usage Information For a Process

To determine the efficiency of your application, you may want to examine its memory usage. The following sample code uses the GetProcessMemoryInfo function to obtain information about the memory usage of a process.

#include <windows.h>
#include <stdio.h>
#include "psapi.h"

void PrintMemoryInfo( DWORD processID )
{
    HANDLE hProcess;
    PROCESS_MEMORY_COUNTERS pmc;

    // Print the process identifier.

    printf( "\nProcess ID: %u\n", processID );

    // Print information about the memory usage of the process.

    hProcess = OpenProcess(  PROCESS_QUERY_INFORMATION |
                                    PROCESS_VM_READ,
                                    FALSE, processID );

    if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
    {
        printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount );
        printf( "\tPeakWorkingSetSize: 0x%08X\n",
                  pmc.PeakWorkingSetSize );
        printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize );
        printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n",
                  pmc.QuotaPeakPagedPoolUsage );
        printf( "\tQuotaPagedPoolUsage: 0x%08X\n",
                  pmc.QuotaPagedPoolUsage );
        printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n",
                  pmc.QuotaPeakNonPagedPoolUsage );
        printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n",
                  pmc.QuotaNonPagedPoolUsage );
        printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage );
        printf( "\tPeakPagefileUsage: 0x%08X\n",
                  pmc.PeakPagefileUsage );
    }

    CloseHandle( hProcess );
}

void main( )
{
    // Get the list of process identifiers.

    DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return;

    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the memory usage for each process

    for ( i = 0; i < cProcesses; i++ )
        PrintMemoryInfo( aProcesses[i] );
}

The main function obtains a list of processes by using the EnumProcesses function. For each process, main calls the PrintMemoryInfo function, passing the process identifier. PrintMemoryInfo in turn calls the OpenProcess function to obtain the process handle. If OpenProcess fails, the output shows only the process identifier. For example, OpenProcess fails for the Idle and CSRSS processes because their access restrictions prevent user-level code from opening them. Finally, PrintMemoryInfo calls the GetProcessMemoryInfo function to obtain the memory usage information.


PSAPI Reference

This section describes the PSAPI functions and structures.

• PSAPI Functions

• PSAPI Structures


PSAPI Functions

The following are the PSAPI functions.

EmptyWorkingSet
EnumDeviceDrivers
EnumProcesses
EnumProcessModules
GetDeviceDriverBaseName
GetDeviceDriverFileName
GetMappedFileName
GetModuleBaseName
GetModuleFileNameEx
GetModuleInformation
GetProcessMemoryInfo
GetWsChanges
InitializeProcessForWsWatch
QueryWorkingSet


EmptyWorkingSet

The EmptyWorkingSet function removes as many pages as possible from the working set of the specified process.

BOOL EmptyWorkingSet(
  HANDLE hProcess  // handle to process
);

Parameters

hProcess
[in] Handle to the process.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

You can also use the SetProcessWorkingSetSize function to do what EmptyWorkingSet does if you pass it -1 for the minimum and maximum sizes.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.
Library: Use Psapi.lib.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses, SetProcessWorkingSetSize


EnumDeviceDrivers

The EnumDeviceDrivers function retrieves the load address for each device driver in the system.

BOOL EnumDeviceDrivers(
  LPVOID *lpImageBase,  // array of load addresses
  DWORD cb,             // size of array
  LPDWORD lpcbNeeded    // number of bytes returned
);

Parameters

lpImageBase
[out] Pointer to an array that receives the list of load addresses for the device drivers.
cb
[in] Specifies the size, in bytes, of the lpImageBase array. If the value is zero, lpcbNeeded receives the size, in bytes, of the array needed to store the load addresses.
lpcbNeeded
[out] Receives the number of bytes returned in the lpImageBase array.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

It is a good idea to give EnumDeviceDrivers a large array of LPVOID values, because it is hard to predict how many device drivers there will be at the time you call EnumDeviceDrivers. To determine how many device drivers were enumerated by the call to EnumDeviceDrivers, divide the resulting value in the lpcbNeeded parameter by sizeof(LPVOID).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.
Library: Use Psapi.lib.

See Also

Process Status Helper Overview, PSAPI Functions


EnumProcesses

The EnumProcesses function retrieves the process identifier for each process object in the system.

BOOL EnumProcesses(
  DWORD *lpidProcess,  // array of process identifiers
  DWORD cb,            // size of array
  DWORD *cbNeeded      // number of bytes returned
);

Parameters

lpidProcess
[out] Pointer to an array that receives the list of process identifiers.
cb
[in] Specifies the size, in bytes, of the lpidProcess array.
cbNeeded
[out] Receives the number of bytes returned in the lpidProcess array.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

It is a good idea to give EnumProcesses a large array of DWORD values, because it is hard to predict how many processes there will be at the time you call EnumProcesses. To determine how many processes were enumerated by the call to EnumProcesses, divide the resulting value in the cbNeeded parameter by sizeof(DWORD). There is no indication given when the buffer is too small to store all process identifiers.

To obtain process handles for the processes whose identifiers you have just obtained, call the OpenProcess function.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.
Library: Use Psapi.lib.

See Also

Process Status Helper Overview, PSAPI Functions, OpenProcess


EnumProcessModules

The EnumProcessModules function retrieves a handle for each module in the specified process.

BOOL EnumProcessModules(
  HANDLE hProcess,      // handle to process
  HMODULE *lphModule,   // array of module handles
  DWORD cb,             // size of array
  LPDWORD lpcbNeeded    // number of bytes required
);

Parameters

hProcess
[in] Handle to the process.
lphModule
[out] Pointer to the array that receives the list of module handles.
cb
[in] Specifies the size, in bytes, of the lphModule array.
lpcbNeeded
[out] Receives the number of bytes required to store all module handles in the lphModule array.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

It is a good idea to give EnumProcessModules a large array of HMODULE values, because it is hard to predict how many modules there will be in the process at the time you call EnumProcessModules. To determine if the lphModule array is too small to hold all module handles for the process, compare the value returned in lpcbNeeded with the value specified in cb. If lpcbNeeded is greater than cb, increase the size of the array and call EnumProcessModules again.

To determine how many modules were enumerated by the call to EnumProcessModules, divide the resulting value in the lpcbNeeded parameter by sizeof(HMODULE).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.
Library: Use Psapi.lib.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses


GetDeviceDriverBaseName

The GetDeviceDriverBaseName function retrieves the base name of the specified device driver.

DWORD GetDeviceDriverBaseName(
  LPVOID ImageBase,  // driver load address
  LPTSTR lpBaseName, // driver base name buffer
  DWORD nSize        // size of buffer
);

Parameters

ImageBase
[in] Specifies the load address of the device driver.
lpBaseName
[out] Pointer to the buffer that receives the base name of the device driver.
nSize
[in] Specifies the size, in bytes, of the lpBaseName buffer.

Return Value

If the function succeeds, the return value specifies the length of the string copied to the buffer.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.
Library: Use Psapi.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Process Status Helper Overview, PSAPI Functions, EnumDeviceDrivers


GetDeviceDriverFileName

The GetDeviceDriverFileName function retrieves the fully qualified path for the specified device driver.

DWORD GetDeviceDriverFileName(
  LPVOID ImageBase,  // driver load address
  LPTSTR lpFilename, // path buffer
  DWORD nSize        // size of buffer
);

Parameters

ImageBase
[in] Specifies the load address of the device driver.
lpFilename
[out] Pointer to the buffer that receives the fully qualified path to the device driver.
nSize
[in] Specifies the size, in bytes, of the lpFilename buffer.

Return Value

If the function succeeds, the return value specifies the length of the string copied to the buffer.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.
Library: Use Psapi.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Process Status Helper Overview, PSAPI Functions, EnumDeviceDrivers


GetMappedFileName

The GetMappedFileName function checks if the specified address is within a memory-mapped file in the address space of the specified process. If so, the function returns the name of the memory-mapped file.

DWORD GetMappedFileName(
  HANDLE hProcess,    // handle to process
  LPVOID lpv,         // address to verify
  LPTSTR lpFilename,  // file name buffer
  DWORD nSize         // size of buffer
);

Parameters

hProcess
[in] Handle to the process.
lpv
[in] Specifies the address to verify.
lpFilename
[out] Pointer to the buffer that receives the name of the memory-mapped file to which the address specified by lpv belongs.
nSize
[in] Specifies the size, in bytes, of the lpFilename buffer.

Return Value

If the function succeeds, the return value specifies the length of the string copied to the buffer.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.
Library: Use Psapi.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses


GetModuleBaseName

The GetModuleBaseName function retrieves the base name of the specified module.

DWORD GetModuleBaseName(
  HANDLE hProcess,    // handle to process
  HMODULE hModule,    // handle to module
  LPTSTR lpBaseName,  // base name buffer
  DWORD nSize         // maximum characters to retrieve
);

Parameters

hProcess
[in] Handle to the process that contains the module.
hModule
[in] Handle to the module.
lpBaseName
[out] Pointer to the buffer that receives the base name of the module. If the base name is longer than maximum number of characters specified by the nSize parameter, the base name is truncated.
nSize
[in] Specifies the maximum number of characters to copy to the lpBaseName buffer.

Return Value

If the function succeeds, the return value specifies the length of the string copied to the buffer.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.
Library: Use Psapi.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses, GetModuleFileNameEx


GetModuleFileNameEx

The GetModuleFileNameEx function retrieves the fully qualified path for the specified module.

DWORD GetModuleFileNameEx(
  HANDLE hProcess,    // handle to process
  HMODULE hModule,    // handle to module
  LPTSTR lpFilename,  // path buffer
  DWORD nSize         // maximum characters to retrieve
);

Parameters

hProcess
[in] Handle to the process that contains the module.
hModule
[in] Handle to the module.
lpFilename
[out] Pointer to the buffer that receives the fully qualified path to the module. If the file name is longer than maximum number of characters specified by the nSize parameter, the file name is truncated.
nSize
[in] Specifies the maximum number of characters to copy to the lpFilename buffer.

Return Value

If the function succeeds, the return value specifies the length of the string copied to the buffer.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.
Library: Use Psapi.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses, GetModuleBaseName


GetModuleInformation

The GetModuleInformation function retrieves information about the specified module in the MODULEINFO structure.

BOOL GetModuleInformation(
  HANDLE hProcess,         // handle to process
  HMODULE hModule,         // handle to module
  LPMODULEINFO lpmodinfo,  // information buffer
  DWORD cb                 // size of buffer
);

Parameters

hProcess
[in] Handle to the process that contains the module.
hModule
[in] Handle to the module.
lpmodinfo
[out] Pointer to the MODULEINFO structure that receives information about the module.
cb
[in] Specifies the size, in bytes, of the MODULEINFO structure.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.
Library: Use Psapi.lib.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses, MODULEINFO


GetProcessMemoryInfo

The GetProcessMemoryInfo function retrieves information about the memory usage of the specified process in the PROCESS_MEMORY_COUNTERS structure.

BOOL GetProcessMemoryInfo(
  HANDLE Process,                          // handle to process
  PPROCESS_MEMORY_COUNTERS ppsmemCounters, // buffer
  DWORD cb                                 // size of buffer
);

Parameters

Process
[in] Handle to the process.
ppsmemCounters
[out] Pointer to the PROCESS_MEMORY_COUNTERS structure that receives information about the memory usage of the process.
cb
[in] Specifies the size, in bytes, of the PROCESS_MEMORY_COUNTERS structure.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.
Library: Use Psapi.lib.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses, PROCESS_MEMORY_COUNTERS


GetWsChanges

The GetWsChanges function retrieves information about the pages that have been added to the working set of the specified process since the InitializeProcessForWsWatch function initiated monitoring.

BOOL GetWsChanges(
  HANDLE hProcess,                         // handle to process
  PPSAPI_WS_WATCH_INFORMATION lpWatchInfo, // buffer
  DWORD cb                                 // size of buffer
);

Parameters

hProcess
[in] Handle to the process.
lpWatchInfo
[out] Pointer to the PSAPI_WS_WATCH_INFORMATION structure that receives information about a page added to a process working set.
cb
[in] Specifies the size, in bytes, of the PSAPI_WS_WATCH_INFORMATION structure.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.
Library: Use Psapi.lib.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses, InitializeProcessForWsWatch, PSAPI_WS_WATCH_INFORMATION


InitializeProcessForWsWatch

The InitializeProcessForWsWatch function initiates monitoring of the working set of the specified process. You must call this function before calling the GetWsChanges function.

BOOL InitializeProcessForWsWatch(
  HANDLE hProcess  // handle to process
);

Parameters

hProcess
[in] Handle to the process.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.
Library: Use Psapi.lib.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses, GetWsChanges


QueryWorkingSet

The QueryWorkingSet function retrieves information about the pages currently added to the working set of the specified process.

BOOL QueryWorkingSet(
  HANDLE hProcess,  // handle to process
  PVOID pv,         // information buffer
  DWORD cb          // size of buffer
);

Parameters

hProcess
[in] Handle to the process.
pv
[out] Pointer to the buffer that receives the information.
cb
[in] Specifies the size, in bytes, of the buffer.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The return buffer consists of a DWORD value and a variable number of DWORD_PTR values. The DWORD contains the number of valid DWORD_PTR values that follow it in the buffer. Each remaining DWORD_PTR represents one page in the process working set.

Each DWORD_PTR value is an address of a bit field containing information about a specific working set page. To decode these DWORD_PTR values, it is necessary to split the highest-order 52 bits from the lowest-order 12 bits.

The highest-order 52 bits (obtained by using a bitwise AND operator with 0xFFFFFFFFFFFFF000) contain the address of a page of memory loaded into the specified process.

The lowest-order 12 bits of this bit field contain the following 4 fields, from highest-order bit to lowest-order.

  • A 3-bit filler field. No information is currently returned in these bits.
  • A 1-bit flag specifying whether the page is shared. The value is 1 if it is a shared page, and 0 if it is not.
  • A 3-bit field containing the number of processes that this field is shared between. The maximum value of this field is 7.
  • A 5-bit field containing a value between 0 and 31 that specifies the protection attributes of the page. The following table lists these values and their corresponding meaning.
Value | Meaning
0 | The page is not accessed.
1 | The page is read-only.
2 | The page is executable.
3 | The page is executable and read-only.
4 | The page has read/write access.
5 | The page is copy-on-write.
6 | The page is executable and has read/write access.
7 | The page is executable and has copy-on-write access.
8 | The page is not accessed.
9 | The page is not cached and has read-only access.
10 | The page is not cached and is executable.
11 | The page is not cached, is executable, and has read-only access.
12 | The page is not cached and has read/write access.
13 | The page is not cached and has copy-on-write access.
14 | The page is not cached, is executable, and has read/write access.
15 | The page is not cached, is executable, and has copy-on-write access.
16 | The page is not accessed.
17 | The page is a guard page and has read-only access.
18 | The page is a guard page and is executable.
19 | The page is a guard page, is executable, and has read-only access.
20 | The page is a guard page and has read/write access.
21 | The page is a guard page and has copy-on-write access.
22 | The page is a guard page, is executable, and has read/write access.
23 | The page is a guard page, is executable, and has copy-on-write access.
24 | The page is not accessed.
25 | The page is a non-cacheable guard page and has read-only access.
26 | The page is a non-cacheable guard page and has executable access.
27 | The page is a non-cacheable guard page, is executable, and has read-only access.
28 | The page is a non-cacheable guard page and has read/write access.
29 | The page is a non-cacheable guard page and has copy-on-write access.
30 | The page is a non-cacheable guard page, is executable, and has read/write access.
31 | The page is a non-cacheable guard page, is executable, and has copy-on-write access.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.
Library: Use Psapi.lib.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses


PSAPI Structures

The following are the PSAPI structures.

MODULEINFO
PROCESS_MEMORY_COUNTERS
PSAPI_WS_WATCH_INFORMATION


MODULEINFO

The MODULEINFO structure contains the module load address, size, and entry point.

typedef struct _MODULEINFO {
    LPVOID lpBaseOfDll;
    DWORD SizeOfImage;
    LPVOID EntryPoint;
} MODULEINFO, *LPMODULEINFO;

Members

lpBaseOfDll
The load address of the module.
SizeOfImage
The size, in bytes, of the linear space that the module occupies.
EntryPoint
The entry point of the module.

Remarks

The load address of a module is the same as the HMODULE value. The information returned in the SizeOfImage and EntryPoint members comes from the module's Portable Executable (PE) header. The module entry point is the location called during process startup, thread startup, process shutdown, and thread shutdown. While this is not the address of the DllMain function, it should be close enough for most purposes.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.

See Also

Process Status Helper Overview, PSAPI Structures, DllMain, GetModuleInformation


PROCESS_MEMORY_COUNTERS

The PROCESS_MEMORY_COUNTERS structure contains the memory statistics for a process.

typedef struct _PROCESS_MEMORY_COUNTERS {
    DWORD cb;
    DWORD PageFaultCount;
    SIZE_T PeakWorkingSetSize;
    SIZE_T WorkingSetSize;
    SIZE_T QuotaPeakPagedPoolUsage;
    SIZE_T QuotaPagedPoolUsage;
    SIZE_T QuotaPeakNonPagedPoolUsage;
    SIZE_T QuotaNonPagedPoolUsage;
    SIZE_T PagefileUsage;
    SIZE_T PeakPagefileUsage;
} PROCESS_MEMORY_COUNTERS;
typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS;

Members

cb
The size of the structure, in bytes.
PageFaultCount
The number of page faults.
PeakWorkingSetSize
The peak working set size.
WorkingSetSize
The current working set size.
QuotaPeakPagedPoolUsage
The peak paged pool usage.
QuotaPagedPoolUsage
The current paged pool usage.
QuotaPeakNonPagedPoolUsage
The peak nonpaged pool usage.
QuotaNonPagedPoolUsage
The current nonpaged pool usage.
PagefileUsage
The current pagefile usage.
PeakPagefileUsage
The peak pagefile usage.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.

See Also

Process Status Helper Overview, PSAPI Structures, GetProcessMemoryInfo


PSAPI_WS_WATCH_INFORMATION

The PSAPI_WS_WATCH_INFORMATION structure contains information about a page added to a process working set.

typedef struct _PSAPI_WS_WATCH_INFORMATION {
    LPVOID FaultingPc;
    LPVOID FaultingVa;
} PSAPI_WS_WATCH_INFORMATION, *PPSAPI_WS_WATCH_INFORMATION;

Members

FaultingPc
Pointer to the instruction that caused the page fault.
FaultingVa
Pointer to the page that was added to the working set.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Psapi.h.

See Also

Process Status Helper Overview, PSAPI Structures, GetWsChanges


System Monitor Automation Interface

The System Monitor automation interface allows control over the operation of the System Monitor MMC snap-in from Microsoft® Visual Basic® programs and ActiveX®-enabled containers like Microsoft Office 2000. Note that this interface does not allow control over the operation of the Performance Monitor in Windows NT, only the System Monitor MMC snap-in that is the Windows 2000 Performance Monitor.

  • Using the System Monitor Automation Interface
  • System Monitor Automation Interface Reference


Using the System Monitor Automation Interface

  • ActiveX Control Support in Office 2000
  • Error Codes


ActiveX Control Support in Office 2000

The following considerations apply when using ActiveX® controls with Office 2000 applications. You may encounter some of the behavior described in the following list when working with the System Monitor control in Office 2000 containers:

  • Microsoft® Excel charts cannot contain ActiveX controls. Controls can be placed on top of chart objects that are embedded in a worksheet, but such controls will not be active when the chart is activated.
  • There is no automatic downloading of ActiveX controls embedded in Office 2000 documents when browsing using Internet Explorer.
  • In Microsoft Excel, restarting the computer with the control active (selecting Shut Down) will result in the message "Cannot quit Microsoft Excel."
  • ActiveX controls may behave unpredictably when seen in multiple views of the same Microsoft Word document (for example, when using New Window or the Split pane).
  • ActiveX controls in an Excel worksheet cannot be activated if Excel is in-place active within a container—that is, if an Excel worksheet is embedded in another container (such as a Word document), the controls in the worksheet are displayed correctly and can be selected in Design Mode in this case; however, the controls are not in-place active.
  • Office 2000 documents do not support multithreaded controls. When the System Monitor control is configured to collect data automatically, it causes a separate thread to run, causing problems with Office 2000 applications. Therefore, Microsoft recommends configuring manual updating when hosting the control in Office 2000 applications.


Error Codes

The SystemMonitor object returns the status as an HRESULT. In addition, the GetValue and GetStatistics methods in the CounterItem object return status information the validity of the counter data as an argument.

The following is a list of all error codes that the System Monitor returns.

Error code: 0xC0001388
Definition: SMON_STATUS_DUPL_COUNTER_PATH
Description: Returned when you attempt to add a counter that already exists.
Message text: "Specified counter is already assigned to this control."

Error code: 0xC0001389
Definition: SMON_STATUS_NO_SYSMON_OBJECT
Description: Returned when the property settings do not contain a complete HTML object.
Message text: "The settings do not contain any complete System Monitor HTML objects."

Error code: 0xC000138A
Definition: SMON_STATUS_TOO_FEW_SAMPLES
Description: Returned when the specified log file contains fewer than two data samples.
Message text: "The specified log file contains fewer than two data samples."

Error code: 0xC000138B
Definition: SMON_STATUS_LOG_FILE_SIZE_LIMIT
Description: Returned when setting the LogFileName property and the size of the specified log file exceeds the size limits of the System Monitor control. The System Monitor attempts to load the new log file before unloading the currently selected log file. In that case, the user or program might choose to unload the current log file by specifying a null file name, then attempt to specify the new log file name again.
Message text: "The specified log file exceeds the size limits of the System Monitor control. If a log file is currently selected, select current activity as the data source in order to unload the current log file, then reselect the specified log file."

For a description of additional error codes returned by the System Monitor automation control, refer to Win32 Error Codes and Checking PDH Interface Return Values.


System Monitor Automation Interface Reference

This section describes the following topics related to the System Monitor automation interface:

  • System Monitor Automation Interface Classes
  • System Monitor Automation Interface Methods
  • System Monitor Automation Interface Properties
  • System Monitor Automation Interface Enumerations
  • System Monitor Automation Interface Events


System Monitor Automation Interface Classes

The System Monitor automation interface includes the following class objects.

Class name | Description
CounterItem | Provides counter property information.
Counters | Provides methods for adding or removing CounterItem objects and accessing related properties. It is a collection of CounterItem objects.
SystemMonitor | Provides methods and properties that correspond to the functionality provided by the System Monitor user interface. Each SystemMonitor object contains one Counters collection object.


CounterItem

The CounterItem interface provides type information, including the methods and properties that define the appearance of individual counters.

SystemMonitorCtl.CounterItem

Remarks

Value is the default property of CounterItem.

The following are the methods provided by CounterItem.

Method name | Description
GetStatistics | Retrieves the statistical values average, maximum, and minimum for a counter.
GetValue | Retrieves the current value of a counter.

The following are the properties provided by CounterItem.

Property name | Description
Color | Retrieves or sets the color of a graphed counter value.
LineStyle | Retrieves or sets the line style of a graphed counter value.
Path | Retrieves the path of a counter used by the control.
ScaleFactor | Retrieves or sets the scale factor used in displaying graphed counter values.
Value | Retrieves the current value of a counter.
Width | Retrieves or sets the width of the line used to display graphed counter values.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Classes


Counters

The Counters collection object defines methods for adding or removing CounterItem objects and their associated properties. Counters is a one-based collection of CounterItem objects.

SystemMonitorCtl.Counters

Remarks

Item is the default property of the Counters object.

The following are the methods provided by Counters.

Method name | Description
Add | Adds an instance of a CounterItem object to the Counters collection object for display by the SystemMonitor object.
Remove | Removes an instance of a CounterItem object from the Counters collection object.

The following are the properties provided by Counters.

Property name | Description
Count | Retrieves the number of CounterItem instances in the Counters object.
Item | Retrieves the specified instance of a CounterItem object from the Counters collection object.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Classes


SystemMonitor

The SystemMonitor interface provides the methods and functionality that correspond to most of the functionality provided by the System Monitor user interface.

SystemMonitorCtl.SystemMonitor

Remarks

The Counters object is the default property of the SystemMonitor object.

The following are the methods provided by SystemMonitor.

Method name | Description
BrowseCounters | Displays the Add Counter dialog box.
CollectSample | Samples a value from each counter in the Counters collection object.
Copy | Copies all of the current property settings to the Clipboard as an HTML object.
DisplayProperties | Displays the Graph Properties dialog box.
Paste | Pastes all of the counters currently in the Clipboard to the graph pane of the System Monitor.
Reset | Removes all CounterItem objects from the Counters collection object.
UpdateGraph | Refreshes the contents of the System Monitor windows.

The following are the properties provided by SystemMonitor.

Property name | Description
Appearance | Retrieves or sets the appearance of the control to include or omit three-dimensional display effects.
BackColor | Retrieves or sets the color of the graph, histogram, or report where the counter data values are displayed.
BackColorCtl | Retrieves or sets the background color of the area that surrounds the graph, histogram, or report.
BorderStyle | Retrieves or sets the border style of the control.
Counters | Retrieves the collection of CounterItem objects included in the Counters collection object for the specified control.
DisplayType | Retrieves or sets the view type (that is, line graph, histogram, or report) of the control.
Font | Retrieves or sets the font of the control.
ForeColor | Retrieves or sets the color of the text that appears in the System Monitor's interface—that is, legend column names, labels, and statistics.
GraphTitle | Retrieves or sets the title of the System Monitor's graph window, line graph, or histogram view.
GridColor | Retrieves or sets the color of the grid lines in the System Monitor's graph window, in the line graph or histogram view.
Highlight | Retrieves or sets a value indicating whether the values of a counter are highlighted in the System Monitor's graph window, in the line graph or histogram view.
LogFileName | Retrieves or sets the name of an existing log file to be used as the source of counter values to be displayed in the System Monitor.
LogViewStart | Retrieves or sets the starting date and time for logged counter value data displayed in the System Monitor.
LogViewEnd | Retrieves or sets the ending date and time for logged counter value data displayed in the System Monitor.
ManualUpdate | Retrieves or sets a value indicating whether the contents of the System Monitor will be updated manually, or automatically at specified intervals.
MaximumScale | Retrieves or sets the maximum value of the vertical (Y) axis of the System Monitor's line graph or histogram view.
MinimumScale | Retrieves or sets the minimum value of the vertical (Y) axis of the System Monitor's line graph or histogram view.
MonitorDuplicateInstances | Retrieves or sets a value that determines whether multiple instances of counters can be monitored.
ReadOnly | Retrieves or sets a value that determines whether a user can modify properties of a control.
ReportValueType | Retrieves or sets a value that determines the statistics to be displayed when Report View or Histogram View is active .
ShowHorizontalGrid | Retrieves or sets a value that determines whether horizontal lines are displayed.
ShowLegend | Retrieves or sets a value that determines whether the legend is displayed.
ShowScaleLabels | Retrieves or sets a value that determines whether the scale labels of the vertical axis of the System Monitor's graph window (in line graph or histogram view) is displayed.
ShowToolBar | Retrieves or sets a value that determines whether the toolbar is displayed.
ShowValueBar | Retrieves or sets a value that determines whether the value bar (the set of statistical values below the System Monitor's graph window) is displayed.
ShowVerticalGrid | Retrieves or sets a value that determines whether vertical lines are displayed in the System Monitor's line graph or histogram view.
TimeBarColor | Retrieves or sets the color of the time bar—that is, the vertical bar that moves across the System Monitor's graph window to indicate the passage of each sampling interval in the line graph view.
UpdateInterval | Retrieves or sets the length of the time interval for automatic collection of data displayed in the System Monitor.
YAxisLabel | Retrieves or sets the label of the vertical (Y) axis of the System Monitor's graph window, in line graph or histogram view.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Classes


System Monitor Automation Interface Methods

The System Monitor automation interface includes the following methods.

Method name | Description
CounterItem.GetStatistics | Retrieves the statistical values average, maximum, and minimum for a counter.
CounterItem.GetValue | Retrieves the current value of a counter.
Counters.Add | Adds an instance of a CounterItem object to the Counters collection object for display by the SystemMonitor object.
Counters.Remove | Removes an instance of a CounterItem object from the Counters collection object.
SystemMonitor.BrowseCounters | Displays the Add Counter dialog box.
SystemMonitor.CollectSample | Samples a value from each counter in the Counters collection object.
SystemMonitor.Copy | Copies all of the current property settings to the Clipboard as an HTML object.
SystemMonitor.DisplayProperties | Displays the Graph Properties dialog box.
SystemMonitor.Paste | Pastes all of the counters currently in the Clipboard to the graph pane of the System Monitor.
SystemMonitor.Reset | Removes all CounterItem objects from the Counters collection object.
SystemMonitor.UpdateGraph | Refreshes the contents of the System Monitor windows.


CounterItem.GetStatistics

Retrieves the statistical values average, maximum, and minimum for a counter.

Public Sub GetStatistics(
  max as Double,
  min as Double,
  average as Double,
  status as Long
);

Parameters

max
[in] Specifies the maximum value of the counter over the display interval.
min
[in] Specifies the minimum value of the counter over the display interval.
average
[in] Specifies the average value of the counter over the display interval.
status
[out] Indicates the validity of the counter value or statistical data.

Return Values

None.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Methods


CounterItem.GetValue

Retrieves the current value of the specified counter.

Public Sub GetValue(
  value as Double,
  status as Long
);

Parameters

value
[out] Indicates the current value of the counter.
status
[out] Indicates the validity of the counter value or statistical data success or failure.

Return Values

None.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Methods


Counters.Add

Adds a CounterItem object with the specified path to the Counters collection object for display by the SystemMonitor object.

Public Function Add(
  pathname as String
) as CounterItem

Parameters

pathname
[in] Specifies the counter path. The path can include a machine name, and must include a performance object name, an object instance name if the specified performance object supports multiple instances, and a counter name. This path specification is not case-sensitive.

Return Values

A reference to the added CounterItem object.

Remarks

If you specify a wildcard counter in the pathname parameter, the Add method creates one CounterItem object for each expanded path. The Add method then returns a pointer to the first added CounterItem.

If the wildcard would result in a duplicate counter, the error is not reported and no duplicate is created. If an error condition occurs before all counters are created, the error is reported and the remaining counters are not created.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Methods


Counters.Remove

Removes the CounterItem object with the specified index from the Counters collection object.

Public Sub Remove(
  index as Variant
)

Parameters

index
[in] Specifies a CounterItem object in the Counters object.

Return Values

This object has no return values.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Methods


SystemMonitor.BrowseCounters

Displays the Add Counters dialog box.

Public Sub BrowseCounters( )

Return Values

None.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Methods


SystemMonitor.CollectSample

Samples a value from each counter in the Counters object.

Public Sub CollectSample( )

Return Values

None.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Methods


SystemMonitor.Copy

Copies all of the current property settings to the Clipboard as a System Monitor HTML object.

Public Sub Copy( )

Return Values

None.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Methods


SystemMonitor.DisplayProperties

Displays the Graph Properties dialog box.

Public Sub DisplayProperties( );

Return Values

None.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Methods


SystemMonitor.Reset

Clears the existing list of counters in the SystemMonitor object.

Public Sub Reset( )

Return Values

None.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Methods


SystemMonitor.Paste

Pastes all of the counters currently in the Clipboard to the System Monitor. The Clipboard data is a System Monitor HTML object.

Public Sub Paste( )

Return Values

None.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Methods


SystemMonitor.UpdateGraph

Refreshes the contents of the System Monitor windows. This is a method of the SystemMonitor object.

Public Sub UpdateGraph( )

Return Values

None.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Methods


System Monitor Automation Interface Properties

The System Monitor automation interface includes the following properties.

Property name | Description
CounterItem.Color | Retrieves or sets the color of a graphed counter value.
CounterItem.LineStyle | Retrieves or sets the line style of a graphed counter value.
CounterItem.Path | Retrieves the path of a counter used by the control.
CounterItem.ScaleFactor | Retrieves or sets the scale factor used in displaying graphed counter values.
CounterItem.Value | Retrieves the current value of a counter.
CounterItem.Width | Retrieves or sets the width of the line used to display graphed counter values.
Counters.Count | Retrieves the number of CounterItem instances in the Counters object.
Counters.Item | Retrieves the specified instance of a CounterItem object from the Counters collection object.
SystemMonitor.Appearance | Retrieves or sets the appearance of the control to include or omit three-dimensional display effects.
SystemMonitor.BackColor | Retrieves or sets the color of the graph, histogram, or report where the counter data values are displayed.
SystemMonitor.BackColorCtl | Retrieves or sets the background color of the area that surrounds the graph, histogram, or report.
SystemMonitor.BorderStyle | Retrieves or sets the border style of the control.
SystemMonitor.Counters | Retrieves the collection of CounterItem objects included in the Counters collection object for the specified control.
SystemMonitor.DisplayType | Retrieves or sets the view type (that is, line graph, histogram, or report) of the control.
SystemMonitor.Font | Retrieves or sets the font of the control.
SystemMonitor.ForeColor | Retrieves or sets the color of the text that appears in the System Monitor's interface—that is, legend column names, labels, and statistics.
SystemMonitor.GraphTitle | Retrieves or sets the title of the System Monitor's graph window, line graph, or histogram view.
SystemMonitor.GridColor | Retrieves or sets the color of the grid lines in the System Monitor's graph window, in the line graph or histogram view.
SystemMonitor.Highlight | Retrieves or sets a value indicating whether the values of a counter are highlighted in the System Monitor's graph window, in the line graph or histogram view.
SystemMonitor.LogFileName | Retrieves or sets the name of an existing log file to be used as the source of counter values to be displayed in the System Monitor.
SystemMonitor.LogViewStart | Retrieves or sets the starting date and time for logged counter value data displayed in the System Monitor.
SystemMonitor.LogViewEnd | Retrieves or sets the ending date and time for logged counter value data displayed in the System Monitor.
SystemMonitor.ManualUpdate | Retrieves or sets a value indicating whether the contents of the System Monitor will be updated manually, or automatically at specified intervals.
SystemMonitor.MaximumScale | Retrieves or sets the maximum value of the vertical (Y) axis of the System Monitor's line graph or histogram view.
SystemMonitor.MinimumScale | Retrieves or sets the minimum value of the vertical (Y) axis of the System Monitor's line graph or histogram view.
SystemMonitor.MonitorDuplicateInstances | Retrieves or sets a value that determines whether multiple instances of counters can be monitored.
SystemMonitor.ReadOnly | Retrieves or sets a value that determines whether a user can modify properties of a control.
SystemMonitor.ReportValueType | Retrieves or sets a value that determines the statistics to be displayed when Report View or Histogram View is active .
SystemMonitor.ShowHorizontalGrid | Retrieves or sets a value that determines whether horizontal lines are displayed.
SystemMonitor.ShowLegend | Retrieves or sets a value that determines whether the legend is displayed.
SystemMonitor.ShowScaleLabels | Retrieves or sets a value that determines whether the scale labels of the vertical axis of the System Monitor's graph window (in line graph or histogram view) is displayed.
SystemMonitor.ShowToolBar | Retrieves or sets a value that determines whether the toolbar is displayed.
SystemMonitor.ShowValueBar | Retrieves or sets a value that determines whether the value bar (the set of statistical values below the System Monitor's graph window) is displayed.
SystemMonitor.ShowVerticalGrid | Retrieves or sets a value that determines whether vertical lines are displayed in the System Monitor's line graph or histogram view.
SystemMonitor.TimeBarColor | Retrieves or sets the color of the time bar—that is, the vertical bar that moves across the System Monitor's graph window to indicate the passage of each sampling interval in the line graph view.
SystemMonitor.UpdateInterval | Retrieves or sets the length of the time interval for automatic collection of data displayed in the System Monitor.
SystemMonitor.YAxisLabel | Retrieves or sets the label of the vertical (Y) axis of the System Monitor's graph window, in line graph or histogram view.


CounterItem.Color

Retrieves or sets the color of the counter value displayed in the System Monitor. This is a read/write property.

Public Property Color(
  value as OLE_COLOR
) as OLE_COLOR

Parameters

value
[in] Determines the color used for the counter values.

Remarks

You can define a custom color in the Visual Basic Editor using the Color combo box of the Properties dialog box. The user cannot modify the custom color using the Properties dialog box in the System Monitor.

The color you specify with this method is applied to the graph pane and legend for line graph and histogram views.

Return Values

The current color setting for the counter value. The OLE_COLOR data type holds color information for controls and their containers to use.

Example

Dim ctrItem as CounterItem
ctrItem.Color = vbRed
ctrItem.Color = RGB(255, 255, 0)
ctrItem.Color = &HFF00FF

Dim ColorVal as Variant
ColorVal = ctrItem.Color

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


CounterItem.LineStyle

Retrieves or sets the line style of the counter value displayed in the System Monitor. This is a read/write property.

Public Property LineStyle(
  value as Long
) as Long

Parameters

value
[in] Specifies the line style used for the counter display in the graph and legend panes. The values correspond to system constants shown in the following table. They are based on pen-style values available for the Windows graphics device interface (GDI).
Value | Meaning
PS_SOLID (0) | Solid (default).
PS_DASH (1) | Dotted line with long segments and narrow spaces.
PS_DOT (2) | Dotted line with uniform segments and spaces.
PS_DASHDOT (3) | Dotted line with alternating short and long segments.
PS_DASHDOTDOT (4) | Dotted line with alternating dashes and double dots.

Remarks

Nonzero values are used only when the line width is set to 1.

Return Values

The current line style setting for the counter value in the graph and legend panes.

Example

ctrItem.LineStyle = 2
ctrItem.LineStyle = PS_DOT

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


CounterItem.Path

Retrieves the counter path used by the System Monitor. This is a read-only property.

Public Property Path( ) as String

Remarks

The path this property returns includes the machine, performance object, instance, and counter.

Return Values

The counter path string.

Example

Dim ctrItem as CounterItem
Dim strPath as String
strpath = ctrItem.strPath

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


CounterItem.ScaleFactor

Retrieves or sets the scale factor used in presenting the counter value displayed in the System Monitor. This is a read/write property.

Public Property ScaleFactor(
  value as Long
) as Long

Parameters

value
[in] Specifies a value for the scale factor (expressed in powers of 10). Valid values of this parameter range from -7 to 7, or INT_MAX (2,147,483,647).

Remarks

Specifying INT_MAX for the value of the value parameter indicates that the default scale factor is to be used.

When a new counter is added, the scale factor for that counter is the default defined for that counter by the operating system.

The scale factor you specify with this method is applied to the graph pane and legend for line graph and histogram views.

Return Values

The current scale factor expressed as a power of 10 for a particular counter, or INT_MAX if the default scale factor is being used.

Example

grphLogMemory.Counters.Item(1).ScaleFactor = 3

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


CounterItem.Value

Retrieves the current value of the object's counter. This is a read-only property and is the default of the CounterItem object.

Public Property Value( ) as Double

Return Values

The current value of the counter. A status value is not returned unless an error condition is indicated. In that case, the property returns a value of -1.

Example

dValue = ctrItem.Value

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


CounterItem.Width

Retrieves or sets the width of the line, in pixels, used to display a counter value in a graph. This is a read/write property.

Public Property Width(
  value as Long
as Long

Parameters

value
[in] Specifies the line width in pixels. The values of this parameter range from 1 to 9, where 1 (the default value) is the narrowest width.

Remarks

The specified line widths appear in the Visual Basic Editor in the Width combo box.

Return Values

The current line width.

Example

Dim ctrItem as CounterItem
ctrItem.Width=2

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


Counters.Count

Returns the number of CounterItem objects in the Counters collection object. This is a read-only property.

Public Property Count( ) as Long;

Return Values

A value indicating the number of counters (CounterItem instances) in the Counters object.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


Counters.Item

Returns the specified counter from the Counters object as a CounterItem object. This is a read-only property and the default of the Counters object.

Public Property Item(
  index as Variant
) as CounterItem;

Parameters

index
[in] Identifies a specific counter in the Counters object. It is a one-based index value.

Return Values

A reference to the specified CounterItem object.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.Appearance

Retrieves or sets the control's appearance to include or omit three-dimensional display effects. This is an ambient read/write property.

Public Property Appearance( ) as Integer

Remarks

This is a standard property of the Form object in Visual Basic. For more information on this property, refer to the specification of the Appearance property in Visual Basic Help and the Microsoft Visual Basic 6.0 Language Reference.

You can set this property to an integer to specify whether to use three-dimensional effects in the control.

Value | Meaning
0 | Paints the control without three-dimensional effects.
1 | Paints the control with three-dimensional effects.

The default value is 1.

Return Values

The current control appearance value.

Example

Dim ctlItem as SystemMonitor
ctlItem.Appearance = 1

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.BackColor

Retrieves or sets the color of the graph pane. This is an ambient read/write property.

Public Property BackColor( ) as OLE_COLOR

Remarks

BackColor is a standard property that you can set to either a palette (RGB) color or a predefined system color. By default, its value corresponds to the foreground color of the control's container.

To set BackColor to a palette (RGB) color value, either include the RGB function followed by an integer value for each of the color components (red, green, and blue), or specify the hexadecimal equivalent of the three color component values. For information on the RGB function and the values you can specify for the function, refer to the "Color Constants" and "RGB Function" sections of Visual Basic Help.

The valid range for an RGB color value is 0 to 16,777,215 (&HFFFFFF). The red, green, and blue components are each represented by a number between 0 and 255 (&HFF). If you are specifying a hexadecimal number, remember that the high byte in the range of RGB color values is 0. The lower 3 bytes, from the lowest-order byte to the highest-order, respectively determine the red, green, and blue component values.

To set BackColor to a predefined system color, use a Visual Basic color constant. For information about these constants, refer to the "Color Constants" section of Visual Basic Help. The user defines the available system colors in the Control Panel—in the Appearance sheet of the Display Properties window.

Return Values

The OLE_COLOR data type for the color of the view or report area of the control. The OLE_COLOR data type holds color information for controls and their containers to use.

Example

Graph1.BackColor=vbRed
Graph1.BackColor=RGB(255,255,0)
Graph1.BackColor=&HFF00FF
Graph1.BackColor=vbDesktop

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.BackColorCtl

Retrieves or sets the background color of the control—that is, the area surrounding the graph pane, including the toolbar and legend. This is a read/write property.

Public Property BackColorCtl( ) as OLE_COLOR

Remarks

BackColorCtl is a standard property that you can set to either a palette (RGB) color or a predefined system color.

To set BackColorCtl to a palette (RGB) color, either include the RGB function followed by an integer value for each of the color components (red, green, and blue), or specify the hexadecimal equivalent of the three color component values. For information on the RGB function and the values you can specify for the function, refer to the "Color Constants" and "RGB Function" sections in Visual Basic Help.

The valid range for an RGB color value is 0 to 16,777,215 (&HFFFFFF). The red, green, and blue components are each represented by a number between 0 and 255 (&HFF). If you are specifying a hexadecimal number, remember that the high byte in the range of RGB color values is 0. The lower 3 bytes, from the lowest-order byte to the highest-order, respectively determine the red, green, and blue component values.

To set BackColorCtl to a predefined system color, use a Visual Basic color constant. For information about these constants, refer to the "Color Constants" section of Visual Basic Help. The user defines the available system colors in Control Panel.

Return Values

The OLE_COLOR data type for the color of the view or report area of the control. The OLE_COLOR data type holds color information for controls and their containers to use.

Example

Graph1.BackColor=vbRed
Graph1.BackColor=RGB(255,255,0)
Graph1.BackColor=&HFF00FF
Graph1.BackColor=vbDesktop

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.BorderStyle

Retrieves or sets the border style of the control. This is a read/write property.

Public Property BorderStyle( ) as Integer

Remarks

You can set BorderStyle to the following values.

Constant (value) | Meaning
vbBSNone (0) | No border. (default)
vbFixedSingle (1) | Fixed, single border.

Return Values

Either vbBSNone (0) or vbFixedSingle (1).

Example

Chart1.BorderStyle=0
Chart1.BorderStyle=vbBSNone

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.Counters

Returns the Counters collection of the control. This is a read-only property.

Public Property Counters( ) as Counters

Remarks

This is the default property of the SystemMonitor object.

You can use this property to perform operations on the returned counter collection.

Return Values

A Counters object.

Example

Dim ctrs as Counters
Set ctrs=Graph1.Counters
ctrs.item(1).Color=vbRed

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.DisplayType

Retrieves or sets the view type (histogram, graph, or report) of the control. This is a read/write property.

Public Property DisplayType( ) as Integer

Remarks

You can set DisplayType to the following values.

Constant (value) | Meaning
sysmonHistogram (0) | The view type is histogram.
sysmonLineGraph (1) | The view type is line graph. (default)
sysmonReport (2) | The view type is report.

Return Values

Either sysmonHistogram (0), sysmonLineGraph (1), or sysmonReport (2). These values are defined in the DisplayTypeConstants enumeration.

Example

Graph1.DisplayType=sysmonGraph
if (sysmonGraph=Graph1.DisplayTypes) then
    …
endif

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.Font

Retrieves or sets the font of the control. This is an ambient read/write property.

Public Property Font( ) as IFontDisp

Remarks

You set the value of the Font property by reference, passing a pointer to the IFontDisp interface to change or retrieve the properties of a Font object through the Font object interface. Properties that you use the IFontDisp interface to define include name, size, bold, italic, underline, strikethrough, and weight.

For more information about the Font object, refer to the "Font Object" section in Visual Basic Help.

Return Values

A reference to a Font object.

Example

Dim fnt as StdFont
Set Graph1.Font=fnt
fnt.Italic=True

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.ForeColor

Retrieves or sets the color of all of the text displayed in the System Monitor. This is an ambient read/write property.

Public Property ForeColor( ) as OLE_COLOR

Remarks

You can set ForeColor to either a palette (RGB) color or a predefined system color. By default, its value corresponds to the foreground color of the control's container.

To set ForeColor to a palette (RGB) color, either include the RGB function followed by an integer value for each of the color components (red, green, and blue), or specify the hexadecimal equivalent of the three color component values. For information on the RGB function and the values you can specify for the function, refer to the "Color Constants" and "RGB Function" sections in Visual Basic Help.

The valid range for an RGB color value is 0 to 16,777,215 (&HFFFFFF). The red, green, and blue components are each represented by a number between 0 and 255 (&HFF). If you are specifying a hexadecimal number, remember that the high byte in the range of RGB color values is 0. The lower 3 bytes, from the lowest-order byte to the highest-order, respectively determine the red, green, and blue component values.

To set ForeColor to a predefined system color, use a Visual Basic color constant. For information about these constants, refer to the "Color Constants" section of Visual Basic Help. The available system colors are defined by the user in the Control Panel—in the Appearance sheet of the Display Properties window.

Return Values

The OLE_COLOR data type for the color of the text used in the view for legend column names, labels, statistics, and grids. The OLE_COLOR data type holds color information for controls and their containers to use.

Example

Graph1.ForeColor=vbRed
Graph1.ForeColor=RGB(255,255,0)
Graph1.ForeColor=&HFF00FF
Graph1.ForeColor=vbDesktop

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.GraphTitle

Retrieves or sets the title of the view. This is a read/write property.

Public Property GraphTitle( ) as String

Remarks

The control truncates the displayed string to the size defined for the control.

Return Values

The specified title string.

Example

Graph1.GraphTitle="Daily Performance: MyServer"

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.GridColor

Retrieves or sets the color of the horizontal and vertical grid lines used in a graph if the ShowHorizontalGrid or ShowVerticalGrid properties are selected. This is a read/write property.

Public Property GridColor( ) as OLE_COLOR

Remarks

You can set GridColor to either a palette (RGB) color or a predefined system color. By default, its value corresponds to the grid color of the control's container.

To set GridColor to a palette (RGB) color, either include the RGB function followed by an integer value for each of the color components (red, green, and blue), or specify the hexadecimal equivalent of the three color component values. For information on the RGB function and the values you can specify for the function, refer to the "Color Constants" and "RGB Function" sections in Visual Basic Help.

The valid range for an RGB color value is 0 to 16,777,215 (&HFFFFFF). The red, green, and blue components are each represented by a number between 0 and 255 (&HFF). If you are specifying a hexadecimal number, remember that the high byte in the range of RGB color values is 0. The lower 3 bytes, from the lowest-order byte to the highest-order, respectively determine the red, green, and blue component values.

To set GridColor to a predefined system color, use a Visual Basic color constant. For information about these constants, refer to the "Color Constants" section of Visual Basic Help. The user defines the available system colors in the Control Panel—in the Appearance sheet of the Display Properties window.

Return Values

The OLE_COLOR data type for the color of the grid lines. The OLE_COLOR data type holds color information for controls and their containers to use.

Example

Graph1.GridColor=vbRed
Graph1.GridColor=RGB(255,255,0)
Graph1.GridColor=&HFF00FF
Graph1.GridColor=vbDesktop

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.Highlight

Retrieves or sets a value indicating whether the selected counter data is highlighted in the line graph or histogram view. This is a read/write property.

Public Property Highlight( ) as Boolean

Remarks

You set Highlight to a Boolean value indicating whether the selected counter's data will be highlighted in the view. The default value is False. When the property is set to True, the selected line or bar displaying counter data is highlighted.

Highlighting can be black or white, depending on the value of the BackColor property. The highlighting is automatically set to the color that will provide sufficient contrast between the colors in the line graph or histogram view.

Return Values

A Boolean value indicating whether the selected counter data is highlighted in the line graph or histogram view.

Example

Graph1.Highlight=False

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.LogFileName

Retrieves or sets the name of an existing log file to be used as the data source of the view. This is a read/write property.

Public Property LogFileName( ) as String

Remarks

The name of the log file you set the LogFileName property to must be a complete path—it must include the name of the drive, computer, and folder as well as the name of the log file.

If the value of this property is an empty string, data will be retrieved from a real-time source such as WMI or the registry. The sources are also referred to as "current activity."

Return Values

A string specifying the name of the log file being used as the data source of the view, or an empty string signifying that data is being retrieved from a real-time source.

Example

Graph1.LogFileName="c:\perflogs\perfdata_000001.csv"

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.LogViewStart

Retrieves or sets the starting date and time for data displayed in a view. This is a read/write property.

Public Property LogViewStart( ) as Date

Remarks

The value you set the LogViewStart property to must be of a Date type. Refer to the Microsoft Visual Basic 6.0 Language Reference, Appendix B, for a description of this type.

If this property is set to a Date value earlier than the first date and time contained in the log file, the control resets the first date and time value of the displayed data to the first date and time value in the log file.

Return Values

A value specifying the starting date and time for the data being displayed in the view.

Example

Graph1.LogViewStart=#9/12/97 2:25:00 PM#

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.LogViewEnd

Retrieves or sets the ending date and time for data displayed in a view. This is a read/write property.

Public Property LogViewEnd( ) as Date

Remarks

The value you set the LogViewEnd property to must be of a Date type. Refer to the Microsoft Visual Basic 6.0 Language Reference, Appendix B, for a description of this type.

If this property is set to a Date value later than the last date and time contained in the log file, the control resets the last date and time value of the displayed data to the last date and time value in the log file.

Return Values

A value specifying the ending date and time for the data being displayed in the view.

Example

Graph1.LogViewStart=#9/12/97 2:30:00 PM#

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.ManualUpdate

Retrieves or sets a value that indicates whether the view will be updated manually or automatically. This is a read/write property.

Public Property ManualUpdate( ) as Boolean

Remarks

Automatic updating is the default.

When this property is set to True, the view is updated by calling the CollectSample method of the SystemMonitor object.

Return Values

A value indicating whether the view is being updated manually or automatically.

Example

Graph1.ManualUpdate=False

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.MaximumScale

Retrieves or sets the maximum value of the vertical axis of the graph. This is a read/write property.

Public Property MaximumScale( ) as Long

Remarks

The default maximum value of the vertical scale is 100, the lowest value the maximum value can be set to is 1, and the highest is 999,999,999. The MaximumScale value must be at least 1 greater than the MinimumScale value.

The control automatically adjusts the numbers displayed in the vertical scale according to the size of the displayed control.

Return Values

The maximum value of the vertical axis of the graph. If the MaximumScale value is less than (MinimumScale + 1), an error value of PDH_INVALID_ARGUMENT will be returned.

Example

Graph1.MaximumScale=1000

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.MinimumScale

Retrieves or sets the minimum value of the vertical axis of the graph. This is a read/write property.

Public Property MinimumScale( ) as Long

Remarks

The default minimum value of the vertical scale is 0, and the maximum value is 999,999,998, or 1 less than the maximum value of MaximumScale. The value set by this property cannot be a negative number.

The control automatically adjust the numbers displayed in the vertical scale according to the size of the displayed control.

Return Values

The minimum value of the vertical axis of the graph. If the value of MinimumScale is greater than (MaximumScale - 1), an error value of PDH_INVALID_ARGUMENT will be returned.

Example

Graph1.MinimumScale=50

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.MonitorDuplicateInstances

Retrieves or sets a value that indicates whether the control allows monitoring of multiple instances of counters. This is a read/write property.

Public Property MonitorDuplicateInstances( ) as Boolean

Remarks

The default value of this property is True, meaning that multiple instances of counters can be monitored. For example, if two instances of Microsoft Excel are running and the value of this property is True, both instances of Excel can be monitored.

Return Values

A value indicating whether the control is allowing monitoring of multiple instances of counters.

Example

Graph1.MonitorDuplicateInstances=False

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.ReadOnly

Retrieves or sets a value that indicates whether users can modify the properties of a control. This is a read/write property.

Public Property ReadOnly( ) as Boolean

Remarks

The default value of this property is False, meaning that users can modify the properties of a control.

This property is available only through the programming interface or the HTML file object.

When ReadOnly is True, the following conditions are in effect:

  • The context menu is unavailable.
  • The following buttons are disabled on the toolbar:
    • New Counter Set
    • View Current Activity
    • View Log File Data
    • Add
    • Delete
    • Paste Counter List
    • Properties

Return Values

A value indicating whether users can modify the properties of a control.

Example

Graph1.ReadOnly=True

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.ReportValueType

Retrieves or sets a value that indicates the type of statistics to be displayed when Report or Histogram View is selected. This is a read/write property.

Public Property ReportValueType( ) as Integer

Remarks

You can set ReportValueType to an enumeration consisting of the following integer values.

Constant (value) | Meaning
sysmonDefaultValue (0) | Default values will be displayed.
sysmonCurrentValue (1) | Current values will be displayed.
sysmonAverage (2) | Average values will be displayed.
sysmonMinimum (3) | Minimum values will be displayed.
sysmonMaximum (4) | Maximum values will be displayed.

The default value of this property for current data is sysmonCurrentValue, and the default value of this property for log file data is sysmonAverage.

Return Values

A value indicating the type of statistics that are displayed when Report or Histogram View is selected.

Example

Graph1.ReportValueType=sysmonAverage
if (sysmonAverage=Graph1.ReportValueType) then
    …
endif

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.ShowHorizontalGrid

Retrieves or sets a value that indicates whether horizontal lines are displayed in the line graph or histogram view. This is a read/write property.

Public Property ShowHorizontalGrid( ) as Boolean

Remarks

The default value of this property is False, meaning that horizontal lines are not displayed in the line graph or histogram view.

Return Values

A Boolean value indicating whether horizontal lines are being displayed in the line graph or histogram view.

Example

Graph1.ShowHorizontalGrid=True

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.ShowLegend

Retrieves or sets a value that indicates whether the legend, which is the listing of selected counters, is displayed in the line graph or histogram view. This is a read/write property.

Public Property ShowLegend( ) as Boolean

Remarks

The default value of this property is True, meaning that the legend is displayed in the line graph or histogram view.

Return Values

A Boolean value indicating whether the legend is being displayed in the line graph or histogram view.

Example

Graph1.ShowLegend=True

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.ShowScaleLabels

Retrieves or sets a value that indicates whether the vertical scale of the line graph or histogram view is displayed. This is a read/write property.

Public Property ShowScaleLabels( ) as Boolean

Remarks

The default value of this property is True, meaning that the vertical scale is displayed in the line graph or histogram view.

Return Values

A Boolean value indicating whether the scale labels are being displayed.

Example

Graph1.ShowScaleLabels=False

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.ShowToolbar

Retrieves or sets a value that indicates whether the toolbar is displayed. This is a read/write property.

Public Property ShowToolbar( ) as Boolean

Remarks

The default value of this property is True, meaning that the toolbar is displayed in the line graph or histogram view.

The toolbar provides easy access to functions such as copying counters to the Clipboard, and changing the data source for the display.

Return Values

A value indicating whether the toolbar is being displayed.

Example

Graph1.ShowScaleLabels=False

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.ShowValueBar

Retrieves or sets a value that indicates whether statistics are displayed beneath the line graph or histogram view. This is a read/write property.

Public Property ShowValueBar( ) as Boolean

Remarks

The default value of this property is True, meaning that statistics are displayed.

The displayed statistics include the last value, the average value, and the minimum and maximum values of the currently selected counter over the displayed time interval.

Return Values

A Boolean value indicating whether statistics are being displayed.

Example

Graph1.ShowValueBar=False

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.ShowVerticalGrid

Retrieves or sets a value that indicates whether vertical lines are displayed in the line graph or histogram view. This is a read/write property.

Public Property ShowVerticalGrid( ) as Boolean

Remarks

The default value of this property is False, meaning that vertical lines are not displayed in the line graph or histogram view.

Return Values

A value indicating whether vertical lines are being displayed in the line graph or histogram view.

Example

Graph1.ShowVerticalGrid=True

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.TimeBarColor

Retrieves or sets the color of the time bar, which is the vertical bar that moves across the graph to indicate the passage of each sampling interval when Chart View is selected. This is a read/write property.

Public Property TimeBarColor( ) as OLE_COLOR

Remarks

TimeBarColor is a standard property that can be set to either a palette (RGB) color or a predefined system color. The default value of this property is vbRed, which equals RGB(255, 0, 0) and &HFF.

To set TimeBarColor to a palette (RGB) color value, either include the RGB function followed by an integer value for each of the color components (red, green, and blue), or specify the hexadecimal equivalent of the three color component values. For information on the RGB function and the values you can specify for the function, refer to the "Color Constants" and "RGB Function" sections of Visual Basic Help.

The valid range for an RGB color value is 0 to 16,777,215 (&HFFFFFF). The red, green, and blue components are each represented by a number between 0 and 255 (&HFF). If you are specifying a hexadecimal number, remember that the high byte in the range of RGB color values is 0. The lower 3 bytes, from the lowest-order byte to the highest-order, respectively determine the red, green, and blue component values.

To set TimeBarColor to a predefined system color, use a Visual Basic color constant. For information about these constants, refer to the "Color Constants" section of Visual Basic Help. The user defines the available system colors in the Control Panel—in the Appearance sheet of the Display Properties window.

Return Values

The OLE_COLOR data type for the color of the time bar. The OLE_COLOR data type holds color information for controls and their containers to use.

Example

Graph1.TimeBarColor=vbRed
Graph1.TimeBarColor=RGB(255,255,0)
Graph1.TimeBarColor=&HFF00FF
Graph1.TimeBarColor=vbDesktop

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.UpdateInterval

Retrieves or sets a value that indicates the length of the time interval, in seconds, that counter data is updated in the view. This is a read/write property.

Public Property UpdateInterval( ) as Short

Remarks

The default value of this property is 1, which is also the default. The maximum value is 1,000,000.

The ManualUpdate property of the SystemMonitor object must be set to False when this property is set.

Return Values

A value indicating the length of the update time interval.

Example

Graph1.UpdateInterval=30

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


SystemMonitor.YAxisLabel

Retrieves or sets the label of the vertical (Y) axis of the graph. This is a read/write property.

Public Property YAxisLabel( ) as String

Remarks

The default value of this property is NULL.

Return Values

The vertical axis label string.

Example

Graph1.YAxisLabel="Counter Data Range"

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Properties


System Monitor Automation Interface Enumerations

The System Monitor automation interface uses the following enumeration types.

Enumeration name | Description
DisplayTypeConstants | Determines the current view of the System Monitor.
ReportValueTypeConstants | Determines the type of value for the System Monitor to display in the Histogram and Report views. The options are current value, last value, average value, minimum value, maximum value, and default value.


SystemMonitorCtl.DisplayTypeConstants

Used in the DisplayType property of the SystemMonitor object for the display type value.

Public Enum DisplayTypeConstants
  sysmonLineGraph = 1
  sysmonHistogram
  sysmonReport
End Enum
Constant (value) | Description
sysmonLineGraph (1) | Counter values will be displayed in a line graph.
sysmonHistogram (2) | Counter values will be displayed in a histogram.
sysmonReport (3) | Counter values will be displayed in a report format.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Enumerations


SystemMonitorCtl.ReportValueTypeConstants

Used in the ReportValueType property of the SystemMonitor object. This enumeration determines the value to be displayed for each counter in the Histogram and Report views.

Public Enum ReportValueTypeConstants
  sysmonDefaultValue
  sysmonCurrentValue
  sysmonAverage
  sysmonMinumum
  sysmonMaximum
End Enum
Constant (value) | Description
sysmonDefaultValue (0) | The default value of the counter.
sysmonCurrentValue (1) | The current value of the counter.
sysmonAverage (2) | The average value of the counter over the display interval.
sysmonMinimum (3) | The minimum value of the counter over the display interval.
sysmonMaximum (4) | The maximum value of the counter over the display interval.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Enumerations


System Monitor Automation Interface Events

The System Monitor automation interface includes the following events.

Event name | Description
ISystemMonitorEvents.OnCounterAdded | Occurs when a counter is added in the System Monitor.
ISystemMonitorEvents.OnCounterDeleted | Occurs when a counter is deleted in the System Monitor.
ISystemMonitorEvents.OnCounterSelected | Occurs when a counter is selected in the System Monitor.
ISystemMonitorEvents.OnDblClick | Occurs when a user double-clicks the graph line, histogram bar, or report item with the left mouse button.
ISystemMonitorEvents.OnSampleCollected | Occurs when a sample is collected for all counters.


ISystemMonitorEvents.OnCounterAdded

Occurs when a counter is added in the System Monitor.

Public Sub OnCounterAdded(
  index as Long
);

Parameters

index
[in] Specifies the index of the counter added to the Counter collection object.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Events


ISystemMonitorEvents.OnCounterDeleted

Occurs when a counter is deleted in the System Monitor.

Public Sub OnCounterDeleted(
  index as Long
);

Parameters

index
[in] Specifies the index of the counter deleted from the Counter collection object.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Events


ISystemMonitorEvents.OnCounterSelected

Occurs when a counter is selected in the System Monitor.

Public Sub OnCounterSelected(
  index as Long
);

Parameters

index
[in] Specifies the index of the selected counter in the Counter collection object.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Events


ISystemMonitorEvents.OnDblClick

Occurs when a user double-clicks the graph line, histogram bar, or report item with the left mouse button.

Public Sub OnDblClick(
  index as Long
);

Parameters

index
[in/out] Specifies the index of the selected counter in the Counter collection object. An index value of 0 is returned if no counter was selected; otherwise, the index of the selected counter is returned.

Remarks

When this event is triggered, the displayed data of a counter is selected in the line graph and histogram view legend. This makes it easier for the user of the System Monitor to see which counter is selected when several counter values are displayed.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Events


ISystemMonitorEvents.OnSampleCollected

Occurs when a sample is collected for all counters.

Public Sub OnSampleCollected ( )

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Smonctrl.odl.

See Also

System Monitor Automation Interface Overview, System Monitor Automation Interface Events


Topic Not Found

No matching topic was found. Some possible reasons and remedies are as follows:

  • The file (.chm) that contains the destination topic is not in the expected location.

    Remedy: Rerun the MSDN Library Setup.

  • The file (.chm) that contains the current topic or destination topic is out-of-date and the link is no longer valid.

    Remedy: Install the latest version of the MSDN Library.

  • The MSDN Library CD is not in the CD-ROM drive.

    Remedy: Insert the MSDN Library CD into the CD-ROM drive.