/// <summary>
 /// the constructor
 /// </summary>
 /// <param name="flags">the security descriptor control flag</param>
 /// <param name="owner">the owner sid</param>
 /// <param name="group">the group sid</param>
 /// <param name="sacl">the sacl</param>
 /// <param name="dacl">the dacl</param>
 public _RawSecurityDescriptor(SECURITY_DESCRIPTOR_Control flags,
                               _SID?owner,
                               _SID?group,
                               _RawAcl sacl,
                               _RawAcl dacl)
 {
     controlFlags = flags;
     ownerSid     = owner;
     groupSid     = group;
     this.sacl    = sacl;
     this.dacl    = dacl;
 }
        /// <summary>
        /// the constructor
        /// </summary>
        /// <param name="binary">the input binary</param>
        /// <param name="offset">the offset in the binary</param>
        public _RawSecurityDescriptor(byte[] binary, int offset)
        {
            if (binary == null)
            {
                throw new ArgumentNullException(nameof(binary));
            }

            if (offset < 0 || offset > binary.Length - 0x14)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }

            controlFlags = (SECURITY_DESCRIPTOR_Control)BitConverter.ToUInt16(binary, offset + 2);

            //Get owner sid
            int ownerStart = BitConverter.ToInt32(binary, offset + 4);

            if (ownerStart != 0)
            {
                ownerSid = new _SID(binary, ownerStart);
            }

            //Get group sid
            int groupStart = BitConverter.ToInt32(binary, offset + 8);

            if (groupStart != 0)
            {
                groupSid = new _SID(binary, groupStart);
            }

            //Get sacl
            int saclStart = BitConverter.ToInt32(binary, offset + 12);

            if (saclStart != 0)
            {
                sacl = new _RawAcl(binary, saclStart);
            }

            //Get dacl
            int daclStart = BitConverter.ToInt32(binary, offset + 16);

            if (daclStart != 0)
            {
                dacl = new _RawAcl(binary, daclStart);
            }
        }
        /// <summary>
        /// Create the binary from the buffer
        /// </summary>
        /// <param name="binary">The input binary</param>
        /// <param name="offset">The offset in the binary</param>
        public void GetBinaryForm(byte[] binary, int offset)
        {
            if (binary == null)
            {
                throw new ArgumentNullException(nameof(binary));
            }

            int binaryLength = Size;

            if (offset < 0 || offset > binary.Length - binaryLength)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }

            SECURITY_DESCRIPTOR_Control controlFlags = this.controlFlags;

            binary[offset]     = 1; //revision
            binary[offset + 1] = 0; //Sbz1
            DtypUtility.WriteUInt16ToByteArray((ushort)controlFlags, binary, offset + 2);

            int pointer = DtypUtility.SECURITY_DESCRIPTOR_FIXED_LENGTH;

            if (Owner != null)
            {
                DtypUtility.WriteInt32ToByteArray(pointer, binary, offset + 4);
                Owner.Value.GetBinaryForm(binary, offset + pointer);
                pointer += Owner.Value.Size;
            }
            else
            {
                DtypUtility.WriteInt32ToByteArray(0, binary, offset + 4);
            }

            if (Group != null)
            {
                DtypUtility.WriteInt32ToByteArray(pointer, binary, offset + 8);
                Group.Value.GetBinaryForm(binary, offset + pointer);
                pointer += Group.Value.Size;
            }
            else
            {
                DtypUtility.WriteInt32ToByteArray(0, binary, offset + 8);
            }

            _RawAcl sacl = this.SACL;

            if (this.controlFlags.HasFlag(SECURITY_DESCRIPTOR_Control.SACLPresent))
            {
                DtypUtility.WriteInt32ToByteArray(pointer, binary, offset + 12);
                sacl.GetBinaryForm(binary, offset + pointer);
                pointer += this.SACL.Size;
            }
            else
            {
                DtypUtility.WriteInt32ToByteArray(0, binary, offset + 12);
            }

            _RawAcl dacl = this.DACL;

            if (this.controlFlags.HasFlag(SECURITY_DESCRIPTOR_Control.DACLPresent))
            {
                DtypUtility.WriteInt32ToByteArray(pointer, binary, offset + 16);
                dacl.GetBinaryForm(binary, offset + pointer);
                pointer += this.DACL.Size;
            }
            else
            {
                DtypUtility.WriteInt32ToByteArray(0, binary, offset + 16);
            }
        }