About virtualization of Registry
Windows Vista 以降のクライアント Windowsでは、特定のKeyへのアクセスがリダイレクトされる
この件について調べてみた
リダイレクトの挙動の概要は下記である。
--------------- Yes ---------------- Yes
Start ->---| 64bitカーネルの |-----| 32bitバイナリか? |-----> rule A 適用
| Windowsか ? | | |
---------------- ----------------
| No 32bit | No 64bitバイナリである
| カーネルである |
|------------------------------------> rule B 適用
[rule A]
64bit カーネルのWindowsにおいて32bitバイナリは、32bitプロセスとしてWOW 64(Windows On Windows 64)に32bit systemをエミュレートしてもらってその上を走るのでこのルールが適用されます。
HKEY_LOCAL_MACHINE\Software 配下等特定のレジストリキーへのアクセスは、Wow6432Nodeに含まれるロケーションにリダイレクトされます。
HKEY_LOCAL_MACHINE\Software -> (リダイレクト先) HKEY_LOCAL_MACHINE\Software\Wow6432Node
[rule B]
UACによるリダイレクト が行われる
HKEY_LOCAL_MACHINE\SOFTWARE ->(リダイレクト先) HKEY_CURRENT_USER\Software\Classes\VirtualStore
[WOW64環境で走っているかどうかの確認]
WOW64.pas
unit WOW64;
// wether OS is windows
{$IFDEF MSWINDOWS}
// wether target platform is Windows 32bit
{$IFDEF WIN32}
{$DEFINE MYTARGET}
{$ENDIF}
{$ENDIF}
interface
{$IFDEF MYTARGET}
uses Windows;
{$ENDIF}
function IsWOW64 : Boolean;
{$IFDEF MYTARGET}
var
IsWow64Process : function(hProcess : THandle; var Wow64Process : BOOL) : BOOL stdcall;
{$ENDIF}
implementation
function IsWOW64 : Boolean;
{$IFDEF MYTARGET}
var
Flg : BOOL;
begin
Result := False;
@IsWow64Process := GetProcAddress(GetModuleHandle('kernel32.dll'), 'IsWow64Process');
if @IsWow64Process
nil then begin
if IsWow64Process(GetCurrentProcess, Flg) then Result := Flg;
end;
{$ELSE}
begin
Result := False;
{$ENDIF}
end;
end.
XP (32bit) での実行結果
なお、UAC制限によるリダイレクトは、Interactive process の場合は行われないらしいが、
Interactive process とは何なのか? 想像するにコマンドラインプログラムは、Interactive processではなさそうだが真相は不明