/// <summary> /// Do an access check between a security descriptor and a token to determine the allowed access. /// </summary> /// <param name="sd">The security descriptor</param> /// <param name="token">The access token.</param> /// <param name="access_rights">The set of access rights to check against</param> /// <param name="generic_mapping">The type specific generic mapping (get from corresponding NtType entry).</param> /// <returns>The allowed access mask as a unsigned integer.</returns> /// <exception cref="NtException">Thrown if an error occurred in the access check.</exception> public static uint GetAllowedAccess(SecurityDescriptor sd, NtToken token, GenericAccessRights access_rights, GenericMapping generic_mapping) { if (sd == null) { throw new ArgumentNullException("sd"); } if (token == null) { throw new ArgumentNullException("token"); } using (var sd_buffer = sd.ToSafeBuffer()) { using (NtToken imp_token = token.DuplicateToken(SecurityImpersonationLevel.Identification)) { uint granted_access; NtStatus result_status; using (var privs = new SafePrivilegeSetBuffer()) { int buffer_length = privs.Length; NtSystemCalls.NtAccessCheck(sd_buffer, imp_token.Handle, (uint)access_rights, ref generic_mapping, privs, ref buffer_length, out granted_access, out result_status).ToNtException(); if (result_status.IsSuccess()) { return(granted_access); } return(0); } } } }