Public Type LARGE_INTEGER
    LowPart As Long
    HighPart As Long
End Type

Public Type SYSTEMTIME
   wYear As Integer
   wMonth As Integer
   wDayOfWeek As Integer
   wDay As Integer
   wHour As Integer
   wMinute As Integer
   wSecond As Integer
   wMilliseconds As Integer
End Type

Type PERF_DATA_BLOCK
    Signature(7) As Byte '"PERF" in unicode
    LittleEndian As Long
    Version As Long
    Revision As Long
    TotalByteLength As Long
    HeaderLength As Long
    NumObjectTypes As Long
    DefaultObject As Long
    SysTime As SYSTEMTIME
    PerfTime As LARGE_INTEGER
    PerfFreq As LARGE_INTEGER
    PerTime100nSec As LARGE_INTEGER
    SystemNameLength As Long
    SystemNameOffset As Long
End Type

Type PERF_OBJECT_TYPE
    TotalByteLength As Long
    DefinitionLength As Long
    HeaderLength As Long
    ObjectNameTitleIndex As Long
    lpwObjectNameTitle As Long 'String
    ObjectHelpTitleIndex As Long
    lpwObjectHelpTitle As Long 'String
    DetailLevel As Long
    NumCounters As Long
    DefaultCounter As Long
    NumInstances As Long
    CodePage As Long
    PerfTime As LARGE_INTEGER
    PerfFreq As LARGE_INTEGER
End Type

Type PERF_COUNTER_DEFINITION
    ByteLength As Long
    CounterNameTitleIndex As Long
    lpwCounterNameTitle As Long 'String
    CounterHelpTitleIndex As Long
    lpwCounterHelpTitle As Long 'String
    DefaultScale As Long
    DetailLevel As Long
    CounterType As Long
    CounterSize As Long
    CounterOffset As Long
End Type

Type PERF_INSTANCE_DEFINITION
    ByteLength As Long
    ParentObjectTitleIndex As Long
    ParentObjectInstance As Long
    UniqueID As Long
    NameOffset As Long
    NameLength As Long
End Type

Type PERF_COUNTER_BLOCK
    ByteLength As Long
End Type

Public Const PERF_NO_INSTANCES = -1  '  no instances

' 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
Public Const PERF_SIZE_DWORD = &H0
Public Const PERF_SIZE_LARGE = &H100
Public Const PERF_SIZE_ZERO = &H200            '  for Zero Length fields
Public Const PERF_SIZE_VARIABLE_LEN = &H300    '  length is in CounterLength field of Counter Definition struct

' select one of the following values to indicate the counter field usage
Public Const PERF_TYPE_NUMBER = &H0            '  a number (not a counter)
Public Const PERF_TYPE_COUNTER = &H400         '  an increasing numeric value
Public Const PERF_TYPE_TEXT = &H800            '  a text field
Public Const PERF_TYPE_ZERO = &HC00            '  displays a zero

' If the PERF_TYPE_NUMBER field was selected, then select one of the
' following to describe the Number
Public Const PERF_NUMBER_HEX = &H0             '  display as HEX value
Public Const PERF_NUMBER_DECIMAL = &H10000     '  display as a decimal integer
Public Const PERF_NUMBER_DEC_1000 = &H20000    '  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
Public Const PERF_COUNTER_VALUE = &H0          '  display counter value
Public Const PERF_COUNTER_RATE = &H10000       '  divide ctr / delta time
Public Const PERF_COUNTER_FRACTION = &H20000   '  divide ctr / base
Public Const PERF_COUNTER_BASE = &H30000       '  base value used in fractions
Public Const PERF_COUNTER_ELAPSED = &H40000    '  subtract counter from current time
Public Const PERF_COUNTER_QUEUELEN = &H50000   '  Use Queuelen processing func.
Public Const PERF_COUNTER_HISTOGRAM = &H60000  '  Counter begins or ends a histogram

' If the PERF_TYPE_TEXT value was selected, then select one of the
' following to indicate the type of TEXT data.
Public Const PERF_TEXT_UNICODE = &H0           '  type of text in text field
Public Const PERF_TEXT_ASCII = &H10000         '  ASCII using the CodePage field

' Timer SubTypes
Public Const PERF_TIMER_TICK = &H0             '  use system perf. freq for base
Public Const PERF_TIMER_100NS = &H100000       '  use 100 NS timer time base units
Public Const PERF_OBJECT_TIMER = &H200000      '  use the object timer freq

' Any types that have calculations performed can use one or more of
' the following calculation modification flags listed here
Public Const PERF_DELTA_COUNTER = &H400000     '  compute difference first
Public Const PERF_DELTA_BASE = &H800000        '  compute base diff as well
Public Const PERF_INVERSE_COUNTER = &H1000000  '  show as 1.00-value (assumes:
Public Const PERF_MULTI_COUNTER = &H2000000    '  sum of multiple instances

' Select one of the following values to indicate the display suffix (if any)
Public Const PERF_DISPLAY_NO_SUFFIX = &H0      '  no suffix
Public Const PERF_DISPLAY_PER_SEC = &H10000000 '  "/sec"
Public Const PERF_DISPLAY_PERCENT = &H20000000 '  "%"
Public Const PERF_DISPLAY_SECONDS = &H30000000 '  "secs"
Public Const PERF_DISPLAY_NOSHOW = &H40000000  '  value is not displayed

' Predefined counter types

' 32-bit Counter.  Divide delta by delta time.  Display suffix: "/sec"
Public Const 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: "%"
Public Const 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.
Public Const 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)

' 64-bit Counter.  Divide delta by delta time. Display Suffix: "/sec"
Public Const 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.
Public Const 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.
Public Const PERF_COUNTER_RAWCOUNT = (PERF_SIZE_DWORD Or PERF_TYPE_NUMBER Or PERF_NUMBER_DECIMAL 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: "%"
Public Const 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.
Public Const 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.
Public Const PERF_COUNTER_NODATA = (PERF_SIZE_ZERO Or PERF_DISPLAY_NOSHOW)

' 64-bit Timer inverse (e.g., idle is measured, but display busy  As Integer)
' Display 100 - delta divided by delta time.  Display suffix: "%"
Public Const 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.
Public Const PERF_SAMPLE_BASE = (PERF_SIZE_DWORD Or PERF_TYPE_COUNTER Or PERF_COUNTER_BASE Or PERF_DISPLAY_NOSHOW Or &H1)         '  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"
Public Const 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.
Public Const PERF_AVERAGE_BASE = (PERF_SIZE_DWORD Or PERF_TYPE_COUNTER Or PERF_COUNTER_BASE Or PERF_DISPLAY_NOSHOW Or &H2)         '  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.
Public Const PERF_AVERAGE_BULK = (PERF_SIZE_LARGE Or PERF_TYPE_COUNTER Or PERF_COUNTER_FRACTION Or PERF_DISPLAY_NOSHOW)

' 64-bit Timer in 100 nsec units. Display delta divided by
' delta time.  Display suffix: "%"
Public Const 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  As Integer)
' Display 100 - delta divided by delta time.  Display suffix: "%"
Public Const 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%.
Public Const 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  As Integer)
' 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.
Public Const 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.
Public Const 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%.
Public Const 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  As Integer)
' 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.
Public Const 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 "%".
Public Const PERF_RAW_FRACTION = (PERF_SIZE_DWORD 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.)
Public Const PERF_RAW_BASE = (PERF_SIZE_DWORD Or PERF_TYPE_COUNTER Or PERF_COUNTER_BASE Or PERF_DISPLAY_NOSHOW Or &H3)         '  for compatibility with pre-beta versions

' 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.
Public Const 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.
Public Const PERF_COUNTER_HISTOGRAM_TYPE = &H80000000  ' Counter begins or ends a histogram

' 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.
Public Const PERF_DETAIL_NOVICE = 100   '  The uninformed can understand it
Public Const PERF_DETAIL_ADVANCED = 200 '  For the advanced user
Public Const PERF_DETAIL_EXPERT = 300   '  For the expert user
Public Const PERF_DETAIL_WIZARD = 400   '  For the system designer

Public Const PerfLibKey = "Software\Microsoft\Windows NT\CurrentVersion\Perflib\009"