static ACCESS_ALLOWED_ACE GetAce(IntPtr pDacl, string sid)
{
var AclSize = new ACL_SIZE_INFORMATION();
GetAclInformation(pDacl, ref AclSize, (uint) Marshal.SizeOf(typeof(ACL_SIZE_INFORMATION)), ACL_INFORMATION_CLASS.AclSizeInformation);
for (var i = 0; i < AclSize.AceCount; i++)
{
IntPtr pAce;
GetAce(pDacl, i, out pAce);
var ace = (ACCESS_ALLOWED_ACE) Marshal.PtrToStructure(pAce, typeof(ACCESS_ALLOWED_ACE));
var iter = (IntPtr) ((long) pAce + (long) Marshal.OffsetOf(typeof(ACCESS_ALLOWED_ACE), "SidStart"));
var size = GetLengthSid(iter);
var bSID = new byte[size];
Marshal.Copy(iter, bSID, 0, size);
IntPtr ptrSid;
ConvertSidToStringSid(bSID, out ptrSid);
var strSID = Marshal.PtrToStringAuto(ptrSid);
if (strSID == sid)
{
return ace;
}
}
throw new Exception($"No ACE for SID {sid} found in security descriptor");
}
}