1 /**
2  * Windows API header module
3  *
4  * Translated from MinGW Windows headers
5  *
6  * Authors: Stewart Gordon
7  * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
8  * Source: $(DRUNTIMESRC core/sys/windows/_winioctl.d)
9  */
10 module core.sys.windows.winioctl;
11 version (Windows):
12 
13 // FIXME: check types of some constants
14 
15 import core.sys.windows.basetyps, core.sys.windows.windef;
16 
17 enum size_t
18     HIST_NO_OF_BUCKETS = 24,
19     HISTOGRAM_BUCKET_SIZE = HISTOGRAM_BUCKET.sizeof,
20     DISK_HISTOGRAM_SIZE = DISK_HISTOGRAM.sizeof;
21 
22 alias DWORD DEVICE_TYPE;
23 
24 enum : DEVICE_TYPE {
25     FILE_DEVICE_BEEP               = 1,
26     FILE_DEVICE_CD_ROM,
27     FILE_DEVICE_CD_ROM_FILE_SYSTEM,
28     FILE_DEVICE_CONTROLLER,
29     FILE_DEVICE_DATALINK,
30     FILE_DEVICE_DFS,
31     FILE_DEVICE_DISK,
32     FILE_DEVICE_DISK_FILE_SYSTEM,
33     FILE_DEVICE_FILE_SYSTEM,
34     FILE_DEVICE_INPORT_PORT,
35     FILE_DEVICE_KEYBOARD,
36     FILE_DEVICE_MAILSLOT,
37     FILE_DEVICE_MIDI_IN,
38     FILE_DEVICE_MIDI_OUT,
39     FILE_DEVICE_MOUSE,
40     FILE_DEVICE_MULTI_UNC_PROVIDER,
41     FILE_DEVICE_NAMED_PIPE,
42     FILE_DEVICE_NETWORK,
43     FILE_DEVICE_NETWORK_BROWSER,
44     FILE_DEVICE_NETWORK_FILE_SYSTEM,
45     FILE_DEVICE_NULL,
46     FILE_DEVICE_PARALLEL_PORT,
47     FILE_DEVICE_PHYSICAL_NETCARD,
48     FILE_DEVICE_PRINTER,
49     FILE_DEVICE_SCANNER,
50     FILE_DEVICE_SERIAL_MOUSE_PORT,
51     FILE_DEVICE_SERIAL_PORT,
52     FILE_DEVICE_SCREEN,
53     FILE_DEVICE_SOUND,
54     FILE_DEVICE_STREAMS,
55     FILE_DEVICE_TAPE,
56     FILE_DEVICE_TAPE_FILE_SYSTEM,
57     FILE_DEVICE_TRANSPORT,
58     FILE_DEVICE_UNKNOWN,
59     FILE_DEVICE_VIDEO,
60     FILE_DEVICE_VIRTUAL_DISK,
61     FILE_DEVICE_WAVE_IN,
62     FILE_DEVICE_WAVE_OUT,
63     FILE_DEVICE_8042_PORT,
64     FILE_DEVICE_NETWORK_REDIRECTOR,
65     FILE_DEVICE_BATTERY,
66     FILE_DEVICE_BUS_EXTENDER,
67     FILE_DEVICE_MODEM,
68     FILE_DEVICE_VDM,
69     FILE_DEVICE_MASS_STORAGE,
70     FILE_DEVICE_SMB,
71     FILE_DEVICE_KS,
72     FILE_DEVICE_CHANGER,
73     FILE_DEVICE_SMARTCARD,
74     FILE_DEVICE_ACPI,
75     FILE_DEVICE_DVD,
76     FILE_DEVICE_FULLSCREEN_VIDEO,
77     FILE_DEVICE_DFS_FILE_SYSTEM,
78     FILE_DEVICE_DFS_VOLUME,
79     FILE_DEVICE_SERENUM,
80     FILE_DEVICE_TERMSRV,
81     FILE_DEVICE_KSEC            // = 57
82 }
83 
84 enum {
85     METHOD_BUFFERED,
86     METHOD_IN_DIRECT,
87     METHOD_OUT_DIRECT,
88     METHOD_NEITHER
89 }
90 
91 enum {
92     FILE_ANY_ACCESS,
93     FILE_SPECIAL_ACCESS = 0,
94     FILE_READ_ACCESS,
95     FILE_WRITE_ACCESS
96 }
97 
98 /*  Bit pattern:
99  *  tttttttt tttttttt aaffffff ffffffmm
100  */
101 /+
102 #define CTL_CODE(t, f, m, a) (((t)<<16)|((a)<<14)|((f)<<2)|(m))
103 +/
104 
105 template CTL_CODE_T(DEVICE_TYPE t, uint f, uint m, uint a) {
106 enum DWORD CTL_CODE_T = (t << 16) | (a << 14) | (f << 2) | m;
107 }
108 
109 DEVICE_TYPE DEVICE_TYPE_FROM_CTL_CODE(DWORD c) {
110     return (c & 0xFFFF0000) >> 16;
111 }
112 
113 enum DEVICE_TYPE
114     IOCTL_STORAGE_BASE = FILE_DEVICE_MASS_STORAGE,
115     IOCTL_DISK_BASE    = FILE_DEVICE_DISK,
116     IOCTL_VOLUME_BASE  = 'V';
117 
118 enum : DWORD {
119     IOCTL_STORAGE_CHECK_VERIFY           = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS),
120     IOCTL_STORAGE_CHECK_VERIFY2          = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_ANY_ACCESS),
121     IOCTL_STORAGE_MEDIA_REMOVAL          = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS),
122     IOCTL_STORAGE_EJECT_MEDIA            = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS),
123     IOCTL_STORAGE_LOAD_MEDIA             = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS),
124     IOCTL_STORAGE_LOAD_MEDIA2            = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_ANY_ACCESS),
125     IOCTL_STORAGE_RESERVE                = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS),
126     IOCTL_STORAGE_RELEASE                = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS),
127     IOCTL_STORAGE_FIND_NEW_DEVICES       = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS),
128     IOCTL_STORAGE_EJECTION_CONTROL       = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0250, METHOD_BUFFERED, FILE_ANY_ACCESS),
129     IOCTL_STORAGE_MCN_CONTROL            = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0251, METHOD_BUFFERED, FILE_ANY_ACCESS),
130     IOCTL_STORAGE_GET_MEDIA_TYPES        = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0300, METHOD_BUFFERED, FILE_ANY_ACCESS),
131     IOCTL_STORAGE_GET_MEDIA_TYPES_EX     = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0301, METHOD_BUFFERED, FILE_ANY_ACCESS),
132     IOCTL_STORAGE_RESET_BUS              = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0400, METHOD_BUFFERED, FILE_READ_ACCESS),
133     IOCTL_STORAGE_RESET_DEVICE           = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS),
134     IOCTL_STORAGE_GET_DEVICE_NUMBER      = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0420, METHOD_BUFFERED, FILE_ANY_ACCESS),
135     IOCTL_STORAGE_PREDICT_FAILURE        = CTL_CODE_T!(IOCTL_STORAGE_BASE, 0x0440, METHOD_BUFFERED, FILE_ANY_ACCESS),
136 
137     IOCTL_DISK_GET_DRIVE_GEOMETRY        = CTL_CODE_T!(IOCTL_DISK_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS),
138     IOCTL_DISK_GET_PARTITION_INFO        = CTL_CODE_T!(IOCTL_DISK_BASE, 1, METHOD_BUFFERED, FILE_READ_ACCESS),
139     IOCTL_DISK_SET_PARTITION_INFO        = CTL_CODE_T!(IOCTL_DISK_BASE, 2, METHOD_BUFFERED, FILE_READ_ACCESS|FILE_WRITE_ACCESS),
140     IOCTL_DISK_GET_DRIVE_LAYOUT          = CTL_CODE_T!(IOCTL_DISK_BASE, 3, METHOD_BUFFERED, FILE_READ_ACCESS),
141     IOCTL_DISK_SET_DRIVE_LAYOUT          = CTL_CODE_T!(IOCTL_DISK_BASE, 4, METHOD_BUFFERED, FILE_READ_ACCESS|FILE_WRITE_ACCESS),
142     IOCTL_DISK_VERIFY                    = CTL_CODE_T!(IOCTL_DISK_BASE, 5, METHOD_BUFFERED, FILE_ANY_ACCESS),
143     IOCTL_DISK_FORMAT_TRACKS             = CTL_CODE_T!(IOCTL_DISK_BASE, 6, METHOD_BUFFERED, FILE_READ_ACCESS|FILE_WRITE_ACCESS),
144     IOCTL_DISK_REASSIGN_BLOCKS           = CTL_CODE_T!(IOCTL_DISK_BASE, 7, METHOD_BUFFERED, FILE_READ_ACCESS|FILE_WRITE_ACCESS),
145     IOCTL_DISK_PERFORMANCE               = CTL_CODE_T!(IOCTL_DISK_BASE, 8, METHOD_BUFFERED, FILE_ANY_ACCESS),
146     IOCTL_DISK_IS_WRITABLE               = CTL_CODE_T!(IOCTL_DISK_BASE, 9, METHOD_BUFFERED, FILE_ANY_ACCESS),
147     IOCTL_DISK_LOGGING                   = CTL_CODE_T!(IOCTL_DISK_BASE, 10, METHOD_BUFFERED, FILE_ANY_ACCESS),
148     IOCTL_DISK_FORMAT_TRACKS_EX          = CTL_CODE_T!(IOCTL_DISK_BASE, 11, METHOD_BUFFERED, FILE_READ_ACCESS|FILE_WRITE_ACCESS),
149     IOCTL_DISK_HISTOGRAM_STRUCTURE       = CTL_CODE_T!(IOCTL_DISK_BASE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS),
150     IOCTL_DISK_HISTOGRAM_DATA            = CTL_CODE_T!(IOCTL_DISK_BASE, 13, METHOD_BUFFERED, FILE_ANY_ACCESS),
151     IOCTL_DISK_HISTOGRAM_RESET           = CTL_CODE_T!(IOCTL_DISK_BASE, 14, METHOD_BUFFERED, FILE_ANY_ACCESS),
152     IOCTL_DISK_REQUEST_STRUCTURE         = CTL_CODE_T!(IOCTL_DISK_BASE, 15, METHOD_BUFFERED, FILE_ANY_ACCESS),
153     IOCTL_DISK_REQUEST_DATA              = CTL_CODE_T!(IOCTL_DISK_BASE, 16, METHOD_BUFFERED, FILE_ANY_ACCESS),
154     IOCTL_DISK_GET_PARTITION_INFO_EX     = CTL_CODE_T!(IOCTL_DISK_BASE, 0x12, METHOD_BUFFERED, FILE_ANY_ACCESS),
155     IOCTL_DISK_SET_PARTITION_INFO_EX     = CTL_CODE_T!(IOCTL_DISK_BASE, 0x13, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
156     IOCTL_DISK_GET_DRIVE_LAYOUT_EX       = CTL_CODE_T!(IOCTL_DISK_BASE, 0x14, METHOD_BUFFERED, FILE_ANY_ACCESS),
157     IOCTL_DISK_SET_DRIVE_LAYOUT_EX       = CTL_CODE_T!(IOCTL_DISK_BASE, 0x15, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
158     IOCTL_DISK_CREATE_DISK               = CTL_CODE_T!(IOCTL_DISK_BASE, 0x16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
159     IOCTL_DISK_GET_LENGTH_INFO           = CTL_CODE_T!(IOCTL_DISK_BASE, 0x17, METHOD_BUFFERED, FILE_READ_ACCESS),
160     IOCTL_DISK_PERFORMANCE_OFF           = CTL_CODE_T!(IOCTL_DISK_BASE, 0x18, METHOD_BUFFERED, FILE_ANY_ACCESS),
161     IOCTL_DISK_GET_DRIVE_GEOMETRY_EX     = CTL_CODE_T!(IOCTL_DISK_BASE, 0x28, METHOD_BUFFERED, FILE_ANY_ACCESS),
162     IOCTL_DISK_GROW_PARTITION            = CTL_CODE_T!(IOCTL_DISK_BASE, 0x34, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
163     IOCTL_DISK_GET_CACHE_INFORMATION     = CTL_CODE_T!(IOCTL_DISK_BASE, 0x35, METHOD_BUFFERED, FILE_READ_ACCESS),
164     IOCTL_DISK_SET_CACHE_INFORMATION     = CTL_CODE_T!(IOCTL_DISK_BASE, 0x36, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
165     IOCTL_DISK_DELETE_DRIVE_LAYOUT       = CTL_CODE_T!(IOCTL_DISK_BASE, 0x40, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
166     IOCTL_DISK_UPDATE_PROPERTIES         = CTL_CODE_T!(IOCTL_DISK_BASE, 0x50, METHOD_BUFFERED, FILE_ANY_ACCESS),
167     IOCTL_DISK_CHECK_VERIFY              = CTL_CODE_T!(IOCTL_DISK_BASE, 0x200, METHOD_BUFFERED, FILE_READ_ACCESS),
168     IOCTL_DISK_MEDIA_REMOVAL             = CTL_CODE_T!(IOCTL_DISK_BASE, 0x201, METHOD_BUFFERED, FILE_READ_ACCESS),
169     IOCTL_DISK_EJECT_MEDIA               = CTL_CODE_T!(IOCTL_DISK_BASE, 0x202, METHOD_BUFFERED, FILE_READ_ACCESS),
170     IOCTL_DISK_LOAD_MEDIA                = CTL_CODE_T!(IOCTL_DISK_BASE, 0x203, METHOD_BUFFERED, FILE_READ_ACCESS),
171     IOCTL_DISK_RESERVE                   = CTL_CODE_T!(IOCTL_DISK_BASE, 0x204, METHOD_BUFFERED, FILE_READ_ACCESS),
172     IOCTL_DISK_RELEASE                   = CTL_CODE_T!(IOCTL_DISK_BASE, 0x205, METHOD_BUFFERED, FILE_READ_ACCESS),
173     IOCTL_DISK_FIND_NEW_DEVICES          = CTL_CODE_T!(IOCTL_DISK_BASE, 0x206, METHOD_BUFFERED, FILE_READ_ACCESS),
174     IOCTL_DISK_REMOVE_DEVICE             = CTL_CODE_T!(IOCTL_DISK_BASE, 0x207, METHOD_BUFFERED, FILE_READ_ACCESS),
175     IOCTL_DISK_GET_MEDIA_TYPES           = CTL_CODE_T!(IOCTL_DISK_BASE, 0x300, METHOD_BUFFERED, FILE_ANY_ACCESS),
176     IOCTL_DISK_UPDATE_DRIVE_SIZE         = CTL_CODE_T!(IOCTL_DISK_BASE, 0x0032, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
177     IOCTL_SERIAL_LSRMST_INSERT           = CTL_CODE_T!(FILE_DEVICE_SERIAL_PORT, 31, METHOD_BUFFERED, FILE_ANY_ACCESS),
178 
179     IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = CTL_CODE_T!(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS),
180     IOCTL_VOLUME_IS_CLUSTERED            = CTL_CODE_T!(IOCTL_VOLUME_BASE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS),
181 
182     FSCTL_LOCK_VOLUME                    = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS),
183     FSCTL_UNLOCK_VOLUME                  = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 7, METHOD_BUFFERED, FILE_ANY_ACCESS),
184     FSCTL_DISMOUNT_VOLUME                = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS),
185     FSCTL_MOUNT_DBLS_VOLUME              = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 13, METHOD_BUFFERED, FILE_ANY_ACCESS),
186     FSCTL_GET_COMPRESSION                = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 15, METHOD_BUFFERED, FILE_ANY_ACCESS),
187     FSCTL_SET_COMPRESSION                = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 16, METHOD_BUFFERED, FILE_READ_DATA|FILE_WRITE_DATA),
188     FSCTL_READ_COMPRESSION               = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 17, METHOD_NEITHER, FILE_READ_DATA),
189     FSCTL_WRITE_COMPRESSION              = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 18, METHOD_NEITHER, FILE_WRITE_DATA),
190     FSCTL_GET_NTFS_VOLUME_DATA           = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 25, METHOD_BUFFERED, FILE_ANY_ACCESS),
191     FSCTL_GET_VOLUME_BITMAP              = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 27, METHOD_NEITHER, FILE_ANY_ACCESS),
192     FSCTL_GET_RETRIEVAL_POINTERS         = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 28, METHOD_NEITHER, FILE_ANY_ACCESS),
193     FSCTL_MOVE_FILE                      = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 29, METHOD_BUFFERED, FILE_ANY_ACCESS),
194     FSCTL_GET_REPARSE_POINT              = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS),
195     FSCTL_SET_REPARSE_POINT              = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_ANY_ACCESS),
196     FSCTL_DELETE_REPARSE_POINT           = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 43, METHOD_BUFFERED, FILE_ANY_ACCESS),
197     FSCTL_SET_SPARSE                     = CTL_CODE_T!(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_SPECIAL_ACCESS),
198 }
199 
200 enum : BYTE {
201     PARTITION_ENTRY_UNUSED,
202     PARTITION_FAT_12,
203     PARTITION_XENIX_1,
204     PARTITION_XENIX_2,
205     PARTITION_FAT_16,
206     PARTITION_EXTENDED,
207     PARTITION_HUGE,
208     PARTITION_IFS,         // = 0x07
209     PARTITION_FAT32           = 0x0B,
210     PARTITION_FAT32_XINT13    = 0x0C,
211     PARTITION_XINT13          = 0x0E,
212     PARTITION_XINT13_EXTENDED = 0x0F,
213     PARTITION_PREP            = 0x41,
214     PARTITION_LDM             = 0x42,
215     PARTITION_UNIX            = 0x63
216 }
217 
218 enum BYTE
219     PARTITION_NTFT = 0x80,
220     VALID_NTFT     = 0xC0;
221 
222 enum {
223     SERIAL_LSRMST_ESCAPE,
224     SERIAL_LSRMST_LSR_DATA,
225     SERIAL_LSRMST_LSR_NODATA,
226     SERIAL_LSRMST_MST
227 }
228 
229 enum {
230     DISK_LOGGING_START,
231     DISK_LOGGING_STOP,
232     DISK_LOGGING_DUMP,
233     DISK_BINNING
234 }
235 
236 alias WORD BAD_TRACK_NUMBER;
237 alias WORD* PBAD_TRACK_NUMBER;
238 
239 enum BIN_TYPES {
240     RequestSize, RequestLocation
241 }
242 
243 struct BIN_RANGE {
244     LARGE_INTEGER StartValue;
245     LARGE_INTEGER Length;
246 }
247 alias BIN_RANGE* PBIN_RANGE;
248 
249 struct BIN_COUNT {
250     BIN_RANGE BinRange;
251     DWORD     BinCount;
252 }
253 alias BIN_COUNT* PBIN_COUNT;
254 
255 struct BIN_RESULTS {
256     DWORD     NumberOfBins;
257     BIN_COUNT _BinCounts;
258 
259     BIN_COUNT* BinCounts() return { return &_BinCounts; }
260 }
261 alias BIN_RESULTS* PBIN_RESULTS;
262 
263 enum PARTITION_STYLE {
264     PARTITION_STYLE_MBR,
265     PARTITION_STYLE_GPT,
266     PARTITION_STYLE_RAW
267 }
268 
269 struct CREATE_DISK_GPT {
270     GUID  DiskId;
271     DWORD MaxPartitionCount;
272 }
273 alias CREATE_DISK_GPT* PCREATE_DISK_GPT;
274 
275 struct CREATE_DISK_MBR {
276     DWORD Signature;
277 }
278 alias CREATE_DISK_MBR* PCREATE_DISK_MBR;
279 
280 struct CREATE_DISK {
281     PARTITION_STYLE PartitionStyle;
282     union {
283         CREATE_DISK_MBR Mbr;
284         CREATE_DISK_GPT Gpt;
285     }
286 }
287 alias CREATE_DISK* PCREATE_DISK;
288 
289 enum DISK_CACHE_RETENTION_PRIORITY {
290     EqualPriority,
291     KeepPrefetchedData,
292     KeepReadData
293 }
294 
295 struct DISK_CACHE_INFORMATION {
296     BOOLEAN ParametersSavable;
297     BOOLEAN ReadCacheEnabled;
298     BOOLEAN WriteCacheEnabled;
299     DISK_CACHE_RETENTION_PRIORITY ReadRetentionPriority;
300     DISK_CACHE_RETENTION_PRIORITY WriteRetentionPriority;
301     WORD    DisablePrefetchTransferLength;
302     BOOLEAN PrefetchScalar;
303     union {
304         struct _ScalarPrefetch {
305             WORD Minimum;
306             WORD Maximum;
307             WORD MaximumBlocks;
308         }
309         _ScalarPrefetch ScalarPrefetch;
310         struct _BlockPrefetch {
311             WORD Minimum;
312             WORD Maximum;
313         }
314         _BlockPrefetch BlockPrefetch;
315     }
316 }
317 alias DISK_CACHE_INFORMATION* PDISK_CACHE_INFORMATION;
318 
319 enum DETECTION_TYPE {
320     DetectNone,
321     DetectInt13,
322     DetectExInt13
323 }
324 
325 struct DISK_INT13_INFO {
326     WORD  DriveSelect;
327     DWORD MaxCylinders;
328     WORD  SectorsPerTrack;
329     WORD  MaxHeads;
330     WORD  NumberDrives;
331     }
332 alias DISK_INT13_INFO* PDISK_INT13_INFO;
333 
334 struct DISK_EX_INT13_INFO {
335     WORD    ExBufferSize;
336     WORD    ExFlags;
337     DWORD   ExCylinders;
338     DWORD   ExHeads;
339     DWORD   ExSectorsPerTrack;
340     DWORD64 ExSectorsPerDrive;
341     WORD    ExSectorSize;
342     WORD    ExReserved;
343 }
344 alias DISK_EX_INT13_INFO* PDISK_EX_INT13_INFO;
345 
346 struct DISK_DETECTION_INFO {
347     DWORD              SizeOfDetectInfo;
348     DETECTION_TYPE     DetectionType;
349     DISK_INT13_INFO    Int13;
350     DISK_EX_INT13_INFO ExInt13;
351 }
352 alias DISK_DETECTION_INFO* PDISK_DETECTION_INFO;
353 
354 enum MEDIA_TYPE {
355     Unknown,
356     F5_1Pt2_512,
357     F3_1Pt44_512,
358     F3_2Pt88_512,
359     F3_20Pt8_512,
360     F3_720_512,
361     F5_360_512,
362     F5_320_512,
363     F5_320_1024,
364     F5_180_512,
365     F5_160_512,
366     RemovableMedia,
367     FixedMedia,
368     F3_120M_512,
369     F3_640_512,
370     F5_640_512,
371     F5_720_512,
372     F3_1Pt2_512,
373     F3_1Pt23_1024,
374     F5_1Pt23_1024,
375     F3_128Mb_512,
376     F3_230Mb_512,
377     F8_256_128,
378     F3_200Mb_512,
379     F3_240M_512,
380     F3_32M_512
381 }
382 alias MEDIA_TYPE* PMEDIA_TYPE;
383 
384 struct DISK_GEOMETRY {
385     LARGE_INTEGER Cylinders;
386     MEDIA_TYPE    MediaType;
387     DWORD         TracksPerCylinder;
388     DWORD         SectorsPerTrack;
389     DWORD         BytesPerSector;
390 }
391 alias DISK_GEOMETRY* PDISK_GEOMETRY;
392 
393 struct DISK_GEOMETRY_EX {
394     DISK_GEOMETRY Geometry;
395     LARGE_INTEGER DiskSize;
396     BYTE          _Data;
397 
398     BYTE* Data() return { return &_Data; }
399 }
400 alias DISK_GEOMETRY_EX* PDISK_GEOMETRY_EX;
401 
402 struct DISK_GROW_PARTITION {
403     DWORD         PartitionNumber;
404     LARGE_INTEGER BytesToGrow;
405 }
406 alias DISK_GROW_PARTITION* PDISK_GROW_PARTITION;
407 
408 struct DISK_PARTITION_INFO {
409     DWORD           SizeOfPartitionInfo;
410     PARTITION_STYLE PartitionStyle;
411     union {
412         //struct {
413             DWORD Signature;
414         //} Mbr;
415         //struct {
416             GUID DiskId;
417         //} Gpt;
418     }
419 }
420 alias DISK_PARTITION_INFO* PDISK_PARTITION_INFO;
421 
422 struct DISK_PERFORMANCE {
423     LARGE_INTEGER BytesRead;
424     LARGE_INTEGER BytesWritten;
425     LARGE_INTEGER ReadTime;
426     LARGE_INTEGER WriteTime;
427     DWORD         ReadCount;
428     DWORD         WriteCount;
429     DWORD         QueueDepth;
430 }
431 alias DISK_PERFORMANCE* PDISK_PERFORMANCE;
432 
433 struct DISK_RECORD {
434     LARGE_INTEGER ByteOffset;
435     LARGE_INTEGER StartTime;
436     LARGE_INTEGER EndTime;
437     PVOID         VirtualAddress;
438     DWORD         NumberOfBytes;
439     BYTE          DeviceNumber;
440     BOOLEAN       ReadRequest;
441 }
442 alias DISK_RECORD* PDISK_RECORD;
443 
444 struct DISK_LOGGING {
445     BYTE  Function;
446     PVOID BufferAddress;
447     DWORD BufferSize;
448 }
449 alias DISK_LOGGING* PDISK_LOGGING;
450 
451 struct DISKQUOTA_USER_INFORMATION {
452     LONGLONG QuotaUsed;
453     LONGLONG QuotaThreshold;
454     LONGLONG QuotaLimit;
455 }
456 alias DISKQUOTA_USER_INFORMATION* PDISKQUOTA_USER_INFORMATION;
457 
458 struct FORMAT_PARAMETERS {
459     MEDIA_TYPE MediaType;
460     DWORD      StartCylinderNumber;
461     DWORD      EndCylinderNumber;
462     DWORD      StartHeadNumber;
463     DWORD      EndHeadNumber;
464 }
465 alias FORMAT_PARAMETERS* PFORMAT_PARAMETERS;
466 
467 struct FORMAT_EX_PARAMETERS {
468     MEDIA_TYPE MediaType;
469     DWORD      StartCylinderNumber;
470     DWORD      EndCylinderNumber;
471     DWORD      StartHeadNumber;
472     DWORD      EndHeadNumber;
473     WORD       FormatGapLength;
474     WORD       SectorsPerTrack;
475     WORD       _SectorNumber;
476 
477     WORD* SectorNumber() return { return &_SectorNumber; }
478 }
479 alias FORMAT_EX_PARAMETERS* PFORMAT_EX_PARAMETERS;
480 
481 struct GET_LENGTH_INFORMATION {
482     LARGE_INTEGER Length;
483 }
484 
485 struct HISTOGRAM_BUCKET {
486     DWORD Reads;
487     DWORD Writes;
488 }
489 alias HISTOGRAM_BUCKET* PHISTOGRAM_BUCKET;
490 
491 struct DISK_HISTOGRAM {
492     LARGE_INTEGER     DiskSize;
493     LARGE_INTEGER     Start;
494     LARGE_INTEGER     End;
495     LARGE_INTEGER     Average;
496     LARGE_INTEGER     AverageRead;
497     LARGE_INTEGER     AverageWrite;
498     DWORD             Granularity;
499     DWORD             Size;
500     DWORD             ReadCount;
501     DWORD             WriteCount;
502     PHISTOGRAM_BUCKET Histogram;
503 }
504 alias DISK_HISTOGRAM* PDISK_HISTOGRAM;
505 
506 struct DISK_EXTENT {
507     DWORD         DiskNumber;
508     LARGE_INTEGER StartingOffset;
509     LARGE_INTEGER ExtentLength;
510 }
511 alias DISK_EXTENT* PDISK_EXTENT;
512 
513 struct VOLUME_DISK_EXTENTS {
514     DWORD       NumberOfDiskExtents;
515     DISK_EXTENT _Extents;
516 
517     DISK_EXTENT* Extents() return { return &_Extents; }
518 }
519 alias VOLUME_DISK_EXTENTS* PVOLUME_DISK_EXTENTS;
520 
521 struct PARTITION_INFORMATION {
522     LARGE_INTEGER StartingOffset;
523     LARGE_INTEGER PartitionLength;
524     DWORD         HiddenSectors;
525     DWORD         PartitionNumber;
526     BYTE          PartitionType;
527     BOOLEAN       BootIndicator;
528     BOOLEAN       RecognizedPartition;
529     BOOLEAN       RewritePartition;
530 }
531 alias PARTITION_INFORMATION* PPARTITION_INFORMATION;
532 
533 struct DRIVE_LAYOUT_INFORMATION {
534     DWORD                 PartitionCount;
535     DWORD                 Signature;
536     PARTITION_INFORMATION _PartitionEntry;
537 
538     PARTITION_INFORMATION* PartitionEntry() return { return &_PartitionEntry; }
539 }
540 alias DRIVE_LAYOUT_INFORMATION* PDRIVE_LAYOUT_INFORMATION;
541 
542 struct DRIVE_LAYOUT_INFORMATION_GPT {
543     GUID          DiskId;
544     LARGE_INTEGER StartingUsableOffset;
545     LARGE_INTEGER UsableLength;
546     ULONG         MaxPartitionCount;
547 }
548 alias DRIVE_LAYOUT_INFORMATION_GPT* PDRIVE_LAYOUT_INFORMATION_GPT;
549 
550 struct DRIVE_LAYOUT_INFORMATION_MBR {
551     ULONG Signature;
552 }
553 alias DRIVE_LAYOUT_INFORMATION_MBR* PDRIVE_LAYOUT_INFORMATION_MBR;
554 
555 struct PARTITION_INFORMATION_MBR {
556     BYTE    PartitionType;
557     BOOLEAN BootIndicator;
558     BOOLEAN RecognizedPartition;
559     DWORD   HiddenSectors;
560 }
561 
562 struct PARTITION_INFORMATION_GPT {
563     GUID      PartitionType;
564     GUID      PartitionId;
565     DWORD64   Attributes;
566     WCHAR[36] Name = 0;
567 }
568 
569 struct PARTITION_INFORMATION_EX {
570     PARTITION_STYLE PartitionStyle;
571     LARGE_INTEGER   StartingOffset;
572     LARGE_INTEGER   PartitionLength;
573     DWORD           PartitionNumber;
574     BOOLEAN         RewritePartition;
575     union {
576         PARTITION_INFORMATION_MBR Mbr;
577         PARTITION_INFORMATION_GPT Gpt;
578     }
579 }
580 
581 struct DRIVE_LAYOUT_INFORMATION_EX {
582     DWORD PartitionStyle;
583     DWORD PartitionCount;
584     union {
585         DRIVE_LAYOUT_INFORMATION_MBR Mbr;
586         DRIVE_LAYOUT_INFORMATION_GPT Gpt;
587     }
588     PARTITION_INFORMATION_EX _PartitionEntry;
589 
590     PARTITION_INFORMATION_EX* PartitionEntry() return { return &_PartitionEntry; }
591 }
592 alias DRIVE_LAYOUT_INFORMATION_EX* PDRIVE_LAYOUT_INFORMATION_EX;
593 
594 struct MOVE_FILE_DATA {
595     HANDLE FileHandle;
596     LARGE_INTEGER StartingVcn;
597     LARGE_INTEGER StartingLcn;
598     DWORD ClusterCount;
599 }
600 alias MOVE_FILE_DATA* PMOVE_FILE_DATA;
601 
602 struct PERF_BIN {
603     DWORD     NumberOfBins;
604     DWORD     TypeOfBin;
605     BIN_RANGE _BinsRanges;
606 
607     BIN_RANGE* BinsRanges() return { return &_BinsRanges; }
608 }
609 alias PERF_BIN* PPERF_BIN;
610 
611 struct PREVENT_MEDIA_REMOVAL {
612     BOOLEAN PreventMediaRemoval;
613 }
614 alias PREVENT_MEDIA_REMOVAL* PPREVENT_MEDIA_REMOVAL;
615 
616 struct RETRIEVAL_POINTERS_BUFFER {
617     DWORD         ExtentCount;
618     LARGE_INTEGER StartingVcn;
619     // In MinGW, this is declared as struct { ... } Extents[1];
620     struct Extent {
621         LARGE_INTEGER NextVcn;
622         LARGE_INTEGER Lcn;
623     }
624     Extent _Extents;
625 
626     Extent* Extents() return { return &_Extents; }
627 }
628 alias RETRIEVAL_POINTERS_BUFFER* PRETRIEVAL_POINTERS_BUFFER;
629 
630 struct REASSIGN_BLOCKS {
631     WORD  Reserved;
632     WORD  Count;
633     DWORD _BlockNumber;
634 
635     DWORD* BlockNumber() return { return &_BlockNumber; }
636 }
637 alias REASSIGN_BLOCKS* PREASSIGN_BLOCKS;
638 
639 struct SET_PARTITION_INFORMATION {
640     BYTE PartitionType;
641 }
642 alias SET_PARTITION_INFORMATION* PSET_PARTITION_INFORMATION;
643 
644 struct STARTING_LCN_INPUT_BUFFER {
645     LARGE_INTEGER StartingLcn;
646 }
647 alias STARTING_LCN_INPUT_BUFFER* PSTARTING_LCN_INPUT_BUFFER;
648 
649 struct STARTING_VCN_INPUT_BUFFER {
650     LARGE_INTEGER StartingVcn;
651 }
652 alias STARTING_VCN_INPUT_BUFFER* PSTARTING_VCN_INPUT_BUFFER;
653 
654 struct VERIFY_INFORMATION {
655     LARGE_INTEGER StartingOffset;
656     DWORD         Length;
657 }
658 alias VERIFY_INFORMATION* PVERIFY_INFORMATION;
659 
660 struct VOLUME_BITMAP_BUFFER {
661     LARGE_INTEGER StartingLcn;
662     LARGE_INTEGER BitmapSize;
663     BYTE          _Buffer;
664 
665     BYTE* Buffer() return { return &_Buffer; }
666 }
667 alias VOLUME_BITMAP_BUFFER* PVOLUME_BITMAP_BUFFER;
668 
669 struct NTFS_VOLUME_DATA_BUFFER {
670     LARGE_INTEGER VolumeSerialNumber;
671     LARGE_INTEGER NumberSectors;
672     LARGE_INTEGER TotalClusters;
673     LARGE_INTEGER FreeClusters;
674     LARGE_INTEGER TotalReserved;
675     DWORD         BytesPerSector;
676     DWORD         BytesPerCluster;
677     DWORD         BytesPerFileRecordSegment;
678     DWORD         ClustersPerFileRecordSegment;
679     LARGE_INTEGER MftValidDataLength;
680     LARGE_INTEGER MftStartLcn;
681     LARGE_INTEGER Mft2StartLcn;
682     LARGE_INTEGER MftZoneStart;
683     LARGE_INTEGER MftZoneEnd;
684 }
685 alias NTFS_VOLUME_DATA_BUFFER* PNTFS_VOLUME_DATA_BUFFER;
686 
687 
688 bool IsRecognizedPartition(BYTE t) {
689     return ((t & PARTITION_NTFT)
690       && ((t & (-1 - VALID_NTFT)) == PARTITION_FAT_12
691         || (t & (-1 - VALID_NTFT)) == PARTITION_FAT_16
692         || (t & (-1 - VALID_NTFT)) == PARTITION_IFS
693         || (t & (-1 - VALID_NTFT)) == PARTITION_HUGE
694         || (t & (-1 - VALID_NTFT)) == PARTITION_FAT32
695         || (t & (-1 - VALID_NTFT)) == PARTITION_FAT32_XINT13
696         || (t & (-1 - VALID_NTFT)) == PARTITION_XINT13))
697       || (t & (-1 - PARTITION_NTFT)) == PARTITION_FAT_12
698       || (t & (-1 - PARTITION_NTFT)) == PARTITION_FAT_16
699       || (t & (-1 - PARTITION_NTFT)) == PARTITION_IFS
700       || (t & (-1 - PARTITION_NTFT)) == PARTITION_HUGE
701       || (t & (-1 - PARTITION_NTFT)) == PARTITION_FAT32
702       || (t & (-1 - PARTITION_NTFT)) == PARTITION_FAT32_XINT13
703       || (t & (-1 - PARTITION_NTFT)) == PARTITION_XINT13;
704 }
705 
706 bool IsContainerPartition(BYTE t) {
707     return ((t & PARTITION_NTFT)
708       && ((t & (-1 - VALID_NTFT)) == PARTITION_EXTENDED
709         || (t & (-1 - VALID_NTFT)) == PARTITION_XINT13_EXTENDED))
710       || (t & (-1 - PARTITION_NTFT)) == PARTITION_EXTENDED
711       || (t & (-1 - PARTITION_NTFT)) == PARTITION_XINT13_EXTENDED;
712 }