Source/Tx.Windows/PerfCounters/PdhNativeMethods.cs (319 lines of code) (raw):

// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. using System; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using Microsoft.Win32.SafeHandles; using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; namespace Tx.Windows { [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] internal class PdhLogHandle : SafeHandleZeroOrMinusOneIsInvalid { public PdhLogHandle() : base(true) { } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { return PdhNativeMethods.PdhCloseLog(handle, PdhNativeMethods.PDH_FLAGS_CLOSE_QUERY) == 0; } } [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] internal class PdhQueryHandle : SafeHandleZeroOrMinusOneIsInvalid { public PdhQueryHandle() : base(true) { } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { return PdhNativeMethods.PdhCloseQuery(handle) == 0; } } [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] internal class PdhCounterHandle : SafeHandleZeroOrMinusOneIsInvalid { public PdhCounterHandle() : base(true) { } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { return PdhNativeMethods.PdhRemoveCounter(handle) == 0; } } [StructLayout(LayoutKind.Explicit)] internal struct PDH_FMT_COUNTERVALUE { [FieldOffset(0)] public uint CStatus; [FieldOffset(8)] public int longValue; [FieldOffset(8)] public double doubleValue; [FieldOffset(8)] public Int64 largeValue; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct PDH_FMT_COUNTERVALUE_ITEM { //[MarshalAs(UnmanagedType.LPWStr)] //public string szName; public IntPtr szName; public PDH_FMT_COUNTERVALUE FmtValue; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct PDH_COUNTER_INFO { public UInt32 dwLength; public UInt32 dwType; public UInt32 CVersion; public UInt32 CStatus; public Int64 lScale; public Int64 lDefaultScale; public IntPtr dwUserData; public IntPtr dwQueryUserData; public IntPtr szFullPath; public IntPtr szMachineName; public IntPtr szObjectName; public IntPtr szInstanceName; public IntPtr szParentInstance; public UInt32 dwInstanceIndex; public IntPtr szCounterName; public IntPtr szExplainText; } [StructLayout(LayoutKind.Sequential)] internal struct PDH_TIME_INFO { public UInt64 StartTime; public UInt64 EndTime; public uint SampleCount; } [StructLayout(LayoutKind.Sequential)] internal struct PDH_RAW_COUNTER { public uint CStatus; public FILETIME TimeStamp; public Int64 FirstValue; public Int64 SecondValue; public uint MultiCount; } internal enum PdhStatus : uint { PDH_CSTATUS_VALID_DATA = 0x00000000, PDH_CSTATUS_NEW_DATA = 0x00000001, PDH_CSTATUS_NO_MACHINE = 0x800007D0, PDH_CSTATUS_NO_INSTANCE = 0x800007D1, PDH_MORE_DATA = 0x800007D2, PDH_CSTATUS_ITEM_NOT_VALIDATED = 0x800007D3, PDH_RETRY = 0x800007D4, PDH_NO_DATA = 0x800007D5, PDH_CALC_NEGATIVE_DENOMINATOR = 0x800007D6, PDH_CALC_NEGATIVE_TIMEBASE = 0x800007D7, PDH_CALC_NEGATIVE_VALUE = 0x800007D8, PDH_DIALOG_CANCELLED = 0x800007D9, PDH_END_OF_LOG_FILE = 0x800007DA, PDH_ASYNC_QUERY_TIMEOUT = 0x800007DB, PDH_CANNOT_SET_DEFAULT_REALTIME_DATASOURCE = 0x800007DC, PDH_CSTATUS_NO_OBJECT = 0xC0000BB8, PDH_CSTATUS_NO_COUNTER = 0xC0000BB9, PDH_CSTATUS_INVALID_DATA = 0xC0000BBA, PDH_MEMORY_ALLOCATION_FAILURE = 0xC0000BBB, PDH_INVALID_HANDLE = 0xC0000BBC, PDH_INVALID_ARGUMENT = 0xC0000BBD, PDH_FUNCTION_NOT_FOUND = 0xC0000BBE, PDH_CSTATUS_NO_COUNTERNAME = 0xC0000BBF, PDH_CSTATUS_BAD_COUNTERNAME = 0xC0000BC0, PDH_INVALID_BUFFER = 0xC0000BC1, PDH_INSUFFICIENT_BUFFER = 0xC0000BC2, PDH_CANNOT_CONNECT_MACHINE = 0xC0000BC3, PDH_INVALID_PATH = 0xC0000BC4, PDH_INVALID_INSTANCE = 0xC0000BC5, PDH_INVALID_DATA = 0xC0000BC6, PDH_NO_DIALOG_DATA = 0xC0000BC7, PDH_CANNOT_READ_NAME_STRINGS = 0xC0000BC8, PDH_LOG_FILE_CREATE_ERROR = 0xC0000BC9, PDH_LOG_FILE_OPEN_ERROR = 0xC0000BCA, PDH_LOG_TYPE_NOT_FOUND = 0xC0000BCB, PDH_NO_MORE_DATA = 0xC0000BCC, PDH_ENTRY_NOT_IN_LOG_FILE = 0xC0000BCD, PDH_DATA_SOURCE_IS_LOG_FILE = 0xC0000BCE, PDH_DATA_SOURCE_IS_REAL_TIME = 0xC0000BCF, PDH_UNABLE_READ_LOG_HEADER = 0xC0000BD0, PDH_FILE_NOT_FOUND = 0xC0000BD1, PDH_FILE_ALREADY_EXISTS = 0xC0000BD2, PDH_NOT_IMPLEMENTED = 0xC0000BD3, PDH_STRING_NOT_FOUND = 0xC0000BD4, PDH_UNABLE_MAP_NAME_FILES = 0x80000BD5, PDH_UNKNOWN_LOG_FORMAT = 0xC0000BD6, PDH_UNKNOWN_LOGSVC_COMMAND = 0xC0000BD7, PDH_LOGSVC_QUERY_NOT_FOUND = 0xC0000BD8, PDH_LOGSVC_NOT_OPENED = 0xC0000BD9, PDH_WBEM_ERROR = 0xC0000BDA, PDH_ACCESS_DENIED = 0xC0000BDB, PDH_LOG_FILE_TOO_SMALL = 0xC0000BDC, PDH_INVALID_DATASOURCE = 0xC0000BDD, PDH_INVALID_SQLDB = 0xC0000BDE, PDH_NO_COUNTERS = 0xC0000BDF, PDH_SQL_ALLOC_FAILED = 0xC0000BE0, PDH_SQL_ALLOCCON_FAILED = 0xC0000BE1, PDH_SQL_EXEC_DIRECT_FAILED = 0xC0000BE2, PDH_SQL_FETCH_FAILED = 0xC0000BE3, PDH_SQL_ROWCOUNT_FAILED = 0xC0000BE4, PDH_SQL_MORE_RESULTS_FAILED = 0xC0000BE5, PDH_SQL_CONNECT_FAILED = 0xC0000BE6, PDH_SQL_BIND_FAILED = 0xC0000BE7, PDH_CANNOT_CONNECT_WMI_SERVER = 0xC0000BE8, PDH_PLA_COLLECTION_ALREADY_RUNNING = 0xC0000BE9, PDH_PLA_ERROR_SCHEDULE_OVERLAP = 0xC0000BEA, PDH_PLA_COLLECTION_NOT_FOUND = 0xC0000BEB, PDH_PLA_ERROR_SCHEDULE_ELAPSED = 0xC0000BEC, PDH_PLA_ERROR_NOSTART = 0xC0000BED, PDH_PLA_ERROR_ALREADY_EXISTS = 0xC0000BEE, PDH_PLA_ERROR_TYPE_MISMATCH = 0xC0000BEF, PDH_PLA_ERROR_FILEPATH = 0xC0000BF0, PDH_PLA_SERVICE_ERROR = 0xC0000BF1, PDH_PLA_VALIDATION_ERROR = 0xC0000BF2, PDH_PLA_VALIDATION_WARNING = 0x80000BF3, PDH_PLA_ERROR_NAME_TOO_LONG = 0xC0000BF4, PDH_INVALID_SQL_LOG_FORMAT = 0xC0000BF5, PDH_COUNTER_ALREADY_IN_QUERY = 0xC0000BF6, PDH_BINARY_LOG_CORRUPT = 0xC0000BF7, PDH_LOG_SAMPLE_TOO_SMALL = 0xC0000BF8, PDH_OS_LATER_VERSION = 0xC0000BF9, PDH_OS_EARLIER_VERSION = 0xC0000BFA, PDH_INCORRECT_APPEND_TIME = 0xC0000BFB, PDH_UNMATCHED_APPEND_COUNTER = 0xC0000BFC, PDH_SQL_ALTER_DETAIL_FAILED = 0xC0000BFD, PDH_QUERY_PERF_DATA_TIMEOUT = 0xC0000BFE, PDH_UNKNOWN = 0xFFFFFFFF } [Flags] internal enum PdhFormat : uint { PDH_FMT_RAW = 0x00000010, PDH_FMT_ANSI = 0x00000020, PDH_FMT_UNICODE = 0x00000040, PDH_FMT_LONG = 0x00000100, PDH_FMT_DOUBLE = 0x00000200, PDH_FMT_LARGE = 0x00000400, PDH_FMT_NOSCALE = 0x00001000, PDH_FMT_1000 = 0x00002000, PDH_FMT_NODATA = 0x00004000 } internal enum PdhDetailLevel : uint { PERF_DETAIL_NOVICE = 100, // The uninformed can understand it PERF_DETAIL_ADVANCED = 200, // For the advanced user PERF_DETAIL_EXPERT = 300, // For the expert user PERF_DETAIL_WIZARD = 400 // For the system designer } [SuppressUnmanagedCodeSecurity] internal class PdhNativeMethods { #region A few common flags and status codes public const UInt32 PDH_FLAGS_CLOSE_QUERY = 1; public const UInt32 PDH_NO_MORE_DATA = 0xC0000BCC; public const UInt32 PDH_INVALID_DATA = 0xC0000BC6; public const UInt32 PDH_ENTRY_NOT_IN_LOG_FILE = 0xC0000BCD; #endregion [DllImport("pdh.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern PdhStatus PdhOpenQuery( string szDataSource, IntPtr dwUserData, out PdhQueryHandle phQuery); /// Opens a query against a bound input source. [DllImport("pdh.dll", SetLastError = true)] private static extern PdhStatus PdhOpenQueryH( PdhLogHandle hDataSource, IntPtr dwUserData, out PdhQueryHandle phQuery); /// Binds multiple logs files together. /// /// Use this along with the API's ending in 'H' to string multiple files together. [DllImport("pdh.dll", SetLastError = true)] private static extern PdhStatus PdhBindInputDataSource( out PdhLogHandle phDataSource, string szLogFileNameList); [DllImport("pdh.dll", SetLastError = true)] public static extern PdhStatus PdhCloseLog( IntPtr hLog, long dwFlags); [DllImport("pdh.dll", SetLastError = true)] public static extern PdhStatus PdhCloseQuery( IntPtr hQuery); [DllImport("pdh.dll", SetLastError = true)] public static extern PdhStatus PdhRemoveCounter( IntPtr hQuery); [DllImport("pdh.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern PdhStatus PdhAddCounter( PdhQueryHandle hQuery, string szFullCounterPath, IntPtr dwUserData, out PdhCounterHandle phCounter); [DllImport("pdh.dll", SetLastError = true)] public static extern PdhStatus PdhCollectQueryData( PdhQueryHandle phQuery); [DllImport("pdh.dll", SetLastError = true)] public static extern PdhStatus PdhCollectQueryDataWithTime( PdhQueryHandle phQuery, out long timestamp); [DllImport("pdh.dll", CharSet = CharSet.Unicode)] public static extern PdhStatus PdhGetFormattedCounterValue( PdhCounterHandle phCounter, PdhFormat dwFormat, ref uint lpdwType, ref PDH_FMT_COUNTERVALUE pValue); [DllImport("pdh.dll", CharSet = CharSet.Unicode)] public static extern PdhStatus PdhGetDataSourceTimeRange( string szDataSource, ref uint pdwNumEntries, ref PDH_TIME_INFO pInfo, ref uint dwBufferSize ); [DllImport("pdh.dll", CharSet = CharSet.Unicode)] public static extern PdhStatus PdhGetFormattedCounterArray( PdhCounterHandle phCounter, PdhFormat dwFormat, ref UInt32 dwBufferSize, out UInt32 dwBufferCount, IntPtr itemBuffer); [DllImport("pdh.dll", CharSet = CharSet.Unicode)] public static extern PdhStatus PdhGetRawCounterValue( PdhCounterHandle phCounter, out uint lpdwType, out PDH_RAW_COUNTER pValue); [DllImport("pdh.dll", CharSet = CharSet.Unicode)] public static extern PdhStatus PdhGetCounterTimeBase( PdhCounterHandle phCounter, out UInt64 pTimeBase); [DllImport("pdh.dll", CharSet = CharSet.Unicode)] public static extern PdhStatus PdhEnumMachines( string szDataSource, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] char[] mszMachineNameList, ref uint pcchBufferLength ); [DllImport("pdh.dll", CharSet = CharSet.Unicode)] public static extern PdhStatus PdhEnumObjects( string szDataSource, string szMachineName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] char[] mszObjectList, ref uint pcchBufferLength, PdhDetailLevel dwDetailLevel, int bRefresh ); [DllImport("pdh.dll", CharSet = CharSet.Unicode)] public static extern PdhStatus PdhEnumObjectItems( string szDataSource, string szMachineName, string szObjectName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 5)] char[] mszCounterList, ref uint pcchCounterListLength, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 7)] char[] mszInstanceList, ref uint pcchInstanceListLength, PdhDetailLevel dwDetailLevel, uint dwFlags ); [DllImport("pdh.dll", CharSet = CharSet.Unicode)] public static extern PdhStatus PdhGetCounterInfo( PdhCounterHandle phCounter, bool bRetrieveExplainText, ref UInt32 pdwBufferSize, IntPtr lpBuffer); } }