/// <summary>Determines if two object handles refer to the same underlying kernel object.</summary> /// <param name="h1">The first object handle to compare.</param> /// <param name="h2">The second object handle to compare.</param> /// <returns><see langword="true"/> if the two handles refer to the same underlying kernel object; <see langword="false"/> otherwise.</returns> public static bool Equals(this IKernelHandle h1, IKernelHandle h2) => CompareObjectHandles(h1.DangerousGetHandle(), h2?.DangerousGetHandle() ?? IntPtr.Zero);
/// <summary>Duplicates an object handle.</summary> /// <param name="hSourceHandle"> /// 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. /// </param> /// <param name="bInheritHandle"> /// A variable that indicates whether the handle is inheritable. If <c>TRUE</c>, the duplicate handle can be inherited by new /// processes created by the target process. If <c>FALSE</c>, the new handle cannot be inherited. /// </param> /// <param name="dwOptions"> /// <para>Optional actions. This parameter can be zero, or any combination of the following values.</para> /// <para> /// <list type="table"> /// <listheader> /// <term>Value</term> /// <term>Meaning</term> /// </listheader> /// <item> /// <term>DUPLICATE_CLOSE_SOURCE0x00000001</term> /// <term>Closes the source handle. This occurs regardless of any error status returned.</term> /// </item> /// <item> /// <term>DUPLICATE_SAME_ACCESS0x00000002</term> /// <term>Ignores the dwDesiredAccess parameter. The duplicate handle has the same access as the source handle.</term> /// </item> /// </list> /// </para> /// </param> /// <param name="dwDesiredAccess"> /// <para> /// The access requested for the new handle. For the flags that can be specified for each object type, see the following Remarks section. /// </para> /// <para> /// 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. /// </para> /// </param> /// <returns> /// <para>The duplicate handle. This handle value is valid in the context of the target process.</para> /// <para> /// If hSourceHandle is a pseudo handle returned by <c>GetCurrentProcess</c> or <c>GetCurrentThread</c>, <c>DuplicateHandle</c> /// converts it to a real handle to a process or thread, respectively. /// </para> /// </returns> public static IntPtr Duplicate(this IKernelHandle hSourceHandle, bool bInheritHandle = true, DUPLICATE_HANDLE_OPTIONS dwOptions = DUPLICATE_HANDLE_OPTIONS.DUPLICATE_SAME_ACCESS, uint dwDesiredAccess = default) => DuplicateHandle(GetCurrentProcess(), hSourceHandle.DangerousGetHandle(), GetCurrentProcess(), out var h, dwDesiredAccess, bInheritHandle, dwOptions) ? h : IntPtr.Zero;