// XXX: L.0006: predefined type: typedef unsigned short wchar_t;

// XXX: define byte.
typedef byte BYTE;

typedef void* ADCONNECTION_HANDLE;
typedef int BOOL, *PBOOL, *LPBOOL;
typedef unsigned char BYTE, *PBYTE, *LPBYTE;
typedef BYTE BOOLEAN, *PBOOLEAN;
typedef wchar_t WCHAR, *PWCHAR;
// typedef WCHAR* BSTR;
typedef char CHAR, *PCHAR;
typedef double DOUBLE;
typedef unsigned long DWORD, *PDWORD, *LPDWORD;

typedef unsigned int DWORD32;
typedef unsigned __int64 DWORD64, *PDWORD64;
typedef unsigned __int64 ULONGLONG;
typedef ULONGLONG DWORDLONG, *PDWORDLONG;
// XXX: L.0006: predefined type: typedef unsigned long error_status_t;
typedef float FLOAT;
typedef unsigned char UCHAR, *PUCHAR;
typedef short SHORT;
typedef small SMALL;

typedef void* HANDLE; 
typedef DWORD HCALL;
typedef int INT, *LPINT;
typedef signed char INT8;
typedef signed short INT16;
typedef signed int INT32;
typedef signed __int64 INT64;
typedef void* LDAP_UDP_HANDLE;
typedef const wchar_t* LMCSTR;
typedef WCHAR* LMSTR;
typedef long LONG, *PLONG, *LPLONG;
typedef signed __int64 LONGLONG;
typedef LONG HRESULT;

typedef __int3264 LONG_PTR;
typedef unsigned __int3264 ULONG_PTR;

typedef signed int LONG32;
typedef signed __int64 LONG64, *PLONG64;
typedef const char* LPCSTR;
typedef const void* LPCVOID;
typedef const wchar_t* LPCWSTR;
typedef char* PSTR, *LPSTR;

typedef wchar_t* LPWSTR, *PWSTR;
typedef DWORD NET_API_STATUS;
typedef long NTSTATUS;
// DEFINED IN DCETYPES.
// typedef [context_handle] void* PCONTEXT_HANDLE;
// typedef [ref] PCONTEXT_HANDLE* PPCONTEXT_HANDLE;

typedef unsigned __int64 QWORD;
typedef void* RPC_BINDING_HANDLE;
typedef UCHAR* STRING;

typedef unsigned int UINT;
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned int UINT32;
typedef unsigned __int64 UINT64;
typedef unsigned long ULONG, *PULONG;

typedef ULONG_PTR DWORD_PTR;
typedef ULONG_PTR SIZE_T;
typedef unsigned int ULONG32;
typedef unsigned __int64 ULONG64;
typedef wchar_t UNICODE;
typedef unsigned short USHORT;
typedef void VOID, *PVOID, *LPVOID;
typedef unsigned short WORD, *PWORD, *LPWORD;

typedef struct _FILETIME {
  DWORD dwLowDateTime;
  DWORD dwHighDateTime;
} FILETIME,
 *PFILETIME,
 *LPFILETIME;

typedef struct _GUID {
  unsigned long Data1;
  unsigned short Data2;
  unsigned short Data3;
  byte Data4[8];
} GUID,
  UUID,
 *PGUID;

// FIXME: from guiddef.
typedef GUID CLSID;

typedef struct _LARGE_INTEGER {
  signed __int64 QuadPart;
} LARGE_INTEGER, *PLARGE_INTEGER;

typedef struct _EVENT_DESCRIPTOR {
  USHORT    Id;
  UCHAR     Version;
  UCHAR     Channel;
  UCHAR     Level;
  UCHAR     Opcode;
  USHORT    Task;
  ULONGLONG Keyword;
} EVENT_DESCRIPTOR,
 *PEVENT_DESCRIPTOR,
 *PCEVENT_DESCRIPTOR;

typedef struct _EVENT_HEADER {
  USHORT           Size;
  USHORT           HeaderType;
  USHORT           Flags;
  USHORT           EventProperty;
  ULONG            ThreadId;
  ULONG            ProcessId;
  LARGE_INTEGER    TimeStamp;
  GUID             ProviderId;
  EVENT_DESCRIPTOR EventDescriptor;
    union {
    struct {
      ULONG KernelTime;
      ULONG UserTime;
    };
    ULONG64 ProcessorTime;
  };
  GUID             ActivityId;
} EVENT_HEADER,
 *PEVENT_HEADER;

typedef DWORD LCID;

typedef struct _LUID {
  DWORD LowPart;
  LONG HighPart;
} LUID,
 *PLUID;

typedef struct _MULTI_SZ {
  wchar_t* Value;
  DWORD nChar;
} MULTI_SZ;

typedef struct _RPC_UNICODE_STRING {
  unsigned short Length;
  unsigned short MaximumLength;
  [size_is(MaximumLength/2), length_is(Length/2)]
    WCHAR* Buffer;
} RPC_UNICODE_STRING,
 *PRPC_UNICODE_STRING;

typedef struct _SERVER_INFO_100 {
  DWORD sv100_platform_id;
  [string] wchar_t* sv100_name;
} SERVER_INFO_100,
 *PSERVER_INFO_100,
 *LPSERVER_INFO_100;

typedef struct _SERVER_INFO_101 {
  DWORD sv101_platform_id;
  [string] wchar_t* sv101_name;
  DWORD sv101_version_major;
  DWORD sv101_version_minor;
  DWORD sv101_version_type;
  [string] wchar_t* sv101_comment;
} SERVER_INFO_101,
 *PSERVER_INFO_101,
 *LPSERVER_INFO_101;

typedef struct _SYSTEMTIME {
  WORD wYear;
  WORD wMonth;
  WORD wDayOfWeek;
  WORD wDay;
  WORD wHour;
  WORD wMinute;
  WORD wSecond;
  WORD wMilliseconds;
} SYSTEMTIME,
 *PSYSTEMTIME;

typedef struct _UINT128 {
  UINT64 lower;
  UINT64 upper;
} UINT128,
 *PUINT128;

typedef struct _ULARGE_INTEGER {
    unsigned __int64 QuadPart;
} ULARGE_INTEGER, *PULARGE_INTEGER;

typedef struct _RPC_SID_IDENTIFIER_AUTHORITY {
  byte Value[6];
} RPC_SID_IDENTIFIER_AUTHORITY;

typedef DWORD ACCESS_MASK;
typedef ACCESS_MASK *PACCESS_MASK;

const DWORD ACCESS_MASK_GENERIC_READ = 0x80000000;
const DWORD ACCESS_MASK_GENERIC_WRITE = 0x40000000;
const DWORD ACCESS_MASK_GENERIC_EXECUTE = 0x20000000;
const DWORD ACCESS_MASK_GENERIC_ALL = 0x10000000;
const DWORD ACCESS_MASK_MAXIMUM_ALLOWED = 0x02000000;
const DWORD ACCESS_MASK_ACCESS_SYSTEM_SECURITY = 0x01000000;
const DWORD ACCESS_MASK_SYNCHRONIZE = 0x00100000;
const DWORD ACCESS_MASK_WRITE_OWNER = 0x00080000;
const DWORD ACCESS_MASK_WRITE_DACL = 0x00040000;
const DWORD ACCESS_MASK_READ_CONTROL = 0x00020000;
const DWORD ACCESS_MASK_DELETE = 0x00010000;

const DWORD ACCESS_MASK_DS_CONTROL_ACCESS = 0x00000100;
const DWORD ACCESS_MASK_DS_CREATE_CHILD = 0x00000001;
const DWORD ACCESS_MASK_DS_DELETE_CHILD = 0x00000002;
const DWORD ACCESS_MASK_DS_READ_PROP = 0x00000010;
const DWORD ACCESS_MASK_DS_WRITE_PROP = 0x00000020;
const DWORD ACCESS_MASK_DS_SELF = 0x00000008;

const DWORD ACE_OBJECT_TYPE_PRESENT = 0x1;
const DWORD ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x2;

const SMALL ACE_FLAG_CONTAINER_INHERIT_ACE = 0x02;
const SMALL ACE_FLAG_FAILED_ACCESS_ACE_FLAG = 0x80;
const SMALL ACE_FLAG_INHERIT_ONLY_ACE = 0x08;
const SMALL ACE_FLAG_INHERITED_ACE = 0x10;
const SMALL ACE_FLAG_NO_PROPAGATE_INHERIT_ACE = 0x04;
const SMALL ACE_FLAG_OBJECT_INHERIT_ACE = 0x01;
const SMALL ACE_FLAG_SUCCESSFUL_ACCESS_ACE_FLAG = 0x40;

typedef struct _OBJECT_TYPE_LIST {
  WORD Level;
  ACCESS_MASK Remaining;
  GUID* ObjectType;
} OBJECT_TYPE_LIST,
 *POBJECT_TYPE_LIST;

typedef struct _ACE_HEADER {
  UCHAR AceType;
  UCHAR AceFlags;
  USHORT AceSize;
} ACE_HEADER,
 *PACE_HEADER;

typedef struct _ACCESS_ALLOWED_ACE {
    ACCESS_MASK Mask;
    PSID Sid;
} ACCESS_ALLOWED_ACE, *PACCESS_ALLOWED_ACE;

typedef struct _ACCESS_ALLOWED_OBJECT_ACE {
    ACCESS_MASK Mask;
    DWORD Flags;
    [switch_is(Flags&ACE_OBJECT_TYPE_PRESENT)] PACE_GUID ObjectType;
    [switch_is(Flags&ACE_INHERITED_OBJECT_TYPE_PRESENT)] PACE_GUID InheritedObjectType;
    PSID Sid;
} ACCESS_ALLOWED_OBJECT_ACE, *PACCESS_ALLOWED_OBJECT_ACE;

typedef [switch_type(DWORD)] union _ACE_GUID {
    [case(0x1, 0x2)] GUID GUID;
    [default];
} ACE_GUID, *PACE_GUID;

typedef struct _ACCESS_DENIED_ACE {
    ACCESS_MASK Mask;
    PSID Sid;
} ACCESS_DENIED_ACE, *PACCESS_DENIED_ACE;

typedef struct _ACCESS_DENIED_OBJECT_ACE {
    ACCESS_MASK Mask;
    DWORD Flags;
    [switch_is(Flags&ACE_OBJECT_TYPE_PRESENT)] PACE_GUID ObjectType;
    [switch_is(Flags&ACE_INHERITED_OBJECT_TYPE_PRESENT)] PACE_GUID InheritedObjectType;
    PSID Sid;
} ACCESS_DENIED_OBJECT_ACE, *PACCESS_DENIED_OBJECT_ACE;

typedef struct _ACCESS_ALLOWED_CALLBACK_ACE {
    ACCESS_MASK Mask;
    PSID Sid;
    [size_is(*)] BYTE *ApplicationData[];
} ACCESS_ALLOWED_CALLBACK_ACE, *PACCESS_ALLOWED_CALLBACK_ACE;

typedef struct _ACCESS_DENIED_CALLBACK_ACE {
    ACCESS_MASK Mask;
    PSID Sid;
    [size_is(*)] BYTE *ApplicationData[];
} ACCESS_DENIED_CALLBACK_ACE, *PACCESS_DENIED_CALLBACK_ACE;

typedef struct _ACCESS_ALLOWED_CALLBACK_OBJECT_ACE {
    ACCESS_MASK Mask;
    DWORD Flags;
    [switch_is(Flags&ACE_OBJECT_TYPE_PRESENT)] PACE_GUID ObjectType;
    [switch_is(Flags&ACE_INHERITED_OBJECT_TYPE_PRESENT)] PACE_GUID InheritedObjectType;
    PSID Sid;
    [size_is(*)] BYTE *ApplicationData[];
} ACCESS_ALLOWED_CALLBACK_OBJECT_ACE, *PACCESS_ALLOWED_CALLBACK_OBJECT_ACE;

typedef struct _ACCESS_DENIED_CALLBACK_OBJECT_ACE {
    ACCESS_MASK Mask;
    DWORD Flags;
    [switch_is(Flags&ACE_OBJECT_TYPE_PRESENT)] PACE_GUID ObjectType;
    [switch_is(Flags&ACE_INHERITED_OBJECT_TYPE_PRESENT)] PACE_GUID InheritedObjectType;
    PSID Sid;
    [size_is(*)] BYTE *ApplicationData[];
} ACCESS_DENIED_CALLBACK_OBJECT_ACE, *PACCESS_DENIED_CALLBACK_OBJECT_ACE;

typedef struct _SYSTEM_AUDIT_ACE {
    ACCESS_MASK Mask;
    PSID Sid;
} SYSTEM_AUDIT_ACE, *PSYSTEM_AUDIT_ACE;

typedef struct _SYSTEM_AUDIT_OBJECT_ACE {
    ACCESS_MASK Mask;
    DWORD Flags;
    [switch_is(Flags&ACE_OBJECT_TYPE_PRESENT)] PACE_GUID ObjectType;
    [switch_is(Flags&ACE_INHERITED_OBJECT_TYPE_PRESENT)] PACE_GUID InheritedObjectType;
    PSID Sid;
    [size_is(*)] BYTE * ApplicationData[];
} SYSTEM_AUDIT_OBJECT_ACE, *PSYSTEM_AUDIT_OBJECT_ACE;

typedef struct _SYSTEM_AUDIT_CALLBACK_ACE {
    ACCESS_MASK Mask;
    PSID Sid;
    [size_is(*)] BYTE * ApplicationData[];
} SYSTEM_AUDIT_CALLBACK_ACE, *PSYSTEM_AUDIT_CALLBACK_ACE;

const DWORD SYSTEM_MANDATORY_LABEL_NO_WRITE_UP = 0x1;
const DWORD SYSTEM_MANDATORY_LABEL_NO_READ_UP = 0x2;
const DWORD SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP = 0x4;

const DWORD SECURITY_NULL_SID_AUTHORITY = 0;
const DWORD SECURITY_WORLD_SID_AUTHORITY = 1;
const DWORD SECURITY_LOCAL_SID_AUTHORITY = 2;
const DWORD SECURITY_CREATOR_SID_AUTHORITY = 3;
const DWORD SECURITY_NT_AUTHORITY = 5;

const DWORD SECURITY_NULL_RID = 0x00000000;
const DWORD SECURITY_WORLD_RID = 0x00000000;
const DWORD SECURITY_LOCAL_RID = 0x00000000;
const DWORD SECURITY_LOCAL_LOGON_RID = 0x00000001;
const DWORD SECURITY_CREATOR_OWNER_RID = 0x00000000;
const DWORD SECURITY_CREATOR_GROUP_RID = 0x00000001;

const DWORD SECURITY_MANDATORY_UNTRUSTED_RID = 0x00000000;
const DWORD SECURITY_MANDATORY_LOW_RID = 0x00001000;
const DWORD SECURITY_MANDATORY_MEDIUM_RID = 0x00002000;
const DWORD SECURITY_MANDATORY_MEDIUM_PLUS_RID = SECURITY_MANDATORY_MEDIUM_RID + 0x100;
const DWORD SECURITY_MANDATORY_HIGH_RID = 0x00003000;
const DWORD SECURITY_MANDATORY_SYSTEM_RID = 0x00004000;
const DWORD SECURITY_MANDATORY_PROTECTED_PROCESS_RID = 0x00005000;

const DWORD DOMAIN_GROUP_RID_ENTERPRISE_READONLY_DOMAIN_CONTROLLERS = 0x000001F2;
const DWORD DOMAIN_USER_RID_ADMIN = 0x000001F4;
const DWORD DOMAIN_USER_RID_GUEST = 0x000001F5;
const DWORD DOMAIN_USER_RID_KRBTGT = 0x000001F6;
const DWORD DOMAIN_USER_RID_DEFAULT_ACCOUNT = 0x000001F7;
const DWORD DOMAIN_GROUP_RID_ADMINS = 0x00000200;
const DWORD DOMAIN_GROUP_RID_USERS = 0x00000201;
const DWORD DOMAIN_GROUP_RID_GUESTS = 0x00000202;
const DWORD DOMAIN_GROUP_RID_COMPUTERS = 0x00000203;
const DWORD DOMAIN_GROUP_RID_CONTROLLERS = 0x00000204;
const DWORD DOMAIN_GROUP_RID_CERT_ADMINS = 0x00000205;
const DWORD DOMAIN_GROUP_RID_SCHEMA_ADMINS = 0x00000206;
const DWORD DOMAIN_GROUP_RID_ENTERPRISE_ADMINS = 0x00000207;
const DWORD DOMAIN_GROUP_RID_POLICY_ADMINS = 0x00000208;
const DWORD DOMAIN_GROUP_RID_READONLY_CONTROLLERS = 0x00000209;
const DWORD DOMAIN_GROUP_RID_CLONEABLE_CONTROLLERS = 0x0000020A;
const DWORD DOMAIN_GROUP_RID_CDC_RESERVED = 0x0000020C;
const DWORD DOMAIN_GROUP_RID_PROTECTED_USERS = 0x0000020D;
const DWORD DOMAIN_GROUP_RID_KEY_ADMINS = 0x0000020E;
const DWORD DOMAIN_GROUP_RID_ENTERPRISE_KEY_ADMINS = 0x0000020F;

const DWORD DOMAIN_ALIAS_RID_ADMINS = 0x00000220;
const DWORD DOMAIN_ALIAS_RID_USERS = 0x00000221;
const DWORD DOMAIN_ALIAS_RID_GUESTS = 0x00000222;
const DWORD DOMAIN_ALIAS_RID_POWER_USERS = 0x00000223;
const DWORD DOMAIN_ALIAS_RID_ACCOUNT_OPS = 0x00000224;
const DWORD DOMAIN_ALIAS_RID_SYSTEM_OPS = 0x00000225;
const DWORD DOMAIN_ALIAS_RID_PRINT_OPS = 0x00000226;
const DWORD DOMAIN_ALIAS_RID_BACKUP_OPS = 0x00000227;
const DWORD DOMAIN_ALIAS_RID_REPLICATOR = 0x00000228;
const DWORD DOMAIN_ALIAS_RID_RAS_SERVERS = 0x00000229;
const DWORD DOMAIN_ALIAS_RID_PRE_W2K_COMP_ACCESS = 0x0000022A;
const DWORD DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS = 0x0000022B;
const DWORD DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS = 0x0000022C;
const DWORD DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x0000022D;
const DWORD DOMAIN_ALIAS_RID_MONITORING_USERS = 0x0000022E;
const DWORD DOMAIN_ALIAS_RID_LOGGING_USERS = 0x0000022F;
const DWORD DOMAIN_ALIAS_RID_AUTHORIZATION_ACCESS = 0x00000230;
const DWORD DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS = 0x00000231;
const DWORD DOMAIN_ALIAS_RID_DCOM_USERS = 0x00000232;
const DWORD DOMAIN_ALIAS_RID_INTERNET_USERS = 0x00000238;
const DWORD DOMAIN_ALIAS_RID_CRYPTO_OPERATORS = 0x00000239;
const DWORD DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP = 0x0000023B;
const DWORD DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 0x0000023C;
const DWORD DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP = 0x0000023D;
const DWORD DOMAIN_ALIAS_RID_CERTSVC_DCOM_ACCESS_GROUP = 0x0000023E;
const DWORD DOMAIN_ALIAS_RID_RDS_REMOTE_ACCESS_SERVERS = 0x0000023F;
const DWORD DOMAIN_ALIAS_RID_RDS_ENDPOINT_SERVERS = 0x00000240;
const DWORD DOMAIN_ALIAS_RID_RDS_MANAGEMENT_SERVERS = 0x00000241;
const DWORD DOMAIN_ALIAS_RID_HYPER_V_ADMINS = 0x00000242;
const DWORD DOMAIN_ALIAS_RID_ACCESS_CONTROL_ASSISTANCE_OPS = 0x00000243;
const DWORD DOMAIN_ALIAS_RID_REMOTE_MANAGEMENT_USERS = 0x00000244;
const DWORD DOMAIN_ALIAS_RID_DEFAULT_ACCOUNT = 0x00000245;
const DWORD DOMAIN_ALIAS_RID_STORAGE_REPLICA_ADMINS = 0x00000246;
const DWORD DOMAIN_ALIAS_RID_DEVICE_OWNERS = 0x00000247;

const DWORD RID_LOW_INTEGRITY_LEVEL = 0x00001000;
const DWORD RID_MEDIUM_INTEGRITY_LEVEL = 0x00002000;
const DWORD RID_HIGH_INTEGRITY_LEVEL = 0x00003000;
const DWORD RID_SYSTEM_INTEGRITY_LEVEL = 0x00004000;
const DWORD RID_PROTECTED_PROCESS_INTEGRITY_LEVEL = 0x00005000;

typedef struct _SYSTEM_MANDATORY_LABEL_ACE {
  ACCESS_MASK Mask;
  PSID Sid;
} SYSTEM_MANDATORY_LABEL_ACE,
 *PSYSTEM_MANDATORY_LABEL_ACE;

typedef struct _SYSTEM_AUDIT_CALLBACK_OBJECT_ACE {
    ACCESS_MASK Mask;
    DWORD Flags;
    [switch_is(Flags&ACE_OBJECT_TYPE_PRESENT)] PACE_GUID ObjectType;
    [switch_is(Flags&ACE_INHERITED_OBJECT_TYPE_PRESENT)] PACE_GUID InheritedObjectType;
    PSID Sid;
    [size_is(*)] BYTE * ApplicationData[];
} SYSTEM_AUDIT_CALLBACK_OBJECT_ACE, *PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE;

typedef struct _SYSTEM_RESOURCE_ATTRIBUTE_ACE {
    ACCESS_MASK Mask;
    PSID Sid;
    [size_is(*)] BYTE * AttributeData[];
} SYSTEM_RESOURCE_ATTRIBUTE_ACE, *PSYSTEM_RESOURCE_ATTRIBUTE_ACE;

typedef struct _SYSTEM_SCOPED_POLICY_ID_ACE {
    ACCESS_MASK Mask;
    PSID Sid;
} SYSTEM_SCOPED_POLICY_ID_ACE, *PSYSTEM_SCOPED_POLICY_ID_ACE;

typedef struct _RAW_ACE {
    [size_is(*)] BYTE * RawData[];
} RAW_ACE, *PRAW_ACE;

typedef enum _ACE_TYPE {
    ACCESS_ALLOWED_ACE_TYPE,
    ACCESS_DENIED_ACE_TYPE,
    SYSTEM_AUDIT_ACE_TYPE,
    SYSTEM_ALARM_ACE_TYPE,
    ACCESS_ALLOWED_COMPOUND_ACE_TYPE,
    ACCESS_ALLOWED_OBJECT_ACE_TYPE,
    ACCESS_DENIED_OBJECT_ACE_TYPE,
    SYSTEM_AUDIT_OBJECT_ACE_TYPE,
    SYSTEM_ALARM_OBJECT_ACE_TYPE,
    ACCESS_ALLOWED_CALLBACK_ACE_TYPE,
    ACCESS_DENIED_CALLBACK_ACE_TYPE,
    ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE,
    ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE,
    SYSTEM_AUDIT_CALLBACK_ACE_TYPE,
    SYSTEM_ALARM_CALLBACK_ACE_TYPE,
    SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE,
    SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE,
    SYSTEM_MANDATORY_LABEL_ACE_TYPE,
    SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPE,
    SYSTEM_SCOPED_POLICY_ID_ACE_TYPE
} ACE_TYPE;

typedef [pad(4)] struct _ACE {
    UCHAR AceType;
    UCHAR AceFlags;
    USHORT AceSize;
    [goext_layout(
        [switch_is(AceType)] PACE_DATA AceData
    )]
    [size_is(AceSize-4)] BYTE * Data;
} ACE, *PACE;

typedef [switch_type(UCHAR)] union _ACE_DATA {

    [case(ACCESS_ALLOWED_ACE_TYPE)]
        PACCESS_ALLOWED_ACE AccessAllowedAce;
    
    [case(ACCESS_DENIED_ACE_TYPE)]
        PACCESS_DENIED_ACE AccessDeniedAce;
    
    [case(SYSTEM_AUDIT_ACE_TYPE)]
        PSYSTEM_AUDIT_ACE SystemAuditAce;
    
    [case(ACCESS_ALLOWED_OBJECT_ACE_TYPE)]
        PACCESS_ALLOWED_OBJECT_ACE AccessAllowedObjectAce;
    
    [case(ACCESS_DENIED_OBJECT_ACE_TYPE)]
        PACCESS_DENIED_OBJECT_ACE AccessDeniedObjectAce;
    
    [case(SYSTEM_AUDIT_OBJECT_ACE_TYPE)]
        PSYSTEM_AUDIT_OBJECT_ACE SystemAuditObjectAce;
    
    [case(ACCESS_ALLOWED_CALLBACK_ACE_TYPE)]
        PACCESS_ALLOWED_CALLBACK_ACE AccessAllowedCallbackAce;
    
    [case(ACCESS_DENIED_CALLBACK_ACE_TYPE)]
        PACCESS_DENIED_CALLBACK_ACE AccessDeniedCallbackAce;
    
    [case(ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE)]
        PACCESS_ALLOWED_CALLBACK_OBJECT_ACE AccessAllowedCallbackObjectAce;
    
    [case(ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE)]
        PACCESS_DENIED_CALLBACK_OBJECT_ACE AccessDeniedCallbackObjectAce;
    
    [case(SYSTEM_AUDIT_CALLBACK_ACE_TYPE)]
        PSYSTEM_AUDIT_CALLBACK_ACE SystemAuditCallbackAce;
    
    // [case(SYSTEM_ALARM_CALLBACK_ACE_TYPE)]
    //    SYSTEM_ALARM_CALLBACK_ACE SystemAlarmCallbackAce;
    
    [case(SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE)]
        PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE SystemAuditCallbackObjectAce;
    
    // [case(SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE)]
    //    SYSTEM_ALARM_CALLBACK_OBJECT_ACE SystemAlarmCallbackObjectAce;
    
    [case(SYSTEM_MANDATORY_LABEL_ACE_TYPE)]
        PSYSTEM_MANDATORY_LABEL_ACE SystemMandatoryLabelAce;
    
    [case(SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPE)]
        PSYSTEM_RESOURCE_ATTRIBUTE_ACE SystemResourceAttributeAce;
    
    [case(SYSTEM_SCOPED_POLICY_ID_ACE_TYPE)]
        PSYSTEM_SCOPED_POLICY_ID_ACE SystemScopedPolicyIdAce;
    
    [default]
        PRAW_ACE RawAce;
    
} ACE_DATA, *PACE_DATA;


typedef struct _TOKEN_MANDATORY_POLICY {
  DWORD Policy;
} TOKEN_MANDATORY_POLICY,
 *PTOKEN_MANDATORY_POLICY;

typedef struct _MANDATORY_INFORMATION {
  ACCESS_MASK AllowedAccess;
  BOOLEAN WriteAllowed;
  BOOLEAN ReadAllowed;
  BOOLEAN ExecuteAllowed;
  TOKEN_MANDATORY_POLICY MandatoryPolicy;
} MANDATORY_INFORMATION,
 *PMANDATORY_INFORMATION;

typedef struct _CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_RELATIVE {
  DWORD Length;
  BYTE OctetString[];
} CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_RELATIVE,
 *PCLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_RELATIVE;

typedef struct _CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1 {
  DWORD Name;
  WORD ValueType;
  WORD Reserved;
  DWORD Flags;
  DWORD ValueCount;
  union {
    PLONG64 pInt64[];
    PDWORD64 pUint64[];
    PWSTR ppString[];
    PCLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_RELATIVE pOctetString[];
  } Values;
} CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1,
 *PCLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1;


typedef DWORD SECURITY_INFORMATION, *PSECURITY_INFORMATION;

typedef struct _RPC_SID {
  unsigned char Revision;
  unsigned char SubAuthorityCount;
  RPC_SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
  [size_is(SubAuthorityCount)] unsigned long SubAuthority[];
} RPC_SID,
 *PRPC_SID,
 *PSID;

typedef struct _ACL {
  unsigned char AclRevision;
  unsigned char Sbz1;
  unsigned short AclSize;
  unsigned short AceCount;
  unsigned short Sbz2;
  [size_is(AceCount)] PACE AceEntries[];
} ACL,
 *PACL;

const USHORT OWNER_DEFAULTED = 0x0001;
const USHORT GROUP_DEFAULTED = 0x0002;
const USHORT DACL_PRESENT = 0x0004;
const USHORT DACL_DEFAULTED = 0x0008;
const USHORT SACL_PRESENT = 0x0010;
const USHORT SACL_DEFAULTED = 0x0020;
const USHORT DACL_TRUSTED = 0x0040;
const USHORT SERVER_SECURITY = 0x0080;
const USHORT DACL_COMPUTED_INHERITANCE_REQUIRED = 0x0100;
const USHORT SACL_COMPUTED_INHERITANCE_REQUIRED = 0x0200;
const USHORT DACL_AUTO_INHERITED = 0x0400;
const USHORT SACL_AUTO_INHERITED = 0x0800;
const USHORT DACL_PROTECTED = 0x1000;
const USHORT SACL_PROTECTED = 0x2000;
const USHORT RM_CONTROL_VALID = 0x4000;
const USHORT SELF_RELATIVE = 0x8000;

typedef struct _SECURITY_DESCRIPTOR {
  UCHAR Revision;
  UCHAR Sbz1;
  USHORT Control;
  // for self-relative representation.
  [ignore] ULONG OffsetOwner;
  [ignore] ULONG OffsetGroup;
  [ignore] ULONG OffsetSacl; 
  [ignore] ULONG OffsetDacl; 
  PSID Owner;
  PSID Group;
  PACL Sacl;
  PACL Dacl;
} SECURITY_DESCRIPTOR,
 *PSECURITY_DESCRIPTOR;

