private static unsafe ProcessInfo[] GetProcessInfos(IntPtr dataPtr)
        {
            // Use a dictionary to avoid duplicate entries if any
            // 60 is a reasonable number for processes on a normal machine.
            Dictionary <int, ProcessInfo> processInfos = new Dictionary <int, ProcessInfo>(60);

            long totalOffset = 0;

            while (true)
            {
                IntPtr currentPtr = (IntPtr)((long)dataPtr + totalOffset);
                ref SystemProcessInformation pi = ref *(SystemProcessInformation *)(currentPtr);

                // get information for a process
                ProcessInfo processInfo = new ProcessInfo();
                // Process ID shouldn't overflow. OS API GetCurrentProcessID returns DWORD.
                processInfo.ProcessId         = pi.UniqueProcessId.ToInt32();
                processInfo.SessionId         = (int)pi.SessionId;
                processInfo.PoolPagedBytes    = (long)pi.QuotaPagedPoolUsage;;
                processInfo.PoolNonPagedBytes = (long)pi.QuotaNonPagedPoolUsage;
                processInfo.VirtualBytes      = (long)pi.VirtualSize;
                processInfo.VirtualBytesPeak  = (long)pi.PeakVirtualSize;
                processInfo.WorkingSetPeak    = (long)pi.PeakWorkingSetSize;
                processInfo.WorkingSet        = (long)pi.WorkingSetSize;
                processInfo.PageFileBytesPeak = (long)pi.PeakPagefileUsage;
                processInfo.PageFileBytes     = (long)pi.PagefileUsage;
                processInfo.PrivateBytes      = (long)pi.PrivatePageCount;
                processInfo.BasePriority      = pi.BasePriority;
                processInfo.HandleCount       = (int)pi.HandleCount;


                if (pi.ImageName.Buffer == IntPtr.Zero)
                {
                    if (processInfo.ProcessId == NtProcessManager.SystemProcessID)
                    {
                        processInfo.ProcessName = "System";
                    }
                    else if (processInfo.ProcessId == NtProcessManager.IdleProcessID)
                    {
                        processInfo.ProcessName = "Idle";
                    }
                    else
                    {
                        // for normal process without name, using the process ID.
                        processInfo.ProcessName = processInfo.ProcessId.ToString(CultureInfo.InvariantCulture);
                    }
                }
                else
                {
                    string processName = GetProcessShortName(Marshal.PtrToStringUni(pi.ImageName.Buffer, pi.ImageName.Length / sizeof(char)));
                    processInfo.ProcessName = processName;
                }

                // get the threads for current process
                processInfos[processInfo.ProcessId] = processInfo;

                currentPtr = (IntPtr)((long)currentPtr + Marshal.SizeOf(pi));
                int i = 0;
                while (i < pi.NumberOfThreads)
                {
                    ref SystemThreadInformation ti = ref *(SystemThreadInformation *)(currentPtr);
                    ThreadInfo threadInfo          = new ThreadInfo();

                    threadInfo._processId        = (int)ti.ClientId.UniqueProcess;
                    threadInfo._threadId         = (ulong)ti.ClientId.UniqueThread;
                    threadInfo._basePriority     = ti.BasePriority;
                    threadInfo._currentPriority  = ti.Priority;
                    threadInfo._startAddress     = ti.StartAddress;
                    threadInfo._threadState      = (ThreadState)ti.ThreadState;
                    threadInfo._threadWaitReason = NtProcessManager.GetThreadWaitReason((int)ti.WaitReason);

                    processInfo._threadInfoList.Add(threadInfo);
                    currentPtr = (IntPtr)((long)currentPtr + Marshal.SizeOf(ti));
                    i++;
                }
        static ProcessInfo[] GetProcessInfos(IntPtr dataPtr)
        {
            // 60 is a reasonable number for processes on a normal machine.
            Dictionary<int, ProcessInfo> processInfos = new Dictionary<int, ProcessInfo>(60);

            long totalOffset = 0;

            while (true)
            {
                IntPtr currentPtr = (IntPtr)((long)dataPtr + totalOffset);
                SystemProcessInformation pi = new SystemProcessInformation();

                Marshal.PtrToStructure(currentPtr, pi);

                // get information for a process
                ProcessInfo processInfo = new ProcessInfo();
                // Process ID shouldn't overflow. OS API GetCurrentProcessID returns DWORD.
                processInfo.ProcessId = pi.UniqueProcessId.ToInt32();
                processInfo.SessionId = (int)pi.SessionId;
                processInfo.PoolPagedBytes = (long)pi.QuotaPagedPoolUsage; ;
                processInfo.PoolNonPagedBytes = (long)pi.QuotaNonPagedPoolUsage;
                processInfo.VirtualBytes = (long)pi.VirtualSize;
                processInfo.VirtualBytesPeak = (long)pi.PeakVirtualSize;
                processInfo.WorkingSetPeak = (long)pi.PeakWorkingSetSize;
                processInfo.WorkingSet = (long)pi.WorkingSetSize;
                processInfo.PageFileBytesPeak = (long)pi.PeakPagefileUsage;
                processInfo.PageFileBytes = (long)pi.PagefileUsage;
                processInfo.PrivateBytes = (long)pi.PrivatePageCount;
                processInfo.BasePriority = pi.BasePriority;


                if (pi.NamePtr == IntPtr.Zero)
                {
                    if (processInfo.ProcessId == NtProcessManager.SystemProcessID)
                    {
                        processInfo.ProcessName = "System";
                    }
                    else if (processInfo.ProcessId == NtProcessManager.IdleProcessID)
                    {
                        processInfo.ProcessName = "Idle";
                    }
                    else
                    {
                        // for normal process without name, using the process ID. 
                        processInfo.ProcessName = processInfo.ProcessId.ToString(CultureInfo.InvariantCulture);
                    }
                }
                else
                {
                    string processName = GetProcessShortName(Marshal.PtrToStringUni(pi.NamePtr, pi.NameLength / sizeof(char)));
                    processInfo.ProcessName = processName;
                }

                // get the threads for current process
                processInfos[processInfo.ProcessId] = processInfo;

                currentPtr = (IntPtr)((long)currentPtr + Marshal.SizeOf(pi));
                int i = 0;
                while (i < pi.NumberOfThreads)
                {
                    SystemThreadInformation ti = new SystemThreadInformation();
                    Marshal.PtrToStructure(currentPtr, ti);
                    ThreadInfo threadInfo = new ThreadInfo();

                    threadInfo._processId = (int)ti.UniqueProcess;
                    threadInfo._threadId = (ulong)ti.UniqueThread;
                    threadInfo._basePriority = ti.BasePriority;
                    threadInfo._currentPriority = ti.Priority;
                    threadInfo._startAddress = ti.StartAddress;
                    threadInfo._threadState = (ThreadState)ti.ThreadState;
                    threadInfo._threadWaitReason = NtProcessManager.GetThreadWaitReason((int)ti.WaitReason);

                    processInfo._threadInfoList.Add(threadInfo);
                    currentPtr = (IntPtr)((long)currentPtr + Marshal.SizeOf(ti));
                    i++;
                }

                if (pi.NextEntryOffset == 0)
                {
                    break;
                }
                totalOffset += pi.NextEntryOffset;
            }

            ProcessInfo[] temp = new ProcessInfo[processInfos.Values.Count];
            processInfos.Values.CopyTo(temp, 0);
            return temp;
        }
       static ProcessInfo[] GetProcessInfos(IntPtr dataPtr) {
            // 60 is a reasonable number for processes on a normal machine.
            Hashtable processInfos = new Hashtable(60);

            long totalOffset = 0;
            
            while(true) {
                IntPtr currentPtr = (IntPtr)((long)dataPtr + totalOffset);
                SystemProcessInformation pi = new SystemProcessInformation();

                Marshal.PtrToStructure(currentPtr, pi);

                // get information for a process
                ProcessInfo processInfo = new ProcessInfo();
                // Process ID shouldn't overflow. OS API GetCurrentProcessID returns DWORD.
                processInfo.processId = pi.UniqueProcessId.ToInt32();
                processInfo.handleCount = (int)pi.HandleCount;
                processInfo.sessionId = (int)pi.SessionId;                
                processInfo.poolPagedBytes = (long)pi.QuotaPagedPoolUsage;;
                processInfo.poolNonpagedBytes = (long)pi.QuotaNonPagedPoolUsage;
                processInfo.virtualBytes = (long)pi.VirtualSize;
                processInfo.virtualBytesPeak = (long)pi.PeakVirtualSize;
                processInfo.workingSetPeak = (long)pi.PeakWorkingSetSize;
                processInfo.workingSet = (long)pi.WorkingSetSize;
                processInfo.pageFileBytesPeak = (long)pi.PeakPagefileUsage;
                processInfo.pageFileBytes = (long)pi.PagefileUsage;
                processInfo.privateBytes = (long)pi.PrivatePageCount;
                processInfo.basePriority = pi.BasePriority;


                if( pi.NamePtr == IntPtr.Zero) {                    
                    if( processInfo.processId == NtProcessManager.SystemProcessID) {
                        processInfo.processName = "System";
                    }
                    else if( processInfo.processId == NtProcessManager.IdleProcessID) {
                        processInfo.processName = "Idle";
                    }
                    else { 
                        // for normal process without name, using the process ID. 
                        processInfo.processName = processInfo.processId.ToString(CultureInfo.InvariantCulture);
                    }
                }
                else {                     
                    string processName = GetProcessShortName(Marshal.PtrToStringUni(pi.NamePtr, pi.NameLength/sizeof(char)));  
                    //
                    // On old operating system (NT4 and windows 2000), the process name might be truncated to 15 
                    // characters. For example, aspnet_admin.exe will show up in performance counter as aspnet_admin.ex.
                    // Process class try to return a nicer name. We used to get the main module name for a process and 
                    // use that as the process name. However normal user doesn't have access to module information, 
                    // so normal user will see an exception when we try to get a truncated process name.
                    //                    
                    if (ProcessManager.IsOSOlderThanXP && (processName.Length == 15)) {
                        if (processName.EndsWith(".", StringComparison.OrdinalIgnoreCase)) {
                            processName = processName.Substring(0, 14);
                        }
                        else if (processName.EndsWith(".e", StringComparison.OrdinalIgnoreCase)) {
                            processName = processName.Substring(0, 13);
                        }
                        else if (processName.EndsWith(".ex", StringComparison.OrdinalIgnoreCase)) {
                            processName = processName.Substring(0, 12);
                        }
                    }
                    processInfo.processName = processName;                                          
                }

                // get the threads for current process
                processInfos[processInfo.processId] =  processInfo;

                currentPtr = (IntPtr)((long)currentPtr + Marshal.SizeOf(pi));
                int i = 0;
                while( i < pi.NumberOfThreads) {
                    SystemThreadInformation ti = new SystemThreadInformation();
                    Marshal.PtrToStructure(currentPtr, ti);                    
                    ThreadInfo threadInfo = new ThreadInfo();                    

                    threadInfo.processId = (int)ti.UniqueProcess;
                    threadInfo.threadId = (int)ti.UniqueThread;
                    threadInfo.basePriority = ti.BasePriority;
                    threadInfo.currentPriority = ti.Priority;
                    threadInfo.startAddress = ti.StartAddress;
                    threadInfo.threadState = (ThreadState)ti.ThreadState;
                    threadInfo.threadWaitReason = NtProcessManager.GetThreadWaitReason((int)ti.WaitReason);

                    processInfo.threadInfoList.Add(threadInfo);
                    currentPtr = (IntPtr)((long)currentPtr + Marshal.SizeOf(ti));
                    i++;
                }

                if (pi.NextEntryOffset == 0) {
                    break;
                }
                totalOffset += pi.NextEntryOffset;
            }

            ProcessInfo[] temp = new ProcessInfo[processInfos.Values.Count];
            processInfos.Values.CopyTo(temp, 0);
            return temp;
        }
Beispiel #4
0
        static ProcessInfo[] GetProcessInfos(IntPtr dataPtr)
        {
            // 60 is a reasonable number for processes on a normal machine.
            Dictionary <int, ProcessInfo> processInfos = new Dictionary <int, ProcessInfo>(60);

            long totalOffset = 0;

            while (true)
            {
                IntPtr currentPtr           = (IntPtr)((long)dataPtr + totalOffset);
                SystemProcessInformation pi = new SystemProcessInformation();

                Marshal.PtrToStructure(currentPtr, pi);

                // get information for a process
                ProcessInfo processInfo = new ProcessInfo();
                // Process ID shouldn't overflow. OS API GetCurrentProcessID returns DWORD.
                processInfo._processId         = pi.UniqueProcessId.ToInt32();
                processInfo._handleCount       = (int)pi.HandleCount;
                processInfo._sessionId         = (int)pi.SessionId;
                processInfo._poolPagedBytes    = (long)pi.QuotaPagedPoolUsage;;
                processInfo._poolNonpagedBytes = (long)pi.QuotaNonPagedPoolUsage;
                processInfo._virtualBytes      = (long)pi.VirtualSize;
                processInfo._virtualBytesPeak  = (long)pi.PeakVirtualSize;
                processInfo._workingSetPeak    = (long)pi.PeakWorkingSetSize;
                processInfo._workingSet        = (long)pi.WorkingSetSize;
                processInfo._pageFileBytesPeak = (long)pi.PeakPagefileUsage;
                processInfo._pageFileBytes     = (long)pi.PagefileUsage;
                processInfo._privateBytes      = (long)pi.PrivatePageCount;
                processInfo._basePriority      = pi.BasePriority;


                if (pi.NamePtr == IntPtr.Zero)
                {
                    if (processInfo._processId == NtProcessManager.SystemProcessID)
                    {
                        processInfo._processName = "System";
                    }
                    else if (processInfo._processId == NtProcessManager.IdleProcessID)
                    {
                        processInfo._processName = "Idle";
                    }
                    else
                    {
                        // for normal process without name, using the process ID.
                        processInfo._processName = processInfo._processId.ToString(CultureInfo.InvariantCulture);
                    }
                }
                else
                {
                    string processName = GetProcessShortName(Marshal.PtrToStringUni(pi.NamePtr, pi.NameLength / sizeof(char)));
                    processInfo._processName = processName;
                }

                // get the threads for current process
                processInfos[processInfo._processId] = processInfo;

                currentPtr = (IntPtr)((long)currentPtr + Marshal.SizeOf(pi));
                int i = 0;
                while (i < pi.NumberOfThreads)
                {
                    SystemThreadInformation ti = new SystemThreadInformation();
                    Marshal.PtrToStructure(currentPtr, ti);
                    ThreadInfo threadInfo = new ThreadInfo();

                    threadInfo._processId        = (int)ti.UniqueProcess;
                    threadInfo._threadId         = (int)ti.UniqueThread;
                    threadInfo._basePriority     = ti.BasePriority;
                    threadInfo._currentPriority  = ti.Priority;
                    threadInfo._startAddress     = ti.StartAddress;
                    threadInfo._threadState      = (ThreadState)ti.ThreadState;
                    threadInfo._threadWaitReason = NtProcessManager.GetThreadWaitReason((int)ti.WaitReason);

                    processInfo._threadInfoList.Add(threadInfo);
                    currentPtr = (IntPtr)((long)currentPtr + Marshal.SizeOf(ti));
                    i++;
                }

                if (pi.NextEntryOffset == 0)
                {
                    break;
                }
                totalOffset += pi.NextEntryOffset;
            }

            ProcessInfo[] temp = new ProcessInfo[processInfos.Values.Count];
            processInfos.Values.CopyTo(temp, 0);
            return(temp);
        }
        protected override void Update()
        {
            // Load symbols if they are not already loaded.
            this.LoadSymbols();

            var threads = Windows.GetProcessThreads(_pid);
            Dictionary <int, ThreadItem> newdictionary = new Dictionary <int, ThreadItem>(this.Dictionary);

            if (threads == null)
            {
                threads = new Dictionary <int, SystemThreadInformation>();
            }

            // look for dead threads
            foreach (int tid in Dictionary.Keys)
            {
                if (!threads.ContainsKey(tid))
                {
                    ThreadItem item = this.Dictionary[tid];

                    if (item.ThreadQueryLimitedHandle != null)
                    {
                        item.ThreadQueryLimitedHandle.Dispose();
                    }

                    this.OnDictionaryRemoved(item);
                    newdictionary.Remove(tid);
                }
            }

            // Get resolve results.
            _messageQueue.Listen();

            // look for new threads
            foreach (int tid in threads.Keys)
            {
                SystemThreadInformation t = threads[tid];

                if (!Dictionary.ContainsKey(tid))
                {
                    ThreadItem item = new ThreadItem
                    {
                        RunId           = this.RunCount,
                        Tid             = tid,
                        ContextSwitches = t.ContextSwitchCount,
                        WaitReason      = t.WaitReason
                    };

                    try
                    {
                        item.ThreadQueryHandle        = new ThreadHandle(tid, OSVersion.MinThreadQueryInfoAccess);
                        item.ThreadQueryLimitedHandle = new ThreadHandle(tid, Program.MinThreadQueryRights);

                        try
                        {
                            item.PriorityI = (int)item.ThreadQueryLimitedHandle.GetBasePriorityWin32();
                            item.Priority  = item.ThreadQueryLimitedHandle.GetBasePriorityWin32().ToString();
                        }
                        catch
                        {
                        }

                        //if (KProcessHacker.Instance != null)
                        //{
                        //    try
                        //    {
                        //        item.IsGuiThread = KProcessHacker.Instance.KphGetThreadWin32Thread(item.ThreadQueryLimitedHandle) != 0;
                        //    }
                        //    catch
                        //    { }
                        //}

                        if (OSVersion.HasCycleTime)
                        {
                            try
                            {
                                item.Cycles = item.ThreadQueryLimitedHandle.GetCycleTime();
                            }
                            catch
                            {
                            }
                        }

                        item.StartAddressI = item.ThreadQueryLimitedHandle.GetWin32StartAddress();
                    }
                    catch
                    {
                        item.StartAddressI = t.StartAddress;
                    }


                    if (_moduleLoadCompletedEvent.Wait(0))
                    {
                        try
                        {
                            item.StartAddress = this.GetThreadBasicStartAddress(
                                item.StartAddressI.ToUInt64(), out item.StartAddressLevel);
                        }
                        catch
                        { }
                    }

                    if (string.IsNullOrEmpty(item.StartAddress))
                    {
                        item.StartAddress      = Utils.FormatAddress(item.StartAddressI);
                        item.StartAddressLevel = SymbolResolveLevel.Address;
                    }

                    this.QueueThreadResolveStartAddress(tid, item.StartAddressI.ToUInt64());

                    newdictionary.Add(tid, item);
                    this.OnDictionaryAdded(item);
                }
                // look for modified threads
                else
                {
                    ThreadItem item    = Dictionary[tid];
                    ThreadItem newitem = item.Clone() as ThreadItem;

                    newitem.JustResolved         = false;
                    newitem.ContextSwitchesDelta = t.ContextSwitchCount - newitem.ContextSwitches;
                    newitem.ContextSwitches      = t.ContextSwitchCount;
                    newitem.WaitReason           = t.WaitReason;

                    try
                    {
                        newitem.PriorityI = (int)newitem.ThreadQueryLimitedHandle.GetBasePriorityWin32();
                        newitem.Priority  = newitem.ThreadQueryLimitedHandle.GetBasePriorityWin32().ToString();
                    }
                    catch
                    { }

                    if (OSVersion.HasCycleTime)
                    {
                        try
                        {
                            ulong thisCycles = newitem.ThreadQueryLimitedHandle.GetCycleTime();

                            newitem.CyclesDelta = thisCycles - newitem.Cycles;
                            newitem.Cycles      = thisCycles;
                        }
                        catch
                        { }
                    }

                    if (newitem.StartAddressLevel == SymbolResolveLevel.Address)
                    {
                        if (_moduleLoadCompletedEvent.Wait(0))
                        {
                            newitem.StartAddress = this.GetThreadBasicStartAddress(
                                newitem.StartAddressI.ToUInt64(), out newitem.StartAddressLevel);
                        }

                        // If we couldn't resolve it to a module+offset,
                        // use the StartAddress (instead of the Win32StartAddress)
                        // and queue the resolve again.
                        if (
                            item.StartAddressLevel == SymbolResolveLevel.Address &&
                            item.JustResolved)
                        {
                            if (item.StartAddressI != t.StartAddress)
                            {
                                item.StartAddressI = t.StartAddress;
                                this.QueueThreadResolveStartAddress(tid, item.StartAddressI.ToUInt64());
                            }
                        }
                    }

                    if (
                        newitem.ContextSwitches != item.ContextSwitches ||
                        newitem.ContextSwitchesDelta != item.ContextSwitchesDelta ||
                        newitem.Cycles != item.Cycles ||
                        newitem.CyclesDelta != item.CyclesDelta ||
                        newitem.IsGuiThread != item.IsGuiThread ||
                        newitem.Priority != item.Priority ||
                        newitem.StartAddress != item.StartAddress ||
                        newitem.WaitReason != item.WaitReason ||
                        item.JustResolved
                        )
                    {
                        newdictionary[tid] = newitem;
                        this.OnDictionaryModified(item, newitem);
                    }
                }
            }

            Dictionary = newdictionary;
        }
Beispiel #6
0
        public static ProcessInfo[] NtGetProcessInfos(IntPtr dataPtr)
        {
            IntPtr    ptr;
            Hashtable hashtable = new Hashtable(100);
            uint      num       = 0;

Label_000B:
            ptr = (IntPtr)(((uint)dataPtr) + num);
            SystemProcessInformation structure = new SystemProcessInformation();

            Marshal.PtrToStructure(ptr, structure);

            ProcessInfo info = new ProcessInfo();

            info.processId         = structure.UniqueProcessId.ToInt32();
            info.handleCount       = (int)structure.HandleCount;
            info.sessionId         = (int)structure.SessionId;
            info.poolPagedBytes    = (long)structure.QuotaPagedPoolUsage;
            info.poolNonpagedBytes = (long)structure.QuotaNonPagedPoolUsage;
            info.virtualBytes      = (long)structure.VirtualSize;
            info.virtualBytesPeak  = (long)structure.PeakVirtualSize;
            info.workingSetPeak    = (long)structure.PeakWorkingSetSize;
            info.workingSet        = (long)structure.WorkingSetSize;
            info.pageFileBytesPeak = (long)structure.PeakPagefileUsage;
            info.pageFileBytes     = (long)structure.PagefileUsage;
            info.privateBytes      = (long)structure.PrivatePageCount;
            info.basePriority      = structure.BasePriority;


            hashtable[info.processId] = info;
            try
            {
                ptr = (IntPtr)(((long)ptr) + Marshal.SizeOf(structure));
            }
            catch
            {
            }
            for (int i = 0; i < structure.NumberOfThreads; i++)
            {
                SystemThreadInformation information2 = new SystemThreadInformation();
                Marshal.PtrToStructure(ptr, information2);
                ThreadInfo info2 = new ThreadInfo
                {
                    processId        = (int)information2.UniqueProcess,
                    threadId         = (int)information2.UniqueThread,
                    basePriority     = information2.BasePriority,
                    currentPriority  = information2.Priority,
                    startAddress     = information2.StartAddress,
                    threadState      = (ThreadState)information2.ThreadState,
                    threadWaitReason = GetThreadWaitReason((int)information2.WaitReason)
                };
                info.threadInfoList.Add(info2);
                try
                {
                    ptr = (IntPtr)(((long)ptr) + Marshal.SizeOf(information2));
                }
                catch
                {
                }
            }
            if (structure.NextEntryOffset != 0)
            {
                num += (uint)structure.NextEntryOffset;
                goto Label_000B;
            }

            ProcessInfo[] array = new ProcessInfo[hashtable.Values.Count];
            hashtable.Values.CopyTo(array, 0);
            return(array);
        }
Beispiel #7
0
        private static ProcessInfo[] GetProcessInfos(IntPtr dataPtr)
        {
            IntPtr    ptr;
            Hashtable hashtable = new Hashtable(60);
            long      num       = 0L;

Label_000B:
            ptr = (IntPtr)(((long)dataPtr) + num);
            SystemProcessInformation structure = new SystemProcessInformation();

            Marshal.PtrToStructure(ptr, structure);
            ProcessInfo info = new ProcessInfo {
                processId         = structure.UniqueProcessId.ToInt32(),
                handleCount       = (int)structure.HandleCount,
                sessionId         = (int)structure.SessionId,
                poolPagedBytes    = (long)((ulong)structure.QuotaPagedPoolUsage),
                poolNonpagedBytes = (long)((ulong)structure.QuotaNonPagedPoolUsage),
                virtualBytes      = (long)((ulong)structure.VirtualSize),
                virtualBytesPeak  = (long)((ulong)structure.PeakVirtualSize),
                workingSetPeak    = (long)((ulong)structure.PeakWorkingSetSize),
                workingSet        = (long)((ulong)structure.WorkingSetSize),
                pageFileBytesPeak = (long)((ulong)structure.PeakPagefileUsage),
                pageFileBytes     = (long)((ulong)structure.PagefileUsage),
                privateBytes      = (long)((ulong)structure.PrivatePageCount),
                basePriority      = structure.BasePriority
            };

            if (structure.NamePtr == IntPtr.Zero)
            {
                if (info.processId == NtProcessManager.SystemProcessID)
                {
                    info.processName = "System";
                }
                else if (info.processId == 0)
                {
                    info.processName = "Idle";
                }
                else
                {
                    info.processName = info.processId.ToString(CultureInfo.InvariantCulture);
                }
            }
            else
            {
                string processShortName = GetProcessShortName(Marshal.PtrToStringUni(structure.NamePtr, structure.NameLength / 2));
                if (ProcessManager.IsOSOlderThanXP && (processShortName.Length == 15))
                {
                    if (processShortName.EndsWith(".", StringComparison.OrdinalIgnoreCase))
                    {
                        processShortName = processShortName.Substring(0, 14);
                    }
                    else if (processShortName.EndsWith(".e", StringComparison.OrdinalIgnoreCase))
                    {
                        processShortName = processShortName.Substring(0, 13);
                    }
                    else if (processShortName.EndsWith(".ex", StringComparison.OrdinalIgnoreCase))
                    {
                        processShortName = processShortName.Substring(0, 12);
                    }
                }
                info.processName = processShortName;
            }
            hashtable[info.processId] = info;
            ptr = (IntPtr)(((long)ptr) + Marshal.SizeOf(structure));
            for (int i = 0; i < structure.NumberOfThreads; i++)
            {
                SystemThreadInformation information2 = new SystemThreadInformation();
                Marshal.PtrToStructure(ptr, information2);
                ThreadInfo info2 = new ThreadInfo {
                    processId        = (int)information2.UniqueProcess,
                    threadId         = (int)information2.UniqueThread,
                    basePriority     = information2.BasePriority,
                    currentPriority  = information2.Priority,
                    startAddress     = information2.StartAddress,
                    threadState      = (ThreadState)information2.ThreadState,
                    threadWaitReason = NtProcessManager.GetThreadWaitReason((int)information2.WaitReason)
                };
                info.threadInfoList.Add(info2);
                ptr = (IntPtr)(((long)ptr) + Marshal.SizeOf(information2));
            }
            if (structure.NextEntryOffset != 0)
            {
                num += structure.NextEntryOffset;
                goto Label_000B;
            }
            ProcessInfo[] array = new ProcessInfo[hashtable.Values.Count];
            hashtable.Values.CopyTo(array, 0);
            return(array);
        }
Beispiel #8
0
        /// <summary>
        /// Gets a dictionary containing the threads owned by the specified process.
        /// </summary>
        /// <param name="pid">A process ID.</param>
        /// <returns>A dictionary, indexed by thread ID.</returns>
        public static Dictionary <int, SystemThreadInformation> GetProcessThreads(int pid)
        {
            int retLength;

            if (_processesBuffer == null)
            {
                _processesBuffer = new MemoryAlloc(0x10000);
            }

            MemoryAlloc data = _processesBuffer;

            NtStatus status;
            int      attempts = 0;

            while (true)
            {
                attempts++;

                if ((status = Win32.NtQuerySystemInformation(
                         SystemInformationClass.SystemProcessInformation,
                         data.Memory,
                         data.Size,
                         out retLength)
                     ).IsError())
                {
                    if (attempts > 3)
                    {
                        Win32.Throw(status);
                    }

                    data.ResizeNew(retLength);
                }
                else
                {
                    break;
                }
            }

            int i = 0;
            SystemProcessInformation process;

            do
            {
                unsafe
                {
                    //process = data.ReadStruct<SystemProcessInformation>(i, 0);
                    process = *(SystemProcessInformation *)((byte *)data.Memory + i);
                }

                if (process.ProcessId == pid)
                {
                    Dictionary <int, SystemThreadInformation> threads = new Dictionary <int, SystemThreadInformation>();

                    for (int j = 0; j < process.NumberOfThreads; j++)
                    {
                        SystemThreadInformation thread = data.ReadStruct <SystemThreadInformation>(i + SystemProcessInformation.SizeOf, SystemThreadInformation.SizeOf, j);

                        if (pid != 0)
                        {
                            threads.Add(thread.ClientId.ThreadId, thread);
                        }
                        else
                        {
                            // Fix System Idle Process threads.
                            // There is one thread per CPU, but they
                            // all have a TID of 0. Assign unique TIDs.
                            threads.Add(j, thread);
                        }
                    }

                    return(threads);
                }

                i += process.NextEntryOffset;
            } while (process.NextEntryOffset != 0);

            return(null);
        }