public SecurityDescriptor(
			SecurityIdentifier owner,
			SecurityIdentifier group,
			AccessControlList dacl,
			AccessControlList sacl,
			SecurityDescriptorControl control)
		{
			// create security descriptor
			_pSd = CreateSecurityDescriptor(
				owner == null ? IntPtr.Zero : owner.Handle,
				group == null ? IntPtr.Zero : group.Handle,
				dacl == null ? IntPtr.Zero : dacl.Handle,
				sacl == null ? IntPtr.Zero : sacl.Handle,
				control);

			// query properties
			uint revision;
			uint controlFlags;
			if (!SecurityNative.GetSecurityDescriptorControl(_pSd, out controlFlags, out revision))
				throw new Win32Exception(Marshal.GetLastWin32Error());

			_revision = (int)revision;
			_control = (SecurityDescriptorControl)controlFlags;
			_owner = owner;
			_group = group;
			_dacl = dacl;
			_sacl = sacl;
		}
		public AccessControlEntry(SecurityIdentifier trustee, AccessControlEntryType aceType, AccessMask accessMask)
		{
			// parameters validation
			if (trustee == null)
				throw new ArgumentNullException("trustee");

			_aceType = aceType;
			_aceFlags = AccessControlEntryFlags.Normal;
			_accessMask = accessMask;
			Trustee = trustee;
		}
		internal AccessControlEntry(IntPtr pAce)
		{
			// parameters validation
			if (pAce == IntPtr.Zero)
				throw new ArgumentNullException("pAce");

			// read ACE properties
			_aceType = (AccessControlEntryType)MarshalHelper.ReadByte(pAce, typeof(SecurityNative.ACE), "AceType");
			_aceFlags = (AccessControlEntryFlags)MarshalHelper.ReadByte(pAce, typeof(SecurityNative.ACE), "AceFlags");
			_accessMask = (AccessMask)MarshalHelper.ReadInt32(pAce, typeof(SecurityNative.ACE), "AccessMask");

			// read SID
			IntPtr pSid = IntPtrHelper.Add(pAce, Marshal.OffsetOf(typeof(SecurityNative.ACE), "SidStart"));
			Trustee = new SecurityIdentifier(pSid, true);
		}
		internal SecurityDescriptor(IntPtr pSd, bool copy)
		{
			// get security descriptor information
			IntPtr pOwner;
			IntPtr pGroup;
			IntPtr pDacl;
			IntPtr pSacl;
			SecurityDescriptorControl control;

			GetSecurityDescriptorInfo(
				pSd,
				out pOwner,
				out pGroup,
				out pDacl,
				out pSacl,
				out control);

			bool copyStructs;
			if (copy)
			{
				// create security descriptor
				_pSd = CreateSecurityDescriptor(pOwner, pGroup, pDacl, pSacl, control);
				copyStructs = true;
			}
			else
			{
				// store pointer
				_pSd = new LocalAllocHandle(pSd);
				copyStructs = (control & SecurityDescriptorControl.SelfRelative) != 0;
			}

			// query properties
			uint revision;
			uint controlFlags;
			if (!SecurityNative.GetSecurityDescriptorControl(_pSd, out controlFlags, out revision))
				throw new Win32Exception(Marshal.GetLastWin32Error());

			_revision = (int)revision;
			_control = (SecurityDescriptorControl)controlFlags;

			if (pOwner != IntPtr.Zero)
				_owner = new SecurityIdentifier(pOwner, copyStructs);
			if (pGroup != IntPtr.Zero)
				_group = new SecurityIdentifier(pGroup, copyStructs);
			if (pDacl != IntPtr.Zero)
				_dacl = new AccessControlList(pDacl, copyStructs);
			if (pSacl != IntPtr.Zero)
				_sacl = new AccessControlList(pSacl, copyStructs);
		}
		public SecurityDescriptor(SecurityIdentifier owner, SecurityIdentifier group, AccessControlList dacl, AccessControlList sacl)
			: this(owner, group, dacl, sacl, 0)
		{
		}
		/// <summary>
		/// Compares two SID prefixes
		/// </summary>
		public bool ComparePrefix(SecurityIdentifier sid)
		{
			return SecurityNative.EqualPrefixSid(_pSid, sid.Handle);
		}
		/// <summary>
		/// Returns account name for the SID
		/// </summary>
		public static string LookupAccount(string systemName, SecurityIdentifier accountSid)
		{
			// parameters validation
			if (accountSid == null)
				throw new ArgumentNullException("accountSid");

			uint cbAccountName = 256;
			IntPtr pAccountName = IntPtr.Zero;

			uint cbDomainName = 256;
			IntPtr pDomainName = IntPtr.Zero;

			try
			{
				while (true)
				{
					// allocate buffers
					pAccountName = Win32.LocalAlloc(Win32.LMEM_FIXED, cbAccountName);
					pDomainName = Win32.LocalAlloc(Win32.LMEM_FIXED, cbDomainName);

					if ((pAccountName == IntPtr.Zero) || (pDomainName == IntPtr.Zero))
						throw new Win32Exception(Marshal.GetLastWin32Error());

					// lookup for account
					int accountType;
					if (SecurityNative.LookupAccountSid(
						systemName,
						accountSid.Handle,
						pAccountName,
						ref cbAccountName,
						pDomainName,
						ref cbDomainName,
						out accountType))
					{
						return Marshal.PtrToStringUni(pDomainName) + "\\" + Marshal.PtrToStringUni(pAccountName);
					}
					else
					{
						int error = Marshal.GetLastWin32Error();
						if (error != Win32.ERROR_OUTOFMEMORY)
							throw new Win32Exception(error);
					}
				}
			}
			finally
			{
				if (pAccountName != IntPtr.Zero)
					Win32.LocalFree(pAccountName);
				if (pDomainName != IntPtr.Zero)
					Win32.LocalFree(pDomainName);
			}
		}
        internal SecurityDescriptor(IntPtr pSd, bool copy)
        {
            // get security descriptor information
            IntPtr pOwner;
            IntPtr pGroup;
            IntPtr pDacl;
            IntPtr pSacl;
            SecurityDescriptorControl control;

            GetSecurityDescriptorInfo(
                pSd,
                out pOwner,
                out pGroup,
                out pDacl,
                out pSacl,
                out control);

            bool copyStructs;

            if (copy)
            {
                // create security descriptor
                _pSd        = CreateSecurityDescriptor(pOwner, pGroup, pDacl, pSacl, control);
                copyStructs = true;
            }
            else
            {
                // store pointer
                _pSd        = new LocalAllocHandle(pSd);
                copyStructs = (control & SecurityDescriptorControl.SelfRelative) != 0;
            }

            // query properties
            uint revision;
            uint controlFlags;

            if (!SecurityNative.GetSecurityDescriptorControl(_pSd, out controlFlags, out revision))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            _revision = (int)revision;
            _control  = (SecurityDescriptorControl)controlFlags;

            if (pOwner != IntPtr.Zero)
            {
                _owner = new SecurityIdentifier(pOwner, copyStructs);
            }
            if (pGroup != IntPtr.Zero)
            {
                _group = new SecurityIdentifier(pGroup, copyStructs);
            }
            if (pDacl != IntPtr.Zero)
            {
                _dacl = new AccessControlList(pDacl, copyStructs);
            }
            if (pSacl != IntPtr.Zero)
            {
                _sacl = new AccessControlList(pSacl, copyStructs);
            }
        }
 public SecurityDescriptor(SecurityIdentifier owner, SecurityIdentifier group, AccessControlList dacl, AccessControlList sacl)
     : this(owner, group, dacl, sacl, 0)
 {
 }
 /// <summary>
 /// Compares two SID prefixes
 /// </summary>
 public bool ComparePrefix(SecurityIdentifier sid)
 {
     return(SecurityNative.EqualPrefixSid(_pSid, sid.Handle));
 }
        /// <summary>
        /// Returns account name for the SID
        /// </summary>
        public static string LookupAccount(string systemName, SecurityIdentifier accountSid)
        {
            // parameters validation
            if (accountSid == null)
            {
                throw new ArgumentNullException("accountSid");
            }

            uint   cbAccountName = 256;
            IntPtr pAccountName  = IntPtr.Zero;

            uint   cbDomainName = 256;
            IntPtr pDomainName  = IntPtr.Zero;

            try
            {
                while (true)
                {
                    // allocate buffers
                    pAccountName = Win32.LocalAlloc(Win32.LMEM_FIXED, cbAccountName);
                    pDomainName  = Win32.LocalAlloc(Win32.LMEM_FIXED, cbDomainName);

                    if ((pAccountName == IntPtr.Zero) || (pDomainName == IntPtr.Zero))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    // lookup for account
                    int accountType;
                    if (SecurityNative.LookupAccountSid(
                            systemName,
                            accountSid.Handle,
                            pAccountName,
                            ref cbAccountName,
                            pDomainName,
                            ref cbDomainName,
                            out accountType))
                    {
                        return(Marshal.PtrToStringUni(pDomainName) + "\\" + Marshal.PtrToStringUni(pAccountName));
                    }
                    else
                    {
                        int error = Marshal.GetLastWin32Error();
                        if (error != Win32.ERROR_OUTOFMEMORY)
                        {
                            throw new Win32Exception(error);
                        }
                    }
                }
            }
            finally
            {
                if (pAccountName != IntPtr.Zero)
                {
                    Win32.LocalFree(pAccountName);
                }
                if (pDomainName != IntPtr.Zero)
                {
                    Win32.LocalFree(pDomainName);
                }
            }
        }