Vanara/PInvoke/Cryptography/NCrypt/NCryptProtect.cs

1490 lines
67 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Text;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
/// <summary>Methods and data types found in ncrypt.dll.</summary>
public static partial class NCrypt
{
/// <summary>
/// <para>
/// The <c>PFNCryptStreamOutputCallback</c> function receives encrypted or decrypted data from tasks started by using the
/// NCryptStreamOpenToProtect or NCryptStreamOpenToUnprotect functions. This callback must be defined by your application using the
/// following syntax.
/// </para>
/// </summary>
/// <param name="*pvCallbackCtxt">
/// <para>Pointer to data that you can use to keep track of your application. The data is not modified by the data protection API.</para>
/// <para>
/// <c>Note</c> You can set a pointer to your context data in the <c>pvCallbackCtxt</c> member of the NCRYPT_PROTECT_STREAM_INFO
/// structure before passing a pointer to that structure in the pStreamInfo parameter of the NCryptStreamOpenToProtect or
/// NCryptStreamOpenToUnprotect functions.
/// </para>
/// </param>
/// <param name="*pbData">
/// <para>Pointer to a block of processed data that can be used by the application.</para>
/// </param>
/// <param name="cbData">
/// <para>The size, in bytes, of the processed data pointed to by the pbData parameter.</para>
/// </param>
/// <param name="fFinal">
/// <para>
/// If this value is <c>TRUE</c>, the current data block is the last to be processed and this is the last time the callback will be called.
/// </para>
/// </param>
/// <returns>
/// <para>
/// If you return any status code other than <c>ERROR_SUCCESS</c> from your implementation of this callback function, the stream
/// encryption or decryption process will fail.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Set a pointer to this callback function in the <c>pfnStreamOutput</c> member of the NCRYPT_PROTECT_STREAM_INFO structure. Set a
/// pointer to the structure in the pStreamInfo parameter of the NCryptStreamOpenToProtect or NCryptStreamOpenToUnprotect functions.
/// </para>
/// <para>
/// You can use this callback to further process the encrypted or decrypted data. A common use of the function is to write the data
/// to disk as it is received from the data protection API. The blocks of encrypted or unencrypted data are created by the
/// NCryptStreamUpdate function.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nc-ncryptprotect-pfncryptstreamoutputcallback
// PFNCryptStreamOutputCallback Pfncryptstreamoutputcallback; SECURITY_STATUS Pfncryptstreamoutputcallback( void *pvCallbackCtxt,
// const BYTE *pbData, SIZE_T cbData, BOOL fFinal ) {...}
[PInvokeData("ncryptprotect.h", MSDNShortId = "D07B2B63-306B-4C41-AA14-320EFEFFB939")]
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate HRESULT PFNCryptStreamOutputCallback(IntPtr pvCallbackCtxt, IntPtr pbData, SizeT cbData, [MarshalAs(UnmanagedType.Bool)] bool fFinal);
/// <summary>
/// The <c>PFNCryptStreamOutputCallbackEx</c> function receives encrypted or decrypted data from tasks started by using the
/// NCryptStreamOpenToProtectEx or NCryptStreamOpenToUnprotectEx functions. This callback must be defined by your application using
/// the following syntax.
/// </summary>
/// <param name="pvCallbackCtxt">The arguments specified by NCRYPT_PROTECT_STREAM_INFO_EX.</param>
/// <param name="pbData">
/// A pointer to a block of processed data that is available to the application. If data is not available yet, but the descriptor is,
/// this will be NULL.
/// </param>
/// <param name="cbData">The size, in bytes, of the processed data pointed to by the pbData parameter.</param>
/// <param name="hDescriptor">Handle of Protection Descriptor.</param>
/// <param name="fFinal">
/// If this value is <c>TRUE</c>, the current data block is the last to be processed and this is the last time the callback will be called.
/// </param>
/// <returns>
/// <para>
/// If you return any status code other than <c>ERROR_SUCCESS</c> from your implementation of this callback function, the stream
/// encryption or decryption process will fail.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Set a pointer to this callback function in the <c>pfnStreamOutput</c> member of the NCRYPT_PROTECT_STREAM_INFO structure. Set a
/// pointer to the structure in the pStreamInfo parameter of the NCryptStreamOpenToProtect or NCryptStreamOpenToUnprotect functions.
/// </para>
/// <para>
/// You can use this callback to further process the encrypted or decrypted data. A common use of the function is to write the data
/// to disk as it is received from the data protection API. The blocks of encrypted or unencrypted data are created by the
/// NCryptStreamUpdate function.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nc-ncryptprotect-pfncryptstreamoutputcallback
[PInvokeData("ncryptprotect.h")]
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate HRESULT PFNCryptStreamOutputCallbackEx(IntPtr pvCallbackCtxt, IntPtr pbData, SizeT cbData, NCRYPT_DESCRIPTOR_HANDLE hDescriptor, [MarshalAs(UnmanagedType.Bool)] bool fFinal);
/// <summary>Flags for <c>NCryptCreateProtectionDescriptor</c>.</summary>
[PInvokeData("ncryptprotect.h", MSDNShortId = "BA6B15AC-2CD8-4D9A-817F-65CF9C09D22C")]
[Flags]
public enum CreateProtectionDescriptorFlags
{
/// <summary>
/// To indicate that the string is a display name and that it is saved, along with its associated descriptor string rule, in the
/// HKEY_CURRENT_USER registry hive, set only the NCRYPT_NAMED_DESCRIPTOR_FLAG value. That is, there is no unique flag to specify
/// the current user registry hive.
/// </summary>
NCRYPT_NAMED_DESCRIPTOR_FLAG = 0x00000001,
/// <summary>
/// To indicate that the string is a display name and that it is saved, along with its associated descriptor rule string, in the
/// HKEY_LOCAL_MACHINE registry hive, bitwise-OR the NCRYPT_NAMED_DESCRIPTOR_FLAG value and the NCRYPT_MACHINE_KEY_FLAG value.
/// </summary>
NCRYPT_MACHINE_KEY_FLAG = 0x00000020,
}
/// <summary>Flags for <c>NCryptProtectSecret</c>.</summary>
[PInvokeData("ncryptprotect.h", MSDNShortId = "8726F92B-34D5-4696-8803-3D7F50F1006D")]
[Flags]
public enum ProtectFlags
{
/// <summary>Requests that the key service provider not display a user interface.</summary>
NCRYPT_SILENT_FLAG = 0x00000040,
}
/// <summary>Flags used by <c>NCryptGetProtectionDescriptorInfo</c>.</summary>
[PInvokeData("ncryptprotect.h", MSDNShortId = "EF4777D5-E218-4868-8D25-58E0EF8C9D30")]
[Flags]
public enum ProtectionDescriptorInfoType
{
/// <summary>The ppvInfo argument returns the descriptor rule string.</summary>
[CorrespondingType(typeof(string))]
NCRYPT_PROTECTION_INFO_TYPE_DESCRIPTOR_STRING = 0x00000001,
}
/// <summary>Flags for <c>NCryptQueryProtectionDescriptorName</c>.</summary>
[PInvokeData("ncryptprotect.h", MSDNShortId = "32953AEC-01EE-4ED1-80F3-29963F43004F")]
[Flags]
public enum ProtectionDescriptorNameFlags
{
/// <summary>
/// To indicate that the string is a display name and that it is saved, along with its associated descriptor rule string, in the
/// HKEY_LOCAL_MACHINE registry hive, bitwise-OR the NCRYPT_NAMED_DESCRIPTOR_FLAG value and the NCRYPT_MACHINE_KEY_FLAG value.
/// </summary>
NCRYPT_MACHINE_KEY_FLAG = 0x00000020,
}
/// <summary>Flags used by <c>NCryptUnprotectSecret</c>.</summary>
[PInvokeData("ncryptprotect.h", MSDNShortId = "F532F0ED-36F4-47E3-B478-089CC083E5D1")]
[Flags]
public enum UnprotectSecretFlags
{
/// <summary>Decodes only the header of the protected data blob. No actual decryption takes place.</summary>
NCRYPT_UNPROTECT_NO_DECRYPT = 0x00000001,
/// <summary>Requests that the key service provider not display a user interface.</summary>
NCRYPT_SILENT_FLAG = 0x00000040,
}
/// <summary>
/// <para>The <c>NCryptCloseProtectionDescriptor</c> function zeros and frees a protection descriptor object and releases its handle.</para>
/// </summary>
/// <param name="hDescriptor">
/// <para>Handle of a protection descriptor created by calling NCryptCreateProtectionDescriptor.</para>
/// </param>
/// <returns>
/// <para>
/// Returns a status code that indicates the success or failure of the function. Possible return codes include, but are not limited
/// to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_HANDLE</term>
/// <term>The handle specified by the hDescriptor parameter cannot be NULL and it must represent a valid descriptor.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nf-ncryptprotect-ncryptcloseprotectiondescriptor
// SECURITY_STATUS NCryptCloseProtectionDescriptor( NCRYPT_DESCRIPTOR_HANDLE hDescriptor );
[DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ncryptprotect.h", MSDNShortId = "523FD83E-85A3-4A0E-BA8D-2F27F82C1072")]
public static extern HRESULT NCryptCloseProtectionDescriptor(NCRYPT_DESCRIPTOR_HANDLE hDescriptor);
/// <summary>
/// <para>The <c>NCryptCreateProtectionDescriptor</c> function retrieves a handle to a protection descriptor object.</para>
/// </summary>
/// <param name="pwszDescriptorString">
/// <para>
/// Null-terminated Unicode string that contains a protection descriptor rule string or a registered display name for the rule.
/// </para>
/// <para>
/// If you specify the display name and you want this function to look in the registry for the associated protection descriptor rule
/// string, you must set the dwFlags parameter to <c>NCRYPT_NAMED_DESCRIPTOR_FLAG</c>.
/// </para>
/// </param>
/// <param name="dwFlags">
/// <para>
/// Flag that specifies whether the string in pwszDescriptorString represents the display name of a protection descriptor and, if so,
/// where in the registry the function should search for the associated protection rule string. The following value combinations can
/// be set:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// To indicate that the value set in the pwszDescriptorString parameter is a complete protection descriptor rule string rather than
/// a display name, set the dwFlags parameter to zero (0).
/// </term>
/// </item>
/// <item>
/// <term>
/// To indicate that the string is a display name and that it is saved, along with its associated descriptor rule string, in the
/// <c>HKEY_LOCAL_MACHINE</c> registry hive, bitwise-OR the <c>NCRYPT_NAMED_DESCRIPTOR_FLAG</c> value and the
/// <c>NCRYPT_MACHINE_KEY_FLAG</c> value.
/// </term>
/// </item>
/// <item>
/// <term>
/// To indicate that the string is a display name and that it is saved, along with its associated descriptor string rule, in the
/// <c>HKEY_CURRENT_USER</c> registry hive, set only the <c>NCRYPT_NAMED_DESCRIPTOR_FLAG</c> value. That is, there is no unique flag
/// to specify the current user registry hive.
/// </term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> To associate a descriptor rule with a display name and save both in the registry, call the
/// NCryptRegisterProtectionDescriptorName function.
/// </para>
/// </param>
/// <param name="phDescriptor">
/// <para>Pointer to a protection descriptor object handle.</para>
/// </param>
/// <returns>
/// <para>
/// Returns a status code that indicates the success or failure of the function. Possible return codes include, but are not limited
/// to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_PARAMETER</term>
/// <term>
/// The phDescriptor parameter cannot be NULL. The pwszDescriptorString parameter cannot be NULL and it cannot be an empty sting.
/// </term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter must be NCRYPT_MACHINE_KEY_FLAG or NCRYPT_NAMED_DESCRIPTOR_FLAG.</term>
/// </item>
/// <item>
/// <term>NTE_NO_MEMORY</term>
/// <term>Memory could not be allocated to retrieve the registered protection descriptor string.</term>
/// </item>
/// <item>
/// <term>NTE_NOT_FOUND</term>
/// <term>The protection descriptor name specified in the pwszDescriptorString parameter could not be found.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The protection descriptor object created by this function is an internal data structure that contains information about the
/// descriptor. You cannot use it directly. Your application can, however, use the returned handle in the following functions:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>NCryptCloseProtectionDescriptor</term>
/// </item>
/// <item>
/// <term>NCryptGetProtectionDescriptorInfo</term>
/// </item>
/// <item>
/// <term>NCryptProtectSecret</term>
/// </item>
/// <item>
/// <term>NCryptProtectSecret</term>
/// </item>
/// <item>
/// <term>NCryptUnprotectSecret</term>
/// </item>
/// <item>
/// <term>NCryptStreamOpenToProtect</term>
/// </item>
/// </list>
/// <para>The following examples show protection descriptor rule strings:</para>
/// <list type="bullet">
/// <item>
/// <term>"SID=S-1-5-21-4392301 AND SID=S-1-5-21-3101812"</term>
/// </item>
/// <item>
/// <term>"SDDL=O:S-1-5-5-0-290724G:SYD:(A;;CCDC;;;S-1-5-5-0-290724)(A;;DC;;;WD)"</term>
/// </item>
/// <item>
/// <term>"LOCAL=user"</term>
/// </item>
/// <item>
/// <term>"LOCAL=machine"</term>
/// </item>
/// <item>
/// <term>"WEBCREDENTIALS=MyPasswordName"</term>
/// </item>
/// <item>
/// <term>"WEBCREDENTIALS=MyPasswordName,myweb.com"</term>
/// </item>
/// </list>
/// <para>
/// You can use the NCryptRegisterProtectionDescriptorName function to associate a display name with a rule string and save both in
/// the registry.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nf-ncryptprotect-ncryptcreateprotectiondescriptor
// SECURITY_STATUS NCryptCreateProtectionDescriptor( LPCWSTR pwszDescriptorString, DWORD dwFlags, NCRYPT_DESCRIPTOR_HANDLE
// *phDescriptor );
[DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ncryptprotect.h", MSDNShortId = "BA6B15AC-2CD8-4D9A-817F-65CF9C09D22C")]
public static extern HRESULT NCryptCreateProtectionDescriptor([MarshalAs(UnmanagedType.LPWStr)] string pwszDescriptorString, CreateProtectionDescriptorFlags dwFlags, out SafeNCRYPT_DESCRIPTOR_HANDLE phDescriptor);
/// <summary>
/// <para>The <c>NCryptGetProtectionDescriptorInfo</c> function retrieves a protection descriptor rule string.</para>
/// </summary>
/// <param name="hDescriptor">
/// <para>Protection descriptor handle created by calling NCryptCreateProtectionDescriptor.</para>
/// </param>
/// <param name="pMemPara">
/// <para>
/// Pointer to an NCRYPT_ALLOC_PARA structure that you can use to specify custom memory management functions. If you set this
/// argument to <c>NULL</c>, the LocalAlloc function is used internally to allocate memory and your application must call LocalFree
/// to release memory pointed to by the ppvInfo parameter.
/// </para>
/// </param>
/// <param name="dwInfoType">
/// <para>Specifies how to return descriptor information to the ppvInfo parameter. This can be the following value:</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>NCRYPT_PROTECTION_INFO_TYPE_DESCRIPTOR_STRING</term>
/// <term>The ppvInfo argument returns the descriptor rule string.</term>
/// </item>
/// </list>
/// </param>
/// <param name="ppvInfo">
/// <para>Pointer to the descriptor information.</para>
/// </param>
/// <returns>
/// <para>
/// Returns a status code that indicates the success or failure of the function. Possible return codes include, but are not limited
/// to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_PARAMETER</term>
/// <term>The ppvInfo parameter cannot be NULL.</term>
/// </item>
/// <item>
/// <term>NTE_NOT_SUPPORTED</term>
/// <term>An unsupported value was specified in the dwInfoType parameter.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_HANDLE</term>
/// <term>The handle specified by the hDescriptor parameter is not valid.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nf-ncryptprotect-ncryptgetprotectiondescriptorinfo
// SECURITY_STATUS NCryptGetProtectionDescriptorInfo( NCRYPT_DESCRIPTOR_HANDLE hDescriptor, const NCRYPT_ALLOC_PARA *pMemPara, DWORD
// dwInfoType, void **ppvInfo );
[DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ncryptprotect.h", MSDNShortId = "EF4777D5-E218-4868-8D25-58E0EF8C9D30")]
public static extern HRESULT NCryptGetProtectionDescriptorInfo(NCRYPT_DESCRIPTOR_HANDLE hDescriptor, in NCRYPT_ALLOC_PARA pMemPara, ProtectionDescriptorInfoType dwInfoType, out IntPtr ppvInfo);
/// <summary>
/// <para>The <c>NCryptGetProtectionDescriptorInfo</c> function retrieves a protection descriptor rule string.</para>
/// </summary>
/// <param name="hDescriptor">
/// <para>Protection descriptor handle created by calling NCryptCreateProtectionDescriptor.</para>
/// </param>
/// <param name="pMemPara">
/// <para>
/// Pointer to an NCRYPT_ALLOC_PARA structure that you can use to specify custom memory management functions. If you set this
/// argument to <c>NULL</c>, the LocalAlloc function is used internally to allocate memory and your application must call LocalFree
/// to release memory pointed to by the ppvInfo parameter.
/// </para>
/// </param>
/// <param name="dwInfoType">
/// <para>Specifies how to return descriptor information to the ppvInfo parameter. This can be the following value:</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>NCRYPT_PROTECTION_INFO_TYPE_DESCRIPTOR_STRING</term>
/// <term>The ppvInfo argument returns the descriptor rule string.</term>
/// </item>
/// </list>
/// </param>
/// <param name="ppvInfo">
/// <para>Pointer to the descriptor information.</para>
/// </param>
/// <returns>
/// <para>
/// Returns a status code that indicates the success or failure of the function. Possible return codes include, but are not limited
/// to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_PARAMETER</term>
/// <term>The ppvInfo parameter cannot be NULL.</term>
/// </item>
/// <item>
/// <term>NTE_NOT_SUPPORTED</term>
/// <term>An unsupported value was specified in the dwInfoType parameter.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_HANDLE</term>
/// <term>The handle specified by the hDescriptor parameter is not valid.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nf-ncryptprotect-ncryptgetprotectiondescriptorinfo
// SECURITY_STATUS NCryptGetProtectionDescriptorInfo( NCRYPT_DESCRIPTOR_HANDLE hDescriptor, const NCRYPT_ALLOC_PARA *pMemPara, DWORD
// dwInfoType, void **ppvInfo );
[DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ncryptprotect.h", MSDNShortId = "EF4777D5-E218-4868-8D25-58E0EF8C9D30")]
public static extern HRESULT NCryptGetProtectionDescriptorInfo(NCRYPT_DESCRIPTOR_HANDLE hDescriptor, [Optional] IntPtr pMemPara, ProtectionDescriptorInfoType dwInfoType, out IntPtr ppvInfo);
/// <summary>
/// <para>
/// The <c>NCryptProtectSecret</c> function encrypts data to a specified protection descriptor. Call NCryptUnprotectSecret to decrypt
/// the data.
/// </para>
/// </summary>
/// <param name="hDescriptor">
/// <para>Handle of the protection descriptor object. Create the handle by calling NCryptCreateProtectionDescriptor.</para>
/// </param>
/// <param name="dwFlags">
/// <para>The flag can be zero or the following value.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>NCRYPT_SILENT_FLAG</term>
/// <term>Requests that the key service provider not display a user interface.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pbData">
/// <para>Pointer to the byte array to be protected.</para>
/// </param>
/// <param name="cbData">
/// <para>Number of bytes in the binary array specified by the pbData parameter.</para>
/// </param>
/// <param name="pMemPara">
/// <para>
/// Pointer to an NCRYPT_ALLOC_PARA structure that you can use to specify custom memory management functions. If you set this
/// argument to <c>NULL</c>, the LocalAlloc function is used internally to allocate memory and your application must call LocalFree
/// to release memory pointed to by the ppbProtectedBlob parameter.
/// </para>
/// </param>
/// <param name="hWnd">
/// <para>Handle to the parent window of the user interface, if any, to be displayed.</para>
/// </param>
/// <param name="ppbProtectedBlob">
/// <para>Address of a variable that receives a pointer to the encrypted data.</para>
/// </param>
/// <param name="pcbProtectedBlob">
/// <para>
/// Pointer to a <c>ULONG</c> variable that contains the size, in bytes, of the encrypted data pointed to by the ppbProtectedBlob variable.
/// </para>
/// </param>
/// <returns>
/// <para>
/// Returns a status code that indicates the success or failure of the function. Possible return codes include, but are not limited
/// to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_PARAMETER</term>
/// <term>
/// The pbData, ppbProtectedBlob, and pcbProtectedBlob parameters cannot be NULL. The cbData parameter cannot be less than one.
/// </term>
/// </item>
/// <item>
/// <term>NTE_NO_MEMORY</term>
/// <term>Insufficient memory exists to allocate the content encryption key.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_HANDLE</term>
/// <term>The handle specified by the hDescriptor parameter is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Use the <c>NCryptProtectSecret</c> function to protect keys, key material, and passwords. Use the NCryptStreamOpenToProtect and
/// the NCryptStreamUpdate functions to encrypt larger messages.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nf-ncryptprotect-ncryptprotectsecret SECURITY_STATUS
// NCryptProtectSecret( NCRYPT_DESCRIPTOR_HANDLE hDescriptor, DWORD dwFlags, const BYTE *pbData, ULONG cbData, const
// NCRYPT_ALLOC_PARA *pMemPara, HWND hWnd, BYTE **ppbProtectedBlob, ULONG *pcbProtectedBlob );
[DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ncryptprotect.h", MSDNShortId = "8726F92B-34D5-4696-8803-3D7F50F1006D")]
public static extern HRESULT NCryptProtectSecret(NCRYPT_DESCRIPTOR_HANDLE hDescriptor, ProtectFlags dwFlags, [In] IntPtr pbData, uint cbData, in NCRYPT_ALLOC_PARA pMemPara, HWND hWnd,
out IntPtr ppbProtectedBlob, out uint pcbProtectedBlob);
/// <summary>
/// <para>
/// The <c>NCryptProtectSecret</c> function encrypts data to a specified protection descriptor. Call NCryptUnprotectSecret to decrypt
/// the data.
/// </para>
/// </summary>
/// <param name="hDescriptor">
/// <para>Handle of the protection descriptor object. Create the handle by calling NCryptCreateProtectionDescriptor.</para>
/// </param>
/// <param name="dwFlags">
/// <para>The flag can be zero or the following value.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>NCRYPT_SILENT_FLAG</term>
/// <term>Requests that the key service provider not display a user interface.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pbData">
/// <para>Pointer to the byte array to be protected.</para>
/// </param>
/// <param name="cbData">
/// <para>Number of bytes in the binary array specified by the pbData parameter.</para>
/// </param>
/// <param name="pMemPara">
/// <para>
/// Pointer to an NCRYPT_ALLOC_PARA structure that you can use to specify custom memory management functions. If you set this
/// argument to <c>NULL</c>, the LocalAlloc function is used internally to allocate memory and your application must call LocalFree
/// to release memory pointed to by the ppbProtectedBlob parameter.
/// </para>
/// </param>
/// <param name="hWnd">
/// <para>Handle to the parent window of the user interface, if any, to be displayed.</para>
/// </param>
/// <param name="ppbProtectedBlob">
/// <para>Address of a variable that receives a pointer to the encrypted data.</para>
/// </param>
/// <param name="pcbProtectedBlob">
/// <para>
/// Pointer to a <c>ULONG</c> variable that contains the size, in bytes, of the encrypted data pointed to by the ppbProtectedBlob variable.
/// </para>
/// </param>
/// <returns>
/// <para>
/// Returns a status code that indicates the success or failure of the function. Possible return codes include, but are not limited
/// to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_PARAMETER</term>
/// <term>
/// The pbData, ppbProtectedBlob, and pcbProtectedBlob parameters cannot be NULL. The cbData parameter cannot be less than one.
/// </term>
/// </item>
/// <item>
/// <term>NTE_NO_MEMORY</term>
/// <term>Insufficient memory exists to allocate the content encryption key.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_HANDLE</term>
/// <term>The handle specified by the hDescriptor parameter is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Use the <c>NCryptProtectSecret</c> function to protect keys, key material, and passwords. Use the NCryptStreamOpenToProtect and
/// the NCryptStreamUpdate functions to encrypt larger messages.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nf-ncryptprotect-ncryptprotectsecret SECURITY_STATUS
// NCryptProtectSecret( NCRYPT_DESCRIPTOR_HANDLE hDescriptor, DWORD dwFlags, const BYTE *pbData, ULONG cbData, const
// NCRYPT_ALLOC_PARA *pMemPara, HWND hWnd, BYTE **ppbProtectedBlob, ULONG *pcbProtectedBlob );
[DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ncryptprotect.h", MSDNShortId = "8726F92B-34D5-4696-8803-3D7F50F1006D")]
public static extern HRESULT NCryptProtectSecret(NCRYPT_DESCRIPTOR_HANDLE hDescriptor, ProtectFlags dwFlags, [In] IntPtr pbData, uint cbData, [Optional] IntPtr pMemPara, HWND hWnd,
out IntPtr ppbProtectedBlob, out uint pcbProtectedBlob);
/// <summary>
/// <para>
/// The <c>NCryptQueryProtectionDescriptorName</c> function retrieves the protection descriptor rule string associated with a
/// registered descriptor display name.
/// </para>
/// </summary>
/// <param name="pwszName">
/// <para>
/// The registered display name for the protection descriptor. Register a name by calling the NCryptRegisterProtectionDescriptorName function.
/// </para>
/// </param>
/// <param name="pwszDescriptorString">
/// <para>
/// A null-terminated Unicode string that contains the protection descriptor rule. Set this value to <c>NULL</c> and set the size of
/// the descriptor string pointed to by pcDescriptorString argument to zero on your initial call to this function. For more
/// information, see Remarks.
/// </para>
/// </param>
/// <param name="pcDescriptorString">
/// <para>
/// Pointer to a variable that contains the number of characters in the string retrieved in the pwszDescriptorString parameter. Set
/// the variable to zero on your initial call to this function. For more information, see Remarks.
/// </para>
/// </param>
/// <param name="dwFlags">
/// <para>
/// Flag that specifies which registry hive to query for the registered name. This can be zero to look in the
/// <c>HKEY_CURRENT_USER</c> hive or you can specify <c>NCRYPT_MACHINE_KEY_FLAG</c> to query the <c>HKEY_LOCAL_MACHINE</c> hive.
/// </para>
/// </param>
/// <returns>
/// <para>
/// Returns a status code that indicates the success or failure of the function. Possible return codes include, but are not limited
/// to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_PARAMETER</term>
/// <term>The pwszName parameter cannot be NULL, and the value pointed to by the parameter cannot be an empty string.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter must be zero or NCRYPT_MACHINE_KEY_FLAG.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// To retrieve a protection descriptor rule string, you must call this function twice. The first time you call, set the
/// pwszDescriptorString argument to <c>NULL</c> and the value pointed to by the pcDescriptorString argument to zero. Your first call
/// retrieves the number of characters in the descriptor string. Use this number to allocate memory for the string and retrieve a
/// pointer to the allocated buffer. To retrieve the string, call the function again using the pointer.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nf-ncryptprotect-ncryptqueryprotectiondescriptorname
// SECURITY_STATUS NCryptQueryProtectionDescriptorName( LPCWSTR pwszName, LPWSTR pwszDescriptorString, SIZE_T *pcDescriptorString,
// DWORD dwFlags );
[DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("ncryptprotect.h", MSDNShortId = "32953AEC-01EE-4ED1-80F3-29963F43004F")]
public static extern HRESULT NCryptQueryProtectionDescriptorName(string pwszName, StringBuilder pwszDescriptorString, out SizeT pcDescriptorString, ProtectionDescriptorNameFlags dwFlags);
/// <summary>
/// <para>
/// The <c>NCryptRegisterProtectionDescriptorName</c> function registers the display name and the associated rule string for a
/// protection descriptor.
/// </para>
/// </summary>
/// <param name="pwszName">
/// <para>Pointer to a null-terminated Unicode string that contains the display name of the descriptor to be registered.</para>
/// </param>
/// <param name="pwszDescriptorString">
/// <para>
/// Pointer to a null-terminated Unicode string that contains a protection descriptor rule. If this parameter is <c>NULL</c> or the
/// string is empty, the registry value previously created for the pwszName parameter will be deleted.
/// </para>
/// </param>
/// <param name="dwFlags">
/// <para>
/// A constant that indicates the registry hive under which to register the new entry. If this value is zero (0), the registry root
/// is <c>HKEY_CURRENT_USER</c>. If this value is <c>NCRYPT_MACHINE_KEY_FLAG</c>, the root is <c>HKEY_LOCAL_MACHINE</c>.
/// </para>
/// </param>
/// <returns>
/// <para>
/// Returns a status code that indicates the success or failure of the function. Possible return codes include, but are not limited
/// to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_PARAMETER</term>
/// <term>The pwszName parameter cannot be NULL, and the value pointed to by the parameter cannot be an empty string.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter must be zero or NCRYPT_MACHINE_KEY_FLAG.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The registry key created by using this function is not volatile. The information is stored in a file and preserved when the
/// computer shuts down.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nf-ncryptprotect-ncryptregisterprotectiondescriptorname
// SECURITY_STATUS NCryptRegisterProtectionDescriptorName( LPCWSTR pwszName, LPCWSTR pwszDescriptorString, DWORD dwFlags );
[DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("ncryptprotect.h", MSDNShortId = "DAB03CB2-630F-4BB3-93BD-06BE9126B1C4")]
public static extern HRESULT NCryptRegisterProtectionDescriptorName(string pwszName, string pwszDescriptorString, ProtectionDescriptorNameFlags dwFlags);
/// <summary>
/// <para>
/// The <c>NCryptStreamClose</c> function closes a data protection stream object opened by using the NCryptStreamOpenToProtect or
/// NCryptStreamOpenToUnprotect functions.
/// </para>
/// </summary>
/// <param name="hStream">
/// <para>Data stream handle returned by NCryptStreamOpenToProtect or NCryptStreamOpenToUnprotect.</para>
/// </param>
/// <returns>
/// <para>
/// Returns a status code that indicates the success or failure of the function. Possible return codes include, but are not limited
/// to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_HANDLE</term>
/// <term>The handle specified by the hStream parameter is not valid.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nf-ncryptprotect-ncryptstreamclose SECURITY_STATUS
// NCryptStreamClose( NCRYPT_STREAM_HANDLE hStream );
[DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ncryptprotect.h", MSDNShortId = "770640F2-04C7-4512-8004-41F4ECDC110E")]
public static extern HRESULT NCryptStreamClose(NCRYPT_STREAM_HANDLE hStream);
/// <summary>
/// <para>
/// The <c>NCryptStreamOpenToProtect</c> function opens a stream object that can be used to encrypt large amounts of data to a given
/// protection descriptor. Call NCryptStreamUpdate to encrypt the content. To encrypt smaller messages such as keys and passwords,
/// call NCryptProtectSecret.
/// </para>
/// </summary>
/// <param name="hDescriptor">
/// <para>Handle of the protection descriptor. Create the handle by calling NCryptCreateProtectionDescriptor.</para>
/// </param>
/// <param name="dwFlags">
/// <para>The flag can be zero or the following value.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>NCRYPT_SILENT_FLAG</term>
/// <term>Requests that the key service provider not display a user interface.</term>
/// </item>
/// </list>
/// </param>
/// <param name="hWnd">
/// <para>Handle to the parent window of the user interface, if any, to be displayed.</para>
/// </param>
/// <param name="pStreamInfo">
/// <para>
/// Pointer to an NCRYPT_PROTECT_STREAM_INFO structure that contains the address of a user defined callback function to receive the
/// encrypted data and a pointer to user-defined context data.
/// </para>
/// </param>
/// <param name="phStream">
/// <para>Pointer to the stream object handle.</para>
/// </param>
/// <returns>
/// <para>
/// Returns a status code that indicates the success or failure of the function. Possible return codes include, but are not limited
/// to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter must contain zero (0), NCRYPT_MACHINE_KEY_FLAG, or NCRYPT_SILENT_FLAG.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_HANDLE</term>
/// <term>The handle specified by the hDescriptor parameter is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_PARAMETER</term>
/// <term>
/// The phStream and pStreamInfo parameters cannot be NULL. The callback function pointed to by the pfnStreamOutput member of the
/// NCRYPT_PROTECT_STREAM_INFO structure pointed to by the pStreamInfo parameter cannot be NULL.
/// </term>
/// </item>
/// <item>
/// <term>NTE_NO_MEMORY</term>
/// <term>There was insufficient memory to allocate a data stream.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>NCryptStreamOpenToProtect</c> function creates an internal stream object that can be used to encrypt large messages. You
/// cannot use the object directly. Instead, you must use the object handle returned by this function.
/// </para>
/// <para>
/// Call this function before calling the NCryptStreamUpdate function. If you are encrypting a large file, use
/// <c>NCryptStreamUpdate</c> in a loop that advances through the file block by block, encrypting each block as it advances and
/// notifying your callback when each block is finished. For more information, see <c>NCryptStreamUpdate</c>.
/// </para>
/// <para>
/// The <c>NCryptStreamOpenToProtect</c> function writes the unencrypted protection descriptor rule string to the stream object
/// header so that NCryptStreamOpenToUnprotect will be able to start the decrypting the stream by using the same protector used
/// during encryption.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nf-ncryptprotect-ncryptstreamopentoprotect SECURITY_STATUS
// NCryptStreamOpenToProtect( NCRYPT_DESCRIPTOR_HANDLE hDescriptor, DWORD dwFlags, HWND hWnd, NCRYPT_PROTECT_STREAM_INFO
// *pStreamInfo, NCRYPT_STREAM_HANDLE *phStream );
[DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ncryptprotect.h", MSDNShortId = "7DE74BB1-1B84-4721-BE4A-4D2661E93E00")]
public static extern HRESULT NCryptStreamOpenToProtect(NCRYPT_DESCRIPTOR_HANDLE hDescriptor, ProtectFlags dwFlags, HWND hWnd, in NCRYPT_PROTECT_STREAM_INFO pStreamInfo, out SafeNCRYPT_STREAM_HANDLE phStream);
/// <summary>
/// <para>
/// The <c>NCryptStreamOpenToUnprotect</c> function opens a stream object that can be used to decrypt large amounts of data to the
/// same protection descriptor used for encryption. Call NCryptStreamUpdate to perform the decryption. To decrypt smaller messages
/// such as keys and passwords, call NCryptUnprotectSecret.
/// </para>
/// </summary>
/// <param name="pStreamInfo">
/// <para>
/// Pointer to an NCRYPT_PROTECT_STREAM_INFO structure that contains the address of a user defined callback function to receive the
/// decrypted data and a pointer to user-defined context data.
/// </para>
/// </param>
/// <param name="dwFlags">
/// <para>A flag that specifies additional information for the key service provider. This can be zero or the following value.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>NCRYPT_SILENT_FLAG</term>
/// <term>Requests that the key service provider not display a user interface.</term>
/// </item>
/// </list>
/// </param>
/// <param name="hWnd">
/// <para>Handle to the parent window of the user interface, if any, to be displayed.</para>
/// </param>
/// <param name="phStream">
/// <para>Pointer to the handle of the decrypted stream of data.</para>
/// </param>
/// <returns>
/// <para>
/// Returns a status code that indicates the success or failure of the function. Possible return codes include, but are not limited
/// to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter must contain zero (0) or NCRYPT_SILENT_FLAG.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_PARAMETER</term>
/// <term>
/// The phStream and pStreamInfo parameters cannot be NULL. The callback function pointed to by the pfnStreamOutput member of the
/// NCRYPT_PROTECT_STREAM_INFO structure pointed to by the pStreamInfo parameter cannot be NULL.
/// </term>
/// </item>
/// <item>
/// <term>NTE_NO_MEMORY</term>
/// <term>There was insufficient memory to allocate a data stream.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>NCryptStreamOpenToUnprotect</c> function creates an internal stream object that can be used to encrypt large messages. You
/// cannot use the object directly. Instead, you must use the object handle returned by this function.
/// </para>
/// <para>
/// Call this function before calling the NCryptStreamUpdate function. If you are encrypting a large file, use
/// <c>NCryptStreamUpdate</c> in a loop that advances through the file block by block, encrypting each block as it advances and
/// notifying your callback when each block is finished. For more information, see <c>NCryptStreamUpdate</c>.
/// </para>
/// <para>
/// The <c>NCryptStreamOpenToUnprotect</c> function retrieves the unencrypted protection descriptor rule string from the stream
/// header. The rule string is placed in the header by the <c>NCryptStreamOpenToUnprotect</c> function.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nf-ncryptprotect-ncryptstreamopentounprotect SECURITY_STATUS
// NCryptStreamOpenToUnprotect( NCRYPT_PROTECT_STREAM_INFO *pStreamInfo, DWORD dwFlags, HWND hWnd, NCRYPT_STREAM_HANDLE *phStream );
[DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ncryptprotect.h", MSDNShortId = "9848082E-EDDA-4DA1-9896-42EAF2ADFAB4")]
public static extern HRESULT NCryptStreamOpenToUnprotect(in NCRYPT_PROTECT_STREAM_INFO pStreamInfo, ProtectFlags dwFlags, HWND hWnd, out SafeNCRYPT_STREAM_HANDLE phStream);
/// <summary>
/// <para>
/// [Some information relates to pre-released product which may be substantially modified before it's commercially released.
/// Microsoft makes no warranties, express or implied, with respect to the information provided here.]
/// </para>
/// <para>
/// Opens a stream object that can be used to decrypt large amounts of data to the same protection descriptor used for
/// encryption.Call NCryptStreamUpdate to perform the decryption. To decrypt smaller messages such as keys and passwords, call NCryptUnprotectSecret.
/// </para>
/// </summary>
/// <param name="pStreamInfo">
/// <para>A pointer to NCRYPT_PROTECT_STREAM_INFO_EX.</para>
/// </param>
/// <param name="dwFlags">
/// <para>Only the NCRYPT_SILENT_FLAG is supported.</para>
/// </param>
/// <param name="hWnd">
/// <para>A window handle to be used as the parent of any user interface that is displayed.</para>
/// </param>
/// <param name="phStream">
/// <para>Receives a pointer to a stream handle.</para>
/// </param>
/// <returns>
/// <para>
/// Returns a status code that indicates the success or failure of the function. Possible return codes include, but are not limited to:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>ERROR_SUCCESS</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_PARAMETER</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// </item>
/// <item>
/// <term>NTE_BAD_DATA</term>
/// </item>
/// <item>
/// <term>NTE_NO_MEMORY</term>
/// </item>
/// <item>
/// <term>NTE_NOT_FOUND</term>
/// </item>
/// <item>
/// <term>NTE_NOT_SUPPORTED</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_HANDLE</term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEY</term>
/// </item>
/// <item>
/// <term>NTE_BAD_PROVIDER</term>
/// </item>
/// <item>
/// <term>NTE_BAD_TYPE</term>
/// </item>
/// <item>
/// <term>NTE_DECRYPTION_FAILURE</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nf-ncryptprotect-ncryptstreamopentounprotectex SECURITY_STATUS
// NCryptStreamOpenToUnprotectEx( NCRYPT_PROTECT_STREAM_INFO_EX *pStreamInfo, DWORD dwFlags, HWND hWnd, NCRYPT_STREAM_HANDLE
// *phStream );
[DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ncryptprotect.h", MSDNShortId = "8E607F4F-4A0F-4796-8F40-D232687815AF")]
public static extern HRESULT NCryptStreamOpenToUnprotectEx(in NCRYPT_PROTECT_STREAM_INFO_EX pStreamInfo, ProtectFlags dwFlags, HWND hWnd, out SafeNCRYPT_STREAM_HANDLE phStream);
/// <summary>
/// <para>The <c>NCryptStreamUpdate</c> function encrypts and decrypts blocks of data.</para>
/// </summary>
/// <param name="hStream">
/// <para>Handle to the stream object created by calling NCryptStreamOpenToProtect or NCryptStreamOpenToUnprotect.</para>
/// </param>
/// <param name="pbData">
/// <para>Pointer to the byte array to be processed.</para>
/// </param>
/// <param name="cbData">
/// <para>Number of bytes in the binary array specified by the pbData parameter.</para>
/// </param>
/// <param name="fFinal">
/// <para>A Boolean value that specifies whether the last block of data has been processed.</para>
/// </param>
/// <returns>
/// <para>
/// Returns a status code that indicates the success or failure of the function. Possible return codes include, but are not limited
/// to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_DATA</term>
/// <term>The content could not be decoded.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_HANDLE</term>
/// <term>The stream handle pointed to by the hStream parameter is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_NO_MEMORY</term>
/// <term>There was insufficient memory available to process the content.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>You must call NCryptStreamOpenToProtect or NCryptStreamOpenToUnprotect to open a stream before calling <c>NCryptStreamUpdate</c></para>
/// <para>
/// Messages can be so large that processing them all at once by storing the entire message in memory can be difficult. It is
/// possible, however, to process large messages by partitioning the data to be processed into manageable blocks.
/// </para>
/// <para>
/// To do this, use <c>NCryptStreamUpdate</c> in a loop that advances through the file block by block. As the streamed message is
/// processed, the resulting output data is passed back to your application by using a callback function that you specify. This is
/// shown by the following example. For more information about the callback function, see PFNCryptStreamOutputCallback.
/// </para>
/// <para>
/// <c>Note</c> We recommend against using too small of a block size. Small blocks require more calls and therefore more calling
/// overhead. Further, the streaming APIs are optimized for larger blocks. You should experiment to find the best block size for the
/// data you must process.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nf-ncryptprotect-ncryptstreamupdate SECURITY_STATUS
// NCryptStreamUpdate( NCRYPT_STREAM_HANDLE hStream, const BYTE *pbData, SIZE_T cbData, BOOL fFinal );
[DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ncryptprotect.h", MSDNShortId = "417F9267-6055-489C-AF26-BEF5E17CB8B4")]
public static extern HRESULT NCryptStreamUpdate(NCRYPT_STREAM_HANDLE hStream, IntPtr pbData, SizeT cbData, [MarshalAs(UnmanagedType.Bool)] bool fFinal);
/// <summary>
/// <para>
/// The <c>NCryptUnprotectSecret</c> function decrypts data to a specified protection descriptor. Call NCryptProtectSecret to encrypt
/// the data.
/// </para>
/// </summary>
/// <param name="phDescriptor">
/// <para>Pointer to the protection descriptor handle.</para>
/// </param>
/// <param name="dwFlags">
/// <para>The flag can be zero or a bitwise OR of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>NCRYPT_SILENT_FLAG</term>
/// <term>Requests that the key service provider not display a user interface.</term>
/// </item>
/// <item>
/// <term>NCRYPT_UNPROTECT_NO_DECRYPT</term>
/// <term>Decodes only the header of the protected data blob. No actual decryption takes place.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pbProtectedBlob">
/// <para>Pointer to an array of bytes that contains the data to decrypt.</para>
/// </param>
/// <param name="cbProtectedBlob">
/// <para>The number of bytes in the array pointed to by the pbProtectedBlob parameter.</para>
/// </param>
/// <param name="pMemPara">
/// <para>
/// Pointer to an NCRYPT_ALLOC_PARA structure that you can use to specify custom memory management functions. If you set this
/// argument to <c>NULL</c>, the LocalAlloc function is used internally to allocate memory and your application must call LocalFree
/// to release memory pointed to by the ppbData parameter.
/// </para>
/// </param>
/// <param name="hWnd">
/// <para>Handle to the parent window of the user interface, if any, to be displayed.</para>
/// </param>
/// <param name="ppbData">
/// <para>Address of a variable that receives a pointer to the decrypted data.</para>
/// </param>
/// <param name="pcbData">
/// <para>Pointer to a <c>ULONG</c> variable that contains the size, in bytes, of the decrypted data pointed to by the ppbData variable.</para>
/// </param>
/// <returns>
/// <para>
/// Returns a status code that indicates the success or failure of the function. Possible return codes include, but are not limited
/// to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter can only contain NCRYPT_SILENT_FLAG or NCRYPT_UNPROTECT_NO_DECRYPT.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_PARAMETER</term>
/// <term>The pbProtectedBlob, ppbData, and pcbData parameters cannot be NULL. The cbData parameter cannot be less than one.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Use the <c>NCryptUnprotectSecret</c> function to decrypt keys, key material, and passwords. Use the NCryptStreamOpenToUnprotect
/// and the NCryptStreamUpdate functions to decrypt larger messages.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nf-ncryptprotect-ncryptunprotectsecret SECURITY_STATUS
// NCryptUnprotectSecret( NCRYPT_DESCRIPTOR_HANDLE *phDescriptor, DWORD dwFlags, const BYTE *pbProtectedBlob, ULONG cbProtectedBlob,
// const NCRYPT_ALLOC_PARA *pMemPara, HWND hWnd, BYTE **ppbData, ULONG *pcbData );
[DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ncryptprotect.h", MSDNShortId = "F532F0ED-36F4-47E3-B478-089CC083E5D1")]
public static extern HRESULT NCryptUnprotectSecret(out SafeNCRYPT_DESCRIPTOR_HANDLE phDescriptor, UnprotectSecretFlags dwFlags, [In] IntPtr pbProtectedBlob, uint cbProtectedBlob, in NCRYPT_ALLOC_PARA pMemPara,
HWND hWnd, out IntPtr ppbData, out uint pcbData);
/// <summary>
/// <para>
/// The <c>NCryptUnprotectSecret</c> function decrypts data to a specified protection descriptor. Call NCryptProtectSecret to encrypt
/// the data.
/// </para>
/// </summary>
/// <param name="phDescriptor">
/// <para>Pointer to the protection descriptor handle.</para>
/// </param>
/// <param name="dwFlags">
/// <para>The flag can be zero or a bitwise OR of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>NCRYPT_SILENT_FLAG</term>
/// <term>Requests that the key service provider not display a user interface.</term>
/// </item>
/// <item>
/// <term>NCRYPT_UNPROTECT_NO_DECRYPT</term>
/// <term>Decodes only the header of the protected data blob. No actual decryption takes place.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pbProtectedBlob">
/// <para>Pointer to an array of bytes that contains the data to decrypt.</para>
/// </param>
/// <param name="cbProtectedBlob">
/// <para>The number of bytes in the array pointed to by the pbProtectedBlob parameter.</para>
/// </param>
/// <param name="pMemPara">
/// <para>
/// Pointer to an NCRYPT_ALLOC_PARA structure that you can use to specify custom memory management functions. If you set this
/// argument to <c>NULL</c>, the LocalAlloc function is used internally to allocate memory and your application must call LocalFree
/// to release memory pointed to by the ppbData parameter.
/// </para>
/// </param>
/// <param name="hWnd">
/// <para>Handle to the parent window of the user interface, if any, to be displayed.</para>
/// </param>
/// <param name="ppbData">
/// <para>Address of a variable that receives a pointer to the decrypted data.</para>
/// </param>
/// <param name="pcbData">
/// <para>Pointer to a <c>ULONG</c> variable that contains the size, in bytes, of the decrypted data pointed to by the ppbData variable.</para>
/// </param>
/// <returns>
/// <para>
/// Returns a status code that indicates the success or failure of the function. Possible return codes include, but are not limited
/// to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_SUCCESS</term>
/// <term>The function was successful.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter can only contain NCRYPT_SILENT_FLAG or NCRYPT_UNPROTECT_NO_DECRYPT.</term>
/// </item>
/// <item>
/// <term>NTE_INVALID_PARAMETER</term>
/// <term>The pbProtectedBlob, ppbData, and pcbData parameters cannot be NULL. The cbData parameter cannot be less than one.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Use the <c>NCryptUnprotectSecret</c> function to decrypt keys, key material, and passwords. Use the NCryptStreamOpenToUnprotect
/// and the NCryptStreamUpdate functions to decrypt larger messages.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/nf-ncryptprotect-ncryptunprotectsecret SECURITY_STATUS
// NCryptUnprotectSecret( NCRYPT_DESCRIPTOR_HANDLE *phDescriptor, DWORD dwFlags, const BYTE *pbProtectedBlob, ULONG cbProtectedBlob,
// const NCRYPT_ALLOC_PARA *pMemPara, HWND hWnd, BYTE **ppbData, ULONG *pcbData );
[DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ncryptprotect.h", MSDNShortId = "F532F0ED-36F4-47E3-B478-089CC083E5D1")]
public static extern HRESULT NCryptUnprotectSecret(out SafeNCRYPT_DESCRIPTOR_HANDLE phDescriptor, UnprotectSecretFlags dwFlags, [In] IntPtr pbProtectedBlob, uint cbProtectedBlob, [Optional] IntPtr pMemPara,
HWND hWnd, out IntPtr ppbData, out uint pcbData);
/// <summary>Provides a handle to a protection descriptor.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct NCRYPT_DESCRIPTOR_HANDLE : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="NCRYPT_DESCRIPTOR_HANDLE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public NCRYPT_DESCRIPTOR_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="NCRYPT_DESCRIPTOR_HANDLE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static NCRYPT_DESCRIPTOR_HANDLE NULL => new NCRYPT_DESCRIPTOR_HANDLE(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="NCRYPT_DESCRIPTOR_HANDLE"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(NCRYPT_DESCRIPTOR_HANDLE h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="NCRYPT_DESCRIPTOR_HANDLE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator NCRYPT_DESCRIPTOR_HANDLE(IntPtr h) => new NCRYPT_DESCRIPTOR_HANDLE(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(NCRYPT_DESCRIPTOR_HANDLE h1, NCRYPT_DESCRIPTOR_HANDLE h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(NCRYPT_DESCRIPTOR_HANDLE h1, NCRYPT_DESCRIPTOR_HANDLE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is NCRYPT_DESCRIPTOR_HANDLE h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>
/// The <c>NCRYPT_PROTECT_STREAM_INFO</c> structure is used by the NCryptStreamOpenToProtect and NCryptStreamOpenToUnprotect
/// functions to pass blocks of processed data to your application.
/// </summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/ncryptprotect/ns-ncryptprotect-ncrypt_protect_stream_info typedef struct
// NCRYPT_PROTECT_STREAM_INFO { PFNCryptStreamOutputCallback pfnStreamOutput; void *pvCallbackCtxt; } NCRYPT_PROTECT_STREAM_INFO;
[PInvokeData("ncryptprotect.h", MSDNShortId = "77FADFC1-6C66-4801-B0BD-263963555C3C")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct NCRYPT_PROTECT_STREAM_INFO
{
/// <summary>
/// Address of a callback function that accepts data from the stream encryption or decryption process. for more information, see PFNCryptStreamOutputCallback.
/// </summary>
public PFNCryptStreamOutputCallback pfnStreamOutput;
/// <summary>
/// Pointer to a buffer supplied the caller. The buffer is not modified by the data protection API. You can use the buffer to
/// keep track of your application.
/// </summary>
public IntPtr pvCallbackCtxt;
}
/// <summary>
/// The <c>NCRYPT_PROTECT_STREAM_INFO_EX</c> structure is used by the NCryptStreamOpenToProtectEx and NCryptStreamOpenToUnprotectEx
/// functions to pass blocks of processed data to your application.
/// </summary>
[PInvokeData("ncryptprotect.h")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct NCRYPT_PROTECT_STREAM_INFO_EX
{
/// <summary>
/// Address of a callback function that accepts data from the stream encryption or decryption process. for more information, see PFNCryptStreamOutputCallback.
/// </summary>
public PFNCryptStreamOutputCallbackEx pfnStreamOutput;
/// <summary>
/// Pointer to a buffer supplied the caller. The buffer is not modified by the data protection API. You can use the buffer to
/// keep track of your application.
/// </summary>
public IntPtr pvCallbackCtxt;
}
/// <summary>Provides a handle to a data protection stream object.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct NCRYPT_STREAM_HANDLE : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="NCRYPT_STREAM_HANDLE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public NCRYPT_STREAM_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="NCRYPT_STREAM_HANDLE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static NCRYPT_STREAM_HANDLE NULL => new NCRYPT_STREAM_HANDLE(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="NCRYPT_STREAM_HANDLE"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(NCRYPT_STREAM_HANDLE h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="NCRYPT_STREAM_HANDLE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator NCRYPT_STREAM_HANDLE(IntPtr h) => new NCRYPT_STREAM_HANDLE(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(NCRYPT_STREAM_HANDLE h1, NCRYPT_STREAM_HANDLE h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(NCRYPT_STREAM_HANDLE h1, NCRYPT_STREAM_HANDLE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is NCRYPT_STREAM_HANDLE h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="NCRYPT_DESCRIPTOR_HANDLE"/> that is disposed using <see cref="NCryptCloseProtectionDescriptor"/>.</summary>
public class SafeNCRYPT_DESCRIPTOR_HANDLE : HANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafeNCRYPT_DESCRIPTOR_HANDLE"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeNCRYPT_DESCRIPTOR_HANDLE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeNCRYPT_DESCRIPTOR_HANDLE"/> class.</summary>
private SafeNCRYPT_DESCRIPTOR_HANDLE() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeNCRYPT_DESCRIPTOR_HANDLE"/> to <see cref="NCRYPT_DESCRIPTOR_HANDLE"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator NCRYPT_DESCRIPTOR_HANDLE(SafeNCRYPT_DESCRIPTOR_HANDLE h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => NCryptCloseProtectionDescriptor(this).Succeeded;
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="NCRYPT_STREAM_HANDLE"/> that is disposed using <see cref="NCryptStreamClose"/>.</summary>
public class SafeNCRYPT_STREAM_HANDLE : HANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafeNCRYPT_STREAM_HANDLE"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeNCRYPT_STREAM_HANDLE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeNCRYPT_STREAM_HANDLE"/> class.</summary>
private SafeNCRYPT_STREAM_HANDLE() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeNCRYPT_STREAM_HANDLE"/> to <see cref="NCRYPT_STREAM_HANDLE"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator NCRYPT_STREAM_HANDLE(SafeNCRYPT_STREAM_HANDLE h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => NCryptStreamClose(this).Succeeded;
}
}
}