static ProcessInfo[] GetProcessInfos(PerformanceCounterLib library, int processIndex, int threadIndex, byte[] data) { #if FEATURE_TRACESWITCH Debug.WriteLineIf(Process._processTracing.TraceVerbose, "GetProcessInfos()"); #endif Dictionary <int, ProcessInfo> processInfos = new Dictionary <int, ProcessInfo>(); List <ThreadInfo> threadInfos = new List <ThreadInfo>(); GCHandle dataHandle = new GCHandle(); try { dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); IntPtr dataBlockPtr = dataHandle.AddrOfPinnedObject(); Interop.Advapi32.PERF_DATA_BLOCK dataBlock = new Interop.Advapi32.PERF_DATA_BLOCK(); Marshal.PtrToStructure(dataBlockPtr, dataBlock); IntPtr typePtr = (IntPtr)((long)dataBlockPtr + dataBlock.HeaderLength); Interop.Advapi32.PERF_INSTANCE_DEFINITION instance = new Interop.Advapi32.PERF_INSTANCE_DEFINITION(); Interop.Advapi32.PERF_COUNTER_BLOCK counterBlock = new Interop.Advapi32.PERF_COUNTER_BLOCK(); for (int i = 0; i < dataBlock.NumObjectTypes; i++) { Interop.Advapi32.PERF_OBJECT_TYPE type = new Interop.Advapi32.PERF_OBJECT_TYPE(); Marshal.PtrToStructure(typePtr, type); IntPtr instancePtr = (IntPtr)((long)typePtr + type.DefinitionLength); IntPtr counterPtr = (IntPtr)((long)typePtr + type.HeaderLength); List <Interop.Advapi32.PERF_COUNTER_DEFINITION> counterList = new List <Interop.Advapi32.PERF_COUNTER_DEFINITION>(); for (int j = 0; j < type.NumCounters; j++) { Interop.Advapi32.PERF_COUNTER_DEFINITION counter = new Interop.Advapi32.PERF_COUNTER_DEFINITION(); Marshal.PtrToStructure(counterPtr, counter); string counterName = library.GetCounterName(counter.CounterNameTitleIndex); if (type.ObjectNameTitleIndex == processIndex) { counter.CounterNameTitlePtr = (int)GetValueId(counterName); } else if (type.ObjectNameTitleIndex == threadIndex) { counter.CounterNameTitlePtr = (int)GetValueId(counterName); } counterList.Add(counter); counterPtr = (IntPtr)((long)counterPtr + counter.ByteLength); } Interop.Advapi32.PERF_COUNTER_DEFINITION[] counters = counterList.ToArray(); for (int j = 0; j < type.NumInstances; j++) { Marshal.PtrToStructure(instancePtr, instance); IntPtr namePtr = (IntPtr)((long)instancePtr + instance.NameOffset); string instanceName = Marshal.PtrToStringUni(namePtr); if (instanceName.Equals("_Total")) { continue; } IntPtr counterBlockPtr = (IntPtr)((long)instancePtr + instance.ByteLength); Marshal.PtrToStructure(counterBlockPtr, counterBlock); if (type.ObjectNameTitleIndex == processIndex) { ProcessInfo processInfo = GetProcessInfo(type, (IntPtr)((long)instancePtr + instance.ByteLength), counters); if (processInfo.ProcessId == 0 && string.Compare(instanceName, "Idle", StringComparison.OrdinalIgnoreCase) != 0) { // Sometimes we'll get a process structure that is not completely filled in. // We can catch some of these by looking for non-"idle" processes that have id 0 // and ignoring those. #if FEATURE_TRACESWITCH Debug.WriteLineIf(Process._processTracing.TraceVerbose, "GetProcessInfos() - found a non-idle process with id 0; ignoring."); #endif } else { if (processInfos.ContainsKey(processInfo.ProcessId)) { // We've found two entries in the perfcounters that claim to be the // same process. We throw an exception. Is this really going to be // helpful to the user? Should we just ignore? #if FEATURE_TRACESWITCH Debug.WriteLineIf(Process._processTracing.TraceVerbose, "GetProcessInfos() - found a duplicate process id"); #endif } else { // the performance counters keep a 15 character prefix of the exe name, and then delete the ".exe", // if it's in the first 15. The problem is that sometimes that will leave us with part of ".exe" // at the end. If instanceName ends in ".", ".e", or ".ex" we remove it. string processName = instanceName; if (processName.Length == 15) { if (instanceName.EndsWith(".", StringComparison.Ordinal)) { processName = instanceName.Substring(0, 14); } else if (instanceName.EndsWith(".e", StringComparison.Ordinal)) { processName = instanceName.Substring(0, 13); } else if (instanceName.EndsWith(".ex", StringComparison.Ordinal)) { processName = instanceName.Substring(0, 12); } } processInfo.ProcessName = processName; processInfos.Add(processInfo.ProcessId, processInfo); } } } else if (type.ObjectNameTitleIndex == threadIndex) { ThreadInfo threadInfo = GetThreadInfo(type, (IntPtr)((long)instancePtr + instance.ByteLength), counters); if (threadInfo._threadId != 0) { threadInfos.Add(threadInfo); } } instancePtr = (IntPtr)((long)instancePtr + instance.ByteLength + counterBlock.ByteLength); } typePtr = (IntPtr)((long)typePtr + type.TotalByteLength); } } finally { if (dataHandle.IsAllocated) { dataHandle.Free(); } } for (int i = 0; i < threadInfos.Count; i++) { ThreadInfo threadInfo = (ThreadInfo)threadInfos[i]; ProcessInfo processInfo; if (processInfos.TryGetValue(threadInfo._processId, out processInfo)) { processInfo._threadInfoList.Add(threadInfo); } } ProcessInfo[] temp = new ProcessInfo[processInfos.Values.Count]; processInfos.Values.CopyTo(temp, 0); return(temp); }
private static ProcessInfo[] GetProcessInfos(PerformanceCounterLib library, int processIndex, int threadIndex, byte[] data) { Hashtable hashtable = new Hashtable(); ArrayList list = new ArrayList(); GCHandle handle = new GCHandle(); try { handle = GCHandle.Alloc(data, GCHandleType.Pinned); IntPtr ptr = handle.AddrOfPinnedObject(); Microsoft.Win32.NativeMethods.PERF_DATA_BLOCK structure = new Microsoft.Win32.NativeMethods.PERF_DATA_BLOCK(); Marshal.PtrToStructure(ptr, structure); IntPtr ptr2 = (IntPtr) (((long) ptr) + structure.HeaderLength); Microsoft.Win32.NativeMethods.PERF_INSTANCE_DEFINITION perf_instance_definition = new Microsoft.Win32.NativeMethods.PERF_INSTANCE_DEFINITION(); Microsoft.Win32.NativeMethods.PERF_COUNTER_BLOCK perf_counter_block = new Microsoft.Win32.NativeMethods.PERF_COUNTER_BLOCK(); for (int j = 0; j < structure.NumObjectTypes; j++) { Microsoft.Win32.NativeMethods.PERF_OBJECT_TYPE perf_object_type = new Microsoft.Win32.NativeMethods.PERF_OBJECT_TYPE(); Marshal.PtrToStructure(ptr2, perf_object_type); IntPtr ptr3 = (IntPtr) (((long) ptr2) + perf_object_type.DefinitionLength); IntPtr ptr4 = (IntPtr) (((long) ptr2) + perf_object_type.HeaderLength); ArrayList list2 = new ArrayList(); for (int k = 0; k < perf_object_type.NumCounters; k++) { Microsoft.Win32.NativeMethods.PERF_COUNTER_DEFINITION perf_counter_definition = new Microsoft.Win32.NativeMethods.PERF_COUNTER_DEFINITION(); Marshal.PtrToStructure(ptr4, perf_counter_definition); string counterName = library.GetCounterName(perf_counter_definition.CounterNameTitleIndex); if (perf_object_type.ObjectNameTitleIndex == processIndex) { perf_counter_definition.CounterNameTitlePtr = (int) GetValueId(counterName); } else if (perf_object_type.ObjectNameTitleIndex == threadIndex) { perf_counter_definition.CounterNameTitlePtr = (int) GetValueId(counterName); } list2.Add(perf_counter_definition); ptr4 = (IntPtr) (((long) ptr4) + perf_counter_definition.ByteLength); } Microsoft.Win32.NativeMethods.PERF_COUNTER_DEFINITION[] perf_counter_definitionArray = new Microsoft.Win32.NativeMethods.PERF_COUNTER_DEFINITION[list2.Count]; list2.CopyTo(perf_counter_definitionArray, 0); for (int m = 0; m < perf_object_type.NumInstances; m++) { Marshal.PtrToStructure(ptr3, perf_instance_definition); IntPtr ptr5 = (IntPtr) (((long) ptr3) + perf_instance_definition.NameOffset); string strA = Marshal.PtrToStringUni(ptr5); if (!strA.Equals("_Total")) { IntPtr ptr6 = (IntPtr) (((long) ptr3) + perf_instance_definition.ByteLength); Marshal.PtrToStructure(ptr6, perf_counter_block); if (perf_object_type.ObjectNameTitleIndex == processIndex) { ProcessInfo info = GetProcessInfo(perf_object_type, (IntPtr) (((long) ptr3) + perf_instance_definition.ByteLength), perf_counter_definitionArray); if (((info.processId != 0) || (string.Compare(strA, "Idle", StringComparison.OrdinalIgnoreCase) == 0)) && (hashtable[info.processId] == null)) { string str3 = strA; if (str3.Length == 15) { if (strA.EndsWith(".", StringComparison.Ordinal)) { str3 = strA.Substring(0, 14); } else if (strA.EndsWith(".e", StringComparison.Ordinal)) { str3 = strA.Substring(0, 13); } else if (strA.EndsWith(".ex", StringComparison.Ordinal)) { str3 = strA.Substring(0, 12); } } info.processName = str3; hashtable.Add(info.processId, info); } } else if (perf_object_type.ObjectNameTitleIndex == threadIndex) { ThreadInfo info2 = GetThreadInfo(perf_object_type, (IntPtr) (((long) ptr3) + perf_instance_definition.ByteLength), perf_counter_definitionArray); if (info2.threadId != 0) { list.Add(info2); } } ptr3 = (IntPtr) ((((long) ptr3) + perf_instance_definition.ByteLength) + perf_counter_block.ByteLength); } } ptr2 = (IntPtr) (((long) ptr2) + perf_object_type.TotalByteLength); } } finally { if (handle.IsAllocated) { handle.Free(); } } for (int i = 0; i < list.Count; i++) { ThreadInfo info3 = (ThreadInfo) list[i]; ProcessInfo info4 = (ProcessInfo) hashtable[info3.processId]; if (info4 != null) { info4.threadInfoList.Add(info3); } } ProcessInfo[] array = new ProcessInfo[hashtable.Values.Count]; hashtable.Values.CopyTo(array, 0); return array; }
static ProcessInfo[] GetProcessInfos(PerformanceCounterLib library, int processIndex, int threadIndex, byte[] data) { Debug.WriteLineIf(Process.processTracing.TraceVerbose, "GetProcessInfos()"); Hashtable processInfos = new Hashtable(); ArrayList threadInfos = new ArrayList(); GCHandle dataHandle = new GCHandle(); try { dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); IntPtr dataBlockPtr = dataHandle.AddrOfPinnedObject(); NativeMethods.PERF_DATA_BLOCK dataBlock = new NativeMethods.PERF_DATA_BLOCK(); Marshal.PtrToStructure(dataBlockPtr, dataBlock); IntPtr typePtr = (IntPtr)((long)dataBlockPtr + dataBlock.HeaderLength); NativeMethods.PERF_INSTANCE_DEFINITION instance = new NativeMethods.PERF_INSTANCE_DEFINITION(); NativeMethods.PERF_COUNTER_BLOCK counterBlock = new NativeMethods.PERF_COUNTER_BLOCK(); for (int i = 0; i < dataBlock.NumObjectTypes; i++) { NativeMethods.PERF_OBJECT_TYPE type = new NativeMethods.PERF_OBJECT_TYPE(); Marshal.PtrToStructure(typePtr, type); IntPtr instancePtr = (IntPtr)((long)typePtr + type.DefinitionLength); IntPtr counterPtr = (IntPtr)((long)typePtr + type.HeaderLength); ArrayList counterList = new ArrayList(); for (int j = 0; j < type.NumCounters; j++) { NativeMethods.PERF_COUNTER_DEFINITION counter = new NativeMethods.PERF_COUNTER_DEFINITION(); Marshal.PtrToStructure(counterPtr, counter); string counterName = library.GetCounterName(counter.CounterNameTitleIndex); if (type.ObjectNameTitleIndex == processIndex) counter.CounterNameTitlePtr = (int)GetValueId(counterName); else if (type.ObjectNameTitleIndex == threadIndex) counter.CounterNameTitlePtr = (int)GetValueId(counterName); counterList.Add(counter); counterPtr = (IntPtr)((long)counterPtr + counter.ByteLength); } NativeMethods.PERF_COUNTER_DEFINITION[] counters = new NativeMethods.PERF_COUNTER_DEFINITION[counterList.Count]; counterList.CopyTo(counters, 0); for (int j = 0; j < type.NumInstances; j++) { Marshal.PtrToStructure(instancePtr, instance); IntPtr namePtr = (IntPtr)((long)instancePtr + instance.NameOffset); string instanceName = Marshal.PtrToStringUni(namePtr); if (instanceName.Equals("_Total")) continue; IntPtr counterBlockPtr = (IntPtr)((long)instancePtr + instance.ByteLength); Marshal.PtrToStructure(counterBlockPtr, counterBlock); if (type.ObjectNameTitleIndex == processIndex) { ProcessInfo processInfo = GetProcessInfo(type, (IntPtr)((long)instancePtr + instance.ByteLength), counters); if (processInfo.processId == 0 && string.Compare(instanceName, "Idle", StringComparison.OrdinalIgnoreCase) != 0) { // Sometimes we'll get a process structure that is not completely filled in. // We can catch some of these by looking for non-"idle" processes that have id 0 // and ignoring those. Debug.WriteLineIf(Process.processTracing.TraceVerbose, "GetProcessInfos() - found a non-idle process with id 0; ignoring."); } else { if (processInfos[processInfo.processId] != null) { // We've found two entries in the perfcounters that claim to be the // same process. We throw an exception. Is this really going to be // helpfull to the user? Should we just ignore? Debug.WriteLineIf(Process.processTracing.TraceVerbose, "GetProcessInfos() - found a duplicate process id"); } else { // the performance counters keep a 15 character prefix of the exe name, and then delete the ".exe", // if it's in the first 15. The problem is that sometimes that will leave us with part of ".exe" // at the end. If instanceName ends in ".", ".e", or ".ex" we remove it. string processName = instanceName; if (processName.Length == 15) { if (instanceName.EndsWith(".", StringComparison.Ordinal )) processName = instanceName.Substring(0, 14); else if (instanceName.EndsWith(".e", StringComparison.Ordinal )) processName = instanceName.Substring(0, 13); else if (instanceName.EndsWith(".ex", StringComparison.Ordinal)) processName = instanceName.Substring(0, 12); } processInfo.processName = processName; processInfos.Add(processInfo.processId, processInfo); } } } else if (type.ObjectNameTitleIndex == threadIndex) { ThreadInfo threadInfo = GetThreadInfo(type, (IntPtr)((long)instancePtr + instance.ByteLength), counters); if (threadInfo.threadId != 0) threadInfos.Add(threadInfo); } instancePtr = (IntPtr)((long)instancePtr + instance.ByteLength + counterBlock.ByteLength); } typePtr = (IntPtr)((long)typePtr + type.TotalByteLength); } } finally { if (dataHandle.IsAllocated) dataHandle.Free(); } for (int i = 0; i < threadInfos.Count; i++) { ThreadInfo threadInfo = (ThreadInfo)threadInfos[i]; ProcessInfo processInfo = (ProcessInfo)processInfos[threadInfo.processId]; if (processInfo != null) { processInfo.threadInfoList.Add(threadInfo); } } ProcessInfo[] temp = new ProcessInfo[processInfos.Values.Count]; processInfos.Values.CopyTo(temp, 0); return temp; }
private static ProcessInfo[] GetProcessInfos(PerformanceCounterLib library, int processIndex, int threadIndex, byte[] data) { Hashtable hashtable = new Hashtable(); ArrayList list = new ArrayList(); GCHandle handle = new GCHandle(); try { handle = GCHandle.Alloc(data, GCHandleType.Pinned); IntPtr ptr = handle.AddrOfPinnedObject(); Microsoft.Win32.NativeMethods.PERF_DATA_BLOCK structure = new Microsoft.Win32.NativeMethods.PERF_DATA_BLOCK(); Marshal.PtrToStructure(ptr, structure); IntPtr ptr2 = (IntPtr)(((long)ptr) + structure.HeaderLength); Microsoft.Win32.NativeMethods.PERF_INSTANCE_DEFINITION perf_instance_definition = new Microsoft.Win32.NativeMethods.PERF_INSTANCE_DEFINITION(); Microsoft.Win32.NativeMethods.PERF_COUNTER_BLOCK perf_counter_block = new Microsoft.Win32.NativeMethods.PERF_COUNTER_BLOCK(); for (int j = 0; j < structure.NumObjectTypes; j++) { Microsoft.Win32.NativeMethods.PERF_OBJECT_TYPE perf_object_type = new Microsoft.Win32.NativeMethods.PERF_OBJECT_TYPE(); Marshal.PtrToStructure(ptr2, perf_object_type); IntPtr ptr3 = (IntPtr)(((long)ptr2) + perf_object_type.DefinitionLength); IntPtr ptr4 = (IntPtr)(((long)ptr2) + perf_object_type.HeaderLength); ArrayList list2 = new ArrayList(); for (int k = 0; k < perf_object_type.NumCounters; k++) { Microsoft.Win32.NativeMethods.PERF_COUNTER_DEFINITION perf_counter_definition = new Microsoft.Win32.NativeMethods.PERF_COUNTER_DEFINITION(); Marshal.PtrToStructure(ptr4, perf_counter_definition); string counterName = library.GetCounterName(perf_counter_definition.CounterNameTitleIndex); if (perf_object_type.ObjectNameTitleIndex == processIndex) { perf_counter_definition.CounterNameTitlePtr = (int)GetValueId(counterName); } else if (perf_object_type.ObjectNameTitleIndex == threadIndex) { perf_counter_definition.CounterNameTitlePtr = (int)GetValueId(counterName); } list2.Add(perf_counter_definition); ptr4 = (IntPtr)(((long)ptr4) + perf_counter_definition.ByteLength); } Microsoft.Win32.NativeMethods.PERF_COUNTER_DEFINITION[] perf_counter_definitionArray = new Microsoft.Win32.NativeMethods.PERF_COUNTER_DEFINITION[list2.Count]; list2.CopyTo(perf_counter_definitionArray, 0); for (int m = 0; m < perf_object_type.NumInstances; m++) { Marshal.PtrToStructure(ptr3, perf_instance_definition); IntPtr ptr5 = (IntPtr)(((long)ptr3) + perf_instance_definition.NameOffset); string strA = Marshal.PtrToStringUni(ptr5); if (!strA.Equals("_Total")) { IntPtr ptr6 = (IntPtr)(((long)ptr3) + perf_instance_definition.ByteLength); Marshal.PtrToStructure(ptr6, perf_counter_block); if (perf_object_type.ObjectNameTitleIndex == processIndex) { ProcessInfo info = GetProcessInfo(perf_object_type, (IntPtr)(((long)ptr3) + perf_instance_definition.ByteLength), perf_counter_definitionArray); if (((info.processId != 0) || (string.Compare(strA, "Idle", StringComparison.OrdinalIgnoreCase) == 0)) && (hashtable[info.processId] == null)) { string str3 = strA; if (str3.Length == 15) { if (strA.EndsWith(".", StringComparison.Ordinal)) { str3 = strA.Substring(0, 14); } else if (strA.EndsWith(".e", StringComparison.Ordinal)) { str3 = strA.Substring(0, 13); } else if (strA.EndsWith(".ex", StringComparison.Ordinal)) { str3 = strA.Substring(0, 12); } } info.processName = str3; hashtable.Add(info.processId, info); } } else if (perf_object_type.ObjectNameTitleIndex == threadIndex) { ThreadInfo info2 = GetThreadInfo(perf_object_type, (IntPtr)(((long)ptr3) + perf_instance_definition.ByteLength), perf_counter_definitionArray); if (info2.threadId != 0) { list.Add(info2); } } ptr3 = (IntPtr)((((long)ptr3) + perf_instance_definition.ByteLength) + perf_counter_block.ByteLength); } } ptr2 = (IntPtr)(((long)ptr2) + perf_object_type.TotalByteLength); } } finally { if (handle.IsAllocated) { handle.Free(); } } for (int i = 0; i < list.Count; i++) { ThreadInfo info3 = (ThreadInfo)list[i]; ProcessInfo info4 = (ProcessInfo)hashtable[info3.processId]; if (info4 != null) { info4.threadInfoList.Add(info3); } } ProcessInfo[] array = new ProcessInfo[hashtable.Values.Count]; hashtable.Values.CopyTo(array, 0); return(array); }