public AccessControlList(AccessControlEntry[] aces)
		{
			// parameters validation
			if (aces == null)
				throw new ArgumentNullException("aces");

			// create aces list
			int listSize;
			LocalAllocHandle pAceList = CreateAceList(aces, out listSize);

			// allocate memory for ACL
			int aclSize = SecurityNative.ACL.Size + listSize;
			_pAcl = new LocalAllocHandle(aclSize);

			// intialize ACL
			if (!SecurityNative.InitializeAcl(_pAcl, (uint)aclSize, SecurityNative.ACL_REVISION))
				throw new Win32Exception(Marshal.GetLastWin32Error());

			// add aces to ACL
			if (!SecurityNative.AddAce(_pAcl, SecurityNative.ACL_REVISION, 0, pAceList, (uint)listSize))
				throw new Win32Exception(Marshal.GetLastWin32Error());

			_revision = (int)SecurityNative.ACL_REVISION;
			_size = aclSize;
			_count = aces.Length;
			_aces = aces;
		}
		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 SecurityIdentifier(byte[] authorityIdentifier, uint[] rids)
        {
            // parameters validation
            if (authorityIdentifier == null)
                throw new ArgumentNullException("authorityIdentifier");
            if (rids == null)
                throw new ArgumentNullException("rids");

            // get SID size
            var subAuthCount = (byte)rids.Length;
            _size = SecurityNative.GetSidLengthRequired(subAuthCount);

            // allocate memory for security identifier
            _pSid = new LocalAllocHandle(_size);

            // initialize security identifier
            GCHandle gcAuthId = GCHandle.Alloc(authorityIdentifier, GCHandleType.Pinned);
            if (!SecurityNative.InitializeSid(_pSid, gcAuthId.AddrOfPinnedObject(), subAuthCount))
                throw new Win32Exception(Marshal.GetLastWin32Error());
            gcAuthId.Free();

            // initialize subauthorities
            for (byte i = 0; i < subAuthCount; ++i)
            {
                Marshal.WriteInt32(SecurityNative.GetSidSubAuthority(_pSid, i), (int)rids[i]);
            }
        }
        public SecurityIdentifier(string sid)
        {
            // parameters validation
            if (sid == null)
                throw new ArgumentNullException("sid");

            // convert string to SID
            IntPtr pSid;
            if (!SecurityNative.ConvertStringSidToSid(sid, out pSid))
                throw new Win32Exception(Marshal.GetLastWin32Error());

            // store pointer
            _pSid = new LocalAllocHandle(pSid);

            // get SID size
            _size = SecurityNative.GetLengthSid(pSid);
        }
		internal AccessControlList(IntPtr pAcl, bool copy)
		{
			// parameters validation
			if (pAcl == IntPtr.Zero)
				throw new ArgumentNullException("pAcl");

			// read properties
			_revision = MarshalHelper.ReadByte(pAcl, typeof(SecurityNative.ACL), "Revision");
			_size = MarshalHelper.ReadInt16(pAcl, typeof(SecurityNative.ACL), "AclSize");
			_count = MarshalHelper.ReadInt16(pAcl, typeof(SecurityNative.ACL), "AceCount");

			if (copy)
			{
				// copy access list
				_pAcl = new LocalAllocHandle(_size);
				Win32.CopyMemory(_pAcl, pAcl, (uint)_size);
			}
			else
			{
				// store pointer
				_pAcl = new LocalAllocHandle(pAcl);
			}
		}
		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);
		}
		/// <summary>
		/// Creates security descriptor
		/// </summary>
		private static LocalAllocHandle CreateSecurityDescriptor(
			IntPtr pOwner,
			IntPtr pGroup,
			IntPtr pDacl,
			IntPtr pSacl,
			SecurityDescriptorControl control)
		{
			// correct control flags
			if (pDacl != IntPtr.Zero)
				control |= SecurityDescriptorControl.DaclPresent;
			if (pSacl != IntPtr.Zero)
				control |= SecurityDescriptorControl.SaclPresent;

			// allocate memory for security descriptor
			LocalAllocHandle pSd = new LocalAllocHandle(SecurityNative.SecurityDescriptor.Size);

			// initialize security descriptor
			if (!SecurityNative.InitializeSecurityDescriptor(pSd, SecurityNative.SECURITY_DESCRIPTOR_REVISION))
				throw new Win32Exception(Marshal.GetLastWin32Error());

			// set security descriptor control
			if (!SecurityNative.SetSecurityDescriptorControl(pSd, (uint)SecurityDescriptorControl.InheritenceMask, (uint)(control & SecurityDescriptorControl.InheritenceMask)))
				throw new Win32Exception(Marshal.GetLastWin32Error());

			// set SIDs
			if (!SecurityNative.SetSecurityDescriptorOwner(pSd, pOwner, (control & SecurityDescriptorControl.OwnerDefaulted) != 0))
				throw new Win32Exception(Marshal.GetLastWin32Error());
			if (!SecurityNative.SetSecurityDescriptorGroup(pSd, pGroup, (control & SecurityDescriptorControl.GroupDefaulted) != 0))
				throw new Win32Exception(Marshal.GetLastWin32Error());

			// set ACLs
			if (!SecurityNative.SetSecurityDescriptorDacl(pSd, (control & SecurityDescriptorControl.DaclPresent) != 0, pDacl, (control & SecurityDescriptorControl.DaclDefaulted) != 0))
				throw new Win32Exception(Marshal.GetLastWin32Error());
			if (!SecurityNative.SetSecurityDescriptorSacl(pSd, (control & SecurityDescriptorControl.SaclPresent) != 0, pSacl, (control & SecurityDescriptorControl.SaclDefaulted) != 0))
				throw new Win32Exception(Marshal.GetLastWin32Error());

			return pSd;
		}
		internal SecurityIdentifier(IntPtr pSid, bool copy)
		{
			// parameters validation
			if (pSid == IntPtr.Zero)
				throw new ArgumentNullException("pSid");

			// get SID size
			_size = SecurityNative.GetLengthSid(pSid);

			if (copy)
			{
				// allocate memory for security identifier
				_pSid = new LocalAllocHandle(_size);

				// copy security identifier
				if (!SecurityNative.CopySid((uint)_size, (IntPtr)_pSid, pSid))
					throw new Win32Exception(Marshal.GetLastWin32Error());
			}
			else
			{
				// store pointer
				_pSid = new LocalAllocHandle(pSid);
			}
		}
		/// <summary>
		/// Creates ACE list in memory
		/// </summary>
		private static LocalAllocHandle CreateAceList(AccessControlEntry[] aces, out int listSize)
		{
			// parameters validation
			if (aces == null)
				throw new ArgumentNullException("aces");

			// calculate list size
			listSize = 0;
			for (int i = 0; i < aces.Length; ++i)
			{
				listSize += aces[i].Size;
			}

			// allocate buffer for aces
			LocalAllocHandle pAceList = new LocalAllocHandle(listSize);

			// write aces to buffer
			IntPtr pAce = pAceList;
			for (int i = 0; i < aces.Length; ++i)
			{
				aces[i].UnsafeWrite(pAce);
				pAce = IntPtrHelper.Add(pAce, aces[i].Size);
			}

			return pAceList;
		}
 /// <summary>
 /// Initializes unmanaged Overlapped structure
 /// </summary>
 private void InitializeOverlapped()
 {
     _pOverlapped = new LocalAllocHandle(PipeNative.Overlapped.Size);
     _asyncEvent = new ManualResetEvent(false);
     Marshal.WriteIntPtr(_pOverlapped, PipeNative.Overlapped.hEventOffset, _asyncEvent.Handle);
 }