Using RegSetKeySecurity to avoid registry redirection
Asked Answered
C

2

1

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);
Constitutionalism answered 27/7, 2011 at 22:21 Comment(0)
C
0

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
);
Constitutionalism answered 7/9, 2011 at 22:22 Comment(0)
P
3

To avoid Registry redirection, you could do something like this...

SafeRegistryHandle handle = rootKey.Handle;

RegistryKey rootKey32 = RegistryKey.FromHandle(handle, RegistryView.Registry32);

RegistryKey rootKey64 = RegistryKey.FromHandle(handle, RegistryView.Registry64);

You can then use rootKey32 or rootKey64 to open a subkey and you'll get the subkey of the view requested.

At least it works in the few test cases I've tried. And, according to the documentation for FromHandle...

The view parameter for this method is used in subsequent operations, such as opening subkeys

Philbo answered 28/7, 2011 at 4:12 Comment(1)
If you're working with 2.0 perhaps it would be easier to use the Common Language Runtime support in C++ to implement your SetKeyAccessControl function. That way you could use native C++ to call RegOpenKeyEx supplying the appropriate flag in the samDesired parameter.Philbo
C
0

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
);
Constitutionalism answered 7/9, 2011 at 22:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.