2017-11-27 12:18:01 -05:00
using System ;
using Microsoft.Win32.SafeHandles ;
using System.Runtime.InteropServices ;
namespace Vanara.InteropServices
{
/// <summary>A <see cref="SafeHandle"/> that takes a delegate in the constructor that closes the supplied handle.</summary>
/// <seealso cref="SafeHandle"/>
public class GenericSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
{
/// <summary>Initializes a new instance of the <see cref="GenericSafeHandle"/> class.</summary>
protected GenericSafeHandle ( ) : base ( true ) { }
2018-08-10 11:46:42 -04:00
/// <summary>Initializes a new instance of the <see cref="GenericSafeHandle"/> class.</summary>
/// <param name="ptr">The pre-existing handle to use.</param>
/// <param name="ownsHandle"><see langword="true"/> to reliably release the handle during the finalization phase; <see langword="false"/> to prevent reliable release (not recommended).</param>
2018-09-19 17:03:45 -04:00
protected GenericSafeHandle ( IntPtr ptr , bool ownsHandle ) : base ( ownsHandle ) = > SetHandle ( ptr ) ;
2018-08-10 11:46:42 -04:00
2017-11-27 12:18:01 -05:00
/// <summary>Initializes a new instance of the <see cref="GenericSafeHandle"/> class.</summary>
/// <param name="closeMethod">The delegate method for closing the handle.</param>
public GenericSafeHandle ( Func < IntPtr , bool > closeMethod ) : this ( IntPtr . Zero , closeMethod , true ) { }
/// <summary>Initializes a new instance of the <see cref="GenericSafeHandle"/> class.</summary>
2018-08-10 11:46:42 -04:00
/// <param name="ptr">The pre-existing handle to use.</param>
2017-11-27 12:18:01 -05:00
/// <param name="closeMethod">The delegate method for closing the handle.</param>
2018-08-10 11:46:42 -04:00
/// <param name="ownsHandle"><see langword="true"/> to reliably release the handle during the finalization phase; <see langword="false"/> to prevent reliable release (not recommended).</param>
2017-11-27 12:18:01 -05:00
/// <exception cref="System.ArgumentNullException">closeMethod</exception>
2020-08-27 12:25:14 -04:00
public GenericSafeHandle ( IntPtr ptr , Func < IntPtr , bool > closeMethod , bool ownsHandle = true ) : base ( ownsHandle )
{
SetHandle ( ptr ) ;
2022-07-29 00:19:53 -04:00
CloseMethod = closeMethod ? ? throw new ArgumentNullException ( nameof ( closeMethod ) ) ;
2020-08-27 12:25:14 -04:00
}
2017-11-27 12:18:01 -05:00
/// <summary>Gets or sets the close method.</summary>
/// <value>The close method.</value>
protected virtual Func < IntPtr , bool > CloseMethod { get ; }
/// <summary>When overridden in a derived class, executes the code required to free the handle.</summary>
/// <returns>
/// true if the handle is released successfully; otherwise, in the event of a catastrophic failure, false. In this case, it generates a
/// releaseHandleFailed MDA Managed Debugging Assistant.
/// </returns>
protected override bool ReleaseHandle ( )
{
var ret = CloseMethod ? . Invoke ( handle ) ? ? true ;
SetHandle ( IntPtr . Zero ) ;
return ret ;
}
}
}