Windows レジストリ(英語: Windows Registry)とは、Microsoft Windows オペレーティングシステムで用いられる設定情報の階層型データベースである。システムに関するデータやアプリケーションの設定、拡張子の関連付け、ユーザーパスワードなどが保存されている。Windows 95およびWindows NT以降で主流となった。

この節では、`reg`ファイルや、レジストリの実体であるハイブのバイナリファイルフォーマット`regf`についても解説する。

## 歴史

Windows 3.1までは、オペレーティングシステムの各種設定情報をINIファイル等の設定ファイルに保持させる方法で行われてきた。しかし、この方法では大量の設定項目を処理するには非効率的であり無駄が多いため、レジストリに置き換えられた。

現在のようにレジストリが広く用いられるようになったのはWindows 95からであるが、レジストリ自体はそれ以前、Windows 3.1のころから存在した。ただし関連付けやOLE情報など小規模な利用にとどまっていた。

## アーキテクチャ

エディタ上では、レジストリはキーと値で構成され、それぞれファイルシステム上におけるフォルダ、またはファイルに相当する。そのため、キーは複数のサブキーや値を持つことができ、キーを参照する方法として、File Explorerにおけるパスに似た参照の仕方ができる(例:`HKEY_LOCAL_MACHINE\Software\Microsoft\Windows`)。

### ルートキー

| 定数 | 名前 | 備考 |
| --- | --- | --- |
| `0x80000000` | HKEY\_CLASSES\_ROOT(HKCR) | ProgIDやCLSID、IIDなどのファイル名拡張子の関連付け情報とCOMクラス登録情報などが保存されている。`HKEY_LOCAL_MACHINE\Software\Classes`と`HKEY_CURRENT_USER\Software\Classes`のキーを結合したレジストリビュー。 |
| `0x80000001` | HKEY\_CURRENT\_USER(HKCU) | 現在コンピューターにログオンしているユーザーのユーザープロファイル(環境変数、個人プログラムグループ、デスクトップ設定、ネットワーク接続、プリンター、およびアプリケーションの設定)が保存されている。ここに保存された情報は他のユーザーの設定情報に影響を及ぼさない。`HKU\現在ログオンしているユーザーのSID`のエイリアス。 |
| `0x80000002` | HKEY\_LOCAL\_MACHINE(HKLM) | バスの種類、システム メモリ、インストールされているハードウェアとソフトウェアに関するデータ、PnP情報、ネットワーク ログオン設定、ネットワークセキュリティ情報、ソフトウェア関連情報、その他のシステム情報が保存されている。 |
| `0x80000003` | HKEY\_USERS(HKU) | ローカル コンピューター上の新しいユーザーの既定のユーザー構成(`.DEFAULT`)と、全てのユーザー(ビルトインユーザーを含む)のユーザー構成を保存。 |
| `0x80000004` | HKEY\_PERFORMANCE\_DATA | Windows NTのみで利用可。レジストリエディタで編集不可。 |
| `0x80000005` | HKEY\_CURRENT\_CONFIG(HKCC) | ローカルコンピューターシステムの現在のハードウェアプロファイルに関する情報が保存されている。 |
| `0x80000006` | HKEY\_DYN\_DATA | Windows 9xのみで利用可。レジストリエディタで編集可。 |

### 値

| 定数 | 名前 | 備考 |
| --- | --- | --- |
| `0x00000000` | REG\_NONE | データ型なし。 |
| `0x00000001` | REG\_SZ | 文字列型(NULLで終端)。ANSIかUnicodeかはデータを編集するのに使用された関数に依存する。 |
| `0x00000002` | REG\_BINARY | 任意のデータ形式。 |
| `0x00000003` | REG\_EXPAND\_SZ | 環境変数を表現可能な文字列型(NULLで終端)。ANSIかUnicodeかはデータを編集するのに使用された関数に依存する。 |
| `0x00000004` | REG\_DWORD / REG\_DWORD\_LITTLE\_ENDIAN | 32ビット符号なし整数。 |
| `0x00000005` | REG\_DWORD\_BIG\_ENDIAN | 32ビット符号なし整数。 |
| `0x00000006` | REG\_LINK | あるレジストリキーへのシンボリックリンク。 |
| `0x00000007` | REG\_MULTI\_SZ | 1つのNULL終端文字で区切られた複数の文字列を表現可能な文字列型(2つのNULLで終端)。ANSIかUnicodeかはデータを編集するのに使用された関数に依存する。 |
| `0x00000008` | REG\_RESOURCE\_LIST | リソース列(PnPで使用されている)。 |
| `0x00000009` | REG\_FULL\_RESOURCE\_DESCRIPTOR | 完全リソース記述子(PnPで使用されている)。 |
| `0x0000000A` | REG\_RESOURCE\_REQUIREMENTS\_LIST | リソース要件列(PnPで使用されている)。 |
| `0x0000000B` | REG\_QWORD / REG\_QWORD\_LITTLE\_ENDIAN | 64ビット符号なし整数。 |

### ハイブ

レジストリエディタでは、レジストリは統合階層型データベースとして仮想的に表示されているが、レジストリは実際にはハイブと呼ばれる多数のディスクファイルに保存される。`HKLM\HARDWARE`など、ディスクに保存されるのではなく、システムの情報を収集し集約したハイブが存在する。また、`HKCU`などディスク上の他のハイブからのショートカットとしてのハイブも存在する。

### ハイブの保存場所(Windows NT以降)

| ハイブのパス | 対応するキーのパス |
| --- | --- |
| `%SYSTEM%\Config\Sam` | `HKEY_LOCAL_MACHINE\SAM` |
| `%SYSTEM%\Config\Security` | `HKEY_LOCAL_MACHINE\SECURITY` |
| `%SYSTEM%\Config\Software` | `HKEY_LOCAL_MACHINE\SOFTWARE` |
| `%SYSTEM%\Config\System` | `HKEY_LOCAL_MACHINE\SYSTEM` |
| `%SYSTEM%\Config\Default` | `HKEY_USERS\.DEFAULT` |
| `%SYSTEM%\Config\Userdiff` | なし(オペレーティングシステムのアップグレード時に使用される)。 |
| `%USERPROFILE%\Ntuser.dat` | `HKEY_USERS\<ユーザーSID>` |
| `%LocalAppData%\Microsoft\Windows\Usrclass.dat` | `HKEY_USERS\<ユーザーSID>_Classes` (現在のユーザーであれば、`HKEY_CURRENT_USER\Software\Classes`) |

## 編集

### レジストリエディタ(regedit.exe)

Windows 3.1では`regedit.exe`、 NT系の場合、`regedit.exe`と`regedt32.exe`の2つが存在する。Windows NT 3.xや4.xの`regedit.exe`には複数の制限があったが、Windows XPからは制限が撤廃され、`regedt32.exe`も単に`regedit.exe`を呼び出すだけのプログラムとなった。

レジストリは階層型データベースであるため、左側のビューにはツリー構造で表示されたキーやサブキーが表示され、右側のビューには選択されたキーの値のリストが表示される。レジストリエディタは次のことができる。

- レジストリキー、サブキー、値、値データの閲覧、作成、操作、名前変更、削除
- キーの`REG`ファイルやレジストリハイブ形式でのインポートやエクスポート
- レジストリハイブ形式のファイルのロード、アンロード、操作(Windows NT系のみ)
- キーに対する操作の権限の閲覧、設定(Windows NT系のみ)
- 選択したキーをお気に入りとしてブックマーク
- キー名、値名、値データで特定の文字列を検索
- ネットワーク上の別のコンピューターのレジストリをリモートで操作

### REGファイル

INIファイル形式の構文を使用して、レジストリの一部をエクスポートおよびインポートするためのテキストベースの人間が読めるファイル。

Windows 9xおよびWindows NT 4.0では、`REGEDIT4`というヘッダが含まれ、Windows 2000以降では、`Windows Registry Editor Version 5.00`というヘッダが含まれる。また、`REGEDIT4`ヘッダを持つREGファイルはWindows 2000以降のシステムでも利用可能。

基本的な構文は、以下の通りである。文字列型の場合、`<値型>`は必要ないが、値データには、C言語同様に、バックスラッシュはもう一つバックスラッシュ(`\\`)をつけ、引用符は先頭にバックスラッシュ(`\"`)をつけて、エスケープしなければならない。

`HKLM\SOFTWARE\Hoge`キーにさまざまな型で値を追加する場合は、以下の通りである。

データを削除するには、削除するデータの後にマイナス記号(`-`)を以下のように追加する。

### コマンドライン

コマンドラインでは、複数のツール(`reg.exe`、`regini.exe`、`regedit.exe`)が利用可能である。

`reg.exe`のコマンドとその用途は次のとおりである。

### PowerShell

PowerShellでは、フォルダと同じようにレジストリキーや値を参照することができる。

### プログラム

プログラムが直接レジストリを編集するための高レベルAPIが`advapi32.dll`を通して公開されている。プラットフォームAPIに直接アクセスする方法があるにもかかわらず、ラッパーを公開している言語も存在する(C#やVB:`Microsoft.Win32.Registry`、Delphi:`TRegistry`)。特に有名な関数を以下に挙げる(ANSIやUnicodeの区別はしない)。

- RegCloseKey
- RegConnectRegistry
- RegCreateKey (RegCreateKeyEx)
- RegDeleteKey
- RegDeleteValue
- RegEnumKey (RegEnumKeyEx)
- RegEnumValue
- RegFlushKey
- RegGetKeySecurity
- RegLoadKey
- RegNotifyChangeKeyValue
- RegOpenKey (RegOpenKeyEx)
- RegQueryInfoKey
- RegQueryMultipleValues
- RegQueryValue (RegQueryValueEx)
- RegReplaceKey
- RegRestoreKey
- RegSaveKey
- RegSetKeySecurity
- RegSetValue
- RegSetValueEx
- RegUnLoadKey

## セキュリティ

Windows NT以降のレジストリの各キーは、NTFS上のファイル等と同様、細かくアクセス制御するためのセキュリティ記述子が存在する。ここでは、レジストリキー特有のアクセス制御の種類のみについて説明する。

### アクセス制御の種類

| 値 | 名前 | 記述子トークン | 備考 |
| --- | --- | --- | --- |
| `0x00000001` | `KEY_QUERY_VALUE` | `CC` | レジストリキー値を読み取る権利。 |
| `0x00000002` | `KEY_SET_VALUE` | `DC` | 新しい値を作成、変更、削除する権利。 |
| `0x00000004` | `KEY_CREATE_SUB_KEY` | `LC` | サブキーを作成する権利。 |
| `0x00000008` | `KEY_ENUMERATE_SUB_KEYS` | `SW` | サブキーを列挙する権利。 |
| `0x00000010` | `KEY_NOTIFY` | `RP` | キーまたはサブキーの変更を通知される権利。 |
| `0x00000020` | `KEY_CREATE_LINK` | `WP` | リンクを作成する権利(システムによって予約済み)。 |

## REGFフォーマット

レジストリハイブのバイナリファイルフォーマット(`REGF`)は公式にはこれまで公開されたことはない。しかし、Microsoft Symbol Serverからは未公開の関数や構造体のシンボル情報が事実上公開されており、Windows Internalsブックには、レジストリとそのバイナリファイル形式の詳細が書かれているセクションが存在する。

`REGF`ファイルには、ベースブロック(ヘッダー)と、ビンのシーケンスで構成され、1つのビンの中にはそのヘッダと断続的に割り当てられたセルが存在する。

### ベースブロック(Base block)

フォーマットのバージョン、一番最初のビンのオフセット、全てのビンのサイズなどの情報が含まれた、4096バイト長(`HBASE_BLOCK`)のデータ。

### ビン(Bin)

自身のオフセット、自身のサイズなどの情報が含まれた、32バイト長(`HBIN`)のデータ。このデータのすぐ後にこのビンの一番最初のセルのデータが続く。

### セル(Cell)

キー、サブキー、値、値データ、ACLなどレジストリエディタで表示される全てのエンティティを表し、自身のサイズと実際のバイナリデータが含まれた可変長(`HCELL`)のデータ(ビン内部の割り当てられていないスペースもこのデータで表される)。

| 種類 | シグネチャ | 備考 |
| --- | --- | --- |
| キーノード | `nk` | 単一のレジストリキーとそれに関連するデータ(`CM_KEY_NODE`)を表す。 |
| サブキーのインデックス | `li`、`lf`、`lh`、`ri` | 特定のキーのサブキーを表すキーノードセルのインデックスの可変長リストのデータ(`CM_KEY_INDEX`)。パフォーマンス上の理由から、サブキーインデックスには、インデックスリーフ(`li`)、ファストリーフ(`lf`)、ハッシュリーフ(`lh`)、ルートインデックス(`ri`)の4つの種類が存在する。 |
| キーの値 | `vk` | キーの名前、タイプ、データの長さ、実際のデータを含むセルへの参照などのデータ(`CM_KEY_VALUE`)を表す。 |
| セキュリティ記述子 | `sk` | 1つ以上のキーのアクセス制御情報のデータ(`CM_KEY_SECURITY`)表す。 |
| ビッグデータ | `bd` | ハイブバージョン1.4以降で16 KiBを超える値データ(`CM_BIG_DATA`)を表す。最大16 KiBのチャンクデータに分割される。 |
| 未割り当てデータ | なし。 | なし。 |

## バックアップ・復旧

何らかの原因によりレジストリに不正な設定が書き込まれたり、レジストリデータベースが破壊された際、システムが自動的にバックアップしたデータベースから復旧できる場合がある。Windows XPの場合、レジストリデータベースの本体は、`%System%\Config\` の配下にある。システムは、`%SystemRoot%\Repair\`配下にWindowsのインストール完了時点の設定データベースをバックアップしているため、回復コンソールなどを使用して、ファイルをコピーすることでレジストリの設定値を戻すことができる。