変なWindows API: RegCreateKeyEx

割引あり

RegCreateKeyEx / RegCreateKeyExA / RegCreateKeyExW

Windows API の中には、「なんでこうなってるの?」と首をかしげたくなる仕様がいくつもあります。今回は、その中で RegCreateKeyEx について取り上げます。

この API の使い方で迷いやすいのが、第四引数の LPTSTR lpClass です。これは一体何を渡せばいいのでしょうか?

  • RegCreateKeyExA なら LPSTR

  • RegCreateKeyExW なら LPWSTR

この引数は「レジストリキーのユーザー定義クラス型 (user-defined class type)」を指定するものですが、実はほとんど活用されていません。ドキュメントでも「無視されうる」とされています。とはいえ、どのように無視するのが正解なのか? ここが問題です。


良くない方法

よく見かけるのが、空の文字列リテラル (_T("") / "" / L"") を渡す方法です。これは避けたほうがよいでしょう。

実際の事例

空文字リテラルを使っているコードは、意外とよく見かけます。たとえば、以下のようなケースです。

  • 「猫でもわかるプログラミング第129章 スクリーンセーバー その3」

lpClassはキーのクラス名を指定します。(""を指定)

http://www.kumei.ne.jp/c_lang/sdk2/sdk_129.htm
  • FFFTP のソースコード

FFFTP のリファクタリング中に見つけたコードがこちら。

if (RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Sota", 0, "", REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hKey2, &Dispos) == ERROR_SUCCESS)

(出典: FFFTPのソースコード)

このような記述は、なぜ良くないのでしょうか?


なぜ良くないのか?

LPTSTR は「変更可能な文字列」を指す

関数内で変更されないことを示す LPCTSTR とは異なり、LPTSTR は関数の中で書き換えられる可能性がある型です。しかし、文字列リテラルは変更不可能であり、本来 const として扱うべき ものです。

参考: JPCERT セキュアコーディングルール

ここから先は

865字

この記事が参加している募集

この記事が気に入ったらチップで応援してみませんか?