using System;
using System.Runtime.InteropServices;
using Vanara.InteropServices;
using static Vanara.PInvoke.Crypt32;
using static Vanara.PInvoke.Kernel32;
namespace Vanara.PInvoke
{
public static partial class AdvApi32
{
/// Adds user keys to the specified encrypted file.
/// The name of the encrypted file.
///
/// A pointer to an ENCRYPTION_CERTIFICATE_LIST structure that contains the list of new user keys to be added to the file.
///
///
/// If the function succeeds, the return value is ERROR_SUCCESS.
///
/// If the function fails, the return value is a system error code. For a complete list of error codes, see System Error Codes or the
/// header file WinError.h.
///
///
///
/// Starting with Windows 8 and Windows Server 2012, this function is supported by the following technologies.
///
///
/// Technology
/// Supported
///
/// -
/// Server Message Block (SMB) 3.0 protocol
/// No
///
/// -
/// SMB 3.0 Transparent Failover (TFO)
/// No
///
/// -
/// SMB 3.0 with Scale-out File Shares (SO)
/// No
///
/// -
/// Cluster Shared Volume File System (CsvFS)
/// No
///
/// -
/// Resilient File System (ReFS)
/// No
///
///
/// SMB 3.0 does not support EFS on shares with continuous availability capability.
/// Examples
/// For example code that uses this function, see Adding Users to an Encrypted File.
///
// https://docs.microsoft.com/en-us/windows/win32/api/winefs/nf-winefs-adduserstoencryptedfile DWORD AddUsersToEncryptedFile( LPCWSTR
// lpFileName, PENCRYPTION_CERTIFICATE_LIST pEncryptionCertificates );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winefs.h", MSDNShortId = "a92d6a52-20d1-4d5c-a222-ab9afaf85c4b")]
public static extern Win32Error AddUsersToEncryptedFile([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, in ENCRYPTION_CERTIFICATE_LIST pEncryptionCertificates);
/// Copies the EFS metadata from one file or directory to another.
///
/// The name of the file or directory from which the EFS metadata is to be copied. This source file or directory must be encrypted.
///
///
/// The name of the file or directory to which the EFS metadata is to be copied.
///
/// This destination file or directory does not have to be encrypted before the call to this function; however if this function
/// completes successfully, it will be encrypted.
///
///
/// If the value of SrcFileName specifies a file, the value of this parameter must also specify a file, and likewise for directories.
/// If a file or directory with the name specified by this parameter does not exist, a file or directory (depending on whether
/// SrcFileName specifies a file or directory) will be created.
///
///
///
///
/// Describes how the destination file or directory identified by the DstFileName parameter value is to be opened. The following are
/// the valid values of this parameter.
///
///
///
/// Value
/// Meaning
///
/// -
/// CREATE_ALWAYS 2
///
/// Always create the destination file or directory. Any value passed in this parameter other than CREATE_NEW will be processed as CREATE_ALWAYS.
///
///
/// -
/// CREATE_NEW 1
///
/// Create the destination file or directory only if it does not already exist. If it does exist, and this value is specified, this
/// function will fail.
///
///
///
///
///
/// The file attributes of the destination file or directory. The FILE_READ_ONLY attribute is currently not processed by this function.
///
///
/// A pointer to a SECURITY_ATTRIBUTES structure that specifies the security attributes of the destination file or directory, if it
/// does not already exist. If you specify NULL, the file or directory gets a default security descriptor. The ACLs in the
/// default security descriptor for a file or directory are inherited from its parent directory.
///
///
/// If the function succeeds, the return value is ERROR_SUCCESS.
///
/// If the function fails, the return value is a system error code. For a complete list of error codes, see System Error Codes or the
/// header file WinError.h.
///
///
///
///
/// Exclusive access to the destination file or directory is required by EFS for the call to this function. If this access is not
/// provided, this function will fail.
///
///
/// The caller should have the EFS key for the source file or directory, and at least the READ_ATTRIBUTE ACL for the source
/// file or directory.
///
///
/// The specified source and destination file or directories should reside on the same computer; otherwise, an error will be returned.
///
/// In Windows 8 and Windows Server 2012, this function is supported by the following technologies.
///
///
/// Technology
/// Supported
///
/// -
/// Server Message Block (SMB) 3.0 protocol
/// Yes
///
/// -
/// SMB 3.0 Transparent Failover (TFO)
/// No
///
/// -
/// SMB 3.0 with Scale-out File Shares (SO)
/// No
///
/// -
/// Cluster Shared Volume File System (CsvFS)
/// No
///
/// -
/// Resilient File System (ReFS)
/// No
///
///
/// SMB 3.0 does not support EFS on shares with continuous availability capability.
///
// https://docs.microsoft.com/en-us/windows/win32/api/winefs/nf-winefs-duplicateencryptioninfofile DWORD DuplicateEncryptionInfoFile(
// LPCWSTR SrcFileName, LPCWSTR DstFileName, DWORD dwCreationDistribution, DWORD dwAttributes, const LPSECURITY_ATTRIBUTES
// lpSecurityAttributes );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("winefs.h", MSDNShortId = "c830ae98-3649-4981-9369-7d4cb019b50f")]
public static extern Win32Error DuplicateEncryptionInfoFile(string SrcFileName, string DstFileName, CreationOption dwCreationDistribution,
FileFlagsAndAttributes dwAttributes, [Optional] SECURITY_ATTRIBUTES lpSecurityAttributes);
///
/// Disables or enables encryption of the specified directory and the files in it. It does not affect encryption of subdirectories
/// below the indicated directory.
///
/// The name of the directory for which to enable or disable encryption.
/// Indicates whether to disable encryption ( TRUE) or enable it ( FALSE).
///
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
///
///
/// Under normal circumstances, EncryptFile will not encrypt files and directories with the FILE_ATTRIBUTE_SYSTEM attribute
/// set. It is possible to override the FILE_ATTRIBUTE_SYSTEM attribute and encrypt files. Also, if a file or directory is
/// marked with the FILE_ATTRIBUTE_SYSTEM attribute, it will normally be invisible to the user in directory listings and
/// Windows Explorer directory windows. EncryptionDisable disables encryption of directories and files. It does not affect the
/// visibility of files with the FILE_ATTRIBUTE_SYSTEM attribute set.
///
///
/// If TRUE is passed in, EncryptionDisable will write the following to the Desktop.ini file in the directory (creating
/// it if necessary):
///
/// If the section already exists but Disable is set to 0, it will be set to 1.
///
/// Thereafter, EncryptFile will fail on the directory and the files in it, and the code that GetLastError returns will be
/// ERROR_DIR_EFS_DISALLOWED. This function does not affect encryption of subdirectories within the given directory.
///
/// The user can also manually add or edit the above lines in the Desktop.ini file and produce the same effect.
///
/// EncryptionDisable affects only FileEncryptionStatus and EncryptFile. After the directory is encrypted, any new files and
/// new subdirectories created without the FILE_ATTRIBUTE_SYSTEM attribute will be encrypted.
///
/// If FALSE is passed in, EncryptionDisable will write the following to the Desktop.ini file:
/// This means that file encryption is permitted on the files in that directory.
///
/// If you try to use EncryptionDisable to set the directory to the state it is already in, the function succeeds but has no effect.
///
/// If you try to use EncryptionDisable to disable or enable encryption on a file, the attempt will fail.
/// In Windows 8 and Windows Server 2012, this function is supported by the following technologies.
///
///
/// Technology
/// Supported
///
/// -
/// Server Message Block (SMB) 3.0 protocol
/// Yes
///
/// -
/// SMB 3.0 Transparent Failover (TFO)
/// No
///
/// -
/// SMB 3.0 with Scale-out File Shares (SO)
/// No
///
/// -
/// Cluster Shared Volume File System (CsvFS)
/// No
///
/// -
/// Resilient File System (ReFS)
/// No
///
///
/// SMB 3.0 does not support EFS on shares with continuous availability capability.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winefs/nf-winefs-encryptiondisable BOOL EncryptionDisable( LPCWSTR DirPath,
// BOOL Disable );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winefs.h", MSDNShortId = "6ff93a90-c1cf-4782-862c-d3d7e294c4b0")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EncryptionDisable([MarshalAs(UnmanagedType.LPWStr)] string DirPath, [MarshalAs(UnmanagedType.Bool)] bool Disable);
/// Frees a certificate hash list.
///
/// A pointer to a certificate hash list structure, ENCRYPTION_CERTIFICATE_HASH_LIST, which was returned by the
/// QueryUsersOnEncryptedFile or QueryRecoveryAgentsOnEncryptedFile function.
///
/// This function does not return a value.
/// ReFS: This function is not supported.
// https://docs.microsoft.com/en-us/windows/desktop/api/winefs/nf-winefs-freeencryptioncertificatehashlist void
// FreeEncryptionCertificateHashList( PENCRYPTION_CERTIFICATE_HASH_LIST pUsers );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winefs.h", MSDNShortId = "63d5811f-a135-45b0-8f23-fd8851f7bcca")]
public static extern void FreeEncryptionCertificateHashList(IntPtr pUsers);
/// Retrieves a list of recovery agents for the specified file.
/// The name of the file.
/// A pointer to a ENCRYPTION_CERTIFICATE_HASH_LIST structure that receives a list of recovery agents.
///
/// If the function succeeds, the return value is ERROR_SUCCESS.
///
/// If the function fails, the return value is a system error code. For a complete list of error codes, see System Error Codes or the
/// header file WinError.h.
///
///
///
/// When the list of recovery agents is no longer needed, free it by calling the FreeEncryptionCertificateHashList function.
/// In Windows 8, Windows Server 2012, and later, this function is supported by the following technologies.
///
///
/// Technology
/// Supported
///
/// -
/// Server Message Block (SMB) 3.0 protocol
/// Yes
///
/// -
/// SMB 3.0 Transparent Failover (TFO)
/// No
///
/// -
/// SMB 3.0 with Scale-out File Shares (SO)
/// No
///
/// -
/// Cluster Shared Volume File System (CsvFS)
/// No
///
/// -
/// Resilient File System (ReFS)
/// No
///
///
/// SMB 3.0 does not support EFS on shares with continuous availability capability.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winefs/nf-winefs-queryrecoveryagentsonencryptedfile DWORD
// QueryRecoveryAgentsOnEncryptedFile( LPCWSTR lpFileName, PENCRYPTION_CERTIFICATE_HASH_LIST *pRecoveryAgents );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winefs.h", MSDNShortId = "2f8d0673-3c87-46a4-b7d5-3888d20bd9b8")]
public static extern Win32Error QueryRecoveryAgentsOnEncryptedFile([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, out SafeENCRYPTION_CERTIFICATE_HASH_LIST pRecoveryAgents);
/// Retrieves a list of users for the specified file.
/// The name of the file.
/// A pointer to a ENCRYPTION_CERTIFICATE_HASH_LIST structure that receives the list of users.
///
/// If the function succeeds, the return value is ERROR_SUCCESS.
///
/// If the function fails, the return value is a system error code. For a complete list of error codes, see System Error Codes or the
/// header file WinError.h.
///
///
///
/// When the list of users is no longer needed, call the FreeEncryptionCertificateHashList function to free the list.
/// In Windows 8, Windows Server 2012, and later, this function is supported by the following technologies.
///
///
/// Technology
/// Supported
///
/// -
/// Server Message Block (SMB) 3.0 protocol
/// Yes
///
/// -
/// SMB 3.0 Transparent Failover (TFO)
/// No
///
/// -
/// SMB 3.0 with Scale-out File Shares (SO)
/// No
///
/// -
/// Cluster Shared Volume File System (CsvFS)
/// No
///
/// -
/// Resilient File System (ReFS)
/// No
///
///
/// SMB 3.0 does not support EFS on shares with continuous availability capability.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winefs/nf-winefs-queryusersonencryptedfile DWORD QueryUsersOnEncryptedFile(
// LPCWSTR lpFileName, PENCRYPTION_CERTIFICATE_HASH_LIST *pUsers );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winefs.h", MSDNShortId = "1bdab753-e7f2-4c08-8b37-3903c0842227")]
public static extern Win32Error QueryUsersOnEncryptedFile([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, out SafeENCRYPTION_CERTIFICATE_HASH_LIST pUsers);
/// Removes specified certificate hashes from a specified file.
/// The name of the file.
///
/// A pointer to an ENCRYPTION_CERTIFICATE_HASH_LIST structure that contains a list of certificate hashes to be removed from the file.
///
///
/// If the function succeeds, the return value is ERROR_SUCCESS.
///
/// If the function fails, the return value is a system error code. For a complete list of error codes, see System Error Codes or the
/// header file WinError.h.
///
///
///
///
/// The RemoveUsersFromEncryptedFile function removes the specified certificate hashes if they exist in the specified file. If
/// any of the certificate hashes are not found in the specified file, they are ignored and no error code is returned.
///
/// Starting with Windows 8 and Windows Server 2012, this function is supported by the following technologies.
///
///
/// Technology
/// Supported
///
/// -
/// Server Message Block (SMB) 3.0 protocol
/// Yes
///
/// -
/// SMB 3.0 Transparent Failover (TFO)
/// No
///
/// -
/// SMB 3.0 with Scale-out File Shares (SO)
/// No
///
/// -
/// Cluster Shared Volume File System (CsvFS)
/// No
///
/// -
/// Resilient File System (ReFS)
/// No
///
///
/// SMB 3.0 does not support EFS on shares with continuous availability capability.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winefs/nf-winefs-removeusersfromencryptedfile DWORD
// RemoveUsersFromEncryptedFile( LPCWSTR lpFileName, PENCRYPTION_CERTIFICATE_HASH_LIST pHashes );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winefs.h", MSDNShortId = "c6672581-24b4-464c-b32d-48a04e56eef8")]
public static unsafe extern Win32Error RemoveUsersFromEncryptedFile([MarshalAs(UnmanagedType.LPWStr)] string lpFileName, in ENCRYPTION_CERTIFICATE_HASH_LIST pHashes);
/// Sets the user's current key to the specified certificate.
///
/// A pointer to a certificate that will be the user's key. This parameter is a pointer to an ENCRYPTION_CERTIFICATE structure.
///
///
/// If the function succeeds, the return value is ERROR_SUCCESS.
///
/// If the function fails, the return value is a system error code. For a complete list of error codes, see System Error Codes or the
/// header file WinError.h.
///
///
///
/// In Windows 8 and Windows Server 2012, this function is supported by the following technologies.
///
///
/// Technology
/// Supported
///
/// -
/// Server Message Block (SMB) 3.0 protocol
/// Yes
///
/// -
/// SMB 3.0 Transparent Failover (TFO)
/// No
///
/// -
/// SMB 3.0 with Scale-out File Shares (SO)
/// No
///
/// -
/// Cluster Shared Volume File System (CsvFS)
/// No
///
/// -
/// Resilient File System (ReFS)
/// No
///
///
/// SMB 3.0 does not support EFS on shares with continuous availability capability.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winefs/nf-winefs-setuserfileencryptionkey DWORD SetUserFileEncryptionKey(
// PENCRYPTION_CERTIFICATE pEncryptionCertificate );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winefs.h", MSDNShortId = "dd23fab7-1675-4d0d-911c-e2aac2273e7f")]
public static extern Win32Error SetUserFileEncryptionKey(in ENCRYPTION_CERTIFICATE pEncryptionCertificate);
/// Contains a certificate.
// https://docs.microsoft.com/en-us/windows/desktop/api/winefs/ns-winefs-_certificate_blob typedef struct _CERTIFICATE_BLOB { DWORD
// dwCertEncodingType; DWORD cbData; PBYTE pbData; } EFS_CERTIFICATE_BLOB, *PEFS_CERTIFICATE_BLOB;
[PInvokeData("winefs.h", MSDNShortId = "e0d0aa0a-ac87-4734-93d0-30c2080319e8")]
[StructLayout(LayoutKind.Sequential)]
public struct EFS_CERTIFICATE_BLOB
{
///
/// A certificate encoding type. This member can be one of the following values.
/// CRYPT_ASN_ENCODING
/// CRYPT_NDR_ENCODING
/// X509_ASN_ENCODING
/// X509_NDR_ENCODING
///
public CertEncodingType dwCertEncodingType;
/// The number of bytes in the pbData buffer.
public uint cbData;
/// The binary certificate. The dwCertEncodingType member specifies the format for this certificate.
public IntPtr pbData;
}
/// Contains a certificate hash.
// https://docs.microsoft.com/en-us/windows/desktop/api/winefs/ns-winefs-_efs_hash_blob typedef struct _EFS_HASH_BLOB { DWORD cbData;
// PBYTE pbData; } EFS_HASH_BLOB, *PEFS_HASH_BLOB;
[PInvokeData("winefs.h", MSDNShortId = "23a172be-6e94-4a1f-afde-fc9437443c7a")]
[StructLayout(LayoutKind.Sequential)]
public struct EFS_HASH_BLOB
{
/// The number of bytes in the pbData buffer.
public uint cbData;
/// The certificate hash.
public IntPtr pbData;
}
/// Contains a certificate and the SID of its owner.
// https://docs.microsoft.com/en-us/windows/desktop/api/winefs/ns-winefs-_encryption_certificate typedef struct
// _ENCRYPTION_CERTIFICATE { DWORD cbTotalLength; SID *pUserSid; PEFS_CERTIFICATE_BLOB pCertBlob; } ENCRYPTION_CERTIFICATE, *PENCRYPTION_CERTIFICATE;
[PInvokeData("winefs.h", MSDNShortId = "33b36659-48bb-4297-8142-f8702db03d20")]
[StructLayout(LayoutKind.Sequential)]
public struct ENCRYPTION_CERTIFICATE
{
/// The length of this structure, in bytes.
public uint cbTotalLength;
/// The SID of the user who owns the certificate.
public PSID pUserSid;
/// A pointer to an EFS_CERTIFICATE_BLOB structure.
public IntPtr pCertBlob;
}
/// Contains a certificate hash and display information for the certificate.
// https://docs.microsoft.com/en-us/windows/desktop/api/winefs/ns-winefs-_encryption_certificate_hash typedef struct
// _ENCRYPTION_CERTIFICATE_HASH { DWORD cbTotalLength; SID *pUserSid; PEFS_HASH_BLOB pHash; LPWSTR lpDisplayInformation; }
// ENCRYPTION_CERTIFICATE_HASH, *PENCRYPTION_CERTIFICATE_HASH;
[PInvokeData("winefs.h", MSDNShortId = "6930446c-5338-4ff9-a662-791fc9e7cefe")]
[StructLayout(LayoutKind.Sequential)]
public struct ENCRYPTION_CERTIFICATE_HASH
{
/// The length of this structure, in bytes.
public uint cbTotalLength;
/// The SID of the user who created the certificate. This member is optional and can be NULL.
public PSID pUserSid;
/// A pointer to an EFS_HASH_BLOB structure.
public IntPtr pHash;
///
/// User-displayable information for the certificate. This is usually the user's common name and universal principal name (UPN).
///
public StrPtrUni lpDisplayInformation;
}
/// Contains a list of certificate hashes.
// https://docs.microsoft.com/en-us/windows/desktop/api/winefs/ns-winefs-_encryption_certificate_hash_list typedef struct
// _ENCRYPTION_CERTIFICATE_HASH_LIST { DWORD nCert_Hash; PENCRYPTION_CERTIFICATE_HASH *pUsers; } ENCRYPTION_CERTIFICATE_HASH_LIST, *PENCRYPTION_CERTIFICATE_HASH_LIST;
[PInvokeData("winefs.h", MSDNShortId = "988159b3-3cb9-4a4d-9c68-ebfb309cff25")]
[StructLayout(LayoutKind.Sequential)]
public struct ENCRYPTION_CERTIFICATE_HASH_LIST
{
/// The number of certificate hashes in the list.
public uint nCert_Hash;
/// A pointer to the first ENCRYPTION_CERTIFICATE_HASH structure in the list.
public IntPtr pUsers;
}
/// Contains a list of certificates.
// https://docs.microsoft.com/en-us/windows/desktop/api/winefs/ns-winefs-_encryption_certificate_list typedef struct
// _ENCRYPTION_CERTIFICATE_LIST { DWORD nUsers; PENCRYPTION_CERTIFICATE *pUsers; } ENCRYPTION_CERTIFICATE_LIST, *PENCRYPTION_CERTIFICATE_LIST;
[PInvokeData("winefs.h", MSDNShortId = "e1914b96-2fba-49ed-9dd2-464659323eda")]
[StructLayout(LayoutKind.Sequential)]
public struct ENCRYPTION_CERTIFICATE_LIST
{
/// The number of certificates in the list.
public uint nUsers;
/// A pointer to the first ENCRYPTION_CERTIFICATE structure in the list.
public IntPtr pUsers;
}
/// Provides a for that is disposed using .
public class SafeENCRYPTION_CERTIFICATE_HASH_LIST : SafeHANDLE
{
///
/// Initializes a new instance of the class and assigns an existing handle.
///
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeENCRYPTION_CERTIFICATE_HASH_LIST(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeENCRYPTION_CERTIFICATE_HASH_LIST() : base() { }
/// Gets the certificate hash items.
public ENCRYPTION_CERTIFICATE_HASH[] Items
{
get
{
unsafe
{
var l = GetList();
var pUsers = *(ENCRYPTION_CERTIFICATE_HASH**)l->pUsers;
var ret = new ENCRYPTION_CERTIFICATE_HASH[l->nCert_Hash];
for (var i = 0; i < l->nCert_Hash; i++)
ret[i] = pUsers[i];
return ret;
}
}
}
/// Performs an implicit conversion from to .
/// The list.
/// The result of the conversion.
public static implicit operator ENCRYPTION_CERTIFICATE_HASH_LIST(SafeENCRYPTION_CERTIFICATE_HASH_LIST l) { unsafe { return *l.GetList(); } }
///
protected override bool InternalReleaseHandle() { FreeEncryptionCertificateHashList(handle); return true; }
private unsafe ENCRYPTION_CERTIFICATE_HASH_LIST* GetList()
{
return (ENCRYPTION_CERTIFICATE_HASH_LIST*)(void*)handle;
}
}
}
}