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