Vanara/PInvoke/Pdh/Pdh.cs

5272 lines
263 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
}
}
}