Vanara/PInvoke/Pdh/Pdh.cs

5272 lines
263 KiB
C#
Raw Normal View History

using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Vanara.Extensions;
using Vanara.InteropServices;
using static Vanara.PInvoke.Kernel32;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
namespace Vanara.PInvoke
{
/// <summary>Pdh Performance Counter functions and structures.</summary>
public static partial class Pdh
{
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
public const uint PDH_CVERSION_WIN40 = 0x0400;
public const uint PDH_CVERSION_WIN50 = 0x0500;
public const int PDH_MAX_COUNTER_PATH = 2048;
// v1.1 revision of PDH -- basic log functions v1.2 of the PDH -- adds variable instance counters v1.3 of the PDH -- adds log service
// control & stubs for NT5/PDH v2 fn's v2.0 of the PDH -- is the NT v 5.0 B2 version
public const uint PDH_VERSION = PDH_CVERSION_WIN50 + 0x0003;
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
/// <summary>
/// Applications implement the <c>CounterPathCallBack</c> function to process the counter path strings returned by the <c>Browse</c>
/// dialog box.
/// </summary>
/// <param name="Arg1"/>
/// <returns>
/// <para>Return ERROR_SUCCESS if the function succeeds.</para>
/// <para>If the function fails due to a transient error, you can return PDH_RETRY and PDH will call your callback immediately.</para>
/// <para>Otherwise, return an appropriate error code. The error code is passed back to the caller of PdhBrowseCounters.</para>
/// </returns>
/// <remarks>The following members of the PDH_BROWSE_DLG_CONFIG structure are used to communicate with the callback function:</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nc-pdh-counterpathcallback CounterPathCallBack Counterpathcallback;
// PDH_STATUS Counterpathcallback( DWORD_PTR Arg1 ) {...}
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
[PInvokeData("pdh.h", MSDNShortId = "b7a2112e-9f50-4a36-b022-f9609b2827bc")]
public delegate Win32Error CounterPathCallBack(IntPtr Arg1);
/// <summary>Flags used by PDH_BROWSE_DLG_CONFIG.</summary>
[PInvokeData("pdh.h", MSDNShortId = "8e045e0b-c157-4527-902c-6096c7922642")]
[Flags]
public enum BrowseFlag
{
/// <summary>
/// If this flag is <c>TRUE</c>, the dialog box includes an index number for duplicate instance names. For example, if there are
/// two cmd instances, the instance list will contain cmd and cmd#1. If this flag is <c>FALSE</c>, duplicate instance names will
/// not contain an index number.
/// </summary>
bIncludeInstanceIndex = 1 << 0,
/// <summary>
/// If this flag is <c>TRUE</c>, the dialog returns only one counter. If this flag is <c>FALSE</c>, the dialog can return
/// multiple selections, and wildcard selections are permitted. Selected counters are returned as a MULTI_SZ string.
/// </summary>
bSingleCounterPerAdd = 1 << 1,
/// <summary>
/// If this flag is <c>TRUE</c>, the dialog box uses an OK and Cancel button. The dialog returns when the user clicks either
/// button. If this flag is <c>FALSE</c>, the dialog box uses an Add and Close button. The dialog box closes when the user clicks
/// the Close button. The Add button can be clicked multiple times. The Add button overwrites the previously selected items with
/// the currently selected items.
/// </summary>
bSingleCounterPerDialog = 1 << 2,
/// <summary>
/// If this flag is <c>TRUE</c>, the dialog box lets the user select counters only from the local computer (the path will not
/// contain a computer name). If this flag is <c>FALSE</c>, the user can specify a computer from which to select counters. The
/// computer name will prefix the counter path unless the user selects <c>Use local computer counters</c>.
/// </summary>
bLocalCountersOnly = 1 << 3,
/// <summary>
/// <para>
/// If this flag is <c>TRUE</c> and the user selects <c>All instances</c>, the counter path will include the wildcard character
/// for the instance field.
/// </para>
/// <para>
/// If this flag is <c>FALSE</c>, and the user selects <c>All instances</c>, all the instances currently found for that object
/// will be returned in a MULTI_SZ string.
/// </para>
/// </summary>
bWildCardInstances = 1 << 4,
/// <summary>
/// <para>
/// If this flag is <c>TRUE</c>, this removes <c>Detail level</c> 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 <c>dwDefaultDetailLevel</c> member.
/// </para>
/// <para>
/// If this flag is <c>FALSE</c>, this displays <c>Detail level</c> in the dialog box, allowing the user to change the detail
/// level of the counters displayed.
/// </para>
/// <para>
/// 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.
/// </para>
/// </summary>
bHideDetailBox = 1 << 5,
/// <summary>
/// <para>
/// If this flag is <c>TRUE</c>, the dialog highlights the counter and object specified in <c>szReturnPathBuffer</c> when the
/// dialog box is first displayed, instead of using the default counter and object specified by the computer.
/// </para>
/// <para>
/// If this flag is <c>FALSE</c>, this selects the initial counter and object using the default counter and object information
/// returned by the computer.
/// </para>
/// </summary>
bInitializePath = 1 << 6,
/// <summary>
/// <para>If this flag is <c>TRUE</c>, the user cannot select a computer from <c>Select counters from computer</c>.</para>
/// <para>
/// If this flag is <c>FALSE</c>, the user can select a computer from <c>Select counters from computer</c>. This is the default
/// value. The list contains the local computer only unless you call the PdhConnectMachine to connect to other computers first.
/// </para>
/// </summary>
bDisableMachineSelection = 1 << 7,
/// <summary>
/// <para>
/// If this flag is <c>TRUE</c>, the counters list will also contain costly data—that is, data that requires a relatively large
/// amount of processor time or memory overhead to collect.
/// </para>
/// <para>If this flag is <c>FALSE</c>, the list will not contain costly counters. This is the default value.</para>
/// </summary>
bIncludeCostlyObjects = 1 << 8,
/// <summary>
/// If this flag is <c>TRUE</c>, the dialog lists only performance objects. When the user selects an object, the dialog returns a
/// counter path that includes the object and wildcard characters for the instance name and counter if the object is a multiple
/// instance object. For example, if the "Process" object is selected, the dialog returns the string "\Process(*)*". If the
/// object is a single instance object, the path contains a wildcard character for counter only. For example, "\System*". You can
/// then pass the path to PdhExpandWildCardPath to retrieve a list of actual paths for the object.
/// </summary>
bShowObjectBrowser = 1 << 9,
}
/// <summary>Performance counter type.</summary>
[Flags]
public enum CounterType : uint
{
/// <summary>A number (not a counter)</summary>
PERF_TYPE_NUMBER = 0x00000000,
/// <summary>32 bit field</summary>
PERF_SIZE_DWORD = 0x00000000,
/// <summary>64 bit field</summary>
PERF_SIZE_LARGE = 0x00000100,
/// <summary>for Zero Length fields</summary>
PERF_SIZE_ZERO = 0x00000200,
/// <summary>length is in CounterLength field</summary>
PERF_SIZE_VARIABLE_LEN = 0x00000300,
/// <summary>An increasing numeric value</summary>
PERF_TYPE_COUNTER = 0x00000400,
/// <summary>A text field</summary>
PERF_TYPE_TEXT = 0x00000800,
/// <summary>Displays a zero</summary>
PERF_TYPE_ZERO = 0x00000C00,
/// <summary>Display as HEX value</summary>
PERF_NUMBER_HEX = 0x00000000,
/// <summary>Display as a decimal integer</summary>
PERF_NUMBER_DECIMAL = 0x00010000,
/// <summary>Display as a decimal/1000</summary>
PERF_NUMBER_DEC_1000 = 0x00020000,
/// <summary>Display counter value</summary>
PERF_COUNTER_VALUE = 0x00000000,
/// <summary>Divide ctr / delta time</summary>
PERF_COUNTER_RATE = 0x00010000,
/// <summary>Divide ctr / base</summary>
PERF_COUNTER_FRACTION = 0x00020000,
/// <summary>Base value used in fractions</summary>
PERF_COUNTER_BASE = 0x00030000,
/// <summary>Subtract counter from current time</summary>
PERF_COUNTER_ELAPSED = 0x00040000,
/// <summary>Use Queuelen processing func.</summary>
PERF_COUNTER_QUEUELEN = 0x00050000,
/// <summary>Counter begins or ends a histogram</summary>
PERF_COUNTER_HISTOGRAM = 0x00060000,
/// <summary>Divide ctr / private clock</summary>
PERF_COUNTER_PRECISION = 0x00070000,
/// <summary>Type of text in text field</summary>
PERF_TEXT_UNICODE = 0x00000000,
/// <summary>ASCII using the CodePage field</summary>
PERF_TEXT_ASCII = 0x00010000,
/// <summary>Use system perf. freq for base</summary>
PERF_TIMER_TICK = 0x00000000,
/// <summary>Use 100 NS timer time base units</summary>
PERF_TIMER_100NS = 0x00100000,
/// <summary>Use the object timer freq</summary>
PERF_OBJECT_TIMER = 0x00200000,
/// <summary>Compute difference first</summary>
PERF_DELTA_COUNTER = 0x00400000,
/// <summary>Compute base diff as well</summary>
PERF_DELTA_BASE = 0x00800000,
/// <summary>Show as 1.00-value (assumes:</summary>
PERF_INVERSE_COUNTER = 0x01000000,
/// <summary>Sum of multiple instances</summary>
PERF_MULTI_COUNTER = 0x02000000,
/// <summary>No suffix</summary>
PERF_DISPLAY_NO_SUFFIX = 0x00000000,
/// <summary>"/sec"</summary>
PERF_DISPLAY_PER_SEC = 0x10000000,
/// <summary>"%"</summary>
PERF_DISPLAY_PERCENT = 0x20000000,
/// <summary>"secs"</summary>
PERF_DISPLAY_SECONDS = 0x30000000,
/// <summary>Value is not displayed</summary>
PERF_DISPLAY_NOSHOW = 0x40000000,
/// <summary>32-bit Counter. Divide delta by delta time. Display suffix: "/sec"</summary>
PERF_COUNTER_COUNTER = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC,
/// <summary>64-bit Timer. Divide delta by delta time. Display suffix: "%"</summary>
PERF_COUNTER_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT,
/// <summary>Queue Length Space-Time Product. Divide delta by delta time. No Display Suffix.</summary>
PERF_COUNTER_QUEUELEN_TYPE = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX,
/// <summary>Queue Length Space-Time Product. Divide delta by delta time. No Display Suffix.</summary>
PERF_COUNTER_LARGE_QUEUELEN_TYPE = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX,
/// <summary>Queue Length Space-Time Product using 100 Ns timebase. Divide delta by delta time. No Display Suffix.</summary>
PERF_COUNTER_100NS_QUEUELEN_TYPE = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX,
/// <summary>Queue Length Space-Time Product using Object specific timebase. Divide delta by delta time. No Display Suffix.</summary>
PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN | PERF_OBJECT_TIMER | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX,
/// <summary>64-bit Counter. Divide delta by delta time. Display Suffix: "/sec"</summary>
PERF_COUNTER_BULK_COUNT = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC,
/// <summary>Indicates the counter is not a counter but rather Unicode text Display as text.</summary>
PERF_COUNTER_TEXT = PERF_SIZE_VARIABLE_LEN | PERF_TYPE_TEXT | PERF_TEXT_UNICODE | PERF_DISPLAY_NO_SUFFIX,
/// <summary>
/// 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.
/// </summary>
PERF_COUNTER_RAWCOUNT = PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX,
/// <summary>Same as PERF_COUNTER_RAWCOUNT except its size is a large integer</summary>
PERF_COUNTER_LARGE_RAWCOUNT = PERF_SIZE_LARGE | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX,
/// <summary>
/// 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.
/// </summary>
PERF_COUNTER_RAWCOUNT_HEX = PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_HEX | PERF_DISPLAY_NO_SUFFIX,
/// <summary>Same as PERF_COUNTER_RAWCOUNT_HEX except its size is a large integer</summary>
PERF_COUNTER_LARGE_RAWCOUNT_HEX = PERF_SIZE_LARGE | PERF_TYPE_NUMBER | PERF_NUMBER_HEX | PERF_DISPLAY_NO_SUFFIX,
/// <summary>
/// A count which is either 1 or 0 on each sampling interrupt (% busy) Divide delta by delta base. Display Suffix: "%"
/// </summary>
PERF_SAMPLE_FRACTION = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DELTA_COUNTER | PERF_DELTA_BASE | PERF_DISPLAY_PERCENT,
/// <summary>A count which is sampled on each sampling interrupt (queue length) Divide delta by delta time. No Display Suffix.</summary>
PERF_SAMPLE_COUNTER = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX,
/// <summary>A label: no data is associated with this counter (it has 0 length) Do not display.</summary>
PERF_COUNTER_NODATA = PERF_SIZE_ZERO | PERF_DISPLAY_NOSHOW,
/// <summary>
/// 64-bit Timer inverse (e.g., idle is measured, but display busy %) Display 100 - delta divided by delta time. Display suffix: "%"
/// </summary>
PERF_COUNTER_TIMER_INV = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT,
/// <summary>
/// The divisor for a sample, used with the previous counter to form a sampled %. You must check for &gt;0 before dividing by
/// this! This counter will directly follow the numerator counter. It should not be displayed to the user.
/// </summary>
PERF_SAMPLE_BASE = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW | 0x00000001,
/// <summary>
/// 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 operations. Display Suffix: "sec"
/// </summary>
PERF_AVERAGE_TIMER = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DISPLAY_SECONDS,
/// <summary>
/// Used as the denominator in the computation of time or count averages. Must directly follow the numerator counter. Not
/// displayed to the user.
/// </summary>
PERF_AVERAGE_BASE = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW | 0x00000002,
/// <summary>
/// A bulk count which, when divided (typically) by the number of operations, gives (typically) the number of bytes per
/// operation. No Display Suffix.
/// </summary>
PERF_AVERAGE_BULK = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DISPLAY_NOSHOW,
/// <summary>
/// 64-bit Timer in object specific units. Display delta divided by delta time as returned in the object type header structure.
/// Display suffix: "%"
/// </summary>
PERF_OBJ_TIME_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_OBJECT_TIMER | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT,
/// <summary>64-bit Timer in 100 nsec units. Display delta divided by delta time. Display suffix: "%"</summary>
PERF_100NSEC_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT,
/// <summary>
/// 64-bit Timer inverse (e.g., idle is measured, but display busy %) Display 100 - delta divided by delta time. Display suffix: "%"
/// </summary>
PERF_100NSEC_TIMER_INV = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT,
/// <summary>
/// 64-bit Timer. Divide delta by delta time. Display suffix: "%" Timer for multiple instances, so result can exceed 100%.
/// </summary>
PERF_COUNTER_MULTI_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_TIMER_TICK | PERF_MULTI_COUNTER | PERF_DISPLAY_PERCENT,
/// <summary>
/// 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.
/// </summary>
PERF_COUNTER_MULTI_TIMER_INV = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_MULTI_COUNTER | PERF_TIMER_TICK | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT,
/// <summary>Number of instances to which the preceding _MULTI_..._INV counter applies. Used as a factor to get the percentage.</summary>
PERF_COUNTER_MULTI_BASE = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_MULTI_COUNTER | PERF_DISPLAY_NOSHOW,
/// <summary>
/// 64-bit Timer in 100 nsec units. Display delta divided by delta time. Display suffix: "%" Timer for multiple instances, so
/// result can exceed 100%.
/// </summary>
PERF_100NSEC_MULTI_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_DELTA_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_MULTI_COUNTER | PERF_DISPLAY_PERCENT,
/// <summary>
/// 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.
/// </summary>
PERF_100NSEC_MULTI_TIMER_INV = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_DELTA_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_MULTI_COUNTER | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT,
/// <summary>
/// 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 "%".
/// </summary>
PERF_RAW_FRACTION = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DISPLAY_PERCENT,
/// <summary>
/// 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 "%".
/// </summary>
PERF_LARGE_RAW_FRACTION = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DISPLAY_PERCENT,
/// <summary>
/// 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.)
/// </summary>
PERF_RAW_BASE = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW | 0x00000003, // for compatibility with pre-beta version,
/// <summary>
/// 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.)
/// </summary>
PERF_LARGE_RAW_BASE = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW,
/// <summary>
/// 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.
/// </summary>
PERF_ELAPSED_TIME = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_ELAPSED | PERF_OBJECT_TIMER | PERF_DISPLAY_SECONDS,
/// <summary>
/// The following counter type can be used with the preceding types to define a range of values to be displayed in a histogram.
/// </summary>
PERF_COUNTER_HISTOGRAM_TYPE = 0x8000000,
/// <summary>
/// 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.
/// </summary>
PERF_COUNTER_DELTA = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_VALUE | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX,
/// <summary>
/// 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.
/// </summary>
PERF_COUNTER_LARGE_DELTA = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_VALUE | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX,
/// <summary>The timer used has the same frequency as the System Performance Timer</summary>
PERF_PRECISION_SYSTEM_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_PRECISION | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT,
/// <summary>The timer used has the same frequency as the 100 NanoSecond Timer</summary>
PERF_PRECISION_100NS_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_PRECISION | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT,
/// <summary>The timer used is of the frequency specified in the Object header's PerfFreq field (PerfTime is ignored)</summary>
PERF_PRECISION_OBJECT_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_PRECISION | PERF_OBJECT_TIMER | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT,
}
/// <summary>Determines the data type of the calculated value.</summary>
[PInvokeData("pdh.h", MSDNShortId = "fd50b1fd-29b7-49a8-bbcc-4d7f0cbd7079")]
public enum PDH_FMT
{
/// <summary/>
PDH_FMT_RAW = 0x00000010,
/// <summary>Return the calculated value as an ANSI string.</summary>
PDH_FMT_ANSI = 0x00000020,
/// <summary>Return the calculated value as a Unicode string.</summary>
PDH_FMT_UNICODE = 0x00000040,
/// <summary>Return the calculated value as a long integer.</summary>
PDH_FMT_LONG = 0x00000100,
/// <summary>Return the calculated value as a double-precision floating point real.</summary>
PDH_FMT_DOUBLE = 0x00000200,
/// <summary>Return the calculated value as a 64-bit integer.</summary>
PDH_FMT_LARGE = 0x00000400,
/// <summary>Do not apply the counter's scaling factor in the calculation.</summary>
PDH_FMT_NOSCALE = 0x00001000,
/// <summary>Multiply the final value by 1,000.</summary>
PDH_FMT_1000 = 0x00002000,
/// <summary/>
PDH_FMT_NODATA = 0x00004000,
/// <summary>
/// Counter values greater than 100 (for example, counter values measuring the processor load on multiprocessor computers) will
/// not be reset to 100. The default behavior is that counter values are capped at a value of 100.
/// </summary>
PDH_FMT_NOCAP100 = 0x00008000,
}
/// <summary>Type of record for <c>PDH_RAW_LOG_RECORD</c>.</summary>
[PInvokeData("pdh.h", MSDNShortId = "ae96515f-ea3f-4578-a249-fb8f41cdfa69")]
public enum PDH_LOG_TYPE
{
/// <summary>Undefined record format.</summary>
PDH_LOG_TYPE_UNDEFINED = 0,
/// <summary>A comma-separated-value format record</summary>
PDH_LOG_TYPE_CSV = 1,
/// <summary>A tab-separated-value format record</summary>
PDH_LOG_TYPE_TSV = 2,
/// <summary/>
PDH_LOG_TYPE_TRACE_KERNEL = 4,
/// <summary/>
PDH_LOG_TYPE_TRACE_GENERIC = 5,
/// <summary>A Perfmon format record</summary>
PDH_LOG_TYPE_PERFMON = 6,
/// <summary>A SQL format record</summary>
PDH_LOG_TYPE_SQL = 7,
/// <summary>A binary trace format record</summary>
PDH_LOG_TYPE_BINARY = 8,
}
/// <summary>Format of the input and output counter values.</summary>
[PInvokeData("pdh.h", MSDNShortId = "f2dc5f77-9f9e-4290-95fa-ce2f1e81fc69")]
public enum PDH_PATH
{
/// <summary>Returns the path in the PDH format, for example, \\computer\object(parent/instance#index)\counter.</summary>
PDH_PATH_DEFAULT = 0x00000000,
/// <summary>Converts a PDH path to the WMI class and property name format.</summary>
PDH_PATH_WBEM_RESULT = 0x00000001,
/// <summary>Converts the WMI class and property name to a PDH path.</summary>
PDH_PATH_WBEM_INPUT = 0x00000002
}
/// <summary>Flags that indicate which wildcard characters not to expand.</summary>
[PInvokeData("pdh.h", MSDNShortId = "415da310-de56-4d58-8959-231426867526")]
[Flags]
public enum PdhExpandFlags
{
/// <summary>Do not expand the counter name if the path contains a wildcard character for counter name.</summary>
PDH_NOEXPANDCOUNTERS = 1,
/// <summary>
/// Do not expand the instance name if the path contains a wildcard character for parent instance, instance name, or instance index.
/// </summary>
PDH_NOEXPANDINSTANCES = 2,
/// <summary/>
PDH_REFRESHCOUNTERS = 4
}
/// <summary>Type of access to use to open the log file.</summary>
[PInvokeData("pdh.h", MSDNShortId = "a8457959-af3a-497f-91ca-0876cbb552cc")]
[Flags]
public enum PdhLogAccess : uint
{
/// <summary>Open the log file for reading.</summary>
PDH_LOG_READ_ACCESS = 0x00010000,
/// <summary>Open a new log file for writing.</summary>
PDH_LOG_WRITE_ACCESS = 0x00020000,
/// <summary>Open an existing log file for writing.</summary>
PDH_LOG_UPDATE_ACCESS = 0x00040000,
/// <summary>Creates a new log file with the specified name.</summary>
PDH_LOG_CREATE_NEW = 0x00000001,
/// <summary>
/// Creates a new log file with the specified name. If the log file already exists, the function removes the existing log file
/// before creating the new file.
/// </summary>
PDH_LOG_CREATE_ALWAYS = 0x00000002,
/// <summary>
/// Opens an existing log file with the specified name or creates a new log file with the specified name.Opens an existing log
/// file with the specified name or creates a new log file with the specified name.
/// </summary>
PDH_LOG_OPEN_ALWAYS = 0x00000003,
/// <summary>
/// Opens an existing log file with the specified name. If a log file with the specified name does not exist, this is equal to PDH_LOG_CREATE_NEW.
/// </summary>
PDH_LOG_OPEN_EXISTING = 0x00000004,
/// <summary>
/// Used with PDH_LOG_TYPE_TSV to write the user caption or log file description indicated by the szUserString parameter of
/// PdhUpdateLog or PdhOpenLog. The user caption or log file description is written as the last column in the first line of the
/// text log.
/// </summary>
PDH_LOG_OPT_USER_STRING = 0x01000000,
/// <summary>
/// Creates a circular log file with the specified name. When the file reaches the value of the dwMaxSize parameter, data wraps
/// to the beginning of the log file. You can specify this flag only if the lpdwLogType parameter is PDH_LOG_TYPE_BINARY.
/// </summary>
PDH_LOG_OPT_CIRCULAR = 0x02000000,
/// <summary/>
PDH_LOG_OPT_MAX_IS_BYTES = 0x04000000,
/// <summary/>
PDH_LOG_OPT_APPEND = 0x08000000,
}
/// <summary>Dialog boxes that will be displayed to prompt for the data source.</summary>
[PInvokeData("pdh.h", MSDNShortId = "211d4504-e1f9-48a0-8ddd-613f2f183c59")]
public enum PdhSelectDataSourceFlags
{
/// <summary>
/// Display the data source selection dialog box. The dialog box lets the user select performance data 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.
/// </summary>
Default,
/// <summary>
/// Display the file browser only. Set this flag when you want to prompt for the name and location of a log file only.
/// </summary>
PDH_FLAGS_FILE_BROWSER_ONLY
}
/// <summary>
/// Default detail level to show in the Detail level list if bHideDetailBox is FALSE. If bHideDetailBox is TRUE, the dialog uses this
/// value to filter the displayed performance counters and objects.
/// </summary>
[PInvokeData("winperf.h")]
public enum PERF_DETAIL
{
/// <summary>A novice user can understand the counter data.</summary>
PERF_DETAIL_NOVICE = 100,
/// <summary>The counter data is provided for advanced users.</summary>
PERF_DETAIL_ADVANCED = 200,
/// <summary>The counter data is provided for expert users.</summary>
PERF_DETAIL_EXPERT = 300,
/// <summary>The counter data is provided for system designers.</summary>
PERF_DETAIL_WIZARD = 400
}
/// <summary>Adds the specified counter to the query.</summary>
/// <param name="hQuery">
/// Handle to the query to which you want to add the counter. This handle is returned by the PdhOpenQuery function.
/// </param>
/// <param name="szFullCounterPath">
/// Null-terminated string that contains the counter path. For details on the format of a counter path, see Specifying a Counter
/// Path. The maximum length of a counter path is PDH_MAX_COUNTER_PATH.
/// </param>
/// <param name="dwUserData">
/// User-defined value. This value becomes part of the counter information. To retrieve this value later, call the PdhGetCounterInfo
/// function and access the <c>dwUserData</c> member of the PDH_COUNTER_INFO structure.
/// </param>
/// <param name="phCounter">
/// Handle to the counter that was added to the query. You may need to reference this handle in subsequent calls.
/// </param>
/// <returns>
/// <para>Return ERROR_SUCCESS if the function succeeds.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_CSTATUS_BAD_COUNTERNAME</term>
/// <term>The counter path could not be parsed or interpreted.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_COUNTER</term>
/// <term>Unable to find the specified counter on the computer or in the log file.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_COUNTERNAME</term>
/// <term>The counter path is empty.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_MACHINE</term>
/// <term>The path did not contain a computer name, and the function was unable to retrieve the local computer name.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_OBJECT</term>
/// <term>Unable to find the specified object on the computer or in the log file.</term>
/// </item>
/// <item>
/// <term>PDH_FUNCTION_NOT_FOUND</term>
/// <term>Unable to determine the calculation function to use for this counter.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>One or more arguments are not valid.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The query handle is not valid.</term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>Unable to allocate memory required to complete the function.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If the counter path contains a wildcard character, all counter names matching the wildcard character are added to the query.
/// </para>
/// <para>
/// If a counter instance is specified that does not yet exist, <c>PdhAddCounter</c> does not report an error condition. Instead, it
/// returns ERROR_SUCCESS. The reason for this behavior is that it is not known whether a nonexistent counter instance has been
/// specified or whether one will exist but has not yet been created.
/// </para>
/// <para>To remove the counter from the query, use the PdhRemoveCounter function.</para>
/// <para>Examples</para>
/// <para>For an example, see Browsing Performance Counters or Reading Performance Data from a Log File.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhaddcountera PDH_FUNCTION PdhAddCounterA( PDH_HQUERY hQuery,
// LPCSTR szFullCounterPath, DWORD_PTR dwUserData, PDH_HCOUNTER *phCounter );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "b8b9a332-ce28-46d4-92e2-91f9f6c24da5")]
public static extern Win32Error PdhAddCounter(PDH_HQUERY hQuery, string szFullCounterPath, IntPtr dwUserData, out SafePDH_HCOUNTER phCounter);
/// <summary>Adds the specified language-neutral counter to the query.</summary>
/// <param name="hQuery">
/// Handle to the query to which you want to add the counter. This handle is returned by the PdhOpenQuery function.
/// </param>
/// <param name="szFullCounterPath">
/// Null-terminated string that contains the counter path. For details on the format of a counter path, see Specifying a Counter
/// Path. The maximum length of a counter path is PDH_MAX_COUNTER_PATH.
/// </param>
/// <param name="dwUserData">
/// User-defined value. This value becomes part of the counter information. To retrieve this value later, call the PdhGetCounterInfo
/// function and access the <c>dwQueryUserData</c> member of the PDH_COUNTER_INFO structure.
/// </param>
/// <param name="phCounter">
/// Handle to the counter that was added to the query. You may need to reference this handle in subsequent calls.
/// </param>
/// <returns>
/// <para>Return ERROR_SUCCESS if the function succeeds.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_CSTATUS_BAD_COUNTERNAME</term>
/// <term>The counter path could not be parsed or interpreted.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_COUNTER</term>
/// <term>Unable to find the specified counter on the computer or in the log file.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_COUNTERNAME</term>
/// <term>The counter path is empty.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_MACHINE</term>
/// <term>The path did not contain a computer name and the function was unable to retrieve the local computer name.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_OBJECT</term>
/// <term>Unable to find the specified object on the computer or in the log file.</term>
/// </item>
/// <item>
/// <term>PDH_FUNCTION_NOT_FOUND</term>
/// <term>Unable to determine the calculation function to use for this counter.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>One or more arguments are not valid.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The query handle is not valid.</term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>Unable to allocate memory required to complete the function.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function provides a language-neutral way to add performance counters to the query. In contrast, the counter path that you
/// specify in the PdhAddCounter function must be localized.
/// </para>
/// <para>
/// If a counter instance is specified that does not yet exist, <c>PdhAddEnglishCounter</c> does not report an error condition.
/// Instead, it returns ERROR_SUCCESS. The reason for this behavior is that it is not known whether a nonexistent counter instance
/// has been specified or whether one will exist but has not yet been created.
/// </para>
/// <para>To remove the counter from the query, use the PdhRemoveCounter function.</para>
/// <para>
/// <c>Note</c> If the counter path contains a wildcard character, the non-wildcard portions of the path will be localized, but
/// wildcards will not be expanded before adding the localized counter path to the query. In this case, you will need use the
/// following procedure to add all matching counter names to the query.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhaddenglishcountera PDH_FUNCTION PdhAddEnglishCounterA( PDH_HQUERY
// hQuery, LPCSTR szFullCounterPath, DWORD_PTR dwUserData, PDH_HCOUNTER *phCounter );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "6a94b40d-0105-4358-93e1-dae603a35cc4")]
public static extern Win32Error PdhAddEnglishCounter(PDH_HQUERY hQuery, string szFullCounterPath, IntPtr dwUserData, out SafePDH_HCOUNTER phCounter);
/// <summary>Binds one or more binary log files together for reading log data.</summary>
/// <param name="phDataSource">Handle to the bound data sources.</param>
/// <param name="LogFileNameList">
/// <para>
/// One or more binary log files to bind together. The log file names can contain absolute or relative paths. You cannot specify more
/// than 32 log files.
/// </para>
/// <para>If <c>NULL</c>, the source is a real-time data source.</para>
/// </param>
/// <returns>
/// <para>Returns ERROR_SUCCESS if the function succeeds.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code.</para>
/// </returns>
/// <remarks>
/// <para>
/// This function is used with the PDH functions that require a handle to a data source. For a list of these functions, see See Also.
/// </para>
/// <para>
/// You cannot specify more than one comma-delimited (CSV) or tab-delimited (TSV) file. The list can contain only one type of
/// file—you cannot combine multiple file types.
/// </para>
/// <para>To close the bound log files, call the PdhCloseLog function using the log handle.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhbindinputdatasourcea PDH_FUNCTION PdhBindInputDataSourceA(
// PDH_HLOG *phDataSource, LPCSTR LogFileNameList );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "eaed9b28-eb09-4123-9317-5d3d50e2d77a")]
public static extern Win32Error PdhBindInputDataSource(out SafePDH_HLOG phDataSource, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")] string[] LogFileNameList);
/// <summary>Binds one or more binary log files together for reading log data.</summary>
/// <param name="LogFileNameList">
/// <para>
/// One or more binary log files to bind together. The log file names can contain absolute or relative paths. You cannot specify more
/// than 32 log files.
/// </para>
/// <para>If <c>NULL</c>, the source is a real-time data source.</para>
/// </param>
/// <returns>Handle to the bound data sources.</returns>
/// <remarks>
/// <para>
/// This function is used with the PDH functions that require a handle to a data source. For a list of these functions, see See Also.
/// </para>
/// <para>
/// You cannot specify more than one comma-delimited (CSV) or tab-delimited (TSV) file. The list can contain only one type of
/// file—you cannot combine multiple file types.
/// </para>
/// </remarks>
[PInvokeData("pdh.h", MSDNShortId = "eaed9b28-eb09-4123-9317-5d3d50e2d77a")]
public static SafePDH_HLOG PdhBindInputDataSource(params string[] LogFileNameList)
{
var err = PdhBindInputDataSource(out var hLog, LogFileNameList is null || LogFileNameList.Length == 0 ? null : LogFileNameList);
return err.Succeeded ? hLog : throw err.GetException();
}
/// <summary>
/// <para>
/// Displays a <c>Browse Counters</c> dialog box that the user can use to select one or more counters that they want to add to the query.
/// </para>
/// <para>To use handles to data sources, use the PdhBrowseCountersH function.</para>
/// </summary>
/// <param name="pBrowseDlgData">A PDH_BROWSE_DLG_CONFIG structure that specifies the behavior of the dialog box.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code.</para>
/// </returns>
/// <remarks>
/// <para>
/// Note that the dialog box can return PDH_DIALOG_CANCELLED if <c>bSingleCounterPerDialog</c> is <c>FALSE</c> and the user clicks
/// the <c>Close</c> button, so your error handling would have to account for this.
/// </para>
/// <para>For information on using this function, see Browsing Counters.</para>
/// <para>Examples</para>
/// <para>For an example, see Browsing Performance Counters.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhbrowsecountersa PDH_FUNCTION PdhBrowseCountersA(
// PPDH_BROWSE_DLG_CONFIG_A pBrowseDlgData );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "4e9e4b20-a573-4f6d-97e8-63bcc675032b")]
public static extern Win32Error PdhBrowseCounters(ref PDH_BROWSE_DLG_CONFIG pBrowseDlgData);
/// <summary>
/// <para>
/// Displays a <c>Browse Counters</c> dialog box that the user can use to select one or more counters that they want to add to the query.
/// </para>
/// <para>This function is identical to the PdhBrowseCounters function, except that it supports the use of handles to data sources.</para>
/// </summary>
/// <param name="pBrowseDlgData">A PDH_BROWSE_DLG_CONFIG_H structure that specifies the behavior of the dialog box.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code.</para>
/// </returns>
/// <remarks>
/// Note that the dialog box can return PDH_DIALOG_CANCELLED if <c>bSingleCounterPerDialog</c> is <c>FALSE</c> and the user clicks
/// the <c>Close</c> button, so your error handling would have to account for this.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhbrowsecountersha PDH_FUNCTION PdhBrowseCountersHA(
// PPDH_BROWSE_DLG_CONFIG_HA pBrowseDlgData );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "ab835bf8-1adc-463f-99c3-654a328af98a")]
public static extern Win32Error PdhBrowseCountersH(in PDH_BROWSE_DLG_CONFIG_H pBrowseDlgData);
/// <summary>Calculates the displayable value of two raw counter values.</summary>
/// <param name="hCounter">
/// Handle to the counter to calculate. The function uses information from the counter to determine how to calculate the value. This
/// handle is returned by the PdhAddCounter function.
/// </param>
/// <param name="dwFormat">
/// <para>Determines the data type of the calculated value. Specify one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_FMT_DOUBLE</term>
/// <term>Return the calculated value as a double-precision floating point real.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_LARGE</term>
/// <term>Return the calculated value as a 64-bit integer.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_LONG</term>
/// <term>Return the calculated value as a long integer.</term>
/// </item>
/// </list>
/// <para>You can use the bitwise inclusive OR operator (|) to combine the data type with one of the following scaling factors.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_FMT_NOSCALE</term>
/// <term>Do not apply the counter's scaling factor in the calculation.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_NOCAP100</term>
/// <term>
/// Counter values greater than 100 (for example, counter values measuring the processor load on multiprocessor computers) will not
/// be reset to 100. The default behavior is that counter values are capped at a value of 100.
/// </term>
/// </item>
/// <item>
/// <term>PDH_FMT_1000</term>
/// <term>Multiply the final value by 1,000.</term>
/// </item>
/// </list>
/// </param>
/// <param name="rawValue1">
/// Raw counter value used to compute the displayable counter value. For details, see the PDH_RAW_COUNTER structure.
/// </param>
/// <param name="rawValue2">
/// Raw counter value used to compute the displayable counter value. For details, see PDH_RAW_COUNTER. Some counters (for example,
/// rate counters) require two raw values to calculate a displayable value. If the counter type does not require a second value, set
/// this parameter to <c>NULL</c>. This value must be the older of the two raw values.
/// </param>
/// <param name="fmtValue">A PDH_FMT_COUNTERVALUE structure that receives the calculated counter value.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>An argument is not correct or is incorrectly formatted.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The counter handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>To retrieve the current raw counter value from the query, call the PdhGetRawCounterValue function.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhcalculatecounterfromrawvalue PDH_FUNCTION
// PdhCalculateCounterFromRawValue( PDH_HCOUNTER hCounter, DWORD dwFormat, PPDH_RAW_COUNTER rawValue1, PPDH_RAW_COUNTER rawValue2,
// PPDH_FMT_COUNTERVALUE fmtValue );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "fd50b1fd-29b7-49a8-bbcc-4d7f0cbd7079")]
public static extern Win32Error PdhCalculateCounterFromRawValue(PDH_HCOUNTER hCounter, PDH_FMT dwFormat, in PDH_RAW_COUNTER rawValue1, in PDH_RAW_COUNTER rawValue2, out PDH_FMT_COUNTERVALUE fmtValue);
/// <summary>Calculates the displayable value of two raw counter values.</summary>
/// <param name="hCounter">
/// Handle to the counter to calculate. The function uses information from the counter to determine how to calculate the value. This
/// handle is returned by the PdhAddCounter function.
/// </param>
/// <param name="dwFormat">
/// <para>Determines the data type of the calculated value. Specify one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_FMT_DOUBLE</term>
/// <term>Return the calculated value as a double-precision floating point real.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_LARGE</term>
/// <term>Return the calculated value as a 64-bit integer.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_LONG</term>
/// <term>Return the calculated value as a long integer.</term>
/// </item>
/// </list>
/// <para>You can use the bitwise inclusive OR operator (|) to combine the data type with one of the following scaling factors.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_FMT_NOSCALE</term>
/// <term>Do not apply the counter's scaling factor in the calculation.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_NOCAP100</term>
/// <term>
/// Counter values greater than 100 (for example, counter values measuring the processor load on multiprocessor computers) will not
/// be reset to 100. The default behavior is that counter values are capped at a value of 100.
/// </term>
/// </item>
/// <item>
/// <term>PDH_FMT_1000</term>
/// <term>Multiply the final value by 1,000.</term>
/// </item>
/// </list>
/// </param>
/// <param name="rawValue1">
/// Raw counter value used to compute the displayable counter value. For details, see the PDH_RAW_COUNTER structure.
/// </param>
/// <param name="rawValue2">
/// Raw counter value used to compute the displayable counter value. For details, see PDH_RAW_COUNTER. Some counters (for example,
/// rate counters) require two raw values to calculate a displayable value. If the counter type does not require a second value, set
/// this parameter to <c>NULL</c>. This value must be the older of the two raw values.
/// </param>
/// <param name="fmtValue">A PDH_FMT_COUNTERVALUE structure that receives the calculated counter value.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>An argument is not correct or is incorrectly formatted.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The counter handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>To retrieve the current raw counter value from the query, call the PdhGetRawCounterValue function.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhcalculatecounterfromrawvalue PDH_FUNCTION
// PdhCalculateCounterFromRawValue( PDH_HCOUNTER hCounter, DWORD dwFormat, PPDH_RAW_COUNTER rawValue1, PPDH_RAW_COUNTER rawValue2,
// PPDH_FMT_COUNTERVALUE fmtValue );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "fd50b1fd-29b7-49a8-bbcc-4d7f0cbd7079")]
public static extern Win32Error PdhCalculateCounterFromRawValue(PDH_HCOUNTER hCounter, PDH_FMT dwFormat, in PDH_RAW_COUNTER rawValue1, [Optional] IntPtr rawValue2, out PDH_FMT_COUNTERVALUE fmtValue);
/// <summary>Closes the specified log file.</summary>
/// <param name="hLog">Handle to the log file to be closed. This handle is returned by the PdhOpenLog function.</param>
/// <param name="dwFlags">
/// <para>You can specify the following flag.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_FLAGS_CLOSE_QUERY</term>
/// <term>Closes the query associated with the specified log file handle. See the hQuery parameter of PdhOpenLog.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS and closes and deletes the query.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following is a possible value.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The log file handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhcloselog PDH_FUNCTION PdhCloseLog( PDH_HLOG hLog, DWORD dwFlags );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "74039bdf-d1b5-41ba-aa4e-4779ce0dd02a")]
public static extern Win32Error PdhCloseLog(PDH_HLOG hLog, uint dwFlags);
/// <summary>
/// Closes all counters contained in the specified query, closes all handles related to the query, and frees all memory associated
/// with the query.
/// </summary>
/// <param name="hQuery">Handle to the query to close. This handle is returned by the PdhOpenQuery function.</param>
/// <returns>
/// <para>
/// If the function succeeds, it returns ERROR_SUCCESS. Otherwise, the function returns a system error code or a PDH error code.
/// </para>
/// <para>The following is a possible value.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The query handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>Do not use the counter handles associated with this query after calling this function.</para>
/// <para>The following shows the syntax if calling this function from Visual Basic.</para>
/// <para>Examples</para>
/// <para>For an example, see Browsing Performance Counters or Reading Performance Data from a Log File.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhclosequery PDH_FUNCTION PdhCloseQuery( PDH_HQUERY hQuery );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "af0fb9f4-3999-48fa-88d7-aa59b5caed75")]
public static extern Win32Error PdhCloseQuery(PDH_HQUERY hQuery);
/// <summary>
/// Collects the current raw data value for all counters in the specified query and updates the status code of each counter.
/// </summary>
/// <param name="hQuery">Handle of the query for which you want to collect data. The PdhOpenQuery function returns this handle.</param>
/// <returns>
/// <para>
/// If the function succeeds, it returns ERROR_SUCCESS. Otherwise, the function returns a system error code or a PDH error code.
/// </para>
/// <para>The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The query handle is not valid.</term>
/// </item>
/// <item>
/// <term>PDH_NO_DATA</term>
/// <term>
/// The query does not currently contain any counters. The query may not contain data because the user is not running with an
/// elevated token (see Limited User Access Support).
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Call this function when you want to collect counter data for the counters in the query. PDH stores the raw counter values for the
/// current and previous collection.
/// </para>
/// <para>
/// If you want to retrieve the current raw counter value, call the PdhGetRawCounterValue function. If you want to compute a
/// displayable value for the counter value, call the PdhGetFormattedCounterValue function. If the counter path contains a wildcard
/// for the instance name, instead call the PdhGetRawCounterArray and PdhGetFormattedCounterArray functions, respectively.
/// </para>
/// <para>
/// When <c>PdhCollectQueryData</c> is called for data from one counter instance only and the counter instance does not exist, the
/// function returns PDH_NO_DATA. However, if data from more than one counter is queried, <c>PdhCollectQueryData</c> may return
/// ERROR_SUCCESS even if one of the counter instances does not yet exist. This is because it is not known if the specified counter
/// instance does not exist, or if it will exist but has not yet been created. In this case, call PdhGetRawCounterValue or
/// PdhGetFormattedCounterValue for each of the counter instances of interest to determine whether they exist.
/// </para>
/// <para>The following shows the syntax if calling this function from Visual Basic.</para>
/// <para>Examples</para>
/// <para>For an example, see Browsing Performance Counters or Reading Performance Data from a Log File.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhcollectquerydata PDH_FUNCTION PdhCollectQueryData( PDH_HQUERY
// hQuery );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "1d83325b-8deb-4731-9df4-6201da292cdc")]
public static extern Win32Error PdhCollectQueryData(PDH_HQUERY hQuery);
/// <summary>
/// Uses a separate thread to collect the current raw data value for all counters in the specified query. The function then signals
/// the application-defined event and waits the specified time interval before returning.
/// </summary>
/// <param name="hQuery">
/// Handle of the query. The query identifies the counters that you want to collect. The PdhOpenQuery function returns this handle.
/// </param>
/// <param name="dwIntervalTime">Time interval to wait, in seconds.</param>
/// <param name="hNewDataEvent">
/// Handle to the event that you want PDH to signal after the time interval expires. To create an event object, call the CreateEvent function.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The query handle is not valid.</term>
/// </item>
/// <item>
/// <term>PDH_NO_DATA</term>
/// <term>The query does not currently have any counters.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// PDH terminates the thread when you call the PdhCloseQuery function. If you call <c>PdhCollectQueryDataEx</c> more than once, each
/// subsequent call terminates the thread from the previous call and then starts a new thread.
/// </para>
/// <para>
/// When <c>PdhCollectQueryDataEx</c> is called for data from one counter instance only and the counter instance does not exist, the
/// function returns PDH_NO_DATA. However, if data from more than one counter is queried, <c>PdhCollectQueryDataEx</c> may return
/// ERROR_SUCCESS even if one of the counter instances does not yet exist. This is because it is not known if the specified counter
/// instance does not exist, or if it will exist but has not yet been created. In this case, call PdhGetRawCounterValue or
/// PdhGetFormattedCounterValue for each of the counter instances of interest to determine whether they exist.
/// </para>
/// <para>
/// PDH stores the raw counter values for the current and previous collection. If you want to retrieve the current raw counter value,
/// call the PdhGetRawCounterValue function. If you want to compute a displayable value for the counter value, call the
/// PdhGetFormattedCounterValue. If the counter path contains a wildcard for the instance name, instead call the
/// PdhGetRawCounterArray and PdhGetFormattedCounterArray functions, respectively.
/// </para>
/// <para>Examples</para>
/// <para>The following example shows how to use this function.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhcollectquerydataex PDH_FUNCTION PdhCollectQueryDataEx( PDH_HQUERY
// hQuery, DWORD dwIntervalTime, HANDLE hNewDataEvent );
[DllImport(Lib.Pdh, SetLastError = true, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "3fa1d193-03d0-44d8-a32b-b7754594d0ca")]
public static extern Win32Error PdhCollectQueryDataEx(PDH_HQUERY hQuery, uint dwIntervalTime, SafeEventHandle hNewDataEvent);
/// <summary>
/// Collects the current raw data value for all counters in the specified query and updates the status code of each counter.
/// </summary>
/// <param name="hQuery">Handle of the query for which you want to collect data. The PdhOpenQuery function returns this handle.</param>
/// <param name="pllTimeStamp">Time stamp when the first counter value in the query was retrieved. The time is specified as FILETIME.</param>
/// <returns>
/// <para>
/// If the function succeeds, it returns ERROR_SUCCESS. Otherwise, the function returns a system error code or a PDH error code.
/// </para>
/// <para>The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The query handle is not valid.</term>
/// </item>
/// <item>
/// <term>PDH_NO_DATA</term>
/// <term>The query does not currently have any counters.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Call this function when you want to collect counter data for the counters in the query. PDH stores the raw counter values for the
/// current and previous collection.
/// </para>
/// <para>
/// If you want to retrieve the current raw counter value, call the PdhGetRawCounterValue function. If you want to compute a
/// displayable value for the counter value, call the PdhGetFormattedCounterValue. If the counter path contains a wildcard for the
/// instance name, instead call the PdhGetRawCounterArray and PdhGetFormattedCounterArray functions, respectively.
/// </para>
/// <para>
/// When PdhCollectQueryDataEx is called for data from one counter instance only, and the counter instance does not exist, the
/// function returns PDH_NO_DATA. However, if data from more than one counter is queried, <c>PdhCollectQueryDataEx</c> may return
/// ERROR_SUCCESS even if one of the counter instances does not yet exist. This is because it is not known if the specified counter
/// instance does not exist, or if it will exist but has not yet been created. In this case, call the PdhGetRawCounterValue or
/// PdhGetFormattedCounterValue function for each of the counter instances of interest to determine whether they exist.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhcollectquerydatawithtime PDH_FUNCTION
// PdhCollectQueryDataWithTime( PDH_HQUERY hQuery, LONGLONG *pllTimeStamp );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "2c47c690-0748-4ed4-a138-894d45c72581")]
public static extern Win32Error PdhCollectQueryDataWithTime(PDH_HQUERY hQuery, out FILETIME pllTimeStamp);
/// <summary>Computes statistics for a counter from an array of raw values.</summary>
/// <param name="hCounter">
/// Handle of the counter for which you want to compute statistics. The PdhAddCounter function returns this handle.
/// </param>
/// <param name="dwFormat">
/// <para>Determines the data type of the formatted value. Specify one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_FMT_DOUBLE</term>
/// <term>Return the calculated value as a double-precision floating point real.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_LARGE</term>
/// <term>Return the calculated value as a 64-bit integer.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_LONG</term>
/// <term>Return the calculated value as a long integer.</term>
/// </item>
/// </list>
/// <para>You can use the bitwise inclusive OR operator (|) to combine the data type with one of the following scaling factors.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_FMT_NOSCALE</term>
/// <term>Do not apply the counter's scaling factors in the calculation.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_NOCAP100</term>
/// <term>
/// Counter values greater than 100 (for example, counter values measuring the processor load on multiprocessor computers) will not
/// be reset to 100. The default behavior is that counter values are capped at a value of 100.
/// </term>
/// </item>
/// <item>
/// <term>PDH_FMT_1000</term>
/// <term>Multiply the final value by 1,000.</term>
/// </item>
/// </list>
/// </param>
/// <param name="dwFirstEntry">
/// Zero-based index of the first raw counter value to use to begin the calculations. The index value must point to the oldest entry
/// in the buffer. The 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.
/// </param>
/// <param name="dwNumEntries">Number of raw counter values in the lpRawValueArray buffer.</param>
/// <param name="lpRawValueArray">Array of PDH_RAW_COUNTER structures that contain dwNumEntries entries.</param>
/// <param name="data">A PDH_STATISTICS structure that receives the counter statistics.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>An argument is not correct or is incorrectly formatted.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The counter handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhcomputecounterstatistics PDH_FUNCTION
// PdhComputeCounterStatistics( PDH_HCOUNTER hCounter, DWORD dwFormat, DWORD dwFirstEntry, DWORD dwNumEntries, PPDH_RAW_COUNTER
// lpRawValueArray, PPDH_STATISTICS data );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "a986ae6c-88ee-4a03-9077-3d286157b9d1")]
public static extern Win32Error PdhComputeCounterStatistics(PDH_HCOUNTER hCounter, PDH_FMT dwFormat, uint dwFirstEntry, uint dwNumEntries, [In] PDH_RAW_COUNTER[] lpRawValueArray, out PDH_STATISTICS data);
/// <summary>Connects to the specified computer.</summary>
/// <param name="szMachineName">
/// <c>Null</c>-terminated string that specifies the name of the computer to connect to. If <c>NULL</c>, PDH connects to the local computer.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_CSTATUS_NO_MACHINE</term>
/// <term>
/// Unable to connect to the specified computer. Could be caused by the computer not being on, not supporting PDH, not being
/// connected to the network, or having the permissions set on the registry that prevent remote connections or remote performance
/// monitoring by the user.
/// </term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Typically, applications do not call this function and instead the connection is made when the application adds the counter to the query.
/// </para>
/// <para>
/// However, you can use this function if you want to include more than the local computer in the <c>Select counters from
/// computer</c> list on the <c>Browse Counters</c> dialog box. For details, see the PDH_BROWSE_DLG_CONFIG structure.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhconnectmachinea PDH_FUNCTION PdhConnectMachineA( LPCSTR
// szMachineName );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "8f8b4651-b550-4b34-bb2f-d2497c56b572")]
public static extern Win32Error PdhConnectMachine([Optional] string szMachineName);
/// <summary>Enumerates the names of the log sets within the DSN.</summary>
/// <param name="szDataSource"><c>Null</c>-terminated string that specifies the DSN.</param>
/// <param name="mszDataSetNameList">
/// Caller-allocated buffer that receives the list of <c>null</c>-terminated log set names. The list is terminated with a
/// <c>null</c>-terminator character. Set to <c>NULL</c> if the pcchBufferLength parameter is zero.
/// </param>
/// <param name="pcchBufferLength">
/// Size of the mszLogSetNameList buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this
/// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the
/// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you
/// should not rely on the returned size to reallocate the buffer.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The size of the mszLogSetNameList buffer is too small to contain all the data. This return value is expected if pcchBufferLength
/// is zero on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the
/// returned size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater
/// than zero but less than the required size.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// You should call this function twice, the first time to get the required buffer size (set mszLogSetNameList to <c>NULL</c> and
/// pcchBufferLength to 0), and the second time to get the data.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhenumlogsetnamesa PDH_FUNCTION PdhEnumLogSetNamesA( LPCSTR
// szDataSource, PZZSTR mszDataSetNameList, LPDWORD pcchBufferLength );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "c74cc8a6-915b-40ed-a88b-bc2147215d52")]
public static extern Win32Error PdhEnumLogSetNames(string szDataSource, IntPtr mszDataSetNameList, ref uint pcchBufferLength);
/// <summary>
/// <para>
/// Returns a list of the computer names associated with counters in a log file. The computer names were either specified when adding
/// counters to the query or when calling the PdhConnectMachine function. The computers listed include those that are currently
/// connected and online, in addition to those that are offline or not returning performance data.
/// </para>
/// <para>To use handles to data sources, use the PdhEnumMachinesH function.</para>
/// </summary>
/// <param name="szDataSource">
/// <c>Null</c>-terminated string that specifies the name of a log file. The function enumerates the names of the computers whose
/// counter data is in the log file. If <c>NULL</c>, the function enumerates the list of computers that were specified when adding
/// counters to a real time query or when calling the PdhConnectMachine function.
/// </param>
/// <param name="mszMachineList">
/// Caller-allocated buffer to receive the list of <c>null</c>-terminated strings that contain the computer names. The list is
/// terminated with two <c>null</c>-terminator characters. Set to <c>NULL</c> if pcchBufferLength is zero.
/// </param>
/// <param name="pcchBufferSize">
/// Size of the mszMachineNameList buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this
/// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the
/// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you
/// should not rely on the returned size to reallocate the buffer.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The mszMachineNameList buffer is too small to contain all the data. This return value is expected if pcchBufferLength is zero on
/// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned
/// size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater
/// than zero but less than the required size.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// You should call this function twice, the first time to get the required buffer size (set mszMachineNameList to <c>NULL</c> and
/// pcchBufferLength to 0), and the second time to get the data.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhenummachinesa PDH_FUNCTION PdhEnumMachinesA( LPCSTR szDataSource,
// PZZSTR mszMachineList, LPDWORD pcchBufferSize );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "77584d3b-3ba5-4288-b730-be2458f4fc1c")]
public static extern Win32Error PdhEnumMachines([Optional] string szDataSource, IntPtr mszMachineList, ref uint pcchBufferSize);
/// <summary>
/// <para>
/// Returns a list of the computer names associated with counters in a log file. The computer names were either specified when adding
/// counters to the query or when calling the PdhConnectMachine function. The computers listed include those that are currently
/// connected and online, in addition to those that are offline or not returning performance data.
/// </para>
/// <para>This function is identical to the PdhEnumMachines function, except that it supports the use of handles to data sources.</para>
/// </summary>
/// <param name="hDataSource">Handle to a data source returned by the PdhBindInputDataSource function.</param>
/// <param name="mszMachineList">
/// Caller-allocated buffer to receive the list of <c>null</c>-terminated strings that contain the computer names. The list is
/// terminated with two <c>null</c>-terminator characters. Set to <c>NULL</c> if pcchBufferLength is zero.
/// </param>
/// <param name="pcchBufferSize">
/// Size of the mszMachineNameList buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this
/// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the
/// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you
/// should not rely on the returned size to reallocate the buffer.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The mszMachineNameList buffer is too small to contain all the data. This return value is expected if pcchBufferLength is zero on
/// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned
/// size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater
/// than zero but less than the required size.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// You should call this function twice, the first time to get the required buffer size (set mszMachineNameList to <c>NULL</c> and
/// pcchBufferLength to 0), and the second time to get the data.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhenummachinesha PDH_FUNCTION PdhEnumMachinesHA( PDH_HLOG
// hDataSource, PZZSTR mszMachineList, LPDWORD pcchBufferSize );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "7e8dc113-76a7-4a7a-bbad-1a4387831501")]
public static extern Win32Error PdhEnumMachinesH([Optional] PDH_HLOG hDataSource, IntPtr mszMachineList, ref uint pcchBufferSize);
/// <summary>
/// <para>
/// Returns the specified object's counter and instance names that exist on the specified computer or in the specified log file.
/// </para>
/// <para>To use handles to data sources, use the PdhEnumObjectItemsH function.</para>
/// </summary>
/// <param name="szDataSource">
/// <para>
/// <c>Null</c>-terminated string that specifies the name of the log file used to enumerate the counter and instance names. If
/// <c>NULL</c>, the function uses the computer specified in
/// </para>
/// <para>the szMachineName parameter to enumerate the names.</para>
/// </param>
/// <param name="szMachineName">
/// <para>
/// <c>Null</c>-terminated string that specifies the name of the computer that contains the counter and instance names that you want
/// to enumerate.
/// </para>
/// <para>Include the leading slashes in the computer name, for example, \computername.</para>
/// <para>If the szDataSource parameter is <c>NULL</c>, you can set szMachineName to <c>NULL</c> to specify the local computer.</para>
/// </param>
/// <param name="szObjectName">
/// <c>Null</c>-terminated string that specifies the name of the object whose counter and instance names you want to enumerate.
/// </param>
/// <param name="mszCounterList">
/// Caller-allocated buffer that receives a list of <c>null</c>-terminated counter names provided by the specified object. The list
/// contains unique counter names. The list is terminated by two <c>NULL</c> characters. Set to <c>NULL</c> if the
/// pcchCounterListLengthparameter is zero.
/// </param>
/// <param name="pcchCounterListLength">
/// Size of the mszCounterList buffer, in <c>TCHARs</c>. If zero on input and the object exists, the function returns PDH_MORE_DATA
/// and sets this parameter to the required buffer size. If the buffer is larger than the required size, the function sets this
/// parameter to the actual size of the buffer that was used. If the specified size on input is greater than zero but less than the
/// required size, you should not rely on the returned size to reallocate the buffer.
/// </param>
/// <param name="mszInstanceList">
/// Caller-allocated buffer that receives a list of <c>null</c>-terminated instance names provided by the specified object. The list
/// contains unique instance names. The list is terminated by two <c>NULL</c> characters. Set to <c>NULL</c> if
/// pcchInstanceListLength is zero.
/// </param>
/// <param name="pcchInstanceListLength">
/// <para>
/// Size of the mszInstanceList buffer, in <c>TCHARs</c>. If zero on input and the object exists, the function returns PDH_MORE_DATA
/// and sets this parameter to the required buffer size. If the buffer is larger than the required size, the function sets this
/// parameter to the actual size of the buffer that was used. If the specified size on input is greater than zero but less than the
/// required size, you should not rely on the returned size to reallocate the buffer.
/// </para>
/// <para>
/// If the specified object does not support variable instances, then the returned value will be zero. 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 of an
/// empty MULTI_SZ list string.
/// </para>
/// </param>
/// <param name="dwDetailLevel">
/// <para>
/// Detail level of the performance items to return. All items that are of the specified detail level or less will be returned (the
/// levels are listed in increasing order). This parameter can be one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PERF_DETAIL_NOVICE</term>
/// <term>Novice user level of detail.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_ADVANCED</term>
/// <term>Advanced user level of detail.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_EXPERT</term>
/// <term>Expert user level of detail.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_WIZARD</term>
/// <term>System designer level of detail.</term>
/// </item>
/// </list>
/// </param>
/// <param name="dwFlags">This parameter must be zero.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// One of the buffers is too small to contain the list of names. This return value is expected if pcchCounterListLength or
/// pcchInstanceListLength is zero on input. If the specified size on input is greater than zero but less than the required size, you
/// should not rely on the returned size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater
/// than zero but less than the required size.
/// </term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>Unable to allocate memory to support this function.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_MACHINE</term>
/// <term>The specified computer is offline or unavailable.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_OBJECT</term>
/// <term>The specified object could not be found on the specified computer or in the specified log file.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// You should call this function twice, the first time to get the required buffer size (set the buffers to <c>NULL</c> and the sizes
/// to 0), and the second time to get the data.
/// </para>
/// <para>
/// Consecutive calls to this function will return identical lists of counters and instances, because <c>PdhEnumObjectItems</c> will
/// always query the list of performance objects defined by the last call to PdhEnumObjects or <c>PdhEnumObjectItems</c>. To refresh
/// the list of performance objects, call <c>PdhEnumObjects</c> with a bRefresh flag value of <c>TRUE</c> before calling
/// <c>PdhEnumObjectItems</c> again.
/// </para>
/// <para>The order of the instance and counter names is undetermined.</para>
/// <para>Examples</para>
/// <para>For an example, see Enumerating Process Objects.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhenumobjectitemsa PDH_FUNCTION PdhEnumObjectItemsA( LPCSTR
// szDataSource, LPCSTR szMachineName, LPCSTR szObjectName, PZZSTR mszCounterList, LPDWORD pcchCounterListLength, PZZSTR
// mszInstanceList, LPDWORD pcchInstanceListLength, DWORD dwDetailLevel, DWORD dwFlags );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "b3efdd31-44e6-47ff-bd0e-d31451c32818")]
public static extern Win32Error PdhEnumObjectItems([Optional] string szDataSource, [Optional] string szMachineName, string szObjectName, [Optional] IntPtr mszCounterList, ref uint pcchCounterListLength, [Optional] IntPtr mszInstanceList, ref uint pcchInstanceListLength, PERF_DETAIL dwDetailLevel, uint dwFlags = 0);
/// <summary>
/// <para>
/// Returns the specified object's counter and instance names that exist on the specified computer or in the specified log file.
/// </para>
/// <para>This function is identical to the PdhEnumObjectItems function, except that it supports the use of handles to data sources.</para>
/// </summary>
/// <param name="hDataSource">Handle to a data source returned by the PdhBindInputDataSource function.</param>
/// <param name="szMachineName">
/// <para>
/// <c>Null</c>-terminated string that specifies the name of the computer that contains the counter and instance names that you want
/// to enumerate.
/// </para>
/// <para>Include the leading slashes in the computer name, for example, \computername.</para>
/// <para>If the szDataSource parameter is <c>NULL</c>, you can set szMachineName to <c>NULL</c> to specify the local computer.</para>
/// </param>
/// <param name="szObjectName">
/// <c>Null</c>-terminated string that specifies the name of the object whose counter and instance names you want to enumerate.
/// </param>
/// <param name="mszCounterList">
/// Caller-allocated buffer that receives a list of <c>null</c>-terminated counter names provided by the specified object. The list
/// contains unique counter names. The list is terminated by two <c>NULL</c> characters. Set to <c>NULL</c> if the
/// pcchCounterListLength parameter is zero.
/// </param>
/// <param name="pcchCounterListLength">
/// Size of the mszCounterList buffer, in <c>TCHARs</c>. If zero on input and the object exists, the function returns PDH_MORE_DATA
/// and sets this parameter to the required buffer size. If the buffer is larger than the required size, the function sets this
/// parameter to the actual size of the buffer that was used. If the specified size on input is greater than zero but less than the
/// required size, you should not rely on the returned size to reallocate the buffer.
/// </param>
/// <param name="mszInstanceList">
/// Caller-allocated buffer that receives a list of <c>null</c>-terminated instance names provided by the specified object. The list
/// contains unique instance names. The list is terminated by two <c>NULL</c> characters. Set to <c>NULL</c> if the
/// pcchInstanceListLength parameter is zero.
/// </param>
/// <param name="pcchInstanceListLength">
/// <para>
/// Size of the mszInstanceList buffer, in <c>TCHARs</c>. If zero on input and the object exists, the function returns PDH_MORE_DATA
/// and sets this parameter to the required buffer size. If the buffer is larger than the required size, the function sets this
/// parameter to the actual size of the buffer that was used. If the specified size on input is greater than zero but less than the
/// required size, you should not rely on the returned size to reallocate the buffer.
/// </para>
/// <para>
/// If the specified object does not support variable instances, then the returned value will be zero. 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 of an
/// empty MULTI_SZ list string.
/// </para>
/// </param>
/// <param name="dwDetailLevel">
/// <para>
/// Detail level of the performance items to return. All items that are of the specified detail level or less will be returned (the
/// levels are listed in increasing order). This parameter can be one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PERF_DETAIL_NOVICE</term>
/// <term>Novice user level of detail.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_ADVANCED</term>
/// <term>Advanced user level of detail.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_EXPERT</term>
/// <term>Expert user level of detail.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_WIZARD</term>
/// <term>System designer level of detail.</term>
/// </item>
/// </list>
/// </param>
/// <param name="dwFlags">This parameter must be zero.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// One of the buffers is too small to contain the list of names. This return value is expected if pcchCounterListLength or
/// pcchInstanceListLength is zero on input. If the specified size on input is greater than zero but less than the required size, you
/// should not rely on the returned size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater
/// than zero but less than the required size.
/// </term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>Unable to allocate memory to support this function.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_MACHINE</term>
/// <term>The specified computer is offline or unavailable.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_OBJECT</term>
/// <term>The specified object could not be found on the specified computer or in the specified log file.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// You should call this function twice, the first time to get the required buffer size (set the buffers to <c>NULL</c> and the sizes
/// to 0), and the second time to get the data.
/// </para>
/// <para>
/// Consecutive calls to this function will return identical lists of counters and instances, because <c>PdhEnumObjectItemsH</c> will
/// always query the list of performance objects defined by the last call to PdhEnumObjectsH or <c>PdhEnumObjectItemsH</c>. To
/// refresh the list of performance objects, call <c>PdhEnumObjectsH</c> with a bRefresh flag value of <c>TRUE</c> before calling
/// <c>PdhEnumObjectItemsH</c> again.
/// </para>
/// <para>The order of the instance and counter names is undetermined.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhenumobjectitemsha PDH_FUNCTION PdhEnumObjectItemsHA( PDH_HLOG
// hDataSource, LPCSTR szMachineName, LPCSTR szObjectName, PZZSTR mszCounterList, LPDWORD pcchCounterListLength, PZZSTR
// mszInstanceList, LPDWORD pcchInstanceListLength, DWORD dwDetailLevel, DWORD dwFlags );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "2cea7d0a-cea2-4fee-a087-37663de254e9")]
public static extern Win32Error PdhEnumObjectItemsH([Optional] PDH_HLOG hDataSource, [Optional] string szMachineName, string szObjectName, [Optional] IntPtr mszCounterList, ref uint pcchCounterListLength, [Optional] IntPtr mszInstanceList, ref uint pcchInstanceListLength, PERF_DETAIL dwDetailLevel, uint dwFlags = 0);
/// <summary>
/// <para>Returns a list of objects available on the specified computer or in the specified log file.</para>
/// <para>To use handles to data sources, use the PdhEnumObjectsH function.</para>
/// </summary>
/// <param name="szDataSource">
/// <para>
/// <c>Null</c>-terminated string that specifies the name of the log file used to enumerate the performance objects. If <c>NULL</c>,
/// the function uses the computer specified in
/// </para>
/// <para>the szMachineName parameter to enumerate the names.</para>
/// </param>
/// <param name="szMachineName">
/// <para><c>Null</c>-terminated string that specifies the name of the computer used to enumerate the performance objects.</para>
/// <para>Include the leading slashes in the computer name, for example, \computername.</para>
/// <para>If the szDataSource parameter is <c>NULL</c>, you can set szMachineName to <c>NULL</c> to specify the local computer.</para>
/// </param>
/// <param name="mszObjectList">
/// Caller-allocated buffer that receives the list of object names. Each object name in this list is terminated by a <c>null</c>
/// character. The list is terminated with two <c>null</c>-terminator characters. Set to <c>NULL</c> if the pcchBufferLength
/// parameter is zero.
/// </param>
/// <param name="pcchBufferSize">
/// <para>
/// Size of the mszObjectList buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this parameter
/// to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size
/// of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not
/// rely on the returned size to reallocate the buffer.
/// </para>
/// <para><c>Windows XP:</c> Add one to the required buffer size.</para>
/// </param>
/// <param name="dwDetailLevel">
/// <para>
/// Detail level of the performance items to return. All items that are of the specified detail level or less will be returned (the
/// levels are listed in increasing order). This parameter can be one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PERF_DETAIL_NOVICE</term>
/// <term>Novice user level of detail.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_ADVANCED</term>
/// <term>Advanced user level of detail.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_EXPERT</term>
/// <term>Expert user level of detail.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_WIZARD</term>
/// <term>System designer level of detail.</term>
/// </item>
/// </list>
/// </param>
/// <param name="bRefresh">
/// <para>Indicates if the cached object list should be automatically refreshed. Specify one of the following values.</para>
/// <para>
/// If you call this function twice, once to get the size of the list and a second time to get the actual list, set this parameter to
/// <c>TRUE</c> on the first call and <c>FALSE</c> on the second call. If both calls are <c>TRUE</c>, the second call may also return
/// PDH_MORE_DATA because the object data may have changed between calls.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>TRUE</term>
/// <term>The object cache is automatically refreshed before the objects are returned.</term>
/// </item>
/// <item>
/// <term>FALSE</term>
/// <term>Do not automatically refresh the cache.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The mszObjectList buffer is too small to hold the list of objects. This return value is expected if pcchBufferLength is zero on
/// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned
/// size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_MACHINE</term>
/// <term>The specified computer is offline or unavailable.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_OBJECT</term>
/// <term>The specified object could not be found.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater
/// than zero but less than the required size.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// You should call this function twice, the first time to get the required buffer size (set mszObjectList to <c>NULL</c> and
/// pcchBufferLength to 0), and the second time to get the data.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhenumobjectsa PDH_FUNCTION PdhEnumObjectsA( LPCSTR szDataSource,
// LPCSTR szMachineName, PZZSTR mszObjectList, LPDWORD pcchBufferSize, DWORD dwDetailLevel, BOOL bRefresh );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "dfa4b10f-5134-4620-a6b0-0fa2c13a33ec")]
public static extern Win32Error PdhEnumObjects([Optional] string szDataSource, [Optional] string szMachineName, [Optional] IntPtr mszObjectList, ref uint pcchBufferSize, PERF_DETAIL dwDetailLevel, [MarshalAs(UnmanagedType.Bool)] bool bRefresh);
/// <summary>
/// <para>Returns a list of objects available on the specified computer or in the specified log file.</para>
/// <para>This function is identical to PdhEnumObjects, except that it supports the use of handles to data sources.</para>
/// </summary>
/// <param name="hDataSource">Handle to a data source returned by the PdhBindInputDataSource function.</param>
/// <param name="szMachineName">
/// <para><c>Null</c>-terminated string that specifies the name of the computer used to enumerate the performance objects.</para>
/// <para>Include the leading slashes in the computer name, for example, \computername.</para>
/// <para>If szDataSource is <c>NULL</c>, you can set szMachineName to <c>NULL</c> to specify the local computer.</para>
/// </param>
/// <param name="mszObjectList">
/// Caller-allocated buffer that receives the list of object names. Each object name in this list is terminated by a <c>null</c>
/// character. The list is terminated with two <c>null</c>-terminator characters. Set to <c>NULL</c> if pcchBufferLength is zero.
/// </param>
/// <param name="pcchBufferSize">
/// <para>
/// Size of the mszObjectList buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this parameter
/// to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size
/// of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not
/// rely on the returned size to reallocate the buffer.
/// </para>
/// <para><c>Windows XP:</c> Add one to the required buffer size.</para>
/// </param>
/// <param name="dwDetailLevel">
/// <para>
/// Detail level of the performance items to return. All items that are of the specified detail level or less will be returned (the
/// levels are listed in increasing order). This parameter can be one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PERF_DETAIL_NOVICE</term>
/// <term>Novice user level of detail.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_ADVANCED</term>
/// <term>Advanced user level of detail.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_EXPERT</term>
/// <term>Expert user level of detail.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_WIZARD</term>
/// <term>System designer level of detail.</term>
/// </item>
/// </list>
/// </param>
/// <param name="bRefresh">
/// <para>Indicates if the cached object list should be automatically refreshed. Specify one of the following values.</para>
/// <para>
/// If you call this function twice, once to get the size of the list and a second time to get the actual list, set this parameter to
/// <c>TRUE</c> on the first call and <c>FALSE</c> on the second call. If both calls are <c>TRUE</c>, the second call may also return
/// PDH_MORE_DATA because the object data may have changed between calls.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>TRUE</term>
/// <term>The object cache is automatically refreshed before the objects are returned.</term>
/// </item>
/// <item>
/// <term>FALSE</term>
/// <term>Do not automatically refresh the cache.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The mszObjectList buffer is too small to hold the list of objects. This return value is expected if pcchBufferLength is zero on
/// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned
/// size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_MACHINE</term>
/// <term>The specified computer is offline or unavailable.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_OBJECT</term>
/// <term>The specified object could not be found.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater
/// than zero but less than the required size.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// You should call this function twice, the first time to get the required buffer size (set mszObjectList to <c>NULL</c> and
/// pcchBufferLength to 0), and the second time to get the data.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhenumobjectsha PDH_FUNCTION PdhEnumObjectsHA( PDH_HLOG
// hDataSource, LPCSTR szMachineName, PZZSTR mszObjectList, LPDWORD pcchBufferSize, DWORD dwDetailLevel, BOOL bRefresh );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "8f68a7a8-cc56-4f7f-a86f-4b439738808d")]
public static extern Win32Error PdhEnumObjectsH([Optional] PDH_HLOG hDataSource, [Optional] string szMachineName, [Optional] IntPtr mszObjectList, ref uint pcchBufferSize, PERF_DETAIL dwDetailLevel, [MarshalAs(UnmanagedType.Bool)] bool bRefresh);
/// <summary>
/// <para>
/// Examines the specified computer (or local computer if none is specified) for counters and instances of counters that match the
/// wildcard strings in the counter path.
/// </para>
/// <para><c>Note</c> This function is superseded by the PdhExpandWildCardPath function.</para>
/// </summary>
/// <param name="szWildCardPath">
/// <c>Null</c>-terminated string that contains the counter path to expand. The function searches the computer specified in the path
/// for matches. If the path does not specify a computer, the function searches the local computer. The maximum length of a counter
/// path is PDH_MAX_COUNTER_PATH.
/// </param>
/// <param name="mszExpandedPathList">
/// Caller-allocated buffer that receives the list of expanded counter paths that match the wildcard specification in szWildCardPath.
/// Each counter path in this list is terminated by a <c>null</c> character. The list is terminated with two <c>NULL</c> characters.
/// Set to <c>NULL</c> if pcchPathListLength is zero.
/// </param>
/// <param name="pcchPathListLength">
/// <para>
/// Size of the mszExpandedPathList buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this
/// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the
/// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you
/// should not rely on the returned size to reallocate the buffer.
/// </para>
/// <para><c>Note</c> You must add one to the required size on Windows XP.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The mszExpandedPathList buffer is too small to contain the list of paths. This return value is expected if pcchPathListLength is
/// zero on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the
/// returned size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater
/// than zero but less than the required size.
/// </term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>Unable to allocate memory to support this function.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// You should call this function twice, the first time to get the required buffer size (set mszExpandedPathList to <c>NULL</c> and
/// pcchPathListLength to 0), and the second time to get the data.
/// </para>
/// <para>The general counter path format is as follows:</para>
/// <para>\computer\object(parent/instance#index)\counter</para>
/// <para>
/// The parent, instance, index, and counter components of the counter path may contain either a valid name or a wildcard character.
/// The computer, parent, instance, and index components are not necessary for all counters.
/// </para>
/// <para>
/// The counter paths that 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:
/// </para>
/// <para>\LogicalDisk(/#*)*</para>
/// <para>In comparison, the Process object does not require an instance index. Therefore, you could use the following format:</para>
/// <para>\Process(*)\ID Process</para>
/// <para>The following is a list of the possible formats:</para>
/// <list type="bullet">
/// <item>
/// <term>\\computer\object(parent/instance#index)\counter</term>
/// </item>
/// <item>
/// <term>\\computer\object(parent/instance)\counter</term>
/// </item>
/// <item>
/// <term>\\computer\object(instance#index)\counter</term>
/// </item>
/// <item>
/// <term>\\computer\object(instance)\counter</term>
/// </item>
/// <item>
/// <term>\\computer\object\counter</term>
/// </item>
/// <item>
/// <term>\object(parent/instance#index)\counter</term>
/// </item>
/// <item>
/// <term>\object(parent/instance)\counter</term>
/// </item>
/// <item>
/// <term>\object(instance#index)\counter</term>
/// </item>
/// <item>
/// <term>\object(instance)\counter</term>
/// </item>
/// <item>
/// <term>\object\counter</term>
/// </item>
/// </list>
/// <para>
/// 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.
/// </para>
/// <para>
/// 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.
/// </para>
/// <para>If a wildcard character is specified in the counter name, all counters of the specified object are returned.</para>
/// <para>Partial counter path string matches (for example, "pro*") are not supported.</para>
/// <para>Examples</para>
/// <para>The following example demonstrates how to this function.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhexpandcounterpatha PDH_FUNCTION PdhExpandCounterPathA( LPCSTR
// szWildCardPath, PZZSTR mszExpandedPathList, LPDWORD pcchPathListLength );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "d90954ab-ec2f-42fd-90b7-66f59f3d1115")]
public static extern Win32Error PdhExpandCounterPath(string szWildCardPath, [Optional] IntPtr mszExpandedPathList, ref uint pcchPathListLength);
/// <summary>
/// <para>
/// Examines the specified computer or log file and returns those counter paths that match the given counter path which contains
/// wildcard characters.
/// </para>
/// <para>To use handles to data sources, use the PdhExpandWildCardPathH function.</para>
/// </summary>
/// <param name="szDataSource">
/// <para>
/// <c>Null</c>-terminated string that contains the name of a log file. The function uses the performance objects and counters
/// defined in the log file to expand the path specified in the szWildCardPath parameter.
/// </para>
/// <para>If <c>NULL</c>, the function searches the computer specified in szWildCardPath.</para>
/// </param>
/// <param name="szWildCardPath">
/// <para><c>Null</c>-terminated string that specifies the counter path to expand. The maximum length of a counter path is PDH_MAX_COUNTER_PATH.</para>
/// <para>
/// If the szDataSource parameter is <c>NULL</c>, the function searches the computer specified in the path for matches. If the path
/// does not specify a computer, the function searches the local computer.
/// </para>
/// </param>
/// <param name="mszExpandedPathList">
/// Caller-allocated buffer that receives a list of <c>null</c>-terminated counter paths that match the wildcard specification in the
/// szWildCardPath. The list is terminated by two <c>NULL</c> characters. Set to <c>NULL</c> if pcchPathListLength is zero.
/// </param>
/// <param name="pcchPathListLength">
/// <para>
/// Size of the mszExpandedPathList buffer, in <c>TCHARs</c>. If zero on input and the object exists, the function returns
/// PDH_MORE_DATA and sets this parameter to the required buffer size. If the buffer is larger than the required size, the function
/// sets this parameter to the actual size of the buffer that was used. If the specified size on input is greater than zero but less
/// than the required size, you should not rely on the returned size to reallocate the buffer.
/// </para>
/// <para><c>Note</c> You must add one to the required size on Windows XP.</para>
/// </param>
/// <param name="dwFlags">
/// <para>Flags that indicate which wildcard characters not to expand. You can specify one or more flags.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_NOEXPANDCOUNTERS</term>
/// <term>Do not expand the counter name if the path contains a wildcard character for counter name.</term>
/// </item>
/// <item>
/// <term>PDH_NOEXPANDINSTANCES</term>
/// <term>
/// Do not expand the instance name if the path contains a wildcard character for parent instance, instance name, or instance index.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The mszExpandedPathList buffer is not large enough to contain the list of paths. This return value is expected if
/// pcchPathListLength is zero on input. If the specified size on input is greater than zero but less than the required size, you
/// should not rely on the returned size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater
/// than zero but less than the required size.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_PATH</term>
/// <term>The specified object does not contain an instance.</term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>Unable to allocate memory to support this function.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_OBJECT</term>
/// <term>Unable to find the specified object on the computer or in the log file.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// You should call this function twice, the first time to get the required buffer size (set mszExpandedPathList to <c>NULL</c> and
/// pcchPathListLength to 0), and the second time to get the data.
/// </para>
/// <para><c>PdhExpandWildCardPath</c> differs from PdhExpandCounterPath in the following ways:</para>
/// <list type="number">
/// <item>
/// <term>Lets you control which wildcard characters are expanded.</term>
/// </item>
/// <item>
/// <term>The contents of a log file can be used as the source of counter names.</term>
/// </item>
/// </list>
/// <para>The general counter path format is as follows:</para>
/// <para>\computer\object(parent/instance#index)\counter</para>
/// <para>
/// The parent, instance, index, and counter components of the counter path may contain either a valid name or a wildcard character.
/// The computer, parent, instance, and index components are not necessary for all counters.
/// </para>
/// <para>The following is a list of the possible formats:</para>
/// <list type="bullet">
/// <item>
/// <term>\\computer\object(parent/instance#index)\counter</term>
/// </item>
/// <item>
/// <term>\\computer\object(parent/instance)\counter</term>
/// </item>
/// <item>
/// <term>\\computer\object(instance#index)\counter</term>
/// </item>
/// <item>
/// <term>\\computer\object(instance)\counter</term>
/// </item>
/// <item>
/// <term>\\computer\object\counter</term>
/// </item>
/// <item>
/// <term>\object(parent/instance#index)\counter</term>
/// </item>
/// <item>
/// <term>\object(parent/instance)\counter</term>
/// </item>
/// <item>
/// <term>\object(instance#index)\counter</term>
/// </item>
/// <item>
/// <term>\object(instance)\counter</term>
/// </item>
/// <item>
/// <term>\object\counter</term>
/// </item>
/// </list>
/// <para>Use an asterisk (*) as the wildcard character, for example, \object(*)\counter.</para>
/// <para>
/// 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. For example, \object(*/instance)\counter.
/// </para>
/// <para>
/// 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. For example,
/// \object(parent/*)\counter. If the object does not contain an instance, an error occurs.
/// </para>
/// <para>If a wildcard character is specified in the counter name, all counters of the specified object are returned.</para>
/// <para>Partial counter path string matches (for example, "pro*") are supported.</para>
/// <para><c>Prior to Windows Vista:</c> Partial wildcard matches are not supprted.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhexpandwildcardpatha PDH_FUNCTION PdhExpandWildCardPathA( LPCSTR
// szDataSource, LPCSTR szWildCardPath, PZZSTR mszExpandedPathList, LPDWORD pcchPathListLength, DWORD dwFlags );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "415da310-de56-4d58-8959-231426867526")]
public static extern Win32Error PdhExpandWildCardPath([Optional] string szDataSource, string szWildCardPath, [Optional] IntPtr mszExpandedPathList, ref uint pcchPathListLength, PdhExpandFlags dwFlags);
/// <summary>
/// <para>
/// Examines the specified computer or log file and returns those counter paths that match the given counter path which contains
/// wildcard characters.
/// </para>
/// <para>This function is identical to the PdhExpandWildCardPath function, except that it supports the use of handles to data sources.</para>
/// </summary>
/// <param name="hDataSource">Handle to a data source returned by the PdhBindInputDataSource function.</param>
/// <param name="szWildCardPath">
/// <para><c>Null</c>-terminated string that specifies the counter path to expand. The maximum length of a counter path is PDH_MAX_COUNTER_PATH.</para>
/// <para>
/// If hDataSource is a real time data source, the function searches the computer specified in the path for matches. If the path does
/// not specify a computer, the function searches the local computer.
/// </para>
/// </param>
/// <param name="mszExpandedPathList">
/// Caller-allocated buffer that receives a list of <c>null</c>-terminated counter paths that match the wildcard specification in the
/// szWildCardPath. The list is terminated by two <c>NULL</c> characters. Set to <c>NULL</c> if pcchPathListLength is zero.
/// </param>
/// <param name="pcchPathListLength">
/// <para>
/// Size of the mszExpandedPathList buffer, in <c>TCHARs</c>. If zero on input and the object exists, the function returns
/// PDH_MORE_DATA and sets this parameter to the required buffer size. If the buffer is larger than the required size, the function
/// sets this parameter to the actual size of the buffer that was used. If the specified size on input is greater than zero but less
/// than the required size, you should not rely on the returned size to reallocate the buffer.
/// </para>
/// <para><c>Note</c> You must add one to the required size on Windows XP.</para>
/// </param>
/// <param name="dwFlags">
/// <para>Flags that indicate which wildcard characters not to expand. You can specify one or more flags.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_NOEXPANDCOUNTERS</term>
/// <term>Do not expand the counter name if the path contains a wildcard character for counter name.</term>
/// </item>
/// <item>
/// <term>PDH_NOEXPANDINSTANCES</term>
/// <term>
/// Do not expand the instance name if the path contains a wildcard character for parent instance, instance name, or instance index.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The mszExpandedPathList buffer is not large enough to contain the list of paths. This return value is expected if
/// pcchPathListLength is zero on input. If the specified size on input is greater than zero but less than the required size, you
/// should not rely on the returned size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater
/// than zero but less than the required size.
/// </term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>Unable to allocate memory to support this function.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_OBJECT</term>
/// <term>Unable to find the specified object on the computer or in the log file.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// You should call this function twice, the first time to get the required buffer size (set mszExpandedPathList to <c>NULL</c> and
/// pcchPathListLength to 0), and the second time to get the data.
/// </para>
/// <para><c>PdhExpandWildCardPathH</c> differs from PdhExpandCounterPath in the following ways:</para>
/// <list type="number">
/// <item>
/// <term>Lets you control which wildcard characters are expanded.</term>
/// </item>
/// <item>
/// <term>The contents of a log file can be used as the source of counter names.</term>
/// </item>
/// </list>
/// <para>The general counter path format is as follows:</para>
/// <para>\computer\object(parent/instance#index)\counter</para>
/// <para>
/// The parent, instance, index, and counter components of the counter path may contain either a valid name or a wildcard character.
/// The computer, parent, instance, and index components are not necessary for all counters.
/// </para>
/// <para>The following is a list of the possible formats:</para>
/// <list type="bullet">
/// <item>
/// <term>\\computer\object(parent/instance#index)\counter</term>
/// </item>
/// <item>
/// <term>\\computer\object(parent/instance)\counter</term>
/// </item>
/// <item>
/// <term>\\computer\object(instance#index)\counter</term>
/// </item>
/// <item>
/// <term>\\computer\object(instance)\counter</term>
/// </item>
/// <item>
/// <term>\\computer\object\counter</term>
/// </item>
/// <item>
/// <term>\object(parent/instance#index)\counter</term>
/// </item>
/// <item>
/// <term>\object(parent/instance)\counter</term>
/// </item>
/// <item>
/// <term>\object(instance#index)\counter</term>
/// </item>
/// <item>
/// <term>\object(instance)\counter</term>
/// </item>
/// <item>
/// <term>\object\counter</term>
/// </item>
/// </list>
/// <para>Use an asterisk (*) as the wildcard character, for example, \object(*)\counter.</para>
/// <para>
/// 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. For example, \object(*/instance)\counter.
/// </para>
/// <para>
/// 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. For example, \object(parent/*)\counter.
/// </para>
/// <para>If a wildcard character is specified in the counter name, all counters of the specified object are returned.</para>
/// <para>Partial counter path string matches (for example, "pro*") are supported.</para>
/// <para><c>Prior to Windows Vista:</c> Partial wildcard matches are not supprted.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhexpandwildcardpathha PDH_FUNCTION PdhExpandWildCardPathHA(
// PDH_HLOG hDataSource, LPCSTR szWildCardPath, PZZSTR mszExpandedPathList, LPDWORD pcchPathListLength, DWORD dwFlags );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "d7d13beb-02ab-4204-808e-d395197f09e1")]
public static extern Win32Error PdhExpandWildCardPathH([Optional] PDH_HLOG hDataSource, string szWildCardPath, [Optional] IntPtr mszExpandedPathList, ref uint pcchPathListLength, PdhExpandFlags dwFlags);
/// <summary>Computes a displayable value for the given raw counter values.</summary>
/// <param name="dwCounterType">
/// <para>
/// Type of counter. Typically, you call PdhGetCounterInfo to retrieve the counter type at the time you call PdhGetRawCounterValue to
/// retrieve the raw counter value.
/// </para>
/// <para>
/// For a list of counter types, see the Counter Types section of the Windows Server 2003 Deployment Kit. (The constant values are
/// defined in Winperf.h.)
/// </para>
/// <para>Note that you cannot specify base types, for example, PERF_LARGE_RAW_BASE.</para>
/// </param>
/// <param name="dwFormat">
/// <para>Determines the data type of the calculated value. Specify one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_FMT_DOUBLE</term>
/// <term>Return the calculated value as a double-precision floating point real.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_LARGE</term>
/// <term>Return the calculated value as a 64-bit integer.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_LONG</term>
/// <term>Return the calculated value as a long integer.</term>
/// </item>
/// </list>
/// <para>You can use the bitwise inclusive OR operator (|) to combine the data type with one of the following scaling factors.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_FMT_NOSCALE</term>
/// <term>Do not apply the counter's scaling factor in the calculation.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_NOCAP100</term>
/// <term>
/// Counter values greater than 100 (for example, counter values measuring the processor load on multiprocessor computers) will not
/// be reset to 100. The default behavior is that counter values are capped at a value of 100.
/// </term>
/// </item>
/// <item>
/// <term>PDH_FMT_1000</term>
/// <term>Multiply the final value by 1,000.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pTimeBase">
/// 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. To retrieve the time base of the counter, call PdhGetCounterTimeBase.
/// </param>
/// <param name="pRawValue1">Raw counter value used to compute the displayable counter value. For details, see PDH_RAW_COUNTER.</param>
/// <param name="pRawValue2">
/// Raw counter value used to compute the displayable counter value. For details, see PDH_RAW_COUNTER. Some counters, for example,
/// rate counters, require two raw values to calculate a displayable value. If the counter type does not require a second value, set
/// this parameter to <c>NULL</c>. This value must be the older of the two raw values.
/// </param>
/// <param name="pFmtValue">A PDH_FMT_COUNTERVALUE structure that receives the calculated counter value.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhformatfromrawvalue PDH_FUNCTION PdhFormatFromRawValue( DWORD
// dwCounterType, DWORD dwFormat, LONGLONG *pTimeBase, PPDH_RAW_COUNTER pRawValue1, PPDH_RAW_COUNTER pRawValue2,
// PPDH_FMT_COUNTERVALUE pFmtValue );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "13027af4-2e76-4c2f-88e8-a2554a16fae3")]
public static extern Win32Error PdhFormatFromRawValue(CounterType dwCounterType, PDH_FMT dwFormat, in FILETIME pTimeBase, in PDH_RAW_COUNTER pRawValue1, in PDH_RAW_COUNTER pRawValue2, out PDH_FMT_COUNTERVALUE pFmtValue);
/// <summary>Retrieves information about a counter, such as data size, counter type, path, and user-supplied data values.</summary>
/// <param name="hCounter">
/// Handle of the counter from which you want to retrieve information. The PdhAddCounter function returns this handle.
/// </param>
/// <param name="bRetrieveExplainText">
/// Determines whether explain text is retrieved. If you set this parameter to <c>TRUE</c>, the explain text for the counter is
/// retrieved. If you set this parameter to <c>FALSE</c>, the field in the returned buffer is <c>NULL</c>.
/// </param>
/// <param name="pdwBufferSize">
/// Size of the lpBuffer buffer, in bytes. If zero on input, the function returns PDH_MORE_DATA and sets this parameter to the
/// required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size of the
/// buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not rely on
/// the returned size to reallocate the buffer.
/// </param>
/// <param name="lpBuffer">
/// Caller-allocated buffer that receives a <see cref="PDH_COUNTER_INFO"/> structure. The structure 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. Set to <c>NULL</c> if pdwBufferSize is zero.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid or is incorrectly formatted. For example, on some releases you could receive this error if the specified
/// size on input is greater than zero but less than the required size.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The counter handle is not valid.</term>
/// </item>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The lpBuffer buffer is too small to hold the counter information. This return value is expected if pdwBufferSize is zero on
/// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned
/// size to reallocate the buffer.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// You should call this function twice, the first time to get the required buffer size (set lpBuffer to <c>NULL</c> and
/// pdwBufferSize to 0), and the second time to get the data.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetcounterinfoa PDH_FUNCTION PdhGetCounterInfoA( PDH_HCOUNTER
// hCounter, BOOLEAN bRetrieveExplainText, LPDWORD pdwBufferSize, PPDH_COUNTER_INFO_A lpBuffer );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "12e1a194-5418-4c2a-9853-ef2d2c666893")]
public static extern Win32Error PdhGetCounterInfo(PDH_HCOUNTER hCounter, [MarshalAs(UnmanagedType.U1)] bool bRetrieveExplainText, ref uint pdwBufferSize, IntPtr lpBuffer);
/// <summary>Returns the time base of the specified counter.</summary>
/// <param name="hCounter">Handle to the counter. The PdhAddCounter function returns this handle.</param>
/// <param name="pTimeBase">Time base that specifies the number of performance values a counter samples per second.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>The specified counter does not use a time base.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The counter handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If you use the PdhFormatFromRawValue function to calculate a displayable value instead of calling the
/// PdhCalculateCounterFromRawValue function, you must call the <c>PdhGetCounterTimeBase</c> function to retrieve the time base.
/// </para>
/// <para>
/// 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.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetcountertimebase PDH_FUNCTION PdhGetCounterTimeBase(
// PDH_HCOUNTER hCounter, LONGLONG *pTimeBase );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "b034c00e-50f1-46af-aebc-0cb968c0b737")]
public static extern Win32Error PdhGetCounterTimeBase(PDH_HCOUNTER hCounter, out FILETIME pTimeBase);
/// <summary>
/// <para>
/// Determines the time range, number of entries and, if applicable, the size of the buffer containing the performance data from the
/// specified input source.
/// </para>
/// <para>To use handles to data sources, use the PdhGetDataSourceTimeRangeH function.</para>
/// </summary>
/// <param name="szDataSource">
/// Null-terminated string that specifies the name of a log file from which the time range information is retrieved.
/// </param>
/// <param name="pdwNumEntries">
/// Number of structures in the pInfo buffer. This function collects information for only one time range, so the value is typically
/// 1, or zero if an error occurred.
/// </param>
/// <param name="pInfo">A PDH_TIME_INFO structure that receives the time range.</param>
/// <param name="pdwBufferSize">Size of the PDH_TIME_INFO structure, in bytes.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>A parameter is not valid or is incorrectly formatted.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The counter handle is not valid.</term>
/// </item>
/// <item>
/// <term>PDH_DATA_SOURCE_IS_REAL_TIME</term>
/// <term>The current data source is a real-time data source.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetdatasourcetimerangea PDH_FUNCTION PdhGetDataSourceTimeRangeA(
// LPCSTR szDataSource, LPDWORD pdwNumEntries, PPDH_TIME_INFO pInfo, LPDWORD pdwBufferSize );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "142ee829-7f1c-4b97-859c-670f7058dfa1")]
public static extern Win32Error PdhGetDataSourceTimeRange(string szDataSource, out uint pdwNumEntries, out PDH_TIME_INFO pInfo, ref uint pdwBufferSize);
/// <summary>
/// <para>
/// Determines the time range, number of entries and, if applicable, the size of the buffer containing the performance data from the
/// specified input source.
/// </para>
/// <para>
/// This function is identical to the PdhGetDataSourceTimeRange function, except that it supports the use of handles to data sources.
/// </para>
/// </summary>
/// <param name="hDataSource">Handle to a data source returned by the PdhBindInputDataSource function.</param>
/// <param name="pdwNumEntries">
/// Number of structures in the pInfo buffer. This function collects information for only one time range, so the value is typically
/// 1, or zero if an error occurred.
/// </param>
/// <param name="pInfo">A PDH_TIME_INFO structure that receives the time range. The information spans all bound log files.</param>
/// <param name="pdwBufferSize">Size of the PDH_TIME_INFO structure, in bytes.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>A parameter is not valid or is incorrectly formatted.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The counter handle is not valid.</term>
/// </item>
/// <item>
/// <term>PDH_DATA_SOURCE_IS_REAL_TIME</term>
/// <term>The current data source is a real-time data source.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetdatasourcetimerangeh PDH_FUNCTION PdhGetDataSourceTimeRangeH(
// PDH_HLOG hDataSource, LPDWORD pdwNumEntries, PPDH_TIME_INFO pInfo, LPDWORD pdwBufferSize );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "55cfef46-999d-43fa-9b09-9d8916fbf755")]
public static extern Win32Error PdhGetDataSourceTimeRangeH(PDH_HLOG hDataSource, out uint pdwNumEntries, out PDH_TIME_INFO pInfo, ref uint pdwBufferSize);
/// <summary>
/// <para>
/// Retrieves the name of the default counter for the specified object. This name can be used to set the initial counter selection in
/// the Browse Counter dialog box.
/// </para>
/// <para>To use handles to data sources, use the PdhGetDefaultPerfCounterH function.</para>
/// </summary>
/// <param name="szDataSource">Should be <c>NULL</c>.</param>
/// <param name="szMachineName">
/// <c>Null</c>-terminated string that specifies the name of the computer used to verify the object name. If <c>NULL</c>, the local
/// computer is used to verify the object name.
/// </param>
/// <param name="szObjectName">
/// <c>Null</c>-terminated string that specifies the name of the object whose default counter name you want to retrieve.
/// </param>
/// <param name="szDefaultCounterName">
/// Caller-allocated buffer that receives the <c>null</c>-terminated default counter name. Set to <c>NULL</c> if pcchBufferSize is zero.
/// </param>
/// <param name="pcchBufferSize">
/// Size of the szDefaultCounterName buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this
/// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the
/// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you
/// should not rely on the returned size to reallocate the buffer.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The szDefaultCounterName buffer is too small to contain the counter name. This return value is expected if pcchBufferSize is zero
/// on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the
/// returned size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A required parameter is not valid. For example, on some releases you could receive this error if the specified size on input is
/// greater than zero but less than the required size.
/// </term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>Unable to allocate memory in order to complete the function.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_MACHINE</term>
/// <term>The specified computer is offline or unavailable.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_COUNTERNAME</term>
/// <term>The default counter name cannot be read or found.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_OBJECT</term>
/// <term>The specified object could not be found.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_COUNTER</term>
/// <term>The object did not specify a default counter.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// You should call this function twice, the first time to get the required buffer size (set szDefaultCounterName to <c>NULL</c> and
/// pcchBufferSize to 0), and the second time to get the data.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetdefaultperfcountera PDH_FUNCTION PdhGetDefaultPerfCounterA(
// LPCSTR szDataSource, LPCSTR szMachineName, LPCSTR szObjectName, LPSTR szDefaultCounterName, LPDWORD pcchBufferSize );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "0eb78071-3496-40e9-91b0-3c06547c88d5")]
public static extern Win32Error PdhGetDefaultPerfCounter([Optional] string szDataSource, [Optional] string szMachineName, string szObjectName, [Optional] StringBuilder szDefaultCounterName, ref uint pcchBufferSize);
/// <summary>
/// <para>
/// Retrieves the name of the default counter for the specified object. This name can be used to set the initial counter selection in
/// the Browse Counter dialog box.
/// </para>
/// <para>This function is identical to PdhGetDefaultPerfCounter, except that it supports the use of handles to data sources.</para>
/// </summary>
/// <param name="hDataSource">Should be <c>NULL</c>.</param>
/// <param name="szMachineName">
/// <c>Null</c>-terminated string that specifies the name of the computer used to verify the object name. If <c>NULL</c>, the local
/// computer is used to verify the name.
/// </param>
/// <param name="szObjectName">
/// <c>Null</c>-terminated string that specifies the name of the object whose default counter name you want to retrieve.
/// </param>
/// <param name="szDefaultCounterName">
/// Caller-allocated buffer that receives the <c>null</c>-terminated default counter name. Set to <c>NULL</c> if pcchBufferSize is zero.
/// </param>
/// <param name="pcchBufferSize">
/// Size of the szDefaultCounterName buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this
/// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the
/// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you
/// should not rely on the returned size to reallocate the buffer.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The szDefaultCounterName buffer is too small to contain the counter name. This return value is expected if pcchBufferSize is zero
/// on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the
/// returned size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A required parameter is not valid. For example, on some releases you could receive this error if the specified size on input is
/// greater than zero but less than the required size.
/// </term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>Unable to allocate memory in order to complete the function.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_MACHINE</term>
/// <term>The specified computer is offline or unavailable.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_COUNTERNAME</term>
/// <term>The default counter name cannot be read or found.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_OBJECT</term>
/// <term>The specified object could not be found.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_COUNTER</term>
/// <term>The object did not specify a default counter.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// You should call this function twice, the first time to get the required buffer size (set szDefaultCounterName to <c>NULL</c> and
/// pcchBufferSize to 0), and the second time to get the data.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetdefaultperfcounterha PDH_FUNCTION PdhGetDefaultPerfCounterHA(
// PDH_HLOG hDataSource, LPCSTR szMachineName, LPCSTR szObjectName, LPSTR szDefaultCounterName, LPDWORD pcchBufferSize );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "d1b3de9a-99ab-4339-8e9f-906f5a5d291d")]
public static extern Win32Error PdhGetDefaultPerfCounterH([Optional] PDH_HLOG hDataSource, [Optional] string szMachineName, string szObjectName, [Optional] StringBuilder szDefaultCounterName, ref uint pcchBufferSize);
/// <summary>
/// <para>
/// Retrieves the name of the default object. This name can be used to set the initial object selection in the Browse Counter dialog box.
/// </para>
/// <para>To use handles to data sources, use the PdhGetDefaultPerfObjectH function.</para>
/// </summary>
/// <param name="szDataSource">Should be <c>NULL</c>.</param>
/// <param name="szMachineName">
/// <c>Null</c>-terminated string that specifies the name of the computer used to verify the object name. If <c>NULL</c>, the local
/// computer is used to verify the name.
/// </param>
/// <param name="szDefaultObjectName">
/// <para>
/// Caller-allocated buffer that receives the <c>null</c>-terminated default object name. Set to <c>NULL</c> if the pcchBufferSize
/// parameter is zero.
/// </para>
/// <para>Note that PDH always returns Processor for the default object name.</para>
/// </param>
/// <param name="pcchBufferSize">
/// Size of the szDefaultObjectName buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this
/// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the
/// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you
/// should not rely on the returned size to reallocate the buffer.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The szDefaultObjectName buffer is too small to contain the object name. This return value is expected if pcchBufferSize is zero
/// on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the
/// returned size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A required parameter is not valid. For example, on some releases you could receive this error if the specified size on input is
/// greater than zero but less than the required size.
/// </term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>Unable to allocate memory in order to complete the function.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_MACHINE</term>
/// <term>The specified computer is offline or unavailable.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// You should call this function twice, the first time to get the required buffer size (set szDefaultObjectName to <c>NULL</c> and
/// pcchBufferSize to 0), and the second time to get the data.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetdefaultperfobjecta PDH_FUNCTION PdhGetDefaultPerfObjectA(
// LPCSTR szDataSource, LPCSTR szMachineName, LPSTR szDefaultObjectName, LPDWORD pcchBufferSize );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "7c6d4d82-8b60-4422-8108-8ac10f254278")]
public static extern Win32Error PdhGetDefaultPerfObject([Optional] string szDataSource, [Optional] string szMachineName, [Optional] StringBuilder szDefaultObjectName, ref uint pcchBufferSize);
/// <summary>
/// <para>
/// Retrieves the name of the default object. This name can be used to set the initial object selection in the Browse Counter dialog box.
/// </para>
/// <para>
/// This function is identical to the PdhGetDefaultPerfObject function, except that it supports the use of handles to data sources.
/// </para>
/// </summary>
/// <param name="hDataSource">Should be <c>NULL</c>.</param>
/// <param name="szMachineName">
/// <c>Null</c>-terminated string that specifies the name of the computer used to verify the object name. If <c>NULL</c>, the local
/// computer is used to verify the name.
/// </param>
/// <param name="szDefaultObjectName">
/// <para>
/// Caller-allocated buffer that receives the <c>null</c>-terminated default object name. Set to <c>NULL</c> if pcchBufferSize is zero.
/// </para>
/// <para>Note that PDH always returns Processor for the default object name.</para>
/// </param>
/// <param name="pcchBufferSize">
/// Size of the szDefaultObjectName buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this
/// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the
/// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you
/// should not rely on the returned size to reallocate the buffer.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The szDefaultObjectName buffer is too small to contain the object name. This return value is expected if pcchBufferSize is zero
/// on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the
/// returned size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A required parameter is not valid. For example, on some releases you could receive this error if the specified size on input is
/// greater than zero but less than the required size.
/// </term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>Unable to allocate memory in order to complete the function.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_MACHINE</term>
/// <term>The specified computer is offline or unavailable.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_COUNTERNAME</term>
/// <term>The default object name cannot be read or found.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// You should call this function twice, the first time to get the required buffer size (set szDefaultObjectName to <c>NULL</c> and
/// pcchBufferSize to 0), and the second time to get the data.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetdefaultperfobjectha PDH_FUNCTION PdhGetDefaultPerfObjectHA(
// PDH_HLOG hDataSource, LPCSTR szMachineName, LPSTR szDefaultObjectName, LPDWORD pcchBufferSize );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "4950d5b7-3a6f-410d-830f-7868aa84f6d5")]
public static extern Win32Error PdhGetDefaultPerfObjectH([Optional] PDH_HLOG hDataSource, [Optional] string szMachineName, [Optional] StringBuilder szDefaultObjectName, ref uint pcchBufferSize);
/// <summary>
/// <para>Returns the version of the currently installed Pdh.dll file.</para>
/// <para><c>Note</c> This function is obsolete and no longer supported.</para>
/// </summary>
/// <param name="lpdwVersion">
/// <para>Pointer to a variable that receives the version of Pdh.dll. This parameter can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_CVERSION_WIN50</term>
/// <term>The file version is a legacy operating system.</term>
/// </item>
/// <item>
/// <term>PDH_VERSION</term>
/// <term>The file version is Windows XP.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// </returns>
/// <remarks>This function is used to help in determining the functionality that the currently installed version of Pdh.dll supports.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetdllversion PDH_FUNCTION PdhGetDllVersion( LPDWORD lpdwVersion );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "09c9ecf6-43e0-480c-b607-537632b56576")]
public static extern Win32Error PdhGetDllVersion(out uint lpdwVersion);
/// <summary>
/// Returns an array of formatted counter values. Use this function when you want to format the counter values of a counter that
/// contains a wildcard character for the instance name.
/// </summary>
/// <param name="hCounter">
/// Handle to the counter whose current value you want to format. The PdhAddCounter function returns this handle.
/// </param>
/// <param name="dwFormat">
/// <para>Determines the data type of the formatted value. Specify one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_FMT_DOUBLE</term>
/// <term>Return data as a double-precision floating point real.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_LARGE</term>
/// <term>Return data as a 64-bit integer.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_LONG</term>
/// <term>Return data as a long integer.</term>
/// </item>
/// </list>
/// <para>You can use the bitwise inclusive OR operator (|) to combine the data type with one of the following scaling factors.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_FMT_NOSCALE</term>
/// <term>Do not apply the counter's default scaling factor.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_NOCAP100</term>
/// <term>
/// Counter values greater than 100 (for example, counter values measuring the processor load on multiprocessor computers) will not
/// be reset to 100. The default behavior is that counter values are capped at a value of 100.
/// </term>
/// </item>
/// <item>
/// <term>PDH_FMT_1000</term>
/// <term>Multiply the actual value by 1,000.</term>
/// </item>
/// </list>
/// </param>
/// <param name="lpdwBufferSize">
/// Size of the ItemBuffer buffer, in bytes. If zero on input, the function returns PDH_MORE_DATA and sets this parameter to the
/// required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size of the
/// buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not rely on
/// the returned size to reallocate the buffer.
/// </param>
/// <param name="lpdwItemCount">Number of counter values in the ItemBuffer buffer.</param>
/// <param name="ItemBuffer">
/// Caller-allocated buffer that receives an array of PDH_FMT_COUNTERVALUE_ITEM structures; the structures contain the counter
/// values. Set to <c>NULL</c> if lpdwBufferSize is zero.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The ItemBuffer buffer is not large enough to contain the object name. This return value is expected if lpdwBufferSize is zero on
/// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned
/// size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid or is incorrectly formatted. For example, on some releases you could receive this error if the specified
/// size on input is greater than zero but less than the required size.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The counter handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// You should call this function twice, the first time to get the required buffer size (set ItemBuffer to <c>NULL</c> and
/// lpdwBufferSize to 0), and the second time to get the data.
/// </para>
/// <para>
/// The data for the counter is locked for the duration of the call to <c>PdhGetFormattedCounterArray</c> to prevent any changes
/// during the processing of the call.
/// </para>
/// <para>Examples</para>
/// <para>The following example shows how to use this function.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetformattedcounterarraya PDH_FUNCTION
// PdhGetFormattedCounterArrayA( PDH_HCOUNTER hCounter, DWORD dwFormat, LPDWORD lpdwBufferSize, LPDWORD lpdwItemCount,
// PPDH_FMT_COUNTERVALUE_ITEM_A ItemBuffer );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "0f388c7e-d0c8-461d-908c-48af92166996")]
public static extern Win32Error PdhGetFormattedCounterArray(PDH_HCOUNTER hCounter, PDH_FMT dwFormat, ref uint lpdwBufferSize, out uint lpdwItemCount, [Optional] IntPtr ItemBuffer);
/// <summary>Computes a displayable value for the specified counter.</summary>
/// <param name="hCounter">
/// Handle of the counter for which you want to compute a displayable value. The PdhAddCounter function returns this handle.
/// </param>
/// <param name="dwFormat">
/// <para>Determines the data type of the formatted value. Specify one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_FMT_DOUBLE</term>
/// <term>Return data as a double-precision floating point real.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_LARGE</term>
/// <term>Return data as a 64-bit integer.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_LONG</term>
/// <term>Return data as a long integer.</term>
/// </item>
/// </list>
/// <para>You can use the bitwise inclusive OR operator (|) to combine the data type with one of the following scaling factors.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_FMT_NOSCALE</term>
/// <term>Do not apply the counter's default scaling factor.</term>
/// </item>
/// <item>
/// <term>PDH_FMT_NOCAP100</term>
/// <term>
/// Counter values greater than 100 (for example, counter values measuring the processor load on multiprocessor computers) will not
/// be reset to 100. The default behavior is that counter values are capped at a value of 100.
/// </term>
/// </item>
/// <item>
/// <term>PDH_FMT_1000</term>
/// <term>Multiply the actual value by 1,000.</term>
/// </item>
/// </list>
/// </param>
/// <param name="lpdwType">
/// Receives the counter type. For a list of counter types, see the Counter Types section of the Windows Server 2003 Deployment Kit.
/// This parameter is optional.
/// </param>
/// <param name="pValue">A PDH_FMT_COUNTERVALUE structure that receives the counter value.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>A parameter is not valid or is incorrectly formatted.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_DATA</term>
/// <term>The specified counter does not contain valid data or a successful status code.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The counter handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The data for the counter is locked (protected) for the duration of the call to <c>PdhGetFormattedCounterValue</c> 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.
/// </para>
/// <para>
/// Some counters, such as rate counters, require two counter values in order to compute a displayable value. In this case you must
/// call PdhCollectQueryData twice before calling <c>PdhGetFormattedCounterValue</c>. For more information, see Collecting
/// Performance Data.
/// </para>
/// <para>
/// If the specified counter instance does not exist, the method will return PDH_INVALID_DATA and set the <c>CStatus</c> member of
/// the PDH_FMT_COUNTERVALUE structure to PDH_CSTATUS_NO_INSTANCE.
/// </para>
/// <para>
/// <c>Prior to Windows Server 2003:</c> The format call may fail for counters that require only a single value when the instance is
/// not found. Try calling the query and format calls again. If the format call fails the second time, the instance is not found. As
/// an alternative, you can call the PdhEnumObjects function with the refresh option set to <c>TRUE</c> to refresh the counter
/// instances before querying and formatting the counter data.
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Browsing Performance Counters or Reading Performance Data from a Log File.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetformattedcountervalue PDH_FUNCTION
// PdhGetFormattedCounterValue( PDH_HCOUNTER hCounter, DWORD dwFormat, LPDWORD lpdwType, PPDH_FMT_COUNTERVALUE pValue );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "cd104b26-1498-4f95-a411-97d868b43836")]
public static extern Win32Error PdhGetFormattedCounterValue(PDH_HCOUNTER hCounter, PDH_FMT dwFormat, out CounterType lpdwType, out PDH_FMT_COUNTERVALUE pValue);
/// <summary>Returns the size of the specified log file.</summary>
/// <param name="hLog">Handle to the log file. The PdhOpenLog or PdhBindInputDataSource function returns this handle.</param>
/// <param name="llSize">Size of the log file, in bytes.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_LOG_FILE_OPEN_ERROR</term>
/// <term>An error occurred when trying to open the log file.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// If the log file handle points to multiple bound log files, the size is the sum of all the log files. If the log file is a SQL log
/// file, the llSize parameter is the number of records in the log file.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetlogfilesize PDH_FUNCTION PdhGetLogFileSize( PDH_HLOG hLog,
// LONGLONG *llSize );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "2bb94019-c664-4144-98b6-a0a545f7e4c1")]
public static extern Win32Error PdhGetLogFileSize(PDH_HLOG hLog, out long llSize);
/// <summary>
/// Returns an array of raw values from the specified counter. Use this function when you want to retrieve the raw counter values of
/// a counter that contains a wildcard character for the instance name.
/// </summary>
/// <param name="hCounter">
/// Handle of the counter for whose current raw instance values you want to retrieve. The PdhAddCounter function returns this handle.
/// </param>
/// <param name="lpdwBufferSize">
/// Size of the ItemBuffer buffer, in bytes. If zero on input, the function returns PDH_MORE_DATA and sets this parameter to the
/// required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size of the
/// buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not rely on
/// the returned size to reallocate the buffer.
/// </param>
/// <param name="lpdwItemCount">Number of raw counter values in the ItemBuffer buffer.</param>
/// <param name="ItemBuffer">
/// Caller-allocated buffer that receives the array of <see cref="PDH_RAW_COUNTER_ITEM"/> structures; the structures contain the raw
/// instance counter values. Set to <c>NULL</c> if lpdwBufferSize is zero.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The ItemBuffer buffer is not large enough to contain the object name. This return value is expected if lpdwBufferSize is zero on
/// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned
/// size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid or is incorrectly formatted. For example, on some releases you could receive this error if the specified
/// size on input is greater than zero but less than the required size.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The counter handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// You should call this function twice, the first time to get the required buffer size (set ItemBuffer to <c>NULL</c> and
/// lpdwBufferSize to 0), and the second time to get the data.
/// </para>
/// <para>
/// The data for the counter is locked for the duration of the call to <c>PdhGetRawCounterArray</c> to prevent any changes during
/// processing of the call.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetrawcounterarraya PDH_FUNCTION PdhGetRawCounterArrayA(
// PDH_HCOUNTER hCounter, LPDWORD lpdwBufferSize, LPDWORD lpdwItemCount, PPDH_RAW_COUNTER_ITEM_A ItemBuffer );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "03b30d08-6901-45cd-bd6d-d2672eb0f914")]
public static extern Win32Error PdhGetRawCounterArray(PDH_HCOUNTER hCounter, ref uint lpdwBufferSize, out uint lpdwItemCount, IntPtr ItemBuffer);
/// <summary>Returns the current raw value of the counter.</summary>
/// <param name="hCounter">
/// Handle of the counter from which to retrieve the current raw value. The PdhAddCounter function returns this handle.
/// </param>
/// <param name="lpdwType">
/// Receives the counter type. For a list of counter types, see the Counter Types section of the Windows Server 2003 Deployment Kit.
/// This parameter is optional.
/// </param>
/// <param name="pValue">A PDH_RAW_COUNTER structure that receives the counter value.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>A parameter is not valid or is incorrectly formatted.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The counter handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The data for the counter is locked (protected) for the duration of the call to <c>PdhGetRawCounterValue</c> to prevent any
/// changes during processing of the call.
/// </para>
/// <para>
/// If the specified counter instance does not exist, this function will return ERROR_SUCCESS and the <c>CStatus</c> member of the
/// PDH_RAW_COUNTER structure will contain PDH_CSTATUS_NO_INSTANCE.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetrawcountervalue PDH_FUNCTION PdhGetRawCounterValue(
// PDH_HCOUNTER hCounter, LPDWORD lpdwType, PPDH_RAW_COUNTER pValue );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "bb246c82-8748-4e2f-9f44-a206199aff90")]
public static extern Win32Error PdhGetRawCounterValue(PDH_HCOUNTER hCounter, out CounterType lpdwType, out PDH_RAW_COUNTER pValue);
/// <summary>Determines if the specified query is a real-time query.</summary>
/// <param name="hQuery">Handle to the query. The PdhOpenQuery function returns this handle.</param>
/// <returns>
/// <para>If the query is a real-time query, the return value is <c>TRUE</c>.</para>
/// <para>If the query is not a real-time query, the return value is <c>FALSE</c>.</para>
/// </returns>
/// <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.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhisrealtimequery BOOL PdhIsRealTimeQuery( PDH_HQUERY hQuery );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "4f6b2d8d-3a0f-4346-8b8e-a7aea11fbc40")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool PdhIsRealTimeQuery(PDH_HQUERY hQuery);
/// <summary>Returns the counter index corresponding to the specified counter name.</summary>
/// <param name="szMachineName">
/// <c>Null</c>-terminated string that specifies the name of the computer where the specified counter is located. The computer name
/// can be specified by the DNS name or the IP address. If <c>NULL</c>, the function uses the local computer.
/// </param>
/// <param name="szNameBuffer"><c>Null</c>-terminated string that contains the counter name.</param>
/// <param name="pdwIndex">Index of the counter.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following is a possible value.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>A parameter is not valid or is incorrectly formatted.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhlookupperfindexbynamea PDH_FUNCTION PdhLookupPerfIndexByNameA(
// LPCSTR szMachineName, LPCSTR szNameBuffer, LPDWORD pdwIndex );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "b8530bf3-0a9b-49c2-9494-4dca14cd57ef")]
public static extern Win32Error PdhLookupPerfIndexByName([Optional] string szMachineName, string szNameBuffer, out uint pdwIndex);
/// <summary>Returns the performance object name or counter name corresponding to the specified index.</summary>
/// <param name="szMachineName">
/// <c>Null</c>-terminated string that specifies the name of the computer where the specified performance object or counter is
/// located. The computer name can be specified by the DNS name or the IP address. If <c>NULL</c>, the function uses the local computer.
/// </param>
/// <param name="dwNameIndex">Index of the performance object or counter.</param>
/// <param name="szNameBuffer">
/// Caller-allocated buffer that receives the <c>null</c>-terminated name of the performance object or counter. Set to <c>NULL</c> if
/// pcchNameBufferSize is zero.
/// </param>
/// <param name="pcchNameBufferSize">
/// Size of the szNameBuffer buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this parameter
/// to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size
/// of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not
/// rely on the returned size to reallocate the buffer.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The szNameBuffer buffer is not large enough to contain the counter name. This return value is expected if pcchNameBufferSize is
/// zero on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the
/// returned size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid or is incorrectly formatted. For example, on some releases you could receive this error if the specified
/// size on input is greater than zero but less than the required size.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// You should call this function twice, the first time to get the required buffer size (set szNameBuffer to <c>NULL</c> and
/// pcchNameBufferSize to 0), and the second time to get the data.
/// </para>
/// <para>
/// <c>Windows XP:</c> You must specify a buffer and buffer size. The function sets pcchNameBufferSize to either the required size or
/// the size of the buffer that was used. If the buffer is too small, the function returns PDH_INSUFFICIENT_BUFFER instead of
/// PDH_MORE_DATA. The maximum string size in bytes is PDH_MAX_COUNTER_NAME * sizeof(TCHAR).
/// </para>
/// <para>
/// The index value that you specify must match one of the index values associated with the objects or counters that were loaded on
/// the computer. The index/name value pairs are stored in the <c>Counters</c> registry value in the following registry location.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhlookupperfnamebyindexa PDH_FUNCTION PdhLookupPerfNameByIndexA(
// LPCSTR szMachineName, DWORD dwNameIndex, LPSTR szNameBuffer, LPDWORD pcchNameBufferSize );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "6d5e1465-296b-4d8c-b0cb-aefdffb8539e")]
public static extern Win32Error PdhLookupPerfNameByIndex([Optional] string szMachineName, uint dwNameIndex, [Optional] StringBuilder szNameBuffer, ref uint pcchNameBufferSize);
/// <summary>Creates a full counter path using the members specified in the PDH_COUNTER_PATH_ELEMENTS structure.</summary>
/// <param name="pCounterPathElements">
/// <para>
/// A PDH_COUNTER_PATH_ELEMENTS structure that contains the members used to make up the path. Only the <c>szObjectName</c> and
/// <c>szCounterName</c> members are required, the others are optional.
/// </para>
/// <para>
/// If the instance name member is <c>NULL</c>, the path will not contain an instance reference and the <c>szParentInstance</c> and
/// <c>dwInstanceIndex</c> members will be ignored.
/// </para>
/// </param>
/// <param name="szFullPathBuffer">
/// Caller-allocated buffer that receives a <c>null</c>-terminated counter path. The maximum length of a counter path is
/// PDH_MAX_COUNTER_PATH. Set to <c>NULL</c> if pcchBufferSize is zero.
/// </param>
/// <param name="pcchBufferSize">
/// Size of the szFullPathBuffer buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this
/// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the
/// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you
/// should not rely on the returned size to reallocate the buffer.
/// </param>
/// <param name="dwFlags">
/// <para>Format of the input and output counter values. You can specify one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_PATH_WBEM_RESULT</term>
/// <term>Converts a PDH path to the WMI class and property name format.</term>
/// </item>
/// <item>
/// <term>PDH_PATH_WBEM_INPUT</term>
/// <term>Converts the WMI class and property name to a PDH path.</term>
/// </item>
/// <item>
/// <term>0</term>
/// <term>Returns the path in the PDH format, for example, \\computer\object(parent/instance#index)\counter.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The szFullPathBuffer buffer is too small to contain the counter name. This return value is expected if pcchBufferSize is zero on
/// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned
/// size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid or is incorrectly formatted. For example, on some releases you could receive this error if the specified
/// size on input is greater than zero but less than the required size.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// You should call this function twice, the first time to get the required buffer size (set szFullPathBuffer to <c>NULL</c> and
/// pcchBufferSize to 0), and the second time to get the data.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhmakecounterpatha PDH_FUNCTION PdhMakeCounterPathA(
// PPDH_COUNTER_PATH_ELEMENTS_A pCounterPathElements, LPSTR szFullPathBuffer, LPDWORD pcchBufferSize, DWORD dwFlags );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "f2dc5f77-9f9e-4290-95fa-ce2f1e81fc69")]
public static extern Win32Error PdhMakeCounterPath(in PDH_COUNTER_PATH_ELEMENTS pCounterPathElements, [Optional] StringBuilder szFullPathBuffer, ref uint pcchBufferSize, [Optional] PDH_PATH dwFlags);
/// <summary>Creates a full counter path using the members specified in the PDH_COUNTER_PATH_ELEMENTS structure.</summary>
/// <param name="pCounterPathElements">
/// <para>
/// A PDH_COUNTER_PATH_ELEMENTS structure that contains the members used to make up the path. Only the <c>szObjectName</c> and
/// <c>szCounterName</c> members are required, the others are optional.
/// </para>
/// <para>
/// If the instance name member is <c>NULL</c>, the path will not contain an instance reference and the <c>szParentInstance</c> and
/// <c>dwInstanceIndex</c> members will be ignored.
/// </para>
/// </param>
/// <param name="szFullPathBuffer">
/// Caller-allocated buffer that receives a <c>null</c>-terminated counter path. The maximum length of a counter path is
/// PDH_MAX_COUNTER_PATH. Set to <c>NULL</c> if pcchBufferSize is zero.
/// </param>
/// <param name="pcchBufferSize">
/// Size of the szFullPathBuffer buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this
/// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the
/// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you
/// should not rely on the returned size to reallocate the buffer.
/// </param>
/// <param name="dwFlags">
/// <para>Format of the input and output counter values. You can specify one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_PATH_WBEM_RESULT</term>
/// <term>Converts a PDH path to the WMI class and property name format.</term>
/// </item>
/// <item>
/// <term>PDH_PATH_WBEM_INPUT</term>
/// <term>Converts the WMI class and property name to a PDH path.</term>
/// </item>
/// <item>
/// <term>0</term>
/// <term>Returns the path in the PDH format, for example, \\computer\object(parent/instance#index)\counter.</term>
/// </item>
/// </list>
/// </param>
/// <param name="langId">The language identifier to be used in creating the path.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The szFullPathBuffer buffer is too small to contain the counter name. This return value is expected if pcchBufferSize is zero on
/// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned
/// size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid or is incorrectly formatted. For example, on some releases you could receive this error if the specified
/// size on input is greater than zero but less than the required size.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// You should call this function twice, the first time to get the required buffer size (set szFullPathBuffer to <c>NULL</c> and
/// pcchBufferSize to 0), and the second time to get the data.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhmakecounterpatha PDH_FUNCTION PdhMakeCounterPathA(
// PPDH_COUNTER_PATH_ELEMENTS_A pCounterPathElements, LPSTR szFullPathBuffer, LPDWORD pcchBufferSize, DWORD dwFlags );
[PInvokeData("pdh.h", MSDNShortId = "f2dc5f77-9f9e-4290-95fa-ce2f1e81fc69")]
public static Win32Error PdhMakeCounterPath(in PDH_COUNTER_PATH_ELEMENTS pCounterPathElements, [Optional] StringBuilder szFullPathBuffer, ref uint pcchBufferSize, PDH_PATH dwFlags, ushort langId) =>
PdhMakeCounterPath(pCounterPathElements, szFullPathBuffer, ref pcchBufferSize, PDH_PATH_LANG_FLAGS(langId, dwFlags));
/// <summary>Opens the specified log file for reading or writing.</summary>
/// <param name="szLogFileName">
/// <para>
/// <c>Null</c>-terminated string that specifies the name of the log file to open. The name can contain an absolute or relative path.
/// </para>
/// <para>
/// If the lpdwLogType parameter is <c>PDH_LOG_TYPE_SQL</c>, specify the name of the log file in the form, <c>SQL:</c> DataSourceName
/// <c>!</c> LogFileName.
/// </para>
/// </param>
/// <param name="dwAccessFlags">
/// <para>Type of access to use to open the log file. Specify one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_LOG_READ_ACCESS</term>
/// <term>Open the log file for reading.</term>
/// </item>
/// <item>
/// <term>PDH_LOG_WRITE_ACCESS</term>
/// <term>Open a new log file for writing.</term>
/// </item>
/// <item>
/// <term>PDH_LOG_UPDATE_ACCESS</term>
/// <term>Open an existing log file for writing.</term>
/// </item>
/// </list>
/// <para>
/// You can use the bitwise inclusive <c>OR</c> operator (|) to combine the access type with one or more of the following creation flags.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_LOG_CREATE_NEW</term>
/// <term>Creates a new log file with the specified name.</term>
/// </item>
/// <item>
/// <term>PDH_LOG_CREATE_ALWAYS</term>
/// <term>
/// Creates a new log file with the specified name. If the log file already exists, the function removes the existing log file before
/// creating the new file.
/// </term>
/// </item>
/// <item>
/// <term>PDH_LOG_OPEN_EXISTING</term>
/// <term>
/// Opens an existing log file with the specified name. If a log file with the specified name does not exist, this is equal to PDH_LOG_CREATE_NEW.
/// </term>
/// </item>
/// <item>
/// <term>PDH_LOG_OPEN_ALWAYS</term>
/// <term>Opens an existing log file with the specified name or creates a new log file with the specified name.</term>
/// </item>
/// <item>
/// <term>PDH_LOG_OPT_CIRCULAR</term>
/// <term>
/// Creates a circular log file with the specified name. When the file reaches the value of the dwMaxSize parameter, data wraps to
/// the beginning of the log file. You can specify this flag only if the lpdwLogType parameter is PDH_LOG_TYPE_BINARY.
/// </term>
/// </item>
/// <item>
/// <term>PDH_LOG_USER_STRING</term>
/// <term>
/// Used with PDH_LOG_TYPE_TSV to write the user caption or log file description indicated by the szUserString parameter of
/// PdhUpdateLog or PdhOpenLog. The user caption or log file description is written as the last column in the first line of the text log.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="lpdwLogType">
/// <para>Type of log file to open. This parameter can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_LOG_TYPE_UNDEFINED</term>
/// <term>
/// Undefined log file format. If specified, PDH determines the log file type. You cannot specify this value if the dwAccessFlags
/// parameter is PDH_LOG_WRITE_ACCESS.
/// </term>
/// </item>
/// <item>
/// <term>PDH_LOG_TYPE_CSV</term>
/// <term>
/// Text file containing column headers in the first line, and individual data records in each subsequent line. The fields of each
/// data record are comma-delimited. The first line also contains information about the format of the file, the PDH version used to
/// create the log file, and the names and paths of each of the counters.
/// </term>
/// </item>
/// <item>
/// <term>PDH_LOG_TYPE_SQL</term>
/// <term>The data source of the log file is an SQL database.</term>
/// </item>
/// <item>
/// <term>PDH_LOG_TYPE_TSV</term>
/// <term>
/// Text file containing column headers in the first line, and individual data records in each subsequent line. The fields of each
/// data record are tab-delimited. The first line also contains information about the format of the file, the PDH version used to
/// create the log file, and the names and paths of each of the counters.
/// </term>
/// </item>
/// <item>
/// <term>PDH_LOG_TYPE_BINARY</term>
/// <term>Binary log file format.</term>
/// </item>
/// </list>
/// </param>
/// <param name="hQuery">
/// <para>Specify a query handle if you are writing query data to a log file. The PdhOpenQuery function returns this handle.</para>
/// <para>This parameter is ignored and should be <c>NULL</c> if you are reading from the log file.</para>
/// </param>
/// <param name="dwMaxSize">
/// <para>
/// Maximum size of the log file, in bytes. Specify the maximum size if you want to limit the file size or if dwAccessFlags specifies
/// <c>PDH_LOG_OPT_CIRCULAR</c>; otherwise, set to 0.
/// </para>
/// <para>
/// For circular log files, you must specify a value large enough to hold at least one sample. Sample size depends on data being
/// collected. However, specifying a value of at least one megabyte will cover most samples.
/// </para>
/// </param>
/// <param name="szUserCaption">
/// <c>Null</c>-terminated string that specifies 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.
/// </param>
/// <param name="phLog">Handle to the opened log file.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code.</para>
/// </returns>
/// <remarks>
/// <para>
/// To use this function to write performance data to a log file, you must open a query using PdhOpenQuery and add the desired
/// counters to it, before calling this function.
/// </para>
/// <para>
/// Newer operating systems can read log files that were generated on older operating systems; however, log files that were created
/// on Windows Vista and later operating systems cannot be read on earlier operating systems.
/// </para>
/// <para>The following rules apply to log files</para>
/// <list type="bullet">
/// <item>
/// <term/>
/// </item>
/// <item>
/// <term/>
/// </item>
/// <item>
/// <term/>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>For an example, see Writing Performance Data to a Log File.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhopenloga PDH_FUNCTION PdhOpenLogA( LPCSTR szLogFileName, DWORD
// dwAccessFlags, LPDWORD lpdwLogType, PDH_HQUERY hQuery, DWORD dwMaxSize, LPCSTR szUserCaption, PDH_HLOG *phLog );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "a8457959-af3a-497f-91ca-0876cbb552cc")]
public static extern Win32Error PdhOpenLog(string szLogFileName, PdhLogAccess dwAccessFlags, ref PDH_LOG_TYPE lpdwLogType, [Optional] PDH_HQUERY hQuery, [Optional] uint dwMaxSize, [Optional] string szUserCaption, out SafePDH_HLOG phLog);
/// <summary>
/// <para>Creates a new query that is used to manage the collection of performance data.</para>
/// <para>To use handles to data sources, use the PdhOpenQueryH function.</para>
/// </summary>
/// <param name="szDataSource">
/// <c>Null</c>-terminated string that specifies the name of the log file from which to retrieve performance data. If <c>NULL</c>,
/// performance data is collected from a real-time data source.
/// </param>
/// <param name="dwUserData">
/// User-defined value to associate with this query. To retrieve the user data later, call PdhGetCounterInfo and access the
/// <c>dwQueryUserData</c> member of PDH_COUNTER_INFO.
/// </param>
/// <param name="phQuery">Handle to the query. You use this handle in subsequent calls.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhopenquerya PDH_FUNCTION PdhOpenQueryA( LPCSTR szDataSource,
// DWORD_PTR dwUserData, PDH_HQUERY *phQuery );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "ec4e5353-c7f5-4957-b7f4-39df508846a0")]
public static extern Win32Error PdhOpenQuery([Optional] string szDataSource, [Optional] IntPtr dwUserData, out SafePDH_HQUERY phQuery);
/// <summary>
/// <para>Creates a new query that is used to manage the collection of performance data.</para>
/// <para>This function is identical to the PdhOpenQuery function, except that it supports the use of handles to data sources.</para>
/// </summary>
/// <param name="hDataSource">Handle to a data source returned by the PdhBindInputDataSource function.</param>
/// <param name="dwUserData">
/// User-defined value to associate with this query. To retrieve the user data later, call the PdhGetCounterInfo function and access
/// the <c>dwQueryUserData</c> member of PDH_COUNTER_INFO.
/// </param>
/// <param name="phQuery">Handle to the query. You use this handle in subsequent calls.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhopenqueryh PDH_FUNCTION PdhOpenQueryH( PDH_HLOG hDataSource,
// DWORD_PTR dwUserData, PDH_HQUERY *phQuery );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "068c55da-d7e0-4111-91c8-a2bbd676f99d")]
public static extern Win32Error PdhOpenQueryH([Optional] PDH_HLOG hDataSource, [Optional] IntPtr dwUserData, out SafePDH_HQUERY phQuery);
/// <summary>Parses the elements of the counter path and stores the results in the PDH_COUNTER_PATH_ELEMENTS structure.</summary>
/// <param name="szFullPathBuffer">
/// <c>Null</c>-terminated string that contains the counter path to parse. The maximum length of a counter path is PDH_MAX_COUNTER_PATH.
/// </param>
/// <param name="pCounterPathElements">
/// Caller-allocated buffer that receives a PDH_COUNTER_PATH_ELEMENTS structure. The structure contains pointers to the individual
/// string elements of the path referenced by the szFullPathBuffer parameter. The function appends the strings to the end of the
/// <c>PDH_COUNTER_PATH_ELEMENTS</c> structure. The allocated buffer should be large enough for the structure and the strings. Set to
/// <c>NULL</c> if pdwBufferSize is zero.
/// </param>
/// <param name="pdwBufferSize">
/// Size of the pCounterPathElements buffer, in bytes. If zero on input, the function returns PDH_MORE_DATA and sets this parameter
/// to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size
/// of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not
/// rely on the returned size to reallocate the buffer.
/// </param>
/// <param name="dwFlags">Reserved. Must be zero.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>A parameter is not valid.</term>
/// </item>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The pCounterPathElements buffer is too small to contain the path elements. This return value is expected if pdwBufferSize is zero
/// on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the
/// returned size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_PATH</term>
/// <term>
/// The path is not formatted correctly and cannot be parsed. For example, on some releases you could receive this error if the
/// specified size on input is greater than zero but less than the required size.
/// </term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>Unable to allocate memory in order to complete the function.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// You should call this function twice, the first time to get the required buffer size (set pCounterPathElements to <c>NULL</c> and
/// pdwBufferSize to 0), and the second time to get the data.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhparsecounterpatha PDH_FUNCTION PdhParseCounterPathA( LPCSTR
// szFullPathBuffer, PPDH_COUNTER_PATH_ELEMENTS_A pCounterPathElements, LPDWORD pdwBufferSize, DWORD dwFlags );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "760b94e9-88df-4f7d-92e9-333d682779f6")]
public static extern Win32Error PdhParseCounterPath(string szFullPathBuffer, [Optional] IntPtr pCounterPathElements, ref uint pdwBufferSize, uint dwFlags = 0);
/// <summary>Parses the elements of an instance string.</summary>
/// <param name="szInstanceString">
/// <para>
/// <c>Null</c>-terminated string that specifies the instance string to parse into individual components. This string can contain the
/// following formats, and is less than MAX_PATH characters in length:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>instance</term>
/// </item>
/// <item>
/// <term>instance#index</term>
/// </item>
/// <item>
/// <term>parent/instance</term>
/// </item>
/// <item>
/// <term>parent/instance#index</term>
/// </item>
/// </list>
/// </param>
/// <param name="szInstanceName">
/// Caller-allocated buffer that receives the <c>null</c>-terminated instance name. Set to <c>NULL</c> if pcchInstanceNameLength is zero.
/// </param>
/// <param name="pcchInstanceNameLength">
/// Size of the szInstanceName buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this parameter
/// to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size
/// of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not
/// rely on the returned size to reallocate the buffer.
/// </param>
/// <param name="szParentName">
/// Caller-allocated buffer that receives the <c>null</c>-terminated name of the parent instance, if one is specified. Set to
/// <c>NULL</c> if pcchParentNameLength is zero.
/// </param>
/// <param name="pcchParentNameLength">
/// Size of the szParentName buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this parameter
/// to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size
/// of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not
/// rely on the returned size to reallocate the buffer.
/// </param>
/// <param name="lpIndex">
/// Index value of the instance. If an index entry is not present in the string, then this value is zero. This parameter can be <c>NULL</c>.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater
/// than zero but less than the required size.
/// </term>
/// </item>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// One or both of the string buffers are too small to contain the data. This return value is expected if the corresponding size
/// buffer is zero on input. If the specified size on input is greater than zero but less than the required size, you should not rely
/// on the returned size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_INVALID_INSTANCE</term>
/// <term>The instance string is incorrectly formatted, exceeds MAX_PATH characters in length, or cannot be parsed.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// You should call this function twice, the first time to get the required buffer size (set the buffers to <c>NULL</c> and buffer
/// sizes to 0), and the second time to get the data.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhparseinstancenamea PDH_FUNCTION PdhParseInstanceNameA( LPCSTR
// szInstanceString, LPSTR szInstanceName, LPDWORD pcchInstanceNameLength, LPSTR szParentName, LPDWORD pcchParentNameLength, LPDWORD
// lpIndex );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "8304ecee-5141-450a-be11-838b9f52413b")]
public static extern Win32Error PdhParseInstanceName(string szInstanceString, [Optional] StringBuilder szInstanceName, ref uint pcchInstanceNameLength, [Optional] StringBuilder szParentName, ref uint pcchParentNameLength, out uint lpIndex);
/// <summary>Reads the information in the specified binary trace log file.</summary>
/// <param name="hLog">Handle to the log file. The PdhOpenLog or PdhBindInputDataSource function returns this handle.</param>
/// <param name="ftRecord">
/// Time stamp of the record to be read. If the time stamp does not match a record in the log file, the function returns the record
/// that has a time stamp closest to (but not greater than) the given time stamp.
/// </param>
/// <param name="pRawLogRecord">
/// Caller-allocated buffer that receives a <see cref="PDH_RAW_LOG_RECORD"/> structure; the structure contains the log file record
/// information. Set to <c>NULL</c> if pdwBufferLength is zero.
/// </param>
/// <param name="pdwBufferLength">
/// Size of the pRawLogRecord buffer, in <c>TCHARs</c>. If zero on input, the function returns PDH_MORE_DATA and sets this parameter
/// to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size
/// of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not
/// rely on the returned size to reallocate the buffer.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>
/// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater
/// than zero but less than the required size.
/// </term>
/// </item>
/// <item>
/// <term>PDH_MORE_DATA</term>
/// <term>
/// The pRawLogRecord buffer is too small to contain the path elements. This return value is expected if pdwBufferLength is zero on
/// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned
/// size to reallocate the buffer.
/// </term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>Unable to allocate memory in order to complete the function.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// You should call this function twice, the first time to get the required buffer size (set pRawLogRecord to <c>NULL</c> and
/// pdwBufferLength to 0), and the second time to get the data.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhreadrawlogrecord PDH_FUNCTION PdhReadRawLogRecord( PDH_HLOG hLog,
// FILETIME ftRecord, PPDH_RAW_LOG_RECORD pRawLogRecord, LPDWORD pdwBufferLength );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "fb93b6ea-ca31-4ff1-a553-b02388be8b72")]
public static extern Win32Error PdhReadRawLogRecord(PDH_HLOG hLog, FILETIME ftRecord, [Optional] IntPtr pRawLogRecord, ref uint pdwBufferLength);
/// <summary>Removes a counter from a query.</summary>
/// <param name="hCounter">Handle of the counter to remove from its query. The PdhAddCounter function returns this handle.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code.</para>
/// <para>The following is a possible value.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The counter handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>Do not use the counter handle after removing the counter from the query.</para>
/// <para>The following shows the syntax if calling this function from Visual Basic.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhremovecounter PDH_FUNCTION PdhRemoveCounter( PDH_HCOUNTER
// hCounter );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "adf9c7bd-47d6-489a-88fc-954fdf127ce8")]
public static extern Win32Error PdhRemoveCounter(PDH_HCOUNTER hCounter);
/// <summary>Displays a dialog window that prompts the user to specify the source of the performance data.</summary>
/// <param name="hWndOwner">Owner of the dialog window. This can be <c>NULL</c> if there is no owner (the desktop becomes the owner).</param>
/// <param name="dwFlags">
/// <para>Dialog boxes that will be displayed to prompt for the data source. This parameter can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_FLAGS_FILE_BROWSER_ONLY</term>
/// <term>Display the file browser only. Set this flag when you want to prompt for the name and location of a log file only.</term>
/// </item>
/// <item>
/// <term>0</term>
/// <term>
/// Display the data source selection dialog box. The dialog box lets the user select performance data 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.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="szDataSource">
/// <para>
/// Caller-allocated buffer that receives a <c>null</c>-terminated string that contains the name of a log file that the user
/// selected. The log file name is truncated to the size of the buffer if the buffer is too small.
/// </para>
/// <para>If the user selected a real time source, the buffer is empty.</para>
/// </param>
/// <param name="pcchBufferLength">Maximum size of the szDataSource buffer, in <c>TCHARs</c>.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>The length of the buffer passed in the pcchBufferLength is not equal to the actual length of the szDataSource buffer.</term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>A zero-length buffer was passed in the szDataSource parameter.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhselectdatasourcea PDH_FUNCTION PdhSelectDataSourceA( HWND
// hWndOwner, DWORD dwFlags, LPSTR szDataSource, LPDWORD pcchBufferLength );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "211d4504-e1f9-48a0-8ddd-613f2f183c59")]
public static extern Win32Error PdhSelectDataSource([Optional] HWND hWndOwner, PdhSelectDataSourceFlags dwFlags, StringBuilder szDataSource, ref uint pcchBufferLength);
/// <summary>
/// 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.
/// </summary>
/// <param name="hCounter">Handle of the counter to apply the scale factor to. The PdhAddCounter function returns this handle.</param>
/// <param name="lFactor">
/// Power of ten by which to multiply the calculated value before returning it. The minimum value of this parameter is PDH_MIN_SCALE
/// (7), where the returned value is the actual value multiplied by 10⁷. The maximum value of this parameter is PDH_MAX_SCALE (+7),
/// where the returned value is the actual value multiplied by 10⁺⁷. A value of zero will set the scale to one, so that the actual
/// value is returned.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>The scale value is out of range.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The counter handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhsetcounterscalefactor PDH_FUNCTION PdhSetCounterScaleFactor(
// PDH_HCOUNTER hCounter, LONG lFactor );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "6db99e03-0b03-4c1c-b82a-2982b52746db")]
public static extern Win32Error PdhSetCounterScaleFactor(PDH_HCOUNTER hCounter, int lFactor);
/// <summary>Specifies the source of the real-time data.</summary>
/// <param name="dwDataSourceId">
/// <para>Source of the performance data. This parameter can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>DATA_SOURCE_REGISTRY</term>
/// <term>The data source is the registry interface. This is the default.</term>
/// </item>
/// <item>
/// <term>DATA_SOURCE_WBEM</term>
/// <term>The data source is a WMI provider.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following is a possible value.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>The parameter is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// 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.
/// </para>
/// <para>
/// If you want to query real-time data from WMI, you must call <c>PdhSetDefaultRealTimeDataSource</c> to set the default real-time
/// data source. You must call this function before calling any other PDH API function.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhsetdefaultrealtimedatasource PDH_FUNCTION
// PdhSetDefaultRealTimeDataSource( DWORD dwDataSourceId );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "5a46ac26-c1a1-40c1-a328-688e0b394e18")]
public static extern Win32Error PdhSetDefaultRealTimeDataSource(uint dwDataSourceId);
/// <summary>Limits the samples that you can read from a log file to those within the specified time range, inclusively.</summary>
/// <param name="hQuery">Handle to the query. The PdhOpenQuery function returns this handle.</param>
/// <param name="pInfo">
/// A PDH_TIME_INFO structure that specifies the time range. Specify the time as local file time. The end time must be greater than
/// the start time. You can specify 0 for the start time and the maximum 64-bit value for the end time if you want to read all records.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The query handle is not valid.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>The ending time range value must be greater than the starting time range value.</term>
/// </item>
/// </list>
/// </returns>
/// <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.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhsetquerytimerange PDH_FUNCTION PdhSetQueryTimeRange( PDH_HQUERY
// hQuery, PPDH_TIME_INFO pInfo );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "ed0e100e-9f82-48c0-b4bb-72820c5eeaa8")]
public static extern Win32Error PdhSetQueryTimeRange(PDH_HQUERY hQuery, in PDH_TIME_INFO pInfo);
/// <summary>Collects counter data for the current query and writes the data to the log file.</summary>
/// <param name="hLog">Handle of a single log file to update. The PdhOpenLog function returns this handle.</param>
/// <param name="szUserString">
/// Null-terminated string that contains a user-defined comment to add to the data record. The string can not be empty.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The log file handle is not valid.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_ARGUMENT</term>
/// <term>An empty string was passed in the szUserString parameter.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>If you are updating a log file from another log file, the comments from the other log file do not migrate.</para>
/// <para>Examples</para>
/// <para>For an example, see Writing Performance Data to a Log File.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhupdateloga PDH_FUNCTION PdhUpdateLogA( PDH_HLOG hLog, LPCSTR
// szUserString );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "b2052275-6944-41f4-92ac-38967ed270f3")]
public static extern Win32Error PdhUpdateLog(PDH_HLOG hLog, string szUserString);
/// <summary>
/// <para>Synchronizes the information in the log file catalog with the performance data in the log file.</para>
/// <para><c>Note</c> This function is obsolete.</para>
/// </summary>
/// <param name="hLog">Handle to the log file containing the file catalog to update. The PdhOpenLog function.</param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_NOT_IMPLEMENTED</term>
/// <term>A handle to a CSV or TSV log file was specified. These log file types do not have catalogs.</term>
/// </item>
/// <item>
/// <term>PDH_UNKNOWN_LOG_FORMAT</term>
/// <term>A handle to a log file with an unknown format was specified.</term>
/// </item>
/// <item>
/// <term>PDH_INVALID_HANDLE</term>
/// <term>The handle is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// 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.
/// </para>
/// <para>
/// 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.
/// </para>
/// <para>
/// 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.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhupdatelogfilecatalog PDH_FUNCTION PdhUpdateLogFileCatalog(
// PDH_HLOG hLog );
[DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)]
[PInvokeData("pdh.h", MSDNShortId = "e8aa8462-48f1-4ccd-8c41-a7358975e056")]
public static extern Win32Error PdhUpdateLogFileCatalog(PDH_HLOG hLog);
/// <summary>Validates that the counter is present on the computer specified in the counter path.</summary>
/// <param name="szFullPathBuffer">
/// Null-terminated string that contains the counter path to validate. The maximum length of a counter path is PDH_MAX_COUNTER_PATH.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_CSTATUS_NO_INSTANCE</term>
/// <term>The specified instance of the performance object was not found.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_COUNTER</term>
/// <term>The specified counter was not found in the performance object.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_OBJECT</term>
/// <term>The specified performance object was not found on the computer.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_MACHINE</term>
/// <term>The specified computer could not be found or connected to.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_BAD_COUNTERNAME</term>
/// <term>The counter path string could not be parsed.</term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>The function is unable to allocate a required temporary buffer.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhvalidatepatha PDH_FUNCTION PdhValidatePathA( LPCSTR
// szFullPathBuffer );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "9248e63c-2672-466f-85f5-46f26e31dc75")]
public static extern Win32Error PdhValidatePath(string szFullPathBuffer);
/// <summary>Validates that the specified counter is present on the computer or in the log file.</summary>
/// <param name="hDataSource">
/// <para>Handle to the data source. The PdhOpenLog and PdhBindInputDataSource functions return this handle.</para>
/// <para>To validate that the counter is present on the local computer, specify <c>NULL</c> (this is the same as calling PdhValidatePath).</para>
/// </param>
/// <param name="szFullPathBuffer">
/// <c>Null</c>-terminated string that specifies the counter path to validate. The maximum length of a counter path is PDH_MAX_COUNTER_PATH.
/// </param>
/// <returns>
/// <para>If the function succeeds, it returns ERROR_SUCCESS.</para>
/// <para>If the function fails, the return value is a system error code or a PDH error code. The following are possible values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>PDH_CSTATUS_NO_INSTANCE</term>
/// <term>The specified instance of the performance object was not found.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_COUNTER</term>
/// <term>The specified counter was not found in the performance object.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_OBJECT</term>
/// <term>The specified performance object was not found on the computer or in the log file.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_NO_MACHINE</term>
/// <term>The specified computer could not be found or connected to.</term>
/// </item>
/// <item>
/// <term>PDH_CSTATUS_BAD_COUNTERNAME</term>
/// <term>The counter path string could not be parsed.</term>
/// </item>
/// <item>
/// <term>PDH_MEMORY_ALLOCATION_FAILURE</term>
/// <term>The function is unable to allocate a required temporary buffer.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhvalidatepathexw PDH_FUNCTION PdhValidatePathExW( PDH_HLOG
// hDataSource, LPCWSTR szFullPathBuffer );
[DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("pdh.h", MSDNShortId = "e6b52af7-7276-4565-aa61-73899796a13c")]
public static extern Win32Error PdhValidatePathExW(PDH_HLOG hDataSource, string szFullPathBuffer);
private static PDH_PATH PDH_PATH_LANG_FLAGS(ushort LangId, PDH_PATH Flags) => (PDH_PATH)(((LangId & 0x0000FFFF) << 16) | ((int)Flags & 0x0000FFFF));
/// <summary>
/// The <c>PDH_BROWSE_DLG_CONFIG</c> structure is used by the PdhBrowseCounters function to configure the <c>Browse Performance
/// Counters</c> dialog box.
/// </summary>
/// <remarks>
/// Each time the Add button is clicked, the <c>szReturnPathBuffer</c> buffer contains the selected counter and the <c>pCallBack</c>
/// callback function is called. The callback function should call the PdhAddCounter function for each counter in the buffer.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_browse_dlg_config_a typedef struct _BrowseDlgConfig_A { DWORD
// bIncludeInstanceIndex : 1; DWORD bSingleCounterPerAdd : 1; DWORD bSingleCounterPerDialog : 1; DWORD bLocalCountersOnly : 1; DWORD
// bWildCardInstances : 1; DWORD bHideDetailBox : 1; DWORD bInitializePath : 1; DWORD bDisableMachineSelection : 1; DWORD
// bIncludeCostlyObjects : 1; DWORD bShowObjectBrowser : 1; DWORD bReserved : 22; HWND hWndOwner; LPSTR szDataSource; LPSTR
// szReturnPathBuffer; DWORD cchReturnPathLength; CounterPathCallBack pCallBack; DWORD_PTR dwCallBackArg; PDH_STATUS CallBackStatus;
// DWORD dwDefaultDetailLevel; LPSTR szDialogBoxCaption; } PDH_BROWSE_DLG_CONFIG_A, *PPDH_BROWSE_DLG_CONFIG_A;
[PInvokeData("pdh.h", MSDNShortId = "8e045e0b-c157-4527-902c-6096c7922642")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct PDH_BROWSE_DLG_CONFIG
{
/// <summary/>
public BrowseFlag Flags;
/// <summary>Handle of the window to own the dialog. If <c>NULL</c>, the owner is the desktop.</summary>
public HWND hWndOwner;
/// <summary>
/// Pointer to a <c>null</c>-terminated string that specifies the name of the log file from which the list of counters is
/// retrieved. If <c>NULL</c>, the list of counters is retrieved from the local computer (or remote computer if specified).
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)] public string szDataSource;
/// <summary>
/// <para>Pointer to a MULTI_SZ that contains the selected counter paths.</para>
/// <para>
/// If <c>bInitializePath</c> is <c>TRUE</c>, you can use this member to specify a counter path whose components are used to
/// highlight entries in computer, object, counter, and instance lists when the dialog is first displayed.
/// </para>
/// </summary>
public IntPtr szReturnPathBuffer;
/// <summary>
/// Size of the <c>szReturnPathBuffer</c> buffer, in <c>TCHARs</c>. If the callback function reallocates a new buffer, it must
/// also update this value.
/// </summary>
public uint cchReturnPathLength;
/// <summary>Pointer to the callback function that processes the user's selection. For more information, see CounterPathCallBack.</summary>
public CounterPathCallBack pCallBack;
/// <summary>Caller-defined value that is passed to the callback function.</summary>
public IntPtr dwCallBackArg;
/// <summary>
/// <para>
/// 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.
/// </para>
/// <para>
/// If the buffer is too small to load the current selection, the dialog sets this value to PDH_MORE_DATA. If this value is
/// ERROR_SUCCESS, then the <c>szReturnPathBuffer</c> member contains a valid counter path or counter path list.
/// </para>
/// <para>
/// If the callback function reallocates a new buffer, it should set this member to PDH_RETRY so that the dialog will try to load
/// the buffer with the selected paths and call the callback function again.
/// </para>
/// <para>If some other error occurred, then the callback function should return the appropriate PDH error status value.</para>
/// </summary>
public Win32Error CallBackStatus;
/// <summary>
/// <para>
/// Default detail level to show in the <c>Detail level</c> list if <c>bHideDetailBox</c> is <c>FALSE</c>. If
/// <c>bHideDetailBox</c> is <c>TRUE</c>, the dialog uses this value to filter the displayed performance counters and objects.
/// You can specify one of the following values:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Detail level</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PERF_DETAIL_NOVICE</term>
/// <term>A novice user can understand the counter data.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_ADVANCED</term>
/// <term>The counter data is provided for advanced users.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_EXPERT</term>
/// <term>The counter data is provided for expert users.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_WIZARD</term>
/// <term>The counter data is provided for system designers.</term>
/// </item>
/// </list>
/// </summary>
public PERF_DETAIL dwDefaultDetailLevel;
/// <summary>
/// Pointer to a <c>null</c>-terminated string that specifies the optional caption to display in the caption bar of the dialog
/// box. If this member is <c>NULL</c>, the caption will be <c>Browse Performance Counters</c>.
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)] public string szDialogBoxCaption;
/// <summary>On return, gets the selected counter paths.</summary>
public string[] CounterPaths => szReturnPathBuffer.ToStringEnum(CharSet.Auto, 0, cchReturnPathLength).ToArray();
}
/// <summary>
/// The <c>PDH_BROWSE_DLG_CONFIG_H</c> structure is used by the PdhBrowseCountersH function to configure the <c>Browse Performance
/// Counters</c> dialog box.
/// </summary>
/// <remarks>
/// Each time the Add button is clicked, the <c>szReturnPathBuffer</c> buffer contains the selected counter and the <c>pCallBack</c>
/// callback function is called. The callback function should call the PdhAddCounter function for each counter in the buffer.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_browse_dlg_config_ha typedef struct _BrowseDlgConfig_HA { DWORD
// bIncludeInstanceIndex : 1; DWORD bSingleCounterPerAdd : 1; DWORD bSingleCounterPerDialog : 1; DWORD bLocalCountersOnly : 1; DWORD
// bWildCardInstances : 1; DWORD bHideDetailBox : 1; DWORD bInitializePath : 1; DWORD bDisableMachineSelection : 1; DWORD
// bIncludeCostlyObjects : 1; DWORD bShowObjectBrowser : 1; DWORD bReserved : 22; HWND hWndOwner; PDH_HLOG hDataSource; LPSTR
// szReturnPathBuffer; DWORD cchReturnPathLength; CounterPathCallBack pCallBack; DWORD_PTR dwCallBackArg; PDH_STATUS CallBackStatus;
// DWORD dwDefaultDetailLevel; LPSTR szDialogBoxCaption; } PDH_BROWSE_DLG_CONFIG_HA, *PPDH_BROWSE_DLG_CONFIG_HA;
[PInvokeData("pdh.h", MSDNShortId = "db30ff94-3238-45a0-a78e-8b3cd00ec79c")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct PDH_BROWSE_DLG_CONFIG_H
{
/// <summary/>
public BrowseFlag Flags;
/// <summary>Handle of the window to own the dialog. If <c>NULL</c>, the owner is the desktop.</summary>
public HWND hWndOwner;
/// <summary>Handle to a data source returned by the PdhBindInputDataSource function.</summary>
public PDH_HLOG hDataSource;
/// <summary>
/// <para>Pointer to a MULTI_SZ that contains the selected counter paths.</para>
/// <para>
/// If <c>bInitializePath</c> is <c>TRUE</c>, you can use this member to specify a counter path whose components are used to
/// highlight entries in computer, object, counter, and instance lists when the dialog is first displayed.
/// </para>
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)] public string szReturnPathBuffer;
/// <summary>
/// Size of the <c>szReturnPathBuffer</c> buffer, in <c>TCHARs</c>. If the callback function reallocates a new buffer, it must
/// also update this value.
/// </summary>
public uint cchReturnPathLength;
/// <summary>Pointer to the callback function that processes the user's selection. For more information, see CounterPathCallBack.</summary>
public CounterPathCallBack pCallBack;
/// <summary>Caller-defined value that is passed to the callback function.</summary>
public IntPtr dwCallBackArg;
/// <summary>
/// <para>
/// 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.
/// </para>
/// <para>
/// If the buffer is too small to load the current selection, the dialog sets this value to PDH_MORE_DATA. If this value is
/// ERROR_SUCCESS, then the <c>szReturnPathBuffer</c> member contains a valid counter path or counter path list.
/// </para>
/// <para>
/// If the callback function reallocates a new buffer, it should set this member to PDH_RETRY so that the dialog will try to load
/// the buffer with the selected paths and call the callback function again.
/// </para>
/// <para>If some other error occurred, then the callback function should return the appropriate PDH error status value.</para>
/// </summary>
public Win32Error CallBackStatus;
/// <summary>
/// <para>
/// Default detail level to show in the <c>Detail level</c> list if <c>bHideDetailBox</c> is <c>FALSE</c>. If
/// <c>bHideDetailBox</c> is <c>TRUE</c>, the dialog uses this value to filter the displayed performance counters and objects.
/// You can specify one of the following values:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Detail level</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PERF_DETAIL_NOVICE</term>
/// <term>A novice user can understand the counter data.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_ADVANCED</term>
/// <term>The counter data is provided for advanced users.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_EXPERT</term>
/// <term>The counter data is provided for expert users.</term>
/// </item>
/// <item>
/// <term>PERF_DETAIL_WIZARD</term>
/// <term>The counter data is provided for system designers.</term>
/// </item>
/// </list>
/// </summary>
public PERF_DETAIL dwDefaultDetailLevel;
/// <summary>
/// Pointer to a <c>null</c>-terminated string that specifies the optional caption to display in the caption bar of the dialog
/// box. If this member is <c>NULL</c>, the caption will be <c>Browse Performance Counters</c>.
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)] public string szDialogBoxCaption;
}
/// <summary>
/// The <c>PDH_COUNTER_INFO</c> structure contains information describing the properties of a counter. This information also includes
/// the counter path.
/// </summary>
/// <remarks>
/// When you allocate memory for this structure, allocate enough memory for the member strings, such as <c>szCounterName</c>, that
/// are appended to the end of this structure.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_counter_info_a typedef struct _PDH_COUNTER_INFO_A { DWORD
// dwLength; DWORD dwType; DWORD CVersion; DWORD CStatus; LONG lScale; LONG lDefaultScale; DWORD_PTR dwUserData; DWORD_PTR
// dwQueryUserData; LPSTR szFullPath; union { PDH_DATA_ITEM_PATH_ELEMENTS_A DataItemPath; PDH_COUNTER_PATH_ELEMENTS_A CounterPath;
// struct { LPSTR szMachineName; LPSTR szObjectName; LPSTR szInstanceName; LPSTR szParentInstance; DWORD dwInstanceIndex; LPSTR
// szCounterName; }; }; LPSTR szExplainText; DWORD DataBuffer[1]; } PDH_COUNTER_INFO_A, *PPDH_COUNTER_INFO_A;
[PInvokeData("pdh.h", MSDNShortId = "c9ede50e-85de-4a68-b539-54285c2599cb")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct PDH_COUNTER_INFO
{
/// <summary>Size of the structure, including the appended strings, in bytes.</summary>
public uint dwLength;
/// <summary>
/// Counter type. For a list of counter types, see the Counter Types section of the Windows Server 2003 Deployment Kit. The
/// counter type constants are defined in Winperf.h.
/// </summary>
public CounterType dwType;
/// <summary>Counter version information. Not used.</summary>
public uint CVersion;
/// <summary>
/// Counter status that indicates if the counter value is valid. For a list of possible values, see Checking PDH Interface Return Values.
/// </summary>
public uint CStatus;
/// <summary>
/// Scale factor to use when computing the displayable value of the counter. The scale factor is a power of ten. The valid range
/// of this parameter is PDH_MIN_SCALE (7) (the returned value is the actual value times 10⁷) to PDH_MAX_SCALE (+7) (the
/// returned value is the actual value times 10⁺⁷). A value of zero will set the scale to one, so that the actual value is returned
/// </summary>
public long lScale;
/// <summary>Default scale factor as suggested by the counter's provider.</summary>
public long lDefaultScale;
/// <summary>The value passed in the dwUserData parameter when calling PdhAddCounter.</summary>
public IntPtr dwUserData;
/// <summary>The value passed in the dwUserData parameter when calling PdhOpenQuery.</summary>
public IntPtr dwQueryUserData;
/// <summary><c>Null</c>-terminated string that specifies the full counter path. The string follows this structure in memory.</summary>
public StrPtrAuto szFullPath;
/// <summary>
/// <c>Null</c>-terminated string that contains the name of the computer specified in the counter path. Is <c>NULL</c>, if the
/// path does not specify a computer. The string follows this structure in memory.
/// </summary>
public StrPtrAuto szMachineName;
/// <summary>
/// <c>Null</c>-terminated string that contains the name of the performance object specified in the counter path. The string
/// follows this structure in memory.
/// </summary>
public StrPtrAuto szObjectName;
/// <summary>
/// <c>Null</c>-terminated string that contains the name of the object instance specified in the counter path. Is <c>NULL</c>, if
/// the path does not specify an instance. The string follows this structure in memory.
/// </summary>
public StrPtrAuto szInstanceName;
/// <summary>
/// <c>Null</c>-terminated string that contains the name of the parent instance specified in the counter path. Is <c>NULL</c>, if
/// the path does not specify a parent instance. The string follows this structure in memory.
/// </summary>
public StrPtrAuto szParentInstance;
/// <summary>Instance index specified in the counter path. Is 0, if the path does not specify an instance index.</summary>
public uint dwInstanceIndex;
/// <summary><c>Null</c>-terminated string that contains the counter name. The string follows this structure in memory.</summary>
public StrPtrAuto szCounterName;
/// <summary>Help text that describes the counter. Is <c>NULL</c> if the source is a log file.</summary>
public StrPtrAuto szExplainText;
/// <summary>Start of the string data that is appended to the structure.</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public uint[] DataBuffer;
}
/// <summary>The <c>PDH_COUNTER_PATH_ELEMENTS</c> structure contains the components of a counter path.</summary>
/// <remarks>
/// <para>This structure is used by PdhMakeCounterPath to create a counter path and by PdhParseCounterPath to parse a counter path.</para>
/// <para>
/// When you allocate memory for this structure, allocate enough memory for the member strings, such as <c>szCounterName</c>, that
/// are appended to the end of this structure.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_counter_path_elements_a typedef struct
// _PDH_COUNTER_PATH_ELEMENTS_A { LPSTR szMachineName; LPSTR szObjectName; LPSTR szInstanceName; LPSTR szParentInstance; DWORD
// dwInstanceIndex; LPSTR szCounterName; } PDH_COUNTER_PATH_ELEMENTS_A, *PPDH_COUNTER_PATH_ELEMENTS_A;
[PInvokeData("pdh.h", MSDNShortId = "ffa2a076-7267-406b-8eed-4a49504a7ad6")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct PDH_COUNTER_PATH_ELEMENTS
{
/// <summary>Pointer to a null-terminated string that specifies the computer name.</summary>
[MarshalAs(UnmanagedType.LPTStr)] public string szMachineName;
/// <summary>Pointer to a null-terminated string that specifies the object name.</summary>
[MarshalAs(UnmanagedType.LPTStr)] public string szObjectName;
/// <summary>Pointer to a null-terminated string that specifies the instance name. Can contain a wildcard character.</summary>
[MarshalAs(UnmanagedType.LPTStr)] public string szInstanceName;
/// <summary>Pointer to a null-terminated string that specifies the parent instance name. Can contain a wildcard character.</summary>
[MarshalAs(UnmanagedType.LPTStr)] public string szParentInstance;
/// <summary>Index used to uniquely identify duplicate instance names.</summary>
public uint dwInstanceIndex;
/// <summary>Pointer to a null-terminated string that specifies the counter name.</summary>
[MarshalAs(UnmanagedType.LPTStr)] public string szCounterName;
}
/// <summary>The <c>PDH_DATA_ITEM_PATH_ELEMENTS</c> structure contains the path elements of a specific data item.</summary>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_data_item_path_elements_a typedef struct
// _PDH_DATA_ITEM_PATH_ELEMENTS_A { LPSTR szMachineName; GUID ObjectGUID; DWORD dwItemId; LPSTR szInstanceName; }
// PDH_DATA_ITEM_PATH_ELEMENTS_A, *PPDH_DATA_ITEM_PATH_ELEMENTS_A;
[PInvokeData("pdh.h", MSDNShortId = "7d80d9ac-0123-4743-93a2-fa9d609d81b2")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct PDH_DATA_ITEM_PATH_ELEMENTS
{
/// <summary>Pointer to a null-terminated string that specifies the name of the computer where the data item resides.</summary>
[MarshalAs(UnmanagedType.LPTStr)] public string szMachineName;
/// <summary>GUID of the object where the data item resides.</summary>
public Guid ObjectGUID;
/// <summary>Identifier of the data item.</summary>
public uint dwItemId;
/// <summary>Pointer to a null-terminated string that specifies the name of the data item instance.</summary>
[MarshalAs(UnmanagedType.LPTStr)] public string szInstanceName;
}
/// <summary>The <c>PDH_FMT_COUNTERVALUE</c> structure contains the computed value of the counter and its status.</summary>
/// <remarks>
/// You specify the data type of the computed counter value when you call PdhGetFormattedCounterValue or
/// PdhCalculateCounterFromRawValue to compute the counter's value.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_fmt_countervalue typedef struct _PDH_FMT_COUNTERVALUE { DWORD
// CStatus; union { LONG longValue; double doubleValue; LONGLONG largeValue; LPCSTR AnsiStringValue; LPCWSTR WideStringValue; }; }
// PDH_FMT_COUNTERVALUE, *PPDH_FMT_COUNTERVALUE;
[PInvokeData("pdh.h", MSDNShortId = "68ccd722-94d2-4610-ba64-f51318f5436e")]
[StructLayout(LayoutKind.Explicit, Size = 16)]
public struct PDH_FMT_COUNTERVALUE
{
/// <summary>
/// Counter status that indicates if the counter value is valid. Check this member before using the data in a calculation or
/// displaying its value. For a list of possible values, see Checking PDH Interface Return Values.
/// </summary>
[FieldOffset(0)]
public Win32Error CStatus;
/// <summary>The computed counter value as a <c>LONG</c>.</summary>
[FieldOffset(8)]
public int longValue;
/// <summary>The computed counter value as a <c>DOUBLE</c>.</summary>
[FieldOffset(8)]
public double doubleValue;
/// <summary>The computed counter value as a <c>LONGLONG</c>.</summary>
[FieldOffset(8)]
public long largeValue;
/// <summary>The computed counter value as a <c>LPCSTR</c>. Not supported.</summary>
[FieldOffset(8)]
public StrPtrAnsi AnsiStringValue;
/// <summary>The computed counter value as a <c>LPCWSTR</c>. Not supported.</summary>
[FieldOffset(8)]
public StrPtrUni WideStringValue;
}
/// <summary>The <c>PDH_FMT_COUNTERVALUE_ITEM</c> structure contains the instance name and formatted value of a counter.</summary>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_fmt_countervalue_item_a typedef struct
// _PDH_FMT_COUNTERVALUE_ITEM_A { LPSTR szName; PDH_FMT_COUNTERVALUE FmtValue; } PDH_FMT_COUNTERVALUE_ITEM_A, *PPDH_FMT_COUNTERVALUE_ITEM_A;
[PInvokeData("pdh.h", MSDNShortId = "d3bc6ad3-0cab-4843-ae1d-5f384948a1ea")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct PDH_FMT_COUNTERVALUE_ITEM
{
/// <summary>
/// Pointer to a null-terminated string that specifies the instance name of the counter. The string is appended to the end of
/// this structure.
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)] public string szName;
/// <summary>A PDH_FMT_COUNTERVALUE structure that contains the counter value of the instance.</summary>
public PDH_FMT_COUNTERVALUE FmtValue;
}
/// <summary>Provides a handle to a PDH counter.</summary>
[PInvokeData("pdh.h")]
[StructLayout(LayoutKind.Sequential)]
public struct PDH_HCOUNTER : IHandle
{
private readonly IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="PDH_HCOUNTER"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public PDH_HCOUNTER(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="PDH_HCOUNTER"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static PDH_HCOUNTER NULL => new PDH_HCOUNTER(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="PDH_HCOUNTER"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(PDH_HCOUNTER h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="PDH_HCOUNTER"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PDH_HCOUNTER(IntPtr h) => new PDH_HCOUNTER(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(PDH_HCOUNTER h1, PDH_HCOUNTER h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(PDH_HCOUNTER h1, PDH_HCOUNTER h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is PDH_HCOUNTER h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a handle to a PDH log.</summary>
[PInvokeData("pdh.h")]
[StructLayout(LayoutKind.Sequential)]
public struct PDH_HLOG : IHandle
{
private readonly IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="PDH_HLOG"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public PDH_HLOG(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="PDH_HLOG"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static PDH_HLOG NULL => new PDH_HLOG(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="PDH_HLOG"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(PDH_HLOG h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="PDH_HLOG"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PDH_HLOG(IntPtr h) => new PDH_HLOG(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(PDH_HLOG h1, PDH_HLOG h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(PDH_HLOG h1, PDH_HLOG h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is PDH_HLOG h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a handle to a PDH query.</summary>
[PInvokeData("pdh.h")]
[StructLayout(LayoutKind.Sequential)]
public struct PDH_HQUERY : IHandle
{
private readonly IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="PDH_HQUERY"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public PDH_HQUERY(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="PDH_HQUERY"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static PDH_HQUERY NULL => new PDH_HQUERY(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="PDH_HQUERY"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(PDH_HQUERY h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="PDH_HQUERY"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PDH_HQUERY(IntPtr h) => new PDH_HQUERY(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(PDH_HQUERY h1, PDH_HQUERY h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(PDH_HQUERY h1, PDH_HQUERY h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is PDH_HQUERY h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>
/// The <c>PDH_RAW_COUNTER</c> structure returns the data as it was collected from the counter provider. No translation, formatting,
/// or other interpretation is performed on the data.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_raw_counter typedef struct _PDH_RAW_COUNTER { DWORD CStatus;
// FILETIME TimeStamp; LONGLONG FirstValue; LONGLONG SecondValue; DWORD MultiCount; } PDH_RAW_COUNTER, *PPDH_RAW_COUNTER;
[PInvokeData("pdh.h", MSDNShortId = "237a3c82-0ab4-45cb-bd93-2f308178c573")]
[StructLayout(LayoutKind.Sequential)]
public struct PDH_RAW_COUNTER
{
/// <summary>
/// Counter status that indicates if the counter value is valid. Check this member before using the data in a calculation or
/// displaying its value. For a list of possible values, see Checking PDH Interface Return Values.
/// </summary>
public Win32Error CStatus;
/// <summary>Local time for when the data was collected, in FILETIME format.</summary>
public FILETIME TimeStamp;
/// <summary>First raw counter value.</summary>
public long FirstValue;
/// <summary>Second raw counter value. Rate counters require two values in order to compute a displayable value.</summary>
public long SecondValue;
/// <summary>
/// If the counter type contains the PERF_MULTI_COUNTER flag, this member contains the additional counter data used in the
/// calculation. For example, the PERF_100NSEC_MULTI_TIMER counter type contains the PERF_MULTI_COUNTER flag.
/// </summary>
public uint MultiCount;
}
/// <summary>The <c>PDH_RAW_COUNTER_ITEM</c> structure contains the instance name and raw value of a counter.</summary>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_raw_counter_item_a typedef struct _PDH_RAW_COUNTER_ITEM_A {
// LPSTR szName; PDH_RAW_COUNTER RawValue; } PDH_RAW_COUNTER_ITEM_A, *PPDH_RAW_COUNTER_ITEM_A;
[PInvokeData("pdh.h", MSDNShortId = "602e0d44-3551-4a26-a5b7-8f7015131f9a")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct PDH_RAW_COUNTER_ITEM
{
/// <summary>
/// Pointer to a null-terminated string that specifies the instance name of the counter. The string is appended to the end of
/// this structure.
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)] public string szName;
/// <summary>A PDH_RAW_COUNTER structure that contains the raw counter value of the instance.</summary>
public PDH_RAW_COUNTER RawValue;
}
/// <summary>The <c>PDH_RAW_LOG_RECORD</c> structure contains information about a binary trace log file record.</summary>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_raw_log_record typedef struct _PDH_RAW_LOG_RECORD { DWORD
// dwStructureSize; DWORD dwRecordType; DWORD dwItems; UCHAR RawBytes[1]; } PDH_RAW_LOG_RECORD, *PPDH_RAW_LOG_RECORD;
[PInvokeData("pdh.h", MSDNShortId = "ae96515f-ea3f-4578-a249-fb8f41cdfa69")]
[VanaraMarshaler(typeof(SafeAnysizeStructMarshaler<PDH_RAW_LOG_RECORD>), nameof(dwItems))]
[StructLayout(LayoutKind.Sequential)]
public struct PDH_RAW_LOG_RECORD
{
/// <summary>
/// Size of this structure, in bytes. The size includes this structure and the <c>RawBytes</c> appended to the end of this structure.
/// </summary>
public uint dwStructureSize;
/// <summary>
/// <para>Type of record. This member can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PDH_LOG_TYPE_BINARY</term>
/// <term>A binary trace format record</term>
/// </item>
/// <item>
/// <term>PDH_LOG_TYPE_CSV</term>
/// <term>A comma-separated-value format record</term>
/// </item>
/// <item>
/// <term>PDH_LOG_TYPE_PERFMON</term>
/// <term>A Perfmon format record</term>
/// </item>
/// <item>
/// <term>PDH_LOG_TYPE_SQL</term>
/// <term>A SQL format record</term>
/// </item>
/// <item>
/// <term>PDH_LOG_TYPE_TSV</term>
/// <term>A tab-separated-value format record</term>
/// </item>
/// </list>
/// </summary>
public PDH_LOG_TYPE dwRecordType;
/// <summary>Size of the <c>RawBytes</c> data.</summary>
public uint dwItems;
/// <summary>Binary record.</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public byte[] RawBytes;
}
/// <summary>
/// The <c>PDH_STATISTICS</c> structure contains the minimum, maximum, and mean values for an array of raw counters values.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_statistics typedef struct _PDH_STATISTICS { DWORD dwFormat;
// DWORD count; PDH_FMT_COUNTERVALUE min; PDH_FMT_COUNTERVALUE max; PDH_FMT_COUNTERVALUE mean; } PDH_STATISTICS, *PPDH_STATISTICS;
[PInvokeData("pdh.h", MSDNShortId = "a1daedfd-55f6-418e-b71f-8334cb628d98")]
[StructLayout(LayoutKind.Sequential)]
public struct PDH_STATISTICS
{
/// <summary>Format of the data. The format is specified in the dwFormat when calling PdhComputeCounterStatistics.</summary>
public PDH_FMT dwFormat;
/// <summary>Number of values in the array.</summary>
public uint count;
/// <summary>Minimum of the values.</summary>
public PDH_FMT_COUNTERVALUE min;
/// <summary>Maximum of the values.</summary>
public PDH_FMT_COUNTERVALUE max;
/// <summary>Mean of the values.</summary>
public PDH_FMT_COUNTERVALUE mean;
}
/// <summary>
/// The <c>PDH_TIME_INFO</c> structure contains information on time intervals as applied to the sampling of performance data.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_time_info typedef struct _PDH_TIME_INFO { LONGLONG StartTime;
// LONGLONG EndTime; DWORD SampleCount; } PDH_TIME_INFO, *PPDH_TIME_INFO;
[PInvokeData("pdh.h", MSDNShortId = "a747f288-8d6c-401c-a927-a61ffea3d423")]
[StructLayout(LayoutKind.Sequential, Size = 24)]
public struct PDH_TIME_INFO
{
/// <summary>Starting time of the sample interval, in local FILETIME format.</summary>
public FILETIME StartTime;
/// <summary>Ending time of the sample interval, in local FILETIME format.</summary>
public FILETIME EndTime;
/// <summary>Number of samples collected during the interval.</summary>
public uint SampleCount;
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="PDH_HCOUNTER"/> that is disposed using <see cref="PdhRemoveCounter"/>.</summary>
public class SafePDH_HCOUNTER : SafeHANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafePDH_HCOUNTER"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafePDH_HCOUNTER(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafePDH_HCOUNTER"/> class.</summary>
private SafePDH_HCOUNTER() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafePDH_HCOUNTER"/> to <see cref="PDH_HCOUNTER"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PDH_HCOUNTER(SafePDH_HCOUNTER h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => PdhRemoveCounter(handle).Succeeded;
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="PDH_HLOG"/> that is disposed using <see cref="PdhCloseLog"/>.</summary>
public class SafePDH_HLOG : SafeHANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafePDH_HLOG"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafePDH_HLOG(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafePDH_HLOG"/> class.</summary>
private SafePDH_HLOG() : base() { }
/// <summary>
/// Gets or sets a value indicating whether to close the query associated with the specified log file handle on disposal. See the
/// hQuery parameter of PdhOpenLog.
/// </summary>
public bool CloseAssocQueries { get; set; }
/// <summary>Performs an implicit conversion from <see cref="SafePDH_HLOG"/> to <see cref="PDH_HLOG"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PDH_HLOG(SafePDH_HLOG h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => PdhCloseLog(handle, CloseAssocQueries ? 1U : 0).Succeeded;
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="PDH_HQUERY"/> that is disposed using <see cref="PdhCloseQuery"/>.</summary>
public class SafePDH_HQUERY : SafeHANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafePDH_HQUERY"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafePDH_HQUERY(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafePDH_HQUERY"/> class.</summary>
private SafePDH_HQUERY() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafePDH_HQUERY"/> to <see cref="PDH_HQUERY"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PDH_HQUERY(SafePDH_HQUERY h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => PdhCloseQuery(handle).Succeeded;
}
}
}