diff --git a/PInvoke/Kernel32/HandleApi.cs b/PInvoke/Kernel32/HandleApi.cs
index 95fa00b3..06455128 100644
--- a/PInvoke/Kernel32/HandleApi.cs
+++ b/PInvoke/Kernel32/HandleApi.cs
@@ -13,6 +13,7 @@ namespace Vanara.PInvoke
{
/// Closes the source handle. This occurs regardless of any error status returned.
DUPLICATE_CLOSE_SOURCE = 0x00000001,
+
/// Ignores the dwDesiredAccess parameter. The duplicate handle has the same access as the source handle.
DUPLICATE_SAME_ACCESS = 0x00000002,
}
@@ -23,10 +24,13 @@ namespace Vanara.PInvoke
{
/// None.
NONE = 0,
+
///
- /// If this flag is set, a child process created with the bInheritHandles parameter of CreateProcess set to TRUE will inherit the object handle.
+ /// If this flag is set, a child process created with the bInheritHandles parameter of CreateProcess set to TRUE will inherit the
+ /// object handle.
///
HANDLE_FLAG_INHERIT = 1,
+
/// If this flag is set, calling the CloseHandle function will not close the object handle.
HANDLE_FLAG_PROTECT_FROM_CLOSE = 2
}
@@ -37,9 +41,9 @@ namespace Vanara.PInvoke
/// 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 application is running under a debugger, the function will throw an exception if it receives either a handle value that is not valid or a
- /// pseudo-handle value. This can happen if you close a handle twice, or if you call CloseHandle on a handle returned by the FindFirstFile
- /// function instead of calling the FindClose function.
+ /// If the application is running under a debugger, the function will throw an exception if it receives either a handle value that is
+ /// not valid or a pseudo-handle value. This can happen if you close a handle twice, or if you call CloseHandle on a handle
+ /// returned by the FindFirstFile function instead of calling the FindClose function.
///
///
// BOOL WINAPI CloseHandle( _In_ HANDLE hObject); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211(v=vs.85).aspx
@@ -52,21 +56,29 @@ namespace Vanara.PInvoke
/// Compares two object handles to determine if they refer to the same underlying kernel object.
/// The first object handle to compare.
/// The second object handle to compare.
- /// A Boolean value that indicates if the two handles refer to the same underlying kernel object. TRUE if the same, otherwise FALSE.
+ ///
+ /// A Boolean value that indicates if the two handles refer to the same underlying kernel object. TRUE if the same, otherwise FALSE.
+ ///
// BOOL WINAPI CompareObjectHandles( _In_ HANDLE hFirstObjectHandle, _In_ HANDLE hSecondObjectHandle); https://msdn.microsoft.com/en-us/library/windows/desktop/mt438733(v=vs.85).aspx
[DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true)]
[PInvokeData("Handleapi.h", MSDNShortId = "mt438733")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CompareObjectHandles(IntPtr hFirstObjectHandle, IntPtr hSecondObjectHandle);
+ /// Determines if two object handles refer to the same underlying kernel object.
+ /// The first object handle to compare.
+ /// The second object handle to compare.
+ /// if the two handles refer to the same underlying kernel object; otherwise.
+ public static bool Equals(this IKernelHandle h1, IKernelHandle h2) => CompareObjectHandles(h1.DangerousGetHandle(), h2?.DangerousGetHandle() ?? IntPtr.Zero);
+
/// Duplicates an object handle.
///
- /// The handle to be duplicated. This is an open object handle that is valid in the context of the source process. For a list of objects whose handles
- /// can be duplicated, see the following Remarks section.
+ /// The handle to be duplicated. This is an open object handle that is valid in the context of the source process. For a list of
+ /// objects whose handles can be duplicated, see the following Remarks section.
///
///
- /// A variable that indicates whether the handle is inheritable. If TRUE, the duplicate handle can be inherited by new processes created by the
- /// target process. If FALSE, the new handle cannot be inherited.
+ /// A variable that indicates whether the handle is inheritable. If TRUE, the duplicate handle can be inherited by new
+ /// processes created by the target process. If FALSE, the new handle cannot be inherited.
///
///
/// Optional actions. This parameter can be zero, or any combination of the following values.
@@ -88,17 +100,19 @@ namespace Vanara.PInvoke
///
///
///
- /// The access requested for the new handle. For the flags that can be specified for each object type, see the following Remarks section.
///
- /// This parameter is ignored if the dwOptions parameter specifies the DUPLICATE_SAME_ACCESS flag. Otherwise, the flags that can be specified depend on
- /// the type of object whose handle is to be duplicated.
+ /// The access requested for the new handle. For the flags that can be specified for each object type, see the following Remarks section.
+ ///
+ ///
+ /// This parameter is ignored if the dwOptions parameter specifies the DUPLICATE_SAME_ACCESS flag. Otherwise, the flags that can be
+ /// specified depend on the type of object whose handle is to be duplicated.
///
///
///
/// The duplicate handle. This handle value is valid in the context of the target process.
///
- /// If hSourceHandle is a pseudo handle returned by GetCurrentProcess or GetCurrentThread, DuplicateHandle converts it to a real
- /// handle to a process or thread, respectively.
+ /// If hSourceHandle is a pseudo handle returned by GetCurrentProcess or GetCurrentThread, DuplicateHandle
+ /// converts it to a real handle to a process or thread, respectively.
///
///
public static IntPtr Duplicate(this IKernelHandle hSourceHandle, bool bInheritHandle = true, DUPLICATE_HANDLE_OPTIONS dwOptions = DUPLICATE_HANDLE_OPTIONS.DUPLICATE_SAME_ACCESS, uint dwDesiredAccess = 0) =>
@@ -110,8 +124,8 @@ namespace Vanara.PInvoke
/// The handle must have the PROCESS_DUP_HANDLE access right. For more information, see Process Security and Access Rights.
///
///
- /// The handle to be duplicated. This is an open object handle that is valid in the context of the source process. For a list of objects whose handles
- /// can be duplicated, see the following Remarks section.
+ /// The handle to be duplicated. This is an open object handle that is valid in the context of the source process. For a list of
+ /// objects whose handles can be duplicated, see the following Remarks section.
///
///
/// A handle to the process that is to receive the duplicated handle. The handle must have the PROCESS_DUP_HANDLE access right.
@@ -119,25 +133,27 @@ namespace Vanara.PInvoke
///
/// A pointer to a variable that receives the duplicate handle. This handle value is valid in the context of the target process.
///
- /// If hSourceHandle is a pseudo handle returned by GetCurrentProcess or GetCurrentThread, DuplicateHandle converts it to a real
- /// handle to a process or thread, respectively.
+ /// If hSourceHandle is a pseudo handle returned by GetCurrentProcess or GetCurrentThread, DuplicateHandle
+ /// converts it to a real handle to a process or thread, respectively.
///
///
- /// If lpTargetHandle is NULL, the function duplicates the handle, but does not return the duplicate handle value to the caller. This behavior
- /// exists only for backward compatibility with previous versions of this function. You should not use this feature, as you will lose system resources
- /// until the target process terminates.
+ /// If lpTargetHandle is NULL, the function duplicates the handle, but does not return the duplicate handle value to the
+ /// caller. This behavior exists only for backward compatibility with previous versions of this function. You should not use this
+ /// feature, as you will lose system resources until the target process terminates.
///
///
///
- /// The access requested for the new handle. For the flags that can be specified for each object type, see the following Remarks section.
///
- /// This parameter is ignored if the dwOptions parameter specifies the DUPLICATE_SAME_ACCESS flag. Otherwise, the flags that can be specified depend on
- /// the type of object whose handle is to be duplicated.
+ /// The access requested for the new handle. For the flags that can be specified for each object type, see the following Remarks section.
+ ///
+ ///
+ /// This parameter is ignored if the dwOptions parameter specifies the DUPLICATE_SAME_ACCESS flag. Otherwise, the flags that can be
+ /// specified depend on the type of object whose handle is to be duplicated.
///
///
///
- /// A variable that indicates whether the handle is inheritable. If TRUE, the duplicate handle can be inherited by new processes created by the
- /// target process. If FALSE, the new handle cannot be inherited.
+ /// A variable that indicates whether the handle is inheritable. If TRUE, the duplicate handle can be inherited by new
+ /// processes created by the target process. If FALSE, the new handle cannot be inherited.
///
///
/// Optional actions. This parameter can be zero, or any combination of the following values.
@@ -162,24 +178,28 @@ namespace Vanara.PInvoke
/// 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 DuplicateHandle( _In_ HANDLE hSourceProcessHandle, _In_ HANDLE hSourceHandle, _In_ HANDLE hTargetProcessHandle, _Out_ LPHANDLE
- // lpTargetHandle, _In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ DWORD dwOptions); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724251(v=vs.85).aspx
+ // BOOL WINAPI DuplicateHandle( _In_ HANDLE hSourceProcessHandle, _In_ HANDLE hSourceHandle, _In_ HANDLE hTargetProcessHandle, _Out_
+ // LPHANDLE lpTargetHandle, _In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ DWORD dwOptions); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724251(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("Winbase.h", MSDNShortId = "ms724251")]
[return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool DuplicateHandle([In] HPROCESS hSourceProcessHandle, [In] IntPtr hSourceHandle, [In] HPROCESS hTargetProcessHandle,
+ public static extern bool DuplicateHandle([In] HPROCESS hSourceProcessHandle, [In] IntPtr hSourceHandle, [In] HPROCESS hTargetProcessHandle,
out IntPtr lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, DUPLICATE_HANDLE_OPTIONS dwOptions);
/// Retrieves certain properties of an object handle.
///
/// A handle to an object whose information is to be retrieved.
///
- /// You can specify a handle to one of the following types of objects: access token, console input buffer, console screen buffer, event, file, file
- /// mapping, job, mailslot, mutex, pipe, printer, process, registry key, semaphore, serial communication device, socket, thread, or waitable timer.
+ /// You can specify a handle to one of the following types of objects: access token, console input buffer, console screen buffer,
+ /// event, file, file mapping, job, mailslot, mutex, pipe, printer, process, registry key, semaphore, serial communication device,
+ /// socket, thread, or waitable timer.
///
///
///
- /// A pointer to a variable that receives a set of bit flags that specify properties of the object handle or 0. The following values are defined.
+ ///
+ /// A pointer to a variable that receives a set of bit flags that specify properties of the object handle or 0. The following values
+ /// are defined.
+ ///
///
///
///
@@ -188,7 +208,10 @@ namespace Vanara.PInvoke
///
/// -
/// HANDLE_FLAG_INHERIT0x00000001
- /// If this flag is set, a child process created with the bInheritHandles parameter of CreateProcess set to TRUE will inherit the object handle.
+ ///
+ /// If this flag is set, a child process created with the bInheritHandles parameter of CreateProcess set to TRUE will inherit the
+ /// object handle.
+ ///
///
/// -
/// HANDLE_FLAG_PROTECT_FROM_CLOSE0x00000002
@@ -207,17 +230,27 @@ namespace Vanara.PInvoke
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetHandleInformation([In] IntPtr hObject, out HANDLE_FLAG lpdwFlags);
+ /// Retrieves certain properties of an object handle.
+ /// A handle to an object whose information is to be retrieved.
+ /// A variable that receives a set of bit flags that specify properties of the object handle
+ public static HANDLE_FLAG GetInformation(this IKernelHandle hObj) => GetHandleInformation(hObj.DangerousGetHandle(), out var flag) ? flag : 0;
+
/// Sets certain properties of an object handle.
///
/// A handle to an object whose information is to be set.
///
- /// You can specify a handle to one of the following types of objects: access token, console input buffer, console screen buffer, event, file, file
- /// mapping, job, mailslot, mutex, pipe, printer, process, registry key, semaphore, serial communication device, socket, thread, or waitable timer.
+ /// You can specify a handle to one of the following types of objects: access token, console input buffer, console screen buffer,
+ /// event, file, file mapping, job, mailslot, mutex, pipe, printer, process, registry key, semaphore, serial communication device,
+ /// socket, thread, or waitable timer.
///
///
- /// A mask that specifies the bit flags to be changed. Use the same constants shown in the description of dwFlags.
+ ///
+ /// A mask that specifies the bit flags to be changed. Use the same constants shown in the description of dwFlags.
+ ///
///
- /// Set of bit flags that specifies properties of the object handle. This parameter can be 0 or one or more of the following values.
+ ///
+ /// Set of bit flags that specifies properties of the object handle. This parameter can be 0 or one or more of the following values.
+ ///
///
///
///
@@ -226,7 +259,10 @@ namespace Vanara.PInvoke
///
/// -
/// HANDLE_FLAG_INHERIT0x00000001
- /// If this flag is set, a child process created with the bInheritHandles parameter of CreateProcess set to TRUE will inherit the object handle.
+ ///
+ /// If this flag is set, a child process created with the bInheritHandles parameter of CreateProcess set to TRUE will inherit the
+ /// object handle.
+ ///
///
/// -
/// HANDLE_FLAG_PROTECT_FROM_CLOSE0x00000002
@@ -253,7 +289,9 @@ namespace Vanara.PInvoke
/// 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).
+ ///
+ /// to reliably release the handle during the finalization phase; otherwise, (not recommended).
+ ///
protected SafeKernelHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
///