From 111dbcce1d687b7deb42e20d903e14e587de4d7a Mon Sep 17 00:00:00 2001 From: wj32 Date: Tue, 21 Jul 2009 11:45:47 +0000 Subject: [PATCH] refactoring + more docs git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1620 21ef857c-d57f-4fe0-8362-d861dc6d29cd --- trunk/ProcessHacker.Common/Utils.cs | 372 +++++++++++------- .../Debugging/DebugBuffer.cs | 4 + trunk/ProcessHacker.Native/Memory/Section.cs | 2 +- .../Objects/ProcessHandle.cs | 55 ++- .../Objects/ThreadHandle.cs | 72 +++- .../Symbols/SymbolProvider.cs | 3 +- .../ProcessHacker.Native/Threading/Waiter.cs | 3 + trunk/ProcessHacker/Common/Extensions.cs | 14 + .../ProcessHacker/Components/JobProperties.cs | 30 +- trunk/ProcessHacker/Components/MemoryList.cs | 2 +- trunk/ProcessHacker/Components/ModuleList.cs | 2 +- .../Components/ProcessStatistics.cs | 26 +- .../Components/ProcessTree/ProcessNode.cs | 36 +- .../ProcessTree/ProcessToolTipProvider.cs | 2 +- .../Components/SectionProperties.cs | 2 +- trunk/ProcessHacker/Components/ThreadList.cs | 8 +- .../Components/TokenProperties.cs | 4 +- trunk/ProcessHacker/Forms/HeapsWindow.cs | 4 +- trunk/ProcessHacker/Forms/PEWindow.cs | 2 +- trunk/ProcessHacker/Forms/ProcessWindow.cs | 18 +- trunk/ProcessHacker/Forms/RunWindow.cs | 2 +- trunk/ProcessHacker/Forms/SysInfoWindow.cs | 54 +-- trunk/ProcessHacker/Program/Program.cs | 4 +- .../Providers/ProcessSystemProvider.cs | 6 +- .../UI/Icons/CommitHistoryIcon.cs | 2 +- trunk/ProcessHacker/UI/Icons/IoHistoryIcon.cs | 6 +- .../UI/Icons/PhysMemHistoryIcon.cs | 2 +- trunk/native.html | 24 +- 28 files changed, 496 insertions(+), 265 deletions(-) diff --git a/trunk/ProcessHacker.Common/Utils.cs b/trunk/ProcessHacker.Common/Utils.cs index cc8c5f77e..729ef1f4b 100644 --- a/trunk/ProcessHacker.Common/Utils.cs +++ b/trunk/ProcessHacker.Common/Utils.cs @@ -31,6 +31,9 @@ using System.Windows.Forms; namespace ProcessHacker.Common { + /// + /// Provides methods for manipulating various types of data. + /// public static class Utils { #region Constants @@ -78,8 +81,19 @@ namespace ProcessHacker.Common #endregion + /// + /// The maximum unit specifier to use when formatting sizes. + /// public static int UnitSpecifier = 4; + /// + /// Flattens an array of arrays into a single array. + /// + /// The type of each element in the arrays. + /// + /// An array of arrays. If an array in the array is null, it will be ignored. + /// + /// An array containing elements from each array. public static T[] Concat(params T[][] ap) { int tl = 0; @@ -103,6 +117,11 @@ namespace ProcessHacker.Common return na; } + /// + /// Counts the number of bits in the specified number. + /// + /// The number to process. + /// The number of bits in the specified number. public static int CountBits(this long value) { int count = 0; @@ -117,75 +136,11 @@ namespace ProcessHacker.Common } /// - /// Swaps the order of the bytes in the argument. + /// Creates an array of bytes from the specified byte pointer. /// - /// The number to change. - /// A number. - public static int ByteSwap(int v) - { - byte b1 = (byte)v; - byte b2 = (byte)(v >> 8); - byte b3 = (byte)(v >> 16); - byte b4 = (byte)(v >> 24); - - return b4 | (b3 << 8) | (b2 << 16) | (b1 << 24); - } - - /// - /// Swaps the order of the bytes. - /// - /// A number. - public static int SwapBytes(this int v) - { - return ByteSwap(v); - } - - /// - /// Swaps the order of the bytes in the argument. - /// - /// The number to change. - /// A number. - public static uint ByteSwap(uint v) - { - byte b1 = (byte)v; - byte b2 = (byte)(v >> 8); - byte b3 = (byte)(v >> 16); - byte b4 = (byte)(v >> 24); - - return (uint)(b4 | (b3 << 8) | (b2 << 16) | (b1 << 24)); - } - - /// - /// Swaps the order of the bytes. - /// - /// A number. - public static uint SwapBytes(this uint v) - { - return ByteSwap(v); - } - - /// - /// Swaps the order of the bytes in the argument. - /// - /// The number to change. - /// A number. - public static ushort ByteSwap(ushort v) - { - byte b1 = (byte)v; - byte b2 = (byte)(v >> 8); - - return (ushort)(b2 | (b1 << 8)); - } - - /// - /// Swaps the order of the bytes. - /// - /// A number. - public static ushort SwapBytes(this ushort v) - { - return ByteSwap(v); - } - + /// A pointer to an array of bytes. + /// The length of the array. + /// A new byte array. public unsafe static byte[] Create(byte* ptr, int length) { byte[] array = new byte[length]; @@ -196,6 +151,36 @@ namespace ProcessHacker.Common return array; } + /// + /// Adds an ellipsis to a string if it is longer than the specified length. + /// + /// The string. + /// The maximum length. + /// The modified string. + public static string CreateEllipsis(string s, int len) + { + if (s.Length <= len) + return s; + else + return s.Substring(0, len - 4) + " ..."; + } + + /// + /// Creates a string containing random uppercase characters. + /// + /// The number of characters to generate. + /// The generated string. + public static string CreateRandomString(int length) + { + Random r = new Random((int)(DateTime.Now.ToFileTime() & 0xffffffff)); + StringBuilder sb = new StringBuilder(length); + + for (int i = 0; i < length; i++) + sb.Append((char)('A' + r.Next(25))); + + return sb.ToString(); + } + /// /// Clears and cleans up resources held by the menu items. /// @@ -209,20 +194,6 @@ namespace ProcessHacker.Common items.Clear(); } - /// - /// Converts a 32-bit Unix time value into a DateTime object. - /// - /// The Unix time value. - public static DateTime DateTimeFromUnixTime(uint time) - { - return new DateTime(1970, 1, 1, 0, 0, 0).Add(new TimeSpan(0, 0, 0, (int)time)); - } - - public static DateTime DateTimeFromFileTime(long time) - { - return new DateTime(1601, 1, 1).AddTicks(time).ToLocalTime(); - } - /// /// Disables the menu items contained in the specified menu. /// @@ -241,6 +212,12 @@ namespace ProcessHacker.Common DisableAllMenuItems(menu); } + /// + /// Duplicates the specified array. + /// + /// The type of array to duplicate. + /// The array to duplicate. + /// A copy of the specified array. public static T[] Duplicate(this T[] array) { T[] newArray = new T[array.Length]; @@ -268,16 +245,40 @@ namespace ProcessHacker.Common EnableAllMenuItems(menu); } + /// + /// Compares two arrays and determines whether they are equal. + /// + /// The type of each element in the arrays. + /// The first array. + /// The second array. + /// Whether the two arrays are considered to be equal. public static bool Equals(T[] array, T[] other) { return Equals(array, other, 0); } + /// + /// Compares two arrays and determines whether they are equal. + /// + /// The type of each element in the arrays. + /// The first array. + /// The second array. + /// The index from which to begin comparing. + /// Whether the two arrays are considered to be equal. public static bool Equals(T[] array, T[] other, int startIndex) { return Equals(array, other, startIndex, array.Length); } + /// + /// Compares two arrays and determines whether they are equal. + /// + /// The type of each element in the arrays. + /// The first array. + /// The second array. + /// The index from which to begin comparing. + /// The number of elements to compare. + /// Whether the two arrays are considered to be equal. public static bool Equals(T[] array, T[] other, int startIndex, int length) { for (int i = startIndex; i < startIndex + length; i++) @@ -305,17 +306,30 @@ namespace ProcessHacker.Common /// /// The combobox to modify. /// The type of the enum. - public static void Fill(ComboBox box, Type t) + public static void Fill(this ComboBox box, Type t) { foreach (string s in Enum.GetNames(t)) box.Items.Add(s); } + /// + /// Moves the specified rectangle to fit inside the working area + /// of the display containing the specified control. + /// + /// The rectangle to process. + /// The control from which to get the display. + /// A new rectangle with its location modified. public static Rectangle FitRectangle(Rectangle rect, Control c) { return FitRectangle(rect, Screen.GetWorkingArea(c)); } + /// + /// Moves the specified rectangle to fit inside the specified bounds. + /// + /// The rectangle to process. + /// The bounds in which the rectangle should be. + /// A new rectangle with its location modified. public static Rectangle FitRectangle(Rectangle rect, Rectangle bounds) { if (rect.X < bounds.Left) @@ -331,13 +345,24 @@ namespace ProcessHacker.Common } /// - /// Formats a object into a string representation using the format "dd/MM/yy hh:mm:ss". + /// Gets the string representation of a priority number. /// - /// The object to format. - /// - public static string GetNiceDateTime(DateTime time) - { - return time.ToString("dd/MM/yy hh:mm:ss"); + /// A priority number. + /// A string. + public static string FormatPriority(int priority) + { + if (priority >= 24) + return "Realtime"; + else if (priority >= 13) + return "High"; + else if (priority >= 10) + return "Above Normal"; + else if (priority >= 8) + return "Normal"; + else if (priority >= 6) + return "Below Normal"; + else + return "Idle"; } /// @@ -345,26 +370,38 @@ namespace ProcessHacker.Common /// /// A DateTime. /// A string. - public static string GetNiceRelativeDateTime(DateTime time) + public static string FormatRelativeDateTime(DateTime time) { + // Get the time span from the time to now. TimeSpan span = DateTime.Now.Subtract(time); + // The partial number of weeks. double weeks = span.TotalDays / 7; + // The partial number of fortnights. double fortnights = weeks / 2; + // ... double months = span.TotalDays * 12 / 365; double years = months / 12; double centuries = years / 100; string str = ""; + // Start from the most general time unit and see if they can be used + // without any fractional component. + // x centur(y|ies) if (centuries >= 1) str = (int)centuries + " " + ((int)centuries == 1 ? "century" : "centuries"); + // x year(s) else if (years >= 1) str = (int)years + " " + ((int)years == 1 ? "year" : "years"); + // x month(s) else if (months >= 1) str = (int)months + " " + ((int)months == 1 ? "month" : "months"); + // x fortnight(s) else if (fortnights >= 1) str = (int)fortnights + " " + ((int)fortnights == 1 ? "fortnight" : "fortnights"); + // x week(s) else if (weeks >= 1) str = (int)weeks + " " + ((int)weeks == 1 ? "week" : "weeks"); + // x day(s) (and y hour(s)) else if (span.TotalDays >= 1) { str = (int)span.TotalDays + " " + ((int)span.TotalDays == 1 ? "day" : "days"); @@ -373,6 +410,7 @@ namespace ProcessHacker.Common str += " and " + span.Hours + " " + (span.Hours == 1 ? "hour" : "hours"); } + // x hour(s) (and y minute(s)) else if (span.Hours >= 1) { str = span.Hours + " " + (span.Hours == 1 ? "hour" : "hours"); @@ -381,6 +419,7 @@ namespace ProcessHacker.Common str += " and " + span.Minutes + " " + (span.Minutes == 1 ? "minute" : "minutes"); } + // x minute(s) (and y second(s)) else if (span.Minutes >= 1) { str = span.Minutes + " " + (span.Minutes == 1 ? "minute" : "minutes"); @@ -389,17 +428,19 @@ namespace ProcessHacker.Common str += " and " + span.Seconds + " " + (span.Seconds == 1 ? "second" : "seconds"); } + // x second(s) else if (span.Seconds >= 1) str = span.Seconds + " " + (span.Seconds == 1 ? "second" : "seconds"); + // x millisecond(s) else if (span.Milliseconds >= 1) str = span.Milliseconds + " " + (span.Milliseconds == 1 ? "millisecond" : "milliseconds"); else str = "a very short time"; - // 1 minute -> a minute + // Turn 1 into "a", e.g. 1 minute -> a minute if (str.StartsWith("1 ")) { - // a hour -> an hour + // Special vowel case: a hour -> an hour if (str[2] != 'h') str = "a " + str.Substring(2); else @@ -413,16 +454,16 @@ namespace ProcessHacker.Common /// Formats a size into a string representation, postfixing it with the correct unit. /// /// The size to format. - public static string GetNiceSizeName(int size) + public static string FormatSize(int size) { - return GetNiceSizeName((uint)size); + return FormatSize((uint)size); } /// /// Formats a size into a string representation, postfixing it with the correct unit. /// /// The size to format. - public static string GetNiceSizeName(uint size) + public static string FormatSize(uint size) { int i = 0; double s = (double)size; @@ -440,19 +481,19 @@ namespace ProcessHacker.Common /// Formats a size into a string representation, postfixing it with the correct unit. /// /// The size to format. - public static string GetNiceSizeName(long size) + public static string FormatSize(long size) { - return GetNiceSizeName((ulong)size); + return FormatSize((ulong)size); } /// /// Formats a size into a string representation, postfixing it with the correct unit. /// /// The size to format. - public static string GetNiceSizeName(ulong size) + public static string FormatSize(ulong size) { int i = 0; - decimal s = (decimal)size; + double s = (double)size; while (s > 1024 && i < SizeUnitNames.Length && i < UnitSpecifier) { @@ -468,7 +509,7 @@ namespace ProcessHacker.Common /// /// The to format. /// - public static string GetNiceTimeSpan(TimeSpan time) + public static string FormatTimeSpan(TimeSpan time) { return String.Format("{0:d2}:{1:d2}:{2:d2}.{3:d3}", time.Hours, @@ -478,24 +519,37 @@ namespace ProcessHacker.Common } /// - /// Gets the string representation of a priority number. + /// Converts a 64-bit Windows time value to a DateTime object. /// - /// A priority number. - /// A string. - public static string GetStringPriority(int priority) + /// The Windows time value. + public static DateTime GetDateTimeFromLongTime(long time) { - if (priority >= 24) - return "Realtime"; - else if (priority >= 13) - return "High"; - else if (priority >= 10) - return "Above Normal"; - else if (priority >= 8) - return "Normal"; - else if (priority >= 6) - return "Below Normal"; - else - return "Idle"; + return (new DateTime(1601, 1, 1)).AddTicks(time).ToLocalTime(); + } + + /// + /// Converts a 32-bit Unix time value into a DateTime object. + /// + /// The Unix time value. + public static DateTime GetDateTimeFromUnixTime(uint time) + { + return (new DateTime(1970, 1, 1, 0, 0, 0)).Add(new TimeSpan(0, 0, 0, (int)time)); + } + + /// + /// Parses a string and produces a rectangle. + /// + /// + /// A string describing a rectangle in the following format: + /// x,y,width,height (with no spaces). + /// + /// A rectangle. + public static Rectangle GetRectangle(string s) + { + var split = s.Split(','); + + return new Rectangle(int.Parse(split[0]), int.Parse(split[1]), + int.Parse(split[2]), int.Parse(split[3])); } /// @@ -504,7 +558,7 @@ namespace ProcessHacker.Common /// The process which the thread belongs to. /// The ID of the thread. /// - public static ProcessThread GetThreadById(Process p, int id) + public static ProcessThread GetThreadFromId(Process p, int id) { foreach (ProcessThread t in p.Threads) if (t.Id == id) @@ -534,20 +588,6 @@ namespace ProcessHacker.Common return empty; } - /// - /// Adds an ellipsis to a string if it is longer than the specified length. - /// - /// The string. - /// The maximum length. - /// The modified string. - public static string MakeEllipsis(string s, int len) - { - if (s.Length <= len) - return s; - else - return s.Substring(0, len - 4) + " ..."; - } - /// /// Makes a character printable by converting unprintable characters to a dot ('.'). /// @@ -576,17 +616,6 @@ namespace ProcessHacker.Common return sb.ToString(); } - public static string MakeRandomString(int length) - { - Random r = new Random((int)(DateTime.Now.ToFileTime() & 0xffffffff)); - StringBuilder sb = new StringBuilder(length); - - for (int i = 0; i < length; i++) - sb.Append((char)('A' + r.Next(25))); - - return sb.ToString(); - } - public static System.Diagnostics.ProcessPriorityClass NativeToWindowsBasePriority(int priority) { if (priority >= 24) @@ -685,14 +714,6 @@ namespace ProcessHacker.Common return str.ToString(); } - public static Rectangle RectangleFromString(string s) - { - var split = s.Split(','); - - return new Rectangle(int.Parse(split[0]), int.Parse(split[1]), - int.Parse(split[2]), int.Parse(split[3])); - } - /// /// Selects all of the specified items. /// @@ -703,6 +724,10 @@ namespace ProcessHacker.Common item.Selected = true; } + /// + /// Selects all of the items in the specified ListView. + /// + /// The ListView to process. public static void SelectAll(this ListView items) { for (int i = 0; i < items.VirtualListSize; i++) @@ -734,6 +759,10 @@ namespace ProcessHacker.Common SetDoubleBuffered(c, c.GetType(), value); } + /// + /// Shows a file in Windows Explorer. + /// + /// The file to show. public static void ShowFileInExplorer(string fileName) { Process.Start("explorer.exe", "/select," + fileName); @@ -760,6 +789,49 @@ namespace ProcessHacker.Common return nameList; } + /// + /// Swaps the order of the bytes. + /// + /// The number to change. + /// A number. + public static int SwapBytes(this int v) + { + byte b1 = (byte)v; + byte b2 = (byte)(v >> 8); + byte b3 = (byte)(v >> 16); + byte b4 = (byte)(v >> 24); + + return b4 | (b3 << 8) | (b2 << 16) | (b1 << 24); + } + + /// + /// Swaps the order of the bytes. + /// + /// The number to change. + /// A number. + public static uint SwapBytes(this uint v) + { + byte b1 = (byte)v; + byte b2 = (byte)(v >> 8); + byte b3 = (byte)(v >> 16); + byte b4 = (byte)(v >> 24); + + return (uint)(b4 | (b3 << 8) | (b2 << 16) | (b1 << 24)); + } + + /// + /// Swaps the order of the bytes. + /// + /// The number to change. + /// A number. + public static ushort SwapBytes(this ushort v) + { + byte b1 = (byte)v; + byte b2 = (byte)(v >> 8); + + return (ushort)(b2 | (b1 << 8)); + } + public static int WindowsToNativeBasePriority(System.Diagnostics.ProcessPriorityClass priority) { switch (priority) diff --git a/trunk/ProcessHacker.Native/Debugging/DebugBuffer.cs b/trunk/ProcessHacker.Native/Debugging/DebugBuffer.cs index 2f309e4cb..66e58b8cc 100644 --- a/trunk/ProcessHacker.Native/Debugging/DebugBuffer.cs +++ b/trunk/ProcessHacker.Native/Debugging/DebugBuffer.cs @@ -127,6 +127,10 @@ namespace ProcessHacker.Native.Debugging } } + /// + /// Reads the debug information structure from the buffer. + /// + /// A RtlDebugInformation structure. private RtlDebugInformation GetDebugInformation() { MemoryAlloc data = new MemoryAlloc(_buffer, false); diff --git a/trunk/ProcessHacker.Native/Memory/Section.cs b/trunk/ProcessHacker.Native/Memory/Section.cs index 25fd90cfc..e68d30573 100644 --- a/trunk/ProcessHacker.Native/Memory/Section.cs +++ b/trunk/ProcessHacker.Native/Memory/Section.cs @@ -5,7 +5,7 @@ using ProcessHacker.Native.Security; namespace ProcessHacker.Native { /// - /// Represents a section. + /// Represents a section, a memory mapping. /// public sealed class Section : NativeObject { diff --git a/trunk/ProcessHacker.Native/Objects/ProcessHandle.cs b/trunk/ProcessHacker.Native/Objects/ProcessHandle.cs index bae5153e6..04815b0d7 100644 --- a/trunk/ProcessHacker.Native/Objects/ProcessHandle.cs +++ b/trunk/ProcessHacker.Native/Objects/ProcessHandle.cs @@ -34,12 +34,14 @@ namespace ProcessHacker.Native.Objects /// /// Represents a handle to a Windows process. /// - /// The idea of a ProcessHandle class is + /// + /// The idea of a ProcessHandle class is /// different to the class; /// instead of opening the process with the right permissions every /// time a query or set function is called, this lets the users control /// when they want to open handles with certain permissions. This - /// means that handles can be cached (by the users). + /// means that handles can be cached (by the users). + /// public sealed class ProcessHandle : NativeHandle, IWithToken { /// @@ -79,7 +81,8 @@ namespace ProcessHacker.Native.Objects using (var fhandle = new FileHandle( fileName, (FileAccess)StandardRights.Synchronize | FileAccess.Execute | FileAccess.ReadData, - FileShareMode.Delete | FileShareMode.Read, FileCreationDisposition.OpenAlways + FileShareMode.Delete | FileShareMode.Read, + FileCreationDisposition.OpenAlways )) { using (var shandle = @@ -594,7 +597,9 @@ namespace ProcessHacker.Native.Objects } /// - /// Disables the collection of handle stack traces. + /// Disables the collection of handle stack traces. This requires + /// PROCESS_SET_INFORMATION access. Note that this function is only + /// available on Windows Vista and above. /// public void DisableHandleTracing() { @@ -2229,6 +2234,9 @@ namespace ProcessHacker.Native.Objects } } + /// + /// Represents a stack trace collected during a handle trace event. + /// public class ProcessHandleTrace { private ClientId _clientId; @@ -2254,27 +2262,42 @@ namespace ProcessHacker.Native.Objects Array.Copy(entry.Stacks, 0, _stack, 0, zeroIndex); } + /// + /// The client ID of the thread which produced the event. + /// public ClientId ClientId { get { return _clientId; } } + /// + /// The handle value associated with the event. + /// public IntPtr Handle { get { return _handle; } } + /// + /// A stack trace of the thread at the time of the event. + /// public IntPtr[] Stack { get { return _stack; } } + /// + /// The type of handle trace event. + /// public HandleTraceType Type { get { return _type; } } } + /// + /// Represents a collection of handle trace events. + /// public class ProcessHandleTraceCollection : ReadOnlyCollection { private IntPtr _handle; @@ -2304,12 +2327,18 @@ namespace ProcessHacker.Native.Objects } } + /// + /// A unique handle representing the collection. + /// public IntPtr Handle { get { return _handle; } } } + /// + /// Represents a module loaded by a process. + /// public class ProcessModule { public ProcessModule( @@ -2329,11 +2358,29 @@ namespace ProcessHacker.Native.Objects this.FileName = fileName; } + /// + /// The base address of the module. + /// public IntPtr BaseAddress { get; private set; } + /// + /// The size of the module. + /// public int Size { get; private set; } + /// + /// The entry point of the module (usually its DllMain function). + /// public IntPtr EntryPoint { get; private set; } + /// + /// The flags set by the NT loader for this module. + /// public LdrpDataTableEntryFlags Flags { get; private set; } + /// + /// The base name of the module (e.g. module.dll). + /// public string BaseName { get; private set; } + /// + /// The file name of the module (e.g. C:\Windows\system32\module.dll). + /// public string FileName { get; private set; } } diff --git a/trunk/ProcessHacker.Native/Objects/ThreadHandle.cs b/trunk/ProcessHacker.Native/Objects/ThreadHandle.cs index 6983a40ac..e6320a1f2 100644 --- a/trunk/ProcessHacker.Native/Objects/ThreadHandle.cs +++ b/trunk/ProcessHacker.Native/Objects/ThreadHandle.cs @@ -151,21 +151,38 @@ namespace ProcessHacker.Native.Objects return Current; } + /// + /// Gets the client ID of the current thread. + /// + /// A client ID. public static ClientId GetCurrentCid() { return new ClientId(ProcessHandle.GetCurrentId(), ThreadHandle.GetCurrentId()); } + /// + /// Gets the ID of the current thread. + /// + /// A thread ID. public static int GetCurrentId() { return Win32.GetCurrentThreadId(); } + /// + /// Opens the current thread. + /// + /// The desired access to the thread. + /// A handle to the current thread. public static ThreadHandle OpenCurrent(ThreadAccess access) { return new ThreadHandle(GetCurrentId(), access); } + /// + /// Registers a port which will be notified when the current thread terminates. + /// + /// A handle to a port. public static void RegisterTerminationPort(PortHandle portHandle) { NtStatus status; @@ -174,11 +191,26 @@ namespace ProcessHacker.Native.Objects Win32.ThrowLastError(status); } + /// + /// Sleeps the current thread. + /// + /// The timeout, in 100ns units. + /// Whether the timeout value is relative. + /// A NT status value. public static NtStatus Sleep(long time, bool relative) { return Sleep(false, time, relative); } + /// + /// Sleeps the current thread. + /// + /// + /// Whether user-mode APCs can be delivered during the wait. + /// + /// The timeout, in 100ns units. + /// Whether the timeout value is relative. + /// A NT status value. public static NtStatus Sleep(bool alertable, long time, bool relative) { if (time == 0) @@ -192,14 +224,27 @@ namespace ProcessHacker.Native.Objects return Win32.NtDelayExecution(alertable, ref realTime); } - public static void TestAlert() + /// + /// Checks whether the current thread is in an alerted state and + /// executes any pending user-mode APCs. + /// + /// + /// NtStatus.Alerted if the current thread was in an alerted state, + /// otherwise NtStatus.Success. + /// + public static NtStatus TestAlert() { NtStatus status; if ((status = Win32.NtTestAlert()) >= NtStatus.Error) Win32.ThrowLastError(status); + + return status; } + /// + /// Switches to another thread. + /// public static void Yield() { Win32.NtYieldExecution(); @@ -643,6 +688,11 @@ namespace ProcessHacker.Native.Objects return this.GetInformationIntPtr(ThreadInformationClass.ThreadQuerySetWin32StartAddress); } + /// + /// Causes the thread to impersonate a client thread. + /// + /// A handle to a client thread. + /// The impersonation level to request. public void Impersonate(ThreadHandle clientThreadHandle, SecurityImpersonationLevel impersonationLevel) { NtStatus status; @@ -653,6 +703,9 @@ namespace ProcessHacker.Native.Objects Win32.ThrowLastError(status); } + /// + /// Causes the thread to impersonate the anonymous account. + /// public void ImpersonateAnonymous() { NtStatus status; @@ -713,12 +766,25 @@ namespace ProcessHacker.Native.Objects Win32.ThrowLastError(); } + /// + /// Adds an user-mode asynchronous procedure call (APC) to the thread's APC queue. + /// This requires THREAD_SET_CONTEXT access. + /// + /// The delegate to execute.. + /// The parameter to pass to the procedure. public void QueueApc(ApcRoutine action, IntPtr parameter) { if (!Win32.QueueUserAPC(action, this, parameter)) Win32.ThrowLastError(); } + /// + /// Queues a user-mode asynchronous procedure call (APC) to the thread. + /// + /// The address of the function to execute. + /// The first parameter to pass to the function. + /// The second parameter to pass to the function. + /// The third parameter to pass to the function. public void QueueApc(IntPtr address, IntPtr param1, IntPtr param2, IntPtr param3) { NtStatus status; @@ -798,6 +864,10 @@ namespace ProcessHacker.Native.Objects } } + /// + /// Sets whether the thread is critical. + /// + /// Whether the thread should be critical. public void SetCritical(bool critical) { this.SetInformationInt32(ThreadInformationClass.ThreadBreakOnTermination, critical ? 1 : 0); diff --git a/trunk/ProcessHacker.Native/Symbols/SymbolProvider.cs b/trunk/ProcessHacker.Native/Symbols/SymbolProvider.cs index 3da3fd00b..2dc4548f0 100644 --- a/trunk/ProcessHacker.Native/Symbols/SymbolProvider.cs +++ b/trunk/ProcessHacker.Native/Symbols/SymbolProvider.cs @@ -322,7 +322,7 @@ namespace ProcessHacker.Native.Symbols public string GetSymbolFromAddress(ulong address, out SymbolResolveLevel level, out SymbolFlags flags, out string fileName, out string symbolName, out ulong displacement) { - // Assume failure. + // Assume failure (and stop the compiler from complaining). if (address == 0) { level = SymbolResolveLevel.Invalid; @@ -330,6 +330,7 @@ namespace ProcessHacker.Native.Symbols fileName = null; } + // Allocate some memory for the symbol information. using (var data = new MemoryAlloc(Marshal.SizeOf(typeof(SymbolInfo)) + _maxNameLen)) { var info = new SymbolInfo(); diff --git a/trunk/ProcessHacker.Native/Threading/Waiter.cs b/trunk/ProcessHacker.Native/Threading/Waiter.cs index deaf99269..ac5cee2d2 100644 --- a/trunk/ProcessHacker.Native/Threading/Waiter.cs +++ b/trunk/ProcessHacker.Native/Threading/Waiter.cs @@ -32,6 +32,9 @@ namespace ProcessHacker.Native.Threading { public delegate void ObjectSignaledDelegate(ISynchronizable obj); + /// + /// Provides methods for waiting on dispatcher objects. + /// public sealed class Waiter : BaseObject { private class WaiterThread : BaseObject diff --git a/trunk/ProcessHacker/Common/Extensions.cs b/trunk/ProcessHacker/Common/Extensions.cs index 7132531d6..7368f0440 100644 --- a/trunk/ProcessHacker/Common/Extensions.cs +++ b/trunk/ProcessHacker/Common/Extensions.cs @@ -27,6 +27,11 @@ namespace ProcessHacker.Common { public static class LongExtensions { + /// + /// Gets the largest value in the specified array of longs. + /// + /// The source array. + /// The largest value in the specified array. public static long Max(this IEnumerable source) { if (source == null) @@ -52,6 +57,15 @@ namespace ProcessHacker.Common return max; } + /// + /// Takes a number of elements from the specified array. + /// + /// The list to process. + /// The number of elements to take. + /// + /// A new list containing the first + /// elements from the specified array. + /// public static IList Take(this IList source, int count) { if (source == null) diff --git a/trunk/ProcessHacker/Components/JobProperties.cs b/trunk/ProcessHacker/Components/JobProperties.cs index 80b7aa29c..8378e3c46 100644 --- a/trunk/ProcessHacker/Components/JobProperties.cs +++ b/trunk/ProcessHacker/Components/JobProperties.cs @@ -89,28 +89,28 @@ namespace ProcessHacker.Components if ((flags & JobObjectLimitFlags.DieOnUnhandledException) != 0) this.AddLimit("Die on Unhandled Exception", "Enabled"); if ((flags & JobObjectLimitFlags.JobMemory) != 0) - this.AddLimit("Job Memory", Utils.GetNiceSizeName(extendedLimits.JobMemoryLimit)); + this.AddLimit("Job Memory", Utils.FormatSize(extendedLimits.JobMemoryLimit)); if ((flags & JobObjectLimitFlags.JobTime) != 0) this.AddLimit("Job Time", - Utils.GetNiceTimeSpan(new TimeSpan(extendedLimits.BasicLimitInformation.PerJobUserTimeLimit))); + Utils.FormatTimeSpan(new TimeSpan(extendedLimits.BasicLimitInformation.PerJobUserTimeLimit))); if ((flags & JobObjectLimitFlags.KillOnJobClose) != 0) this.AddLimit("Kill on Job Close", "Enabled"); if ((flags & JobObjectLimitFlags.PriorityClass) != 0) this.AddLimit("Priority Class", ((System.Diagnostics.ProcessPriorityClass)extendedLimits.BasicLimitInformation.PriorityClass).ToString()); if ((flags & JobObjectLimitFlags.ProcessMemory) != 0) - this.AddLimit("Process Memory", Utils.GetNiceSizeName(extendedLimits.ProcessMemoryLimit)); + this.AddLimit("Process Memory", Utils.FormatSize(extendedLimits.ProcessMemoryLimit)); if ((flags & JobObjectLimitFlags.ProcessTime) != 0) this.AddLimit("Process Time", - Utils.GetNiceTimeSpan(new TimeSpan(extendedLimits.BasicLimitInformation.PerProcessUserTimeLimit))); + Utils.FormatTimeSpan(new TimeSpan(extendedLimits.BasicLimitInformation.PerProcessUserTimeLimit))); if ((flags & JobObjectLimitFlags.SchedulingClass) != 0) this.AddLimit("Scheduling Class", extendedLimits.BasicLimitInformation.SchedulingClass.ToString()); if ((flags & JobObjectLimitFlags.SilentBreakawayOk) != 0) this.AddLimit("Silent Breakaway OK", "Enabled"); if ((flags & JobObjectLimitFlags.WorkingSet) != 0) { - this.AddLimit("Minimum Working Set", Utils.GetNiceSizeName(extendedLimits.BasicLimitInformation.MinimumWorkingSetSize)); - this.AddLimit("Maximum Working Set", Utils.GetNiceSizeName(extendedLimits.BasicLimitInformation.MaximumWorkingSetSize)); + this.AddLimit("Minimum Working Set", Utils.FormatSize(extendedLimits.BasicLimitInformation.MinimumWorkingSetSize)); + this.AddLimit("Maximum Working Set", Utils.FormatSize(extendedLimits.BasicLimitInformation.MaximumWorkingSetSize)); } if ((uiRestrictions & JobObjectBasicUiRestrictions.Desktop) != 0) @@ -166,21 +166,21 @@ namespace ProcessHacker.Components labelGeneralTotalProcesses.Text = accounting.BasicInfo.TotalProcesses.ToString("N0"); labelGeneralTerminatedProcesses.Text = accounting.BasicInfo.TotalTerminatedProcesses.ToString("N0"); - labelTimeUserTime.Text = Utils.GetNiceTimeSpan(new TimeSpan(accounting.BasicInfo.TotalUserTime)); - labelTimeKernelTime.Text = Utils.GetNiceTimeSpan(new TimeSpan(accounting.BasicInfo.TotalKernelTime)); - labelTimeUserTimePeriod.Text = Utils.GetNiceTimeSpan(new TimeSpan(accounting.BasicInfo.ThisPeriodTotalUserTime)); - labelTimeKernelTimePeriod.Text = Utils.GetNiceTimeSpan(new TimeSpan(accounting.BasicInfo.ThisPeriodTotalKernelTime)); + labelTimeUserTime.Text = Utils.FormatTimeSpan(new TimeSpan(accounting.BasicInfo.TotalUserTime)); + labelTimeKernelTime.Text = Utils.FormatTimeSpan(new TimeSpan(accounting.BasicInfo.TotalKernelTime)); + labelTimeUserTimePeriod.Text = Utils.FormatTimeSpan(new TimeSpan(accounting.BasicInfo.ThisPeriodTotalUserTime)); + labelTimeKernelTimePeriod.Text = Utils.FormatTimeSpan(new TimeSpan(accounting.BasicInfo.ThisPeriodTotalKernelTime)); labelMemoryPageFaults.Text = accounting.BasicInfo.TotalPageFaultCount.ToString("N0"); - labelMemoryPeakProcessUsage.Text = Utils.GetNiceSizeName(limits.PeakProcessMemoryUsed); - labelMemoryPeakJobUsage.Text = Utils.GetNiceSizeName(limits.PeakJobMemoryUsed); + labelMemoryPeakProcessUsage.Text = Utils.FormatSize(limits.PeakProcessMemoryUsed); + labelMemoryPeakJobUsage.Text = Utils.FormatSize(limits.PeakJobMemoryUsed); labelIOReads.Text = accounting.IoInfo.ReadOperationCount.ToString("N0"); - labelIOReadBytes.Text = Utils.GetNiceSizeName(accounting.IoInfo.ReadTransferCount); + labelIOReadBytes.Text = Utils.FormatSize(accounting.IoInfo.ReadTransferCount); labelIOWrites.Text = accounting.IoInfo.WriteOperationCount.ToString("N0"); - labelIOWriteBytes.Text = Utils.GetNiceSizeName(accounting.IoInfo.WriteTransferCount); + labelIOWriteBytes.Text = Utils.FormatSize(accounting.IoInfo.WriteTransferCount); labelIOOther.Text = accounting.IoInfo.OtherOperationCount.ToString("N0"); - labelIOOtherBytes.Text = Utils.GetNiceSizeName(accounting.IoInfo.OtherTransferCount); + labelIOOtherBytes.Text = Utils.FormatSize(accounting.IoInfo.OtherTransferCount); } catch { } diff --git a/trunk/ProcessHacker/Components/MemoryList.cs b/trunk/ProcessHacker/Components/MemoryList.cs index d807dd257..c0cf0345b 100644 --- a/trunk/ProcessHacker/Components/MemoryList.cs +++ b/trunk/ProcessHacker/Components/MemoryList.cs @@ -321,7 +321,7 @@ namespace ProcessHacker.Components } litem.SubItems[1].Text = "0x" + item.Address.ToString("x8"); - litem.SubItems[2].Text = Utils.GetNiceSizeName(item.Size); + litem.SubItems[2].Text = Utils.FormatSize(item.Size); litem.SubItems[3].Text = GetProtectStr(item.Protection); litem.Tag = item; } diff --git a/trunk/ProcessHacker/Components/ModuleList.cs b/trunk/ProcessHacker/Components/ModuleList.cs index 9f17fc5fd..96400c2b5 100644 --- a/trunk/ProcessHacker/Components/ModuleList.cs +++ b/trunk/ProcessHacker/Components/ModuleList.cs @@ -273,7 +273,7 @@ namespace ProcessHacker.Components litem.Name = item.BaseAddress.ToString(); litem.Text = item.Name; litem.SubItems.Add(new ListViewItem.ListViewSubItem(litem, "0x" + item.BaseAddress.ToString("x8"))); - litem.SubItems.Add(new ListViewItem.ListViewSubItem(litem, _pid != 4 ? Utils.GetNiceSizeName(item.Size) : "")); + litem.SubItems.Add(new ListViewItem.ListViewSubItem(litem, _pid != 4 ? Utils.FormatSize(item.Size) : "")); litem.SubItems.Add(new ListViewItem.ListViewSubItem(litem, item.FileDescription)); litem.ToolTipText = item.FileName; litem.Tag = item; diff --git a/trunk/ProcessHacker/Components/ProcessStatistics.cs b/trunk/ProcessHacker/Components/ProcessStatistics.cs index f66cb393c..4d98f0577 100644 --- a/trunk/ProcessHacker/Components/ProcessStatistics.cs +++ b/trunk/ProcessHacker/Components/ProcessStatistics.cs @@ -99,25 +99,25 @@ namespace ProcessHacker.Components ProcessItem item = Program.ProcessProvider.Dictionary[_pid]; labelCPUPriority.Text = item.Process.BasePriority.ToString(); - labelCPUKernelTime.Text = Utils.GetNiceTimeSpan(new TimeSpan(item.Process.KernelTime)); - labelCPUUserTime.Text = Utils.GetNiceTimeSpan(new TimeSpan(item.Process.UserTime)); - labelCPUTotalTime.Text = Utils.GetNiceTimeSpan(new TimeSpan(item.Process.KernelTime + item.Process.UserTime)); + labelCPUKernelTime.Text = Utils.FormatTimeSpan(new TimeSpan(item.Process.KernelTime)); + labelCPUUserTime.Text = Utils.FormatTimeSpan(new TimeSpan(item.Process.UserTime)); + labelCPUTotalTime.Text = Utils.FormatTimeSpan(new TimeSpan(item.Process.KernelTime + item.Process.UserTime)); - labelMemoryPB.Text = Utils.GetNiceSizeName(item.Process.VirtualMemoryCounters.PrivateBytes); - labelMemoryWS.Text = Utils.GetNiceSizeName(item.Process.VirtualMemoryCounters.WorkingSetSize); - labelMemoryPWS.Text = Utils.GetNiceSizeName(item.Process.VirtualMemoryCounters.PeakWorkingSetSize); - labelMemoryVS.Text = Utils.GetNiceSizeName(item.Process.VirtualMemoryCounters.VirtualSize); - labelMemoryPVS.Text = Utils.GetNiceSizeName(item.Process.VirtualMemoryCounters.PeakVirtualSize); - labelMemoryPU.Text = Utils.GetNiceSizeName(item.Process.VirtualMemoryCounters.PagefileUsage); - labelMemoryPPU.Text = Utils.GetNiceSizeName(item.Process.VirtualMemoryCounters.PeakPagefileUsage); + labelMemoryPB.Text = Utils.FormatSize(item.Process.VirtualMemoryCounters.PrivateBytes); + labelMemoryWS.Text = Utils.FormatSize(item.Process.VirtualMemoryCounters.WorkingSetSize); + labelMemoryPWS.Text = Utils.FormatSize(item.Process.VirtualMemoryCounters.PeakWorkingSetSize); + labelMemoryVS.Text = Utils.FormatSize(item.Process.VirtualMemoryCounters.VirtualSize); + labelMemoryPVS.Text = Utils.FormatSize(item.Process.VirtualMemoryCounters.PeakVirtualSize); + labelMemoryPU.Text = Utils.FormatSize(item.Process.VirtualMemoryCounters.PagefileUsage); + labelMemoryPPU.Text = Utils.FormatSize(item.Process.VirtualMemoryCounters.PeakPagefileUsage); labelMemoryPF.Text = ((ulong)item.Process.VirtualMemoryCounters.PageFaultCount).ToString("N0"); labelIOReads.Text = ((ulong)item.Process.IoCounters.ReadOperationCount).ToString("N0"); - labelIOReadBytes.Text = Utils.GetNiceSizeName(item.Process.IoCounters.ReadTransferCount); + labelIOReadBytes.Text = Utils.FormatSize(item.Process.IoCounters.ReadTransferCount); labelIOWrites.Text = ((ulong)item.Process.IoCounters.WriteOperationCount).ToString("N0"); - labelIOWriteBytes.Text = Utils.GetNiceSizeName(item.Process.IoCounters.WriteTransferCount); + labelIOWriteBytes.Text = Utils.FormatSize(item.Process.IoCounters.WriteTransferCount); labelIOOther.Text = ((ulong)item.Process.IoCounters.OtherOperationCount).ToString("N0"); - labelIOOtherBytes.Text = Utils.GetNiceSizeName(item.Process.IoCounters.OtherTransferCount); + labelIOOtherBytes.Text = Utils.FormatSize(item.Process.IoCounters.OtherTransferCount); labelOtherHandles.Text = ((ulong)item.Process.HandleCount).ToString("N0"); diff --git a/trunk/ProcessHacker/Components/ProcessTree/ProcessNode.cs b/trunk/ProcessHacker/Components/ProcessTree/ProcessNode.cs index ba3dc3c9a..76620689e 100644 --- a/trunk/ProcessHacker/Components/ProcessTree/ProcessNode.cs +++ b/trunk/ProcessHacker/Components/ProcessTree/ProcessNode.cs @@ -175,20 +175,20 @@ namespace ProcessHacker public string PvtMemory { - get { return Utils.GetNiceSizeName(_pitem.Process.VirtualMemoryCounters.PrivateBytes); } + get { return Utils.FormatSize(_pitem.Process.VirtualMemoryCounters.PrivateBytes); } } public string WorkingSet { get { - return Utils.GetNiceSizeName(_pitem.Process.VirtualMemoryCounters.WorkingSetSize); + return Utils.FormatSize(_pitem.Process.VirtualMemoryCounters.WorkingSetSize); } } public string PeakWorkingSet { - get { return Utils.GetNiceSizeName(_pitem.Process.VirtualMemoryCounters.PeakWorkingSetSize); } + get { return Utils.FormatSize(_pitem.Process.VirtualMemoryCounters.PeakWorkingSetSize); } } private int GetWorkingSetNumber(NProcessHacker.WsInformationClass WsInformationClass) @@ -225,7 +225,7 @@ namespace ProcessHacker public string PrivateWorkingSet { - get { return Utils.GetNiceSizeName(this.PrivateWorkingSetNumber); } + get { return Utils.FormatSize(this.PrivateWorkingSetNumber); } } public int SharedWorkingSetNumber @@ -235,7 +235,7 @@ namespace ProcessHacker public string SharedWorkingSet { - get { return Utils.GetNiceSizeName(this.SharedWorkingSetNumber); } + get { return Utils.FormatSize(this.SharedWorkingSetNumber); } } public int ShareableWorkingSetNumber @@ -245,27 +245,27 @@ namespace ProcessHacker public string ShareableWorkingSet { - get { return Utils.GetNiceSizeName(this.ShareableWorkingSetNumber); } + get { return Utils.FormatSize(this.ShareableWorkingSetNumber); } } public string VirtualSize { - get { return Utils.GetNiceSizeName(_pitem.Process.VirtualMemoryCounters.VirtualSize); } + get { return Utils.FormatSize(_pitem.Process.VirtualMemoryCounters.VirtualSize); } } public string PeakVirtualSize { - get { return Utils.GetNiceSizeName(_pitem.Process.VirtualMemoryCounters.PeakVirtualSize); } + get { return Utils.FormatSize(_pitem.Process.VirtualMemoryCounters.PeakVirtualSize); } } public string PagefileUsage { - get { return Utils.GetNiceSizeName(_pitem.Process.VirtualMemoryCounters.PagefileUsage); } + get { return Utils.FormatSize(_pitem.Process.VirtualMemoryCounters.PagefileUsage); } } public string PeakPagefileUsage { - get { return Utils.GetNiceSizeName(_pitem.Process.VirtualMemoryCounters.PeakPagefileUsage); } + get { return Utils.FormatSize(_pitem.Process.VirtualMemoryCounters.PeakPagefileUsage); } } public string PageFaults @@ -325,7 +325,7 @@ namespace ProcessHacker if (Pid < 4) return ""; else - return Utils.GetStringPriority(_pitem.Process.BasePriority); + return Utils.FormatPriority(_pitem.Process.BasePriority); } } @@ -500,7 +500,7 @@ namespace ProcessHacker if (this.IoTotalNumber == 0) return ""; else - return Utils.GetNiceSizeName(this.IoTotalNumber) + "/s"; + return Utils.FormatSize(this.IoTotalNumber) + "/s"; } } @@ -523,7 +523,7 @@ namespace ProcessHacker if (this.IoReadOtherNumber == 0) return ""; else - return Utils.GetNiceSizeName(this.IoReadOtherNumber) + "/s"; + return Utils.FormatSize(this.IoReadOtherNumber) + "/s"; } } @@ -546,7 +546,7 @@ namespace ProcessHacker if (this.IoWriteNumber == 0) return ""; else - return Utils.GetNiceSizeName(this.IoWriteNumber) + "/s"; + return Utils.FormatSize(this.IoWriteNumber) + "/s"; } } @@ -613,23 +613,23 @@ namespace ProcessHacker if (Pid < 4 || _pitem.CreateTime.Year == 1) return ""; else - return Utils.GetNiceRelativeDateTime(_pitem.CreateTime); + return Utils.FormatRelativeDateTime(_pitem.CreateTime); } } public string TotalCpuTime { - get { return Utils.GetNiceTimeSpan(new TimeSpan(_pitem.Process.KernelTime + _pitem.Process.UserTime)); } + get { return Utils.FormatTimeSpan(new TimeSpan(_pitem.Process.KernelTime + _pitem.Process.UserTime)); } } public string KernelCpuTime { - get { return Utils.GetNiceTimeSpan(new TimeSpan(_pitem.Process.KernelTime)); } + get { return Utils.FormatTimeSpan(new TimeSpan(_pitem.Process.KernelTime)); } } public string UserCpuTime { - get { return Utils.GetNiceTimeSpan(new TimeSpan(_pitem.Process.UserTime)); } + get { return Utils.FormatTimeSpan(new TimeSpan(_pitem.Process.UserTime)); } } } } diff --git a/trunk/ProcessHacker/Components/ProcessTree/ProcessToolTipProvider.cs b/trunk/ProcessHacker/Components/ProcessTree/ProcessToolTipProvider.cs index 019965d67..fbcf5a259 100644 --- a/trunk/ProcessHacker/Components/ProcessTree/ProcessToolTipProvider.cs +++ b/trunk/ProcessHacker/Components/ProcessTree/ProcessToolTipProvider.cs @@ -45,7 +45,7 @@ namespace ProcessHacker ProcessNode pNode = _tree.FindNode(node); string cmdText = (pNode.ProcessItem.CmdLine != null ? - (Utils.MakeEllipsis(pNode.ProcessItem.CmdLine.Replace("\0", ""), 100) + "\n") : ""); + (Utils.CreateEllipsis(pNode.ProcessItem.CmdLine.Replace("\0", ""), 100) + "\n") : ""); string fileText = ""; diff --git a/trunk/ProcessHacker/Components/SectionProperties.cs b/trunk/ProcessHacker/Components/SectionProperties.cs index 162faa0a7..3dcc0c788 100644 --- a/trunk/ProcessHacker/Components/SectionProperties.cs +++ b/trunk/ProcessHacker/Components/SectionProperties.cs @@ -23,7 +23,7 @@ namespace ProcessHacker.Components var basicInfo = _sectionHandle.GetBasicInformation(); labelAttributes.Text = basicInfo.SectionAttributes.ToString(); - labelSize.Text = Utils.GetNiceSizeName(basicInfo.SectionSize); + labelSize.Text = Utils.FormatSize(basicInfo.SectionSize); } } } diff --git a/trunk/ProcessHacker/Components/ThreadList.cs b/trunk/ProcessHacker/Components/ThreadList.cs index 4aa73e7d8..59b578b15 100644 --- a/trunk/ProcessHacker/Components/ThreadList.cs +++ b/trunk/ProcessHacker/Components/ThreadList.cs @@ -135,7 +135,7 @@ namespace ProcessHacker.Components try { - processThread = Utils.GetThreadById(Process.GetProcessById(_pid), tid); + processThread = Utils.GetThreadFromId(Process.GetProcessById(_pid), tid); } catch { } @@ -156,9 +156,9 @@ namespace ProcessHacker.Components labelState.Text = processThread.ThreadState.ToString(); } - labelKernelTime.Text = Utils.GetNiceTimeSpan(processThread.PrivilegedProcessorTime); - labelUserTime.Text = Utils.GetNiceTimeSpan(processThread.UserProcessorTime); - labelTotalTime.Text = Utils.GetNiceTimeSpan(processThread.TotalProcessorTime); + labelKernelTime.Text = Utils.FormatTimeSpan(processThread.PrivilegedProcessorTime); + labelUserTime.Text = Utils.FormatTimeSpan(processThread.UserProcessorTime); + labelTotalTime.Text = Utils.FormatTimeSpan(processThread.TotalProcessorTime); } catch { diff --git a/trunk/ProcessHacker/Components/TokenProperties.cs b/trunk/ProcessHacker/Components/TokenProperties.cs index f4258327a..58fcfba65 100644 --- a/trunk/ProcessHacker/Components/TokenProperties.cs +++ b/trunk/ProcessHacker/Components/TokenProperties.cs @@ -148,8 +148,8 @@ namespace ProcessHacker.Components textImpersonationLevel.Text = statistics.ImpersonationLevel.ToString(); textTokenId.Text = "0x" + statistics.TokenId.ToString(); textAuthenticationId.Text = "0x" + statistics.AuthenticationId.ToString(); - textMemoryUsed.Text = Utils.GetNiceSizeName(statistics.DynamicCharged); - textMemoryAvailable.Text = Utils.GetNiceSizeName(statistics.DynamicAvailable); + textMemoryUsed.Text = Utils.FormatSize(statistics.DynamicCharged); + textMemoryAvailable.Text = Utils.FormatSize(statistics.DynamicAvailable); } catch (Exception ex) { diff --git a/trunk/ProcessHacker/Forms/HeapsWindow.cs b/trunk/ProcessHacker/Forms/HeapsWindow.cs index ee7a2efe3..0b74b549c 100644 --- a/trunk/ProcessHacker/Forms/HeapsWindow.cs +++ b/trunk/ProcessHacker/Forms/HeapsWindow.cs @@ -191,8 +191,8 @@ namespace ProcessHacker } else { - item.SubItems[1].Text = Utils.GetNiceSizeName(heap.BytesAllocated); - item.SubItems[2].Text = Utils.GetNiceSizeName(heap.BytesCommitted); + item.SubItems[1].Text = Utils.FormatSize(heap.BytesAllocated); + item.SubItems[2].Text = Utils.FormatSize(heap.BytesCommitted); } } } diff --git a/trunk/ProcessHacker/Forms/PEWindow.cs b/trunk/ProcessHacker/Forms/PEWindow.cs index 2f0f4f1ac..e2fb798b2 100644 --- a/trunk/ProcessHacker/Forms/PEWindow.cs +++ b/trunk/ProcessHacker/Forms/PEWindow.cs @@ -142,7 +142,7 @@ namespace ProcessHacker listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Number of Sections", _peFile.COFFHeader.NumberOfSections.ToString() })); listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Time/Date Stamp", - Utils.DateTimeFromUnixTime(_peFile.COFFHeader.TimeDateStamp).ToString() })); + Utils.GetDateTimeFromUnixTime(_peFile.COFFHeader.TimeDateStamp).ToString() })); listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Pointer to Symbol Table", "0x" + _peFile.COFFHeader.PointerToSymbolTable.ToString("x8") })); listCOFFHeader.Items.Add(new ListViewItem(new string[] { "Number of Symbols", diff --git a/trunk/ProcessHacker/Forms/ProcessWindow.cs b/trunk/ProcessHacker/Forms/ProcessWindow.cs index 50021e0a1..98291ea99 100644 --- a/trunk/ProcessHacker/Forms/ProcessWindow.cs +++ b/trunk/ProcessHacker/Forms/ProcessWindow.cs @@ -305,14 +305,14 @@ namespace ProcessHacker plotterMemory.LongData1 = _processItem.LongHistoryManager[ProcessStats.PrivateMemory]; plotterMemory.LongData2 = _processItem.LongHistoryManager[ProcessStats.WorkingSet]; plotterMemory.GetToolTip = i => - "Pvt. Memory: " + Utils.GetNiceSizeName(plotterMemory.LongData1[i]) + "\n" + - "Working Set: " + Utils.GetNiceSizeName(plotterMemory.LongData2[i]) + "\n" + + "Pvt. Memory: " + Utils.FormatSize(plotterMemory.LongData1[i]) + "\n" + + "Working Set: " + Utils.FormatSize(plotterMemory.LongData2[i]) + "\n" + Program.ProcessProvider.TimeHistory[i].ToString(); plotterIO.LongData1 = _processItem.LongHistoryManager[ProcessStats.IoReadOther]; plotterIO.LongData2 = _processItem.LongHistoryManager[ProcessStats.IoWrite]; plotterIO.GetToolTip = i => - "R+O: " + Utils.GetNiceSizeName(plotterIO.LongData1[i]) + "\n" + - "W: " + Utils.GetNiceSizeName(plotterIO.LongData2[i]) + "\n" + + "R+O: " + Utils.FormatSize(plotterIO.LongData1[i]) + "\n" + + "W: " + Utils.FormatSize(plotterIO.LongData2[i]) + "\n" + Program.ProcessProvider.TimeHistory[i].ToString(); // Set the indicator colors. @@ -521,7 +521,7 @@ namespace ProcessHacker { DateTime startTime = DateTime.FromFileTime(_processItem.Process.CreateTime); - textStartTime.Text = Utils.GetNiceRelativeDateTime(startTime) + + textStartTime.Text = Utils.FormatRelativeDateTime(startTime) + " (" + startTime.ToString() + ")"; } catch (Exception ex) @@ -904,12 +904,12 @@ namespace ProcessHacker " (K: " + (procKernel * 100).ToString("F2") + "%, U: " + (procUser * 100).ToString("F2") + "%)"; - string pvtString = Utils.GetNiceSizeName(item.Process.VirtualMemoryCounters.PrivateBytes); + string pvtString = Utils.FormatSize(item.Process.VirtualMemoryCounters.PrivateBytes); plotterMemory.Text = "Pvt: " + pvtString + - ", WS: " + Utils.GetNiceSizeName(item.Process.VirtualMemoryCounters.WorkingSetSize); + ", WS: " + Utils.FormatSize(item.Process.VirtualMemoryCounters.WorkingSetSize); - string ioROString = Utils.GetNiceSizeName(ioRO); - plotterIO.Text = "R+O: " + ioROString + ", W: " + Utils.GetNiceSizeName(ioW); + string ioROString = Utils.FormatSize(ioRO); + plotterIO.Text = "R+O: " + ioROString + ", W: " + Utils.FormatSize(ioW); plotterCPUUsage.MoveGrid(); plotterCPUUsage.Draw(); diff --git a/trunk/ProcessHacker/Forms/RunWindow.cs b/trunk/ProcessHacker/Forms/RunWindow.cs index 74298ec75..c8bccd270 100644 --- a/trunk/ProcessHacker/Forms/RunWindow.cs +++ b/trunk/ProcessHacker/Forms/RunWindow.cs @@ -175,7 +175,7 @@ namespace ProcessHacker } else { - string serviceName = Utils.MakeRandomString(8); + string serviceName = Utils.CreateRandomString(8); using (var manager = new ServiceManagerHandle(ScManagerAccess.CreateService)) { diff --git a/trunk/ProcessHacker/Forms/SysInfoWindow.cs b/trunk/ProcessHacker/Forms/SysInfoWindow.cs index 67c90e946..5df862248 100644 --- a/trunk/ProcessHacker/Forms/SysInfoWindow.cs +++ b/trunk/ProcessHacker/Forms/SysInfoWindow.cs @@ -112,14 +112,14 @@ namespace ProcessHacker plotterIO.LongData2 = Program.ProcessProvider.LongHistory[SystemStats.IoWrite]; plotterIO.GetToolTip = i => Program.ProcessProvider.MostIoHistory[i] + "\n" + - "R+O: " + Utils.GetNiceSizeName(plotterIO.LongData1[i]) + "\n" + - "W: " + Utils.GetNiceSizeName(plotterIO.LongData2[i]) + "\n" + + "R+O: " + Utils.FormatSize(plotterIO.LongData1[i]) + "\n" + + "W: " + Utils.FormatSize(plotterIO.LongData2[i]) + "\n" + Program.ProcessProvider.TimeHistory[i].ToString(); plotterMemory.LongData1 = Program.ProcessProvider.LongHistory[SystemStats.Commit]; plotterMemory.LongData2 = Program.ProcessProvider.LongHistory[SystemStats.PhysicalMemory]; plotterMemory.GetToolTip = i => - "Commit: " + Utils.GetNiceSizeName(plotterMemory.LongData1[i]) + "\n" + - "Phys. Memory: " + Utils.GetNiceSizeName(plotterMemory.LongData2[i]) + "\n" + + "Commit: " + Utils.FormatSize(plotterMemory.LongData1[i]) + "\n" + + "Phys. Memory: " + Utils.FormatSize(plotterMemory.LongData2[i]) + "\n" + Program.ProcessProvider.TimeHistory[i].ToString(); // Create a plotter per CPU. @@ -192,7 +192,7 @@ namespace ProcessHacker else indicatorIO.Maximum = (int)maxW; indicatorIO.Data1 = (int)(Program.ProcessProvider.LongHistory[SystemStats.IoReadOther][0]); - indicatorIO.TextValue = Utils.GetNiceSizeName(Program.ProcessProvider.LongHistory[SystemStats.IoReadOther][0]); + indicatorIO.TextValue = Utils.FormatSize(Program.ProcessProvider.LongHistory[SystemStats.IoReadOther][0]); // Update the plotter settings. plotterIO.LongData1 = Program.ProcessProvider.LongHistory[SystemStats.IoReadOther]; @@ -221,12 +221,12 @@ namespace ProcessHacker "%, U: " + (plotterCPU.Data2[0] * 100).ToString("F2") + "%)"; // update the I/O graph text - plotterIO.Text = "R+O: " + Utils.GetNiceSizeName(plotterIO.LongData1[0]) + - ", W: " + Utils.GetNiceSizeName(plotterIO.LongData2[0]); + plotterIO.Text = "R+O: " + Utils.FormatSize(plotterIO.LongData1[0]) + + ", W: " + Utils.FormatSize(plotterIO.LongData2[0]); // update the memory graph text - plotterMemory.Text = "Commit: " + Utils.GetNiceSizeName(plotterMemory.LongData1[0]) + - ", Phys. Mem: " + Utils.GetNiceSizeName(plotterMemory.LongData2[0]); + plotterMemory.Text = "Commit: " + Utils.FormatSize(plotterMemory.LongData1[0]) + + ", Phys. Mem: " + Utils.FormatSize(plotterMemory.LongData2[0]); plotterCPU.MoveGrid(); plotterCPU.Draw(); @@ -280,16 +280,16 @@ namespace ProcessHacker labelTotalsHandles.Text = ((ulong)info.HandlesCount).ToString("N0"); // Commit - labelCCC.Text = Utils.GetNiceSizeName((ulong)perfInfo.CommittedPages * _pageSize); - labelCCP.Text = Utils.GetNiceSizeName((ulong)perfInfo.PeakCommitment * _pageSize); - labelCCL.Text = Utils.GetNiceSizeName((ulong)perfInfo.CommitLimit * _pageSize); + labelCCC.Text = Utils.FormatSize((ulong)perfInfo.CommittedPages * _pageSize); + labelCCP.Text = Utils.FormatSize((ulong)perfInfo.PeakCommitment * _pageSize); + labelCCL.Text = Utils.FormatSize((ulong)perfInfo.CommitLimit * _pageSize); // Physical Memory - string physMemText = Utils.GetNiceSizeName((ulong)(_pages - perfInfo.AvailablePages) * _pageSize); + string physMemText = Utils.FormatSize((ulong)(_pages - perfInfo.AvailablePages) * _pageSize); labelPMC.Text = physMemText; - labelPSC.Text = Utils.GetNiceSizeName((ulong)info.SystemCache * _pageSize); - labelPMT.Text = Utils.GetNiceSizeName((ulong)_pages * _pageSize); + labelPSC.Text = Utils.FormatSize((ulong)info.SystemCache * _pageSize); + labelPMT.Text = Utils.FormatSize((ulong)_pages * _pageSize); // Update the physical memory indicator here because we have perfInfo available. @@ -297,17 +297,17 @@ namespace ProcessHacker indicatorPhysical.TextValue = physMemText; // File cache - labelCacheCurrent.Text = Utils.GetNiceSizeName(cacheInfo.SystemCacheWsSize); - labelCachePeak.Text = Utils.GetNiceSizeName(cacheInfo.SystemCacheWsPeakSize); - labelCacheMinimum.Text = Utils.GetNiceSizeName((ulong)cacheInfo.SystemCacheWsMinimum * _pageSize); - labelCacheMaximum.Text = Utils.GetNiceSizeName((ulong)cacheInfo.SystemCacheWsMaximum * _pageSize); + labelCacheCurrent.Text = Utils.FormatSize(cacheInfo.SystemCacheWsSize); + labelCachePeak.Text = Utils.FormatSize(cacheInfo.SystemCacheWsPeakSize); + labelCacheMinimum.Text = Utils.FormatSize((ulong)cacheInfo.SystemCacheWsMinimum * _pageSize); + labelCacheMaximum.Text = Utils.FormatSize((ulong)cacheInfo.SystemCacheWsMaximum * _pageSize); // Paged/Non-paged pools - labelKPPPU.Text = Utils.GetNiceSizeName((ulong)perfInfo.PagedPoolPages * _pageSize); - labelKPPVU.Text = Utils.GetNiceSizeName((ulong)perfInfo.PagedPoolUsage * _pageSize); + labelKPPPU.Text = Utils.FormatSize((ulong)perfInfo.PagedPoolPages * _pageSize); + labelKPPVU.Text = Utils.FormatSize((ulong)perfInfo.PagedPoolUsage * _pageSize); labelKPPA.Text = ((ulong)perfInfo.PagedPoolAllocs).ToString("N0"); labelKPPF.Text = ((ulong)perfInfo.PagedPoolFrees).ToString("N0"); - labelKPNPU.Text = Utils.GetNiceSizeName((ulong)perfInfo.NonPagedPoolUsage * _pageSize); + labelKPNPU.Text = Utils.FormatSize((ulong)perfInfo.NonPagedPoolUsage * _pageSize); labelKPNPA.Text = ((ulong)perfInfo.NonPagedPoolAllocs).ToString("N0"); labelKPNPF.Text = ((ulong)perfInfo.NonPagedPoolFrees).ToString("N0"); @@ -331,8 +331,8 @@ namespace ProcessHacker if (pagedLimit != 0 && nonPagedLimit != 0) { - labelKPPL.Text = Utils.GetNiceSizeName(pagedLimit); - labelKPNPL.Text = Utils.GetNiceSizeName(nonPagedLimit); + labelKPPL.Text = Utils.FormatSize(pagedLimit); + labelKPNPL.Text = Utils.FormatSize(nonPagedLimit); } else if (KProcessHacker.Instance == null) { @@ -355,11 +355,11 @@ namespace ProcessHacker // I/O labelIOR.Text = ((ulong)perfInfo.IoReadOperationCount).ToString("N0"); - labelIORB.Text = Utils.GetNiceSizeName(perfInfo.IoReadTransferCount); + labelIORB.Text = Utils.FormatSize(perfInfo.IoReadTransferCount); labelIOW.Text = ((ulong)perfInfo.IoWriteOperationCount).ToString("N0"); - labelIOWB.Text = Utils.GetNiceSizeName(perfInfo.IoWriteTransferCount); + labelIOWB.Text = Utils.FormatSize(perfInfo.IoWriteTransferCount); labelIOO.Text = ((ulong)perfInfo.IoOtherOperationCount).ToString("N0"); - labelIOOB.Text = Utils.GetNiceSizeName(perfInfo.IoOtherTransferCount); + labelIOOB.Text = Utils.FormatSize(perfInfo.IoOtherTransferCount); // CPU labelCPUContextSwitches.Text = ((ulong)perfInfo.ContextSwitches).ToString("N0"); diff --git a/trunk/ProcessHacker/Program/Program.cs b/trunk/ProcessHacker/Program/Program.cs index 2d3e92d92..cb712e437 100644 --- a/trunk/ProcessHacker/Program/Program.cs +++ b/trunk/ProcessHacker/Program/Program.cs @@ -497,7 +497,7 @@ namespace ProcessHacker if (pArgs.ContainsKey("-rect")) { - Rectangle rect = Utils.RectangleFromString(pArgs["-rect"]); + Rectangle rect = Utils.GetRectangle(pArgs["-rect"]); options.Location = new Point(rect.X + 20, rect.Y + 20); options.StartPosition = FormStartPosition.Manual; @@ -788,7 +788,7 @@ namespace ProcessHacker info.AppendLine("CLR Version: " + Environment.Version.ToString()); info.AppendLine("OS Version: " + Environment.OSVersion.VersionString); info.AppendLine("Elevation: " + ElevationType.ToString()); - info.AppendLine("Working set: " + Utils.GetNiceSizeName(Environment.WorkingSet)); + info.AppendLine("Working set: " + Utils.FormatSize(Environment.WorkingSet)); info.AppendLine("Private heap: 0x" + MemoryAlloc.PrivateHeap.ToString("x")); if (KProcessHacker.Instance == null) diff --git a/trunk/ProcessHacker/Providers/ProcessSystemProvider.cs b/trunk/ProcessHacker/Providers/ProcessSystemProvider.cs index 56ab8bc75..c0d233ed9 100644 --- a/trunk/ProcessHacker/Providers/ProcessSystemProvider.cs +++ b/trunk/ProcessHacker/Providers/ProcessSystemProvider.cs @@ -876,7 +876,7 @@ namespace ProcessHacker try { - item.CreateTime = Utils.DateTimeFromFileTime(processInfo.CreateTime); + item.CreateTime = Utils.GetDateTimeFromLongTime(processInfo.CreateTime); } catch { } @@ -1184,9 +1184,9 @@ namespace ProcessHacker try { _mostUsageHistory.Update(true, newdictionary[this.PIDWithMostIoActivity].Name + ": " + - "R+O: " + Utils.GetNiceSizeName( + "R+O: " + Utils.FormatSize( newdictionary[this.PIDWithMostIoActivity].LongHistoryManager[ProcessStats.IoReadOther][0]) + - ", W: " + Utils.GetNiceSizeName( + ", W: " + Utils.FormatSize( newdictionary[this.PIDWithMostIoActivity].LongHistoryManager[ProcessStats.IoWrite][0])); } catch diff --git a/trunk/ProcessHacker/UI/Icons/CommitHistoryIcon.cs b/trunk/ProcessHacker/UI/Icons/CommitHistoryIcon.cs index aab7c3bed..4f9b2aa43 100644 --- a/trunk/ProcessHacker/UI/Icons/CommitHistoryIcon.cs +++ b/trunk/ProcessHacker/UI/Icons/CommitHistoryIcon.cs @@ -46,7 +46,7 @@ namespace ProcessHacker this.Update(this.Provider.Performance.CommittedPages, 0); this.Redraw(); - this.Text = "Commit: " + Utils.GetNiceSizeName( + this.Text = "Commit: " + Utils.FormatSize( (long)this.Provider.Performance.CommittedPages * this.Provider.System.PageSize); } } diff --git a/trunk/ProcessHacker/UI/Icons/IoHistoryIcon.cs b/trunk/ProcessHacker/UI/Icons/IoHistoryIcon.cs index 64ad5ede1..5c308fb57 100644 --- a/trunk/ProcessHacker/UI/Icons/IoHistoryIcon.cs +++ b/trunk/ProcessHacker/UI/Icons/IoHistoryIcon.cs @@ -50,9 +50,9 @@ namespace ProcessHacker this.Redraw(); - string text = "R: " + Utils.GetNiceSizeName(this.Provider.LongDeltas[SystemStats.IoRead]) + - "\nW: " + Utils.GetNiceSizeName(this.Provider.LongDeltas[SystemStats.IoWrite]) + - "\nO: " + Utils.GetNiceSizeName(this.Provider.LongDeltas[SystemStats.IoOther]); + string text = "R: " + Utils.FormatSize(this.Provider.LongDeltas[SystemStats.IoRead]) + + "\nW: " + Utils.FormatSize(this.Provider.LongDeltas[SystemStats.IoWrite]) + + "\nO: " + Utils.FormatSize(this.Provider.LongDeltas[SystemStats.IoOther]); if (this.Provider.Dictionary.ContainsKey(this.Provider.PIDWithMostIoActivity)) { diff --git a/trunk/ProcessHacker/UI/Icons/PhysMemHistoryIcon.cs b/trunk/ProcessHacker/UI/Icons/PhysMemHistoryIcon.cs index 166b408ae..a4e371f3a 100644 --- a/trunk/ProcessHacker/UI/Icons/PhysMemHistoryIcon.cs +++ b/trunk/ProcessHacker/UI/Icons/PhysMemHistoryIcon.cs @@ -46,7 +46,7 @@ namespace ProcessHacker this.Update(this.MinMaxValue - this.Provider.Performance.AvailablePages, 0); this.Redraw(); - this.Text = "Physical Memory: " + Utils.GetNiceSizeName( + this.Text = "Physical Memory: " + Utils.FormatSize( (long)(this.MinMaxValue - this.Provider.Performance.AvailablePages) * this.Provider.System.PageSize); } diff --git a/trunk/native.html b/trunk/native.html index ac9236a90..7ad4a0235 100644 --- a/trunk/native.html +++ b/trunk/native.html @@ -54,6 +54,26 @@ h4 {

NT Concepts

+

Alertable

+

A thread contains fields for two alertable states, one for kernel-mode and one for user-mode. + When a caller from one of these modes alerts a thread (e.g. using NtAlertThread), + the thread is put into an alerted state for the mode, and one of several things happen:

+
    +
  • If the thread is performing a kernel-mode alertable wait and it has just been alerted from + user-mode, nothing will happen.
  • +
  • If the thread is performing a kernel-mode alertable wait and it has just been alerted from + kernel-mode, the wait will be interrupted and the wait function will return + STATUS_ALERTED.
  • +
  • If the thread is performing a user-mode alertable wait and it has just been alerted from + user-mode, the wait will be interrupted as above.
  • +
  • If the thread is performing a user-mode alertable wait and it has just been alerted from + kernel-mode, the wait will be interrupted as above.
  • +
+

Note that if the thread is alerted and then performs an alertable wait, it will be interrupted + immediately without performing the wait.

+

The thread can also call NtTestAlert to check if it is alerted. In all of these + cases, the thread will be reset to a non-alerted state if it is alerted.

+

ALPC Port

Local Inter-process Communication (LPC) ports are an interprocess communication (IPC) method. A server process creates a port object and waits for a client to connect to the port. Once @@ -86,8 +106,8 @@ h4 {

User-mode APCs are queued using NtQueueApcThread. They will not be called unless an alertable wait is being performed or NtTestAlert is called in the target thread. In those cases, a flag will be set in the target thread's APC state indicating that - one or more user-mode APCs are pending and the wait operation will be interrupted. When the system - call returns to user-mode, any pending user-mode APCs will be called.

+ one or more user-mode APCs are pending and the wait operation, if any, will be interrupted. When the + system call returns to user-mode, any pending user-mode APCs will be called.

A special use of user-mode APCs is thread termination, where a thread termination APC (PspExitNormalApc) is inserted into the target thread. KiInsertQueueApc contains a special case for thread termination and inserts the APC at the beginning of the