Fork me on GitHub

文件和注册表的重定向解决方法

32位程序如何访问64位的注册表(HKLM/Software)

在调用函数RegCreateKeyEx创建注册表项时,对其第六个参数REGSAM samDesired设置中添加参数KEY_WOW64_64KEY,这样可以实现对64位注册表的访问;

在调用函数RegOpenKeyEx打开注册表项时,要对其第四个参数REGSAM samDesired设置中添加参数KEY_WOW64_64KEY,这样可以实现对64位注册表的访问;

64位程序如何访问32位的注册表(HKLM/Software/Wow6432Node)

在调用函数RegCreateKeyEx创建注册表项时,对其第六个参数REGSAM samDesired设置中添加参数KEY_WOW32_64KEY,这样可以实现对32位注册表的访问;

在调用函数RegOpenKeyEx打开注册表项时,要对其第四个参数REGSAM samDesired设置中添加参数KEY_WOW32_64KEY,这样可以实现对32位注册表的访问;

文件重定向解决办法:

我们可以调用相关的API来关闭和打开这种转向。常用的函数有3个:

Wow64DisableWow64FsRedirection(关闭系统转向),

Wow64RevertWow64FsRedirection (打开系统转向),

Wow64EnableWow64FsRedirection (打开系统转向)。

但是Wow64EnableWow64FsRedirection在嵌套使用的时候不可靠,所以通常用上面的Wow64RevertWow64FsRedirection来打开文件系统转向功能。

执行批处理与代码调用批处理的区别:

(1)在64位系统上直接双击运行批处理文件QQBrowser.reg,

结果会导入到目录 HKEY_LOCAL_MACHINE\SOFTWARE\Tencent\QQBrowser

[java] view plain copy
  1. Windows Registry Editor Version 5.00  
  2. HKEY_LOCAL_MACHINE\SOFTWARE\Tencent\QQBrowser  
  3. "Version"="7.7.28658.400"  
  4. "InstallDir"="{AutoPath}QQ浏览器{/AutoPath}"  
  5. "INSTLANG"="2052"  
  6. "Exe"="{AutoPath}QQ浏览器{/AutoPath}\\QQBrowser.exe"  
  7. "SupplyID"="607"  

(2)在64位系统上直接双击运行批处理文件QQBrowser.reg,

结果会导入到目录 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Tencent\QQBrowser

[java] view plain copy
  1. Windows Registry Editor Version 5.00  
  2. [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Tencent\QQBrowser]  
  3. "Version"="7.7.28658.400"  
  4. "InstallDir"="{AutoPath}QQ浏览器{/AutoPath}"  
  5. "INSTLANG"="2052"  
  6. "Exe"="{AutoPath}QQ浏览器{/AutoPath}\\QQBrowser.exe"  
  7. "SupplyID"="607"  

(3)如果在VC编译的32位程序中调用"regedit.exe /s QQBrowser.reg"命令来实现导入批处理文件,

则结果将导入到 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Tencent\QQBrowser

[java] view plain copy
  1. Windows Registry Editor Version 5.00  
  2. HKEY_LOCAL_MACHINE\SOFTWARE\Tencent\QQBrowser  
  3. "Version"="7.7.28658.400"  
  4. "InstallDir"="{AutoPath}QQ浏览器{/AutoPath}"  
  5. "INSTLANG"="2052"  
  6. "Exe"="{AutoPath}QQ浏览器{/AutoPath}\\QQBrowser.exe"  
  7. "SupplyID"="607"  

(4)如果在VC编译的32位程序中调用"regedit.exe /s QQBrowser.reg"命令来实现导入批处理文件,

则结果也将导入到 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Tencent\QQBrowser

[java] view plain copy
  1. Windows Registry Editor Version 5.00  
  2. HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Tencent\QQBrowser  
  3. "Version"="7.7.28658.400"  
  4. "InstallDir"="{AutoPath}QQ浏览器{/AutoPath}"  
  5. "INSTLANG"="2052"  
  6. "Exe"="{AutoPath}QQ浏览器{/AutoPath}\\QQBrowser.exe"  
  7. "SupplyID"="607"  

(5)先删除注册表节点HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Tencent,即删除QQBrowser的父目录Tencent,

然后通过VC编译的32位程序中调用"regedit.exe /s QQBrowser.reg"命令来实现导入批处理文件,

则结果会自动创建并导入 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Tencent\QQBrowser

[java] view plain copy
  1. Windows Registry Editor Version 5.00  
  2. HKEY_LOCAL_MACHINE\SOFTWARE\Tencent\QQBrowser  
  3. "Version"="7.7.28658.400"  
  4. "InstallDir"="{AutoPath}QQ浏览器{/AutoPath}"  
  5. "INSTLANG"="2052"  
  6. "Exe"="{AutoPath}QQ浏览器{/AutoPath}\\QQBrowser.exe"  
  7. "SupplyID"="607"  

(6)先删除注册表节点HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Tencent,即删除QQBrowser的父目录Tencent,

然后通过VC编译的32位程序中调用"regedit.exe /s QQBrowser.reg"命令来实现导入批处理文件,

则结果会多创建一级Wow6432Node目录,即导入到了 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Wow6432Node\Tencent

[java] view plain copy
  1. <pre name="code" class="html">Windows Registry Editor Version 5.00  
  2. HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Tencent\QQBrowser  
  3. "Version"="7.7.28658.400"  
  4. "InstallDir"="{AutoPath}QQ浏览器{/AutoPath}"  
  5. "INSTLANG"="2052"  
  6. "Exe"="{AutoPath}QQ浏览器{/AutoPath}\\QQBrowser.exe"  
  7. "SupplyID"="607"  
[java] view plain copy
  1.   

说明:

(1)和(2)由于是在64位操作系统上,所以直接双击运行批处理文件,相当执行64位DOS应用程序,所以会如期导入到指定的目录下;

(3)但通过VC编译的32位程序来调用"regedit.exe /s QQBrowser.reg“命令实现导入批处理文件,结果却不如所料,虽然指定导入到HKEY_LOCAL_MACHINE\SOFTWARE\Tencent\QQBrowser,但实际却导入到了HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Tencent\QQBrowser,

要想导入到HKEY_LOCAL_MACHINE\SOFTWARE\Tencent\QQBrowser,必须在导入之前关闭重定向,导入完成之后回复重定向。

解决(3)和(6)的异常,都需要在导入之前先关闭重定向,代码如下:

[java] view plain copy
  1. //判断操作系统是否x64  
  2. BOOL IsWow64()  
  3. {  
  4.     BOOL bIsWow64 = FALSE;  
  5.     typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);  
  6.     LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");  
  7.     if (NULL != fnIsWow64Process)  
  8.     {  
  9.         fnIsWow64Process(GetCurrentProcess(), &bIsWow64);  
  10.     }  
  11.   
  12.     return bIsWow64;  
  13. }  
  14.   
  15. //注册回调,用于跟WOW64相关的操作  
  16. void InitDriver(lpFunc func, LPVOID lpParam)  
  17. {  
  18.     if (NULL == func)  
  19.     {  
  20.         return;  
  21.     }  
  22.   
  23.     if (IsWow64())  
  24.     {  
  25.         PVOID oldValue = NULL;  
  26.         BOOL IssysWow64 = IsWow64();  
  27.   
  28.         //关闭WOW64重定向(在导注册表时很重要,避免文件被写到Wow6432Node)  
  29.         if (IssysWow64)  
  30.         {  
  31.             typedef BOOL(WINAPI *LPFN_Wow64DisableWow64FsRedirection)(PVOID *OldValue);  
  32.             LPFN_Wow64DisableWow64FsRedirection fnWow64DisableWow64FsRedirection;  
  33.   
  34.             fnWow64DisableWow64FsRedirection = (LPFN_Wow64DisableWow64FsRedirection)GetProcAddress(  
  35.                 GetModuleHandle(TEXT("kernel32")), "Wow64DisableWow64FsRedirection");  
  36.   
  37.             if (fnWow64DisableWow64FsRedirection != NULL)  
  38.             {  
  39.                 fnWow64DisableWow64FsRedirection(&oldValue);  
  40.             }  
  41.         }  
  42.   
  43.         //当关闭重定向后,32位会导入到64位系统的64位节点下,例如:  
  44.         //预计导入节点:[HKEY_LOCAL_MACHINE\SOFTWARE\Tencent\QQBrowser]  
  45.         //实际导入节点:[HKEY_LOCAL_MACHINE\SOFTWARE\Tencent\QQBrowser]  
  46.         func(lpParam);  
  47.   
  48.         //恢复WOW64重定向  
  49.         if (IssysWow64)  
  50.         {  
  51.             typedef BOOL(WINAPI *LPFN_Wow64RevertWow64FsRedirection)(PVOID OlValue);  
  52.             LPFN_Wow64RevertWow64FsRedirection fnWow64RevertWow64FsRedirection;  
  53.             fnWow64RevertWow64FsRedirection = (LPFN_Wow64RevertWow64FsRedirection)GetProcAddress(  
  54.                 GetModuleHandle(TEXT("kernel32")), "Wow64RevertWow64FsRedirection");  
  55.   
  56.             if (fnWow64RevertWow64FsRedirection != NULL)  
  57.             {  
  58.                 fnWow64RevertWow64FsRedirection(oldValue);  
  59.             }  
  60.         }  
  61.     }  
  62.     else  
  63.     {  
  64.         //32位会重定向导入到64位系统的32位节点WOW6432Node下,例如:  
  65.         //预计导入节点:[HKEY_LOCAL_MACHINE\SOFTWARE\Tencent\QQBrowser]  
  66.         //实际导入节点:[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Tencent\QQBrowser]  
  67.         func(lpParam);  
  68.     }  
  69. }  
posted @ 2016-12-23 09:52  江湖码客Mark  阅读(1451)  评论(0编辑  收藏  举报