Exemplo n.º 1
0
        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.PERF_DATA_BLOCK dataBlock = new Interop.PERF_DATA_BLOCK();
                Marshal.PtrToStructure(dataBlockPtr, dataBlock);
                IntPtr typePtr = (IntPtr)((long)dataBlockPtr + dataBlock.HeaderLength);
                Interop.PERF_INSTANCE_DEFINITION instance     = new Interop.PERF_INSTANCE_DEFINITION();
                Interop.PERF_COUNTER_BLOCK       counterBlock = new Interop.PERF_COUNTER_BLOCK();
                for (int i = 0; i < dataBlock.NumObjectTypes; i++)
                {
                    Interop.PERF_OBJECT_TYPE type = new Interop.PERF_OBJECT_TYPE();
                    Marshal.PtrToStructure(typePtr, type);
                    IntPtr instancePtr = (IntPtr)((long)typePtr + type.DefinitionLength);
                    IntPtr counterPtr  = (IntPtr)((long)typePtr + type.HeaderLength);
                    List <Interop.PERF_COUNTER_DEFINITION> counterList = new List <Interop.PERF_COUNTER_DEFINITION>();

                    for (int j = 0; j < type.NumCounters; j++)
                    {
                        Interop.PERF_COUNTER_DEFINITION counter = new Interop.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.PERF_COUNTER_DEFINITION[] counters = new Interop.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.
#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
                                    // helpfull 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);
        }
Exemplo n.º 2
0
        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.PERF_DATA_BLOCK dataBlock = new Interop.PERF_DATA_BLOCK();
                Marshal.PtrToStructure(dataBlockPtr, dataBlock);
                IntPtr typePtr = (IntPtr)((long)dataBlockPtr + dataBlock.HeaderLength);
                Interop.PERF_INSTANCE_DEFINITION instance = new Interop.PERF_INSTANCE_DEFINITION();
                Interop.PERF_COUNTER_BLOCK counterBlock = new Interop.PERF_COUNTER_BLOCK();
                for (int i = 0; i < dataBlock.NumObjectTypes; i++)
                {
                    Interop.PERF_OBJECT_TYPE type = new Interop.PERF_OBJECT_TYPE();
                    Marshal.PtrToStructure(typePtr, type);
                    IntPtr instancePtr = (IntPtr)((long)typePtr + type.DefinitionLength);
                    IntPtr counterPtr = (IntPtr)((long)typePtr + type.HeaderLength);
                    List<Interop.PERF_COUNTER_DEFINITION> counterList = new List<Interop.PERF_COUNTER_DEFINITION>();

                    for (int j = 0; j < type.NumCounters; j++)
                    {
                        Interop.PERF_COUNTER_DEFINITION counter = new Interop.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.PERF_COUNTER_DEFINITION[] counters = new Interop.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.
#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
                                    // helpfull 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;
        }