〜 システム 〜
レジストリの項目値を取得 (要ADVAPI32.DLL)

今回はAPI関数RegQueryValueExにハイブ(メインキー・サブキー・名前のセット)を指定して、
項目値を取得します。
レジストリエディタ(Regedit.exe)を見ると左側ペインのツリービューに以下5種類の「メインキー」

HKEY_CLASSES_ROOT(=0x80000000)」  拡張子や関連付け等のファイルそのものに関するキー。通称「HKCR」。 「HKEY_CURRENT_USER(=0x80000001)」  字の如く、現在のログインユーザーに関するキー。通称「HKCU」。 「HKEY_LOCAL_MACHINE(=0x80000002)」  全ユーザー共通のシステム全体の設定に関するキー。通称「HKLM」。 「HKEY_USERS(=0x80000003)」  ウィンドウズの初期情報とユーザー毎の設定に関するキー。通称「HKU」。 「HKEY_CURRENT_CONFIG(=0x80000005)」  現在のシステム設定に関するキー。通称「HKCC」。

ツリーを開くと幾つもぶら下がっている「サブキー」 選択したサブキー右側ペインのリストビューに一覧で表示される項目「名前」と、 タイプ「種類」と項目値「データ」が表示されます。 API関数の第1引数は対象キーのハンドルを指定しますので、 当関数実行の前にコチラで紹介した「ハンドルを取得する関数」を実行します。 第2引数に値の名前…つまり、項目名を指定します。 第3引数は予約されているので0を指定してください。 第4引数はデータ型の受取先変数のポインタを指定します。0を指定するとデータ型は取得しません。 データ型とは「REG_SZ」や「REG_DWORD」等のタイプのことで以下のいずれかになります。
REG_NONE0定義されていない型。
REG_SZ1NULLで終わる文字列。
REG_EXPAND_SZ2展開前の環境変数への参照が入った文字列。
REG_BINARY3バイナリーデータ。
REG_DWORD
REG_DWORD_LITTLE_ENDIAN
432ビット数値。
REG_DWORD_BIG_ENDIAN5ビッグエンディアン形式の32ビット数値。
REG_LINK6Unicodeシンボリックリンク。
REG_MULTI_SZ7NULLで終わる複数行文字列。
REG_RESOURCE_LIST8デバイスドライバのリソースリスト。
REG_QWORD
REG_QWORD_LITTLE_ENDIAN
1164ビット数値。
上記のうちのいずれかの型が数値で取得されます。(例.REG_BINARYなら3) 第5引数はデータの受取先変数のポインタを指定します。0を指定するとデータは取得しません。 第6引数は「第5引数の変数サイズを入れた変数」のポインタを指定します。 サイズをそのまま指定できないのが煩わしいですね。 コレらを指定し、取得に成功すると0が、失敗するとエラーコードが返ります。 HSP3からは型を問わず、変数としてユーザー定義命令・関数のパラメータに指定できますが、 HSP2まではmref命令により数値型・文字列型の受け取る型を指定しなければなりません。 コレが曲者で、モジュール内部で型を変換しても、グローバル側に返ると定義時の変数の型になるので、 ユーザー定義命令処理内で文字列型変数に数値を代入する際、数値型に変換して代入し、 メインスクリプトに戻ってきてからもint命令等で変数を数値型にしなければなりません。 予め、型が決まっている場合は、定義から適切な型の変数をパラメータにすればよいのですが、 今回のように、受け取る情報により型がまちまちな場合は、 下記のHSP2サンプルスクリプト66行目のように、クローンを作り直しましょう。 尚、下記のサンプルは、レジストリに記録されているDirectXのバージョンを取得していますが、 実際に取得される値は「4.06.02.0436」や「4.09.0000.0904」といったもので、 よく言われる「DirectX6.0」「DirectX9.0c」等のリリースバージョンではありません。

gethkey キー文字列
キー文字列 定義済キー文字列を指定するとメインキーの定義値を返し、
以下の数値文字列を指定すれば定義済キー文字列を返す。
"0"HKEY_CLASSES_ROOT
"1"HKEY_CURRENT_USER
"2"HKEY_LOCAL_MACHINE
"3"HKEY_USERS
"4"HKEY_PERFORMANCE_DATA
"5"HKEY_CURRENT_CONFIG
"6"HKEY_DYN_DATA

regopenkey 受取変数, キー文字列, アクセスマスク
受取変数開く対象のキーハンドル受取先変数を指定する。
尚、オープン成功なら0、失敗ならエラーコードがstatに代入される。
キー文字列オープンするキーのパス(メインキー+サブキー)を指定する。
アクセスマスク以下に示すキーのセキュリティ権を指定する。
0x0001サブキーデータの問い合わせを許可
0x0002サブキーデータの問い合わせを許可
0x0004サブキーの作成を許可
0x0008サブキーの列挙を許可
0x0010変更の通知を許可
0x0020シンボリックリンクの作成を許可
0x00020006読込系の処理を許可
0x00020019書込系の処理を許可
0x000F003F全ての処理を許可

reggetvalue 受取変数, 項目名, キーハンドル, タイプフラグ
受取変数データまたはデータの型を受け取る変数を指定する。
尚、取得成功すれば0、失敗すればエラーコードがstatに代入される。
項目名値の名前文字列を指定する。
キーハンドルregopenkey命令で取得した対象キーのハンドルを指定する。
タイプフラグデータは0を、データ型を取得する場合は1を指定する。
尚、取得されるデータ型は次のいずれかの数値である。
0定義されていない型
1NULLで終わる文字列
2展開前の環境変数への参照が入った文字列
3バイナリーデータ
432ビット数値(リトルエンディアン形式)
532ビット数値(ビッグエンディアン形式)
6Unicodeシンボリックリンク
7NULLで終わる複数行文字列
8デバイスドライバのリソースリスト
1164ビット数値(リトルエンディアン形式)

regclose キーハンドル
キーハンドル使い終わって解放する、または設定し終えて更新するキーハンドルを指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
	ll_libload advapi, "advapi32.dll"
	ll_getproc RegOpenKeyEx, "RegOpenKeyExA", advapi
	ll_getproc RegQueryValueEx, "RegQueryValueExA", advapi
	ll_getproc RegCloseKey, "RegCloseKey", advapi

#module
#deffunc gethkey str
	mref string, 32
	sdim s, 22, 7
	mref stt, 64
	mref rstr, 65
	s.0 = "HKEY_CLASSES_ROOT", "HKEY_CURRENT_USER", "HKEY_LOCAL_MACHINE", "HKEY_USERS"
	s.4 = "HKEY_PERFORMANCE_DATA", "HKEY_CURRENT_CONFIG", "HKEY_DYN_DATA"
	strmid rstr, string, 0, 1
	if rstr ! "H" {
		i = 0 + rstr
		rstr = s.i
		return
	}
	instr i, string, "\\"
	if i ! -1 : strmid rstr, string, 0, i : else : rstr = string
	stt = 0
	repeat 7
		if s.cnt = rstr {
			stt = 0x80000000 + cnt
			instr i.0, string, "\\"
			strlen i.1, string
			strmid rstr, string, i + 1, i.1 - i.0 - 1
			break
		}
	loop
	return

#deffunc regopenkey val, str, int
	mref hkey, 16 : mref path, 33 : mref sa, 3
	mref stt, 64
	gethkey path
	if stat = 0 : return
	path = refstr
	prm = stat, 0, 0, (sa = 0) * 0x000F003F + sa
	ll_getptr path : ll_ret prm.1
	ll_getptr hkey : ll_ret prm.4
	ll_callfunc prm, 5, RegOpenKeyEx@
	ll_ret prm : stt = prm
	return

#deffunc reggetvalue val, str ,int, int
	mref data, 24 : mref name, 33 : mref hkey, 2 : mref type, 3
	mref stt, 64
	prm = hkey
	i.1 = 256
	ll_getptr name : ll_ret prm.1
	ll_getptr i    : ll_ret prm.3
	ll_getptr data : ll_ret prm.4
	ll_getptr i.1  : ll_ret prm.5
	ll_callfunc prm, 6, RegQueryValueEx@
	ll_ret prm : stt = prm
	if i >= 4 & (i <= 6) | (i = 11) | (type ! 0) : mref data, 16 // 強制的に数値型に変換
	if type : data = i
	return

#deffunc regclose int
	mref hkey, 0
	ll_callfunc hkey, 1, RegCloseKey@
	return
#global

	sdim path, 128
	sdim dat, 128
	sdim type, 20, 12
	value = "Version"
	type.0 = "NONE", "SZ", "EXPAND_SZ", "BINARY", "DWORD", "DWORD_BIG_ENDIAN"
	type.6 = "LINK", "MULTI_SZ", "RESOURCE_LIST", "", "", "QWORD"
	gethkey "2"
	path = refstr + "\\SOFTWARE\\Microsoft\\DirectX"
	regopenkey key, path
	if stat {
		mes "キーが存在しません"
	} else {
		reggetvalue dat, value, key
		if stat {
			mes "値が存在しません"
		} else {
			mes "キー [ " + path + " ]"
			mes "値  [ " + value + " ]"
			mes "データ[ " + dat + " ]"
			reggetvalue dat, value, key, 1
			if stat {
				mes "型の取得に失敗しました"
			} else {
				mes "型  [ REG_" + type.dat + " ]"
			}
		}
		regclose key
	}
	stop

定義済情報 = gethkey(キー文字列)
定義済情報定義済情報の受取先を指定する。
キー文字列 定義済キー文字列を指定するとメインキーの定義値を返し、
以下の数値文字列を指定すれば定義済キー文字列を返す。
"0"HKEY_CLASSES_ROOT
"1"HKEY_CURRENT_USER
"2"HKEY_LOCAL_MACHINE
"3"HKEY_USERS
"4"HKEY_PERFORMANCE_DATA
"5"HKEY_CURRENT_CONFIG
"6"HKEY_DYN_DATA

エラーコード = regopenkey(受取変数, キー文字列, アクセスマスク)
エラーコードオープン成功(=0)したか失敗(=エラーコード)したかの状態受取先を指定する。
受取変数開く対象のキーハンドル受取先変数を指定する。
キー文字列オープンするキーのパス(メインキー+サブキー)を指定する。
アクセスマスク以下に示すキーのセキュリティ権を指定する。
0x0001サブキーデータの問い合わせを許可
0x0002サブキーデータの問い合わせを許可
0x0004サブキーの作成を許可
0x0008サブキーの列挙を許可
0x0010変更の通知を許可
0x0020シンボリックリンクの作成を許可
0x00020006読込系の処理を許可
0x00020019書込系の処理を許可
0x000F003F全ての処理を許可

エラーコード = reggetvalue(受取変数, 項目名, キーハンドル, タイプフラグ)
エラーコード取得成功(=0)したか失敗(=エラーコード)したかの状態受取先を指定する。
受取変数データまたはデータの型を受け取る変数を指定する。
項目名値の名前文字列を指定する。
キーハンドルregopenkey命令で取得した対象キーのハンドルを指定する。
タイプフラグデータは0を、データ型を取得する場合は1を指定する。
尚、取得されるデータ型は次のいずれかの数値である。
0定義されていない型
1NULLで終わる文字列
2展開前の環境変数への参照が入った文字列
3バイナリーデータ
432ビット数値(リトルエンディアン形式)
532ビット数値(ビッグエンディアン形式)
6Unicodeシンボリックリンク
7NULLで終わる複数行文字列
8デバイスドライバのリソースリスト
1164ビット数値(リトルエンディアン形式)

regclose キーハンドル
キーハンドル使い終わって解放する、または設定し終えて更新するキーハンドルを指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#uselib "advapi32.dll"
#cfunc global RegOpenKeyEx "RegOpenKeyExA" int, sptr, int, int, var
#cfunc global RegQueryValueEx "RegQueryValueExA" int, sptr, int, var, var, var
#func  global regclose "RegCloseKey" int

#module
#defcfunc gethkey str string, local i, local s
	mref rstr, 65
	s.0 = "HKEY_CLASSES_ROOT", "HKEY_CURRENT_USER", "HKEY_LOCAL_MACHINE", "HKEY_USERS"
	s.4 = "HKEY_PERFORMANCE_DATA", "HKEY_CURRENT_CONFIG", "HKEY_DYN_DATA"
	rstr = string
	if strmid(rstr, 0, 1) ! "H" : return s(int(rstr))
	if instr(rstr, , "\\") ! -1 : rstr = strmid(rstr, 0, instr(rstr, , "\\"))
	foreach s
		if s.cnt = rstr {
			i = 0x80000000 + cnt
			rstr = string
			rstr = strmid(rstr, instr(rstr, , "\\") + 1, strlen(rstr) - instr(rstr, , "\\") - 1)
			break
		}
	loop
	return i

#defcfunc regopenkey var hkey, var path, int sa, local s
	return RegOpenKeyEx(int(gethkey(path)), refstr, , (sa = 0) * 0x000F003F + sa, hkey)

#defcfunc reggetvalue var data, int hkey, str name, int type, local i
	i = 256
	i.1 = RegQueryValueEx(hkey, name, , i.2, data, i)
	if type : data = i.2
	return i.1
#global

	sdim dat, 128
	value = "Version"
	type.0 = "NONE", "SZ", "EXPAND_SZ", "BINARY", "DWORD", "DWORD_BIG_ENDIAN"
	type.6 = "LINK", "MULTI_SZ", "RESOURCE_LIST", "", "", "QWORD"
	path = gethkey("2") + "\\SOFTWARE\\Microsoft\\DirectX"
	if regopenkey(key, path) {
		mes "キーが存在しません"
	} else {
		if reggetvalue(dat, key, value) = 0 {
			mes "キー [ " + path + " ]"
			mes "値  [ " + value + " ]"
			mes "データ[ " + dat + " ]"
			if reggetvalue(dat, key, value, 1) = 0 {
				mes "型  [ REG_" + type.dat + " ]"
			} else {
				mes "型の取得に失敗しました"
			}
		} else {
			mes "値が存在しません"
		}
		regclose key
	}