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;
processInfo.HandleCount = (int)pi.HandleCount;
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;
}