diff --git a/PInvoke/Security/AdvApi32/WinNT.Extensions.cs b/PInvoke/Security/AdvApi32/WinNT.Extensions.cs
new file mode 100644
index 00000000..ce48a19a
--- /dev/null
+++ b/PInvoke/Security/AdvApi32/WinNT.Extensions.cs
@@ -0,0 +1,154 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using Vanara.Extensions;
+using static Vanara.PInvoke.AdvApi32;
+
+namespace Vanara.PInvoke
+{
+ /// Extension methods for PACE, PACL and PSECURITY_DESCRIPTOR.
+ public static class WinNTExtensions
+ {
+ /// Gets the number of ACEs held by an ACL.
+ /// The pointer to the ACL structure to query.
+ /// The ace count.
+ public static uint AceCount(this PACL pACL) => IsValidAcl(pACL) && GetAclInformation(pACL, out ACL_SIZE_INFORMATION si) ? si.AceCount : 0;
+
+ /// Gets the total number of bytes allocated to the ACL.
+ /// The pointer to the ACL structure to query.
+ /// The total of the free and used bytes in the ACL.
+ public static uint BytesAllocated(this PACL pACL) => IsValidAcl(pACL) && GetAclInformation(pACL, out ACL_SIZE_INFORMATION si) ? si.AclBytesFree + si.AclBytesInUse : 0;
+
+ /// The GetAce function obtains a pointer to an access control entry (ACE) in an access control list (ACL).
+ /// A pointer to an ACL that contains the ACE to be retrieved.
+ ///
+ /// The index of the ACE to be retrieved. A value of zero corresponds to the first ACE in the ACL, a value of one to the second ACE,
+ /// and so on.
+ ///
+ /// A pointer to the ACE.
+ public static PACE GetAce(this PACL pAcl, uint aceIndex)
+ {
+ Win32Error.ThrowLastErrorIfFalse(AdvApi32.GetAce(pAcl, aceIndex, out var acePtr));
+ return acePtr;
+ }
+
+ /// Enumerates the ACEs in an ACL.
+ /// A pointer to an ACL that contains the ACE to be retrieved.
+ /// A sequence of PACE values from the ACL.
+ public static IEnumerable EnumerateAces(this PACL pAcl)
+ {
+ for (var i = 0U; i < pAcl.AceCount(); i++)
+ yield return GetAce(pAcl, i);
+ }
+
+ /// Gets the Flags for an ACE, if defined.
+ /// A pointer to an ACE.
+ /// The Flags value, if this is an object ACE, otherwise .
+ /// pAce
+ public static AdvApi32.ObjectAceFlags? GetFlags(this PACE pAce)
+ {
+ if (pAce.IsNull) throw new ArgumentNullException(nameof(pAce));
+ return !pAce.IsObjectAce() ? null : pAce.DangerousGetHandle().ToStructure().Flags;
+ }
+
+ /// Gets the header for an ACE.
+ /// A pointer to an ACE.
+ /// The value.
+ /// pAce
+ public static ACE_HEADER GetHeader(this PACE pAce) => !pAce.IsNull ? pAce.DangerousGetHandle().ToStructure() : throw new ArgumentNullException(nameof(pAce));
+
+ /// Gets the InheritedObjectType for an ACE, if defined.
+ /// A pointer to an ACE.
+ /// The InheritedObjectType value, if this is an object ACE, otherwise .
+ /// pAce
+ public static Guid? GetInheritedObjectType(this PACE pAce)
+ {
+ if (pAce.IsNull) throw new ArgumentNullException(nameof(pAce));
+ return !pAce.IsObjectAce() ? null : pAce.DangerousGetHandle().ToStructure().InheritedObjectType;
+ }
+
+ /// Gets the mask for an ACE.
+ /// A pointer to an ACE.
+ /// The ACCESS_MASK value.
+ /// pAce
+ public static uint GetMask(this PACE pAce) => !pAce.IsNull ? pAce.DangerousGetHandle().ToStructure().Mask : throw new ArgumentNullException(nameof(pAce));
+
+ /// Gets the ObjectType for an ACE, if defined.
+ /// A pointer to an ACE.
+ /// The ObjectType value, if this is an object ACE, otherwise .
+ /// pAce
+ public static Guid? GetObjectType(this PACE pAce)
+ {
+ if (pAce.IsNull) throw new ArgumentNullException(nameof(pAce));
+ return !pAce.IsObjectAce() ? null : pAce.DangerousGetHandle().ToStructure().ObjectType;
+ }
+
+ /// Gets the SID for an ACE.
+ /// A pointer to an ACE.
+ /// The SID value.
+ /// pAce
+ public static SafePSID GetSid(this PACE pAce)
+ {
+ if (pAce.IsNull) throw new ArgumentNullException(nameof(pAce));
+ var offset = Marshal.SizeOf(typeof(ACE_HEADER)) + sizeof(uint);
+ if (pAce.IsObjectAce()) offset += sizeof(uint) + Marshal.SizeOf(typeof(Guid)) * 2;
+ unsafe
+ {
+ return SafePSID.CreateFromPtr((IntPtr)((byte*)pAce.DangerousGetHandle() + offset));
+ }
+ }
+
+ /// Determines if a ACE is an object ACE.
+ /// A pointer to an ACE.
+ /// if is this is an object ACE; otherwise, .
+ /// pAce
+ /// pAce - Unknown ACE type.
+ public static bool IsObjectAce(this PACE pAce)
+ {
+ if (pAce.IsNull) throw new ArgumentNullException(nameof(pAce));
+ var aceType = (byte)GetHeader(pAce).AceType;
+ if (aceType > 0x15) throw new ArgumentOutOfRangeException(nameof(pAce), "Unknown ACE type.");
+ return (aceType >= 0x5 && aceType <= 0x8) || aceType == 0xB || aceType == 0xC || aceType == 0xF || aceType == 0x10;
+ }
+
+ /// Determines whether the security descriptor is self-relative.
+ /// The pointer to the SECURITY_DESCRIPTOR structure to query.
+ /// true if it is self-relative; otherwise, false.
+ public static bool IsSelfRelative(this PSECURITY_DESCRIPTOR pSD) => GetSecurityDescriptorControl(pSD, out var ctrl, out _) ? ctrl.IsFlagSet(SECURITY_DESCRIPTOR_CONTROL.SE_SELF_RELATIVE) : throw Win32Error.GetLastError().GetException();
+
+ /// Validates an access control list (ACL).
+ /// The pointer to the ACL structure to query.
+ /// true if the ACL is valid; otherwise, false.
+ public static bool IsValidAcl(this PACL pAcl) => IsValidAcl(pAcl);
+
+ /// Determines whether the components of a security descriptor are valid.
+ /// The pointer to the SECURITY_DESCRIPTOR structure to query.
+ ///
+ /// true if the components of the security descriptor are valid. If any of the components of the security descriptor are not
+ /// valid, the return value is false.
+ ///
+ public static bool IsValidSecurityDescriptor(this PSECURITY_DESCRIPTOR pSD) => IsValidSecurityDescriptor(pSD);
+
+ /// Gets the size, in bytes, of an ACE.
+ /// The pointer to the ACE structure to query.
+ /// The size, in bytes, of the ACE.
+ public static uint Length(this PACE pAce)
+ {
+ unsafe
+ {
+ var p = (ACE_HEADER*)(void*)pAce.DangerousGetHandle();
+ return p == null ? 0U : p->AceSize;
+ }
+ }
+
+ /// Gets the size, in bytes, of an ACL. If the ACL is not valid, 0 is returned.
+ /// The pointer to the ACL structure to query.
+ /// The size, in bytes, of an ACL. If the ACL is not valid, 0 is returned.
+ public static uint Length(this PACL pACL) => IsValidAcl(pACL) && GetAclInformation(pACL, out ACL_SIZE_INFORMATION si) ? si.AclBytesInUse : 0;
+
+ /// Gets the size, in bytes, of a security descriptor. If it is not valid, 0 is returned.
+ /// The pointer to the SECURITY_DESCRIPTOR structure to query.
+ /// The size, in bytes, of a security descriptor. If it is not valid, 0 is returned.
+ public static uint Length(this PSECURITY_DESCRIPTOR pSD) => IsValidSecurityDescriptor(pSD) ? GetSecurityDescriptorLength(pSD) : 0U;
+ }
+}
\ No newline at end of file
diff --git a/PInvoke/Security/AdvApi32/WinNT.cs b/PInvoke/Security/AdvApi32/WinNT.cs
index bc3c912f..70eca830 100644
--- a/PInvoke/Security/AdvApi32/WinNT.cs
+++ b/PInvoke/Security/AdvApi32/WinNT.cs
@@ -4979,128 +4979,4 @@ namespace Vanara.PInvoke
public string ToString(SECURITY_INFORMATION secInfo) => ConvertSecurityDescriptorToStringSecurityDescriptor(handle, secInfo);
}
}
-
- /// Extension methods for PACE, PACL and PSECURITY_DESCRIPTOR.
- public static class WinNTExtensions
- {
- /// Gets the number of ACEs held by an ACL.
- /// The pointer to the ACL structure to query.
- /// The ace count.
- public static uint AceCount(this PACL pACL) => AdvApi32.IsValidAcl(pACL) && AdvApi32.GetAclInformation(pACL, out AdvApi32.ACL_SIZE_INFORMATION si) ? si.AceCount : 0;
-
- /// Gets the total number of bytes allocated to the ACL.
- /// The pointer to the ACL structure to query.
- /// The total of the free and used bytes in the ACL.
- public static uint BytesAllocated(this PACL pACL) => AdvApi32.IsValidAcl(pACL) && AdvApi32.GetAclInformation(pACL, out AdvApi32.ACL_SIZE_INFORMATION si) ? si.AclBytesFree + si.AclBytesInUse : 0;
-
- /// Gets the Flags for an ACE, if defined.
- /// A pointer to an ACE.
- /// The Flags value, if this is an object ACE, otherwise .
- /// pAce
- public static ObjectAceFlags? GetFlags(this PACE pAce)
- {
- if (pAce.IsNull) throw new ArgumentNullException(nameof(pAce));
- return !pAce.IsObjectAce() ? null : (ObjectAceFlags?)pAce.DangerousGetHandle().ToStructure().Flags;
- }
-
- /// Gets the header for an ACE.
- /// A pointer to an ACE.
- /// The value.
- /// pAce
- public static AdvApi32.ACE_HEADER GetHeader(this PACE pAce) => !pAce.IsNull ? pAce.DangerousGetHandle().ToStructure() : throw new ArgumentNullException(nameof(pAce));
-
- /// Gets the InheritedObjectType for an ACE, if defined.
- /// A pointer to an ACE.
- /// The InheritedObjectType value, if this is an object ACE, otherwise .
- /// pAce
- public static Guid? GetInheritedObjectType(this PACE pAce)
- {
- if (pAce.IsNull) throw new ArgumentNullException(nameof(pAce));
- return !pAce.IsObjectAce() ? null : (Guid?)pAce.DangerousGetHandle().ToStructure().InheritedObjectType;
- }
-
- /// Gets the mask for an ACE.
- /// A pointer to an ACE.
- /// The ACCESS_MASK value.
- /// pAce
- public static uint GetMask(this PACE pAce) => !pAce.IsNull ? pAce.DangerousGetHandle().ToStructure().Mask : throw new ArgumentNullException(nameof(pAce));
-
- /// Gets the ObjectType for an ACE, if defined.
- /// A pointer to an ACE.
- /// The ObjectType value, if this is an object ACE, otherwise .
- /// pAce
- public static Guid? GetObjectType(this PACE pAce)
- {
- if (pAce.IsNull) throw new ArgumentNullException(nameof(pAce));
- return !pAce.IsObjectAce() ? null : (Guid?)pAce.DangerousGetHandle().ToStructure().ObjectType;
- }
-
- /// Gets the SID for an ACE.
- /// A pointer to an ACE.
- /// The SID value.
- /// pAce
- public static AdvApi32.SafePSID GetSid(this PACE pAce)
- {
- if (pAce.IsNull) throw new ArgumentNullException(nameof(pAce));
- var offset = Marshal.SizeOf(typeof(AdvApi32.ACE_HEADER)) + sizeof(uint);
- if (pAce.IsObjectAce()) offset += sizeof(uint) + Marshal.SizeOf(typeof(Guid)) * 2;
- unsafe
- {
- return AdvApi32.SafePSID.CreateFromPtr((IntPtr)((byte*)pAce.DangerousGetHandle() + offset));
- }
- }
-
- /// Determines if a ACE is an object ACE.
- /// A pointer to an ACE.
- /// if is this is an object ACE; otherwise, .
- /// pAce
- /// pAce - Unknown ACE type.
- public static bool IsObjectAce(this PACE pAce)
- {
- if (pAce.IsNull) throw new ArgumentNullException(nameof(pAce));
- var aceType = (byte)GetHeader(pAce).AceType;
- if (aceType > 0x15) throw new ArgumentOutOfRangeException(nameof(pAce), "Unknown ACE type.");
- return (aceType >= 0x5 && aceType <= 0x8) || aceType == 0xB || aceType == 0xC || aceType == 0xF || aceType == 0x10;
- }
-
- /// Determines whether the security descriptor is self-relative.
- /// The pointer to the SECURITY_DESCRIPTOR structure to query.
- /// true if it is self-relative; otherwise, false.
- public static bool IsSelfRelative(this PSECURITY_DESCRIPTOR pSD) => AdvApi32.GetSecurityDescriptorControl(pSD, out var ctrl, out _) ? ctrl.IsFlagSet(AdvApi32.SECURITY_DESCRIPTOR_CONTROL.SE_SELF_RELATIVE) : throw Win32Error.GetLastError().GetException();
-
- /// Validates an access control list (ACL).
- /// The pointer to the ACL structure to query.
- /// true if the ACL is valid; otherwise, false.
- public static bool IsValidAcl(this PACL pAcl) => AdvApi32.IsValidAcl(pAcl);
-
- /// Determines whether the components of a security descriptor are valid.
- /// The pointer to the SECURITY_DESCRIPTOR structure to query.
- ///
- /// true if the components of the security descriptor are valid. If any of the components of the security descriptor are not
- /// valid, the return value is false.
- ///
- public static bool IsValidSecurityDescriptor(this PSECURITY_DESCRIPTOR pSD) => AdvApi32.IsValidSecurityDescriptor(pSD);
-
- /// Gets the size, in bytes, of an ACE.
- /// The pointer to the ACE structure to query.
- /// The size, in bytes, of the ACE.
- public static uint Length(this PACE pAce)
- {
- unsafe
- {
- var p = (AdvApi32.ACE_HEADER*)(void*)pAce.DangerousGetHandle();
- return p == null ? 0U : p->AceSize;
- }
- }
-
- /// Gets the size, in bytes, of an ACL. If the ACL is not valid, 0 is returned.
- /// The pointer to the ACL structure to query.
- /// The size, in bytes, of an ACL. If the ACL is not valid, 0 is returned.
- public static uint Length(this PACL pACL) => AdvApi32.IsValidAcl(pACL) && AdvApi32.GetAclInformation(pACL, out AdvApi32.ACL_SIZE_INFORMATION si) ? si.AclBytesInUse : 0;
-
- /// Gets the size, in bytes, of a security descriptor. If it is not valid, 0 is returned.
- /// The pointer to the SECURITY_DESCRIPTOR structure to query.
- /// The size, in bytes, of a security descriptor. If it is not valid, 0 is returned.
- public static uint Length(this PSECURITY_DESCRIPTOR pSD) => AdvApi32.IsValidSecurityDescriptor(pSD) ? AdvApi32.GetSecurityDescriptorLength(pSD) : 0U;
- }
}
\ No newline at end of file