Windows XP以降の Windows には32bits版と64bits版が存在するが、64bits版の Windows で32bits アプリを動作させるには、色々と制限がある。所謂UAE(アラブ首長国連邦、、、ではない:w)を引き起こす原因の一つである UAC(ユーザ・アカウント制御:User Account Control)がこれをさらに複雑に面倒にしてくれる。
UACはウィルスなどのマルウェア対策などのため(それだけではなく、本来のOSにはこういう、必要以上の機能はユーザに与えないという制限があるのがあたりまえ、と言う原則論の方が大きい、かも)に導入されたものだが、より大きな権限が必要な場合は確認ダイアログを出して、必要に応じて与えてしまう、と言う機能もあり、完全に制限しているわけではない。
ま、正直言ってお役所仕事みたいなもので(WindowsというかMicrosoftが)責任回避をするために、イチイチ確認を取る(ここから先はあんたの責任だぜ、いいね?ってなもん)だけみたいなもんで、肝心のマルウェア対策としてどれだけ実効があるか・・・神のみぞ知る、だ(マルウェア製作者は、そのあたりの平凡な技術者より数段優秀な人間が多いのので、たいていの回避策は心得ていると思われる)。
とはいえ、普通のアプリを制作する立場として、面倒だ、ややこしいのは嫌だなぁ、と言って避けるわけにもいかない。
前置きが長くなったが、UAC絡みで32bitsアプリを64bits版 Windows上で動作させるには、あれこれ対策を盛り込まないといけない。そのあたりをまとめてみると・・・
まず、64bits版 Windows にはWOW64(Windows 32-bit emulation On Windows 64-bit) という仕組みがあり、32bits アプリはこの一種の(簡易)仮想マシン上で動作させられる。
このWOW64上ではネイティブな64bitsアプリの動作環境と比べても、さらに多くの制限がある。
制限以前の問題として、そもそもシステムフォルダが64bits用と32bits用では異なるのだが、64bits 環境でも、システムプログラムの多くは 32bits時代からの実行ファイル名をそのまま引き継いでおり、まったく同じ名前のファイルが両方のフォルダに存在する。
つまり、アプリ上からはシステムプログラムの名前に違いはなく、32bits環境から実行すれば、32bits版が、64bits環境から実行すれば64bits版が実行される仕組みだ。謂わばこれを実現するためもあり、アプリ上からはシステムフォルダ名の違いなどが見えないようになっている。
具体的に言えば、ファイルシステム上では64bits用のシステムフォルダは \Windows\system32 で、32bits用は \Windows\SysWOW64 なのだが、32bitsアプリから \Windows\system32 を参照しても、実際に見えるのは SysWOW64 の方である。逆もまたしかり。
では32bitsアプリからは、この実体としての \Windows\system32 はまったく見えないのかというと、そうでもなくて、 \Windows\sysnative と言うフォルダを参照すると見ることが出来る。もちろん、実際のファイルシステム上には sysnative と言うフォルダは存在しないのだが。
逆に SysWOW64 を参照するにはその通りに指定すれば見える。
実際には、この名称は変更される可能性もあるため具体的な名称は
UINT WINAPI GetSystemWow64Directory(LPTSTR lpBuffer,UINT uSize);
と言うAPIを使用して得るのが正しい。
このあたりの仕組みは、「ファイルシステムリダイレクタ(File System Redirector)」と呼び、一時的に On/Off をコントロールすることも出来る。
そのためには、
BOOL WINAPI Wow64DisableWow64FsRedirection(PVOID* OldValue);
BOOLEAN WINAPI Wow64EnableWow64FsRedirection(BOOLEAN Wow64FsEnableRedirection);
BOOL WINAPI Wow64RevertWow64FsRedirection(PVOID OldValue);
あたりのAPIを使用する。これらの効果はアプリ単位ではなく、スレッド単位である。
・・・[未完]