Home  >  Article  >  Backend Development  >  Sample code for C# 32-bit program to access 64-bit registry

Sample code for C# 32-bit program to access 64-bit registry

黄舟
黄舟Original
2017-03-10 14:14:492434browse


 My last article has already explained the "difference between 32-bit programs and 64-bit programs in reading and writing the registry on 64-bit platforms", so what follows is To answer a question left over from the previous article: How do 32-bit programs access the 64-bit system registry (ie: the registry location accessed by 64-bit programs).

We already know:

①: Native mode 64-bit programs run in native mode, and access keys and storage are registered in the following Values ​​in the table subkey: HKEY_LOCAL_MACHINE\Software

 ②: 32-bit programs run in WOW64 mode, and access keys and values ​​are stored in the following registry subkey: HKEY_LOCAL_MACHINE\Software \WOW6432nod

Then to implement a 32-bit program to access 64-bit registry information, you must also know the following concepts: 1: File system steering. 2: Registry redirection (direction). 3: Registry reflection.

   ①:File system redirection

    32-bit processes cannot load 64-bit Dlls, and neither can 64-bit processes Load 32-bit Dll. The Windows system directory contains all installed applications and their Dll files. According to the rules we described,

it should be divided into directories for 64-bit applications and directories for 64-bit applications. Directory for 32-bit applications. If not, we would not be able to differentiate between 32-bit and 64-bit Dll files. For 64-bit applications, their files are usually placed in %windir%\system32 and %programfiles% (for example: c:\program files). For 32-bit applications, the files are usually under %windir%\syswow64 and

  C:\program files (x86). If we use a 32-bit program to access %windir%\system32, whether we use hard coding or other methods, the system will automatically give us

and redirect to %windir%\syswow64 . This redirection is turned on by default for every 32-bit application. But this kind of redirection is not always necessary for us. Then we can call the relevant API in C# to close and open this kind of redirection. There are three commonly used functions:

Wow64DisableWow64FsRedirection (turn off system redirection),

Wow64RevertWow64FsRedirection (turn on system redirection),

    Wow64EnableWow64FsRedirection (turn on system redirection).

However, Wow64EnableWow64FsRedirection is not reliable when used in nested applications, so the above Wow64RevertWow64FsRedirection is usually used to open the file system redirection

function. In C#, we can use DllImport to directly call these two functions.

   ②: Registry redirection (direction)

  To support 32-bit and 64-bit COM registration Along with program coexistence status, the WOW64 subsystem provides another view of the registry used by 32-bit programs. Using the registry

in the WOW64 subsystem redirects intercepted bit-level registry calls. Registry redirection also ensures that registry calls are directed to the correct branch in the registry.

 When we install a new program or run a program on a Windows x64 version of the computer, the registry call made by the 64-bit program accesses the HKEY_LOCAL_MACHINE\Software registry subkey

Does not redirect. WOW64 intercepts registry calls made by 32-bit programs to HKEY_LOCAL_MACHINE\Software and then redirects them to the
  HKEY_LOCAL_MACHINE\Software\WOW6432node subkey. By redirecting only 32-bit program calls, WOW64 ensures that programs always write to the corresponding registry subkey.

Registry redirection does not require program code modification, and the process is transparent to the user.

 ③: Registry reflection

Reflection makes two identical registries to support simultaneous The presence of a physical copy of the machine and WOW64 operations,

opens the 64-bit section of the registry at all times and registry reflection provides a real-time method of accommodating 32-bit.

Having briefly understood these, let’s talk about the specific implementation steps:

Turn off the 64-bit (file system) operation diversion

Obtain the handle of the operation Key value

Turn off the registry diversion (Disable registry reflection for specific items)

Get accessed Key value

Turn on registry redirection (enable registry reflection for specific items) )

                                                          int DllImport is used in the program, so the namespace must be introduced: System.Runtime.InteropServices】


Please see the code example below

1 using System;
  2  using System.Collections.Generic;
  3  using System.Linq;
  4  using System.Text;
  5  using Microsoft.Win32;
  6  using System.Runtime.InteropServices;
  7 
  8  namespace OperateRegistrationTable
  9 {
 10     class Programe
 11     {
 12         static void Main(string[] args)
 13         {
 14             string myParentKeyName = "HKEY_LOCAL_MACHINE";
 15             string mySubKeyName = @"SOFTWARE\EricSun\MyTestKey";
 16             string myKeyName = "MyKeyName";
 17 
 18             string value = string.Empty;
 19             value = Utility.Get64BitRegistryKey(myParentKeyName, mySubKeyName, myKeyName);
 20             Console.WriteLine("The Value is: {0}", value);
 21         }
 22     }
 23 
 24     public class Utility
 25     {
 26         #region 32位程序读写64注册表
 27 
 28         static UIntPtr HKEY_CLASSES_ROOT = (UIntPtr)0x80000000;
 29         static UIntPtr HKEY_CURRENT_USER = (UIntPtr)0x80000001;
 30         static UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002;
 31         static UIntPtr HKEY_USERS = (UIntPtr)0x80000003;
 32         static UIntPtr HKEY_CURRENT_CONFIG = (UIntPtr)0x80000005;
 33 
 34         // 关闭64位(文件系统)的操作转向
 35          [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 36         public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
 37         // 开启64位(文件系统)的操作转向
 38          [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 39         public static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr);    
 40    
 41         // 获取操作Key值句柄
 42          [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 43         public static extern uint RegOpenKeyEx(UIntPtr hKey, string lpSubKey, uint ulOptions, 
                                  int samDesired, out IntPtr phkResult);
 44         //关闭注册表转向(禁用特定项的注册表反射)
 45         [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 46         public static extern long RegDisableReflectionKey(IntPtr hKey);
 47         //使能注册表转向(开启特定项的注册表反射)
 48         [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 49         public static extern long RegEnableReflectionKey(IntPtr hKey);
 50         //获取Key值(即:Key值句柄所标志的Key对象的值)
 51         [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 52         private static extern int RegQueryValueEx(IntPtr hKey, string lpValueName, int lpReserved,
 53                                                   out uint lpType, System.Text.StringBuilder lpData,
 54                                                   ref uint lpcbData);
 55 
 56         private static UIntPtr TransferKeyName(string keyName)
 57         {
 58             switch (keyName)
 59             {
 60                 case "HKEY_CLASSES_ROOT":
 61                     return HKEY_CLASSES_ROOT;
 62                 case "HKEY_CURRENT_USER":
 63                     return HKEY_CURRENT_USER;
 64                 case "HKEY_LOCAL_MACHINE":
 65                     return HKEY_LOCAL_MACHINE;
 66                 case "HKEY_USERS":
 67                     return HKEY_USERS;
 68                 case "HKEY_CURRENT_CONFIG":
 69                     return HKEY_CURRENT_CONFIG;
 70             }
 71 
 72             return HKEY_CLASSES_ROOT;
 73         }
 74 
 75         public static string Get64BitRegistryKey(string parentKeyName, string subKeyName, string keyName)
 76         {
 77             int KEY_QUERY_VALUE = (0x0001);
 78             int KEY_WOW64_64KEY = (0x0100);
 79             int KEY_ALL_WOW64 = (KEY_QUERY_VALUE | KEY_WOW64_64KEY);
 80 
 81             try
 82             {
 83                 //将Windows注册表主键名转化成为不带正负号的整形句柄(与平台是32或者64位有关)
 84                 UIntPtr hKey = TransferKeyName(parentKeyName);
 85 
 86                 //声明将要获取Key值的句柄
 87                 IntPtr pHKey = IntPtr.Zero;
 88 
 89                 //记录读取到的Key值
 90                 StringBuilder result = new StringBuilder("".PadLeft(1024));
 91                 uint resultSize = 1024;
 92                 uint lpType = 0;
 93 
 94                 //关闭文件系统转向 
 95                 IntPtr oldWOW64State = new IntPtr();
 96                 if (Wow64DisableWow64FsRedirection(ref oldWOW64State))
 97                 {
 98                     //获得操作Key值的句柄
 99                     RegOpenKeyEx(hKey, subKeyName, 0, KEY_ALL_WOW64, out pHKey);
100 
101                     //关闭注册表转向(禁止特定项的注册表反射)
102                     RegDisableReflectionKey(pHKey);
103 
104                     //获取访问的Key值
105                     RegQueryValueEx(pHKey, keyName, 0, out lpType, result, ref resultSize);
106 
107                     //打开注册表转向(开启特定项的注册表反射)
108                     RegEnableReflectionKey(pHKey);
109                 }
110 
111                 //打开文件系统转向
112                 Wow64RevertWow64FsRedirection(oldWOW64State);
113 
114                 //返回Key值
115                 return result.ToString().Trim();
116             }
117             catch (Exception ex)
118             {
119                 return null;
120             }
121         }
122 
123         #endregion
124     }
125 }

The three parameters of the Get64BitRegistryKey function respectively represent: primary key name (such as: HKEY_LOCAL_MACHINE, etc.), sub-key name, Key name, and the value returned is the Value of the Key (the key value of the 64-bit system registry) ), through the above method, it is completely possible to use 32-bit programs to access the 64-bit system registry (ie: the registry location accessed by 64-bit programs).

The above is the detailed content of Sample code for C# 32-bit program to access 64-bit registry. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn