64 位 Windows 平台開發要點之文件系統重定向


  • Program Files 的重定向

    很多開發人員都知道,在 64 位 Windows 系統上,32 位程序是無法獲取得到 C:\Program Files 的完整路徑的,只能獲取到 C:\Program Files (x86)。不管你用的是什么方法:

    TCHAR szPath[MAX_PATH] = { 0 };
    ExpandEnvironmentStrings(_T("%ProgramFiles%"), szPath, MAX_PATH);
    

    又或者是:

    SHGetSpecialFolderPath(NULL, szPath, CSIDL_PROGRAM_FILES, FALSE);
    SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, szPath);

    這個問題在 Windows NT 6.0 (Windows Vista) 之前的系統上無解,只有 64 程序可以拿到這個路徑。Windows NT 6.0 開始,微軟對此進行了重新設計,以前稱作「Special Folders」(特殊文件夾)的系統文件夾有了一個全新的名字,叫「Known Folders」(已知文件夾),同時提供了一套新的接口,包括 Windows API 函數 SHGetKnownFolderPath,COM 接口 IKnownFolder 和 IKnownFolderManager 來管理這些系統文件夾,原來的 CSIDL(Constant Special Item ID list)系列整數值也被一套新的「KNOWNFOLDERID」系列 GUID 所代替,可以獲取得到的文件夾數量比以前也更多,而且隨着 Windows 的版本越來越高,可獲取的文件夾路徑也越來越多。如,程序可以直接通過 FOLDERID_QuickLaunch 獲取 Quick Launch(快速啟動),以及通過 FOLDERID_LocalAppDataLow 獲取 LocalLow 等路徑。不過,經測試,32 位程序使用下面的代碼仍然無法獲取到 C:\Program Files。

    PWSTR pszPath = NULL;
    HRESULT hr = SHGetKnownFolderPath(FOLDERID_ProgramFilesX64, 0, NULL, &pszPath);
    if (hr == S_OK)
    {
    	CoTaskMemFree((void *)pszPath);
    }

    在 64 位系統上,上面的代碼編譯為 32 位程序,結果依然是失敗。多年來,經過多次不懈的搜索,終於找到 32 位程序在 64 位系統上獲取 C:\Program Files 的方法:

    TCHAR szPath[MAX_PATH] = { 0 };
    ExpandEnvironmentStrings(_T("%ProgramW6432%"), szPath, MAX_PATH);

    雖然說這個環境變量並無法在批處理和命令行中使用。個人猜測,這個環境變量僅在 64 位系統上的 32 位程序中有效。而 64 位系統的 cmd 也是 64 位,自然批處理中無法使用環境變量。經測試,Windows XP x64 Edition 也能通過這個方法得到該路徑。

  • System32 的重定向

    System32 重定向和 Program Files 不同的是,System32 的重定向是底層實現的,即 32 位程序顯式的指定向 System32 文件夾寫入,實際還是寫入到 SysWOW64。而 32 位程序在擁有權限的情況下,向 Program Files 寫入並不會被重定向到 Program Files (x86)。向 System32 和 Program Files 兩個文件夾中寫入數據的相同點是都需要管理員權限,否則無法寫入。System32 的重定向是可以通過以下的 API 來更改:

    PVOID lpOldValue = NULL;
    if (Wow64DisableWow64FsRedirection(&lpOldValue))
    {
    	// 調用 CreateFile、_open、fopen 等
    	Wow64RevertWow64FsRedirection(lpOldValue);
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM