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; } } } }