前言

因为一次偶然的机会,需要访问系统目录“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文件系统重定向的更多相关文章

  1. C# 32位程序在64位系统下注册表操作

    在64位的Windows操作系统中,为了兼容32位程序的运行,64位的Windows操作系统采用重定向机制.目的是为了能让32位程序在64位的操作系统不仅能操作关键文件文夹和关键的注册表并且又要避免与 ...

  2. 64位系统下注册32位dll文件

    64位系统下注册32位dll文件 在64位系统里注册32位软件所需的一些dll会提示不兼容,大概因为32 位进程不能加载64位Dll,64位进程也不可以加载32的导致. 若要支持的32 位和64 位C ...

  3. delphi在64位系统下写注册表注意事项

    HKEY_LOCAL_MACHINE写这个主键下的项,在64位系统下可能会重定向,所以构造时要加KEY_WOW64_64KEY reg := TRegistry.Create(KEY_WRITE or ...

  4. PL/SQL Developer 在windows7 64位系统下连Oaracle11g64位系统的解决经验

    PL/SQL Developer 在windows7 64位系统下连Oaracle11g64位系统的解决经验 一.问题现象及解决方法 现象: 1.PL/SQL 无法登录64位数据库 2.在PL/SQL ...

  5. win7 64位系统下安装autoitlibrary库遇到问题解决

    转载来自http://blog.sina.com.cn/s/blog_53f023270101skyq.html 今天需要在win7 64位系统下安装autoitlibrary库,起初安装好了robo ...

  6. (转)Win7 64位系统下 Retional rose 2003 安装及破解

    网上关于Retional rose 2003安装和破解的文章比较多,这里,我结合自己的亲身体验,和大家分享一下win7 旗舰版 64位系统下Retional rose 2003(下面简称rose200 ...

  7. 64位系统下注册32位dll、ax文件

    64位系统下注册32位dll.ax文件. 换了64位系统遇到的新问题,目前常用的影音处理软件多数为32位. 注册这些32的滤镜会提示不兼容,大概因为32 位进程不能加载64位Dll,64位进程也不可以 ...

  8. Win7 64位系统下 Retional rose 2003 安装及破解

    网上关于Retional rose 2003安装和破解的文章比较多,这里,我结合自己的亲身体验,和大家分享一下win7 旗舰版 64位系统下Retional rose 2003(下面简称rose200 ...

  9. 64位系统下,一个32位的程序究竟可以申请到多少内存,4GB还是更多?(一)

    前言: cpu的位是指一次性可处理的数据量是多少,1字节=8位,32位处理器可以一次性处理4个字节的数据量,依次类推.32位操作系统针对的32位的CPU设计.64位操作系统针对的64位的CPU设计.操 ...

随机推荐

  1. Nginx windows下搭建过程

    内容列表: 简要介绍 下载安装 配置测试 一.简要介绍 Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP ...

  2. (转载)mysql中limit用法

    (转载)http://hi.baidu.com/sppeivan/item/e45179375d6778c62f8ec221   mysql中limit用法 使用查询语句的时候,经常要返回前几条或者中 ...

  3. python 正则表达式(一)

    正则表达式(regular exprssion)是一种形式化语法描述的文本匹配模式.模式被解释为一组指令,然后会执行这组指令.以一个字符串作为输入,生成一个匹配的子集或源字符串的修改版本. 表达式可以 ...

  4. Linux学习笔记23——取消线程

    一 相关函数 1 发送终止信号 #include <pthread.h> int pthread_cancel(pthread_t thread); 2 设置取消状态 #include & ...

  5. Telephone directory - SGU 127(水)

    题目大意:有一个电话簿,每页最多纪录K行电话,现在有N个电话要记录在电话薄上,要求同页的电话号码的首位要相同,电话簿的前两页是纪录的别的东西,问最少需要多少页电话簿. 分析:直接求首位数字有多少个即可 ...

  6. liststack——链表栈(procedure)

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include "list.h&q ...

  7. ckeditor_4.5.10_full上传图片功能

    1.找到image.js

  8. 正经学C#_变量与其转换:《c#入门经典》

    上一节上了变量.末尾简单了说了下 命名方式,声明变量. 命名方式在C#,或者任何语言都是非常重要的一门学问.值得去深入思考一下.变量名的优化与其工作效率的提升,有很多大的关系的. 声明变量,上节介绍了 ...

  9. 找不到这个cache.properties缓存文件

    Android  Studio在导入第三库同步时报错: C:\Users\Administrator\.gradle\caches\2.4\scripts\asLocalRepo88_4u65z0u2 ...

  10. git 分支策略

    转 http://www.ruanyifeng.com/blog/2012/07/git.html  作者: 阮一峰 如果你严肃对待编程,就必定会使用"版本管理系统"(Versio ...