diff --git a/PInvoke/Security/AdvApi32/LsaLookup.cs b/PInvoke/Security/AdvApi32/LsaLookup.cs index 8e532436..014b7a51 100644 --- a/PInvoke/Security/AdvApi32/LsaLookup.cs +++ b/PInvoke/Security/AdvApi32/LsaLookup.cs @@ -1,16 +1,32 @@ using System; using System.Runtime.InteropServices; using Vanara.Extensions; -using static Vanara.PInvoke.NetSecApi; namespace Vanara.PInvoke { public static partial class AdvApi32 { /// - /// The LSA_OBJECT_ATTRIBUTES structure is used with the LsaOpenPolicy function to specify the attributes of the connection to the Policy object. When - /// you call LsaOpenPolicy, initialize the members of this structure to NULL or zero because the function does not use the information. + /// + /// The LSA_OBJECT_ATTRIBUTES structure is used with the LsaOpenPolicy function to specify the attributes of the connection to + /// the Policy object. + /// + /// + /// When you call LsaOpenPolicy, initialize the members of this structure to NULL or zero because the function does not use + /// the information. + /// /// + /// + /// The LSA_OBJECT_ATTRIBUTES structure is defined in the LsaLookup.h header file. + /// + /// Windows Server 2008 with SP2 and earlier, Windows Vista with SP2 and earlier, Windows Server 2003, Windows XP/2000: The + /// LSA_OBJECT_ATTRIBUTES structure is defined in the NTSecAPI.h header file. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/lsalookup/ns-lsalookup-_lsa_object_attributes typedef struct + // _LSA_OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PLSA_UNICODE_STRING ObjectName; ULONG Attributes; PVOID + // SecurityDescriptor; PVOID SecurityQualityOfService; } LSA_OBJECT_ATTRIBUTES, *PLSA_OBJECT_ATTRIBUTES; + [PInvokeData("lsalookup.h", MSDNShortId = "ad05cb52-8e58-46a9-b3e8-0c9c2a24a997")] [StructLayout(LayoutKind.Sequential)] public struct LSA_OBJECT_ATTRIBUTES { @@ -33,7 +49,8 @@ namespace Vanara.PInvoke public IntPtr SecurityQualityOfService; /// - /// Returns a completely empty reference. This value should be used when calling . + /// Returns a completely empty reference. This value should be used when calling . /// /// An instance with all members set to NULL or zero. public static LSA_OBJECT_ATTRIBUTES Empty { get; } = new LSA_OBJECT_ATTRIBUTES(); @@ -48,13 +65,14 @@ namespace Vanara.PInvoke public struct LSA_STRING { /// - /// Specifies the length, in bytes, of the string pointed to by the Buffer member, not including the terminating null character, if any. + /// Specifies the length, in bytes, of the string pointed to by the Buffer member, not including the terminating null character, + /// if any. /// public ushort length; /// - /// Specifies the total size, in bytes, of the memory allocated for Buffer. Up to MaximumLength bytes can be written into the buffer without - /// trampling memory. + /// Specifies the total size, in bytes, of the memory allocated for Buffer. Up to MaximumLength bytes can be written into the + /// buffer without trampling memory. /// public ushort MaximumLength; @@ -95,32 +113,49 @@ namespace Vanara.PInvoke public static implicit operator string(LSA_STRING value) => value.ToString(); } - /// The LSA_TRANSLATED_NAME structure is used with the LsaLookupSids function to return information about the account identified by a SID. + /// + /// + /// The LSA_TRANSLATED_NAME structure is used with the LsaLookupSids function to return information about the account + /// identified by a SID. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/lsalookup/ns-lsalookup-_lsa_translated_name typedef struct + // _LSA_TRANSLATED_NAME { SID_NAME_USE Use; LSA_UNICODE_STRING Name; LONG DomainIndex; } LSA_TRANSLATED_NAME, *PLSA_TRANSLATED_NAME; + [PInvokeData("lsalookup.h", MSDNShortId = "edea8317-5cdf-4d1e-9e6d-fcf17b91adb7")] [StructLayout(LayoutKind.Sequential)] public struct LSA_TRANSLATED_NAME { - /// - /// An SID_NAME_USE enumeration value that identifies the type of SID. - /// + /// An SID_NAME_USE enumeration value that identifies the type of SID. public SID_NAME_USE Use; - /// An LSA_UNICODE_STRING structure that contains the isolated name of the translated SID. An isolated name is a user, group, or local group account name without the domain name (for example, user_name, rather than Acctg\user_name). + /// + /// An LSA_UNICODE_STRING structure that contains the isolated name of the translated SID. An isolated name is a user, group, or + /// local group account name without the domain name (for example, user_name, rather than Acctg\user_name). + /// public LSA_UNICODE_STRING Name; /// - /// The index of an entry in a related LSA_REFERENCED_DOMAIN_LIST data structure which describes the domain that owns the account. If there is no - /// corresponding reference domain for an entry, then DomainIndex will contain a negative value. + /// The index of an entry in a related LSA_REFERENCED_DOMAIN_LIST data structure which describes the domain that owns the + /// account. If there is no corresponding reference domain for an entry, then DomainIndex will contain a negative value. /// public int DomainIndex; } - /// Contains SIDs that are retrieved based on account names. This structure is used by the LsaLookupNames2 function. + /// + /// + /// The LSA_TRANSLATED_SID2 structure contains SIDs that are retrieved based on account names. This structure is used by the + /// LsaLookupNames2 function. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/lsalookup/ns-lsalookup-_lsa_translated_sid2 typedef struct + // _LSA_TRANSLATED_SID2 { SID_NAME_USE Use; PSID Sid; LONG DomainIndex; ULONG Flags; } LSA_TRANSLATED_SID2, *PLSA_TRANSLATED_SID2; + [PInvokeData("lsalookup.h", MSDNShortId = "792de958-8e24-46d8-b484-159435bc96e3")] [StructLayout(LayoutKind.Sequential)] public struct LSA_TRANSLATED_SID2 { /// - /// An SID_NAME_USE enumeration value that identifies the use of the SID. If this value is SidTypeUnknown or SidTypeInvalid, the rest of the - /// information in the structure is not valid and should be ignored. + /// An SID_NAME_USE enumeration value that identifies the use of the SID. If this value is SidTypeUnknown or SidTypeInvalid, the + /// rest of the information in the structure is not valid and should be ignored. /// public SID_NAME_USE Use; @@ -128,8 +163,8 @@ namespace Vanara.PInvoke public IntPtr Sid; /// - /// The index of an entry in a related LSA_REFERENCED_DOMAIN_LIST data structure which describes the domain that owns the account. If there is no - /// corresponding reference domain for an entry, then DomainIndex will contain a negative value. + /// The index of an entry in a related LSA_REFERENCED_DOMAIN_LIST data structure which describes the domain that owns the + /// account. If there is no corresponding reference domain for an entry, then DomainIndex will contain a negative value. /// public int DomainIndex; diff --git a/PInvoke/Security/AdvApi32/NTSecApi.cs b/PInvoke/Security/AdvApi32/NTSecApi.cs index 1d4423df..ba37cab1 100644 --- a/PInvoke/Security/AdvApi32/NTSecApi.cs +++ b/PInvoke/Security/AdvApi32/NTSecApi.cs @@ -6,7 +6,6 @@ using System.Security; using System.Text; using Vanara.Extensions; using Vanara.InteropServices; -using static Vanara.PInvoke.NetSecApi; namespace Vanara.PInvoke { @@ -18,15 +17,18 @@ namespace Vanara.PInvoke public enum LsaPolicyRights : uint { /// - /// This access type is needed to read the target system's miscellaneous security policy information. This includes the default quota, auditing, - /// server state and role information, and trust information. This access type is also needed to enumerate trusted domains, accounts, and privileges. + /// This access type is needed to read the target system's miscellaneous security policy information. This includes the default + /// quota, auditing, server state and role information, and trust information. This access type is also needed to enumerate + /// trusted domains, accounts, and privileges. /// POLICY_VIEW_LOCAL_INFORMATION = 1, /// This access type is needed to view audit trail or audit requirements information. POLICY_VIEW_AUDIT_INFORMATION = 2, - /// This access type is needed to view sensitive information, such as the names of accounts established for trusted domain relationships. + /// + /// This access type is needed to view sensitive information, such as the names of accounts established for trusted domain relationships. + /// POLICY_GET_PRIVATE_INFORMATION = 4, /// This access type is needed to change the account domain or primary domain information. @@ -48,14 +50,14 @@ namespace Vanara.PInvoke POLICY_SET_AUDIT_REQUIREMENTS = 0x100, /// - /// This access type is needed to change the characteristics of the audit trail such as its maximum size or the retention period for audit records, - /// or to clear the log. + /// This access type is needed to change the characteristics of the audit trail such as its maximum size or the retention period + /// for audit records, or to clear the log. /// POLICY_AUDIT_LOG_ADMIN = 0x200, /// - /// This access type is needed to modify the server state or role (master/replica) information. It is also needed to change the replica source and - /// account name information. + /// This access type is needed to modify the server state or role (master/replica) information. It is also needed to change the + /// replica source and account name information. /// POLICY_SERVER_ADMIN = 0x400, @@ -103,20 +105,23 @@ namespace Vanara.PInvoke } /// - /// The LsaAddAccountRights function assigns one or more privileges to an account. If the account does not exist, LsaAddAccountRights creates it. + /// The LsaAddAccountRights function assigns one or more privileges to an account. If the account does not exist, LsaAddAccountRights + /// creates it. /// /// - /// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. If the account identified by the AccountSid parameter does - /// not exist, the handle must have the POLICY_CREATE_ACCOUNT access right. For more information, see Opening a Policy Object Handle. + /// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. If the account identified by the + /// AccountSid parameter does not exist, the handle must have the POLICY_CREATE_ACCOUNT access right. For more information, see + /// Opening a Policy Object Handle. /// /// Pointer to the SID of the account to which the function assigns privileges. /// - /// Pointer to an array of strings. Each string contains the name of a privilege to add to the account. For a list of privilege names, see Privilege Constants. + /// Pointer to an array of strings. Each string contains the name of a privilege to add to the account. For a list of privilege + /// names, see Privilege Constants. /// /// Specifies the number of elements in the UserRights array. /// - /// If the function succeeds, the return value is STATUS_SUCCESS. If the function fails, the return value is an NTSTATUS code, which can be the following - /// value or one of the LSA Policy Function Return Values. + /// If the function succeeds, the return value is STATUS_SUCCESS. If the function fails, the return value is an NTSTATUS code, which + /// can be the following value or one of the LSA Policy Function Return Values. /// [DllImport(Lib.AdvApi32, ExactSpelling = true), SuppressUnmanagedCodeSecurity] [PInvokeData("ntsecapi.h", MSDNShortId = "ms721786")] @@ -126,36 +131,54 @@ namespace Vanara.PInvoke [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringArrayMarshaler))] string[] UserRights, int CountOfRights); + /// Undocumented function for creating an account. /// A handle to a Policy object. For more information, see Opening a Policy Object Handle. /// Pointer to the SID of the account for which to enumerate privileges. /// The desired access. /// The account handle. /// - /// If the function succeeds, the return value is STATUS_SUCCESS. If the function fails, the return value is an NTSTATUS code.For more information, see - /// LSA Policy Function Return Values. You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code. + /// If the function succeeds, the return value is STATUS_SUCCESS. If the function fails, the return value is an NTSTATUS code.For + /// more information, see LSA Policy Function Return Values. You can use the LsaNtStatusToWinError function to convert the NTSTATUS + /// code to a Windows error code. /// [DllImport(Lib.AdvApi32, ExactSpelling = true)] public static extern uint LsaCreateAccount(SafeLsaPolicyHandle PolicyHandle, PSID AccountSid, LsaAccountAccessMask DesiredAccess, out SafeLsaPolicyHandle AccountHandle); - /// The LsaEnumerateAccountRights function enumerates the privileges assigned to an account. + /// + /// The LsaEnumerateAccountRights function enumerates the privileges assigned to an account. + /// /// - /// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a Policy Object Handle. - /// - /// Pointer to the SID of the account for which to enumerate privileges. - /// - /// Receives a pointer to an array of LSA_UNICODE_STRING structures. Each structure contains the name of a privilege held by the account. For a list of - /// privilege names, see Privilege Constants. - /// - /// Pointer to a variable that receives the number of privileges in the UserRights array. - /// - /// If at least one account right is found, the function succeeds and returns STATUS_SUCCESS. /// - /// If no account rights are found or if the function fails for any other reason, the function returns an NTSTATUS code such as FILE_NOT_FOUND. For more - /// information, see LSA Policy Function Return Values. Use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code. + /// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a + /// Policy Object Handle. + /// + /// + /// + /// Pointer to the SID of the account for which to enumerate privileges. + /// + /// + /// + /// Receives a pointer to an array of LSA_UNICODE_STRING structures. Each structure contains the name of a privilege held by the + /// account. For a list of privilege names, see Privilege Constants + /// + /// When you no longer need the information, pass the returned pointer to LsaFreeMemory. + /// + /// + /// Pointer to a variable that receives the number of privileges in the UserRights array. + /// + /// + /// If at least one account right is found, the function succeeds and returns STATUS_SUCCESS. + /// + /// If no account rights are found or if the function fails for any other reason, the function returns an NTSTATUS code such as + /// FILE_NOT_FOUND. For more information, see LSA Policy Function Return Values. Use the LsaNtStatusToWinError function to convert + /// the NTSTATUS code to a Windows error code. /// /// - [DllImport(Lib.AdvApi32, ExactSpelling = true)] + // https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaenumerateaccountrights NTSTATUS + // LsaEnumerateAccountRights( LSA_HANDLE PolicyHandle, PSID AccountSid, PLSA_UNICODE_STRING *UserRights, PULONG CountOfRights ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ntsecapi.h", MSDNShortId = "3f4a4a9a-66ca-410a-8bdc-c390e8b966e3")] public static extern uint LsaEnumerateAccountRights( SafeLsaPolicyHandle PolicyHandle, PSID AccountSid, @@ -164,60 +187,103 @@ namespace Vanara.PInvoke /// The LsaEnumerateAccountRights function enumerates the privileges assigned to an account. /// - /// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a Policy Object Handle. + /// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a + /// Policy Object Handle. /// /// Pointer to the SID of the account for which to enumerate privileges. - /// An enumeration of strings containing the names of privileges held by the account. For a list of privilege names, see Privilege Constants. + /// + /// An enumeration of strings containing the names of privileges held by the account. For a list of privilege names, see Privilege Constants. + /// public static IEnumerable LsaEnumerateAccountRights(SafeLsaPolicyHandle PolicyHandle, PSID AccountSid) { var ret = LsaEnumerateAccountRights(PolicyHandle, AccountSid, out SafeLsaMemoryHandle mem, out uint cnt); var winErr = LsaNtStatusToWinError(ret); if (winErr == Win32Error.ERROR_FILE_NOT_FOUND) return new string[0]; winErr.ThrowIfFailed(); - return mem.DangerousGetHandle().ToIEnum((int) cnt).Select(u => (string) u.ToString().Clone()); + return mem.DangerousGetHandle().ToIEnum((int)cnt).Select(u => (string)u.ToString().Clone()); } /// - /// The LsaEnumerateAccountsWithUserRight function returns the accounts in the database of a Local Security Authority (LSA) Policy object that hold a - /// specified privilege. The accounts returned by this function hold the specified privilege directly through the user account, not as part of membership - /// to a group. + /// + /// The LsaEnumerateAccountsWithUserRight function returns the accounts in the database of a Local Security Authority (LSA) + /// Policy object that hold a specified privilege. The accounts returned by this function hold the specified privilege directly + /// through the user account, not as part of membership to a group. + /// /// /// - /// A handle to a Policy object. The handle must have POLICY_LOOKUP_NAMES and POLICY_VIEW_LOCAL_INFORMATION user rights. For more information, see - /// Opening a Policy Object Handle. + /// + /// A handle to a Policy object. The handle must have POLICY_LOOKUP_NAMES and POLICY_VIEW_LOCAL_INFORMATION user rights. For more + /// information, see Opening a Policy Object Handle. + /// /// - /// - /// A string that specifies the name of a privilege. For a list of privileges, see Privilege Constants and Account Rights Constants. - /// If this parameter is NULL, the function enumerates all accounts in the LSA database of the system associated with the Policy object. + /// + /// + /// Pointer to an LSA_UNICODE_STRING structure that specifies the name of a privilege. For a list of privileges, see Privilege + /// Constants and Account Rights Constants. + /// + /// + /// If this parameter is NULL, the function enumerates all accounts in the LSA database of the system associated with the + /// Policy object. + /// /// - /// - /// Pointer to a variable that receives a pointer to an array of LSA_ENUMERATION_INFORMATION structures. The Sid member of each structure is a pointer to - /// the security identifier (SID) of an account that holds the specified privilege. + /// + /// + /// Pointer to a variable that receives a pointer to an array of LSA_ENUMERATION_INFORMATION structures. The Sid member of + /// each structure is a pointer to the security identifier (SID) of an account that holds the specified privilege. + /// + /// When you no longer need the information, free the memory by passing the returned pointer to the LsaFreeMemory function. + /// + /// + /// Pointer to a variable that receives the number of entries returned in the EnumerationBuffer parameter. /// - /// Pointer to a variable that receives the number of entries returned in the EnumerationBuffer parameter. /// - /// If the function succeeds, the function returns STATUS_SUCCESS. If the function fails, it returns an NTSTATUS code, which can be one of the following - /// values or one of the LSA Policy Function Return Values. + /// If the function succeeds, the function returns STATUS_SUCCESS. + /// + /// If the function fails, it returns an NTSTATUS code, which can be one of the following values or one of the LSA Policy + /// Function Return Values. + /// + /// + /// + /// Value + /// Description + /// + /// + /// STATUS_NO_SUCH_PRIVILEGE + /// The privilege string specified was not a valid privilege. + /// + /// + /// STATUS_NO_MORE_ENTRIES + /// There were no accounts with the specified privilege. + /// + /// + /// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code. /// - [DllImport(Lib.AdvApi32, ExactSpelling = true)] + // https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaenumerateaccountswithuserright NTSTATUS + // LsaEnumerateAccountsWithUserRight( LSA_HANDLE PolicyHandle, PLSA_UNICODE_STRING UserRight, PVOID *Buffer, PULONG CountReturned ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ntsecapi.h", MSDNShortId = "97e7180e-4edb-4edd-915e-0477e7e7a9ff")] + // public static extern NTSTATUS LsaEnumerateAccountsWithUserRight(LSA_HANDLE PolicyHandle, PLSA_UNICODE_STRING UserRight, ref IntPtr + // Buffer, ref uint CountReturned); public static extern uint LsaEnumerateAccountsWithUserRight( SafeLsaPolicyHandle PolicyHandle, - [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string UserRights, - out SafeLsaMemoryHandle EnumerationBuffer, + [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string UserRight, + out SafeLsaMemoryHandle Buffer, out int CountReturned); /// - /// The LsaEnumerateAccountsWithUserRight function returns the accounts in the database of a Local Security Authority (LSA) Policy object that hold a - /// specified privilege. The accounts returned by this function hold the specified privilege directly through the user account, not as part of membership - /// to a group. + /// The LsaEnumerateAccountsWithUserRight function returns the accounts in the database of a Local Security Authority (LSA) Policy + /// object that hold a specified privilege. The accounts returned by this function hold the specified privilege directly through the + /// user account, not as part of membership to a group. /// /// - /// A handle to a Policy object. The handle must have POLICY_LOOKUP_NAMES and POLICY_VIEW_LOCAL_INFORMATION user rights. For more information, see - /// Opening a Policy Object Handle. + /// A handle to a Policy object. The handle must have POLICY_LOOKUP_NAMES and POLICY_VIEW_LOCAL_INFORMATION user rights. For more + /// information, see Opening a Policy Object Handle. /// /// /// A string that specifies the name of a privilege. For a list of privileges, see Privilege Constants and Account Rights Constants. - /// If this parameter is NULL, the function enumerates all accounts in the LSA database of the system associated with the Policy object. + /// + /// If this parameter is NULL, the function enumerates all accounts in the LSA database of the system associated with the Policy object. + /// /// /// An enumeration of security identifiers (SID) of accounts that holds the specified privilege. public static IEnumerable LsaEnumerateAccountsWithUserRight(SafeLsaPolicyHandle PolicyHandle, string UserRights) @@ -233,32 +299,160 @@ namespace Vanara.PInvoke public static extern uint LsaGetSystemAccessAccount(SafeLsaPolicyHandle AccountHandle, out int SystemAccess); /// - /// The LsaLookupNames2 function retrieves the security identifiers (SIDs) for specified account names. LsaLookupNames2 can look up the SID for any - /// account in any domain in a Windows forest. + /// + /// The LsaLookupNames2 function retrieves the security identifiers (SIDs) for specified account names. LsaLookupNames2 + /// can look up the SID for any account in any domain in a Windows forest. + /// + /// + /// The LsaLookupNames function is superseded by the LsaLookupNames2 function. Applications should use the + /// LsaLookupNames2 function to ensure future compatibility. + /// + /// + /// This function differs from the LsaLookupNames function in that LsaLookupNames2 returns each SID as a single element, while + /// LsaLookupNames divides each SID into an RID/domain pair. + /// /// /// - /// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a Policy Object Handle. + /// + /// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a + /// Policy Object Handle. + /// + /// + /// + /// Values that control the behavior of this function. The following value is currently defined. + /// + /// + /// Value + /// Meaning + /// + /// + /// LSA_LOOKUP_ISOLATED_AS_LOCAL 0x80000000 + /// + /// The function searches only on the local systems for names that do not specify a domain. The function does search on remote + /// systems for names that do specify a domain. + /// + /// + /// + /// + /// + /// Specifies the number of names in the Names array. This is also the number of entries returned in the Sids array. /// - /// Values that control the behavior of this function. - /// Specifies the number of names in the Names array. This is also the number of entries returned in the Sids array. /// - /// An array of strings that contain the names to look up. These strings can be the names of user, group, or local group accounts, or the names of - /// domains. Domain names can be DNS domain names or NetBIOS domain names. + /// + /// Pointer to an array of LSA_UNICODE_STRING structures that contain the names to look up. These strings can be the names of user, + /// group, or local group accounts, or the names of domains. Domain names can be DNS domain names or NetBIOS domain names. + /// + /// For more information about the format of the name strings, see Remarks. /// /// - /// Receives a pointer to an LSA_REFERENCED_DOMAIN_LIST structure. The Domains member of this structure is an array that contains an entry for each - /// domain in which a name was found. The DomainIndex member of each entry in the Sids array is the index of the Domains array entry for the domain in - /// which the name was found. + /// + /// Receives a pointer to an LSA_REFERENCED_DOMAIN_LIST structure. The Domains member of this structure is an array that + /// contains an entry for each domain in which a name was found. The DomainIndex member of each entry in the Sids array is the + /// index of the Domains array entry for the domain in which the name was found. + /// + /// + /// When you have finished using the returned pointer, free it by calling the LsaFreeMemory function. This memory must be freed even + /// when the function fails with the either of the error codes STATUS_NONE_MAPPED or STATUS_SOME_NOT_MAPPED + /// /// /// - /// Receives a pointer to an array of LSA_TRANSLATED_SID2 structures. Each entry in the Sids array contains the SID information for the corresponding - /// entry in the Names array. + /// + /// Receives a pointer to an array of LSA_TRANSLATED_SID2 structures. Each entry in the Sids array contains the SID information for + /// the corresponding entry in the Names array. + /// + /// + /// When you have finished using the returned pointer, free it by calling the LsaFreeMemory function. This memory must be freed even + /// when the function fails with the either of the error codes STATUS_NONE_MAPPED or STATUS_SOME_NOT_MAPPED + /// /// /// - /// If the function succeeds, the function returns one of the following NTSTATUS values. If the function fails, the return value is the following - /// NTSTATUS value or one of the LSA Policy Function Return Values. + /// If the function succeeds, the function returns one of the following NTSTATUS values. + /// + /// + /// Value + /// Description + /// + /// + /// STATUS_SOME_NOT_MAPPED + /// Some of the names could not be translated. This is an informational-level return value. + /// + /// + /// STATUS_SUCCESS + /// All of the names were found and successfully translated. + /// + /// + /// + /// If the function fails, the return value is the following NTSTATUS value or one of the LSA Policy Function Return Values. + /// + /// + /// + /// Value + /// Description + /// + /// + /// STATUS_NONE_MAPPED + /// None of the names were translated. + /// + /// + /// Use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code. /// - [DllImport(Lib.AdvApi32, CharSet = CharSet.Unicode, ExactSpelling = true)] + /// + /// + /// Use fully qualified account names (for example, DomainName<i>UserName) instead of isolated names (for example, UserName). + /// Fully qualified names are unambiguous and provide better performance when the lookup is performed. This function also supports + /// fully qualified DNS names (for example, Example.Example.com<i>UserName) and user principal names (UPN) (for example, Someone@Example.com). + /// + /// + /// Translation of isolated names introduces the possibility of name collisions because the same name may be used in multiple + /// domains. The LsaLookupNames2 function uses the following algorithm to translate isolated names. + /// + /// To translate isolated names + /// + /// + /// + /// If the name is a well-known name, such as Local or Interactive, the function returns the corresponding well-known security + /// identifier (SID). + /// + /// + /// + /// If the name is the name of the built-in domain, the function returns the SID of that domain. + /// + /// + /// If the name is the name of the account domain, the function returns the SID of that domain. + /// + /// + /// If the name is the name of the primary domain, the function returns the SID of that domain. + /// + /// + /// If the name is one of the names of the trusted domain, the function returns the SID of that domain. + /// + /// + /// If the name is a user, group, or local group account in the built-in domain, the function returns the SID of that account. + /// + /// + /// + /// If the name is a user, group, or local group account in the account domain on the local system, the function returns the SID of + /// that account. + /// + /// + /// + /// If the name is a user, group, or a local group in the primary domain, the function returns the SID of that account. + /// + /// + /// After looking in the primary domain, the function looks in each of the primary domain's trusted domains. + /// + /// + /// Otherwise, the name is not translated. + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsalookupnames2 NTSTATUS LsaLookupNames2( LSA_HANDLE + // PolicyHandle, ULONG Flags, ULONG Count, PLSA_UNICODE_STRING Names, PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains, + // PLSA_TRANSLATED_SID2 *Sids ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] + [PInvokeData("ntsecapi.h", MSDNShortId = "fe219070-6a00-4b8c-b2e4-2ad290a1cb9c")] + // public static extern NTSTATUS LsaLookupNames2(LSA_HANDLE PolicyHandle, uint Flags, uint Count, PLSA_UNICODE_STRING Names, ref + // PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains, ref PLSA_TRANSLATED_SID2 Sids); public static extern uint LsaLookupNames2( SafeLsaPolicyHandle PolicyHandle, LsaLookupNamesFlags Flags, @@ -268,21 +462,158 @@ namespace Vanara.PInvoke out SafeLsaMemoryHandle ReferencedDomains, out SafeLsaMemoryHandle Sids); - /// The LsaLookupSids2 function looks up the names that correspond to an array of security identifiers (SIDs) and supports Internet provider identities. If LsaLookupSids2 cannot find a name that corresponds to a SID, the function returns the SID in character form. You should use this function instead of the LsaLookupSids function. - /// A handle to a Policy object. This handle must have the POLICY_LOOKUP_NAMES access right. - /// Flags that modify the lookup behavior. - /// Specifies the number of SIDs in the Sids array. This is also the number of entries returned in the Names array. - /// Pointer to an array of SID pointers to look up. The SIDs can be well-known SIDs, user, group, or local group account SIDs, or domain SIDs. - /// Receives a pointer to a pointer to a LSA_REFERENCED_DOMAIN_LIST structure. The Domains member of this structure is an array that contains an entry for each domain in which a SID was found. The entry for each domain contains the SID and flat name of the domain. For Windows domains, the flat name is the NetBIOS name. For links with non–Windows domains, the flat name is the identifying name of that domain, or it is NULL. - /// When you no longer need the information, pass the returned pointer to LsaFreeMemory. This memory must be freed even when the function fails with the either of the error codes STATUS_NONE_MAPPED or STATUS_SOME_NOT_MAPPED - /// Receives a pointer to an array of LSA_TRANSLATED_NAME structures. Each entry in the Names array contains the name information for the corresponding entry in the Sids array. For account SIDs, the Name member of each structure contains the isolated name of the account. For domain SIDs, the Name member is not valid. - /// The DomainIndex member of each entry in the Names array is the index of an entry in the Domains array returned in the ReferencedDomains parameter. The index identifies the Domains array for the domain in which the SID was found. - /// When you no longer need the information, pass the returned pointer to LsaFreeMemory. This memory must be freed even when the function fails with the either of the error codes STATUS_NONE_MAPPED or STATUS_SOME_NOT_MAPPED + /// + /// + /// The LsaLookupSids2 function looks up the names that correspond to an array of security identifiers (SIDs) and supports + /// Internet provider identities. If LsaLookupSids2 cannot find a name that corresponds to a SID, the function returns the SID + /// in character form. You should use this function instead of the LsaLookupSids function. + /// + /// + /// + /// + /// A handle to a Policy object. This handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a + /// Policy Object Handle. + /// + /// + /// + /// Flags that modify the lookup behavior. + /// + /// + /// Value + /// Meaning + /// + /// + /// LSA_LOOKUP_DISALLOW_CONNECTED_ACCOUNT_INTERNET_SID + /// + /// Internet SIDs from identity providers for connected accounts are disallowed. Connected accounts are those accounts which have a + /// corresponding shadow account in the local SAM database connected to an online identity provider. For example, MicrosoftAccount is + /// a connected account. + /// + /// + /// + /// LSA_LOOKUP_PREFER_INTERNET_NAMES + /// + /// Returns the internet names. Otherwise the NT4 style name (domain\username) is returned. The exception is if the Microsoft Account + /// internet SID is specified, in which case the internet name is returned unless LSA_LOOKUP_DISALLOW_NON_WINDOWS_INTERNET_SID is specified. + /// + /// + /// + /// LSA_LOOKUP_RETURN_LOCAL_NAMES + /// Always returns local SAM account names even for Internet provider identities. + /// + /// + /// + /// + /// Specifies the number of SIDs in the Sids array. This is also the number of entries returned in the Names array. + /// + /// + /// + /// Pointer to an array of SID pointers to look up. The SIDs can be well-known SIDs, user, group, or local group account SIDs, or + /// domain SIDs. + /// + /// + /// + /// + /// Receives a pointer to a pointer to a LSA_REFERENCED_DOMAIN_LIST structure. The Domains member of this structure is an + /// array that contains an entry for each domain in which a SID was found. The entry for each domain contains the SID and flat name + /// of the domain. For Windows domains, the flat name is the NetBIOS name. For links with non–Windows domains, the flat name is the + /// identifying name of that domain, or it is NULL. + /// + /// + /// When you no longer need the information, pass the returned pointer to LsaFreeMemory. This memory must be freed even when the + /// function fails with the either of the error codes STATUS_NONE_MAPPED or STATUS_SOME_NOT_MAPPED + /// + /// + /// + /// + /// Receives a pointer to an array of LSA_TRANSLATED_NAME structures. Each entry in the Names array contains the name information for + /// the corresponding entry in the Sids array. For account SIDs, the Name member of each structure contains the isolated name + /// of the account. For domain SIDs, the Name member is not valid. + /// + /// + /// The DomainIndex member of each entry in the Names array is the index of an entry in the Domains array returned in + /// the ReferencedDomains parameter. The index identifies the Domains array for the domain in which the SID was found. + /// + /// + /// When you no longer need the information, pass the returned pointer to LsaFreeMemory. This memory must be freed even when the + /// function fails with the either of the error codes STATUS_NONE_MAPPED or STATUS_SOME_NOT_MAPPED + /// + /// /// - /// If the function succeeds, the function returns one of the following NTSTATUS values. If the function fails, the return value is the following - /// NTSTATUS value or one of the LSA Policy Function Return Values. + /// If the function succeeds, the return value is one of the following NTSTATUS values. + /// + /// + /// Return code + /// Description + /// + /// + /// STATUS_SOME_NOT_MAPPED + /// Some of the SIDs could not be translated. This is an informational-level return value. + /// + /// + /// STATUS_SUCCESS + /// All of the SIDs were found and successfully translated. + /// + /// + /// + /// If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the LSA + /// Policy Function Return Values. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// STATUS_NONE_MAPPED + /// None of the SIDs were translated. This is an error-level return value. + /// + /// + /// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code. /// - [DllImport(Lib.AdvApi32, CharSet = CharSet.Unicode, ExactSpelling = true)] + /// + /// + /// The flag LSA_LOOKUP_PREFER_INTERNET_NAMES should be used for internet accounts such as MicrosoftAccount and Azure Active + /// Directory accounts. When this flag is specified then SID-Name lookup returns the UPN of the account in the form + /// MicrosoftAccount\foo@outlook.com or AzureAD\foo@contoso.com. For Microsoft Accounts both the local SAM SID and the internet SID + /// result in the UPN being returned if this flag is specified. If LSA_LOOKUP_PREFER_INTERNET_NAMES is not specified then for AAD + /// accounts the NT4 style name of the form AzureAD\foo is returned. The NT4 style name is machine specific and its usage should be + /// carefully evaluated and if possible should be avoided. For MicrosoftAccounts if LSA_LOOKUP_PREFER_INTERNET_NAMES is not specified + /// then the local SID of the account translates to the local SAM name, and the internet SID translates to the UPN name. + /// + /// + /// For account SIDs, the string returned in the Name member is the isolated name of the account (for example, user_name). If + /// you need the composite name of the account (for example, Acctg\user_name), get the domain name from the ReferencedDomains buffer + /// and append a backslash and the isolated name. + /// + /// If the LsaLookupSids2 function cannot translate a SID, the function uses the following algorithm: + /// + /// + /// + /// If the SID's domain is known, the ReferencedDomains buffer contains an entry for the domain, and the string returned in the Names + /// parameter is a Unicode representation of the account's relative identifier (RID) from the SID. + /// + /// + /// + /// + /// If the SID's domain is not known, the string returned in the Names parameter is a Unicode representation of the entire SID, and + /// there is no domain record for this SID in the ReferencedDomains buffer. + /// + /// + /// + /// + /// In addition to looking up SIDs for local accounts, local domain accounts, and explicitly trusted domain accounts, + /// LsaLookupSids2 can look up SIDs for any account in any domain in the Windows forest, including SIDs that appear only in + /// the SIDhistory field of an account in the forest. The SIDhistory field stores the former SIDs of an account that + /// has been moved from another domain. To perform these searches, the function queries the global catalog of the forest. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsalookupsids2 NTSTATUS LsaLookupSids2( LSA_HANDLE + // PolicyHandle, ULONG LookupOptions, ULONG Count, PSID *Sids, PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains, PLSA_TRANSLATED_NAME + // *Names ); public static extern NTSTATUS LsaLookupSids2(LSA_HANDLE PolicyHandle, uint LookupOptions, uint Count, ref PSID Sids, ref + // PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains, ref PLSA_TRANSLATED_NAME Names); + [PInvokeData("ntsecapi.h", MSDNShortId = "6B30D1FF-35DC-44E8-A765-36A5761EC0CE")] + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] public static extern uint LsaLookupSids2( SafeLsaPolicyHandle PolicyHandle, LsaLookupSidsFlags LookupOptions, @@ -291,40 +622,75 @@ namespace Vanara.PInvoke out SafeLsaMemoryHandle ReferencedDomains, out SafeLsaMemoryHandle Names); - /// The LsaNtStatusToWinError function converts an NTSTATUS code returned by an LSA function to a Windows error code. - /// An NTSTATUS code returned by an LSA function call. This value will be converted to a System error code. + /// + /// The LsaNtStatusToWinError function converts an NTSTATUS code returned by an LSA function to a Windows error code. + /// + /// + /// An NTSTATUS code returned by an LSA function call. This value will be converted to a System error code. + /// /// - /// The return value is the Windows error code that corresponds to the Status parameter. If there is no corresponding Windows error code, the return - /// value is ERROR_MR_MID_NOT_FOUND. + /// + /// The return value is the Windows error code that corresponds to the Status parameter. If there is no corresponding Windows error + /// code, the return value is ERROR_MR_MID_NOT_FOUND. + /// /// - [DllImport(Lib.AdvApi32, ExactSpelling = true)] - public static extern Win32Error LsaNtStatusToWinError(uint NTSTATUS); + // https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsantstatustowinerror ULONG LsaNtStatusToWinError( + // NTSTATUS Status ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ntsecapi.h", MSDNShortId = "fa91794c-c502-4b36-84cc-a8d77c8e9d9f")] + // public static extern uint LsaNtStatusToWinError(NTSTATUS Status); + public static extern Win32Error LsaNtStatusToWinError(uint Status); [DllImport(Lib.AdvApi32, ExactSpelling = true)] public static extern uint LsaOpenAccount(SafeLsaPolicyHandle PolicyHandle, PSID AccountSid, LsaAccountAccessMask DesiredAccess, out SafeLsaPolicyHandle AccountHandle); /// - /// The LsaOpenPolicy function opens a handle to the Policy object on a local or remote system. You must run the process "As Administrator" so that the - /// call doesn't fail with ERROR_ACCESS_DENIED. + /// The LsaOpenPolicy function opens a handle to the Policy object on a local or remote system. + /// You must run the process "As Administrator" so that the call doesn't fail with ERROR_ACCESS_DENIED. /// /// - /// Name of the target system. The name can have the form "ComputerName" or "\\ComputerName". If this parameter is NULL, the function opens the Policy - /// object on the local system. + /// + /// A pointer to an LSA_UNICODE_STRING structure that contains the name of the target system. The name can have the form + /// "ComputerName" or "\ComputerName". If this parameter is NULL, the function opens the Policy object on the local system. + /// /// /// - /// A pointer to an LSA_OBJECT_ATTRIBUTES structure that specifies the connection attributes. The structure members are not used; initialize them to NULL - /// or zero. + /// + /// A pointer to an LSA_OBJECT_ATTRIBUTES structure that specifies the connection attributes. The structure members are not used; + /// initialize them to NULL or zero. + /// /// /// - /// An ACCESS_MASK that specifies the requested access rights. The function fails if the DACL of the target system does not allow the caller the - /// requested access. To determine the access rights that you need, see the documentation for the LSA functions with which you want to use the policy handle. + /// + /// An ACCESS_MASK that specifies the requested access rights. The function fails if the DACL of the target system does not allow the + /// caller the requested access. To determine the access rights that you need, see the documentation for the LSA functions with which + /// you want to use the policy handle. + /// + /// + /// + /// A pointer to an LSA_HANDLE variable that receives a handle to the Policy object. + /// When you no longer need this handle, pass it to the LsaClose function to close it. /// - /// A pointer to an LSA_HANDLE variable that receives a handle to the Policy object. /// - /// If the function succeeds, the function returns STATUS_SUCCESS. If the function fails, it returns an NTSTATUS code.For more information, see LSA - /// Policy Function Return Values. + /// If the function succeeds, the function returns STATUS_SUCCESS. + /// If the function fails, it returns an NTSTATUS code. For more information, see LSA Policy Function Return Values. + /// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code. /// - [DllImport(Lib.AdvApi32, ExactSpelling = true), SuppressUnmanagedCodeSecurity] + /// + /// + /// To administer the local security policy of a local or remote system, you must call the LsaOpenPolicy function to establish + /// a session with that system's LSA subsystem. LsaOpenPolicy connects to the LSA of the target system and returns a handle to + /// the Policy object of that system. You can use this handle in subsequent LSA function calls to administer the local security + /// policy information of the target system. + /// + /// For an example that demonstrates calling this function see Opening a Policy Object Handle. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaopenpolicy NTSTATUS LsaOpenPolicy( + // PLSA_UNICODE_STRING SystemName, PLSA_OBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK DesiredAccess, PLSA_HANDLE PolicyHandle ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ntsecapi.h", MSDNShortId = "361bc962-1e97-4606-a835-cbce37692c55")] + // public static extern NTSTATUS LsaOpenPolicy(PLSA_UNICODE_STRING SystemName, PLSA_OBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK + // DesiredAccess, PLSA_HANDLE PolicyHandle); public static extern uint LsaOpenPolicy( [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, @@ -332,16 +698,17 @@ namespace Vanara.PInvoke out SafeLsaPolicyHandle PolicyHandle); /// - /// The LsaOpenPolicy function opens a handle to the Policy object on a local or remote system. You must run the process "As Administrator" so that the - /// call doesn't fail with ERROR_ACCESS_DENIED. + /// The LsaOpenPolicy function opens a handle to the Policy object on a local or remote system. You must run the process "As + /// Administrator" so that the call doesn't fail with ERROR_ACCESS_DENIED. /// /// - /// An ACCESS_MASK that specifies the requested access rights. The function fails if the DACL of the target system does not allow the caller the - /// requested access. To determine the access rights that you need, see the documentation for the LSA functions with which you want to use the policy handle. + /// An ACCESS_MASK that specifies the requested access rights. The function fails if the DACL of the target system does not allow the + /// caller the requested access. To determine the access rights that you need, see the documentation for the LSA functions with which + /// you want to use the policy handle. /// /// - /// Name of the target system. The name can have the form "ComputerName" or "\\ComputerName". If this parameter is NULL, the function opens the Policy - /// object on the local system. + /// Name of the target system. The name can have the form "ComputerName" or "\\ComputerName". If this parameter is NULL, the function + /// opens the Policy object on the local system. /// /// A pointer to an LSA_HANDLE variable that receives a handle to the Policy object. public static SafeLsaPolicyHandle LsaOpenPolicy(LsaPolicyRights DesiredAccess, string SystemName = null) @@ -352,27 +719,64 @@ namespace Vanara.PInvoke } /// - /// The LsaRemoveAccountRights function removes one or more privileges from an account. You can specify the privileges to be removed, or you can set a - /// flag to remove all privileges. When you remove all privileges, the function deletes the account. If you specify privileges not held by the account, - /// the function ignores them. + /// + /// The LsaRemoveAccountRights function removes one or more privileges from an account. You can specify the privileges to be + /// removed, or you can set a flag to remove all privileges. When you remove all privileges, the function deletes the account. If you + /// specify privileges not held by the account, the function ignores them. + /// /// /// - /// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a Policy Object Handle. + /// + /// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a + /// Policy Object Handle. + /// + /// + /// + /// Pointer to the security identifier (SID) of the account from which the privileges are removed. /// - /// Pointer to the security identifier (SID) of the account from which the privileges are removed. /// - /// If TRUE, the function removes all privileges and deletes the account. In this case, the function ignores the UserRights parameter. If FALSE, the - /// function removes the privileges specified by the UserRights parameter. + /// + /// If TRUE, the function removes all privileges and deletes the account. In this case, the function ignores the UserRights + /// parameter. If FALSE, the function removes the privileges specified by the UserRights parameter. + /// /// /// - /// An array of strings. Each string contains the name of a privilege to be removed from the account. For a list of privilege names, see Privilege Constants. + /// + /// Pointer to an array of LSA_UNICODE_STRING structures. Each structure contains the name of a privilege to be removed from the + /// account. For a list of privilege names, see Privilege Constants. + /// + /// + /// + /// Specifies the number of elements in the UserRights array. /// - /// Specifies the number of elements in the UserRights array. /// - /// If the function succeeds, the return value is STATUS_SUCCESS. If the function fails, the return value is an NTSTATUS code, which can be one of the - /// following values or one of the LSA Policy Function Return Values. + /// If the function succeeds, the return value is STATUS_SUCCESS. + /// + /// If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the LSA Policy + /// Function Return Values. + /// + /// + /// + /// Value + /// Description + /// + /// + /// STATUS_NO_SUCH_PRIVILEGE + /// One of the privilege names is not valid. + /// + /// + /// STATUS_INVALID_PARAMETER + /// Indicates the UserRights parameter was NULL and the AllRights parameter was FALSE. + /// + /// + /// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code. /// - [DllImport(Lib.AdvApi32, ExactSpelling = true)] + // https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaremoveaccountrights NTSTATUS LsaRemoveAccountRights( + // LSA_HANDLE PolicyHandle, PSID AccountSid, BOOLEAN AllRights, PLSA_UNICODE_STRING UserRights, ULONG CountOfRights ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ntsecapi.h", MSDNShortId = "ad250a01-7a24-4fae-975c-aa3e65731c82")] + // public static extern NTSTATUS LsaRemoveAccountRights(LSA_HANDLE PolicyHandle, PSID AccountSid, [MarshalAs(UnmanagedType.U1)] bool + // AllRights, PLSA_UNICODE_STRING UserRights, uint CountOfRights); public static extern uint LsaRemoveAccountRights( SafeLsaPolicyHandle PolicyHandle, PSID AccountSid, @@ -385,44 +789,97 @@ namespace Vanara.PInvoke /// The account handle. /// The system access. /// - /// If the function succeeds, the return value is STATUS_SUCCESS. If the function fails, the return value is an NTSTATUS code, which can be one of the - /// following values or one of the LSA Policy Function Return Values. + /// If the function succeeds, the return value is STATUS_SUCCESS. If the function fails, the return value is an NTSTATUS code, which + /// can be one of the following values or one of the LSA Policy Function Return Values. /// [DllImport(Lib.AdvApi32, ExactSpelling = true)] public static extern uint LsaSetSystemAccessAccount(SafeLsaPolicyHandle AccountHandle, int SystemAccess); - /// The LsaClose function closes a handle to a Policy or TrustedDomain object. + /// + /// The LsaClose function closes a handle to a Policy or TrustedDomain object. + /// /// - /// A handle to a Policy object returned by the LsaOpenPolicy function or to a TrustedDomain object returned by the LsaOpenTrustedDomainByName function. - /// Following the completion of this call, the handle is no longer valid. + /// + /// A handle to a Policy object returned by the LsaOpenPolicy function or to a TrustedDomain object returned by the + /// LsaOpenTrustedDomainByName function. Following the completion of this call, the handle is no longer valid. + /// /// /// - /// If the function succeeds, the return value is STATUS_SUCCESS. If the function fails, the return value is an NTSTATUS code.For more information, see - /// LSA Policy Function Return Values. You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code. + /// If the function succeeds, the return value is STATUS_SUCCESS. + /// If the function fails, the return value is an NTSTATUS code. For more information, see LSA Policy Function Return Values. + /// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code. /// - [DllImport(Lib.AdvApi32, ExactSpelling = true)] + // https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaclose NTSTATUS LsaClose( LSA_HANDLE ObjectHandle ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ntsecapi.h", MSDNShortId = "6283b1da-4ec3-48e1-91f6-321c6390befe")] + // public static extern NTSTATUS LsaClose(LSA_HANDLE ObjectHandle); private static extern uint LsaClose(IntPtr ObjectHandle); /// - /// The LsaFreeMemory function frees memory allocated for an output buffer by an LSA function call. LSA functions that return variable-length output - /// buffers always allocate the buffer on behalf of the caller. The caller must free this memory by passing the returned buffer pointer to LsaFreeMemory - /// when the memory is no longer required. + /// + /// The LsaFreeMemory function frees memory allocated for an output buffer by an LSA function call. LSA functions that return + /// variable-length output buffers always allocate the buffer on behalf of the caller. The caller must free this memory by passing + /// the returned buffer pointer to LsaFreeMemory when the memory is no longer required. + /// /// - /// Pointer to memory buffer that was allocated by an LSA function call. If LsaFreeMemory is successful, this buffer is freed. + /// + /// + /// Pointer to memory buffer that was allocated by an LSA function call. If LsaFreeMemory is successful, this buffer is freed. + /// + /// /// - /// If the function succeeds, the return value is STATUS_SUCCESS. If the function fails, the return value is an NTSTATUS code, which can be the following - /// value or one of the LSA Policy Function Return Values. + /// If the function succeeds, the return value is STATUS_SUCCESS. + /// + /// If the function fails, the return value is an NTSTATUS code, which can be the following value or one of the LSA Policy Function + /// Return Values. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// STATUS_UNSUCCESSFUL + /// Memory could not be freed because it was not allocated by an LSA function call. + /// + /// + /// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code. /// - [DllImport(Lib.AdvApi32, ExactSpelling = true)] + // https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsafreememory NTSTATUS LsaFreeMemory( PVOID Buffer ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ntsecapi.h", MSDNShortId = "6eb3d18f-c54c-4e51-8a4b-b7a3f930cfa9")] + // public static extern NTSTATUS LsaFreeMemory(IntPtr Buffer); private static extern uint LsaFreeMemory(IntPtr Buffer); - /// The LsaFreeReturnBuffer function frees the memory used by a buffer previously allocated by the LSA. - /// Pointer to the buffer to be freed. - /// If the function succeeds, the return value is STATUS_SUCCESS. If the function fails, the return value is an NTSTATUS code. - [DllImport(Lib.Secur32, ExactSpelling = true)] + /// + /// The LsaFreeReturnBuffer function frees the memory used by a buffer previously allocated by the LSA. + /// + /// + /// Pointer to the buffer to be freed. + /// + /// + /// If the function succeeds, the return value is STATUS_SUCCESS. + /// If the function fails, the return value is an NTSTATUS code. For more information, see LSA Policy Function Return Values. + /// The LsaNtStatusToWinError function converts an NTSTATUS code to a Windows error code. + /// + /// + /// + /// Some of the LSA authentication functions allocate memory buffers to hold returned information, for example, LsaLogonUser and + /// LsaCallAuthenticationPackage. Your application should call LsaFreeReturnBuffer to free these buffers when they are no + /// longer needed. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsafreereturnbuffer _IRQL_requires_same_ NTSTATUS + // LsaFreeReturnBuffer( PVOID Buffer ); + [DllImport(Lib.Secur32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ntsecapi.h", MSDNShortId = "e814ed68-07e7-4936-ba96-5411086f43f6")] + // public static extern _IRQL_requires_same_ NTSTATUS LsaFreeReturnBuffer(IntPtr Buffer); private static extern uint LsaFreeReturnBuffer(IntPtr Buffer); /// Used with the LsaEnumerateAccountsWithUserRight function to return a pointer to a SID. + // https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-_lsa_enumeration_information typedef struct + // _LSA_ENUMERATION_INFORMATION { PSID Sid; } LSA_ENUMERATION_INFORMATION, *PLSA_ENUMERATION_INFORMATION; + [PInvokeData("ntsecapi.h", MSDNShortId = "7577548f-3ceb-43a5-b447-6f66a09963fe")] [StructLayout(LayoutKind.Sequential)] public struct LSA_ENUMERATION_INFORMATION { @@ -430,7 +887,10 @@ namespace Vanara.PInvoke public IntPtr Sid; } - /// Contains information about the domains referenced in a lookup operation. + /// The LSA_REFERENCED_DOMAIN_LIST structure contains information about the domains referenced in a lookup operation. + // typedef struct _LSA_REFERENCED_DOMAIN_LIST { ULONG Entries; PLSA_TRUST_INFORMATION Domains;} LSA_REFERENCED_DOMAIN_LIST, + // *PLSA_REFERENCED_DOMAIN_LIST; https://msdn.microsoft.com/en-us/library/windows/desktop/ms721834(v=vs.85).aspx + [PInvokeData("Ntsecapi.h", MSDNShortId = "ms721834")] [StructLayout(LayoutKind.Sequential)] public struct LSA_REFERENCED_DOMAIN_LIST { @@ -444,7 +904,19 @@ namespace Vanara.PInvoke public IEnumerable DomainList => Domains == IntPtr.Zero ? new LSA_TRUST_INFORMATION[0] : Domains.ToIEnum((int)Entries); } - /// Identifies a domain. + /// + /// The LSA_TRUST_INFORMATION structure identifies a domain. + /// + /// + /// TRUSTED_DOMAIN_INFORMATION_BASIC is an alias for this structure. + /// + /// The TRUSTED_DOMAIN_INFORMATION_BASIC structure identifies a domain. This structure is used by the LsaQueryTrustedDomainInfo + /// function when its InformationClass parameter is set to TrustedDomainInformationBasic. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/lsalookup/ns-lsalookup-_lsa_trust_information typedef struct + // _LSA_TRUST_INFORMATION { LSA_UNICODE_STRING Name; PSID Sid; } LSA_TRUST_INFORMATION, *PLSA_TRUST_INFORMATION; + [PInvokeData("lsalookup.h", MSDNShortId = "2b5e6f79-b97a-4018-a45a-37c300c3dc0d")] [StructLayout(LayoutKind.Sequential)] public struct LSA_TRUST_INFORMATION { @@ -455,6 +927,66 @@ namespace Vanara.PInvoke public IntPtr Sid; } + /// + /// The LSA_UNICODE_STRING structure is used by various Local Security Authority (LSA) functions to specify a Unicode string. Also an + /// example of unnecessary over-engineering and re-engineering. + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Size = 8)] + [PInvokeData("Ntsecapi.h", MSDNShortId = "ms721841")] + public struct LSA_UNICODE_STRING + { + /// + /// Specifies the length, in bytes, of the string pointed to by the Buffer member, not including the terminating null character, + /// if any. + /// + public ushort length; + + /// + /// Specifies the total size, in bytes, of the memory allocated for Buffer. Up to MaximumLength bytes can be written into the + /// buffer without trampling memory. + /// + public ushort MaximumLength; + + /// + /// Pointer to a wide character string. Note that the strings returned by the various LSA functions might not be null-terminated. + /// + public string Buffer; + + /// Initializes a new instance of the struct from a string. + /// The string value. + /// String exceeds 32Kb of data. + public LSA_UNICODE_STRING(string s) + { + if (s == null) + { + length = MaximumLength = 0; + Buffer = null; + } + else + { + var l = s.Length * UnicodeEncoding.CharSize; + // Unicode strings max. 32KB + if (l >= ushort.MaxValue) + throw new ArgumentException("String too long"); + Buffer = s; + length = (ushort)l; + MaximumLength = (ushort)(l + UnicodeEncoding.CharSize); + } + } + + /// Gets the number of characters in the string. + public int Length => length / UnicodeEncoding.CharSize; + + /// Returns a that represents this instance. + /// A that represents this instance. + public override string ToString() => Buffer; + + /// Performs an implicit conversion from to . + /// The value. + /// The result of the conversion. + public static implicit operator string(LSA_UNICODE_STRING value) => value.ToString(); + } + /// A for values that must be freed using the function. public sealed class SafeLsaMemoryHandle : GenericSafeHandle { @@ -505,63 +1037,6 @@ namespace Vanara.PInvoke private static bool Free(IntPtr h) => LsaFreeReturnBuffer(h) == 0; } - /// - /// The LSA_UNICODE_STRING structure is used by various Local Security Authority (LSA) functions to specify a Unicode string. Also an example of - /// unnecessary over-engineering and re-engineering. - /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Size = 8)] - [PInvokeData("Ntsecapi.h", MSDNShortId = "ms721841")] - public struct LSA_UNICODE_STRING - { - /// - /// Specifies the length, in bytes, of the string pointed to by the Buffer member, not including the terminating null character, if any. - /// - public ushort length; - - /// - /// Specifies the total size, in bytes, of the memory allocated for Buffer. Up to MaximumLength bytes can be written into the buffer without - /// trampling memory. - /// - public ushort MaximumLength; - - /// Pointer to a wide character string. Note that the strings returned by the various LSA functions might not be null-terminated. - public string Buffer; - - /// Initializes a new instance of the struct from a string. - /// The string value. - /// String exceeds 32Kb of data. - public LSA_UNICODE_STRING(string s) - { - if (s == null) - { - length = MaximumLength = 0; - Buffer = null; - } - else - { - var l = s.Length * UnicodeEncoding.CharSize; - // Unicode strings max. 32KB - if (l >= ushort.MaxValue) - throw new ArgumentException("String too long"); - Buffer = s; - length = (ushort)l; - MaximumLength = (ushort)(l + UnicodeEncoding.CharSize); - } - } - - /// Gets the number of characters in the string. - public int Length => length / UnicodeEncoding.CharSize; - - /// Returns a that represents this instance. - /// A that represents this instance. - public override string ToString() => Buffer; - - /// Performs an implicit conversion from to . - /// The value. - /// The result of the conversion. - public static implicit operator string(LSA_UNICODE_STRING value) => value.ToString(); - } - /// A custom marshaler for functions using LSA_UNICODE_STRING arrays so that managed string arrays can be used. /// internal class LsaUnicodeStringArrayMarshaler : ICustomMarshaler diff --git a/PInvoke/Security/AdvApi32/WinBase.cs b/PInvoke/Security/AdvApi32/WinBase.cs index 26e993a5..100732ee 100644 --- a/PInvoke/Security/AdvApi32/WinBase.cs +++ b/PInvoke/Security/AdvApi32/WinBase.cs @@ -14,8 +14,8 @@ namespace Vanara.PInvoke public enum LogonUserProvider { /// - /// Use the standard logon provider for the system. The default security provider is negotiate, unless you pass NULL for the domain name and the user - /// name is not in UPN format. In this case, the default provider is NTLM. + /// Use the standard logon provider for the system. The default security provider is negotiate, unless you pass NULL for the + /// domain name and the user name is not in UPN format. In this case, the default provider is NTLM. /// LOGON32_PROVIDER_DEFAULT = 0, @@ -36,21 +36,22 @@ namespace Vanara.PInvoke public enum LogonUserType { /// - /// This logon type is intended for users who will be interactively using the computer, such as a user being logged on by a terminal server, remote - /// shell, or similar process. This logon type has the additional expense of caching logon information for disconnected operations; therefore, it is - /// inappropriate for some client/server applications, such as a mail server. + /// This logon type is intended for users who will be interactively using the computer, such as a user being logged on by a + /// terminal server, remote shell, or similar process. This logon type has the additional expense of caching logon information + /// for disconnected operations; therefore, it is inappropriate for some client/server applications, such as a mail server. /// LOGON32_LOGON_INTERACTIVE = 2, /// - /// This logon type is intended for high performance servers to authenticate plaintext passwords. The LogonUser function does not cache credentials - /// for this logon type. + /// This logon type is intended for high performance servers to authenticate plaintext passwords. The LogonUser function does not + /// cache credentials for this logon type. /// LOGON32_LOGON_NETWORK = 3, /// - /// This logon type is intended for batch servers, where processes may be executing on behalf of a user without their direct intervention. This type - /// is also for higher performance servers that process many plaintext authentication attempts at a time, such as mail or web servers. + /// This logon type is intended for batch servers, where processes may be executing on behalf of a user without their direct + /// intervention. This type is also for higher performance servers that process many plaintext authentication attempts at a time, + /// such as mail or web servers. /// LOGON32_LOGON_BATCH = 4, @@ -60,67 +61,71 @@ namespace Vanara.PInvoke /// /// GINAs are no longer supported. /// - /// Windows Server 2003 and Windows XP: This logon type is for GINA DLLs that log on users who will be interactively using the computer. This - /// logon type can generate a unique audit record that shows when the workstation was unlocked. + /// Windows Server 2003 and Windows XP: This logon type is for GINA DLLs that log on users who will be interactively using + /// the computer. This logon type can generate a unique audit record that shows when the workstation was unlocked. /// /// LOGON32_LOGON_UNLOCK = 7, /// - /// This logon type preserves the name and password in the authentication package, which allows the server to make connections to other network - /// servers while impersonating the client. A server can accept plain-text credentials from a client, call LogonUser, verify that the user can access - /// the system across the network, and still communicate with other servers. + /// This logon type preserves the name and password in the authentication package, which allows the server to make connections to + /// other network servers while impersonating the client. A server can accept plain-text credentials from a client, call + /// LogonUser, verify that the user can access the system across the network, and still communicate with other servers. /// LOGON32_LOGON_NETWORK_CLEARTEXT = 8, /// - /// This logon type allows the caller to clone its current token and specify new credentials for outbound connections. The new logon session has the - /// same local identifier but uses different credentials for other network connections. This logon type is supported only by the - /// LOGON32_PROVIDER_WINNT50 logon provider. + /// This logon type allows the caller to clone its current token and specify new credentials for outbound connections. The new + /// logon session has the same local identifier but uses different credentials for other network connections. This logon type is + /// supported only by the LOGON32_PROVIDER_WINNT50 logon provider. /// LOGON32_LOGON_NEW_CREDENTIALS = 9 } /// - /// The AdjustTokenPrivileges function enables or disables privileges in the specified access token. Enabling or disabling privileges in an access token - /// requires TOKEN_ADJUST_PRIVILEGES access. + /// The AdjustTokenPrivileges function enables or disables privileges in the specified access token. Enabling or disabling privileges + /// in an access token requires TOKEN_ADJUST_PRIVILEGES access. /// /// - /// A handle to the access token that contains the privileges to be modified. The handle must have TOKEN_ADJUST_PRIVILEGES access to the token. If the - /// PreviousState parameter is not NULL, the handle must also have TOKEN_QUERY access. + /// A handle to the access token that contains the privileges to be modified. The handle must have TOKEN_ADJUST_PRIVILEGES access to + /// the token. If the PreviousState parameter is not NULL, the handle must also have TOKEN_QUERY access. /// /// - /// Specifies whether the function disables all of the token's privileges. If this value is TRUE, the function disables all privileges and ignores the - /// NewState parameter. If it is FALSE, the function modifies privileges based on the information pointed to by the NewState parameter. + /// Specifies whether the function disables all of the token's privileges. If this value is TRUE, the function disables all + /// privileges and ignores the NewState parameter. If it is FALSE, the function modifies privileges based on the information pointed + /// to by the NewState parameter. /// /// - /// A pointer to a TOKEN_PRIVILEGES structure that specifies an array of privileges and their attributes. If DisableAllPrivileges is TRUE, the function - /// ignores this parameter. If the DisableAllPrivileges parameter is FALSE, the AdjustTokenPrivileges function enables, disables, or removes these - /// privileges for the token. The following table describes the action taken by the AdjustTokenPrivileges function, based on the privilege attribute. + /// A pointer to a TOKEN_PRIVILEGES structure that specifies an array of privileges and their attributes. If DisableAllPrivileges is + /// TRUE, the function ignores this parameter. If the DisableAllPrivileges parameter is FALSE, the AdjustTokenPrivileges function + /// enables, disables, or removes these privileges for the token. The following table describes the action taken by the + /// AdjustTokenPrivileges function, based on the privilege attribute. /// /// - /// Specifies the size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be zero if the PreviousState parameter is NULL. + /// Specifies the size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be zero if the + /// PreviousState parameter is NULL. /// /// - /// A pointer to a buffer that the function fills with a TOKEN_PRIVILEGES structure that contains the previous state of any privileges that the function - /// modifies. That is, if a privilege has been modified by this function, the privilege and its previous state are contained in the TOKEN_PRIVILEGES - /// structure referenced by PreviousState. If the PrivilegeCount member of TOKEN_PRIVILEGES is zero, then no privileges have been changed by this - /// function. This parameter can be NULL. + /// A pointer to a buffer that the function fills with a TOKEN_PRIVILEGES structure that contains the previous state of any + /// privileges that the function modifies. That is, if a privilege has been modified by this function, the privilege and its previous + /// state are contained in the TOKEN_PRIVILEGES structure referenced by PreviousState. If the PrivilegeCount member of + /// TOKEN_PRIVILEGES is zero, then no privileges have been changed by this function. This parameter can be NULL. /// - /// If you specify a buffer that is too small to receive the complete list of modified privileges, the function fails and does not adjust any privileges. - /// In this case, the function sets the variable pointed to by the ReturnLength parameter to the number of bytes required to hold the complete list of - /// modified privileges. + /// If you specify a buffer that is too small to receive the complete list of modified privileges, the function fails and does not + /// adjust any privileges. In this case, the function sets the variable pointed to by the ReturnLength parameter to the number of + /// bytes required to hold the complete list of modified privileges. /// /// /// - /// A pointer to a variable that receives the required size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be - /// NULL if PreviousState is NULL. + /// A pointer to a variable that receives the required size, in bytes, of the buffer pointed to by the PreviousState parameter. This + /// parameter can be NULL if PreviousState is NULL. /// /// - /// If the function succeeds, the return value is nonzero. To determine whether the function adjusted all of the specified privileges, call GetLastError, - /// which returns either ERROR_SUCCESS, indicating that the function adjusted all specified privileges, or ERROR_NOT_ALL_ASSIGNED, indicating that the - /// token does not have one or more of the privileges specified in the NewState parameter. The function may succeed with this error value even if no - /// privileges were adjusted. The PreviousState parameter indicates the privileges that were adjusted. + /// If the function succeeds, the return value is nonzero. To determine whether the function adjusted all of the specified + /// privileges, call GetLastError, which returns either ERROR_SUCCESS, indicating that the function adjusted all specified + /// privileges, or ERROR_NOT_ALL_ASSIGNED, indicating that the token does not have one or more of the privileges specified in the + /// NewState parameter. The function may succeed with this error value even if no privileges were adjusted. The PreviousState + /// parameter indicates the privileges that were adjusted. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)] @@ -135,45 +140,49 @@ namespace Vanara.PInvoke [In, Out] ref uint ReturnLength); /// - /// The AdjustTokenPrivileges function enables or disables privileges in the specified access token. Enabling or disabling privileges in an access token - /// requires TOKEN_ADJUST_PRIVILEGES access. + /// The AdjustTokenPrivileges function enables or disables privileges in the specified access token. Enabling or disabling privileges + /// in an access token requires TOKEN_ADJUST_PRIVILEGES access. /// /// - /// A handle to the access token that contains the privileges to be modified. The handle must have TOKEN_ADJUST_PRIVILEGES access to the token. If the - /// PreviousState parameter is not NULL, the handle must also have TOKEN_QUERY access. + /// A handle to the access token that contains the privileges to be modified. The handle must have TOKEN_ADJUST_PRIVILEGES access to + /// the token. If the PreviousState parameter is not NULL, the handle must also have TOKEN_QUERY access. /// /// - /// Specifies whether the function disables all of the token's privileges. If this value is TRUE, the function disables all privileges and ignores the - /// NewState parameter. If it is FALSE, the function modifies privileges based on the information pointed to by the NewState parameter. + /// Specifies whether the function disables all of the token's privileges. If this value is TRUE, the function disables all + /// privileges and ignores the NewState parameter. If it is FALSE, the function modifies privileges based on the information pointed + /// to by the NewState parameter. /// /// - /// A pointer to a TOKEN_PRIVILEGES structure that specifies an array of privileges and their attributes. If DisableAllPrivileges is TRUE, the function - /// ignores this parameter. If the DisableAllPrivileges parameter is FALSE, the AdjustTokenPrivileges function enables, disables, or removes these - /// privileges for the token. The following table describes the action taken by the AdjustTokenPrivileges function, based on the privilege attribute. + /// A pointer to a TOKEN_PRIVILEGES structure that specifies an array of privileges and their attributes. If DisableAllPrivileges is + /// TRUE, the function ignores this parameter. If the DisableAllPrivileges parameter is FALSE, the AdjustTokenPrivileges function + /// enables, disables, or removes these privileges for the token. The following table describes the action taken by the + /// AdjustTokenPrivileges function, based on the privilege attribute. /// /// - /// Specifies the size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be zero if the PreviousState parameter is NULL. + /// Specifies the size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be zero if the + /// PreviousState parameter is NULL. /// /// - /// A pointer to a buffer that the function fills with a TOKEN_PRIVILEGES structure that contains the previous state of any privileges that the function - /// modifies. That is, if a privilege has been modified by this function, the privilege and its previous state are contained in the TOKEN_PRIVILEGES - /// structure referenced by PreviousState. If the PrivilegeCount member of TOKEN_PRIVILEGES is zero, then no privileges have been changed by this - /// function. This parameter can be NULL. + /// A pointer to a buffer that the function fills with a TOKEN_PRIVILEGES structure that contains the previous state of any + /// privileges that the function modifies. That is, if a privilege has been modified by this function, the privilege and its previous + /// state are contained in the TOKEN_PRIVILEGES structure referenced by PreviousState. If the PrivilegeCount member of + /// TOKEN_PRIVILEGES is zero, then no privileges have been changed by this function. This parameter can be NULL. /// - /// If you specify a buffer that is too small to receive the complete list of modified privileges, the function fails and does not adjust any privileges. - /// In this case, the function sets the variable pointed to by the ReturnLength parameter to the number of bytes required to hold the complete list of - /// modified privileges. + /// If you specify a buffer that is too small to receive the complete list of modified privileges, the function fails and does not + /// adjust any privileges. In this case, the function sets the variable pointed to by the ReturnLength parameter to the number of + /// bytes required to hold the complete list of modified privileges. /// /// /// - /// A pointer to a variable that receives the required size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be - /// NULL if PreviousState is NULL. + /// A pointer to a variable that receives the required size, in bytes, of the buffer pointed to by the PreviousState parameter. This + /// parameter can be NULL if PreviousState is NULL. /// /// - /// If the function succeeds, the return value is nonzero. To determine whether the function adjusted all of the specified privileges, call GetLastError, - /// which returns either ERROR_SUCCESS, indicating that the function adjusted all specified privileges, or ERROR_NOT_ALL_ASSIGNED, indicating that the - /// token does not have one or more of the privileges specified in the NewState parameter. The function may succeed with this error value even if no - /// privileges were adjusted. The PreviousState parameter indicates the privileges that were adjusted. + /// If the function succeeds, the return value is nonzero. To determine whether the function adjusted all of the specified + /// privileges, call GetLastError, which returns either ERROR_SUCCESS, indicating that the function adjusted all specified + /// privileges, or ERROR_NOT_ALL_ASSIGNED, indicating that the token does not have one or more of the privileges specified in the + /// NewState parameter. The function may succeed with this error value even if no privileges were adjusted. The PreviousState + /// parameter indicates the privileges that were adjusted. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)] @@ -192,13 +201,16 @@ namespace Vanara.PInvoke /// The DuplicateToken function creates a new access token that duplicates one already in existence. /// A handle to an access token opened with TOKEN_DUPLICATE access. - /// Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that supplies the impersonation level of the new token. + /// + /// Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that supplies the impersonation level of the new token. + /// /// - /// A pointer to a variable that receives a handle to the duplicate token. This handle has TOKEN_IMPERSONATE and TOKEN_QUERY access to the new token. - /// When you have finished using the new token, call the CloseHandle function to close the token handle. + /// A pointer to a variable that receives a handle to the duplicate token. This handle has TOKEN_IMPERSONATE and TOKEN_QUERY access + /// to the new token. When you have finished using the new token, call the CloseHandle function to close the token handle. /// /// - /// 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. + /// 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. /// [DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -206,31 +218,35 @@ namespace Vanara.PInvoke SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, out SafeTokenHandle duplicateObjectHandle); /// - /// The DuplicateTokenEx function creates a new access token that duplicates an existing token. This function can create either a primary token or an - /// impersonation token. + /// The DuplicateTokenEx function creates a new access token that duplicates an existing token. This function can create either a + /// primary token or an impersonation token. /// /// A handle to an access token opened with TOKEN_DUPLICATE access. /// - /// Specifies the requested access rights for the new token. The DuplicateTokenEx function compares the requested access rights with the existing token's - /// discretionary access control list (DACL) to determine which rights are granted or denied. To request the same access rights as the existing token, - /// specify zero. To request all access rights that are valid for the caller, specify MAXIMUM_ALLOWED. + /// Specifies the requested access rights for the new token. The DuplicateTokenEx function compares the requested access rights with + /// the existing token's discretionary access control list (DACL) to determine which rights are granted or denied. To request the + /// same access rights as the existing token, specify zero. To request all access rights that are valid for the caller, specify MAXIMUM_ALLOWED. /// /// - /// A pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new token and determines whether child processes can - /// inherit the token. If lpTokenAttributes is NULL, the token gets a default security descriptor and the handle cannot be inherited. If the security - /// descriptor contains a system access control list (SACL), the token gets ACCESS_SYSTEM_SECURITY access right, even if it was not requested in dwDesiredAccess. - /// To set the owner in the security descriptor for the new token, the caller's process token must have the SE_RESTORE_NAME privilege set. + /// A pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new token and determines whether child + /// processes can inherit the token. If lpTokenAttributes is NULL, the token gets a default security descriptor and the handle cannot + /// be inherited. If the security descriptor contains a system access control list (SACL), the token gets ACCESS_SYSTEM_SECURITY + /// access right, even if it was not requested in dwDesiredAccess. + /// + /// To set the owner in the security descriptor for the new token, the caller's process token must have the SE_RESTORE_NAME privilege set. + /// /// /// /// Specifies a value from the SECURITY_IMPERSONATION_LEVEL enumeration that indicates the impersonation level of the new token. /// /// Specifies one of the values from the TOKEN_TYPE enumeration. /// - /// A pointer to a HANDLE variable that receives the new token. When you have finished using the new token, call the CloseHandle function to close the - /// token handle. + /// A pointer to a HANDLE variable that receives the new token. When you have finished using the new token, call the CloseHandle + /// function to close the token handle. /// /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error information, call GetLastError. + /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error + /// information, call GetLastError. /// [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -240,11 +256,13 @@ namespace Vanara.PInvoke /// The GetAce function obtains a pointer to an access control entry (ACE) in an access control list (ACL). /// A pointer to an ACL that contains the ACE to be retrieved. /// - /// The index of the ACE to be retrieved. A value of zero corresponds to the first ACE in the ACL, a value of one to the second ACE, and so on. + /// The index of the ACE to be retrieved. A value of zero corresponds to the first ACE in the ACL, a value of one to the second ACE, + /// and so on. /// /// A pointer to a pointer that the function sets to the address of the ACE. /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error information, call GetLastError. + /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error + /// information, call GetLastError. /// [DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -256,26 +274,30 @@ namespace Vanara.PInvoke /// A pointer to an ACL. The function retrieves information about this ACL. If a null value is passed, the function causes an access violation. /// /// - /// A pointer to a buffer to receive the requested information. The structure that is placed into the buffer depends on the information class requested - /// in the dwAclInformationClass parameter. + /// A pointer to a buffer to receive the requested information. The structure that is placed into the buffer depends on the + /// information class requested in the dwAclInformationClass parameter. /// /// The size, in bytes, of the buffer pointed to by the pAclInformation parameter. /// - /// A value of the ACL_INFORMATION_CLASS enumeration that indicates the class of information requested. This parameter can be one of two values from this enumeration: + /// A value of the ACL_INFORMATION_CLASS enumeration that indicates the class of information requested. This parameter can be one of + /// two values from this enumeration: /// /// /// - /// If the value is AclRevisionInformation, the function fills the buffer pointed to by the pAclInformation parameter with an ACL_REVISION_INFORMATION structure. + /// If the value is AclRevisionInformation, the function fills the buffer pointed to by the pAclInformation parameter with an + /// ACL_REVISION_INFORMATION structure. /// /// /// - /// If the value is AclSizeInformation, the function fills the buffer pointed to by the pAclInformation parameter with an ACL_SIZE_INFORMATION structure. + /// If the value is AclSizeInformation, the function fills the buffer pointed to by the pAclInformation parameter with an + /// ACL_SIZE_INFORMATION structure. /// /// /// /// /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error information, call GetLastError. + /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error + /// information, call GetLastError. /// [DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)] [PInvokeData("Winbase.h", MSDNShortId = "aa446635")] @@ -286,26 +308,30 @@ namespace Vanara.PInvoke /// A pointer to an ACL. The function retrieves information about this ACL. If a null value is passed, the function causes an access violation. /// /// - /// A pointer to a buffer to receive the requested information. The structure that is placed into the buffer depends on the information class requested - /// in the dwAclInformationClass parameter. + /// A pointer to a buffer to receive the requested information. The structure that is placed into the buffer depends on the + /// information class requested in the dwAclInformationClass parameter. /// /// The size, in bytes, of the buffer pointed to by the pAclInformation parameter. /// - /// A value of the ACL_INFORMATION_CLASS enumeration that indicates the class of information requested. This parameter can be one of two values from this enumeration: + /// A value of the ACL_INFORMATION_CLASS enumeration that indicates the class of information requested. This parameter can be one of + /// two values from this enumeration: /// /// /// - /// If the value is AclRevisionInformation, the function fills the buffer pointed to by the pAclInformation parameter with an ACL_REVISION_INFORMATION structure. + /// If the value is AclRevisionInformation, the function fills the buffer pointed to by the pAclInformation parameter with an + /// ACL_REVISION_INFORMATION structure. /// /// /// - /// If the value is AclSizeInformation, the function fills the buffer pointed to by the pAclInformation parameter with an ACL_SIZE_INFORMATION structure. + /// If the value is AclSizeInformation, the function fills the buffer pointed to by the pAclInformation parameter with an + /// ACL_SIZE_INFORMATION structure. /// /// /// /// /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error information, call GetLastError. + /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error + /// information, call GetLastError. /// [DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)] [PInvokeData("Winbase.h", MSDNShortId = "aa446635")] @@ -314,21 +340,23 @@ namespace Vanara.PInvoke /// The GetPrivateObjectSecurity function retrieves information from a private object's security descriptor. /// A pointer to a SECURITY_DESCRIPTOR structure. This is the security descriptor to be queried. /// - /// A set of bit flags that indicate the parts of the security descriptor to retrieve. This parameter can be a combination of the SECURITY_INFORMATION - /// bit flags. + /// A set of bit flags that indicate the parts of the security descriptor to retrieve. This parameter can be a combination of the + /// SECURITY_INFORMATION bit flags. /// /// - /// A pointer to a buffer that receives a copy of the requested information from the specified security descriptor. The SECURITY_DESCRIPTOR structure is - /// returned in self-relative format. + /// A pointer to a buffer that receives a copy of the requested information from the specified security descriptor. The + /// SECURITY_DESCRIPTOR structure is returned in self-relative format. /// /// Specifies the size, in bytes, of the buffer pointed to by the ResultantDescriptor parameter. /// - /// A pointer to a variable the function sets to zero if the descriptor is copied successfully. If the buffer is too small for the security descriptor, - /// this variable receives the number of bytes required. If this variable's value is greater than the value of the DescriptorLength parameter when the - /// function returns, the function returns FALSE and none of the security descriptor is copied to the buffer. + /// A pointer to a variable the function sets to zero if the descriptor is copied successfully. If the buffer is too small for the + /// security descriptor, this variable receives the number of bytes required. If this variable's value is greater than the value of + /// the DescriptorLength parameter when the function returns, the function returns FALSE and none of the security descriptor is + /// copied to the buffer. /// /// - /// 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. + /// 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. /// [DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -336,33 +364,42 @@ namespace Vanara.PInvoke public static extern bool GetPrivateObjectSecurity(IntPtr ObjectDescriptor, SECURITY_INFORMATION SecurityInformation, IntPtr ResultantDescriptor, uint DescriptorLength, out uint ReturnLength); - /// The GetSecurityDescriptorDacl function retrieves a pointer to the discretionary access control list (DACL) in a specified security descriptor. - /// A pointer to the SECURITY_DESCRIPTOR structure that contains the DACL. The function retrieves a pointer to it. + /// + /// The GetSecurityDescriptorDacl function retrieves a pointer to the discretionary access control list (DACL) in a specified + /// security descriptor. + /// + /// + /// A pointer to the SECURITY_DESCRIPTOR structure that contains the DACL. The function retrieves a pointer to it. + /// /// - /// A pointer to a value that indicates the presence of a DACL in the specified security descriptor. If lpbDaclPresent is TRUE, the security descriptor - /// contains a DACL, and the remaining output parameters in this function receive valid values. If lpbDaclPresent is FALSE, the security descriptor does - /// not contain a DACL, and the remaining output parameters do not receive valid values. + /// A pointer to a value that indicates the presence of a DACL in the specified security descriptor. If lpbDaclPresent is TRUE, the + /// security descriptor contains a DACL, and the remaining output parameters in this function receive valid values. If lpbDaclPresent + /// is FALSE, the security descriptor does not contain a DACL, and the remaining output parameters do not receive valid values. /// - /// A value of TRUE for lpbDaclPresent does not mean that pDacl is not NULL. That is, lpbDaclPresent can be TRUE while pDacl is NULL, meaning that a NULL - /// DACL is in effect. A NULL DACL implicitly allows all access to an object and is not the same as an empty DACL. An empty DACL permits no access to an - /// object. For information about creating a proper DACL, see Creating a DACL. + /// A value of TRUE for lpbDaclPresent does not mean that pDacl is not NULL. That is, lpbDaclPresent can be TRUE while pDacl is NULL, + /// meaning that a NULL DACL is in effect. A NULL DACL implicitly allows all access to an object and is not the same as an empty + /// DACL. An empty DACL permits no access to an object. For information about creating a proper DACL, see Creating a DACL. /// /// /// - /// A pointer to a pointer to an access control list (ACL). If a DACL exists, the function sets the pointer pointed to by pDacl to the address of the - /// security descriptor's DACL. If a DACL does not exist, no value is stored. + /// A pointer to a pointer to an access control list (ACL). If a DACL exists, the function sets the pointer pointed to by pDacl to + /// the address of the security descriptor's DACL. If a DACL does not exist, no value is stored. /// - /// If the function stores a NULL value in the pointer pointed to by pDacl, the security descriptor has a NULL DACL. A NULL DACL implicitly allows all - /// access to an object. + /// If the function stores a NULL value in the pointer pointed to by pDacl, the security descriptor has a NULL DACL. A NULL DACL + /// implicitly allows all access to an object. + /// + /// + /// If an application expects a non-NULL DACL but encounters a NULL DACL, the application should fail securely and not allow access. /// - /// If an application expects a non-NULL DACL but encounters a NULL DACL, the application should fail securely and not allow access. /// /// - /// A pointer to a flag set to the value of the SE_DACL_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure if a DACL exists for the security - /// descriptor. If this flag is TRUE, the DACL was retrieved by a default mechanism; if FALSE, the DACL was explicitly specified by a user. + /// A pointer to a flag set to the value of the SE_DACL_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure if a DACL exists + /// for the security descriptor. If this flag is TRUE, the DACL was retrieved by a default mechanism; if FALSE, the DACL was + /// explicitly specified by a user. /// /// - /// 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. + /// 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. /// [DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -372,10 +409,19 @@ namespace Vanara.PInvoke /// The GetSecurityDescriptorOwner function retrieves the owner information from a security descriptor. /// A pointer to a SECURITY_DESCRIPTOR structure whose owner information the function retrieves. - /// A pointer to a pointer to a security identifier (SID) that identifies the owner when the function returns. If the security descriptor does not contain an owner, the function sets the pointer pointed to by pOwner to NULL and ignores the remaining output parameter, lpbOwnerDefaulted. If the security descriptor contains an owner, the function sets the pointer pointed to by pOwner to the address of the security descriptor's owner SID and provides a valid value for the variable pointed to by lpbOwnerDefaulted. - /// A pointer to a flag that is set to the value of the SE_OWNER_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure when the function returns. If the value stored in the variable pointed to by the pOwner parameter is NULL, no value is set. + /// + /// A pointer to a pointer to a security identifier (SID) that identifies the owner when the function returns. If the security + /// descriptor does not contain an owner, the function sets the pointer pointed to by pOwner to NULL and ignores the remaining output + /// parameter, lpbOwnerDefaulted. If the security descriptor contains an owner, the function sets the pointer pointed to by pOwner to + /// the address of the security descriptor's owner SID and provides a valid value for the variable pointed to by lpbOwnerDefaulted. + /// + /// + /// A pointer to a flag that is set to the value of the SE_OWNER_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure when the + /// function returns. If the value stored in the variable pointed to by the pOwner parameter is NULL, no value is set. + /// /// - /// 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. + /// 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. /// [DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -384,35 +430,39 @@ namespace Vanara.PInvoke out IntPtr pOwner, [MarshalAs(UnmanagedType.Bool)] out bool lpbOwnerDefaulted); /// - /// The GetTokenInformation function retrieves a specified type of information about an access token. The calling process must have appropriate access - /// rights to obtain the information. + /// The GetTokenInformation function retrieves a specified type of information about an access token. The calling process must have + /// appropriate access rights to obtain the information. /// /// - /// A handle to an access token from which information is retrieved. If TokenInformationClass specifies TokenSource, the handle must have - /// TOKEN_QUERY_SOURCE access. For all other TokenInformationClass values, the handle must have TOKEN_QUERY access. + /// A handle to an access token from which information is retrieved. If TokenInformationClass specifies TokenSource, the handle must + /// have TOKEN_QUERY_SOURCE access. For all other TokenInformationClass values, the handle must have TOKEN_QUERY access. /// /// - /// Specifies a value from the TOKEN_INFORMATION_CLASS enumerated type to identify the type of information the function retrieves. Any callers who check - /// the TokenIsAppContainer and have it return 0 should also verify that the caller token is not an identify level impersonation token. If the current - /// token is not an application container but is an identity level token, you should return AccessDenied. + /// Specifies a value from the TOKEN_INFORMATION_CLASS enumerated type to identify the type of information the function retrieves. + /// Any callers who check the TokenIsAppContainer and have it return 0 should also verify that the caller token is not an identify + /// level impersonation token. If the current token is not an application container but is an identity level token, you should return AccessDenied. /// /// - /// A pointer to a buffer the function fills with the requested information. The structure put into this buffer depends upon the type of information - /// specified by the TokenInformationClass parameter. + /// A pointer to a buffer the function fills with the requested information. The structure put into this buffer depends upon the type + /// of information specified by the TokenInformationClass parameter. /// /// - /// Specifies the size, in bytes, of the buffer pointed to by the TokenInformation parameter. If TokenInformation is NULL, this parameter must be zero. + /// Specifies the size, in bytes, of the buffer pointed to by the TokenInformation parameter. If TokenInformation is NULL, this + /// parameter must be zero. /// /// - /// A pointer to a variable that receives the number of bytes needed for the buffer pointed to by the TokenInformation parameter. If this value is larger - /// than the value specified in the TokenInformationLength parameter, the function fails and stores no data in the buffer. + /// A pointer to a variable that receives the number of bytes needed for the buffer pointed to by the TokenInformation parameter. If + /// this value is larger than the value specified in the TokenInformationLength parameter, the function fails and stores no data in + /// the buffer. /// - /// If the value of the TokenInformationClass parameter is TokenDefaultDacl and the token has no default DACL, the function sets the variable pointed to - /// by ReturnLength to sizeof(TOKEN_DEFAULT_DACL) and sets the DefaultDacl member of the TOKEN_DEFAULT_DACL structure to NULL. + /// If the value of the TokenInformationClass parameter is TokenDefaultDacl and the token has no default DACL, the function sets the + /// variable pointed to by ReturnLength to sizeof(TOKEN_DEFAULT_DACL) and sets the DefaultDacl member of the TOKEN_DEFAULT_DACL + /// structure to NULL. /// /// /// - /// 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. + /// 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. /// [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -425,32 +475,32 @@ namespace Vanara.PInvoke /// 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. /// - // BOOL WINAPI ImpersonateNamedPipeClient( _In_ HANDLE hNamedPipe); - // https://msdn.microsoft.com/en-us/library/windows/desktop/aa378618(v=vs.85).aspx + // BOOL WINAPI ImpersonateNamedPipeClient( _In_ HANDLE hNamedPipe); https://msdn.microsoft.com/en-us/library/windows/desktop/aa378618(v=vs.85).aspx [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [PInvokeData("Winbase.h", MSDNShortId = "aa378618")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool ImpersonateNamedPipeClient(IntPtr hNamedPipe); /// - /// 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. + /// 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. /// /// - /// 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. + /// 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. /// /// - /// 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. + /// 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. /// /// - /// 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. + /// 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. /// /// The type of logon operation to perform. /// Specifies the logon provider. @@ -458,14 +508,15 @@ namespace Vanara.PInvoke /// A pointer to a handle variable that receives a handle to a token that represents the specified user. /// You can use the returned handle in calls to the ImpersonateLoggedOnUser function. /// - /// 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. + /// 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. /// /// When you no longer need this handle, close it by calling the CloseHandle function. /// /// - /// 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. + /// 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. /// [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false, ThrowOnUnmappableChar = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -474,24 +525,25 @@ namespace Vanara.PInvoke out SafeTokenHandle phObject); /// - /// 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. + /// 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. /// /// - /// 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. + /// 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. /// /// - /// 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. + /// 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. /// /// - /// 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. + /// 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. /// /// The type of logon operation to perform. /// The logon provider. @@ -499,9 +551,9 @@ namespace Vanara.PInvoke /// A pointer to a handle variable that receives a handle to a token that represents the specified user. /// You can use the returned handle in calls to the ImpersonateLoggedOnUser function. /// - /// 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. + /// 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. /// /// When you no longer need this handle, close it by calling the CloseHandle function. /// @@ -509,11 +561,16 @@ namespace Vanara.PInvoke /// A pointer to a pointer to a security identifier (SID) that receives the SID of the user logged on. /// When you have finished using the SID, free it by calling the LocalFree function. /// - /// A pointer to a pointer that receives the address of a buffer that contains the logged on user's profile. + /// + /// A pointer to a pointer that receives the address of a buffer that contains the logged on user's profile. + /// /// A pointer to a DWORD that receives the length of the profile buffer. - /// A pointer to a QUOTA_LIMITS structure that receives information about the quotas for the logged on user. + /// + /// A pointer to a QUOTA_LIMITS structure that receives information about the quotas for the logged on user. + /// /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error information, call GetLastError. + /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error + /// information, call GetLastError. /// [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false, ThrowOnUnmappableChar = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -522,39 +579,43 @@ namespace Vanara.PInvoke out SafeTokenHandle phObject, out PSID ppLogonSid, out SafeLsaReturnBufferHandle ppProfileBuffer, out uint pdwProfileLength, out QUOTA_LIMITS pQuotaLimits); /// - /// 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. + /// 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. /// /// - /// 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. + /// 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. /// /// /// A pointer to a null-terminated string that specifies the account name. - /// Use a fully qualified string in the domain_name\user_name format to ensure that LookupAccountName finds the account in the desired domain. + /// + /// Use a fully qualified string in the domain_name\user_name format to ensure that LookupAccountName finds the account in the + /// desired domain. + /// /// /// - /// 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. + /// 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. /// /// - /// 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. + /// 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. /// /// - /// 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. + /// 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. /// /// - /// 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. + /// 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. /// /// A pointer to a SID_NAME_USE enumerated type that indicates the type of the account when the function returns. /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. For extended error information, call GetLastError. + /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. For extended error information, + /// call GetLastError. /// [DllImport(Lib.AdvApi32, CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -563,27 +624,31 @@ namespace Vanara.PInvoke StringBuilder ReferencedDomainName, ref int cchReferencedDomainName, ref SID_NAME_USE peUse); /// - /// 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. + /// 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. /// /// - /// 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. + /// 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. /// /// /// A string that specifies the account name. - /// Use a fully qualified string in the domain_name\user_name format to ensure that LookupAccountName finds the account in the desired domain. + /// + /// Use a fully qualified string in the domain_name\user_name format to ensure that LookupAccountName finds the account in the + /// desired domain. + /// /// /// A PSID class that corresponds to the account name pointed to by the lpAccountName parameter. /// - /// 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. + /// 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. /// /// A SID_NAME_USE enumerated type that indicates the type of the account when the function returns. /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. For extended error information, call GetLastError. + /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. For extended error information, + /// call GetLastError. /// [PInvokeData("Winbase.h", MSDNShortId = "aa379159")] public static bool LookupAccountName(string systemName, string accountName, out PSID sid, out string domainName, out SID_NAME_USE snu) @@ -600,43 +665,45 @@ namespace Vanara.PInvoke } /// - /// 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. + /// 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. /// /// - /// 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. + /// 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. /// /// A pointer to the SID to look up. /// /// A pointer to a buffer that receives a null-terminated string that contains the account name that corresponds to the lpSid parameter. /// /// - /// 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. + /// 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. /// /// /// A pointer to a buffer that receives a null-terminated string that contains the name of the domain where the account name was found. /// - /// 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. + /// 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. /// /// - /// 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. + /// 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. /// /// Some accounts are predefined by the system. The domain name returned for these accounts is BUILTIN. /// /// - /// 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. + /// 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. /// /// A pointer to a variable that receives a SID_NAME_USE value that indicates the type of the account. /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error information, call GetLastError. + /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error + /// information, call GetLastError. /// [DllImport(Lib.AdvApi32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -645,43 +712,45 @@ namespace Vanara.PInvoke StringBuilder lpReferencedDomainName, ref int cchReferencedDomainName, out SID_NAME_USE peUse); /// - /// 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. + /// 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. /// /// - /// 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. + /// 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. /// /// A pointer to the SID to look up. /// /// A pointer to a buffer that receives a null-terminated string that contains the account name that corresponds to the lpSid parameter. /// /// - /// 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. + /// 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. /// /// /// A pointer to a buffer that receives a null-terminated string that contains the name of the domain where the account name was found. /// - /// 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. + /// 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. /// /// - /// 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. + /// 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. /// /// Some accounts are predefined by the system. The domain name returned for these accounts is BUILTIN. /// /// - /// 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. + /// 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. /// /// A pointer to a variable that receives a SID_NAME_USE value that indicates the type of the account. /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error information, call GetLastError. + /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error + /// information, call GetLastError. /// [DllImport(Lib.AdvApi32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -690,126 +759,189 @@ namespace Vanara.PInvoke StringBuilder lpReferencedDomainName, ref int cchReferencedDomainName, out SID_NAME_USE peUse); /// - /// The LookupPrivilegeName function retrieves the name that corresponds to the privilege represented on a specific system by a specified locally unique - /// identifier (LUID). + /// + /// The LookupPrivilegeName function retrieves the name that corresponds to the privilege represented on a specific system by + /// a specified locally unique identifier (LUID). + /// /// /// - /// 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. + /// + /// 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. + /// + /// + /// + /// A pointer to the LUID by which the privilege is known on the target system. /// - /// A pointer to the LUID by which the privilege is known on the target system. /// - /// A pointer to a buffer that receives a null-terminated string that represents the privilege name. For example, this string could be "SeSecurityPrivilege". + /// + /// A pointer to a buffer that receives a null-terminated string that represents the privilege name. For example, this string could + /// be "SeSecurityPrivilege". + /// /// /// - /// A pointer to a variable that specifies the size, in a TCHAR 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. + /// + /// A pointer to a variable that specifies the size, in a TCHAR 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. + /// /// /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero.To get extended error information, call GetLastError. + /// If the function succeeds, the function returns nonzero. + /// If the function fails, it returns zero. To get extended error information, call GetLastError. /// + /// + /// + /// The LookupPrivilegeName function supports only the privileges specified in the Defined Privileges section of Winnt.h. For + /// a list of values, see Privilege Constants. + /// + /// + // 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( string lpSystemName, PLUID lpLuid, + // StringBuilder lpName, ref uint cchName); [return: MarshalAs(UnmanagedType.Bool)] public static extern bool LookupPrivilegeName(string lpSystemName, ref LUID lpLuid, StringBuilder lpName, ref int cchName); /// - /// The LookupPrivilegeValue function retrieves the locally unique identifier (LUID) used on a specified system to locally represent the specified - /// privilege name. + /// + /// The LookupPrivilegeValue function retrieves the locally unique identifier (LUID) used on a specified system to locally + /// represent the specified privilege name. + /// /// /// - /// 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. + /// + /// 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. + /// /// /// - /// 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". + /// + /// 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". + /// /// /// + /// /// A pointer to a variable that receives the LUID by which the privilege is known on the system specified by the lpSystemName parameter. + /// /// /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error information, call GetLastError. + /// If the function succeeds, the function returns nonzero. + /// If the function fails, it returns zero. To get extended error information, call GetLastError. /// + /// + /// + /// The LookupPrivilegeValue function supports only the privileges specified in the Defined Privileges section of Winnt.h. For + /// a list of values, see Privilege Constants. + /// + /// Examples + /// For an example that uses this function, see Enabling and Disabling Privileges. + /// + // 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(string lpSystemName, string lpName, out LUID lpLuid); /// - /// The MapGenericMask function maps the generic access rights in an access mask to specific and standard access rights. The function applies a mapping - /// supplied in a structure. + /// The MapGenericMask function maps the generic access rights in an access mask to specific and standard access rights. The function + /// applies a mapping supplied in a structure. /// /// A pointer to an access mask. /// - /// A pointer to a structure specifying a mapping of generic access types to specific and standard access types. + /// A pointer to a structure specifying a mapping of generic access types to specific and standard + /// access types. /// [DllImport(Lib.AdvApi32, ExactSpelling = true)] [PInvokeData("Winbase.h", MSDNShortId = "aa379266")] public static extern void MapGenericMask(ref uint AccessMask, ref GENERIC_MAPPING GenericMapping); /// The OpenProcessToken function opens the access token associated with a process. - /// A handle to the process whose access token is opened. The process must have the PROCESS_QUERY_INFORMATION access permission. + /// + /// A handle to the process whose access token is opened. The process must have the PROCESS_QUERY_INFORMATION access permission. + /// /// - /// Specifies an access mask that specifies the requested types of access to the access token. These requested access types are compared with the - /// discretionary access control list (DACL) of the token to determine which accesses are granted or denied. + /// Specifies an access mask that specifies the requested types of access to the access token. These requested access types are + /// compared with the discretionary access control list (DACL) of the token to determine which accesses are granted or denied. /// /// A pointer to a handle that identifies the newly opened access token when the function returns. /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error information, call GetLastError. + /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error + /// information, call GetLastError. /// [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] [return: MarshalAs(UnmanagedType.Bool)] [PInvokeData("winbase.h", MSDNShortId = "aa379295")] public static extern bool OpenProcessToken([In] IntPtr ProcessHandle, TokenAccess DesiredAccess, out SafeTokenHandle TokenHandle); - /// The OpenThreadToken function opens the access token associated with a thread. + /// The OpenThreadToken function opens the access token associated with a thread. /// A handle to the thread whose access token is opened. /// - /// Specifies an access mask that specifies the requested types of access to the access token. These requested access types are reconciled against the - /// token's discretionary access control list (DACL) to determine which accesses are granted or denied. + /// + /// Specifies an access mask that specifies the requested types of access to the access token. These requested access types are + /// reconciled against the token's discretionary access control list (DACL) to determine which accesses are granted or denied. + /// /// For a list of access rights for access tokens, see Access Rights for Access-Token Objects. /// /// - /// TRUE if the access check is to be made against the process-level security context. - /// FALSE if the access check is to be made against the current security context of the thread calling the OpenThreadToken function. + /// TRUE if the access check is to be made against the process-level security context. /// - /// The OpenAsSelf parameter allows the caller of this function to open the access token of a specified thread when the caller is impersonating a token - /// at SecurityIdentification level. Without this parameter, the calling thread cannot open the access token on the specified thread because it is - /// impossible to open executive-level objects by using the SecurityIdentification impersonation level. + /// FALSE if the access check is to be made against the current security context of the thread calling the + /// OpenThreadToken function. + /// + /// + /// The OpenAsSelf parameter allows the caller of this function to open the access token of a specified thread when the caller is + /// impersonating a token at SecurityIdentification level. Without this parameter, the calling thread cannot open the access + /// token on the specified thread because it is impossible to open executive-level objects by using the SecurityIdentification + /// impersonation level. /// /// /// A pointer to a variable that receives the handle to the newly opened access token. /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error information, call GetLastError. + /// 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. If the token has + /// the anonymous impersonation level, the token will not be opened and OpenThreadToken sets ERROR_CANT_OPEN_ANONYMOUS as the error. + /// /// + // BOOL WINAPI OpenThreadToken( _In_ HANDLE ThreadHandle, _In_ DWORD DesiredAccess, _In_ BOOL OpenAsSelf, _Out_ PHANDLE TokenHandle); https://msdn.microsoft.com/en-us/library/windows/desktop/aa379296(v=vs.85).aspx [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("Winbase.h", MSDNShortId = "aa379296")] + // [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WINAPI OpenThreadToken([In] IntPtr ThreadHandle, [In] uint + // DesiredAccess, [In] [MarshalAs(UnmanagedType.Bool)] bool OpenAsSelf, [Out] ref IntPtr TokenHandle); [return: MarshalAs(UnmanagedType.Bool)] public static extern bool OpenThreadToken([In] IntPtr ThreadHandle, TokenAccess DesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool OpenAsSelf, out SafeTokenHandle TokenHandle); /// - /// The PrivilegeCheck function determines whether a specified set of privileges are enabled in an access token. The PrivilegeCheck function is typically - /// called by a server application to check the privileges of a client's access token. + /// The PrivilegeCheck function determines whether a specified set of privileges are enabled in an access token. The PrivilegeCheck + /// function is typically called by a server application to check the privileges of a client's access token. /// /// - /// A handle to an access token representing a client process. 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. + /// A handle to an access token representing a client process. 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. /// /// - /// A pointer to a PRIVILEGE_SET structure. The Privilege member of this structure is an array of LUID_AND_ATTRIBUTES structures. Before calling - /// PrivilegeCheck, use the Privilege array to indicate the set of privileges to check. Set the Control member to PRIVILEGE_SET_ALL_NECESSARY if all of - /// the privileges must be enabled; or set it to zero if it is sufficient that any one of the privileges be enabled. + /// A pointer to a PRIVILEGE_SET structure. The Privilege member of this structure is an array of LUID_AND_ATTRIBUTES structures. + /// Before calling PrivilegeCheck, use the Privilege array to indicate the set of privileges to check. Set the Control member to + /// PRIVILEGE_SET_ALL_NECESSARY if all of the privileges must be enabled; or set it to zero if it is sufficient that any one of the + /// privileges be enabled. /// - /// When PrivilegeCheck returns, the Attributes member of each LUID_AND_ATTRIBUTES structure is set to SE_PRIVILEGE_USED_FOR_ACCESS if the corresponding - /// privilege is enabled. + /// When PrivilegeCheck returns, the Attributes member of each LUID_AND_ATTRIBUTES structure is set to SE_PRIVILEGE_USED_FOR_ACCESS + /// if the corresponding privilege is enabled. /// /// /// - /// A pointer to a value the function sets to indicate whether any or all of the specified privileges are enabled in the access token. If the Control - /// member of the PRIVILEGE_SET structure specifies PRIVILEGE_SET_ALL_NECESSARY, this value is TRUE only if all the privileges are enabled; otherwise, - /// this value is TRUE if any of the privileges are enabled. + /// A pointer to a value the function sets to indicate whether any or all of the specified privileges are enabled in the access + /// token. If the Control member of the PRIVILEGE_SET structure specifies PRIVILEGE_SET_ALL_NECESSARY, this value is TRUE only if all + /// the privileges are enabled; otherwise, this value is TRUE if any of the privileges are enabled. /// /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error information, call GetLastError. + /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error + /// information, call GetLastError. /// [PInvokeData("Winbase.h", MSDNShortId = "aa379304")] [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] @@ -852,15 +984,16 @@ namespace Vanara.PInvoke /// Examples /// For an example, see Reporting an Event. /// - // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-registereventsourcea - // HANDLE RegisterEventSourceA( LPCSTR lpUNCServerName, LPCSTR lpSourceName ); + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-registereventsourcea HANDLE RegisterEventSourceA( LPCSTR + // lpUNCServerName, LPCSTR lpSourceName ); [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("winbase.h", MSDNShortId = "53706f83-6bc9-45d6-981c-bd0680d7bc08")] public static extern IntPtr RegisterEventSource(string lpUNCServerName, string lpSourceName); /// The RevertToSelf function terminates the impersonation of a client application. /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error information, call GetLastError. + /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error + /// information, call GetLastError. /// [DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -868,27 +1001,35 @@ namespace Vanara.PInvoke public static extern bool RevertToSelf(); /// - /// The SetThreadToken function assigns an impersonation token to a thread. The function can also cause a thread to stop using an impersonation token. + /// The SetThreadToken function assigns an impersonation token to a thread. The function can also cause a thread to stop using + /// an impersonation token. /// /// - /// A pointer to a handle to the thread to which the function assigns the impersonation token. If Thread is NULL, the function assigns the impersonation - /// token to the calling thread. + /// A pointer to a handle to the thread to which the function assigns the impersonation token. + /// If Thread is NULL, the function assigns the impersonation token to the calling thread. /// /// - /// A handle to the impersonation token to assign to the thread. This handle must have been opened with TOKEN_IMPERSONATE access rights. For more - /// information, see Access Rights for Access-Token Objects. If Token is NULL, the function causes the thread to stop using an impersonation token. + /// + /// A handle to the impersonation token to assign to the thread. This handle must have been opened with TOKEN_IMPERSONATE access + /// rights. For more information, see Access Rights for Access-Token Objects. + /// + /// If Token is NULL, the function causes the thread to stop using an impersonation token. /// /// - /// If the function succeeds, the function returns nonzero. If the function fails, it returns zero. To get extended error information, call GetLastError. + /// 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. /// + // BOOL WINAPI SetThreadToken( _In_opt_ PHANDLE Thread, _In_opt_ HANDLE Token); https://msdn.microsoft.com/en-us/library/windows/desktop/aa379590(v=vs.85).aspx [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("Winbase.h", MSDNShortId = "aa379590")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetThreadToken(IntPtr Thread, SafeTokenHandle Token); /// Closes an open object handle. /// A valid handle to an open object. /// - /// 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. + /// 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. /// [PInvokeData("WinBase.h", MSDNShortId = "ms724211")] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport(Lib.Kernel32, ExactSpelling = true, SetLastError = true)] @@ -898,27 +1039,65 @@ namespace Vanara.PInvoke /// Represents a safe handle for HTOKEN. public class SafeTokenHandle : GenericSafeHandle { - /// Retrieves a pseudo-handle that you can use as a shorthand way to refer to the access token associated with a process. - /// A pseudo-handle is a special constant that can function as the access token for the current process. The calling process can use a pseudo-handle to specify the access token for that process whenever a token handle is required. Child processes do not inherit pseudo-handles. + /// + /// Retrieves a pseudo-handle that you can use as a shorthand way to refer to the access token associated with a process. + /// + /// + /// A pseudo-handle is a special constant that can function as the access token for the current process. The calling process can + /// use a pseudo-handle to specify the access token for that process whenever a token handle is required. Child processes do not + /// inherit pseudo-handles. /// Starting in Windows 8, this pseudo-handle has only TOKEN_QUERY and TOKEN_QUERY_SOURCE access rights. - /// A process can create a standard handle that is valid in the context of other processes and can be inherited by other processes. To create this standard handle, call the DuplicateHandle function and specify the pseudo-handle as the source handle. - /// You do not need to close the pseudo-handle when you no longer need it. If you call the CloseHandle function with a pseudo-handle, the function has no effect. If you call DuplicateHandle to duplicate the pseudo-handle, however, you must close the duplicate handle. + /// + /// A process can create a standard handle that is valid in the context of other processes and can be inherited by other + /// processes. To create this standard handle, call the DuplicateHandle function and specify the pseudo-handle as the source handle. + /// + /// + /// You do not need to close the pseudo-handle when you no longer need it. If you call the CloseHandle function with a + /// pseudo-handle, the function has no effect. If you call DuplicateHandle to duplicate the pseudo-handle, however, you must + /// close the duplicate handle. + /// /// public static readonly SafeTokenHandle CurrentProcessToken = new SafeTokenHandle((IntPtr)4, false); - /// Retrieves a pseudo-handle that you can use as a shorthand way to refer to the token that is currently in effect for the thread, which is the thread token if one exists and the process token otherwise. - /// A pseudo-handle is a special constant that can function as the access token for the current thread. The calling thread can use a pseudo-handle to specify the access token for that thread whenever a token handle is required. Child threads do not inherit pseudo-handles. + /// + /// Retrieves a pseudo-handle that you can use as a shorthand way to refer to the token that is currently in effect for the + /// thread, which is the thread token if one exists and the process token otherwise. + /// + /// + /// A pseudo-handle is a special constant that can function as the access token for the current thread. The calling thread can + /// use a pseudo-handle to specify the access token for that thread whenever a token handle is required. Child threads do not + /// inherit pseudo-handles. /// Starting in Windows 8, this pseudo-handle has only TOKEN_QUERY and TOKEN_QUERY_SOURCE access rights. - /// A thread can create a standard handle that is valid in the context of other threads and can be inherited by other threads. To create this standard handle, call the DuplicateHandle function and specify the pseudo-handle as the source handle. - /// You do not need to close the pseudo-handle when you no longer need it. If you call the CloseHandle function with a pseudo-handle, the function has no effect. If you call DuplicateHandle to duplicate the pseudo-handle, however, you must close the duplicate handle. + /// + /// A thread can create a standard handle that is valid in the context of other threads and can be inherited by other threads. To + /// create this standard handle, call the DuplicateHandle function and specify the pseudo-handle as the source handle. + /// + /// + /// You do not need to close the pseudo-handle when you no longer need it. If you call the CloseHandle function with a + /// pseudo-handle, the function has no effect. If you call DuplicateHandle to duplicate the pseudo-handle, however, you must + /// close the duplicate handle. + /// /// public static readonly SafeTokenHandle CurrentThreadEffectiveToken = new SafeTokenHandle((IntPtr)6, false); - /// Retrieves a pseudo-handle that you can use as a shorthand way to refer to the impersonation token that was assigned to the current thread. - /// A pseudo-handle is a special constant that can function as the impersonation token for the current thread. The calling thread can use a pseudo-handle to specify the impersonation token for that thread whenever a token handle is required. Child threads do not inherit pseudo-handles. + /// + /// Retrieves a pseudo-handle that you can use as a shorthand way to refer to the impersonation token that was assigned to the + /// current thread. + /// + /// + /// A pseudo-handle is a special constant that can function as the impersonation token for the current thread. The calling thread + /// can use a pseudo-handle to specify the impersonation token for that thread whenever a token handle is required. Child threads + /// do not inherit pseudo-handles. /// Starting in Windows 8, this pseudo-handle has only TOKEN_QUERY and TOKEN_QUERY_SOURCE access rights. - /// A thread can create a standard handle that is valid in the context of other threads and can be inherited by other threads. To create this standard handle, call the DuplicateHandle function and specify the pseudo-handle as the source handle. - /// You do not need to close the pseudo-handle when you no longer need it. If you call the CloseHandle function with a pseudo-handle, the function has no effect. If you call DuplicateHandle to duplicate the pseudo-handle, however, you must close the duplicate handle. + /// + /// A thread can create a standard handle that is valid in the context of other threads and can be inherited by other threads. To + /// create this standard handle, call the DuplicateHandle function and specify the pseudo-handle as the source handle. + /// + /// + /// You do not need to close the pseudo-handle when you no longer need it. If you call the CloseHandle function with a + /// pseudo-handle, the function has no effect. If you call DuplicateHandle to duplicate the pseudo-handle, however, you must + /// close the duplicate handle. + /// /// public static readonly SafeTokenHandle CurrentThreadToken = new SafeTokenHandle((IntPtr)5, false); @@ -934,6 +1113,7 @@ namespace Vanara.PInvoke /// Gets an instance that is equivalent to NULL HTOKEN. public static SafeTokenHandle Null { get; } = new SafeTokenHandle(IntPtr.Zero, false); + /// Gets a value indicating whether this token is elevated. /// true if this instance is elevated; otherwise, false. public bool IsElevated => GetInfo(TOKEN_INFORMATION_CLASS.TokenElevation).TokenIsElevated; @@ -942,7 +1122,7 @@ namespace Vanara.PInvoke /// The process handle. /// The desired access. TOKEN_DUPLICATE must usually be included. /// Resulting token handle. - public static SafeTokenHandle FromProcess(IntPtr hProcess, TokenAccess desiredAccess = TokenAccess.TOKEN_DUPLICATE) => + public static SafeTokenHandle FromProcess(IntPtr hProcess, TokenAccess desiredAccess = TokenAccess.TOKEN_DUPLICATE) => !OpenProcessToken(hProcess, desiredAccess, out SafeTokenHandle val) ? throw new Win32Exception() : val; /// Get the token handle instance from a process handle. @@ -969,14 +1149,15 @@ namespace Vanara.PInvoke } /// - /// Retrieves a specified type of information about an access token cast to supplied type. The calling process must have - /// appropriate access rights to obtain the information. The caller is responsible for ensuring that the type requested by - /// matches the type information requested by . + /// Retrieves a specified type of information about an access token cast to supplied type. The calling + /// process must have appropriate access rights to obtain the information. The caller is responsible for + /// ensuring that the type requested by matches the type information requested by . /// /// - /// Specifies a value from the TOKEN_INFORMATION_CLASS enumerated type to identify the type of information the function retrieves. Any callers who - /// check the TokenIsAppContainer and have it return 0 should also verify that the caller token is not an identify level impersonation token. If the - /// current token is not an application container but is an identity level token, you should return AccessDenied. + /// Specifies a value from the TOKEN_INFORMATION_CLASS enumerated type to identify the type of information the function + /// retrieves. Any callers who check the TokenIsAppContainer and have it return 0 should also verify that the caller token is not + /// an identify level impersonation token. If the current token is not an application container but is an identity level token, + /// you should return AccessDenied. /// public T GetInfo(TOKEN_INFORMATION_CLASS tokenInfoClass) { @@ -1004,9 +1185,9 @@ namespace Vanara.PInvoke case TOKEN_INFORMATION_CLASS.TokenOrigin: case TOKEN_INFORMATION_CLASS.TokenElevationType: case TOKEN_INFORMATION_CLASS.TokenUIAccess: - var i = Marshal.ReadInt32((IntPtr) pType); + var i = Marshal.ReadInt32((IntPtr)pType); if (typeof(T).IsEnum) - return (T) Enum.ToObject(typeof(T), i); + return (T)Enum.ToObject(typeof(T), i); return (T)Convert.ChangeType(i, typeof(T)); case TOKEN_INFORMATION_CLASS.TokenLinkedToken: @@ -1038,7 +1219,7 @@ namespace Vanara.PInvoke return pType.ToStructure(); case TOKEN_INFORMATION_CLASS.TokenPrivileges: - return (T)Convert.ChangeType(PTOKEN_PRIVILEGES.FromPtr((IntPtr) pType), typeof(T)); + return (T)Convert.ChangeType(PTOKEN_PRIVILEGES.FromPtr((IntPtr)pType), typeof(T)); default: return default(T); @@ -1047,12 +1228,14 @@ namespace Vanara.PInvoke } /// - /// Retrieves a specified type of information about an access token. The calling process must have appropriate access rights to obtain the information. + /// Retrieves a specified type of information about an access token. The calling process must have appropriate access rights to + /// obtain the information. /// /// - /// Specifies a value from the TOKEN_INFORMATION_CLASS enumerated type to identify the type of information the function retrieves. Any callers who - /// check the TokenIsAppContainer and have it return 0 should also verify that the caller token is not an identify level impersonation token. If the - /// current token is not an application container but is an identity level token, you should return AccessDenied. + /// Specifies a value from the TOKEN_INFORMATION_CLASS enumerated type to identify the type of information the function + /// retrieves. Any callers who check the TokenIsAppContainer and have it return 0 should also verify that the caller token is not + /// an identify level impersonation token. If the current token is not an application container but is an identity level token, + /// you should return AccessDenied. /// /// The block of memory containing the requested information. public SafeCoTaskMemHandle GetInfo(TOKEN_INFORMATION_CLASS tokenInfoClass) @@ -1074,4 +1257,4 @@ namespace Vanara.PInvoke } } } -} +} \ No newline at end of file