From b04aeeb56aefcb39a9d615bfc0f721b7b606731b Mon Sep 17 00:00:00 2001 From: wj32 Date: Sat, 27 Dec 2008 04:26:58 +0000 Subject: [PATCH] switch to using ZwQuerySystemInformation for enumerating processes git-svn-id: svn://svn.code.sf.net/p/processhacker/code@431 21ef857c-d57f-4fe0-8362-d861dc6d29cd --- .../Components/ProcessTree/ProcessTree.cs | 18 +- .../ProcessTree/ProcessTreeModel.cs | 13 +- trunk/ProcessHacker/Forms/HackerWindow.cs | 12 +- trunk/ProcessHacker/Forms/ProcessWindow.cs | 5 + trunk/ProcessHacker/ProcessHacker.csproj | 2 +- ...ssProvider.cs => ProcessSystemProvider.cs} | 166 ++++++++-------- trunk/ProcessHacker/Win32/API/Functions.cs | 16 +- trunk/ProcessHacker/Win32/API/Structs.cs | 182 ++++++++++-------- trunk/ProcessHacker/Win32/Win32.cs | 48 ++--- 9 files changed, 258 insertions(+), 204 deletions(-) rename trunk/ProcessHacker/Providers/{ProcessProvider.cs => ProcessSystemProvider.cs} (66%) diff --git a/trunk/ProcessHacker/Components/ProcessTree/ProcessTree.cs b/trunk/ProcessHacker/Components/ProcessTree/ProcessTree.cs index e49a20ee8..eec73b9ae 100644 --- a/trunk/ProcessHacker/Components/ProcessTree/ProcessTree.cs +++ b/trunk/ProcessHacker/Components/ProcessTree/ProcessTree.cs @@ -27,7 +27,7 @@ namespace ProcessHacker { public partial class ProcessTree : UserControl { - ProcessProvider _provider; + ProcessSystemProvider _provider; ProcessTreeModel _treeModel; public new event KeyEventHandler KeyDown; public new event MouseEventHandler MouseDown; @@ -122,16 +122,16 @@ namespace ProcessHacker get { return _treeModel; } } - public ProcessProvider Provider + public ProcessSystemProvider Provider { get { return _provider; } set { if (_provider != null) { - _provider.DictionaryAdded -= new ProcessProvider.ProviderDictionaryAdded(provider_DictionaryAdded); - _provider.DictionaryModified -= new ProcessProvider.ProviderDictionaryModified(provider_DictionaryModified); - _provider.DictionaryRemoved -= new ProcessProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved); + _provider.DictionaryAdded -= new ProcessSystemProvider.ProviderDictionaryAdded(provider_DictionaryAdded); + _provider.DictionaryModified -= new ProcessSystemProvider.ProviderDictionaryModified(provider_DictionaryModified); + _provider.DictionaryRemoved -= new ProcessSystemProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved); } _provider = value; @@ -146,10 +146,10 @@ namespace ProcessHacker } _provider.UseInvoke = true; - _provider.Invoke = new ProcessProvider.ProviderInvokeMethod(this.BeginInvoke); - _provider.DictionaryAdded += new ProcessProvider.ProviderDictionaryAdded(provider_DictionaryAdded); - _provider.DictionaryModified += new ProcessProvider.ProviderDictionaryModified(provider_DictionaryModified); - _provider.DictionaryRemoved += new ProcessProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved); + _provider.Invoke = new ProcessSystemProvider.ProviderInvokeMethod(this.BeginInvoke); + _provider.DictionaryAdded += new ProcessSystemProvider.ProviderDictionaryAdded(provider_DictionaryAdded); + _provider.DictionaryModified += new ProcessSystemProvider.ProviderDictionaryModified(provider_DictionaryModified); + _provider.DictionaryRemoved += new ProcessSystemProvider.ProviderDictionaryRemoved(provider_DictionaryRemoved); } } } diff --git a/trunk/ProcessHacker/Components/ProcessTree/ProcessTreeModel.cs b/trunk/ProcessHacker/Components/ProcessTree/ProcessTreeModel.cs index 007fda4c9..f3d8318ce 100644 --- a/trunk/ProcessHacker/Components/ProcessTree/ProcessTreeModel.cs +++ b/trunk/ProcessHacker/Components/ProcessTree/ProcessTreeModel.cs @@ -126,23 +126,26 @@ namespace ProcessHacker return TreePath.Empty; else { + ProcessNode currentNode = node; Stack stack = new Stack(); while (true) { - stack.Push(node); + stack.Push(currentNode); - if (_processes.ContainsKey(node.PPID)) + if (_processes.ContainsKey(currentNode.PPID)) { - ProcessNode newNode = _processes[node.PPID]; + ProcessNode newNode = _processes[currentNode.PPID]; - if (newNode == node) + if (newNode == currentNode) break; - node = newNode; + currentNode = newNode; } else + { break; + } } return new TreePath(stack.ToArray()); diff --git a/trunk/ProcessHacker/Forms/HackerWindow.cs b/trunk/ProcessHacker/Forms/HackerWindow.cs index 01f533ff9..12818ff9e 100644 --- a/trunk/ProcessHacker/Forms/HackerWindow.cs +++ b/trunk/ProcessHacker/Forms/HackerWindow.cs @@ -45,7 +45,7 @@ namespace ProcessHacker public SysInfoWindow SysInfoWindow = null; public HandleFilterWindow HandleFilterForm = new HandleFilterWindow(); - ProcessProvider processP = new ProcessProvider(); + ProcessSystemProvider processP = new ProcessSystemProvider(); ServiceProvider serviceP = new ServiceProvider(); Dictionary> processServices = new Dictionary>(); @@ -78,7 +78,7 @@ namespace ProcessHacker get { return vistaMenu; } } - public ProcessProvider ProcessProvider + public ProcessSystemProvider ProcessProvider { get { return processP; } } @@ -1394,9 +1394,9 @@ namespace ProcessHacker private void processP_Updated() { - processP.DictionaryAdded += new ProcessProvider.ProviderDictionaryAdded(processP_DictionaryAdded); - processP.DictionaryRemoved += new ProcessProvider.ProviderDictionaryRemoved(processP_DictionaryRemoved); - processP.Updated -= new ProcessProvider.ProviderUpdateOnce(processP_Updated); + processP.DictionaryAdded += new ProcessSystemProvider.ProviderDictionaryAdded(processP_DictionaryAdded); + processP.DictionaryRemoved += new ProcessSystemProvider.ProviderDictionaryRemoved(processP_DictionaryRemoved); + processP.Updated -= new ProcessSystemProvider.ProviderUpdateOnce(processP_Updated); if (processP.RunCount >= 1) this.Invoke(new MethodInvoker(UpdateCommon)); @@ -1435,7 +1435,7 @@ namespace ProcessHacker processP.Interval = RefreshInterval; treeProcesses.Provider = processP; - processP.Updated += new ProcessProvider.ProviderUpdateOnce(processP_Updated); + processP.Updated += new ProcessSystemProvider.ProviderUpdateOnce(processP_Updated); processP.Enabled = true; HighlightedListViewItem.HighlightingDuration = Properties.Settings.Default.HighlightingDuration; diff --git a/trunk/ProcessHacker/Forms/ProcessWindow.cs b/trunk/ProcessHacker/Forms/ProcessWindow.cs index 14bc2d656..027810814 100644 --- a/trunk/ProcessHacker/Forms/ProcessWindow.cs +++ b/trunk/ProcessHacker/Forms/ProcessWindow.cs @@ -187,6 +187,11 @@ namespace ProcessHacker buttonInspectParent.Enabled = false; } } + else + { + textParent.Text = "No parent"; + buttonInspectParent.Enabled = false; + } this.UpdateDEPStatus(); diff --git a/trunk/ProcessHacker/ProcessHacker.csproj b/trunk/ProcessHacker/ProcessHacker.csproj index 297f29709..4e00d99ce 100644 --- a/trunk/ProcessHacker/ProcessHacker.csproj +++ b/trunk/ProcessHacker/ProcessHacker.csproj @@ -482,12 +482,12 @@ + - Component diff --git a/trunk/ProcessHacker/Providers/ProcessProvider.cs b/trunk/ProcessHacker/Providers/ProcessSystemProvider.cs similarity index 66% rename from trunk/ProcessHacker/Providers/ProcessProvider.cs rename to trunk/ProcessHacker/Providers/ProcessSystemProvider.cs index e17cc19c3..216a9cf41 100644 --- a/trunk/ProcessHacker/Providers/ProcessProvider.cs +++ b/trunk/ProcessHacker/Providers/ProcessSystemProvider.cs @@ -22,6 +22,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Windows.Forms; +using System.Runtime.InteropServices; namespace ProcessHacker { @@ -35,12 +36,14 @@ namespace ProcessHacker public long MemoryUsage; public string Name; public string Username; + public Win32.SYSTEM_PROCESS_INFORMATION Process; + public Win32.SYSTEM_THREAD_INFORMATION[] Threads; public Win32.TOKEN_ELEVATION_TYPE ElevationType; public bool IsElevated; public bool IsBeingDebugged; public bool IsVirtualizationEnabled; - public ulong LastTime; + public long LastTime; public int SessionId; public int ParentPID; public int IconAttempts; @@ -51,40 +54,65 @@ namespace ProcessHacker public Win32.ProcessHandle ProcessQueryLimitedVmReadHandle; } - public class ProcessProvider : Provider + public class ProcessSystemProvider : Provider { - private ulong _lastSysTime; + private long _lastSysTime; - public ProcessProvider() + public ProcessSystemProvider() : base() { this.ProviderUpdate += new ProviderUpdateOnce(UpdateOnce); - ulong[] systemTimes = Win32.GetSystemTimes(); + Win32.SYSTEM_BASIC_INFORMATION basic = new Win32.SYSTEM_BASIC_INFORMATION(); + int retLen; - _lastSysTime = systemTimes[1] / 10000 + systemTimes[2] / 10000; + Win32.ZwQuerySystemInformation(Win32.SYSTEM_INFORMATION_CLASS.SystemBasicInformation, ref basic, + Marshal.SizeOf(basic), out retLen); + this.System = basic; + + this.UpdateProcessorPerf(); + _lastSysTime = this.ProcessorPerf.KernelTime + this.ProcessorPerf.UserTime; + } + + public Win32.SYSTEM_BASIC_INFORMATION System { get; private set; } + public Win32.SYSTEM_PERFORMANCE_INFORMATION Performance { get; private set; } + public Win32.SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION ProcessorPerf { get; private set; } + + private void UpdateProcessorPerf() + { + int retLen; + Win32.SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION procPerf = new Win32.SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION(); + + Win32.ZwQuerySystemInformation(Win32.SYSTEM_INFORMATION_CLASS.SystemProcessorTimes, + ref procPerf, Marshal.SizeOf(procPerf), out retLen); + this.ProcessorPerf = procPerf; + } + + private void UpdatePerformance() + { + int retLen; + Win32.SYSTEM_PERFORMANCE_INFORMATION performance = new Win32.SYSTEM_PERFORMANCE_INFORMATION(); + + Win32.ZwQuerySystemInformation(Win32.SYSTEM_INFORMATION_CLASS.SystemPerformanceInformation, + ref performance, Marshal.SizeOf(performance), out retLen); + this.Performance = performance; } private void UpdateOnce() { - Process[] processes = Process.GetProcesses(); + this.UpdatePerformance(); + this.UpdateProcessorPerf(); + Dictionary tsProcesses = new Dictionary(); - Dictionary procs = new Dictionary(); + Dictionary procs = Win32.EnumProcesses(); Dictionary newdictionary = new Dictionary(this.Dictionary); Win32.WtsEnumProcessesFastData wtsEnumData = Win32.TSEnumProcessesFast(); - ulong[] systemTimes = Win32.GetSystemTimes(); - ulong thisSysTime = systemTimes[1] / 10000 + systemTimes[2] / 10000; - ulong sysTime = thisSysTime - _lastSysTime; + long thisSysTime = this.ProcessorPerf.KernelTime + this.ProcessorPerf.UserTime; + long sysTime = thisSysTime - _lastSysTime; _lastSysTime = thisSysTime; - for (int i = 0; i < wtsEnumData.PIDs.Length; i++) - tsProcesses.Add(wtsEnumData.PIDs[i], wtsEnumData.SIDs[i]); - - foreach (Process p in processes) - procs.Add(p.Id, p); - // look for dead processes foreach (int pid in Dictionary.Keys) { @@ -110,22 +138,18 @@ namespace ProcessHacker // look for new processes foreach (int pid in procs.Keys) { - Process p = procs[pid]; + Win32.SYSTEM_PROCESS_INFORMATION processInfo = procs[pid].Process; + Process p = Process.GetProcessById(pid); if (!Dictionary.ContainsKey(pid)) - { + { ProcessItem item = new ProcessItem(); item.PID = pid; - - try - { - item.SessionId = Win32.GetProcessSessionId(pid); - } - catch - { - item.SessionId = -1; - } + item.LastTime = processInfo.KernelTime + processInfo.UserTime; + item.MemoryUsage = processInfo.VirtualMemoryCounters.PrivatePageCount; + item.Process = processInfo; + item.SessionId = processInfo.SessionId; try { @@ -139,32 +163,20 @@ namespace ProcessHacker if (p.Id == 0) item.Name = "System Idle Process"; else - item.Name = p.MainModule.ModuleName; + item.Name = procs[pid].Name; } catch { - item.Name = Win32.GetNameFromPID(pid); - - if (item.Name == "(error)" || item.Name == "(unknown)") + try { - try - { - item.Name = "(" + p.ProcessName + ")"; - } - catch - { - item.Name = "(unknown)"; - } + item.Name = p.MainModule.ModuleName; + } + catch + { + item.Name = Win32.GetNameFromPID(pid); } } - try - { - item.MemoryUsage = p.PrivateMemorySize64; - } - catch - { } - try { item.ProcessQueryHandle = new Win32.ProcessHandle(pid, Win32.PROCESS_RIGHTS.PROCESS_QUERY_INFORMATION); @@ -182,15 +194,6 @@ namespace ProcessHacker try { item.ProcessQueryLimitedHandle = new Win32.ProcessHandle(pid, Program.MinProcessQueryRights); - - try - { - ulong[] times = Win32.GetProcessTimes(item.ProcessQueryLimitedHandle); - - item.LastTime = times[2] / 10000 + times[3] / 10000; - } - catch - { } try { @@ -211,6 +214,18 @@ namespace ProcessHacker try { item.ParentPID = item.ProcessQueryLimitedHandle.GetParentPID(); + + // check the parent's creation time to see if it's actually the parent + try + { + DateTime thisStartTime = p.StartTime; + DateTime parentStartTime = Process.GetProcessById(item.ParentPID).StartTime; + + if (parentStartTime > thisStartTime) + item.ParentPID = -1; // parent was started later than child! it's a fake. + } + catch + { } // item.ParentPID = -1; } catch { @@ -227,6 +242,13 @@ namespace ProcessHacker if (item.Username == null) { + if (tsProcesses.Count == 0) + { + // delay loading until this point + for (int i = 0; i < wtsEnumData.PIDs.Length; i++) + tsProcesses.Add(wtsEnumData.PIDs[i], wtsEnumData.SIDs[i]); + } + try { item.Username = Win32.GetAccountName(tsProcesses[pid], true); @@ -236,7 +258,7 @@ namespace ProcessHacker } if (pid == 0) - item.LastTime = systemTimes[0] / 10000; + item.LastTime = this.ProcessorPerf.IdleTime; try { @@ -259,14 +281,23 @@ namespace ProcessHacker ProcessItem newitem = new ProcessItem(); newitem = item; + newitem.LastTime = processInfo.KernelTime + processInfo.UserTime; + newitem.MemoryUsage = processInfo.VirtualMemoryCounters.PrivatePageCount; try { - newitem.MemoryUsage = p.PrivateMemorySize64; + newitem.CPUUsage = ((float)(newitem.LastTime - item.LastTime) * 100 / sysTime) / + this.System.NumberOfProcessors; } catch { } + if (pid == 0) + { + newitem.LastTime = this.ProcessorPerf.IdleTime; + newitem.CPUUsage = ((float)(newitem.LastTime - item.LastTime) * 100 / sysTime); + } + if (newitem.Icon == null && newitem.IconAttempts < 5) { try @@ -293,25 +324,10 @@ namespace ProcessHacker catch { } - try - { - ulong[] times = Win32.GetProcessTimes(item.ProcessQueryLimitedHandle); - - newitem.LastTime = times[2] / 10000 + times[3] / 10000; - newitem.CPUUsage = ((float)(newitem.LastTime - item.LastTime) * 100 / sysTime); - } - catch - { } - - if (pid == 0) - { - newitem.LastTime = systemTimes[0] / 10000; - newitem.CPUUsage = ((float)(newitem.LastTime - item.LastTime) * 100 / sysTime); - } - if (newitem.MemoryUsage != item.MemoryUsage || newitem.CPUUsage != item.CPUUsage || - newitem.IsBeingDebugged != item.IsBeingDebugged) + newitem.IsBeingDebugged != item.IsBeingDebugged || + newitem.IsVirtualizationEnabled != item.IsVirtualizationEnabled) { newdictionary[pid] = newitem; this.CallDictionaryModified(item, newitem); diff --git a/trunk/ProcessHacker/Win32/API/Functions.cs b/trunk/ProcessHacker/Win32/API/Functions.cs index 96ca41639..68dadce8f 100644 --- a/trunk/ProcessHacker/Win32/API/Functions.cs +++ b/trunk/ProcessHacker/Win32/API/Functions.cs @@ -602,11 +602,23 @@ namespace ProcessHacker [DllImport("ntdll.dll", SetLastError = true)] public static extern uint ZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, - IntPtr SystemInformation, int SystemInformationLength, ref int ReturnLength); + ref SYSTEM_BASIC_INFORMATION SystemInformation, int SystemInformationLength, out int ReturnLength); + + [DllImport("ntdll.dll", SetLastError = true)] + public static extern uint ZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, + ref SYSTEM_PERFORMANCE_INFORMATION SystemInformation, int SystemInformationLength, out int ReturnLength); + + [DllImport("ntdll.dll", SetLastError = true)] + public static extern uint ZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, + ref SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SystemInformation, int SystemInformationLength, out int ReturnLength); + + [DllImport("ntdll.dll", SetLastError = true)] + public static extern uint ZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, + IntPtr SystemInformation, int SystemInformationLength, out int ReturnLength); [DllImport("ntdll.dll", SetLastError = true)] public static extern uint ZwQueryObject(int Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, - IntPtr ObjectInformation, int ObjectInformationLength, ref int ReturnLength); + IntPtr ObjectInformation, int ObjectInformationLength, out int ReturnLength); #endregion diff --git a/trunk/ProcessHacker/Win32/API/Structs.cs b/trunk/ProcessHacker/Win32/API/Structs.cs index 1dc2e85b0..1f45b233a 100644 --- a/trunk/ProcessHacker/Win32/API/Structs.cs +++ b/trunk/ProcessHacker/Win32/API/Structs.cs @@ -564,6 +564,22 @@ namespace ProcessHacker [MarshalAs(UnmanagedType.ByValTStr, SizeConst = SYMBOL_NAME_MAXSIZE)] public string Name; + } + + [StructLayout(LayoutKind.Sequential)] + public struct SYSTEM_BASIC_INFORMATION + { + public int Reserved; + public int TimerResolution; + public int PageSize; + public int NumberOfPhysicalPages; + public int LowestPhysicalPageNumber; + public int HighestPhysicalPageNumber; + public int AllocationGranularity; + public int MinimumUserModeAddress; + public int MaximumUserModeAddress; + public int ActiveProcessorsAffinityMask; + public byte NumberOfProcessors; } [StructLayout(LayoutKind.Sequential)] @@ -597,80 +613,80 @@ namespace ProcessHacker [StructLayout(LayoutKind.Sequential)] public struct SYSTEM_PERFORMANCE_INFORMATION { - long IdleProcessTime; - long IoReadTransferCount; - long IoWriteTransferCount; - long IoOtherTransferCount; - int IoReadOperationCount; - int IoWriteOperationCount; - int IoOtherOperationCount; - int AvailablePages; - int CommittedPages; - int CommitLimit; - int PeakCommitment; - int PageFaultCount; - int CopyOnWriteCount; - int TransitionCount; - int CacheTransitionCount; - int DemandZeroCount; - int PageReadCount; - int PageReadIoCount; - int CacheReadCount; - int CacheIoCount; - int DirtyPagesWriteCount; - int DirtyWriteIoCount; - int MappedPagesWriteCount; - int MappedWriteIoCount; - int PagedPoolPages; - int NonPagedPoolPages; - int PagedPoolAllocs; - int PagedPoolFrees; - int NonPagedPoolAllocs; - int NonPagedPoolFrees; - int FreeSystemPtes; - int ResidentSystemCodePage; - int TotalSystemDriverPages; - int TotalSystemCodePages; - int NonPagedPoolLookasideHits; - int PagedPoolLookasideHits; - int Spare3Count; - int ResidentSystemCachePage; - int ResidentPagedPoolPage; - int ResidentSystemDriverPage; - int CcFastReadNoWait; - int CcFastReadWait; - int CcFastReadResourceMiss; - int CcFastReadNotPossible; - int CcFastMdlReadNoWait; - int CcFastMdlReadWait; - int CcFastMdlReadResourceMiss; - int CcFastMdlReadNotPossible; - int CcMapDataNoWait; - int CcMapDataWait; - int CcMapDataNoWaitMiss; - int CcMapDataWaitMiss; - int CcPinMappedDataCount; - int CcPinReadNoWait; - int CcPinReadWait; - int CcPinReadNoWaitMiss; - int CcPinReadWaitMiss; - int CcCopyReadNoWait; - int CcCopyReadWait; - int CcCopyReadNoWaitMiss; - int CcCopyReadWaitMiss; - int CcMdlReadNoWait; - int CcMdlReadWait; - int CcMdlReadNoWaitMiss; - int CcMdlReadWaitMiss; - int CcReadAheadIos; - int CcLazyWriteIos; - int CcLazyWritePages; - int CcDataFlushes; - int CcDataPages; - int ContextSwitches; - int FirstLevelTbFills; - int SecondLevelTbFills; - int SystemCalls; + public long IdleProcessTime; + public long IoReadTransferCount; + public long IoWriteTransferCount; + public long IoOtherTransferCount; + public int IoReadOperationCount; + public int IoWriteOperationCount; + public int IoOtherOperationCount; + public int AvailablePages; + public int CommittedPages; + public int CommitLimit; + public int PeakCommitment; + public int PageFaultCount; + public int CopyOnWriteCount; + public int TransitionCount; + public int CacheTransitionCount; + public int DemandZeroCount; + public int PageReadCount; + public int PageReadIoCount; + public int CacheReadCount; + public int CacheIoCount; + public int DirtyPagesWriteCount; + public int DirtyWriteIoCount; + public int MappedPagesWriteCount; + public int MappedWriteIoCount; + public int PagedPoolPages; + public int NonPagedPoolPages; + public int PagedPoolAllocs; + public int PagedPoolFrees; + public int NonPagedPoolAllocs; + public int NonPagedPoolFrees; + public int FreeSystemPtes; + public int ResidentSystemCodePage; + public int TotalSystemDriverPages; + public int TotalSystemCodePages; + public int NonPagedPoolLookasideHits; + public int PagedPoolLookasideHits; + public int Spare3Count; + public int ResidentSystemCachePage; + public int ResidentPagedPoolPage; + public int ResidentSystemDriverPage; + public int CcFastReadNoWait; + public int CcFastReadWait; + public int CcFastReadResourceMiss; + public int CcFastReadNotPossible; + public int CcFastMdlReadNoWait; + public int CcFastMdlReadWait; + public int CcFastMdlReadResourceMiss; + public int CcFastMdlReadNotPossible; + public int CcMapDataNoWait; + public int CcMapDataWait; + public int CcMapDataNoWaitMiss; + public int CcMapDataWaitMiss; + public int CcPinMappedDataCount; + public int CcPinReadNoWait; + public int CcPinReadWait; + public int CcPinReadNoWaitMiss; + public int CcPinReadWaitMiss; + public int CcCopyReadNoWait; + public int CcCopyReadWait; + public int CcCopyReadNoWaitMiss; + public int CcCopyReadWaitMiss; + public int CcMdlReadNoWait; + public int CcMdlReadWait; + public int CcMdlReadNoWaitMiss; + public int CcMdlReadWaitMiss; + public int CcReadAheadIos; + public int CcLazyWriteIos; + public int CcLazyWritePages; + public int CcDataFlushes; + public int CcDataPages; + public int ContextSwitches; + public int FirstLevelTbFills; + public int SecondLevelTbFills; + public int SystemCalls; } [StructLayout(LayoutKind.Sequential)] @@ -682,9 +698,9 @@ namespace ProcessHacker [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public long[] Reserved1; - public ulong CreateTime; - public ulong UserTime; - public ulong KernelTime; + public long CreateTime; + public long UserTime; + public long KernelTime; public UNICODE_STRING ImageName; public int BasePriority; public int ProcessId; @@ -699,12 +715,12 @@ namespace ProcessHacker [StructLayout(LayoutKind.Sequential)] public struct SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION { - long IdleTime; - long KernelTime; - long UserTime; - long DpcTime; - long InterruptTime; - int InterruptCount; + public long IdleTime; + public long KernelTime; + public long UserTime; + public long DpcTime; + public long InterruptTime; + public int InterruptCount; } [StructLayout(LayoutKind.Sequential)] diff --git a/trunk/ProcessHacker/Win32/Win32.cs b/trunk/ProcessHacker/Win32/Win32.cs index 9afdd001b..4e1d56349 100644 --- a/trunk/ProcessHacker/Win32/Win32.cs +++ b/trunk/ProcessHacker/Win32/Win32.cs @@ -158,7 +158,7 @@ namespace ProcessHacker using (MemoryAlloc data = new MemoryAlloc(0x1000)) { while (ZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS.SystemHandleInformation, data.Memory, - data.Size, ref retLength) == STATUS_INFO_LENGTH_MISMATCH) + data.Size, out retLength) == STATUS_INFO_LENGTH_MISMATCH) data.Resize(data.Size * 2); handleCount = data.ReadInt32(0); @@ -195,14 +195,14 @@ namespace ProcessHacker ObjectInformation info = new ObjectInformation(); ZwQueryObject(object_handle, OBJECT_INFORMATION_CLASS.ObjectBasicInformation, - IntPtr.Zero, 0, ref retLength); + IntPtr.Zero, 0, out retLength); if (retLength > 0) { using (MemoryAlloc obiMem = new MemoryAlloc(retLength)) { ZwQueryObject(object_handle, OBJECT_INFORMATION_CLASS.ObjectBasicInformation, - obiMem.Memory, obiMem.Size, ref retLength); + obiMem.Memory, obiMem.Size, out retLength); OBJECT_BASIC_INFORMATION obi = obiMem.ReadStruct(); info.Basic = obi; @@ -216,14 +216,14 @@ namespace ProcessHacker else { ZwQueryObject(object_handle, OBJECT_INFORMATION_CLASS.ObjectTypeInformation, - IntPtr.Zero, 0, ref retLength); + IntPtr.Zero, 0, out retLength); if (retLength > 0) { using (MemoryAlloc otiMem = new MemoryAlloc(retLength)) { if (ZwQueryObject(object_handle, OBJECT_INFORMATION_CLASS.ObjectTypeInformation, - otiMem.Memory, otiMem.Size, ref retLength) != 0) + otiMem.Memory, otiMem.Size, out retLength) != 0) throw new Exception("ZwQueryObject failed"); OBJECT_TYPE_INFORMATION oti = otiMem.ReadStruct(); @@ -239,14 +239,14 @@ namespace ProcessHacker throw new Exception("0x0012019f access is banned"); ZwQueryObject(object_handle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, - IntPtr.Zero, 0, ref retLength); + IntPtr.Zero, 0, out retLength); if (retLength > 0) { using (MemoryAlloc oniMem = new MemoryAlloc(retLength)) { if (ZwQueryObject(object_handle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, - oniMem.Memory, oniMem.Size, ref retLength) != 0) + oniMem.Memory, oniMem.Size, out retLength) != 0) throw new Exception("ZwQueryObject failed"); OBJECT_NAME_INFORMATION oni = oniMem.ReadStruct(); @@ -425,21 +425,23 @@ namespace ProcessHacker { public string Name; public SYSTEM_PROCESS_INFORMATION Process; - public SYSTEM_THREAD_INFORMATION[] Threads; + // public SYSTEM_THREAD_INFORMATION[] Threads; } - public static SystemProcess[] EnumProcesses() + public static Dictionary EnumProcesses() { int retLength = 0; - List returnProcesses; + Dictionary returnProcesses; - using (MemoryAlloc data = new MemoryAlloc(0x1000)) + ZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS.SystemProcessesAndThreadsInformation, IntPtr.Zero, + 0, out retLength); + + using (MemoryAlloc data = new MemoryAlloc(retLength)) { - while (ZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS.SystemProcessesAndThreadsInformation, data.Memory, - data.Size, ref retLength) == STATUS_INFO_LENGTH_MISMATCH) - data.Resize(data.Size * 2); + ZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS.SystemProcessesAndThreadsInformation, data.Memory, + data.Size, out retLength); - returnProcesses = new List(); + returnProcesses = new Dictionary(); int i = 0; SystemProcess currentProcess = new SystemProcess(); @@ -447,16 +449,16 @@ namespace ProcessHacker while (true) { currentProcess.Process = data.ReadStruct(i, 0); - currentProcess.Threads = new SYSTEM_THREAD_INFORMATION[currentProcess.Process.NumberOfThreads]; + //currentProcess.Threads = new SYSTEM_THREAD_INFORMATION[currentProcess.Process.NumberOfThreads]; currentProcess.Name = ReadUnicodeString(currentProcess.Process.ImageName); - for (int j = 0; j < currentProcess.Process.NumberOfThreads; j++) - { - currentProcess.Threads[j] = data.ReadStruct(i + - Marshal.SizeOf(typeof(SYSTEM_PROCESS_INFORMATION)), j); - } + //for (int j = 0; j < currentProcess.Process.NumberOfThreads; j++) + //{ + // currentProcess.Threads[j] = data.ReadStruct(i + + // Marshal.SizeOf(typeof(SYSTEM_PROCESS_INFORMATION)), j); + //} - returnProcesses.Add(currentProcess); + returnProcesses.Add(currentProcess.Process.ProcessId, currentProcess); if (currentProcess.Process.NextEntryOffset == 0) break; @@ -464,7 +466,7 @@ namespace ProcessHacker i += currentProcess.Process.NextEntryOffset; } - return returnProcesses.ToArray(); + return returnProcesses; } }