64bitのWindows OSでは、32bitアプリケーションとの互換性のために一部のレジストリやファイルが「リダイレクト」や「リフレクト」されたり、「仮想化」されている。その仕組みと役割について解説。レジストリを操作するツールについてもまとめておく。
前回は、レジストリの概要と主要なキーなどについて解説した。今回はレジストリに関するより進んだ話題として、レジストリの「リダイレクト」や「リフレクション」「仮想化」とレジストリを操作するツールなどについて見ていく。
Windows OSには32bit版と64bit版の2種類があり、それに応じて、アプリケーションのバイナリにも32bit版(Win32)と64bit版(Win64)の2種類のタイプがある(64bit OSについては関連記事も参照)。32bit版と64bit版のアプリケーションは、通常はほぼ同じ機能を提供するべく、ソースコードや仕様なども共通化するのが原則である。だが、そのためにいくらか問題が生じることがある。
例えばアプリケーションが利用できる最大メモリサイズを規定するようなレジストリエントリMaxUseMemSizeを作成したとする。32bit版アプリケーションではプロセス空間の制約上、この値はせいぜい2Gbytes以下にしなければならない(関連記事参照)。しかし、64bit版アプリケーションでは10Gbytesとかもっと大きな値でもよいだろう。
このレジストリエントリは、32bit版と64bit版の両方のアプリケーションで同じ場所や名前として参照できなければならない。そうでないと、ソースコードをいちいち作り分ける必要があるし、レジストリを使う意味も薄れてしまう。
また1台のシステムに両方のバイナリがインストールされる(可能性がある)ことを考えると、2種類のバイナリで設定やコンポーネントなどは分離しつつも(32bitのDLLと64bitのDLLは、同じ名前でも隔離して管理する必要がある)、レジストリのような共通機能へは同じようにアクセスできる必要がある。
このような要請に応えるためにWindows OSに用意されているのが「レジストリ(およびファイル)のリダイレクト」機能である。これは、論理的には同じレジストリ値やファイル/フォルダーを参照しながらも、32bit版と64bit版のアプケーションに対して異なるビュー(視点)を提供するものである。
64bit Windows OS下で32bitアプリケーションがレジストリへアクセスする場合、以下のレジストリキーに対してリダイレクトが行われる。ただしこれらのサブキー以下が全てリダイレクトされるわけではなく、一部はリダイレクトされない(=元の場所へアクセスされる。「共有」と呼ぶ)ものもある。詳細は先のMSDNサイトのページを参照していただきたい。
「Wow6432Node」というキーは、「WOW64」という、64bit Windows OS上で、32bitアプリケーションを実行するための実行環境(関連記事参照)によって作成されるキーである。
32bitアプリケーションが「HKLM\SOFTWARE」へアクセスすると、実際には「HKLM\SOFTWARE\Wow6432Node」にアクセスするようにWOW64によって自動的にリダイレクトされる。これにより、32bitアプリケーションと64bitアプリケーションは、同じレジストリを参照しながらも、実際にはそれぞれ別の場所にアクセスするようになっている。
これら以外のキー、例えばHKLM\SYSTEMなどは32bitアプリケーションでも64bitアプリケーションでも、同じ場所を参照する(=共有される)ことになる。
レジストリのリダイレクト処理では、レジストリキーのアクセス先の変更に加えて、リダイレクトされた内容の変更(上書き)が行われることもある。これは、上の関連記事で述べている「ファイルシステムのリダイレクト」に対応させるための措置である。
例えば、32bitアプリケーションがREG_SZやREG_EXPAND_SZタイプで次のような文字列をレジストリに書き込もうとしているのを検出すると、その値を変更して、32bitアプリケーションのためのフォルダーである「C:\Program Files (x86)」などに誘導する。
レジストリが実際にリダイレクトされるとどうなるかの例を次に示す。ここでは「reg query」コマンドでレジストリ「HKLM\SOFTWARE\Microsoft\Help」を参照している(regコマンドについては後述)。regコマンドは、通常は64bitモードの(リダイレクトされていない)レジストリを表示するが、32bitモードのregコマンドを起動するか、「/reg:32」といオプションを付けると、リダイレクトされた様子を観察できる。
※以下は全て64bit版のWindows 7上での実行例。レジストリのリダイレクトは64bit Windowsでのみ行われる。
C:\>reg query HKLM\SOFTWARE\Microsoft\Help ……64bitアプリから通常アクセスしてみる
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Help\v1.0 ……1キーだけ見つかった
C:\>C:\Windows\SysWOW64\reg query HKLM\SOFTWARE\Microsoft\Help ……32bitアプリケーションのregコマンドからアクセスしてみる
※C:\Windows\SysWOW64以下には、WOW64で利用する、32bitモードの実行プログラム環境が保存されている
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Help\v1.0 ……32bitモードだとキーが3つ見つかっている。64bit版とはレジストリのビューが異なることが分かる
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Help\v2.0 ……見つかった2つ目のキー
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Help\v2.1 ……見つかった3つ目のキー
C:\>reg query HKLM\SOFTWARE\Microsoft\Help /reg:32 ……32bitモードでアクセスしてみる。regコマンドに「/reg:32」とすると、32bitアプリケーションのためにリダイレクトされたレジストリにアクセスできる
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Help\v1.0 ……結果は3つ見つかった。32bitアプリケーションでの実行結果と同じ
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Help\v2.0
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Help\v2.1
C:\>reg query HKLM\SOFTWARE\Microsoft\Help /reg:64 ……「/reg:64」は64bitモードでのアクセスの指示
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Help\v1.0 ……最初の例と同じで結果は1つだけ。64bitモードのレジストリが見えているということ
C:\>C:\Windows\SysWOW64\reg query HKLM\SOFTWARE\Microsoft\Help /reg:64 ……32bitアプリケーションから64bitモードのレジストリを参照してみる
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Help\v1.0 ……結果は1つだけ。64bitモードのレジストリが見えている
C:\>reg query HKLM\SOFTWARE\Wow6432Node\Microsoft\Help ……リダイレクト先を確認してみる
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Help\v1.0 ……結果は3つ見つかった。32bitモードでの実行結果と同じで、この場所にリダイレクトされていることが分かる
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Help\v2.0
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Help\v2.1
C:\>
「レジストリのリダイレクト」と似たものとして、「レジストリのリフレクション(反映)」という機能もある。
これは、32bitもしくは64bitのアプリケーションで、あるレジストリを更新すると、自動的に対応する他方のキーが更新され(反映され)、レジストリ内容を同期できるという機能である。完全に分けてしまうと、保存したはずの値が読み出せない(例:32bitアプリケーションで保存したものが、64bitアプリケーションで読み出せないなど)ということが起こる可能性もあるので、自動的に反映するようになっている。
この機能は64bit版のWindows XP/Windows Vista/Windows Server 2003/Windows Server 2008で利用できたが、使いづらかったためか、Windows 7/Windows Server 2008 R2以降では廃止されて、全てリダイレクトと共有を使うようになっている。
「レジストリのリダイレクト」「レジストリのリフレクション」と並んで、さらにもう1つ、UAC環境で利用されている「レジストリの仮想化」という機能もある。
Windows Vista/Windows Server 2008以降のWindows OSには、管理者権限の利用を制限する「UAC(ユーザーアクセス制御)」という機能がある。たとえAdministratorsグループのアカウントでログオンしていても、UACによる確認ダイアログに同意しないと、管理者権限の利用を制限する、という機能である。管理者権限のあるアカウントでログオンするとユーザーにはさまざまな特権が与えられるが(関連記事参照)、UACが有効な環境ではその特権の付与は一時的に保留されており、UACに同意した場合にのみ実際の権限を割り当てる、という仕組みで動作している。
このUACによるアクセス権の制限はレジストリへの書き込みにも適用される。だが、アプリケーションによってはこのせいで実行に失敗する可能性がある。特に古い従来の32bitアプリケーションではこの影響が大きいため、互換性のために「レジストリとファイルの仮想化」という機能が用意された(詳細は関連記事参照)。
UACが有効な環境で、アプリケーションが権限不足で以下のレジストリに書き込めなかった場合、その代替場所として、ユーザーレジストリの中へデータを書き込む(ファイルの仮想化については省略)。
レジストリから読み出す場合は、まず仮想化で迂回して書き込まれた先から読み出しを試み、存在しなければ元の指定された場所から読み出す(Copy-on-Write方式で、権限不足で書き込めなかったレジストリ値だけがVirtualStoreに保存されている)。
レジストリが仮想化されているかどうかは、「reg flags」コマンドで確認・設定できる。
C:\>reg flags HKLM\Software\Microsoft ……仮想化を確認する
HKEY_LOCAL_MACHINE\Software\Microsoft
REG_KEY_DONT_VIRTUALIZE: CLEAR ……仮想化されているという意味
REG_KEY_DONT_SILENT_FAIL: CLEAR
REG_KEY_RECURSE_FLAG: CLEAR
この操作を正しく終了しました。
C:\>reg flags HKLM\Software\Microsoft\Windows ……サブキーの仮想化を確認する
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows
REG_KEY_DONT_VIRTUALIZE: SET ……仮想化されていないという意味
REG_KEY_DONT_SILENT_FAIL: CLEAR
REG_KEY_RECURSE_FLAG: SET
この操作を正しく終了しました。
C:\>reg flags HKLM\System ……対象外のキーをチェックしてみる
エラー: この操作は、HKLM\Software のサブキーでのみ実行できます。……仮想化の対象外でエラー
「REG FLAGS /?」と入力すると使用法が表示されます。
C:\>
このレジストリ(およびファイル)の仮想化は、32bitのインタラクティブなアプリケーションでしか利用できない。それでも古いレガシーなアプリケーションにとっては、改修することなくUAC環境との互換性を確保できる、便利な機能である。
レジストリを操作するためのツールやコマンドを紹介しておく。
Windows OS上でレジストリを操作する場合、まず最初に使うのはWindows OS標準の「レジストリエディター」だろう。「スタート」メニューなどには登録されていないので、実行するためには、「ファイル名を指定して実行」で「regedit」と入力して起動する。主な機能は次の通りだ。
レジストリエディターの使い方についてはここでは触れないので、以下の記事などを参照していただきたい。
コマンドプロンプト上で作業する場合は、Windows XP/Windows Server 2003以降のWindows OSなら「reg.exe」コマンドが利用できる。レジストリの閲覧や検索、値の追加/修正、エクスポート/インポート(.regテキストファイル形式)、セーブ/リストア(ハイブ形式)、ロード/アンロード(一時的に別の場所に復元する)、コピーなどが行える。具体的な操作方法については以下の記事を参照していただきたい。
以下にregコマンドによる操作例を示しておく。
C:\>reg query hklm ……HKLMキーのトップレベルを見る
HKEY_LOCAL_MACHINE\BCD00000000
HKEY_LOCAL_MACHINE\COMPONENTS
HKEY_LOCAL_MACHINE\HARDWARE
HKEY_LOCAL_MACHINE\SAM
HKEY_LOCAL_MACHINE\SECURITY
HKEY_LOCAL_MACHINE\SOFTWARE
HKEY_LOCAL_MACHINE\SYSTEM
C:\>reg query hklm\software ……HKLM\Softwareを見る
HKEY_LOCAL_MACHINE\software
(既定) REG_SZ
HKEY_LOCAL_MACHINE\software\3Dconnexion
HKEY_LOCAL_MACHINE\software\7-Zip
HKEY_LOCAL_MACHINE\software\AGEIA Technologies
……(以下省略)……
C:\>reg query "hklm\software\microsoft\windows nt" /s ……空白が含まれる場合は引用符で囲む。/sを付けるとサブキーまで全部表示される
HKEY_LOCAL_MACHINE\software\microsoft\windows nt\CurrentVersion
CurrentVersion REG_SZ 6.1
CurrentBuild REG_SZ 7601
SoftwareType REG_SZ System
CurrentType REG_SZ Multiprocessor Free
……(以下省略)……
PowerShellには「Registryプロバイダー」という機能があり、レジストリをファイルシステム(ファイルやフォルダー)のようにシームレスに扱うことができる。例えば「dir HKLM:\SOFTWARE」と実行すれば、「HKLM\Software」の一覧を表示できる。PowerShellによるレジストリの操作方法については、以下の記事を参照していただきたい。
PS C:\> dir hklm: ……HKLMの表示
Hive: HKEY_LOCAL_MACHINE
Name Property
---- --------
BCD00000000
COMPONENTS StoreFormatVersion : {48, 0, 46, 0...}
StoreArchitecture : {9, 0, 0, 0}
HARDWARE
……(以下省略)……
PS C:\> dir HKLM:\SYSTEM\CurrentControlSet ……サブキーの表示
Hive: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet
Name Property
---- --------
Control PreshutdownOrder : {wuauserv, gpsvc, trustedinstaller}
WaitToKillServiceTimeout: 12000
……(以下省略)……
WSHスクリプトでレジストリを操作するには、RegRead/RegWrite/RegDeleteなどのメソッドを使う。具体的な操作方法については、以下の記事を参照していただきたい。
レジストリを操作するツールは有償/無償を含め非常に多く存在する。ここではSysinternalsツール集に含まれる「Process Monitor(procmon.exe)」ツールを紹介しておく。
Process Monitorは、システム上で動作している各種プロセスの状態をモニター(監視)するツールだ。その監視対象の1つに、レジストリ操作の監視機能がある。あるアプリケーションがどのようなレジストリエントリを参照・操作しているかがリアルタイムで確認できるので、トラブルシューティングなどに便利なツールである。
今回はレジストリのリダイレクトやリフレクション、仮想化などについて解説した。通常はこれらの機能についてはユーザーが気にする必要はないだろう。だがプログラムから見たレジストリ(やファイル)の場所と、実際に書き込まれている場所が異なるので、その仕組みを知らないと原因の究明などが困難になる可能性がある。トラブルシューティングなどでレジストリ関連の作業をよく行うなら、知っておくとよいだろう。
Copyright© Digital Advantage Corp. All Rights Reserved.