Search code examples
c#.net-2.0registryadvapi32

Using RegSetKeySecurity to avoid registry redirection


In order to avoid registry redirection to Wow64 keys, how to translate the following code that uses Microsoft.Win32 APIs

public void SetKeyAccessControl(
            RegistryKey rootKey, string subKeyName, string identity, 
            RegistryRights rights, InheritanceFlags inheritanceFlags,
            PropagationFlags propagationFlags, AccessControlType accessType)
{
   using (RegistryKey regKey = rootKey.OpenSubKey(subKeyName, true))
   {
       RegistrySecurity acl = new RegistrySecurity();
       RegistryAccessRule rule = new RegistryAccessRule(identity, rights, inheritanceFlags, propagationFlags, accessType);
       acl.AddAccessRule(rule);

       regKey.SetAccessControl(acl);
   }            
}

into using advapi32 RegSetKeySecurity API

[DllImport(@"advapi32.dll", EntryPoint = "RegSetKeySecurity", SetLastError = true)]
internal static extern int RegSetKeySecurity(IntPtr handle, uint securityInformation, IntPtr pSecurityDescriptor);

Solution

  • Another native method needs to be involved and given an SDDL, the following code sets ACLs on the right registry key:

    
    [DllImport("Advapi32.dll", CallingConvention = CallingConvention.Winapi, SetLastError = true, CharSet = CharSet.Auto)]
    internal static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string stringSecurityDescriptor, int stringSDRevision, out IntPtr ppSecurityDescriptor, ref int securityDescriptorSize);
    
    string sddl = "...";
    IntPtr secDescriptor = IntPtr.Zero;
    int size = 0;
    ConvertStringSecurityDescriptorToSecurityDescriptor
       (
          sddl,
          1,                              // revision 1
          out secDescriptor,
          ref size
       );
    
    // get handle with RegOpenKeyEx
    
    RegSetKeySecurity
    (
         handle,
         0x00000004,                      // DACL_SECURITY_INFORMATION
         secDescriptor
    );