Win32/64技術 005 レジストリ操作

提供:yonewiki
2024年1月27日 (土) 01:19時点におけるYo-net (トーク | 投稿記録)による版 (→‎RegSetValueExW)

Win32/64_アプリケーション開発に戻る。

前の記事:Win32/64技術 004 文字列グローバル変数にHGLOBALを使う一例

次の記事:[[Win32/64技術 006]]

概要

 レジストリ操作の処理に関わる部分についての記事です。レジストリの個々の役割についての情報自体は別の項目でまとめ上げる必要があると感じてはいます。しかし、レジストリの役割やレジストリの技術概要を述べるだけでも一冊の本になってもおかしくない内容になります。ここでは、その全体像の中から、C++(Cpp)プログラムでの操作についてのみ纏めたいと思います。


 操作するプログラムを走らせる場合は、システムを壊してしまう可能性があります。すべてのレジストリ項目についてバックアップを取った上で操作することが必要で、レジストリ構造が壊れてしまった場合はWindowsが一切機能しなくなる可能性もゼロではありません。それでも説明している側にはなんら責任はないことを理解して下さい。安全確認は開発者個人で進める必要があります。なめてると痛い目に逢う。それがレジストリ操作です。このたぐいのだいたいのSiteでもこのような注意書きがあるはずです。それと同じです。


 レジストリでキーを作成するには以下の関数を使います。


RegCreateKeyExW

■RegCreateKeyExW(HKEY, LPCWSTR, DWORD, LPWSTR, DWORD, REGSAM, CONST LPSECURITY_ATTRIBUTES, PHKEY, LPDWORD)

第1引数:HKEY hKey

 レジストリ操作をする大分類のキー構造のトップキーの種類について指定する部分です。HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CURRENT_CONFIG が代表的な値です。Windows.hを読み込んでいれば読み込まれるwinreg.hにIDが定義されたマクロが定義されています。あるいは、この関数の実行により得られるハンドル値を指定すると前回作成したキー値に対しての相対パスのようなキー構造の指定ができるようになります。


第2引数:LPCWSTR lpSubKey

 作成するキー構造について文字列で指定します。下のサンプルでは、LR""リテラルに文字列を定義しています。リテラルの種類に関してはリテラルの記事を参考にして下さい。


第3引数:DWORD Reserved

 このパラメーターは予約されており、0 である必要があります。


第4引数:LPWSTR lpClass

 このキーのユーザー定義クラス型。このパラメーターは無視できます。このパラメーターは、NULL(nullptrの利用を推奨) でもかまいません。


第5引数:DWORD dwOptions

 規定値はREG_OPTION_NON_VOLATILEで0です。揮発性でないレジストリキー作成であることを意味します。そのほかの意味を持たせる場合はそれ以外の値を指定します。REG_OPTION_VOLATILEで揮発性のレジストリキーを作成し、保存されないけど、アプリケーション実行中だけ存在するレジストリキーとすることができます。REG_OPTION_CREATE_LINKでシンボリックリンク、REG_OPTION_BACKUP_RESTOREで第6引数のキーのバックアップ、復元をするのに必要な権限で操作します。


第6引数:REGSAM samDesired  様々なアクセス権設定フラグが準備されています。キーや値を作成するにはKEY_WRITEの権限が必要です。その他の権限の説明についてはマイクロソフト公式の説明に今のところは譲っておきます。https://learn.microsoft.com/ja-jp/windows/win32/sysinfo/registry-key-security-and-access-rights


第7引数:CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes

 SECURITY_ATTRIBUTES型の変数で例えばsaなら&saとポインタを指定すると、そのメンバ変数sa.bInheritHandle = TRUEのように設定した値であったなら、子プロセスの継承が許可できます。このようにしてキーの作成をすると、プログラムで子プロセスを生成したときに継承を許可していれば、作成したキーが継承されて参照できるようになります。


第8引数:PHKEY phkResult

 HKEY型のポインタを指定すると、作成したキーへのハンドル値のようなものを得ることができます。これを使って、作成したキーへの相対的なキー構造操作を実現します。HKEY型のeventlabelsという変数を作ったなら、&eventlabelsのように指定するとよいです。


第9引数:LPDWORD lpdwDisposition

いずれかの処理値を受け取る変数へのDWORD型のロングポインターを設定すると、その中身にREG_CREATED_NEW_KEY(1)かREG_OPENED_EXISTING_KEY(2)が返ります。1ならキーが存在せず作成されましたことを意味していて、2ならキーは存在し変更されずに単純に開かれたことを意味します。


 HKEY_CURRENT_USERのAppEvents\EventLabelsを作る。既に存在している場合は何もしないプログラムは以下のようになります。


サンプルプログラム

if (HKEY eventlabels; RegCreateKeyExW(/*1*/ HKEY_CURRENT_USER, /*2*/ LR"(AppEvents\EventLabels)", /*3*/ 0, 
                                      /*4*/ nullptr, /*5*/ 0, /*6*/ KEY_WRITE, 
                                      /*7*/ nullptr, /*8*/ &eventlabels, /*9*/ nullptr) == ERROR_SUCCESS){
  if (HKEY key; RegCreateKeyExW(/*1*/ eventlabels, /*2*/ LR"(Sample_Connected)", /*3*/ 0,
                                /*4*/ nullptr, /*5*/ 0, /*6*/ KEY_SET_VALUE,
                                /*7*/ nullptr, /*8*/ &key, /*9*/ nullptr) == ERROR_SUCCESS) {
    RegCloseKey(key);
  }
  RegCloseKey(eventlabels);
}


 RegCreateKeyExW関数を正常に実行できた場合、レジストリ編集をする必要がなくなった時にRegCloseKey関数を実行しないと、リソースリークが起きたままになります。必要がなくなったら、RegCloseKey関数を実行しましょう。簡単な関数ですが重要です。次の項目で紹介します。

 

RegCloseKey

■RegCloseKey(HKEY)

第1引数:HKEY hKey

 RegCreateKeyExWでレジストリキー操作をしたときの第8引数に設定したHKEY型のポインタの実体の変数を設定すると、キー操作したときのキーハンドルを閉じることができます。実行しない場合はキーをオープンするために使用するリソースが解放されないままになってしまいます。必要がなくなったら閉じましょう。


 コードのサンプルはひとつ前の項目で示したので省略します。


RegSetValueExW

■RegSetValueExW(HKEY, LPCWSTR, DWORD, DWORD, CONST BYTE*, DWORD)

第1引数:HKEY hKey

RegCreateKeyExWでレジストリキー操作をしたときの第8引数に設定したHKEY型のポインタの実体の変数を設定すると、そのキーに対する値の設定処理ができる。

第2引数:LPCWSTR lpValueName

第3引数:DWORD Reserved

第4引数:DWORD dwType

第5引数:CONST BYTE* lpData

第6引数:DWORD cbData

 

前の記事:Win32/64技術 004 文字列グローバル変数にHGLOBALを使う一例

次の記事:[[Win32/64技術 006]]

Win32/64_アプリケーション開発に戻る。