' ########################################################################################
' Microsoft Windows
' File: WinPerf.inc
' Copyright (c) 2011 Jos? Roca
' Portions Copyright (c) Microsoft Corporation.
' All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
#IF NOT %DEF(PBX_WinPerf_PBI)
#DEFINE PBX_WinPerf_PBI
%EQUATE `WINPERF_INC = 1
#INCLUDE ONCE "Legacy/System/sdkddkver.inc"
'/*++
'Copyright (c) Microsoft Corporation. All rights reserved.
'Module Name:
' winperf.h
'Abstract:
' Header file for the Performance Monitor data.
' This file contains the definitions of the data structures returned
' by the Configuration Registry in response to a request for
' performance data. This file is used by both the Configuration
' Registry and the Performance Monitor to define their interface.
' The complete interface is described here, except for the name
' of the node to query in the registry. It is
' HKEY_PERFORMANCE_DATA.
' By querying that node with a subkey of "Global" the caller will
' retrieve the structures described here.
' There is no need to RegOpenKey() the reserved handle HKEY_PERFORMANCE_DATA,
' but the caller should RegCloseKey() the handle so that network transports
' and drivers can be removed or installed (which cannot happen while
' they are open for monitoring.) Remote requests must first
' RegConnectRegistry().
'--*/
#INCLUDE ONCE "Legacy/System/WTypes.inc"
'#include <pshpack8.h>
'// Data structure definitions.
'// In order for data to be returned through the Configuration Registry
'// in a system-independent fashion, it must be self-describing.
'// In the following, all offsets are in bytes.
'//
'// Data is returned through the Configuration Registry in a
'// a data block which begins with a _PERF_DATA_BLOCK structure.
'//
%EQUATE `PERF_DATA_VERSION = 1
%EQUATE `PERF_DATA_REVISION = 1
' // Size = 88 bytes
TYPE PERF_DATA_BLOCK QWORD FILL ' Must be 8 byte aligned
 Signature AS WSTRINGZ * 4 ' WCHAR[4]
 LittleEndian AS DWORD
 Version AS DWORD
 Revision AS DWORD
 TotalByteLength AS DWORD
 HeaderLength AS DWORD
 NumObjectTypes AS DWORD
 DefaultObject AS LONG
 SystemTime AS SYSTEMTIME ' SYSTEMTIME
 PerfTime AS QUAD ' LARGE_INTEGER
 PerfFreq AS QUAD ' LARGE_INTEGER
 PerfTime100nSec AS QUAD ' LARGE_INTEGER
 SystemNameLength AS DWORD
 SystemNameOffset AS DWORD
END TYPE
'//
'// The _PERF_DATA_BLOCK structure is followed by NumObjectTypes of
'// data sections, one for each type of object measured. Each object
'// type section begins with a _PERF_OBJECT_TYPE structure.
'//
' // Size = 64 bytes
TYPE PERF_OBJECT_TYPE QWORD FILL ' Must be 8 byte aligned
 TotalByteLength AS DWORD
 DefinitionLength AS DWORD
 HeaderLength AS DWORD
 ObjectNameTitleIndex AS DWORD
'#ifdef _WIN64
' DWORD ObjectHelpTitle; // Should use this as an offset
'#else
 ObjectNameTitle AS WSTRINGZ PTR
'#endif
 ObjectHelpTitleIndex AS DWORD
'#ifdef _WIN64
' DWORD ObjectHelpTitle; // Should use this as an offset
'#else
 ObjectHelpTitle AS WSTRINGZ PTR
'#endif
 DetailLevel AS DWORD
 NumCounters AS DWORD
 DefaultCounter AS LONG
 NumInstances AS LONG
 CodePage AS DWORD
 PerfTime AS QUAD ' LARGE_INTEGER
 PerfFreq AS QUAD ' LARGE_INTEGER
END TYPE
%EQUATE `PERF_NO_INSTANCES = -1 ' no instances
'//
'// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'//
'// PERF_COUNTER_DEFINITION.CounterType field values
'//
'//
'// Counter ID Field Definition:
'//
'// 3 2 2 2 2 1 1 1
'// 1 8 4 2 0 6 2 0 8 0
'// +--------+--------+----+----+--------+--------+----+----+----------------+
'// |Display |Calculation |Time|Counter | |Ctr |Size| |
'// |Flags |Modifiers |Base|SubType |Reserved|Type|Fld | Reserved |
'// +--------+--------+----+----+--------+--------+----+----+----------------+
'//
'//
'// The counter type is the "or" of the following values as described below
'//
'// select one of the following to indicate the counter's data size
'//
%EQUATE `PERF_SIZE_DWORD = &H00000000
%EQUATE `PERF_SIZE_LARGE = &H00000100
%EQUATE `PERF_SIZE_ZERO = &H00000200 ' for Zero Length fields
%EQUATE `PERF_SIZE_VARIABLE_LEN = &H00000300 ' length is in CounterLength field of Counter Definition struct
'//
'// select one of the following values to indicate the counter field usage
'//
%EQUATE `PERF_TYPE_NUMBER = &H00000000 ' a number (not a counter)
%EQUATE `PERF_TYPE_COUNTER = &H00000400 ' an increasing numeric value
%EQUATE `PERF_TYPE_TEXT = &H00000800 ' a text field
%EQUATE `PERF_TYPE_ZERO = &H00000C00 ' displays a zero
'//
'// If the PERF_TYPE_NUMBER field was selected, then select one of the
'// following to describe the Number
'//
%EQUATE `PERF_NUMBER_HEX = &H00000000 ' display as HEX value
%EQUATE `PERF_NUMBER_DECIMAL = &H00010000 ' display as a decimal integer
%EQUATE `PERF_NUMBER_DEC_1000 = &H00020000 ' display as a decimal/1000
'//
'// If the PERF_TYPE_COUNTER value was selected then select one of the
'// following to indicate the type of counter
'//
%EQUATE `PERF_COUNTER_VALUE = &H00000000 ' display counter value
%EQUATE `PERF_COUNTER_RATE = &H00010000 ' divide ctr / delta time
%EQUATE `PERF_COUNTER_FRACTION = &H00020000 ' divide ctr / base
%EQUATE `PERF_COUNTER_BASE = &H00030000 ' base value used in fractions
%EQUATE `PERF_COUNTER_ELAPSED = &H00040000 ' subtract counter from current time
%EQUATE `PERF_COUNTER_QUEUELEN = &H00050000 ' Use Queuelen processing func.
%EQUATE `PERF_COUNTER_HISTOGRAM = &H00060000 ' Counter begins or ends a histogram
%EQUATE `PERF_COUNTER_PRECISION = &H00070000 ' // divide ctr / private clock
'//
'// If the PERF_TYPE_TEXT value was selected, then select one of the
'// following to indicate the type of TEXT data.
'//
%EQUATE `PERF_TEXT_UNICODE = &H00000000 ' type of text in text field
%EQUATE `PERF_TEXT_ASCII = &H00010000 ' ASCII using the CodePage field
'//
'// Timer SubTypes
'//
%EQUATE `PERF_TIMER_TICK = &H00000000 ' use system perf. freq for base
%EQUATE `PERF_TIMER_100NS = &H00100000 ' use 100 NS timer time base units
%EQUATE `PERF_OBJECT_TIMER = &H00200000 ' use the object timer freq
'//
'// Any types that have calculations performed can use one or more of
'// the following calculation modification flags listed here
'//
%EQUATE `PERF_DELTA_COUNTER = &H00400000 ' compute difference first
%EQUATE `PERF_DELTA_BASE = &H00800000 ' compute base diff as well
%EQUATE `PERF_INVERSE_COUNTER = &H01000000 ' show as 1.00-value (assumes:
%EQUATE `PERF_MULTI_COUNTER = &H02000000 ' sum of multiple instances
'//
'// Select one of the following values to indicate the display suffix (if any)
'//
%EQUATE `PERF_DISPLAY_NO_SUFFIX = &H00000000 ' no suffix
%EQUATE `PERF_DISPLAY_PER_SEC = &H10000000 ' "/sec"
%EQUATE `PERF_DISPLAY_PERCENT = &H20000000 ' "%"
%EQUATE `PERF_DISPLAY_SECONDS = &H30000000 ' "secs"
%EQUATE `PERF_DISPLAY_NOSHOW = &H40000000 ' value is not displayed
'//
'// Predefined counter types
'//
'// 32-bit Counter. Divide delta by delta time. Display suffix: "/sec"
'#define PERF_COUNTER_COUNTER \
' (PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE |\
' PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC)
%EQUATE `PERF_COUNTER_COUNTER = %PERF_SIZE_DWORD OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_RATE OR %PERF_TIMER_TICK OR %PERF_DELTA_COUNTER OR %PERF_DISPLAY_PER_SEC
'// 64-bit Timer. Divide delta by delta time. Display suffix: "%"
%EQUATE `PERF_COUNTER_TIMER = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_RATE OR %PERF_TIMER_TICK OR %PERF_DELTA_COUNTER OR %PERF_DISPLAY_PERCENT
'// Queue Length Space-Time Product. Divide delta by delta time. No Display Suffix.
%EQUATE `PERF_COUNTER_QUEUELEN_TYPE = %PERF_SIZE_DWORD OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_QUEUELEN OR %PERF_TIMER_TICK OR %PERF_DELTA_COUNTER OR %PERF_DISPLAY_NO_SUFFIX
'// Queue Length Space-Time Product. Divide delta by delta time. No Display Suffix.
%EQUATE `PERF_COUNTER_LARGE_QUEUELEN_TYPE = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_QUEUELEN OR %PERF_TIMER_TICK OR %PERF_DELTA_COUNTER OR %PERF_DISPLAY_NO_SUFFIX
'// Queue Length Space-Time Product using 100 Ns timebase.
'// Divide delta by delta time. No Display Suffix.
%EQUATE `PERF_COUNTER_100NS_QUEUELEN_TYPE = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_QUEUELEN OR %PERF_TIMER_100NS OR %PERF_DELTA_COUNTER OR %PERF_DISPLAY_NO_SUFFIX
'// Queue Length Space-Time Product using Object specific timebase.
'// Divide delta by delta time. No Display Suffix.
%EQUATE `PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_QUEUELEN OR %PERF_OBJECT_TIMER OR %PERF_DELTA_COUNTER OR %PERF_DISPLAY_NO_SUFFIX
'// 64-bit Counter. Divide delta by delta time. Display Suffix: "/sec"
%EQUATE `PERF_COUNTER_BULK_COUNT = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_RATE OR %PERF_TIMER_TICK OR %PERF_DELTA_COUNTER OR %PERF_DISPLAY_PER_SEC
'// Indicates the counter is not a counter but rather Unicode text Display as text.
%EQUATE `PERF_COUNTER_TEXT = %PERF_SIZE_VARIABLE_LEN OR %PERF_TYPE_TEXT OR %PERF_TEXT_UNICODE OR %PERF_DISPLAY_NO_SUFFIX
'// Indicates the data is a counter which should not be
'// time averaged on display (such as an error counter on a serial line)
'// Display as is. No Display Suffix.
%EQUATE `PERF_COUNTER_RAWCOUNT = %PERF_SIZE_DWORD OR %PERF_TYPE_NUMBER OR %PERF_NUMBER_DECIMAL OR %PERF_DISPLAY_NO_SUFFIX
'// Same as PERF_COUNTER_RAWCOUNT except its size is a large integer
%EQUATE `PERF_COUNTER_LARGE_RAWCOUNT = %PERF_SIZE_LARGE OR %PERF_TYPE_NUMBER OR %PERF_NUMBER_DECIMAL OR %PERF_DISPLAY_NO_SUFFIX
'// Special case for RAWCOUNT that want to be displayed in hex
'// Indicates the data is a counter which should not be
'// time averaged on display (such as an error counter on a serial line)
'// Display as is. No Display Suffix.
%EQUATE `PERF_COUNTER_RAWCOUNT_HEX = %PERF_SIZE_DWORD OR %PERF_TYPE_NUMBER OR %PERF_NUMBER_HEX OR %PERF_DISPLAY_NO_SUFFIX
'// Same as PERF_COUNTER_RAWCOUNT_HEX except its size is a large integer
%EQUATE `PERF_COUNTER_LARGE_RAWCOUNT_HEX = %PERF_SIZE_LARGE OR %PERF_TYPE_NUMBER OR %PERF_NUMBER_HEX OR %PERF_DISPLAY_NO_SUFFIX
'// A count which is either 1 or 0 on each sampling interrupt (% busy)
'// Divide delta by delta base. Display Suffix: "%"
%EQUATE `PERF_SAMPLE_FRACTION = %PERF_SIZE_DWORD OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_FRACTION OR %PERF_DELTA_COUNTER OR %PERF_DELTA_BASE OR %PERF_DISPLAY_PERCENT
'// A count which is sampled on each sampling interrupt (queue length)
'// Divide delta by delta time. No Display Suffix.
%EQUATE `PERF_SAMPLE_COUNTER = %PERF_SIZE_DWORD OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_RATE OR %PERF_TIMER_TICK OR %PERF_DELTA_COUNTER OR %PERF_DISPLAY_NO_SUFFIX
'// A label: no data is associated with this counter (it has 0 length)
'// Do not display.
%EQUATE `PERF_COUNTER_NODATA = %PERF_SIZE_ZERO OR %PERF_DISPLAY_NOSHOW
'// 64-bit Timer inverse (e.g., idle is measured, but display busy %)
'// Display 100 - delta divided by delta time. Display suffix: "%"
%EQUATE `PERF_COUNTER_TIMER_INV = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_RATE OR %PERF_TIMER_TICK OR %PERF_DELTA_COUNTER OR %PERF_INVERSE_COUNTER OR %PERF_DISPLAY_PERCENT
'// The divisor for a sample, used with the previous counter to form a
'// sampled %. You must check for >0 before dividing by this! This
'// counter will directly follow the numerator counter. It should not
'// be displayed to the user.
%EQUATE `PERF_SAMPLE_BASE = %PERF_SIZE_DWORD OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_BASE OR %PERF_DISPLAY_NOSHOW OR &H00000001 ' // for compatibility with pre-beta versions
'// A timer which, when divided by an average base, produces a time
'// in seconds which is the average time of some operation. This
'// timer times total operations, and the base is the number of opera-
'// tions. Display Suffix: "sec"
%EQUATE `PERF_AVERAGE_TIMER = %PERF_SIZE_DWORD OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_FRACTION OR %PERF_DISPLAY_SECONDS
'// Used as the denominator in the computation of time or count
'// averages. Must directly follow the numerator counter. Not dis-
'// played to the user.
%EQUATE `PERF_AVERAGE_BASE = %PERF_SIZE_DWORD OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_BASE OR %PERF_DISPLAY_NOSHOW OR &H00000002 ' // for compatibility with pre-beta versions
'// A bulk count which, when divided (typically) by the number of
'// operations, gives (typically) the number of bytes per operation.
'// No Display Suffix.
%EQUATE `PERF_AVERAGE_BULK = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_FRACTION OR %PERF_DISPLAY_NOSHOW
'// 64-bit Timer in object specific units. Display delta divided by
'// delta time as returned in the object type header structure. Display suffix: "%"
%EQUATE `PERF_OBJ_TIME_TIMER = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_RATE OR %PERF_OBJECT_TIMER OR %PERF_DELTA_COUNTER OR %PERF_DISPLAY_PERCENT
'// 64-bit Timer in 100 nsec units. Display delta divided by
'// delta time. Display suffix: "%"
%EQUATE `PERF_100NSEC_TIMER = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_RATE OR %PERF_TIMER_100NS OR %PERF_DELTA_COUNTER OR %PERF_DISPLAY_PERCENT
'// 64-bit Timer inverse (e.g., idle is measured, but display busy %)
'// Display 100 - delta divided by delta time. Display suffix: "%"
%EQUATE `PERF_100NSEC_TIMER_INV = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_RATE OR %PERF_TIMER_100NS OR %PERF_DELTA_COUNTER OR %PERF_INVERSE_COUNTER OR %PERF_DISPLAY_PERCENT
'// 64-bit Timer. Divide delta by delta time. Display suffix: "%"
'// Timer for multiple instances, so result can exceed 100%.
%EQUATE `PERF_COUNTER_MULTI_TIMER = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_RATE OR %PERF_DELTA_COUNTER OR %PERF_TIMER_TICK OR %PERF_MULTI_COUNTER OR %PERF_DISPLAY_PERCENT
'// 64-bit Timer inverse (e.g., idle is measured, but display busy %)
'// Display 100 * _MULTI_BASE - delta divided by delta time.
'// Display suffix: "%" Timer for multiple instances, so result
'// can exceed 100%. Followed by a counter of type _MULTI_BASE.
%EQUATE `PERF_COUNTER_MULTI_TIMER_INV = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_RATE OR %PERF_DELTA_COUNTER OR %PERF_MULTI_COUNTER OR %PERF_TIMER_TICK OR %PERF_INVERSE_COUNTER OR %PERF_DISPLAY_PERCENT
'// Number of instances to which the preceding _MULTI_..._INV counter
'// applies. Used as a factor to get the percentage.
%EQUATE `PERF_COUNTER_MULTI_BASE = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_BASE OR %PERF_MULTI_COUNTER OR %PERF_DISPLAY_NOSHOW
'// 64-bit Timer in 100 nsec units. Display delta divided by delta time.
'// Display suffix: "%" Timer for multiple instances, so result can exceed 100%.
%EQUATE `PERF_100NSEC_MULTI_TIMER = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_DELTA_COUNTER OR %PERF_COUNTER_RATE OR %PERF_TIMER_100NS OR %PERF_MULTI_COUNTER OR %PERF_DISPLAY_PERCENT
'// 64-bit Timer inverse (e.g., idle is measured, but display busy %)
'// Display 100 * _MULTI_BASE - delta divided by delta time.
'// Display suffix: "%" Timer for multiple instances, so result
'// can exceed 100%. Followed by a counter of type _MULTI_BASE.
%EQUATE `PERF_100NSEC_MULTI_TIMER_INV = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_DELTA_COUNTER OR %PERF_COUNTER_RATE OR %PERF_TIMER_100NS OR %PERF_MULTI_COUNTER OR %PERF_INVERSE_COUNTER OR %PERF_DISPLAY_PERCENT
'// Indicates the data is a fraction of the following counter which
'// should not be time averaged on display (such as free space over
'// total space.) Display as is. Display the quotient as "%".
%EQUATE `PERF_RAW_FRACTION = %PERF_SIZE_DWORD OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_FRACTION OR %PERF_DISPLAY_PERCENT
%EQUATE `PERF_LARGE_RAW_FRACTION = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_FRACTION OR %PERF_DISPLAY_PERCENT
'// Indicates the data is a base for the preceding counter which should
'// not be time averaged on display (such as free space over total space.)
%EQUATE `PERF_RAW_BASE = %PERF_SIZE_DWORD OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_BASE OR %PERF_DISPLAY_NOSHOW OR &H00000003 ' // for compatibility with pre-beta versions
%EQUATE `PERF_LARGE_RAW_BASE = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_BASE OR %PERF_DISPLAY_NOSHOW
'// The data collected in this counter is actually the start time of the
'// item being measured. For display, this data is subtracted from the
'// sample time to yield the elapsed time as the difference between the two.
'// In the definition below, the PerfTime field of the Object contains
'// the sample time as indicated by the PERF_OBJECT_TIMER bit and the
'// difference is scaled by the PerfFreq of the Object to convert the time
'// units into seconds.
%EQUATE `PERF_ELAPSED_TIME = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_ELAPSED OR %PERF_OBJECT_TIMER OR %PERF_DISPLAY_SECONDS
'//
'// The following counter type can be used with the preceding types to
'// define a range of values to be displayed in a histogram.
'//
%EQUATE `PERF_COUNTER_HISTOGRAM_TYPE = &H80000000 ' // Counter begins or ends a histogram
'//
'// This counter is used to display the difference from one sample
'// to the next. The counter value is a constantly increasing number
'// and the value displayed is the difference between the current
'// value and the previous value. Negative numbers are not allowed
'// which shouldn't be a problem as long as the counter value is
'// increasing or unchanged.
'//
%EQUATE `PERF_COUNTER_DELTA = %PERF_SIZE_DWORD OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_VALUE OR %PERF_DELTA_COUNTER OR %PERF_DISPLAY_NO_SUFFIX
%EQUATE `PERF_COUNTER_LARGE_DELTA = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_VALUE OR %PERF_DELTA_COUNTER OR %PERF_DISPLAY_NO_SUFFIX
'//
'// The precision counters are timers that consist of two counter values:
'// 1) the count of elapsed time of the event being monitored
'// 2) the "clock" time in the same units
'//
'// the precition timers are used where the standard system timers are not
'// precise enough for accurate readings. It's assumed that the service
'// providing the data is also providing a timestamp at the same time which
'// will eliminate any error that may occur since some small and variable
'// time elapses between the time the system timestamp is captured and when
'// the data is collected from the performance DLL. Only in extreme cases
'// has this been observed to be problematic.
'//
'// when using this type of timer, the definition of the
'// PERF_PRECISION_TIMESTAMP counter must immediately follow the
'// definition of the PERF_PRECISION_*_TIMER in the Object header
'//
'// The timer used has the same frequency as the System Performance Timer
%EQUATE `PERF_PRECISION_SYSTEM_TIMER = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_PRECISION OR %PERF_TIMER_TICK OR %PERF_DELTA_COUNTER OR %PERF_DISPLAY_PERCENT
'//
'// The timer used has the same frequency as the 100 NanoSecond Timer
%EQUATE `PERF_PRECISION_100NS_TIMER = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_PRECISION OR %PERF_TIMER_100NS OR %PERF_DELTA_COUNTER OR %PERF_DISPLAY_PERCENT
'//
'// The timer used is of the frequency specified in the Object header's
'// PerfFreq field (PerfTime is ignored)
%EQUATE `PERF_PRECISION_OBJECT_TIMER = %PERF_SIZE_LARGE OR %PERF_TYPE_COUNTER OR %PERF_COUNTER_PRECISION OR %PERF_OBJECT_TIMER OR %PERF_DELTA_COUNTER OR %PERF_DISPLAY_PERCENT
'//
'// This is the timestamp to use in the computation of the timer specified
'// in the previous description block
%EQUATE `PERF_PRECISION_TIMESTAMP = %PERF_LARGE_RAW_BASE
'//
'// The following are used to determine the level of detail associated
'// with the counter. The user will be setting the level of detail
'// that should be displayed at any given time.
'//
'//
%EQUATE `PERF_DETAIL_NOVICE = 100 ' // The uninformed can understand it
%EQUATE `PERF_DETAIL_ADVANCED = 200 ' // For the advanced user
%EQUATE `PERF_DETAIL_EXPERT = 300 ' // For the expert user
%EQUATE `PERF_DETAIL_WIZARD = 400 ' // For the system designer
'//
'//
'// There is one of the following for each of the
'// PERF_OBJECT_TYPE.NumCounters. The Unicode names in this structure MUST
'// come from a message file.
'//
'//
' // Size = 40 bytes
TYPE PERF_COUNTER_DEFINITION DWORD
 ByteLength AS DWORD
 CounterNameTitleIndex AS DWORD
'#ifdef _WIN64
' DWORD CounterNameTitle;
'#else
 CounterNameTitle AS DWORD ' pointer to Unicode string
'#endif
 CounterHelpTitleIndex AS DWORD
'#ifdef _WIN64
' DWORD CounterHelpTitle;
'#else
 CounterHelpTitle AS DWORD ' pointer to Unicode string
'#endif
 DefaultScale AS LONG
 DetailLevel AS DWORD
 CounterType AS DWORD
 CounterSize AS DWORD
 CounterOffset AS DWORD
END TYPE
'//
'//
'// If (PERF_DATA_BLOCK.NumInstances >= 0) then there will be
'// PERF_DATA_BLOCK.NumInstances of a (PERF_INSTANCE_DEFINITION
'// followed by a PERF_COUNTER_BLOCK followed by the counter data fields)
'// for each instance.
'//
'// If (PERF_DATA_BLOCK.NumInstances < 0) then the counter definition
'// strucutre above will be followed by only a PERF_COUNTER_BLOCK and the
'// counter data for that COUNTER.
'//
%EQUATE `PERF_NO_UNIQUE_ID = -1
' // Size = 24 bytes
TYPE PERF_INSTANCE_DEFINITION DWORD
 ByteLength AS DWORD
 ParentObjectTitleIndex AS DWORD
 ParentObjectInstance AS DWORD
 UniqueID AS LONG
 NameOffset AS DWORD
 NameLength AS DWORD
END TYPE
'//
'// If .ParentObjectName is 0, there
'// is no parent-child hierarchy for this object type. Otherwise,
'// the .ParentObjectInstance is an index, starting at 0, into the
'// instances reported for the parent object type. It is only
'// meaningful if .ParentObjectName is not 0. The purpose of all this
'// is to permit reporting/summation of object instances like threads
'// within processes, and logical drives within physical drives.
'//
'//
'// The PERF_INSTANCE_DEFINITION will be followed by a PERF_COUNTER_BLOCK.
'//
'typedef struct _PERF_COUNTER_BLOCK {
' DWORD ByteLength; // Length in bytes of this structure,
' // including the following counters
'} PERF_COUNTER_BLOCK, *PPERF_COUNTER_BLOCK;
' // Size = 4 bytes
TYPE PERF_COUNTER_BLOCK DWORD
 ByteLength AS DWORD
END TYPE
'//
'// The PERF_COUNTER_BLOCK is followed by PERF_OBJECT_TYPE.NumCounters
'// number of counters.
'//
'//
'// Support for New Extensible API starting with NT 5.0
'//
%EQUATE `PERF_QUERY_OBJECTS = &H80000000& ' ((LONG)0x80000000)
%EQUATE `PERF_QUERY_GLOBAL = &H80000001& ' ((LONG)0x80000001)
%EQUATE `PERF_QUERY_COSTLY = &H80000002& ' ((LONG)0x80000002)
'//
'// function typedefs for extensible counter function prototypes
'//
'typedef DWORD (APIENTRY PM_OPEN_PROC) (LPWSTR);
'typedef DWORD (APIENTRY PM_COLLECT_PROC) (LPWSTR, LPVOID *, LPDWORD, LPDWORD);
'typedef DWORD (APIENTRY PM_CLOSE_PROC) (void);
'typedef DWORD (APIENTRY PM_QUERY_PROC) (LPDWORD, LPVOID *, LPDWORD, LPDWORD);
'#if (_WIN32_WINDOWS >= 0x0501 || _WIN32_WINNT >= 0x0501 || (defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINXP))
#IF %WINVER >= &H0501
%EQUATE `MAX_PERF_OBJECTS_IN_QUERY_FUNCTION = 64
'//
'// The following are the possible values for
'// HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\EventLogLevel
'// The default is WINPERF_LOG_NONE if the registry value is not defined.
'// This should be adopted by all perfdlls to avoid flooding the application
'// event log.
'//
%EQUATE `WINPERF_LOG_NONE = 0 ' // No event reported
%EQUATE `WINPERF_LOG_USER = 1 ' // Report only errors
%EQUATE `WINPERF_LOG_DEBUG = 2 ' // Report debug errors as well
%EQUATE `WINPERF_LOG_VERBOSE = 3 ' // Report everything
#ELSE
%EQUATE `MAX_PERF_OBJECTS_IN_QUERY_FUNCTION = 8
#ENDIF
'#include <poppack.h>
#ENDIF
