64位系统下System32文件系统重定向
前言
因为一次偶然的机会,需要访问系统目录“C:/Windows/System32“文件夹下的内容,使用的测试机器上预装了win7 64系统。在程序运行中竟然发生了该文件路径不存在的问题!!通过查看网上相关的资料,了解到64位系统下,System32(同时也包括Program Files)这两个文件夹被动态地重定向了。为了可以直观的反映这个问题,这里将编写一个小的测试程序进行验证。
实例验证
首先随机选择一个文件,并将其拷贝到系统目录的System32文件夹下。本文选择QQ启动程序进行验证(主要是QQ自带企鹅图标易于辨认,哈哈),如图1所示

图1 手动将QQ拷贝到系统System32文件夹下
编写实际测试程序,直接上代码(调用了windows系统API PathFileExists来判断文件是否存在)
/************************************************************************/
/* file : 验证在64位机器上system32以及Program Files的exe不能用API直接找到
* author : Huagang Li
* date : 2014-8-23 01:22:55
* tips : 64位系统下system32 文件夹重定向机制
*
*/
/************************************************************************/
#include <Windows.h>
#include <string>
#include <tchar.h>
#include <Shlwapi.h> #pragma comment(lib,"Shlwapi.lib") // PathFileExists链接时需要 int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
std::wstring strFile = L"C:\\Windows\\System32\\QQProtect.exe"; if (::PathFileExists(strFile.c_str()))
{
::MessageBox(NULL, _T("文件存在"), _T("Good"), MB_OK);
}
else
{
::MessageBox(NULL, _T("文件不存在"), _T("Opps"), MB_OK);
} return EXIT_SUCCESS;
}
运行的结果如图2所示:

图2 文件不存在??
从上面的结果可以看出,在调用windows API检测QQ文件是否存在时,系统给出了一个令人匪夷所思的结论:文件不存在!!但这个文件确实被拷贝进了该目录下啊。要解释这个奇怪的现象,就得从windows 64位系统中的文件系统重定向说起。当微软开发了64位系统时,为了做到向前兼容,需要重新实现32为系统中需要的相关文件(system32文件夹下的dll以及exe)。然而,这些新的实现版本是基于64位系统开发的,因此如果继续存放于System32文件夹下,显得名不副实。可是为了做到向前兼容,又需要将这些依赖文件存放于这个目录下,为了解决上述冲突,微软采用了一种文件系统重定向机制:在64位系统下,System32文件夹下的文件实际重定向到SysNative这个文件夹(注意,这个文件夹不能直接找到)。这样,就可以将64位系统下64位的库和应用程序存放于System32文件夹下(因为已经重定向到SysNative了),而32位的库和应用程序则被存放在另一个叫做SysWOW64的文件夹中。具体的对应关系为:
\Windows\SysWOW64 文件夹下存放32位的库和应用程序 (WOW64 == Windows on Windows 64 bit )
\Windows\System32 文件夹下存放64位的库和应用程序
为了验证文件系统重定向,将前文中的测试路径改为:
std::wstring strFile = L"C:\\Windows\\SysNative\\QQProtect.exe";
测试结果如图3所示:

图3 改为Sysnative结果
上述结果显示了,64位系统下如果需要访问System32目录下的文件,一个可行的方法是将访问路径改为SysNative。但是由于sysnative文件夹不能通过windows资源管理器访问到(如图4所示),因此对于一般人来讲,这样的改名其实很困惑。

图4 资源管理器访问不到Sysnative文件夹
既然微软开发了文件系统重定向机制机制,那就可以通过一定的方式操作这种机制。通过查看msdn可以发现,http://msdn.microsoft.com/en-us/library/aa365743.aspx 提供的方式可以禁用文件系统重定向问题。因此,本文尝试调用这个API接口进行验证:
/************************************************************************/
/* file : 验证在64位机器上system32以及Program Files的exe不能用API直接找到
* author : Huagang Li
* date : 2014-8-23 01:22:55
* tips : 64位系统下system32 文件夹重定向机制
*
*/
/************************************************************************/
#include <Windows.h>
#include <string>
#include <tchar.h>
#include <Shlwapi.h> #pragma comment(lib,"Shlwapi.lib") // PathFileExists链接时需要 int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
std::wstring strFile = L"C:\\Windows\\System32\\QQProtect.exe";
// 64位系统下 system32 文件系统重定向 PVOID OldValue = NULL;
Wow64DisableWow64FsRedirection(&OldValue);
if (::PathFileExists(strFile.c_str()))
{
::MessageBox(NULL, _T("文件存在"), _T("Good"), MB_OK);
}
else
{
::MessageBox(NULL, _T("文件不存在"), _T("Opps"), MB_OK);
}
Wow64RevertWow64FsRedirection(OldValue); return EXIT_SUCCESS;
}
运行后得到的结果和上文中Sysnative一样,如图5所示:

图5 禁用文件系统重定向机制后的结果
注意,由于禁用文件系统重定向后可能引起其他一些问题(例如原本依赖于System32下的dll文件加载失败),因此在禁用并完成需要的操作后,要回复原来的禁用状态(如程序中Wow64RevertWow64FsRedirection(OldValue);)。这样,在调用PathFileExists后,恢复了文件系统重定向机制,不会影响后续操作。
另外,64位系统下Program Files与Program Files(x86)的关系就与上面的System32和S也是WOW64一致,也存在文件系统重定向。
结论
1. 64位系统下存在文件系统重定向机制(File System Redirector)
2. System32文件夹动态被定向到SysNative文件夹
3. 可以通过windows API Wow64DisableWow64FsRedirection禁用这种定向机制
参考链接
[1] http://msdn.microsoft.com/en-us/library/aa384187.aspx
[2] http://msdn.microsoft.com/en-us/library/aa365743.aspx
[3] http://blog.sina.com.cn/s/blog_792da39c01013bzh.html
64位系统下System32文件系统重定向的更多相关文章
- C# 32位程序在64位系统下注册表操作
在64位的Windows操作系统中,为了兼容32位程序的运行,64位的Windows操作系统采用重定向机制.目的是为了能让32位程序在64位的操作系统不仅能操作关键文件文夹和关键的注册表并且又要避免与 ...
- 64位系统下注册32位dll文件
64位系统下注册32位dll文件 在64位系统里注册32位软件所需的一些dll会提示不兼容,大概因为32 位进程不能加载64位Dll,64位进程也不可以加载32的导致. 若要支持的32 位和64 位C ...
- delphi在64位系统下写注册表注意事项
HKEY_LOCAL_MACHINE写这个主键下的项,在64位系统下可能会重定向,所以构造时要加KEY_WOW64_64KEY reg := TRegistry.Create(KEY_WRITE or ...
- PL/SQL Developer 在windows7 64位系统下连Oaracle11g64位系统的解决经验
PL/SQL Developer 在windows7 64位系统下连Oaracle11g64位系统的解决经验 一.问题现象及解决方法 现象: 1.PL/SQL 无法登录64位数据库 2.在PL/SQL ...
- win7 64位系统下安装autoitlibrary库遇到问题解决
转载来自http://blog.sina.com.cn/s/blog_53f023270101skyq.html 今天需要在win7 64位系统下安装autoitlibrary库,起初安装好了robo ...
- (转)Win7 64位系统下 Retional rose 2003 安装及破解
网上关于Retional rose 2003安装和破解的文章比较多,这里,我结合自己的亲身体验,和大家分享一下win7 旗舰版 64位系统下Retional rose 2003(下面简称rose200 ...
- 64位系统下注册32位dll、ax文件
64位系统下注册32位dll.ax文件. 换了64位系统遇到的新问题,目前常用的影音处理软件多数为32位. 注册这些32的滤镜会提示不兼容,大概因为32 位进程不能加载64位Dll,64位进程也不可以 ...
- Win7 64位系统下 Retional rose 2003 安装及破解
网上关于Retional rose 2003安装和破解的文章比较多,这里,我结合自己的亲身体验,和大家分享一下win7 旗舰版 64位系统下Retional rose 2003(下面简称rose200 ...
- 64位系统下,一个32位的程序究竟可以申请到多少内存,4GB还是更多?(一)
前言: cpu的位是指一次性可处理的数据量是多少,1字节=8位,32位处理器可以一次性处理4个字节的数据量,依次类推.32位操作系统针对的32位的CPU设计.64位操作系统针对的64位的CPU设计.操 ...
随机推荐
- 数据结构(莫队算法):国家集训队2010 小Z的袜子
[题目描述] 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… 具体来说,小Z把这N只袜子从1到 ...
- 游戏开发设计模式之状态模式 & 有限状态机 & c#委托事件(unity3d 示例实现)
命令模式:游戏开发设计模式之命令模式(unity3d 示例实现) 对象池模式:游戏开发设计模式之对象池模式(unity3d 示例实现) 原型模式:游戏开发设计模式之原型模式 & unity3d ...
- [QT]构建正则表达式测试
正则表达式是个强大的东西 暂时先记录一个用法: QString str = "Peak memory: KEY s"; QString data = "Peak memo ...
- Unity Skin Shader Optimized
Shader "Skin Shader" { Properties { _MainTex ("Diffuse (RGB)", 2D) = "white ...
- 在Xcode中使用Clang Format
Xcode中的Re-Indent,顾名思义,只是一个调整缩进的功能,完全依赖它来进行代码格式化显然不够用.我们使用了一个叫做ClangFormat-Xcode的插件,配合Re-Indent一起来做代码 ...
- 排序之直接插入排序(Straight Insertion Sort)
一.直接插入排序(Straight Insertion Sort) 排序的过程如下:给定无需序列:(3,6,9,7,1,8,2,4) ① 3,6,9,7,1,8,2,4 (将6插入到有序序列3中) ② ...
- How to install Python 2.7 and Python 3.3 on CentOS 6
原文地址:http://toomuchdata.com/2014/02/16/how-to-install-python-on-centos/
- Apple Pay强势来袭,开发者应做的事情
"iOS8.1就已经有这个功能了,只是木有现在这么的火,现在的趋势是要火的节奏,因此很多电商平台B2B,P2P,C2C,X2X都有可能需要这个屌丝的付款功能了,在此简单的研究一下." ...
- ASP.NET datable导出excel
本文转载:http://www.cnblogs.com/chwkai/archive/2005/10/08/250426.html 不错的文章:http://www.cnblogs.com/lzhp/ ...
- 生成 git 密钥 步骤
http://blog.csdn.net/wfdtxz/article/details/8678982 git使用https协议,每次pull, push都要输入密码,相当的烦.使用git协议,然后使 ...