using System;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
public static partial class Kernel32
{
///
/// An application-defined function that serves as the starting address for a timer callback or a registered wait callback. Specify
/// this address when calling the CreateTimerQueueTimer, RegisterWaitForSingleObject function.
///
///
/// The thread data passed to the function using a parameter of the CreateTimerQueueTimer or RegisterWaitForSingleObject function.
///
///
/// If this parameter is TRUE, the wait timed out. If this parameter is FALSE, the wait event has been signaled. (This parameter is
/// always TRUE for timer callbacks.)
///
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms687066(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "ms687066")]
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void WaitOrTimerCallback(IntPtr lpParameter, [MarshalAs(UnmanagedType.U1)] bool TimerOrWaitFired);
/// The flags that control execution.
public enum WT
{
///
/// By default, the callback function is queued to a non-I/O worker thread.
///
/// The callback function is queued to a thread that uses I/O completion ports, which means they cannot perform an alertable
/// wait. Therefore, if I/O completes and generates an APC, the APC might wait indefinitely because there is no guarantee that
/// the thread will enter an alertable wait state after the callback completes.
///
///
WT_EXECUTEDEFAULT = 0x00000000,
///
/// This flag is not used.
///
/// Windows Server 2003 and Windows XP: The callback function is queued to an I/O worker thread. This flag should be used if the
/// function should be executed in a thread that waits in an alertable state. I/O worker threads were removed starting with
/// Windows Vista and Windows Server 2008.
///
///
WT_EXECUTEINIOTHREAD = 0x00000001,
/// Undocumented.
WT_EXECUTEINUITHREAD = 0x00000002,
///
/// The callback function is invoked by the wait thread itself. This flag should be used only for short tasks or it could affect
/// other wait operations.
///
/// Deadlocks can occur if some other thread acquires an exclusive lock and calls the UnregisterWait or UnregisterWaitEx function
/// while the callback function is trying to acquire the same lock.
///
///
WT_EXECUTEINWAITTHREAD = 0x00000004,
/// The timer will be set to the signaled state only once. If this flag is set, the Period parameter must be zero.
WT_EXECUTEONLYONCE = 0x00000008,
///
/// The callback function is invoked by the timer thread itself. This flag should be used only for short tasks or it could affect
/// other timer operations.
/// The callback function is queued as an APC. It should not perform alertable wait operations.
///
WT_EXECUTEINTIMERTHREAD = 0x00000020,
///
/// The callback function can perform a long wait. This flag helps the system to decide if it should create a new thread.
///
WT_EXECUTELONGFUNCTION = 0x00000010,
/// Undocumented.
WT_EXECUTEINPERSISTENTIOTHREAD = 0x00000040,
///
/// The callback function is queued to a thread that never terminates. It does not guarantee that the same thread is used each
/// time. This flag should be used only for short tasks or it could affect other timer operations. This flag must be set if the
/// thread calls functions that use APCs. For more information, see Asynchronous Procedure Calls.
///
/// Note that currently no worker thread is truly persistent, although worker threads do not terminate if there are any pending
/// I/O requests.
///
///
WT_EXECUTEINPERSISTENTTHREAD = 0x00000080,
///
/// Callback functions will use the current access token, whether it is a process or impersonation token. If this flag is not
/// specified, callback functions execute only with the process token.
/// Windows XP: This flag is not supported until Windows XP SP2 and Windows Server 2003.
///
WT_TRANSFER_IMPERSONATION = 0x00000100,
///
/// The callback function can perform a long wait. This flag helps the system to decide if it should create a new thread.
///
WT_EXECUTEINLONGTHREAD = 0x00000010,
/// The timer will be set to the signaled state only once. If this flag is set, the Period parameter must be zero.
WT_EXECUTEDELETEWAIT = 0x00000008,
}
///
/// Associates the I/O completion port owned by the thread pool with the specified file handle. On completion of an I/O request
/// involving this file, a non-I/O worker thread will execute the specified callback function.
///
///
/// A handle to the file opened for overlapped I/O completion. This handle is returned by the CreateFile function, with the
/// FILE_FLAG_OVERLAPPED flag.
///
///
///
/// A pointer to the callback function to be executed in a non-I/O worker thread when the I/O operation is complete. This callback
/// function must not call the TerminateThread function.
///
/// For more information about the completion routine, see FileIOCompletionRoutine.
///
/// This parameter must be zero.
///
/// If the function succeeds, the return value is nonzero.
///
/// If the function fails, the return value is zero. To get extended error information, call the GetLastError function. The
/// value returned is an NTSTATUS error code. To retrieve the corresponding system error code, use the
/// RtlNtStatusToDosError function.
///
///
// BOOL WINAPI BindIoCompletionCallback( _In_ HANDLE FileHandle, _In_ LPOVERLAPPED_COMPLETION_ROUTINE Function, _In_ ULONG Flags); https://msdn.microsoft.com/en-us/library/windows/desktop/aa363484(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "aa363484")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool BindIoCompletionCallback([In] HFILE FileHandle, FileIOCompletionRoutine Function, [Optional] uint Flags);
/// Updates a timer-queue timer that was created by the CreateTimerQueueTimer function.
///
/// A handle to the timer queue. This handle is returned by the CreateTimerQueue function.
/// If this parameter is NULL, the timer is associated with the default timer queue.
///
/// A handle to the timer-queue timer. This handle is returned by the CreateTimerQueueTimer function.
/// The time after which the timer should expire, in milliseconds.
///
/// The period of the timer, in milliseconds. If this parameter is zero, the timer is signaled once. If this parameter is greater
/// than zero, the timer is periodic. A periodic timer automatically reactivates each time the period elapses, until the timer is
/// canceled using the DeleteTimerQueueTimer function or reset using ChangeTimerQueueTimer.
///
///
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
// BOOL WINAPI ChangeTimerQueueTimer( _In_opt_ HANDLE TimerQueue, _Inout_ HANDLE Timer, _In_ ULONG DueTime, _In_ ULONG Period); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682004(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms682004")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ChangeTimerQueueTimer([In] TimerQueueHandle TimerQueue, TimerQueueTimerHandle Timer, uint DueTime, uint Period);
///
/// Creates a queue for timers. Timer-queue timers are lightweight objects that enable you to specify a callback function to be
/// called at a specified time.
///
///
///
/// If the function succeeds, the return value is a handle to the timer queue. This handle can be used only in functions that require
/// a handle to a timer queue.
///
/// If the function fails, the return value is NULL. To get extended error information, call GetLastError.
///
// HANDLE WINAPI CreateTimerQueue(void); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682483(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms682483")]
public static extern SafeTimerQueueHandle CreateTimerQueue();
///
/// Creates a timer-queue timer. This timer expires at the specified due time, then after every specified period. When the timer
/// expires, the callback function is called.
///
///
/// A pointer to a buffer that receives a handle to the timer-queue timer on return. When this handle has expired and is no longer
/// required, release it by calling DeleteTimerQueueTimer.
///
///
/// A handle to the timer queue. This handle is returned by the CreateTimerQueue function.
/// If this parameter is NULL, the timer is associated with the default timer queue.
///
///
/// A pointer to the application-defined function of type WAITORTIMERCALLBACK to be executed when the timer expires. For more
/// information, see WaitOrTimerCallback.
///
/// A single parameter value that will be passed to the callback function.
///
/// The amount of time in milliseconds relative to the current time that must elapse before the timer is signaled for the first time.
///
///
/// The period of the timer, in milliseconds. If this parameter is zero, the timer is signaled once. If this parameter is greater
/// than zero, the timer is periodic. A periodic timer automatically reactivates each time the period elapses, until the timer is canceled.
///
///
/// This parameter can be one or more of the following values from WinNT.h.
///
///
///
/// Value
/// Meaning
///
/// -
/// WT_EXECUTEDEFAULT0x00000000
/// By default, the callback function is queued to a non-I/O worker thread.
///
/// -
/// WT_EXECUTEINTIMERTHREAD0x00000020
///
/// The callback function is invoked by the timer thread itself. This flag should be used only for short tasks or it could affect
/// other timer operations. The callback function is queued as an APC. It should not perform alertable wait operations.
///
///
/// -
/// WT_EXECUTEINIOTHREAD0x00000001
///
/// This flag is not used.Windows Server 2003 and Windows XP: The callback function is queued to an I/O worker thread. This flag
/// should be used if the function should be executed in a thread that waits in an alertable state. I/O worker threads were removed
/// starting with Windows Vista and Windows Server 2008.
///
///
/// -
/// WT_EXECUTEINPERSISTENTTHREAD0x00000080
///
/// The callback function is queued to a thread that never terminates. It does not guarantee that the same thread is used each time.
/// This flag should be used only for short tasks or it could affect other timer operations. This flag must be set if the thread
/// calls functions that use APCs. For more information, see Asynchronous Procedure Calls.Note that currently no worker thread is
/// truly persistent, although no worker thread will terminate if there are any pending I/O requests.
///
///
/// -
/// WT_EXECUTELONGFUNCTION0x00000010
/// The callback function can perform a long wait. This flag helps the system to decide if it should create a new thread.
///
/// -
/// WT_EXECUTEONLYONCE0x00000008
/// The timer will be set to the signaled state only once. If this flag is set, the Period parameter must be zero.
///
/// -
/// WT_TRANSFER_IMPERSONATION0x00000100
///
/// Callback functions will use the current access token, whether it is a process or impersonation token. If this flag is not
/// specified, callback functions execute only with the process token.Windows XP: This flag is not supported until Windows XP with
/// SP2 and Windows Server 2003.
///
///
///
///
///
///
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
// BOOL WINAPI CreateTimerQueueTimer( _Out_ PHANDLE phNewTimer, _In_opt_ HANDLE TimerQueue, _In_ WAITORTIMERCALLBACK Callback,
// _In_opt_ PVOID Parameter, _In_ DWORD DueTime, _In_ DWORD Period, _In_ ULONG Flags); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682485(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "ms682485")]
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CreateTimerQueueTimer(out TimerQueueTimerHandle phNewTimer, [In] TimerQueueHandle TimerQueue, WaitOrTimerCallback Callback, [In, Optional] IntPtr Parameter, uint DueTime, [Optional] uint Period, [Optional] WT Flags);
/// Deletes a timer queue. Any pending timers in the queue are canceled and deleted.
/// A handle to the timer queue. This handle is returned by the CreateTimerQueue function.
///
///
/// A handle to the event object to be signaled when the function is successful and all callback functions have completed. This
/// parameter can be NULL.
///
/// If this parameter is INVALID_HANDLE_VALUE, the function waits for all callback functions to complete before returning.
///
/// If this parameter is NULL, the function marks the timer for deletion and returns immediately. However, most callers should
/// wait for the callback function to complete so they can perform any needed cleanup.
///
///
///
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
// BOOL WINAPI DeleteTimerQueueEx( _In_ HANDLE TimerQueue, _In_opt_ HANDLE CompletionEvent); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682568(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms682568")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeleteTimerQueueEx([In] TimerQueueHandle TimerQueue, [In] SafeEventHandle CompletionEvent);
///
/// Removes a timer from the timer queue and optionally waits for currently running timer callback functions to complete before
/// deleting the timer.
///
///
/// A handle to the timer queue. This handle is returned by the CreateTimerQueue function.
/// If the timer was created using the default timer queue, this parameter should be NULL.
///
/// A handle to the timer-queue timer. This handle is returned by the CreateTimerQueueTimer function.
///
///
/// A handle to the event object to be signaled when the system has canceled the timer and all callback functions have completed.
/// This parameter can be NULL.
///
///
/// If this parameter is INVALID_HANDLE_VALUE, the function waits for any running timer callback functions to complete before returning.
///
///
/// If this parameter is NULL, the function marks the timer for deletion and returns immediately. If the timer has already
/// expired, the timer callback function will run to completion. However, there is no notification sent when the timer callback
/// function has completed. Most callers should not use this option, and should wait for running timer callback functions to complete
/// so they can perform any needed cleanup.
///
///
///
/// If the function succeeds, the return value is nonzero.
///
/// If the function fails, the return value is zero. To get extended error information, call GetLastError. If the error code
/// is ERROR_IO_PENDING, it is not necessary to call this function again. For any other error, you should retry the call.
///
///
// BOOL WINAPI DeleteTimerQueueTimer( _In_opt_ HANDLE TimerQueue, _In_ HANDLE Timer, _In_opt_ HANDLE CompletionEvent); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682569(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms682569")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeleteTimerQueueTimer([In] TimerQueueHandle TimerQueue, [In] TimerQueueTimerHandle Timer, [In] SafeEventHandle CompletionEvent);
/// Queues a work item to a worker thread in the thread pool.
///
/// A pointer to the application-defined callback function of type LPTHREAD_START_ROUTINE to be executed by the thread in the thread
/// pool. This value represents the starting address of the thread. This callback function must not call the TerminateThread function.
/// For more information, see ThreadProc.
///
/// A single parameter value to be passed to the thread function.
/// The flags that control execution. This parameter can be one or more of the following values.
///
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684957(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms684957")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool QueueUserWorkItem(ThreadProc Function, [In] IntPtr Context, WT Flags);
///
///
/// Directs a wait thread in the thread pool to wait on the object. The wait thread queues the specified callback function to the
/// thread pool when one of the following occurs:
///
///
/// -
/// The specified object is in the signaled state.
///
/// -
/// The time-out interval elapses.
///
///
///
/// A pointer to a variable that receives a wait handle on return. Note that a wait handle cannot be used in functions that require
/// an object handle, such as CloseHandle.
/// A handle to the object. For a list of the object types whose handles can be specified, see the following Remarks section.
/// If this handle is closed while the wait is still pending, the function's behavior is undefined.
/// The handles must have the SYNCHRONIZE access right. For more information, see Standard Access Rights.
/// A pointer to the application-defined function of type WAITORTIMERCALLBACK to be executed when hObject is in the signaled
/// state, or dwMilliseconds elapses. For more information, see WaitOrTimerCallback.
/// A single value that is passed to the callback function.
/// The time-out interval, in milliseconds. The function returns if the interval elapses, even if the object's state is nonsignaled.
/// If dwMilliseconds is zero, the function tests the object's state and returns immediately. If dwMilliseconds is INFINITE,
/// the function's time-out interval never elapses.
/// This parameter can be one or more of the following values.
/// For information about using these values with objects that remain signaled, see the Remarks section.
///
///
/// Value
/// Meaning
///
/// -
/// WT_EXECUTEDEFAULT 0x00000000
/// By default, the callback function is queued to a non-I/O worker thread.
///
/// -
/// WT_EXECUTEINIOTHREAD 0x00000001
///
/// This flag is not used. Windows Server 2003 and Windows XP: The callback function is queued to an I/O worker thread. This flag
/// should be used if the function should be executed in a thread that waits in an alertable state. I/O worker threads were removed
/// starting with Windows Vista and Windows Server 2008.
///
///
/// -
/// WT_EXECUTEINPERSISTENTTHREAD 0x00000080
///
/// The callback function is queued to a thread that never terminates. It does not guarantee that the same thread is used each time.
/// This flag should be used only for short tasks or it could affect other wait operations. This flag must be set if the thread calls
/// functions that use APCs. For more information, see Asynchronous Procedure Calls. Note that currently no worker thread is truly
/// persistent, although no worker thread will terminate if there are any pending I/O requests.
///
///
/// -
/// WT_EXECUTEINWAITTHREAD 0x00000004
///
/// The callback function is invoked by the wait thread itself. This flag should be used only for short tasks or it could affect
/// other wait operations. Deadlocks can occur if some other thread acquires an exclusive lock and calls the UnregisterWait or
/// UnregisterWaitEx function while the callback function is trying to acquire the same lock.
///
///
/// -
/// WT_EXECUTELONGFUNCTION 0x00000010
/// The callback function can perform a long wait. This flag helps the system to decide if it should create a new thread.
///
/// -
/// WT_EXECUTEONLYONCE 0x00000008
///
/// The thread will no longer wait on the handle after the callback function has been called once. Otherwise, the timer is reset
/// every time the wait operation completes until the wait operation is canceled.
///
///
/// -
/// WT_TRANSFER_IMPERSONATION 0x00000100
///
/// Callback functions will use the current access token, whether it is a process or impersonation token. If this flag is not
/// specified, callback functions execute only with the process token. Windows XP: This flag is not supported until Windows XP with
/// SP2 and Windows Server 2003.
///
///
///
///
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
///
///
/// New wait threads are created automatically when required. The wait operation is performed by a wait thread from the thread pool.
/// The callback routine is executed by a worker thread when the object's state becomes signaled or the time-out interval elapses. If
/// dwFlags is not WT_EXECUTEONLYONCE, the timer is reset every time the event is signaled or the time-out interval elapses.
///
///
/// When the wait is completed, you must call the UnregisterWait or UnregisterWaitEx function to cancel the wait operation. (Even
/// wait operations that use WT_EXECUTEONLYONCE must be canceled.) Do not make a blocking call to either of these functions
/// from within the callback function.
///
///
/// Note that you should not pulse an event object passed to RegisterWaitForSingleObject, because the wait thread might not
/// detect that the event is signaled before it is reset. You should not register an object that remains signaled (such as a manual
/// reset event or terminated process) unless you set the WT_EXECUTEONLYONCE or WT_EXECUTEINWAITTHREAD flag. For other
/// flags, the callback function might be called too many times before the event is reset.
///
///
/// The function modifies the state of some types of synchronization objects. Modification occurs only for the object whose signaled
/// state caused the wait condition to be satisfied. For example, the count of a semaphore object is decreased by one.
///
/// The RegisterWaitForSingleObject function can wait for the following objects:
///
/// -
/// Change notification
///
/// -
/// Console input
///
/// -
/// Event
///
/// -
/// Memory resource notification
///
/// -
/// Mutex
///
/// -
/// Process
///
/// -
/// Semaphore
///
/// -
/// Thread
///
/// -
/// Waitable timer
///
///
/// For more information, see Synchronization Objects.
///
/// By default, the thread pool has a maximum of 500 threads. To raise this limit, use the WT_SET_MAX_THREADPOOL_THREAD macro
/// defined in WinNT.h.
///
///
/// Use this macro when specifying the dwFlags parameter. The macro parameters are the desired flags and the new limit (up to
/// (2<<16)-1 threads). However, note that your application can improve its performance by keeping the number of worker threads low.
///
///
/// The work item and all functions it calls must be thread-pool safe. Therefore, you cannot call an asynchronous call that requires
/// a persistent thread, such as the RegNotifyChangeKeyValue function, from the default callback environment. Instead, set the thread
/// pool maximum equal to the thread pool minimum using the SetThreadpoolThreadMaximum and SetThreadpoolThreadMinimum functions, or
/// create your own thread using the CreateThread function. (For the original thread pool API, specify
/// WT_EXECUTEINPERSISTENTTHREAD using the QueueUserWorkItem function.)
///
///
/// To compile an application that uses this function, define _WIN32_WINNT as 0x0500 or later. For more information, see Using
/// the Windows Headers.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-registerwaitforsingleobject
// BOOL RegisterWaitForSingleObject( PHANDLE phNewWaitObject, HANDLE hObject, WAITORTIMERCALLBACK Callback, PVOID Context, ULONG dwMilliseconds, ULONG dwFlags );
[PInvokeData("winbase.h", MSDNShortId = "d0cd8b28-6e20-449a-94dd-cca2be46b812")]
public static bool RegisterWaitForSingleObject(out SafeRegisteredWaitHandle phNewWaitObject, ISyncHandle hObject, WaitOrTimerCallback Callback, IntPtr Context, uint dwMilliseconds, WT dwFlags) =>
RegisterWaitForSingleObject(out phNewWaitObject, hObject?.DangerousGetHandle() ?? IntPtr.Zero, Callback, Context, dwMilliseconds, dwFlags);
/// Gets a value that combines flags values with a new maximum threadpool thread count limit.
/// The desired flags.
/// The threadpool thread count limit. The default is 500.
/// A value that has been augmented with the limit.
public static WT WT_SET_MAX_THREADPOOL_THREADS(WT Flags, ushort Limit) => Flags | (WT)((uint)Limit << 16);
/// Cancels a registered wait operation issued by the RegisterWaitForSingleObject function.
/// The wait handle. This handle is returned by the RegisterWaitForSingleObject function.
///
/// A handle to the event object to be signaled when the wait operation has been unregistered. This parameter can be NULL.
/// If this parameter is INVALID_HANDLE_VALUE, the function waits for all callback functions to complete before returning.
///
/// If this parameter is NULL, the function marks the timer for deletion and returns immediately. However, most callers should
/// wait for the callback function to complete so they can perform any needed cleanup.
///
///
/// If the caller provides this event and the function succeeds or the function fails with ERROR_IO_PENDING, do not close the
/// event until it is signaled.
///
///
///
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
// BOOL WINAPI UnregisterWaitEx( _In_ HANDLE WaitHandle, _In_opt_ HANDLE CompletionEvent); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686876(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("LibLoaderAPI.h", MSDNShortId = "ms686876")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnregisterWaitEx([In] IntPtr WaitHandle, [In] SafeEventHandle CompletionEvent);
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool RegisterWaitForSingleObject(out SafeRegisteredWaitHandle phNewWaitObject, [In] IntPtr hObject, WaitOrTimerCallback Callback, [In] IntPtr Context, uint dwMilliseconds, WT dwFlags);
/// Provides a handle to a timer queue.
[StructLayout(LayoutKind.Sequential)]
public struct TimerQueueHandle : IHandle
{
private IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public TimerQueueHandle(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static TimerQueueHandle NULL => new TimerQueueHandle(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(TimerQueueHandle h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator TimerQueueHandle(IntPtr h) => new TimerQueueHandle(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(TimerQueueHandle h1, TimerQueueHandle h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(TimerQueueHandle h1, TimerQueueHandle h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is TimerQueueHandle h ? handle == h.handle : false;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// Provides a handle to a timer queue timer.
[StructLayout(LayoutKind.Sequential)]
public struct TimerQueueTimerHandle : IHandle
{
private IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public TimerQueueTimerHandle(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static TimerQueueTimerHandle NULL => new TimerQueueTimerHandle(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(TimerQueueTimerHandle h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator TimerQueueTimerHandle(IntPtr h) => new TimerQueueTimerHandle(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(TimerQueueTimerHandle h1, TimerQueueTimerHandle h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(TimerQueueTimerHandle h1, TimerQueueTimerHandle h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is TimerQueueTimerHandle h ? handle == h.handle : false;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
///
/// Provides a to a timer queue that releases a created TimerQueueHandle instance at disposal using CloseHandle.
///
public class SafeTimerQueueHandle : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeTimerQueueHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
private SafeTimerQueueHandle() : base() { }
/// Gets or sets the completion event associated with the disposal or closure of this timer queue.
///
///
/// A handle to the event object to be signaled when the function is successful and all callback functions have completed. This
/// parameter can be .
///
///
/// If this parameter is , the function waits for all callback functions to complete before returning.
///
///
/// If this parameter is , the function marks the timer for deletion and returns immediately. However, most
/// callers should wait for the callback function to complete so they can perform any needed cleanup.
///
///
public SafeEventHandle CompletionEvent { get; set; }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator TimerQueueHandle(SafeTimerQueueHandle h) => h.handle;
///
protected override bool InternalReleaseHandle() => DeleteTimerQueueEx(this, CompletionEvent ?? SafeEventHandle.Null);
}
}
}