title: REVOKE_ACCESS : how to remove 'revoke' an inherited ACE?
body: <p>I have the code below working for various ACE changes and adds and revoking - it just does NOT work when I try and remove an ACE that is in the ACL (clearly there), but this ACE is inherited. </p>
  
  <p>The <code>SetEntriesInAcl()</code> for revoke of non-inherited ACEs works, reduces the ACL ACE count and the following <code>SetNamedSecurityInfo()</code> does the revoke and the ACE is gone. </p>
  
  <p>When the ACE is inherited though - both these API return <code>SUCCESS</code> - but the ACE is not removed/revoked, the ACL ACE count remains the same. </p>
  
  <p>I have also coded doing <code>DeleteAce()</code> but when that DACL is used in <code>SetNamedSecurityInfo()</code> again the RC is <code>SUCCESS</code> (no return codes) and the ACE remains for the folder I am dealing with - clearly there is a trick on how to remove an inherited ACE. </p>
  
  <p>Btw, for the same folder in question SUBINACL command line tool does the revoke of this inherited ACE without problem.</p>
  
  <pre><code>                 if( EqualSid( pSid_for_ace, pSid )  )
                      { /* ACE SID matched edit SID */
  
                      if( cmd_se_edit == SE_REM )
                         { /* remove */
  
                         rem_lst[ ace_idx ] = x;
  
                         exp_ace[ ace_idx ].grfAccessPermissions = dwAccessRights;
                         exp_ace[ ace_idx ].grfAccessMode        = REVOKE_ACCESS;
                         exp_ace[ ace_idx ].grfInheritance       = dwInheritance;
                         exp_ace[ ace_idx ].Trustee.TrusteeForm  = TRUSTEE_IS_SID;
                         exp_ace[ ace_idx ].Trustee.TrusteeType  = TRUSTEE_IS_WELL_KNOWN_GROUP;
                         exp_ace[ ace_idx ].Trustee.ptstrName    = pSid;
  
                         if( ace_idx &lt; (REMMAX-1) ) ++ace_idx;
  
                         } /* remove */
  
                      } /* ACE SID matched edit SID */
  
                pBA = (BYTE *)p_aceHdr;
  
                ace_sz = p_aceHdr-&gt;AceSize;
  
                p_aceHdr = (PACE_HEADER)&amp;pBA[ ace_sz ];
  
                } /* loop through ACEs */
  
  
             // Create a new ACL that merges the new ACE
             // into the existing DACL.
  
             if( ace_idx )
                { /* ACEs to remove */
  
                dwRes = SetEntriesInAcl( ace_idx, &amp;exp_ace[0],
                                                          pDacl, &amp;pNewDacl );
                if( ERROR_SUCCESS != dwRes )
                   {
                   printf( "SetEntriesInAcl Error %u\n", dwRes );
                   goto Cleanup2;
                   }
  
                // Attach the new ACL as the object's DACL.
  
                dwRes = SetNamedSecurityInfo(    ObjName,
                                                 ObjectType,
                                                 DACL_SECURITY_INFORMATION,
                                                 NULL,
                                                 NULL,
                                                pNewDacl,
                                                 NULL );
  
                if( ERROR_SUCCESS != dwRes )
                   {
                   rc3 = GetLastError();
                   printf( "SetNamedSecurityInfo Error %u\n", dwRes );
                   goto Cleanup2;
                   }
  
                } /* ACEs to remove */
  </code></pre>