using System; using ProcessHacker.Native.Api; using ProcessHacker.Native.Security; namespace ProcessHacker.Native.Objects { public sealed class TimerHandle : NativeHandle { /// /// Creates a timer. /// /// The desired access to the timer. /// /// The type of timer; synchronization timers will be reset once waiting threads are released. /// /// A handle to the timer. public static TimerHandle Create(TimerAccess access, TimerType type) { return Create(access, null, type); } /// /// Creates a timer. /// /// The desired access to the timer. /// A name for the timer in the object manager namespace. /// /// The type of timer; synchronization timers will be reset once waiting threads are released. /// /// A handle to the timer. public static TimerHandle Create(TimerAccess access, string name, TimerType type) { return Create(access, name, 0, null, type); } /// /// Creates a timer. /// /// The desired access to the timer. /// A name for the timer in the object manager namespace. /// The flags to use when creating the object. /// The directory in which to place the timer. This can be null. /// /// The type of timer; synchronization timers will be reset once waiting threads are released. /// /// A handle to the timer. public static TimerHandle Create(TimerAccess access, string name, ObjectFlags objectFlags, DirectoryHandle rootDirectory, TimerType type) { ObjectAttributes oa = new ObjectAttributes(name, objectFlags, rootDirectory); IntPtr handle; try { Win32.NtCreateTimer(out handle, access, ref oa, type).ThrowIf(); } finally { oa.Dispose(); } return new TimerHandle(handle, true); } public static TimerHandle FromHandle(IntPtr handle) { return new TimerHandle(handle, false); } private TimerHandle(IntPtr handle, bool owned) : base(handle, owned) { } public TimerHandle(string name, ObjectFlags objectFlags, DirectoryHandle rootDirectory, TimerAccess access) { ObjectAttributes oa = new ObjectAttributes(name, objectFlags, rootDirectory); IntPtr handle; try { Win32.NtOpenTimer(out handle, access, ref oa).ThrowIf(); } finally { oa.Dispose(); } this.Handle = handle; } public TimerHandle(string name, TimerAccess access) : this(name, 0, null, access) { } /// /// Cancels the timer, preventing it from being signaled. /// /// The state of the timer (whether it is signaled). public bool Cancel() { bool currentState; Win32.NtCancelTimer(this, out currentState).ThrowIf(); return currentState; } /// /// Gets information about the timer. /// public TimerBasicInformation BasicInformation { get { TimerBasicInformation tbi; int retLength; Win32.NtQueryTimer( this, TimerInformationClass.TimerBasicInformation, out tbi, TimerBasicInformation.SizeOf, out retLength ).ThrowIf(); return tbi; } } /// /// Sets the timer. /// /// The time at which the timer is to be signaled. /// /// The time interval for periodic signaling of the timer, in milliseconds. /// Specify 0 for no periodic signaling. /// /// The state of the timer (whether it is signaled). public bool Set(DateTime dueTime, int period) { return this.Set(dueTime.ToFileTime(), false, null, IntPtr.Zero, period); } /// /// Sets the timer. /// /// A relative due time, in 100ns units. /// /// The time interval for periodic signaling of the timer, in milliseconds. /// Specify 0 for no periodic signaling. /// /// The state of the timer (whether it is signaled). public bool Set(long dueTime, int period) { return this.Set(dueTime, null, period); } /// /// Sets the timer. /// /// A relative due time, in 100ns units. /// A routine to call when the timer is signaled. /// /// The time interval for periodic signaling of the timer, in milliseconds. /// Specify 0 for no periodic signaling. /// /// The state of the timer (whether it is signaled). public bool Set(long dueTime, TimerApcRoutine routine, int period) { return this.Set(dueTime, true, routine, IntPtr.Zero, period); } /// /// Sets the timer. /// /// A due time, in 100ns units. /// Whether the due time is relative. /// A routine to call when the timer is signaled. /// A value to pass to the timer callback routine. /// /// The time interval for periodic signaling of the timer, in milliseconds. /// Specify 0 for no periodic signaling. /// /// The state of the timer (whether it is signaled). public bool Set(long dueTime, bool relative, TimerApcRoutine routine, IntPtr context, int period) { return this.Set(dueTime, relative, routine, context, false, period); } /// /// Sets the timer. /// /// A due time, in 100ns units. /// Whether the due time is relative. /// A routine to call when the timer is signaled. /// A value to pass to the timer callback routine. /// /// Whether the power manager should restore the system when the timer is signaled. /// /// /// The time interval for periodic signaling of the timer, in milliseconds. /// Specify 0 for no periodic signaling. /// /// The state of the timer (whether it is signaled). public bool Set(long dueTime, bool relative, TimerApcRoutine routine, IntPtr context, bool resume, int period) { long realDueTime = relative ? -dueTime : dueTime; bool previousState; // Keep the APC routine alive. Win32.NtSetTimer( this, ref realDueTime, routine, context, resume, period, out previousState ).ThrowIf(); return previousState; } } }