PH1.x: fixed build

git-svn-id: svn://svn.code.sf.net/p/processhacker/code@5614 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
dmex
2014-02-25 23:14:38 +00:00
parent 3224849b3b
commit b02427417c
620 changed files with 23415 additions and 21517 deletions
@@ -30,7 +30,7 @@ namespace ProcessHacker.Common
/// </summary>
public static class BaseConverter
{
private static readonly int[] _reverseChars = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
private static int[] _reverseChars = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 52,
53, 54, 55, 56, 57, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -74,7 +74,7 @@ namespace ProcessHacker.Common
if (b > 70)
return 0;
if (string.IsNullOrEmpty(number))
if (number == "")
return 0;
bool negative = number[0] == '-';
@@ -95,8 +95,8 @@ namespace ProcessHacker.Common
if (negative)
return -result;
return result;
else
return result;
}
/// <summary>
@@ -118,11 +118,11 @@ namespace ProcessHacker.Common
/// <returns></returns>
public static decimal ToNumberParse(string number, bool allowNonStandardExts)
{
if (string.IsNullOrEmpty(number))
if (number == "")
return 0;
bool negative = number[0] == '-';
decimal result;
decimal result = 0;
if (negative)
number = number.Substring(1);
@@ -169,8 +169,8 @@ namespace ProcessHacker.Common
if (negative)
return -result;
return result;
else
return result;
}
}
}
@@ -21,13 +21,15 @@
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace ProcessHacker.Common
{
public sealed class ByteStreamReader : Stream
{
private readonly byte[] _data;
private byte[] _data;
private long _position;
public ByteStreamReader(byte[] data)
@@ -20,6 +20,8 @@
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
namespace ProcessHacker.Common
{
/// <summary>
@@ -36,10 +38,10 @@ namespace ProcessHacker.Common
public static class Subtractor
{
private static readonly Int64Subtractor _int64Subtractor = new Int64Subtractor();
private static readonly Int32Subtractor _int32Subtractor = new Int32Subtractor();
private static readonly DoubleSubtractor _doubleSubtractor = new DoubleSubtractor();
private static readonly FloatSubtractor _floatSubtractor = new FloatSubtractor();
private static Int64Subtractor _int64Subtractor = new Int64Subtractor();
private static Int32Subtractor _int32Subtractor = new Int32Subtractor();
private static DoubleSubtractor _doubleSubtractor = new DoubleSubtractor();
private static FloatSubtractor _floatSubtractor = new FloatSubtractor();
public static Int64Subtractor Int64Subtractor
{
@@ -115,7 +117,7 @@ namespace ProcessHacker.Common
public struct DeltaValue<T> : IDeltaValue<T>
{
private readonly ISubtractor<T> _subtractor;
private ISubtractor<T> _subtractor;
private T _value;
private T _delta;
+18 -18
View File
@@ -6,6 +6,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection.Emit;
namespace ProcessHacker.Common
@@ -14,6 +15,7 @@ namespace ProcessHacker.Common
where TEnum : struct, IComparable, IConvertible, IFormattable
{
public static readonly EnumComparer<TEnum> Instance;
private static readonly Func<TEnum, TEnum, bool> _equals;
private static readonly Func<TEnum, int> _getHashCode;
@@ -51,11 +53,12 @@ namespace ProcessHacker.Common
private static void AssertUnderlyingTypeIsSupported()
{
var underlyingType = Enum.GetUnderlyingType(typeof(TEnum));
ICollection<Type> supportedTypes = new[]
{
typeof(byte), typeof(sbyte), typeof(short), typeof(ushort),
typeof(int), typeof(uint), typeof(long), typeof(ulong)
};
ICollection<Type> supportedTypes =
new[]
{
typeof (byte), typeof (sbyte), typeof (short), typeof (ushort),
typeof (int), typeof (uint), typeof (long), typeof (ulong)
};
if (supportedTypes.Contains(underlyingType))
return;
@@ -75,19 +78,18 @@ namespace ProcessHacker.Common
/// <returns>The generated method.</returns>
private static Func<TEnum, TEnum, bool> generateEquals()
{
var method = new DynamicMethod(typeof(TEnum).Name + "_Equals", typeof(bool), new[]
{
typeof(TEnum), typeof(TEnum)
}, typeof(TEnum), true);
var method = new DynamicMethod(typeof(TEnum).Name + "_Equals",
typeof(bool),
new[] { typeof(TEnum), typeof(TEnum) },
typeof(TEnum), true);
var generator = method.GetILGenerator();
// Writing body
generator.Emit(OpCodes.Ldarg_0); // load x to stack
generator.Emit(OpCodes.Ldarg_1); // load y to stack
generator.Emit(OpCodes.Ceq); // x == y
generator.Emit(OpCodes.Ret); // return result
return (Func<TEnum, TEnum, bool>)method.CreateDelegate(typeof(Func<TEnum, TEnum, bool>));
return (Func<TEnum, TEnum, bool>)method.CreateDelegate
(typeof(Func<TEnum, TEnum, bool>));
}
/// <summary>
@@ -102,11 +104,10 @@ namespace ProcessHacker.Common
/// <returns>The generated method.</returns>
private static Func<TEnum, int> generateGetHashCode()
{
var method = new DynamicMethod(typeof(TEnum).Name + "_GetHashCode", typeof(int), new[]
{
typeof(TEnum)
}, typeof(TEnum), true);
var method = new DynamicMethod(typeof(TEnum).Name + "_GetHashCode",
typeof(int),
new[] { typeof(TEnum) },
typeof(TEnum), true);
var generator = method.GetILGenerator();
var underlyingType = Enum.GetUnderlyingType(typeof(TEnum));
var getHashCodeMethod = underlyingType.GetMethod("GetHashCode");
@@ -117,7 +118,6 @@ namespace ProcessHacker.Common
generator.Emit(OpCodes.Ldloca_S, castValue); // load *castValue to stack
generator.Emit(OpCodes.Call, getHashCodeMethod); // castValue.GetHashCode()
generator.Emit(OpCodes.Ret); // return result
return (Func<TEnum, int>)method.CreateDelegate(typeof(Func<TEnum, int>));
}
}
+5 -3
View File
@@ -20,6 +20,7 @@
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Threading;
namespace ProcessHacker.Common
@@ -27,10 +28,11 @@ namespace ProcessHacker.Common
/// <summary>
/// Manages a list of free objects that can be re-used.
/// </summary>
public class FreeList<T> where T : IResettable, new()
public class FreeList<T>
where T : IResettable, new()
{
private readonly T[] _list;
private int _freeIndex;
private T[] _list;
private int _freeIndex = 0;
public FreeList(int maximumCount)
{
@@ -1,4 +1,8 @@
namespace ProcessHacker.Common
using System;
using System.Collections.Generic;
using System.Text;
namespace ProcessHacker.Common
{
public interface IResettable
{
@@ -30,9 +30,9 @@ namespace ProcessHacker.Common
/// </summary>
public class IdGenerator
{
private readonly int _step = 1;
private bool _sort;
private readonly List<int> _ids = new List<int>();
private int _step = 1;
private bool _sort = false;
private List<int> _ids = new List<int>();
private int _id;
/// <summary>
@@ -88,9 +88,11 @@ namespace ProcessHacker.Common
return id;
}
id = this._id;
this._id += this._step;
else
{
id = _id;
_id += _step;
}
}
return id;
+5 -1
View File
@@ -1,4 +1,8 @@
namespace ProcessHacker.Common
using System;
using System.Collections.Generic;
using System.Text;
namespace ProcessHacker.Common
{
public static class LibC
{
+3 -1
View File
@@ -1,4 +1,6 @@
namespace ProcessHacker.Common
using System;
namespace ProcessHacker.Common
{
public class LinkedListEntry<T>
{
+18 -9
View File
@@ -22,6 +22,7 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ProcessHacker.Common
{
@@ -29,7 +30,7 @@ namespace ProcessHacker.Common
public static class Logging
{
public enum Importance
public enum Importance : int
{
Information = 0,
Warning,
@@ -39,18 +40,26 @@ namespace ProcessHacker.Common
public static event LoggingDelegate Logged;
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
private static extern void OutputDebugString(string OutputString);
private static object _logLock = new object();
[Conditional("DEBUG")]
public static void Log(Importance importance, string message)
{
string debugMessage =
DateTime.Now.ToString("hh:mm:ss:fff:") +
" ProcessHacker (T" + System.Threading.Thread.CurrentThread.ManagedThreadId +
"): (" + importance.ToString() + ") " + message + "\r\n\r\n" + Environment.StackTrace;
lock (_logLock)
{
string debugMessage =
DateTime.Now.ToString("hh:mm:ss:fff:") +
" ProcessHacker (T" + System.Threading.Thread.CurrentThread.ManagedThreadId +
"): (" + importance.ToString() + ") " + message + "\r\n\r\n" + Environment.StackTrace;
Debugger.Log(0, "DEBUG", debugMessage);
OutputDebugString(debugMessage);
if (Logged != null)
Logged(debugMessage);
if (Logged != null)
Logged(debugMessage);
}
}
[Conditional("DEBUG")]
@@ -59,7 +68,7 @@ namespace ProcessHacker.Common
string message = ex.Message;
if (ex.InnerException != null)
message += "\r\nInner exception:\r\n" + ex.InnerException;
message += "\r\nInner exception:\r\n" + ex.InnerException.ToString();
if (ex.StackTrace != null)
message += "\r\n" + ex.StackTrace;
@@ -1,15 +1,23 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ProcessHacker.Common.Messaging
{
public class Message
{
public object Tag { get; set; }
private object _tag;
public object Tag
{
get { return _tag; }
set { _tag = value; }
}
}
public class ActionMessage : Message
{
private readonly Action _action;
private Action _action;
public ActionMessage(Action action)
{
@@ -1,17 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ProcessHacker.Common.Messaging
{
public class MessageQueue
{
private readonly Queue<Message> _queue = new Queue<Message>();
private readonly List<MessageQueueListener> _listeners = new List<MessageQueueListener>();
private Queue<Message> _queue = new Queue<Message>();
private List<MessageQueueListener> _listeners = new List<MessageQueueListener>();
public MessageQueue()
{
// Action message listener.
this.AddListener(new MessageQueueListener<ActionMessage>(action => action.Action()));
this.AddListener(new MessageQueueListener<ActionMessage>((action) => action.Action()));
}
public void AddListener(MessageQueueListener listener)
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ProcessHacker.Common.Messaging
{
@@ -6,8 +8,8 @@ namespace ProcessHacker.Common.Messaging
public class MessageQueueListener
{
private readonly MessageReceivedDelegate _callback;
private readonly Type _type;
private MessageReceivedDelegate _callback;
private Type _type;
public MessageQueueListener(MessageReceivedDelegate callback, Type type)
{
@@ -26,12 +28,13 @@ namespace ProcessHacker.Common.Messaging
}
}
public class MessageQueueListener<T> : MessageQueueListener where T : Message
public class MessageQueueListener<T> : MessageQueueListener
where T : Message
{
public delegate void MessageReceivedDelegate(T message);
public MessageQueueListener(MessageReceivedDelegate callback)
: base(message => callback((T)message), typeof(T))
: base((message) => callback((T)message), typeof(T))
{ }
}
}
@@ -21,7 +21,7 @@
*/
/* If enabled, the object system will keep statistics. */
//#define ENABLE_STATISTICS
#define ENABLE_STATISTICS
/* If enabled, the finalizers on objects can be enabled and disabled.
* If disabled, the finalizers on objects can only be disabled.
@@ -61,23 +61,23 @@ namespace ProcessHacker.Common.Objects
/// the object will be freed.
/// </para>
/// </remarks>
public abstract class BaseObject : IRefCounted
public abstract class BaseObject : IDisposable, IRefCounted
{
private const long ObjectOwned = 0x1;
private const long ObjectOwnedByGc = 0x2;
private const long ObjectDisposed = 0x4;
private const long ObjectRefCountShift = 3;
private const long ObjectRefCountMask = 0x1fffffff;
private const long ObjectRefCountIncrement = 0x8;
private const int ObjectOwned = 0x1;
private const int ObjectOwnedByGc = 0x2;
private const int ObjectDisposed = 0x4;
private const int ObjectRefCountShift = 3;
private const int ObjectRefCountMask = 0x1fffffff;
private const int ObjectRefCountIncrement = 0x8;
private static long _createdCount;
private static long _freedCount;
private static long _disposedCount;
private static long _finalizedCount;
private static long _referencedCount;
private static long _dereferencedCount;
private static int _createdCount = 0;
private static int _freedCount = 0;
private static int _disposedCount = 0;
private static int _finalizedCount = 0;
private static int _referencedCount = 0;
private static int _dereferencedCount = 0;
#if DEBUG_ENABLE_LIVE_LIST
#if DEBUG && DEBUG_ENABLE_LIVE_LIST
private static System.Collections.Generic.List<WeakReference<BaseObject>> _liveList =
new System.Collections.Generic.List<WeakReference<BaseObject>>();
#endif
@@ -85,29 +85,29 @@ namespace ProcessHacker.Common.Objects
/// <summary>
/// Gets the number of disposable, owned objects that have been created.
/// </summary>
public static long CreatedCount { get { return _createdCount; } }
public static int CreatedCount { get { return _createdCount; } }
/// <summary>
/// Gets the number of disposable objects that have been freed.
/// </summary>
public static long FreedCount { get { return _freedCount; } }
public static int FreedCount { get { return _freedCount; } }
/// <summary>
/// Gets the number of disposable objects that have been Disposed with managed = true.
/// </summary>
public static long DisposedCount { get { return _disposedCount; } }
public static int DisposedCount { get { return _disposedCount; } }
/// <summary>
/// Gets the number of disposable objects that have been Disposed with managed = false.
/// </summary>
public static long FinalizedCount { get { return _finalizedCount; } }
public static int FinalizedCount { get { return _finalizedCount; } }
/// <summary>
/// Gets the number of times disposable objects have been referenced.
/// </summary>
public static long ReferencedCount { get { return _referencedCount; } }
public static int ReferencedCount { get { return _referencedCount; } }
/// <summary>
/// Gets the number of times disposable objects have been dereferenced.
/// </summary>
public static long DereferencedCount { get { return _dereferencedCount; } }
public static int DereferencedCount { get { return _dereferencedCount; } }
#if DEBUG_ENABLE_LIVE_LIST
#if DEBUG && DEBUG_ENABLE_LIVE_LIST
public static void CleanLiveList()
{
var list = new System.Collections.Generic.List<WeakReference<BaseObject>>();
@@ -122,17 +122,16 @@ namespace ProcessHacker.Common.Objects
}
#endif
public static T SwapRef<T>(ref T reference, T newObj) where T : class, IRefCounted
public static T SwapRef<T>(ref T reference, T newObj)
where T : class, IRefCounted
{
T oldObj;
// Swap the reference.
oldObj = Interlocked.Exchange(ref reference, newObj);
oldObj = Interlocked.Exchange<T>(ref reference, newObj);
// Reference the new object.
if (newObj != null)
newObj.Reference();
// Dereference the old object.
if (oldObj != null)
oldObj.Dereference();
@@ -140,27 +139,27 @@ namespace ProcessHacker.Common.Objects
return oldObj;
}
#if DEBUG_ENABLE_LIVE_LIST
#if DEBUG
/// <summary>
/// A stack trace collected when the object is created.
/// </summary>
private string _creationStackTrace;
#endif
/// <summary>
/// An UInt32 containing various fields.
/// An Int32 containing various fields.
/// </summary>
private long _value;
private int _value;
#if EXTENDED_FINALIZER
/// <summary>
/// Whether the finalizer will run.
/// </summary>
private uint _finalizerRegistered = 1;
private int _finalizerRegistered = 1;
#endif
/// <summary>
/// Initializes a disposable object.
/// </summary>
protected BaseObject()
public BaseObject()
: this(true)
{ }
@@ -168,7 +167,7 @@ namespace ProcessHacker.Common.Objects
/// Initializes a disposable object.
/// </summary>
/// <param name="owned">Whether the resource is owned.</param>
protected BaseObject(bool owned)
public BaseObject(bool owned)
{
_value = ObjectOwned + ObjectOwnedByGc + ObjectRefCountIncrement;
@@ -188,9 +187,11 @@ namespace ProcessHacker.Common.Objects
Interlocked.Increment(ref _createdCount);
#endif
#if DEBUG_ENABLE_LIVE_LIST
#if DEBUG
_creationStackTrace = Environment.StackTrace;
#if DEBUG_ENABLE_LIVE_LIST
_liveList.Add(new WeakReference<BaseObject>(this));
#endif
#endif
}
@@ -223,8 +224,8 @@ namespace ProcessHacker.Common.Objects
/// </summary>
/// <param name="managed">Whether to dispose managed resources.</param>
public void Dispose(bool managed)
{
long value = 0;
{
int value;
if ((_value & ObjectOwned) == 0)
return;
@@ -315,9 +316,9 @@ namespace ProcessHacker.Common.Objects
/// This information is for debugging purposes ONLY. DO NOT
/// base memory management logic upon this value.
/// </remarks>
public long ReferenceCount
public int ReferenceCount
{
get { return (_value >> (int)ObjectRefCountShift) & ObjectRefCountMask; }
get { return (_value >> ObjectRefCountShift) & ObjectRefCountMask; }
}
#if EXTENDED_FINALIZER
@@ -326,7 +327,7 @@ namespace ProcessHacker.Common.Objects
/// </summary>
private void DisableFinalizer()
{
long oldFinalizerRegistered;
int oldFinalizerRegistered;
oldFinalizerRegistered = Interlocked.CompareExchange(ref _finalizerRegistered, 0, 1);
@@ -342,7 +343,7 @@ namespace ProcessHacker.Common.Objects
/// </summary>
protected void DisableOwnership(bool dispose)
{
long value = 0;
int value;
if (dispose)
this.Dispose();
@@ -383,7 +384,7 @@ namespace ProcessHacker.Common.Objects
/// Dereference(false).
/// </para>
/// </remarks>
public long Dereference()
public int Dereference()
{
return this.Dereference(true);
}
@@ -397,7 +398,7 @@ namespace ProcessHacker.Common.Objects
/// <para>If you are calling this method from a finalizer, set
/// <paramref name="managed" /> to false.</para>
/// </remarks>
public long Dereference(bool managed)
public int Dereference(bool managed)
{
return this.Dereference(1, managed);
}
@@ -407,7 +408,7 @@ namespace ProcessHacker.Common.Objects
/// </summary>
/// <param name="count">The number of times to dereference the object.</param>
/// <returns>The new reference count.</returns>
public long Dereference(long count)
public int Dereference(int count)
{
return this.Dereference(count, true);
}
@@ -418,10 +419,10 @@ namespace ProcessHacker.Common.Objects
/// <param name="count">The number of times to dereference the object.</param>
/// <param name="managed">Whether to dispose managed resources.</param>
/// <returns>The new reference count.</returns>
public long Dereference(long count, bool managed)
public int Dereference(int count, bool managed)
{
long value = 0;
long newRefCount = 0;
int value;
int newRefCount;
// Initial parameter validation.
if (count == 0)
@@ -439,7 +440,7 @@ namespace ProcessHacker.Common.Objects
// Decrease the reference count.
value = Interlocked.Add(ref _value, -ObjectRefCountIncrement * count);
newRefCount = (value >> (int)ObjectRefCountShift) & ObjectRefCountMask;
newRefCount = (value >> ObjectRefCountShift) & ObjectRefCountMask;
// Should not ever happen.
if (newRefCount < 0)
@@ -485,7 +486,7 @@ namespace ProcessHacker.Common.Objects
/// </summary>
private void EnableFinalizer()
{
long oldFinalizerRegistered;
int oldFinalizerRegistered;
oldFinalizerRegistered = Interlocked.CompareExchange(ref _finalizerRegistered, 1, 0);
@@ -506,7 +507,7 @@ namespace ProcessHacker.Common.Objects
/// object) to match each call to Reference. Do not call Dispose.
/// </para>
/// </remarks>
public long Reference()
public int Reference()
{
return this.Reference(1);
}
@@ -516,9 +517,9 @@ namespace ProcessHacker.Common.Objects
/// </summary>
/// <param name="count">The number of times to reference the object.</param>
/// <returns>The new reference count.</returns>
public long Reference(long count)
public int Reference(int count)
{
long value;
int value;
// Don't do anything if the object isn't owned.
if ((_value & ObjectOwned) == 0)
@@ -535,7 +536,7 @@ namespace ProcessHacker.Common.Objects
value = Interlocked.Add(ref _value, ObjectRefCountIncrement * count);
return (value >> (int)ObjectRefCountShift) & ObjectRefCountMask;
return (value >> ObjectRefCountShift) & ObjectRefCountMask;
}
}
}
@@ -56,8 +56,8 @@ namespace ProcessHacker.Common.Objects
/// </summary>
private struct DelayedReleaseObject
{
private readonly DelayedReleaseFlags _flags;
private readonly BaseObject _object;
private DelayedReleaseFlags _flags;
private BaseObject _object;
public DelayedReleaseObject(DelayedReleaseFlags flags, BaseObject obj)
{
@@ -86,7 +86,14 @@ namespace ProcessHacker.Common.Objects
/// </summary>
public static DelayedReleasePool CurrentPool
{
get { return _currentPool ?? (_currentPool = new DelayedReleasePool()); }
get
{
if (_currentPool == null)
_currentPool = new DelayedReleasePool();
return _currentPool;
}
private set { _currentPool = value; }
}
/// <summary>
@@ -97,7 +104,10 @@ namespace ProcessHacker.Common.Objects
get
{
// No locking needed because the stack is thread-local.
return _poolStack ?? (_poolStack = new Stack<DelayedReleasePool>());
if (_poolStack == null)
_poolStack = new Stack<DelayedReleasePool>();
return _poolStack;
}
}
@@ -107,9 +117,6 @@ namespace ProcessHacker.Common.Objects
/// <param name="pool">The current delayed release pool.</param>
private static void PopPool(DelayedReleasePool pool)
{
if (pool == null)
throw new ArgumentNullException("pool");
if (_currentPool != pool)
throw new OutOfOrderException(
"Attempted to pop a pool when it wasn't on top of the stack. " +
@@ -129,8 +136,8 @@ namespace ProcessHacker.Common.Objects
_currentPool = pool;
}
private readonly int _creatorThreadId;
private readonly List<DelayedReleaseObject> _objects = new List<DelayedReleaseObject>();
private int _creatorThreadId;
private List<DelayedReleaseObject> _objects = new List<DelayedReleaseObject>();
/// <summary>
/// Creates a delayed release pool and sets it as the currently active pool.
@@ -188,12 +195,11 @@ namespace ProcessHacker.Common.Objects
/// <param name="managed">Whether to release managed resources.</param>
public void Drain(bool managed)
{
foreach (DelayedReleaseObject obj in _objects)
foreach (var obj in _objects)
{
if (obj.Flags.HasFlag(DelayedReleaseFlags.Dispose))
if ((obj.Flags & DelayedReleaseFlags.Dispose) == DelayedReleaseFlags.Dispose)
obj.Object.Dispose();
if (obj.Flags.HasFlag(DelayedReleaseFlags.Dereference))
if ((obj.Flags & DelayedReleaseFlags.Dereference) == DelayedReleaseFlags.Dereference)
obj.Object.Dereference(managed);
}
@@ -27,8 +27,20 @@ namespace ProcessHacker.Common.Objects
{
public class HandleTableEntry
{
public int Handle { get; internal set; }
public IRefCounted Object { get; internal set; }
private int _handle;
private IRefCounted _object;
public int Handle
{
get { return _handle; }
internal set { _handle = value; }
}
public IRefCounted Object
{
get { return _object; }
internal set { _object = value; }
}
}
/// <summary>
@@ -52,9 +64,9 @@ namespace ProcessHacker.Common.Objects
/// <returns>Return true to stop enumerating; otherwise return false.</returns>
public delegate bool EnumerateHandleTableDelegate(int handle, TEntry entry);
private readonly IdGenerator _handleGenerator = new IdGenerator(4, 4);
private readonly FastResourceLock _lock = new FastResourceLock();
private readonly Dictionary<int, TEntry> _handles = new Dictionary<int, TEntry>();
private IdGenerator _handleGenerator = new IdGenerator(4, 4);
private FastResourceLock _lock = new FastResourceLock();
private Dictionary<int, TEntry> _handles = new Dictionary<int, TEntry>();
protected override void DisposeObject(bool disposing)
{
@@ -306,7 +318,8 @@ namespace ProcessHacker.Common.Objects
/// An object. This object has been referenced and must be
/// dereferenced once it is no longer needed.
/// </returns>
public T ReferenceByHandle<T>(int handle, out TEntry entry) where T : class, IRefCounted
public T ReferenceByHandle<T>(int handle, out TEntry entry)
where T : class, IRefCounted
{
IRefCounted obj = this.ReferenceByHandle(handle, out entry);
@@ -318,10 +331,12 @@ namespace ProcessHacker.Common.Objects
{
return (T)obj;
}
// Wrong type. Dereference and return.
obj.Dereference();
return null;
else
{
// Wrong type. Dereference and return.
obj.Dereference();
return null;
}
}
}
}
@@ -8,21 +8,21 @@ namespace ProcessHacker.Common.Objects
/// Decrements the reference count of the object.
/// </summary>
/// <returns>The new reference count.</returns>
long Dereference();
int Dereference();
/// <summary>
/// Decrements the reference count of the object.
/// </summary>
/// <param name="managed">Whether to dispose managed resources.</param>
/// <returns>The new reference count.</returns>
long Dereference(bool managed);
int Dereference(bool managed);
/// <summary>
/// Decreases the reference count of the object.
/// </summary>
/// <param name="count">The number of times to dereference the object.</param>
/// <returns>The new reference count.</returns>
long Dereference(long count);
int Dereference(int count);
/// <summary>
/// Decreases the reference count of the object.
@@ -30,7 +30,7 @@ namespace ProcessHacker.Common.Objects
/// <param name="count">The number of times to dereference the object.</param>
/// <param name="managed">Whether to dispose managed resources.</param>
/// <returns>The new reference count.</returns>
long Dereference(long count, bool managed);
int Dereference(int count, bool managed);
/// <summary>
/// Ensures that the reference counting system has exclusive control
@@ -43,13 +43,13 @@ namespace ProcessHacker.Common.Objects
/// Increments the reference count of the object.
/// </summary>
/// <returns>The new reference count.</returns>
long Reference();
int Reference();
/// <summary>
/// Increases the reference count of the object.
/// </summary>
/// <param name="count">The number of times to reference the object.</param>
/// <returns>The new reference count.</returns>
long Reference(long count);
int Reference(int count);
}
}
@@ -27,30 +27,33 @@ namespace ProcessHacker.Common.Objects
public class SecuredHandleTableEntry : HandleTableEntry
{
private long _grantedAccess;
public long GrantedAccess
{
get { return _grantedAccess; }
set { _grantedAccess = value; }
}
public bool AreAllAccessesGranted<TAccess>(TAccess access) where TAccess : struct
public bool AreAllAccessesGranted<TAccess>(TAccess access)
where TAccess : struct
{
long accessLong = Convert.ToInt64(access);
if ((_grantedAccess & accessLong) == accessLong)
return true;
return false;
else
return false;
}
public bool AreAnyAccessesGranted<TAccess>(TAccess access) where TAccess : struct
public bool AreAnyAccessesGranted<TAccess>(TAccess access)
where TAccess : struct
{
long accessLong = Convert.ToInt64(access);
if ((_grantedAccess & accessLong) != 0)
return true;
return false;
else
return false;
}
}
@@ -74,12 +77,12 @@ namespace ProcessHacker.Common.Objects
/// <param name="obj">The object to reference.</param>
/// <param name="grantedAccess">The granted access to the object.</param>
/// <returns>The new handle.</returns>
public int Allocate<TAccess>(IRefCounted obj, TAccess grantedAccess) where TAccess : struct
public int Allocate<TAccess>(IRefCounted obj, TAccess grantedAccess)
where TAccess : struct
{
TEntry entry = new TEntry
{
GrantedAccess = Convert.ToInt64(grantedAccess)
};
TEntry entry = new TEntry();
entry.GrantedAccess = Convert.ToInt64(grantedAccess);
return base.Allocate(obj, entry);
}
@@ -94,9 +97,10 @@ namespace ProcessHacker.Common.Objects
/// An object. This object has been referenced and must be
/// dereferenced once it is no longer needed.
/// </returns>
public IRefCounted ReferenceByHandle<TAccess>(int handle, TAccess access) where TAccess : struct
public IRefCounted ReferenceByHandle<TAccess>(int handle, TAccess access)
where TAccess : struct
{
return this.ReferenceByHandle(handle, access, false);
return this.ReferenceByHandle<TAccess>(handle, access, false);
}
/// <summary>
@@ -112,30 +116,34 @@ namespace ProcessHacker.Common.Objects
/// An object. This object has been referenced and must be
/// dereferenced once it is no longer needed.
/// </returns>
public IRefCounted ReferenceByHandle<TAccess>(int handle, TAccess access, bool throwOnAccessDenied) where TAccess : struct
public IRefCounted ReferenceByHandle<TAccess>(int handle, TAccess access, bool throwOnAccessDenied)
where TAccess : struct
{
TEntry entry;
IRefCounted obj;
// Reference the object.
IRefCounted obj = this.ReferenceByHandle(handle, out entry);
obj = this.ReferenceByHandle(handle, out entry);
if (obj == null)
return null;
// Check the access.
if (entry.AreAllAccessesGranted(access))
if (entry.AreAllAccessesGranted<TAccess>(access))
{
// OK, return the object.
return obj;
}
// Access denied. Dereference the object and return.
obj.Dereference();
else
{
// Access denied. Dereference the object and return.
obj.Dereference();
if (throwOnAccessDenied)
throw new UnauthorizedAccessException("Access denied.");
return null;
if (throwOnAccessDenied)
throw new UnauthorizedAccessException("Access denied.");
else
return null;
}
}
/// <summary>
@@ -149,7 +157,9 @@ namespace ProcessHacker.Common.Objects
/// An object. This object has been referenced and must be
/// dereferenced once it is no longer needed.
/// </returns>
public T ReferenceByHandle<T, TAccess>(int handle, TAccess access) where T : class, IRefCounted where TAccess : struct
public T ReferenceByHandle<T, TAccess>(int handle, TAccess access)
where T : class, IRefCounted
where TAccess : struct
{
return this.ReferenceByHandle<T, TAccess>(handle, access, false);
}
@@ -168,9 +178,11 @@ namespace ProcessHacker.Common.Objects
/// An object. This object has been referenced and must be
/// dereferenced once it is no longer needed.
/// </returns>
public T ReferenceByHandle<T, TAccess>(int handle, TAccess access, bool throwOnAccessDenied) where T : class, IRefCounted where TAccess : struct
public T ReferenceByHandle<T, TAccess>(int handle, TAccess access, bool throwOnAccessDenied)
where T : class, IRefCounted
where TAccess : struct
{
IRefCounted obj = this.ReferenceByHandle(handle, access, throwOnAccessDenied);
IRefCounted obj = this.ReferenceByHandle<TAccess>(handle, access, throwOnAccessDenied);
if (obj == null)
return null;
@@ -178,12 +190,13 @@ namespace ProcessHacker.Common.Objects
// Check the type.
if (obj is T)
{
return obj as T;
return (T)obj;
}
else
{
obj.Dereference();
return null;
}
obj.Dereference();
return null;
}
}
}
@@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ProcessHacker.Common</RootNamespace>
<AssemblyName>ProcessHacker.Common</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<FileUpgradeFlags>
</FileUpgradeFlags>
@@ -48,7 +48,6 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -62,7 +61,6 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -117,6 +115,7 @@
<Compile Include="Ui\SortedListViewComparer.cs" />
<Compile Include="Utils.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WeakReference.cs" />
<Compile Include="WorkQueue.cs" />
</ItemGroup>
<ItemGroup>
@@ -1,4 +1,5 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
@@ -30,7 +30,7 @@ namespace ProcessHacker.Common.Settings
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class SettingDefaultAttribute : Attribute
{
private readonly string _value;
private string _value;
/// <summary>
/// Initializes a new instance of the SettingDefaultAttribute class.
@@ -32,17 +32,17 @@ namespace ProcessHacker.Common.Settings
/// </summary>
public abstract class SettingsBase
{
private readonly ISettingsStore _store;
private readonly Dictionary<string, object> _settings = new Dictionary<string, object>();
private readonly Dictionary<string, object> _modifiedSettings = new Dictionary<string, object>();
private readonly Dictionary<string, string> _defaultsCache = new Dictionary<string, string>();
private readonly Dictionary<string, Type> _typeCache = new Dictionary<string, Type>();
private ISettingsStore _store;
private Dictionary<string, object> _settings = new Dictionary<string, object>();
private Dictionary<string, object> _modifiedSettings = new Dictionary<string, object>();
private Dictionary<string, string> _defaultsCache = new Dictionary<string, string>();
private Dictionary<string, Type> _typeCache = new Dictionary<string, Type>();
/// <summary>
/// Creates a settings class with the specified storage provider.
/// </summary>
/// <param name="store">The storage provider.</param>
protected SettingsBase(ISettingsStore store)
public SettingsBase(ISettingsStore store)
{
_store = store;
}
@@ -76,15 +76,14 @@ namespace ProcessHacker.Common.Settings
{
if (valueType.IsPrimitive)
return Convert.ChangeType(value, valueType);
if (valueType == typeof(string))
else if (valueType == typeof(string))
return value;
TypeConverter converter = TypeDescriptor.GetConverter(valueType);
var converter = TypeDescriptor.GetConverter(valueType);
// Since all types can convert to System.String, we also need to make sure they can
// convert from System.String.
if (converter != null && (converter.CanConvertFrom(typeof(string)) && converter.CanConvertTo(typeof(string))))
if (converter.CanConvertFrom(typeof(string)) && converter.CanConvertTo(typeof(string)))
return converter.ConvertFromInvariantString(value);
throw new InvalidOperationException("The setting '" + value + "' has an unsupported type.");
@@ -100,15 +99,14 @@ namespace ProcessHacker.Common.Settings
{
if (valueType.IsPrimitive)
return (string)Convert.ChangeType(value, typeof(string));
if (valueType == typeof(string))
else if (valueType == typeof(string))
return (string)value;
TypeConverter converter = TypeDescriptor.GetConverter(valueType);
var converter = TypeDescriptor.GetConverter(valueType);
// Since all types can convert to System.String, we also need to make sure they can
// convert from System.String.
if (converter != null && (converter.CanConvertFrom(typeof(string)) && converter.CanConvertTo(typeof(string))))
if (converter.CanConvertFrom(typeof(string)) && converter.CanConvertTo(typeof(string)))
return converter.ConvertToInvariantString(value);
throw new InvalidOperationException("The setting '" + value + "' has an unsupported type.");
@@ -125,15 +123,12 @@ namespace ProcessHacker.Common.Settings
{
if (!_defaultsCache.ContainsKey(name))
{
PropertyInfo property = this.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Public);
object[] attributes = property.GetCustomAttributes(typeof(SettingDefaultAttribute), true);
var property = this.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Public);
var attributes = property.GetCustomAttributes(typeof(SettingDefaultAttribute), true);
if (attributes.Length == 1)
{
SettingDefaultAttribute settingDefaultAttribute = attributes[0] as SettingDefaultAttribute;
if (settingDefaultAttribute != null)
this._defaultsCache.Add(name, settingDefaultAttribute.Value);
_defaultsCache.Add(name, (attributes[0] as SettingDefaultAttribute).Value);
}
else
{
@@ -173,6 +168,8 @@ namespace ProcessHacker.Common.Settings
private object GetValue(string name)
{
object value;
string settingValue;
Type settingType;
lock (_modifiedSettings)
{
@@ -186,14 +183,14 @@ namespace ProcessHacker.Common.Settings
return _settings[name];
}
string settingValue = this._store.GetValue(name);
settingValue = _store.GetValue(name);
if (string.IsNullOrEmpty(settingValue))
if (settingValue == null)
settingValue = this.GetSettingDefault(name);
if (string.IsNullOrEmpty(settingValue))
settingValue = string.Empty;
if (settingValue == null)
settingValue = "";
Type settingType = this.GetSettingType(name);
settingType = this.GetSettingType(name);
try
{
@@ -253,7 +250,7 @@ namespace ProcessHacker.Common.Settings
{
lock (_modifiedSettings)
{
foreach (KeyValuePair<string, object> pair in _modifiedSettings)
foreach (var pair in _modifiedSettings)
{
_store.SetValue(pair.Key, this.ConvertToString(pair.Value, this.GetSettingType(pair.Key)));
}
@@ -1,4 +1,8 @@
namespace ProcessHacker.Common.Settings
using System;
using System.Collections.Generic;
using System.Text;
namespace ProcessHacker.Common.Settings
{
public sealed class VolatileSettingsStore : ISettingsStore
{
@@ -20,7 +20,10 @@
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
namespace ProcessHacker.Common.Settings
@@ -34,8 +37,8 @@ namespace ProcessHacker.Common.Settings
private const string _settingElementName = "setting";
private const string _nameAttributeName = "name";
private readonly string _fileName;
private readonly object _docLock = new object();
private string _fileName;
private object _docLock = new object();
private XmlDocument _doc;
private XmlNode _rootNode;
@@ -80,10 +83,7 @@ namespace ProcessHacker.Common.Settings
{
lock (_docLock)
{
XmlNodeList nodes = _rootNode.SelectNodes(_settingElementName + "[@" + _nameAttributeName + "='" + name + "']");
if (nodes == null)
return null;
var nodes = _rootNode.SelectNodes(_settingElementName + "[@" + _nameAttributeName + "='" + name + "']");
if (nodes.Count == 0)
return null;
@@ -146,16 +146,16 @@ namespace ProcessHacker.Common.Settings
{
lock (_docLock)
{
XmlNodeList nodes = _rootNode.SelectNodes(_settingElementName + "[@" + _nameAttributeName + "='" + name + "']");
var nodes = _rootNode.SelectNodes(_settingElementName + "[@" + _nameAttributeName + "='" + name + "']");
if (nodes != null && nodes.Count != 0)
if (nodes.Count != 0)
{
nodes[0].InnerText = value;
}
else
{
XmlElement settingElement = _doc.CreateElement(_settingElementName);
XmlAttribute nameAttribute = _doc.CreateAttribute(_nameAttributeName);
var settingElement = _doc.CreateElement(_settingElementName);
var nameAttribute = _doc.CreateAttribute(_nameAttributeName);
nameAttribute.Value = name;
settingElement.Attributes.Append(nameAttribute);
+19 -10
View File
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ProcessHacker.Common
{
@@ -108,8 +110,8 @@ namespace ProcessHacker.Common
fixed (char* buffer = this.Buffer)
{
foreach (char t in str)
buffer[this.Length++] = t;
for (int i = 0; i < str.Length; i++)
buffer[this.Length++] = str[i];
buffer[this.Length] = '\0';
}
@@ -119,11 +121,14 @@ namespace ProcessHacker.Common
{
fixed (char* buffer = this.Buffer)
{
int result = LibC.WMemCmp(buffer, str.Buffer, this.Length < str.Length ? this.Length : str.Length);
int result;
result = LibC.WMemCmp(buffer, str.Buffer, this.Length < str.Length ? this.Length : str.Length);
if (result == 0)
return this.Length - str.Length;
return result;
else
return result;
}
}
@@ -140,9 +145,10 @@ namespace ProcessHacker.Common
{
if (other is String255)
return this.Equals((String255)other);
if (other is string)
else if (other is string)
return this.Equals((string)other);
return false;
else
return false;
}
public bool Equals(String255 other)
@@ -189,8 +195,8 @@ namespace ProcessHacker.Common
if (ptr != null)
return (int)(ptr - buffer);
return -1;
else
return -1;
}
}
@@ -198,9 +204,12 @@ namespace ProcessHacker.Common
{
int hashCode = 0x15051505;
for (int i = 0; i < this.Length; i += 4)
fixed (char* buffer = this.Buffer)
{
hashCode += hashCode ^ (hashCode << ((i % 4) * 8));
for (int i = 0; i < this.Length; i += 4)
{
hashCode += hashCode ^ (hashCode << ((i % 4) * 8));
}
}
return hashCode;
@@ -21,6 +21,8 @@
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ProcessHacker.Common.Threading
@@ -32,8 +34,8 @@ namespace ProcessHacker.Common.Threading
public struct ActionSync
{
private int _value;
private readonly int _target;
private readonly Action _action;
private int _target;
private Action _action;
/// <summary>
/// Initializes an action-sync structure.
@@ -21,11 +21,8 @@
*/
#define DEFER_EVENT_CREATION
#if DEBUG
#define ENABLE_STATISTICS
#define RIGOROUS_CHECKS
#endif
//#define ENABLE_STATISTICS
//#define RIGOROUS_CHECKS
using System;
using System.Runtime.InteropServices;
@@ -124,18 +121,13 @@ namespace ProcessHacker.Common.Threading
public int PeakShrdWtrsCount;
}
private struct WaitBlock
private unsafe struct WaitBlock
{
public static readonly int SizeOf;
public static readonly int Size = Marshal.SizeOf(typeof(WaitBlock));
public WaitBlock* Flink;
public WaitBlock* Blink;
public int Flags;
static WaitBlock()
{
SizeOf = Marshal.SizeOf(typeof(WaitBlock));
}
}
private enum ListPosition
@@ -214,20 +206,20 @@ namespace ProcessHacker.Common.Threading
private WaitBlock* _firstSharedWaiter;
#if ENABLE_STATISTICS
private int _exclusiveWaitersCount;
private int _sharedWaitersCount;
private int _exclusiveWaitersCount = 0;
private int _sharedWaitersCount = 0;
private int _acqExclCount;
private int _acqShrdCount;
private int _acqExclContCount;
private int _acqShrdContCount;
private int _acqExclBlkCount;
private int _acqShrdBlkCount;
private int _acqExclSlpCount;
private int _acqShrdSlpCount;
private int _insWaitBlkRetryCount;
private int _peakExclWtrsCount;
private int _peakShrdWtrsCount;
private int _acqExclCount = 0;
private int _acqShrdCount = 0;
private int _acqExclContCount = 0;
private int _acqShrdContCount = 0;
private int _acqExclBlkCount = 0;
private int _acqShrdBlkCount = 0;
private int _acqExclSlpCount = 0;
private int _acqShrdSlpCount = 0;
private int _insWaitBlkRetryCount = 0;
private int _peakExclWtrsCount = 0;
private int _peakShrdWtrsCount = 0;
#endif
/// <summary>
@@ -249,7 +241,7 @@ namespace ProcessHacker.Common.Threading
_lock = new SpinLock();
_spinCount = Environment.ProcessorCount != 1 ? spinCount : 0;
_waitersListHead = (WaitBlock*)Marshal.AllocHGlobal(WaitBlock.SizeOf);
_waitersListHead = (WaitBlock*)Marshal.AllocHGlobal(WaitBlock.Size);
_waitersListHead->Flink = _waitersListHead;
_waitersListHead->Blink = _waitersListHead;
_waitersListHead->Flags = 0;
@@ -726,7 +718,7 @@ namespace ProcessHacker.Common.Threading
public Statistics GetStatistics()
{
#if ENABLE_STATISTICS
return new Statistics
return new Statistics()
{
AcqExcl = _acqExclCount,
AcqShrd = _acqShrdCount,
@@ -1134,7 +1126,7 @@ namespace ProcessHacker.Common.Threading
private void WakeShared()
{
WaitBlock wakeList = new WaitBlock();
WaitBlock* wb;
WaitBlock* wb = null;
wakeList.Flink = &wakeList;
wakeList.Blink = &wakeList;
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ProcessHacker.Common.Threading
@@ -41,10 +43,13 @@ namespace ProcessHacker.Common.Threading
}
// Slow path 2 - wait on the event.
IntPtr newEvent;
// Note: see FastEvent.cs for a more detailed explanation of this
// technique.
IntPtr newEvent = Interlocked.CompareExchange(ref this._event, IntPtr.Zero, IntPtr.Zero);
newEvent = Interlocked.CompareExchange(ref _event, IntPtr.Zero, IntPtr.Zero);
if (newEvent == IntPtr.Zero)
{
@@ -16,7 +16,7 @@ namespace ProcessHacker.Common.Threading
public struct FastMutexContext : IDisposable
{
private bool _disposed;
private readonly FastMutex _fastMutex;
private FastMutex _fastMutex;
internal FastMutexContext(FastMutex fastMutex)
{
@@ -37,7 +37,7 @@ namespace ProcessHacker.Common.Threading
}
}
private readonly object _lock = new object();
private object _lock = new object();
/// <summary>
/// Acquires the mutex and prevents others from acquiring it.
@@ -21,11 +21,8 @@
*/
#define DEFER_EVENT_CREATION
#if DEBUG
#define ENABLE_STATISTICS
#define RIGOROUS_CHECKS
#endif
//#define ENABLE_STATISTICS
//#define RIGOROUS_CHECKS
using System;
using System.Threading;
@@ -201,24 +198,21 @@ namespace ProcessHacker.Common.Threading
private IntPtr _exclusiveWakeEvent;
#if ENABLE_STATISTICS
private int _acqExclCount;
private int _acqShrdCount;
private int _acqExclContCount;
private int _acqShrdContCount;
private int _acqExclSlpCount;
private int _acqShrdSlpCount;
private int _peakExclWtrsCount;
private int _peakShrdWtrsCount;
private int _acqExclCount = 0;
private int _acqShrdCount = 0;
private int _acqExclContCount = 0;
private int _acqShrdContCount = 0;
private int _acqExclSlpCount = 0;
private int _acqShrdSlpCount = 0;
private int _peakExclWtrsCount = 0;
private int _peakShrdWtrsCount = 0;
#endif
/// <summary>
/// Creates a FastResourceLock.
/// </summary>
public FastResourceLock()
{
#if ENABLE_STATISTICS
this._acqExclContCount = 0;
#endif
{
_value = 0;
#if !DEFER_EVENT_CREATION
@@ -353,8 +347,8 @@ namespace ProcessHacker.Common.Threading
Interlocked2.Set(
ref _peakExclWtrsCount,
p => p < exclWtrsCount,
p => exclWtrsCount
(p) => p < exclWtrsCount,
(p) => exclWtrsCount
);
#endif
@@ -463,8 +457,8 @@ namespace ProcessHacker.Common.Threading
Interlocked2.Set(
ref _peakShrdWtrsCount,
p => p < shrdWtrsCount,
p => shrdWtrsCount
(p) => p < shrdWtrsCount,
(p) => shrdWtrsCount
);
#endif
@@ -534,10 +528,12 @@ namespace ProcessHacker.Common.Threading
/// <param name="handle">A reference to the event handle.</param>
private void EnsureEventCreated(ref IntPtr handle)
{
IntPtr eventHandle;
if (Thread.VolatileRead(ref handle) != IntPtr.Zero)
return;
IntPtr eventHandle = NativeMethods.CreateSemaphore(IntPtr.Zero, 0, int.MaxValue, null);
eventHandle = NativeMethods.CreateSemaphore(IntPtr.Zero, 0, int.MaxValue, null);
if (Interlocked.CompareExchange(ref handle, eventHandle, IntPtr.Zero) != IntPtr.Zero)
NativeMethods.CloseHandle(eventHandle);
@@ -551,7 +547,7 @@ namespace ProcessHacker.Common.Threading
public Statistics GetStatistics()
{
#if ENABLE_STATISTICS
return new Statistics
return new Statistics()
{
AcqExcl = _acqExclCount,
AcqShrd = _acqShrdCount,
@@ -601,7 +597,9 @@ namespace ProcessHacker.Common.Threading
// Case 2: if we have shared waiters, release all of them.
else
{
int sharedWaiters = (value >> LockSharedWaitersShift) & LockSharedWaitersMask;
int sharedWaiters;
sharedWaiters = (value >> LockSharedWaitersShift) & LockSharedWaitersMask;
if (Interlocked.CompareExchange(
ref _value,
@@ -824,17 +822,18 @@ namespace ProcessHacker.Common.Threading
value
) == value;
}
if (((value >> LockSharedOwnersShift) & LockSharedOwnersMask) != 0)
else if (((value >> LockSharedOwnersShift) & LockSharedOwnersMask) != 0)
{
return Interlocked.CompareExchange(
ref this._value,
ref _value,
value + LockSharedOwnersIncrement,
value
) == value;
}
return false;
else
{
return false;
}
}
/// <summary>
@@ -13,13 +13,8 @@ namespace ProcessHacker.Common.Threading
public FastStackNode<U> Next;
}
private readonly int _count;
private FastStackNode<T> _bottom;
public FastStack(int count)
{
_count = count;
}
private int _count = 0;
private FastStackNode<T> _bottom = null;
public int Count
{
@@ -53,7 +48,7 @@ namespace ProcessHacker.Common.Threading
throw new InvalidOperationException("The stack is empty.");
// Try to replace the pointer.
if (Interlocked.CompareExchange(
if (Interlocked.CompareExchange<FastStackNode<T>>(
ref _bottom,
bottom.Next,
bottom
@@ -68,11 +63,10 @@ namespace ProcessHacker.Common.Threading
public void Push(T value)
{
FastStackNode<T> bottom;
FastStackNode<T> entry;
FastStackNode<T> entry = new FastStackNode<T>
{
Value = value
};
entry = new FastStackNode<T>();
entry.Value = value;
// Atomically replace the bottom of the stack.
while (true)
@@ -81,7 +75,7 @@ namespace ProcessHacker.Common.Threading
entry.Next = bottom;
// Try to replace the pointer.
if (Interlocked.CompareExchange(
if (Interlocked.CompareExchange<FastStackNode<T>>(
ref _bottom,
entry,
bottom
@@ -1,4 +1,8 @@
namespace ProcessHacker.Common.Threading
using System;
using System.Collections.Generic;
using System.Text;
namespace ProcessHacker.Common.Threading
{
public interface IResourceLock
{
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ProcessHacker.Common.Threading
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
namespace ProcessHacker.Common.Threading
{
@@ -20,6 +20,7 @@
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Threading;
namespace ProcessHacker.Common.Threading
@@ -129,7 +130,9 @@ namespace ProcessHacker.Common.Threading
// Has the rundown already started?
if ((value & RundownActive) != 0)
{
int newValue = Interlocked.Add(ref this._value, -RundownCountIncrement);
int newValue;
newValue = Interlocked.Add(ref _value, -RundownCountIncrement);
// Are we the last out? Set the event if that's the case.
if (newValue == RundownActive)
@@ -139,13 +142,15 @@ namespace ProcessHacker.Common.Threading
return;
}
if (Interlocked.CompareExchange(
ref this._value,
value - RundownCountIncrement,
value
) == value)
return;
else
{
if (Interlocked.CompareExchange(
ref _value,
value - RundownCountIncrement,
value
) == value)
return;
}
}
}
@@ -164,7 +169,9 @@ namespace ProcessHacker.Common.Threading
// Has the rundown already started?
if ((value & RundownActive) != 0)
{
int newValue = Interlocked.Add(ref this._value, -RundownCountIncrement * count);
int newValue;
newValue = Interlocked.Add(ref _value, -RundownCountIncrement * count);
// Are we the last out? Set the event if that's the case.
if (newValue == RundownActive)
@@ -174,13 +181,15 @@ namespace ProcessHacker.Common.Threading
return;
}
if (Interlocked.CompareExchange(
ref this._value,
value - RundownCountIncrement * count,
value
) == value)
return;
else
{
if (Interlocked.CompareExchange(
ref _value,
value - RundownCountIncrement * count,
value
) == value)
return;
}
}
}
@@ -201,10 +210,12 @@ namespace ProcessHacker.Common.Threading
/// <returns>Whether all references were released.</returns>
public bool Wait(int millisecondsTimeout)
{
int value;
// Fast path. Just in case there are no users, we can go ahead
// and set the active flag and exit. Or if someone has already
// initiated the rundown, exit as well.
int value = Interlocked.CompareExchange(ref this._value, RundownActive, 0);
value = Interlocked.CompareExchange(ref _value, RundownActive, 0);
if (value == 0 || value == RundownActive)
return true;
@@ -222,8 +233,8 @@ namespace ProcessHacker.Common.Threading
// Wait for the event, but only if we had users.
if ((value & ~RundownActive) != 0)
return _wakeEvent.Wait(millisecondsTimeout);
return true;
else
return true;
}
}
}
@@ -5,9 +5,9 @@ namespace ProcessHacker.Common.Threading
{
public class SemaphorePair : IDisposable
{
private readonly int _count;
private readonly Semaphore _readSemaphore;
private readonly Semaphore _writeSemaphore;
private int _count;
private Semaphore _readSemaphore;
private Semaphore _writeSemaphore;
public SemaphorePair(int count)
{
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ProcessHacker.Common.Threading
@@ -11,11 +13,11 @@ namespace ProcessHacker.Common.Threading
public event ThreadTaskCompletedDelegate Completed;
public event ThreadTaskRunTaskDelegate RunTask;
private Thread _thread;
private Thread _thread = null;
private object _result;
private Exception _exception;
private bool _cancelled;
private bool _running;
private bool _cancelled = false;
private bool _running = false;
public bool Cancelled
{
@@ -55,10 +57,8 @@ namespace ProcessHacker.Common.Threading
_cancelled = false;
_running = true;
_thread = new Thread(this.ThreadStart)
{
IsBackground = true
};
_thread = new Thread(this.ThreadStart);
_thread.IsBackground = true;
_thread.Start(param);
}
@@ -1,12 +1,15 @@
using System.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ProcessHacker.Common.Threading
{
public class WaitableQueue<T> : IEnumerable<T>
public class WaitableQueue<T> : IEnumerable, IEnumerable<T>
{
private readonly Queue<T> _queue = new Queue<T>();
private readonly SemaphorePair _pair;
private Queue<T> _queue = new Queue<T>();
private SemaphorePair _pair;
public WaitableQueue()
: this(int.MaxValue)
@@ -47,8 +50,10 @@ namespace ProcessHacker.Common.Threading
public bool Dequeue(int timeout, out T item)
{
bool waitResult = true;
// Wait for an item to dequeue.
bool waitResult = _pair.WaitRead(timeout);
waitResult = _pair.WaitRead(timeout);
// Dequeue an item if we waited successfully,
// otherwise pass the default value back.
+17 -26
View File
@@ -5,8 +5,8 @@ namespace ProcessHacker.Common
{
public class Tokenizer
{
private readonly string _text;
private int _i;
private string _text;
private int _i = 0;
public Tokenizer(string text)
{
@@ -90,7 +90,7 @@ namespace ProcessHacker.Common
_i++;
}
else
return string.Empty;
return "";
while (_i < _text.Length)
{
@@ -102,29 +102,20 @@ namespace ProcessHacker.Common
}
else if (inEscape)
{
switch (this._text[this._i])
{
case '\\':
sb.Append('\\');
break;
case '"':
sb.Append('"');
break;
case '\'':
sb.Append('\'');
break;
case 'r':
sb.Append('\r');
break;
case 'n':
sb.Append('\n');
break;
case 't':
sb.Append('\t');
break;
default:
throw new Exception("Unrecognized escape sequence '\\" + this._text[this._i] + "'");
}
if (_text[_i] == '\\')
sb.Append('\\');
else if (_text[_i] == '"')
sb.Append('"');
else if (_text[_i] == '\'')
sb.Append('\'');
else if (_text[_i] == 'r')
sb.Append('\r');
else if (_text[_i] == 'n')
sb.Append('\n');
else if (_text[_i] == 't')
sb.Append('\t');
else
throw new Exception("Unrecognized escape sequence '\\" + _text[_i] + "'");
_i++;
inEscape = false;
@@ -10,7 +10,7 @@ namespace ProcessHacker.Common.Ui
public static class ColumnHeaderExtensions
{
[StructLayout(LayoutKind.Sequential)]
public struct LVCOLUMN
private struct LVCOLUMN
{
public Int32 mask;
public Int32 cx;
@@ -45,13 +45,11 @@ namespace ProcessHacker.Common.Ui
for (int i = 0; i <= listView.Columns.Count - 1; i++)
{
IntPtr ColumnPtr = new IntPtr(i);
LVCOLUMN lvColumn = new LVCOLUMN
{
mask = HDI_FORMAT
};
LVCOLUMN lvColumn = new LVCOLUMN();
lvColumn.mask = HDI_FORMAT;
SendMessage(columnHeader, HDM_GETITEM, ColumnPtr, ref lvColumn);
if (order != SortOrder.None && i == column.Index)
if (!(order == SortOrder.None) && i == column.Index)
{
switch (order)
{
@@ -43,19 +43,26 @@ namespace ProcessHacker.Common.Ui
{
private class DefaultComparer : ISortedListViewComparer
{
private SortedListViewComparer _sortedListComparer;
public DefaultComparer(SortedListViewComparer sortedListComparer)
{
_sortedListComparer = sortedListComparer;
}
public int Compare(ListViewItem x, ListViewItem y, int column)
{
string sx, sy;
long ix, iy;
IComparable cx, cy;
sx = x.SubItems[column].Text.Replace(",", string.Empty);
sy = y.SubItems[column].Text.Replace(",", string.Empty);
sx = x.SubItems[column].Text.Replace(",", "");
sy = y.SubItems[column].Text.Replace(",", "");
if (!long.TryParse(sx.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? sx.Substring(2) : sx,
if (!long.TryParse(sx.StartsWith("0x") ? sx.Substring(2) : sx,
sx.StartsWith("0x") ? NumberStyles.AllowHexSpecifier : 0,
null, out ix) ||
!long.TryParse(sy.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? sy.Substring(2) : sy,
!long.TryParse(sy.StartsWith("0x") ? sy.Substring(2) : sy,
sy.StartsWith("0x") ? NumberStyles.AllowHexSpecifier : 0,
null, out iy))
{
@@ -72,17 +79,17 @@ namespace ProcessHacker.Common.Ui
}
}
private readonly ListView _list;
private bool _virtualMode;
private ListView _list;
private bool _virtualMode = false;
private RetrieveVirtualItemEventHandler _retrieveVirtualItem;
private bool _triState;
private bool _triState = false;
private ISortedListViewComparer _comparer;
private ISortedListViewComparer _triStateComparer;
private int _sortColumn;
private SortOrder _sortOrder;
private readonly Dictionary<int, Comparison<ListViewItem>> _customSorters =
private Dictionary<int, Comparison<ListViewItem>> _customSorters =
new Dictionary<int, Comparison<ListViewItem>>();
private readonly List<int> _columnSortOrder = new List<int>();
private List<int> _columnSortOrder = new List<int>();
/// <summary>
/// Creates a new sorted list manager.
@@ -91,10 +98,10 @@ namespace ProcessHacker.Common.Ui
public SortedListViewComparer(ListView list)
{
_list = list;
_list.ColumnClick += this.list_ColumnClick;
_list.ColumnClick += new ColumnClickEventHandler(list_ColumnClick);
_sortColumn = 0;
_sortOrder = SortOrder.Ascending;
_comparer = new DefaultComparer();
_comparer = new DefaultComparer(this);
this.SetSortIcon();
}
@@ -135,7 +142,7 @@ namespace ProcessHacker.Common.Ui
set
{
if (value == null)
_comparer = new DefaultComparer();
_comparer = new DefaultComparer(this);
else
_comparer = value;
}
@@ -229,20 +236,31 @@ namespace ProcessHacker.Common.Ui
// Avoid forcing handle creation before all other initialization
// has finished. This is done by handling the Layout event and
// performing the icon setting there.
_list.DoDelayed(control => _list.Columns[_sortColumn].SetSortIcon(_sortOrder));
_list.DoDelayed((control) => _list.Columns[_sortColumn].SetSortIcon(_sortOrder));
}
private ListViewItem GetItem(int index)
{
if (_virtualMode)
{
var args = new RetrieveVirtualItemEventArgs(index);
_retrieveVirtualItem(this, args);
return args.Item;
}
else
{
return _list.Items[index];
}
}
private int ModifySort(int result, SortOrder order)
{
switch (order)
{
case SortOrder.Ascending:
return result;
case SortOrder.Descending:
return -result;
default:
return result;
}
if (order == SortOrder.Ascending)
return result;
else if (order == SortOrder.Descending)
return -result;
else
return result;
}
private int Compare(ListViewItem x, ListViewItem y, int column)
+132 -68
View File
@@ -25,6 +25,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
@@ -70,6 +71,8 @@ namespace ProcessHacker.Common
/// </summary>
public static int UnitSpecifier = 4;
private static PropertyInfo _doubleBufferedProperty;
/// <summary>
/// Aligns a number to the specified power-of-two alignment value.
/// </summary>
@@ -130,7 +133,7 @@ namespace ProcessHacker.Common
/// <returns>True if the array contains the value, otherwise false.</returns>
public static bool Contains<T>(this T[] array, T value)
{
return Array.IndexOf(array, value) != -1;
return Array.IndexOf<T>(array, value) != -1;
}
/// <summary>
@@ -195,8 +198,8 @@ namespace ProcessHacker.Common
{
if (s.Length <= len)
return s;
return s.Substring(0, len - 4) + " ...";
else
return s.Substring(0, len - 4) + " ...";
}
/// <summary>
@@ -215,11 +218,24 @@ namespace ProcessHacker.Common
return sb.ToString();
}
/// <summary>
/// Clears and cleans up resources held by the menu items.
/// </summary>
public static void DisposeAndClear(this Menu.MenuItemCollection items)
{
//foreach (MenuItem item in items)
//{
// item.Dispose();
//}
items.Clear();
}
/// <summary>
/// Disables the menu items contained in the specified menu.
/// </summary>
/// <param name="menu">The menu.</param>
public static void DisableAllMenuItems(MenuItem menu)
public static void DisableAllMenuItems(Menu menu)
{
foreach (MenuItem item in menu.MenuItems)
item.Enabled = false;
@@ -228,7 +244,7 @@ namespace ProcessHacker.Common
/// <summary>
/// Disables all menu items.
/// </summary>
public static void DisableAll(this MenuItem menu)
public static void DisableAll(this Menu menu)
{
DisableAllMenuItems(menu);
}
@@ -521,7 +537,7 @@ namespace ProcessHacker.Common
double months = span.TotalDays * 12 / 365;
double years = months / 12;
double centuries = years / 100;
string str;
string str = "";
// Start from the most general time unit and see if they can be used
// without any fractional component.
@@ -577,7 +593,7 @@ namespace ProcessHacker.Common
str = "a very short time";
// Turn 1 into "a", e.g. 1 minute -> a minute
if (str.StartsWith("1 ", StringComparison.OrdinalIgnoreCase))
if (str.StartsWith("1 "))
{
// Special vowel case: a hour -> an hour
if (str[2] != 'h')
@@ -605,7 +621,7 @@ namespace ProcessHacker.Common
public static string FormatSize(uint size)
{
int i = 0;
double s = size;
double s = (double)size;
while (s > 1024 && i < SizeUnitNames.Length && i < UnitSpecifier)
{
@@ -644,7 +660,7 @@ namespace ProcessHacker.Common
public static string FormatSize(ulong size)
{
int i = 0;
double s = size;
double s = (double)size;
while (s > 1024 && i < SizeUnitNames.Length && i < UnitSpecifier)
{
@@ -708,7 +724,7 @@ namespace ProcessHacker.Common
// <returns>The last write time of the assembly, or DateTime.MaxValue if an exception occurred.</returns>
public static DateTime GetAssemblyLastWriteTime(Assembly assembly)
{
if (string.IsNullOrEmpty(assembly.Location))
if (assembly.Location == null || assembly.Location == "")
return DateTime.MaxValue;
try
@@ -824,10 +840,10 @@ namespace ProcessHacker.Common
if (minimum < 0)
throw new ArgumentOutOfRangeException("minimum");
foreach (int t in Primes)
for (int i = 0; i < Primes.Length; i++)
{
if (t >= minimum)
return t;
if (Primes[i] >= minimum)
return Primes[i];
}
for (int i = minimum | 1; i < int.MaxValue; i += 2)
@@ -936,8 +952,8 @@ namespace ProcessHacker.Common
{
if (c >= ' ' && c <= '~')
return c;
return '.';
else
return '.';
}
/// <summary>
@@ -949,8 +965,8 @@ namespace ProcessHacker.Common
{
StringBuilder sb = new StringBuilder();
foreach (char t in s)
sb.Append(MakePrintable(t));
for (int i = 0; i < s.Length; i++)
sb.Append(MakePrintable(s[i]));
return sb.ToString();
}
@@ -1043,7 +1059,7 @@ namespace ProcessHacker.Common
foreach (string s in args)
{
if (s.StartsWith("-", StringComparison.OrdinalIgnoreCase))
if (s.StartsWith("-"))
{
if (dict.ContainsKey(s))
throw new ArgumentException("Option already specified.");
@@ -1108,7 +1124,7 @@ namespace ProcessHacker.Common
if (s.Read(buffer, 0, length) == 0)
throw new EndOfStreamException();
return Encoding.ASCII.GetString(buffer);
return System.Text.Encoding.ASCII.GetString(buffer);
}
public static uint ReadUInt32(Stream s, Endianness type)
@@ -1145,7 +1161,7 @@ namespace ProcessHacker.Common
if (b == 0 && b2 == 0)
break;
str.Append(Encoding.Unicode.GetChars(new[] { (byte)b, (byte)b2 }));
str.Append(Encoding.Unicode.GetChars(new byte[] { (byte)b, (byte)b2 }));
}
return str.ToString();
@@ -1174,7 +1190,7 @@ namespace ProcessHacker.Common
if (b2 == -1)
break;
str.Append(Encoding.Unicode.GetChars(new[] { (byte)b, (byte)b2 }));
str.Append(Encoding.Unicode.GetChars(new byte[] { (byte)b, (byte)b2 }));
i += 2;
}
@@ -1298,6 +1314,35 @@ namespace ProcessHacker.Common
}
}
/// <summary>
/// Enables or disables double buffering for a control.
/// </summary>
/// <param name="c">The control.</param>
/// <param name="t">The type of the control.</param>
/// <param name="value">The new setting.</param>
public static void SetDoubleBuffered(this Control c, Type t, bool value)
{
PropertyInfo doubleBufferedProperty = _doubleBufferedProperty;
if (doubleBufferedProperty == null)
{
_doubleBufferedProperty = doubleBufferedProperty = t.GetProperty("DoubleBuffered",
BindingFlags.NonPublic | BindingFlags.Instance);
}
doubleBufferedProperty.SetValue(c, value, null);
}
/// <summary>
/// Enables or disables double buffering for a control.
/// </summary>
/// <param name="c">The control to set the property on.</param>
/// <param name="value">The new value.</param>
public static void SetDoubleBuffered(this Control c, bool value)
{
c.SetDoubleBuffered(c.GetType(), value);
}
/// <summary>
/// Shows a file in Windows Explorer.
/// </summary>
@@ -1310,13 +1355,23 @@ namespace ProcessHacker.Common
/// <summary>
/// Calculates the size of a structure.
/// </summary>
/// <param name="alignment">A power-of-two whole-structure alignment to apply.</param>
/// <param name="size"></param>
/// <typeparam name="T">The structure type.</typeparam>
/// <returns>The size of the structure.</returns>
public static int SizeOf(int alignment, int size)
public static int SizeOf<T>()
{
return System.Runtime.InteropServices.Marshal.SizeOf(typeof(T));
}
/// <summary>
/// Calculates the size of a structure.
/// </summary>
/// <typeparam name="T">The structure type.</typeparam>
/// <param name="alignment">A power-of-two whole-structure alignment to apply.</param>
/// <returns>The size of the structure.</returns>
public static int SizeOf<T>(int alignment)
{
// HACK: This is wrong, but it works.
return size + alignment;
return SizeOf<T>() + alignment;
}
/// <summary>
@@ -1381,14 +1436,17 @@ namespace ProcessHacker.Common
public static int ToInt32(this byte[] data, Endianness type)
{
switch (type)
if (type == Endianness.Little)
{
case Endianness.Little:
return (data[0]) | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
case Endianness.Big:
return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]);
default:
throw new ArgumentException();
return (data[0]) | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
}
else if (type == Endianness.Big)
{
return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]);
}
else
{
throw new ArgumentException();
}
}
@@ -1399,16 +1457,19 @@ namespace ProcessHacker.Common
public static long ToInt64(this byte[] data, Endianness type)
{
switch (type)
if (type == Endianness.Little)
{
case Endianness.Little:
return (data[0]) | (data[1] << 8) | (data[2] << 16) | (data[3] << 24) |
(data[4] << 32) | (data[5] << 40) | (data[6] << 48) | (data[7] << 56);
case Endianness.Big:
return (data[0] << 56) | (data[1] << 48) | (data[2] << 40) | (data[3] << 32) |
(data[4] << 24) | (data[5] << 16) | (data[6] << 8) | (data[7]);
default:
throw new ArgumentException();
return (data[0]) | (data[1] << 8) | (data[2] << 16) | (data[3] << 24) |
(data[4] << 32) | (data[5] << 40) | (data[6] << 48) | (data[7] << 56);
}
else if (type == Endianness.Big)
{
return (data[0] << 56) | (data[1] << 48) | (data[2] << 40) | (data[3] << 32) |
(data[4] << 24) | (data[5] << 16) | (data[6] << 8) | (data[7]);
}
else
{
throw new ArgumentException();
}
}
@@ -1417,15 +1478,12 @@ namespace ProcessHacker.Common
if (IntPtr.Size != data.Length)
throw new ArgumentException("data");
switch (IntPtr.Size)
{
case sizeof(int):
return new IntPtr(data.ToInt32(Endianness.Little));
case sizeof(long):
return new IntPtr(data.ToInt64(Endianness.Little));
default:
throw new ArgumentException("data");
}
if (IntPtr.Size == sizeof(int))
return new IntPtr(data.ToInt32(Endianness.Little));
else if (IntPtr.Size == sizeof(long))
return new IntPtr(data.ToInt64(Endianness.Little));
else
throw new ArgumentException("data");
}
public static ushort ToUInt16(this byte[] data, Endianness type)
@@ -1435,14 +1493,17 @@ namespace ProcessHacker.Common
public static ushort ToUInt16(this byte[] data, int offset, Endianness type)
{
switch (type)
if (type == Endianness.Little)
{
case Endianness.Little:
return (ushort)(data[offset] | (data[offset + 1] << 8));
case Endianness.Big:
return (ushort)((data[offset] << 8) | data[offset + 1]);
default:
throw new ArgumentException();
return (ushort)(data[offset] | (data[offset + 1] << 8));
}
else if (type == Endianness.Big)
{
return (ushort)((data[offset] << 8) | data[offset + 1]);
}
else
{
throw new ArgumentException();
}
}
@@ -1453,16 +1514,19 @@ namespace ProcessHacker.Common
public static uint ToUInt32(this byte[] data, int offset, Endianness type)
{
switch (type)
if (type == Endianness.Little)
{
case Endianness.Little:
return (uint)(data[offset]) | (uint)(data[offset + 1] << 8) |
(uint)(data[offset + 2] << 16) | (uint)(data[offset + 3] << 24);
case Endianness.Big:
return (uint)(data[offset] << 24) | (uint)(data[offset + 1] << 16) |
(uint)(data[offset + 2] << 8) | (uint)(data[offset + 3]);
default:
throw new ArgumentException();
return (uint)(data[offset]) | (uint)(data[offset + 1] << 8) |
(uint)(data[offset + 2] << 16) | (uint)(data[offset + 3] << 24);
}
else if (type == Endianness.Big)
{
return (uint)(data[offset] << 24) | (uint)(data[offset + 1] << 16) |
(uint)(data[offset + 2] << 8) | (uint)(data[offset + 3]);
}
else
{
throw new ArgumentException();
}
}
@@ -1485,7 +1549,7 @@ namespace ProcessHacker.Common
if (buffer != null)
{
if (buffer.Length - offset < length)
throw new ArgumentOutOfRangeException("buffer", "The buffer is too small for the specified offset and length.");
throw new ArgumentOutOfRangeException("The buffer is too small for the specified offset and length.");
}
else
{
@@ -1494,7 +1558,7 @@ namespace ProcessHacker.Common
// We don't have a buffer, so make sure the offset and length are zero.
if (offset != 0 || length != 0)
throw new ArgumentOutOfRangeException("offset", "The offset and length must be zero for a null buffer.");
throw new ArgumentOutOfRangeException("The offset and length must be zero for a null buffer.");
}
}
}
@@ -0,0 +1,39 @@
using System;
namespace ProcessHacker.Common
{
public class WeakReference<T>
where T : class
{
public static implicit operator T(WeakReference<T> reference)
{
return reference.Target;
}
private WeakReference _weakReference;
public WeakReference(T obj)
: this(obj, false)
{ }
public WeakReference(T obj, bool trackResurrection)
{
_weakReference = new WeakReference(obj, trackResurrection);
}
public bool Alive
{
get { return _weakReference.IsAlive; }
}
public bool TrackResurrection
{
get { return _weakReference.TrackResurrection; }
}
public T Target
{
get { return _weakReference.Target as T; }
}
}
}
+36 -26
View File
@@ -37,10 +37,10 @@ namespace ProcessHacker.Common
/// </summary>
public sealed class WorkItem
{
private readonly WorkQueue _owner;
private readonly string _tag;
private readonly Delegate _work;
private readonly object[] _args;
private WorkQueue _owner;
private string _tag;
private Delegate _work;
private object[] _args;
private bool _enabled = true;
private FastEvent _completedEvent = new FastEvent(false);
private object _result;
@@ -175,7 +175,7 @@ namespace ProcessHacker.Common
}
}
private static readonly WorkQueue _globalWorkQueue = new WorkQueue();
private static WorkQueue _globalWorkQueue = new WorkQueue();
/// <summary>
/// Gets the global work queue instance.
@@ -228,7 +228,7 @@ namespace ProcessHacker.Common
/// <summary>
/// The work queue. This object is used as a lock.
/// </summary>
private readonly Queue<WorkItem> _workQueue = new Queue<WorkItem>();
private Queue<WorkItem> _workQueue = new Queue<WorkItem>();
/// <summary>
/// The maximum number of worker threads. If there are less worker threads
/// than this limit, they will be created as necessary. If there are more
@@ -241,15 +241,15 @@ namespace ProcessHacker.Common
/// as necessary and the number of worker threads will never drop below
/// this number.
/// </summary>
private int _minWorkerThreads;
private int _minWorkerThreads = 0;
/// <summary>
/// The pool of worker threads. This object is used as a lock.
/// </summary>
private readonly Dictionary<int, Thread> _workerThreads = new Dictionary<int, Thread>();
private Dictionary<int, Thread> _workerThreads = new Dictionary<int, Thread>();
/// <summary>
/// The number of worker threads which are currently running work.
/// </summary>
private int _busyCount;
private int _busyCount = 0;
/// <summary>
/// A worker will block on the work-arrived event for this amount of time
/// before terminating.
@@ -258,7 +258,13 @@ namespace ProcessHacker.Common
/// <summary>
/// If true, prevents new work items from being queued.
/// </summary>
private volatile bool _isJoining;
private volatile bool _isJoining = false;
/// <summary>
/// Creates a new work queue.
/// </summary>
public WorkQueue()
{ }
/// <summary>
/// Gets the number of worker threads that are currently busy.
@@ -336,11 +342,9 @@ namespace ProcessHacker.Common
/// </summary>
private void CreateWorkerThread()
{
Thread workThread = new Thread(this.WorkerThreadStart, Utils.SixteenthStackSize)
{
IsBackground = true,
Priority = ThreadPriority.Lowest
};
Thread workThread = new Thread(this.WorkerThreadStart, Utils.SixteenthStackSize);
workThread.IsBackground = true;
workThread.Priority = ThreadPriority.Lowest;
workThread.SetApartmentState(ApartmentState.STA);
_workerThreads.Add(workThread.ManagedThreadId, workThread);
workThread.Start();
@@ -374,7 +378,7 @@ namespace ProcessHacker.Common
// Check for work items.
while (_workQueue.Count > 0)
{
WorkItem workItem;
WorkItem workItem = null;
// Lock and re-check.
lock (_workQueue)
@@ -407,8 +411,11 @@ namespace ProcessHacker.Common
workItem.Enabled = false;
return true;
}
// The work item is no longer in the queue.
return false;
else
{
// The work item is no longer in the queue.
return false;
}
}
}
@@ -528,7 +535,7 @@ namespace ProcessHacker.Common
// Check for work.
if (_workQueue.Count > 0)
{
WorkItem workItem;
WorkItem workItem = null;
// There is work, but we must lock and re-check.
lock (_workQueue)
@@ -546,7 +553,7 @@ namespace ProcessHacker.Common
else
{
// No work available. Wait for work.
bool workArrived;
bool workArrived = false;
lock (_workQueue)
workArrived = Monitor.Wait(_workQueue, _noWorkTimeout);
@@ -556,14 +563,17 @@ namespace ProcessHacker.Common
// Work arrived. Go back so we can perform it.
continue;
}
// No work arrived during the timeout period. Delete the thread.
lock (this._workerThreads)
else
{
// Check the minimum.
if (this._workerThreads.Count > this._minWorkerThreads)
// No work arrived during the timeout period. Delete the thread.
lock (_workerThreads)
{
this.DestroyWorkerThread();
return;
// Check the minimum.
if (_workerThreads.Count > _minWorkerThreads)
{
this.DestroyWorkerThread();
return;
}
}
}
}
+1 -1
View File
@@ -1,3 +1,3 @@
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
+8 -44
View File
@@ -179,7 +179,7 @@ namespace ProcessHacker.Native.Api
TruncateExisting = 5
}
public enum GdiBlendMode
public enum GdiBlendMode : int
{
Black = 1,
NotMergePen,
@@ -200,7 +200,7 @@ namespace ProcessHacker.Native.Api
Last
}
public enum GdiPenStyle
public enum GdiPenStyle : int
{
Solid = 0,
Dash,
@@ -213,7 +213,7 @@ namespace ProcessHacker.Native.Api
Alternate
}
public enum GdiStockObject
public enum GdiStockObject : int
{
WhiteBrush = 0,
LightGrayBrush,
@@ -236,7 +236,7 @@ namespace ProcessHacker.Native.Api
DcPen
}
public enum GetWindowLongOffset
public enum GetWindowLongOffset : int
{
WndProc = -4,
HInstance = -6,
@@ -248,14 +248,14 @@ namespace ProcessHacker.Native.Api
}
[Flags]
public enum HeapEntry32Flags
public enum HeapEntry32Flags : int
{
Fixed = 0x00000001,
Free = 0x00000002,
Moveable = 0x00000004
}
public enum LoadImageType
public enum LoadImageType : int
{
Bitmap = 0,
Icon = 1,
@@ -308,14 +308,14 @@ namespace ProcessHacker.Native.Api
LargePages = 0x20000000
}
public enum MemoryType
public enum MemoryType : int
{
Image = 0x1000000,
Mapped = 0x40000,
Private = 0x20000
}
public enum MibTcpState
public enum MibTcpState : int
{
Closed = 1,
Listening = 2,
@@ -331,7 +331,6 @@ namespace ProcessHacker.Native.Api
DeleteTcb = 12
}
[Flags]
public enum MinidumpType : uint
{
Normal = 0x00000000,
@@ -457,41 +456,6 @@ namespace ProcessHacker.Native.Api
AboveNormal = 0x8000
}
[Flags]
public enum PropSheetPageFlags
{
Default = 0x0,
DlgIndirect = 0x1,
UseHIcon = 0x2,
UseIconID = 0x4,
UseTitle = 0x8,
RtlReading = 0x10,
HasHelp = 0x20,
UseRefParent = 0x40,
UseCallback = 0x80,
Premature = 0x400,
HideHeader = 0x800,
UseHeaderTitle = 0x1000,
UseHeaderSubTitle = 0x2000,
UseFusionContext = 0x4000
}
public enum PropSheetPageCallbackMessage
{
AddRef = 0,
Release = 1,
Create = 2
}
public enum PropSheetNotification : uint
{
First = ~200u + 1, // -200
SetActive = First - 0,
KillActive = First - 1
}
[Flags]
public enum RedrawWindowFlags
{
+182 -122
View File
@@ -21,6 +21,7 @@
*/
using System;
using System.Runtime.InteropServices;
using ProcessHacker.Native.Api;
using ProcessHacker.Native.Objects;
using ProcessHacker.Native.Security;
@@ -29,7 +30,7 @@ namespace ProcessHacker.Native
{
public static class NativeExtensions
{
private static bool NphNotAvailable;
private static bool NphNotAvailable = false;
public static ObjectBasicInformation GetBasicInfo(this SystemHandleEntry thisHandle)
{
@@ -41,34 +42,39 @@ namespace ProcessHacker.Native
public static ObjectBasicInformation GetBasicInfo(this SystemHandleEntry thisHandle, ProcessHandle process)
{
NtStatus status = NtStatus.Success;
IntPtr handle = new IntPtr(thisHandle.Handle);
IntPtr objectHandleI;
GenericHandle objectHandle = null;
int retLength;
int baseAddress;
Win32.NtDuplicateObject(
process,
handle,
ProcessHandle.Current,
out objectHandleI,
0,
0,
0
).ThrowIf();
if (KProcessHacker.Instance == null)
{
if ((status = Win32.NtDuplicateObject(
process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0)) >= NtStatus.Error)
Win32.Throw();
objectHandle = new GenericHandle(objectHandleI);
}
try
{
objectHandle = new GenericHandle(objectHandleI);
using (MemoryAlloc data = new MemoryAlloc(ObjectBasicInformation.SizeOf))
using (var data = new MemoryAlloc(Marshal.SizeOf(typeof(ObjectBasicInformation))))
{
Win32.NtQueryObject(
objectHandle,
ObjectInformationClass.ObjectBasicInformation,
data,
data.Size,
out retLength
).ThrowIf();
if (KProcessHacker.Instance != null)
{
KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectBasicInformation,
data, data.Size, out retLength, out baseAddress);
}
else
{
status = Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectBasicInformation,
data, data.Size, out retLength);
}
if (status >= NtStatus.Error)
Win32.Throw(status);
return data.ReadStruct<ObjectBasicInformation>();
}
@@ -91,49 +97,62 @@ namespace ProcessHacker.Native
if (includeThread)
{
if (!string.IsNullOrEmpty(processName))
return processName + " (" + clientId.ProcessId.ToString() + "): " + clientId.ThreadId.ToString();
return "Non-existent process (" + clientId.ProcessId.ToString() + "): " + clientId.ThreadId.ToString();
if (processName != null)
return processName + " (" + clientId.ProcessId.ToString() + "): " +
clientId.ThreadId.ToString();
else
return "Non-existent process (" + clientId.ProcessId.ToString() + "): " +
clientId.ThreadId.ToString();
}
else
{
if (processName != null)
return processName + " (" + clientId.ProcessId.ToString() + ")";
else
return "Non-existent process (" + clientId.ProcessId.ToString() + ")";
}
if (!string.IsNullOrEmpty(processName))
return processName + " (" + clientId.ProcessId.ToString() + ")";
return "Non-existent process (" + clientId.ProcessId.ToString() + ")";
}
private static string GetObjectNameNt(ProcessHandle process, IntPtr handle, GenericHandle dupHandle)
{
int retLength;
int baseAddress = 0;
Win32.NtQueryObject(
dupHandle,
ObjectInformationClass.ObjectNameInformation,
IntPtr.Zero,
0,
out retLength
);
if (KProcessHacker.Instance != null)
{
KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectNameInformation,
IntPtr.Zero, 0, out retLength, out baseAddress);
}
else
{
Win32.NtQueryObject(dupHandle, ObjectInformationClass.ObjectNameInformation,
IntPtr.Zero, 0, out retLength);
}
if (retLength > 0)
{
using (MemoryAlloc oniMem = new MemoryAlloc(retLength))
{
Win32.NtQueryObject(
dupHandle,
ObjectInformationClass.ObjectNameInformation,
oniMem,
oniMem.Size,
out retLength
).ThrowIf();
if (KProcessHacker.Instance != null)
{
if (KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectNameInformation,
oniMem, oniMem.Size, out retLength, out baseAddress) >= NtStatus.Error)
throw new Exception("ZwQueryObject failed.");
}
else
{
if (Win32.NtQueryObject(dupHandle, ObjectInformationClass.ObjectNameInformation,
oniMem, oniMem.Size, out retLength) >= NtStatus.Error)
throw new Exception("NtQueryObject failed.");
}
ObjectNameInformation oni = oniMem.ReadStruct<ObjectNameInformation>();
UnicodeString str = oni.Name;
var oni = oniMem.ReadStruct<ObjectNameInformation>();
var str = oni.Name;
//if (KProcessHacker.Instance != null)
//str.Buffer = str.Buffer.Increment(oniMem.Memory.Decrement(baseAddress));
if (KProcessHacker.Instance != null)
str.Buffer = str.Buffer.Increment(oniMem.Memory.Decrement(baseAddress));
return str.Text;
return str.Read();
}
}
@@ -147,7 +166,8 @@ namespace ProcessHacker.Native
public static ObjectInformation GetHandleInfo(this SystemHandleEntry thisHandle, bool getName)
{
using (ProcessHandle process = new ProcessHandle(thisHandle.ProcessId, ProcessAccess.DupHandle))
using (ProcessHandle process = new ProcessHandle(thisHandle.ProcessId,
KProcessHacker.Instance != null ? OSVersion.MinProcessQueryInfoAccess : ProcessAccess.DupHandle))
{
return thisHandle.GetHandleInfo(process, getName);
}
@@ -162,24 +182,20 @@ namespace ProcessHacker.Native
{
IntPtr handle = new IntPtr(thisHandle.Handle);
IntPtr objectHandleI;
int retLength;
int retLength = 0;
GenericHandle objectHandle = null;
if (thisHandle.Handle == 0 || thisHandle.Handle == -1 || thisHandle.Handle == -2)
throw new WindowsException(NtStatus.InvalidHandle);
// Duplicate the handle if we're not using KPH
//if (KProcessHacker.Instance == null)
if (KProcessHacker.Instance == null)
{
Win32.NtDuplicateObject(
process,
handle,
ProcessHandle.Current,
out objectHandleI,
0,
0,
0
).ThrowIf();
NtStatus status;
if ((status = Win32.NtDuplicateObject(
process, handle, ProcessHandle.Current, out objectHandleI, 0, 0, 0)) >= NtStatus.Error)
Win32.Throw(status);
objectHandle = new GenericHandle(objectHandleI);
}
@@ -202,35 +218,45 @@ namespace ProcessHacker.Native
Windows.ObjectTypesLock.ReleaseShared();
}
if (string.IsNullOrEmpty(info.TypeName))
if (info.TypeName == null)
{
Win32.NtQueryObject(
objectHandle,
ObjectInformationClass.ObjectTypeInformation,
IntPtr.Zero,
0,
out retLength
);
int baseAddress = 0;
if (KProcessHacker.Instance != null)
{
KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectTypeInformation,
IntPtr.Zero, 0, out retLength, out baseAddress);
}
else
{
Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectTypeInformation,
IntPtr.Zero, 0, out retLength);
}
if (retLength > 0)
{
using (MemoryAlloc otiMem = new MemoryAlloc(retLength))
{
Win32.NtQueryObject(
objectHandle,
ObjectInformationClass.ObjectTypeInformation,
otiMem,
otiMem.Size,
out retLength
).ThrowIf();
if (KProcessHacker.Instance != null)
{
if (KProcessHacker.Instance.ZwQueryObject(process, handle, ObjectInformationClass.ObjectTypeInformation,
otiMem, otiMem.Size, out retLength, out baseAddress) >= NtStatus.Error)
throw new Exception("ZwQueryObject failed.");
}
else
{
if (Win32.NtQueryObject(objectHandle, ObjectInformationClass.ObjectTypeInformation,
otiMem, otiMem.Size, out retLength) >= NtStatus.Error)
throw new Exception("NtQueryObject failed.");
}
ObjectTypeInformation oti = otiMem.ReadStruct<ObjectTypeInformation>();
UnicodeString str = oti.Name;
var oti = otiMem.ReadStruct<ObjectTypeInformation>();
var str = oti.Name;
//if (KProcessHacker.Instance != null)
//str.Buffer = str.Buffer.Increment(otiMem.Memory.Decrement(baseAddress));
if (KProcessHacker.Instance != null)
str.Buffer = str.Buffer.Increment(otiMem.Memory.Decrement(baseAddress));
info.TypeName = str.Text;
info.TypeName = str.Read();
Windows.ObjectTypesLock.AcquireExclusive();
@@ -252,14 +278,14 @@ namespace ProcessHacker.Native
// Get the object's name. If the object is a file we must take special
// precautions so that we don't hang.
if (string.Equals(info.TypeName, "File", StringComparison.OrdinalIgnoreCase))
if (info.TypeName == "File")
{
//if (KProcessHacker.Instance != null)
//{
// // Use KProcessHacker for files to avoid hangs.
// info.OrigName = KProcessHacker.Instance.GetHandleObjectName(process, handle);
//}
//else
if (KProcessHacker.Instance != null)
{
// Use KProcessHacker for files to avoid hangs.
info.OrigName = KProcessHacker.Instance.GetHandleObjectName(process, handle);
}
else
{
// 0: No hack, query the thing normally.
// 1: No hack, use NProcessHacker.
@@ -289,16 +315,13 @@ namespace ProcessHacker.Native
// Use NProcessHacker.
using (MemoryAlloc oniMem = new MemoryAlloc(0x4000))
{
NProcessHacker.PhQueryNameFileObject(
objectHandle,
oniMem,
oniMem.Size,
out retLength
).ThrowIf();
if (NProcessHacker.PhQueryNameFileObject(
objectHandle, oniMem, oniMem.Size, out retLength) >= NtStatus.Error)
throw new Exception("PhQueryNameFileObject failed.");
var oni = oniMem.ReadStruct<ObjectNameInformation>();
info.OrigName = oni.Name.Text;
info.OrigName = oni.Name.Read();
}
}
catch (DllNotFoundException)
@@ -316,7 +339,7 @@ namespace ProcessHacker.Native
{
// KProcessHacker and NProcessHacker not available. Fall back to using hack
// (i.e. not querying the name at all if the access is 0x0012019f).
if (thisHandle.GrantedAccess != 0x0012019f)
if ((int)thisHandle.GrantedAccess != 0x0012019f)
info.OrigName = GetObjectNameNt(process, handle, objectHandle);
}
}
@@ -341,20 +364,33 @@ namespace ProcessHacker.Native
case "Key":
info.BestName = NativeUtils.FormatNativeKeyName(info.OrigName);
break;
case "Process":
{
int processId;
using (NativeHandle<ProcessAccess> processHandle = new NativeHandle<ProcessAccess>(process, handle, OSVersion.MinProcessQueryInfoAccess))
if (KProcessHacker.Instance != null)
{
if ((processId = Win32.GetProcessId(processHandle)) == 0)
Win32.Throw();
processId = KProcessHacker.Instance.KphGetProcessId(process, handle);
if (processId == 0)
throw new Exception("Invalid PID");
}
else
{
using (var processHandle =
new NativeHandle<ProcessAccess>(process, handle, OSVersion.MinProcessQueryInfoAccess))
{
if ((processId = Win32.GetProcessId(processHandle)) == 0)
Win32.Throw();
}
}
info.BestName = (new ClientId(processId, 0)).GetName(false);
}
break;
case "Thread":
@@ -362,82 +398,106 @@ namespace ProcessHacker.Native
int processId;
int threadId;
using (var threadHandle = new NativeHandle<ThreadAccess>(process, handle, OSVersion.MinThreadQueryInfoAccess))
if (KProcessHacker.Instance != null)
{
var basicInfo = ThreadHandle.FromHandle(threadHandle).GetBasicInformation();
threadId = KProcessHacker.Instance.KphGetThreadId(process, handle, out processId);
threadId = basicInfo.ClientId.ThreadId;
processId = basicInfo.ClientId.ProcessId;
if (threadId == 0 || processId == 0)
throw new Exception("Invalid TID or PID");
}
else
{
using (var threadHandle =
new NativeHandle<ThreadAccess>(process, handle, OSVersion.MinThreadQueryInfoAccess))
{
var basicInfo = ThreadHandle.FromHandle(threadHandle).GetBasicInformation();
threadId = basicInfo.ClientId.ThreadId;
processId = basicInfo.ClientId.ProcessId;
}
}
info.BestName = (new ClientId(processId, threadId)).GetName(true);
}
break;
case "TmEn":
{
using (NativeHandle<EnlistmentAccess> enHandleDup = new NativeHandle<EnlistmentAccess>(process, handle, EnlistmentAccess.QueryInformation))
using (EnlistmentHandle enHandle = EnlistmentHandle.FromHandle(enHandleDup))
using (var enHandleDup =
new NativeHandle<EnlistmentAccess>(process, handle, EnlistmentAccess.QueryInformation))
{
info.BestName = enHandle.BasicInformation.EnlistmentId.ToString("B");
var enHandle = EnlistmentHandle.FromHandle(enHandleDup);
info.BestName = enHandle.GetBasicInformation().EnlistmentId.ToString("B");
}
}
break;
case "TmRm":
{
using (var rmHandleDup = new NativeHandle<ResourceManagerAccess>(process, handle, ResourceManagerAccess.QueryInformation))
using (var rmHandleDup =
new NativeHandle<ResourceManagerAccess>(process, handle, ResourceManagerAccess.QueryInformation))
{
var rmHandle = ResourceManagerHandle.FromHandle(rmHandleDup);
info.BestName = rmHandle.Description;
info.BestName = rmHandle.GetDescription();
if (string.IsNullOrEmpty(info.BestName))
info.BestName = rmHandle.Guid.ToString("B");
info.BestName = rmHandle.GetGuid().ToString("B");
}
}
break;
case "TmTm":
{
using (NativeHandle<TmAccess> tmHandleDup = new NativeHandle<TmAccess>(process, handle, TmAccess.QueryInformation))
using (TmHandle tmHandle = TmHandle.FromHandle(tmHandleDup))
using (var tmHandleDup =
new NativeHandle<TmAccess>(process, handle, TmAccess.QueryInformation))
{
info.BestName = FileUtils.GetFileName(FileUtils.GetFileName(tmHandle.LogFileName));
var tmHandle = TmHandle.FromHandle(tmHandleDup);
info.BestName = FileUtils.GetFileName(FileUtils.GetFileName(tmHandle.GetLogFileName()));
if (string.IsNullOrEmpty(info.BestName))
info.BestName = tmHandle.BasicInformation.TmIdentity.ToString("B");
info.BestName = tmHandle.GetBasicInformation().TmIdentity.ToString("B");
}
}
break;
case "TmTx":
{
using (var transactionHandleDup = new NativeHandle<TransactionAccess>(process, handle, TransactionAccess.QueryInformation))
using (var transactionHandleDup =
new NativeHandle<TransactionAccess>(process, handle, TransactionAccess.QueryInformation))
{
TransactionHandle transactionHandle = TransactionHandle.FromHandle(transactionHandleDup);
var transactionHandle = TransactionHandle.FromHandle(transactionHandleDup);
info.BestName = transactionHandle.Description;
info.BestName = transactionHandle.GetDescription();
if (string.IsNullOrEmpty(info.BestName))
info.BestName = transactionHandle.BasicInformation.TransactionId.ToString("B");
info.BestName = transactionHandle.GetBasicInformation().TransactionId.ToString("B");
}
}
break;
case "Token":
{
using (var tokenHandleDup = new NativeHandle<TokenAccess>(process, handle, TokenAccess.Query))
using (TokenHandle tokenHandle = TokenHandle.FromHandle(tokenHandleDup))
using (tokenHandle.User)
using (var tokenHandleDup =
new NativeHandle<TokenAccess>(process, handle, TokenAccess.Query))
{
info.BestName = tokenHandle.User.GetFullName(true) + ": 0x" + tokenHandle.Statistics.AuthenticationId;
var tokenHandle = TokenHandle.FromHandle(tokenHandleDup);
var sid = tokenHandle.GetUser();
using (sid)
info.BestName = sid.GetFullName(true) + ": 0x" +
tokenHandle.GetStatistics().AuthenticationId.ToString();
}
}
break;
default:
if (!string.IsNullOrEmpty(info.OrigName))
if (info.OrigName != null &&
info.OrigName != "")
{
info.BestName = info.OrigName;
}
@@ -451,7 +511,7 @@ namespace ProcessHacker.Native
}
catch
{
if (!string.IsNullOrEmpty(info.OrigName))
if (info.OrigName != null && info.OrigName != "")
{
info.BestName = info.OrigName;
}
@@ -35,6 +35,7 @@ using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using ProcessHacker.Native.Objects;
using ProcessHacker.Native.Security;
namespace ProcessHacker.Native.Api
@@ -441,7 +442,7 @@ namespace ProcessHacker.Native.Api
[In] IntPtr ImageBase
);
[DllImport("imagehlp.dll", SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true, CharSet = CharSet.Ansi)]
[DllImport("imagehlp.dll", SetLastError = true, CharSet = CharSet.Ansi)]
public static extern bool MapAndLoad(
[In] string ImageName,
[In] [Optional] string DllPath,
@@ -2590,8 +2591,8 @@ namespace ProcessHacker.Native.Api
public static extern IntPtr SendMessage(
[In] IntPtr hWnd,
[In] WindowMessage msg,
[In] IntPtr w,
[In] IntPtr l
[In] int w,
[In] int l
);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
@@ -21,6 +21,7 @@
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Runtime.InteropServices;
namespace ProcessHacker.Native.Api
@@ -21,6 +21,8 @@
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace ProcessHacker.Native.Api
@@ -21,7 +21,9 @@
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using ProcessHacker.Native.Security;
namespace ProcessHacker.Native.Api
@@ -21,7 +21,9 @@
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace ProcessHacker.Native.Api
{
@@ -60,13 +62,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct LsaTrustInformation
{
public static readonly int SizeOf;
static LsaTrustInformation()
{
SizeOf = Marshal.SizeOf(typeof(LsaTrustInformation));
}
public UnicodeString Name;
public IntPtr Sid; // Sid*
}
@@ -74,13 +69,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct Msv1_0_InteractiveLogon
{
public static readonly int SizeOf;
static Msv1_0_InteractiveLogon()
{
SizeOf = Marshal.SizeOf(typeof(Msv1_0_InteractiveLogon));
}
public Msv1_0_LogonSubmitType MessageType;
public UnicodeString LogonDomainName;
public UnicodeString UserName;
@@ -111,13 +99,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct PolicyPrivilegeDefinition
{
public static readonly int SizeOf;
static PolicyPrivilegeDefinition()
{
SizeOf = Marshal.SizeOf(typeof(PolicyPrivilegeDefinition));
}
public UnicodeString Name;
public Luid LocalValue;
}
@@ -84,9 +84,9 @@ namespace ProcessHacker.Native.Api
public const string TransactionManagerPath = @"\TransactionManager";
public static readonly IntPtr KnownAceSidStartOffset = Marshal.OffsetOf(typeof(KnownAceStruct), "SidStart");
public static readonly int SecurityDescriptorMinLength = SecurityDescriptorStruct.SizeOf;
public static readonly int SecurityDescriptorMinLength = Marshal.SizeOf(typeof(SecurityDescriptorStruct));
public static readonly int SecurityMaxSidSize =
SidStruct.SizeOf - sizeof(int) + (SidMaxSubAuthorities * sizeof(int));
Marshal.SizeOf(typeof(SidStruct)) - sizeof(int) + (SidMaxSubAuthorities * sizeof(int));
public static readonly IntPtr UserSharedData = new IntPtr(0x7ffe0000);
public static int CsrMakeApiNumber(int dllIndex, int apiIndex)
@@ -210,7 +210,6 @@ namespace ProcessHacker.Native.Api
MaxDebugObjectInfoClass
}
[Flags]
public enum DeviceControlAccess : int
{
Any = 0,
@@ -425,7 +424,7 @@ namespace ProcessHacker.Native.Api
OverwriteIf = 0x5
}
public enum FileInformationClass
public enum FileInformationClass : int
{
FileDirectoryInformation = 1, // dir
FileFullDirectoryInformation, // dir
@@ -1507,15 +1507,6 @@ namespace ProcessHacker.Native.Api
[Out] [Optional] out int ReturnLength
);
[DllImport("ntdll.dll")]
public static unsafe extern NtStatus NtQueryInformationToken(
[In] IntPtr TokenHandle,
[In] TokenInformationClass TokenInformationClass,
void* TokenInformation,
[In] int TokenInformationLength,
[Optional] void* ReturnLength
);
[DllImport("ntdll.dll")]
public static extern NtStatus NtQueryInformationToken(
[In] IntPtr TokenHandle,
@@ -1676,14 +1667,6 @@ namespace ProcessHacker.Native.Api
[Out] [Optional] out int ReturnLength
);
[DllImport("ntdll.dll")]
public static unsafe extern NtStatus NtQuerySystemInformation(
[In] SystemInformationClass SystemInformationClass,
void* SystemInformation,
[In] int SystemInformationLength,
int* ReturnLength
);
[DllImport("ntdll.dll")]
public static extern NtStatus NtQuerySystemInformation(
[In] SystemInformationClass SystemInformationClass,
@@ -2520,7 +2503,7 @@ namespace ProcessHacker.Native.Api
[DllImport("ntdll.dll", CharSet = CharSet.Unicode)]
public static extern NtStatus LdrGetDllHandle(
[In] [Optional] string DllPath,
[In] [Optional] int DllCharacteristics,
[In] [Optional] ref int DllCharacteristics,
[In] ref UnicodeString DllName,
[Out] out IntPtr DllHandle
);
@@ -2528,7 +2511,7 @@ namespace ProcessHacker.Native.Api
[DllImport("ntdll.dll")]
public static extern NtStatus LdrGetProcedureAddress(
[In] IntPtr DllHandle,
[In] [Optional] IntPtr ProcedureName,
[In] [Optional] ref AnsiString ProcedureName,
[In] [Optional] int ProcedureNumber,
[Out] out IntPtr ProcedureAddress
);
@@ -2536,7 +2519,7 @@ namespace ProcessHacker.Native.Api
[DllImport("ntdll.dll", CharSet = CharSet.Unicode)]
public static extern NtStatus LdrLoadDll(
[In] [Optional] string DllPath,
[In] [Optional] int DllCharacteristics,
[In] [Optional] ref int DllCharacteristics,
[In] ref UnicodeString DllName,
[Out] out IntPtr DllHandle
);
@@ -3311,14 +3294,6 @@ namespace ProcessHacker.Native.Api
[In] IntPtr Length
);
[DllImport("ntdll.dll")]
public static extern unsafe void RtlMoveMemory(
void* Destination,
void* Source,
[In] IntPtr Length
);
[DllImport("ntdll.dll")]
public static extern void RtlZeroMemory(
[In] IntPtr Destination,
File diff suppressed because it is too large Load Diff
@@ -20,7 +20,6 @@
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
namespace ProcessHacker.Native.Api
{
/// <summary>
@@ -390,7 +389,7 @@ namespace ProcessHacker.Native.Api
{
// Fix those messages which are formatted like:
// {Asdf}\r\nAsdf asdf asdf...
if (message.StartsWith("{", StringComparison.OrdinalIgnoreCase))
if (message.StartsWith("{"))
{
string[] split = message.Split('\n');
@@ -1,4 +1,8 @@
namespace ProcessHacker.Native.Api
using System;
using System.Collections.Generic;
using System.Text;
namespace ProcessHacker.Native.Api
{
public static partial class Win32
{
@@ -21,6 +21,7 @@
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using ProcessHacker.Native.Security;
@@ -21,6 +21,7 @@
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace ProcessHacker.Native.Api
@@ -123,13 +124,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct SamRidEnumeration
{
public static readonly int SizeOf;
static SamRidEnumeration()
{
SizeOf = Marshal.SizeOf(typeof(SamRidEnumeration));
}
public int RelativeId;
public UnicodeString Name;
}
@@ -137,13 +131,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct SamSidEnumeration
{
public static readonly int SizeOf;
static SamSidEnumeration()
{
SizeOf = Marshal.SizeOf(typeof(SamSidEnumeration));
}
public IntPtr Sid; // Sid*
public UnicodeString Name;
}
+12 -285
View File
@@ -31,6 +31,7 @@
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using ProcessHacker.Native.Objects;
namespace ProcessHacker.Native.Api
{
@@ -91,13 +92,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CredUiInfo
{
public static readonly int SizeOf;
static CredUiInfo()
{
SizeOf = Marshal.SizeOf(typeof(CredUiInfo));
}
public int Size;
public IntPtr Parent;
public string MessageText;
@@ -161,25 +155,6 @@ namespace ProcessHacker.Native.Api
public IntPtr ChainContext;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DlgTemplate
{
public static readonly int SizeOf;
public int style;
public int dwExtendedStyle;
public short cdit;
public short x;
public short y;
public short cx;
public short cy;
static DlgTemplate()
{
SizeOf = Marshal.SizeOf(typeof(DlgTemplate));
}
}
[StructLayout(LayoutKind.Sequential)]
public struct EnumServiceStatus
{
@@ -196,13 +171,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct EnumServiceStatusProcess
{
public static readonly int SizeOf;
static EnumServiceStatusProcess()
{
SizeOf = Marshal.SizeOf(typeof(EnumServiceStatusProcess));
}
[MarshalAs(UnmanagedType.LPTStr)]
public string ServiceName;
@@ -235,13 +203,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct HeapEntry32
{
public static readonly int SizeOf;
static HeapEntry32()
{
SizeOf = Marshal.SizeOf(typeof(HeapEntry32));
}
public int dwSize;
public IntPtr hHandle;
public IntPtr dwAddress;
@@ -256,13 +217,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct HeapList32
{
public static readonly int SizeOf;
static HeapList32()
{
SizeOf = Marshal.SizeOf(typeof(HeapList32));
}
public int dwSize;
public int th32ProcessID;
public IntPtr th32HeapID;
@@ -335,13 +289,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct LuidAndAttributes
{
public static readonly int SizeOf;
static LuidAndAttributes()
{
SizeOf = Marshal.SizeOf(typeof(LuidAndAttributes));
}
public Luid Luid;
public SePrivilegeAttributes Attributes;
}
@@ -349,8 +296,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct MemoryBasicInformation
{
public static readonly int SizeOf;
public IntPtr BaseAddress;
public IntPtr AllocationBase;
public MemoryProtection AllocationProtect;
@@ -358,11 +303,6 @@ namespace ProcessHacker.Native.Api
public MemoryState State;
public MemoryProtection Protect;
public MemoryType Type;
static MemoryBasicInformation()
{
SizeOf = Marshal.SizeOf(typeof(MemoryBasicInformation));
}
}
[StructLayout(LayoutKind.Sequential, Pack = 16)]
@@ -371,12 +311,12 @@ namespace ProcessHacker.Native.Api
public IntPtr BaseAddress;
public IntPtr AllocationBase;
public MemoryProtection AllocationProtect;
public int _alignment1;
private int _alignment1;
public ulong RegionSize;
public MemoryState State;
public MemoryProtection Protect;
public MemoryType Type;
public int _alignment2;
private int _alignment2;
}
[StructLayout(LayoutKind.Sequential)]
@@ -418,13 +358,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct MibTcpRowOwnerPid
{
public static readonly int SizeOf;
static MibTcpRowOwnerPid()
{
SizeOf = Marshal.SizeOf(typeof(MibTcpRowOwnerPid));
}
public MibTcpState State;
public uint LocalAddress;
public int LocalPort;
@@ -435,14 +368,7 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MibTcp6RowOwnerPid
{
public static readonly int SizeOf;
static MibTcp6RowOwnerPid()
{
SizeOf = Marshal.SizeOf(typeof(MibTcp6RowOwnerPid));
}
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] LocalAddress;
public uint LocalScopeId;
@@ -534,14 +460,7 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct MibUdpRowOwnerPid
{
public static readonly int SizeOf;
static MibUdpRowOwnerPid()
{
SizeOf = Marshal.SizeOf(typeof(MibUdpRowOwnerPid));
}
{
public uint LocalAddress;
public int LocalPort;
public int OwningProcessId;
@@ -550,13 +469,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MibUdp6RowOwnerPid
{
public static readonly int SizeOf;
static MibUdp6RowOwnerPid()
{
SizeOf = Marshal.SizeOf(typeof(MibUdp6RowOwnerPid));
}
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] LocalAddress;
public uint LocalScopeId;
@@ -626,13 +538,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct ModuleInfo
{
public static readonly int SizeOf;
static ModuleInfo()
{
SizeOf = Marshal.SizeOf(typeof(ModuleInfo));
}
public IntPtr BaseOfDll;
public int SizeOfImage;
public IntPtr EntryPoint;
@@ -647,84 +552,23 @@ namespace ProcessHacker.Native.Api
public uint Flags;
}
/// <summary>
/// Contains performance information.
/// </summary>
/// <remarks>http://msdn.microsoft.com/en-us/library/ms684824.aspx</remarks>
[StructLayout(LayoutKind.Sequential)]
public struct PerformanceInformation
{
public static readonly int SizeOf = Marshal.SizeOf(typeof(PerformanceInformation));
/// <summary>
/// The size of this structure, in bytes.
/// </summary>
public int cbSize;
/// <summary>
/// The number of pages currently committed by the system. Note that committing pages (using VirtualAlloc with MEM_COMMIT) changes this value immediately; however, the physical memory is not charged until the pages are accessed.
/// </summary>
public int Size;
public IntPtr CommitTotal;
/// <summary>
/// The current maximum number of pages that can be committed by the system without extending the paging file(s). This number can change if memory is added or deleted, or if pagefiles have grown, shrunk, or been added. If the paging file can be extended, this is a soft limit.
/// </summary>
public IntPtr CommitLimit;
/// <summary>
/// The maximum number of pages that were simultaneously in the committed state since the last system reboot.
/// </summary>
public IntPtr CommitPeak;
/// <summary>
/// The amount of actual physical memory, in pages.
/// </summary>
public IntPtr PhysicalTotal;
/// <summary>
/// The amount of physical memory currently available, in pages. This is the amount of physical memory that can be immediately reused without having to write its contents to disk first. It is the sum of the size of the standby, free, and zero lists.
/// </summary>
public IntPtr PhysicalAvailable;
/// <summary>
/// The amount of system cache memory, in pages. This is the size of the standby list plus the system working set.
/// </summary>
public IntPtr SystemCache;
/// <summary>
/// The sum of the memory currently in the paged and nonpaged kernel pools, in pages.
/// </summary>
public IntPtr KernelTotal;
/// <summary>
/// The memory currently in the paged kernel pool, in pages.
/// </summary>
public IntPtr KernelPaged;
/// <summary>
/// The memory currently in the nonpaged kernel pool, in pages.
/// </summary>
public IntPtr KernelNonPaged;
/// <summary>
/// The size of a page, in bytes.
/// </summary>
public IntPtr PageSize;
/// <summary>
/// The current number of open handles.
/// </summary>
public uint HandlesCount;
/// <summary>
/// The current number of processes.
/// </summary>
public uint ProcessCount;
/// <summary>
/// The current number of threads.
/// </summary>
public uint ThreadCount;
public int HandlesCount;
public int ProcessCount;
public int ThreadCount;
}
[StructLayout(LayoutKind.Sequential)]
@@ -753,32 +597,6 @@ namespace ProcessHacker.Native.Api
public int ThreadId;
}
[StructLayout(LayoutKind.Sequential)]
public struct PropSheetPageW
{
public static readonly int SizeOf;
static PropSheetPageW()
{
SizeOf = Marshal.SizeOf(typeof(PropSheetPageW));
}
public int dwSize;
public PropSheetPageFlags dwFlags;
public IntPtr hInstance;
public IntPtr pResource; // pszTemplate
public IntPtr hIcon;
public IntPtr pszTitle;
public IntPtr pfnDlgProc;
public IntPtr lParam;
public IntPtr pfnCallback;
public IntPtr pcRefParent;
public IntPtr pszHeaderTitle;
public IntPtr pszHeaderSubTitle;
public IntPtr hActCtx;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct ProfileInformation
{
@@ -847,13 +665,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SecPkgInfo
{
public static readonly int SizeOf;
static SecPkgInfo()
{
SizeOf = Marshal.SizeOf(typeof(SecPkgInfo));
}
public int Capabilities;
public ushort Version;
public ushort RpcId;
@@ -884,13 +695,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct ServiceStatusProcess
{
public static readonly int SizeOf;
static ServiceStatusProcess()
{
SizeOf = Marshal.SizeOf(typeof(ServiceStatusProcess));
}
public ServiceType ServiceType;
public ServiceState CurrentState;
public ServiceAccept ControlsAccepted;
@@ -905,13 +709,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct ShellExecuteInfo
{
public static readonly int SizeOf;
static ShellExecuteInfo()
{
SizeOf = Marshal.SizeOf(typeof(ShellExecuteInfo));
}
public int cbSize;
public uint fMask;
public IntPtr hWnd;
@@ -933,13 +730,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct ShFileInfo
{
public static readonly int SizeOf;
static ShFileInfo()
{
SizeOf = Marshal.SizeOf(typeof(ShFileInfo));
}
public IntPtr hIcon;
public IntPtr iIcon;
public uint dwAttributes;
@@ -952,13 +742,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SiAccess
{
public static readonly int SizeOf;
static SiAccess()
{
SizeOf = Marshal.SizeOf(typeof(SiAccess));
}
public IntPtr Guid;
public int Mask;
public IntPtr Name; // string
@@ -1010,13 +793,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct StartupInfo
{
public static readonly int SizeOf;
static StartupInfo()
{
SizeOf = Marshal.SizeOf(typeof(StartupInfo));
}
public int Size;
[MarshalAs(UnmanagedType.LPWStr)]
public string Reserved;
@@ -1043,8 +819,7 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct SymbolInfo
{
public static readonly int SizeOf;
public static readonly int NameOffset;
public static readonly int NameOffset = Marshal.OffsetOf(typeof(SymbolInfo), "Name").ToInt32();
public int SizeOfStruct;
public int TypeIndex;
@@ -1061,12 +836,6 @@ namespace ProcessHacker.Native.Api
public int NameLen;
public int MaxNameLen;
public byte Name;
static SymbolInfo()
{
SizeOf = Marshal.SizeOf(typeof(SymbolInfo));
NameOffset = Marshal.OffsetOf(typeof(SymbolInfo), "Name").ToInt32();
}
}
[StructLayout(LayoutKind.Sequential)]
@@ -1090,8 +859,8 @@ namespace ProcessHacker.Native.Api
public int Styles;
[MarshalAs(UnmanagedType.FunctionPtr)]
public WndProcDelegate WindowsProc;
public int ExtraClassData;
public int ExtraWindowData;
private int ExtraClassData;
private int ExtraWindowData;
public IntPtr InstanceHandle;
public IntPtr IconHandle;
public IntPtr CursorHandle;
@@ -1105,13 +874,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct WindowPlacement
{
public static readonly int SizeOf;
static WindowPlacement()
{
SizeOf = Marshal.SizeOf(typeof(WindowPlacement));
}
public int Length;
public WindowPlacementFlags Flags;
public ShowWindowType ShowState;
@@ -1123,13 +885,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct WintrustCatalogInfo
{
public static readonly int SizeOf;
static WintrustCatalogInfo()
{
SizeOf = Marshal.SizeOf(typeof(WintrustCatalogInfo));
}
public int Size;
public int CatalogVersion;
public string CatalogFilePath;
@@ -1144,13 +899,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct WintrustData
{
public static readonly int SizeOf;
static WintrustData()
{
SizeOf = Marshal.SizeOf(typeof(WintrustData));
}
public int Size;
public IntPtr PolicyCallbackData;
public IntPtr SIPClientData;
@@ -1168,13 +916,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential)]
public struct WintrustFileInfo
{
public static readonly int SizeOf;
static WintrustFileInfo()
{
SizeOf = Marshal.SizeOf(typeof(WintrustFileInfo));
}
public int Size;
public IntPtr FilePath;
public IntPtr FileHandle;
@@ -1200,13 +941,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct WtsProcessInfo
{
public static readonly int SizeOf;
static WtsProcessInfo()
{
SizeOf = Marshal.SizeOf(typeof(WtsProcessInfo));
}
public int SessionId;
public int ProcessId;
public IntPtr ProcessName;
@@ -1216,13 +950,6 @@ namespace ProcessHacker.Native.Api
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct WtsSessionInfo
{
public static readonly int SizeOf;
static WtsSessionInfo()
{
SizeOf = Marshal.SizeOf(typeof(WtsSessionInfo));
}
public int SessionID;
public string WinStationName;
public WtsConnectStateClass State;
+43 -71
View File
@@ -39,20 +39,18 @@ namespace ProcessHacker.Native.Api
public delegate IntPtr WndProcDelegate(IntPtr hWnd, WindowMessage msg, IntPtr wParam, IntPtr lParam);
public delegate bool SymEnumSymbolsProc(IntPtr SymInfo, int SymbolSize, int UserContext);
public delegate bool ReadProcessMemoryProc64(IntPtr ProcessHandle, ulong BaseAddress, IntPtr Buffer, int Size, out int BytesRead);
public unsafe delegate bool ReadProcessMemoryProc64(IntPtr ProcessHandle, ulong BaseAddress, IntPtr Buffer,
int Size, out int BytesRead);
public delegate IntPtr FunctionTableAccessProc64(IntPtr ProcessHandle, ulong AddrBase);
public delegate ulong GetModuleBaseProc64(IntPtr ProcessHandle, ulong Address);
public delegate int PropSheetPageCallback(IntPtr hwnd, PropSheetPageCallbackMessage uMsg, IntPtr ppsp);
public delegate bool DialogProc(IntPtr hwndDlg, WindowMessage uMsg, IntPtr wParam, IntPtr lParam);
/// <summary>
/// Provides interfacing to the Win32 and Native APIs.
/// </summary>
[SuppressUnmanagedCodeSecurity]
public static partial class Win32
{
private static readonly FastMutex _dbgHelpLock = new FastMutex();
private static FastMutex _dbgHelpLock = new FastMutex();
/// <summary>
/// A mutex which controls access to the dbghelp.dll functions.
@@ -95,12 +93,7 @@ namespace ProcessHacker.Native.Api
/// </summary>
public static void Throw()
{
Win32Error last = GetLastErrorCode();
if (last != Win32Error.Success)
{
Throw(last);
}
Throw(GetLastErrorCode());
}
public static void Throw(NtStatus status)
@@ -122,7 +115,7 @@ namespace ProcessHacker.Native.Api
#region Handles
public static void DuplicateObject(
public unsafe static void DuplicateObject(
IntPtr sourceProcessHandle,
IntPtr sourceHandle,
int desiredAccess,
@@ -143,7 +136,7 @@ namespace ProcessHacker.Native.Api
);
}
public static void DuplicateObject(
public unsafe static void DuplicateObject(
IntPtr sourceProcessHandle,
IntPtr sourceHandle,
IntPtr targetProcessHandle,
@@ -153,15 +146,34 @@ namespace ProcessHacker.Native.Api
DuplicateOptions options
)
{
NtDuplicateObject(
sourceProcessHandle,
sourceHandle,
targetProcessHandle,
out targetHandle,
desiredAccess,
handleAttributes,
options
).ThrowIf();
if (KProcessHacker.Instance != null)
{
int target;
KProcessHacker.Instance.KphDuplicateObject(
sourceProcessHandle.ToInt32(),
sourceHandle.ToInt32(),
targetProcessHandle.ToInt32(),
out target,
desiredAccess,
handleAttributes,
options);
targetHandle = new IntPtr(target);
}
else
{
NtStatus status;
if ((status = NtDuplicateObject(
sourceProcessHandle,
sourceHandle,
targetProcessHandle,
out targetHandle,
desiredAccess,
handleAttributes,
options)) >= NtStatus.Error)
Throw(status);
}
}
#endregion
@@ -181,7 +193,7 @@ namespace ProcessHacker.Native.Api
{
using (ProcessHandle phandle = new ProcessHandle(ProcessId, OSVersion.MinProcessQueryInfoAccess))
{
return phandle.GetToken(TokenAccess.Query).SessionId;
return phandle.GetToken(TokenAccess.Query).GetSessionId();
}
}
@@ -190,43 +202,6 @@ namespace ProcessHacker.Native.Api
#endregion
#region Property Sheets
[DllImport("comctl32.dll")]
public static extern IntPtr CreatePropertySheetPageW(
ref PropSheetPageW lppsp
);
[DllImport("user32.dll")]
public static extern bool MapDialogRect(
IntPtr hDlg,
ref Rect lpRect
);
[DllImport("user32.dll")]
public static extern IntPtr SetParent(
IntPtr hWndChild,
IntPtr hWndNewParent
);
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(
IntPtr hWnd,
int Msg,
IntPtr wParam,
IntPtr lParam
);
[StructLayout(LayoutKind.Sequential)]
public struct NmHdr
{
public IntPtr hwndFrom;
public IntPtr idFrom;
public uint code;
}
#endregion
#region TCP
public static MibTcpStats GetTcpStats()
@@ -253,7 +228,7 @@ namespace ProcessHacker.Native.Api
table.Table = new MibTcpRowOwnerPid[count];
for (int i = 0; i < count; i++)
table.Table[i] = mem.ReadStruct<MibTcpRowOwnerPid>(sizeof(int), MibTcpRowOwnerPid.SizeOf, i);
table.Table[i] = mem.ReadStruct<MibTcpRowOwnerPid>(sizeof(int), i);
}
return table;
@@ -274,11 +249,13 @@ namespace ProcessHacker.Native.Api
{
IntPtr processes;
int count;
int[] pids;
IntPtr[] sids;
WTSEnumerateProcesses(IntPtr.Zero, 0, 1, out processes, out count);
int[] pids = new int[count];
IntPtr[] sids = new IntPtr[count];
pids = new int[count];
sids = new IntPtr[count];
WtsMemoryAlloc data = new WtsMemoryAlloc(processes);
WtsProcessInfo* dataP = (WtsProcessInfo*)data.Memory;
@@ -289,12 +266,7 @@ namespace ProcessHacker.Native.Api
sids[i] = dataP[i].Sid;
}
return new WtsEnumProcessesFastData
{
PIDs = pids,
SIDs = sids,
Memory = data
};
return new WtsEnumProcessesFastData() { PIDs = pids, SIDs = sids, Memory = data };
}
#endregion
@@ -325,7 +297,7 @@ namespace ProcessHacker.Native.Api
table.Table = new MibUdpRowOwnerPid[count];
for (int i = 0; i < count; i++)
table.Table[i] = mem.ReadStruct<MibUdpRowOwnerPid>(sizeof(int), MibTcpRowOwnerPid.SizeOf, i);
table.Table[i] = mem.ReadStruct<MibUdpRowOwnerPid>(sizeof(int), i);
}
return table;
@@ -358,7 +330,7 @@ namespace ProcessHacker.Native.Api
string str = currentString.ToString();
if (string.IsNullOrEmpty(str))
if (str == "")
{
break;
}
+51 -50
View File
@@ -56,7 +56,7 @@ namespace ProcessHacker.Native
new Guid("{fc451c16-ac75-11d1-b4b8-00c04fb66ea0}");
public static readonly Guid WintrustActionGenericVerifyV2 =
new Guid("{00aac56b-cd44-11d0-8cc2-00c04fc295ee}");
public static readonly Guid WintrustActionTrustProviderTest =
public static readonly System.Guid WintrustActionTrustProviderTest =
new Guid("{573e31f8-ddba-11d0-8ccb-00c04fc295ee}");
private static string GetX500Value(string subject, string keyName)
@@ -106,12 +106,14 @@ namespace ProcessHacker.Native
// Well, here's a shitload of indirection for you...
// 1. State data -> Provider data
IntPtr provData = Win32.WTHelperProvDataFromStateData(stateData);
if (provData == IntPtr.Zero)
return null;
// 2. Provider data -> Provider signer
IntPtr signerInfo = Win32.WTHelperGetProvSignerFromChain(provData, 0, false, 0);
if (signerInfo == IntPtr.Zero)
@@ -125,22 +127,25 @@ namespace ProcessHacker.Native
return null;
// 3. Provider signer -> Provider cert
CryptProviderCert cert = (CryptProviderCert)Marshal.PtrToStructure(sngr.CertChain, typeof(CryptProviderCert));
if (cert.Cert == IntPtr.Zero)
return null;
// 4. Provider cert -> Cert context
CertContext context = (CertContext)Marshal.PtrToStructure(cert.Cert, typeof(CertContext));
if (context.CertInfo != IntPtr.Zero)
{
// 5. Cert context -> Cert info
CertInfo certInfo = (CertInfo)Marshal.PtrToStructure(context.CertInfo, typeof(CertInfo));
unsafe
{
using (MemoryAlloc buffer = new MemoryAlloc(0x200))
using (var buffer = new MemoryAlloc(0x200))
{
int length;
@@ -168,12 +173,13 @@ namespace ProcessHacker.Native
}
string name = buffer.ReadUnicodeString(0);
string value;
// 7. Subject X.500 string -> CN or OU value
string value = GetX500Value(name, "CN");
value = GetX500Value(name, "CN");
if (string.IsNullOrEmpty(value))
if (value == null)
value = GetX500Value(name, "OU");
return value;
@@ -186,23 +192,20 @@ namespace ProcessHacker.Native
public static VerifyResult StatusToVerifyResult(uint status)
{
switch (status)
{
case 0:
return VerifyResult.Trusted;
case 0x800b0100:
return VerifyResult.NoSignature;
case 0x800b0101:
return VerifyResult.Expired;
case 0x800b010c:
return VerifyResult.Revoked;
case 0x800b0111:
return VerifyResult.Distrust;
case 0x80092026:
return VerifyResult.SecuritySettings;
default:
return VerifyResult.SecuritySettings;
}
if (status == 0)
return VerifyResult.Trusted;
else if (status == 0x800b0100)
return VerifyResult.NoSignature;
else if (status == 0x800b0101)
return VerifyResult.Expired;
else if (status == 0x800b010c)
return VerifyResult.Revoked;
else if (status == 0x800b0111)
return VerifyResult.Distrust;
else if (status == 0x80092026)
return VerifyResult.SecuritySettings;
else
return VerifyResult.SecuritySettings;
}
public static VerifyResult VerifyFile(string fileName)
@@ -214,7 +217,7 @@ namespace ProcessHacker.Native
public static VerifyResult VerifyFile(string fileName, out string signerName)
{
VerifyResult result;
VerifyResult result = VerifyResult.NoSignature;
using (MemoryAlloc strMem = new MemoryAlloc(fileName.Length * 2 + 2))
{
@@ -223,25 +226,24 @@ namespace ProcessHacker.Native
strMem.WriteUnicodeString(0, fileName);
strMem.WriteInt16(fileName.Length * 2, 0);
fileInfo.Size = WintrustFileInfo.SizeOf;
fileInfo.Size = Marshal.SizeOf(fileInfo);
fileInfo.FilePath = strMem;
WintrustData trustData = new WintrustData
{
Size = WintrustData.SizeOf,
UIChoice = 2, // WTD_UI_NONE
UnionChoice = 1, // WTD_CHOICE_FILE
RevocationChecks = WtdRevocationChecks.None,
ProvFlags = WtdProvFlags.Safer,
StateAction = WtdStateAction.Verify
};
WintrustData trustData = new WintrustData();
trustData.Size = Marshal.SizeOf(typeof(WintrustData));
trustData.UIChoice = 2; // WTD_UI_NONE
trustData.UnionChoice = 1; // WTD_CHOICE_FILE
trustData.RevocationChecks = WtdRevocationChecks.None;
trustData.ProvFlags = WtdProvFlags.Safer;
trustData.StateAction = WtdStateAction.Verify;
if (OSVersion.IsAboveOrEqual(WindowsVersion.Vista))
trustData.ProvFlags |= WtdProvFlags.CacheOnlyUrlRetrieval;
using (MemoryAlloc mem = new MemoryAlloc(fileInfo.Size))
{
mem.WriteStruct(fileInfo);
mem.WriteStruct<WintrustFileInfo>(fileInfo);
trustData.UnionData = mem;
uint winTrustResult = Win32.WinVerifyTrust(IntPtr.Zero, WintrustActionGenericVerifyV2, ref trustData);
@@ -268,7 +270,8 @@ namespace ProcessHacker.Native
signerName = null;
using (FileHandle sourceFile = FileHandle.CreateWin32(fileName, FileAccess.GenericRead, FileShareMode.Read, FileCreationDispositionWin32.OpenExisting))
using (FileHandle sourceFile = FileHandle.CreateWin32(fileName, FileAccess.GenericRead, FileShareMode.Read,
FileCreationDispositionWin32.OpenExisting))
{
byte[] hash = new byte[256];
int hashLength = 256;
@@ -308,29 +311,27 @@ namespace ProcessHacker.Native
return VerifyResult.NoSignature;
}
WintrustCatalogInfo wci = new WintrustCatalogInfo
{
Size = WintrustCatalogInfo.SizeOf,
CatalogFilePath = ci.CatalogFile,
MemberFilePath = fileName,
MemberTag = memberTag.ToString()
};
WintrustCatalogInfo wci = new WintrustCatalogInfo();
WintrustData trustData = new WintrustData
{
Size = WintrustData.SizeOf,
UIChoice = 1,
UnionChoice = 2,
RevocationChecks = WtdRevocationChecks.None,
StateAction = WtdStateAction.Verify
};
wci.Size = Marshal.SizeOf(wci);
wci.CatalogFilePath = ci.CatalogFile;
wci.MemberFilePath = fileName;
wci.MemberTag = memberTag.ToString();
WintrustData trustData = new WintrustData();
trustData.Size = Marshal.SizeOf(typeof(WintrustData));
trustData.UIChoice = 1;
trustData.UnionChoice = 2;
trustData.RevocationChecks = WtdRevocationChecks.None;
trustData.StateAction = WtdStateAction.Verify;
if (OSVersion.IsAboveOrEqual(WindowsVersion.Vista))
trustData.ProvFlags = WtdProvFlags.CacheOnlyUrlRetrieval;
using (MemoryAlloc mem = new MemoryAlloc(wci.Size))
{
mem.WriteStruct(wci);
mem.WriteStruct<WintrustCatalogInfo>(wci);
try
{
@@ -37,7 +37,7 @@ namespace ProcessHacker.Native.Debugging
/// </summary>
public sealed class DebugBuffer : BaseObject
{
private readonly IntPtr _buffer;
private IntPtr _buffer;
/// <summary>
/// Creates a new debug buffer.
@@ -64,7 +64,7 @@ namespace ProcessHacker.Native.Debugging
/// <param name="callback">The callback for the enumeration.</param>
public void EnumHeaps(DebugEnumHeapsDelegate callback)
{
RtlDebugInformation debugInfo = this.GetDebugInformation();
var debugInfo = this.GetDebugInformation();
if (debugInfo.Heaps == IntPtr.Zero)
throw new InvalidOperationException("Heap information does not exist.");
@@ -74,7 +74,7 @@ namespace ProcessHacker.Native.Debugging
for (int i = 0; i < heaps.NumberOfHeaps; i++)
{
RtlHeapInformation heap = heapInfo.ReadStruct<RtlHeapInformation>(RtlProcessHeaps.HeapsOffset, RtlHeapInformation.SizeOf, i);
var heap = heapInfo.ReadStruct<RtlHeapInformation>(RtlProcessHeaps.HeapsOffset, i);
if (!callback(new HeapInformation(heap)))
break;
@@ -97,7 +97,7 @@ namespace ProcessHacker.Native.Debugging
for (int i = 0; i < locks.NumberOfLocks; i++)
{
var lock_ = locksInfo.ReadStruct<RtlProcessLockInformation>(sizeof(int), RtlProcessLockInformation.SizeOf, i);
var lock_ = locksInfo.ReadStruct<RtlProcessLockInformation>(sizeof(int), i);
if (!callback(new LockInformation(lock_)))
break;
@@ -110,17 +110,17 @@ namespace ProcessHacker.Native.Debugging
/// <param name="callback">The callback for the enumeration.</param>
public void EnumModules(DebugEnumModulesDelegate callback)
{
RtlDebugInformation debugInfo = this.GetDebugInformation();
var debugInfo = this.GetDebugInformation();
if (debugInfo.Modules == IntPtr.Zero)
throw new InvalidOperationException("Module information does not exist.");
MemoryRegion modulesInfo = new MemoryRegion(debugInfo.Modules);
RtlProcessModules modules = modulesInfo.ReadStruct<RtlProcessModules>();
var modules = modulesInfo.ReadStruct<RtlProcessModules>();
for (int i = 0; i < modules.NumberOfModules; i++)
{
var module = modulesInfo.ReadStruct<RtlProcessModuleInformation>(RtlProcessModules.ModulesOffset, RtlProcessModuleInformation.SizeOf, i);
var module = modulesInfo.ReadStruct<RtlProcessModuleInformation>(RtlProcessModules.ModulesOffset, i);
if (!callback(new ModuleInformation(module)))
break;
@@ -146,7 +146,7 @@ namespace ProcessHacker.Native.Debugging
{
List<HeapInformation> heaps = new List<HeapInformation>();
this.EnumHeaps(heap =>
this.EnumHeaps((heap) =>
{
heaps.Add(heap);
return true;
@@ -163,7 +163,7 @@ namespace ProcessHacker.Native.Debugging
{
List<LockInformation> locks = new List<LockInformation>();
this.EnumLocks(lock_ =>
this.EnumLocks((lock_) =>
{
locks.Add(lock_);
return true;
@@ -180,7 +180,7 @@ namespace ProcessHacker.Native.Debugging
{
List<ModuleInformation> modules = new List<ModuleInformation>();
this.EnumModules(module =>
this.EnumModules((module) =>
{
modules.Add(module);
return true;
@@ -195,7 +195,7 @@ namespace ProcessHacker.Native.Debugging
/// <param name="flags">The information to query.</param>
public void Query(RtlQueryProcessDebugFlags flags)
{
this.Query(ProcessHandle.CurrentId, flags);
this.Query(ProcessHandle.GetCurrentId(), flags);
}
/// <summary>
@@ -205,11 +205,14 @@ namespace ProcessHacker.Native.Debugging
/// <param name="flags">The information to query.</param>
public void Query(int pid, RtlQueryProcessDebugFlags flags)
{
Win32.RtlQueryProcessDebugInformation(
NtStatus status;
if ((status = Win32.RtlQueryProcessDebugInformation(
pid.ToIntPtr(),
flags,
_buffer
).ThrowIf();
)) >= NtStatus.Error)
Win32.Throw(status);
}
/// <summary>
@@ -217,7 +220,10 @@ namespace ProcessHacker.Native.Debugging
/// </summary>
public void QueryBackTraces()
{
Win32.RtlQueryProcessBackTraceInformation(_buffer).ThrowIf();
NtStatus status;
if ((status = Win32.RtlQueryProcessBackTraceInformation(_buffer)) >= NtStatus.Error)
Win32.Throw(status);
}
/// <summary>
@@ -225,7 +231,10 @@ namespace ProcessHacker.Native.Debugging
/// </summary>
public void QueryHeaps()
{
Win32.RtlQueryProcessHeapInformation(_buffer).ThrowIf();
NtStatus status;
if ((status = Win32.RtlQueryProcessHeapInformation(_buffer)) >= NtStatus.Error)
Win32.Throw(status);
}
/// <summary>
@@ -233,7 +242,10 @@ namespace ProcessHacker.Native.Debugging
/// </summary>
public void QueryLocks()
{
Win32.RtlQueryProcessLockInformation(_buffer).ThrowIf();
NtStatus status;
if ((status = Win32.RtlQueryProcessLockInformation(_buffer)) >= NtStatus.Error)
Win32.Throw(status);
}
//public void QueryModules()
@@ -243,11 +255,14 @@ namespace ProcessHacker.Native.Debugging
//public void QueryModules(ProcessHandle processHandle, RtlQueryProcessDebugFlags flags)
//{
// Win32.RtlQueryProcessModuleInformation(
// NtStatus status;
// if ((status = Win32.RtlQueryProcessModuleInformation(
// processHandle ?? IntPtr.Zero,
// flags,
// _buffer
// ).ThrowIf();
// )) >= NtStatus.Error)
// Win32.ThrowLastError(status);
//}
}
}
+46 -80
View File
@@ -23,6 +23,8 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using ProcessHacker.Native.Api;
using ProcessHacker.Native.Objects;
using ProcessHacker.Native.Security;
@@ -42,18 +44,20 @@ namespace ProcessHacker.Native
/// <summary>
/// Used to resolve device prefixes (\Device\Harddisk1) into DOS drive names.
/// </summary>
private static Dictionary<string, string> _fileNamePrefixes;
private static Dictionary<string, string> _fileNamePrefixes = new Dictionary<string, string>();
public static string FindFile(string basePath, string fileName)
{
if (!string.IsNullOrEmpty(basePath))
string path;
if (basePath != null)
{
// Search the base path first.
if (System.IO.File.Exists(basePath + "\\" + fileName))
return System.IO.Path.Combine(basePath, fileName);
}
string path = Environment.GetEnvironmentVariable("Path");
path = Environment.GetEnvironmentVariable("Path");
string[] directories = path.Split(';');
@@ -68,11 +72,12 @@ namespace ProcessHacker.Native
public static string FindFileWin32(string fileName)
{
using (MemoryAlloc data = new MemoryAlloc(0x400))
using (var data = new MemoryAlloc(0x400))
{
int retLength;
IntPtr filePart;
int retLength = Win32.SearchPath(null, fileName, null, data.Size / 2, data, out filePart);
retLength = Win32.SearchPath(null, fileName, null, data.Size / 2, data, out filePart);
if (retLength * 2 > data.Size)
{
@@ -94,26 +99,24 @@ namespace ProcessHacker.Native
public static Icon GetFileIcon(string fileName, bool large)
{
ShFileInfo shinfo = new ShFileInfo();
if (string.IsNullOrEmpty(fileName))
throw new Exception("File name cannot be empty.");
try
{
ShFileInfo shinfo;
if (Win32.SHGetFileInfo(
fileName,
0,
out shinfo,
(uint)ShFileInfo.SizeOf,
if (Win32.SHGetFileInfo(fileName, 0, out shinfo,
(uint)Marshal.SizeOf(shinfo),
Win32.ShgFiIcon |
(large ? Win32.ShgFiLargeIcon : Win32.ShgFiSmallIcon)
) == 0)
(large ? Win32.ShgFiLargeIcon : Win32.ShgFiSmallIcon)) == 0)
{
return null;
}
return Icon.FromHandle(shinfo.hIcon);
else
{
return Icon.FromHandle(shinfo.hIcon);
}
}
catch
{
@@ -121,43 +124,6 @@ namespace ProcessHacker.Native
}
}
public static unsafe string GetVistaFileName(int pid)
{
using (MemoryAlloc buffer = new MemoryAlloc(0x100))
{
SystemProcessImageNameInformation info;
info.ProcessId = pid;
info.ImageName.Length = 0;
info.ImageName.MaximumLength = 0x100;
info.ImageName.Buffer = buffer;
NtStatus status = Win32.NtQuerySystemInformation(
SystemInformationClass.SystemProcessImageName,
&info,
SystemProcessImageNameInformation.SizeOf,
null
);
if (status == NtStatus.InfoLengthMismatch)
{
// Our buffer was too small. The required buffer length is stored in MaximumLength.
buffer.ResizeNew(info.ImageName.MaximumLength);
status = Win32.NtQuerySystemInformation(
SystemInformationClass.SystemProcessImageName,
&info,
SystemProcessImageNameInformation.SizeOf,
null
);
}
status.ThrowIf();
return GetFileName(info.ImageName.Text);
}
}
public static string GetFileName(string fileName)
{
return GetFileName(fileName, false);
@@ -180,23 +146,25 @@ namespace ProcessHacker.Native
alreadyCanonicalized = true;
}
// If the path starts with "\??\", we can remove it and we will have the path.
else if (fileName.StartsWith("\\??\\", StringComparison.OrdinalIgnoreCase))
else if (fileName.StartsWith("\\??\\"))
{
fileName = fileName.Substring(4);
}
// If the path still starts with a backslash, we probably need to
// resolve any native object name to a DOS drive letter.
if (fileName.StartsWith("\\", StringComparison.OrdinalIgnoreCase))
if (fileName.StartsWith("\\"))
{
foreach (KeyValuePair<string, string> pair in _fileNamePrefixes)
var prefixes = _fileNamePrefixes;
foreach (var pair in prefixes)
{
if (fileName.StartsWith(pair.Key + "\\", StringComparison.OrdinalIgnoreCase))
if (fileName.StartsWith(pair.Key + "\\"))
{
fileName = pair.Value + "\\" + fileName.Substring(pair.Key.Length + 1);
break;
}
if (fileName == pair.Key)
else if (fileName == pair.Key)
{
fileName = pair.Value;
break;
@@ -217,44 +185,42 @@ namespace ProcessHacker.Native
if (driveLetter < 'A' || driveLetter > 'Z')
throw new ArgumentException("The drive letter must be between A to Z (inclusive).");
using (SymbolicLinkHandle shandle = new SymbolicLinkHandle(@"\??\" + driveLetter + ":", SymbolicLinkAccess.Query))
using (var shandle = new SymbolicLinkHandle(@"\??\" + driveLetter + ":", SymbolicLinkAccess.Query))
{
return shandle.Target;
return shandle.GetTarget();
}
}
public static void RefreshFileNamePrefixes()
{
if (_fileNamePrefixes == null)
// Just create a new dictionary to avoid having to lock the existing one.
var newPrefixes = new Dictionary<string, string>();
for (char c = 'A'; c <= 'Z'; c++)
{
// Just create a new dictionary to avoid having to lock the existing one.
_fileNamePrefixes = new Dictionary<string, string>();
for (char c = 'A'; c <= 'Z'; c++)
using (var data = new MemoryAlloc(1024))
{
using (MemoryAlloc data = new MemoryAlloc(1024))
{
int length;
int length;
if ((length = Win32.QueryDosDevice(c.ToString() + ":", data, data.Size/2)) > 2)
{
_fileNamePrefixes.Add(data.ReadUnicodeString(0, length - 2), c.ToString() + ":");
}
if ((length = Win32.QueryDosDevice(c.ToString() + ":", data, data.Size / 2)) > 2)
{
newPrefixes.Add(data.ReadUnicodeString(0, length - 2), c.ToString() + ":");
}
}
}
_fileNamePrefixes = newPrefixes;
}
public static void ShowProperties(string fileName)
{
ShellExecuteInfo info = new ShellExecuteInfo
{
cbSize = ShellExecuteInfo.SizeOf,
lpFile = fileName,
nShow = ShowWindowType.Show,
fMask = Win32.SeeMaskInvokeIdList,
lpVerb = "properties"
};
var info = new ShellExecuteInfo();
info.cbSize = Marshal.SizeOf(info);
info.lpFile = fileName;
info.nShow = ShowWindowType.Show;
info.fMask = Win32.SeeMaskInvokeIdList;
info.lpVerb = "properties";
Win32.ShellExecuteEx(ref info);
}
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using ProcessHacker.Native.Api;
namespace ProcessHacker.Native
@@ -21,7 +21,11 @@
*/
using System;
using System.Collections.Generic;
using System.Text;
using ProcessHacker.Native.Api;
using ProcessHacker.Native.Objects;
using ProcessHacker.Native.Security;
namespace ProcessHacker.Native.Image
{
@@ -29,12 +33,12 @@ namespace ProcessHacker.Native.Image
{
public delegate bool EnumEntriesDelegate(ImageExportEntry entry);
private readonly MappedImage _mappedImage;
private readonly ImageDataDirectory* _dataDirectory;
private readonly ImageExportDirectory* _exportDirectory;
private readonly int* _addressTable;
private readonly int* _namePointerTable;
private readonly short* _ordinalTable;
private MappedImage _mappedImage;
private ImageDataDirectory* _dataDirectory;
private ImageExportDirectory* _exportDirectory;
private int* _addressTable;
private int* _namePointerTable;
private short* _ordinalTable;
internal ImageExports(MappedImage mappedImage)
{
@@ -56,8 +60,8 @@ namespace ProcessHacker.Native.Image
{
if (_exportDirectory != null)
return _exportDirectory->NumberOfFunctions;
return 0;
else
return 0;
}
}
@@ -68,10 +72,9 @@ namespace ProcessHacker.Native.Image
if (index >= _exportDirectory->NumberOfFunctions)
return ImageExportEntry.Empty;
ImageExportEntry entry = new ImageExportEntry
{
Ordinal = (short)(this._ordinalTable[index] + this._exportDirectory->Base)
};
ImageExportEntry entry = new ImageExportEntry();
entry.Ordinal = (short)(_ordinalTable[index] + _exportDirectory->Base);
if (index < _exportDirectory->NumberOfNames)
entry.Name = new string((sbyte*)_mappedImage.RvaToVa(_namePointerTable[index]));
@@ -84,7 +87,9 @@ namespace ProcessHacker.Native.Image
if (_exportDirectory == null || _namePointerTable == null || _ordinalTable == null)
return ImageExportFunction.Empty;
int index = this.LookupName(name);
int index;
index = this.LookupName(name);
if (index == -1)
return ImageExportFunction.Empty;
@@ -107,17 +112,13 @@ namespace ProcessHacker.Native.Image
)
{
// This is a forwarder RVA.
return new ImageExportFunction
{
ForwardedName = new string((sbyte*)_mappedImage.RvaToVa(rva))
};
return new ImageExportFunction() { ForwardedName = new string((sbyte*)_mappedImage.RvaToVa(rva)) };
}
else
{
// This is a function RVA.
return new ImageExportFunction() { Function = (IntPtr)_mappedImage.RvaToVa(rva) };
}
// This is a function RVA.
return new ImageExportFunction
{
Function = (IntPtr)this._mappedImage.RvaToVa(rva)
};
}
private int LookupName(string name)
@@ -154,7 +155,7 @@ namespace ProcessHacker.Native.Image
public struct ImageExportEntry
{
public static readonly ImageExportEntry Empty;
public static readonly ImageExportEntry Empty = new ImageExportEntry();
public string Name;
public short Ordinal;
@@ -162,7 +163,7 @@ namespace ProcessHacker.Native.Image
public struct ImageExportFunction
{
public static readonly ImageExportFunction Empty;
public static readonly ImageExportFunction Empty = new ImageExportFunction();
public IntPtr Function;
public string ForwardedName;
@@ -28,10 +28,10 @@ namespace ProcessHacker.Native.Image
{
public delegate bool EnumEntriesDelegate(ImageExportEntry entry);
private readonly MappedImage _mappedImage;
private readonly int _count;
private readonly ImageImportDescriptor* _descriptorTable;
private readonly ImageImportDll[] _dlls;
private MappedImage _mappedImage;
private int _count;
private ImageImportDescriptor* _descriptorTable;
private ImageImportDll[] _dlls;
internal ImageImports(MappedImage mappedImage)
{
@@ -82,11 +82,11 @@ namespace ProcessHacker.Native.Image
public unsafe sealed class ImageImportDll
{
private readonly MappedImage _mappedImage;
private readonly ImageImportDescriptor* _descriptor;
private MappedImage _mappedImage;
private ImageImportDescriptor* _descriptor;
private string _name;
private readonly void* _lookupTable;
private readonly int _count;
private void* _lookupTable;
private int _count;
internal ImageImportDll(MappedImage mappedImage, ImageImportDescriptor* descriptor)
{
@@ -144,50 +144,45 @@ namespace ProcessHacker.Native.Image
if (index >= _count)
return ImageImportEntry.Empty;
switch (this._mappedImage.Magic)
if (_mappedImage.Magic == Win32.Pe32Magic)
{
case Win32.Pe32Magic:
int entry = ((int*)_lookupTable)[index];
// Is this entry using an ordinal?
if ((entry & 0x80000000) != 0)
{
return new ImageImportEntry() { Ordinal = (short)(entry & 0xffff) };
}
else
{
ImageImportByName* nameEntry = (ImageImportByName*)_mappedImage.RvaToVa(entry);
return new ImageImportEntry()
{
int entry = ((int*)this._lookupTable)[index];
NameHint = nameEntry->Hint,
Name = new string((sbyte*)&nameEntry->Name)
};
}
}
else if (_mappedImage.Magic == Win32.Pe32PlusMagic)
{
long entry = ((long*)_lookupTable)[index];
// Is this entry using an ordinal?
if ((entry & 0x80000000) != 0)
{
return new ImageImportEntry
{
Ordinal = (short)(entry & 0xffff)
};
}
// Is this entry using an ordinal?
if (((ulong)entry & 0x8000000000000000) != 0)
{
return new ImageImportEntry() { Ordinal = (short)(entry & 0xffff) };
}
else
{
ImageImportByName* nameEntry = (ImageImportByName*)_mappedImage.RvaToVa((int)(entry & 0xffffffff));
ImageImportByName* nameEntry = (ImageImportByName*)this._mappedImage.RvaToVa(entry);
return new ImageImportEntry
{
NameHint = nameEntry->Hint,
Name = new string((sbyte*)&nameEntry->Name)
};
}
case Win32.Pe32PlusMagic:
return new ImageImportEntry()
{
long entry = ((long*)this._lookupTable)[index];
// Is this entry using an ordinal?
if (((ulong)entry & 0x8000000000000000) != 0)
{
return new ImageImportEntry
{
Ordinal = (short)(entry & 0xffff)
};
}
ImageImportByName* nameEntry = (ImageImportByName*)this._mappedImage.RvaToVa((int)(entry & 0xffffffff));
return new ImageImportEntry
{
NameHint = nameEntry->Hint,
Name = new string((sbyte*)&nameEntry->Name)
};
}
NameHint = nameEntry->Hint,
Name = new string((sbyte*)&nameEntry->Name)
};
}
}
return ImageImportEntry.Empty;
@@ -157,41 +157,52 @@ namespace ProcessHacker.Native.Image
public ImageDataDirectory* GetDataEntry(ImageDataEntry entry)
{
switch (this._magic)
if (_magic == Win32.Pe32Magic)
{
case Win32.Pe32Magic:
if ((int)entry >= this._ntHeaders->OptionalHeader.NumberOfRvaAndSizes)
return null;
return &(&this._ntHeaders->OptionalHeader.DataDirectory)[(int)entry];
case Win32.Pe32PlusMagic:
if ((int)entry >= this.GetOptionalHeader64()->NumberOfRvaAndSizes)
return null;
return &(&this.GetOptionalHeader64()->DataDirectory)[(int)entry];
default:
if ((int)entry >= _ntHeaders->OptionalHeader.NumberOfRvaAndSizes)
return null;
return &(&_ntHeaders->OptionalHeader.DataDirectory)[(int)entry];
}
else if (_magic == Win32.Pe32PlusMagic)
{
if ((int)entry >= this.GetOptionalHeader64()->NumberOfRvaAndSizes)
return null;
return &(&this.GetOptionalHeader64()->DataDirectory)[(int)entry];
}
else
{
return null;
}
}
public ImageExportDirectory* GetExportDirectory()
{
ImageDataDirectory* dataEntry = this.GetDataEntry(ImageDataEntry.Export);
ImageDataDirectory* dataEntry;
dataEntry = this.GetDataEntry(ImageDataEntry.Export);
return (ImageExportDirectory*)this.RvaToVa(dataEntry->VirtualAddress);
}
public ImageImportDescriptor* GetImportDirectory()
{
ImageDataDirectory* dataEntry = this.GetDataEntry(ImageDataEntry.Import);
ImageDataDirectory* dataEntry;
dataEntry = this.GetDataEntry(ImageDataEntry.Import);
return (ImageImportDescriptor*)this.RvaToVa(dataEntry->VirtualAddress);
}
private void* GetLoadConfig(short magic)
{
ImageDataDirectory* dataEntry;
if (_magic != magic)
return null;
ImageDataDirectory* dataEntry = this.GetDataEntry(ImageDataEntry.LoadConfig);
dataEntry = this.GetDataEntry(ImageDataEntry.LoadConfig);
if (dataEntry == null)
return null;
@@ -211,14 +222,17 @@ namespace ProcessHacker.Native.Image
private ImageNtHeaders* GetNtHeaders()
{
int offset = *((int*)((byte*)this._memory + 0x3c));
int offset;
ImageNtHeaders* ntHeaders;
offset = *((int*)((byte*)_memory + 0x3c));
if (offset == 0)
throw new Exception("Invalid NT headers offset.");
if (offset >= 0x10000000 || offset >= _size)
throw new Exception("The NT headers offset is too large.");
ImageNtHeaders* ntHeaders = (ImageNtHeaders*)((byte*)this._memory + offset);
ntHeaders = (ImageNtHeaders*)((byte*)_memory + offset);
return ntHeaders;
}
@@ -271,7 +285,7 @@ namespace ProcessHacker.Native.Image
readOnly ? MemoryProtection.ExecuteRead : MemoryProtection.ExecuteReadWrite
))
{
_size = (int)fileHandle.FileSize;
_size = (int)fileHandle.GetSize();
_view = section.MapView(_size);
this.Load(_view);
@@ -299,7 +313,9 @@ namespace ProcessHacker.Native.Image
public void* RvaToVa(int rva)
{
ImageSectionHeader* section = this.RvaToSection(rva);
ImageSectionHeader* section;
section = this.RvaToSection(rva);
if (section == null)
return null;
@@ -6,7 +6,7 @@ namespace ProcessHacker.Native
{
public class ImpersonationContext : IDisposable
{
private bool _disposed;
private bool _disposed = false;
public ImpersonationContext(TokenHandle token)
{
@@ -16,11 +16,11 @@ namespace ProcessHacker.Native
public void Dispose()
{
if (_disposed)
return;
Win32.RevertToSelf();
this._disposed = true;
if (!_disposed)
{
Win32.RevertToSelf();
_disposed = true;
}
}
}
}
@@ -22,6 +22,7 @@
*/
using System;
using System.Runtime.InteropServices;
namespace ProcessHacker.Native
{
@@ -34,34 +35,26 @@ namespace ProcessHacker.Native
public static IntPtr And(this IntPtr ptr, int value)
{
switch (IntPtr.Size)
{
case sizeof(int):
return new IntPtr(ptr.ToInt32() & value);
default:
return new IntPtr(ptr.ToInt64() & value);
}
if (IntPtr.Size == sizeof(Int32))
return new IntPtr(ptr.ToInt32() & value);
else
return new IntPtr(ptr.ToInt64() & value);
}
public static IntPtr And(this IntPtr ptr, IntPtr value)
{
switch (IntPtr.Size)
{
case sizeof(int):
return new IntPtr(ptr.ToInt32() & value.ToInt32());
default:
return new IntPtr(ptr.ToInt64() & value.ToInt64());
}
if (IntPtr.Size == sizeof(Int32))
return new IntPtr(ptr.ToInt32() & value.ToInt32());
else
return new IntPtr(ptr.ToInt64() & value.ToInt64());
}
public static int CompareTo(this IntPtr ptr, IntPtr ptr2)
{
if (ptr.ToUInt64() > ptr2.ToUInt64())
return 1;
if (ptr.ToUInt64() < ptr2.ToUInt64())
return -1;
return 0;
}
@@ -74,22 +67,17 @@ namespace ProcessHacker.Native
{
if (ptr.ToUInt64() > ptr2)
return 1;
if (ptr.ToUInt64() < ptr2)
return -1;
return 0;
}
public static IntPtr Decrement(this IntPtr ptr, IntPtr ptr2)
{
switch (IntPtr.Size)
{
case sizeof(int):
return new IntPtr(ptr.ToInt32() - ptr2.ToInt32());
default:
return new IntPtr(ptr.ToInt64() - ptr2.ToInt64());
}
if (IntPtr.Size == sizeof(Int32))
return new IntPtr(ptr.ToInt32() - ptr2.ToInt32());
else
return new IntPtr(ptr.ToInt64() - ptr2.ToInt64());
}
public static IntPtr Decrement(this IntPtr ptr, int value)
@@ -102,6 +90,13 @@ namespace ProcessHacker.Native
return Increment(ptr, -value);
}
public static T ElementAt<T>(this IntPtr ptr, int index)
{
var offset = Marshal.SizeOf(typeof(T)) * index;
var offsetPtr = ptr.Increment(offset);
return (T)Marshal.PtrToStructure(offsetPtr, typeof(T));
}
public static bool Equals(this IntPtr ptr, IntPtr ptr2)
{
return ptr == ptr2;
@@ -131,13 +126,10 @@ namespace ProcessHacker.Native
{
unchecked
{
switch (IntPtr.Size)
{
case sizeof(int):
return new IntPtr(ptr.ToInt32() + value);
default:
return new IntPtr(ptr.ToInt64() + value);
}
if (IntPtr.Size == sizeof(Int32))
return new IntPtr(ptr.ToInt32() + value);
else
return new IntPtr(ptr.ToInt64() + value);
}
}
@@ -145,13 +137,10 @@ namespace ProcessHacker.Native
{
unchecked
{
switch (IntPtr.Size)
{
case sizeof(int):
return new IntPtr((int)(ptr.ToInt32() + value));
default:
return new IntPtr(ptr.ToInt64() + value);
}
if (IntPtr.Size == sizeof(Int32))
return new IntPtr((int)(ptr.ToInt32() + value));
else
return new IntPtr(ptr.ToInt64() + value);
}
}
@@ -159,16 +148,18 @@ namespace ProcessHacker.Native
{
unchecked
{
switch (IntPtr.Size)
{
case sizeof(int):
return new IntPtr(ptr.ToInt32() + ptr2.ToInt32());
default:
return new IntPtr(ptr.ToInt64() + ptr2.ToInt64());
}
if (IntPtr.Size == sizeof(Int32))
return new IntPtr(ptr.ToInt32() + ptr2.ToInt32());
else
return new IntPtr(ptr.ToInt64() + ptr2.ToInt64());
}
}
public static IntPtr Increment<T>(this IntPtr ptr)
{
return ptr.Increment(Marshal.SizeOf(typeof(T)));
}
public static bool IsGreaterThanOrEqualTo(this IntPtr ptr, IntPtr ptr2)
{
return ptr.CompareTo(ptr2) >= 0;
@@ -181,40 +172,40 @@ namespace ProcessHacker.Native
public static IntPtr Not(this IntPtr ptr)
{
switch (IntPtr.Size)
{
case sizeof(int):
return new IntPtr(~ptr.ToInt32());
default:
return new IntPtr(~ptr.ToInt64());
}
if (IntPtr.Size == sizeof(Int32))
return new IntPtr(~ptr.ToInt32());
else
return new IntPtr(~ptr.ToInt64());
}
public static IntPtr Or(this IntPtr ptr, IntPtr value)
{
switch (IntPtr.Size)
if (IntPtr.Size == sizeof(Int32))
return new IntPtr(ptr.ToInt32() | value.ToInt32());
else
return new IntPtr(ptr.ToInt64() | value.ToInt64());
}
public static uint ToUInt32(this IntPtr ptr)
{
// Avoid sign-extending the pointer - we want it zero-extended.
unsafe
{
case sizeof(int):
return new IntPtr(ptr.ToInt32() | value.ToInt32());
default:
return new IntPtr(ptr.ToInt64() | value.ToInt64());
void* voidPtr = (void*)ptr;
return (uint)voidPtr;
}
}
public unsafe static uint ToUInt32(this IntPtr ptr)
public static ulong ToUInt64(this IntPtr ptr)
{
// Avoid sign-extending the pointer - we want it zero-extended.
void* voidPtr = (void*)ptr;
unsafe
{
void* voidPtr = (void*)ptr;
return (uint)voidPtr;
}
public unsafe static ulong ToUInt64(this IntPtr ptr)
{
// Avoid sign-extending the pointer - we want it zero-extended.
void* voidPtr = (void*)ptr;
return (ulong)voidPtr;
return (ulong)voidPtr;
}
}
public static IntPtr ToIntPtr(this int value)
@@ -251,13 +242,10 @@ namespace ProcessHacker.Native
public static IntPtr Xor(this IntPtr ptr, IntPtr value)
{
switch (IntPtr.Size)
{
case sizeof(int):
return new IntPtr(ptr.ToInt32() ^ value.ToInt32());
default:
return new IntPtr(ptr.ToInt64() ^ value.ToInt64());
}
if (IntPtr.Size == sizeof(Int32))
return new IntPtr(ptr.ToInt32() ^ value.ToInt32());
else
return new IntPtr(ptr.ToInt64() ^ value.ToInt64());
}
}
}
@@ -13,15 +13,8 @@ namespace ProcessHacker.Native.Io
[StructLayout(LayoutKind.Sequential)]
public struct BeepSetParameters
{
public static readonly int SizeOf;
public int Frequency;
public int Duration;
static BeepSetParameters()
{
SizeOf = Marshal.SizeOf(typeof(BeepSetParameters));
}
}
public const int BeepFrequencyMinimum = 0x25;
@@ -29,15 +22,18 @@ namespace ProcessHacker.Native.Io
public static readonly int IoCtlSet = Win32.CtlCode(DeviceType.Beep, 0, DeviceControlMethod.Buffered, DeviceControlAccess.Any);
public static unsafe void Beep(int frequency, int duration)
public static void Beep(int frequency, int duration)
{
BeepSetParameters p;
unsafe
{
BeepSetParameters p;
p.Frequency = frequency;
p.Duration = duration;
p.Frequency = frequency;
p.Duration = duration;
using (var fhandle = OpenBeepDevice(FileAccess.GenericRead))
fhandle.IoControl(IoCtlSet, &p, BeepSetParameters.SizeOf, null, 0);
using (var fhandle = OpenBeepDevice(FileAccess.GenericRead))
fhandle.IoControl(IoCtlSet, &p, Marshal.SizeOf(typeof(BeepSetParameters)), null, 0);
}
}
private static FileHandle OpenBeepDevice(FileAccess access)
+35 -33
View File
@@ -1,5 +1,8 @@
using System.Runtime.InteropServices;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using ProcessHacker.Native;
using ProcessHacker.Native.Api;
using ProcessHacker.Native.Objects;
using ProcessHacker.Native.Security;
@@ -8,7 +11,7 @@ namespace ProcessHacker.Native.Io
{
public static class DiskDevice
{
public enum DiskCacheState
public enum DiskCacheState : int
{
Normal,
WriteThroughNotSupported,
@@ -19,17 +22,10 @@ namespace ProcessHacker.Native.Io
[StructLayout(LayoutKind.Sequential)]
public struct DiskCacheSetting
{
public static readonly int SizeOf;
public int Version;
public DiskCacheState State;
[MarshalAs(UnmanagedType.I1)]
public bool IsPowerProtected;
static DiskCacheSetting()
{
SizeOf = Marshal.SizeOf(typeof(DiskCacheSetting));
}
}
[StructLayout(LayoutKind.Sequential)]
@@ -71,21 +67,24 @@ namespace ProcessHacker.Native.Io
return GetCacheSetting(fhandle, out isPowerProtected);
}
public static unsafe DiskCacheState GetCacheSetting(FileHandle fileHandle, out bool isPowerProtected)
public static DiskCacheState GetCacheSetting(FileHandle fileHandle, out bool isPowerProtected)
{
DiskCacheSetting diskCacheSetting;
unsafe
{
DiskCacheSetting diskCacheSetting;
fileHandle.IoControl(
IoCtlGetCacheSetting,
null,
0,
&diskCacheSetting,
DiskCacheSetting.SizeOf
);
fileHandle.IoControl(
IoCtlGetCacheSetting,
null,
0,
&diskCacheSetting,
Marshal.SizeOf(typeof(DiskCacheSetting))
);
isPowerProtected = diskCacheSetting.IsPowerProtected;
isPowerProtected = diskCacheSetting.IsPowerProtected;
return diskCacheSetting.State;
return diskCacheSetting.State;
}
}
public static void SetCacheSetting(string fileName, DiskCacheState state, bool isPowerProtected)
@@ -94,21 +93,24 @@ namespace ProcessHacker.Native.Io
SetCacheSetting(fhandle, state, isPowerProtected);
}
public static unsafe void SetCacheSetting(FileHandle fileHandle, DiskCacheState state, bool isPowerProtected)
public static void SetCacheSetting(FileHandle fileHandle, DiskCacheState state, bool isPowerProtected)
{
DiskCacheSetting diskCacheSetting;
unsafe
{
DiskCacheSetting diskCacheSetting;
diskCacheSetting.Version = DiskCacheSetting.SizeOf;
diskCacheSetting.State = state;
diskCacheSetting.IsPowerProtected = isPowerProtected;
diskCacheSetting.Version = Marshal.SizeOf(typeof(DiskCacheSetting));
diskCacheSetting.State = state;
diskCacheSetting.IsPowerProtected = isPowerProtected;
fileHandle.IoControl(
IoCtlSetCacheSetting,
&diskCacheSetting,
DiskCacheSetting.SizeOf,
null,
0
);
fileHandle.IoControl(
IoCtlSetCacheSetting,
&diskCacheSetting,
Marshal.SizeOf(typeof(DiskCacheSetting)),
null,
0
);
}
}
}
}
@@ -21,7 +21,10 @@
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using ProcessHacker.Native;
using ProcessHacker.Native.Api;
using ProcessHacker.Native.Objects;
using ProcessHacker.Native.Security;
@@ -44,12 +47,7 @@ namespace ProcessHacker.Native.Io
[StructLayout(LayoutKind.Sequential)]
public struct MountMgrMountPoint
{
public static readonly int SizeOf;
static MountMgrMountPoint()
{
SizeOf = Marshal.SizeOf(typeof(MountMgrMountPoint));
}
public static readonly int Size = Marshal.SizeOf(typeof(MountMgrMountPoint));
public int SymbolicLinkNameOffset;
public ushort SymbolicLinkNameLength;
@@ -96,17 +94,12 @@ namespace ProcessHacker.Native.Io
[StructLayout(LayoutKind.Sequential)]
public struct MountMgrVolumeMountPoint
{
public static readonly int SizeOf;
public static readonly int Size = Marshal.SizeOf(typeof(MountMgrVolumeMountPoint));
public ushort SourceVolumeNameOffset;
public ushort SourceVolumeNameLength;
public ushort TargetVolumeNameOffset;
public ushort TargetVolumeNameLength;
static MountMgrVolumeMountPoint()
{
SizeOf = Marshal.SizeOf(typeof(MountMgrVolumeMountPoint));
}
}
// Input, output for IoCtlChangeNotify
@@ -172,16 +165,14 @@ namespace ProcessHacker.Native.Io
private static void DeleteSymbolicLink(string path)
{
using (MemoryAlloc data = new MemoryAlloc(MountMgrMountPoint.SizeOf + path.Length * 2))
using (MemoryAlloc outData = new MemoryAlloc(1600))
using (var data = new MemoryAlloc(MountMgrMountPoint.Size + path.Length * 2))
using (var outData = new MemoryAlloc(1600))
{
MountMgrMountPoint mountPoint = new MountMgrMountPoint
{
SymbolicLinkNameLength = (ushort)(path.Length*2),
SymbolicLinkNameOffset = MountMgrMountPoint.SizeOf
};
MountMgrMountPoint mountPoint = new MountMgrMountPoint();
data.WriteStruct(mountPoint);
mountPoint.SymbolicLinkNameLength = (ushort)(path.Length * 2);
mountPoint.SymbolicLinkNameOffset = MountMgrMountPoint.Size;
data.WriteStruct<MountMgrMountPoint>(mountPoint);
data.WriteUnicodeString(mountPoint.SymbolicLinkNameOffset, path);
using (var fhandle = OpenMountManager(FileAccess.GenericRead | FileAccess.GenericWrite))
@@ -201,7 +192,7 @@ namespace ProcessHacker.Native.Io
/// <returns>The device name associated with the DOS drive.</returns>
public static string GetDeviceName(string fileName)
{
using (FileHandle fhandle = new FileHandle(
using (var fhandle = new FileHandle(
fileName,
FileShareMode.ReadWrite,
FileCreateOptions.SynchronousIoNonAlert,
@@ -212,7 +203,7 @@ namespace ProcessHacker.Native.Io
public static string GetDeviceName(FileHandle fhandle)
{
using (MemoryAlloc data = new MemoryAlloc(600))
using (var data = new MemoryAlloc(600))
{
fhandle.IoControl(IoCtlQueryDeviceName, IntPtr.Zero, 0, data, data.Size);
@@ -224,7 +215,7 @@ namespace ProcessHacker.Native.Io
private static string GetReparsePointTarget(FileHandle fhandle)
{
using (MemoryAlloc data = new MemoryAlloc(FileSystem.MaximumReparseDataBufferSize))
using (var data = new MemoryAlloc(FileSystem.MaximumReparseDataBufferSize))
{
fhandle.IoControl(FileSystem.FsCtlGetReparsePoint, IntPtr.Zero, 0, data, data.Size);
@@ -299,15 +290,13 @@ namespace ProcessHacker.Native.Io
public static string GetVolumeName(string deviceName)
{
using (MemoryAlloc data = new MemoryAlloc(MountMgrMountPoint.SizeOf + deviceName.Length * 2))
using (var data = new MemoryAlloc(MountMgrMountPoint.Size + deviceName.Length * 2))
{
MountMgrMountPoint mountPoint = new MountMgrMountPoint
{
DeviceNameLength = (ushort)(deviceName.Length*2),
DeviceNameOffset = MountMgrMountPoint.SizeOf
};
MountMgrMountPoint mountPoint = new MountMgrMountPoint();
data.WriteStruct(mountPoint);
mountPoint.DeviceNameLength = (ushort)(deviceName.Length * 2);
mountPoint.DeviceNameOffset = MountMgrMountPoint.Size;
data.WriteStruct<MountMgrMountPoint>(mountPoint);
data.WriteUnicodeString(mountPoint.DeviceNameOffset, deviceName);
using (var fhandle = OpenMountManager((FileAccess)StandardRights.Synchronize))
@@ -315,7 +304,7 @@ namespace ProcessHacker.Native.Io
NtStatus status;
int retLength;
using (MemoryAlloc outData = new MemoryAlloc(0x100))
using (var outData = new MemoryAlloc(0x100))
{
while (true)
{
@@ -339,7 +328,8 @@ namespace ProcessHacker.Native.Io
}
}
status.ThrowIf();
if (status >= NtStatus.Error)
Win32.Throw(status);
MountMgrMountPoints mountPoints = outData.ReadStruct<MountMgrMountPoints>();
@@ -349,11 +339,11 @@ namespace ProcessHacker.Native.Io
{
MountMgrMountPoint mp = outData.ReadStruct<MountMgrMountPoint>(
MountMgrMountPoints.MountPointsOffset,
MountMgrMountPoint.SizeOf,
i
);
string symLinkName;
string symLinkName = Marshal.PtrToStringUni(
symLinkName = Marshal.PtrToStringUni(
outData.Memory.Increment(mp.SymbolicLinkNameOffset),
mp.SymbolicLinkNameLength / 2
);
@@ -372,20 +362,20 @@ namespace ProcessHacker.Native.Io
{
if (
path.Length == 14 &&
path.StartsWith(@"\DosDevices\", StringComparison.OrdinalIgnoreCase) &&
path.StartsWith(@"\DosDevices\") &&
path[12] >= 'A' && path[12] <= 'Z' &&
path[13] == ':'
)
return true;
return false;
else
return false;
}
public static bool IsVolumePath(string path)
{
if (
(path.Length == 48 || (path.Length == 49 && path[48] == '\\')) &&
(path.StartsWith(@"\??\Volume", StringComparison.OrdinalIgnoreCase) || path.StartsWith(@"\\?\Volume", StringComparison.OrdinalIgnoreCase)) &&
(path.StartsWith(@"\??\Volume") || path.StartsWith(@"\\?\Volume")) &&
path[10] == '{' &&
path[19] == '-' &&
path[24] == '-' &&
@@ -394,32 +384,31 @@ namespace ProcessHacker.Native.Io
path[47] == '}'
)
return true;
return false;
else
return false;
}
private static void Notify(bool created, string sourceVolumeName, string targetVolumeName)
{
using (MemoryAlloc data = new MemoryAlloc(
MountMgrVolumeMountPoint.SizeOf +
using (var data = new MemoryAlloc(
MountMgrVolumeMountPoint.Size +
sourceVolumeName.Length * 2 +
targetVolumeName.Length * 2
))
{
MountMgrVolumeMountPoint mountPoint = new MountMgrVolumeMountPoint
{
SourceVolumeNameLength = (ushort)(sourceVolumeName.Length * 2),
SourceVolumeNameOffset = (ushort)MountMgrVolumeMountPoint.SizeOf,
TargetVolumeNameLength = (ushort)(targetVolumeName.Length * 2)
};
MountMgrVolumeMountPoint mountPoint = new MountMgrVolumeMountPoint();
mountPoint.TargetVolumeNameOffset = (ushort)(mountPoint.SourceVolumeNameOffset + mountPoint.SourceVolumeNameLength);
mountPoint.SourceVolumeNameLength = (ushort)(sourceVolumeName.Length * 2);
mountPoint.SourceVolumeNameOffset = (ushort)MountMgrVolumeMountPoint.Size;
mountPoint.TargetVolumeNameLength = (ushort)(targetVolumeName.Length * 2);
mountPoint.TargetVolumeNameOffset =
(ushort)(mountPoint.SourceVolumeNameOffset + mountPoint.SourceVolumeNameLength);
data.WriteStruct(mountPoint);
data.WriteStruct<MountMgrVolumeMountPoint>(mountPoint);
data.WriteUnicodeString(mountPoint.SourceVolumeNameOffset, sourceVolumeName);
data.WriteUnicodeString(mountPoint.TargetVolumeNameOffset, targetVolumeName);
using (FileHandle fhandle = OpenMountManager(FileAccess.GenericRead | FileAccess.GenericWrite))
using (var fhandle = OpenMountManager(FileAccess.GenericRead | FileAccess.GenericWrite))
{
fhandle.IoControl(
created ? IoCtlVolumeMountPointCreated : IoCtlVolumeMountPointDeleted,
@@ -23,8 +23,6 @@ namespace ProcessHacker.Native.Io
[StructLayout(LayoutKind.Sequential)]
public struct StorageHotplugInfo
{
public static readonly int SizeOf;
public int Size;
[MarshalAs(UnmanagedType.I1)]
public bool MediaRemovable;
@@ -34,11 +32,6 @@ namespace ProcessHacker.Native.Io
public bool DeviceHotplug;
[MarshalAs(UnmanagedType.I1)]
public bool WriteCacheEnableOverride;
static StorageHotplugInfo()
{
SizeOf = Marshal.SizeOf(typeof(StorageHotplugInfo));
}
}
public static readonly int IoCtlMediaRemoval = Win32.CtlCode(DeviceType.MassStorage, 0x0201, DeviceControlMethod.Buffered, DeviceControlAccess.Read);
@@ -68,13 +61,16 @@ namespace ProcessHacker.Native.Io
return GetHotplugInfo(fhandle);
}
public static unsafe StorageHotplugInfo GetHotplugInfo(FileHandle fileHandle)
public static StorageHotplugInfo GetHotplugInfo(FileHandle fileHandle)
{
StorageHotplugInfo hotplugInfo;
unsafe
{
StorageHotplugInfo hotplugInfo;
fileHandle.IoControl(IoCtlGetHotplugInfo, null, 0, &hotplugInfo, StorageHotplugInfo.SizeOf);
fileHandle.IoControl(IoCtlGetHotplugInfo, null, 0, &hotplugInfo, Marshal.SizeOf(typeof(StorageHotplugInfo)));
return hotplugInfo;
return hotplugInfo;
}
}
public static FileHandle OpenStorageDevice(string fileName, FileAccess access)
@@ -28,18 +28,11 @@ using ProcessHacker.Native.Threading;
namespace ProcessHacker.Native.Ipc
{
public unsafe class IpcCircularBuffer : IDisposable
public unsafe class IpcCircularBuffer
{
[StructLayout(LayoutKind.Sequential)]
public struct BufferHeader
private struct BufferHeader
{
public static readonly int SizeOf;
static BufferHeader()
{
SizeOf = Marshal.SizeOf(typeof(BufferHeader));
}
public int BlockSize;
public int NumberOfBlocks;
@@ -57,21 +50,22 @@ namespace ProcessHacker.Native.Ipc
Random r = new Random();
long readSemaphoreId = ((long)r.Next() << 32) + r.Next();
long writeSemaphoreId = ((long)r.Next() << 32) + r.Next();
Section section;
Section section = new Section(name, blockSize * numberOfBlocks, MemoryProtection.ReadWrite);
section = new Section(name, blockSize * numberOfBlocks, MemoryProtection.ReadWrite);
using (SectionView view = section.MapView(BufferHeader.SizeOf))
using (var view = section.MapView(Marshal.SizeOf(typeof(BufferHeader))))
{
BufferHeader header = new BufferHeader
{
BlockSize = blockSize,
NumberOfBlocks = numberOfBlocks,
ReadSemaphoreId = readSemaphoreId,
WriteSemaphoreId = writeSemaphoreId,
ReadPosition = 0, WritePosition = 0
};
BufferHeader header = new BufferHeader();
view.WriteStruct(header);
header.BlockSize = blockSize;
header.NumberOfBlocks = numberOfBlocks;
header.ReadSemaphoreId = readSemaphoreId;
header.WriteSemaphoreId = writeSemaphoreId;
header.ReadPosition = 0;
header.WritePosition = 0;
view.WriteStruct<BufferHeader>(header);
}
return new IpcCircularBuffer(
@@ -87,13 +81,13 @@ namespace ProcessHacker.Native.Ipc
return new IpcCircularBuffer(new Section(name, SectionAccess.All), name, null, null);
}
private readonly Section _section;
private readonly SectionView _sectionView;
private readonly Semaphore _readSemaphore;
private readonly Semaphore _writeSemaphore;
private Section _section;
private SectionView _sectionView;
private Semaphore _readSemaphore;
private Semaphore _writeSemaphore;
private readonly BufferHeader* _header;
private readonly void* _data;
private BufferHeader* _header;
private void* _data;
private IpcCircularBuffer(Section section, string sectionName, Semaphore readSemaphore, Semaphore writeSemaphore)
{
@@ -101,7 +95,7 @@ namespace ProcessHacker.Native.Ipc
_section = section;
_sectionView = section.MapView(BufferHeader.SizeOf);
_sectionView = section.MapView(Marshal.SizeOf(typeof(BufferHeader)));
header = _sectionView.ReadStruct<BufferHeader>();
_sectionView.Dispose();
@@ -121,17 +115,16 @@ namespace ProcessHacker.Native.Ipc
_data = &_header->Data;
}
public T Read<T>() where T : struct
public T Read<T>()
where T : struct
{
using (MemoryAlloc data = this.Read())
{
using (var data = this.Read())
return data.ReadStruct<T>();
}
}
public MemoryAlloc Read()
{
MemoryAlloc data = new MemoryAlloc(_header->BlockSize);
var data = new MemoryAlloc(_header->BlockSize);
this.Read(data);
@@ -175,12 +168,13 @@ namespace ProcessHacker.Native.Ipc
_writeSemaphore.Release();
}
public void Write<T>(int size, T s) where T : struct
public void Write<T>(T s)
where T : struct
{
using (MemoryAlloc data = new MemoryAlloc(size))
using (var data = new MemoryAlloc(Marshal.SizeOf(typeof(T))))
{
data.WriteStruct(s);
this.Write(data);
data.WriteStruct<T>(s);
this.Write((MemoryRegion)data);
}
}
@@ -225,14 +219,5 @@ namespace ProcessHacker.Native.Ipc
// Release the read semaphore to allow a reader to read one more block.
_readSemaphore.Release();
}
public void Dispose()
{
if (_readSemaphore != null)
_readSemaphore.Dispose();
if (_writeSemaphore != null)
_writeSemaphore.Dispose();
}
}
}
File diff suppressed because it is too large Load Diff
+2
View File
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using ProcessHacker.Native.Api;
namespace ProcessHacker.Native
@@ -1,4 +1,5 @@
using System;
using System.Runtime.InteropServices;
using ProcessHacker.Common.Objects;
using ProcessHacker.Native.Api;
@@ -6,6 +7,8 @@ namespace ProcessHacker.Native.Lpc
{
public class PortMessage : BaseObject
{
private static readonly int _portMessageSize = Marshal.SizeOf(typeof(PortMessageStruct));
public static MemoryAlloc AllocateBuffer()
{
return new MemoryAlloc(Win32.PortMessageMaxLength);
@@ -40,7 +43,7 @@ namespace ProcessHacker.Native.Lpc
internal PortMessage(MemoryRegion headerAndData)
{
_message = headerAndData.ReadStruct<PortMessageStruct>();
_data = new MemoryRegion(headerAndData, PortMessageStruct.SizeOf, _message.DataLength);
_data = new MemoryRegion(headerAndData, _portMessageSize, _message.DataLength);
_referencedData = headerAndData;
_referencedData.Reference();
@@ -89,12 +92,11 @@ namespace ProcessHacker.Native.Lpc
if (dataLength < 0)
throw new ArgumentOutOfRangeException("Data length cannot be negative.");
_message = new PortMessageStruct
{
DataLength = dataLength,
TotalLength = (short)(PortMessageStruct.SizeOf + dataLength),
DataInfoOffset = 0
};
_message = new PortMessageStruct();
_message.DataLength = dataLength;
_message.TotalLength = (short)(_portMessageSize + dataLength);
_message.DataInfoOffset = 0;
if (existingMessage != null)
{
@@ -115,10 +117,10 @@ namespace ProcessHacker.Native.Lpc
public MemoryAlloc ToMemory()
{
MemoryAlloc data = new MemoryAlloc(PortMessageStruct.SizeOf + _message.DataLength);
MemoryAlloc data = new MemoryAlloc(_portMessageSize + _message.DataLength);
data.WriteStruct(_message);
data.WriteMemory(PortMessageStruct.SizeOf, _data, _message.DataLength);
data.WriteStruct<PortMessageStruct>(_message);
data.WriteMemory(_portMessageSize, _data, _message.DataLength);
return data;
}
@@ -1,21 +1,23 @@
using System;
using System.Collections.Generic;
using System.Text;
using ProcessHacker.Common;
namespace ProcessHacker.Native
{
public sealed class AlignedMemoryAlloc : MemoryAlloc
public class AlignedMemoryAlloc : MemoryAlloc
{
private readonly IntPtr _realMemory;
private IntPtr _realMemory;
public AlignedMemoryAlloc(int size, int alignment)
{
// Make sure the alignment is positive and a power of two.
if (alignment <= 0 || alignment.CountBits() != 1)
if (alignment <= 0 || Utils.CountBits(alignment) != 1)
throw new ArgumentOutOfRangeException("alignment");
// Since we are going to align our pointer, we need to account for
// any padding at the beginning.
_realMemory = PrivateHeap.Allocate(size + alignment - 1);
_realMemory = MemoryAlloc.PrivateHeap.Allocate(0, size + alignment - 1);
// aligned memory = (memory + alignment - 1) & ~(alignment - 1)
this.Memory = _realMemory.Align(alignment);
@@ -24,7 +26,7 @@ namespace ProcessHacker.Native
protected override void Free()
{
PrivateHeap.Free(_realMemory);
MemoryAlloc.PrivateHeap.Free(0, _realMemory);
}
public override void Resize(int newSize)
+11 -15
View File
@@ -60,13 +60,11 @@ namespace ProcessHacker.Native
return heaps;
}
private readonly IntPtr _heap;
private readonly HeapFlags _flags;
private IntPtr _heap;
private Heap(IntPtr heap)
{
_heap = heap;
_flags = 0;
}
public Heap(HeapFlags flags)
@@ -86,8 +84,6 @@ namespace ProcessHacker.Native
if (_heap == IntPtr.Zero)
throw new OutOfMemoryException();
_flags = flags;
}
public IntPtr Address
@@ -95,9 +91,9 @@ namespace ProcessHacker.Native
get { return _heap; }
}
public IntPtr Allocate(int size)
public IntPtr Allocate(HeapFlags flags, int size)
{
IntPtr memory = Win32.RtlAllocateHeap(_heap, _flags, size.ToIntPtr());
IntPtr memory = Win32.RtlAllocateHeap(_heap, flags, size.ToIntPtr());
if (memory == IntPtr.Zero)
throw new OutOfMemoryException();
@@ -105,9 +101,9 @@ namespace ProcessHacker.Native
return memory;
}
public int Compact()
public int Compact(HeapFlags flags)
{
return Win32.RtlCompactHeap(_heap, _flags).ToInt32();
return Win32.RtlCompactHeap(_heap, flags).ToInt32();
}
public void Destroy()
@@ -115,19 +111,19 @@ namespace ProcessHacker.Native
Win32.RtlDestroyHeap(_heap);
}
public void Free(IntPtr memory)
public void Free(HeapFlags flags, IntPtr memory)
{
Win32.RtlFreeHeap(_heap, _flags, memory);
Win32.RtlFreeHeap(_heap, flags, memory);
}
public int GetBlockSize(IntPtr memory)
public int GetBlockSize(HeapFlags flags, IntPtr memory)
{
return Win32.RtlSizeHeap(_heap, _flags, memory).ToInt32();
return Win32.RtlSizeHeap(_heap, flags, memory).ToInt32();
}
public IntPtr Reallocate(IntPtr memory, int size)
public IntPtr Reallocate(HeapFlags flags, IntPtr memory, int size)
{
IntPtr newMemory = Win32.RtlReAllocateHeap(_heap, _flags, memory, size.ToIntPtr());
IntPtr newMemory = Win32.RtlReAllocateHeap(_heap, flags, memory, size.ToIntPtr());
if (newMemory == IntPtr.Zero)
throw new OutOfMemoryException();
@@ -31,7 +31,7 @@ namespace ProcessHacker.Native
/// </summary>
public sealed class LsaMemoryAlloc : MemoryAlloc
{
private readonly bool _secur32;
private bool _secur32;
public LsaMemoryAlloc(IntPtr memory)
: this(memory, false)
@@ -20,11 +20,13 @@
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#if DEBUG
#define ENABLE_STATISTICS
#endif
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using ProcessHacker.Common.Objects;
using ProcessHacker.Native.Api;
namespace ProcessHacker.Native
@@ -34,13 +36,13 @@ namespace ProcessHacker.Native
/// </summary>
public class MemoryAlloc : MemoryRegion
{
private static int _allocatedCount;
private static int _freedCount;
private static int _reallocatedCount;
private static int _allocatedCount = 0;
private static int _freedCount = 0;
private static int _reallocatedCount = 0;
// A private heap just for the client.
private static Heap _privateHeap = new Heap(HeapFlags.Class1 | HeapFlags.Growable);
//private static Heap _processHeap = Heap.GetDefault();
private static Heap _processHeap = Heap.GetDefault();
public static int AllocatedCount
{
@@ -67,6 +69,7 @@ namespace ProcessHacker.Native
/// You must set the pointer using the Memory property.
/// </summary>
protected MemoryAlloc()
: base()
{ }
public MemoryAlloc(IntPtr memory)
@@ -96,25 +99,21 @@ namespace ProcessHacker.Native
/// <param name="flags">Any flags to use.</param>
public MemoryAlloc(int size, HeapFlags flags)
{
this.Memory = _privateHeap.Allocate(size);
this.Memory = _privateHeap.Allocate(flags, size);
this.Size = size;
#if ENABLE_STATISTICS
System.Threading.Interlocked.Increment(ref _allocatedCount);
#endif
if (this.Size > 0)
GC.AddMemoryPressure(this.Size);
}
protected override void Free()
{
_privateHeap.Free(this);
_privateHeap.Free(0, this);
#if ENABLE_STATISTICS
System.Threading.Interlocked.Increment(ref _freedCount);
#endif
if (this.Size > 0)
GC.RemoveMemoryPressure(this.Size);
}
/// <summary>
@@ -123,17 +122,12 @@ namespace ProcessHacker.Native
/// <param name="newSize">The new size of the allocation.</param>
public virtual void Resize(int newSize)
{
if (newSize > 0)
GC.RemoveMemoryPressure(this.Size);
this.Memory = _privateHeap.Reallocate(this.Memory, newSize);
this.Memory = _privateHeap.Reallocate(0, this.Memory, newSize);
this.Size = newSize;
#if ENABLE_STATISTICS
System.Threading.Interlocked.Increment(ref _reallocatedCount);
#endif
if (this.Size > 0)
GC.AddMemoryPressure(this.Size);
}
/// <summary>
@@ -143,16 +137,9 @@ namespace ProcessHacker.Native
/// <param name="newSize">The new size of the allocation.</param>
public virtual void ResizeNew(int newSize)
{
if (newSize > 0)
GC.RemoveMemoryPressure(this.Size);
_privateHeap.Free(this.Memory);
this.Memory = _privateHeap.Allocate(newSize);
_privateHeap.Free(0, this.Memory);
this.Memory = _privateHeap.Allocate(0, newSize);
this.Size = newSize;
if (this.Size > 0)
GC.AddMemoryPressure(this.Size);
}
}
}
@@ -20,15 +20,68 @@
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#define SIZE_CACHE_USE_RESOURCE_LOCK
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using ProcessHacker.Common.Objects;
using ProcessHacker.Native.Api;
using ProcessHacker.Common.Threading;
namespace ProcessHacker.Native
{
public class MemoryRegion : BaseObject
{
private static Dictionary<Type, int> _sizeCache = new Dictionary<Type, int>();
#if SIZE_CACHE_USE_RESOURCE_LOCK
private static FastResourceLock _sizeCacheLock = new FastResourceLock();
#endif
private static int GetStructSize(Type structType)
{
int size;
#if SIZE_CACHE_USE_RESOURCE_LOCK
_sizeCacheLock.AcquireShared();
if (_sizeCache.ContainsKey(structType))
{
size = _sizeCache[structType];
_sizeCacheLock.ReleaseShared();
}
else
{
_sizeCacheLock.ReleaseShared();
size = Marshal.SizeOf(structType);
_sizeCacheLock.AcquireExclusive();
try
{
if (!_sizeCache.ContainsKey(structType))
_sizeCache.Add(structType, size);
}
finally
{
_sizeCacheLock.ReleaseExclusive();
}
}
return size;
#else
lock (_sizeCache)
{
if (_sizeCache.ContainsKey(structType))
size = _sizeCache[structType];
else
_sizeCache.Add(structType, size = Marshal.SizeOf(structType));
return size;
}
#endif
}
public static T ReadStruct<T>(IntPtr ptr)
{
return (T)Marshal.PtrToStructure(ptr, typeof(T));
@@ -44,7 +97,7 @@ namespace ProcessHacker.Native
return memory.Memory.ToPointer();
}
private readonly MemoryRegion _parent;
private MemoryRegion _parent;
private IntPtr _memory;
private int _size;
@@ -121,15 +174,15 @@ namespace ProcessHacker.Native
public void DestroyStruct<T>()
{
Marshal.DestroyStructure(_memory, typeof(T));
this.DestroyStruct<T>(0);
}
public void DestroyStruct<T>(int index, int size)
public void DestroyStruct<T>(int index)
{
this.DestroyStruct<T>(0, index, size);
this.DestroyStruct<T>(0, index);
}
public void DestroyStruct<T>(int offset, int index, int size)
public void DestroyStruct<T>(int offset, int index)
{
if (index == 0)
{
@@ -138,7 +191,7 @@ namespace ProcessHacker.Native
else
{
Marshal.DestroyStructure(
_memory.Increment(offset + size * index),
_memory.Increment(offset + GetStructSize(typeof(T)) * index),
typeof(T)
);
}
@@ -146,7 +199,7 @@ namespace ProcessHacker.Native
public void Fill(int offset, int length, byte value)
{
Win32.RtlFillMemory(
ProcessHacker.Native.Api.Win32.RtlFillMemory(
_memory.Increment(offset),
length.ToIntPtr(),
value
@@ -213,9 +266,12 @@ namespace ProcessHacker.Native
/// <param name="offset">The offset at which to begin reading.</param>
/// <param name="index">The index at which to begin reading, after the offset is added.</param>
/// <returns>The integer.</returns>
public unsafe int ReadInt32(int offset, int index)
public int ReadInt32(int offset, int index)
{
return ((int*)((byte*)this._memory + offset))[index];
unsafe
{
return ((int*)((byte*)_memory + offset))[index];
}
}
public int[] ReadInt32Array(int offset, int count)
@@ -232,14 +288,17 @@ namespace ProcessHacker.Native
return this.ReadIntPtr(offset, 0);
}
public unsafe IntPtr ReadIntPtr(int offset, int index)
public IntPtr ReadIntPtr(int offset, int index)
{
return ((IntPtr*)((byte*)this._memory + offset))[index];
unsafe
{
return ((IntPtr*)((byte*)_memory + offset))[index];
}
}
public void ReadMemory(IntPtr buffer, int destOffset, int srcOffset, int length)
{
Win32.RtlMoveMemory(
ProcessHacker.Native.Api.Win32.RtlMoveMemory(
buffer.Increment(destOffset),
_memory.Increment(srcOffset),
length.ToIntPtr()
@@ -262,14 +321,36 @@ namespace ProcessHacker.Native
/// <param name="offset">The offset at which to begin reading.</param>
/// <param name="index">The index at which to begin reading, after the offset is added.</param>
/// <returns>The integer.</returns>
public unsafe uint ReadUInt32(int offset, int index)
public uint ReadUInt32(int offset, int index)
{
return ((uint*)((byte*)this._memory + offset))[index];
unsafe
{
return ((uint*)((byte*)_memory + offset))[index];
}
}
public T ReadStruct<T>() where T : struct
/// <summary>
/// Creates a struct from the memory allocation.
/// </summary>
/// <typeparam name="T">The type of the struct.</typeparam>
/// <returns>The new struct.</returns>
public T ReadStruct<T>()
where T : struct
{
return (T)Marshal.PtrToStructure(_memory, typeof(T));
return this.ReadStruct<T>(0);
}
/// <summary>
/// Creates a struct from the memory allocation.
/// </summary>
/// <typeparam name="T">The type of the struct.</typeparam>
/// <param name="index">The index at which to begin reading to the struct. This is multiplied by
/// the size of the struct.</param>
/// <returns>The new struct.</returns>
public T ReadStruct<T>(int index)
where T : struct
{
return this.ReadStruct<T>(0, index);
}
/// <summary>
@@ -277,18 +358,23 @@ namespace ProcessHacker.Native
/// </summary>
/// <typeparam name="T">The type of the struct.</typeparam>
/// <param name="offset">The offset to add before reading.</param>
/// <param name="size"></param>
/// <param name="index">The index at which to begin reading to the struct. This is multiplied by
/// the size of the struct.</param>
/// <returns>The new struct.</returns>
public T ReadStruct<T>(int offset, int size, int index) where T : struct
public T ReadStruct<T>(int offset, int index)
where T : struct
{
if (index == 0)
{
return (T)Marshal.PtrToStructure(_memory.Increment(offset), typeof(T));
}
return (T)Marshal.PtrToStructure(this._memory.Increment(offset + size * index), typeof(T));
else
{
return (T)Marshal.PtrToStructure(
_memory.Increment(offset + GetStructSize(typeof(T)) * index),
typeof(T)
);
}
}
public string ReadUnicodeString(int offset)
@@ -306,9 +392,12 @@ namespace ProcessHacker.Native
/// </summary>
/// <param name="offset">The offset at which to write.</param>
/// <param name="b">The value of the byte.</param>
public unsafe void WriteByte(int offset, byte b)
public void WriteByte(int offset, byte b)
{
*((byte*)this._memory + offset) = b;
unsafe
{
*((byte*)_memory + offset) = b;
}
}
public void WriteBytes(int offset, byte[] b)
@@ -316,41 +405,53 @@ namespace ProcessHacker.Native
Marshal.Copy(b, 0, _memory.Increment(offset), b.Length);
}
public unsafe void WriteInt16(int offset, short i)
public void WriteInt16(int offset, short i)
{
*(short*)((byte*)this._memory + offset) = i;
unsafe
{
*(short*)((byte*)_memory + offset) = i;
}
}
public unsafe void WriteInt32(int offset, int i)
public void WriteInt32(int offset, int i)
{
*(int*)((byte*)this._memory + offset) = i;
unsafe
{
*(int*)((byte*)_memory + offset) = i;
}
}
public unsafe void WriteIntPtr(int offset, IntPtr i)
public void WriteIntPtr(int offset, IntPtr i)
{
*(IntPtr*)((byte*)this._memory + offset) = i;
unsafe
{
*(IntPtr*)((byte*)_memory + offset) = i;
}
}
public void WriteMemory(int offset, IntPtr buffer, int length)
{
Win32.RtlMoveMemory(
ProcessHacker.Native.Api.Win32.RtlMoveMemory(
_memory.Increment(offset),
buffer,
length.ToIntPtr()
);
}
public void WriteStruct<T>(T s) where T : struct
public void WriteStruct<T>(T s)
where T : struct
{
Marshal.StructureToPtr(s, _memory, false);
this.WriteStruct<T>(0, s);
}
public void WriteStruct<T>(int index, int size, T s) where T : struct
public void WriteStruct<T>(int index, T s)
where T : struct
{
this.WriteStruct(0, size, index, s);
this.WriteStruct<T>(0, index, s);
}
public void WriteStruct<T>(int offset, int size, int index, T s) where T : struct
public void WriteStruct<T>(int offset, int index, T s)
where T : struct
{
if (index == 0)
{
@@ -360,7 +461,7 @@ namespace ProcessHacker.Native
{
Marshal.StructureToPtr(
s,
_memory.Increment(offset + size * index),
_memory.Increment(offset + GetStructSize(typeof(T)) * index),
false
);
}
@@ -371,17 +472,20 @@ namespace ProcessHacker.Native
/// </summary>
/// <param name="offset">The offset to add.</param>
/// <param name="s">The string to write.</param>
public unsafe void WriteUnicodeString(int offset, string s)
public void WriteUnicodeString(int offset, string s)
{
fixed (char* ptr = s)
unsafe
{
this.WriteMemory(offset, (IntPtr)ptr, s.Length * 2);
fixed (char* ptr = s)
{
this.WriteMemory(offset, (IntPtr)ptr, s.Length * 2);
}
}
}
public void Zero(int offset, int length)
{
Win32.RtlZeroMemory(
ProcessHacker.Native.Api.Win32.RtlZeroMemory(
_memory.Increment(offset),
length.ToIntPtr()
);
@@ -28,8 +28,8 @@ namespace ProcessHacker.Native
{
public class MemoryRegionStream : Stream
{
private readonly MemoryRegion _memory;
private long _position;
private MemoryRegion _memory;
private long _position = 0;
public MemoryRegionStream(MemoryRegion memory)
{
@@ -86,18 +86,12 @@ namespace ProcessHacker.Native
public override long Seek(long offset, SeekOrigin origin)
{
switch (origin)
{
case SeekOrigin.Begin:
this._position = offset;
break;
case SeekOrigin.Current:
this._position += offset;
break;
case SeekOrigin.End:
this._position = this._memory.Size + offset;
break;
}
if (origin == SeekOrigin.Begin)
_position = offset;
else if (origin == SeekOrigin.Current)
_position += offset;
else if (origin == SeekOrigin.End)
_position = _memory.Size + offset;
return _position;
}
@@ -33,9 +33,11 @@ namespace ProcessHacker.Native
{
public PebMemoryAlloc(int size)
{
NtStatus status;
IntPtr block;
Win32.RtlAllocateFromPeb(size, out block).ThrowIf();
if ((status = Win32.RtlAllocateFromPeb(size, out block)) >= NtStatus.Error)
Win32.Throw(status);
this.Memory = block;
this.Size = size;
@@ -43,7 +45,10 @@ namespace ProcessHacker.Native
protected override void Free()
{
Win32.RtlFreeToPeb(this, this.Size).ThrowIf();
NtStatus status;
if ((status = Win32.RtlFreeToPeb(this, this.Size)) >= NtStatus.Error)
Win32.Throw(status);
}
[EditorBrowsable(EditorBrowsableState.Never)]
@@ -10,9 +10,9 @@ namespace ProcessHacker.Native.Memory
/// </summary>
public sealed class PhysicalPages : BaseObject
{
private readonly ProcessHandle _processHandle;
private readonly int _count;
private readonly IntPtr[] _pfnArray;
private ProcessHandle _processHandle;
private int _count;
private IntPtr[] _pfnArray;
/// <summary>
/// Allocates physical pages.
@@ -1,10 +1,11 @@
using System;
using ProcessHacker.Native.Api;
namespace ProcessHacker.Native.Memory
{
public sealed class PhysicalPagesMapping : MemoryAlloc
{
private readonly PhysicalPages _physicalPages;
private PhysicalPages _physicalPages;
internal PhysicalPagesMapping(PhysicalPages physicalPages, IntPtr baseAddress)
{
@@ -1,11 +1,14 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using ProcessHacker.Common.Objects;
namespace ProcessHacker.Native
{
public sealed class PinnedObject<T> : MemoryRegion
public sealed class PinnedObject<T> : BaseObject
{
private readonly T _object;
private T _object;
private GCHandle _handle;
public PinnedObject(T obj)
@@ -14,7 +17,7 @@ namespace ProcessHacker.Native
_handle = GCHandle.Alloc(obj, GCHandleType.Pinned);
}
protected override void Free()
protected override void DisposeObject(bool disposing)
{
_handle.Free();
}
@@ -9,7 +9,7 @@ namespace ProcessHacker.Native
/// </summary>
public sealed class Section : NativeObject<SectionHandle>
{
private readonly MemoryProtection _originalProtection = MemoryProtection.ReadWrite;
private MemoryProtection _originalProtection = MemoryProtection.ReadWrite;
/// <summary>
/// Opens an existing section.
@@ -64,7 +64,7 @@ namespace ProcessHacker.Native
name,
ObjectFlags.OpenIf,
null,
fileHandle.FileSize,
fileHandle.GetSize(),
image ? SectionAttributes.Image : SectionAttributes.Commit,
protection,
fileHandle
@@ -40,7 +40,10 @@ namespace ProcessHacker.Native
protected override void Free()
{
Win32.NtUnmapViewOfSection(ProcessHandle.Current, this).ThrowIf();
NtStatus status;
if ((status = Win32.NtUnmapViewOfSection(ProcessHandle.Current, this)) >= NtStatus.Error)
Win32.Throw(status);
}
/// <summary>
@@ -62,8 +65,8 @@ namespace ProcessHacker.Native
{
if ((uint)Win32.NtAreMappedFilesTheSame(this, mappedAsFile) == this.Memory.ToUInt32())
return true;
return false;
else
return false;
}
[EditorBrowsable(EditorBrowsableState.Never)]
@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ProcessHacker.Native.Mfs
{
[Serializable]
public class MfsException : Exception
{
public MfsException()
: base()
{ }
public MfsException(string message)
@@ -17,7 +19,6 @@ namespace ProcessHacker.Native.Mfs
{ }
}
[Serializable]
public class MfsInvalidFileSystemException : MfsException
{
public MfsInvalidFileSystemException()
@@ -32,8 +33,7 @@ namespace ProcessHacker.Native.Mfs
: base(message, innerException)
{ }
}
[Serializable]
public class MfsInvalidOperationException : MfsException
{
public MfsInvalidOperationException()
@@ -98,13 +98,6 @@ namespace ProcessHacker.Native.Mfs
[StructLayout(LayoutKind.Sequential, Pack = 4)]
internal unsafe struct MfsObjectHeader
{
public static readonly int SizeOf;
static MfsObjectHeader()
{
SizeOf = Marshal.SizeOf(typeof(MfsObjectHeader));
}
public MfsCellId Flink;
public MfsCellId Blink;
public MfsCellId Parent;
@@ -118,11 +111,11 @@ namespace ProcessHacker.Native.Mfs
public MfsCellId LastData;
public int NameLength;
public fixed char Name [32];
public fixed char Name[32];
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
internal struct MfsDataCell
internal unsafe struct MfsDataCell
{
public static readonly int DataOffset = Marshal.OffsetOf(typeof(MfsDataCell), "Data").ToInt32();
@@ -21,15 +21,17 @@
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using ProcessHacker.Common;
namespace ProcessHacker.Native.Mfs
{
public class MemoryDataWriteStream : Stream
{
private readonly MemoryObject _obj;
private readonly byte[] _buffer;
private MemoryObject _obj;
private byte[] _buffer;
private int _bufferLength;
internal MemoryDataWriteStream(MemoryObject obj, int bufferSize)
@@ -53,23 +53,26 @@ namespace ProcessHacker.Native.Mfs
}
}
private readonly bool _readOnly;
private readonly MemoryProtection _protection;
private readonly Section _section;
private bool _readOnly;
private MemoryProtection _protection;
private Section _section;
private MfsFsHeader* _header;
private readonly int _blockSize;
private readonly int _blockMask;
private readonly int _cellSize;
private readonly int _cellCount;
private readonly int _dataCellDataMaxLength;
private int _blockSize;
private int _blockMask;
private int _cellSize;
private int _cellCount;
private int _dataCellDataMaxLength;
private readonly MfsCellId _rootObjectCellId = new MfsCellId(0, 1);
private readonly MemoryObject _rootObjectMo;
private MfsCellId _rootObjectCellId = new MfsCellId(0, 1);
private MfsObjectHeader* _rootObject;
private MemoryObject _rootObjectMo;
private readonly FreeList<ViewDescriptor> _vdFreeList = new FreeList<ViewDescriptor>(16);
private readonly Dictionary<ushort, ViewDescriptor> _views = new Dictionary<ushort, ViewDescriptor>();
private readonly Dictionary<IntPtr, ViewDescriptor> _views2 = new Dictionary<IntPtr, ViewDescriptor>();
private FreeList<ViewDescriptor> _vdFreeList = new FreeList<ViewDescriptor>(16);
private Dictionary<ushort, ViewDescriptor> _views =
new Dictionary<ushort, ViewDescriptor>();
private Dictionary<IntPtr, ViewDescriptor> _views2 =
new Dictionary<IntPtr, ViewDescriptor>();
private ViewDescriptor _cachedLastBlockView;
@@ -106,7 +109,7 @@ namespace ProcessHacker.Native.Mfs
break;
}
using (FileHandle fhandle = FileHandle.CreateWin32(
using (var fhandle = FileHandle.CreateWin32(
fileName,
FileAccess.GenericRead | (!readOnly ? FileAccess.GenericWrite : 0),
FileShareMode.Read,
@@ -118,42 +121,46 @@ namespace ProcessHacker.Native.Mfs
_readOnly = readOnly;
_protection = !readOnly ? MemoryProtection.ReadWrite : MemoryProtection.ReadOnly;
if (fhandle.FileSize == 0)
if (fhandle.GetSize() == 0)
{
if (readOnly)
{
throw new MfsInvalidFileSystemException();
}
// File is too small. Make it 1 byte large and we'll deal with it soon.
fhandle.SetEnd(1);
else
{
// File is too small. Make it 1 byte large and we'll deal with it
// soon.
fhandle.SetEnd(1);
}
}
_section = new Section(fhandle, _protection);
_blockSize = MfsBlockSizeBase; // fake block size to begin with; we'll fix it up later.
if (fhandle.FileSize < _blockSize)
if (fhandle.GetSize() < _blockSize)
{
if (readOnly)
{
throw new MfsInvalidFileSystemException();
}
// We're creating a new file system. We need the correct block size now.
if (createParams != null)
this._blockSize = createParams.BlockSize;
else
this._blockSize = MfsDefaultBlockSize;
this._section.Extend(this._blockSize);
using (SectionView view = this._section.MapView(0, this._blockSize, this._protection))
{
this.InitializeFs((MfsFsHeader*)view.Memory, createParams);
}
// We're creating a new file system. We need the correct block size
// now.
if (createParams != null)
_blockSize = createParams.BlockSize;
else
_blockSize = MfsDefaultBlockSize;
justCreated = true;
_section.Extend(_blockSize);
using (var view = _section.MapView(0, _blockSize, _protection))
this.InitializeFs((MfsFsHeader*)view.Memory, createParams);
justCreated = true;
}
}
_header = (MfsFsHeader*)this.ReferenceBlock(0);
@@ -189,6 +196,7 @@ namespace ProcessHacker.Native.Mfs
_header = (MfsFsHeader*)this.ReferenceBlock(0);
// Set up the root object.
_rootObject = (MfsObjectHeader*)((byte*)_header + _cellSize);
_rootObjectMo = new MemoryObject(this, _rootObjectCellId, true);
if (_header->NextFreeBlock != 1 && !readOnly)
@@ -203,16 +211,15 @@ namespace ProcessHacker.Native.Mfs
protected override void DisposeObject(bool disposing)
{
foreach (ViewDescriptor vd in _views.Values)
foreach (var vd in _views.Values)
vd.View.Dispose(disposing);
if (_rootObjectMo != null)
_rootObjectMo.Dispose();
if (_section != null)
_section.Dispose();
_header = null;
_rootObject = null;
}
public int BlockSize
@@ -627,7 +634,7 @@ namespace ProcessHacker.Native.Mfs
throw new ArgumentException("The block size must be a multiple of the cell size.");
if ((blockSize / cellSize) < 2)
throw new ArgumentException("There must be a least 2 cells in each block.");
if (cellSize < MfsObjectHeader.SizeOf)
if (cellSize < Marshal.SizeOf(typeof(MfsObjectHeader)))
throw new ArgumentException("The cell size is too small.");
}
}
@@ -30,9 +30,9 @@ namespace ProcessHacker.Native.Mfs
{
public delegate bool EnumChildrenDelegate(MemoryObject mo);
private readonly bool _fsInternal;
private readonly MemoryFileSystem _fs;
private readonly MfsCellId _cellId;
private bool _fsInternal;
private MemoryFileSystem _fs;
private MfsCellId _cellId;
private MfsObjectHeader* _obj;
private string _name;
@@ -80,7 +80,7 @@ namespace ProcessHacker.Native.Mfs
{
get
{
if (string.IsNullOrEmpty(_name))
if (_name == null)
_name = _fs.GetObjectName(_obj);
return _name;
@@ -184,26 +184,23 @@ namespace ProcessHacker.Native.Mfs
return null;
}
public string[] ChildNames
public string[] GetChildNames()
{
get
{
List<string> names = new List<string>();
List<string> names = new List<string>();
this.EnumChildren(mo =>
this.EnumChildren((mo) =>
{
names.Add(mo.Name);
mo.Dispose();
return true;
});
return names.ToArray();
}
return names.ToArray();
}
public MemoryObject Parent
public MemoryObject GetParent()
{
get { return new MemoryObject(_fs, _obj->Parent); }
return new MemoryObject(_fs, _obj->Parent);
}
public MemoryDataWriteStream GetWriteStream()
+17 -10
View File
@@ -21,6 +21,8 @@
*/
using System;
using System.Collections.Generic;
using System.Text;
using ProcessHacker.Common;
using ProcessHacker.Common.Objects;
using ProcessHacker.Native.Api;
@@ -54,7 +56,7 @@ namespace ProcessHacker.Native
}
private RtlBitmap _bitmap;
private readonly MemoryAlloc _buffer;
private MemoryAlloc _buffer;
public NativeBitmap(int bits)
{
@@ -129,8 +131,9 @@ namespace ProcessHacker.Native
public BitmapRun[] FindClearRuns(int count, bool locateLongest)
{
RtlBitmapRun[] runs = new RtlBitmapRun[count];
int numberOfRuns;
int numberOfRuns = Win32.RtlFindClearRuns(ref this._bitmap, runs, count, locateLongest);
numberOfRuns = Win32.RtlFindClearRuns(ref _bitmap, runs, count, locateLongest);
BitmapRun[] returnRuns = new BitmapRun[numberOfRuns];
@@ -143,8 +146,9 @@ namespace ProcessHacker.Native
public BitmapRun FindBackwardClearRun(int index)
{
int startingIndex;
int numberOfBits;
int numberOfBits = Win32.RtlFindLastBackwardRunClear(ref this._bitmap, index, out startingIndex);
numberOfBits = Win32.RtlFindLastBackwardRunClear(ref _bitmap, index, out startingIndex);
return new BitmapRun(startingIndex, numberOfBits);
}
@@ -152,8 +156,9 @@ namespace ProcessHacker.Native
public BitmapRun FindFirstClearRun()
{
int startingIndex;
int numberOfBits;
int numberOfBits = Win32.RtlFindFirstRunClear(ref this._bitmap, out startingIndex);
numberOfBits = Win32.RtlFindFirstRunClear(ref _bitmap, out startingIndex);
return new BitmapRun(startingIndex, numberOfBits);
}
@@ -161,8 +166,9 @@ namespace ProcessHacker.Native
public BitmapRun FindForwardClearRun(int index)
{
int startingIndex;
int numberOfBits;
int numberOfBits = Win32.RtlFindNextForwardRunClear(ref this._bitmap, index, out startingIndex);
numberOfBits = Win32.RtlFindNextForwardRunClear(ref _bitmap, index, out startingIndex);
return new BitmapRun(startingIndex, numberOfBits);
}
@@ -170,8 +176,9 @@ namespace ProcessHacker.Native
public BitmapRun FindLongestClearRun()
{
int startingIndex;
int numberOfBits;
int numberOfBits = Win32.RtlFindLongestRunClear(ref this._bitmap, out startingIndex);
numberOfBits = Win32.RtlFindLongestRunClear(ref _bitmap, out startingIndex);
return new BitmapRun(startingIndex, numberOfBits);
}
@@ -196,14 +203,14 @@ namespace ProcessHacker.Native
return Win32.RtlFindSetBitsAndClear(ref _bitmap, length, hintIndex);
}
public int ClearCount
public int GetClearCount()
{
get { return Win32.RtlNumberOfClearBits(ref _bitmap); }
return Win32.RtlNumberOfClearBits(ref _bitmap);
}
public int SetCount
public int GetSetCount()
{
get { return Win32.RtlNumberOfSetBits(ref _bitmap); }
return Win32.RtlNumberOfSetBits(ref _bitmap);
}
public void Set()
@@ -1,184 +0,0 @@
namespace System
{
using Runtime.InteropServices;
using ProcessHacker.Native;
using ProcessHacker.Native.Api;
using ProcessHacker.Native.Objects;
/// <summary>
/// Utility class to wrap an unmanaged DLL and be responsible for freeing it.
/// </summary>
/// <remarks>This is a managed wrapper over the native LoadLibrary, GetProcAddress, and FreeLibrary calls.</remarks>
public sealed class NativeLibrary : NativeHandle
{
/// <summary>
/// LoadLibraryEx constructor to load a dll and be responsible for freeing it.
/// </summary>
/// <param name="dllName">full path name of dll to load</param>
/// <param name="flags"></param>
/// <remarks>Throws exceptions on failure. Most common failure would be file-not-found, or that the file is not a loadable image.</remarks>
public NativeLibrary(string dllName, LoadLibraryFlags flags)
{
UnicodeString str = new UnicodeString(dllName);
IntPtr ptr;
NtStatus result = Win32.LdrLoadDll(null, (int)flags, ref str, out ptr);
if (result.IsError())
{
this.MarkAsInvalid();
}
str.Dispose();
}
/// <summary>
/// Dynamically lookup a function in the dll via kernel32!GetProcAddress.
/// </summary>
/// <param name="functionName">raw name of the function in the export table.</param>
/// <returns>null if function is not found. Else a delegate to the unmanaged function.</returns>
/// <remarks>GetProcAddress results are valid as long as the dll is not yet unloaded. This
/// is very very dangerous to use since you need to ensure that the dll is not unloaded
/// until after you're done with any objects implemented by the dll. For example, if you
/// get a delegate that then gets an IUnknown implemented by this dll,
/// you can not dispose this library until that IUnknown is collected. Else, you may free
/// the library and then the CLR may call release on that IUnknown and it will crash.</remarks>
public TDelegate GetUnmanagedFunction<TDelegate>(string functionName) where TDelegate : class
{
using (AnsiString str = new AnsiString(functionName))
{
IntPtr functionPtr;
NtStatus result = Win32.LdrGetProcedureAddress(this, str.Buffer, 0, out functionPtr);
// Failure is a common case, especially for adaptive code.
if (result.IsError())
{
//result.ReturnException().Log();
return null;
}
Delegate function = Marshal.GetDelegateForFunctionPointer(functionPtr, typeof(TDelegate));
// Ideally, we'd just make the constraint on TDelegate be
// System.Delegate, but compiler error CS0702 (constrained can't be System.Delegate)
// prevents that. So we make the constraint system.object and do the cast from object-->TDelegate.
object o = function;
return (TDelegate)o;
}
}
#region Disposable Members
/// <summary>
/// Call FreeLibrary on the unmanaged dll. All function pointers handed out from this class become invalid after this.
/// </summary>
/// <remarks>This is very dangerous because it suddenly invalidate
/// everything retrieved from this dll. This includes any functions
/// handed out via GetProcAddress, and potentially any objects returned
/// from those functions (which may have an implementation in the dll).
/// </remarks>
protected override void Close()
{
Win32.LdrUnloadDll(this).ThrowIf();
}
#endregion
public IntPtr GetProcedure(string procedureName)
{
AnsiString str = new AnsiString(procedureName);
{
IntPtr functionPtr = IntPtr.Zero;
NtStatus result = Win32.LdrGetProcedureAddress(this, functionPtr, 0, out functionPtr);
return functionPtr;
}
}
public IntPtr GetProcedure(int procedureNumber)
{
IntPtr functionPtr;
NtStatus result = Win32.LdrGetProcedureAddress(this, IntPtr.Zero, procedureNumber, out functionPtr);
return functionPtr;
}
#region Static Methods
public static IntPtr GetProcedure(string dllName, string procedureName)
{
return GetProcedure(GetModuleHandle(dllName), procedureName);
}
public static IntPtr GetProcedure(IntPtr dllHandle, string procedureName)
{
IntPtr handle;
using (AnsiString str = new AnsiString(procedureName))
{
Win32.LdrGetProcedureAddress(dllHandle, str.Buffer, 0, out handle).ThrowIf();
}
return handle;
}
public static IntPtr GetModuleHandle(string dllName)
{
IntPtr handle;
UnicodeString str = new UnicodeString(dllName);
{
Win32.LdrGetDllHandle(null, 0, ref str, out handle).ThrowIf();
}
return handle;
}
#endregion
}
[Flags] //TODO: move to enum file
public enum LoadLibraryFlags
{
None = 0,
/// <summary>
/// If this value is used, and the executable module is a DLL, the system does not call DllMain for process and thread initialization and termination. Also, the system does not load additional executable modules that are referenced by the specified module. Do not use this value; it is provided only for backwards compatibility. If you are planning to access only data or resources in the DLL, use LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE or LOAD_LIBRARY_AS_IMAGE_RESOURCE or both. Otherwise, load the library as a DLL or executable module using the LoadLibrary function.
/// </summary>
DontResolveDllReferences = 0x00000001,
/// <summary>
/// If this value is used, the system maps the file into the calling process's virtual address space as if it were a data file. Nothing is done to execute or prepare to execute the mapped file. Therefore, you cannot call functions like GetModuleFileName, GetModuleHandle or GetProcAddress with this DLL. Using this value causes writes to read-only memory to raise an access violation. Use this flag when you want to load a DLL only to extract messages or resources from it. This value can be used with LOAD_LIBRARY_AS_IMAGE_RESOURCE.
/// </summary>
LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
/// <summary>
/// If this value is used and lpFileName specifies an absolute path, the system uses the alternate file search strategy discussed in the Remarks section to find associated executable modules that the specified module causes to be loaded. If this value is used and lpFileName specifies a relative path, the behavior is undefined. If this value is not used, or if lpFileName does not specify a path, the system uses the standard search strategy discussed in the Remarks section to find associated executable modules that the specified module causes to be loaded.
/// </summary>
LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008,
/// <summary>
/// If this value is used, the system does not check AppLocker rules or apply Software Restriction Policies for the DLL. This action applies only to the DLL being loaded and not to its dependents. This value is recommended for use in setup programs that must run extracted DLLs during installation.
/// </summary>
LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010,
/// <summary>
/// If this value is used, the system maps the file into the process's virtual address space as an image file. However, the loader does not load the static imports or perform the other usual initialization steps. Use this flag when you want to load a DLL only to extract messages or resources from it. Unless the application depends on the image layout, this value should be used with either LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE or LOAD_LIBRARY_AS_DATAFILE. For more information, see the Remarks section.
/// </summary>
LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020,
/// <summary>
/// Similar to LOAD_LIBRARY_AS_DATAFILE, except that the DLL file on the disk is opened for exclusive write access. Therefore, other processes cannot open the DLL file for write access while it is in use. However, the DLL can still be opened by other processes. This value can be used with LOAD_LIBRARY_AS_IMAGE_RESOURCE. For more information, see Remarks.
/// </summary>
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040,
LOAD_LIBRARY_REQUIRE_SIGNED_TARGET = 0x00000080
}
}
+44 -23
View File
@@ -1,6 +1,7 @@
using System;
using ProcessHacker.Native.Api;
using ProcessHacker.Native.Objects;
using System.Runtime.InteropServices;
using ProcessHacker.Native.Security;
namespace ProcessHacker.Native
@@ -41,23 +42,34 @@ namespace ProcessHacker.Native
ref StartupInfo startupInfo
)
{
UnicodeString imagePathNameStr;
UnicodeString dllPathStr;
UnicodeString currentDirectoryStr;
UnicodeString commandLineStr;
UnicodeString windowTitleStr;
UnicodeString desktopInfoStr;
UnicodeString shellInfoStr;
UnicodeString runtimeInfoStr;
// Create the unicode strings.
UnicodeString imagePathNameStr = new UnicodeString(imagePathName);
UnicodeString dllPathStr = new UnicodeString(dllPath);
UnicodeString currentDirectoryStr = new UnicodeString(currentDirectory);
UnicodeString commandLineStr = new UnicodeString(commandLine);
UnicodeString windowTitleStr = new UnicodeString(windowTitle);
UnicodeString desktopInfoStr = new UnicodeString(desktopInfo);
UnicodeString shellInfoStr = new UnicodeString(shellInfo);
UnicodeString runtimeInfoStr = new UnicodeString(runtimeInfo);
imagePathNameStr = new UnicodeString(imagePathName);
dllPathStr = new UnicodeString(dllPath);
currentDirectoryStr = new UnicodeString(currentDirectory);
commandLineStr = new UnicodeString(commandLine);
windowTitleStr = new UnicodeString(windowTitle);
desktopInfoStr = new UnicodeString(desktopInfo);
shellInfoStr = new UnicodeString(shellInfo);
runtimeInfoStr = new UnicodeString(runtimeInfo);
try
{
NtStatus status;
IntPtr processParameters;
// Create the process parameter block.
Win32.RtlCreateProcessParameters(
status = Win32.RtlCreateProcessParameters(
out processParameters,
ref imagePathNameStr,
ref dllPathStr,
@@ -68,15 +80,21 @@ namespace ProcessHacker.Native
ref desktopInfoStr,
ref shellInfoStr,
ref runtimeInfoStr
).ThrowIf();
);
if (status >= NtStatus.Error)
Win32.Throw(status);
try
{
// Allocate a new memory region in the remote process for
// the environment block and copy it over.
int environmentLength = environment.Length;
IntPtr newEnvironment = processHandle.AllocateMemory(
int environmentLength;
IntPtr newEnvironment;
environmentLength = environment.GetLength();
newEnvironment = processHandle.AllocateMemory(
environmentLength,
MemoryProtection.ReadWrite
);
@@ -113,9 +131,10 @@ namespace ProcessHacker.Native
// Allocate a new memory region in the remote process for
// the process parameters.
IntPtr newProcessParameters;
IntPtr regionSize = paramsStruct->Length.ToIntPtr();
IntPtr newProcessParameters = processHandle.AllocateMemory(
newProcessParameters = processHandle.AllocateMemory(
IntPtr.Zero,
ref regionSize,
MemoryFlags.Commit,
@@ -161,23 +180,25 @@ namespace ProcessHacker.Native
if (nativeKeyName.StartsWith(hkcrString, StringComparison.OrdinalIgnoreCase))
return "HKCR" + nativeKeyName.Substring(hkcrString.Length);
if (nativeKeyName.StartsWith(hklmString, StringComparison.OrdinalIgnoreCase))
else if (nativeKeyName.StartsWith(hklmString, StringComparison.OrdinalIgnoreCase))
return "HKLM" + nativeKeyName.Substring(hklmString.Length);
if (nativeKeyName.StartsWith(hkcucrString, StringComparison.OrdinalIgnoreCase))
else if (nativeKeyName.StartsWith(hkcucrString, StringComparison.OrdinalIgnoreCase))
return @"HKCU\Software\Classes" + nativeKeyName.Substring(hkcucrString.Length);
if (nativeKeyName.StartsWith(hkcuString, StringComparison.OrdinalIgnoreCase))
else if (nativeKeyName.StartsWith(hkcuString, StringComparison.OrdinalIgnoreCase))
return "HKCU" + nativeKeyName.Substring(hkcuString.Length);
if (nativeKeyName.StartsWith(hkuString, StringComparison.OrdinalIgnoreCase))
else if (nativeKeyName.StartsWith(hkuString, StringComparison.OrdinalIgnoreCase))
return "HKU" + nativeKeyName.Substring(hkuString.Length);
return nativeKeyName;
else
return nativeKeyName;
}
public static string GetMessage(IntPtr dllHandle, int messageTableId, int messageLanguageId, int messageId)
{
NtStatus status;
IntPtr messageEntry;
string message;
NtStatus status = Win32.RtlFindMessage(
status = Win32.RtlFindMessage(
dllHandle,
messageTableId,
messageLanguageId,
@@ -188,8 +209,8 @@ namespace ProcessHacker.Native
if (status.IsError())
return null;
MemoryRegion region = new MemoryRegion(messageEntry);
MessageResourceEntry entry = region.ReadStruct<MessageResourceEntry>();
var region = new MemoryRegion(messageEntry);
var entry = region.ReadStruct<MessageResourceEntry>();
// Read the message, depending on format.
if ((entry.Flags & MessageResourceFlags.Unicode) == MessageResourceFlags.Unicode)
@@ -217,7 +238,7 @@ namespace ProcessHacker.Native
try
{
using (var dhandle = new DirectoryHandle(dirPart, DirectoryAccess.Query))
using (var dhandle = new DirectoryHandle(dirPart, ProcessHacker.Native.Security.DirectoryAccess.Query))
{
var objects = dhandle.GetObjects();
@@ -242,7 +263,7 @@ namespace ProcessHacker.Native
try
{
return null;// new NativeHandle(KProcessHacker.Instance.KphOpenNamedObject(access, oa).ToIntPtr(), true);
return new NativeHandle(KProcessHacker.Instance.KphOpenNamedObject(access, oa).ToIntPtr(), true);
}
finally
{
+26 -33
View File
@@ -25,7 +25,7 @@ using ProcessHacker.Native.Security;
namespace ProcessHacker.Native
{
public enum OSArch
public enum OSArch : int
{
Unknown,
I386,
@@ -59,11 +59,6 @@ namespace ProcessHacker.Native
/// </summary>
Seven = 61,
/// <summary>
/// Windows 8.
/// </summary>
Eight = 62,
/// <summary>
/// An unknown version of Windows.
/// </summary>
@@ -72,31 +67,31 @@ namespace ProcessHacker.Native
public static class OSVersion
{
private static readonly int _bits = IntPtr.Size * 8;
private static readonly OSArch _arch = IntPtr.Size == 4 ? OSArch.I386 : OSArch.Amd64;
private static readonly string _versionString;
private static readonly WindowsVersion _windowsVersion;
private static int _bits = IntPtr.Size * 8;
private static OSArch _arch = IntPtr.Size == 4 ? OSArch.I386 : OSArch.Amd64;
private static string _versionString;
private static WindowsVersion _windowsVersion;
private static readonly ProcessAccess _minProcessQueryInfoAccess = ProcessAccess.QueryInformation;
private static readonly ThreadAccess _minThreadQueryInfoAccess = ThreadAccess.QueryInformation;
private static readonly ThreadAccess _minThreadSetInfoAccess = ThreadAccess.SetInformation;
private static ProcessAccess _minProcessQueryInfoAccess = ProcessAccess.QueryInformation;
private static ThreadAccess _minThreadQueryInfoAccess = ThreadAccess.QueryInformation;
private static ThreadAccess _minThreadSetInfoAccess = ThreadAccess.SetInformation;
private static readonly bool _hasCycleTime;
private static readonly bool _hasExtendedTaskbar;
private static readonly bool _hasIoPriority;
private static readonly bool _hasPagePriority;
private static readonly bool _hasProtectedProcesses;
private static readonly bool _hasPsSuspendResumeProcess;
private static readonly bool _hasQueryLimitedInformation;
private static readonly bool _hasSetAccessToken;
private static readonly bool _hasTaskDialogs;
private static readonly bool _hasThemes;
private static readonly bool _hasUac;
private static readonly bool _hasWin32ImageFileName;
private static bool _hasCycleTime = false;
private static bool _hasExtendedTaskbar = false;
private static bool _hasIoPriority = false;
private static bool _hasPagePriority = false;
private static bool _hasProtectedProcesses = false;
private static bool _hasPsSuspendResumeProcess = false;
private static bool _hasQueryLimitedInformation = false;
private static bool _hasSetAccessToken = false;
private static bool _hasTaskDialogs = false;
private static bool _hasThemes = false;
private static bool _hasUac = false;
private static bool _hasWin32ImageFileName = false;
static OSVersion()
{
Version version = Environment.OSVersion.Version;
System.Version version = Environment.OSVersion.Version;
if (version.Major == 5 && version.Minor == 0)
_windowsVersion = WindowsVersion.TwoThousand;
@@ -107,9 +102,7 @@ namespace ProcessHacker.Native
else if (version.Major == 6 && version.Minor == 0)
_windowsVersion = WindowsVersion.Vista;
else if (version.Major == 6 && version.Minor == 1)
_windowsVersion = WindowsVersion.Seven;
else if (version.Major == 6 && version.Minor == 2)
_windowsVersion = WindowsVersion.Eight;
_windowsVersion = WindowsVersion.Seven;
else
_windowsVersion = WindowsVersion.Unknown;
@@ -263,22 +256,22 @@ namespace ProcessHacker.Native
public static bool IsAbove(WindowsVersion version)
{
return _windowsVersion > version;
return (int)_windowsVersion > (int)version;
}
public static bool IsAboveOrEqual(WindowsVersion version)
{
return _windowsVersion >= version;
return (int)_windowsVersion >= (int)version;
}
public static bool IsBelowOrEqual(WindowsVersion version)
{
return _windowsVersion <= version;
return (int)_windowsVersion <= (int)version;
}
public static bool IsBelow(WindowsVersion version)
{
return _windowsVersion < version;
return (int)_windowsVersion < (int)version;
}
public static bool IsEqualTo(WindowsVersion version)

Some files were not shown because too many files have changed in this diff Show More