Vanara/PInvoke/Security/AdvApi32/WinNT.cs

5098 lines
233 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Text;
using Vanara.Extensions;
using Vanara.InteropServices;
using static Vanara.PInvoke.Kernel32;
namespace Vanara.PInvoke
{
public static partial class AdvApi32
{
/// <summary/>
public const uint SECURITY_DESCRIPTOR_REVISION = 1;
/// <summary/>
public const uint SECURITY_DESCRIPTOR_REVISION1 = 1;
/// <summary/>
public const int SID_MAX_SUB_AUTHORITIES = 15;
/// <summary/>
public const int SID_RECOMMENDED_SUB_AUTHORITIES = 1; // Will change to around 6
/// <summary/>
public const uint SID_REVISION = 1; // Current revision level
private const int sizeofSID = 12;
/// <summary>The maximum size of a SID.</summary>
public static readonly int SECURITY_MAX_SID_SIZE = SECURITY_SID_SIZE(SID_MAX_SUB_AUTHORITIES);
/// <summary>Returns the number of bytes required for SID given the number of sub-authorities.</summary>
/// <param name="SubAuthorityCount">The sub authority count.</param>
/// <returns>The number of bytes required for ths SID.</returns>
public static int SECURITY_SID_SIZE(int SubAuthorityCount) => sizeofSID + ((SubAuthorityCount - 1) * sizeof(uint));
// 2 (S-)
// 4 (Rev(max: 255)-)
// 15 (
// If (Auth < 2^32): Auth(max:4294967295)-
// Else: 0xAuth(max:FFFFFFFFFFFF)-
// )
// (11 * SID_MAX_SUB_AUTHORITIES) (SubN(max:4294967295)-)
// 1 (NULL character)
// = 187 (assuming SID_MAX_SUB_AUTHORITIES = 15)
/// <summary>The maximum characters in a string representation of a SID.</summary>
public const int SECURITY_MAX_SID_STRING_CHARACTERS = (2 + 4 + 15 + (11 * SID_MAX_SUB_AUTHORITIES) + 1);
/// <summary>Indicates whether the ObjectTypeName and InheritedObjectTypeName members contain strings.</summary>
[PInvokeData("winnt.h")]
[Flags]
public enum AceObjectPresence : uint
{
/// <summary>The ObjectTypeName member contains a string.</summary>
ACE_OBJECT_TYPE_PRESENT = 0x1,
/// <summary>The InheritedObjectTypeName member contains a string.</summary>
ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x2
}
/// <summary>Used by the <see cref="GetAclInformation(PACL, IntPtr, uint, ACL_INFORMATION_CLASS)"/> function.</summary>
[PInvokeData("winnt.h")]
public enum ACL_INFORMATION_CLASS : uint
{
/// <summary>Indicates ACL revision information.</summary>
[CorrespondingType(typeof(ACL_REVISION_INFORMATION))]
AclRevisionInformation = 1,
/// <summary>Indicates ACL size information.</summary>
[CorrespondingType(typeof(ACL_SIZE_INFORMATION))]
AclSizeInformation
}
/// <summary>
/// The attribute flags that are a 32-bitmask. Bits 16 through 31 may be set to any value. Bits 0 through 15 must be zero or a
/// combination of one or more of the following mask values.
/// </summary>
[PInvokeData("winnt.h", MSDNShortId = "FDBB9B00-01C3-474A-81FF-97C5CBA3261B")]
[Flags]
public enum CLAIM_SECURITY_ATTRIBUTE_FLAG : uint
{
/// <summary>This attribute is ignored by the operating system. This claim security attribute is not inherited across processes.</summary>
CLAIM_SECURITY_ATTRIBUTE_NON_INHERITABLE = 0x0001,
/// <summary>
/// The value of the claim security attribute is case sensitive. This flag is valid for values that contain string types.
/// </summary>
CLAIM_SECURITY_ATTRIBUTE_VALUE_CASE_SENSITIVE = 0x0002,
/// <summary>The claim security attribute is considered only for deny access control entries (ACEs).</summary>
CLAIM_SECURITY_ATTRIBUTE_USE_FOR_DENY_ONLY = 0x0004,
/// <summary>The claim security attribute is disabled by default.</summary>
CLAIM_SECURITY_ATTRIBUTE_DISABLED_BY_DEFAULT = 0x0008,
/// <summary>The claim security attribute is disabled and will not be applied by the AccessCheck function.</summary>
CLAIM_SECURITY_ATTRIBUTE_DISABLED = 0x0010,
/// <summary>The claim security attribute is mandatory.</summary>
CLAIM_SECURITY_ATTRIBUTE_MANDATORY = 0x0020,
}
/// <summary>A union tag value that indicates the type of information contained in the <c>Values</c> member.</summary>
[PInvokeData("winnt.h", MSDNShortId = "FDBB9B00-01C3-474A-81FF-97C5CBA3261B")]
public enum CLAIM_SECURITY_ATTRIBUTE_TYPE : ushort
{
/// <summary>The Values member refers to an array of LONG64 values.</summary>
CLAIM_SECURITY_ATTRIBUTE_TYPE_INT64 = 0x0001,
/// <summary>The Values member refers to an array of ULONG64 values.</summary>
CLAIM_SECURITY_ATTRIBUTE_TYPE_UINT64 = 0x0002,
/// <summary>The Values member refers to an array of pointers to Unicode string values.</summary>
CLAIM_SECURITY_ATTRIBUTE_TYPE_STRING = 0x0003,
/// <summary>The Values member refers to an array of CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE values.</summary>
CLAIM_SECURITY_ATTRIBUTE_TYPE_FQBN = 0x0004,
/// <summary>
/// The Values member refers to an array of CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE values where the pValue member of each
/// CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE is a PSID.
/// </summary>
CLAIM_SECURITY_ATTRIBUTE_TYPE_SID = 0x0005,
/// <summary>
/// The Values member refers to an array of ULONG64 values where each element indicates a Boolean value. The value 1 indicates
/// TRUE and the value 0 indicates FALSE.
/// </summary>
CLAIM_SECURITY_ATTRIBUTE_TYPE_BOOLEAN = 0x0006,
/// <summary>The Values member refers to an array of CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE values.</summary>
CLAIM_SECURITY_ATTRIBUTE_TYPE_OCTET_STRING = 0x0010,
}
/// <summary>Flags that affect the behavior of <see cref="CheckTokenMembershipEx"/>.</summary>
[PInvokeData("winnt.h")]
[Flags]
public enum CTMF : uint
{
/// <summary>
/// Allows app containers to pass the call as long as the other requirements of the token are met, such as the group specified is
/// present and enabled.
/// </summary>
CTMF_INCLUDE_APPCONTAINER = 0x00000001,
/// <summary>Undocumented.</summary>
CTMF_INCLUDE_LPAC = 0x00000002
}
/// <summary>The status of the event log.</summary>
[PInvokeData("Winnt.h", MSDNShortId = "bb309024")]
[Flags]
public enum ELF_FLAGS
{
/// <summary>
/// Indicates that records have been written to an event log, but the event log file has not been properly closed. For more
/// information about this flag, see the Remarks section.
/// </summary>
ELF_LOGFILE_HEADER_DIRTY = 0x0001,
/// <summary>Indicates that records in the event log have wrapped.</summary>
ELF_LOGFILE_HEADER_WRAP = 0x0002,
/// <summary>Indicates that the most recent write attempt failed due to insufficient space.</summary>
ELF_LOGFILE_LOGFULL_WRITTEN = 0x0004,
/// <summary>
/// Indicates that the archive attribute has been set for the file. Normal file APIs can also be used to determine the value of
/// this flag.
/// </summary>
ELF_LOGFILE_ARCHIVE_SET = 0x0008,
}
/// <summary>Indicate how to read the log file.</summary>
[PInvokeData("winnt.h", MSDNShortId = "53706f83-6bc9-45d6-981c-bd0680d7bc08")]
[Flags]
public enum EVENTLOG_READ
{
/// <summary>The eventlog sequential read</summary>
EVENTLOG_SEQUENTIAL_READ = 0x0001,
/// <summary>
/// Begin reading from the record specified in the dwRecordOffset parameter. This option may not work with large log files if the
/// function cannot determine the log file's size. For details, see Knowledge Base article, 177199.
/// </summary>
EVENTLOG_SEEK_READ = 0x0002,
/// <summary>The log is read in chronological order (oldest to newest).</summary>
EVENTLOG_FORWARDS_READ = 0x0004,
/// <summary>The log is read in reverse chronological order (newest to oldest).</summary>
EVENTLOG_BACKWARDS_READ = 0x0008,
}
/// <summary>The type of event to be logged.</summary>
[PInvokeData("winnt.h", MSDNShortId = "e39273c3-9e42-41a1-9ec1-1cdff2ab7b55")]
public enum EVENTLOG_TYPE : ushort
{
/// <summary>Information event</summary>
EVENTLOG_SUCCESS = 0x0000,
/// <summary>Error event</summary>
EVENTLOG_ERROR_TYPE = 0x0001,
/// <summary>Warning event</summary>
EVENTLOG_WARNING_TYPE = 0x0002,
/// <summary>Information event</summary>
EVENTLOG_INFORMATION_TYPE = 0x0004,
/// <summary>Success Audit event</summary>
EVENTLOG_AUDIT_SUCCESS = 0x0008,
/// <summary>Failure Audit event</summary>
EVENTLOG_AUDIT_FAILURE = 0x0010,
}
/// <summary>Group attributes.</summary>
[Flags]
[PInvokeData("winnt.h")]
public enum GroupAttributes : uint
{
/// <summary>
/// The SID cannot have the SE_GROUP_ENABLED attribute cleared by a call to the AdjustTokenGroups function. However, you can use
/// the CreateRestrictedToken function to convert a mandatory SID to a deny-only SID.
/// </summary>
SE_GROUP_MANDATORY = 0x00000001,
/// <summary>The SID is enabled by default.</summary>
SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002,
/// <summary>
/// The SID is enabled for access checks. When the system performs an access check, it checks for access-allowed and
/// access-denied access control entries (ACEs) that apply to the SID. A SID without this attribute is ignored during an access
/// check unless the SE_GROUP_USE_FOR_DENY_ONLY attribute is set.
/// </summary>
SE_GROUP_ENABLED = 0x00000004,
/// <summary>
/// The SID identifies a group account for which the user of the token is the owner of the group, or the SID can be assigned as
/// the owner of the token or objects.
/// </summary>
SE_GROUP_OWNER = 0x00000008,
/// <summary>
/// The SID is a deny-only SID in a restricted token. When the system performs an access check, it checks for access-denied ACEs
/// that apply to the SID; it ignores access-allowed ACEs for the SID. If this attribute is set, SE_GROUP_ENABLED is not set, and
/// the SID cannot be reenabled.
/// </summary>
SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010,
/// <summary>The SID is a mandatory integrity SID.</summary>
SE_GROUP_INTEGRITY = 0x00000020,
/// <summary>The SID is enabled for mandatory integrity checks.</summary>
SE_GROUP_INTEGRITY_ENABLED = 0x00000040,
/// <summary>The SID is a logon SID that identifies the logon session associated with an access token.</summary>
SE_GROUP_LOGON_ID = 0xC0000000,
/// <summary>The SID identifies a domain-local group.</summary>
SE_GROUP_RESOURCE = 0x20000000
}
/// <summary>
/// The capability SID constants define for applications well-known capabilities by using the AllocateAndInitializeSid function.
/// </summary>
/// <remarks>
/// When constructing a capability SID, you need to include the package authority, SECURITY_APP_PACKAGE_AUTHORITY {0,0,0,0,0,15}, in
/// the call to the AllocateAndInitializeSid function. Additionally, you need the base RID and RID count for the built-in
/// capabilities, SECURITY_CAPABILITY_BASE_RID (0x00000003L) and SECURITY_BUILTIN_CAPABILITY_RID_COUNT (2L).
/// </remarks>
public enum KnownSIDCapability
{
/// <summary>An account has access to the Internet from a client computer.</summary>
SECURITY_CAPABILITY_INTERNET_CLIENT = 0x00000001,
/// <summary>An account has access to the Internet from the client and server computers.</summary>
SECURITY_CAPABILITY_INTERNET_CLIENT_SERVER = 0x00000002,
/// <summary>An account has access to the Internet from a private network.</summary>
SECURITY_CAPABILITY_PRIVATE_NETWORK_CLIENT_SERVER = 0x00000003,
/// <summary>An account has access to the pictures library.</summary>
SECURITY_CAPABILITY_PICTURES_LIBRARY = 0x00000004,
/// <summary>An account has access to the videos library.</summary>
SECURITY_CAPABILITY_VIDEOS_LIBRARY = 0x00000005,
/// <summary>An account has access to the music library.</summary>
SECURITY_CAPABILITY_MUSIC_LIBRARY = 0x00000006,
/// <summary>An account has access to the documentation library.</summary>
SECURITY_CAPABILITY_DOCUMENTS_LIBRARY = 0x00000007,
/// <summary>An account has access to the default Windows credentials.</summary>
SECURITY_CAPABILITY_ENTERPRISE_AUTHENTICATION = 0x00000008,
/// <summary>An account has access to the shared user certificates.</summary>
SECURITY_CAPABILITY_SHARED_USER_CERTIFICATES = 0x00000009,
/// <summary>An account has access to removable storage.</summary>
SECURITY_CAPABILITY_REMOVABLE_STORAGE = 0x0000000A,
}
/// <summary>
/// A set of bit flags that indicate whether the <c>ObjectType</c> and <c>InheritedObjectType</c> members are present in an object ACE.
/// </summary>
[Flags]
public enum ObjectAceFlags : uint
{
/// <summary>
/// ObjectType is present and contains a GUID. If this value is not specified, the InheritedObjectType member follows immediately
/// after the Flags member.
/// </summary>
ACE_OBJECT_TYPE_PRESENT = 0x1,
/// <summary>
/// InheritedObjectType is present and contains a GUID. If this value is not specified, all types of child objects can inherit
/// the ACE.
/// </summary>
ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x2
}
/// <summary>Privilege attributes.</summary>
[Flags]
[PInvokeData("winnt.h")]
public enum PrivilegeAttributes : uint
{
/// <summary>The privilege is disabled.</summary>
SE_PRIVILEGE_DISABLED = 0x00000000,
/// <summary>The privilege is enabled by default.</summary>
SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001,
/// <summary>The privilege is enabled.</summary>
SE_PRIVILEGE_ENABLED = 0x00000002,
/// <summary>Used to remove a privilege. The other privileges in the list are reordered to remain contiguous.</summary>
SE_PRIVILEGE_REMOVED = 0x00000004,
/// <summary>
/// The privilege was used to gain access to an object or service. This flag is used to identify the relevant privileges in a set
/// passed by a client application that may contain unnecessary privileges.
/// </summary>
SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000
}
/// <summary>Flags used by PRIVILEGE_SET.</summary>
[PInvokeData("winnt.h")]
public enum PrivilegeSetControl
{
/// <summary>The presence of any privileges in the user's access token grants the access.</summary>
None = 0,
/// <summary>Indicates that all of the specified privileges must be held by the process requesting access.</summary>
PRIVILEGE_SET_ALL_NECESSARY = 1
}
/// <summary>Additional privilege options for <see cref="CreateRestrictedToken"/>.</summary>
[PInvokeData("winnt.h")]
public enum RestrictedPrivilegeOptions : uint
{
/// <summary>
/// Disables all privileges in the new token except the SeChangeNotifyPrivilege privilege. If this value is specified, the
/// DeletePrivilegeCount and PrivilegesToDelete parameters are ignored.
/// </summary>
DISABLE_MAX_PRIVILEGE = 0x1,
/// <summary>
/// If this value is used, the system does not check AppLocker rules or apply Software Restriction Policies. For AppLocker, this
/// flag disables checks for all four rule collections: Executable, Windows Installer, Script, and DLL.
/// <para>
/// When creating a setup program that must run extracted DLLs during installation, use the flag SAFER_TOKEN_MAKE_INERT in the
/// SaferComputeTokenFromLevel function.
/// </para>
/// <para>A token can be queried for existence of this flag by using GetTokenInformation.</para>
/// <para>
/// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: On systems with
/// KB2532445 installed, the caller must be running as LocalSystem or TrustedInstaller or the system ignores this flag. For more
/// information, see "You can circumvent AppLocker rules by using an Office macro on a computer that is running Windows 7 or
/// Windows Server 2008 R2" in the Help and Support Knowledge Base at http://support.microsoft.com/kb/2532445.
/// </para>
/// <para>
/// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: AppLocker is not supported. AppLocker was introduced
/// in Windows 7 and Windows Server 2008 R2.
/// </para>
/// </summary>
SANDBOX_INERT = 0x2,
/// <summary>
/// The new token is a LUA token.
/// <para>Windows Server 2003 and Windows XP: This value is not supported.</para>
/// </summary>
LUA_TOKEN = 0x4,
/// <summary>
/// The new token contains restricting SIDs that are considered only when evaluating write access.
/// <para>
/// Windows XP with SP2 and later: The value of this constant is 0x4. For an application to be compatible with Windows XP with
/// SP2 and later operating systems, the application should query the operating system by calling the GetVersionEx function to
/// determine which value should be used.
/// </para>
/// <para>Windows Server 2003 and Windows XP with SP1 and earlier: This value is not supported.</para>
/// </summary>
WRITE_RESTRICTED = 0x8,
}
/// <summary>
/// A set of bit flags that qualify the meaning of a security descriptor or its components. Each security descriptor has a Control
/// member that stores the SECURITY_DESCRIPTOR_CONTROL bits.
/// </summary>
[Flags]
public enum SECURITY_DESCRIPTOR_CONTROL : ushort
{
/// <summary>
/// Indicates a required security descriptor in which the discretionary access control list (DACL) is set up to support automatic
/// propagation of inheritable access control entries (ACEs) to existing child objects.
/// <para>
/// For access control lists (ACLs) that support auto inheritance, this bit is always set. Protected servers can call the
/// ConvertToAutoInheritPrivateObjectSecurity function to convert a security descriptor and set this flag.
/// </para>
/// </summary>
SE_DACL_AUTO_INHERIT_REQ = 0x0100,
/// <summary>
/// Indicates a security descriptor in which the discretionary access control list (DACL) is set up to support automatic
/// propagation of inheritable access control entries (ACEs) to existing child objects.
/// <para>
/// For access control lists (ACLs) that support auto inheritance, this bit is always set. Protected servers can call the
/// ConvertToAutoInheritPrivateObjectSecurity function to convert a security descriptor and set this flag.
/// </para>
/// </summary>
SE_DACL_AUTO_INHERITED = 0x0400,
/// <summary>
/// Indicates a security descriptor with a default DACL. For example, if the creator an object does not specify a DACL, the
/// object receives the default DACL from the access token of the creator. This flag can affect how the system treats the DACL
/// with respect to ACE inheritance. The system ignores this flag if the SE_DACL_PRESENT flag is not set.
/// <para>
/// This flag is used to determine how the final DACL on the object is to be computed and is not stored physically in the
/// security descriptor control of the securable object.
/// </para>
/// <para>To set this flag, use the SetSecurityDescriptorDacl function.</para>
/// </summary>
SE_DACL_DEFAULTED = 0x0008,
/// <summary>
/// Indicates a security descriptor that has a DACL. If this flag is not set, or if this flag is set and the DACL is NULL, the
/// security descriptor allows full access to everyone.
/// <para>
/// This flag is used to hold the security information specified by a caller until the security descriptor is associated with a
/// securable object. After the security descriptor is associated with a securable object, the SE_DACL_PRESENT flag is always set
/// in the security descriptor control.
/// </para>
/// <para>To set this flag, use the SetSecurityDescriptorDacl function.</para>
/// </summary>
SE_DACL_PRESENT = 0x0004,
/// <summary>
/// Prevents the DACL of the security descriptor from being modified by inheritable ACEs. To set this flag, use the
/// SetSecurityDescriptorControl function.
/// </summary>
SE_DACL_PROTECTED = 0x1000,
/// <summary>
/// Indicates that the security identifier (SID) of the security descriptor group was provided by a default mechanism. This flag
/// can be used by a resource manager to identify objects whose security descriptor group was set by a default mechanism. To set
/// this flag, use the SetSecurityDescriptorGroup function.
/// </summary>
SE_GROUP_DEFAULTED = 0x0002,
/// <summary>
/// Indicates that the SID of the owner of the security descriptor was provided by a default mechanism. This flag can be used by
/// a resource manager to identify objects whose owner was set by a default mechanism. To set this flag, use the
/// SetSecurityDescriptorOwner function.
/// </summary>
SE_OWNER_DEFAULTED = 0x0001,
/// <summary>Indicates that the resource manager control is valid.</summary>
SE_RM_CONTROL_VALID = 0x4000,
/// <summary>
/// Indicates a required security descriptor in which the system access control list (SACL) is set up to support automatic
/// propagation of inheritable ACEs to existing child objects.
/// <para>
/// The system sets this bit when it performs the automatic inheritance algorithm for the object and its existing child objects.
/// To convert a security descriptor and set this flag, protected servers can call the ConvertToAutoInheritPrivateObjectSecurity function.
/// </para>
/// </summary>
SE_SACL_AUTO_INHERIT_REQ = 0x0200,
/// <summary>
/// Indicates a security descriptor in which the system access control list (SACL) is set up to support automatic propagation of
/// inheritable ACEs to existing child objects.
/// <para>
/// The system sets this bit when it performs the automatic inheritance algorithm for the object and its existing child objects.
/// To convert a security descriptor and set this flag, protected servers can call the ConvertToAutoInheritPrivateObjectSecurity function.
/// </para>
/// </summary>
SE_SACL_AUTO_INHERITED = 0x0800,
/// <summary>
/// A default mechanism, rather than the original provider of the security descriptor, provided the SACL. This flag can affect
/// how the system treats the SACL, with respect to ACE inheritance. The system ignores this flag if the SE_SACL_PRESENT flag is
/// not set. To set this flag, use the SetSecurityDescriptorSacl function.
/// </summary>
SE_SACL_DEFAULTED = 0x0008,
/// <summary>Indicates a security descriptor that has a SACL. To set this flag, use the SetSecurityDescriptorSacl function.</summary>
SE_SACL_PRESENT = 0x0010,
/// <summary>
/// Prevents the SACL of the security descriptor from being modified by inheritable ACEs. To set this flag, use the
/// SetSecurityDescriptorControl function.
/// </summary>
SE_SACL_PROTECTED = 0x2000,
/// <summary>
/// Indicates a self-relative security descriptor. If this flag is not set, the security descriptor is in absolute format. For
/// more information, see Absolute and Self-Relative Security Descriptors.
/// </summary>
SE_SELF_RELATIVE = 0x8000
}
/// <summary>
/// The SECURITY_IMPERSONATION_LEVEL enumeration contains values that specify security impersonation levels. Security impersonation
/// levels govern the degree to which a server process can act on behalf of a client process.
/// </summary>
[PInvokeData("winnt.h")]
public enum SECURITY_IMPERSONATION_LEVEL
{
/// <summary>
/// The server process cannot obtain identification information about the client, and it cannot impersonate the client. It is
/// defined with no value given, and thus, by ANSI C rules, defaults to a value of zero.
/// </summary>
SecurityAnonymous,
/// <summary>
/// The server process can obtain information about the client, such as security identifiers and privileges, but it cannot
/// impersonate the client. This is useful for servers that export their own objects, for example, database products that export
/// tables and views. Using the retrieved client-security information, the server can make access-validation decisions without
/// being able to use other services that are using the client's security context.
/// </summary>
SecurityIdentification,
/// <summary>
/// The server process can impersonate the client's security context on its local system. The server cannot impersonate the
/// client on remote systems.
/// </summary>
SecurityImpersonation,
/// <summary>The server process can impersonate the client's security context on remote systems.</summary>
SecurityDelegation
}
/// <summary>A set of bit flags that control how access control entries (ACEs) are inherited from ParentDescriptor.</summary>
[PInvokeData("winnt.h")]
[Flags]
public enum SEF : uint
{
/// <summary>
/// The new discretionary access control list (DACL) contains ACEs inherited from the DACL of ParentDescriptor, as well as any
/// explicit ACEs specified in the DACL of CreatorDescriptor. If this flag is not set, the new DACL does not inherit ACEs.
/// </summary>
SEF_DACL_AUTO_INHERIT = 0x01,
/// <summary>
/// The new system access control list (SACL) contains ACEs inherited from the SACL of ParentDescriptor, as well as any explicit
/// ACEs specified in the SACL of CreatorDescriptor. If this flag is not set, the new SACL does not inherit ACEs.
/// </summary>
SEF_SACL_AUTO_INHERIT = 0x02,
/// <summary>
/// CreatorDescriptor is the default descriptor for the types of objects specified by ObjectTypes. As such, CreatorDescriptor is
/// ignored if ParentDescriptor has any object-specific ACEs for the types of objects specified by the ObjectTypes parameter. If
/// no such ACEs are inherited, CreatorDescriptor is handled as though this flag were not specified.
/// </summary>
SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT = 0x04,
/// <summary>
/// The function does not perform privilege checking. If the SEF_AVOID_OWNER_CHECK flag is also set, the Token parameter can be
/// NULL. This flag is useful while implementing automatic inheritance to avoid checking privileges on each child updated.
/// </summary>
SEF_AVOID_PRIVILEGE_CHECK = 0x08,
/// <summary>
/// The function does not check the validity of the owner in the resultant NewDescriptor as described in the Remarks section. If
/// the SEF_AVOID_PRIVILEGE_CHECK flag is also set, the Token parameter can be NULL.
/// </summary>
SEF_AVOID_OWNER_CHECK = 0x10,
/// <summary>
/// The owner of NewDescriptor defaults to the owner from ParentDescriptor. If not set, the owner of NewDescriptor defaults to
/// the owner of the token specified by the Token parameter. The owner of the token is specified in the token itself. In either
/// case, if the CreatorDescriptor parameter is not NULL, the NewDescriptor owner is set to the owner from CreatorDescriptor.
/// </summary>
SEF_DEFAULT_OWNER_FROM_PARENT = 0x20,
/// <summary>
/// The group of NewDescriptor defaults to the group from ParentDescriptor. If not set, the group of NewDescriptor defaults to
/// the group of the token specified by the Token parameter. The group of the token is specified in the token itself. In either
/// case, if the CreatorDescriptor parameter is not NULL, the NewDescriptor group is set to the group from CreatorDescriptor.
/// </summary>
SEF_DEFAULT_GROUP_FROM_PARENT = 0x40,
/// <summary>A principal with a mandatory level lower than that of the object cannot write to the object.</summary>
SEF_MACL_NO_WRITE_UP = 0x100,
/// <summary>A principal with a mandatory level lower than that of the object cannot read the object.</summary>
SEF_MACL_NO_READ_UP = 0x200,
/// <summary>A principal with a mandatory level lower than that of the object cannot execute the object.</summary>
SEF_MACL_NO_EXECUTE_UP = 0x400,
/// <summary>Undocumented</summary>
SEF_AI_USE_EXTRA_PARAMS = 0x800,
/// <summary>
/// Any restrictions specified by the ParentDescriptor parameter that would limit the caller's ability to specify a DACL in the
/// CreatorDescriptor are ignored.
/// </summary>
SEF_AVOID_OWNER_RESTRICTION = 0x1000,
/// <summary>Undocumented</summary>
SEF_FORCE_USER_MODE = 0x2000
}
/// <summary>The SID_NAME_USE enumeration contains values that specify the type of a security identifier (SID).</summary>
public enum SID_NAME_USE
{
/// <summary>A user SID.</summary>
SidTypeUser = 1,
/// <summary>A group SID</summary>
SidTypeGroup,
/// <summary>A domain SID.</summary>
SidTypeDomain,
/// <summary>An alias SID.</summary>
SidTypeAlias,
/// <summary>A SID for a well-known group.</summary>
SidTypeWellKnownGroup,
/// <summary>A SID for a deleted account.</summary>
SidTypeDeletedAccount,
/// <summary>A SID that is not valid.</summary>
SidTypeInvalid,
/// <summary>A SID of unknown type/.</summary>
SidTypeUnknown,
/// <summary>A SID for a computer.</summary>
SidTypeComputer,
/// <summary>A mandatory integrity label SID.</summary>
SidTypeLabel,
/// <summary/>
SidTypeLogonSession
}
/// <summary>
/// The access policy for principals with a mandatory integrity level lower than the object associated with the SACL that contains
/// this ACE.
/// </summary>
[PInvokeData("winnt.h")]
[Flags]
public enum SYSTEM_MANDATORY_LABEL : uint
{
/// <summary>A principal with a lower mandatory level than the object cannot write to the object.</summary>
SYSTEM_MANDATORY_LABEL_NO_WRITE_UP = 0x1,
/// <summary>A principal with a lower mandatory level than the object cannot read the object.</summary>
SYSTEM_MANDATORY_LABEL_NO_READ_UP = 0x2,
/// <summary>A principal with a lower mandatory level than the object cannot execute the object.</summary>
SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP = 0x4,
}
/// <summary>
/// The TOKEN_ELEVATION_TYPE enumeration indicates the elevation type of token being queried by the GetTokenInformation function.
/// </summary>
[PInvokeData("winnt.h")]
public enum TOKEN_ELEVATION_TYPE
{
/// <summary>The token does not have a linked token.</summary>
TokenElevationTypeDefault = 1,
/// <summary>The token is an elevated token.</summary>
TokenElevationTypeFull,
/// <summary>The token is a limited token.</summary>
TokenElevationTypeLimited
}
/// <summary>
/// The TOKEN_INFORMATION_CLASS enumeration contains values that specify the type of information being assigned to or retrieved from
/// an access token.
/// <para>The GetTokenInformation function uses these values to indicate the type of token information to retrieve.</para>
/// <para>The SetTokenInformation function uses these values to set the token information.</para>
/// </summary>
[PInvokeData("winnt.h")]
public enum TOKEN_INFORMATION_CLASS
{
/// <summary>The buffer receives a TOKEN_USER structure that contains the user account of the token.</summary>
[CorrespondingType(typeof(TOKEN_USER), CorrespondingAction.Get)]
TokenUser = 1,
/// <summary>The buffer receives a TOKEN_GROUPS structure that contains the group accounts associated with the token.</summary>
[CorrespondingType(typeof(TOKEN_GROUPS), CorrespondingAction.Get)]
TokenGroups,
/// <summary>The buffer receives a TOKEN_PRIVILEGES structure that contains the privileges of the token.</summary>
[CorrespondingType(typeof(TOKEN_PRIVILEGES), CorrespondingAction.Get)]
TokenPrivileges,
/// <summary>
/// The buffer receives a TOKEN_OWNER structure that contains the default owner security identifier (SID) for newly created objects.
/// </summary>
[CorrespondingType(typeof(TOKEN_OWNER), CorrespondingAction.GetSet)]
TokenOwner,
/// <summary>
/// The buffer receives a TOKEN_PRIMARY_GROUP structure that contains the default primary group SID for newly created objects.
/// </summary>
[CorrespondingType(typeof(TOKEN_PRIMARY_GROUP), CorrespondingAction.GetSet)]
TokenPrimaryGroup,
/// <summary>The buffer receives a TOKEN_DEFAULT_DACL structure that contains the default DACL for newly created objects.</summary>
[CorrespondingType(typeof(TOKEN_DEFAULT_DACL), CorrespondingAction.GetSet)]
TokenDefaultDacl,
/// <summary>
/// The buffer receives a TOKEN_SOURCE structure that contains the source of the token. TOKEN_QUERY_SOURCE access is needed to
/// retrieve this information.
/// </summary>
[CorrespondingType(typeof(TOKEN_SOURCE), CorrespondingAction.Get)]
TokenSource,
/// <summary>The buffer receives a TOKEN_TYPE value that indicates whether the token is a primary or impersonation token.</summary>
[CorrespondingType(typeof(TOKEN_TYPE), CorrespondingAction.Get)]
TokenType,
/// <summary>
/// The buffer receives a SECURITY_IMPERSONATION_LEVEL value that indicates the impersonation level of the token. If the access
/// token is not an impersonation token, the function fails.
/// </summary>
[CorrespondingType(typeof(SECURITY_IMPERSONATION_LEVEL), CorrespondingAction.Get)]
TokenImpersonationLevel,
/// <summary>The buffer receives a TOKEN_STATISTICS structure that contains various token statistics.</summary>
[CorrespondingType(typeof(TOKEN_STATISTICS), CorrespondingAction.Get)]
TokenStatistics,
/// <summary>The buffer receives a TOKEN_GROUPS structure that contains the list of restricting SIDs in a restricted token.</summary>
[CorrespondingType(typeof(TOKEN_GROUPS), CorrespondingAction.Get)]
TokenRestrictedSids,
/// <summary>
/// The buffer receives a DWORD value that indicates the Terminal Services session identifier that is associated with the token.
/// <para>If the token is associated with the terminal server client session, the session identifier is nonzero.</para>
/// <para>
/// Windows Server 2003 and Windows XP: If the token is associated with the terminal server console session, the session
/// identifier is zero.
/// </para>
/// <para>In a non-Terminal Services environment, the session identifier is zero.</para>
/// <para>
/// If TokenSessionId is set with SetTokenInformation, the application must have the Act As Part Of the Operating System
/// privilege, and the application must be enabled to set the session ID in a token.
/// </para>
/// </summary>
[CorrespondingType(typeof(uint), CorrespondingAction.GetSet)]
TokenSessionId,
/// <summary>
/// The buffer receives a TOKEN_GROUPS_AND_PRIVILEGES structure that contains the user SID, the group accounts, the restricted
/// SIDs, and the authentication ID associated with the token.
/// </summary>
[CorrespondingType(typeof(TOKEN_GROUPS_AND_PRIVILEGES), CorrespondingAction.Get)]
TokenGroupsAndPrivileges,
/// <summary>Reserved.</summary>
[CorrespondingType(CorrespondingAction.Exception)]
TokenSessionReference,
/// <summary>The buffer receives a DWORD value that is nonzero if the token includes the SANDBOX_INERT flag.</summary>
[CorrespondingType(typeof(uint), CorrespondingAction.Get)]
TokenSandBoxInert,
/// <summary>Reserved.</summary>
[CorrespondingType(CorrespondingAction.Exception)]
TokenAuditPolicy,
/// <summary>
/// The buffer receives a TOKEN_ORIGIN value.
/// <para>
/// If the token resulted from a logon that used explicit credentials, such as passing a name, domain, and password to the
/// LogonUser function, then the TOKEN_ORIGIN structure will contain the ID of the logon session that created it.
/// </para>
/// <para>
/// If the token resulted from network authentication, such as a call to AcceptSecurityContext or a call to LogonUser with
/// dwLogonType set to LOGON32_LOGON_NETWORK or LOGON32_LOGON_NETWORK_CLEARTEXT, then this value will be zero.
/// </para>
/// </summary>
[CorrespondingType(typeof(TOKEN_ORIGIN), CorrespondingAction.GetSet)]
TokenOrigin,
/// <summary>The buffer receives a TOKEN_ELEVATION_TYPE value that specifies the elevation level of the token.</summary>
[CorrespondingType(typeof(TOKEN_ELEVATION_TYPE), CorrespondingAction.Get)]
TokenElevationType,
/// <summary>
/// The buffer receives a TOKEN_LINKED_TOKEN structure that contains a handle to another token that is linked to this token.
/// </summary>
[CorrespondingType(typeof(TOKEN_LINKED_TOKEN), CorrespondingAction.GetSet)]
TokenLinkedToken,
/// <summary>The buffer receives a TOKEN_ELEVATION structure that specifies whether the token is elevated.</summary>
[CorrespondingType(typeof(TOKEN_ELEVATION), CorrespondingAction.Get)]
TokenElevation,
/// <summary>The buffer receives a DWORD value that is nonzero if the token has ever been filtered.</summary>
[CorrespondingType(typeof(uint), CorrespondingAction.Get)]
TokenHasRestrictions,
/// <summary>
/// The buffer receives a TOKEN_ACCESS_INFORMATION structure that specifies security information contained in the token.
/// </summary>
[CorrespondingType(typeof(TOKEN_ACCESS_INFORMATION), CorrespondingAction.Get)]
TokenAccessInformation,
/// <summary>The buffer receives a DWORD value that is nonzero if virtualization is allowed for the token.</summary>
[CorrespondingType(typeof(uint), CorrespondingAction.GetSet)]
TokenVirtualizationAllowed,
/// <summary>The buffer receives a DWORD value that is nonzero if virtualization is enabled for the token.</summary>
[CorrespondingType(typeof(uint), CorrespondingAction.GetSet)]
TokenVirtualizationEnabled,
/// <summary>The buffer receives a TOKEN_MANDATORY_LABEL structure that specifies the token's integrity level.</summary>
[CorrespondingType(typeof(TOKEN_MANDATORY_LABEL), CorrespondingAction.GetSet)]
TokenIntegrityLevel,
/// <summary>The buffer receives a DWORD value that is nonzero if the token has the UIAccess flag set.</summary>
[CorrespondingType(typeof(uint), CorrespondingAction.GetSet)]
TokenUIAccess,
/// <summary>The buffer receives a TOKEN_MANDATORY_POLICY structure that specifies the token's mandatory integrity policy.</summary>
[CorrespondingType(typeof(TOKEN_MANDATORY_POLICY), CorrespondingAction.GetSet)]
TokenMandatoryPolicy,
/// <summary>The buffer receives a TOKEN_GROUPS structure that specifies the token's logon SID.</summary>
[CorrespondingType(typeof(TOKEN_GROUPS), CorrespondingAction.Get)]
TokenLogonSid,
/// <summary>
/// The buffer receives a DWORD value that is nonzero if the token is an application container token. 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.
/// </summary>
[CorrespondingType(typeof(uint), CorrespondingAction.Get)]
TokenIsAppContainer,
/// <summary>The buffer receives a TOKEN_GROUPS structure that contains the capabilities associated with the token.</summary>
[CorrespondingType(typeof(TOKEN_GROUPS), CorrespondingAction.Get)]
TokenCapabilities,
/// <summary>
/// The buffer receives a TOKEN_APPCONTAINER_INFORMATION structure that contains the AppContainerSid associated with the token.
/// If the token is not associated with an application container, the TokenAppContainer member of the
/// TOKEN_APPCONTAINER_INFORMATION structure points to NULL.
/// </summary>
[CorrespondingType(typeof(TOKEN_APPCONTAINER_INFORMATION), CorrespondingAction.Get)]
TokenAppContainerSid,
/// <summary>
/// The buffer receives a DWORD value that includes the application container number for the token. For tokens that are not
/// application container tokens, this value is zero.
/// </summary>
[CorrespondingType(typeof(uint), CorrespondingAction.Get)]
TokenAppContainerNumber,
/// <summary>
/// The buffer receives a CLAIM_SECURITY_ATTRIBUTES_INFORMATION structure that contains the user claims associated with the token.
/// </summary>
[CorrespondingType(typeof(CLAIM_SECURITY_ATTRIBUTES_INFORMATION), CorrespondingAction.Get)]
TokenUserClaimAttributes,
/// <summary>
/// The buffer receives a CLAIM_SECURITY_ATTRIBUTES_INFORMATION structure that contains the device claims associated with the token.
/// </summary>
[CorrespondingType(typeof(CLAIM_SECURITY_ATTRIBUTES_INFORMATION), CorrespondingAction.Get)]
TokenDeviceClaimAttributes,
/// <summary>This value is reserved.</summary>
[CorrespondingType(CorrespondingAction.Exception)]
TokenRestrictedUserClaimAttributes,
/// <summary>This value is reserved.</summary>
[CorrespondingType(CorrespondingAction.Exception)]
TokenRestrictedDeviceClaimAttributes,
/// <summary>The buffer receives a TOKEN_GROUPS structure that contains the device groups that are associated with the token.</summary>
[CorrespondingType(typeof(TOKEN_GROUPS), CorrespondingAction.Get)]
TokenDeviceGroups,
/// <summary>
/// The buffer receives a TOKEN_GROUPS structure that contains the restricted device groups that are associated with the token.
/// </summary>
[CorrespondingType(typeof(TOKEN_GROUPS), CorrespondingAction.Get)]
TokenRestrictedDeviceGroups,
/// <summary>This value is reserved.</summary>
[CorrespondingType(CorrespondingAction.Exception)]
TokenSecurityAttributes,
/// <summary>This value is reserved.</summary>
[CorrespondingType(CorrespondingAction.Exception)]
TokenIsRestricted
}
/// <summary>The TOKEN_TYPE enumeration contains values that differentiate between a primary token and an impersonation token.</summary>
[Serializable]
[PInvokeData("winnt.h")]
public enum TOKEN_TYPE
{
/// <summary>Indicates a primary token.</summary>
TokenPrimary = 1,
/// <summary>Indicates an impersonation token.</summary>
TokenImpersonation = 2
}
/// <summary>Token access flags.</summary>
[Flags]
[PInvokeData("winnt.h")]
public enum TokenAccess : uint
{
/// <summary>
/// Required to attach a primary token to a process. The SE_ASSIGNPRIMARYTOKEN_NAME privilege is also required to accomplish this task.
/// </summary>
TOKEN_ASSIGN_PRIMARY = 0x0001,
/// <summary>Required to duplicate an access token.</summary>
TOKEN_DUPLICATE = 0x0002,
/// <summary>Required to attach an impersonation access token to a process.</summary>
TOKEN_IMPERSONATE = 0x0004,
/// <summary>Required to query an access token.</summary>
TOKEN_QUERY = 0x0008,
/// <summary>Required to query the source of an access token.</summary>
TOKEN_QUERY_SOURCE = 0x0010,
/// <summary>Required to enable or disable the privileges in an access token.</summary>
TOKEN_ADJUST_PRIVILEGES = 0x0020,
/// <summary>Required to adjust the attributes of the groups in an access token.</summary>
TOKEN_ADJUST_GROUPS = 0x0040,
/// <summary>Required to change the default owner, primary group, or DACL of an access token.</summary>
TOKEN_ADJUST_DEFAULT = 0x0080,
/// <summary>Required to adjust the session ID of an access token. The SE_TCB_NAME privilege is required.</summary>
TOKEN_ADJUST_SESSIONID = 0x0100,
/// <summary>The token all access p</summary>
TOKEN_ALL_ACCESS_P = 0x000F00FF,
/// <summary>Combines all possible access rights for a token.</summary>
TOKEN_ALL_ACCESS = 0x000F01FF,
/// <summary>Combines STANDARD_RIGHTS_READ and TOKEN_QUERY.</summary>
TOKEN_READ = 0x00020008,
/// <summary>Combines STANDARD_RIGHTS_WRITE, TOKEN_ADJUST_PRIVILEGES, TOKEN_ADJUST_GROUPS, and TOKEN_ADJUST_DEFAULT.</summary>
TOKEN_WRITE = 0x000200E0,
/// <summary>Combines STANDARD_RIGHTS_EXECUTE and TOKEN_IMPERSONATE.</summary>
TOKEN_EXECUTE = 0x00020000
}
/// <summary>The mandatory integrity access policy for the associated token.</summary>
[PInvokeData("winnt.h", MSDNShortId = "f5fc438b-c4f0-46f6-a188-52ce660d13da")]
public enum TokenMandatoryPolicy
{
/// <summary>No mandatory integrity policy is enforced for the token.</summary>
TOKEN_MANDATORY_POLICY_OFF = 0x0,
/// <summary>A process associated with the token cannot write to objects that have a greater mandatory integrity level.</summary>
TOKEN_MANDATORY_POLICY_NO_WRITE_UP = 0x1,
/// <summary>
/// A process created with the token has an integrity level that is the lesser of the parent-process integrity level and the
/// executable-file integrity level.
/// </summary>
TOKEN_MANDATORY_POLICY_NEW_PROCESS_MIN = 0x2,
/// <summary>A combination of TOKEN_MANDATORY_POLICY_NO_WRITE_UP and TOKEN_MANDATORY_POLICY_NEW_PROCESS_MIN.</summary>
TOKEN_MANDATORY_POLICY_VALID_MASK = 0x3,
}
/// <summary>
/// <para>
/// The <c>WELL_KNOWN_SID_TYPE</c> enumeration is a list of commonly used security identifiers (SIDs). Programs can pass these values
/// to the CreateWellKnownSid function to create a SID from this list.
/// </para>
/// </summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ne-winnt-well_known_sid_type
[PInvokeData("winnt.h", MSDNShortId = "6f1fa59e-17c0-412b-937b-ddf746ed68bd")]
public enum WELL_KNOWN_SID_TYPE
{
/// <summary>Indicates a null SID.</summary>
WinNullSid,
/// <summary>Indicates a SID that matches everyone.</summary>
WinWorldSid,
/// <summary>Indicates a local SID.</summary>
WinLocalSid,
/// <summary>Indicates a SID that matches the owner or creator of an object.</summary>
WinCreatorOwnerSid,
/// <summary>Indicates a SID that matches the creator group of an object.</summary>
WinCreatorGroupSid,
/// <summary>Indicates a creator owner server SID.</summary>
WinCreatorOwnerServerSid,
/// <summary>Indicates a creator group server SID.</summary>
WinCreatorGroupServerSid,
/// <summary>Indicates a SID for the Windows NT authority account.</summary>
WinNtAuthoritySid,
/// <summary>Indicates a SID for a dial-up account.</summary>
WinDialupSid,
/// <summary>
/// Indicates a SID for a network account. This SID is added to the process of a token when it logs on across a network. The
/// corresponding logon type is LOGON32_LOGON_NETWORK.
/// </summary>
WinNetworkSid,
/// <summary>
/// Indicates a SID for a batch process. This SID is added to the process of a token when it logs on as a batch job. The
/// corresponding logon type is LOGON32_LOGON_BATCH.
/// </summary>
WinBatchSid,
/// <summary>
/// Indicates a SID for an interactive account. This SID is added to the process of a token when it logs on interactively. The
/// corresponding logon type is LOGON32_LOGON_INTERACTIVE.
/// </summary>
WinInteractiveSid,
/// <summary>
/// Indicates a SID for a service. This SID is added to the process of a token when it logs on as a service. The corresponding
/// logon type is LOGON32_LOGON_SERVICE.
/// </summary>
WinServiceSid,
/// <summary>Indicates a SID for the anonymous account.</summary>
WinAnonymousSid,
/// <summary>Indicates a proxy SID.</summary>
WinProxySid,
/// <summary>Indicates a SID for an enterprise controller.</summary>
WinEnterpriseControllersSid,
/// <summary>Indicates a SID for self.</summary>
WinSelfSid,
/// <summary>Indicates a SID that matches any authenticated user.</summary>
WinAuthenticatedUserSid,
/// <summary>Indicates a SID for restricted code.</summary>
WinRestrictedCodeSid,
/// <summary>Indicates a SID that matches a terminal server account.</summary>
WinTerminalServerSid,
/// <summary>Indicates a SID that matches remote logons.</summary>
WinRemoteLogonIdSid,
/// <summary>Indicates a SID that matches logon IDs.</summary>
WinLogonIdsSid,
/// <summary>Indicates a SID that matches the local system.</summary>
WinLocalSystemSid,
/// <summary>Indicates a SID that matches a local service.</summary>
WinLocalServiceSid,
/// <summary>Indicates a SID that matches a network service.</summary>
WinNetworkServiceSid,
/// <summary>Indicates a SID that matches the domain account.</summary>
WinBuiltinDomainSid,
/// <summary>Indicates a SID that matches the administrator group.</summary>
WinBuiltinAdministratorsSid,
/// <summary>Indicates a SID that matches built-in user accounts.</summary>
WinBuiltinUsersSid,
/// <summary>Indicates a SID that matches the guest account.</summary>
WinBuiltinGuestsSid,
/// <summary>Indicates a SID that matches the power users group.</summary>
WinBuiltinPowerUsersSid,
/// <summary>Indicates a SID that matches the account operators account.</summary>
WinBuiltinAccountOperatorsSid,
/// <summary>Indicates a SID that matches the system operators group.</summary>
WinBuiltinSystemOperatorsSid,
/// <summary>Indicates a SID that matches the print operators group.</summary>
WinBuiltinPrintOperatorsSid,
/// <summary>Indicates a SID that matches the backup operators group.</summary>
WinBuiltinBackupOperatorsSid,
/// <summary>Indicates a SID that matches the replicator account.</summary>
WinBuiltinReplicatorSid,
/// <summary>Indicates a SID that matches pre-Windows 2000 compatible accounts.</summary>
WinBuiltinPreWindows2000CompatibleAccessSid,
/// <summary>Indicates a SID that matches remote desktop users.</summary>
WinBuiltinRemoteDesktopUsersSid,
/// <summary>Indicates a SID that matches the network operators group.</summary>
WinBuiltinNetworkConfigurationOperatorsSid,
/// <summary>Indicates a SID that matches the account administrator's account.</summary>
WinAccountAdministratorSid,
/// <summary>Indicates a SID that matches the account guest group.</summary>
WinAccountGuestSid,
/// <summary>Indicates a SID that matches account Kerberos target group.</summary>
WinAccountKrbtgtSid,
/// <summary>Indicates a SID that matches the account domain administrator group.</summary>
WinAccountDomainAdminsSid,
/// <summary>Indicates a SID that matches the account domain users group.</summary>
WinAccountDomainUsersSid,
/// <summary>Indicates a SID that matches the account domain guests group.</summary>
WinAccountDomainGuestsSid,
/// <summary>Indicates a SID that matches the account computer group.</summary>
WinAccountComputersSid,
/// <summary>Indicates a SID that matches the account controller group.</summary>
WinAccountControllersSid,
/// <summary>Indicates a SID that matches the certificate administrators group.</summary>
WinAccountCertAdminsSid,
/// <summary>Indicates a SID that matches the schema administrators group.</summary>
WinAccountSchemaAdminsSid,
/// <summary>Indicates a SID that matches the enterprise administrators group.</summary>
WinAccountEnterpriseAdminsSid,
/// <summary>Indicates a SID that matches the policy administrators group.</summary>
WinAccountPolicyAdminsSid,
/// <summary>Indicates a SID that matches the RAS and IAS server account.</summary>
WinAccountRasAndIasServersSid,
/// <summary>Indicates a SID present when the Microsoft NTLM authentication package authenticated the client.</summary>
WinNTLMAuthenticationSid,
/// <summary>Indicates a SID present when the Microsoft Digest authentication package authenticated the client.</summary>
WinDigestAuthenticationSid,
/// <summary>Indicates a SID present when the Secure Channel (SSL/TLS) authentication package authenticated the client.</summary>
WinSChannelAuthenticationSid,
/// <summary>
/// Indicates a SID present when the user authenticated from within the forest or across a trust that does not have the selective
/// authentication option enabled. If this SID is present, then WinOtherOrganizationSid cannot be present.
/// </summary>
WinThisOrganizationSid,
/// <summary>
/// Indicates a SID present when the user authenticated across a forest with the selective authentication option enabled. If this
/// SID is present, then WinThisOrganizationSid cannot be present.
/// </summary>
WinOtherOrganizationSid,
/// <summary>
/// Indicates a SID that allows a user to create incoming forest trusts. It is added to the token of users who are a member of
/// the Incoming Forest Trust Builders built-in group in the root domain of the forest.
/// </summary>
WinBuiltinIncomingForestTrustBuildersSid,
/// <summary>Indicates a SID that matches the performance monitor user group.</summary>
WinBuiltinPerfMonitoringUsersSid,
/// <summary>Indicates a SID that matches the performance log user group.</summary>
WinBuiltinPerfLoggingUsersSid,
/// <summary>Indicates a SID that matches the Windows Authorization Access group.</summary>
WinBuiltinAuthorizationAccessSid,
/// <summary>Indicates a SID is present in a server that can issue terminal server licenses.</summary>
WinBuiltinTerminalServerLicenseServersSid,
/// <summary>Indicates a SID that matches the distributed COM user group.</summary>
WinBuiltinDCOMUsersSid,
/// <summary>Indicates a SID that matches the Internet built-in user group.</summary>
WinBuiltinIUsersSid,
/// <summary>Indicates a SID that matches the Internet user group.</summary>
WinIUserSid,
/// <summary>
/// Indicates a SID that allows a user to use cryptographic operations. It is added to the token of users who are a member of the
/// CryptoOperators built-in group.
/// </summary>
WinBuiltinCryptoOperatorsSid,
/// <summary>Indicates a SID that matches an untrusted label.</summary>
WinUntrustedLabelSid,
/// <summary>Indicates a SID that matches an low level of trust label.</summary>
WinLowLabelSid,
/// <summary>Indicates a SID that matches an medium level of trust label.</summary>
WinMediumLabelSid,
/// <summary>Indicates a SID that matches a high level of trust label.</summary>
WinHighLabelSid,
/// <summary>Indicates a SID that matches a system label.</summary>
WinSystemLabelSid,
/// <summary>Indicates a SID that matches a write restricted code group.</summary>
WinWriteRestrictedCodeSid,
/// <summary>Indicates a SID that matches a creator and owner rights group.</summary>
WinCreatorOwnerRightsSid,
/// <summary>Indicates a SID that matches a cacheable principals group.</summary>
WinCacheablePrincipalsGroupSid,
/// <summary>Indicates a SID that matches a non-cacheable principals group.</summary>
WinNonCacheablePrincipalsGroupSid,
/// <summary>Indicates a SID that matches an enterprise wide read-only controllers group.</summary>
WinEnterpriseReadonlyControllersSid,
/// <summary>Indicates a SID that matches an account read-only controllers group.</summary>
WinAccountReadonlyControllersSid,
/// <summary>Indicates a SID that matches an event log readers group.</summary>
WinBuiltinEventLogReadersGroup,
/// <summary>Indicates a SID that matches a read-only enterprise domain controller.</summary>
WinNewEnterpriseReadonlyControllersSid,
/// <summary>Indicates a SID that matches the built-in DCOM certification services access group.</summary>
WinBuiltinCertSvcDComAccessGroup,
/// <summary>
/// Indicates a SID that matches the medium plus integrity label. Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows
/// Vista, Windows Server 2003 and Windows XP: This value is not available.
/// </summary>
WinMediumPlusLabelSid,
/// <summary>
/// Indicates a SID that matches a local logon group. Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista,
/// Windows Server 2003 and Windows XP: This value is not available.
/// </summary>
WinLocalLogonSid,
/// <summary>
/// Indicates a SID that matches a console logon group. Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista,
/// Windows Server 2003 and Windows XP: This value is not available.
/// </summary>
WinConsoleLogonSid,
/// <summary>Undocumented</summary>
WinThisOrganizationCertificateSid,
/// <summary>
/// Indicates a SID that matches the application package authority. Windows Server 2008 R2, Windows 7, Windows Server 2008,
/// Windows Vista, Windows Server 2003 and Windows XP: This value is not available.
/// </summary>
WinApplicationPackageAuthoritySid,
/// <summary>Undocumented</summary>
WinBuiltinAnyPackageSid,
/// <summary>
/// Indicates a SID of Internet client capability for app containers. Windows Server 2008 R2, Windows 7, Windows Server 2008,
/// Windows Vista, Windows Server 2003 and Windows XP: This value is not available.
/// </summary>
WinCapabilityInternetClientSid,
/// <summary>Undocumented</summary>
WinCapabilityInternetClientServerSid,
/// <summary>
/// Indicates a SID of private network client and server capability for app containers. Windows Server 2008 R2, Windows 7,
/// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This value is not available.
/// </summary>
WinCapabilityPrivateNetworkClientServerSid,
/// <summary>Undocumented</summary>
WinCapabilityPicturesLibrarySid,
/// <summary>
/// Indicates a SID for videos library capability for app containers. Windows Server 2008 R2, Windows 7, Windows Server 2008,
/// Windows Vista, Windows Server 2003 and Windows XP: This value is not available.
/// </summary>
WinCapabilityVideosLibrarySid,
/// <summary>Undocumented</summary>
WinCapabilityMusicLibrarySid,
/// <summary>
/// Indicates a SID for documents library capability for app containers. Windows Server 2008 R2, Windows 7, Windows Server 2008,
/// Windows Vista, Windows Server 2003 and Windows XP: This value is not available.
/// </summary>
WinCapabilityDocumentsLibrarySid,
/// <summary>Undocumented</summary>
WinCapabilitySharedUserCertificatesSid,
/// <summary>
/// Indicates a SID for Windows credentials capability for app containers. Windows Server 2008 R2, Windows 7, Windows Server
/// 2008, Windows Vista, Windows Server 2003 and Windows XP: This value is not available.
/// </summary>
WinCapabilityEnterpriseAuthenticationSid,
/// <summary>Undocumented</summary>
WinCapabilityRemovableStorageSid,
/// <summary/>
WinBuiltinRDSRemoteAccessServersSid,
/// <summary/>
WinBuiltinRDSEndpointServersSid,
/// <summary/>
WinBuiltinRDSManagementServersSid,
/// <summary/>
WinUserModeDriversSid,
/// <summary/>
WinBuiltinHyperVAdminsSid,
/// <summary/>
WinAccountCloneableControllersSid,
/// <summary/>
WinBuiltinAccessControlAssistanceOperatorsSid,
/// <summary/>
WinBuiltinRemoteManagementUsersSid,
/// <summary/>
WinAuthenticationAuthorityAssertedSid,
/// <summary/>
WinAuthenticationServiceAssertedSid,
/// <summary/>
WinLocalAccountSid,
/// <summary/>
WinLocalAccountAndAdministratorSid,
/// <summary/>
WinAccountProtectedUsersSid,
/// <summary/>
WinCapabilityAppointmentsSid,
/// <summary/>
WinCapabilityContactsSid,
/// <summary/>
WinAccountDefaultSystemManagedSid,
/// <summary/>
WinBuiltinDefaultSystemManagedGroupSid,
/// <summary/>
WinBuiltinStorageReplicaAdminsSid,
/// <summary/>
WinAccountKeyAdminsSid,
/// <summary/>
WinAccountEnterpriseKeyAdminsSid,
/// <summary/>
WinAuthenticationKeyTrustSid,
/// <summary/>
WinAuthenticationKeyPropertyMFASid,
/// <summary/>
WinAuthenticationKeyPropertyAttestationSid,
/// <summary/>
WinAuthenticationFreshKeyAuthSid,
/// <summary/>
WinBuiltinDeviceOwnersSid,
}
/// <summary>
/// The <c>ACCESS_ALLOWED_ACE</c> structure defines an access control entry (ACE) for the discretionary access control list (DACL)
/// that controls access to an object. An access-allowed ACE allows access to an object for a specific trustee identified by a
/// security identifier (SID).
/// </summary>
/// <remarks>
/// <para>
/// ACE structures must be aligned on <c>DWORD</c> boundaries. All Windows memory-management functions return <c>DWORD</c>-aligned
/// handles to memory.
/// </para>
/// <para>
/// The access rights specified by the <c>Mask</c> member are granted to any trustee that possesses an enabled SID that matches the
/// SID stored in the <c>SidStart</c> member.
/// </para>
/// <para>
/// An <c>ACCESS_ALLOWED_ACE</c> structure can be created in an access control list (ACL) by a call to the AddAccessAllowedAce or
/// AddAccessAllowedAceEx function. When these functions are used, the correct amount of memory needed to accommodate the trustee's
/// SID is allocated and the values of the <c>Header.AceType</c> and <c>Header.AceSize</c> members are set automatically. If the
/// <c>AddAccessAllowedAceEx</c> function is used, the <c>Header.AceFlags</c> member is also set. When an <c>ACCESS_ALLOWED_ACE</c>
/// structure is created outside an ACL, sufficient memory must be allocated to accommodate the complete SID of the trustee in the
/// <c>SidStart</c> member and the contiguous memory following it, and the values of the <c>Header.AceType</c>,
/// <c>Header.AceFlags</c>, and <c>Header.AceSize</c> members must be set explicitly by the application.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace typedef struct _ACCESS_ALLOWED_ACE {
// ACE_HEADER Header; ACCESS_MASK Mask; DWORD SidStart; } ACCESS_ALLOWED_ACE;
[PInvokeData("winnt.h", MSDNShortId = "002a3fa7-02a3-4832-948e-b048f5f5818f")]
[StructLayout(LayoutKind.Sequential)]
public struct ACCESS_ALLOWED_ACE
{
/// <summary>
/// ACE_HEADER structure that specifies the size and type of ACE. It also contains flags that control inheritance of the ACE by
/// child objects. The AceType member of the ACE_HEADER structure should be set to ACCESS_ALLOWED_ACE_TYPE, and the AceSize
/// member should be set to the total number of bytes allocated for the ACCESS_ALLOWED_ACE structure.
/// </summary>
public ACE_HEADER Header;
/// <summary>Specifies an ACCESS_MASK structure that specifies the access rights granted by this ACE.</summary>
public ACCESS_MASK Mask;
/// <summary>
/// The first DWORD of a trustee's SID. The remaining bytes of the SID are stored in contiguous memory after the SidStart member.
/// This SID can be appended with application data.
/// </summary>
public uint SidStart;
}
/// <summary>
/// <para>
/// The <c>ACCESS_ALLOWED_CALLBACK_ACE</c> structure defines an access control entry (ACE) for the discretionary access control list
/// (DACL) that controls access to an object. An access-allowed ACE allows access to an object for a specific trustee identified by a
/// security identifier (SID).
/// </para>
/// <para>
/// When the AuthzAccessCheck function is called, each <c>ACCESS_ALLOWED_CALLBACK_ACE</c> structure contained in the DACL of a
/// SECURITY_DESCRIPTOR structure passed through a pointer to the <c>AuthzAccessCheck</c> function invokes a call to the
/// application-defined AuthzAccessCheckCallback function, in which a pointer to the <c>ACCESS_ALLOWED_CALLBACK_ACE</c> structure
/// found is passed in the pAce parameter.
/// </para>
/// </summary>
/// <remarks>
/// <para>
/// ACE structures must be aligned on <c>DWORD</c> boundaries. All Windows memory-management functions return <c>DWORD</c>-aligned
/// handles to memory.
/// </para>
/// <para>
/// The access rights specified by the <c>Mask</c> member are granted to any trustee that possesses an enabled SID that matches the
/// SID stored in the <c>SidStart</c> member.
/// </para>
/// <para>
/// When an <c>ACCESS_ALLOWED_CALLBACK_ACE</c> structure is created, sufficient memory must be allocated to accommodate the complete
/// SID of the trustee in the <c>SidStart</c> member and the contiguous memory that follows it.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_callback_ace typedef struct
// _ACCESS_ALLOWED_CALLBACK_ACE { ACE_HEADER Header; ACCESS_MASK Mask; DWORD SidStart; } ACCESS_ALLOWED_CALLBACK_ACE, *PACCESS_ALLOWED_CALLBACK_ACE;
[PInvokeData("winnt.h", MSDNShortId = "0dbca19b-4b54-4c55-920a-c00335692d68")]
[StructLayout(LayoutKind.Sequential)]
public struct ACCESS_ALLOWED_CALLBACK_ACE
{
/// <summary>
/// ACE_HEADER structure that specifies the size and type of ACE. It also contains flags that control inheritance of the ACE by
/// child objects. The <c>AceType</c> member of the <c>ACE_HEADER</c> structure should be set to
/// ACCESS_ALLOWED_CALLBACK_ACE_TYPE, and the <c>AceSize</c> member should be set to the total number of bytes allocated for the
/// <c>ACCESS_ALLOWED_CALLBACK_ACE</c> structure.
/// </summary>
public ACE_HEADER Header;
/// <summary>Specifies an ACCESS_MASK structure that specifies the access rights granted by this ACE.</summary>
public ACCESS_MASK Mask;
/// <summary>The first <c>DWORD</c> of a trustee's SID.</summary>
public uint SidStart;
}
/// <summary>
/// <para>
/// The <c>ACCESS_ALLOWED_CALLBACK_OBJECT_ACE</c> structure defines an access control entry (ACE) that controls allowed access to an
/// object, property set, or property. The ACE contains a set of access rights, a <c>GUID</c> that identifies the type of object, and
/// a security identifier (SID) that identifies the trustee to whom the system will grant access. The ACE also contains a <c>GUID</c>
/// and a set of flags that control inheritance of the ACE by child objects.
/// </para>
/// <para>
/// When the AuthzAccessCheck function is called, each <c>ACCESS_ALLOWED_CALLBACK_OBJECT_ACE</c> structure contained in the DACL of a
/// SECURITY_DESCRIPTOR structure passed through a pointer to the <c>AuthzAccessCheck</c> function invokes a call to the
/// application-defined AuthzAccessCheckCallback function, in which a pointer to the <c>ACCESS_ALLOWED_CALLBACK_OBJECT_ACE</c>
/// structure found is passed in the pAce parameter.
/// </para>
/// </summary>
/// <remarks>
/// <para>
/// If neither the <c>ObjectType</c> nor <c>InheritedObjectType</c><c>GUID</c> is specified, the
/// <c>ACCESS_ALLOWED_CALLBACK_OBJECT_ACE</c> structure has the same semantics as those used by the ACCESS_ALLOWED_CALLBACK_ACE
/// structure. In that case, use the <c>ACCESS_ALLOWED_CALLBACK_ACE</c> structure because it is smaller and more efficient.
/// </para>
/// <para>
/// An ACL that contains an <c>ACCESS_ALLOWED_CALLBACK_OBJECT_ACE</c> must specify the ACL_REVISION_DS revision number in its ACL header.
/// </para>
/// <para>
/// The access rights specified by the <c>Mask</c> member are granted to any trustee that possesses an enabled SID that matches the
/// SID stored in the <c>SidStart</c> member.
/// </para>
/// <para>
/// When an <c>ACCESS_ALLOWED_CALLBACK_OBJECT_ACE</c> structure is created, sufficient memory must be allocated to accommodate the
/// GUID structures in the <c>ObjectType</c> and <c>InheritedObjectType</c> members, if one or both of them exists, as well as to
/// accommodate the complete SID of the trustee in the <c>SidStart</c> member and the contiguous memory that follows it.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_callback_object_ace typedef struct
// _ACCESS_ALLOWED_CALLBACK_OBJECT_ACE { ACE_HEADER Header; ACCESS_MASK Mask; DWORD Flags; GUID ObjectType; GUID InheritedObjectType;
// DWORD SidStart; } ACCESS_ALLOWED_CALLBACK_OBJECT_ACE, *PACCESS_ALLOWED_CALLBACK_OBJECT_ACE;
[PInvokeData("winnt.h", MSDNShortId = "83b00ef3-f7b2-455e-8f3f-01b1da6024b7")]
[StructLayout(LayoutKind.Sequential)]
public struct ACCESS_ALLOWED_CALLBACK_OBJECT_ACE
{
/// <summary>
/// ACE_HEADER structure that specifies the size and type of ACE. It also contains flags that control inheritance of the ACE by
/// child objects. The <c>AceType</c> member of the <c>ACE_HEADER</c> structure should be set to
/// ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE, and the <c>AceSize</c> member should be set to the total number of bytes allocated
/// for the <c>ACCESS_ALLOWED_CALLBACK_OBJECT_ACE</c> structure.
/// </summary>
public ACE_HEADER Header;
/// <summary>An ACCESS_MASK that specifies the access rights the system will allow to the trustee.</summary>
public ACCESS_MASK Mask;
/// <summary>
/// <para>
/// A set of bit flags that indicate whether the <c>ObjectType</c> and <c>InheritedObjectType</c> members are present. This
/// parameter can be one or more of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>Neither ObjectType nor InheritedObjectType are present. The SidStart member follows immediately after the Flags member.</term>
/// </item>
/// <item>
/// <term>ACE_OBJECT_TYPE_PRESENT</term>
/// <term>
/// ObjectType is present and contains a GUID. If this value is not specified, the InheritedObjectType member follows immediately
/// after the Flags member.
/// </term>
/// </item>
/// <item>
/// <term>ACE_INHERITED_OBJECT_TYPE_PRESENT</term>
/// <term>
/// InheritedObjectType is present and contains a GUID. If this value is not specified, all types of child objects can inherit
/// the ACE.
/// </term>
/// </item>
/// </list>
/// </summary>
public ObjectAceFlags Flags;
/// <summary>
/// <para>
/// This member exists only if the ACE_OBJECT_TYPE_PRESENT bit is set in the <c>Flags</c> member. Otherwise, the
/// <c>InheritedObjectType</c> member follows immediately after the <c>Flags</c> member.
/// </para>
/// <para>
/// If this member exists, it is a GUID structure that identifies a property set, property, extended right, or type of child
/// object. The purpose of this <c>GUID</c> depends on the access rights specified in the <c>Mask</c> member.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ADS_RIGHT_DS_CONTROL_ACCESS</term>
/// <term>The ObjectType GUID identifies an extended access right.</term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_CREATE_CHILD</term>
/// <term>
/// The ObjectType GUID identifies a type of child object. The ACE controls the trustee's right to create this type of child object.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_READ_PROP</term>
/// <term>
/// The ObjectType GUID identifies a property set or property of the object. The ACE controls the trustee's right to read the
/// property or property set.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_WRITE_PROP</term>
/// <term>
/// The ObjectType GUID identifies a property set or property of the object. The ACE controls the trustee's right to write the
/// property or property set.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_SELF</term>
/// <term>The ObjectType GUID identifies a validated write.</term>
/// </item>
/// </list>
/// </summary>
public Guid ObjectType;
/// <summary>
/// <para>This member exists only if the ACE_INHERITED_OBJECT_TYPE_PRESENT bit is set in the <c>Flags</c> member.</para>
/// <para>
/// If this member exists, it is a GUID structure that identifies the type of child object that can inherit the ACE. Inheritance
/// is also controlled by the inheritance flags in the ACE_HEADER, as well as by any protection against inheritance placed on the
/// child objects.
/// </para>
/// <para>
/// The offset of this member can vary. If the <c>Flags</c> member does not contain the ACE_OBJECT_TYPE_PRESENT flag, the
/// <c>InheritedObjectType</c> member starts at the offset specified by the <c>ObjectType</c> member.
/// </para>
/// </summary>
public Guid InheritedObjectType;
/// <summary>
/// The first <c>DWORD</c> of a trustee's SID. The remaining bytes of the SID are stored in contiguous memory after the
/// <c>SidStart</c> member. This SID can be appended with application data.
/// </summary>
public uint SidStart;
}
/// <summary>
/// The <c>ACCESS_ALLOWED_OBJECT_ACE</c> structure defines an access control entry (ACE) that controls allowed access to an object, a
/// property set, or property. The ACE contains a set of access rights, a <c>GUID</c> that identifies the type of object, and a
/// security identifier (SID) that identifies the trustee to whom the system will grant access. The ACE also contains a <c>GUID</c>
/// and a set of flags that control inheritance of the ACE by child objects.
/// </summary>
/// <remarks>
/// <para>
/// If neither the <c>ObjectType</c> nor <c>InheritedObjectType</c> GUID is specified, the <c>ACCESS_ALLOWED_OBJECT_ACE</c> structure
/// has the same semantics as those used by the ACCESS_ALLOWED_ACE structure. In that case, use the <c>ACCESS_ALLOWED_ACE</c>
/// structure because it is smaller and more efficient.
/// </para>
/// <para>An ACL that contains an <c>ACCESS_ALLOWED_OBJECT_ACE</c> must specify the ACL_REVISION_DS revision number in its ACL header.</para>
/// <para>
/// The access rights specified by the <c>Mask</c> member are granted to any trustee that possesses an enabled SID that matches the
/// SID stored in the <c>SidStart</c> member.
/// </para>
/// <para>
/// An <c>ACCESS_ALLOWED_OBJECT_ACE</c> structure can be created in an access control list (ACL) by a call to the
/// AddAccessAllowedObjectAce function. When this function is used, the correct amount of memory needed to accommodate the GUID
/// structures in the <c>ObjectType</c> and <c>InheritedObjectType</c> members, if one or both of them exists, as well as to
/// accommodate the trustee's SID is automatically allocated. In addition, the values of the <c>Header.AceType</c> and
/// <c>Header.AceSize</c> members are set automatically. When an <c>ACCESS_ALLOWED_OBJECT_ACE</c> structure is created outside an
/// ACL, sufficient memory must be allocated to accommodate the GUID structures in the <c>ObjectType</c> and
/// <c>InheritedObjectType</c> members, if one or both of them exists, as well as to accommodate the complete SID of the trustee in
/// the <c>SidStart</c> member and the contiguous memory following it. In addition, the values of the <c>Header.AceType</c> and
/// <c>Header.AceSize</c> members must be set explicitly by the application.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_access_allowed_object_ace typedef struct
// _ACCESS_ALLOWED_OBJECT_ACE { ACE_HEADER Header; ACCESS_MASK Mask; DWORD Flags; GUID ObjectType; GUID InheritedObjectType; DWORD
// SidStart; } ACCESS_ALLOWED_OBJECT_ACE, *PACCESS_ALLOWED_OBJECT_ACE;
[PInvokeData("winnt.h", MSDNShortId = "ee91ca50-e81b-4872-95eb-349c2d5be004")]
[StructLayout(LayoutKind.Sequential)]
public struct ACCESS_ALLOWED_OBJECT_ACE
{
/// <summary>
/// ACE_HEADER structure that specifies the size and type of ACE. It also contains flags that control inheritance of the ACE by
/// child objects. The <c>AceType</c> member of the <c>ACE_HEADER</c> structure should be set to ACCESS_ALLOWED_OBJECT_ACE_TYPE,
/// and the <c>AceSize</c> member should be set to the total number of bytes allocated for the <c>ACCESS_ALLOWED_OBJECT_ACE</c> structure.
/// </summary>
public ACE_HEADER Header;
/// <summary>An ACCESS_MASK that specifies the access rights the system will allow to the trustee.</summary>
public ACCESS_MASK Mask;
/// <summary>
/// <para>
/// A set of bit flags that indicate whether the <c>ObjectType</c> and <c>InheritedObjectType</c> members are present. This
/// parameter can be one or more of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>Neither ObjectType nor InheritedObjectType are present. The SidStart member follows immediately after the Flags member.</term>
/// </item>
/// <item>
/// <term>ACE_OBJECT_TYPE_PRESENT</term>
/// <term>
/// ObjectType is present and contains a GUID. If this value is not specified, the InheritedObjectType member follows immediately
/// after the Flags member.
/// </term>
/// </item>
/// <item>
/// <term>ACE_INHERITED_OBJECT_TYPE_PRESENT</term>
/// <term>
/// InheritedObjectType is present and contains a GUID. If this value is not specified, all types of child objects can inherit
/// the ACE.
/// </term>
/// </item>
/// </list>
/// </summary>
public ObjectAceFlags Flags;
/// <summary>
/// <para>
/// This member exists only if the ACE_OBJECT_TYPE_PRESENT bit is set in the <c>Flags</c> member. Otherwise, the
/// <c>InheritedObjectType</c> member follows immediately after the <c>Flags</c> member.
/// </para>
/// <para>
/// If this member exists, it is a GUID structure that identifies a property set, property, extended right, or type of child
/// object. The purpose of this <c>GUID</c> depends on the access rights specified in the <c>Mask</c> member.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ADS_RIGHT_DS_CONTROL_ACCESS</term>
/// <term>The ObjectType GUID identifies an extended access right.</term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_CREATE_CHILD</term>
/// <term>
/// The ObjectType GUID identifies a type of child object. The ACE controls the trustee's right to create this type of child object.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_READ_PROP</term>
/// <term>
/// The ObjectType GUID identifies a property set or property of the object. The ACE controls the trustee's right to read the
/// property or property set.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_WRITE_PROP</term>
/// <term>
/// The ObjectType GUID identifies a property set or property of the object. The ACE controls the trustee's right to write the
/// property or property set.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_SELF</term>
/// <term>The ObjectType GUID identifies a validated write.</term>
/// </item>
/// </list>
/// </summary>
public Guid ObjectType;
/// <summary>
/// <para>This member exists only if the ACE_INHERITED_OBJECT_TYPE_PRESENT bit is set in the <c>Flags</c> member.</para>
/// <para>
/// If this member exists, it is a GUID structure that identifies the type of child object that can inherit the ACE. Inheritance
/// is also controlled by the inheritance flags in the ACE_HEADER, as well as by any protection against inheritance placed on the
/// child objects.
/// </para>
/// <para>
/// The offset of this member can vary. If the <c>Flags</c> member does not contain the ACE_OBJECT_TYPE_PRESENT flag, the
/// <c>InheritedObjectType</c> member starts at the offset specified by the <c>ObjectType</c> member.
/// </para>
/// </summary>
public Guid InheritedObjectType;
/// <summary>
/// <para>
/// Specifies the first <c>DWORD</c> of a SID that identifies the trustee to whom the access rights are granted. The remaining
/// bytes of the SID are stored in contiguous memory after the <c>SidStart</c> member. This SID can be appended with application data.
/// </para>
/// <para>
/// The offset of this member can vary. If the <c>Flags</c> member is zero, the <c>SidStart</c> member starts at the offset
/// specified by the <c>ObjectType</c> member. If <c>Flags</c> contains only one flag (either ACE_OBJECT_TYPE_PRESENT or
/// ACE_INHERITED_OBJECT_TYPE_PRESENT), the <c>SidStart</c> member starts at the offset specified by the
/// <c>InheritedObjectType</c> member.
/// </para>
/// </summary>
public uint SidStart;
}
/// <summary>
/// The <c>ACCESS_DENIED_ACE</c> structure defines an access control entry (ACE) for the discretionary access control list (DACL)
/// that controls access to an object. An access-denied ACE denies access to an object for a specific trustee identified by a
/// security identifier (SID).
/// </summary>
/// <remarks>
/// <para>
/// ACE structures must be aligned on <c>DWORD</c> boundaries. All Windows memory-management functions return <c>DWORD</c>-aligned
/// handles to memory.
/// </para>
/// <para>
/// The access rights specified by the <c>Mask</c> member are denied to any trustee that possesses an enabled SID that matches the
/// SID stored in the <c>SidStart</c> member.
/// </para>
/// <para>
/// An <c>ACCESS_DENIED_ACE</c> structure can be created in an access control list (ACL) by a call to the AddAccessDeniedAce or
/// AddAccessDeniedAceEx function. When these functions are used, the correct amount of memory needed to accommodate the trustee's
/// SID is allocated and the values of the <c>Header.AceType</c> and <c>Header.AceSize</c> members are set automatically. If the
/// <c>AddAccessDeniedAceEx</c> function is used, the <c>Header.AceFlags</c> member is also set. When an <c>ACCESS_DENIED_ACE</c>
/// structure is created outside an ACL, sufficient memory must be allocated to accommodate the complete SID of the trustee in the
/// <c>SidStart</c> member and the contiguous memory following it, and the values of the <c>Header.AceType</c>,
/// <c>Header.AceFlags</c>, and <c>Header.AceSize</c> members must be set explicitly by the application.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_denied_ace typedef struct _ACCESS_DENIED_ACE { ACE_HEADER
// Header; ACCESS_MASK Mask; DWORD SidStart; } ACCESS_DENIED_ACE;
[PInvokeData("winnt.h", MSDNShortId = "d76a92d0-ccd0-4e73-98b6-43bcd661134d")]
[StructLayout(LayoutKind.Sequential)]
public struct ACCESS_DENIED_ACE
{
/// <summary>
/// An ACE_HEADER structure that specifies the size and type of ACE. It also contains flags that control inheritance of the ACE
/// by child objects. The <c>AceType</c> member of the <c>ACE_HEADER</c> structure should be set to ACCESS_DENIED_ACE_TYPE, and
/// the <c>AceSize</c> member should be set to the total number of bytes allocated for the <c>ACCESS_DENIED_ACE</c> structure.
/// </summary>
public ACE_HEADER Header;
/// <summary>An ACCESS_MASK structure that specifies the access rights explicitly denied by this ACE.</summary>
public ACCESS_MASK Mask;
/// <summary>
/// The first <c>DWORD</c> of a trustee's SID. The remaining bytes of the SID are stored in contiguous memory after the
/// <c>SidStart</c> member. This SID can be appended with application data.
/// </summary>
public uint SidStart;
}
/// <summary>
/// <para>
/// The <c>ACCESS_DENIED_CALLBACK_ACE</c> structure defines an access control entry (ACE) for the discretionary access control list
/// (DACL) that controls access to an object. An access-denied ACE denies access to an object for a specific trustee identified by a
/// security identifier (SID).
/// </para>
/// <para>
/// When the AuthzAccessCheck function is called, each <c>ACCESS_DENIED_CALLBACK_ACE</c> structure contained in the DACL of a
/// SECURITY_DESCRIPTOR structure passed through a pointer to the <c>AuthzAccessCheck</c> function invokes a call to the
/// applicationdefined AuthzAccessCheckCallback function, in which a pointer to the <c>ACCESS_DENIED_CALLBACK_ACE</c> structure
/// found is passed in the pAce parameter.
/// </para>
/// </summary>
/// <remarks>
/// <para>
/// ACE structures must be aligned on <c>DWORD</c> boundaries. All Windows memory-management functions return <c>DWORD</c>-aligned
/// handles to memory.
/// </para>
/// <para>
/// The access rights specified by the <c>Mask</c> member are granted to any trustee that possesses an enabled SID that matches the
/// SID stored in the <c>SidStart</c> member.
/// </para>
/// <para>
/// When an <c>ACCESS_DENIED_CALLBACK_ACE</c> structure is created, sufficient memory must be allocated to accommodate the complete
/// SID of the trustee in the <c>SidStart</c> member and the contiguous memory that follows it.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_denied_callback_ace typedef struct
// _ACCESS_DENIED_CALLBACK_ACE { ACE_HEADER Header; ACCESS_MASK Mask; DWORD SidStart; } ACCESS_DENIED_CALLBACK_ACE, *PACCESS_DENIED_CALLBACK_ACE;
[PInvokeData("winnt.h", MSDNShortId = "6df77b27-7aa3-455f-bffe-eeb90ba1bc15")]
[StructLayout(LayoutKind.Sequential)]
public struct ACCESS_DENIED_CALLBACK_ACE
{
/// <summary>
/// ACE_HEADER structure that specifies the size and type of ACE. It also contains flags that control inheritance of the ACE by
/// child objects. The <c>AceType</c> member of the <c>ACE_HEADER</c> structure should be set to ACCESS_DENIED_CALLBACK_ACE_TYPE,
/// and the <c>AceSize</c> member should be set to the total number of bytes allocated for the <c>ACCESS_DENIED_CALLBACK_ACE</c> structure.
/// </summary>
public ACE_HEADER Header;
/// <summary>Specifies an ACCESS_MASK structure that specifies the access rights explicitly denied by this ACE.</summary>
public ACCESS_MASK Mask;
/// <summary>
/// The first <c>DWORD</c> of a trustee's SID. The remaining bytes of the SID are stored in contiguous memory after the
/// <c>SidStart</c> member. This SID can be appended with application data.
/// </summary>
public uint SidStart;
}
/// <summary>
/// <para>
/// The <c>ACCESS_DENIED_CALLBACK_OBJECT_ACE</c> structure defines an access control entry (ACE) that controls denied access to an
/// object, a property set, or property. The ACE contains a set of access rights, a <c>GUID</c> that identifies the type of object,
/// and a security identifier (SID) that identifies the trustee to whom the system will deny access. The ACE also contains a
/// <c>GUID</c> and a set of flags that control inheritance of the ACE by child objects.
/// </para>
/// <para>
/// When the AuthzAccessCheck function is called, each <c>ACCESS_DENIED_CALLBACK_OBJECT_ACE</c> structure contained in the DACL of a
/// SECURITY_DESCRIPTOR structure passed through a pointer to the <c>AuthzAccessCheck</c> function invokes a call to the
/// applicationdefined AuthzAccessCheckCallback function, in which a pointer to the <c>ACCESS_DENIED_CALLBACK_OBJECT_ACE</c>
/// structure found is passed in the pAce parameter.
/// </para>
/// </summary>
/// <remarks>
/// <para>
/// If neither the <c>ObjectType</c> nor <c>InheritedObjectType</c><c>GUID</c> is specified, the
/// <c>ACCESS_DENIED_CALLBACK_OBJECT_ACE</c> structure has the same semantics as those used by the ACCESS_DENIED_CALLBACK_ACE
/// structure. In that case, use the <c>ACCESS_DENIED_CALLBACK_ACE</c> structure because it is smaller and more efficient.
/// </para>
/// <para>
/// An ACL that contains an <c>ACCESS_DENIED_CALLBACK_OBJECT_ACE</c> must specify the ACL_REVISION_DS revision number in its ACL header.
/// </para>
/// <para>
/// The access rights specified by the <c>Mask</c> member are denied to any trustee that possesses an enabled SID that matches the
/// SID stored in the <c>SidStart</c> member.
/// </para>
/// <para>
/// When an <c>ACCESS_DENIED_CALLBACK_OBJECT_ACE</c> structure is created, sufficient memory must be allocated to accommodate the
/// GUID structures in the <c>ObjectType</c> and <c>InheritedObjectType</c> members, if one or both of them exists, as well as to
/// accommodate the complete SID of the trustee in the <c>SidStart</c> member and the contiguous memory that follows it.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_denied_callback_object_ace typedef struct
// _ACCESS_DENIED_CALLBACK_OBJECT_ACE { ACE_HEADER Header; ACCESS_MASK Mask; DWORD Flags; GUID ObjectType; GUID InheritedObjectType;
// DWORD SidStart; } ACCESS_DENIED_CALLBACK_OBJECT_ACE, *PACCESS_DENIED_CALLBACK_OBJECT_ACE;
[PInvokeData("winnt.h", MSDNShortId = "945d9c3b-922f-481d-bb1d-3dca50fb9edb")]
[StructLayout(LayoutKind.Sequential)]
public struct ACCESS_DENIED_CALLBACK_OBJECT_ACE
{
/// <summary>
/// ACE_HEADER structure that specifies the size and type of ACE. It contains flags that control inheritance of the ACE by child
/// objects. The <c>AceType</c> member of the <c>ACE_HEADER</c> structure should be set to ACCESS_DENIED_CALLBACK_ACE_TYPE, and
/// the <c>AceSize</c> member should be set to the total number of bytes allocated for the
/// <c>ACCESS_DENIED_CALLBACK_OBJECT_ACE</c> structure.
/// </summary>
public ACE_HEADER Header;
/// <summary>An ACCESS_MASK that specifies the access rights the system will deny to the trustee.</summary>
public ACCESS_MASK Mask;
/// <summary>
/// <para>
/// A set of bit flags that indicate whether the <c>ObjectType</c> and <c>InheritedObjectType</c> members are present. This
/// parameter can be one or more of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>Neither ObjectType nor InheritedObjectType are present. The SidStart member follows immediately after the Flags member.</term>
/// </item>
/// <item>
/// <term>ACE_OBJECT_TYPE_PRESENT</term>
/// <term>
/// ObjectType is present and contains a GUID. If this value is not specified, the InheritedObjectType member follows immediately
/// after the Flags member.
/// </term>
/// </item>
/// <item>
/// <term>ACE_INHERITED_OBJECT_TYPE_PRESENT</term>
/// <term>
/// InheritedObjectType is present and contains a GUID. If this value is not specified, all types of child objects can inherit
/// the ACE.
/// </term>
/// </item>
/// </list>
/// </summary>
public ObjectAceFlags Flags;
/// <summary>
/// <para>
/// This member exists only if the ACE_OBJECT_TYPE_PRESENT bit is set in the <c>Flags</c> member. Otherwise, the
/// <c>InheritedObjectType</c> member follows immediately after the <c>Flags</c> member.
/// </para>
/// <para>
/// If this member exists, it is a GUID structure that identifies a property set, property, extended right, or type of child
/// object. The purpose of this <c>GUID</c> depends on the access rights specified in the <c>Mask</c> member.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ADS_RIGHT_DS_CONTROL_ACCESS</term>
/// <term>The ObjectType GUID identifies an extended access right.</term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_CREATE_CHILD</term>
/// <term>
/// The ObjectType GUID identifies a type of child object. The ACE controls the trustee's right to create this type of child object.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_READ_PROP</term>
/// <term>
/// The ObjectType GUID identifies a property set or property of the object. The ACE controls the trustee's right to read the
/// property or property set.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_WRITE_PROP</term>
/// <term>
/// The ObjectType GUID identifies a property set or property of the object. The ACE controls the trustee's right to write the
/// property or property set.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_SELF</term>
/// <term>The ObjectType GUID identifies a validated write.</term>
/// </item>
/// </list>
/// </summary>
public Guid ObjectType;
/// <summary>
/// <para>This member exists only if the ACE_INHERITED_OBJECT_TYPE_PRESENT bit is set in the <c>Flags</c> member.</para>
/// <para>
/// If this member exists, it is a GUID structure that identifies the type of child object that can inherit the ACE. Inheritance
/// is also controlled by the inheritance flags in the ACE_HEADER, as well as by any protection against inheritance placed on the
/// child objects.
/// </para>
/// <para>
/// The offset of this member can vary. If the <c>Flags</c> member does not contain the ACE_OBJECT_TYPE_PRESENT flag, the
/// <c>InheritedObjectType</c> member starts at the offset specified by the <c>ObjectType</c> member.
/// </para>
/// </summary>
public Guid InheritedObjectType;
/// <summary>
/// The first <c>DWORD</c> of a trustee's SID. The remaining bytes of the SID are stored in contiguous memory after the
/// <c>SidStart</c> member. This SID can be appended with application data.
/// </summary>
public uint SidStart;
}
/// <summary>
/// The <c>ACCESS_DENIED_OBJECT_ACE</c> structure defines an access control entry (ACE) that controls denied access to an object, a
/// property set, or property. The ACE contains a set of access rights, a <c>GUID</c> that identifies the type of object, and a
/// security identifier (SID) that identifies the trustee to whom the system will deny access. The ACE also contains a <c>GUID</c>
/// and a set of flags that control inheritance of the ACE by child objects.
/// </summary>
/// <remarks>
/// <para>
/// If neither the <c>ObjectType</c> nor <c>InheritedObjectType</c><c>GUID</c> is specified, the <c>ACCESS_DENIED_OBJECT_ACE</c>
/// structure has the same semantics as those used by the ACCESS_DENIED_ACE structure. In that case, use the <c>ACCESS_DENIED_ACE</c>
/// structure because it is smaller and more efficient.
/// </para>
/// <para>An ACL that contains an <c>ACCESS_DENIED_OBJECT_ACE</c> must specify the ACL_REVISION_DS revision number in its ACL header.</para>
/// <para>
/// The access rights specified by the <c>Mask</c> member are denied to any trustee that possesses an enabled SID that matches the
/// SID stored in the <c>SidStart</c> member.
/// </para>
/// <para>
/// An <c>ACCESS_DENIED_OBJECT_ACE</c> structure can be created in an access control list (ACL) by a call to the
/// AddAccessDeniedObjectAce function. When this function is used, the correct amount of memory needed to accommodate the GUID
/// structures in the <c>ObjectType</c> and <c>InheritedObjectType</c> members, if one or both of them exists, as well as to
/// accommodate the trustee's SID is automatically allocated. In addition, the values of the <c>Header.AceType</c> and
/// <c>Header.AceSize</c> members are set automatically. When an <c>ACCESS_DENIED_OBJECT_ACE</c> structure is created outside an ACL,
/// sufficient memory must be allocated to accommodate the GUID structures in the <c>ObjectType</c> and <c>InheritedObjectType</c>
/// members, if one or both of them exists, as well as to accommodate the complete SID of the trustee in the <c>SidStart</c> member
/// and the contiguous memory following it. In addition, the values of the <c>Header.AceType</c> and <c>Header.AceSize</c> members
/// must be set explicitly by the application.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_denied_object_ace typedef struct
// _ACCESS_DENIED_OBJECT_ACE { ACE_HEADER Header; ACCESS_MASK Mask; DWORD Flags; GUID ObjectType; GUID InheritedObjectType; DWORD
// SidStart; } ACCESS_DENIED_OBJECT_ACE, *PACCESS_DENIED_OBJECT_ACE;
[PInvokeData("winnt.h", MSDNShortId = "80e00c2b-7c31-428d-96c1-c4e3d22619f3")]
[StructLayout(LayoutKind.Sequential)]
public struct ACCESS_DENIED_OBJECT_ACE
{
/// <summary>
/// ACE_HEADER structure that specifies the size and type of ACE. It contains flags that control inheritance of the ACE by child
/// objects. The <c>AceType</c> member of the <c>ACE_HEADER</c> structure should be set to ACCESS_DENIED_OBJECT_ACE_TYPE, and the
/// <c>AceSize</c> member should be set to the total number of bytes allocated for the <c>ACCESS_DENIED_OBJECT_ACE</c> structure.
/// </summary>
public ACE_HEADER Header;
/// <summary>An ACCESS_MASK that specifies the access rights the system will deny to the trustee.</summary>
public ACCESS_MASK Mask;
/// <summary>
/// <para>
/// A set of bit flags that indicate whether the <c>ObjectType</c> and <c>InheritedObjectType</c> members are present. This
/// parameter can be one or more of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>Neither ObjectType nor InheritedObjectType are present. The SidStart member follows immediately after the Flags member.</term>
/// </item>
/// <item>
/// <term>ACE_OBJECT_TYPE_PRESENT</term>
/// <term>
/// ObjectType is present and contains a GUID. If this value is not specified, the InheritedObjectType member follows immediately
/// after the Flags member.
/// </term>
/// </item>
/// <item>
/// <term>ACE_INHERITED_OBJECT_TYPE_PRESENT</term>
/// <term>
/// InheritedObjectType is present and contains a GUID. If this value is not specified, all types of child objects can inherit
/// the ACE.
/// </term>
/// </item>
/// </list>
/// </summary>
public ObjectAceFlags Flags;
/// <summary>
/// <para>
/// This member exists only if the ACE_OBJECT_TYPE_PRESENT bit is set in the <c>Flags</c> member. Otherwise, the
/// <c>InheritedObjectType</c> member follows immediately after the <c>Flags</c> member.
/// </para>
/// <para>
/// If this member exists, it is a GUID structure that identifies a property set, property, extended right, or type of child
/// object. The purpose of this <c>GUID</c> depends on the access rights specified in the <c>Mask</c> member.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ADS_RIGHT_DS_CONTROL_ACCESS</term>
/// <term>The ObjectType GUID identifies an extended access right.</term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_CREATE_CHILD</term>
/// <term>
/// The ObjectType GUID identifies a type of child object. The ACE controls the trustee's right to create this type of child object.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_READ_PROP</term>
/// <term>
/// The ObjectType GUID identifies a property set or property of the object. The ACE controls the trustee's right to read the
/// property or property set.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_WRITE_PROP</term>
/// <term>
/// The ObjectType GUID identifies a property set or property of the object. The ACE controls the trustee's right to write the
/// property or property set.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_SELF</term>
/// <term>The ObjectType GUID identifies a validated write.</term>
/// </item>
/// </list>
/// </summary>
public Guid ObjectType;
/// <summary>
/// <para>This member exists only if the ACE_INHERITED_OBJECT_TYPE_PRESENT bit is set in the <c>Flags</c> member.</para>
/// <para>
/// If this member exists, it is a GUID structure that identifies the type of child object that can inherit the ACE. Inheritance
/// is also controlled by the inheritance flags in the ACE_HEADER, as well as by any protection against inheritance placed on the
/// child objects.
/// </para>
/// <para>
/// The offset of this member can vary. If the <c>Flags</c> member does not contain the ACE_OBJECT_TYPE_PRESENT flag, the
/// <c>InheritedObjectType</c> member starts at the offset specified by the <c>ObjectType</c> member.
/// </para>
/// </summary>
public Guid InheritedObjectType;
/// <summary>
/// <para>
/// Specifies the first <c>DWORD</c> of a SID that identifies the trustee for whom the access rights are denied. The remaining
/// bytes of the SID are stored in contiguous memory after the <c>SidStart</c> member. This SID can be appended with application data.
/// </para>
/// <para>
/// The offset of this member can vary. If the <c>Flags</c> member is zero, the <c>SidStart</c> member starts at the offset
/// specified by the <c>ObjectType</c> member. If <c>Flags</c> contains only one flag (either ACE_OBJECT_TYPE_PRESENT or
/// ACE_INHERITED_OBJECT_TYPE_PRESENT), the <c>SidStart</c> member starts at the offset specified by the
/// <c>InheritedObjectType</c> member.
/// </para>
/// </summary>
public uint SidStart;
}
/// <summary>The ACE_HEADER structure describes the type and size of an access-control entry (ACE).</summary>
/// <remarks>
/// <para>The ACE_HEADER structure is the first member of the various types of ACE structures, such as ACCESS_ALLOWED_ACE.</para>
/// <para>
/// System-alarm ACEs are not currently supported. The <c>AceType</c> member cannot specify the SYSTEM_ALARM_ACE_TYPE. Do not use the
/// SYSTEM_ALARM_ACE structure.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntifs/ns-ntifs-_ace_header typedef struct _ACE_HEADER {
// UCHAR AceType; UCHAR AceFlags; USHORT AceSize; } ACE_HEADER;
[PInvokeData("ntifs.h", MSDNShortId = "f5f39310-8b15-4d6b-a985-3f25522a16b1")]
[StructLayout(LayoutKind.Sequential)]
public struct ACE_HEADER
{
/// <summary>
/// <para>ACE type. This member can be one of the following values:</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ACCESS_ALLOWED_ACE_TYPE</term>
/// <term>Access-allowed ACE that uses the ACCESS_ALLOWED_ACE structure.</term>
/// </item>
/// <item>
/// <term>ACCESS_DENIED_ACE_TYPE</term>
/// <term>Access-denied ACE that uses the ACCESS_DENIED_ACE structure.</term>
/// </item>
/// <item>
/// <term>SYSTEM_AUDIT_ACE_TYPE</term>
/// <term>System-audit ACE that uses the SYSTEM_AUDIT_ACE structure.</term>
/// </item>
/// </list>
/// </summary>
public AceType AceType;
/// <summary>
/// <para>Set of ACE type-specific control flags. This member can be a combination of the following values:</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CONTAINER_INHERIT_ACE</term>
/// <term>
/// Child objects that are containers, such as directories, inherit the ACE as an effective ACE. The inherited ACE is inheritable
/// unless the NO_PROPAGATE_INHERIT_ACE bit flag is also set.
/// </term>
/// </item>
/// <item>
/// <term>FAILED_ACCESS_ACE_FLAG</term>
/// <term>Used with system-audit ACEs in a SACL to generate audit messages for failed access attempts.</term>
/// </item>
/// <item>
/// <term>INHERIT_ONLY_ACE</term>
/// <term>
/// Indicates an inherit-only ACE which does not control access to the object to which it is attached. If this flag is not set,
/// the ACE is an effective ACE which controls access to the object to which it is attached. Both effective and inherit-only ACEs
/// can be inherited depending on the state of the other inheritance flags.
/// </term>
/// </item>
/// <item>
/// <term>INHERITED_ACE</term>
/// <term>
/// Microsoft Windows 2000 or later: Indicates that the ACE was inherited. The system sets this bit when it propagates an
/// inherited ACE to a child object.
/// </term>
/// </item>
/// <item>
/// <term>NO_PROPAGATE_INHERIT_ACE</term>
/// <term>
/// If the ACE is inherited by a child object, the system clears the OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE flags in the
/// inherited ACE. This prevents the ACE from being inherited by subsequent generations of objects.
/// </term>
/// </item>
/// <item>
/// <term>OBJECT_INHERIT_ACE</term>
/// <term>
/// Noncontainer child objects inherit the ACE as an effective ACE. For child objects that are containers, the ACE is inherited
/// as an inherit-only ACE unless the NO_PROPAGATE_INHERIT_ACE bit flag is also set.
/// </term>
/// </item>
/// <item>
/// <term>SUCCESSFUL_ACCESS_ACE_FLAG</term>
/// <term>Used with system-audit ACEs in a SACL to generate audit messages for successful access attempts.</term>
/// </item>
/// </list>
/// </summary>
public AceFlags AceFlags;
/// <summary>Size, in bytes, of the ACE.</summary>
public ushort AceSize;
/// <summary>Initializes a new instance of the <see cref="ACE_HEADER"/> struct.</summary>
/// <param name="aceType">ACE type.</param>
/// <param name="aceFlags">Set of ACE type-specific control flags.</param>
/// <param name="aceSize">Size, in bytes, of the ACE.</param>
public ACE_HEADER(AceType aceType, AceFlags aceFlags, int aceSize)
{
AceType = aceType;
AceFlags = aceFlags;
AceSize = (ushort)aceSize;
}
}
/// <summary>
/// The ACL structure is the header of an access control list (ACL). A complete ACL consists of an ACL structure followed by an
/// ordered list of zero or more access control entries (ACEs).
/// </summary>
/// <remarks>
/// An ACL includes a sequential list of zero or more ACEs. The individual ACEs in an ACL are numbered from 0 to n, where n+1 is the
/// number of ACEs in the ACL. When editing an ACL, an application refers to an ACE within the ACL by the ACE's index.
/// <para>There are two types of ACL: discretionary and system.</para>
/// <para>
/// A discretionary access control list (DACL) is controlled by the owner of an object or anyone granted WRITE_DAC access to the
/// object. It specifies the access particular users and groups can have to an object. For example, the owner of a file can use a
/// DACL to control which users and groups can and cannot have access to the file.
/// </para>
/// <para>
/// An object can also have system-level security information associated with it, in the form of a system access control list (SACL)
/// controlled by a system administrator. A SACL allows the system administrator to audit any attempts to gain access to an object.
/// </para>
/// <para>For a list of currently defined ACE structures, see ACE.</para>
/// <para>A fourth ACE structure, SYSTEM_ALARM_ACE, is not currently supported.</para>
/// <para>
/// The ACL structure is to be treated as though it were opaque and applications are not to attempt to work with its members
/// directly. To ensure that ACLs are semantically correct, applications can use the functions listed in the See Also section to
/// create and manipulate ACLs.
/// </para>
/// <para>Each ACL and ACE structure begins on a DWORD boundary.</para>
/// <para>The maximum size for an ACL, including its ACEs, is 64 KB.</para>
/// </remarks>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
[PInvokeData("Winnt.h", MSDNShortId = "aa374931")]
public struct ACL
{
/// <summary>
/// Specifies the revision level of the ACL. This value should be ACL_REVISION, unless the ACL contains an object-specific ACE,
/// in which case this value must be ACL_REVISION_DS. All ACEs in an ACL must be at the same revision level.
/// </summary>
public byte AclRevision;
/// <summary>Specifies a zero byte of padding that aligns the AclRevision member on a 16-bit boundary.</summary>
public byte Sbz1;
/// <summary>Specifies the size, in bytes, of the ACL. This value includes both the ACL structure and all the ACEs.</summary>
public ushort AclSize;
/// <summary>Specifies the number of ACEs stored in the ACL.</summary>
public ushort AceCount;
/// <summary>Specifies two zero-bytes of padding that align the ACL structure on a 32-bit boundary.</summary>
public ushort Sbz2;
}
/// <summary>The ACL_REVISION_INFORMATION structure contains revision information about an ACL structure.</summary>
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("Winnt.h", MSDNShortId = "aa374942")]
public struct ACL_REVISION_INFORMATION
{
/// <summary>Specifies a revision number. The current revision number is ACL_REVISION.</summary>
public uint AclRevision;
}
/// <summary>The ACL_SIZE_INFORMATION structure contains information about the size of an ACL structure.</summary>
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("Winnt.h", MSDNShortId = "aa374945")]
public struct ACL_SIZE_INFORMATION
{
/// <summary>The number of access control entries (ACEs) in the access control list (ACL).</summary>
public uint AceCount;
/// <summary>
/// The number of bytes in the ACL actually used to store the ACEs and ACL structure. This may be less than the total number of
/// bytes allocated to the ACL.
/// </summary>
public uint AclBytesInUse;
/// <summary>The number of unused bytes in the ACL.</summary>
public uint AclBytesFree;
}
/// <summary>The <c>CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE</c> structure specifies the fully qualified binary name.</summary>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-_claim_security_attribute_fqbn_value typedef struct
// _CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE { DWORD64 Version; PWSTR Name; } CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE, *PCLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE;
[PInvokeData("winnt.h", MSDNShortId = "1FD9A519-40EA-4780-90F5-C9DF4ADAE72C")]
[StructLayout(LayoutKind.Sequential)]
public struct CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE
{
/// <summary>The version of the fully qualified binary name value.</summary>
public ulong Version;
/// <summary>A fully qualified binary name.</summary>
[MarshalAs(UnmanagedType.LPWStr)]
public string Name;
}
/// <summary>
/// The <c>CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE</c> structure specifies the <c>OCTET_STRING</c> value type of the claim
/// security attribute.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-claim_security_attribute_octet_string_value typedef struct
// _CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE { PVOID pValue; DWORD ValueLength; } CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE, *PCLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE;
[PInvokeData("winnt.h", MSDNShortId = "6647CC4F-1A84-43B2-A80E-7B6BF3A2D7AD")]
[StructLayout(LayoutKind.Sequential)]
public struct CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE
{
/// <summary>
/// A pointer buffer that contains the <c>OCTET_STRING</c> value. The value is a series of bytes of the length indicated in the
/// <c>ValueLength</c> member.
/// </summary>
public IntPtr pValue;
/// <summary>The length, in bytes, of the <c>OCTET_STRING</c> value.</summary>
public uint ValueLength;
}
/// <summary>
/// The <c>CLAIM_SECURITY_ATTRIBUTE_V1</c> structure defines a security attribute that can be associated with a token or
/// authorization context.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-_claim_security_attribute_v1 typedef struct
// _CLAIM_SECURITY_ATTRIBUTE_V1 { PWSTR Name; WORD ValueType; WORD Reserved; DWORD Flags; DWORD ValueCount; union { PLONG64 pInt64;
// PDWORD64 pUint64; PWSTR *ppString; PCLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE pFqbn; PCLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE
// pOctetString; } Values; } CLAIM_SECURITY_ATTRIBUTE_V1, *PCLAIM_SECURITY_ATTRIBUTE_V1;
[PInvokeData("winnt.h", MSDNShortId = "FDBB9B00-01C3-474A-81FF-97C5CBA3261B")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CLAIM_SECURITY_ATTRIBUTE_V1
{
/// <summary>
/// A pointer to a string of Unicode characters that contains the name of the security attribute. This string must be at least 4
/// bytes in length.
/// </summary>
[MarshalAs(UnmanagedType.LPWStr)]
public string Name;
/// <summary>
/// <para>
/// A union tag value that indicates the type of information contained in the <c>Values</c> member. The <c>ValueType</c> member
/// must be one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CLAIM_SECURITY_ATTRIBUTE_TYPE_INT64 0x0001</term>
/// <term>The Values member refers to an array of LONG64 values.</term>
/// </item>
/// <item>
/// <term>CLAIM_SECURITY_ATTRIBUTE_TYPE_UINT64 0x0002</term>
/// <term>The Values member refers to an array of ULONG64 values.</term>
/// </item>
/// <item>
/// <term>CLAIM_SECURITY_ATTRIBUTE_TYPE_STRING 0x0003</term>
/// <term>The Values member refers to an array of pointers to Unicode string values.</term>
/// </item>
/// <item>
/// <term>CLAIM_SECURITY_ATTRIBUTE_TYPE_FQBN 0x0004</term>
/// <term>The Values member refers to an array of CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE values.</term>
/// </item>
/// <item>
/// <term>CLAIM_SECURITY_ATTRIBUTE_TYPE_SID 0x0005</term>
/// <term>
/// The Values member refers to an array of CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE values where the pValue member of each
/// CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE is a PSID.
/// </term>
/// </item>
/// <item>
/// <term>CLAIM_SECURITY_ATTRIBUTE_TYPE_BOOLEAN 0x0006</term>
/// <term>
/// The Values member refers to an array of ULONG64 values where each element indicates a Boolean value. The value 1 indicates
/// TRUE and the value 0 indicates FALSE.
/// </term>
/// </item>
/// <item>
/// <term>CLAIM_SECURITY_ATTRIBUTE_TYPE_OCTET_STRING 0x0010</term>
/// <term>The Values member refers to an array of CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE values.</term>
/// </item>
/// </list>
/// </summary>
public CLAIM_SECURITY_ATTRIBUTE_TYPE ValueType;
/// <summary>This member is reserved and must be set to zero when sent and must be ignored when received.</summary>
public ushort Reserved;
/// <summary>
/// <para>
/// The attribute flags that are a 32-bitmask. Bits 16 through 31 may be set to any value. Bits 0 through 15 must be zero or a
/// combination of one or more of the following mask values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CLAIM_SECURITY_ATTRIBUTE_NON_INHERITABLE 0x0001</term>
/// <term>This attribute is ignored by the operating system. This claim security attribute is not inherited across processes.</term>
/// </item>
/// <item>
/// <term>CLAIM_SECURITY_ATTRIBUTE_VALUE_CASE_SENSITIVE 0x0002</term>
/// <term>The value of the claim security attribute is case sensitive. This flag is valid for values that contain string types.</term>
/// </item>
/// <item>
/// <term>CLAIM_SECURITY_ATTRIBUTE_USE_FOR_DENY_ONLY 0x0004</term>
/// <term>The claim security attribute is considered only for deny access control entries (ACEs).</term>
/// </item>
/// <item>
/// <term>CLAIM_SECURITY_ATTRIBUTE_DISABLED_BY_DEFAULT 0x0008</term>
/// <term>The claim security attribute is disabled by default.</term>
/// </item>
/// <item>
/// <term>CLAIM_SECURITY_ATTRIBUTE_DISABLED 0x0010</term>
/// <term>The claim security attribute is disabled and will not be applied by the AccessCheck function.</term>
/// </item>
/// <item>
/// <term>CLAIM_SECURITY_ATTRIBUTE_MANDATORY 0x0020</term>
/// <term>The claim security attribute is mandatory.</term>
/// </item>
/// </list>
/// </summary>
public CLAIM_SECURITY_ATTRIBUTE_FLAG Flags;
/// <summary>The number of values specified in the <c>Values</c> member.</summary>
public uint ValueCount;
/// <summary>An array of security attribute values of the type specified in the <c>ValueType</c> member.</summary>
public VALUESUNION Values;
/// <summary/>
[StructLayout(LayoutKind.Explicit)]
public struct VALUESUNION
{
/// <summary>Pointer to an array of <c>ValueCount</c> members where each member is a <c>LONG64</c> of type CLAIM_SECURITY_ATTRIBUTE_TYPE_INT64.</summary>
[FieldOffset(0)]
public IntPtr pInt64;
/// <summary>Pointer to an array of <c>ValueCount</c> members where each member is a <c>ULONG64</c> of type CLAIM_SECURITY_ATTRIBUTE_TYPE_UINT64.</summary>
[FieldOffset(0)]
public IntPtr pUint64;
/// <summary>Pointer to an array of <c>ValueCount</c> members where each member is a <c>PWSTR</c> of type CLAIM_SECURITY_ATTRIBUTE_TYPE_STRING.</summary>
[FieldOffset(0)]
public IntPtr ppString;
/// <summary>
/// Pointer to an array of <c>ValueCount</c> members where each member is a fully qualified binary name value of type CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE.
/// </summary>
[FieldOffset(0)]
public IntPtr pFqbn;
/// <summary>Pointer to an array of <c>ValueCount</c> members where each member is an octet string of type CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE.</summary>
[FieldOffset(0)]
public IntPtr pOctetString;
}
}
/// <summary>The CLAIM_SECURITY_ATTRIBUTES_INFORMATION structure defines the security attributes for the claim.</summary>
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("Winnt.h", MSDNShortId = "hh448481")]
public struct CLAIM_SECURITY_ATTRIBUTES_INFORMATION
{
/// <summary>A default instance which sets the <see cref="Version"/> field.</summary>
public static readonly CLAIM_SECURITY_ATTRIBUTES_INFORMATION Default = new CLAIM_SECURITY_ATTRIBUTES_INFORMATION { Version = 1 };
/// <summary>The version of the security attribute. This must be 1.</summary>
public ushort Version;
/// <summary>
/// This member is currently reserved and must be zero when setting an attribute and is ignored when getting an attribute.
/// </summary>
public ushort Reserved;
/// <summary>The number of values.</summary>
public uint AttributeCount;
/// <summary>The actual attribute.</summary>
public ATTRUNION Attribute;
/// <summary>The actual attribute.</summary>
[StructLayout(LayoutKind.Explicit)]
[PInvokeData("Winnt.h", MSDNShortId = "hh448481")]
public struct ATTRUNION
{
/// <summary>Pointer to an array that contains the AttributeCount member of the CLAIM_SECURITY_ATTRIBUTE_V1 structure.</summary>
[FieldOffset(0)]
public IntPtr pAttributeV1;
}
}
/// <summary>
/// <para>Contains information that is included immediately after the newest event log record.</para>
/// <para>
/// The <c>ELF_EOF_RECORD</c> structure is used in an event log to enable the event-logging service to reconstruct the
/// <c>ELF_LOGFILE_HEADER</c>. The event-logging service must add the <c>ELF_EOF_RECORD</c> to the event log. For more information
/// about <c>ELF_EOF_RECORD</c>, see Event Log File Format.
/// </para>
/// </summary>
// typedef struct _EVENTLOGEOF { ULONG RecordSizeBeginning; ULONG One; ULONG Two; ULONG Three; ULONG Four; ULONG BeginRecord; ULONG
// EndRecord; ULONG CurrentRecordNumber; ULONG OldestRecordNumber; ULONG RecordSizeEnd;} EVENTLOGEOF, *PEVENTLOGEOF; https://msdn.microsoft.com/en-us/library/windows/desktop/bb309022(v=vs.85).aspx
[PInvokeData("Winnt.h", MSDNShortId = "bb309022")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct EVENTLOGEOF
{
/// <summary>The beginning size of the <c>ELF_EOF_RECORD</c>. The beginning size is always 0x28.</summary>
public uint RecordSizeBeginning;
/// <summary>
/// An identifier that helps to differentiate this record from other records in the event log. The value is always set to 0x11111111.
/// </summary>
public uint One;
/// <summary>
/// An identifier that helps to differentiate this record from other records in the event log. The value is always set to 0x22222222.
/// </summary>
public uint Two;
/// <summary>
/// An identifier that helps to differentiate this record from other records in the event log. The value is always set to 0x33333333.
/// </summary>
public uint Three;
/// <summary>
/// An identifier that helps to differentiate this record from other records in the event log. The value is always set to 0x44444444.
/// </summary>
public uint Four;
/// <summary>The offset to the oldest record. If the event log is empty, this is set to the start of this structure.</summary>
public uint BeginRecord;
/// <summary>The offset to the start of this structure.</summary>
public uint EndRecord;
/// <summary>The record number of the next event that will be written to the event log.</summary>
public uint CurrentRecordNumber;
/// <summary>The record number of the oldest record in the event log. The record number will be 0 if the event log is empty.</summary>
public uint OldestRecordNumber;
/// <summary>The ending size of the <c>ELF_EOF_RECORD</c>. The ending size is always 0x28.</summary>
public uint RecordSizeEnd;
}
/// <summary>
/// <para>Contains information that is included at the beginning of an event log.</para>
/// <para>
/// The <c>ELF_LOGFILE_HEADER</c> structure is used at the beginning of an event log to define information about the event log. The
/// event-logging service must add the <c>ELF_LOGFILE_HEADER</c> to the event log. For more information about how the
/// <c>ELF_LOGFILE_HEADER</c> is used, see Event Log File Format.
/// </para>
/// </summary>
// typedef struct _EVENTLOGHEADER { ULONG HeaderSize; ULONG Signature; ULONG MajorVersion; ULONG MinorVersion; ULONG StartOffset;
// ULONG EndOffset; ULONG CurrentRecordNumber; ULONG OldestRecordNumber; ULONG MaxSize; ULONG Flags; ULONG Retention; ULONG
// EndHeaderSize;} EVENTLOGHEADER, *PEVENTLOGHEADER; https://msdn.microsoft.com/en-us/library/windows/desktop/bb309024(v=vs.85).aspx
[PInvokeData("Winnt.h", MSDNShortId = "bb309024")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct EVENTLOGHEADER
{
/// <summary>The size of the header structure. The size is always 0x30.</summary>
public uint HeaderSize;
/// <summary>The signature is always 0x654c664c, which is ASCII for eLfL.</summary>
public uint Signature;
/// <summary>The major version number of the event log. The major version number is always set to 1.</summary>
public uint MajorVersion;
/// <summary>The minor version number of the event log. The minor version number is always set to 1.</summary>
public uint MinorVersion;
/// <summary>The offset to the oldest record in the event log.</summary>
public uint StartOffset;
/// <summary>The offset to the <c>ELF_EOF_RECORD</c> in the event log.</summary>
public uint EndOffset;
/// <summary>The number of the next record that will be added to the event log.</summary>
public uint CurrentRecordNumber;
/// <summary>The number of the oldest record in the event log. For an empty file, the oldest record number is set to 0.</summary>
public uint OldestRecordNumber;
/// <summary>
/// The maximum size, in bytes, of the event log. The maximum size is defined when the event log is created. The event-logging
/// service does not typically update this value, it relies on the registry configuration. The reader of the event log can use
/// normal file APIs to determine the size of the file. For more information about registry configuration values, see Eventlog Key.
/// </summary>
public uint MaxSize;
/// <summary>
/// <para>The status of the event log. This member can be one of the following values:</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ELF_LOGFILE_HEADER_DIRTY0x0001</term>
/// <term>
/// Indicates that records have been written to an event log, but the event log file has not been properly closed. For more
/// information about this flag, see the Remarks section.
/// </term>
/// </item>
/// <item>
/// <term>ELF_LOGFILE_HEADER_WRAP0x0002</term>
/// <term>Indicates that records in the event log have wrapped.</term>
/// </item>
/// <item>
/// <term>ELF_LOGFILE_LOGFULL_WRITTEN0x0004</term>
/// <term>Indicates that the most recent write attempt failed due to insufficient space.</term>
/// </item>
/// <item>
/// <term>ELF_LOGFILE_ARCHIVE_SET0x0008</term>
/// <term>
/// Indicates that the archive attribute has been set for the file. Normal file APIs can also be used to determine the value of
/// this flag.
/// </term>
/// </item>
/// </list>
/// </para>
/// </summary>
public ELF_FLAGS Flags;
/// <summary>
/// The retention value of the file when it is created. The event-logging service does not typically update this value, it relies
/// on the registry configuration. For more information about registry configuration values, see Eventlog Key.
/// </summary>
public uint Retention;
/// <summary>The ending size of the header structure. The size is always 0x30.</summary>
public uint EndHeaderSize;
}
/// <summary>Contains information about an event record returned by the ReadEventLog function.</summary>
/// <remarks>
/// <para>
/// The defined members are followed by the replacement strings for the message identified by the event identifier, the binary
/// information, some pad bytes to make sure the full entry is on a <c>DWORD</c> boundary, and finally the length of the log entry
/// again. Because the strings and the binary information can be of any length, no structure members are defined to reference them.
/// The declaration of this structure in Winnt.h describes these members as follows:
/// </para>
/// <para>
/// The source name is a variable-length string that specifies the name of the event source. The computer name is the name of the
/// computer that generated the event. It may be followed with some padding bytes so that the user SID is aligned on a <c>DWORD</c>
/// boundary. The user SID identifies the active user at the time this event was logged. If <c>UserSidLength</c> is zero, this field
/// may be empty.
/// </para>
/// <para>
/// The event identifier together with source name and a language identifier identify a string that describes the event in more
/// detail. The strings are used as replacement strings and are merged into the message string to make a complete message. The
/// message strings are contained in a message file specified in the source entry in the registry. To obtain the appropriate message
/// string from the message file, load the message file with the LoadLibrary function and use the FormatMessage function.
/// </para>
/// <para>
/// The binary information is information that is specific to the event. It could be the contents of the processor registers when a
/// device driver got an error, a dump of an invalid packet that was received from the network, a dump of all the structures in a
/// program (when the data area was detected to be corrupt), and so on. This information should be useful to the writer of the device
/// driver or the application in tracking down bugs or unauthorized breaks into the application.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_eventlogrecord typedef struct _EVENTLOGRECORD { DWORD Length;
// DWORD Reserved; DWORD RecordNumber; DWORD TimeGenerated; DWORD TimeWritten; DWORD EventID; WORD EventType; WORD NumStrings; WORD
// EventCategory; WORD ReservedFlags; DWORD ClosingRecordNumber; DWORD StringOffset; DWORD UserSidLength; DWORD UserSidOffset; DWORD
// DataLength; DWORD DataOffset; } EVENTLOGRECORD, *PEVENTLOGRECORD;
[PInvokeData("winnt.h", MSDNShortId = "669b182a-bc81-4386-9815-6ffa09e2e743")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct EVENTLOGRECORD
{
/// <summary>
/// The size of this event record, in bytes. Note that this value is stored at both ends of the entry to ease moving forward or
/// backward through the log. The length includes any pad bytes inserted at the end of the record for <c>DWORD</c> alignment.
/// </summary>
public uint Length;
/// <summary>A DWORD value that is always set to <c>ELF_LOG_SIGNATURE</c> (the value is 0x654c664c), which is ASCII for eLfL.</summary>
public uint Reserved;
/// <summary>
/// The number of the record. This value can be used with the EVENTLOG_SEEK_READ flag in the ReadEventLog function to begin
/// reading at a specified record. For more information, see Event Log Records.
/// </summary>
public uint RecordNumber;
/// <summary>
/// The time at which this entry was submitted. This time is measured in the number of seconds elapsed since 00:00:00 January 1,
/// 1970, Universal Coordinated Time.
/// </summary>
public uint TimeGenerated;
/// <summary>
/// The time at which this entry was received by the service to be written to the log. This time is measured in the number of
/// seconds elapsed since 00:00:00 January 1, 1970, Universal Coordinated Time.
/// </summary>
public uint TimeWritten;
/// <summary>
/// The event identifier. The value is specific to the event source for the event, and is used with source name to locate a
/// description string in the message file for the event source. For more information, see Event Identifiers.
/// </summary>
public uint EventID;
/// <summary>
/// <para>The type of event. This member can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>EVENTLOG_ERROR_TYPE 0x0001</term>
/// <term>Error event</term>
/// </item>
/// <item>
/// <term>EVENTLOG_AUDIT_FAILURE 0x0010</term>
/// <term>Failure Audit event</term>
/// </item>
/// <item>
/// <term>EVENTLOG_AUDIT_SUCCESS 0x0008</term>
/// <term>Success Audit event</term>
/// </item>
/// <item>
/// <term>EVENTLOG_INFORMATION_TYPE 0x0004</term>
/// <term>Information event</term>
/// </item>
/// <item>
/// <term>EVENTLOG_WARNING_TYPE 0x0002</term>
/// <term>Warning event</term>
/// </item>
/// </list>
/// <para>For more information, see Event Types.</para>
/// </summary>
public EVENTLOG_TYPE EventType;
/// <summary>
/// The number of strings present in the log (at the position indicated by <c>StringOffset</c>). These strings are merged into
/// the message before it is displayed to the user.
/// </summary>
public ushort NumStrings;
/// <summary>
/// The category for this event. The meaning of this value depends on the event source. For more information, see Event Categories.
/// </summary>
public ushort EventCategory;
/// <summary>Reserved.</summary>
public ushort ReservedFlags;
/// <summary>Reserved.</summary>
public uint ClosingRecordNumber;
/// <summary>The offset of the description strings within this event log record.</summary>
public uint StringOffset;
/// <summary>The size of the <c>UserSid</c> member, in bytes. This value can be zero if no security identifier was provided.</summary>
public uint UserSidLength;
/// <summary>
/// The offset of the security identifier (SID) within this event log record. To obtain the user name for this SID, use the
/// LookupAccountSid function.
/// </summary>
public uint UserSidOffset;
/// <summary>The size of the event-specific data (at the position indicated by <c>DataOffset</c>), in bytes.</summary>
public uint DataLength;
/// <summary>
/// The offset of the event-specific information within this event log record, in bytes. This information could be something
/// specific (a disk driver might log the number of retries, for example), followed by binary information specific to the event
/// being logged and to the source that generated the entry.
/// </summary>
public uint DataOffset;
}
/// <summary>
/// Defines the mapping of generic access rights to specific and standard access rights for an object. When a client application
/// requests generic access to an object, that request is mapped to the access rights defined in this structure.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("Winnt.h", MSDNShortId = "aa446633")]
public struct GENERIC_MAPPING
{
/// <summary>Specifies an access mask defining read access to an object.</summary>
public uint GenericRead;
/// <summary>Specifies an access mask defining write access to an object.</summary>
public uint GenericWrite;
/// <summary>Specifies an access mask defining execute access to an object.</summary>
public uint GenericExecute;
/// <summary>Specifies an access mask defining all possible types of access to an object.</summary>
public uint GenericAll;
/// <summary>Initializes a new instance of the <see cref="GENERIC_MAPPING"/> structure.</summary>
/// <param name="read">The read mapping.</param>
/// <param name="write">The write mapping.</param>
/// <param name="execute">The execute mapping.</param>
/// <param name="all">The 'all' mapping.</param>
public GENERIC_MAPPING(uint read, uint write, uint execute, uint all)
{
GenericRead = read;
GenericWrite = write;
GenericExecute = execute;
GenericAll = all;
}
/// <summary>The generic file mappings (FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_READ, FILE_ALL_ACCESS).</summary>
public static readonly GENERIC_MAPPING GenericFileMapping = new GENERIC_MAPPING((uint)FileAccess.FILE_GENERIC_READ, (uint)FileAccess.FILE_GENERIC_WRITE, (uint)FileAccess.FILE_GENERIC_READ, (uint)FileAccess.FILE_ALL_ACCESS);
}
/// <summary>
/// An LUID is a 64-bit value guaranteed to be unique only on the system on which it was generated. The uniqueness of a locally
/// unique identifier (LUID) is guaranteed only until the system is restarted.
/// <para>Applications must use functions and structures to manipulate LUID values.</para>
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct LUID
{
/// <summary>Low order bits.</summary>
public uint LowPart;
/// <summary>High order bits.</summary>
public int HighPart;
/// <summary>Gets the privilege name for this LUID.</summary>
/// <param name="systemName">
/// Name of the system on which to perform the lookup. Specifying <c>null</c> will query the local system.
/// </param>
/// <returns>The name retrieved for the LUID.</returns>
public string GetName(string systemName = null)
{
var sb = new StringBuilder(1024);
var sz = (uint)sb.Capacity;
if (!LookupPrivilegeName(systemName, in this, sb, ref sz))
Win32Error.ThrowLastError();
return sb.ToString();
}
/// <summary>Creates a new LUID instance from a privilege name.</summary>
/// <param name="name">The privilege name.</param>
/// <param name="systemName">
/// Name of the system on which to perform the lookup. Specifying <c>null</c> will query the local system.
/// </param>
/// <returns>The LUID instance corresponding to the <paramref name="name"/>.</returns>
public static LUID FromName(string name, string systemName = null) =>
!LookupPrivilegeValue(systemName, name, out var val) ? throw Win32Error.GetLastError().GetException() : val;
/// <summary>
/// Creates a new LUID that is unique to the local system only, and uniqueness is guaranteed only until the system is next restarted.
/// </summary>
/// <returns>A new LUID.</returns>
public static LUID NewLUID()
{
if (!AllocateLocallyUniqueId(out var ret))
Win32Error.ThrowLastError();
return ret;
}
/// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary>
/// <returns>A <see cref="System.String"/> that represents this instance.</returns>
public override string ToString()
{
try { return GetName(); } catch { return $"0x{Macros.MAKELONG64(LowPart, (uint)HighPart):X}"; }
}
}
/// <summary>The LUID_AND_ATTRIBUTES structure represents a locally unique identifier (LUID) and its attributes.</summary>
/// <remarks>
/// An LUID_AND_ATTRIBUTES structure can represent an LUID whose attributes change frequently, such as when the LUID is used to
/// represent privileges in the PRIVILEGE_SET structure. Privileges are represented by LUIDs and have attributes indicating whether
/// they are currently enabled or disabled.
/// </remarks>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct LUID_AND_ATTRIBUTES
{
/// <summary>Specifies a LUID value.</summary>
public LUID Luid;
/// <summary>
/// Specifies attributes of the LUID. This value contains up to 32 one-bit flags. Its meaning is dependent on the definition and
/// use of the LUID.
/// </summary>
public PrivilegeAttributes Attributes;
/// <summary>Initializes a new instance of the <see cref="LUID_AND_ATTRIBUTES"/> struct.</summary>
/// <param name="luid">The LUID value.</param>
/// <param name="attr">The attribute value.</param>
public LUID_AND_ATTRIBUTES(LUID luid, PrivilegeAttributes attr)
{
Luid = luid;
Attributes = attr;
}
/// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary>
/// <returns>A <see cref="System.String"/> that represents this instance.</returns>
public override string ToString() => $"{Luid}:{Attributes}";
}
/// <summary>The QUOTA_LIMITS structure describes the amount of system resources available to a user.</summary>
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("Winnt.h", MSDNShortId = "aa379363")]
public struct QUOTA_LIMITS
{
/// <summary>
/// Specifies the amount of paged pool memory assigned to the user. The paged pool is an area of system memory (physical memory
/// used by the operating
/// system) for objects that can be written to disk when they are not being used.
/// <para>
/// The value set in this member is not enforced by the LSA. You should set this member to 0, which causes the default value to
/// be used.
/// </para>
/// </summary>
public uint PagedPoolLimit;
/// <summary>
/// Specifies the amount of nonpaged pool memory assigned to the user. The nonpaged pool is an area of system memory for objects
/// that cannot be written to disk but must remain in physical memory as long as they are allocated.
/// <para>
/// The value set in this member is not enforced by the LSA. You should set this member to 0, which causes the default value to
/// be used.
/// </para>
/// </summary>
public uint NonPagedPoolLimit;
/// <summary>
/// Specifies the minimum set size assigned to the user. The "working set" of a process is the set of memory pages currently
/// visible to the process in physical RAM memory. These pages are present in memory when the application is running and
/// available for an application to use without triggering a page fault.
/// <para>
/// The value set in this member is not enforced by the LSA. You should set this member to NULL, which causes the default value
/// to be used.
/// </para>
/// </summary>
public uint MinimumWorkingSetSize;
/// <summary>
/// Specifies the maximum set size assigned to the user.
/// <para>
/// The value set in this member is not enforced by the LSA. You should set this member to 0, which causes the default value to
/// be used.
/// </para>
/// </summary>
public uint MaximumWorkingSetSize;
/// <summary>
/// Specifies the maximum size, in bytes, of the paging file, which is a reserved space on disk that backs up committed physical
/// memory on the computer.
/// <para>
/// The value set in this member is not enforced by the LSA. You should set this member to 0, which causes the default value to
/// be used.
/// </para>
/// </summary>
public uint PagefileLimit;
/// <summary>
/// Indicates the maximum amount of time the process can run.
/// <para>
/// The value set in this member is not enforced by the LSA. You should set this member to NULL, which causes the default value
/// to be used.
/// </para>
/// </summary>
public long TimeLimit;
}
/// <summary>
/// The SECURITY_DESCRIPTOR structure contains the security information associated with an object. Applications use this structure to
/// set and query an object's security status.
/// <para>
/// Because the internal format of a security descriptor can vary, we recommend that applications not modify the SECURITY_DESCRIPTOR
/// structure directly.
/// </para>
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
[PInvokeData("Winnt.h", MSDNShortId = "aa379561")]
public struct SECURITY_DESCRIPTOR
{
/// <summary>Undocumented.</summary>
public byte Revision;
/// <summary>Undocumented.</summary>
public byte Sbz1;
/// <summary>Undocumented.</summary>
public SECURITY_DESCRIPTOR_CONTROL Control;
/// <summary>Undocumented.</summary>
public PSID Owner;
/// <summary>Undocumented.</summary>
public PSID Group;
/// <summary>Undocumented.</summary>
public PACL Sacl;
/// <summary>Undocumented.</summary>
public PACL Dacl;
}
/// <summary>
/// <para>The security identifier (SID) structure is a variable-length structure used to uniquely identify users or groups.</para>
/// <para>
/// Applications should not modify a SID directly. To create and manipulate a security identifier, use the functions listed in the
/// See Also section.
/// </para>
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-sid typedef struct _SID { BYTE Revision; BYTE
// SubAuthorityCount; SID_IDENTIFIER_AUTHORITY IdentifierAuthority; #if ... DWORD *SubAuthority[]; #else DWORD
// SubAuthority[ANYSIZE_ARRAY]; #endif } SID, *PISID;
[PInvokeData("winnt.h", MSDNShortId = "NS:winnt._SID")]
[VanaraMarshaler(typeof(AnySizeStringMarshaler<SID>), nameof(SubAuthorityCount))]
[StructLayout(LayoutKind.Sequential)]
public struct SID
{
/// <summary />
public byte Revision;
/// <summary />
public byte SubAuthorityCount;
/// <summary />
public SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
/// <summary />
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public uint[] SubAuthority;
}
/// <summary>
/// The SID_AND_ATTRIBUTES structure represents a security identifier (SID) and its attributes. SIDs are used to uniquely identify
/// users or groups.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct SID_AND_ATTRIBUTES
{
/// <summary>A pointer to a SID structure.</summary>
public PSID Sid;
/// <summary>
/// Specifies attributes of the SID. This value contains up to 32 one-bit flags. Its meaning depends on the definition and use of
/// the SID.
/// </summary>
public uint Attributes;
/// <summary>Initializes a new instance of the <see cref="SID_AND_ATTRIBUTES"/> struct.</summary>
/// <param name="sid">The SID.</param>
/// <param name="attributes">The attributes of the SID.</param>
public SID_AND_ATTRIBUTES(PSID sid, uint attributes)
{
Sid = sid;
Attributes = attributes;
}
/// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary>
/// <returns>A <see cref="System.String"/> that represents this instance.</returns>
public override string ToString() => $"{(Sid.IsValidSid() ? Sid.ToString("N") : "")}:{Attributes}";
}
/// <summary>The SID_IDENTIFIER_AUTHORITY structure represents the top-level authority of a security identifier (SID).</summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
[PInvokeData("Winnt.h", MSDNShortId = "aa379598")]
public struct SID_IDENTIFIER_AUTHORITY
{
/// <summary>An array of 6 bytes specifying a SID's top-level authority.</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] Value;
}
/// <summary>
/// <para>Not supported.</para>
/// <para>The <c>SYSTEM_ALARM_ACE</c> structure is reserved for future use.</para>
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-system_alarm_ace typedef struct _SYSTEM_ALARM_ACE { ACE_HEADER
// Header; ACCESS_MASK Mask; DWORD SidStart; } SYSTEM_ALARM_ACE;
[PInvokeData("winnt.h", MSDNShortId = "491cc5c7-abb6-4d03-b3b0-ba5eedb5e2ba")]
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_ALARM_ACE
{
/// <summary/>
public ACE_HEADER Header;
/// <summary/>
public ACCESS_MASK Mask;
/// <summary/>
public uint SidStart;
}
/// <summary>
/// <para>Not supported.</para>
/// <para>The <c>SYSTEM_ALARM_CALLBACK_ACE</c> structure is reserved for future use.</para>
/// </summary>
/// <remarks>
/// ACE structures must be aligned on <c>DWORD</c> boundaries. All Windows memory-management functions return <c>DWORD</c>-aligned
/// handles to memory.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-system_alarm_callback_ace typedef struct
// _SYSTEM_ALARM_CALLBACK_ACE { ACE_HEADER Header; ACCESS_MASK Mask; DWORD SidStart; } SYSTEM_ALARM_CALLBACK_ACE, *PSYSTEM_ALARM_CALLBACK_ACE;
[PInvokeData("winnt.h", MSDNShortId = "8bfb579f-4bee-454e-827b-63a800bccf85")]
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_ALARM_CALLBACK_ACE
{
/// <summary>
/// ACE_HEADER structure that specifies the size and type of ACE. It also contains flags that control inheritance of the ACE by
/// child objects. The <c>AceType</c> member of the <c>ACE_HEADER</c> structure should be set to SYSTEM_ALARM_CALLBACK_ACE_TYPE.
/// </summary>
public ACE_HEADER Header;
/// <summary>
/// Specifies an ACCESS_MASK structure that gives the access rights that cause audit messages to be generated. The
/// SUCCESSFUL_ACCESS_ACE_FLAG and FAILED_ACCESS_ACE_FLAG flags in the <c>AceFlags</c> member of the ACE_HEADER structure
/// indicate whether messages are generated for successful access attempts, unsuccessful access attempts, or both.
/// </summary>
public ACCESS_MASK Mask;
/// <summary>
/// The first <c>DWORD</c> of a trustee's ACE. This ACE can be appended with application data. When the AuthzAccessCheckCallback
/// function is called, this ACE is passed as the pAce parameter of that function.
/// </summary>
public uint SidStart;
}
/// <summary>
/// <para>Not supported.</para>
/// <para>The <c>SYSTEM_ALARM_CALLBACK_OBJECT_ACE</c> structure is reserved for future use.</para>
/// </summary>
/// <remarks>
/// <para>
/// If neither the <c>ObjectType</c> nor <c>InheritedObjectType</c> GUID is specified, the <c>SYSTEM_ALARM_CALLBACK_OBJECT_ACE</c>
/// structure has the same semantics as the SYSTEM_ALARM_CALLBACK_ACE structure. In that case, use the
/// <c>SYSTEM_ALARM_CALLBACK_ACE</c> structure because it is smaller and more efficient.
/// </para>
/// <para>
/// An ACL that contains an <c>SYSTEM_ALARM_CALLBACK_OBJECT_ACE</c> must specify the ACL_REVISION_DS revision number in its
/// ACE_HEADER structure.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-system_alarm_callback_object_ace typedef struct
// _SYSTEM_ALARM_CALLBACK_OBJECT_ACE { ACE_HEADER Header; ACCESS_MASK Mask; DWORD Flags; GUID ObjectType; GUID InheritedObjectType;
// DWORD SidStart; } SYSTEM_ALARM_CALLBACK_OBJECT_ACE, *PSYSTEM_ALARM_CALLBACK_OBJECT_ACE;
[PInvokeData("winnt.h", MSDNShortId = "3fdd0b75-666a-4064-95ed-9e708f34bed6")]
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_ALARM_CALLBACK_OBJECT_ACE
{
/// <summary>
/// ACE_HEADER structure that specifies the size and type of ACE. It contains flags that control inheritance of the ACE by child
/// objects. The structure also contains flags that indicate whether the ACE audits successful access attempts, failed access
/// attempts, or both. The <c>AceType</c> member of the <c>ACE_HEADER</c> structure should be set to SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE.
/// </summary>
public ACE_HEADER Header;
/// <summary>An ACCESS_MASK that specifies the access rights the system will audit for access attempts by the trustee.</summary>
public ACCESS_MASK Mask;
/// <summary>
/// <para>
/// A set of bit flags that indicate whether the <c>ObjectType</c> and <c>InheritedObjectType</c> members contain GUIDs. This
/// parameter can be a combination of the following values. Set all undefined bits to zero.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ACE_OBJECT_TYPE_PRESENT</term>
/// <term>The ObjectType member contains a GUID.</term>
/// </item>
/// <item>
/// <term>ACE_INHERITED_OBJECT_TYPE_PRESENT</term>
/// <term>The InheritedObjectType member contains a GUID.</term>
/// </item>
/// </list>
/// </summary>
public ObjectAceFlags Flags;
/// <summary>
/// <para>A GUID structure that identifies a property set, property, extended right, or type of child object.</para>
/// <para>
/// This member is valid only if the ACE_OBJECT_TYPE_PRESENT bit is set in the <c>Flags</c> member. Otherwise, <c>ObjectType</c>
/// is ignored.
/// </para>
/// <para>The purpose of this GUID depends on the access rights specified in the <c>Mask</c> member.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ADS_RIGHT_DS_READ_PROP and/or ADS_RIGHT_DS_WRITE_PROP</term>
/// <term>
/// The ObjectType GUID identifies a property set or property of the object. The ACE controls auditing of the trustee's attempts
/// to read or write the property or property set.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_CONTROL_ACCESS</term>
/// <term>The ObjectType GUID identifies an extended access right.</term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_CREATE_CHILD</term>
/// <term>
/// The ObjectType GUID identifies a type of child object. The ACE controls auditing of the trustee's attempts to create this
/// type of child object.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_SELF</term>
/// <term>The ObjectType GUID identifies a validated write.</term>
/// </item>
/// </list>
/// </summary>
public Guid ObjectType;
/// <summary>
/// <para>A GUID structure that identifies the type of child object that can inherit the ACE.</para>
/// <para>
/// This member is valid only if the ACE_INHERITED_OBJECT_TYPE_PRESENT bit is set in the <c>Flags</c> member. If that bit is not
/// set, <c>InheritedObjectType</c> is ignored and all types of child objects can inherit the ACE. In either case, inheritance is
/// also controlled by the inheritance flags in the ACE_HEADER, as well as by any protection against inheritance placed on the
/// child objects.
/// </para>
/// </summary>
public Guid InheritedObjectType;
/// <summary>
/// The first <c>DWORD</c> of a trustee's ACE. This ACE can be appended with application data. When the AuthzAccessCheckCallback
/// function is called, this ACE is passed as the pAce parameter of that function.
/// </summary>
public uint SidStart;
}
/// <summary>The <c>SYSTEM_ALARM_OBJECT_ACE</c> structure is reserved for future use.</summary>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-system_alarm_object_ace typedef struct _SYSTEM_ALARM_OBJECT_ACE
// { ACE_HEADER Header; ACCESS_MASK Mask; DWORD Flags; GUID ObjectType; GUID InheritedObjectType; DWORD SidStart; }
// SYSTEM_ALARM_OBJECT_ACE, *PSYSTEM_ALARM_OBJECT_ACE;
[PInvokeData("winnt.h", MSDNShortId = "a55f6039-d1d2-4a7d-a6c9-e8f51b291582")]
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_ALARM_OBJECT_ACE
{
/// <summary/>
public ACE_HEADER Header;
/// <summary/>
public ACCESS_MASK Mask;
/// <summary/>
public ObjectAceFlags Flags;
/// <summary/>
public Guid ObjectType;
/// <summary/>
public Guid InheritedObjectType;
/// <summary/>
public uint SidStart;
}
/// <summary>
/// The <c>SYSTEM_AUDIT_ACE</c> structure defines an access control entry (ACE) for the system access control list (SACL) that
/// specifies what types of access cause system-level notifications. A system-audit ACE causes an audit message to be logged when a
/// specified trustee attempts to gain access to an object. The trustee is identified by a security identifier (SID).
/// </summary>
/// <remarks>
/// <para>
/// Audit messages are stored in an event log that can be manipulated by using the Windows API event-logging functions or by using
/// the Event Viewer (Eventvwr.exe).
/// </para>
/// <para>
/// ACE structures should be aligned on <c>DWORD</c> boundaries. All Windows memory-management functions return <c>DWORD</c>-aligned
/// handles to memory.
/// </para>
/// <para>
/// When a <c>SYSTEM_AUDIT_ACE</c> structure is created, sufficient memory must be allocated to accommodate the complete SID of the
/// trustee in the <c>SidStart</c> member and the contiguous memory that follows it.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-system_audit_ace typedef struct _SYSTEM_AUDIT_ACE { ACE_HEADER
// Header; ACCESS_MASK Mask; DWORD SidStart; } SYSTEM_AUDIT_ACE;
[PInvokeData("winnt.h", MSDNShortId = "c26b5856-5447-4606-8110-f24a4d235c64")]
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_AUDIT_ACE
{
/// <summary>
/// ACE_HEADER structure that specifies the size and type of ACE. It also contains flags that control inheritance of the ACE by
/// child objects. The <c>AceType</c> member of the <c>ACE_HEADER</c> structure should be set to SYSTEM_AUDIT_ACE_TYPE, and the
/// <c>AceSize</c> member should be set to the total number of bytes allocated for the <c>SYSTEM_AUDIT_ACE</c> structure.
/// </summary>
public ACE_HEADER Header;
/// <summary>
/// Specifies an ACCESS_MASK structure that gives the access rights that cause audit messages to be generated. The
/// SUCCESSFUL_ACCESS_ACE_FLAG and FAILED_ACCESS_ACE_FLAG flags in the <c>AceFlags</c> member of the ACE_HEADER structure
/// indicate whether messages are generated for successful access attempts, unsuccessful access attempts, or both.
/// </summary>
public ACCESS_MASK Mask;
/// <summary>
/// <para>
/// The first <c>DWORD</c> of a trustee's SID. The remaining bytes of the SID are stored in contiguous memory after the
/// <c>SidStart</c> member. This SID can be appended with application data.
/// </para>
/// <para>
/// An access attempt of a kind specified by the <c>Mask</c> member by any trustee whose SID matches the <c>SidStart</c> member
/// causes the system to generate an audit message. If an application does not specify a SID for this member, audit messages are
/// generated for the specified access rights for all trustees.
/// </para>
/// </summary>
public uint SidStart;
}
/// <summary>
/// <para>
/// The <c>SYSTEM_AUDIT_CALLBACK_ACE</c> structure defines an access control entry (ACE) for the system access control list (SACL)
/// that specifies what types of access cause system-level notifications. A system-audit ACE causes an audit message to be logged
/// when a specified trustee attempts to gain access to an object. The trustee is identified by a security identifier (SID).
/// </para>
/// <para>
/// When the AuthzAccessCheck function is called, each <c>SYSTEM_AUDIT_CALLBACK_ACE</c> structure contained in the DACL of a
/// SECURITY_DESCRIPTOR structure passed through a pointer to the <c>AuthzAccessCheck</c> function invokes a call to the
/// application-defined AuthzAccessCheckCallback function, in which a pointer to the <c>SYSTEM_AUDIT_CALLBACK_ACE</c> structure found
/// is passed in the pAce parameter.
/// </para>
/// </summary>
/// <remarks>
/// <para>
/// ACE structures must be aligned on <c>DWORD</c> boundaries. All Windows memory-management functions return <c>DWORD</c>-aligned
/// handles to memory.
/// </para>
/// <para>
/// When a <c>SYSTEM_AUDIT_CALLBACK_ACE</c> structure is created, sufficient memory must be allocated to accommodate the complete SID
/// of the trustee in the <c>SidStart</c> member and the contiguous memory that follows it.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-system_audit_callback_ace typedef struct
// _SYSTEM_AUDIT_CALLBACK_ACE { ACE_HEADER Header; ACCESS_MASK Mask; DWORD SidStart; } SYSTEM_AUDIT_CALLBACK_ACE, *PSYSTEM_AUDIT_CALLBACK_ACE;
[PInvokeData("winnt.h", MSDNShortId = "4d1799b0-3e55-48d7-94ff-c0094945adea")]
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_AUDIT_CALLBACK_ACE
{
/// <summary>
/// ACE_HEADER structure that specifies the size and type of ACE. It also contains flags that control inheritance of the ACE by
/// child objects. The <c>AceType</c> member of the <c>ACE_HEADER</c> structure should be set to SYSTEM_AUDIT_CALLBACK_ACE_TYPE,
/// and the <c>AceSize</c> member should be set to the total number of bytes allocated for the <c>SYSTEM_AUDIT_CALLBACK_ACE</c> structure.
/// </summary>
public ACE_HEADER Header;
/// <summary>
/// Specifies an ACCESS_MASK structure that gives the access rights that cause audit messages to be generated. The
/// SUCCESSFUL_ACCESS_ACE_FLAG and FAILED_ACCESS_ACE_FLAG flags in the <c>AceFlags</c> member of the ACE_HEADER structure
/// indicate whether messages are generated for successful access attempts, unsuccessful access attempts, or both.
/// </summary>
public ACCESS_MASK Mask;
/// <summary>
/// The first <c>DWORD</c> of a trustee's SID. The remaining bytes of the SID are stored in contiguous memory after the
/// <c>SidStart</c> member. This SID can be appended with application data.
/// </summary>
public uint SidStart;
}
/// <summary>
/// <para>
/// The <c>SYSTEM_AUDIT_CALLBACK_OBJECT_ACE</c> structure defines an access control entry (ACE) for a system access control list
/// (SACL). The ACE can audit access to an object or subobjects such as property sets or properties. The ACE contains a set of access
/// rights, a GUID that identifies the type of object or subobject, and a security identifier (SID) that identifies the trustee for
/// whom the system will audit access. The ACE also contains a GUID and a set of flags that control inheritance of the ACE by child objects.
/// </para>
/// <para>
/// When the AuthzAccessCheck function is called, each <c>SYSTEM_AUDIT_CALLBACK_OBJECT_ACE</c> structure contained in the DACL of a
/// SECURITY_DESCRIPTOR structure passed through a pointer to the <c>AuthzAccessCheck</c> function invokes a call to the
/// application-defined AuthzAccessCheckCallback function, in which a pointer to the <c>SYSTEM_AUDIT_CALLBACK_OBJECT_ACE</c>
/// structure found is passed in the pAce parameter.
/// </para>
/// </summary>
/// <remarks>
/// <para>
/// If neither the <c>ObjectType</c> nor <c>InheritedObjectType</c> GUID is specified, the <c>SYSTEM_AUDIT_CALLBACK_OBJECT_ACE</c>
/// structure has the same semantics as the SYSTEM_AUDIT_CALLBACK_ACE structure. In that case, use the
/// <c>SYSTEM_AUDIT_CALLBACK_ACE</c> structure because it is smaller and more efficient.
/// </para>
/// <para>
/// An ACL that contains a <c>SYSTEM_AUDIT_CALLBACK_OBJECT_ACE</c> structure must specify the ACL_REVISION_DS revision number in its
/// ACE_HEADER structure.
/// </para>
/// <para>
/// When a <c>SYSTEM_AUDIT_CALLBACK_OBJECT_ACE</c> structure is created, sufficient memory must be allocated to accommodate the GUID
/// structures in <c>ObjectType</c> and <c>InheritedObjectType</c> members, if one or both of them exists, as well as to accommodate
/// the complete SID of the trustee in the <c>SidStart</c> member and the contiguous memory that follows it.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-system_audit_callback_object_ace typedef struct
// _SYSTEM_AUDIT_CALLBACK_OBJECT_ACE { ACE_HEADER Header; ACCESS_MASK Mask; DWORD Flags; GUID ObjectType; GUID InheritedObjectType;
// DWORD SidStart; } SYSTEM_AUDIT_CALLBACK_OBJECT_ACE, *PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE;
[PInvokeData("winnt.h", MSDNShortId = "f547c928-4850-4072-be05-76a6c83b79bb")]
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_AUDIT_CALLBACK_OBJECT_ACE
{
/// <summary>
/// ACE_HEADER structure that specifies the size and type of ACE. It contains flags that control inheritance of the ACE by child
/// objects. The structure also contains flags that indicate whether the ACE audits successful access attempts, failed access
/// attempts, or both. The <c>AceType</c> member of the <c>ACE_HEADER</c> structure should be set to
/// SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE, and the <c>AceSize</c> member should be set to the total number of bytes allocated for
/// the <c>SYSTEM_AUDIT_CALLBACK_OBJECT_ACE</c> structure.
/// </summary>
public ACE_HEADER Header;
/// <summary>An ACCESS_MASK that specifies the access rights the system will audit for access attempts by the trustee.</summary>
public ACCESS_MASK Mask;
/// <summary>
/// <para>
/// A set of bit flags that indicate whether the <c>ObjectType</c> and <c>InheritedObjectType</c> members contain GUIDs. This
/// member can be a combination of the following values. Set all undefined bits to zero.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ACE_OBJECT_TYPE_PRESENT</term>
/// <term>The ObjectType member contains a GUID.</term>
/// </item>
/// <item>
/// <term>ACE_INHERITED_OBJECT_TYPE_PRESENT</term>
/// <term>The InheritedObjectType member contains a GUID.</term>
/// </item>
/// </list>
/// </summary>
public ObjectAceFlags Flags;
/// <summary>
/// <para>A GUID structure that identifies a property set, property, extended right, or type of child object.</para>
/// <para>
/// This member is valid only if the ACE_OBJECT_TYPE_PRESENT bit is set in the <c>Flags</c> member. Otherwise, <c>ObjectType</c>
/// is ignored.
/// </para>
/// <para>The purpose of this GUID depends on the access rights specified in the <c>Mask</c> member.</para>
/// <para>This member can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ADS_RIGHT_DS_READ_PROP and/or ADS_RIGHT_DS_WRITE_PROP</term>
/// <term>
/// The ObjectType GUID identifies a property set or property of the object. The ACE controls auditing of the trustee's attempts
/// to read or write the property or property set.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_CONTROL_ACCESS</term>
/// <term>The ObjectType GUID identifies an extended access right.</term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_CREATE_CHILD</term>
/// <term>
/// The ObjectType GUID identifies a type of child object. The ACE controls auditing of the trustee's attempts to create this
/// type of child object.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_SELF</term>
/// <term>The ObjectType GUID identifies a validated write.</term>
/// </item>
/// </list>
/// </summary>
public Guid ObjectType;
/// <summary>
/// <para>A GUID structure that identifies the type of child object that can inherit the ACE.</para>
/// <para>
/// This member is valid only if the ACE_INHERITED_OBJECT_TYPE_PRESENT bit is set in the <c>Flags</c> member. If that bit is not
/// set, <c>InheritedObjectType</c> is ignored and all types of child objects can inherit the ACE. In either case, inheritance is
/// also controlled by the inheritance flags in the ACE_HEADER, as well as by any protection against inheritance placed on the
/// child objects.
/// </para>
/// </summary>
public Guid InheritedObjectType;
/// <summary>
/// The first <c>DWORD</c> of a trustee's SID. The remaining bytes of the SID are stored in contiguous memory after the
/// <c>SidStart</c> member. This SID can be appended with application data.
/// </summary>
public uint SidStart;
}
/// <summary>
/// The <c>SYSTEM_AUDIT_OBJECT_ACE</c> structure defines an access control entry (ACE) for a system access control list (SACL). The
/// ACE can audit access to an object or subobjects such as property sets or properties. The ACE contains a set of access rights, a
/// GUID that identifies the type of object or subobject, and a security identifier (SID) that identifies the trustee for whom the
/// system will audit access. The ACE also contains a GUID and a set of flags that control inheritance of the ACE by child objects.
/// </summary>
/// <remarks>
/// <para>
/// If neither the <c>ObjectType</c> nor <c>InheritedObjectType</c> GUID is specified, the <c>SYSTEM_AUDIT_OBJECT_ACE</c> structure
/// has the same semantics as the SYSTEM_AUDIT_ACE structure. In that case, use the <c>SYSTEM_AUDIT_ACE</c> structure because it is
/// smaller and more efficient.
/// </para>
/// <para>
/// An ACL that contains an <c>SYSTEM_AUDIT_OBJECT_ACE</c> must specify the ACL_REVISION_DS revision number in its ACE_HEADER structure.
/// </para>
/// <para>
/// When a <c>SYSTEM_AUDIT_OBJECT_ACE</c> structure is created, sufficient memory must be allocated to accommodate the GUID
/// structures in <c>ObjectType</c> and <c>InheritedObjectType</c> members, if one or both of them exists, as well as to accommodate
/// the complete SID of the trustee in the <c>SidStart</c> member and the contiguous memory that follows it.
/// </para>
/// <para>
/// An <c>SYSTEM_AUDIT_OBJECT_ACE</c> structure can be created in an access control list (ACL) by a call to the
/// AddAuditAccessObjectAce function. When this function is used, the correct amount of memory needed to accommodate the GUID
/// structures in the <c>ObjectType</c> and <c>InheritedObjectType</c> members, if one or both of them exists, as well as to
/// accommodate the trustee's SID is automatically allocated. In addition, the values of the <c>Header.AceType</c> and
/// <c>Header.AceSize</c> members are set automatically. When an <c>SYSTEM_AUDIT_OBJECT_ACE</c> structure is created outside an ACL,
/// sufficient memory must be allocated to accommodate the GUID structures in the <c>ObjectType</c> and <c>InheritedObjectType</c>
/// members, if one or both of them exists, as well as to accommodate the complete SID of the trustee in the <c>SidStart</c> member
/// and the contiguous memory following it. In addition, the values of the <c>Header.AceType</c> and <c>Header.AceSize</c> members
/// must be set explicitly by the application.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-system_audit_object_ace typedef struct _SYSTEM_AUDIT_OBJECT_ACE
// { ACE_HEADER Header; ACCESS_MASK Mask; DWORD Flags; GUID ObjectType; GUID InheritedObjectType; DWORD SidStart; }
// SYSTEM_AUDIT_OBJECT_ACE, *PSYSTEM_AUDIT_OBJECT_ACE;
[PInvokeData("winnt.h", MSDNShortId = "de37bef6-e6c8-4455-856a-adebebda4cc7")]
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_AUDIT_OBJECT_ACE
{
/// <summary>
/// An ACE_HEADER structure that specifies the size and type of ACE. It contains flags that control inheritance of the ACE by
/// child objects. The structure also contains flags that indicate whether the ACE audits successful access attempts, failed
/// access attempts, or both. The <c>AceType</c> member of the <c>ACE_HEADER</c> structure should be set to
/// SYSTEM_AUDIT_OBJECT_ACE_TYPE, and the <c>AceSize</c> member should be set to the total number of bytes allocated for the
/// <c>SYSTEM_AUDIT_OBJECT_ACE</c> structure.
/// </summary>
public ACE_HEADER Header;
/// <summary>An ACCESS_MASK that specifies the access rights the system will audit for access attempts by the trustee.</summary>
public ACCESS_MASK Mask;
/// <summary>
/// <para>
/// A set of bit flags that indicate whether the <c>ObjectType</c> and <c>InheritedObjectType</c> members contain GUIDs. This
/// member can be a combination of the following values. Set all undefined bits to zero.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ACE_OBJECT_TYPE_PRESENT</term>
/// <term>The ObjectType member contains a GUID.</term>
/// </item>
/// <item>
/// <term>ACE_INHERITED_OBJECT_TYPE_PRESENT</term>
/// <term>The InheritedObjectType member contains a GUID.</term>
/// </item>
/// </list>
/// </summary>
public ObjectAceFlags Flags;
/// <summary>
/// <para>A GUID structure that identifies a property set, property, extended right, or type of child object.</para>
/// <para>
/// This member is valid only if the ACE_OBJECT_TYPE_PRESENT bit is set in the <c>Flags</c> member. Otherwise, <c>ObjectType</c>
/// is ignored.
/// </para>
/// <para>The purpose of this GUID depends on the access rights specified in the <c>Mask</c> member.</para>
/// <para>This member can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ADS_RIGHT_DS_READ_PROP and/or ADS_RIGHT_DS_WRITE_PROP</term>
/// <term>
/// The ObjectType GUID identifies a property set or property of the object. The ACE controls auditing of the trustee's attempts
/// to read or write the property or property set.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_CONTROL_ACCESS</term>
/// <term>The ObjectType GUID identifies an extended access right.</term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_CREATE_CHILD</term>
/// <term>
/// The ObjectType GUID identifies a type of child object. The ACE controls auditing of the trustee's attempts to create this
/// type of child object.
/// </term>
/// </item>
/// <item>
/// <term>ADS_RIGHT_DS_SELF</term>
/// <term>The ObjectType GUID identifies a validated write.</term>
/// </item>
/// </list>
/// </summary>
public Guid ObjectType;
/// <summary>
/// <para>A GUID structure that identifies the type of child object that can inherit the ACE.</para>
/// <para>
/// This member is valid only if the ACE_INHERITED_OBJECT_TYPE_PRESENT bit is set in the <c>Flags</c> member. If that bit is not
/// set, <c>InheritedObjectType</c> is ignored and all types of child objects can inherit the ACE. In either case, inheritance is
/// also controlled by the inheritance flags in the ACE_HEADER, as well as by any protection against inheritance placed on the
/// child objects.
/// </para>
/// <para>
/// The offset of this member can vary. If the <c>Flags</c> member does not contain the ACE_OBJECT_TYPE_PRESENT flag, the
/// <c>InheritedObjectType</c> member starts at the offset specified by the <c>ObjectType</c> member.
/// </para>
/// </summary>
public Guid InheritedObjectType;
/// <summary>
/// <para>
/// Specifies the first <c>DWORD</c> of a SID that identifies the trustee for whom the access attempts are audited. The remaining
/// bytes of the SID are stored in contiguous memory after the <c>SidStart</c> member. This SID can be appended with application data.
/// </para>
/// <para>
/// The offset of this member can vary. If the <c>Flags</c> member is zero, the <c>SidStart</c> member starts at the offset
/// specified by the <c>ObjectType</c> member. If <c>Flags</c> contains only one flag (either ACE_OBJECT_TYPE_PRESENT or
/// ACE_INHERITED_OBJECT_TYPE_PRESENT), the <c>SidStart</c> member starts at the offset specified by the
/// <c>InheritedObjectType</c> member.
/// </para>
/// </summary>
public uint SidStart;
}
/// <summary>
/// The TOKEN_ACCESS_INFORMATION structure specifies all the information in a token that is necessary to perform an access check.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("WinNT.h", MSDNShortId = "bb394726")]
public struct TOKEN_ACCESS_INFORMATION
{
/// <summary>A pointer to a SID_AND_ATTRIBUTES_HASH structure that specifies a hash of the token's security identifier (SID).</summary>
public IntPtr SidHash;
/// <summary>A pointer to a SID_AND_ATTRIBUTES_HASH structure that specifies a hash of the token's restricted SID.</summary>
public IntPtr RestrictedSidHash;
/// <summary>A pointer to a TOKEN_PRIVILEGES structure that specifies information about the token's privileges.</summary>
public IntPtr Privileges;
/// <summary>A LUID structure that specifies the token's identity.</summary>
public LUID AuthenticationId;
/// <summary>A value of the TOKEN_TYPE enumeration that specifies the token's type.</summary>
public TOKEN_TYPE TokenType;
/// <summary>A value of the SECURITY_IMPERSONATION_LEVEL enumeration that specifies the token's impersonation level.</summary>
public SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
/// <summary>A TOKEN_MANDATORY_POLICY structure that specifies the token's mandatory integrity policy.</summary>
public TOKEN_MANDATORY_POLICY MandatoryPolicy;
/// <summary>Reserved. Must be set to zero.</summary>
public uint Flags;
/// <summary>
/// The app container number for the token or zero if this is not an app container token.
/// <para><c>Windows Server 2008 R2, Windows 7, Windows Server 2008 and Windows Vista:</c> This member is not available.</para>
/// </summary>
public uint AppContainerNumber;
/// <summary>
/// The app container SID or NULL if this is not an app container token.
/// <para><c>Windows Server 2008 R2, Windows 7, Windows Server 2008 and Windows Vista:</c> This member is not available.</para>
/// </summary>
public PSID PackageSid;
/// <summary>
/// Pointer to a SID_AND_ATTRIBUTES_HASH structure that specifies a hash of the token's capability SIDs.
/// <para><c>Windows Server 2008 R2, Windows 7, Windows Server 2008 and Windows Vista:</c> This member is not available.</para>
/// </summary>
public IntPtr CapabilitiesHash;
/// <summary>The protected process trust level of the token.</summary>
public PSID TrustLevelSid;
/// <summary>
/// Reserved. Must be set to NULL.
/// <para><c>Prior to Windows 10:</c> This member is not available.</para>
/// </summary>
public IntPtr SecurityAttributes;
}
/// <summary>
/// The TOKEN_APPCONTAINER_INFORMATION structure specifies all the information in a token that is necessary for an app container.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_APPCONTAINER_INFORMATION
{
/// <summary>The security identifier (SID) of the app container.</summary>
public PSID TokenAppContainer;
}
/// <summary>The TOKEN_DEFAULT_DACL structure specifies a discretionary access control list (DACL).</summary>
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("WinNT.h", MSDNShortId = "aa379623")]
public struct TOKEN_DEFAULT_DACL
{
/// <summary>
/// A pointer to an ACL structure assigned by default to any objects created by the user. The user is represented by the access token.
/// </summary>
public PACL DefaultDacl;
}
/// <summary>The TOKEN_ELEVATION structure indicates whether a token has elevated privileges.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_ELEVATION
{
/// <summary>A nonzero value if the token has elevated privileges; otherwise, a zero value.</summary>
[MarshalAs(UnmanagedType.Bool)]
public bool TokenIsElevated;
}
/// <summary>The TOKEN_GROUPS structure contains information about the group security identifiers (SIDs) in an access token.</summary>
[VanaraMarshaler(typeof(SafeAnysizeStructMarshaler<TOKEN_GROUPS>), nameof(GroupCount))]
[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_GROUPS
{
/// <summary>Specifies the number of groups in the access token.</summary>
public uint GroupCount;
/// <summary>Specifies an array of SID_AND_ATTRIBUTES structures that contain a set of SIDs and corresponding attributes.</summary>
[MarshalAs(UnmanagedType.ByValArray)]
public SID_AND_ATTRIBUTES[] Groups;
/// <summary>Initializes a new instance of the <see cref="TOKEN_GROUPS"/> struct.</summary>
/// <param name="count">The number of groups.</param>
public TOKEN_GROUPS(uint count = 0)
{
GroupCount = count;
Groups = new SID_AND_ATTRIBUTES[count];
}
/// <summary>Initializes a new instance of the <see cref="TOKEN_GROUPS"/> struct with and array of SIDs and attributes.</summary>
/// <param name="groups">An array of SID_AND_ATTRIBUTES structures that contain a set of SIDs and corresponding attributes.</param>
public TOKEN_GROUPS(SID_AND_ATTRIBUTES[] groups)
{
Groups = groups;
GroupCount = (uint)(groups?.Length ?? 0);
}
/// <summary>Initializes a new instance of the <see cref="TOKEN_GROUPS"/> struct with a single SID and attribute.</summary>
/// <param name="sid">The SID.</param>
/// <param name="attributes">The attributes of the SID.</param>
public TOKEN_GROUPS(PSID sid, uint attributes = 0) : this(1U)
{
Groups[0] = new SID_AND_ATTRIBUTES(sid, attributes);
}
}
/// <summary>
/// The TOKEN_GROUPS_AND_PRIVILEGES structure contains information about the group security identifiers (SIDs) and privileges in an
/// access token.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("WinNT.h", MSDNShortId = "aa379625")]
public struct TOKEN_GROUPS_AND_PRIVILEGES
{
/// <summary>Number of SIDs in the access token.</summary>
public uint SidCount;
/// <summary>Length, in bytes, required to hold all of the user SIDs and the account SID for the group.</summary>
public uint SidLength;
/// <summary>A pointer to an array of SID_AND_ATTRIBUTES structures that contain a set of SIDs and corresponding attributes.</summary>
public IntPtr Sids;
/// <summary>Number of restricted SIDs.</summary>
public uint RestrictedSidCount;
/// <summary>Length, in bytes, required to hold all of the restricted SIDs.</summary>
public uint RestrictedSidLength;
/// <summary>
/// A pointer to an array of SID_AND_ATTRIBUTES structures that contain a set of restricted SIDs and corresponding attributes.
/// <para>
/// The Attributes members of the SID_AND_ATTRIBUTES structures can have the same values as those listed for the preceding Sids member.
/// </para>
/// </summary>
public IntPtr RestrictedSids;
/// <summary>Number of privileges.</summary>
public uint PrivilegeCount;
/// <summary>Length, in bytes, needed to hold the privilege array.</summary>
public uint PrivilegeLength;
/// <summary>Array of privileges.</summary>
public IntPtr Privileges;
/// <summary>Locally unique identifier (LUID) of the authenticator of the token.</summary>
public LUID AuthenticationId;
}
/// <summary>
/// The TOKEN_LINKED_TOKEN structure contains a handle to a token. This token is linked to the token being queried by the
/// GetTokenInformation function or set by the SetTokenInformation function.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("WinNT.h", MSDNShortId = "bb530719")]
public struct TOKEN_LINKED_TOKEN
{
/// <summary>A handle to the linked token. When you have finished using the handle, close it by calling the CloseHandle function.</summary>
public HTOKEN LinkedToken;
}
/// <summary>The TOKEN_MANDATORY_LABEL structure specifies the mandatory integrity level for a token.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_MANDATORY_LABEL
{
/// <summary>A SID_AND_ATTRIBUTES structure that specifies the mandatory integrity level of the token.</summary>
public SID_AND_ATTRIBUTES Label;
}
/// <summary>The <c>TOKEN_MANDATORY_POLICY</c> structure specifies the mandatory integrity policy for a token.</summary>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-token_mandatory_policy
// typedef struct _TOKEN_MANDATORY_POLICY { DWORD Policy; } TOKEN_MANDATORY_POLICY, *PTOKEN_MANDATORY_POLICY;
[PInvokeData("winnt.h", MSDNShortId = "f5fc438b-c4f0-46f6-a188-52ce660d13da")]
[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_MANDATORY_POLICY
{
/// <summary>
/// <para>The mandatory integrity access policy for the associated token. This can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>TOKEN_MANDATORY_POLICY_OFF 0x0</term>
/// <term>No mandatory integrity policy is enforced for the token.</term>
/// </item>
/// <item>
/// <term>TOKEN_MANDATORY_POLICY_NO_WRITE_UP 0x1</term>
/// <term>A process associated with the token cannot write to objects that have a greater mandatory integrity level.</term>
/// </item>
/// <item>
/// <term>TOKEN_MANDATORY_POLICY_NEW_PROCESS_MIN 0x2</term>
/// <term>A process created with the token has an integrity level that is the lesser of the parent-process integrity level and the executable-file integrity level.</term>
/// </item>
/// <item>
/// <term>TOKEN_MANDATORY_POLICY_VALID_MASK 0x3</term>
/// <term>A combination of TOKEN_MANDATORY_POLICY_NO_WRITE_UP and TOKEN_MANDATORY_POLICY_NEW_PROCESS_MIN.</term>
/// </item>
/// </list>
/// </summary>
public TokenMandatoryPolicy Policy;
}
/// <summary>
/// The TOKEN_ORIGIN structure contains information about the origin of the logon session. This structure is used by the
/// GetTokenInformation function.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("WinNT.h", MSDNShortId = "aa379627")]
public struct TOKEN_ORIGIN
{
/// <summary>
/// Locally unique identifier (LUID) for the logon session. If the token passed to GetTokenInformation resulted from a logon
/// using explicit credentials, such as passing name, domain, and password to the LogonUser function, then this member will
/// contain the ID of the logon session that created it. If the token resulted from network authentication, such as a call to
/// AcceptSecurityContext, or a call to LogonUser with dwLogonType set to LOGON32_LOGON_NETWORK or
/// LOGON32_LOGON_NETWORK_CLEARTEXT, then this member will be zero.
/// </summary>
public LUID OriginatingLogonSession;
}
/// <summary>
/// The TOKEN_OWNER structure contains the default owner security identifier (SID) that will be applied to newly created objects.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("WinNT.h", MSDNShortId = "aa379628")]
public struct TOKEN_OWNER
{
/// <summary>
/// A pointer to a SID structure representing a user who will become the owner of any objects created by a process using this
/// access token. The SID must be one of the user or group SIDs already in the token.
/// </summary>
public PSID Owner;
}
/// <summary>The TOKEN_PRIMARY_GROUP structure specifies a group security identifier (SID) for an access token.</summary>
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("WinNT.h", MSDNShortId = "aa379629")]
public struct TOKEN_PRIMARY_GROUP
{
/// <summary>
/// A pointer to a SID structure representing a group that will become the primary group of any objects created by a process
/// using this access token. The SID must be one of the group SIDs already in the token.
/// </summary>
public PSID PrimaryGroup;
}
/// <summary>The <c>TOKEN_PRIVILEGES</c> structure contains information about a set of privileges for an access token.</summary>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-token_privileges typedef struct _TOKEN_PRIVILEGES { DWORD
// PrivilegeCount; LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]; } TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
[PInvokeData("winnt.h", MSDNShortId = "c9016511-740f-44f3-92ed-17cc518c6612")]
[StructLayout(LayoutKind.Sequential)]
[VanaraMarshaler(typeof(SafeAnysizeStructMarshaler<TOKEN_PRIVILEGES>), nameof(PrivilegeCount))]
public struct TOKEN_PRIVILEGES
{
/// <summary>This must be set to the number of entries in the <c>Privileges</c> array.</summary>
public uint PrivilegeCount;
/// <summary>
/// <para>
/// Specifies an array of LUID_AND_ATTRIBUTES structures. Each structure contains the LUID and attributes of a privilege. To get
/// the name of the privilege associated with a <c>LUID</c>, call the LookupPrivilegeName function, passing the address of the
/// <c>LUID</c> as the value of the lpLuid parameter.
/// </para>
/// <para>
/// <c>Important</c> The constant <c>ANYSIZE_ARRAY</c> is defined as 1 in the public header Winnt.h. To create this array with
/// more than one element, you must allocate sufficient memory for the structure to take into account additional elements.
/// </para>
/// <para>The attributes of a privilege can be a combination of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>SE_PRIVILEGE_ENABLED</term>
/// <term>The privilege is enabled.</term>
/// </item>
/// <item>
/// <term>SE_PRIVILEGE_ENABLED_BY_DEFAULT</term>
/// <term>The privilege is enabled by default.</term>
/// </item>
/// <item>
/// <term>SE_PRIVILEGE_REMOVED</term>
/// <term>Used to remove a privilege. For details, see AdjustTokenPrivileges.</term>
/// </item>
/// <item>
/// <term>SE_PRIVILEGE_USED_FOR_ACCESS</term>
/// <term>
/// The privilege was used to gain access to an object or service. This flag is used to identify the relevant privileges in a set
/// passed by a client application that may contain unnecessary privileges.
/// </term>
/// </item>
/// </list>
/// </summary>
[MarshalAs(UnmanagedType.ByValArray)]
public LUID_AND_ATTRIBUTES[] Privileges;
/// <summary>Initializes a new instance of the <see cref="TOKEN_PRIVILEGES"/> structure with a single LUID_AND_ATTRIBUTES value.</summary>
/// <param name="luid">The LUID value.</param>
/// <param name="attribute">The attribute value.</param>
public TOKEN_PRIVILEGES(LUID luid, PrivilegeAttributes attribute)
{
PrivilegeCount = 1;
Privileges = new[] { new LUID_AND_ATTRIBUTES(luid, attribute) };
}
/// <summary>Initializes a new instance of the <see cref="TOKEN_PRIVILEGES"/> structure from a list of privileges.</summary>
/// <param name="values">The values.</param>
public TOKEN_PRIVILEGES(LUID_AND_ATTRIBUTES[] values)
{
PrivilegeCount = (uint)(values?.Length ?? 0);
Privileges = (LUID_AND_ATTRIBUTES[])values?.Clone() ?? new LUID_AND_ATTRIBUTES[0];
}
}
/// <summary>The TOKEN_SOURCE structure identifies the source of an access token.</summary>
[StructLayout(LayoutKind.Sequential)]
[PInvokeData("WinNT.h", MSDNShortId = "aa379631")]
public struct TOKEN_SOURCE
{
private const int TOKEN_SOURCE_LENGTH = 8;
/// <summary>
/// Specifies an 8-byte character string used to identify the source of an access token. This is used to distinguish between such
/// sources as Session Manager, LAN Manager, and RPC Server. A string, rather than a constant, is used to identify the source so
/// users and developers can make extensions to the system, such as by adding other networks, that act as the source of access tokens.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = TOKEN_SOURCE_LENGTH)]
public char[] SourceName;
/// <summary>
/// Specifies a locally unique identifier (LUID) provided by the source component named by the SourceName member. This value aids
/// the source component in relating context blocks, such as session-control structures, to the token. This value is typically,
/// but not necessarily, an LUID.
/// </summary>
public LUID SourceIdentifier;
}
/// <summary>
/// The TOKEN_STATISTICS structure contains information about an access token. An application can retrieve this information by
/// calling the GetTokenInformation function.
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
[PInvokeData("WinNT.h", MSDNShortId = "aa379632")]
public struct TOKEN_STATISTICS
{
/// <summary>Specifies a locally unique identifier (LUID) that identifies this instance of the token object.</summary>
public LUID TokenId;
/// <summary>
/// Specifies an LUID assigned to the session this token represents. There can be many tokens representing a single logon session.
/// </summary>
public LUID AuthenticationId;
/// <summary>Specifies the time at which this token expires. Expiration times for access tokens are not currently supported.</summary>
public long ExpirationTime;
/// <summary>Specifies a TOKEN_TYPE enumeration type indicating whether the token is a primary or impersonation token.</summary>
public TOKEN_TYPE TokenType;
/// <summary>
/// Specifies a SECURITY_IMPERSONATION_LEVEL enumeration type indicating the impersonation level of the token. This member is
/// valid only if the TokenType is TokenImpersonation.
/// </summary>
public SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
/// <summary>Specifies the amount, in bytes, of memory allocated for storing default protection and a primary group identifier.</summary>
public uint DynamicCharged;
/// <summary>
/// Specifies the portion of memory allocated for storing default protection and a primary group identifier not already in use.
/// This value is returned as a count of free bytes.
/// </summary>
public uint DynamicAvailable;
/// <summary>Specifies the number of supplemental group security identifiers (SIDs) included in the token.</summary>
public uint GroupCount;
/// <summary>Specifies the number of privileges included in the token.</summary>
public uint PrivilegeCount;
/// <summary>
/// Specifies an LUID that changes each time the token is modified. An application can use this value as a test of whether a
/// security context has changed since it was last used.
/// </summary>
public LUID ModifiedId;
}
/// <summary>The TOKEN_USER structure identifies the user associated with an access token.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_USER
{
/// <summary>
/// Specifies a SID_AND_ATTRIBUTES structure representing the user associated with the access token. There are currently no
/// attributes defined for user security identifiers (SIDs).
/// </summary>
public SID_AND_ATTRIBUTES User;
}
/// <summary>Known SID authorities.</summary>
public static class KnownSIDAuthority
{
/// <summary>The application package authority</summary>
public static readonly PSID_IDENTIFIER_AUTHORITY SECURITY_APP_PACKAGE_AUTHORITY = new byte[] { 0, 0, 0, 0, 0, 15 };
/// <summary>The authentication authority</summary>
public static readonly PSID_IDENTIFIER_AUTHORITY SECURITY_AUTHENTICATION_AUTHORITY = new byte[] { 0, 0, 0, 0, 0, 18 };
/// <summary>The identifier authority for the creator owner.</summary>
public static readonly PSID_IDENTIFIER_AUTHORITY SECURITY_CREATOR_SID_AUTHORITY = new byte[] { 0, 0, 0, 0, 0, 3 };
/// <summary>The identifier authority for locally connected users.</summary>
public static readonly PSID_IDENTIFIER_AUTHORITY SECURITY_LOCAL_SID_AUTHORITY = new byte[] { 0, 0, 0, 0, 0, 2 };
/// <summary>The mandatory label authority</summary>
public static readonly PSID_IDENTIFIER_AUTHORITY SECURITY_MANDATORY_LABEL_AUTHORITY = new byte[] { 0, 0, 0, 0, 0, 16 };
/// <summary>The non-unique identifier authority.</summary>
public static readonly PSID_IDENTIFIER_AUTHORITY SECURITY_NON_UNIQUE_AUTHORITY = new byte[] { 0, 0, 0, 0, 0, 4 };
/// <summary>The Windows security authority</summary>
public static readonly PSID_IDENTIFIER_AUTHORITY SECURITY_NT_AUTHORITY = new byte[] { 0, 0, 0, 0, 0, 5 };
/// <summary>The identifier authority with no members.</summary>
public static readonly PSID_IDENTIFIER_AUTHORITY SECURITY_NULL_SID_AUTHORITY = new byte[] { 0, 0, 0, 0, 0, 0 };
/// <summary>The process trust authority</summary>
public static readonly PSID_IDENTIFIER_AUTHORITY SECURITY_PROCESS_TRUST_AUTHORITY = new byte[] { 0, 0, 0, 0, 0, 19 };
/// <summary>The security resource manager authority</summary>
public static readonly PSID_IDENTIFIER_AUTHORITY SECURITY_RESOURCE_MANAGER_AUTHORITY = new byte[] { 0, 0, 0, 0, 0, 9 };
/// <summary>The scoped policy identifier authority</summary>
public static readonly PSID_IDENTIFIER_AUTHORITY SECURITY_SCOPED_POLICY_ID_AUTHORITY = new byte[] { 0, 0, 0, 0, 0, 17 };
/// <summary>The identifier authority all users.</summary>
public static readonly PSID_IDENTIFIER_AUTHORITY SECURITY_WORLD_SID_AUTHORITY = new byte[] { 0, 0, 0, 0, 0, 1 };
}
/// <summary>Known RIDs</summary>
public static class KnownSIDRelativeID
{
/// <summary/>
public const int SECURITY_APP_PACKAGE_BASE_RID = 0x00000002;
/// <summary/>
public const int SECURITY_CAPABILITY_APP_RID = 0x00000040;
/// <summary/>
public const int SECURITY_CAPABILITY_BASE_RID = 0x00000003;
/// <summary>The security creator group rid</summary>
public const int SECURITY_CREATOR_GROUP_RID = 0x00000001;
/// <summary>The security creator group server rid</summary>
public const int SECURITY_CREATOR_GROUP_SERVER_RID = 0x00000003;
/// <summary>The security creator owner rid</summary>
public const int SECURITY_CREATOR_OWNER_RID = 0x00000000;
/// <summary>The security creator owner rights rid</summary>
public const int SECURITY_CREATOR_OWNER_RIGHTS_RID = 0x00000004;
/// <summary>The security creator owner server rid</summary>
public const int SECURITY_CREATOR_OWNER_SERVER_RID = 0x00000002;
/// <summary>The security local logon rid</summary>
public const int SECURITY_LOCAL_LOGON_RID = 0x00000001;
/// <summary>The security local rid</summary>
public const int SECURITY_LOCAL_RID = 0x00000000;
/// <summary>High integrity.</summary>
public const int SECURITY_MANDATORY_HIGH_RID = 0x00003000;
/// <summary>Low integrity.</summary>
public const int SECURITY_MANDATORY_LOW_RID = 0x00001000;
/// <summary>Medium-high integrity.</summary>
public const int SECURITY_MANDATORY_MEDIUM_PLUS_RID = SECURITY_MANDATORY_MEDIUM_RID + 0x100;
/// <summary>Medium integrity.</summary>
public const int SECURITY_MANDATORY_MEDIUM_RID = 0x00002000;
/// <summary>Protected process.</summary>
public const int SECURITY_MANDATORY_PROTECTED_PROCESS_RID = 0x00005000;
/// <summary>System integrity.</summary>
public const int SECURITY_MANDATORY_SYSTEM_RID = 0x00004000;
/// <summary>Untrusted.</summary>
public const int SECURITY_MANDATORY_UNTRUSTED_RID = 0x00000000;
/// <summary>The security null rid</summary>
public const int SECURITY_NULL_RID = 0x00000000;
/// <summary>The security world rid</summary>
public const int SECURITY_WORLD_RID = 0x00000000;
}
/// <summary>
/// The PRIVILEGE_SET structure specifies a set of privileges. It is also used to indicate which, if any, privileges are held by a
/// user or group requesting access to an object.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public class PRIVILEGE_SET
{
/// <summary>Specifies the number of privileges in the privilege set.</summary>
public uint PrivilegeCount;
/// <summary>
/// Specifies a control flag related to the privileges. The PRIVILEGE_SET_ALL_NECESSARY control flag is currently defined. It
/// indicates that all of the specified privileges must be held by the process requesting access. If this flag is not set, the
/// presence of any privileges in the user's access token grants the access.
/// </summary>
public PrivilegeSetControl Control;
/// <summary>Specifies an array of LUID_AND_ATTRIBUTES structures describing the set's privileges.</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public LUID_AND_ATTRIBUTES[] Privilege;
/// <summary>Initializes a new instance of the <see cref="PRIVILEGE_SET"/> class with a single LUID_AND_ATTRIBUTES value.</summary>
/// <param name="control">The control flag. See <see cref="Control"/>.</param>
/// <param name="luid">The LUID value.</param>
/// <param name="attribute">The attribute value.</param>
public PRIVILEGE_SET(PrivilegeSetControl control, LUID luid, PrivilegeAttributes attribute)
{
PrivilegeCount = 1;
Control = control;
Privilege = new[] { new LUID_AND_ATTRIBUTES(luid, attribute) };
}
/// <summary>Initializes a new instance of the <see cref="PRIVILEGE_SET"/> class.</summary>
/// <param name="control">The control flag. See <see cref="Control"/>.</param>
/// <param name="privileges">A list of privileges to assign to the structure.</param>
public PRIVILEGE_SET(PrivilegeSetControl control, LUID_AND_ATTRIBUTES[] privileges)
{
PrivilegeCount = (uint)(privileges?.Length ?? 0);
Control = control;
Privilege = (LUID_AND_ATTRIBUTES[])privileges?.Clone() ?? new LUID_AND_ATTRIBUTES[0];
}
/// <summary>Initializes a new instance of the <see cref="PRIVILEGE_SET"/> class.</summary>
internal PRIVILEGE_SET() : this(PrivilegeSetControl.PRIVILEGE_SET_ALL_NECESSARY, null)
{
}
/// <summary>Initializes a new instance of the <see cref="PRIVILEGE_SET"/> class from a pointer to allocated memory.</summary>
internal PRIVILEGE_SET(IntPtr ptr)
{
if (ptr == IntPtr.Zero) return;
var sz = Marshal.SizeOf(typeof(uint));
PrivilegeCount = (uint)Marshal.ReadInt32(ptr);
Control = (PrivilegeSetControl)Marshal.ReadInt32(ptr, sz);
Privilege = PrivilegeCount > 0 ? ptr.ToArray<LUID_AND_ATTRIBUTES>((int)PrivilegeCount, sz * 2) : new LUID_AND_ATTRIBUTES[0];
}
/// <summary>Gets the size in bytes of this instance.</summary>
/// <value>The size in bytes.</value>
public uint SizeInBytes => (uint)Marshal.SizeOf(typeof(uint)) * 2 + (uint)(Marshal.SizeOf(typeof(LUID_AND_ATTRIBUTES)) * (PrivilegeCount == 0 ? 1 : PrivilegeCount));
/// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary>
/// <returns>A <see cref="System.String"/> that represents this instance.</returns>
public override string ToString() => $"Count:{PrivilegeCount}";
/// <summary>Initializes a new <c>PRIVILEGE_SET</c> the with capacity to hold the specified number of privileges.</summary>
/// <param name="privilegeCount">The privilege count to allocate.</param>
/// <returns>A <c>PRIVILEGE_SET</c> instance with sufficient capacity for marshaling.</returns>
public static PRIVILEGE_SET InitializeWithCapacity(int privilegeCount = 1) => new PRIVILEGE_SET() { PrivilegeCount = (uint)privilegeCount };
internal class Marshaler : ICustomMarshaler
{
public static ICustomMarshaler GetInstance(string _) => new Marshaler();
public void CleanUpManagedData(object ManagedObj)
{
}
public void CleanUpNativeData(IntPtr pNativeData) => Marshal.FreeCoTaskMem(pNativeData);
public int GetNativeDataSize() => -1;
public IntPtr MarshalManagedToNative(object ManagedObj)
{
if (!(ManagedObj is PRIVILEGE_SET ps)) return IntPtr.Zero;
var ptr = Marshal.AllocCoTaskMem((int)ps.SizeInBytes);
if (ps.Privilege?.Length != ps.PrivilegeCount)
ptr.FillMemory(0, (int)ps.SizeInBytes);
Marshal.WriteInt32(ptr, (int)ps.PrivilegeCount);
Marshal.WriteInt32(ptr, Marshal.SizeOf(typeof(int)), (int)ps.Control);
ptr.Write(ps.Privilege, Marshal.SizeOf(typeof(int)) * 2);
return ptr;
}
public object MarshalNativeToManaged(IntPtr pNativeData) => new PRIVILEGE_SET(pNativeData);
}
}
/// <summary>
/// <para>The <c>SID_IDENTIFIER_AUTHORITY</c> structure represents the top-level authority of a security identifier (SID).</para>
/// </summary>
/// <remarks>
/// <para>The identifier authority value identifies the agency that issued the SID. The following identifier authorities are predefined.</para>
/// <list type="table">
/// <listheader>
/// <term>Identifier authority</term>
/// <term>Value</term>
/// </listheader>
/// <item>
/// <term>SECURITY_NULL_SID_AUTHORITY</term>
/// <term>0</term>
/// </item>
/// <item>
/// <term>SECURITY_WORLD_SID_AUTHORITY</term>
/// <term>1</term>
/// </item>
/// <item>
/// <term>SECURITY_LOCAL_SID_AUTHORITY</term>
/// <term>2</term>
/// </item>
/// <item>
/// <term>SECURITY_CREATOR_SID_AUTHORITY</term>
/// <term>3</term>
/// </item>
/// <item>
/// <term>SECURITY_NON_UNIQUE_AUTHORITY</term>
/// <term>4</term>
/// </item>
/// <item>
/// <term>SECURITY_NT_AUTHORITY</term>
/// <term>5</term>
/// </item>
/// <item>
/// <term>SECURITY_RESOURCE_MANAGER_AUTHORITY</term>
/// <term>9</term>
/// </item>
/// </list>
/// <para>A SID must contain a top-level authority and at least one relative identifier (RID) value.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_sid_identifier_authority typedef struct
// _SID_IDENTIFIER_AUTHORITY { BYTE Value[6]; } SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;
[PInvokeData("winnt.h", MSDNShortId = "450a6d2d-d2e4-4098-90af-a8024ddcfcb5")]
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class PSID_IDENTIFIER_AUTHORITY
{
/// <summary>An array of 6 bytes specifying a SID's top-level authority.</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] Value = new byte[6];
/// <summary>Initializes a new instance of the <see cref="SID_IDENTIFIER_AUTHORITY"/> struct.</summary>
/// <param name="value">The value.</param>
/// <exception cref="System.ArgumentOutOfRangeException">value</exception>
public PSID_IDENTIFIER_AUTHORITY(byte[] value)
{
if (value == null || value.Length != 6)
throw new ArgumentOutOfRangeException(nameof(value));
Array.Copy(value, Value, 6);
}
/// <summary>Initializes a new instance of the <see cref="SID_IDENTIFIER_AUTHORITY"/> struct.</summary>
/// <param name="value">The value.</param>
public PSID_IDENTIFIER_AUTHORITY(long value)
{
LongValue = value;
}
internal PSID_IDENTIFIER_AUTHORITY(IntPtr existingPtr)
{
if (existingPtr == IntPtr.Zero)
Value = existingPtr.ToArray<byte>(6);
}
private PSID_IDENTIFIER_AUTHORITY()
{
}
/// <summary>Gets or sets the long value.</summary>
/// <value>The long value.</value>
public long LongValue
{
get
{
long nAuthority = 0;
for (var i = 0; i <= 5; i++)
nAuthority |= (long)Value[i] << (8 * i);
return nAuthority;
}
set
{
var bsia = BitConverter.GetBytes(value);
for (var i = 0; i <= 5; i++)
Value[i] = bsia[5 - i];
}
}
/// <summary>Performs an implicit conversion from byte[] to <see cref="PSID_IDENTIFIER_AUTHORITY"/>.</summary>
/// <param name="bytes">The bytes.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PSID_IDENTIFIER_AUTHORITY(byte[] bytes) => new PSID_IDENTIFIER_AUTHORITY(bytes);
/// <summary>Performs an implicit conversion from <see cref="SID_IDENTIFIER_AUTHORITY"/> to <see cref="PSID_IDENTIFIER_AUTHORITY"/>.</summary>
/// <param name="sia">The sia.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PSID_IDENTIFIER_AUTHORITY(SID_IDENTIFIER_AUTHORITY sia) => new PSID_IDENTIFIER_AUTHORITY(sia.Value);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(PSID_IDENTIFIER_AUTHORITY h1, PSID_IDENTIFIER_AUTHORITY h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(PSID_IDENTIFIER_AUTHORITY h1, PSID_IDENTIFIER_AUTHORITY h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is PSID_IDENTIFIER_AUTHORITY h ? h.LongValue == h.LongValue : false;
/// <inheritdoc/>
public override int GetHashCode() => LongValue.GetHashCode();
}
/// <summary>A SafeHandle for access control lists. If owned, will call LocalFree on the pointer when disposed.</summary>
[DebuggerDisplay("{DebugString}")]
public class SafePACL : SafeMemoryHandle<LocalMemoryMethods>, ISecurityObject
{
/// <summary>The null value for a SafePACL.</summary>
public static readonly SafePACL Null = new SafePACL();
/// <summary>Initializes a new instance of the <see cref="SafePACL"/> class.</summary>
public SafePACL() : base(IntPtr.Zero, 0, true) { }
/// <summary>
/// Initializes a new instance of the <see cref="SafePACL"/> class from an existing pointer, copying its content if owning.
/// </summary>
/// <param name="pAcl">The access control list pointer.</param>
public SafePACL(PACL pAcl) : this(IsValidAcl(pAcl) ? (int)pAcl.BytesAllocated() : throw new ArgumentException("Invalid ACL.", nameof(pAcl)))
{
((IntPtr)pAcl).CopyTo(handle, Size);
}
/// <summary>Initializes a new instance of the <see cref="SafePACL"/> class to an empty memory buffer.</summary>
/// <param name="size">The size of the uninitialized access control list.</param>
/// <param name="revision">ACL revision.</param>
public SafePACL(int size, uint revision = ACL_REVISION) : base(size)
{
if (size % 4 != 0) throw new ArgumentOutOfRangeException(nameof(size), "ACL structures must be DWORD aligned. This value must be a multiple of 4.");
InitializeAcl(handle, (uint)size, revision);
}
/// <summary>Initializes a new instance of the <see cref="SafePACL"/> class.</summary>
/// <param name="bytes">An array of bytes that contain an existing access control list.</param>
public SafePACL(byte[] bytes) : this(bytes?.Length ?? 0)
{
if (bytes is null) return;
Marshal.Copy(bytes, 0, handle, bytes.Length);
}
/// <summary>Determines whether the components of this access control list are valid.</summary>
public bool IsValidAcl => IsValidAcl(handle);
/// <summary>Gets the revision number for the ACL.</summary>
/// <value>The revision.</value>
public uint Revision => IsValidAcl && GetAclInformation(handle, out ACL_REVISION_INFORMATION ri) ? ri.AclRevision : 0U;
/// <inheritdoc/>
public override SizeT Size
{
get => base.Size;
set
{
// Make sure divisible by 4.
value = ((value + 3) >> 2) << 2;
// Setup newly allocated ACL
var newHandle = mm.AllocMem(value);
if (!InitializeAcl(newHandle, value, Revision))
Win32Error.ThrowLastError();
if (!GetAce(handle, 0, out var pace))
Win32Error.ThrowLastError();
if (!AddAce(newHandle, Revision, 0, (IntPtr)pace, ((PACL)handle).Length() - (uint)Marshal.SizeOf(typeof(ACL))))
Win32Error.ThrowLastError();
// Update SafeHandle with new ACL and destroy old
var oldHandle = handle;
SetHandle(newHandle);
sz = value;
mm.FreeMem(oldHandle);
}
}
/// <summary>Gets the number of ACEs held by this ACL.</summary>
/// <value>The ace count.</value>
public int AceCount => (int)((PACL)handle).AceCount();
/// <summary>
/// Gets the length, in bytes, of a structurally valid access control list. The length includes the length of all associated structures.
/// </summary>
public uint Length => ((PACL)handle).Length();
internal string DebugString => IsInvalid ? "NULL" : $"Aces:{AceCount}, Size:{Length}";
/// <summary>Performs an explicit conversion from <see cref="SafePACL"/> to <see cref="PACL"/>.</summary>
/// <param name="sd">The safe access control list.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PACL(SafePACL sd) => sd.DangerousGetHandle();
}
/// <summary>Contains information about an event record returned by the ReadEventLog function.</summary>
/// <remarks>
/// <para>
/// The defined members are followed by the replacement strings for the message identified by the event identifier, the binary
/// information, some pad bytes to make sure the full entry is on a <c>DWORD</c> boundary, and finally the length of the log entry
/// again. Because the strings and the binary information can be of any length, no structure members are defined to reference them.
/// The declaration of this structure in Winnt.h describes these members as follows:
/// </para>
/// <para>
/// The source name is a variable-length string that specifies the name of the event source. The computer name is the name of the
/// computer that generated the event. It may be followed with some padding bytes so that the user SID is aligned on a <c>DWORD</c>
/// boundary. The user SID identifies the active user at the time this event was logged. If <c>UserSidLength</c> is zero, this field
/// may be empty.
/// </para>
/// <para>
/// The event identifier together with source name and a language identifier identify a string that describes the event in more
/// detail. The strings are used as replacement strings and are merged into the message string to make a complete message. The
/// message strings are contained in a message file specified in the source entry in the registry. To obtain the appropriate message
/// string from the message file, load the message file with the LoadLibrary function and use the FormatMessage function.
/// </para>
/// <para>
/// The binary information is information that is specific to the event. It could be the contents of the processor registers when a
/// device driver got an error, a dump of an invalid packet that was received from the network, a dump of all the structures in a
/// program (when the data area was detected to be corrupt), and so on. This information should be useful to the writer of the device
/// driver or the application in tracking down bugs or unauthorized breaks into the application.
/// </para>
/// </remarks>
[PInvokeData("winnt.h", MSDNShortId = "669b182a-bc81-4386-9815-6ffa09e2e743")]
public class SafePEVENTLOGRECORD : SafeMemoryHandle<LocalMemoryMethods>
{
/// <summary>Initializes a new instance of the <see cref="SafePEVENTLOGRECORD"/> class.</summary>
/// <param name="bytesToAllocate">The bytes to allocate.</param>
public SafePEVENTLOGRECORD(int bytesToAllocate = 512) : base(bytesToAllocate) { }
private SafePEVENTLOGRECORD()
{
}
/// <summary>Reserved.</summary>
public uint ClosingRecordNumber => handle.ToStructure<uint>(Size, 32);
/// <summary>Gets the name of the computer that generated the event.</summary>
public string ComputerName
{
get
{
var offset = 56 + (Source.Length + 1) * 2;
return StringHelper.GetString(handle.Offset(offset), CharSet.Unicode, Size - offset);
}
}
/// <summary>
/// Gets the event-specific information within this event log record, in bytes. This information could be something specific (a
/// disk driver might log the number of retries, for example), followed by binary information specific to the event being logged
/// and to the source that generated the entry.
/// </summary>
public byte[] Data => handle.ToArray<byte>(DataLength, DataOffset, Size);
/// <summary>
/// The category for this event. The meaning of this value depends on the event source. For more information, see Event Categories.
/// </summary>
public ushort EventCategory => handle.ToStructure<ushort>(Size, 28);
/// <summary>
/// The event identifier. The value is specific to the event source for the event, and is used with source name to locate a
/// description string in the message file for the event source. For more information, see Event Identifiers.
/// </summary>
public uint EventID => handle.ToStructure<uint>(Size, 20);
/// <summary>
/// <para>The type of event. This member can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>EVENTLOG_ERROR_TYPE 0x0001</term>
/// <term>Error event</term>
/// </item>
/// <item>
/// <term>EVENTLOG_AUDIT_FAILURE 0x0010</term>
/// <term>Failure Audit event</term>
/// </item>
/// <item>
/// <term>EVENTLOG_AUDIT_SUCCESS 0x0008</term>
/// <term>Success Audit event</term>
/// </item>
/// <item>
/// <term>EVENTLOG_INFORMATION_TYPE 0x0004</term>
/// <term>Information event</term>
/// </item>
/// <item>
/// <term>EVENTLOG_WARNING_TYPE 0x0002</term>
/// <term>Warning event</term>
/// </item>
/// </list>
/// <para>For more information, see Event Types.</para>
/// </summary>
public EVENTLOG_TYPE EventType => handle.ToStructure<EVENTLOG_TYPE>(Size, 24);
/// <summary>
/// The number of strings present in the log (at the position indicated by <c>StringOffset</c>). These strings are merged into
/// the message before it is displayed to the user.
/// </summary>
public ushort NumStrings => handle.ToStructure<ushort>(Size, 26);
/// <summary>
/// The number of the record. This value can be used with the EVENTLOG_SEEK_READ flag in the ReadEventLog function to begin
/// reading at a specified record. For more information, see Event Log Records.
/// </summary>
public uint RecordNumber => handle.ToStructure<uint>(Size, 8);
/// <summary>Gets a string that specifies the name of the event source.</summary>
public string Source => StringHelper.GetString(handle.Offset(56), CharSet.Unicode, Size - 56);
/// <summary>Gets the description strings within this event log record.</summary>
public string[] Strings =>
NumStrings == 0 ? new string[0] : handle.ToStringEnum(CharSet.Unicode, StringOffset, Size).ToArray();
/// <summary>Gets the <see cref="DateTime"/> value at which this entry was submitted.</summary>
public DateTime TimeGenerated => new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) + TimeSpan.FromSeconds(handle.ToStructure<int>(Size, 12));
/// <summary>Gets the <see cref="DateTime"/> value at which this entry was written.</summary>
public DateTime TimeWritten => new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) + TimeSpan.FromSeconds(handle.ToStructure<int>(Size, 16));
/// <summary>Gets the security identifier (SID) within this event log record.</summary>
public SafePSID UserSid => UserSidLength == 0 ? SafePSID.Null : new SafePSID(handle.ToArray<byte>(UserSidLength, UserSidOffset, Size));
/// <summary>The size of the event-specific data (at the position indicated by <c>DataOffset</c>), in bytes.</summary>
private int DataLength => handle.ToStructure<int>(Size, 48);
/// <summary>
/// The offset of the event-specific information within this event log record, in bytes. This information could be something
/// specific (a disk driver might log the number of retries, for example), followed by binary information specific to the event
/// being logged and to the source that generated the entry.
/// </summary>
private int DataOffset => handle.ToStructure<int>(Size, 52);
/// <summary>The offset of the description strings within this event log record.</summary>
private int StringOffset => handle.ToStructure<int>(Size, 36);
/// <summary>The size of the <c>UserSid</c> member, in bytes. This value can be zero if no security identifier was provided.</summary>
private int UserSidLength => handle.ToStructure<int>(Size, 40);
/// <summary>
/// The offset of the security identifier (SID) within this event log record. To obtain the user name for this SID, use the
/// LookupAccountSid function.
/// </summary>
private int UserSidOffset => handle.ToStructure<int>(Size, 44);
}
/// <summary>A SafeHandle for security descriptors. If owned, will call LocalFree on the pointer when disposed.</summary>
public class SafePSECURITY_DESCRIPTOR : SafeMemoryHandle<LocalMemoryMethods>, IEquatable<SafePSECURITY_DESCRIPTOR>, IEquatable<PSECURITY_DESCRIPTOR>, IEquatable<IntPtr>, ISecurityObject
{
/// <summary>The null value for a SafeSecurityDescriptor.</summary>
public static readonly SafePSECURITY_DESCRIPTOR Null = new SafePSECURITY_DESCRIPTOR();
private const SECURITY_INFORMATION defSecInfo = SECURITY_INFORMATION.DACL_SECURITY_INFORMATION | SECURITY_INFORMATION.SACL_SECURITY_INFORMATION | SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION | SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION;
/// <summary>Initializes a new instance of the <see cref="SafePSECURITY_DESCRIPTOR"/> class.</summary>
public SafePSECURITY_DESCRIPTOR() : base(IntPtr.Zero, 0, true) { }
/// <summary>Initializes a new instance of the <see cref="SafePSECURITY_DESCRIPTOR"/> class from an existing pointer.</summary>
/// <param name="pSecurityDescriptor">The security descriptor pointer.</param>
/// <param name="own">if set to <c>true</c> indicates that this pointer should be freed when disposed.</param>
public SafePSECURITY_DESCRIPTOR(PSECURITY_DESCRIPTOR pSecurityDescriptor, bool own = true) : base(IntPtr.Zero, 0, own)
{
if (pSecurityDescriptor.IsSelfRelative())
{
sz = (int)pSecurityDescriptor.Length();
SetHandle((IntPtr)pSecurityDescriptor);
}
else if (own)
{
var newSz = 0U;
if (!MakeSelfRelativeSD(pSecurityDescriptor, Null, ref newSz) && newSz == 0)
Win32Error.ThrowLastError();
Size = newSz;
InitializeSecurityDescriptor(this, SECURITY_DESCRIPTOR_REVISION);
if (!MakeSelfRelativeSD(pSecurityDescriptor, this, ref newSz))
Win32Error.ThrowLastError();
}
else
throw new InvalidOperationException("The supplied security descriptor is in absolute format and can only be copied if this class has ownership of the memory.");
}
/// <summary>Initializes a new instance of the <see cref="SafePSECURITY_DESCRIPTOR"/> class to an empty memory buffer.</summary>
/// <param name="size">The size of the uninitialized security descriptor.</param>
public SafePSECURITY_DESCRIPTOR(int size) : base(size) => InitializeSecurityDescriptor(this, SECURITY_DESCRIPTOR_REVISION);
/// <summary>Initializes a new instance of the <see cref="SafePSECURITY_DESCRIPTOR"/> class.</summary>
/// <param name="bytes">An array of bytes that contain an existing security descriptor.</param>
public SafePSECURITY_DESCRIPTOR(byte[] bytes) : this(bytes?.Length ?? 0)
{
if (bytes is null) return;
Marshal.Copy(bytes, 0, handle, bytes.Length);
}
/// <summary>Initializes a new instance of the <see cref="SafePSECURITY_DESCRIPTOR"/> class with an SDDL string.</summary>
/// <param name="sddl">An SDDL value representing the security descriptor.</param>
public SafePSECURITY_DESCRIPTOR(string sddl)
{
if (!ConvertStringSecurityDescriptorToSecurityDescriptor(sddl, SDDL_REVISION.SDDL_REVISION_1, out var sd, out var sdsz))
Win32Error.ThrowLastError();
handle = sd.DangerousGetHandle();
sz = (int)sdsz;
sd.SetHandleAsInvalid();
}
/// <summary>Determines whether the components of this security descriptor are valid.</summary>
public bool IsValidSecurityDescriptor => IsValidSecurityDescriptor(handle);
/// <summary>Gets or sets the size in bytes of the security descriptor.</summary>
/// <value>The size in bytes of the security descriptor.</value>
public override SizeT Size
{
get
{
if (sz == 0 && Length > 0)
sz = Length;
return base.Size;
}
set => base.Size = value;
}
/// <summary>Determines whether the format of this security descriptor is self-relative.</summary>
public bool IsSelfRelative => ((PSECURITY_DESCRIPTOR)handle).IsSelfRelative();
/// <summary>
/// Gets the length, in bytes, of a structurally valid security descriptor. The length includes the length of all associated structures.
/// </summary>
public uint Length => ((PSECURITY_DESCRIPTOR)handle).Length();
/// <summary>Performs an explicit conversion from <see cref="SafePSECURITY_DESCRIPTOR"/> to <see cref="PSECURITY_DESCRIPTOR"/>.</summary>
/// <param name="sd">The safe security descriptor.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PSECURITY_DESCRIPTOR(SafePSECURITY_DESCRIPTOR sd) => sd.DangerousGetHandle();
/// <summary>Implements the operator !=.</summary>
/// <param name="psd1">The first value.</param>
/// <param name="psd2">The second value.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(SafePSECURITY_DESCRIPTOR psd1, SafePSECURITY_DESCRIPTOR psd2) => !(psd1 == psd2);
/// <summary>Implements the operator ==.</summary>
/// <param name="psd1">The first value.</param>
/// <param name="psd2">The second value.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(SafePSECURITY_DESCRIPTOR psd1, SafePSECURITY_DESCRIPTOR psd2)
{
if (ReferenceEquals(psd1, psd2)) return true;
if (Equals(null, psd1) || Equals(null, psd2)) return false;
return psd1.Equals(psd2);
}
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
public bool Equals(SafePSECURITY_DESCRIPTOR other) => Equals(other.DangerousGetHandle());
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
public bool Equals(PSECURITY_DESCRIPTOR other) => Equals(other.DangerousGetHandle());
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <param name="other">An object to compare with this object.</param>
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
public bool Equals(IntPtr other)
{
if (GetSecurityDescriptorLength(handle) != GetSecurityDescriptorLength(other)) return false;
var s1 = ConvertSecurityDescriptorToStringSecurityDescriptor(handle, defSecInfo);
var s2 = ConvertSecurityDescriptorToStringSecurityDescriptor(other, defSecInfo);
return string.CompareOrdinal(s1, s2) == 0;
}
/// <summary>Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.</summary>
/// <param name="obj">The object to compare with the current object.</param>
/// <returns>
/// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
/// </returns>
public override bool Equals(object obj)
{
if (obj is SafePSECURITY_DESCRIPTOR psid2)
return Equals(psid2);
if (obj is PSECURITY_DESCRIPTOR psidh)
return Equals(psidh);
if (obj is IntPtr ptr)
return Equals(ptr);
return false;
}
/// <summary>Gets the binary form of this SafePSECURITY_DESCRIPTOR.</summary>
/// <returns>An array of bytes containing the entire security descriptor.</returns>
public byte[] GetBinaryForm() => GetBytes(0, (int)Length);
/// <summary>Returns a hash code for this instance.</summary>
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
public override int GetHashCode() => ToString().GetHashCode();
/// <summary>
/// The <c>MakeAbsoluteSD</c> function creates a security descriptor in absolute format by using a security descriptor in
/// self-relative format as a template.
/// </summary>
/// <returns>
/// <para>A tuple containing the following:</para>
/// <list type="bullet">
/// <item>
/// <term><see cref="SafePSECURITY_DESCRIPTOR"/> pAbsoluteSecurityDescriptor</term>
/// <description>
/// The main body of an absolute-format security descriptor. This information is formatted as a SECURITY_DESCRIPTOR structure.
/// </description>
/// </item>
/// <item>
/// <term><see cref="SafePACL"/> pDacl</term>
/// <description>
/// The discretionary access control list (DACL) of the absolute-format security descriptor. The main body of the absolute-format
/// security descriptor references this pointer.
/// </description>
/// </item>
/// <item>
/// <term><see cref="SafePACL"/> pSacl</term>
/// <description>
/// The system access control list (SACL) of the absolute-format security descriptor. The main body of the absolute-format
/// security descriptor references this pointer.
/// </description>
/// </item>
/// <item>
/// <term><see cref="SafePSID"/> pOwner</term>
/// <description>
/// The security identifier (SID) of the owner of the absolute-format security descriptor. The main body of the absolute-format
/// security descriptor references this pointer.
/// </description>
/// </item>
/// <item>
/// <term><see cref="SafePSID"/> pPrimaryGroup</term>
/// <description>
/// The absolute-format security descriptor's primary group. The main body of the absolute-format security descriptor references
/// this pointer.
/// </description>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// A security descriptor in absolute format contains pointers to the information it contains, rather than the information
/// itself. A security descriptor in self-relative format contains the information in a contiguous block of memory. In a
/// self-relative security descriptor, a SECURITY_DESCRIPTOR structure always starts the information, but the security
/// descriptor's other components can follow the structure in any order. Instead of using memory addresses, the components of the
/// self-relative security descriptor are identified by offsets from the beginning of the security descriptor. This format is
/// useful when a security descriptor must be stored on a floppy disk or transmitted by means of a communications protocol.
/// </para>
/// <para>
/// A server that copies secured objects to various media can use the <c>MakeAbsoluteSD</c> function to create an absolute
/// security descriptor from a self-relative security descriptor and the MakeSelfRelativeSD function to create a self-relative
/// security descriptor from an absolute security descriptor.
/// </para>
/// </remarks>
public (SafePSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor, SafePACL pDacl, SafePACL pSacl, SafePSID pOwner, SafePSID pPrimaryGroup) MakeAbsolute()
{
uint cSD = 0, cOwn = 0, cGrp = 0, cDacl = 0, cSacl = 0;
if (!MakeAbsoluteSD(this, Null, ref cSD, SafePACL.Null, ref cDacl, SafePACL.Null, ref cSacl, SafePSID.Null, ref cOwn, SafePSID.Null, ref cGrp))
{
var err = Win32Error.GetLastError();
if (err != Win32Error.ERROR_INSUFFICIENT_BUFFER)
throw err.GetException();
}
var pSD = new SafePSECURITY_DESCRIPTOR((int)cSD);
var pDacl = new SafePACL((int)cDacl);
var pSacl = new SafePACL((int)cSacl);
var pOwn = new SafePSID((int)cOwn);
var pGrp = new SafePSID((int)cGrp);
if (!MakeAbsoluteSD(this, pSD, ref cSD, pDacl, ref cDacl, pSacl, ref cSacl, pOwn, ref cOwn, pGrp, ref cGrp))
Win32Error.ThrowLastError();
return (pSD, pDacl, pSacl, pOwn, pGrp);
}
/// <summary>Returns a <see cref="string"/> that represents this instance.</summary>
/// <returns>A <see cref="string"/> that represents this instance.</returns>
public override string ToString() => ConvertSecurityDescriptorToStringSecurityDescriptor(handle, defSecInfo);
}
}
/// <summary>Extension methods for PACE, PACL and PSECURITY_DESCRIPTOR.</summary>
public static class WinNTExtensions
{
/// <summary>Gets the number of ACEs held by an ACL.</summary>
/// <param name="pACL">The pointer to the ACL structure to query.</param>
/// <returns>The ace count.</returns>
public static uint AceCount(this PACL pACL) => AdvApi32.IsValidAcl(pACL) && AdvApi32.GetAclInformation(pACL, out AdvApi32.ACL_SIZE_INFORMATION si) ? si.AceCount : 0;
/// <summary>Gets the total number of bytes allocated to the ACL.</summary>
/// <param name="pACL">The pointer to the ACL structure to query.</param>
/// <returns>The total of the free and used bytes in the ACL.</returns>
public static uint BytesAllocated(this PACL pACL) => AdvApi32.IsValidAcl(pACL) && AdvApi32.GetAclInformation(pACL, out AdvApi32.ACL_SIZE_INFORMATION si) ? si.AclBytesFree + si.AclBytesInUse : 0;
/// <summary>Gets the Flags for an ACE, if defined.</summary>
/// <param name="pAce">A pointer to an ACE.</param>
/// <returns>The Flags value, if this is an object ACE, otherwise <see langword="null"/>.</returns>
/// <exception cref="System.ArgumentNullException">pAce</exception>
public static ObjectAceFlags? GetFlags(this PACE pAce)
{
if (pAce.IsNull) throw new ArgumentNullException(nameof(pAce));
return !pAce.IsObjectAce() ? null : (ObjectAceFlags?)pAce.DangerousGetHandle().ToStructure<AdvApi32.ACCESS_ALLOWED_OBJECT_ACE>().Flags;
}
/// <summary>Gets the header for an ACE.</summary>
/// <param name="pAce">A pointer to an ACE.</param>
/// <returns>The <see cref="AdvApi32.ACE_HEADER"/> value.</returns>
/// <exception cref="System.ArgumentNullException">pAce</exception>
public static AdvApi32.ACE_HEADER GetHeader(this PACE pAce) => !pAce.IsNull ? pAce.DangerousGetHandle().ToStructure<AdvApi32.ACE_HEADER>() : throw new ArgumentNullException(nameof(pAce));
/// <summary>Gets the InheritedObjectType for an ACE, if defined.</summary>
/// <param name="pAce">A pointer to an ACE.</param>
/// <returns>The InheritedObjectType value, if this is an object ACE, otherwise <see langword="null"/>.</returns>
/// <exception cref="System.ArgumentNullException">pAce</exception>
public static Guid? GetInheritedObjectType(this PACE pAce)
{
if (pAce.IsNull) throw new ArgumentNullException(nameof(pAce));
return !pAce.IsObjectAce() ? null : (Guid?)pAce.DangerousGetHandle().ToStructure<AdvApi32.ACCESS_ALLOWED_OBJECT_ACE>().InheritedObjectType;
}
/// <summary>Gets the mask for an ACE.</summary>
/// <param name="pAce">A pointer to an ACE.</param>
/// <returns>The ACCESS_MASK value.</returns>
/// <exception cref="System.ArgumentNullException">pAce</exception>
public static uint GetMask(this PACE pAce) => !pAce.IsNull ? pAce.DangerousGetHandle().ToStructure<AdvApi32.ACCESS_ALLOWED_ACE>().Mask : throw new ArgumentNullException(nameof(pAce));
/// <summary>Gets the ObjectType for an ACE, if defined.</summary>
/// <param name="pAce">A pointer to an ACE.</param>
/// <returns>The ObjectType value, if this is an object ACE, otherwise <see langword="null"/>.</returns>
/// <exception cref="System.ArgumentNullException">pAce</exception>
public static Guid? GetObjectType(this PACE pAce)
{
if (pAce.IsNull) throw new ArgumentNullException(nameof(pAce));
return !pAce.IsObjectAce() ? null : (Guid?)pAce.DangerousGetHandle().ToStructure<AdvApi32.ACCESS_ALLOWED_OBJECT_ACE>().ObjectType;
}
/// <summary>Gets the SID for an ACE.</summary>
/// <param name="pAce">A pointer to an ACE.</param>
/// <returns>The SID value.</returns>
/// <exception cref="System.ArgumentNullException">pAce</exception>
public static AdvApi32.SafePSID GetSid(this PACE pAce)
{
if (pAce.IsNull) throw new ArgumentNullException(nameof(pAce));
var offset = Marshal.SizeOf(typeof(AdvApi32.ACE_HEADER)) + sizeof(uint);
if (pAce.IsObjectAce()) offset += sizeof(uint) + Marshal.SizeOf(typeof(Guid)) * 2;
unsafe
{
return AdvApi32.SafePSID.CreateFromPtr((IntPtr)((byte*)pAce.DangerousGetHandle() + offset));
}
}
/// <summary>Determines if a ACE is an object ACE.</summary>
/// <param name="pAce">A pointer to an ACE.</param>
/// <returns><see langword="true"/> if is this is an object ACE; otherwise, <see langword="false"/>.</returns>
/// <exception cref="System.ArgumentNullException">pAce</exception>
/// <exception cref="System.ArgumentOutOfRangeException">pAce - Unknown ACE type.</exception>
public static bool IsObjectAce(this PACE pAce)
{
if (pAce.IsNull) throw new ArgumentNullException(nameof(pAce));
var aceType = (byte)GetHeader(pAce).AceType;
if (aceType > 0x15) throw new ArgumentOutOfRangeException(nameof(pAce), "Unknown ACE type.");
return (aceType >= 0x5 && aceType <= 0x8) || aceType == 0xB || aceType == 0xC || aceType == 0xF || aceType == 0x10;
}
/// <summary>Determines whether the security descriptor is self-relative.</summary>
/// <param name="pSD">The pointer to the SECURITY_DESCRIPTOR structure to query.</param>
/// <returns><c>true</c> if it is self-relative; otherwise, <c>false</c>.</returns>
public static bool IsSelfRelative(this PSECURITY_DESCRIPTOR pSD) => AdvApi32.GetSecurityDescriptorControl(pSD, out var ctrl, out _) ? ctrl.IsFlagSet(AdvApi32.SECURITY_DESCRIPTOR_CONTROL.SE_SELF_RELATIVE) : throw Win32Error.GetLastError().GetException();
/// <summary>Validates an access control list (ACL).</summary>
/// <param name="pAcl">The pointer to the ACL structure to query.</param>
/// <returns><c>true</c> if the ACL is valid; otherwise, <c>false</c>.</returns>
public static bool IsValidAcl(this PACL pAcl) => AdvApi32.IsValidAcl(pAcl);
/// <summary>Determines whether the components of a security descriptor are valid.</summary>
/// <param name="pSD">The pointer to the SECURITY_DESCRIPTOR structure to query.</param>
/// <returns>
/// <c>true</c> if the components of the security descriptor are valid. If any of the components of the security descriptor are not
/// valid, the return value is <c>false</c>.
/// </returns>
public static bool IsValidSecurityDescriptor(this PSECURITY_DESCRIPTOR pSD) => AdvApi32.IsValidSecurityDescriptor(pSD);
/// <summary>Gets the size, in bytes, of an ACE.</summary>
/// <param name="pAce">The pointer to the ACE structure to query.</param>
/// <returns>The size, in bytes, of the ACE.</returns>
public static uint Length(this PACE pAce)
{
unsafe
{
var p = (AdvApi32.ACE_HEADER*)(void*)pAce.DangerousGetHandle();
return p == null ? 0U : p->AceSize;
}
}
/// <summary>Gets the size, in bytes, of an ACL. If the ACL is not valid, 0 is returned.</summary>
/// <param name="pACL">The pointer to the ACL structure to query.</param>
/// <returns>The size, in bytes, of an ACL. If the ACL is not valid, 0 is returned.</returns>
public static uint Length(this PACL pACL) => AdvApi32.IsValidAcl(pACL) && AdvApi32.GetAclInformation(pACL, out AdvApi32.ACL_SIZE_INFORMATION si) ? si.AclBytesInUse : 0;
/// <summary>Gets the size, in bytes, of a security descriptor. If it is not valid, 0 is returned.</summary>
/// <param name="pSD">The pointer to the SECURITY_DESCRIPTOR structure to query.</param>
/// <returns>The size, in bytes, of a security descriptor. If it is not valid, 0 is returned.</returns>
public static uint Length(this PSECURITY_DESCRIPTOR pSD) => AdvApi32.IsValidSecurityDescriptor(pSD) ? AdvApi32.GetSecurityDescriptorLength(pSD) : 0U;
}
}