64位系統下System32文件系統重定向

前言html

      由於一次偶然的機會,須要訪問系統目錄「C:/Windows/System32「文件夾下的內容,使用的測試機器上預裝了win7 64系統。在程序運行中居然發生了該文件路徑不存在的問題!!經過查看網上相關的資料,瞭解到64位系統下,System32(同時也包括Program Files)這兩個文件夾被動態地重定向了。爲了能夠直觀的反映這個問題,這裏將編寫一個小的測試程序進行驗證。windows

 

實例驗證api

      首先隨機選擇一個文件,並將其拷貝到系統目錄的System32文件夾下。本文選擇QQ啓動程序進行驗證(主要是QQ自帶企鵝圖標易於辨認,哈哈),如圖1所示測試

QQ拷貝到System32下

圖1 手動將QQ拷貝到系統System32文件夾下spa

    編寫實際測試程序,直接上代碼(調用了windows系統API PathFileExists來判斷文件是否存在)code

/************************************************************************/
/* 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所示:htm

Opps

圖2 文件不存在??blog

      從上面的結果能夠看出,在調用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 )ip

\Windows\System32  文件夾下存放64位的庫和應用程序

      爲了驗證文件系統重定向,將前文中的測試路徑改成:

std::wstring strFile = L"C:\\Windows\\SysNative\\QQProtect.exe";

     測試結果如圖3所示:

Good

圖3 改成Sysnative結果

      上述結果顯示了,64位系統下若是須要訪問System32目錄下的文件,一個可行的方法是將訪問路徑改成SysNative。可是因爲sysnative文件夾不能經過windows資源管理器訪問到(如圖4所示),所以對於通常人來說,這樣的更名其實很困惑。

sysnative不存在

圖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所示:

Good

圖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

相關文章
相關標籤/搜索