回答編集履歴

1

情報追加およびC言語のサンプル

2018/08/20 14:28

投稿

okrt
okrt

スコア366

test CHANGED
@@ -3,3 +3,165 @@
3
3
 
4
4
 
5
5
  また別の方法としては、FindFirstVolume~FindNextVolume~FindVolumeCloseでボリュームを列挙して、各ボリュームに対してIOCTL_VOLUME_GET_VOLUME_DISK_EXTENTSで情報を取得して「ディスク全体から全ボリュームの分を引き算した結果が空き位置」という手法が使えるかもしれません。少し手間はかかりそうですが。
6
+
7
+
8
+
9
+ (ここから下は2018/08/20に追記)
10
+
11
+ QueryDosDevice()を利用する場合、HarddiskVolumeX形式だけで良いかどうかを調査したほうが良いかもしれません。
12
+
13
+ (昔のWindowsのダイナミックディスクでストライピングか何かにすると、普通のとは少し違った形式になってた物もあったかも……)
14
+
15
+ そこさえクリアすれば、以下の内容は無視していいかもしれません。
16
+
17
+
18
+
19
+ GitHubのソースはきちんと理解できていませんが、
20
+
21
+ ・FindVolumes()の中でFindFirstVolume~FindNextVolume~FindVolumeCloseを使用している
22
+
23
+ ・FindVolumes()ではD:の部分は得られたけど(EFI システムパーティション)の部分が得られなかった
24
+
25
+ ということですよね?
26
+
27
+ 一応、以下のソースではドライブレターが割り当てられてなくても列挙できています。C言語またはC++のソースとして適当なWindows用のコンパイラでコンパイルできるはずです。
28
+
29
+ ```C
30
+
31
+ #include <Windows.h>
32
+
33
+ #include <tchar.h>
34
+
35
+ #include <stdio.h>
36
+
37
+
38
+
39
+ void print_volume_info(TCHAR szVolumeName[])
40
+
41
+ {
42
+
43
+ HANDLE hV;
44
+
45
+ VOLUME_DISK_EXTENTS VolumeDiskExtents[16]; /* 本当はVOLUME_DISK_EXTENTSの配列じゃないけど適当 */
46
+
47
+ BOOL Bret;
48
+
49
+ DWORD lBytesReturned;
50
+
51
+ int loop;
52
+
53
+
54
+
55
+ _tprintf(_T("%s\n"), szVolumeName);
56
+
57
+ szVolumeName[_tcslen(szVolumeName)-1] = _T('\0'); /* 末尾1文字を削除する */
58
+
59
+ hV = CreateFile(
60
+
61
+ szVolumeName,
62
+
63
+ 0,
64
+
65
+ FILE_SHARE_READ|FILE_SHARE_WRITE,
66
+
67
+ NULL,
68
+
69
+ OPEN_EXISTING,
70
+
71
+ FILE_ATTRIBUTE_READONLY,
72
+
73
+ NULL );
74
+
75
+ if (hV == INVALID_HANDLE_VALUE) {
76
+
77
+ return;
78
+
79
+ }
80
+
81
+ Bret = DeviceIoControl(
82
+
83
+ hV,
84
+
85
+ IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
86
+
87
+ NULL,
88
+
89
+ 0,
90
+
91
+ &VolumeDiskExtents,
92
+
93
+ sizeof(VOLUME_DISK_EXTENTS)*16,
94
+
95
+ &lBytesReturned,
96
+
97
+ NULL);
98
+
99
+ if (Bret != 0) {
100
+
101
+ _tprintf(_T("IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS\n"));
102
+
103
+ _tprintf(_T("%d NumberOfDiskExtents\n"), VolumeDiskExtents[0].NumberOfDiskExtents);
104
+
105
+ for(loop=0; loop<(int)VolumeDiskExtents[0].NumberOfDiskExtents; loop++) {
106
+
107
+ _tprintf(_T(" %d DiskNumber\n"), VolumeDiskExtents[0].Extents[loop].DiskNumber);
108
+
109
+ _tprintf(_T(" %f StartingOffset\n"), VolumeDiskExtents[0].Extents[loop].StartingOffset.QuadPart/1.0);
110
+
111
+ _tprintf(_T(" %f ExtentLength\n"), VolumeDiskExtents[0].Extents[loop].ExtentLength.QuadPart/1.0);
112
+
113
+ }
114
+
115
+ _tprintf(_T("OK\n\n"), szVolumeName);
116
+
117
+ }
118
+
119
+ /* DVDドライブも列挙されたりするのでOKが出ない物もある */
120
+
121
+ CloseHandle(hV);
122
+
123
+ }
124
+
125
+
126
+
127
+ int list_all_volumes(void)
128
+
129
+ {
130
+
131
+ HANDLE hFV;
132
+
133
+ TCHAR szVolumeName[MAX_PATH];
134
+
135
+
136
+
137
+ hFV = FindFirstVolume(szVolumeName, MAX_PATH);
138
+
139
+ if (hFV == INVALID_HANDLE_VALUE) {
140
+
141
+ return 1;
142
+
143
+ }
144
+
145
+ do {
146
+
147
+ print_volume_info(szVolumeName);
148
+
149
+ } while(FindNextVolume(hFV, szVolumeName, MAX_PATH));
150
+
151
+ FindVolumeClose(hFV);
152
+
153
+ return 0;
154
+
155
+ }
156
+
157
+
158
+
159
+ int main(int argc, TCHAR **argv)
160
+
161
+ {
162
+
163
+ return list_all_volumes();
164
+
165
+ }
166
+
167
+ ```