视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Accessingbitregistryfroma32bitprocess
2020-11-09 07:24:51 责编:小采
文档

As you may know, Windows is virtualizing some parts of the registry under bit. So if you try to open, for example, this key : “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\90″, from a 32 bit C# application running on a 6

As you may know, Windows is virtualizing some parts of the registry under bit.

So if you try to open, for example, this key : “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\90″, from a 32 bit C# application running on a bit system, you will be redirected to : “HKEY_LOCAL_MACHINE\SOFTWARE\Wow32Node\Microsoft\Microsoft SQL Server\90″

Why ? Because Windows uses the Wow32Node registry entry to present a separate view of HKEY_LOCAL_MACHINE\SOFTWARE for 32 bit applications that runs on a bit systems.

If you want to explicitly open the bit view of the registry, here is what you have to perform :

You are using VS 2010 and version 4.x of the .NET framework

It’s really simple, all you need to do is, instead of doing :

//Will redirect you to the 32 bit view

RegistryKey sqlsrvKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server\90");

do the following :

RegistryKey localMachineXView = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry);

RegistryKey sqlsrvKey = localMachineXView.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server\90");


Prior versions of the .NET framework

For the prior versions of the framework, we have to use P/Invoke and call the function RegOpenKeyExW with parameter KEY_WOW_KEY

enum RegWowOptions

{

None = 0,

KEY_WOW_KEY = 0x0100,

KEY_WOW_32KEY = 0x0200

}

enum RegistryRights

{

ReadKey = 131097,

WriteKey = 131078

}

///

/// Open a registry key using the Wow node instead of the default 32-bit node.

///

/// Parent key to the key to be opened.

/// Name of the key to be opened

/// Whether or not this key is writable

/// 32-bit node or -bit node

///

static RegistryKey _openSubKey(RegistryKey parentKey, string subKeyName, bool writable, RegWowOptions options)

{

//Sanity check

if (parentKey == null || _getRegistryKeyHandle(parentKey) == IntPtr.Zero)

{

return null;

}

//Set rights

int rights = (int)RegistryRights.ReadKey;

if (writable)

rights = (int)RegistryRights.WriteKey;

//Call the native function >.<

int subKeyHandle, result = RegOpenKeyEx(_getRegistryKeyHandle(parentKey), subKeyName, 0, rights | (int)options, out subKeyHandle);

//If we errored, return null

if (result != 0)

{

return null;

}

//Get the key represented by the pointer returned by RegOpenKeyEx

RegistryKey subKey = _pointerToRegistryKey((IntPtr)subKeyHandle, writable, false);

return subKey;

}

///

/// Get a pointer to a registry key.

///

/// Registry key to obtain the pointer of.

/// Pointer to the given registry key.

static IntPtr _getRegistryKeyHandle(RegistryKey registryKey)

{

//Get the type of the RegistryKey

Type registryKeyType = typeof(RegistryKey);

//Get the FieldInfo of the 'hkey' member of RegistryKey

System.Reflection.FieldInfo fieldInfo =

registryKeyType.GetField("hkey", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

//Get the handle held by hkey

SafeHandle handle = (SafeHandle)fieldInfo.GetValue(registryKey);

//Get the unsafe handle

IntPtr dangerousHandle = handle.DangerousGetHandle();

return dangerousHandle;

}

///

/// Get a registry key from a pointer.

///

/// Pointer to the registry key

/// Whether or not the key is writable.

/// Whether or not we own the handle.

/// Registry key pointed to by the given pointer.

static RegistryKey _pointerToRegistryKey(IntPtr hKey, bool writable, bool ownsHandle)

{

//Get the BindingFlags for private contructors

System.Reflection.BindingFlags privateConstructors = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic;

//Get the Type for the SafeRegistryHandle

Type safeRegistryHandleType = typeof(Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid).Assembly.GetType("Microsoft.Win32.SafeHandles.SafeRegistryHandle");

//Get the array of types matching the args of the ctor we want

Type[] safeRegistryHandleCtorTypes = new Type[] { typeof(IntPtr), typeof(bool) };

//Get the constructorinfo for our object

System.Reflection.ConstructorInfo safeRegistryHandleCtorInfo = safeRegistryHandleType.GetConstructor(

privateConstructors, null, safeRegistryHandleCtorTypes, null);

//Invoke the constructor, getting us a SafeRegistryHandle

Object safeHandle = safeRegistryHandleCtorInfo.Invoke(new Object[] { hKey, ownsHandle });

//Get the type of a RegistryKey

Type registryKeyType = typeof(RegistryKey);

//Get the array of types matching the args of the ctor we want

Type[] registryKeyConstructorTypes = new Type[] { safeRegistryHandleType, typeof(bool) };

//Get the constructorinfo for our object

System.Reflection.ConstructorInfo registryKeyCtorInfo = registryKeyType.GetConstructor(

privateConstructors, null, registryKeyConstructorTypes, null);

//Invoke the constructor, getting us a RegistryKey

RegistryKey resultKey = (RegistryKey)registryKeyCtorInfo.Invoke(new Object[] { safeHandle, writable });

//return the resulting key

return resultKey;

}

[DllImport("advapi32.dll", CharSet = CharSet.Auto)]

public static extern int RegOpenKeyEx(IntPtr hKey, string subKey, int ulOptions, int samDesired, out int phkResult);


Then we can open our registry key like this :

RegistryKey sqlsrvKey = _openSubKey(Registry.LocalMachine, @"SOFTWARE\Microsoft\Microsoft SQL Server\90", false, RegWowOptions.KEY_WOW_KEY);

As you can see, the framework 4 make our life easier.


Referenced from: http://dotnetgalactics.wordpress.com/2010/05/10/accessing--bit-registry-from-a-32-bit-process/

下载本文
显示全文
专题