/// <summary>
        /// Calculate the length of the ApplicationData byte array according to the specified ace header.
        /// </summary>
        /// <param name="header">The specified ace header.</param>
        /// <param name="sid">The sid of the specified ace.</param>
        /// <returns>The calculated length.</returns>
        /// <exception cref="ArgumentOutOfRangeException">Throw when the ace type is invalid.</exception> 
        internal static int CalculateApplicationDataLength(_ACE_HEADER header, _SID sid)
        {
            int applicationDataLength = 0;
            switch (header.AceType)
            {
                case ACE_TYPE.ACCESS_ALLOWED_CALLBACK_ACE_TYPE:
                case ACE_TYPE.ACCESS_DENIED_CALLBACK_ACE_TYPE:
                case ACE_TYPE.SYSTEM_AUDIT_CALLBACK_ACE_TYPE:
                    //The AceSize contains the following parts:
                    //_ACE_HEADER Header,(4 bytes)
                    //uint Mask,(4 bytes)
                    //_SID Sid;(variable length)
                    //byte[] ApplicationData,(variable length)
                    applicationDataLength =
                        header.AceSize - SHORT_FIXED_ACE_LENGTH - TypeMarshal.ToBytes<_SID>(sid).GetLength(0);
                    break;

                case ACE_TYPE.ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
                case ACE_TYPE.ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
                case ACE_TYPE.SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
                    //The AceSize contains the following parts:
                    //_ACE_HEADER Header,(4 bytes)
                    //uint Mask,(4 bytes)
                    //uint Flags,(4 bytes)
                    //Guid ObjectType,(16 bytes)
                    //Guid InheritedObjectType,(16 bytes)
                    //_SID Sid;(variable length)
                    //byte[] ApplicationData,(variable length)
                    applicationDataLength =
                        header.AceSize - LONG_FIXED_ACE_LENGTH - TypeMarshal.ToBytes<_SID>(sid).GetLength(0);
                    break;

                default:
                    throw new ArgumentOutOfRangeException("header", "The ace type is invalid.");
            }
            return applicationDataLength > 0 ? applicationDataLength : 0;
        }
        /// <summary>
        /// Create an ACCESS_DENIED_ACE by using specific SID, access mask and optional ace flags.
        /// </summary>
        /// <param name="sid">The SID of the trustee.</param>
        /// <param name="mask">An ACCESS_MASK that specifies the user rights denied by this ACE.</param>
        /// <param name="flags">ACE type-specific control flags in the ACE header.</param>
        /// <returns>The constructed ACCESS_DENIED_ACE structure</returns>
        public static _ACCESS_DENIED_ACE CreateAccessDeniedAce(_SID sid, uint mask, ACE_FLAGS flags = ACE_FLAGS.None)
        {
            _ACE_HEADER aceHeader = new _ACE_HEADER
            {
                AceFlags = flags,
                AceType = ACE_TYPE.ACCESS_DENIED_ACE_TYPE,
                // Header (4 bytes) + Mask (4 bytes) + SID length;
                // For details, please refer to MS-DTYP.
                AceSize = (ushort)(4 + 4 + DtypUtility.SidLength(sid)),
            };

            _ACCESS_DENIED_ACE ace = new _ACCESS_DENIED_ACE
            {
                Header = aceHeader,
                Mask = mask,
                Sid = sid,
            };
            return ace;
        }
        /// <summary>
        /// Create a SYSTEM_SCOPED_POLICY_ID_ACE with specified SID and optional ACE_FLAGS.
        /// </summary>
        /// <param name="sid">A SID that identifies a central access policy.</param>
        /// <param name="flags">An unsigned 8-bit integer that specifies a set of ACE type-specific control flags. </param>
        /// <returns>Return the ACE.</returns>
        public static _SYSTEM_SCOPED_POLICY_ID_ACE CreateSystemScopedPolicyIdAce(_SID sid,
            ACE_FLAGS flags = ACE_FLAGS.OBJECT_INHERIT_ACE | ACE_FLAGS.CONTAINER_INHERIT_ACE)
        {
            _ACE_HEADER aceHeader = new _ACE_HEADER
            {
                AceFlags = flags,
                AceType = ACE_TYPE.SYSTEM_SCOPED_POLICY_ID_ACE_TYPE,
                // Header (4 bytes) + Mask (4 bytes) + SID length;
                // For details, please refer to MS-DTYP.
                AceSize = (ushort)(4 + 4 + DtypUtility.SidLength(sid)),
            };

            _SYSTEM_SCOPED_POLICY_ID_ACE ace = new _SYSTEM_SCOPED_POLICY_ID_ACE
            {
                Header = aceHeader,
                Mask = 0, // An ACCESS_MASK that MUST be set to zero.
                Sid = sid,
            };
            return ace;
        }
        private SystemResourceAttributeAce(string attributeName)
        {
            if (attributeName.Length < 2)
            {
                throw new ArgumentException("attributeName must be at least 4 bytes in length.");
            }

            AttributeName = attributeName;
            Sid = DtypUtility.GetWellKnownSid(WellKnownSid.EVERYONE, null);
            AttributeData.Flags = CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1.FlagEnum.CLAIM_SECURITY_ATTRIBUTE_MANDATORY
                | CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1.FlagEnum.FCI_CLAIM_SECURITY_ATTRIBUTE_MANUAL;
            Mask = 0;
            Header = new _ACE_HEADER
            {
                AceFlags = ACE_FLAGS.CONTAINER_INHERIT_ACE | ACE_FLAGS.OBJECT_INHERIT_ACE,
                AceType = ACE_TYPE.SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPE,
                // Size would be filled later
            };
        }