Skip to content

Commit b414548

Browse files
author
dahall
committed
Migrated all PInvoke.Cryptography handles to autogen
1 parent 9723555 commit b414548

16 files changed

+121
-1924
lines changed

PInvoke/Cryptography/BCrypt/BCrypt.cs

Lines changed: 6 additions & 383 deletions
Large diffs are not rendered by default.

PInvoke/Cryptography/Crypt32/Wincrypt.Cert.cs

Lines changed: 19 additions & 213 deletions
Original file line numberDiff line numberDiff line change
@@ -3057,6 +3057,24 @@ public static extern bool CertSelectCertificateChains([Optional] IntPtr pSelecti
30573057
public static unsafe extern bool CertSelectCertificateChains([In, Optional] Guid* pSelectionContext, CertSelection dwFlags, [In, Optional] CERT_SELECT_CHAIN_PARA* pChainParameters,
30583058
uint cCriteria, [In, Optional] CERT_SELECT_CRITERIA* rgpCriteria, HCERTSTORE hStore, out uint pcSelection, out CERT_CHAIN_CONTEXT* pprgpSelection);
30593059

3060+
//public static CERT_SELECT_CRITERIA[] CertSelectCertificateChains(in Guid pSelectionContext, HCERTSTORE hStore, CertSelection dwFlags, [Optional] CERT_SELECT_CHAIN_PARA? pChainParameters, [Optional] CERT_SELECT_CRITERIA[]? rgpCriteria)
3061+
//{
3062+
// unsafe
3063+
// {
3064+
// var cpdef = pChainParameters.GetValueOrDefault();
3065+
// if (!CertSelectCertificateChains(pSelectionContext, dwFlags, pChainParameters.HasValue ? &cpdef : null, rgpCriteria?.Length ?? 0, rgpCriteria, hStore, out var cSelections, out var ppSelections))
3066+
// throw new Win32Exception();
3067+
// var ret = new CERT_CHAIN_CONTEXT[cSelections];
3068+
// for (var i = 0; i < cSelections; i++)
3069+
// ret[i] = *ppSelections[i];
3070+
// return ret;
3071+
// }
3072+
//}
3073+
//[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
3074+
//[return: MarshalAs(UnmanagedType.Bool)]
3075+
//private static extern unsafe bool CertSelectCertificateChains(in Guid pSelectionContext, CertSelection dwFlags, [In, Optional] CERT_SELECT_CHAIN_PARA* pChainParameters, int cCriteria,
3076+
// [In, Optional, MarshalAs(UnmanagedType.LPArray)] CERT_SELECT_CRITERIA[]? rgpCriteria, HCERTSTORE hStore, out int pcSelection, out CERT_CHAIN_CONTEXT*[] pprgpSelection);
3077+
30603078
/// <summary>
30613079
/// The <c>CertSerializeCertificateStoreElement</c> function serializes a certificate context's encoded certificate and its encoded
30623080
/// properties. The result can be persisted to storage so that the certificate and properties can be retrieved at a later time.
@@ -3630,191 +3648,8 @@ public struct CERT_TRUST_LIST_INFO
36303648
public PCCTL_CONTEXT pCtlContext;
36313649
}
36323650

3633-
/// <summary>Provides a handle to an online certificate status protocol (OCSP) response.</summary>
3634-
[StructLayout(LayoutKind.Sequential)]
3635-
public readonly struct HCERT_SERVER_OCSP_RESPONSE : IHandle
3636-
{
3637-
private readonly IntPtr handle;
3638-
3639-
/// <summary>Initializes a new instance of the <see cref="HCERT_SERVER_OCSP_RESPONSE"/> struct.</summary>
3640-
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
3641-
public HCERT_SERVER_OCSP_RESPONSE(IntPtr preexistingHandle) => handle = preexistingHandle;
3642-
3643-
/// <summary>Returns an invalid handle by instantiating a <see cref="HCERT_SERVER_OCSP_RESPONSE"/> object with <see cref="IntPtr.Zero"/>.</summary>
3644-
public static HCERT_SERVER_OCSP_RESPONSE NULL => new(IntPtr.Zero);
3645-
3646-
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
3647-
public bool IsNull => handle == IntPtr.Zero;
3648-
3649-
/// <summary>Performs an explicit conversion from <see cref="HCERT_SERVER_OCSP_RESPONSE"/> to <see cref="IntPtr"/>.</summary>
3650-
/// <param name="h">The handle.</param>
3651-
/// <returns>The result of the conversion.</returns>
3652-
public static explicit operator IntPtr(HCERT_SERVER_OCSP_RESPONSE h) => h.handle;
3653-
3654-
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="HCERT_SERVER_OCSP_RESPONSE"/>.</summary>
3655-
/// <param name="h">The pointer to a handle.</param>
3656-
/// <returns>The result of the conversion.</returns>
3657-
public static implicit operator HCERT_SERVER_OCSP_RESPONSE(IntPtr h) => new(h);
3658-
3659-
/// <summary>Implements the operator !=.</summary>
3660-
/// <param name="h1">The first handle.</param>
3661-
/// <param name="h2">The second handle.</param>
3662-
/// <returns>The result of the operator.</returns>
3663-
public static bool operator !=(HCERT_SERVER_OCSP_RESPONSE h1, HCERT_SERVER_OCSP_RESPONSE h2) => !(h1 == h2);
3664-
3665-
/// <summary>Implements the operator ==.</summary>
3666-
/// <param name="h1">The first handle.</param>
3667-
/// <param name="h2">The second handle.</param>
3668-
/// <returns>The result of the operator.</returns>
3669-
public static bool operator ==(HCERT_SERVER_OCSP_RESPONSE h1, HCERT_SERVER_OCSP_RESPONSE h2) => h1.Equals(h2);
3670-
3671-
/// <inheritdoc/>
3672-
public override bool Equals(object? obj) => obj is HCERT_SERVER_OCSP_RESPONSE h && handle == h.handle;
3673-
3674-
/// <inheritdoc/>
3675-
public override int GetHashCode() => handle.GetHashCode();
3676-
3677-
/// <inheritdoc/>
3678-
public IntPtr DangerousGetHandle() => handle;
3679-
}
3680-
3681-
//public static CERT_SELECT_CRITERIA[] CertSelectCertificateChains(in Guid pSelectionContext, HCERTSTORE hStore, CertSelection dwFlags, [Optional] CERT_SELECT_CHAIN_PARA? pChainParameters, [Optional] CERT_SELECT_CRITERIA[]? rgpCriteria)
3682-
//{
3683-
// unsafe
3684-
// {
3685-
// var cpdef = pChainParameters.GetValueOrDefault();
3686-
// if (!CertSelectCertificateChains(pSelectionContext, dwFlags, pChainParameters.HasValue ? &cpdef : null, rgpCriteria?.Length ?? 0, rgpCriteria, hStore, out var cSelections, out var ppSelections))
3687-
// throw new Win32Exception();
3688-
// var ret = new CERT_CHAIN_CONTEXT[cSelections];
3689-
// for (var i = 0; i < cSelections; i++)
3690-
// ret[i] = *ppSelections[i];
3691-
// return ret;
3692-
// }
3693-
//}
3694-
//[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
3695-
//[return: MarshalAs(UnmanagedType.Bool)]
3696-
//private static extern unsafe bool CertSelectCertificateChains(in Guid pSelectionContext, CertSelection dwFlags, [In, Optional] CERT_SELECT_CHAIN_PARA* pChainParameters, int cCriteria,
3697-
// [In, Optional, MarshalAs(UnmanagedType.LPArray)] CERT_SELECT_CRITERIA[]? rgpCriteria, HCERTSTORE hStore, out int pcSelection, out CERT_CHAIN_CONTEXT*[] pprgpSelection);
3698-
3699-
/// <summary>Provides a handle to a Certificate Chain Engine.</summary>
3700-
[StructLayout(LayoutKind.Sequential)]
3701-
public readonly struct HCERTCHAINENGINE : IHandle
3702-
{
3703-
private readonly IntPtr handle;
3704-
3705-
/// <summary>Initializes a new instance of the <see cref="HCERTCHAINENGINE"/> struct.</summary>
3706-
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
3707-
public HCERTCHAINENGINE(IntPtr preexistingHandle) => handle = preexistingHandle;
3708-
3709-
/// <summary>Returns an invalid handle by instantiating a <see cref="HCERTCHAINENGINE"/> object with <see cref="IntPtr.Zero"/>.</summary>
3710-
public static HCERTCHAINENGINE NULL => new(IntPtr.Zero);
3711-
3712-
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
3713-
public bool IsNull => handle == IntPtr.Zero;
3714-
3715-
/// <summary>Performs an explicit conversion from <see cref="HCERTCHAINENGINE"/> to <see cref="IntPtr"/>.</summary>
3716-
/// <param name="h">The handle.</param>
3717-
/// <returns>The result of the conversion.</returns>
3718-
public static explicit operator IntPtr(HCERTCHAINENGINE h) => h.handle;
3719-
3720-
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="HCERTCHAINENGINE"/>.</summary>
3721-
/// <param name="h">The pointer to a handle.</param>
3722-
/// <returns>The result of the conversion.</returns>
3723-
public static implicit operator HCERTCHAINENGINE(IntPtr h) => new(h);
3724-
3725-
/// <summary>Implements the operator !=.</summary>
3726-
/// <param name="h1">The first handle.</param>
3727-
/// <param name="h2">The second handle.</param>
3728-
/// <returns>The result of the operator.</returns>
3729-
public static bool operator !=(HCERTCHAINENGINE h1, HCERTCHAINENGINE h2) => !(h1 == h2);
3730-
3731-
/// <summary>Implements the operator ==.</summary>
3732-
/// <param name="h1">The first handle.</param>
3733-
/// <param name="h2">The second handle.</param>
3734-
/// <returns>The result of the operator.</returns>
3735-
public static bool operator ==(HCERTCHAINENGINE h1, HCERTCHAINENGINE h2) => h1.Equals(h2);
3736-
3737-
/// <inheritdoc/>
3738-
public override bool Equals(object? obj) => obj is HCERTCHAINENGINE h && handle == h.handle;
3739-
3740-
/// <inheritdoc/>
3741-
public override int GetHashCode() => handle.GetHashCode();
3742-
3743-
/// <inheritdoc/>
3744-
public IntPtr DangerousGetHandle() => handle;
3745-
}
3746-
3747-
/// <summary>Provides a handle to a CERT_SERVER_OCSP_RESPONSE_CONTEXT.</summary>
3748-
[StructLayout(LayoutKind.Sequential)]
3749-
public readonly struct PCCERT_SERVER_OCSP_RESPONSE_CONTEXT : IHandle
3750-
{
3751-
private readonly IntPtr handle;
3752-
3753-
/// <summary>Initializes a new instance of the <see cref="PCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/> struct.</summary>
3754-
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
3755-
public PCCERT_SERVER_OCSP_RESPONSE_CONTEXT(IntPtr preexistingHandle) => handle = preexistingHandle;
3756-
3757-
/// <summary>
3758-
/// Returns an invalid handle by instantiating a <see cref="PCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/> object with <see cref="IntPtr.Zero"/>.
3759-
/// </summary>
3760-
public static PCCERT_SERVER_OCSP_RESPONSE_CONTEXT NULL => new(IntPtr.Zero);
3761-
3762-
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
3763-
public bool IsNull => handle == IntPtr.Zero;
3764-
3765-
/// <summary>Performs an explicit conversion from <see cref="PCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/> to <see cref="IntPtr"/>.</summary>
3766-
/// <param name="h">The handle.</param>
3767-
/// <returns>The result of the conversion.</returns>
3768-
public static explicit operator IntPtr(PCCERT_SERVER_OCSP_RESPONSE_CONTEXT h) => h.handle;
3769-
3770-
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="PCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/>.</summary>
3771-
/// <param name="h">The pointer to a handle.</param>
3772-
/// <returns>The result of the conversion.</returns>
3773-
public static implicit operator PCCERT_SERVER_OCSP_RESPONSE_CONTEXT(IntPtr h) => new(h);
3774-
3775-
/// <summary>Implements the operator !=.</summary>
3776-
/// <param name="h1">The first handle.</param>
3777-
/// <param name="h2">The second handle.</param>
3778-
/// <returns>The result of the operator.</returns>
3779-
public static bool operator !=(PCCERT_SERVER_OCSP_RESPONSE_CONTEXT h1, PCCERT_SERVER_OCSP_RESPONSE_CONTEXT h2) => !(h1 == h2);
3780-
3781-
/// <summary>Implements the operator ==.</summary>
3782-
/// <param name="h1">The first handle.</param>
3783-
/// <param name="h2">The second handle.</param>
3784-
/// <returns>The result of the operator.</returns>
3785-
public static bool operator ==(PCCERT_SERVER_OCSP_RESPONSE_CONTEXT h1, PCCERT_SERVER_OCSP_RESPONSE_CONTEXT h2) => h1.Equals(h2);
3786-
3787-
/// <inheritdoc/>
3788-
public override bool Equals(object? obj) => obj is PCCERT_SERVER_OCSP_RESPONSE_CONTEXT h && handle == h.handle;
3789-
3790-
/// <inheritdoc/>
3791-
public override int GetHashCode() => handle.GetHashCode();
3792-
3793-
/// <inheritdoc/>
3794-
public IntPtr DangerousGetHandle() => handle;
3795-
}
3796-
3797-
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="PCCERT_CONTEXT"/> that is disposed using <see cref="CertFreeCertificateContext"/>.</summary>
3798-
public class SafePCCERT_CONTEXT : SafeHANDLE
3651+
public partial class SafePCCERT_CONTEXT
37993652
{
3800-
/// <summary>Represents a NULL handle for <see cref="SafePCCERT_CONTEXT"/>. This must be used instead of <see langword="null"/>.</summary>
3801-
public static readonly SafePCCERT_CONTEXT Null = new(IntPtr.Zero, false);
3802-
3803-
/// <summary>Initializes a new instance of the <see cref="SafePCCERT_CONTEXT"/> class and assigns an existing handle.</summary>
3804-
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
3805-
/// <param name="ownsHandle">
3806-
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
3807-
/// </param>
3808-
public SafePCCERT_CONTEXT(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
3809-
3810-
/// <summary>Initializes a new instance of the <see cref="SafePCCERT_CONTEXT"/> class.</summary>
3811-
private SafePCCERT_CONTEXT() : base() { }
3812-
3813-
/// <summary>Performs an implicit conversion from <see cref="SafePCCERT_CONTEXT"/> to <see cref="PCCERT_CONTEXT"/>.</summary>
3814-
/// <param name="h">The safe handle instance.</param>
3815-
/// <returns>The result of the conversion.</returns>
3816-
public static implicit operator PCCERT_CONTEXT(SafePCCERT_CONTEXT h) => h.handle;
3817-
38183653
/// <summary>
38193654
/// Performs an explicit conversion from <see cref="SafePCCERT_CONTEXT"/> to <see cref="CERT_CONTEXT"/>.
38203655
/// </summary>
@@ -3823,34 +3658,5 @@ private SafePCCERT_CONTEXT() : base() { }
38233658
/// The resulting <see cref="CERT_CONTEXT"/> instance from the conversion.
38243659
/// </returns>
38253660
public static unsafe explicit operator CERT_CONTEXT*(SafePCCERT_CONTEXT h) => (CERT_CONTEXT*)(void*)h.handle;
3826-
3827-
/// <inheritdoc/>
3828-
protected override bool InternalReleaseHandle() => CertFreeCertificateContext(handle);
3829-
}
3830-
3831-
/// <summary>
3832-
/// Provides a <see cref="SafeHandle"/> for <see cref="PCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/> that is disposed using <see cref="CertFreeServerOcspResponseContext"/>.
3833-
/// </summary>
3834-
public class SafePCCERT_SERVER_OCSP_RESPONSE_CONTEXT : SafeHANDLE
3835-
{
3836-
/// <summary>
3837-
/// Initializes a new instance of the <see cref="SafePCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/> class and assigns an existing handle.
3838-
/// </summary>
3839-
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
3840-
/// <param name="ownsHandle">
3841-
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
3842-
/// </param>
3843-
public SafePCCERT_SERVER_OCSP_RESPONSE_CONTEXT(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
3844-
3845-
/// <summary>Initializes a new instance of the <see cref="SafePCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/> class.</summary>
3846-
private SafePCCERT_SERVER_OCSP_RESPONSE_CONTEXT() : base() { }
3847-
3848-
/// <summary>Performs an implicit conversion from <see cref="SafePCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/> to <see cref="PCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/>.</summary>
3849-
/// <param name="h">The safe handle instance.</param>
3850-
/// <returns>The result of the conversion.</returns>
3851-
public static implicit operator PCCERT_SERVER_OCSP_RESPONSE_CONTEXT(SafePCCERT_SERVER_OCSP_RESPONSE_CONTEXT h) => h.handle;
3852-
3853-
/// <inheritdoc/>
3854-
protected override bool InternalReleaseHandle() { CertFreeServerOcspResponseContext(handle); return true; }
38553661
}
38563662
}

PInvoke/Cryptography/Crypt32/Wincrypt.DataMgmt.cs

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,6 +1498,52 @@ public static unsafe extern bool CertVerifyRevocation(CertEncodingType dwEncodin
14981498
[return: MarshalAs(UnmanagedType.Bool)]
14991499
public static extern bool CertVerifyValidityNesting(in CERT_INFO pSubjectInfo, in CERT_INFO pIssuerInfo);
15001500

1501+
/// <summary>If the handle refers to a session key, or to a public key that has been imported into the <c>cryptographic service provider</c> (CSP) through <c>CryptImportKey</c>, this function destroys the key and frees the memory that the key used. Many CSPs overwrite the memory where the key was held before freeing it. However, the underlying <c>public/private key pair</c> is not destroyed by this function. Only the handle is destroyed.</summary>
1502+
/// <param name="hKey">The handle of the key to be destroyed.</param>
1503+
/// <returns>
1504+
/// <para>If the function succeeds, the return value is nonzero.</para>
1505+
/// <para>If the function fails, the return value is zero. For extended error information, call <c>GetLastError</c>.</para>
1506+
/// <para>The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the following table.</para>
1507+
/// <list type="table">
1508+
/// <listheader>
1509+
/// <description>Return code</description>
1510+
/// <description>Description</description>
1511+
/// </listheader>
1512+
/// <item>
1513+
/// <description><b>ERROR_BUSY</b></description>
1514+
/// <description>The key object specified by <i>hKey</i> is currently being used and cannot be destroyed.</description>
1515+
/// </item>
1516+
/// <item>
1517+
/// <description><b>ERROR_INVALID_HANDLE</b></description>
1518+
/// <description>The <i>hKey</i> parameter specifies a handle that is not valid.</description>
1519+
/// </item>
1520+
/// <item>
1521+
/// <description><b>ERROR_INVALID_PARAMETER</b></description>
1522+
/// <description>The <i>hKey</i> parameter contains a value that is not valid.</description>
1523+
/// </item>
1524+
/// <item>
1525+
/// <description><b>NTE_BAD_KEY</b></description>
1526+
/// <description>The <i>hKey</i> parameter does not contain a valid handle to a key.</description>
1527+
/// </item>
1528+
/// <item>
1529+
/// <description><b>NTE_BAD_UID</b></description>
1530+
/// <description>The CSP context that was specified when the key was created cannot be found.</description>
1531+
/// </item>
1532+
/// </list>
1533+
/// </returns>
1534+
/// <remarks>
1535+
/// <para>Keys take up both operating system's memory space and the CSP's memory space. Some CSPs are implemented in hardware with limited memory resources. Applications must destroy all keys with the <b>CryptDestroyKey</b> function when they are finished with them.</para>
1536+
/// <para>All key handles that have been created or imported by using a specific CSP must be destroyed before that CSP handle is released with the <c>CryptReleaseContext</c> function.</para>
1537+
/// <para>Examples</para>
1538+
/// <para>For an example that uses the <b>CryptDestroyKey</b> function, see <c>Example C Program: Creating and Hashing a Session Key</c>.</para>
1539+
/// </remarks>
1540+
// https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdestroykey
1541+
// BOOL CryptDestroyKey( [in] HCRYPTKEY hKey );
1542+
[PInvokeData("wincrypt.h", MSDNShortId = "NF:wincrypt.CryptDestroyKey")]
1543+
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
1544+
[return: MarshalAs(UnmanagedType.Bool)]
1545+
public static extern bool CryptDestroyKey([In] HCRYPTKEY hKey);
1546+
15011547
/// <summary>
15021548
/// <para>
15031549
/// [The <c>CryptExportPKCS8</c> function is no longer available for use as of Windows Server 2008 and Windows Vista. Instead, use
@@ -6373,32 +6419,4 @@ public SafeCryptMem(byte[] bytes) : base(bytes) { }
63736419
/// <returns>SafeMemoryHandleExt object to an native (unmanaged) string</returns>
63746420
public SafeCryptMem(string s, CharSet charSet = CharSet.Unicode) : base(s, charSet) { }
63756421
}
6376-
6377-
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="HCRYPTKEY"/> that is disposed using <see cref="CryptDestroyKey"/>.</summary>
6378-
public class SafeHCRYPTKEY : SafeHANDLE
6379-
{
6380-
/// <summary>Represents a NULL handle for <see cref="SafeHCRYPTKEY"/>. This must be used instead of <see langword="null"/>.</summary>
6381-
public static readonly SafeHCRYPTKEY Null = new(IntPtr.Zero, false);
6382-
6383-
/// <summary>Initializes a new instance of the <see cref="SafeHCRYPTKEY"/> class and assigns an existing handle.</summary>
6384-
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
6385-
/// <param name="ownsHandle">
6386-
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
6387-
/// </param>
6388-
public SafeHCRYPTKEY(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
6389-
6390-
/// <summary>Initializes a new instance of the <see cref="SafeHCRYPTKEY"/> class.</summary>
6391-
private SafeHCRYPTKEY() : base() { }
6392-
6393-
/// <summary>Performs an implicit conversion from <see cref="SafeHCRYPTKEY"/> to <see cref="HCRYPTKEY"/>.</summary>
6394-
/// <param name="h">The safe handle instance.</param>
6395-
/// <returns>The result of the conversion.</returns>
6396-
public static implicit operator HCRYPTKEY(SafeHCRYPTKEY h) => h.handle;
6397-
6398-
/// <inheritdoc/>
6399-
protected override bool InternalReleaseHandle() => CryptDestroyKey(handle);
6400-
6401-
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
6402-
[return: MarshalAs(UnmanagedType.Bool)] private static extern bool CryptDestroyKey(HCRYPTKEY hKey);
6403-
}
64046422
}

0 commit comments

Comments
 (0)