WOW64のファイルシステムのリダイレクトをOFFにする
会社で、WiXを使って、とあるプロジェクトのインストーラを作っているのですが、ほとんどは.NETなものの、一部のコードだけ、ドライバに依存するため、64bit対応するに当たって、system32(system64ではないんだなこれが。)にファイルをコピーしないといけません(プログラム自体は、32bitなので、32bit/64bit兼用のインストーラ)。
本来なら、%windir%\Sysnativeにファイルをコピーすれば、リダイレクトの影響を受けずにファイルをコピーできるはずなんですが、なぜか、sysnativeがちゃんと動きません。普通にsystem32にファイルをコピーすればsyswow64にリダイレクトされるので、八方塞がりです。
仕方がないので、カスタムアクションで、ファイルをコピーするという暴挙に出ることにしました。仕方がありません。下のコードは、WOW64のリダイレクトを一時的にOFFにするコード。
class Wow64RedirDisabler { public: Wow64RedirDisabler() { HINSTANCE hKrnl32 = GetModuleHandle(_T("kernel32")); m_disable = (LPFN_WOW64Disable) ::GetProcAddress(hKrnl32, "Wow64DisableWow64FsRedirection"); m_revert = (LPFN_WOW64Revert) ::GetProcAddress(hKrnl32, "Wow64RevertWow64FsRedirection"); if(m_disable) m_disablingWow64Redirection = m_disable(&m_val); else m_disablingWow64Redirection = FALSE; } ~Wow64RedirDisabler() { if(m_revert && m_disablingWow64Redirection) m_revert(m_val); } private: typedef BOOL (WINAPI* LPFN_WOW64Disable)(PVOID*); typedef BOOL (WINAPI* LPFN_WOW64Revert)(PVOID); LPFN_WOW64Disable m_disable; LPFN_WOW64Revert m_revert; PVOID m_val; BOOL m_disablingWow64Redirection; };
system32のパス自体は、
TCHAR sys32[MAX_PATH]; SHGetFolderPath(NULL, CSIDL_SYSTEM, NULL, 0, sys32);
で取得できます。APIが微妙に古いのはWindows 2000も対応しないといけないため。おもしろいことに(?)、このAPIは、WOW64下でも、%windir%\system32のパスを返します。完全にリダイレクトに頼りきりなんですね。まぁ、逆に言えば、このAPIがsyswow64を返したぐらいで、32bitのプログラムが全部動くような理想的な世界だったら、WOW64のリダイレクションなんていらなかったのかもしれませんけど、微妙に矛盾を感じます。