为了向后兼容,我的 64 进程需要查看文件系统和注册表的 32 位视图。
我知道如何让 32 位进程看到文件系统和注册表的 64 位视图(使用 Wow64DisableWow64FsRedirection 和 Wow64RevertWow64FsRedirection)
但是如何使 64 位进程具有文件系统和注册表的 32 位视图?
您需要明确查看“WOW64”键/目录。实际上没有“64 位”注册表,只有“注册表”,Wow64 重定向内容只是将 32 位进程重定向到不同的子项。因此,当一个 32 位进程请求“HKLM\Software\foo”时,注册表 API 实际上会说,“等等,你是 32 位的,所以我会假装你请求的是 'HKLM\Software \Wow6432Node \foo ' 反而”。
因此,考虑到这一点,没有办法让 64 位进程在“32 位”注册表中查找,因为没有“32 位注册表”之类的东西。相反,您只需执行 Wow64 重定向逻辑自动执行的操作。
编辑
对于注册表,实际上有您可以在各种方法调用KEY_WOW64_32KEY
中指定的键。
对于文件系统,您也许可以尝试Wow64EnableWow64FsRedirection,但我不确定它是否会工作......
KEY_WOW64_32KEY 适用于 64 位和 32 位进程。
从实验来看,Wow64EnableWow64FsRedirection/Wow64DisableWow64FsRedirection 似乎不能在 64 位进程中工作 - 顾名思义,它似乎只能在 WOW64 进程中工作。
因此,为了从 64 位进程获得文件系统的 32 位“视图”,需要更改路径以指向正确的位置
这真的很难看,但这里有一个 c++ 代码示例,说明如何根据Microsoft执行文件系统重定向。需要升压。
#include"boost/filesystem.hpp"
#include"wstring"
#include"shfolder.h"
#include"Shlobj.h"
bool redirectPathRoot( boost::filesystem::wpath pathFromRoot, boost::filesystem::wpath pathToRoot, boost::filesystem::wpath & pathToRedirect )
{
bool bPathWasRedirected = false;
boost::filesystem::wpath theNewPath;
boost::filesystem::wpath::iterator iPathToRedirect = pathToRedirect.begin();
boost::filesystem::wpath::iterator iFromRoot = pathFromRoot.begin();
bool bMatch = true;
while( iPathToRedirect != pathToRedirect.end() && iFromRoot != pathFromRoot.end() && bMatch )
{
//
// see if the root of the path we are checking matches
//
bMatch = ( std::wstring(*iPathToRedirect++) == std::wstring(*iFromRoot++) );
}
if( bMatch && iFromRoot == pathFromRoot.end() )
{
theNewPath = pathToRoot;
//
// these guys need to be redirected
//
while( iPathToRedirect != pathToRedirect.end() )
{
theNewPath /= *iPathToRedirect++;
}
bPathWasRedirected = true;
pathToRedirect = theNewPath;
}
return bPathWasRedirected;
}
std::wstring adjustPathFor32BitOn64BitProcess( LPCWSTR thePath )
{
std::wstring strPath(thePath);
boost::to_lower(strPath);
//
// default to the original path
//
boost::filesystem::wpath theNewPath(strPath.c_str());
theNewPath.normalize();
//
// init the supplied path
//
boost::filesystem::wpath pathToCheck( strPath.c_str() );
pathToCheck.normalize();
//
// get the path for the 32 bit folder on a 64 bit system
//
wchar_t strTemp[MAX_PATH] = L"\0";
GetSystemWow64Directory( strTemp, MAX_PATH );
std::wstring strSysWow64 = strTemp;
boost::to_lower( strSysWow64 );
boost::filesystem::wpath pathSysWow64( strSysWow64.c_str() );
pathSysWow64.normalize();
//
// get the path for the system directory
//
GetSystemDirectory( strTemp, MAX_PATH );
std::wstring strSys = strTemp;
boost::to_lower( strSys );
boost::filesystem::wpath pathSys( strSys.c_str() );
pathSys.normalize();
//
// get the path for the Program Files directory
//
SHGetFolderPath( NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_DEFAULT, strTemp);
std::wstring strPrograms = strTemp;
boost::to_lower( strPrograms );
boost::filesystem::wpath pathPrograms( strPrograms.c_str() );
pathPrograms.normalize();
//
// get the path for the Program Files x86 directory
//
SHGetFolderPath( NULL, CSIDL_PROGRAM_FILESX86, NULL, SHGFP_TYPE_DEFAULT, strTemp);
std::wstring strProgramsX86 = strTemp;
boost::to_lower( strProgramsX86 );
boost::filesystem::wpath pathProgramsX86( strProgramsX86.c_str() );
pathProgramsX86.normalize();
//
// get the path for the Windows\lastgood\system32 directory
//
SHGetFolderPath( NULL, CSIDL_WINDOWS, NULL, SHGFP_TYPE_DEFAULT, strTemp);
std::wstring strWindows = strTemp;
boost::to_lower( strWindows );
boost::filesystem::wpath pathWindows( strWindows.c_str() );
pathWindows.normalize();
boost::filesystem::wpath pathWindowsLastGoodSystem32( strWindows.c_str() );
pathWindowsLastGoodSystem32 /= L"lastgood";
pathWindowsLastGoodSystem32 /= L"system32";
pathWindowsLastGoodSystem32.normalize();
boost::filesystem::wpath pathWindowsLastGoodSysWOW64( strWindows.c_str() );
pathWindowsLastGoodSysWOW64 /= L"lastgood";
pathWindowsLastGoodSysWOW64 /= L"syswow64";
pathWindowsLastGoodSysWOW64.normalize();
//
// finally, regedit...
//
boost::filesystem::wpath pathRegedit( strWindows.c_str() );
pathRegedit /= L"regedit.exe";
pathRegedit.normalize();
boost::filesystem::wpath pathRegeditSysWOW64( pathSysWow64 );
pathRegeditSysWOW64 /= L"regedit.exe";
pathRegeditSysWOW64.normalize();
//
// now see if the supplied path matches system directoy
//
boost::filesystem::wpath::iterator iPathToCheck = pathToCheck.begin();
boost::filesystem::wpath::iterator iSys = pathSys.begin();
bool bMatch = true;
while( iPathToCheck != pathToCheck.end() && iSys != pathSys.end() && bMatch )
{
//
// see if the beginning of the path we are checking matches the system path
//
bMatch = ( std::wstring(*iPathToCheck++) == std::wstring(*iSys++) );
}
if( bMatch && iSys == pathSys.end() )
{
//
// the supplied path matches at least as far as the system dir...
//
if( iPathToCheck == pathToCheck.end() )
{
//
// ...actually its an exact match, so redirect it
//
theNewPath = pathSysWow64;
}
else
{
//
// ...however, there are a few exceptions....
//
boost::filesystem::wpath::iterator iTemp = iPathToCheck;
if(
!(
std::wstring(*iTemp) == L"drivers" &&
(
(++iTemp) != pathToCheck.end() &&
std::wstring(*(iTemp)) == L"etc"
)
)
&&
(std::wstring(*iPathToCheck) != L"catroot") &&
(std::wstring(*iPathToCheck) != L"catroot2") &&
(std::wstring(*iPathToCheck) != L"logfiles") &&
(std::wstring(*iPathToCheck) != L"spool")
)
{
//
// all but the above dirs should be redirected
//
theNewPath = pathSysWow64;
while( iPathToCheck != pathToCheck.end() )
{
theNewPath /= *iPathToCheck++;
}
}
}
}
else
{
//
// didn't match the system dir... see if it matches the Program Files dir
//
if(!redirectPathRoot( pathPrograms, pathProgramsX86, theNewPath ))
{
//
// now try %windir%/lastgood/system32
//
if(!redirectPathRoot( pathWindowsLastGoodSystem32, pathWindowsLastGoodSysWOW64, theNewPath ))
{
//
// finally, regedit
//
redirectPathRoot( pathRegedit, pathRegeditSysWOW64, theNewPath );
}
}
}
return theNewPath.file_string();}
如果您想查看 32 位注册表,您可以使用此处所述的 KEY_WOW64_32KEY
如果您想访问 SysWOW64 目录,您可以使用 GetSystemWow64Directory,如此处所述
聚会有点晚了,但你能不能创建一个小的 32 位进程来让你的 32 位工作?然后 WOW64 的所有内置优点都将起作用。
不确定您的开发语言/运行时是什么样的,因此无法就进程间通信的外观提供进一步的建议。