mirror of https://github.com/dahall/Vanara.git
4248 lines
249 KiB
C#
4248 lines
249 KiB
C#
using System;
|
||
using System.Runtime.InteropServices;
|
||
using System.Security.AccessControl;
|
||
using System.Text;
|
||
using Vanara.InteropServices;
|
||
using static Vanara.PInvoke.Kernel32;
|
||
|
||
namespace Vanara.PInvoke
|
||
{
|
||
public static partial class AdvApi32
|
||
{
|
||
/// <summary>size of alert string in server</summary>
|
||
public const int ALERTSZ = 128;
|
||
|
||
/// <summary>Length of client type string</summary>
|
||
public const int CLTYPE_LEN = 12;
|
||
|
||
/// <summary>Computer name length</summary>
|
||
public const int CNLEN = 15;
|
||
|
||
/// <summary/>
|
||
public const int CRYPT_KEY_LEN = 7;
|
||
|
||
/// <summary/>
|
||
public const int CRYPT_TXT_LEN = 8;
|
||
|
||
/// <summary>Device name length</summary>
|
||
public const int DEVLEN = 80;
|
||
|
||
/// <summary>Maximum domain name length</summary>
|
||
public const int DNLEN = CNLEN;
|
||
|
||
/// <summary/>
|
||
public const int ENCRYPTED_PWLEN = 16;
|
||
|
||
/// <summary>Event name length</summary>
|
||
public const int EVLEN = 16;
|
||
|
||
/// <summary>Group name</summary>
|
||
public const int GNLEN = UNLEN;
|
||
|
||
/// <summary>LM 2.0 Computer name length</summary>
|
||
public const int LM20_CNLEN = 15;
|
||
|
||
/// <summary>LM 2.0 Device name length</summary>
|
||
public const int LM20_DEVLEN = 8;
|
||
|
||
/// <summary>LM 2.0 Maximum domain name length</summary>
|
||
public const int LM20_DNLEN = LM20_CNLEN;
|
||
|
||
/// <summary>LM 2.0 Group name</summary>
|
||
public const int LM20_GNLEN = LM20_UNLEN;
|
||
|
||
/// <summary>LM 2.0 Multipurpose comment length</summary>
|
||
public const int LM20_MAXCOMMENTSZ = 48;
|
||
|
||
/// <summary>LM 2.0 Net name length</summary>
|
||
public const int LM20_NNLEN = 12;
|
||
|
||
/// <summary>LM 2.0 Max. path</summary>
|
||
public const int LM20_PATHLEN = 256;
|
||
|
||
/// <summary>LM 2.0 Maximum password length</summary>
|
||
public const int LM20_PWLEN = 14;
|
||
|
||
/// <summary>LM 2.0 Queue name maximum length</summary>
|
||
public const int LM20_QNLEN = LM20_NNLEN;
|
||
|
||
/// <summary>LM 2.0 Max remote name length</summary>
|
||
public const int LM20_RMLEN = (LM20_UNCLEN + 1 + LM20_NNLEN);
|
||
|
||
/// <summary>LM 2.0 Service name length</summary>
|
||
public const int LM20_SNLEN = 15;
|
||
|
||
/// <summary>LM 2.0 Service text length</summary>
|
||
public const int LM20_STXTLEN = 63;
|
||
|
||
/// <summary>LM 2.0 UNC computer name length</summary>
|
||
public const int LM20_UNCLEN = (LM20_CNLEN + 2);
|
||
|
||
/// <summary>LM 2.0 Maximum user name length</summary>
|
||
public const int LM20_UNLEN = 20;
|
||
|
||
/// <summary/>
|
||
public const uint MAX_PREFERRED_LENGTH = uint.MaxValue;
|
||
|
||
/// <summary>Multipurpose comment length</summary>
|
||
public const int MAXCOMMENTSZ = 256;
|
||
|
||
/// <summary>NetBIOS net name (bytes)</summary>
|
||
public const int NETBIOS_NAME_LEN = 16;
|
||
|
||
/// <summary>Net name length (share name)</summary>
|
||
public const int NNLEN = 80;
|
||
|
||
/// <summary/>
|
||
public const uint OPERATION_API_VERSION = 1;
|
||
|
||
/// <summary>Max. path (not including drive name)</summary>
|
||
public const int PATHLEN = 256;
|
||
|
||
/// <summary>Maximum password length</summary>
|
||
public const int PWLEN = 256;
|
||
|
||
/// <summary>Queue name maximum length</summary>
|
||
public const int QNLEN = NNLEN;
|
||
|
||
/// <summary>Max remote name length</summary>
|
||
public const int RMLEN = (UNCLEN + 1 + NNLEN);
|
||
|
||
/// <summary/>
|
||
public const int SESSION_CRYPT_KLEN = 21;
|
||
|
||
/// <summary/>
|
||
public const int SESSION_PWLEN = 24;
|
||
|
||
/// <summary>Share password length (bytes)</summary>
|
||
public const int SHPWLEN = 8;
|
||
|
||
/// <summary>Service name length</summary>
|
||
public const int SNLEN = 80;
|
||
|
||
/// <summary>Service text length</summary>
|
||
public const int STXTLEN = 256;
|
||
|
||
/// <summary>UNC computer name length</summary>
|
||
public const int UNCLEN = (CNLEN + 2);
|
||
|
||
/// <summary>Maximum user name length</summary>
|
||
public const int UNLEN = 256;
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// An application-defined callback function used with ReadEncryptedFileRaw. The system calls <c>ExportCallback</c> one or more
|
||
/// times, each time with a block of the encrypted file's data, until it has received all of the file data. <c>ExportCallback</c>
|
||
/// writes the encrypted file's data to another storage media, usually for purposes of backing up the file.
|
||
/// </para>
|
||
/// <para>
|
||
/// The <c>PFE_EXPORT_FUNC</c> type defines a pointer to the callback function. <c>ExportCallback</c> is a placeholder for the
|
||
/// application-defined function name.
|
||
/// </para>
|
||
/// </summary>
|
||
/// <param name="pbData">
|
||
/// A pointer to a block of the encrypted file's data to be backed up. This block of data is allocated by the system.
|
||
/// </param>
|
||
/// <param name="pvCallbackContext">
|
||
/// A pointer to an application-defined and allocated context block. The application passes this pointer to ReadEncryptedFileRaw, and
|
||
/// <c>ReadEncryptedFileRaw</c> passes this pointer to the callback function so that it can have access to application-specific data.
|
||
/// This data can be a structure and can contain any data the application needs, such as the handle to the file that contains the
|
||
/// backup copy of the encrypted file.
|
||
/// </param>
|
||
/// <param name="ulLength">The size of the data pointed to by the pbData parameter, in bytes.</param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, it must set the return value to <c>ERROR_SUCCESS</c>.</para>
|
||
/// <para>
|
||
/// If the function fails, set the return value to a nonzero error code defined in WinError.h. For example, if this function fails
|
||
/// because an API that it calls fails, you can set the return value to the value returned by GetLastError for the failed API.
|
||
/// </para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// You can use the application-defined context block for internal tracking of information such as the file handle and the current
|
||
/// offset in the file.
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nc-winbase-pfe_export_func PFE_EXPORT_FUNC PfeExportFunc; DWORD
|
||
// PfeExportFunc( PBYTE pbData, PVOID pvCallbackContext, ULONG ulLength ) {...}
|
||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "156948c9-d7b4-4491-bdb1-e1864a32caab")]
|
||
public delegate Win32Error ExportCallback(IntPtr pbData, IntPtr pvCallbackContext, uint ulLength);
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// An application-defined callback function used with WriteEncryptedFileRaw. The system calls <c>ImportCallback</c> one or more
|
||
/// times, each time to retrieve a portion of a backup file's data. <c>ImportCallback</c> reads the data from a backup file
|
||
/// sequentially and restores the data, and the system continues calling it until it has read all of the backup file data.
|
||
/// </para>
|
||
/// <para>
|
||
/// The <c>PFE_IMPORT_FUNC</c> type defines a pointer to this callback function. <c>ImportCallback</c> is a placeholder for the
|
||
/// application-defined function name.
|
||
/// </para>
|
||
/// </summary>
|
||
/// <param name="pbData">A pointer to a system-supplied buffer that will receive a block of data to be restored.</param>
|
||
/// <param name="pvCallbackContext">
|
||
/// A pointer to an application-defined and allocated context block. The application passes this pointer to WriteEncryptedFileRaw,
|
||
/// and it passes this pointer to the callback function so that the callback function can have access to application-specific data.
|
||
/// This data can be a structure and can contain any data the application needs, such as the handle to the file that contains the
|
||
/// backup copy of the encrypted file.
|
||
/// </param>
|
||
/// <param name="ulLength">
|
||
/// <para>
|
||
/// On function entry, this parameter specifies the length of the buffer the system has supplied. The callback function must write no
|
||
/// more than this many bytes to the buffer pointed to by the pbData parameter.
|
||
/// </para>
|
||
/// <para>On exit, the function must set this to the number of bytes of data written into the pbData.</para>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// If the function succeeds, it must set the return value to <c>ERROR_SUCCESS</c>, and set the value pointed to by the ulLength
|
||
/// parameter to the number of bytes copied into pbData.
|
||
/// </para>
|
||
/// <para>When the end of the backup file is reached, set ulLength to zero to tell the system that the entire file has been processed.</para>
|
||
/// <para>
|
||
/// If the function fails, set the return value to a nonzero error code defined in WinError.h. For example, if this function fails
|
||
/// because an API that it calls fails, you can set the return value to the value returned by GetLastError for the failed API.
|
||
/// </para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// The system calls the <c>ImportCallback</c> function until the callback function indicates there is no more data to restore. To
|
||
/// indicate that there is no more data to be restored, set *ulLength to 0 and use a return code of <c>ERROR_SUCCESS</c>. You can use
|
||
/// the application-defined context block for internal tracking of information such as the file handle and the current offset in the file.
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nc-winbase-pfe_import_func PFE_IMPORT_FUNC PfeImportFunc; DWORD
|
||
// PfeImportFunc( PBYTE pbData, PVOID pvCallbackContext, PULONG ulLength ) {...}
|
||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "4c951e44-15d8-43c8-bd3d-293a1ec9d444")]
|
||
public delegate Win32Error ImportCallback(IntPtr pbData, IntPtr pvCallbackContext, ref uint ulLength);
|
||
|
||
/// <summary>Flags used by <see cref="AccessCheckByTypeAndAuditAlarm"/>.</summary>
|
||
[PInvokeData("winbase.h", MSDNShortId = "ea14fd55-e0e4-4bf2-b20e-5874783c16c3")]
|
||
[Flags]
|
||
public enum AccessCheckFlags
|
||
{
|
||
/// <summary>The function performs the access check without generating audit messages when the privilege is not enabled.</summary>
|
||
AUDIT_ALLOW_NO_PRIVILEGE = 1
|
||
}
|
||
|
||
/// <summary>
|
||
/// The <c>AUDIT_EVENT_TYPE</c> enumeration type defines values that indicate the type of object being audited. The
|
||
/// AccessCheckByTypeAndAuditAlarm and AccessCheckByTypeResultListAndAuditAlarm functions use these values.
|
||
/// </summary>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ne-winnt-_audit_event_type typedef enum _AUDIT_EVENT_TYPE {
|
||
// AuditEventObjectAccess, AuditEventDirectoryServiceAccess } AUDIT_EVENT_TYPE, *PAUDIT_EVENT_TYPE;
|
||
[PInvokeData("winnt.h", MSDNShortId = "7dc21840-6dcc-445b-a254-f8ca27008d63")]
|
||
public enum AUDIT_EVENT_TYPE
|
||
{
|
||
/// <summary>
|
||
/// Indicates an object that generates audit messages only if the system administrator has enabled auditing access to files and objects.
|
||
/// </summary>
|
||
AuditEventObjectAccess,
|
||
|
||
/// <summary>
|
||
/// Indicates a directory service object that generates audit messages only if the system administrator has enabled auditing
|
||
/// access to directory service objects.
|
||
/// </summary>
|
||
AuditEventDirectoryServiceAccess,
|
||
}
|
||
|
||
/// <summary>The reported docking state of the computer.</summary>
|
||
[PInvokeData("winbase.h", MSDNShortId = "b1c8eb4c-8c62-4e3e-a7d2-0888512b3d4c")]
|
||
[Flags]
|
||
public enum DOCKINFO : uint
|
||
{
|
||
/// <summary>The computer is undocked. This flag is always set for desktop systems that cannot be undocked.</summary>
|
||
DOCKINFO_UNDOCKED = 0x1,
|
||
|
||
/// <summary>The computer is docked.</summary>
|
||
DOCKINFO_DOCKED = 0x2,
|
||
|
||
/// <summary>
|
||
/// If this flag is set, GetCurrentHwProfile retrieved the current docking state from information provided by the user in the
|
||
/// Hardware Profiles page of the System control panel application.
|
||
/// <para>If there is no such value or the value is set to 0, this flag is set.</para>
|
||
/// </summary>
|
||
DOCKINFO_USER_SUPPLIED = 0x4,
|
||
|
||
/// <summary>
|
||
/// The computer is docked, according to information provided by the user. This value is a combination of the
|
||
/// DOCKINFO_USER_SUPPLIED and DOCKINFO_DOCKED flags.
|
||
/// </summary>
|
||
DOCKINFO_USER_DOCKED = DOCKINFO_UNDOCKED | DOCKINFO_USER_SUPPLIED,
|
||
|
||
/// <summary>
|
||
/// The computer is undocked, according to information provided by the user. This value is a combination of the
|
||
/// DOCKINFO_USER_SUPPLIED and DOCKINFO_UNDOCKED flags.
|
||
/// </summary>
|
||
DOCKINFO_USER_UNDOCKED = DOCKINFO_DOCKED | DOCKINFO_USER_SUPPLIED,
|
||
}
|
||
|
||
/// <summary>The encryption status of the file.</summary>
|
||
[PInvokeData("winbase.h", MSDNShortId = "96efe065-de62-4941-811d-610465cd7ef5")]
|
||
public enum EncryptionStatus
|
||
{
|
||
/// <summary>
|
||
/// The file can be encrypted.
|
||
/// <para>
|
||
/// Home, Home Premium, Starter, and ARM Editions of Windows: FILE_ENCRYPTABLE may be returned but EFS does not support
|
||
/// encrypting files on these editions of Windows.
|
||
/// </para>
|
||
/// </summary>
|
||
FILE_ENCRYPTABLE = 0,
|
||
|
||
/// <summary>The file is encrypted.</summary>
|
||
FILE_IS_ENCRYPTED = 1,
|
||
|
||
/// <summary>The file is a read-only file.</summary>
|
||
FILE_READ_ONLY = 8,
|
||
|
||
/// <summary>The file is a root directory. Root directories cannot be encrypted.</summary>
|
||
FILE_ROOT_DIR = 3,
|
||
|
||
/// <summary>The file is a system file. System files cannot be encrypted.</summary>
|
||
FILE_SYSTEM_ATTR = 2,
|
||
|
||
/// <summary>The file is a system directory. System directories cannot be encrypted.</summary>
|
||
FILE_SYSTEM_DIR = 4,
|
||
|
||
/// <summary>The file system does not support file encryption.</summary>
|
||
FILE_SYSTEM_NOT_SUPPORT = 6,
|
||
|
||
/// <summary>The encryption status is unknown. The file may be encrypted.</summary>
|
||
FILE_UNKNOWN = 5,
|
||
|
||
/// <summary>Reserved for future use.</summary>
|
||
FILE_USER_DISALLOWED = 7,
|
||
|
||
/// <summary>Reserved for future use.</summary>
|
||
FILE_DIR_DISALLOWED = 9,
|
||
}
|
||
|
||
/// <summary>Flags used by <see cref="IsTextUnicode(byte[], int, ref IS_TEXT_UNICODE)"/>.</summary>
|
||
[Flags]
|
||
public enum IS_TEXT_UNICODE : uint
|
||
{
|
||
/// <summary>The text is Unicode, and contains only zero-extended ASCII values/characters.</summary>
|
||
IS_TEXT_UNICODE_ASCII16 = 0x0001,
|
||
|
||
/// <summary>
|
||
/// The text is probably Unicode, with the determination made by applying statistical analysis. Absolute certainty is not
|
||
/// guaranteed. See the Remarks section.
|
||
/// </summary>
|
||
IS_TEXT_UNICODE_STATISTICS = 0x0002,
|
||
|
||
/// <summary>Same as the preceding, except that the Unicode text is byte-reversed.</summary>
|
||
IS_TEXT_UNICODE_REVERSE_ASCII16 = 0x0010,
|
||
|
||
/// <summary>Same as the preceding, except that the text that is probably Unicode is byte-reversed.</summary>
|
||
IS_TEXT_UNICODE_REVERSE_STATISTICS = 0x0020,
|
||
|
||
/// <summary>
|
||
/// The text contains Unicode representations of one or more of these nonprinting characters: RETURN, LINEFEED, SPACE, CJK_SPACE, TAB.
|
||
/// </summary>
|
||
IS_TEXT_UNICODE_CONTROLS = 0x0004,
|
||
|
||
/// <summary>Same as the preceding, except that the Unicode characters are byte-reversed.</summary>
|
||
IS_TEXT_UNICODE_REVERSE_CONTROLS = 0x0040,
|
||
|
||
/// <summary>The text contains the Unicode byte-order mark (BOM) 0xFEFF as its first character.</summary>
|
||
IS_TEXT_UNICODE_SIGNATURE = 0x0008,
|
||
|
||
/// <summary>The text contains the Unicode byte-reversed byte-order mark (Reverse BOM) 0xFFFE as its first character.</summary>
|
||
IS_TEXT_UNICODE_REVERSE_SIGNATURE = 0x0080,
|
||
|
||
/// <summary>
|
||
/// The text contains one of these Unicode-illegal characters: embedded Reverse BOM, UNICODE_NUL, CRLF (packed into one word), or 0xFFFF.
|
||
/// </summary>
|
||
IS_TEXT_UNICODE_ILLEGAL_CHARS = 0x0100,
|
||
|
||
/// <summary>The number of characters in the string is odd. A string of odd length cannot (by definition) be Unicode text.</summary>
|
||
IS_TEXT_UNICODE_ODD_LENGTH = 0x0200,
|
||
|
||
/// <summary>Undocumented.</summary>
|
||
IS_TEXT_UNICODE_DBCS_LEADBYTE = 0x0400,
|
||
|
||
/// <summary>The text contains null bytes, which indicate non-ASCII text.</summary>
|
||
IS_TEXT_UNICODE_NULL_BYTES = 0x1000,
|
||
|
||
/// <summary>
|
||
/// The value is a combination of IS_TEXT_UNICODE_ASCII16, IS_TEXT_UNICODE_STATISTICS, IS_TEXT_UNICODE_CONTROLS, IS_TEXT_UNICODE_SIGNATURE.
|
||
/// </summary>
|
||
IS_TEXT_UNICODE_UNICODE_MASK = 0x000F,
|
||
|
||
/// <summary>
|
||
/// The value is a combination of IS_TEXT_UNICODE_REVERSE_ASCII16, IS_TEXT_UNICODE_REVERSE_STATISTICS,
|
||
/// IS_TEXT_UNICODE_REVERSE_CONTROLS, IS_TEXT_UNICODE_REVERSE_SIGNATURE.
|
||
/// </summary>
|
||
IS_TEXT_UNICODE_REVERSE_MASK = 0x00F0,
|
||
|
||
/// <summary>
|
||
/// The value is a combination of IS_TEXT_UNICODE_ILLEGAL_CHARS, IS_TEXT_UNICODE_ODD_LENGTH, and two currently unused bit flags.
|
||
/// </summary>
|
||
IS_TEXT_UNICODE_NOT_UNICODE_MASK = 0x0F00,
|
||
|
||
/// <summary>The value is a combination of IS_TEXT_UNICODE_NULL_BYTES and three currently unused bit flags.</summary>
|
||
IS_TEXT_UNICODE_NOT_ASCII_MASK = 0xF000,
|
||
}
|
||
|
||
/// <summary>The operation to perform when calling <c>OpenEncryptedFileRaw</c>.</summary>
|
||
[PInvokeData("winbase.h", MSDNShortId = "f792f38d-783e-4f39-a9d8-0c378d508d97")]
|
||
public enum OpenRawFlags
|
||
{
|
||
/// <summary>The file is being opened for import (restore).</summary>
|
||
CREATE_FOR_IMPORT = 1,
|
||
|
||
/// <summary>
|
||
/// Import (restore) a directory containing encrypted files. This must be combined with one of the previous two flags to indicate
|
||
/// the operation.
|
||
/// </summary>
|
||
CREATE_FOR_DIR = 2,
|
||
|
||
/// <summary>Overwrite a hidden file on import.</summary>
|
||
OVERWRITE_HIDDEN = 4,
|
||
|
||
/// <summary/>
|
||
EFSRPC_SECURE_ONLY = 8,
|
||
|
||
/// <summary/>
|
||
EFS_DROP_ALTERNATE_STREAMS = 0x10
|
||
}
|
||
|
||
/// <summary>The logon option.</summary>
|
||
[PInvokeData("winbase.h", MSDNShortId = "dcfdcd5b-0269-4081-b1db-e272171c27a2")]
|
||
[Flags]
|
||
public enum ProcessLogonFlags : uint
|
||
{
|
||
/// <summary>
|
||
/// Log on, then load the user profile in the HKEY_USERS registry key. The function returns after the profile is loaded. Loading
|
||
/// the profile can be time-consuming, so it is best to use this value only if you must access the information in the
|
||
/// HKEY_CURRENT_USER registry key.
|
||
/// <para>
|
||
/// Windows Server 2003: The profile is unloaded after the new process is terminated, whether or not it has created child processes.
|
||
/// </para>
|
||
/// <para>Windows XP: The profile is unloaded after the new process and all child processes it has created are terminated.</para>
|
||
/// </summary>
|
||
LOGON_WITH_PROFILE = 0x00000001,
|
||
|
||
/// <summary>
|
||
/// Log on, but use the specified credentials on the network only. The new process uses the same token as the caller, but the
|
||
/// system creates a new logon session within LSA, and the process uses the specified credentials as the default credentials.
|
||
/// <para>
|
||
/// This value can be used to create a process that uses a different set of credentials locally than it does remotely. This is
|
||
/// useful in inter-domain scenarios where there is no trust relationship.
|
||
/// </para>
|
||
/// <para>
|
||
/// The system does not validate the specified credentials. Therefore, the process can start, but it may not have access to
|
||
/// network resources.
|
||
/// </para>
|
||
/// </summary>
|
||
LOGON_NETCREDENTIALS_ONLY = 0x00000002,
|
||
|
||
/// <summary>The logon zero password buffer</summary>
|
||
LOGON_ZERO_PASSWORD_BUFFER = 0x80000000
|
||
}
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// The <c>AccessCheckAndAuditAlarm</c> function determines whether a security descriptor grants a specified set of access rights to
|
||
/// the client being impersonated by the calling thread. If the security descriptor has a SACL with ACEs that apply to the client,
|
||
/// the function generates any necessary audit messages in the security event log.
|
||
/// </para>
|
||
/// <para>Alarms are not currently supported.</para>
|
||
/// </summary>
|
||
/// <param name="SubsystemName">
|
||
/// A pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit
|
||
/// message that the function generates.
|
||
/// </param>
|
||
/// <param name="HandleId">
|
||
/// A pointer to a unique value representing the client's handle to the object. If the access is denied, the system ignores this value.
|
||
/// </param>
|
||
/// <param name="ObjectTypeName">
|
||
/// A pointer to a null-terminated string specifying the type of object being created or accessed. This string appears in any audit
|
||
/// message that the function generates.
|
||
/// </param>
|
||
/// <param name="ObjectName">
|
||
/// A pointer to a null-terminated string specifying the name of the object being created or accessed. This string appears in any
|
||
/// audit message that the function generates.
|
||
/// </param>
|
||
/// <param name="SecurityDescriptor">A pointer to the SECURITY_DESCRIPTOR structure against which access is checked.</param>
|
||
/// <param name="DesiredAccess">
|
||
/// <para>
|
||
/// Access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function to contain
|
||
/// no generic access rights.
|
||
/// </para>
|
||
/// <para>
|
||
/// If this parameter is MAXIMUM_ALLOWED, the function sets the GrantedAccess access mask to indicate the maximum access rights the
|
||
/// security descriptor allows the client.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="GenericMapping">
|
||
/// A pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
|
||
/// </param>
|
||
/// <param name="ObjectCreation">
|
||
/// Specifies a flag that determines whether the calling application will create a new object when access is granted. A value of
|
||
/// <c>TRUE</c> indicates the application will create a new object. A value of <c>FALSE</c> indicates the application will open an
|
||
/// existing object.
|
||
/// </param>
|
||
/// <param name="GrantedAccess">
|
||
/// A pointer to an access mask that receives the granted access rights. If AccessStatus is set to <c>FALSE</c>, the function sets
|
||
/// the access mask to zero. If the function fails, it does not set the access mask.
|
||
/// </param>
|
||
/// <param name="AccessStatus">
|
||
/// A pointer to a variable that receives the results of the access check. If the security descriptor allows the requested access
|
||
/// rights to the client, AccessStatus is set to <c>TRUE</c>. Otherwise, AccessStatus is set to <c>FALSE</c>.
|
||
/// </param>
|
||
/// <param name="pfGenerateOnClose">
|
||
/// A pointer to a flag set by the audit-generation routine when the function returns. Pass this flag to the ObjectCloseAuditAlarm
|
||
/// function when the object handle is closed.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is nonzero.</para>
|
||
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>For more information, see the How AccessCheck Works overview.</para>
|
||
/// <para>
|
||
/// The <c>AccessCheckAndAuditAlarm</c> function requires the calling process to have the SE_AUDIT_NAME privilege enabled. The test
|
||
/// for this privilege is performed against the primary token of the calling process, not the impersonation token of the thread.
|
||
/// </para>
|
||
/// <para>The <c>AccessCheckAndAuditAlarm</c> function fails if the calling thread is not impersonating a client.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-accesscheckandauditalarma BOOL AccessCheckAndAuditAlarmA(
|
||
// LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName, LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD
|
||
// DesiredAccess, PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess, LPBOOL AccessStatus, LPBOOL
|
||
// pfGenerateOnClose );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "c2d144f4-9eeb-4723-9d28-97cfd1a07274")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool AccessCheckAndAuditAlarm(string SubsystemName, IntPtr HandleId, string ObjectTypeName, [Optional] string ObjectName,
|
||
PSECURITY_DESCRIPTOR SecurityDescriptor, ACCESS_MASK DesiredAccess, in GENERIC_MAPPING GenericMapping, [MarshalAs(UnmanagedType.Bool)] bool ObjectCreation,
|
||
out ACCESS_MASK GrantedAccess, [MarshalAs(UnmanagedType.Bool)] out bool AccessStatus, [MarshalAs(UnmanagedType.Bool)] out bool pfGenerateOnClose);
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// The <c>AccessCheckByTypeAndAuditAlarm</c> function determines whether a security descriptor grants a specified set of access
|
||
/// rights to the client being impersonated by the calling thread. The function can check the client's access to a hierarchy of
|
||
/// objects, such as an object, its property sets, and properties. The function grants or denies access to the hierarchy as a whole.
|
||
/// If the security descriptor has a system access control list (SACL) with access control entries (ACEs) that apply to the client,
|
||
/// the function generates any necessary audit messages in the security event log.
|
||
/// </para>
|
||
/// <para>Alarms are not currently supported.</para>
|
||
/// </summary>
|
||
/// <param name="SubsystemName">
|
||
/// A pointer to a null-terminated string that specifies the name of the subsystem calling the function. This string appears in any
|
||
/// audit message that the function generates.
|
||
/// </param>
|
||
/// <param name="HandleId">
|
||
/// A pointer to a unique value that represents the client's handle to the object. If the access is denied, the system ignores this value.
|
||
/// </param>
|
||
/// <param name="ObjectTypeName">
|
||
/// A pointer to a null-terminated string that specifies the type of object being created or accessed. This string appears in any
|
||
/// audit message that the function generates.
|
||
/// </param>
|
||
/// <param name="ObjectName">
|
||
/// A pointer to a null-terminated string that specifies the name of the object being created or accessed. This string appears in any
|
||
/// audit message that the function generates.
|
||
/// </param>
|
||
/// <param name="SecurityDescriptor">A pointer to a SECURITY_DESCRIPTOR structure against which access is checked.</param>
|
||
/// <param name="PrincipalSelfSid">
|
||
/// <para>
|
||
/// A pointer to a security identifier (SID). If the security descriptor is associated with an object that represents a principal
|
||
/// (for example, a user object), the PrincipalSelfSid parameter should be the SID of the object. When evaluating access, this SID
|
||
/// logically replaces the SID in any ACE containing the well-known PRINCIPAL_SELF SID (S-1-5-10). For information about well-known
|
||
/// SIDs, see Well-known SIDs.
|
||
/// </para>
|
||
/// <para>If the protected object does not represent a principal, set this parameter to <c>NULL</c>.</para>
|
||
/// </param>
|
||
/// <param name="DesiredAccess">
|
||
/// <para>
|
||
/// An access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function to
|
||
/// contain no generic access rights.
|
||
/// </para>
|
||
/// <para>
|
||
/// If this parameter is MAXIMUM_ALLOWED, the function sets the GrantedAccess access mask to indicate the maximum access rights the
|
||
/// security descriptor allows the client.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="AuditType">
|
||
/// The type of audit to be generated. This can be one of the values from the AUDIT_EVENT_TYPE enumeration type.
|
||
/// </param>
|
||
/// <param name="Flags">
|
||
/// A flag that controls the function's behavior if the calling process does not have the SE_AUDIT_NAME privilege enabled. If the
|
||
/// AUDIT_ALLOW_NO_PRIVILEGE flag is set, the function performs the access check without generating audit messages when the privilege
|
||
/// is not enabled. If this parameter is zero, the function fails if the privilege is not enabled.
|
||
/// </param>
|
||
/// <param name="ObjectTypeList">
|
||
/// <para>
|
||
/// A pointer to an array of OBJECT_TYPE_LIST structures that identify the hierarchy of object types for which to check access. Each
|
||
/// element in the array specifies a GUID that identifies the object type and a value that indicates the level of the object type in
|
||
/// the hierarchy of object types. The array should not have two elements with the same GUID.
|
||
/// </para>
|
||
/// <para>
|
||
/// The array must have at least one element. The first element in the array must be at level zero and identify the object itself.
|
||
/// The array can have only one level zero element. The second element is a subobject, such as a property set, at level 1. Following
|
||
/// each level 1 entry are subordinate entries for the level 2 through 4 subobjects. Thus, the levels for the elements in the array
|
||
/// might be {0, 1, 2, 2, 1, 2, 3}. If the object type list is out of order, <c>AccessCheckByTypeAndAuditAlarm</c> fails and
|
||
/// GetLastError returns ERROR_INVALID_PARAMETER.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="ObjectTypeListLength">The number of elements in the ObjectTypeList array.</param>
|
||
/// <param name="GenericMapping">
|
||
/// A pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
|
||
/// </param>
|
||
/// <param name="ObjectCreation">
|
||
/// A flag that determines whether the calling application will create a new object when access is granted. A value of <c>TRUE</c>
|
||
/// indicates the application will create a new object. A value of <c>FALSE</c> indicates the application will open an existing object.
|
||
/// </param>
|
||
/// <param name="GrantedAccess">
|
||
/// A pointer to an access mask that receives the granted access rights. If AccessStatus is set to <c>FALSE</c>, the function sets
|
||
/// the access mask to zero. If the function fails, it does not set the access mask.
|
||
/// </param>
|
||
/// <param name="AccessStatus">
|
||
/// A pointer to a variable that receives the results of the access check. If the security descriptor allows the requested access
|
||
/// rights to the client, AccessStatus is set to <c>TRUE</c>. Otherwise, AccessStatus is set to <c>FALSE</c> and you can call
|
||
/// GetLastError to get extended error information.
|
||
/// </param>
|
||
/// <param name="pfGenerateOnClose">
|
||
/// A pointer to a flag set by the audit-generation routine when the function returns. Pass this flag to the ObjectCloseAuditAlarm
|
||
/// function when the object handle is closed.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the function returns nonzero.</para>
|
||
/// <para>If the function fails, it returns zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>For more information, see the How AccessCheck Works overview.</para>
|
||
/// <para>
|
||
/// If the PrincipalSelfSid and ObjectTypeList parameters are <c>NULL</c>, the AuditType parameter is AuditEventObjectAccess, and the
|
||
/// Flags parameter is zero, <c>AccessCheckByTypeAndAuditAlarm</c> performs in the same way as the AccessCheckAndAuditAlarm function.
|
||
/// </para>
|
||
/// <para>
|
||
/// The ObjectTypeList array does not necessarily represent the entire defined object. Rather, it represents that subset of the
|
||
/// object for which to check access. For instance, to check access to two properties in a property set, specify an object type list
|
||
/// with four elements: the object itself at level zero, the property set at level 1, and the two properties at level 2.
|
||
/// </para>
|
||
/// <para>
|
||
/// The <c>AccessCheckByTypeAndAuditAlarm</c> function evaluates ACEs that apply to the object itself and object-specific ACEs for
|
||
/// the object types listed in the ObjectTypeList array. The function ignores object-specific ACEs for object types not listed in the
|
||
/// ObjectTypeList array. Thus, the results returned in the AccessStatus parameter indicate the access allowed to the subset of the
|
||
/// object defined by the ObjectTypeList parameter, not to the entire object.
|
||
/// </para>
|
||
/// <para>
|
||
/// For more information about how a hierarchy of ACEs controls access to an object and its subobjects, see ACEs to Control Access to
|
||
/// an Object's Properties.
|
||
/// </para>
|
||
/// <para>
|
||
/// To generate audit messages in the security event log, the calling process must have the SE_AUDIT_NAME privilege enabled. The
|
||
/// system checks for this privilege in the primary token of the calling process, not the impersonation token of the thread. If the
|
||
/// Flags parameter includes the AUDIT_ALLOW_NO_PRIVILEGE flag, the function performs the access check without generating audit
|
||
/// messages when the privilege is not enabled.
|
||
/// </para>
|
||
/// <para>The <c>AccessCheckByTypeAndAuditAlarm</c> function fails if the calling thread is not impersonating a client.</para>
|
||
/// <para>If the security descriptor does not contain owner and group SIDs, <c>AccessCheckByTypeAndAuditAlarm</c> fails with ERROR_INVALID_SECURITY_DESCR.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-accesscheckbytypeandauditalarma BOOL
|
||
// AccessCheckByTypeAndAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, LPCSTR ObjectTypeName, LPCSTR ObjectName,
|
||
// PSECURITY_DESCRIPTOR SecurityDescriptor, PSID PrincipalSelfSid, DWORD DesiredAccess, AUDIT_EVENT_TYPE AuditType, DWORD Flags,
|
||
// POBJECT_TYPE_LIST ObjectTypeList, DWORD ObjectTypeListLength, PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD
|
||
// GrantedAccess, LPBOOL AccessStatus, LPBOOL pfGenerateOnClose );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "ea14fd55-e0e4-4bf2-b20e-5874783c16c3")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool AccessCheckByTypeAndAuditAlarm(string SubsystemName, [In] IntPtr HandleId, string ObjectTypeName, [Optional] string ObjectName,
|
||
[In] PSECURITY_DESCRIPTOR SecurityDescriptor, [In, Optional] PSID PrincipalSelfSid, ACCESS_MASK DesiredAccess, AUDIT_EVENT_TYPE AuditType,
|
||
AccessCheckFlags Flags, [In, Out, MarshalAs(UnmanagedType.LPArray)] OBJECT_TYPE_LIST[] ObjectTypeList, uint ObjectTypeListLength,
|
||
in GENERIC_MAPPING GenericMapping, [MarshalAs(UnmanagedType.Bool)] bool ObjectCreation, out ACCESS_MASK GrantedAccess,
|
||
[MarshalAs(UnmanagedType.Bool)] out bool AccessStatus, [MarshalAs(UnmanagedType.Bool)] out bool pfGenerateOnClose);
|
||
|
||
/// <summary>
|
||
/// The <c>AccessCheckByTypeResultListAndAuditAlarm</c> function determines whether a security descriptor grants a specified set of
|
||
/// access rights to the client being impersonated by the calling thread. The function can check access to a hierarchy of objects,
|
||
/// such as an object, its property sets, and properties. The function reports the access rights granted or denied to each object
|
||
/// type in the hierarchy. If the security descriptor has a system access control list (SACL) with access control entries (ACEs) that
|
||
/// apply to the client, the function generates any necessary audit messages in the security event log. Alarms are not currently supported.
|
||
/// </summary>
|
||
/// <param name="SubsystemName">
|
||
/// A pointer to a null-terminated string that specifies the name of the subsystem calling the function. This string appears in any
|
||
/// audit message that the function generates.
|
||
/// </param>
|
||
/// <param name="HandleId">
|
||
/// A pointer to a unique value that represents the client's handle to the object. If the access is denied, the system ignores this value.
|
||
/// </param>
|
||
/// <param name="ObjectTypeName">
|
||
/// A pointer to a null-terminated string that specifies the type of object being created or accessed. This string appears in any
|
||
/// audit message that the function generates.
|
||
/// </param>
|
||
/// <param name="ObjectName">
|
||
/// A pointer to a null-terminated string that specifies the name of the object being created or accessed. This string appears in any
|
||
/// audit message that the function generates.
|
||
/// </param>
|
||
/// <param name="SecurityDescriptor">A pointer to a SECURITY_DESCRIPTOR structure against which access is checked.</param>
|
||
/// <param name="PrincipalSelfSid">
|
||
/// <para>
|
||
/// A pointer to a security identifier (SID). If the security descriptor is associated with an object that represents a principal
|
||
/// (for example, a user object), the PrincipalSelfSid parameter should be the SID of the object. When evaluating access, this SID
|
||
/// logically replaces the SID in any ACE that contains the well-known PRINCIPAL_SELF SID (S-1-5-10). For information about
|
||
/// well-known SIDs, see Well-known SIDs.
|
||
/// </para>
|
||
/// <para>Set this parameter to <c>NULL</c> if the protected object does not represent a principal.</para>
|
||
/// </param>
|
||
/// <param name="DesiredAccess">
|
||
/// <para>
|
||
/// An access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function so that
|
||
/// it contains no generic access rights.
|
||
/// </para>
|
||
/// <para>
|
||
/// If this parameter is MAXIMUM_ALLOWED, the function sets the access mask in GrantedAccess to indicate the maximum access rights
|
||
/// the security descriptor allows the client.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="AuditType">
|
||
/// The type of audit to be generated. This can be one of the values from the AUDIT_EVENT_TYPE enumeration type.
|
||
/// </param>
|
||
/// <param name="Flags">
|
||
/// A flag that controls the function's behavior if the calling process does not have the SE_AUDIT_NAME privilege enabled. If the
|
||
/// AUDIT_ALLOW_NO_PRIVILEGE flag is set, the function performs the access check without generating audit messages when the privilege
|
||
/// is not enabled. If this parameter is zero, the function fails if the privilege is not enabled.
|
||
/// </param>
|
||
/// <param name="ObjectTypeList">
|
||
/// <para>
|
||
/// A pointer to an array of OBJECT_TYPE_LIST structures that identify the hierarchy of object types for which to check access. Each
|
||
/// element in the array specifies a GUID that identifies the object type and a value that indicates the level of the object type in
|
||
/// the hierarchy of object types. The array should not have two elements with the same GUID.
|
||
/// </para>
|
||
/// <para>
|
||
/// The array must have at least one element. The first element in the array must be at level zero and identify the object itself.
|
||
/// The array can have only one level zero element. The second element is a subobject, such as a property set, at level 1. Following
|
||
/// each level 1 entry are subordinate entries for the level 2 through 4 subobjects. Thus, the levels for the elements in the array
|
||
/// might be {0, 1, 2, 2, 1, 2, 3}. If the object type list is out of order, <c>AccessCheckByTypeResultListAndAuditAlarm</c> fails,
|
||
/// and GetLastError returns ERROR_INVALID_PARAMETER.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="ObjectTypeListLength">The number of elements in the ObjectTypeList array.</param>
|
||
/// <param name="GenericMapping">
|
||
/// A pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
|
||
/// </param>
|
||
/// <param name="ObjectCreation">
|
||
/// A flag that determines whether the calling application will create a new object when access is granted. A value of <c>TRUE</c>
|
||
/// indicates the application will create a new object. A value of <c>FALSE</c> indicates the application will open an existing object.
|
||
/// </param>
|
||
/// <param name="GrantedAccess">
|
||
/// A pointer to an array of access masks. The function sets each access mask to indicate the access rights granted to the
|
||
/// corresponding element in the object type list. If the function fails, it does not set the access masks.
|
||
/// </param>
|
||
/// <param name="AccessStatusList">
|
||
/// A pointer to an array of status codes for the corresponding elements in the object type list. The function sets an element to
|
||
/// zero to indicate success or to a nonzero value to indicate the specific error during the access check. If the function fails, it
|
||
/// does not set any of the elements in the array.
|
||
/// </param>
|
||
/// <param name="pfGenerateOnClose">
|
||
/// A pointer to a flag set by the audit-generation routine when the function returns. Pass this flag to the ObjectCloseAuditAlarm
|
||
/// function when the object handle is closed.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the function returns nonzero.</para>
|
||
/// <para>If the function fails, it returns zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>For more information, see the How AccessCheck Works overview.</para>
|
||
/// <para>
|
||
/// The <c>AccessCheckByTypeResultListAndAuditAlarm</c> function is a combination of the AccessCheckByTypeResultList and
|
||
/// AccessCheckAndAuditAlarm functions.
|
||
/// </para>
|
||
/// <para>
|
||
/// The ObjectTypeList array does not necessarily represent the entire defined object. Rather, it represents that subset of the
|
||
/// object for which to check access. For instance, to check access to two properties in a property set, specify an object type list
|
||
/// with four elements: the object itself at level zero, the property set at level 1, and the two properties at level 2.
|
||
/// </para>
|
||
/// <para>
|
||
/// The <c>AccessCheckByTypeResultListAndAuditAlarm</c> function evaluates ACEs that apply to the object itself and object-specific
|
||
/// ACEs for the object types listed in the ObjectTypeList array. The function ignores object-specific ACEs for object types not
|
||
/// listed in the ObjectTypeList array.
|
||
/// </para>
|
||
/// <para>
|
||
/// For more information about how a hierarchy of ACEs controls access to an object and its subobjects, see ACEs to Control Access to
|
||
/// an Object's Properties.
|
||
/// </para>
|
||
/// <para>
|
||
/// To generate audit messages in the security event log, the calling process must have the SE_AUDIT_NAME privilege enabled. The
|
||
/// system checks for this privilege in the primary token of the calling process, not the impersonation token of the thread. If the
|
||
/// Flags parameter includes the AUDIT_ALLOW_NO_PRIVILEGE flag, the function performs the access check without generating audit
|
||
/// messages when the privilege is not enabled.
|
||
/// </para>
|
||
/// <para>The <c>AccessCheckByTypeResultListAndAuditAlarm</c> function fails if the calling thread is not impersonating a client.</para>
|
||
/// <para>
|
||
/// If the security descriptor does not contain owner and group SIDs, <c>AccessCheckByTypeResultListAndAuditAlarm</c> fails with ERROR_INVALID_SECURITY_DESCR.
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-accesscheckbytyperesultlistandauditalarma BOOL
|
||
// AccessCheckByTypeResultListAndAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, LPCSTR ObjectTypeName, LPCSTR ObjectName,
|
||
// PSECURITY_DESCRIPTOR SecurityDescriptor, PSID PrincipalSelfSid, DWORD DesiredAccess, AUDIT_EVENT_TYPE AuditType, DWORD Flags,
|
||
// POBJECT_TYPE_LIST ObjectTypeList, DWORD ObjectTypeListLength, PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD
|
||
// GrantedAccess, LPDWORD AccessStatusList, LPBOOL pfGenerateOnClose );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "4b53a15a-5a6b-40c7-acf8-26b1f4bca4ae")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool AccessCheckByTypeResultListAndAuditAlarm(string SubsystemName, IntPtr HandleId, string ObjectTypeName, [Optional] string ObjectName,
|
||
PSECURITY_DESCRIPTOR SecurityDescriptor, [Optional] PSID PrincipalSelfSid, ACCESS_MASK DesiredAccess, AUDIT_EVENT_TYPE AuditType, AccessCheckFlags Flags,
|
||
[In, Out, MarshalAs(UnmanagedType.LPArray)] OBJECT_TYPE_LIST[] ObjectTypeList, uint ObjectTypeListLength, in GENERIC_MAPPING GenericMapping,
|
||
[MarshalAs(UnmanagedType.Bool)] bool ObjectCreation, [Out] uint[] GrantedAccess, [Out] uint[] AccessStatusList,
|
||
[MarshalAs(UnmanagedType.Bool)] out bool pfGenerateOnClose);
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// The <c>AccessCheckByTypeResultListAndAuditAlarmByHandle</c> function determines whether a security descriptor grants a specified
|
||
/// set of access rights to the client that the calling thread is impersonating. The difference between this function and
|
||
/// AccessCheckByTypeResultListAndAuditAlarm is that this function allows the calling thread to perform the access check before
|
||
/// impersonating the client.
|
||
/// </para>
|
||
/// <para>
|
||
/// The function can check access to a hierarchy of objects, such as an object, its property sets, and properties. The function
|
||
/// reports the access rights granted or denied to each object type in the hierarchy. If the security descriptor has a system access
|
||
/// control list (SACL) with access control entries (ACEs) that apply to the client, the function generates any necessary audit
|
||
/// messages in the security event log. Alarms are not currently supported.
|
||
/// </para>
|
||
/// </summary>
|
||
/// <param name="SubsystemName">
|
||
/// A pointer to a null-terminated string that specifies the name of the subsystem calling the function. This string appears in any
|
||
/// audit message that the function generates.
|
||
/// </param>
|
||
/// <param name="HandleId">
|
||
/// A pointer to a unique value that represents the client's handle to the object. If the access is denied, the system ignores this value.
|
||
/// </param>
|
||
/// <param name="ClientToken">
|
||
/// A handle to a token object that represents the client that requested the operation. This handle must be obtained through a
|
||
/// communication session layer, such as a local named pipe, to prevent possible security policy violations. The caller must have
|
||
/// TOKEN_QUERY access for the specified token.
|
||
/// </param>
|
||
/// <param name="ObjectTypeName">
|
||
/// A pointer to a null-terminated string that specifies the type of object being created or accessed. This string appears in any
|
||
/// audit message that the function generates.
|
||
/// </param>
|
||
/// <param name="ObjectName">
|
||
/// A pointer to a null-terminated string that specifies the name of the object being created or accessed. This string appears in any
|
||
/// audit message that the function generates.
|
||
/// </param>
|
||
/// <param name="SecurityDescriptor">A pointer to a SECURITY_DESCRIPTOR structure against which access is checked.</param>
|
||
/// <param name="PrincipalSelfSid">
|
||
/// <para>
|
||
/// A pointer to a SID. If the security descriptor is associated with an object that represents a principal (for example, a user
|
||
/// object), the PrincipalSelfSid parameter should be the SID of the object. When evaluating access, this SID logically replaces the
|
||
/// SID in any ACE containing the well-known PRINCIPAL_SELF SID (S-1-5-10). For information about well-known SIDs, see Well-known SIDs.
|
||
/// </para>
|
||
/// <para>Set this parameter to <c>NULL</c> if the protected object does not represent a principal.</para>
|
||
/// </param>
|
||
/// <param name="DesiredAccess">
|
||
/// <para>
|
||
/// An access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function so that
|
||
/// it contains no generic access rights.
|
||
/// </para>
|
||
/// <para>
|
||
/// If this parameter is MAXIMUM_ALLOWED, the function sets the access mask in GrantedAccess to indicate the maximum access rights
|
||
/// the security descriptor allows the client.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="AuditType">
|
||
/// The type of audit to be generated. This can be one of the values from the AUDIT_EVENT_TYPE enumeration type.
|
||
/// </param>
|
||
/// <param name="Flags">
|
||
/// A flag that controls the function's behavior if the calling process does not have the SE_AUDIT_NAME privilege enabled. If the
|
||
/// AUDIT_ALLOW_NO_PRIVILEGE flag is set, the function performs the access check without generating audit messages when the privilege
|
||
/// is not enabled. If this parameter is zero, the function fails if the privilege is not enabled.
|
||
/// </param>
|
||
/// <param name="ObjectTypeList">
|
||
/// <para>
|
||
/// A pointer to an array of OBJECT_TYPE_LIST structures that identify the hierarchy of object types for which to check access. Each
|
||
/// element in the array specifies a GUID that identifies the object type and a value that indicates the level of the object type in
|
||
/// the hierarchy of object types. The array should not have two elements with the same GUID.
|
||
/// </para>
|
||
/// <para>
|
||
/// The array must have at least one element. The first element in the array must be at level zero and identify the object itself.
|
||
/// The array can have only one level zero element. The second element is a subobject, such as a property set, at level 1. Following
|
||
/// each level 1 entry are subordinate entries for the level 2 through 4 subobjects. Thus, the levels for the elements in the array
|
||
/// might be {0, 1, 2, 2, 1, 2, 3}. If the object type list is out of order, <c>AccessCheckByTypeResultListAndAuditAlarmByHandle</c>
|
||
/// fails, and GetLastError returns ERROR_INVALID_PARAMETER.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="ObjectTypeListLength">The number of elements in the ObjectTypeList array.</param>
|
||
/// <param name="GenericMapping">
|
||
/// A pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
|
||
/// </param>
|
||
/// <param name="ObjectCreation">
|
||
/// A flag that determines whether the calling application will create a new object when access is granted. A value of <c>TRUE</c>
|
||
/// indicates the application will create a new object. A value of <c>FALSE</c> indicates the application will open an existing object.
|
||
/// </param>
|
||
/// <param name="GrantedAccess">
|
||
/// A pointer to an array of access masks. The function sets each access mask to indicate the access rights granted to the
|
||
/// corresponding element in the object type list. If the function fails, it does not set the access masks.
|
||
/// </param>
|
||
/// <param name="AccessStatusList">
|
||
/// A pointer to an array of status codes for the corresponding elements in the object type list. The function sets an element to
|
||
/// zero to indicate success or to a nonzero value to indicate the specific error during the access check. If the function fails, it
|
||
/// does not set any of the elements in the array.
|
||
/// </param>
|
||
/// <param name="pfGenerateOnClose">
|
||
/// A pointer to a flag set by the audit-generation routine when the function returns. Pass this flag to the ObjectCloseAuditAlarm
|
||
/// function when the object handle is closed.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the function returns nonzero.</para>
|
||
/// <para>If the function fails, it returns zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>For more information, see the How AccessCheck Works overview.</para>
|
||
/// <para>
|
||
/// Like AccessCheckByTypeResultListAndAuditAlarm, the <c>AccessCheckByTypeResultListAndAuditAlarmByHandle</c> function is a
|
||
/// combination of the AccessCheckByTypeResultList and AccessCheckAndAuditAlarm functions. However,
|
||
/// <c>AccessCheckByTypeResultListAndAuditAlarmByHandle</c> also requires a client token handle to provide security information on
|
||
/// the client.
|
||
/// </para>
|
||
/// <para>
|
||
/// The ObjectTypeList array does not necessarily represent the entire defined object. Rather, it represents that subset of the
|
||
/// object for which to check access. For instance, to check access to two properties in a property set, specify an object type list
|
||
/// with four elements: the object itself at level zero, the property set at level 1, and the two properties at level 2.
|
||
/// </para>
|
||
/// <para>
|
||
/// The <c>AccessCheckByTypeResultListAndAuditAlarmByHandle</c> function evaluates ACEs that apply to the object itself and
|
||
/// object-specific ACEs for the object types listed in the ObjectTypeList array. The function ignores object-specific ACEs for
|
||
/// object types not listed in the ObjectTypeList array.
|
||
/// </para>
|
||
/// <para>
|
||
/// For more information about how a hierarchy of ACEs controls access to an object and its subobjects, see ACEs to Control Access to
|
||
/// an Object's Properties.
|
||
/// </para>
|
||
/// <para>
|
||
/// To generate audit messages in the security event log, the calling process must have the SE_AUDIT_NAME privilege enabled. The
|
||
/// system checks for this privilege in the primary token of the calling process, not the impersonation token of the thread. If the
|
||
/// Flags parameter includes the AUDIT_ALLOW_NO_PRIVILEGE flag, the function performs the access check without generating audit
|
||
/// messages when the privilege is not enabled.
|
||
/// </para>
|
||
/// <para>
|
||
/// The <c>AccessCheckByTypeResultListAndAuditAlarmByHandle</c> function fails if the calling thread is not impersonating a client.
|
||
/// </para>
|
||
/// <para>
|
||
/// If the security descriptor does not contain owner and group SIDs, <c>AccessCheckByTypeResultListAndAuditAlarmByHandle</c> fails
|
||
/// with ERROR_INVALID_SECURITY_DESCR.
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-accesscheckbytyperesultlistandauditalarmbyhandlea BOOL
|
||
// AccessCheckByTypeResultListAndAuditAlarmByHandleA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken, LPCSTR
|
||
// ObjectTypeName, LPCSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, PSID PrincipalSelfSid, DWORD DesiredAccess,
|
||
// AUDIT_EVENT_TYPE AuditType, DWORD Flags, POBJECT_TYPE_LIST ObjectTypeList, DWORD ObjectTypeListLength, PGENERIC_MAPPING
|
||
// GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess, LPDWORD AccessStatusList, LPBOOL pfGenerateOnClose );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "7d3ddce4-40a2-483d-8cff-48d89313b383")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool AccessCheckByTypeResultListAndAuditAlarmByHandle(string SubsystemName, [In] IntPtr HandleId, [In] HTOKEN ClientToken, string ObjectTypeName,
|
||
[Optional] string ObjectName, [In] PSECURITY_DESCRIPTOR SecurityDescriptor, [Optional] PSID PrincipalSelfSid,
|
||
ACCESS_MASK DesiredAccess, AUDIT_EVENT_TYPE AuditType, AccessCheckFlags Flags,
|
||
[In, Out, MarshalAs(UnmanagedType.LPArray)] OBJECT_TYPE_LIST[] ObjectTypeList, uint ObjectTypeListLength,
|
||
in GENERIC_MAPPING GenericMapping, [MarshalAs(UnmanagedType.Bool)] bool ObjectCreation,
|
||
[In, Out, MarshalAs(UnmanagedType.LPArray)] uint[] GrantedAccess,
|
||
[In, Out, MarshalAs(UnmanagedType.LPArray)] uint[] AccessStatusList,
|
||
[MarshalAs(UnmanagedType.Bool)] out bool pfGenerateOnClose);
|
||
|
||
/// <summary>
|
||
/// The <c>AddConditionalAce</c> function adds a conditional access control entry (ACE) to the specified access control list (ACL). A
|
||
/// conditional ACE specifies a logical condition that is evaluated during access checks.
|
||
/// </summary>
|
||
/// <param name="pAcl">
|
||
/// <para>A pointer to an ACL. This function adds an ACE to this ACL.</para>
|
||
/// <para>The value of this parameter cannot be <c>NULL</c>.</para>
|
||
/// </param>
|
||
/// <param name="dwAceRevision">
|
||
/// Specifies the revision level of the ACL being modified. This value can be ACL_REVISION or ACL_REVISION_DS. Use ACL_REVISION_DS if
|
||
/// the ACL contains object-specific ACEs.
|
||
/// </param>
|
||
/// <param name="AceFlags">
|
||
/// A set of bit flags that control ACE inheritance. The function sets these flags in the <c>AceFlags</c> member of the ACE_HEADER
|
||
/// structure of the new ACE. This parameter can be a combination of the following values.
|
||
/// </param>
|
||
/// <param name="AceType">
|
||
/// <para>The type of the ACE.</para>
|
||
/// <para>This can be one of the following values.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>ACCESS_ALLOWED_CALLBACK_ACE_TYPE 0x9</term>
|
||
/// <term>Access-allowed callback ACE that uses the ACCESS_ALLOWED_CALLBACK_ACE structure.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>ACCESS_DENIED_CALLBACK_ACE_TYPE 0xA</term>
|
||
/// <term>Access-denied callback ACE that uses the ACCESS_DENIED_CALLBACK_ACE structure.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>SYSTEM_AUDIT_CALLBACK_ACE_TYPE 0xD</term>
|
||
/// <term>System audit callback ACE that uses the SYSTEM_AUDIT_CALLBACK_ACE structure.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <param name="AccessMask">Specifies the mask of access rights to be granted to the specified SID.</param>
|
||
/// <param name="pSid">A pointer to the SID that represents a user, group, or logon account being granted access.</param>
|
||
/// <param name="ConditionStr">A string that specifies the conditional statement to be evaluated for the ACE.</param>
|
||
/// <param name="ReturnLength">
|
||
/// The size, in bytes, of the ACL. If the buffer specified by the pACL parameter is not of sufficient size, the value of this
|
||
/// parameter is the required size.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, it returns <c>TRUE</c>.</para>
|
||
/// <para>
|
||
/// If the function fails, it returns <c>FALSE</c>. For extended error information, call GetLastError. The following are possible
|
||
/// error values.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Return code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>ERROR_INSUFFICIENT_BUFFER</term>
|
||
/// <term>The new ACE does not fit into the pAcl buffer.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-addconditionalace BOOL AddConditionalAce( PACL pAcl, DWORD
|
||
// dwAceRevision, DWORD AceFlags, UCHAR AceType, DWORD AccessMask, PSID pSid, PWCHAR ConditionStr, DWORD *ReturnLength );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "89f038be-d15c-4c0b-8145-ba531bdf87ce")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool AddConditionalAce([In, Out] PACL pAcl, uint dwAceRevision, AceFlags AceFlags, AceType AceType, ACCESS_MASK AccessMask, PSID pSid, [MarshalAs(UnmanagedType.LPWStr)] string ConditionStr, out uint ReturnLength);
|
||
|
||
/// <summary>
|
||
/// Closes an encrypted file after a backup or restore operation, and frees associated system resources. This is one of a group of
|
||
/// Encrypted File System (EFS) functions that is intended to implement backup and restore functionality, while maintaining files in
|
||
/// their encrypted state.
|
||
/// </summary>
|
||
/// <param name="pvContext">
|
||
/// A pointer to a system-defined context block. The OpenEncryptedFileRaw function returns the context block.
|
||
/// </param>
|
||
/// <returns>This function does not return a value.</returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// The <c>CloseEncryptedFileRaw</c> function frees allocated system resources such as the system-defined context block and closes
|
||
/// the file.
|
||
/// </para>
|
||
/// <para>The BackupRead and BackupWrite functions handle backup and restore of unencrypted files.</para>
|
||
/// <para>In Windows 8, Windows Server 2012, and later, this function is supported by the following technologies.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Technology</term>
|
||
/// <term>Supported</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>Server Message Block (SMB) 3.0 protocol</term>
|
||
/// <term>Yes</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>SMB 3.0 Transparent Failover (TFO)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>SMB 3.0 with Scale-out File Shares (SO)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>Cluster Shared Volume File System (CsvFS)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>Resilient File System (ReFS)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>Note that SMB 3.0 does not support EFS on shares with continuous availability capability.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-closeencryptedfileraw void CloseEncryptedFileRaw( PVOID
|
||
// pvContext );
|
||
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "54bf7114-0ebb-4d9c-bc67-2ac351dbe55d")]
|
||
public static extern void CloseEncryptedFileRaw(EncryptedFileContext pvContext);
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// Creates a new process and its primary thread. Then the new process runs the specified executable file in the security context of
|
||
/// the specified credentials (user, domain, and password). It can optionally load the user profile for a specified user.
|
||
/// </para>
|
||
/// <para>
|
||
/// This function is similar to the CreateProcessAsUser and CreateProcessWithTokenW functions, except that the caller does not need
|
||
/// to call the LogonUser function to authenticate the user and get a token.
|
||
/// </para>
|
||
/// </summary>
|
||
/// <param name="lpUsername">
|
||
/// <para>
|
||
/// The name of the user. This is the name of the user account to log on to. If you use the UPN format, user@DNS_domain_name, the
|
||
/// lpDomain parameter must be NULL.
|
||
/// </para>
|
||
/// <para>
|
||
/// The user account must have the Log On Locally permission on the local computer. This permission is granted to all users on
|
||
/// workstations and servers, but only to administrators on domain controllers.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpDomain">
|
||
/// The name of the domain or server whose account database contains the lpUsername account. If this parameter is NULL, the user name
|
||
/// must be specified in UPN format.
|
||
/// </param>
|
||
/// <param name="lpPassword">The clear-text password for the lpUsername account.</param>
|
||
/// <param name="dwLogonFlags">The logon option. This parameter can be 0 (zero) or one of the following values.</param>
|
||
/// <param name="lpApplicationName">
|
||
/// <para>
|
||
/// The name of the module to be executed. This module can be a Windows-based application. It can be some other type of module (for
|
||
/// example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.
|
||
/// </para>
|
||
/// <para>
|
||
/// The string can specify the full path and file name of the module to execute or it can specify a partial name. If it is a partial
|
||
/// name, the function uses the current drive and current directory to complete the specification. The function does not use the
|
||
/// search path. This parameter must include the file name extension; no default extension is assumed.
|
||
/// </para>
|
||
/// <para>
|
||
/// The lpApplicationName parameter can be NULL, and the module name must be the first white space–delimited token in the
|
||
/// lpCommandLine string. If you are using a long file name that contains a space, use quoted strings to indicate where the file name
|
||
/// ends and the arguments begin; otherwise, the file name is ambiguous.
|
||
/// </para>
|
||
/// <para>For example, the following string can be interpreted in different ways:</para>
|
||
/// <para>"c:\program files\sub dir\program name"</para>
|
||
/// <para>The system tries to interpret the possibilities in the following order:</para>
|
||
/// <list type="number">
|
||
/// <item>
|
||
/// <term><c>c:\program.exe</c> files\sub dir\program name</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>c:\program files\sub.exe</c> dir\program name</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>c:\program files\sub dir\program.exe</c> name</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>c:\program files\sub dir\program name.exe</c></term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>
|
||
/// If the executable module is a 16-bit application, lpApplicationName should be NULL, and the string pointed to by lpCommandLine
|
||
/// should specify the executable module and its arguments.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpCommandLine">
|
||
/// <para>
|
||
/// The command line to be executed. The maximum length of this string is 1024 characters. If lpApplicationName is <c>NULL</c>, the
|
||
/// module name portion of lpCommandLine is limited to <c>MAX_PATH</c> characters.
|
||
/// </para>
|
||
/// <para>
|
||
/// The function can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a
|
||
/// <c>const</c> variable or a literal string). If this parameter is a constant string, the function may cause an access violation.
|
||
/// </para>
|
||
/// <para>
|
||
/// The lpCommandLine parameter can be <c>NULL</c>, and the function uses the string pointed to by lpApplicationName as the command line.
|
||
/// </para>
|
||
/// <para>
|
||
/// If both lpApplicationName and lpCommandLine are non- <c>NULL</c>, *lpApplicationName specifies the module to execute, and
|
||
/// *lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console
|
||
/// processes written in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C
|
||
/// programmers typically repeat the module name as the first token in the command line.
|
||
/// </para>
|
||
/// <para>
|
||
/// If lpApplicationName is <c>NULL</c>, the first white space–delimited token of the command line specifies the module name. If you
|
||
/// are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin
|
||
/// (see the explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended.
|
||
/// Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period
|
||
/// with no extension, or if the file name contains a path, .exe is not appended. If the file name does not contain a directory path,
|
||
/// the system searches for the executable file in the following sequence:
|
||
/// </para>
|
||
/// <list type="number">
|
||
/// <item>
|
||
/// <term>The directory from which the application loaded.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The current directory for the parent process.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>
|
||
/// The directories that are listed in the PATH environment variable. Note that this function does not search the per-application
|
||
/// path specified by the <c>App Paths</c> registry key. To include this per-application path in the search sequence, use the
|
||
/// ShellExecute function.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>
|
||
/// The system adds a null character to the command line string to separate the file name from the arguments. This divides the
|
||
/// original string into two strings for internal processing.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="dwCreationFlags">
|
||
/// <para>
|
||
/// The flags that control how the process is created. The <c>CREATE_DEFAULT_ERROR_MODE</c>, <c>CREATE_NEW_CONSOLE</c>, and
|
||
/// <c>CREATE_NEW_PROCESS_GROUP</c> flags are enabled by default— even if you do not set the flag, the system functions as if it were
|
||
/// set. You can specify additional flags as noted.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>CREATE_DEFAULT_ERROR_MODE 0x04000000</term>
|
||
/// <term>
|
||
/// The new process does not inherit the error mode of the calling process. Instead, CreateProcessWithLogonW gives the new process
|
||
/// the current default error mode. An application sets the current default error mode by calling SetErrorMode. This flag is enabled
|
||
/// by default.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_NEW_CONSOLE 0x00000010</term>
|
||
/// <term>
|
||
/// The new process has a new console, instead of inheriting the parent's console. This flag cannot be used with the DETACHED_PROCESS
|
||
/// flag. This flag is enabled by default.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_NEW_PROCESS_GROUP 0x00000200</term>
|
||
/// <term>
|
||
/// The new process is the root process of a new process group. The process group includes all processes that are descendants of this
|
||
/// root process. The process identifier of the new process group is the same as the process identifier, which is returned in the
|
||
/// lpProcessInfo parameter. Process groups are used by the GenerateConsoleCtrlEvent function to enable sending a CTRL+C or
|
||
/// CTRL+BREAK signal to a group of console processes. This flag is enabled by default.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_SEPARATE_WOW_VDM 0x00000800</term>
|
||
/// <term>
|
||
/// This flag is only valid starting a 16-bit Windows-based application. If set, the new process runs in a private Virtual DOS
|
||
/// Machine (VDM). By default, all 16-bit Windows-based applications run in a single, shared VDM. The advantage of running separately
|
||
/// is that a crash only terminates the single VDM; any other programs running in distinct VDMs continue to function normally. Also,
|
||
/// 16-bit Windows-based applications that run in separate VDMs have separate input queues, which means that if one application stops
|
||
/// responding momentarily, applications in separate VDMs continue to receive input.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_SUSPENDED 0x00000004</term>
|
||
/// <term>
|
||
/// The primary thread of the new process is created in a suspended state, and does not run until the ResumeThread function is called.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_UNICODE_ENVIRONMENT 0x00000400</term>
|
||
/// <term>
|
||
/// Indicates the format of the lpEnvironment parameter. If this flag is set, the environment block pointed to by lpEnvironment uses
|
||
/// Unicode characters. Otherwise, the environment block uses ANSI characters.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>
|
||
/// This parameter also controls the new process's priority class, which is used to determine the scheduling priorities of the
|
||
/// process's threads. For a list of values, see GetPriorityClass. If none of the priority class flags is specified, the priority
|
||
/// class defaults to <c>NORMAL_PRIORITY_CLASS</c> unless the priority class of the creating process is <c>IDLE_PRIORITY_CLASS</c> or
|
||
/// <c>BELOW_NORMAL_PRIORITY_CLASS</c>. In this case, the child process receives the default priority class of the calling process.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpEnvironment">
|
||
/// <para>
|
||
/// A pointer to an environment block for the new process. If this parameter is <c>NULL</c>, the new process uses an environment
|
||
/// created from the profile of the user specified by lpUsername.
|
||
/// </para>
|
||
/// <para>An environment block consists of a null-terminated block of null-terminated strings. Each string is in the following form:</para>
|
||
/// <para>name=value</para>
|
||
/// <para>Because the equal sign (=) is used as a separator, it must not be used in the name of an environment variable.</para>
|
||
/// <para>
|
||
/// An environment block can contain Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains
|
||
/// Unicode characters, ensure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>. If this parameter is NULL and the
|
||
/// environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>.
|
||
/// </para>
|
||
/// <para>
|
||
/// An ANSI environment block is terminated by two 0 (zero) bytes: one for the last string and one more to terminate the block. A
|
||
/// Unicode environment block is terminated by four zero bytes: two for the last string and two more to terminate the block.
|
||
/// </para>
|
||
/// <para>To retrieve a copy of the environment block for a specific user, use the CreateEnvironmentBlock function.</para>
|
||
/// </param>
|
||
/// <param name="lpCurrentDirectory">
|
||
/// <para>The full path to the current directory for the process. The string can also specify a UNC path.</para>
|
||
/// <para>
|
||
/// If this parameter is <c>NULL</c>, the new process has the same current drive and directory as the calling process. This feature
|
||
/// is provided primarily for shells that need to start an application, and specify its initial drive and working directory.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpStartupInfo">
|
||
/// <para>A pointer to a STARTUPINFO structure.</para>
|
||
/// <para>
|
||
/// The application must add permission for the specified user account to the specified window station and desktop, even for WinSta0\Default.
|
||
/// </para>
|
||
/// <para>
|
||
/// If the <c>lpDesktop</c> member is <c>NULL</c> or an empty string, the new process inherits the desktop and window station of its
|
||
/// parent process. The application must add permission for the specified user account to the inherited window station and desktop.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>Windows XP:</c><c>CreateProcessWithLogonW</c> adds permission for the specified user account to the inherited window station
|
||
/// and desktop.
|
||
/// </para>
|
||
/// <para>Handles in STARTUPINFO must be closed with CloseHandle when they are no longer needed.</para>
|
||
/// <para>
|
||
/// <c>Important</c> If the <c>dwFlags</c> member of the STARTUPINFO structure specifies <c>STARTF_USESTDHANDLES</c>, the standard
|
||
/// handle fields are copied unchanged to the child process without validation. The caller is responsible for ensuring that these
|
||
/// fields contain valid handle values. Incorrect values can cause the child process to misbehave or crash. Use the Application
|
||
/// Verifier runtime verification tool to detect invalid handles.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpProcessInformation">
|
||
/// <para>
|
||
/// A pointer to a PROCESS_INFORMATION structure that receives identification information for the new process, including a handle to
|
||
/// the process.
|
||
/// </para>
|
||
/// <para>Handles in PROCESS_INFORMATION must be closed with the CloseHandle function when they are not needed.</para>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is nonzero.</para>
|
||
/// <para>If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError.</para>
|
||
/// <para>
|
||
/// Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to
|
||
/// initialize, the process is terminated. To get the termination status of a process, call GetExitCodeProcess.
|
||
/// </para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// By default, <c>CreateProcessWithLogonW</c> does not load the specified user profile into the <c>HKEY_USERS</c> registry key. This
|
||
/// means that access to information in the <c>HKEY_CURRENT_USER</c> registry key may not produce results that are consistent with a
|
||
/// normal interactive logon. It is your responsibility to load the user registry hive into <c>HKEY_USERS</c> before calling
|
||
/// <c>CreateProcessWithLogonW</c>, by using <c>LOGON_WITH_PROFILE</c>, or by calling the LoadUserProfile function.
|
||
/// </para>
|
||
/// <para>
|
||
/// If the lpEnvironment parameter is NULL, the new process uses an environment block created from the profile of the user specified
|
||
/// by lpUserName. If the HOMEDRIVE and HOMEPATH variables are not set, <c>CreateProcessWithLogonW</c> modifies the environment block
|
||
/// to use the drive and path of the user's working directory.
|
||
/// </para>
|
||
/// <para>
|
||
/// When created, the new process and thread handles receive full access rights ( <c>PROCESS_ALL_ACCESS</c> and
|
||
/// <c>THREAD_ALL_ACCESS</c>). For either handle, if a security descriptor is not provided, the handle can be used in any function
|
||
/// that requires an object handle of that type. When a security descriptor is provided, an access check is performed on all
|
||
/// subsequent uses of the handle before access is granted. If access is denied, the requesting process cannot use the handle to gain
|
||
/// access to the process or thread.
|
||
/// </para>
|
||
/// <para>To retrieve a security token, pass the process handle in the PROCESS_INFORMATION structure to the OpenProcessToken function.</para>
|
||
/// <para>
|
||
/// The process is assigned a process identifier. The identifier is valid until the process terminates. It can be used to identify
|
||
/// the process, or it can be specified in the OpenProcess function to open a handle to the process. The initial thread in the
|
||
/// process is also assigned a thread identifier. It can be specified in the OpenThread function to open a handle to the thread. The
|
||
/// identifier is valid until the thread terminates and can be used to uniquely identify the thread within the system. These
|
||
/// identifiers are returned in PROCESS_INFORMATION.
|
||
/// </para>
|
||
/// <para>
|
||
/// The calling thread can use the WaitForInputIdle function to wait until the new process has completed its initialization and is
|
||
/// waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because
|
||
/// <c>CreateProcessWithLogonW</c> returns without waiting for the new process to finish its initialization. For example, the
|
||
/// creating process would use <c>WaitForInputIdle</c> before trying to find a window that is associated with the new process.
|
||
/// </para>
|
||
/// <para>
|
||
/// The preferred way to shut down a process is by using the ExitProcess function, because this function sends notification of
|
||
/// approaching termination to all DLLs attached to the process. Other means of shutting down a process do not notify the attached
|
||
/// DLLs. Note that when a thread calls <c>ExitProcess</c>, other threads of the process are terminated without an opportunity to
|
||
/// execute any additional code (including the thread termination code of attached DLLs). For more information, see Terminating a Process.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>CreateProcessWithLogonW</c> accesses the specified directory and executable image in the security context of the target user.
|
||
/// If the executable image is on a network and a network drive letter is specified in the path, the network drive letter is not
|
||
/// available to the target user, as network drive letters can be assigned for each logon. If a network drive letter is specified,
|
||
/// this function fails. If the executable image is on a network, use the UNC path.
|
||
/// </para>
|
||
/// <para>
|
||
/// There is a limit to the number of child processes that can be created by this function and run simultaneously. For example, on
|
||
/// Windows XP, this limit is <c>MAXIMUM_WAIT_OBJECTS</c>*4. However, you may not be able to create this many processes due to
|
||
/// system-wide quota limits.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>Windows XP with SP2,Windows Server 2003, or later:</c> You cannot call <c>CreateProcessWithLogonW</c> from a process that is
|
||
/// running under the "LocalSystem" account, because the function uses the logon SID in the caller token, and the token for the
|
||
/// "LocalSystem" account does not contain this SID. As an alternative, use the CreateProcessAsUser and LogonUser functions.
|
||
/// </para>
|
||
/// <para>
|
||
/// To compile an application that uses this function, define <c>_WIN32_WINNT</c> as 0x0500 or later. For more information, see Using
|
||
/// the Windows Headers.
|
||
/// </para>
|
||
/// <para>Security Remarks</para>
|
||
/// <para>
|
||
/// The lpApplicationName parameter can be <c>NULL</c>, and the executable name must be the first white space–delimited string in
|
||
/// lpCommandLine. If the executable or path name has a space in it, there is a risk that a different executable could be run because
|
||
/// of the way the function parses spaces. Avoid the following example, because the function attempts to run "Program.exe", if it
|
||
/// exists, instead of "MyApp.exe".
|
||
/// </para>
|
||
/// <para>
|
||
/// If a malicious user creates an application called "Program.exe" on a system, any program that incorrectly calls
|
||
/// <c>CreateProcessWithLogonW</c> using the Program Files directory runs the malicious user application instead of the intended application.
|
||
/// </para>
|
||
/// <para>
|
||
/// To avoid this issue, do not pass <c>NULL</c> for lpApplicationName. If you pass <c>NULL</c> for lpApplicationName, use quotation
|
||
/// marks around the executable path in lpCommandLine, as shown in the following example:
|
||
/// </para>
|
||
/// <para>Examples</para>
|
||
/// <para>The following example demonstrates how to call this function.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-createprocesswithlogonw BOOL CreateProcessWithLogonW(
|
||
// LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags, LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
|
||
// DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION
|
||
// lpProcessInformation );
|
||
[PInvokeData("winbase.h", MSDNShortId = "dcfdcd5b-0269-4081-b1db-e272171c27a2")]
|
||
public static bool CreateProcessWithLogonW(string lpUsername, [Optional] string lpDomain, string lpPassword, ProcessLogonFlags dwLogonFlags,
|
||
[Optional] string lpApplicationName, [Optional] StringBuilder lpCommandLine, CREATE_PROCESS dwCreationFlags,
|
||
[Optional] string[] lpEnvironment, [Optional] string lpCurrentDirectory, in STARTUPINFO lpStartupInfo, out SafePROCESS_INFORMATION lpProcessInformation)
|
||
{
|
||
var ret = CreateProcessWithLogonW(lpUsername, lpDomain, lpPassword, dwLogonFlags, lpApplicationName, lpCommandLine, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, out PROCESS_INFORMATION pi);
|
||
lpProcessInformation = ret ? new SafePROCESS_INFORMATION(pi) : null;
|
||
return ret;
|
||
}
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// Creates a new process and its primary thread. The new process runs in the security context of the specified token. It can
|
||
/// optionally load the user profile for the specified user.
|
||
/// </para>
|
||
/// <para>
|
||
/// The process that calls <c>CreateProcessWithTokenW</c> must have the SE_IMPERSONATE_NAME privilege. If this function fails with
|
||
/// ERROR_PRIVILEGE_NOT_HELD (1314), use the CreateProcessAsUser or CreateProcessWithLogonW function instead. Typically, the process
|
||
/// that calls <c>CreateProcessAsUser</c> must have the SE_INCREASE_QUOTA_NAME privilege and may require the
|
||
/// SE_ASSIGNPRIMARYTOKEN_NAME privilege if the token is not assignable. <c>CreateProcessWithLogonW</c> requires no special
|
||
/// privileges, but the specified user account must be allowed to log on interactively. Generally, it is best to use
|
||
/// <c>CreateProcessWithLogonW</c> to create a process with alternate credentials.
|
||
/// </para>
|
||
/// </summary>
|
||
/// <param name="hToken">
|
||
/// <para>
|
||
/// A handle to the primary token that represents a user. The handle must have the TOKEN_QUERY, TOKEN_DUPLICATE, and
|
||
/// TOKEN_ASSIGN_PRIMARY access rights. For more information, see Access Rights for Access-Token Objects. The user represented by the
|
||
/// token must have read and execute access to the application specified by the lpApplicationName or the lpCommandLine parameter.
|
||
/// </para>
|
||
/// <para>
|
||
/// To get a primary token that represents the specified user, call the LogonUser function. Alternatively, you can call the
|
||
/// DuplicateTokenEx function to convert an impersonation token into a primary token. This allows a server application that is
|
||
/// impersonating a client to create a process that has the security context of the client.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>Terminal Services:</c> The process is run in the session specified in the token. By default, this is the same session that
|
||
/// called LogonUser. To change the session, use the SetTokenInformation function.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="dwLogonFlags">The logon option. This parameter can be zero or one of the following values.</param>
|
||
/// <param name="lpApplicationName">
|
||
/// <para>
|
||
/// The name of the module to be executed. This module can be a Windows-based application. It can be some other type of module (for
|
||
/// example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.
|
||
/// </para>
|
||
/// <para>
|
||
/// The string can specify the full path and file name of the module to execute or it can specify a partial name. In the case of a
|
||
/// partial name, the function uses the current drive and current directory to complete the specification. The function will not use
|
||
/// the search path. This parameter must include the file name extension; no default extension is assumed.
|
||
/// </para>
|
||
/// <para>
|
||
/// The lpApplicationName parameter can be NULL. In that case, the module name must be the first white space–delimited token in the
|
||
/// lpCommandLine string. If you are using a long file name that contains a space, use quoted strings to indicate where the file name
|
||
/// ends and the arguments begin; otherwise, the file name is ambiguous. For example, consider the string "c:\program files\sub
|
||
/// dir\program name". This string can be interpreted in a number of ways. The system tries to interpret the possibilities in the
|
||
/// following order:
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>c:\program.exe</c><c>c:\program files\sub.exe</c><c>c:\program files\sub dir\program.exe</c><c>c:\program files\sub
|
||
/// dir\program name.exe</c> If the executable module is a 16-bit application, lpApplicationName should be NULL, and the string
|
||
/// pointed to by lpCommandLine should specify the executable module as well as its arguments.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpCommandLine">
|
||
/// <para>The command line to be executed.</para>
|
||
/// <para>
|
||
/// The maximum length of this string is 1024 characters. If lpApplicationName is NULL, the module name portion of lpCommandLine is
|
||
/// limited to MAX_PATH characters.
|
||
/// </para>
|
||
/// <para>
|
||
/// The function can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a
|
||
/// <c>const</c> variable or a literal string). If this parameter is a constant string, the function may cause an access violation.
|
||
/// </para>
|
||
/// <para>
|
||
/// The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the
|
||
/// command line.
|
||
/// </para>
|
||
/// <para>
|
||
/// If both lpApplicationName and lpCommandLine are non-NULL, *lpApplicationName specifies the module to execute, and *lpCommandLine
|
||
/// specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console processes written
|
||
/// in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C programmers generally
|
||
/// repeat the module name as the first token in the command line.
|
||
/// </para>
|
||
/// <para>
|
||
/// If lpApplicationName is NULL, the first white space–delimited token of the command line specifies the module name. If you are
|
||
/// using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin
|
||
/// (see the explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended.
|
||
/// Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period
|
||
/// (.) with no extension, or if the file name contains a path, .exe is not appended. If the file name does not contain a directory
|
||
/// path, the system searches for the executable file in the following sequence:
|
||
/// </para>
|
||
/// <list type="number">
|
||
/// <item>
|
||
/// <term>The directory from which the application loaded.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The current directory for the parent process.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>
|
||
/// The directories that are listed in the PATH environment variable. Note that this function does not search the per-application
|
||
/// path specified by the <c>App Paths</c> registry key. To include this per-application path in the search sequence, use the
|
||
/// ShellExecute function.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>
|
||
/// The system adds a null character to the command line string to separate the file name from the arguments. This divides the
|
||
/// original string into two strings for internal processing.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="dwCreationFlags">
|
||
/// <para>
|
||
/// The flags that control how the process is created. The CREATE_DEFAULT_ERROR_MODE, CREATE_NEW_CONSOLE, and
|
||
/// CREATE_NEW_PROCESS_GROUP flags are enabled by default. You can specify additional flags as noted.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>CREATE_DEFAULT_ERROR_MODE 0x04000000</term>
|
||
/// <term>
|
||
/// The new process does not inherit the error mode of the calling process. Instead, the new process gets the current default error
|
||
/// mode. An application sets the current default error mode by calling SetErrorMode. This flag is enabled by default.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_NEW_CONSOLE 0x00000010</term>
|
||
/// <term>
|
||
/// The new process has a new console, instead of inheriting the parent's console. This flag cannot be used with the DETACHED_PROCESS
|
||
/// flag. This flag is enabled by default.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_NEW_PROCESS_GROUP 0x00000200</term>
|
||
/// <term>
|
||
/// The new process is the root process of a new process group. The process group includes all processes that are descendants of this
|
||
/// root process. The process identifier of the new process group is the same as the process identifier, which is returned in the
|
||
/// lpProcessInfo parameter. Process groups are used by the GenerateConsoleCtrlEvent function to enable sending a CTRL+C or
|
||
/// CTRL+BREAK signal to a group of console processes. This flag is enabled by default.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_SEPARATE_WOW_VDM 0x00000800</term>
|
||
/// <term>
|
||
/// This flag is only valid starting a 16-bit Windows-based application. If set, the new process runs in a private Virtual DOS
|
||
/// Machine (VDM). By default, all 16-bit Windows-based applications run in a single, shared VDM. The advantage of running separately
|
||
/// is that a crash only terminates the single VDM; any other programs running in distinct VDMs continue to function normally. Also,
|
||
/// 16-bit Windows-based applications that run in separate VDMs have separate input queues. That means that if one application stops
|
||
/// responding momentarily, applications in separate VDMs continue to receive input.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_SUSPENDED 0x00000004</term>
|
||
/// <term>
|
||
/// The primary thread of the new process is created in a suspended state, and does not run until the ResumeThread function is called.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_UNICODE_ENVIRONMENT 0x00000400</term>
|
||
/// <term>
|
||
/// Indicates the format of the lpEnvironment parameter. If this flag is set, the environment block pointed to by lpEnvironment uses
|
||
/// Unicode characters. Otherwise, the environment block uses ANSI characters.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>EXTENDED_STARTUPINFO_PRESENT 0x00080000</term>
|
||
/// <term>
|
||
/// The process is created with extended startup information; the lpStartupInfo parameter specifies a STARTUPINFOEX structure.
|
||
/// Windows Server 2003: This value is not supported.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>
|
||
/// This parameter also controls the new process's priority class, which is used to determine the scheduling priorities of the
|
||
/// process's threads. For a list of values, see GetPriorityClass. If none of the priority class flags is specified, the priority
|
||
/// class defaults to NORMAL_PRIORITY_CLASS unless the priority class of the creating process is IDLE_PRIORITY_CLASS or
|
||
/// BELOW_NORMAL_PRIORITY_CLASS. In this case, the child process receives the default priority class of the calling process.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpEnvironment">
|
||
/// <para>
|
||
/// A pointer to an environment block for the new process. If this parameter is NULL, the new process uses an environment created
|
||
/// from the profile of the user specified by lpUsername.
|
||
/// </para>
|
||
/// <para>An environment block consists of a null-terminated block of null-terminated strings. Each string is in the following form:</para>
|
||
/// <para>name=value</para>
|
||
/// <para>Because the equal sign (=) is used as a separator, it must not be used in the name of an environment variable.</para>
|
||
/// <para>
|
||
/// An environment block can contain Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains
|
||
/// Unicode characters, be sure that dwCreationFlags includes CREATE_UNICODE_ENVIRONMENT. If this parameter is NULL and the
|
||
/// environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes CREATE_UNICODE_ENVIRONMENT.
|
||
/// </para>
|
||
/// <para>
|
||
/// An ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A Unicode
|
||
/// environment block is terminated by four zero bytes: two for the last string and two more to terminate the block.
|
||
/// </para>
|
||
/// <para>To retrieve a copy of the environment block for a specific user, use the CreateEnvironmentBlock function.</para>
|
||
/// </param>
|
||
/// <param name="lpCurrentDirectory">
|
||
/// <para>The full path to the current directory for the process. The string can also specify a UNC path.</para>
|
||
/// <para>
|
||
/// If this parameter is NULL, the new process will have the same current drive and directory as the calling process. (This feature
|
||
/// is provided primarily for shells that need to start an application and specify its initial drive and working directory.)
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpStartupInfo">
|
||
/// <para>A pointer to a STARTUPINFO or STARTUPINFOEX structure.</para>
|
||
/// <para>
|
||
/// If the <c>lpDesktop</c> member is NULL or an empty string, the new process inherits the desktop and window station of its parent
|
||
/// process. The function adds permission for the specified user account to the inherited window station and desktop. Otherwise, if
|
||
/// this member specifies a desktop, it is the responsibility of the application to add permission for the specified user account to
|
||
/// the specified window station and desktop, even for WinSta0\Default.
|
||
/// </para>
|
||
/// <para>Handles in STARTUPINFO or STARTUPINFOEX must be closed with CloseHandle when they are no longer needed.</para>
|
||
/// <para>
|
||
/// <c>Important</c> If the <c>dwFlags</c> member of the STARTUPINFO structure specifies <c>STARTF_USESTDHANDLES</c>, the standard
|
||
/// handle fields are copied unchanged to the child process without validation. The caller is responsible for ensuring that these
|
||
/// fields contain valid handle values. Incorrect values can cause the child process to misbehave or crash. Use the Application
|
||
/// Verifier runtime verification tool to detect invalid handles.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpProcessInformation">
|
||
/// <para>
|
||
/// A pointer to a PROCESS_INFORMATION structure that receives identification information for the new process, including a handle to
|
||
/// the process.
|
||
/// </para>
|
||
/// <para>Handles in PROCESS_INFORMATION must be closed with the CloseHandle function when they are no longer needed.</para>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is nonzero.</para>
|
||
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
|
||
/// <para>
|
||
/// Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to
|
||
/// initialize, the process is terminated. To get the termination status of a process, call GetExitCodeProcess.
|
||
/// </para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// By default, <c>CreateProcessWithTokenW</c> does not load the specified user's profile into the <c>HKEY_USERS</c> registry key.
|
||
/// This means that access to information in the <c>HKEY_CURRENT_USER</c> registry key may not produce results consistent with a
|
||
/// normal interactive logon. It is your responsibility to load the user's registry hive into <c>HKEY_USERS</c> by either using
|
||
/// LOGON_WITH_PROFILE, or by calling the LoadUserProfile function before calling this function.
|
||
/// </para>
|
||
/// <para>
|
||
/// If the lpEnvironment parameter is NULL, the new process uses an environment block created from the profile of the user specified
|
||
/// by lpUserName. If the HOMEDRIVE and HOMEPATH variables are not set, <c>CreateProcessWithTokenW</c> modifies the environment block
|
||
/// to use the drive and path of the user's working directory.
|
||
/// </para>
|
||
/// <para>
|
||
/// When created, the new process and thread handles receive full access rights (PROCESS_ALL_ACCESS and THREAD_ALL_ACCESS). For
|
||
/// either handle, if a security descriptor is not provided, the handle can be used in any function that requires an object handle of
|
||
/// that type. When a security descriptor is provided, an access check is performed on all subsequent uses of the handle before
|
||
/// access is granted. If access is denied, the requesting process cannot use the handle to gain access to the process or thread.
|
||
/// </para>
|
||
/// <para>To retrieve a security token, pass the process handle in the PROCESS_INFORMATION structure to the OpenProcessToken function.</para>
|
||
/// <para>
|
||
/// The process is assigned a process identifier. The identifier is valid until the process terminates. It can be used to identify
|
||
/// the process, or specified in the OpenProcess function to open a handle to the process. The initial thread in the process is also
|
||
/// assigned a thread identifier. It can be specified in the OpenThread function to open a handle to the thread. The identifier is
|
||
/// valid until the thread terminates and can be used to uniquely identify the thread within the system. These identifiers are
|
||
/// returned in PROCESS_INFORMATION.
|
||
/// </para>
|
||
/// <para>
|
||
/// The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is
|
||
/// waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because
|
||
/// <c>CreateProcessWithTokenW</c> returns without waiting for the new process to finish its initialization. For example, the
|
||
/// creating process would use <c>WaitForInputIdle</c> before trying to find a window associated with the new process.
|
||
/// </para>
|
||
/// <para>
|
||
/// The preferred way to shut down a process is by using the ExitProcess function, because this function sends notification of
|
||
/// approaching termination to all DLLs attached to the process. Other means of shutting down a process do not notify the attached
|
||
/// DLLs. Note that when a thread calls <c>ExitProcess</c>, other threads of the process are terminated without an opportunity to
|
||
/// execute any additional code (including the thread termination code of attached DLLs). For more information, see Terminating a Process.
|
||
/// </para>
|
||
/// <para>
|
||
/// To compile an application that uses this function, define _WIN32_WINNT as 0x0500 or later. For more information, see Using the
|
||
/// Windows Headers.
|
||
/// </para>
|
||
/// <para>Security Remarks</para>
|
||
/// <para>
|
||
/// The lpApplicationName parameter can be NULL, in which case the executable name must be the first white space–delimited string in
|
||
/// lpCommandLine. If the executable or path name has a space in it, there is a risk that a different executable could be run because
|
||
/// of the way the function parses spaces. The following example is dangerous because the function will attempt to run "Program.exe",
|
||
/// if it exists, instead of "MyApp.exe".
|
||
/// </para>
|
||
/// <para>
|
||
/// If a malicious user were to create an application called "Program.exe" on a system, any program that incorrectly calls
|
||
/// <c>CreateProcessWithTokenW</c> using the Program Files directory will run this application instead of the intended application.
|
||
/// </para>
|
||
/// <para>
|
||
/// To avoid this problem, do not pass NULL for lpApplicationName. If you do pass NULL for lpApplicationName, use quotation marks
|
||
/// around the executable path in lpCommandLine, as shown in the example below.
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-createprocesswithtokenw BOOL CreateProcessWithTokenW(
|
||
// HANDLE hToken, DWORD dwLogonFlags, LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
|
||
// LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation );
|
||
[PInvokeData("winbase.h", MSDNShortId = "b329866a-0c0d-4cb3-838c-36aac17c87ed")]
|
||
public static bool CreateProcessWithTokenW(HTOKEN hToken, ProcessLogonFlags dwLogonFlags, string lpApplicationName, [Optional] StringBuilder lpCommandLine, CREATE_PROCESS dwCreationFlags,
|
||
[Optional] string[] lpEnvironment, [Optional] string lpCurrentDirectory, in STARTUPINFO lpStartupInfo, out SafePROCESS_INFORMATION lpProcessInformation)
|
||
{
|
||
var ret = CreateProcessWithTokenW(hToken, dwLogonFlags, lpApplicationName, lpCommandLine, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, out PROCESS_INFORMATION pi);
|
||
lpProcessInformation = ret ? new SafePROCESS_INFORMATION(pi) : null;
|
||
return ret;
|
||
}
|
||
|
||
/// <summary>Decrypts an encrypted file or directory.</summary>
|
||
/// <param name="lpFileName">
|
||
/// <para>The name of the file or directory to be decrypted.</para>
|
||
/// <para>
|
||
/// The caller must have the <c>FILE_READ_DATA</c>, <c>FILE_WRITE_DATA</c>, <c>FILE_READ_ATTRIBUTES</c>,
|
||
/// <c>FILE_WRITE_ATTRIBUTES</c>, and <c>SYNCHRONIZE</c> access rights. For more information, see File Security and Access Rights.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="dwReserved">Reserved; must be zero.</param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is nonzero.</para>
|
||
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// The <c>DecryptFile</c> function requires exclusive access to the file being decrypted, and will fail if another process is using
|
||
/// the file. If the file is not encrypted, <c>DecryptFile</c> simply returns a nonzero value, which indicates success.
|
||
/// </para>
|
||
/// <para>
|
||
/// If lpFileName specifies a read-only file, the function fails and GetLastError returns <c>ERROR_FILE_READ_ONLY</c>. If lpFileName
|
||
/// specifies a directory that contains a read-only file, the functions succeeds but the directory is not decrypted.
|
||
/// </para>
|
||
/// <para>In Windows 8, Windows Server 2012, and later, this function is supported by the following technologies.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Technology</term>
|
||
/// <term>Supported</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>Server Message Block (SMB) 3.0 protocol</term>
|
||
/// <term>Yes</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>SMB 3.0 Transparent Failover (TFO)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>SMB 3.0 with Scale-out File Shares (SO)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>Cluster Shared Volume File System (CsvFS)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>Resilient File System (ReFS)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>SMB 3.0 does not support EFS on shares with continuous availability capability.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-decryptfilea BOOL DecryptFileA( LPCSTR lpFileName, DWORD
|
||
// dwReserved );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "6b8f0ed0-8825-4c84-bf58-3a89cda882b4")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool DecryptFile(string lpFileName, uint dwReserved = 0);
|
||
|
||
/// <summary>
|
||
/// Encrypts a file or directory. All data streams in a file are encrypted. All new files created in an encrypted directory are encrypted.
|
||
/// </summary>
|
||
/// <param name="lpFileName">
|
||
/// <para>The name of the file or directory to be encrypted.</para>
|
||
/// <para>
|
||
/// The caller must have the <c>FILE_READ_DATA</c>, <c>FILE_WRITE_DATA</c>, <c>FILE_READ_ATTRIBUTES</c>,
|
||
/// <c>FILE_WRITE_ATTRIBUTES</c>, and <c>SYNCHRONIZE</c> access rights. For more information, see File Security and Access Rights.
|
||
/// </para>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is nonzero.</para>
|
||
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// The <c>EncryptFile</c> function requires exclusive access to the file being encrypted, and will fail if another process is using
|
||
/// the file.
|
||
/// </para>
|
||
/// <para>
|
||
/// If the file is already encrypted, <c>EncryptFile</c> simply returns a nonzero value, which indicates success. If the file is
|
||
/// compressed, <c>EncryptFile</c> will decompress the file before encrypting it.
|
||
/// </para>
|
||
/// <para>
|
||
/// If lpFileName specifies a read-only file, the function fails and GetLastError returns <c>ERROR_FILE_READ_ONLY</c>. If lpFileName
|
||
/// specifies a directory that contains a read-only file, the functions succeeds but the directory is not encrypted.
|
||
/// </para>
|
||
/// <para>To decrypt an encrypted file, use the DecryptFile function.</para>
|
||
/// <para>In Windows 8, Windows Server 2012, and later, this function is supported by the following technologies.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Technology</term>
|
||
/// <term>Supported</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>Server Message Block (SMB) 3.0 protocol</term>
|
||
/// <term>Yes</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>SMB 3.0 Transparent Failover (TFO)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>SMB 3.0 with Scale-out File Shares (SO)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>Cluster Shared Volume File System (CsvFS)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>Resilient File System (ReFS)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>SMB 3.0 does not support EFS on shares with continuous availability capability.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-encryptfilea BOOL EncryptFileA( LPCSTR lpFileName );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "7620e9fa-74d6-4b41-93db-4a562be63202")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool EncryptFile(string lpFileName);
|
||
|
||
/// <summary>Retrieves the encryption status of the specified file.</summary>
|
||
/// <param name="lpFileName">The name of the file.</param>
|
||
/// <param name="lpStatus">
|
||
/// A pointer to a variable that receives the encryption status of the file. This parameter can be one of the following values.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is nonzero.</para>
|
||
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>In Windows 8 and Windows Server 2012, this function is supported by the following technologies.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Technology</term>
|
||
/// <term>Supported</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>Server Message Block (SMB) 3.0 protocol</term>
|
||
/// <term>Yes</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>SMB 3.0 Transparent Failover (TFO)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>SMB 3.0 with Scale-out File Shares (SO)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>Cluster Shared Volume File System (CsvFS)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>Resilient File System (ReFS)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>SMB 3.0 does not support EFS on shares with continuous availability capability.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-fileencryptionstatusa BOOL FileEncryptionStatusA( LPCSTR
|
||
// lpFileName, LPDWORD lpStatus );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "96efe065-de62-4941-811d-610465cd7ef5")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool FileEncryptionStatus(string lpFileName, out EncryptionStatus lpStatus);
|
||
|
||
/// <summary>Retrieves information about the current hardware profile for the local computer.</summary>
|
||
/// <param name="lpHwProfileInfo">
|
||
/// A pointer to an HW_PROFILE_INFO structure that receives information about the current hardware profile.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is a nonzero value.</para>
|
||
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// The <c>GetCurrentHwProfile</c> function retrieves the display name and globally unique identifier (GUID) string for the hardware
|
||
/// profile. The function also retrieves the reported docking state for portable computers with docking stations.
|
||
/// </para>
|
||
/// <para>
|
||
/// The system generates a GUID for each hardware profile and stores it as a string in the registry. You can use
|
||
/// <c>GetCurrentHwProfile</c> to retrieve the GUID string to use as a registry subkey under your application's configuration
|
||
/// settings key in <c>HKEY_CURRENT_USER</c>. This enables you to store each user's settings for each hardware profile. For example,
|
||
/// the Colors control panel application could use the subkey to store each user's color preferences for different hardware profiles,
|
||
/// such as profiles for the docked and undocked states. Applications that use this functionality can check the current hardware
|
||
/// profile when they start up, and update their settings accordingly.
|
||
/// </para>
|
||
/// <para>
|
||
/// Applications can also update their settings when a system device message, such as DBT_CONFIGCHANGED, indicates that the hardware
|
||
/// profile has changed.
|
||
/// </para>
|
||
/// <para>
|
||
/// To compile an application that uses this function, define the _WIN32_WINNT macro as 0x0400 or later. For more information, see
|
||
/// Using the Windows Headers.
|
||
/// </para>
|
||
/// <para>Examples</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-getcurrenthwprofilea BOOL GetCurrentHwProfileA(
|
||
// LPHW_PROFILE_INFOA lpHwProfileInfo );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "152067bb-3896-43ef-a882-12a159f92cc7")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool GetCurrentHwProfile(out HW_PROFILE_INFO lpHwProfileInfo);
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// The <c>GetFileSecurity</c> function obtains specified information about the security of a file or directory. The information
|
||
/// obtained is constrained by the caller's access rights and privileges.
|
||
/// </para>
|
||
/// <para>
|
||
/// The GetNamedSecurityInfo function provides functionality similar to <c>GetFileSecurity</c> for files as well as other types of objects.
|
||
/// </para>
|
||
/// </summary>
|
||
/// <param name="lpFileName">
|
||
/// A pointer to a null-terminated string that specifies the file or directory for which security information is retrieved.
|
||
/// </param>
|
||
/// <param name="RequestedInformation">A SECURITY_INFORMATION value that identifies the security information being requested.</param>
|
||
/// <param name="pSecurityDescriptor">
|
||
/// A pointer to a buffer that receives a copy of the security descriptor of the object specified by the lpFileName parameter. The
|
||
/// calling process must have permission to view the specified aspects of the object's security status. The SECURITY_DESCRIPTOR
|
||
/// structure is returned in self-relative security descriptor format.
|
||
/// </param>
|
||
/// <param name="nLength">Specifies the size, in bytes, of the buffer pointed to by the pSecurityDescriptor parameter.</param>
|
||
/// <param name="lpnLengthNeeded">
|
||
/// A pointer to the variable that receives the number of bytes necessary to store the complete security descriptor. If the returned
|
||
/// number of bytes is less than or equal to nLength, the entire security descriptor is returned in the output buffer; otherwise,
|
||
/// none of the descriptor is returned.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is nonzero.</para>
|
||
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// To read the owner, group, or DACL from the security descriptor for the specified file or directory, the DACL for the file or
|
||
/// directory must grant READ_CONTROL access to the caller, or the caller must be the owner of the file or directory.
|
||
/// </para>
|
||
/// <para>To read the SACL of a file or directory, the SE_SECURITY_NAME privilege must be enabled for the calling process.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-getfilesecuritya BOOL GetFileSecurityA( LPCSTR lpFileName,
|
||
// SECURITY_INFORMATION RequestedInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength, LPDWORD lpnLengthNeeded );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "4043b76b-76b9-4111-8a29-a808b2412be0")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool GetFileSecurity(string lpFileName, SECURITY_INFORMATION RequestedInformation, SafePSECURITY_DESCRIPTOR pSecurityDescriptor, uint nLength, out uint lpnLengthNeeded);
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// The <c>GetFileSecurity</c> function obtains specified information about the security of a file or directory. The information
|
||
/// obtained is constrained by the caller's access rights and privileges.
|
||
/// </para>
|
||
/// <para>
|
||
/// The GetNamedSecurityInfo function provides functionality similar to <c>GetFileSecurity</c> for files as well as other types of objects.
|
||
/// </para>
|
||
/// </summary>
|
||
/// <param name="lpFileName">
|
||
/// A pointer to a null-terminated string that specifies the file or directory for which security information is retrieved.
|
||
/// </param>
|
||
/// <param name="RequestedInformation">A SECURITY_INFORMATION value that identifies the security information being requested.</param>
|
||
/// <returns>
|
||
/// The security descriptor of the object specified by the lpFileName parameter. The calling process must have permission to view the
|
||
/// specified aspects of the object's security status. The SECURITY_DESCRIPTOR structure is returned in self-relative security
|
||
/// descriptor format.
|
||
/// </returns>
|
||
[PInvokeData("winbase.h", MSDNShortId = "4043b76b-76b9-4111-8a29-a808b2412be0")]
|
||
public static SafePSECURITY_DESCRIPTOR GetFileSecurity(string lpFileName, SECURITY_INFORMATION RequestedInformation = SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION | SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION | SECURITY_INFORMATION.DACL_SECURITY_INFORMATION)
|
||
{
|
||
if (!GetFileSecurity(lpFileName, RequestedInformation, SafePSECURITY_DESCRIPTOR.Null, 0, out var sz) && sz == 0)
|
||
Win32Error.ThrowLastError();
|
||
var sd = new SafePSECURITY_DESCRIPTOR((int)sz);
|
||
if (!GetFileSecurity(lpFileName, RequestedInformation, sd, (uint)sd.Size, out sz))
|
||
Win32Error.ThrowLastError();
|
||
return sd;
|
||
}
|
||
|
||
/// <summary>
|
||
/// <para>Retrieves the name of the user associated with the current thread.</para>
|
||
/// <para>
|
||
/// Use the GetUserNameEx function to retrieve the user name in a specified format. Additional information is provided by the
|
||
/// IADsADSystemInfo interface.
|
||
/// </para>
|
||
/// </summary>
|
||
/// <param name="lpBuffer">
|
||
/// A pointer to the buffer to receive the user's logon name. If this buffer is not large enough to contain the entire user name, the
|
||
/// function fails. A buffer size of (UNLEN + 1) characters will hold the maximum length user name including the terminating null
|
||
/// character. UNLEN is defined in Lmcons.h.
|
||
/// </param>
|
||
/// <param name="pcbBuffer">
|
||
/// <para>
|
||
/// On input, this variable specifies the size of the lpBuffer buffer, in <c>TCHARs</c>. On output, the variable receives the number
|
||
/// of <c>TCHARs</c> copied to the buffer, including the terminating null character.
|
||
/// </para>
|
||
/// <para>
|
||
/// If lpBuffer is too small, the function fails and GetLastError returns ERROR_INSUFFICIENT_BUFFER. This parameter receives the
|
||
/// required buffer size, including the terminating null character.
|
||
/// </para>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// If the function succeeds, the return value is a nonzero value, and the variable pointed to by lpnSize contains the number of
|
||
/// <c>TCHARs</c> copied to the buffer specified by lpBuffer, including the terminating null character.
|
||
/// </para>
|
||
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// If the current thread is impersonating another client, the <c>GetUserName</c> function returns the user name of the client that
|
||
/// the thread is impersonating.
|
||
/// </para>
|
||
/// <para>
|
||
/// If <c>GetUserName</c> is called from a process that is running under the "NETWORK SERVICE" account, the string returned in
|
||
/// lpBuffer may be different depending on the version of Windows. On Windows XP, the "NETWORK SERVICE" string is returned. On
|
||
/// Windows Vista, the “<HOSTNAME>$” string is returned.
|
||
/// </para>
|
||
/// <para>Examples</para>
|
||
/// <para>For an example, see Getting System Information.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-getusernamea BOOL GetUserNameA( LPSTR lpBuffer, LPDWORD
|
||
// pcbBuffer );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "87adc46a-c069-4ee5-900a-03b646306e64")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool GetUserName(StringBuilder lpBuffer, ref uint pcbBuffer);
|
||
|
||
/// <summary>The <c>ImpersonateNamedPipeClient</c> function impersonates a named-pipe client application.</summary>
|
||
/// <param name="hNamedPipe">A handle to a named pipe.</param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is nonzero.</para>
|
||
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// The <c>ImpersonateNamedPipeClient</c> function allows the server end of a named pipe to impersonate the client end. When this
|
||
/// function is called, the named-pipe file system changes the thread of the calling process to start impersonating the security
|
||
/// context of the last message read from the pipe. Only the server end of the pipe can call this function.
|
||
/// </para>
|
||
/// <para>The server can call the RevertToSelf function when the impersonation is complete.</para>
|
||
/// <para>
|
||
/// <c>Important</c> If the <c>ImpersonateNamedPipeClient</c> function fails, the client is not impersonated, and all subsequent
|
||
/// client requests are made in the security context of the process that called the function. If the calling process is running as a
|
||
/// privileged account, it can perform actions that the client would not be allowed to perform. To avoid security risks, the calling
|
||
/// process should always check the return value. If the return value indicates that the function call failed, no client requests
|
||
/// should be executed.
|
||
/// </para>
|
||
/// <para>
|
||
/// All impersonate functions, including <c>ImpersonateNamedPipeClient</c> allow the requested impersonation if one of the following
|
||
/// is true:
|
||
/// </para>
|
||
/// <list type="bullet">
|
||
/// <item>
|
||
/// <term>
|
||
/// The requested impersonation level of the token is less than <c>SecurityImpersonation</c>, such as <c>SecurityIdentification</c>
|
||
/// or <c>SecurityAnonymous</c>.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The caller has the <c>SeImpersonatePrivilege</c> privilege.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>
|
||
/// A process (or another process in the caller's logon session) created the token using explicit credentials through LogonUser or
|
||
/// LsaLogonUser function.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The authenticated identity is same as the caller.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para><c>Windows XP with SP1 and earlier:</c> The <c>SeImpersonatePrivilege</c> privilege is not supported.</para>
|
||
/// <para>Examples</para>
|
||
/// <para>For an example that uses this function, see Verifying Client Access with ACLs.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient BOOL
|
||
// ImpersonateNamedPipeClient( HANDLE hNamedPipe );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("namedpipeapi.h", MSDNShortId = "63fc90ac-536a-4d9b-ba0d-19dc0cc09e6b")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool ImpersonateNamedPipeClient(HPIPE hNamedPipe);
|
||
|
||
/// <summary>Determines if a buffer is likely to contain a form of Unicode text.</summary>
|
||
/// <param name="lpv">Pointer to the input buffer to examine.</param>
|
||
/// <param name="iSize">Size, in bytes, of the input buffer indicated by lpv.</param>
|
||
/// <param name="lpiResult">
|
||
/// <para>
|
||
/// On input, pointer to the tests to apply to the input buffer text. On output, this parameter receives the results of the specified
|
||
/// tests: 1 if the contents of the buffer pass a test, 0 for failure. Only flags that are set upon input to the function are
|
||
/// significant upon output.
|
||
/// </para>
|
||
/// <para>
|
||
/// If lpiResult is <c>NULL</c>, the function uses all available tests to determine if the data in the buffer is likely to be Unicode text.
|
||
/// </para>
|
||
/// <para>This parameter can be one or more of the following values. Values can be combined with binary "OR".</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_ASCII16</term>
|
||
/// <term>The text is Unicode, and contains only zero-extended ASCII values/characters.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_REVERSE_ASCII16</term>
|
||
/// <term>Same as the preceding, except that the Unicode text is byte-reversed.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_STATISTICS</term>
|
||
/// <term>
|
||
/// The text is probably Unicode, with the determination made by applying statistical analysis. Absolute certainty is not guaranteed.
|
||
/// See the Remarks section.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_REVERSE_STATISTICS</term>
|
||
/// <term>Same as the preceding, except that the text that is probably Unicode is byte-reversed.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_CONTROLS</term>
|
||
/// <term>
|
||
/// The text contains Unicode representations of one or more of these nonprinting characters: RETURN, LINEFEED, SPACE, CJK_SPACE, TAB.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_REVERSE_CONTROLS</term>
|
||
/// <term>Same as the preceding, except that the Unicode characters are byte-reversed.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_BUFFER_TOO_SMALL</term>
|
||
/// <term>There are too few characters in the buffer for meaningful analysis (fewer than two bytes).</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_SIGNATURE</term>
|
||
/// <term>The text contains the Unicode byte-order mark (BOM) 0xFEFF as its first character.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_REVERSE_SIGNATURE</term>
|
||
/// <term>The text contains the Unicode byte-reversed byte-order mark (Reverse BOM) 0xFFFE as its first character.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_ILLEGAL_CHARS</term>
|
||
/// <term>
|
||
/// The text contains one of these Unicode-illegal characters: embedded Reverse BOM, UNICODE_NUL, CRLF (packed into one word), or 0xFFFF.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_ODD_LENGTH</term>
|
||
/// <term>The number of characters in the string is odd. A string of odd length cannot (by definition) be Unicode text.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_NULL_BYTES</term>
|
||
/// <term>The text contains null bytes, which indicate non-ASCII text.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_UNICODE_MASK</term>
|
||
/// <term>The value is a combination of IS_TEXT_UNICODE_ASCII16, IS_TEXT_UNICODE_STATISTICS, IS_TEXT_UNICODE_CONTROLS, IS_TEXT_UNICODE_SIGNATURE.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_REVERSE_MASK</term>
|
||
/// <term>
|
||
/// The value is a combination of IS_TEXT_UNICODE_REVERSE_ASCII16, IS_TEXT_UNICODE_REVERSE_STATISTICS,
|
||
/// IS_TEXT_UNICODE_REVERSE_CONTROLS, IS_TEXT_UNICODE_REVERSE_SIGNATURE.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_NOT_UNICODE_MASK</term>
|
||
/// <term>
|
||
/// The value is a combination of IS_TEXT_UNICODE_ILLEGAL_CHARS, IS_TEXT_UNICODE_ODD_LENGTH, and two currently unused bit flags.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_NOT_ASCII_MASK</term>
|
||
/// <term>The value is a combination of IS_TEXT_UNICODE_NULL_BYTES and three currently unused bit flags.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <returns>
|
||
/// Returns a nonzero value if the data in the buffer passes the specified tests. The function returns 0 if the data in the buffer
|
||
/// does not pass the specified tests.
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// This function uses various statistical and deterministic methods to make its determination, under the control of flags passed in
|
||
/// the lpiResult parameter. When the function returns, the results of such tests are reported using the same parameter.
|
||
/// </para>
|
||
/// <para>
|
||
/// The IS_TEXT_UNICODE_STATISTICS and IS_TEXT_UNICODE_REVERSE_STATISTICS tests use statistical analysis. These tests are not
|
||
/// foolproof. The statistical tests assume certain amounts of variation between low and high bytes in a string, and some ASCII
|
||
/// strings can slip through. For example, if lpv indicates the ASCII string 0x41, 0x0A, 0x0D, 0x1D (A\n\r^Z), the string passes the
|
||
/// IS_TEXT_UNICODE_STATISTICS test, although failure would be preferable.
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-istextunicode BOOL IsTextUnicode( const VOID *lpv, int
|
||
// iSize, LPINT lpiResult );
|
||
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "47e05b5b-a16b-4957-bc86-ed3cef4968ee")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool IsTextUnicode(byte[] lpv, int iSize, ref IS_TEXT_UNICODE lpiResult);
|
||
|
||
/// <summary>Determines if a buffer is likely to contain a form of Unicode text.</summary>
|
||
/// <param name="lpv">Pointer to the input buffer to examine.</param>
|
||
/// <param name="iSize">Size, in bytes, of the input buffer indicated by lpv.</param>
|
||
/// <param name="lpiResult">
|
||
/// <para>
|
||
/// On input, pointer to the tests to apply to the input buffer text. On output, this parameter receives the results of the specified
|
||
/// tests: 1 if the contents of the buffer pass a test, 0 for failure. Only flags that are set upon input to the function are
|
||
/// significant upon output.
|
||
/// </para>
|
||
/// <para>
|
||
/// If lpiResult is <c>NULL</c>, the function uses all available tests to determine if the data in the buffer is likely to be Unicode text.
|
||
/// </para>
|
||
/// <para>This parameter can be one or more of the following values. Values can be combined with binary "OR".</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_ASCII16</term>
|
||
/// <term>The text is Unicode, and contains only zero-extended ASCII values/characters.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_REVERSE_ASCII16</term>
|
||
/// <term>Same as the preceding, except that the Unicode text is byte-reversed.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_STATISTICS</term>
|
||
/// <term>
|
||
/// The text is probably Unicode, with the determination made by applying statistical analysis. Absolute certainty is not guaranteed.
|
||
/// See the Remarks section.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_REVERSE_STATISTICS</term>
|
||
/// <term>Same as the preceding, except that the text that is probably Unicode is byte-reversed.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_CONTROLS</term>
|
||
/// <term>
|
||
/// The text contains Unicode representations of one or more of these nonprinting characters: RETURN, LINEFEED, SPACE, CJK_SPACE, TAB.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_REVERSE_CONTROLS</term>
|
||
/// <term>Same as the preceding, except that the Unicode characters are byte-reversed.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_BUFFER_TOO_SMALL</term>
|
||
/// <term>There are too few characters in the buffer for meaningful analysis (fewer than two bytes).</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_SIGNATURE</term>
|
||
/// <term>The text contains the Unicode byte-order mark (BOM) 0xFEFF as its first character.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_REVERSE_SIGNATURE</term>
|
||
/// <term>The text contains the Unicode byte-reversed byte-order mark (Reverse BOM) 0xFFFE as its first character.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_ILLEGAL_CHARS</term>
|
||
/// <term>
|
||
/// The text contains one of these Unicode-illegal characters: embedded Reverse BOM, UNICODE_NUL, CRLF (packed into one word), or 0xFFFF.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_ODD_LENGTH</term>
|
||
/// <term>The number of characters in the string is odd. A string of odd length cannot (by definition) be Unicode text.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_NULL_BYTES</term>
|
||
/// <term>The text contains null bytes, which indicate non-ASCII text.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_UNICODE_MASK</term>
|
||
/// <term>The value is a combination of IS_TEXT_UNICODE_ASCII16, IS_TEXT_UNICODE_STATISTICS, IS_TEXT_UNICODE_CONTROLS, IS_TEXT_UNICODE_SIGNATURE.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_REVERSE_MASK</term>
|
||
/// <term>
|
||
/// The value is a combination of IS_TEXT_UNICODE_REVERSE_ASCII16, IS_TEXT_UNICODE_REVERSE_STATISTICS,
|
||
/// IS_TEXT_UNICODE_REVERSE_CONTROLS, IS_TEXT_UNICODE_REVERSE_SIGNATURE.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_NOT_UNICODE_MASK</term>
|
||
/// <term>
|
||
/// The value is a combination of IS_TEXT_UNICODE_ILLEGAL_CHARS, IS_TEXT_UNICODE_ODD_LENGTH, and two currently unused bit flags.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>IS_TEXT_UNICODE_NOT_ASCII_MASK</term>
|
||
/// <term>The value is a combination of IS_TEXT_UNICODE_NULL_BYTES and three currently unused bit flags.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <returns>
|
||
/// Returns a nonzero value if the data in the buffer passes the specified tests. The function returns 0 if the data in the buffer
|
||
/// does not pass the specified tests.
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// This function uses various statistical and deterministic methods to make its determination, under the control of flags passed in
|
||
/// the lpiResult parameter. When the function returns, the results of such tests are reported using the same parameter.
|
||
/// </para>
|
||
/// <para>
|
||
/// The IS_TEXT_UNICODE_STATISTICS and IS_TEXT_UNICODE_REVERSE_STATISTICS tests use statistical analysis. These tests are not
|
||
/// foolproof. The statistical tests assume certain amounts of variation between low and high bytes in a string, and some ASCII
|
||
/// strings can slip through. For example, if lpv indicates the ASCII string 0x41, 0x0A, 0x0D, 0x1D (A\n\r^Z), the string passes the
|
||
/// IS_TEXT_UNICODE_STATISTICS test, although failure would be preferable.
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-istextunicode BOOL IsTextUnicode( const VOID *lpv, int
|
||
// iSize, LPINT lpiResult );
|
||
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "47e05b5b-a16b-4957-bc86-ed3cef4968ee")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool IsTextUnicode(IntPtr lpv, int iSize, ref IS_TEXT_UNICODE lpiResult);
|
||
|
||
/// <summary>
|
||
/// The LogonUser function attempts to log a user on to the local computer. The local computer is the computer from which LogonUser
|
||
/// was called. You cannot use LogonUser to log on to a remote computer. You specify the user with a user name and domain and
|
||
/// authenticate the user with a plain-text password. If the function succeeds, you receive a handle to a token that represents the
|
||
/// logged-on user. You can then use this token handle to impersonate the specified user or, in most cases, to create a process that
|
||
/// runs in the context of the specified user.
|
||
/// </summary>
|
||
/// <param name="lpszUserName">
|
||
/// A pointer to a null-terminated string that specifies the name of the user. This is the name of the user account to log on to. If
|
||
/// you use the user principal name (UPN) format, User@DNSDomainName, the lpszDomain parameter must be NULL.
|
||
/// </param>
|
||
/// <param name="lpszDomain">
|
||
/// A pointer to a null-terminated string that specifies the name of the domain or server whose account database contains the
|
||
/// lpszUsername account. If this parameter is NULL, the user name must be specified in UPN format. If this parameter is ".", the
|
||
/// function validates the account by using only the local account database.
|
||
/// </param>
|
||
/// <param name="lpszPassword">
|
||
/// A pointer to a null-terminated string that specifies the plain-text password for the user account specified by lpszUsername. When
|
||
/// you have finished using the password, clear the password from memory by calling the SecureZeroMemory function. For more
|
||
/// information about protecting passwords, see Handling Passwords.
|
||
/// </param>
|
||
/// <param name="dwLogonType">The type of logon operation to perform.</param>
|
||
/// <param name="dwLogonProvider">Specifies the logon provider.</param>
|
||
/// <param name="phObject">
|
||
/// A pointer to a handle variable that receives a handle to a token that represents the specified user.
|
||
/// <para>You can use the returned handle in calls to the ImpersonateLoggedOnUser function.</para>
|
||
/// <para>
|
||
/// In most cases, the returned handle is a primary token that you can use in calls to the CreateProcessAsUser function. However, if
|
||
/// you specify the LOGON32_LOGON_NETWORK flag, LogonUser returns an impersonation token that you cannot use in CreateProcessAsUser
|
||
/// unless you call DuplicateTokenEx to convert it to a primary token.
|
||
/// </para>
|
||
/// <para>When you no longer need this handle, close it by calling the CloseHandle function.</para>
|
||
/// </param>
|
||
/// <returns>
|
||
/// 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.
|
||
/// </returns>
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false, ThrowOnUnmappableChar = true)]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "aa378184")]
|
||
public static extern bool LogonUser(string lpszUserName, [Optional] string lpszDomain, [Optional] string lpszPassword, LogonUserType dwLogonType, LogonUserProvider dwLogonProvider,
|
||
out SafeHTOKEN phObject);
|
||
|
||
/// <summary>
|
||
/// The LogonUserEx function attempts to log a user on to the local computer. The local computer is the computer from which
|
||
/// LogonUserEx was called. You cannot use LogonUserEx to log on to a remote computer. You specify the user with a user name and
|
||
/// domain and authenticate the user with a plaintext password. If the function succeeds, you receive a handle to a token that
|
||
/// represents the logged-on user. You can then use this token handle to impersonate the specified user or, in most cases, to create
|
||
/// a process that runs in the context of the specified user.
|
||
/// </summary>
|
||
/// <param name="lpszUserName">
|
||
/// A pointer to a null-terminated string that specifies the name of the user. This is the name of the user account to log on to. If
|
||
/// you use the user principal name (UPN) format, user@DNS_domain_name, the lpszDomain parameter must be NULL.
|
||
/// </param>
|
||
/// <param name="lpszDomain">
|
||
/// A pointer to a null-terminated string that specifies the name of the domain or server whose account database contains the
|
||
/// lpszUsername account. If this parameter is NULL, the user name must be specified in UPN format. If this parameter is ".", the
|
||
/// function validates the account by using only the local account database.
|
||
/// </param>
|
||
/// <param name="lpszPassword">
|
||
/// A pointer to a null-terminated string that specifies the plaintext password for the user account specified by lpszUsername. When
|
||
/// you have finished using the password, clear the password from memory by calling the SecureZeroMemory function. For more
|
||
/// information about protecting passwords, see Handling Passwords.
|
||
/// </param>
|
||
/// <param name="dwLogonType">The type of logon operation to perform.</param>
|
||
/// <param name="dwLogonProvider">The logon provider.</param>
|
||
/// <param name="phObject">
|
||
/// A pointer to a handle variable that receives a handle to a token that represents the specified user.
|
||
/// <para>You can use the returned handle in calls to the ImpersonateLoggedOnUser function.</para>
|
||
/// <para>
|
||
/// In most cases, the returned handle is a primary token that you can use in calls to the CreateProcessAsUser function. However, if
|
||
/// you specify the LOGON32_LOGON_NETWORK flag, LogonUser returns an impersonation token that you cannot use in CreateProcessAsUser
|
||
/// unless you call DuplicateTokenEx to convert it to a primary token.
|
||
/// </para>
|
||
/// <para>When you no longer need this handle, close it by calling the CloseHandle function.</para>
|
||
/// </param>
|
||
/// <param name="ppLogonSid">
|
||
/// A pointer to a pointer to a security identifier (SID) that receives the SID of the user logged on.
|
||
/// <para>When you have finished using the SID, free it by calling the LocalFree function.</para>
|
||
/// </param>
|
||
/// <param name="ppProfileBuffer">
|
||
/// A pointer to a pointer that receives the address of a buffer that contains the logged on user's profile.
|
||
/// </param>
|
||
/// <param name="pdwProfileLength">A pointer to a DWORD that receives the length of the profile buffer.</param>
|
||
/// <param name="pQuotaLimits">
|
||
/// A pointer to a QUOTA_LIMITS structure that receives information about the quotas for the logged on user.
|
||
/// </param>
|
||
/// <returns>
|
||
/// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error
|
||
/// information, call GetLastError.
|
||
/// </returns>
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false, ThrowOnUnmappableChar = true)]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "aa378189")]
|
||
public static extern bool LogonUserEx(string lpszUserName, [Optional] string lpszDomain, [Optional] string lpszPassword, LogonUserType dwLogonType, LogonUserProvider dwLogonProvider,
|
||
out SafeHTOKEN phObject, out SafePSID ppLogonSid, out SafeLsaReturnBufferHandle ppProfileBuffer, out uint pdwProfileLength, out QUOTA_LIMITS pQuotaLimits);
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// The <c>LogonUserExExW</c> function attempts to log a user on to the local computer. The local computer is the computer from which
|
||
/// <c>LogonUserExExW</c> was called. You cannot use <c>LogonUserExExW</c> to log on to a remote computer. Specify the user by using
|
||
/// a user name and domain and authenticate the user by using a plaintext password. If the function succeeds, it receives a handle to
|
||
/// a token that represents the logged-on user. You can then use this token handle to impersonate the specified user or, in most
|
||
/// cases, to create a process that runs in the context of the specified user.
|
||
/// </para>
|
||
/// <para>
|
||
/// This function is similar to the <c>LogonUserEx</c> function, except that it takes the additional parameter, pTokenGroups, which
|
||
/// is a set of one or more security identifiers (SIDs) that are added to the token returned to the caller when the logon is successful.
|
||
/// </para>
|
||
/// <para>
|
||
/// This function is not declared in a public header and has no associated import library. You must use the <c>LoadLibrary</c> and
|
||
/// <c>GetProcAddress</c> functions to dynamically link to Advapi32.dll.
|
||
/// </para>
|
||
/// </summary>
|
||
/// <param name="lpszUserName">
|
||
/// A pointer to a null-terminated string that specifies the name of the user. This is the name of the user account to log on to. If
|
||
/// you use the user principal name (UPN) format, user@DNS_domain_name, the lpszDomain parameter must be NULL.
|
||
/// </param>
|
||
/// <param name="lpszDomain">
|
||
/// A pointer to a null-terminated string that specifies the name of the domain or server whose account database contains the
|
||
/// lpszUsername account. If this parameter is NULL, the user name must be specified in UPN format. If this parameter is ".", the
|
||
/// function validates the account by using only the local account database.
|
||
/// </param>
|
||
/// <param name="lpszPassword">
|
||
/// A pointer to a null-terminated string that specifies the plaintext password for the user account specified by lpszUsername. When
|
||
/// you have finished using the password, clear the password from memory by calling the SecureZeroMemory function. For more
|
||
/// information about protecting passwords, see Handling Passwords.
|
||
/// </param>
|
||
/// <param name="dwLogonType">The type of logon operation to perform.</param>
|
||
/// <param name="dwLogonProvider">The logon provider.</param>
|
||
/// <param name="pTokenGroups">
|
||
/// A pointer to a TOKEN_GROUPS structure that specifies a list of group SIDs that are added to the token that this function receives
|
||
/// upon successful logon. Any SIDs added to the token also effect group expansion. For example, if the added SIDs are members of
|
||
/// local groups, those groups are also added to the received access token.
|
||
/// <para>If this parameter is not NULL, the caller of this function must have the SE_TCB_PRIVILEGE privilege granted and enabled.</para>
|
||
/// </param>
|
||
/// <param name="phToken">
|
||
/// A pointer to a handle variable that receives a handle to a token that represents the specified user.
|
||
/// <para>You can use the returned handle in calls to the ImpersonateLoggedOnUser function.</para>
|
||
/// <para>
|
||
/// In most cases, the returned handle is a primary token that you can use in calls to the CreateProcessAsUser function.However, if
|
||
/// you specify the LOGON32_LOGON_NETWORK flag, LogonUserExExW returns an impersonation token that you cannot use in
|
||
/// CreateProcessAsUser unless you call DuplicateTokenEx to convert the impersonation token to a primary token.
|
||
/// </para>
|
||
/// <para>When you no longer need this handle, close it by calling the CloseHandle function.</para>
|
||
/// </param>
|
||
/// <param name="ppLogonSid">
|
||
/// A pointer to a pointer to a SID that receives the SID of the user logged on.
|
||
/// <para>When you have finished using the SID, free it by calling the LocalFree function.</para>
|
||
/// </param>
|
||
/// <param name="ppProfileBuffer">
|
||
/// A pointer to a pointer that receives the address of a buffer that contains the logged on user's profile.
|
||
/// </param>
|
||
/// <param name="pdwProfileLength">A pointer to a DWORD that receives the length of the profile buffer.</param>
|
||
/// <param name="pQuotaLimits">
|
||
/// A pointer to a QUOTA_LIMITS structure that receives information about the quotas for the logged on user.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the function returns nonzero.</para>
|
||
/// <para>If the function fails, it returns zero. To get extended error information, call <c>GetLastError</c>.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>The <c>LOGON32_LOGON_NETWORK</c> logon type is fastest, but it has the following limitations:</para>
|
||
/// <list type="bullet">
|
||
/// <item>
|
||
/// <term>
|
||
/// The function returns an impersonation token, not a primary token. You cannot use this token directly in the
|
||
/// <c>CreateProcessAsUser</c> function. However, you can call the <c>DuplicateTokenEx</c> function to convert the token to a primary
|
||
/// token, and then use it in <c>CreateProcessAsUser</c>.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>
|
||
/// If you convert the token to a primary token and use it in <c>CreateProcessAsUser</c> to start a process, the new process cannot
|
||
/// access other network resources, such as remote servers or printers, through the redirector. An exception is that if the network
|
||
/// resource is not access controlled, then the new process will be able to access it.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>
|
||
/// The account specified by lpszUsername must have the necessary account rights. For example, to log on a user with the
|
||
/// <c>LOGON32_LOGON_INTERACTIVE</c> flag, the user (or a group to which the user belongs) must have the
|
||
/// <c>SE_INTERACTIVE_LOGON_NAME</c> account right. For a list of the account rights that affect the various logon operations, see
|
||
/// Account Object Access Rights.
|
||
/// </para>
|
||
/// <para>
|
||
/// A user is considered logged on if at least one token exists. If you call <c>CreateProcessAsUser</c> and then close the token, the
|
||
/// user is still logged on until the process (and all child processes) have ended.
|
||
/// </para>
|
||
/// <para>If the optional pTokenGroups parameter is supplied, LSA will not add either the local SID or the logon SID automatically.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/logonuserexexw BOOL WINAPI LogonUserExExW( _In_ LPTSTR lpszUsername,
|
||
// _In_opt_ LPTSTR lpszDomain, _In_opt_ LPTSTR lpszPassword, _In_ DWORD dwLogonType, _In_ DWORD dwLogonProvider, _In_opt_
|
||
// PTOKEN_GROUPS pTokenGroups, _Out_opt_ PHANDLE phToken, _Out_opt_ PSID *ppLogonSid, _Out_opt_ PVOID *ppProfileBuffer, _Out_opt_
|
||
// LPDWORD pdwProfileLength, _Out_opt_ PQUOTA_LIMITS pQuotaLimits );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
|
||
[PInvokeData("", MSDNShortId = "d90db4c6-a711-4519-8b91-5069cee07738")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool LogonUserExExW(string lpszUserName, [Optional] string lpszDomain, [Optional] string lpszPassword, LogonUserType dwLogonType, LogonUserProvider dwLogonProvider,
|
||
[In, Optional] in TOKEN_GROUPS pTokenGroups, out SafeHTOKEN phToken, out SafePSID ppLogonSid, out SafeLsaReturnBufferHandle ppProfileBuffer, out uint pdwProfileLength, out QUOTA_LIMITS pQuotaLimits);
|
||
|
||
/// <summary>
|
||
/// The LookupAccountName function accepts the name of a system and an account as input. It retrieves a security identifier (SID) for
|
||
/// the account and the name of the domain on which the account was found.
|
||
/// </summary>
|
||
/// <param name="lpSystemName">
|
||
/// A pointer to a null-terminated character string that specifies the name of the system. This string can be the name of a remote
|
||
/// computer. If this string is NULL, the account name translation begins on the local system. If the name cannot be resolved on the
|
||
/// local system, this function will try to resolve the name using domain controllers trusted by the local system. Generally, specify
|
||
/// a value for lpSystemName only when the account is in an untrusted domain and the name of a computer in that domain is known.
|
||
/// </param>
|
||
/// <param name="lpAccountName">
|
||
/// A pointer to a null-terminated string that specifies the account name.
|
||
/// <para>
|
||
/// Use a fully qualified string in the domain_name\user_name format to ensure that LookupAccountName finds the account in the
|
||
/// desired domain.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="Sid">
|
||
/// A pointer to a buffer that receives the SID structure that corresponds to the account name pointed to by the lpAccountName
|
||
/// parameter. If this parameter is NULL, cbSid must be zero.
|
||
/// </param>
|
||
/// <param name="cbSid">
|
||
/// A pointer to a variable. On input, this value specifies the size, in bytes, of the Sid buffer. If the function fails because the
|
||
/// buffer is too small or if cbSid is zero, this variable receives the required buffer size.
|
||
/// </param>
|
||
/// <param name="ReferencedDomainName">
|
||
/// A pointer to a buffer that receives the name of the domain where the account name is found. For computers that are not joined to
|
||
/// a domain, this buffer receives the computer name. If this parameter is NULL, the function returns the required buffer size.
|
||
/// </param>
|
||
/// <param name="cchReferencedDomainName">
|
||
/// A pointer to a variable. On input, this value specifies the size, in TCHARs, of the ReferencedDomainName buffer. If the function
|
||
/// fails because the buffer is too small, this variable receives the required buffer size, including the terminating null character.
|
||
/// If the ReferencedDomainName parameter is NULL, this parameter must be zero.
|
||
/// </param>
|
||
/// <param name="peUse">A pointer to a SID_NAME_USE enumerated type that indicates the type of the account when the function returns.</param>
|
||
/// <returns>
|
||
/// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. For extended error information,
|
||
/// call GetLastError.
|
||
/// </returns>
|
||
[DllImport(Lib.AdvApi32, CharSet = CharSet.Auto, SetLastError = true)]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "aa379159")]
|
||
public static extern bool LookupAccountName([Optional] string lpSystemName, string lpAccountName, SafePSID Sid, ref int cbSid,
|
||
StringBuilder ReferencedDomainName, ref int cchReferencedDomainName, out SID_NAME_USE peUse);
|
||
|
||
/// <summary>
|
||
/// The LookupAccountName function accepts the name of a system and an account as input. It retrieves a security identifier (SID) for
|
||
/// the account and the name of the domain on which the account was found.
|
||
/// </summary>
|
||
/// <param name="systemName">
|
||
/// A string that specifies the name of the system. This string can be the name of a remote computer. If this string is NULL, the
|
||
/// account name translation begins on the local system. If the name cannot be resolved on the local system, this function will try
|
||
/// to resolve the name using domain controllers trusted by the local system. Generally, specify a value for lpSystemName only when
|
||
/// the account is in an untrusted domain and the name of a computer in that domain is known.
|
||
/// </param>
|
||
/// <param name="accountName">
|
||
/// A string that specifies the account name.
|
||
/// <para>
|
||
/// Use a fully qualified string in the domain_name\user_name format to ensure that LookupAccountName finds the account in the
|
||
/// desired domain.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="sid">A PSID class that corresponds to the account name pointed to by the lpAccountName parameter.</param>
|
||
/// <param name="domainName">
|
||
/// A string that receives the name of the domain where the account name is found. For computers that are not joined to a domain,
|
||
/// this buffer receives the computer name.
|
||
/// </param>
|
||
/// <param name="snu">A SID_NAME_USE enumerated type that indicates the type of the account when the function returns.</param>
|
||
/// <returns>
|
||
/// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. For extended error information,
|
||
/// call GetLastError.
|
||
/// </returns>
|
||
[PInvokeData("winbase.h", MSDNShortId = "aa379159")]
|
||
public static bool LookupAccountName([Optional] string systemName, string accountName, out SafePSID sid, out string domainName, out SID_NAME_USE snu)
|
||
{
|
||
var sb = new StringBuilder(1024);
|
||
sid = new SafePSID(256);
|
||
int sidSz = sid.Size;
|
||
var sbSz = sb.Capacity;
|
||
var ret = LookupAccountName(systemName, accountName, sid, ref sidSz, sb, ref sbSz, out snu);
|
||
domainName = sb.ToString();
|
||
return ret;
|
||
}
|
||
|
||
/// <summary>
|
||
/// The LookupAccountSid function accepts a security identifier (SID) as input. It retrieves the name of the account for this SID and
|
||
/// the name of the first domain on which this SID is found.
|
||
/// </summary>
|
||
/// <param name="lpSystemName">
|
||
/// A pointer to a null-terminated character string that specifies the target computer. This string can be the name of a remote
|
||
/// computer. If this parameter is NULL, the account name translation begins on the local system. If the name cannot be resolved on
|
||
/// the local system, this function will try to resolve the name using domain controllers trusted by the local system. Generally,
|
||
/// specify a value for lpSystemName only when the account is in an untrusted domain and the name of a computer in that domain is known.
|
||
/// </param>
|
||
/// <param name="lpSid">A pointer to the SID to look up.</param>
|
||
/// <param name="lpName">
|
||
/// A pointer to a buffer that receives a null-terminated string that contains the account name that corresponds to the lpSid parameter.
|
||
/// </param>
|
||
/// <param name="cchName">
|
||
/// On input, specifies the size, in TCHARs, of the lpName buffer. If the function fails because the buffer is too small or if
|
||
/// cchName is zero, cchName receives the required buffer size, including the terminating null character.
|
||
/// </param>
|
||
/// <param name="lpReferencedDomainName">
|
||
/// A pointer to a buffer that receives a null-terminated string that contains the name of the domain where the account name was found.
|
||
/// <para>
|
||
/// On a server, the domain name returned for most accounts in the security database of the local computer is the name of the domain
|
||
/// for which the server is a domain controller.
|
||
/// </para>
|
||
/// <para>
|
||
/// On a workstation, the domain name returned for most accounts in the security database of the local computer is the name of the
|
||
/// computer as of the last start of the system (backslashes are excluded). If the name of the computer changes, the old name
|
||
/// continues to be returned as the domain name until the system is restarted.
|
||
/// </para>
|
||
/// <para>Some accounts are predefined by the system. The domain name returned for these accounts is BUILTIN.</para>
|
||
/// </param>
|
||
/// <param name="cchReferencedDomainName">
|
||
/// On input, specifies the size, in TCHARs, of the lpReferencedDomainName buffer. If the function fails because the buffer is too
|
||
/// small or if cchReferencedDomainName is zero, cchReferencedDomainName receives the required buffer size, including the terminating
|
||
/// null character.
|
||
/// </param>
|
||
/// <param name="peUse">A pointer to a variable that receives a SID_NAME_USE value that indicates the type of the account.</param>
|
||
/// <returns>
|
||
/// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error
|
||
/// information, call GetLastError.
|
||
/// </returns>
|
||
[DllImport(Lib.AdvApi32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "aa379166")]
|
||
public static extern bool LookupAccountSid([Optional] string lpSystemName, byte[] lpSid, StringBuilder lpName, ref int cchName,
|
||
StringBuilder lpReferencedDomainName, ref int cchReferencedDomainName, out SID_NAME_USE peUse);
|
||
|
||
/// <summary>
|
||
/// The LookupAccountSid function accepts a security identifier (SID) as input. It retrieves the name of the account for this SID and
|
||
/// the name of the first domain on which this SID is found.
|
||
/// </summary>
|
||
/// <param name="lpSystemName">
|
||
/// A pointer to a null-terminated character string that specifies the target computer. This string can be the name of a remote
|
||
/// computer. If this parameter is NULL, the account name translation begins on the local system. If the name cannot be resolved on
|
||
/// the local system, this function will try to resolve the name using domain controllers trusted by the local system. Generally,
|
||
/// specify a value for lpSystemName only when the account is in an untrusted domain and the name of a computer in that domain is known.
|
||
/// </param>
|
||
/// <param name="lpSid">A pointer to the SID to look up.</param>
|
||
/// <param name="lpName">
|
||
/// A pointer to a buffer that receives a null-terminated string that contains the account name that corresponds to the lpSid parameter.
|
||
/// </param>
|
||
/// <param name="cchName">
|
||
/// On input, specifies the size, in TCHARs, of the lpName buffer. If the function fails because the buffer is too small or if
|
||
/// cchName is zero, cchName receives the required buffer size, including the terminating null character.
|
||
/// </param>
|
||
/// <param name="lpReferencedDomainName">
|
||
/// A pointer to a buffer that receives a null-terminated string that contains the name of the domain where the account name was found.
|
||
/// <para>
|
||
/// On a server, the domain name returned for most accounts in the security database of the local computer is the name of the domain
|
||
/// for which the server is a domain controller.
|
||
/// </para>
|
||
/// <para>
|
||
/// On a workstation, the domain name returned for most accounts in the security database of the local computer is the name of the
|
||
/// computer as of the last start of the system (backslashes are excluded). If the name of the computer changes, the old name
|
||
/// continues to be returned as the domain name until the system is restarted.
|
||
/// </para>
|
||
/// <para>Some accounts are predefined by the system. The domain name returned for these accounts is BUILTIN.</para>
|
||
/// </param>
|
||
/// <param name="cchReferencedDomainName">
|
||
/// On input, specifies the size, in TCHARs, of the lpReferencedDomainName buffer. If the function fails because the buffer is too
|
||
/// small or if cchReferencedDomainName is zero, cchReferencedDomainName receives the required buffer size, including the terminating
|
||
/// null character.
|
||
/// </param>
|
||
/// <param name="peUse">A pointer to a variable that receives a SID_NAME_USE value that indicates the type of the account.</param>
|
||
/// <returns>
|
||
/// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error
|
||
/// information, call GetLastError.
|
||
/// </returns>
|
||
[DllImport(Lib.AdvApi32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "aa379166")]
|
||
public static extern bool LookupAccountSid([Optional] string lpSystemName, PSID lpSid, StringBuilder lpName, ref int cchName,
|
||
StringBuilder lpReferencedDomainName, ref int cchReferencedDomainName, out SID_NAME_USE peUse);
|
||
|
||
/// <summary>
|
||
/// <para>The <c>LookupPrivilegeDisplayName</c> function retrieves the display name that represents a specified privilege.</para>
|
||
/// </summary>
|
||
/// <param name="lpSystemName">
|
||
/// <para>
|
||
/// A pointer to a null-terminated string that specifies the name of the system on which the privilege name is retrieved. If a null
|
||
/// string is specified, the function attempts to find the display name on the local system.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpName">
|
||
/// <para>
|
||
/// A pointer to a null-terminated string that specifies the name of the privilege, as defined in Winnt.h. For example, this
|
||
/// parameter could specify the constant, SE_REMOTE_SHUTDOWN_NAME, or its corresponding string, "SeRemoteShutdownPrivilege". For a
|
||
/// list of values, see Privilege Constants.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpDisplayName">
|
||
/// <para>
|
||
/// A pointer to a buffer that receives a null-terminated string that specifies the privilege display name. For example, if the
|
||
/// lpName parameter is SE_REMOTE_SHUTDOWN_NAME, the privilege display name is "Force shutdown from a remote system."
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="cchDisplayName">
|
||
/// <para>
|
||
/// A pointer to a variable that specifies the size, in <c>TCHAR</c> s, of the lpDisplayName buffer. When the function returns, this
|
||
/// parameter contains the length of the privilege display name, not including the terminating null character. If the buffer pointed
|
||
/// to by the lpDisplayName parameter is too small, this variable contains the required size.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpLanguageId">
|
||
/// <para>A pointer to a variable that receives the language identifier for the returned display name.</para>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is nonzero.</para>
|
||
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// The <c>LookupPrivilegeDisplayName</c> function retrieves display names only for the privileges specified in the Defined
|
||
/// Privileges section of Winnt.h.
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-lookupprivilegedisplaynamea BOOL
|
||
// LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName, LPDWORD cchDisplayName, LPDWORD lpLanguageId );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "1fbb26b6-615e-4883-9f4b-3a1d05d9feaa")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool LookupPrivilegeDisplayName([Optional] string lpSystemName, string lpName, StringBuilder lpDisplayName, ref uint cchDisplayName, out uint lpLanguageId);
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// The <c>LookupPrivilegeName</c> function retrieves the name that corresponds to the privilege represented on a specific system by
|
||
/// a specified locally unique identifier (LUID).
|
||
/// </para>
|
||
/// </summary>
|
||
/// <param name="lpSystemName">
|
||
/// <para>
|
||
/// A pointer to a null-terminated string that specifies the name of the system on which the privilege name is retrieved. If a null
|
||
/// string is specified, the function attempts to find the privilege name on the local system.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpLuid">
|
||
/// <para>A pointer to the LUID by which the privilege is known on the target system.</para>
|
||
/// </param>
|
||
/// <param name="lpName">
|
||
/// <para>
|
||
/// A pointer to a buffer that receives a null-terminated string that represents the privilege name. For example, this string could
|
||
/// be "SeSecurityPrivilege".
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="cchName">
|
||
/// <para>
|
||
/// A pointer to a variable that specifies the size, in a <c>TCHAR</c> value, of the lpName buffer. When the function returns, this
|
||
/// parameter contains the length of the privilege name, not including the terminating null character. If the buffer pointed to by
|
||
/// the lpName parameter is too small, this variable contains the required size.
|
||
/// </para>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the function returns nonzero.</para>
|
||
/// <para>If the function fails, it returns zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// The <c>LookupPrivilegeName</c> function supports only the privileges specified in the Defined Privileges section of Winnt.h. For
|
||
/// a list of values, see Privilege Constants.
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-lookupprivilegenamea BOOL LookupPrivilegeNameA( LPCSTR
|
||
// lpSystemName, PLUID lpLuid, LPSTR lpName, LPDWORD cchName );
|
||
[DllImport(Lib.AdvApi32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "580fb58f-1470-4389-9f07-8f37403e2bdf")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool LookupPrivilegeName([Optional] string lpSystemName, in LUID lpLuid, StringBuilder lpName, ref uint cchName);
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// The <c>LookupPrivilegeValue</c> function retrieves the locally unique identifier (LUID) used on a specified system to locally
|
||
/// represent the specified privilege name.
|
||
/// </para>
|
||
/// </summary>
|
||
/// <param name="lpSystemName">
|
||
/// <para>
|
||
/// A pointer to a null-terminated string that specifies the name of the system on which the privilege name is retrieved. If a null
|
||
/// string is specified, the function attempts to find the privilege name on the local system.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpName">
|
||
/// <para>
|
||
/// A pointer to a null-terminated string that specifies the name of the privilege, as defined in the Winnt.h header file. For
|
||
/// example, this parameter could specify the constant, SE_SECURITY_NAME, or its corresponding string, "SeSecurityPrivilege".
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpLuid">
|
||
/// <para>
|
||
/// A pointer to a variable that receives the LUID by which the privilege is known on the system specified by the lpSystemName parameter.
|
||
/// </para>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the function returns nonzero.</para>
|
||
/// <para>If the function fails, it returns zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// The <c>LookupPrivilegeValue</c> function supports only the privileges specified in the Defined Privileges section of Winnt.h. For
|
||
/// a list of values, see Privilege Constants.
|
||
/// </para>
|
||
/// <para>Examples</para>
|
||
/// <para>For an example that uses this function, see Enabling and Disabling Privileges.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-lookupprivilegevaluea BOOL LookupPrivilegeValueA( LPCSTR
|
||
// lpSystemName, LPCSTR lpName, PLUID lpLuid );
|
||
[DllImport(Lib.AdvApi32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "334b8ba8-101d-43a1-a8bf-1c7e0448c272")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool LookupPrivilegeValue([Optional] string lpSystemName, string lpName, out LUID lpLuid);
|
||
|
||
/// <summary>
|
||
/// The <c>ObjectCloseAuditAlarm</c> function generates an audit message in the security event log when a handle to a private object
|
||
/// is deleted. Alarms are not currently supported.
|
||
/// </summary>
|
||
/// <param name="SubsystemName">
|
||
/// A pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit
|
||
/// message that the function generates.
|
||
/// </param>
|
||
/// <param name="HandleId">
|
||
/// A unique value representing the client's handle to the object. This should be the same value that was passed to the
|
||
/// AccessCheckAndAuditAlarm or ObjectOpenAuditAlarm function.
|
||
/// </param>
|
||
/// <param name="GenerateOnClose">
|
||
/// Specifies a flag set by a call to the AccessCheckAndAuditAlarm or <c>ObjectCloseAuditAlarm</c> function when the object handle is
|
||
/// created. If this flag is <c>TRUE</c>, the function generates an audit message. If it is <c>FALSE</c>, the function does not
|
||
/// generate an audit message.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is nonzero.</para>
|
||
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// The <c>ObjectCloseAuditAlarm</c> function requires the calling application to have the SE_AUDIT_NAME privilege enabled. The test
|
||
/// for this privilege is always performed against the primary token of the calling process, allowing the calling process to
|
||
/// impersonate a client.
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-objectcloseauditalarma BOOL ObjectCloseAuditAlarmA( LPCSTR
|
||
// SubsystemName, LPVOID HandleId, BOOL GenerateOnClose );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "274f3a62-1833-402b-b362-f526b2bee14b")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool ObjectCloseAuditAlarm(string SubsystemName, IntPtr HandleId, [MarshalAs(UnmanagedType.Bool)] bool GenerateOnClose);
|
||
|
||
/// <summary>
|
||
/// The <c>ObjectOpenAuditAlarm</c> function generates audit messages when a client application attempts to gain access to an object
|
||
/// or to create a new one. Alarms are not currently supported.
|
||
/// </summary>
|
||
/// <param name="SubsystemName">
|
||
/// A pointer to a <c>null</c>-terminated string specifying the name of the subsystem calling the function. This string appears in
|
||
/// any audit message that the function generates.
|
||
/// </param>
|
||
/// <param name="HandleId">
|
||
/// <para>
|
||
/// A pointer to a unique value representing the client's handle to the object. If the access is denied, this parameter is ignored.
|
||
/// </para>
|
||
/// <para>For cross-platform compatibility, the value addressed by this pointer must be sizeof(LPVOID) bytes long.</para>
|
||
/// </param>
|
||
/// <param name="ObjectTypeName">
|
||
/// A pointer to a <c>null</c>-terminated string specifying the type of object to which the client is requesting access. This string
|
||
/// appears in any audit message that the function generates.
|
||
/// </param>
|
||
/// <param name="ObjectName">
|
||
/// A pointer to a <c>null</c>-terminated string specifying the name of the object to which the client is requesting access. This
|
||
/// string appears in any audit message that the function generates.
|
||
/// </param>
|
||
/// <param name="pSecurityDescriptor">A pointer to the SECURITY_DESCRIPTOR structure for the object being accessed.</param>
|
||
/// <param name="ClientToken">
|
||
/// Identifies an access token representing the client requesting the operation. This handle must be obtained by opening the token of
|
||
/// a thread impersonating the client. The token must be open for TOKEN_QUERY access.
|
||
/// </param>
|
||
/// <param name="DesiredAccess">
|
||
/// Specifies the desired access mask. This mask must have been previously mapped by the MapGenericMask function to contain no
|
||
/// generic access rights.
|
||
/// </param>
|
||
/// <param name="GrantedAccess">
|
||
/// Specifies an access mask indicating which access rights are granted. This access mask is intended to be the same value set by one
|
||
/// of the access-checking functions in its GrantedAccess parameter. Examples of access-checking functions include
|
||
/// AccessCheckAndAuditAlarm and AccessCheck.
|
||
/// </param>
|
||
/// <param name="Privileges">
|
||
/// A pointer to a PRIVILEGE_SET structure that specifies the set of privileges required for the access attempt. This parameter can
|
||
/// be <c>NULL</c>.
|
||
/// </param>
|
||
/// <param name="ObjectCreation">
|
||
/// Specifies a flag that determines whether the application creates a new object when access is granted. When this value is
|
||
/// <c>TRUE</c>, the application creates a new object; when it is <c>FALSE</c>, the application opens an existing object.
|
||
/// </param>
|
||
/// <param name="AccessGranted">
|
||
/// Specifies a flag indicating whether access was granted or denied in a previous call to an access-checking function, such as
|
||
/// AccessCheck. If access was granted, this value is <c>TRUE</c>. If not, it is <c>FALSE</c>.
|
||
/// </param>
|
||
/// <param name="GenerateOnClose">
|
||
/// A pointer to a flag set by the audit-generation routine when the function returns. This value must be passed to the
|
||
/// ObjectCloseAuditAlarm function when the object handle is closed.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is nonzero.</para>
|
||
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// The <c>ObjectOpenAuditAlarm</c> function requires the calling application to have the SE_AUDIT_NAME privilege enabled. The test
|
||
/// for this privilege is always performed against the primary token of the calling process, not the impersonation token of the
|
||
/// thread. This allows the calling process to impersonate a client during the call.
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-objectopenauditalarma BOOL ObjectOpenAuditAlarmA( LPCSTR
|
||
// SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName, LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE
|
||
// ClientToken, DWORD DesiredAccess, DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted, LPBOOL
|
||
// GenerateOnClose );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "f3cb607b-a8fd-4a1b-9361-7ccd7cd8aac2")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool ObjectOpenAuditAlarm(string SubsystemName, IntPtr HandleId, string ObjectTypeName, string ObjectName,
|
||
PSECURITY_DESCRIPTOR pSecurityDescriptor, HTOKEN ClientToken, ACCESS_MASK DesiredAccess, ACCESS_MASK GrantedAccess,
|
||
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PRIVILEGE_SET.Marshaler))] PRIVILEGE_SET Privileges,
|
||
[MarshalAs(UnmanagedType.Bool)] bool ObjectCreation, [MarshalAs(UnmanagedType.Bool)] bool AccessGranted,
|
||
[MarshalAs(UnmanagedType.Bool)] out bool GenerateOnClose);
|
||
|
||
/// <summary>
|
||
/// The <c>ObjectPrivilegeAuditAlarm</c> function generates an audit message in the security event log. A protected server can use
|
||
/// this function to log attempts by a client to use a specified set of privileges with an open handle to a private object. Alarms
|
||
/// are not currently supported.
|
||
/// </summary>
|
||
/// <param name="SubsystemName">
|
||
/// A pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in the audit message.
|
||
/// </param>
|
||
/// <param name="HandleId">A pointer to a unique value representing the client's handle to the object.</param>
|
||
/// <param name="ClientToken">
|
||
/// Identifies an access token representing the client that requested the operation. This handle must have been obtained by opening
|
||
/// the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access. The function uses this token to
|
||
/// get the identity of the client for the audit message.
|
||
/// </param>
|
||
/// <param name="DesiredAccess">
|
||
/// Specifies an access mask indicating the privileged access types being used or whose use is being attempted. The access mask can
|
||
/// be mapped by the MapGenericMask function so it does not contain any generic access types.
|
||
/// </param>
|
||
/// <param name="Privileges">
|
||
/// A pointer to a PRIVILEGE_SET structure containing the privileges that the client attempted to use. The names of the privileges
|
||
/// appear in the audit message.
|
||
/// </param>
|
||
/// <param name="AccessGranted">
|
||
/// Indicates whether the client's attempt to use the privileges was successful. If this value is <c>TRUE</c>, the audit message
|
||
/// indicates success. If this value is <c>FALSE</c>, the audit message indicates failure.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is nonzero.</para>
|
||
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// The <c>ObjectPrivilegeAuditAlarm</c> function does not check the client's access to the object or check the client's access token
|
||
/// to determine whether the privileges are held or enabled. Typically, you call the PrivilegeCheck function to determine whether the
|
||
/// specified privileges are enabled in the access token, call the AccessCheck function to check the client's access to the object,
|
||
/// and then call <c>ObjectPrivilegeAuditAlarm</c> to log the results.
|
||
/// </para>
|
||
/// <para>
|
||
/// The <c>ObjectPrivilegeAuditAlarm</c> function requires the calling process to have SE_AUDIT_NAME privilege enabled. The test for
|
||
/// this privilege is always performed against the primary token of the calling process, not the impersonation token of the thread.
|
||
/// This allows the calling process to impersonate a client during the call.
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-objectprivilegeauditalarma BOOL
|
||
// ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken, DWORD DesiredAccess, PPRIVILEGE_SET
|
||
// Privileges, BOOL AccessGranted );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "76714ffe-be7c-4928-b7c9-e72441ada4c7")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool ObjectPrivilegeAuditAlarm(string SubsystemName, IntPtr HandleId, HTOKEN ClientToken, ACCESS_MASK DesiredAccess,
|
||
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PRIVILEGE_SET.Marshaler))] PRIVILEGE_SET Privileges,
|
||
[MarshalAs(UnmanagedType.Bool)] bool AccessGranted);
|
||
|
||
/// <summary>
|
||
/// Opens an encrypted file in order to backup (export) or restore (import) the file. This is one of a group of Encrypted File System
|
||
/// (EFS) functions that is intended to implement backup and restore functionality, while maintaining files in their encrypted state.
|
||
/// </summary>
|
||
/// <param name="lpFileName">
|
||
/// The name of the file to be opened. The string must consist of characters from the Windows character set.
|
||
/// </param>
|
||
/// <param name="ulFlags">The operation to be performed. This parameter may be one of the following values.</param>
|
||
/// <param name="pvContext">
|
||
/// The address of a context block that must be presented in subsequent calls to ReadEncryptedFileRaw, WriteEncryptedFileRaw, or
|
||
/// CloseEncryptedFileRaw. Do not modify it.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, it returns <c>ERROR_SUCCESS</c>.</para>
|
||
/// <para>
|
||
/// If the function fails, it returns a nonzero error code defined in WinError.h. You can use FormatMessage with the
|
||
/// <c>FORMAT_MESSAGE_FROM_SYSTEM</c> flag to get a generic text description of the error.
|
||
/// </para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// The caller must either have read or write access to the file, or it must have backup privilege SeBackupPrivilege on the machine
|
||
/// on which the files reside in order for the call to succeed.
|
||
/// </para>
|
||
/// <para>
|
||
/// To back up an encrypted file, call <c>OpenEncryptedFileRaw</c> to open the file and then call ReadEncryptedFileRaw. When the
|
||
/// backup is complete, call CloseEncryptedFileRaw.
|
||
/// </para>
|
||
/// <para>
|
||
/// To restore an encrypted file, call <c>OpenEncryptedFileRaw</c>, specifying <c>CREATE_FOR_IMPORT</c> in the ulFlags parameter, and
|
||
/// then call WriteEncryptedFileRaw once. When the operation is completed, call CloseEncryptedFileRaw.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>OpenEncryptedFileRaw</c> fails if lpFileName exceeds <c>MAX_PATH</c> characters when opening an encrypted file on a remote machine.
|
||
/// </para>
|
||
/// <para>
|
||
/// If the caller does not have access to the key for the file, the caller needs SeBackupPrivilege to export encrypted files or
|
||
/// SeRestorePrivilege to import encrypted files.
|
||
/// </para>
|
||
/// <para>The BackupRead and BackupWrite functions handle backup and restore of unencrypted files.</para>
|
||
/// <para>In Windows 8, Windows Server 2012, and later, this function is supported by the following technologies.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Technology</term>
|
||
/// <term>Supported</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>Server Message Block (SMB) 3.0 protocol</term>
|
||
/// <term>Yes</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>SMB 3.0 Transparent Failover (TFO)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>SMB 3.0 with Scale-out File Shares (SO)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>Cluster Shared Volume File System (CsvFS)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>Resilient File System (ReFS)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>SMB 3.0 does not support EFS on shares with continuous availability capability.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-openencryptedfilerawa DWORD OpenEncryptedFileRawA( LPCSTR
|
||
// lpFileName, ULONG ulFlags, PVOID *pvContext );
|
||
[DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "f792f38d-783e-4f39-a9d8-0c378d508d97")]
|
||
public static extern Win32Error OpenEncryptedFileRaw(string lpFileName, OpenRawFlags ulFlags, out SafeEncryptedFileContext pvContext);
|
||
|
||
/// <summary>
|
||
/// <para>Notifies the system that the application is about to end an operation</para>
|
||
/// <para>
|
||
/// Every call to OperationStart must be followed by a call to <c>OperationEnd</c>, otherwise the operation's record of file access
|
||
/// patterns is discarded after 10 seconds.
|
||
/// </para>
|
||
/// </summary>
|
||
/// <param name="OperationEndParams">
|
||
/// An _OPERATION_END_PARAMETERS structure that specifies <c>VERSION</c>, <c>OPERATION_ID</c> and <c>FLAGS</c>.
|
||
/// </param>
|
||
/// <returns><c>TRUE</c> for all valid parameters and <c>FALSE</c> otherwise. To get extended error information, call <c>GetLastError</c>.</returns>
|
||
/// <remarks>
|
||
/// <para>The version of the _OPERATION_END_PARAMETERS structure is defined as <c>OPERATION_API_VERSION</c> in the Windows SDK.</para>
|
||
/// <para>The <c>OperationEnd</c> function is safe to call on any thread.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-operationend BOOL OperationEnd( OPERATION_END_PARAMETERS
|
||
// *OperationEndParams );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "73C6FBDD-BB4A-46A5-8E39-7862A1938F47")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool OperationEnd(in OPERATION_END_PARAMETERS OperationEndParams);
|
||
|
||
/// <summary>
|
||
/// <para>Notifies the system that the application is about to start an operation.</para>
|
||
/// <para>
|
||
/// If an application calls <c>OperationStart</c> with a valid OPERATION_ID value, the system records the specified operation’s file
|
||
/// access patterns until OperationEnd is called for the same operation ID. This record is stored in a filename.pf prefetch file.
|
||
/// Every call to <c>OperationStart</c> must be followed by a call to <c>OperationEnd</c>, otherwise the operation's record is
|
||
/// discarded after 10 seconds.
|
||
/// </para>
|
||
/// <para>
|
||
/// If an application calls <c>OperationStart</c> for an operation ID for which a prefetch file exists, the system loads the
|
||
/// operation's files into memory prior to running the operation. The recording process remains the same and the system updates the
|
||
/// appropriate filename.pf prefetch file.
|
||
/// </para>
|
||
/// </summary>
|
||
/// <param name="OperationStartParams">
|
||
/// An _OPERATION_START_PARAMETERS structure that specifies <c>VERSION</c>, <c>OPERATION_ID</c> and <c>FLAGS</c>.
|
||
/// </param>
|
||
/// <returns><c>TRUE</c> for all valid parameters and <c>FALSE</c> otherwise. To get extended error information, call <c>GetLastError</c>.</returns>
|
||
/// <remarks>
|
||
/// <para>The version of the _OPERATION_START_PARAMETERS structure is defined as <c>OPERATION_API_VERSION</c> in the Windows SDK.</para>
|
||
/// <para>
|
||
/// Because the <c>OperationStart</c> function is synchronous, it can take several seconds to return. This should be avoided in UI
|
||
/// threads for the best responsiveness.
|
||
/// </para>
|
||
/// <para>
|
||
/// There is a single instance of the operation recorder in a process. Although the operation recorder APIs can be called from
|
||
/// multiple threads within the process, all calls act on the single instance.
|
||
/// </para>
|
||
/// <para>
|
||
/// Application launch tracing lasts for the first 10 second of the process lifetime. <c>OperationStart</c> should be called after
|
||
/// the end of application launch tracing by the system.
|
||
/// </para>
|
||
/// <para>
|
||
/// Every call to <c>OperationStart</c> must be followed by a call to OperationEnd. Otherwise, the operation trace will be discarded
|
||
/// after about 10s.
|
||
/// </para>
|
||
/// <para>
|
||
/// The maximum number of operations that can be recorded on a given system is configurable. If this maximum is exceeded, the least
|
||
/// recently used prefetch files are replaced.
|
||
/// </para>
|
||
/// <para>
|
||
/// On Windows 8, this functionality requires the Superfetch service to be enabled. Windows 8 will have the service enabled by
|
||
/// default. For Windows Server 2012, this prefetching functionality needs to be enabled and disabled as required. This can be done
|
||
/// using CIM based PowerShell cmdlets. The prefetcher functionality can be exposed using the CIM class of the <c>CIM_PrefetcherService</c>.
|
||
/// </para>
|
||
/// <para>Examples</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-operationstart BOOL OperationStart(
|
||
// OPERATION_START_PARAMETERS *OperationStartParams );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "3E67057E-D09F-48BA-A95A-5D00F4783D9C")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool OperationStart(in OPERATION_START_PARAMETERS OperationStartParams);
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// The <c>PrivilegedServiceAuditAlarm</c> function generates an audit message in the security event log. A protected server can use
|
||
/// this function to log attempts by a client to use a specified set of privileges.
|
||
/// </para>
|
||
/// <para>Alarms are not currently supported.</para>
|
||
/// </summary>
|
||
/// <param name="SubsystemName">
|
||
/// A pointer to a null-terminated string specifying the name of the subsystem calling the function. This information appears in the
|
||
/// security event log record.
|
||
/// </param>
|
||
/// <param name="ServiceName">
|
||
/// A pointer to a null-terminated string specifying the name of the privileged subsystem service. This information appears in the
|
||
/// security event log record.
|
||
/// </param>
|
||
/// <param name="ClientToken">
|
||
/// Identifies an access token representing the client that requested the operation. This handle must have been obtained by opening
|
||
/// the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access. The function uses this token to
|
||
/// get the identity of the client for the security event log record.
|
||
/// </param>
|
||
/// <param name="Privileges">
|
||
/// A pointer to a PRIVILEGE_SET structure containing the privileges that the client attempted to use. The names of the privileges
|
||
/// appear in the security event log record.
|
||
/// </param>
|
||
/// <param name="AccessGranted">
|
||
/// Indicates whether the client's attempt to use the privileges was successful. If this value is <c>TRUE</c>, the security event log
|
||
/// record indicates success. If this value is <c>FALSE</c>, the security event log record indicates failure.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is nonzero.</para>
|
||
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// The <c>PrivilegedServiceAuditAlarm</c> function does not check the client's access token to determine whether the privileges are
|
||
/// held or enabled. Typically, you first call the PrivilegeCheck function to determine whether the specified privileges are enabled
|
||
/// in the access token, and then call <c>PrivilegedServiceAuditAlarm</c> to log the results.
|
||
/// </para>
|
||
/// <para>
|
||
/// The <c>PrivilegedServiceAuditAlarm</c> function requires the calling process to have SE_AUDIT_NAME privilege enabled. The test
|
||
/// for this privilege is always performed against the primary token of the calling process. This allows the calling process to
|
||
/// impersonate a client during the call.
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-privilegedserviceauditalarma BOOL
|
||
// PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken, PPRIVILEGE_SET Privileges, BOOL
|
||
// AccessGranted );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "a424c583-bb71-4bda-a27f-2389b89104d8")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool PrivilegedServiceAuditAlarm(string SubsystemName, string ServiceName, HTOKEN ClientToken,
|
||
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PRIVILEGE_SET.Marshaler))] PRIVILEGE_SET Privileges,
|
||
[MarshalAs(UnmanagedType.Bool)] bool AccessGranted);
|
||
|
||
/// <summary>
|
||
/// Backs up (export) encrypted files. This is one of a group of Encrypted File System (EFS) functions that is intended to implement
|
||
/// backup and restore functionality, while maintaining files in their encrypted state.
|
||
/// </summary>
|
||
/// <param name="pfExportCallback">
|
||
/// A pointer to the export callback function. The system calls the callback function multiple times, each time passing a block of
|
||
/// the file's data to the callback function until the entire file has been read. For more information, see ExportCallback.
|
||
/// </param>
|
||
/// <param name="pvCallbackContext">
|
||
/// A pointer to an application-defined and allocated context block. The system passes this pointer to the callback function as a
|
||
/// parameter so that the callback function can have access to application-specific data. This can be a structure and can contain any
|
||
/// data the application needs, such as the handle to the file that will contain the backup copy of the encrypted file.
|
||
/// </param>
|
||
/// <param name="pvContext">
|
||
/// A pointer to a system-defined context block. The context block is returned by the OpenEncryptedFileRaw function. Do not modify it.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is <c>ERROR_SUCCESS</c>.</para>
|
||
/// <para>
|
||
/// If the function fails, it returns a nonzero error code defined in WinError.h. You can use FormatMessage with the
|
||
/// <c>FORMAT_MESSAGE_FROM_SYSTEM</c> flag to get a generic text description of the error.
|
||
/// </para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>The file being backed up is not decrypted; it is backed up in its encrypted state.</para>
|
||
/// <para>
|
||
/// To back up an encrypted file, call OpenEncryptedFileRaw to open the file. Then call <c>ReadEncryptedFileRaw</c>, passing it the
|
||
/// address of an application-defined export callback function. The system calls this callback function multiple times until the
|
||
/// entire file's contents have been read and backed up. When the backup is complete, call CloseEncryptedFileRaw to free resources
|
||
/// and close the file. See ExportCallback for details about how to declare the export callback function.
|
||
/// </para>
|
||
/// <para>
|
||
/// To restore an encrypted file, call OpenEncryptedFileRaw, specifying <c>CREATE_FOR_IMPORT</c> in the ulFlags parameter. Then call
|
||
/// WriteEncryptedFileRaw, passing it the address of an application-defined import callback function. The system calls this callback
|
||
/// function multiple times until the entire file's contents have been read and restored. When the restore is complete, call
|
||
/// CloseEncryptedFileRaw to free resources and close the file. See ImportCallback for details about how to declare the import
|
||
/// callback function.
|
||
/// </para>
|
||
/// <para>This function is intended for the backup of only encrypted files; see BackupRead for backup of unencrypted files.</para>
|
||
/// <para>In Windows 8, Windows Server 2012, and later, this function is supported by the following technologies.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Technology</term>
|
||
/// <term>Supported</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>Server Message Block (SMB) 3.0 protocol</term>
|
||
/// <term>Yes</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>SMB 3.0 Transparent Failover (TFO)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>SMB 3.0 with Scale-out File Shares (SO)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>Cluster Shared Volume File System (CsvFS)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>Resilient File System (ReFS)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>SMB 3.0 does not support EFS on shares with continuous availability capability.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-readencryptedfileraw DWORD ReadEncryptedFileRaw(
|
||
// PFE_EXPORT_FUNC pfExportCallback, PVOID pvCallbackContext, PVOID pvContext );
|
||
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "15f6f617-969d-4a40-9038-b902a3c2518b")]
|
||
public static extern Win32Error ReadEncryptedFileRaw(ExportCallback pfExportCallback, IntPtr pvCallbackContext, EncryptedFileContext pvContext);
|
||
|
||
/// <summary>
|
||
/// <para>The <c>SetFileSecurity</c> function sets the security of a file or directory object.</para>
|
||
/// <para>This function is obsolete. Use the SetNamedSecurityInfo function instead.</para>
|
||
/// </summary>
|
||
/// <param name="lpFileName">
|
||
/// A pointer to a null-terminated string that specifies the file or directory for which security is set. Note that security applied
|
||
/// to a directory is not inherited by its children.
|
||
/// </param>
|
||
/// <param name="SecurityInformation">
|
||
/// Specifies a SECURITY_INFORMATION structure that identifies the contents of the security descriptor pointed to by the
|
||
/// pSecurityDescriptor parameter.
|
||
/// </param>
|
||
/// <param name="pSecurityDescriptor">A pointer to a SECURITY_DESCRIPTOR structure.</param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the function returns nonzero.</para>
|
||
/// <para>If the function fails, it returns zero. To get extended error information, call GetLastError.</para>
|
||
/// </returns>
|
||
/// <remarks>The <c>SetFileSecurity</c> function is successful only if the following conditions are met:</remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-setfilesecuritya BOOL SetFileSecurityA( LPCSTR lpFileName,
|
||
// SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "27766c97-7ac5-40fc-b798-7cd07e496c0d")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool SetFileSecurity(string lpFileName, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor);
|
||
|
||
/// <summary>
|
||
/// Restores (import) encrypted files. This is one of a group of Encrypted File System (EFS) functions that is intended to implement
|
||
/// backup and restore functionality, while maintaining files in their encrypted state.
|
||
/// </summary>
|
||
/// <param name="pfImportCallback">
|
||
/// A pointer to the import callback function. The system calls the callback function multiple times, each time passing a buffer that
|
||
/// will be filled by the callback function with a portion of backed-up file's data. When the callback function signals that the
|
||
/// entire file has been processed, it tells the system that the restore operation is finished. For more information, see ImportCallback.
|
||
/// </param>
|
||
/// <param name="pvCallbackContext">
|
||
/// A pointer to an application-defined and allocated context block. The system passes this pointer to the callback function as a
|
||
/// parameter so that the callback function can have access to application-specific data. This can be a structure and can contain any
|
||
/// data the application needs, such as the handle to the file that will contain the backup copy of the encrypted file.
|
||
/// </param>
|
||
/// <param name="pvContext">
|
||
/// A pointer to a system-defined context block. The context block is returned by the OpenEncryptedFileRaw function. Do not modify it.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is <c>ERROR_SUCCESS</c>.</para>
|
||
/// <para>
|
||
/// If the function fails, it returns a nonzero error code defined in WinError.h. You can use FormatMessage with the
|
||
/// <c>FORMAT_MESSAGE_FROM_SYSTEM</c> flag to get a generic text description of the error.
|
||
/// </para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>The file being restored is not decrypted; it is restored in its encrypted state.</para>
|
||
/// <para>
|
||
/// To back up an encrypted file, call OpenEncryptedFileRaw to open the file. Then call ReadEncryptedFileRaw, passing it the address
|
||
/// of an application-defined export callback function. The system calls this callback function multiple times until the entire
|
||
/// file's contents have been read and backed up. When the backup is complete, call CloseEncryptedFileRaw to free resources and close
|
||
/// the file. See ExportCallback for details about how to declare the export callback function.
|
||
/// </para>
|
||
/// <para>
|
||
/// To restore an encrypted file, call OpenEncryptedFileRaw, specifying <c>CREATE_FOR_IMPORT</c> in the ulFlags parameter. Then call
|
||
/// <c>WriteEncryptedFileRaw</c>, passing it the address of an application-defined import callback function. The system calls this
|
||
/// callback function multiple times until the entire file's contents have been read and restored. When the restore is complete, call
|
||
/// CloseEncryptedFileRaw to free resources and close the file. See ImportCallback for details about how to declare the export
|
||
/// callback function.
|
||
/// </para>
|
||
/// <para>
|
||
/// If the file is a sparse file that was backed up from a volume with a smaller sparse allocation unit size than the volume it is
|
||
/// being restored to, the sparse blocks in the middle of the file may not properly align with the larger blocks and the function
|
||
/// call would fail and set an <c>ERROR_INVALID_PARAMETER</c> last error code. The sparse allocation unit size is either 16 clusters
|
||
/// or 64 KB, whichever is smaller.
|
||
/// </para>
|
||
/// <para>This function is intended for restoring only encrypted files; see BackupWrite for restoring unencrypted files.</para>
|
||
/// <para>In Windows 8, Windows Server 2012, and later, this function is supported by the following technologies.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Technology</term>
|
||
/// <term>Supported</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>Server Message Block (SMB) 3.0 protocol</term>
|
||
/// <term>Yes</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>SMB 3.0 Transparent Failover (TFO)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>SMB 3.0 with Scale-out File Shares (SO)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>Cluster Shared Volume File System (CsvFS)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>Resilient File System (ReFS)</term>
|
||
/// <term>No</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>SMB 3.0 does not support EFS on shares with continuous availability capability.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-writeencryptedfileraw DWORD WriteEncryptedFileRaw(
|
||
// PFE_IMPORT_FUNC pfImportCallback, PVOID pvCallbackContext, PVOID pvContext );
|
||
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "f44e291e-dbc6-4a44-92ba-92a81e043764")]
|
||
public static extern Win32Error WriteEncryptedFileRaw(ImportCallback pfImportCallback, IntPtr pvCallbackContext, EncryptedFileContext pvContext);
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// Creates a new process and its primary thread. Then the new process runs the specified executable file in the security context of
|
||
/// the specified credentials (user, domain, and password). It can optionally load the user profile for a specified user.
|
||
/// </para>
|
||
/// <para>
|
||
/// This function is similar to the CreateProcessAsUser and CreateProcessWithTokenW functions, except that the caller does not need
|
||
/// to call the LogonUser function to authenticate the user and get a token.
|
||
/// </para>
|
||
/// </summary>
|
||
/// <param name="lpUsername">
|
||
/// <para>
|
||
/// The name of the user. This is the name of the user account to log on to. If you use the UPN format, user@DNS_domain_name, the
|
||
/// lpDomain parameter must be NULL.
|
||
/// </para>
|
||
/// <para>
|
||
/// The user account must have the Log On Locally permission on the local computer. This permission is granted to all users on
|
||
/// workstations and servers, but only to administrators on domain controllers.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpDomain">
|
||
/// The name of the domain or server whose account database contains the lpUsername account. If this parameter is NULL, the user name
|
||
/// must be specified in UPN format.
|
||
/// </param>
|
||
/// <param name="lpPassword">The clear-text password for the lpUsername account.</param>
|
||
/// <param name="dwLogonFlags">The logon option. This parameter can be 0 (zero) or one of the following values.</param>
|
||
/// <param name="lpApplicationName">
|
||
/// <para>
|
||
/// The name of the module to be executed. This module can be a Windows-based application. It can be some other type of module (for
|
||
/// example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.
|
||
/// </para>
|
||
/// <para>
|
||
/// The string can specify the full path and file name of the module to execute or it can specify a partial name. If it is a partial
|
||
/// name, the function uses the current drive and current directory to complete the specification. The function does not use the
|
||
/// search path. This parameter must include the file name extension; no default extension is assumed.
|
||
/// </para>
|
||
/// <para>
|
||
/// The lpApplicationName parameter can be NULL, and the module name must be the first white space–delimited token in the
|
||
/// lpCommandLine string. If you are using a long file name that contains a space, use quoted strings to indicate where the file name
|
||
/// ends and the arguments begin; otherwise, the file name is ambiguous.
|
||
/// </para>
|
||
/// <para>For example, the following string can be interpreted in different ways:</para>
|
||
/// <para>"c:\program files\sub dir\program name"</para>
|
||
/// <para>The system tries to interpret the possibilities in the following order:</para>
|
||
/// <list type="number">
|
||
/// <item>
|
||
/// <term><c>c:\program.exe</c> files\sub dir\program name</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>c:\program files\sub.exe</c> dir\program name</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>c:\program files\sub dir\program.exe</c> name</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>c:\program files\sub dir\program name.exe</c></term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>
|
||
/// If the executable module is a 16-bit application, lpApplicationName should be NULL, and the string pointed to by lpCommandLine
|
||
/// should specify the executable module and its arguments.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpCommandLine">
|
||
/// <para>
|
||
/// The command line to be executed. The maximum length of this string is 1024 characters. If lpApplicationName is <c>NULL</c>, the
|
||
/// module name portion of lpCommandLine is limited to <c>MAX_PATH</c> characters.
|
||
/// </para>
|
||
/// <para>
|
||
/// The function can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a
|
||
/// <c>const</c> variable or a literal string). If this parameter is a constant string, the function may cause an access violation.
|
||
/// </para>
|
||
/// <para>
|
||
/// The lpCommandLine parameter can be <c>NULL</c>, and the function uses the string pointed to by lpApplicationName as the command line.
|
||
/// </para>
|
||
/// <para>
|
||
/// If both lpApplicationName and lpCommandLine are non- <c>NULL</c>, *lpApplicationName specifies the module to execute, and
|
||
/// *lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console
|
||
/// processes written in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C
|
||
/// programmers typically repeat the module name as the first token in the command line.
|
||
/// </para>
|
||
/// <para>
|
||
/// If lpApplicationName is <c>NULL</c>, the first white space–delimited token of the command line specifies the module name. If you
|
||
/// are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin
|
||
/// (see the explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended.
|
||
/// Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period
|
||
/// with no extension, or if the file name contains a path, .exe is not appended. If the file name does not contain a directory path,
|
||
/// the system searches for the executable file in the following sequence:
|
||
/// </para>
|
||
/// <list type="number">
|
||
/// <item>
|
||
/// <term>The directory from which the application loaded.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The current directory for the parent process.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>
|
||
/// The directories that are listed in the PATH environment variable. Note that this function does not search the per-application
|
||
/// path specified by the <c>App Paths</c> registry key. To include this per-application path in the search sequence, use the
|
||
/// ShellExecute function.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>
|
||
/// The system adds a null character to the command line string to separate the file name from the arguments. This divides the
|
||
/// original string into two strings for internal processing.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="dwCreationFlags">
|
||
/// <para>
|
||
/// The flags that control how the process is created. The <c>CREATE_DEFAULT_ERROR_MODE</c>, <c>CREATE_NEW_CONSOLE</c>, and
|
||
/// <c>CREATE_NEW_PROCESS_GROUP</c> flags are enabled by default— even if you do not set the flag, the system functions as if it were
|
||
/// set. You can specify additional flags as noted.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>CREATE_DEFAULT_ERROR_MODE 0x04000000</term>
|
||
/// <term>
|
||
/// The new process does not inherit the error mode of the calling process. Instead, CreateProcessWithLogonW gives the new process
|
||
/// the current default error mode. An application sets the current default error mode by calling SetErrorMode. This flag is enabled
|
||
/// by default.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_NEW_CONSOLE 0x00000010</term>
|
||
/// <term>
|
||
/// The new process has a new console, instead of inheriting the parent's console. This flag cannot be used with the DETACHED_PROCESS
|
||
/// flag. This flag is enabled by default.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_NEW_PROCESS_GROUP 0x00000200</term>
|
||
/// <term>
|
||
/// The new process is the root process of a new process group. The process group includes all processes that are descendants of this
|
||
/// root process. The process identifier of the new process group is the same as the process identifier, which is returned in the
|
||
/// lpProcessInfo parameter. Process groups are used by the GenerateConsoleCtrlEvent function to enable sending a CTRL+C or
|
||
/// CTRL+BREAK signal to a group of console processes. This flag is enabled by default.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_SEPARATE_WOW_VDM 0x00000800</term>
|
||
/// <term>
|
||
/// This flag is only valid starting a 16-bit Windows-based application. If set, the new process runs in a private Virtual DOS
|
||
/// Machine (VDM). By default, all 16-bit Windows-based applications run in a single, shared VDM. The advantage of running separately
|
||
/// is that a crash only terminates the single VDM; any other programs running in distinct VDMs continue to function normally. Also,
|
||
/// 16-bit Windows-based applications that run in separate VDMs have separate input queues, which means that if one application stops
|
||
/// responding momentarily, applications in separate VDMs continue to receive input.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_SUSPENDED 0x00000004</term>
|
||
/// <term>
|
||
/// The primary thread of the new process is created in a suspended state, and does not run until the ResumeThread function is called.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_UNICODE_ENVIRONMENT 0x00000400</term>
|
||
/// <term>
|
||
/// Indicates the format of the lpEnvironment parameter. If this flag is set, the environment block pointed to by lpEnvironment uses
|
||
/// Unicode characters. Otherwise, the environment block uses ANSI characters.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>
|
||
/// This parameter also controls the new process's priority class, which is used to determine the scheduling priorities of the
|
||
/// process's threads. For a list of values, see GetPriorityClass. If none of the priority class flags is specified, the priority
|
||
/// class defaults to <c>NORMAL_PRIORITY_CLASS</c> unless the priority class of the creating process is <c>IDLE_PRIORITY_CLASS</c> or
|
||
/// <c>BELOW_NORMAL_PRIORITY_CLASS</c>. In this case, the child process receives the default priority class of the calling process.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpEnvironment">
|
||
/// <para>
|
||
/// A pointer to an environment block for the new process. If this parameter is <c>NULL</c>, the new process uses an environment
|
||
/// created from the profile of the user specified by lpUsername.
|
||
/// </para>
|
||
/// <para>An environment block consists of a null-terminated block of null-terminated strings. Each string is in the following form:</para>
|
||
/// <para>name=value</para>
|
||
/// <para>Because the equal sign (=) is used as a separator, it must not be used in the name of an environment variable.</para>
|
||
/// <para>
|
||
/// An environment block can contain Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains
|
||
/// Unicode characters, ensure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>. If this parameter is NULL and the
|
||
/// environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>.
|
||
/// </para>
|
||
/// <para>
|
||
/// An ANSI environment block is terminated by two 0 (zero) bytes: one for the last string and one more to terminate the block. A
|
||
/// Unicode environment block is terminated by four zero bytes: two for the last string and two more to terminate the block.
|
||
/// </para>
|
||
/// <para>To retrieve a copy of the environment block for a specific user, use the CreateEnvironmentBlock function.</para>
|
||
/// </param>
|
||
/// <param name="lpCurrentDirectory">
|
||
/// <para>The full path to the current directory for the process. The string can also specify a UNC path.</para>
|
||
/// <para>
|
||
/// If this parameter is <c>NULL</c>, the new process has the same current drive and directory as the calling process. This feature
|
||
/// is provided primarily for shells that need to start an application, and specify its initial drive and working directory.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpStartupInfo">
|
||
/// <para>A pointer to a STARTUPINFO structure.</para>
|
||
/// <para>
|
||
/// The application must add permission for the specified user account to the specified window station and desktop, even for WinSta0\Default.
|
||
/// </para>
|
||
/// <para>
|
||
/// If the <c>lpDesktop</c> member is <c>NULL</c> or an empty string, the new process inherits the desktop and window station of its
|
||
/// parent process. The application must add permission for the specified user account to the inherited window station and desktop.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>Windows XP:</c><c>CreateProcessWithLogonW</c> adds permission for the specified user account to the inherited window station
|
||
/// and desktop.
|
||
/// </para>
|
||
/// <para>Handles in STARTUPINFO must be closed with CloseHandle when they are no longer needed.</para>
|
||
/// <para>
|
||
/// <c>Important</c> If the <c>dwFlags</c> member of the STARTUPINFO structure specifies <c>STARTF_USESTDHANDLES</c>, the standard
|
||
/// handle fields are copied unchanged to the child process without validation. The caller is responsible for ensuring that these
|
||
/// fields contain valid handle values. Incorrect values can cause the child process to misbehave or crash. Use the Application
|
||
/// Verifier runtime verification tool to detect invalid handles.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpProcessInformation">
|
||
/// <para>
|
||
/// A pointer to a PROCESS_INFORMATION structure that receives identification information for the new process, including a handle to
|
||
/// the process.
|
||
/// </para>
|
||
/// <para>Handles in PROCESS_INFORMATION must be closed with the CloseHandle function when they are not needed.</para>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is nonzero.</para>
|
||
/// <para>If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError.</para>
|
||
/// <para>
|
||
/// Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to
|
||
/// initialize, the process is terminated. To get the termination status of a process, call GetExitCodeProcess.
|
||
/// </para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// By default, <c>CreateProcessWithLogonW</c> does not load the specified user profile into the <c>HKEY_USERS</c> registry key. This
|
||
/// means that access to information in the <c>HKEY_CURRENT_USER</c> registry key may not produce results that are consistent with a
|
||
/// normal interactive logon. It is your responsibility to load the user registry hive into <c>HKEY_USERS</c> before calling
|
||
/// <c>CreateProcessWithLogonW</c>, by using <c>LOGON_WITH_PROFILE</c>, or by calling the LoadUserProfile function.
|
||
/// </para>
|
||
/// <para>
|
||
/// If the lpEnvironment parameter is NULL, the new process uses an environment block created from the profile of the user specified
|
||
/// by lpUserName. If the HOMEDRIVE and HOMEPATH variables are not set, <c>CreateProcessWithLogonW</c> modifies the environment block
|
||
/// to use the drive and path of the user's working directory.
|
||
/// </para>
|
||
/// <para>
|
||
/// When created, the new process and thread handles receive full access rights ( <c>PROCESS_ALL_ACCESS</c> and
|
||
/// <c>THREAD_ALL_ACCESS</c>). For either handle, if a security descriptor is not provided, the handle can be used in any function
|
||
/// that requires an object handle of that type. When a security descriptor is provided, an access check is performed on all
|
||
/// subsequent uses of the handle before access is granted. If access is denied, the requesting process cannot use the handle to gain
|
||
/// access to the process or thread.
|
||
/// </para>
|
||
/// <para>To retrieve a security token, pass the process handle in the PROCESS_INFORMATION structure to the OpenProcessToken function.</para>
|
||
/// <para>
|
||
/// The process is assigned a process identifier. The identifier is valid until the process terminates. It can be used to identify
|
||
/// the process, or it can be specified in the OpenProcess function to open a handle to the process. The initial thread in the
|
||
/// process is also assigned a thread identifier. It can be specified in the OpenThread function to open a handle to the thread. The
|
||
/// identifier is valid until the thread terminates and can be used to uniquely identify the thread within the system. These
|
||
/// identifiers are returned in PROCESS_INFORMATION.
|
||
/// </para>
|
||
/// <para>
|
||
/// The calling thread can use the WaitForInputIdle function to wait until the new process has completed its initialization and is
|
||
/// waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because
|
||
/// <c>CreateProcessWithLogonW</c> returns without waiting for the new process to finish its initialization. For example, the
|
||
/// creating process would use <c>WaitForInputIdle</c> before trying to find a window that is associated with the new process.
|
||
/// </para>
|
||
/// <para>
|
||
/// The preferred way to shut down a process is by using the ExitProcess function, because this function sends notification of
|
||
/// approaching termination to all DLLs attached to the process. Other means of shutting down a process do not notify the attached
|
||
/// DLLs. Note that when a thread calls <c>ExitProcess</c>, other threads of the process are terminated without an opportunity to
|
||
/// execute any additional code (including the thread termination code of attached DLLs). For more information, see Terminating a Process.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>CreateProcessWithLogonW</c> accesses the specified directory and executable image in the security context of the target user.
|
||
/// If the executable image is on a network and a network drive letter is specified in the path, the network drive letter is not
|
||
/// available to the target user, as network drive letters can be assigned for each logon. If a network drive letter is specified,
|
||
/// this function fails. If the executable image is on a network, use the UNC path.
|
||
/// </para>
|
||
/// <para>
|
||
/// There is a limit to the number of child processes that can be created by this function and run simultaneously. For example, on
|
||
/// Windows XP, this limit is <c>MAXIMUM_WAIT_OBJECTS</c>*4. However, you may not be able to create this many processes due to
|
||
/// system-wide quota limits.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>Windows XP with SP2,Windows Server 2003, or later:</c> You cannot call <c>CreateProcessWithLogonW</c> from a process that is
|
||
/// running under the "LocalSystem" account, because the function uses the logon SID in the caller token, and the token for the
|
||
/// "LocalSystem" account does not contain this SID. As an alternative, use the CreateProcessAsUser and LogonUser functions.
|
||
/// </para>
|
||
/// <para>
|
||
/// To compile an application that uses this function, define <c>_WIN32_WINNT</c> as 0x0500 or later. For more information, see Using
|
||
/// the Windows Headers.
|
||
/// </para>
|
||
/// <para>Security Remarks</para>
|
||
/// <para>
|
||
/// The lpApplicationName parameter can be <c>NULL</c>, and the executable name must be the first white space–delimited string in
|
||
/// lpCommandLine. If the executable or path name has a space in it, there is a risk that a different executable could be run because
|
||
/// of the way the function parses spaces. Avoid the following example, because the function attempts to run "Program.exe", if it
|
||
/// exists, instead of "MyApp.exe".
|
||
/// </para>
|
||
/// <para>
|
||
/// If a malicious user creates an application called "Program.exe" on a system, any program that incorrectly calls
|
||
/// <c>CreateProcessWithLogonW</c> using the Program Files directory runs the malicious user application instead of the intended application.
|
||
/// </para>
|
||
/// <para>
|
||
/// To avoid this issue, do not pass <c>NULL</c> for lpApplicationName. If you pass <c>NULL</c> for lpApplicationName, use quotation
|
||
/// marks around the executable path in lpCommandLine, as shown in the following example:
|
||
/// </para>
|
||
/// <para>Examples</para>
|
||
/// <para>The following example demonstrates how to call this function.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-createprocesswithlogonw BOOL CreateProcessWithLogonW(
|
||
// LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags, LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
|
||
// DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION
|
||
// lpProcessInformation );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "dcfdcd5b-0269-4081-b1db-e272171c27a2")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
private static extern bool CreateProcessWithLogonW(string lpUsername, [Optional] string lpDomain, string lpPassword, ProcessLogonFlags dwLogonFlags,
|
||
[Optional] string lpApplicationName, [Optional] StringBuilder lpCommandLine, CREATE_PROCESS dwCreationFlags,
|
||
[In, Optional, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")] string[] lpEnvironment,
|
||
[Optional] string lpCurrentDirectory, in STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// Creates a new process and its primary thread. The new process runs in the security context of the specified token. It can
|
||
/// optionally load the user profile for the specified user.
|
||
/// </para>
|
||
/// <para>
|
||
/// The process that calls <c>CreateProcessWithTokenW</c> must have the SE_IMPERSONATE_NAME privilege. If this function fails with
|
||
/// ERROR_PRIVILEGE_NOT_HELD (1314), use the CreateProcessAsUser or CreateProcessWithLogonW function instead. Typically, the process
|
||
/// that calls <c>CreateProcessAsUser</c> must have the SE_INCREASE_QUOTA_NAME privilege and may require the
|
||
/// SE_ASSIGNPRIMARYTOKEN_NAME privilege if the token is not assignable. <c>CreateProcessWithLogonW</c> requires no special
|
||
/// privileges, but the specified user account must be allowed to log on interactively. Generally, it is best to use
|
||
/// <c>CreateProcessWithLogonW</c> to create a process with alternate credentials.
|
||
/// </para>
|
||
/// </summary>
|
||
/// <param name="hToken">
|
||
/// <para>
|
||
/// A handle to the primary token that represents a user. The handle must have the TOKEN_QUERY, TOKEN_DUPLICATE, and
|
||
/// TOKEN_ASSIGN_PRIMARY access rights. For more information, see Access Rights for Access-Token Objects. The user represented by the
|
||
/// token must have read and execute access to the application specified by the lpApplicationName or the lpCommandLine parameter.
|
||
/// </para>
|
||
/// <para>
|
||
/// To get a primary token that represents the specified user, call the LogonUser function. Alternatively, you can call the
|
||
/// DuplicateTokenEx function to convert an impersonation token into a primary token. This allows a server application that is
|
||
/// impersonating a client to create a process that has the security context of the client.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>Terminal Services:</c> The process is run in the session specified in the token. By default, this is the same session that
|
||
/// called LogonUser. To change the session, use the SetTokenInformation function.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="dwLogonFlags">The logon option. This parameter can be zero or one of the following values.</param>
|
||
/// <param name="lpApplicationName">
|
||
/// <para>
|
||
/// The name of the module to be executed. This module can be a Windows-based application. It can be some other type of module (for
|
||
/// example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.
|
||
/// </para>
|
||
/// <para>
|
||
/// The string can specify the full path and file name of the module to execute or it can specify a partial name. In the case of a
|
||
/// partial name, the function uses the current drive and current directory to complete the specification. The function will not use
|
||
/// the search path. This parameter must include the file name extension; no default extension is assumed.
|
||
/// </para>
|
||
/// <para>
|
||
/// The lpApplicationName parameter can be NULL. In that case, the module name must be the first white space–delimited token in the
|
||
/// lpCommandLine string. If you are using a long file name that contains a space, use quoted strings to indicate where the file name
|
||
/// ends and the arguments begin; otherwise, the file name is ambiguous. For example, consider the string "c:\program files\sub
|
||
/// dir\program name". This string can be interpreted in a number of ways. The system tries to interpret the possibilities in the
|
||
/// following order:
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>c:\program.exe</c><c>c:\program files\sub.exe</c><c>c:\program files\sub dir\program.exe</c><c>c:\program files\sub
|
||
/// dir\program name.exe</c> If the executable module is a 16-bit application, lpApplicationName should be NULL, and the string
|
||
/// pointed to by lpCommandLine should specify the executable module as well as its arguments.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpCommandLine">
|
||
/// <para>The command line to be executed.</para>
|
||
/// <para>
|
||
/// The maximum length of this string is 1024 characters. If lpApplicationName is NULL, the module name portion of lpCommandLine is
|
||
/// limited to MAX_PATH characters.
|
||
/// </para>
|
||
/// <para>
|
||
/// The function can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a
|
||
/// <c>const</c> variable or a literal string). If this parameter is a constant string, the function may cause an access violation.
|
||
/// </para>
|
||
/// <para>
|
||
/// The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the
|
||
/// command line.
|
||
/// </para>
|
||
/// <para>
|
||
/// If both lpApplicationName and lpCommandLine are non-NULL, *lpApplicationName specifies the module to execute, and *lpCommandLine
|
||
/// specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console processes written
|
||
/// in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C programmers generally
|
||
/// repeat the module name as the first token in the command line.
|
||
/// </para>
|
||
/// <para>
|
||
/// If lpApplicationName is NULL, the first white space–delimited token of the command line specifies the module name. If you are
|
||
/// using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin
|
||
/// (see the explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended.
|
||
/// Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period
|
||
/// (.) with no extension, or if the file name contains a path, .exe is not appended. If the file name does not contain a directory
|
||
/// path, the system searches for the executable file in the following sequence:
|
||
/// </para>
|
||
/// <list type="number">
|
||
/// <item>
|
||
/// <term>The directory from which the application loaded.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The current directory for the parent process.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>
|
||
/// The directories that are listed in the PATH environment variable. Note that this function does not search the per-application
|
||
/// path specified by the <c>App Paths</c> registry key. To include this per-application path in the search sequence, use the
|
||
/// ShellExecute function.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>
|
||
/// The system adds a null character to the command line string to separate the file name from the arguments. This divides the
|
||
/// original string into two strings for internal processing.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="dwCreationFlags">
|
||
/// <para>
|
||
/// The flags that control how the process is created. The CREATE_DEFAULT_ERROR_MODE, CREATE_NEW_CONSOLE, and
|
||
/// CREATE_NEW_PROCESS_GROUP flags are enabled by default. You can specify additional flags as noted.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>CREATE_DEFAULT_ERROR_MODE 0x04000000</term>
|
||
/// <term>
|
||
/// The new process does not inherit the error mode of the calling process. Instead, the new process gets the current default error
|
||
/// mode. An application sets the current default error mode by calling SetErrorMode. This flag is enabled by default.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_NEW_CONSOLE 0x00000010</term>
|
||
/// <term>
|
||
/// The new process has a new console, instead of inheriting the parent's console. This flag cannot be used with the DETACHED_PROCESS
|
||
/// flag. This flag is enabled by default.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_NEW_PROCESS_GROUP 0x00000200</term>
|
||
/// <term>
|
||
/// The new process is the root process of a new process group. The process group includes all processes that are descendants of this
|
||
/// root process. The process identifier of the new process group is the same as the process identifier, which is returned in the
|
||
/// lpProcessInfo parameter. Process groups are used by the GenerateConsoleCtrlEvent function to enable sending a CTRL+C or
|
||
/// CTRL+BREAK signal to a group of console processes. This flag is enabled by default.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_SEPARATE_WOW_VDM 0x00000800</term>
|
||
/// <term>
|
||
/// This flag is only valid starting a 16-bit Windows-based application. If set, the new process runs in a private Virtual DOS
|
||
/// Machine (VDM). By default, all 16-bit Windows-based applications run in a single, shared VDM. The advantage of running separately
|
||
/// is that a crash only terminates the single VDM; any other programs running in distinct VDMs continue to function normally. Also,
|
||
/// 16-bit Windows-based applications that run in separate VDMs have separate input queues. That means that if one application stops
|
||
/// responding momentarily, applications in separate VDMs continue to receive input.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_SUSPENDED 0x00000004</term>
|
||
/// <term>
|
||
/// The primary thread of the new process is created in a suspended state, and does not run until the ResumeThread function is called.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>CREATE_UNICODE_ENVIRONMENT 0x00000400</term>
|
||
/// <term>
|
||
/// Indicates the format of the lpEnvironment parameter. If this flag is set, the environment block pointed to by lpEnvironment uses
|
||
/// Unicode characters. Otherwise, the environment block uses ANSI characters.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>EXTENDED_STARTUPINFO_PRESENT 0x00080000</term>
|
||
/// <term>
|
||
/// The process is created with extended startup information; the lpStartupInfo parameter specifies a STARTUPINFOEX structure.
|
||
/// Windows Server 2003: This value is not supported.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>
|
||
/// This parameter also controls the new process's priority class, which is used to determine the scheduling priorities of the
|
||
/// process's threads. For a list of values, see GetPriorityClass. If none of the priority class flags is specified, the priority
|
||
/// class defaults to NORMAL_PRIORITY_CLASS unless the priority class of the creating process is IDLE_PRIORITY_CLASS or
|
||
/// BELOW_NORMAL_PRIORITY_CLASS. In this case, the child process receives the default priority class of the calling process.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpEnvironment">
|
||
/// <para>
|
||
/// A pointer to an environment block for the new process. If this parameter is NULL, the new process uses an environment created
|
||
/// from the profile of the user specified by lpUsername.
|
||
/// </para>
|
||
/// <para>An environment block consists of a null-terminated block of null-terminated strings. Each string is in the following form:</para>
|
||
/// <para>name=value</para>
|
||
/// <para>Because the equal sign (=) is used as a separator, it must not be used in the name of an environment variable.</para>
|
||
/// <para>
|
||
/// An environment block can contain Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains
|
||
/// Unicode characters, be sure that dwCreationFlags includes CREATE_UNICODE_ENVIRONMENT. If this parameter is NULL and the
|
||
/// environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes CREATE_UNICODE_ENVIRONMENT.
|
||
/// </para>
|
||
/// <para>
|
||
/// An ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A Unicode
|
||
/// environment block is terminated by four zero bytes: two for the last string and two more to terminate the block.
|
||
/// </para>
|
||
/// <para>To retrieve a copy of the environment block for a specific user, use the CreateEnvironmentBlock function.</para>
|
||
/// </param>
|
||
/// <param name="lpCurrentDirectory">
|
||
/// <para>The full path to the current directory for the process. The string can also specify a UNC path.</para>
|
||
/// <para>
|
||
/// If this parameter is NULL, the new process will have the same current drive and directory as the calling process. (This feature
|
||
/// is provided primarily for shells that need to start an application and specify its initial drive and working directory.)
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpStartupInfo">
|
||
/// <para>A pointer to a STARTUPINFO or STARTUPINFOEX structure.</para>
|
||
/// <para>
|
||
/// If the <c>lpDesktop</c> member is NULL or an empty string, the new process inherits the desktop and window station of its parent
|
||
/// process. The function adds permission for the specified user account to the inherited window station and desktop. Otherwise, if
|
||
/// this member specifies a desktop, it is the responsibility of the application to add permission for the specified user account to
|
||
/// the specified window station and desktop, even for WinSta0\Default.
|
||
/// </para>
|
||
/// <para>Handles in STARTUPINFO or STARTUPINFOEX must be closed with CloseHandle when they are no longer needed.</para>
|
||
/// <para>
|
||
/// <c>Important</c> If the <c>dwFlags</c> member of the STARTUPINFO structure specifies <c>STARTF_USESTDHANDLES</c>, the standard
|
||
/// handle fields are copied unchanged to the child process without validation. The caller is responsible for ensuring that these
|
||
/// fields contain valid handle values. Incorrect values can cause the child process to misbehave or crash. Use the Application
|
||
/// Verifier runtime verification tool to detect invalid handles.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="lpProcessInformation">
|
||
/// <para>
|
||
/// A pointer to a PROCESS_INFORMATION structure that receives identification information for the new process, including a handle to
|
||
/// the process.
|
||
/// </para>
|
||
/// <para>Handles in PROCESS_INFORMATION must be closed with the CloseHandle function when they are no longer needed.</para>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the return value is nonzero.</para>
|
||
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
|
||
/// <para>
|
||
/// Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to
|
||
/// initialize, the process is terminated. To get the termination status of a process, call GetExitCodeProcess.
|
||
/// </para>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// By default, <c>CreateProcessWithTokenW</c> does not load the specified user's profile into the <c>HKEY_USERS</c> registry key.
|
||
/// This means that access to information in the <c>HKEY_CURRENT_USER</c> registry key may not produce results consistent with a
|
||
/// normal interactive logon. It is your responsibility to load the user's registry hive into <c>HKEY_USERS</c> by either using
|
||
/// LOGON_WITH_PROFILE, or by calling the LoadUserProfile function before calling this function.
|
||
/// </para>
|
||
/// <para>
|
||
/// If the lpEnvironment parameter is NULL, the new process uses an environment block created from the profile of the user specified
|
||
/// by lpUserName. If the HOMEDRIVE and HOMEPATH variables are not set, <c>CreateProcessWithTokenW</c> modifies the environment block
|
||
/// to use the drive and path of the user's working directory.
|
||
/// </para>
|
||
/// <para>
|
||
/// When created, the new process and thread handles receive full access rights (PROCESS_ALL_ACCESS and THREAD_ALL_ACCESS). For
|
||
/// either handle, if a security descriptor is not provided, the handle can be used in any function that requires an object handle of
|
||
/// that type. When a security descriptor is provided, an access check is performed on all subsequent uses of the handle before
|
||
/// access is granted. If access is denied, the requesting process cannot use the handle to gain access to the process or thread.
|
||
/// </para>
|
||
/// <para>To retrieve a security token, pass the process handle in the PROCESS_INFORMATION structure to the OpenProcessToken function.</para>
|
||
/// <para>
|
||
/// The process is assigned a process identifier. The identifier is valid until the process terminates. It can be used to identify
|
||
/// the process, or specified in the OpenProcess function to open a handle to the process. The initial thread in the process is also
|
||
/// assigned a thread identifier. It can be specified in the OpenThread function to open a handle to the thread. The identifier is
|
||
/// valid until the thread terminates and can be used to uniquely identify the thread within the system. These identifiers are
|
||
/// returned in PROCESS_INFORMATION.
|
||
/// </para>
|
||
/// <para>
|
||
/// The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is
|
||
/// waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because
|
||
/// <c>CreateProcessWithTokenW</c> returns without waiting for the new process to finish its initialization. For example, the
|
||
/// creating process would use <c>WaitForInputIdle</c> before trying to find a window associated with the new process.
|
||
/// </para>
|
||
/// <para>
|
||
/// The preferred way to shut down a process is by using the ExitProcess function, because this function sends notification of
|
||
/// approaching termination to all DLLs attached to the process. Other means of shutting down a process do not notify the attached
|
||
/// DLLs. Note that when a thread calls <c>ExitProcess</c>, other threads of the process are terminated without an opportunity to
|
||
/// execute any additional code (including the thread termination code of attached DLLs). For more information, see Terminating a Process.
|
||
/// </para>
|
||
/// <para>
|
||
/// To compile an application that uses this function, define _WIN32_WINNT as 0x0500 or later. For more information, see Using the
|
||
/// Windows Headers.
|
||
/// </para>
|
||
/// <para>Security Remarks</para>
|
||
/// <para>
|
||
/// The lpApplicationName parameter can be NULL, in which case the executable name must be the first white space–delimited string in
|
||
/// lpCommandLine. If the executable or path name has a space in it, there is a risk that a different executable could be run because
|
||
/// of the way the function parses spaces. The following example is dangerous because the function will attempt to run "Program.exe",
|
||
/// if it exists, instead of "MyApp.exe".
|
||
/// </para>
|
||
/// <para>
|
||
/// If a malicious user were to create an application called "Program.exe" on a system, any program that incorrectly calls
|
||
/// <c>CreateProcessWithTokenW</c> using the Program Files directory will run this application instead of the intended application.
|
||
/// </para>
|
||
/// <para>
|
||
/// To avoid this problem, do not pass NULL for lpApplicationName. If you do pass NULL for lpApplicationName, use quotation marks
|
||
/// around the executable path in lpCommandLine, as shown in the example below.
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-createprocesswithtokenw BOOL CreateProcessWithTokenW(
|
||
// HANDLE hToken, DWORD dwLogonFlags, LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
|
||
// LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation );
|
||
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
|
||
[PInvokeData("winbase.h", MSDNShortId = "b329866a-0c0d-4cb3-838c-36aac17c87ed")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
private static extern bool CreateProcessWithTokenW(HTOKEN hToken, ProcessLogonFlags dwLogonFlags, string lpApplicationName, [Optional] StringBuilder lpCommandLine, CREATE_PROCESS dwCreationFlags,
|
||
[In, Optional, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")] string[] lpEnvironment,
|
||
[Optional] string lpCurrentDirectory, in STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
|
||
|
||
/// <summary>Provides a context handle to an open encrypted file.</summary>
|
||
[StructLayout(LayoutKind.Sequential)]
|
||
public struct EncryptedFileContext : IHandle
|
||
{
|
||
private IntPtr handle;
|
||
|
||
/// <summary>Initializes a new instance of the <see cref="EncryptedFileContext"/> struct.</summary>
|
||
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
|
||
public EncryptedFileContext(IntPtr preexistingHandle) => handle = preexistingHandle;
|
||
|
||
/// <summary>Returns an invalid handle by instantiating a <see cref="EncryptedFileContext"/> object with <see cref="IntPtr.Zero"/>.</summary>
|
||
public static EncryptedFileContext NULL => new EncryptedFileContext(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="EncryptedFileContext"/> to <see cref="IntPtr"/>.</summary>
|
||
/// <param name="h">The handle.</param>
|
||
/// <returns>The result of the conversion.</returns>
|
||
public static explicit operator IntPtr(EncryptedFileContext h) => h.handle;
|
||
|
||
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="EncryptedFileContext"/>.</summary>
|
||
/// <param name="h">The pointer to a handle.</param>
|
||
/// <returns>The result of the conversion.</returns>
|
||
public static implicit operator EncryptedFileContext(IntPtr h) => new EncryptedFileContext(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 !=(EncryptedFileContext h1, EncryptedFileContext 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 ==(EncryptedFileContext h1, EncryptedFileContext h2) => h1.Equals(h2);
|
||
|
||
/// <inheritdoc/>
|
||
public override bool Equals(object obj) => obj is EncryptedFileContext h ? handle == h.handle : false;
|
||
|
||
/// <inheritdoc/>
|
||
public override int GetHashCode() => handle.GetHashCode();
|
||
|
||
/// <inheritdoc/>
|
||
public IntPtr DangerousGetHandle() => handle;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Contains information about a hardware profile. The GetCurrentHwProfile function uses this structure to retrieve the current
|
||
/// hardware profile for the local computer.
|
||
/// </summary>
|
||
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-hw_profile_infow typedef struct tagHW_PROFILE_INFOW {
|
||
// DWORD dwDockInfo; WCHAR szHwProfileGuid[HW_PROFILE_GUIDLEN]; WCHAR szHwProfileName[MAX_PROFILE_LEN]; } HW_PROFILE_INFOW, *LPHW_PROFILE_INFOW;
|
||
[PInvokeData("winbase.h", MSDNShortId = "b1c8eb4c-8c62-4e3e-a7d2-0888512b3d4c")]
|
||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||
public struct HW_PROFILE_INFO
|
||
{
|
||
/// <summary>The reported docking state of the computer. This member can be a combination of the following bit values.</summary>
|
||
public DOCKINFO dwDockInfo;
|
||
|
||
/// <summary>
|
||
/// <para>
|
||
/// The globally unique identifier (GUID) string for the current hardware profile. The string returned by GetCurrentHwProfile
|
||
/// encloses the GUID in curly braces, {}; for example:
|
||
/// </para>
|
||
/// <para>{12340001-4980-1920-6788-123456789012}</para>
|
||
/// <para>
|
||
/// You can use this string as a registry subkey under your application's configuration settings key in <c>HKEY_CURRENT_USER</c>.
|
||
/// This enables you to store settings for each hardware profile.
|
||
/// </para>
|
||
/// </summary>
|
||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 39)]
|
||
public string szHwProfileGuid;
|
||
|
||
/// <summary>The display name for the current hardware profile.</summary>
|
||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
|
||
public string szHwProfileName;
|
||
}
|
||
|
||
/// <summary>This structure is used by the OperationEnd function.</summary>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-operation_end_parameters typedef struct
|
||
// _OPERATION_END_PARAMETERS { ULONG Version; OPERATION_ID OperationId; ULONG Flags; } OPERATION_END_PARAMETERS, *POPERATION_END_PARAMETERS;
|
||
[PInvokeData("winbase.h", MSDNShortId = "45ABFE6A-7B70-418F-8C3C-6388079D1306")]
|
||
[StructLayout(LayoutKind.Sequential)]
|
||
public struct OPERATION_END_PARAMETERS
|
||
{
|
||
/// <summary>
|
||
/// <para>This parameter should be initialized to the <c>OPERATION_API_VERSION</c> defined in the Windows SDK.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>OPERATION_API_VERSION 1</term>
|
||
/// <term>This API was introduced in Windows 8 and Windows Server 2012 as version 1.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </summary>
|
||
public uint Version;
|
||
|
||
/// <summary>
|
||
/// Each operation has an OPERATION_ID namespace that is unique for each process. If two applications both use the same
|
||
/// <c>OPERATION_ID</c> value to identify two operations, the system maintains separate contexts for each operation.
|
||
/// </summary>
|
||
public uint OperationId;
|
||
|
||
/// <summary>
|
||
/// <para>The value of this parameter can include any combination of the following values.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>OPERATION_END_DISCARD 1</term>
|
||
/// <term>
|
||
/// Specifies that the system should discard the information it has been tracking for this operation. Specify this flag when the
|
||
/// operation either fails or does not follow the expected sequence of steps.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </summary>
|
||
public uint Flags;
|
||
|
||
/// <summary>Initializes a new instance of the <see cref="OPERATION_END_PARAMETERS"/> struct.</summary>
|
||
/// <param name="opId">An OPERATION_ID namespace that is unique for each process.</param>
|
||
/// <param name="singleThreadOnly">
|
||
/// if set to <c>true</c> specifies that the system should discard the information it has been tracking for this operation.
|
||
/// </param>
|
||
public OPERATION_END_PARAMETERS(uint opId, bool singleThreadOnly = false)
|
||
{
|
||
Version = OPERATION_API_VERSION;
|
||
OperationId = opId;
|
||
Flags = singleThreadOnly ? 1U : 0U;
|
||
}
|
||
}
|
||
|
||
/// <summary>This structure is used by the OperationStart function.</summary>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-operation_start_parameters typedef struct
|
||
// _OPERATION_START_PARAMETERS { ULONG Version; OPERATION_ID OperationId; ULONG Flags; } OPERATION_START_PARAMETERS, *POPERATION_START_PARAMETERS;
|
||
[PInvokeData("winbase.h", MSDNShortId = "51AE0017-2CDE-4BCD-AE03-B366343DE558")]
|
||
[StructLayout(LayoutKind.Sequential)]
|
||
public struct OPERATION_START_PARAMETERS
|
||
{
|
||
/// <summary>
|
||
/// <para>This parameter should be initialized to the <c>OPERATION_API_VERSION</c> value defined in the Windows SDK.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>OPERATION_API_VERSION 1</term>
|
||
/// <term>This API was introduced in Windows 8 and Windows Server 2012 as version 1.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </summary>
|
||
public uint Version;
|
||
|
||
/// <summary>
|
||
/// Each operation has an OPERATION_ID namespace that is unique for each process. If two applications both use the same
|
||
/// <c>OPERATION_ID</c> value to identify two operations, the system maintains separate contexts for each operation.
|
||
/// </summary>
|
||
public uint OperationId;
|
||
|
||
/// <summary>
|
||
/// <para>The value of this parameter can include any combination of the following values.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>OPERATION_START_TRACE_CURRENT_THREAD 1</term>
|
||
/// <term>
|
||
/// Specifies that the system should only track the activities of the calling thread in a multi-threaded application. Specify
|
||
/// this flag when the operation is performed on a single thread to isolate its activity from other threads in the process.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </summary>
|
||
public uint Flags;
|
||
|
||
/// <summary>Initializes a new instance of the <see cref="OPERATION_START_PARAMETERS"/> struct.</summary>
|
||
/// <param name="opId">An OPERATION_ID namespace that is unique for each process.</param>
|
||
/// <param name="singleThreadOnly">
|
||
/// if set to <c>true</c> specifies that the system should only track the activities of the calling thread in a multi-threaded application.
|
||
/// </param>
|
||
public OPERATION_START_PARAMETERS(uint opId, bool singleThreadOnly = false)
|
||
{
|
||
Version = OPERATION_API_VERSION;
|
||
OperationId = opId;
|
||
Flags = singleThreadOnly ? 1U : 0U;
|
||
}
|
||
}
|
||
|
||
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="EncryptedFileContext"/> that is disposed using <see cref="CloseEncryptedFileRaw"/>.</summary>
|
||
public class SafeEncryptedFileContext : SafeHANDLE
|
||
{
|
||
/// <summary>Initializes a new instance of the <see cref="SafeEncryptedFileContext"/> 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 SafeEncryptedFileContext(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
|
||
|
||
/// <summary>Initializes a new instance of the <see cref="SafeEncryptedFileContext"/> class.</summary>
|
||
private SafeEncryptedFileContext() : base() { }
|
||
|
||
/// <summary>Performs an implicit conversion from <see cref="SafeEncryptedFileContext"/> to <see cref="EncryptedFileContext"/>.</summary>
|
||
/// <param name="h">The safe handle instance.</param>
|
||
/// <returns>The result of the conversion.</returns>
|
||
public static implicit operator EncryptedFileContext(SafeEncryptedFileContext h) => h.handle;
|
||
|
||
/// <inheritdoc/>
|
||
protected override bool InternalReleaseHandle() { CloseEncryptedFileRaw(handle); return true; }
|
||
}
|
||
}
|
||
} |