32位Windows XP上的Wow64DisableWow64FsRedirection

时间:2014-08-20 20:12:55

标签: c++ windows windows-xp 32bit-64bit

我在Visual Studio C ++中编写程序,需要在运行Windows XP 32位或任何更高版本Windows操作系统的任何计算机上以32位进程本机运行。无论程序是在64位还是32位系统上运行,该程序都需要能够访问计算机上的C:\Windows\system32\文件夹。为此,我使用Wow64DisableWow64FsRedirection来禁用Windows通常对32位进程执行的重定向,并将它们发送到C:\Windows\syswow64。不幸的是,这打破了兼容性 - 虽然我的程序可以在Server 2003和XP x64版本上运行,但只要它在32位XP RTM系统上运行,程序就会失败,给我这个错误:

[Program Name] - Entry Point Not Found
  The procedure entry point Wow64DisableWow64FsRedirection could not be located
  in the dynamic link library KERNEL32.dll.

由于系统是32位的,因此调用显然是多余的,但我无法找到一种在运行时确定系统是否为64位的方法,因此是否跳过调用,而不添加本身破坏兼容性的另一个调用,例如IsWow64Process(),这需要XP Service Pack 2.

tl; dr:如何在不使用消费者64位Windows出现之后引入的任何调用的情况下确定系统是64位还是32位。

1 个答案:

答案 0 :(得分:7)

继续使用Wow64DisableWow64FsRedirection,但不要静态导入它。而是使用动态绑定(GetProcAddress)或延迟加载,其中任何一个都允许您处理丢失的函数而不会崩溃(或者更糟糕的是,甚至不启动,这是当前的情况)。

并且不用担心系统的位数。如果该功能存在,请将其调用。

typedef BOOL WINAPI fntype_Wow64DisableWow64FsRedirection(PVOID *OldValue);
auto pfnWow64DisableWow64FsRedirection = (fntype_Wow64DisableWow64FsRedirection*)GetProcAddress(GetModuleHandleA("kernel32.dll"), "Wow64DisableWow64FsRedirection");

if (pfnWow64DisableWow64FsRedirection) {
   // function found, call it via pointer
   PVOID arg;
   (*pfnWow64DisableWow64FsRedirection)(&arg);
}
else {
   // function was missing
}

现在链接器找不到名为Wow64DisableWow64FsRedirection的未解析符号,因此它不会将该函数放入导入表中,Windows在进程中不会去寻找它启动。