〜 ファイル 〜
ドライブの情報を取得 (要KERNEL32.DLL)

Hspext.DLLにドライブに関する情報を取得するfxinfo命令が用意されていますが、
ココでは、別途DLLを同梱する必要なくAPI関数GetVolumeInformationを直接呼び出して、取得します。
API関数GetVolumeInformationは、ボリューム名やシリアル番号、圧縮・暗号化の可否等の取得、
それら取得に必要な変数サイズや格納先を複数同時に指定する必要がありますが、
HSP2のユーザー定義命令は制約上2つしか変数を用意できないので、配列で渡す必要があります。
また、3つ以上格納変数をパラメータに渡せるHSP3を使う場合であっても、
取得の必要がない不要項目がある時、毎回ダミー変数を渡すようにしなければなりません。
そこで、1項目ずつ受け取る形にすると、HSP2、HSP3のどちらの問題にも対応できるわけですが、
同じドライブの情報を複数取得する際、取得済情報も毎回取り直される形になるのでコレもまたムダです。
そこで下記のサンプルモジュールではトラップを設けて、前回と違うドライブを取得しようとした時か、
明示的に再取得をする場合を除き、前回取得した情報から読み込む形をとりました。
最後に、API関数側の「ボリューム付加情報」について、補足説明しておきます。
付加情報には複数の可否情報が含まれており、以下の項目値の論理和がまとめて格納されます。
0x00000001FS_CASE_SENSITIVEファイルシステム(以下FS)が英大・小文字を区別してファイル検索できる
0x00000002FS_CASE_IS_PRESERVEDFSが英字の大文字小文字を区別してファイル保存できる
0x00000004FS_UNICODE_STORED_ON_DISKFSがUnicodeファイル名を格納でき、正しく表示もできる
0x00000008FS_PERSISTENT_ACLSFSがACL(アクセス制御リスト)の保存と適用を行える
0x00000010FS_FILE_COMPRESSIONFSがファイルベースの圧縮をサポートしている
0x00008000FS_VOL_IS_COMPRESSEDボリュームはDoubleSpaces等で圧縮済みである
0x00000020FILE_VOLUME_QUOTASFSがディスク使用量の割当をサポートしている
0x00000040FILE_SUPPORTS_SPARSE_FILESFSが多くの未使用領域、同一値が続くファイルをサポートしている
0x00000080FILE_SUPPORTS_REPARSE_POINTSFSが再解析ポイントをサポートしている
0x00010000FILE_SUPPORTS_OBJECT_IDSFSがオブジェクト識別子をサポートしている
0x00020000FILE_SUPPORTS_ENCRYPTIONFSがEPS(暗号化ファイルシステム)をサポートしている
0x00040000FILE_NAMED_STREAMSFSが名前付きストリームをサポートしている

getvolumeinfo ドライブ番号, タイプ, 取り直し
ドライブ番号Aドライブを1、Bドライブを2…Zドライブを26としたドライブ番号を指定する。
タイプ取得する情報タイプを指定する。0:ルートフォルダパス(結果はrefstrに代入)
                            1:ボリューム名(結果はrefstrに代入)
                            2:シリアル番号(結果はstatに代入)
                            3:ファイル名の最大長(結果はstatに代入)
                            4:付加情報(結果はstatに代入)
                            5:ファイルシステム名(結果はrefstrに代入)
取り直しAPI関数実行により再取得を行う(=1)か否(=0)かを指定する。
尚、初めて取得するか、前回に異なるドライブの情報を取得していた場合は強制的に取り直す。

 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
	ll_libload kernel, "kernel32.dll"
	ll_getproc GetVolumeInformation, "GetVolumeInformationA", kernel

#module
#deffunc getvolumeinfo int, int, int
	mref root, 0 : mref type, 1 : mref reget, 2
	mref stt, 64
	mref rstr, 65
	if reget ! 0 || (root + 100 ! rootb) {
		sdim name, 256, 3
		name = "?:\\" : poke name, , root + 64
		if type = 0 : return name
		ll_getptr name.0 : ll_ret p.0
		ll_getptr name.1 : ll_ret p.1
		ll_getptr size.0 : ll_ret p.2
		ll_getptr size.1 : ll_ret p.3
		ll_getptr size.2 : ll_ret p.4
		ll_getptr name.2 : ll_ret p.5
		prm = p.0, p.1, 256, p.2, p.3, p.4, p.5, 256
		ll_callfunc prm, 8, GetVolumeInformation@
		ll_ret i
		if i = 0 {
			if type = 1 || (type = 5) : rstr = "" : else : stt = 0
			return
		}
		rootb = root + 100
	}
	switch type
		case 1:	rstr = name.1 : swbreak
		case 2:	stt  = size.0 : swbreak
		case 3:	stt  = size.1 : swbreak
		case 4:	stt  = size.2 : swbreak
		case 5:	rstr = name.2 : swbreak
		default:rstr = name.0
	swend
	return
#global

	sdim drv, 128
	sdim flginfo, 30, 12
	sdim yn, 8, 2
	flag = 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x8000, 0x00000020, 0x00000040, 0x00000080, 0x00010000, 0x00020000, 0x00040000
	flginfo.0 = "大・小文字を区別して検索可能"
	flginfo.1 = "大・小文字を区別して保存可能"
	flginfo.2 = "Unicodeファイル名を格納可能"
	flginfo.3 = "ACLの保存と適用が可能"
	flginfo.4 = "ファイルベースの圧縮が可能"
	flginfo.5 = "ボリュームは圧縮済み"
	flginfo.6 = "ディスククォータに対応可能"
	flginfo.7 = "ディスパースに対応可能"
	flginfo.8 = "再解析ポイントに対応可能"
	flginfo.9 = "オブジェクト識別子に対応可能"
	flginfo.10 = "EPSが可能"
	flginfo.11= "名前付きストリームに対応可能"
	yn = "でない", "である"
	repeat 26, 1
		if cnt > 1 : drv += "\n"
		wpoke drv, (cnt - 1) * 3, (':' << 8) + cnt + 64 // コンボボックス用に「A: B: C: … Z:」を格納
	loop
	pos  10, 10 : mes "ドライブ"
	pos  80, 10 : combox index, 100, drv
	pos 150, 10 : button "確認", *check
	stop

*check
	color 255, 255, 255 : boxf , 50 : color
	getvolumeinfo index + 1, 0
	pos 10,  50 : mes "【ドライブ" + refstr + "の情報】"
	getvolumeinfo index + 1, 1
	pos 10,  80 : mes "ボリューム名:" + refstr
	getvolumeinfo index + 1, 2
	pos 10, 110 : mes "シリアル番号:" + stat
	getvolumeinfo index + 1, 3
	pos 10, 140 : mes "ファイル名最大長:" + stat
	getvolumeinfo index + 1, 5
	pos 10, 170 : mes "ファイルシステム名:" + refstr
	getvolumeinfo index + 1, 4
	pos 10, 200 : mes "付加情報:"
	repeat 12
		pos 90, cnt * 20 + 200 : mes flginfo.cnt
		i = stat & flag.cnt ! 0
		ginfo 7
		pos prmx + 90, cnt * 20 + 200 : mes yn.i
	loop
	stop

受取先 = getvolumeinfo(ドライブ番号, タイプ, 取り直し)
受取先取得したドライブ情報の受取先を指定する。
ドライブ番号Aドライブを1、Bドライブを2…Zドライブを26としたドライブ番号を指定する。
タイプ取得する情報タイプを指定する。0:ルートフォルダパス
                            1:ボリューム名
                            2:シリアル番号
                            3:ファイル名の最大長
                            4:付加情報
                            5:ファイルシステム名
取り直しAPI関数実行により再取得を行う(=1)か否(=0)かを指定する。
尚、初めて取得するか、前回に異なるドライブの情報を取得していた場合は強制的に取り直す。

 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
#uselib "kernel32.dll"
#cfunc global GetVolumeInformation "GetVolumeInformationA" sptr, var, int, var, var, var, var, int

#module
#defcfunc getvolumeinfo int root, int type, int reget, local i
	if reget ! 0 || root + 100 ! rootb {
		sdim name, 256, 3
		name = "?:\\" : poke name, , root + 64
		if type = 0 : return name
		i = GetVolumeInformation(name, name.1, 256, size, size.1, size.2, name.2, 256)
		if i = 0 {
			if type = 1 || type = 5 : return "" : else : return 0
		}
		rootb = root + 100
	}
	if type = 1 || type = 5 : return name((type = 5) + (type ! 0)) : else : return size(type - 2)
#global

	sdim drv, 128
	sdim flginfo, 30, 12
	sdim yn, 8, 2
	flag = 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x8000, 0x00000020, 0x00000040, 0x00000080, 0x00010000, 0x00020000, 0x00040000
	flginfo.0 = "大・小文字を区別して検索可能"
	flginfo.1 = "大・小文字を区別して保存可能"
	flginfo.2 = "Unicodeファイル名を格納可能"
	flginfo.3 = "ACLの保存と適用が可能"
	flginfo.4 = "ファイルベースの圧縮が可能"
	flginfo.5 = "ボリュームは圧縮済み"
	flginfo.6 = "ディスククォータに対応可能"
	flginfo.7 = "ディスパースに対応可能"
	flginfo.8 = "再解析ポイントに対応可能"
	flginfo.9 = "オブジェクト識別子に対応可能"
	flginfo.10 = "EPSが可能"
	flginfo.11= "名前付きストリームに対応可能"
	yn = "でない", "である"
	repeat 26, 1
		if cnt > 1 : drv += "\n"
		wpoke drv, (cnt - 1) * 3, (':' << 8) + cnt + 64 // コンボボックス用に「A: B: C: … Z:」を格納
	loop
	pos  10, 10 : mes "ドライブ"
	pos  80, 10 : combox index, 100, drv
	pos 150, 10 : button gosub "確認", *check
	stop

*check
	color 255, 255, 255 : boxf , 50 : color
	pos 10,  50 : mes "【ドライブ" + getvolumeinfo(index + 1, 0) + "の情報】"
	pos 10,  80 : mes "ボリューム名:" + getvolumeinfo(index + 1, 1)
	pos 10, 110 : mes "シリアル番号:" + getvolumeinfo(index + 1, 2)
	pos 10, 140 : mes "ファイル名最大長:" + getvolumeinfo(index + 1, 3)
	pos 10, 170 : mes "ファイルシステム名:" + getvolumeinfo(index + 1, 5)
	pos 10, 200 : mes "付加情報:"
	repeat length(flag)
		pos 90, cnt * 20 + 200 : mes flginfo.cnt
		pos ginfo_mesx + 90, cnt * 20 + 200 : mes yn((getvolumeinfo(index + 1, 4) & flag.cnt) ! 0)
	loop
	return