xref: /reactos/sdk/include/ddk/scsi.h (revision d7d716a6)
1 /*
2  * scsi.h
3  *
4  * SCSI port and class interface.
5  *
6  * This file is part of the w32api package.
7  *
8  * Contributors:
9  *   Created by Casper S. Hornstrup <chorns@users.sourceforge.net>
10  *
11  * THIS SOFTWARE IS NOT COPYRIGHTED
12  *
13  * This source code is offered for use in the public domain. You may
14  * use, modify or distribute it freely.
15  *
16  * This code is distributed in the hope that it will be useful but
17  * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
18  * DISCLAIMED. This includes but is not limited to warranties of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  */
22 
23 #ifndef _NTSCSI_
24 #define _NTSCSI_
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 #ifndef _NTSCSI_USER_MODE_
31 #include "srb.h"
32 #endif
33 
34 #define NOTIFICATION_OPERATIONAL_CHANGE_CLASS_MASK    0x02
35 #define NOTIFICATION_POWER_MANAGEMENT_CLASS_MASK      0x04
36 #define NOTIFICATION_EXTERNAL_REQUEST_CLASS_MASK      0x08
37 #define NOTIFICATION_MEDIA_STATUS_CLASS_MASK          0x10
38 #define NOTIFICATION_MULTI_HOST_CLASS_MASK            0x20
39 #define NOTIFICATION_DEVICE_BUSY_CLASS_MASK           0x40
40 
41 
42 #define NOTIFICATION_NO_CLASS_EVENTS                  0x0
43 #define NOTIFICATION_OPERATIONAL_CHANGE_CLASS_EVENTS  0x1
44 #define NOTIFICATION_POWER_MANAGEMENT_CLASS_EVENTS    0x2
45 #define NOTIFICATION_EXTERNAL_REQUEST_CLASS_EVENTS    0x3
46 #define NOTIFICATION_MEDIA_STATUS_CLASS_EVENTS        0x4
47 #define NOTIFICATION_MULTI_HOST_CLASS_EVENTS          0x5
48 #define NOTIFICATION_DEVICE_BUSY_CLASS_EVENTS         0x6
49 
50 #define NOTIFICATION_OPERATIONAL_EVENT_NO_CHANGE         0x0
51 #define NOTIFICATION_OPERATIONAL_EVENT_CHANGE_REQUESTED  0x1
52 #define NOTIFICATION_OPERATIONAL_EVENT_CHANGE_OCCURRED   0x2
53 
54 #define NOTIFICATION_OPERATIONAL_STATUS_AVAILABLE        0x0
55 #define NOTIFICATION_OPERATIONAL_STATUS_TEMPORARY_BUSY   0x1
56 #define NOTIFICATION_OPERATIONAL_STATUS_EXTENDED_BUSY    0x2
57 
58 #define NOTIFICATION_OPERATIONAL_OPCODE_NONE             0x0
59 #define NOTIFICATION_OPERATIONAL_OPCODE_FEATURE_CHANGE   0x1
60 #define NOTIFICATION_OPERATIONAL_OPCODE_FEATURE_ADDED    0x2
61 #define NOTIFICATION_OPERATIONAL_OPCODE_UNIT_RESET       0x3
62 #define NOTIFICATION_OPERATIONAL_OPCODE_FIRMWARE_CHANGED 0x4
63 #define NOTIFICATION_OPERATIONAL_OPCODE_INQUIRY_CHANGED  0x5
64 
65 #define NOTIFICATION_POWER_EVENT_NO_CHANGE          0x0
66 #define NOTIFICATION_POWER_EVENT_CHANGE_SUCCEEDED   0x1
67 #define NOTIFICATION_POWER_EVENT_CHANGE_FAILED      0x2
68 
69 #define NOTIFICATION_POWER_STATUS_ACTIVE            0x1
70 #define NOTIFICATION_POWER_STATUS_IDLE              0x2
71 #define NOTIFICATION_POWER_STATUS_STANDBY           0x3
72 #define NOTIFICATION_POWER_STATUS_SLEEP             0x4
73 
74 #define NOTIFICATION_MEDIA_EVENT_NO_EVENT           0x0
75 #define NOTIFICATION_EXTERNAL_EVENT_NO_CHANGE       0x0
76 #define NOTIFICATION_EXTERNAL_EVENT_BUTTON_DOWN     0x1
77 #define NOTIFICATION_EXTERNAL_EVENT_BUTTON_UP       0x2
78 #define NOTIFICATION_EXTERNAL_EVENT_EXTERNAL        0x3
79 
80 #define NOTIFICATION_EXTERNAL_STATUS_READY          0x0
81 #define NOTIFICATION_EXTERNAL_STATUS_PREVENT        0x1
82 
83 #define NOTIFICATION_EXTERNAL_REQUEST_NONE          0x0000
84 #define NOTIFICATION_EXTERNAL_REQUEST_QUEUE_OVERRUN 0x0001
85 #define NOTIFICATION_EXTERNAL_REQUEST_PLAY          0x0101
86 #define NOTIFICATION_EXTERNAL_REQUEST_REWIND_BACK   0x0102
87 #define NOTIFICATION_EXTERNAL_REQUEST_FAST_FORWARD  0x0103
88 #define NOTIFICATION_EXTERNAL_REQUEST_PAUSE         0x0104
89 #define NOTIFICATION_EXTERNAL_REQUEST_STOP          0x0106
90 #define NOTIFICATION_EXTERNAL_REQUEST_ASCII_LOW     0x0200
91 #define NOTIFICATION_EXTERNAL_REQUEST_ASCII_HIGH    0x02ff
92 
93 #define NOTIFICATION_MEDIA_EVENT_NO_CHANGE          0x0
94 #define NOTIFICATION_MEDIA_EVENT_EJECT_REQUEST      0x1
95 #define NOTIFICATION_MEDIA_EVENT_NEW_MEDIA          0x2
96 #define NOTIFICATION_MEDIA_EVENT_MEDIA_REMOVAL      0x3
97 #define NOTIFICATION_MEDIA_EVENT_MEDIA_CHANGE       0x4
98 
99 #define NOTIFICATION_BUSY_EVENT_NO_EVENT               0x0
100 #define NOTIFICATION_MULTI_HOST_EVENT_NO_CHANGE        0x0
101 #define NOTIFICATION_MULTI_HOST_EVENT_CONTROL_REQUEST  0x1
102 #define NOTIFICATION_MULTI_HOST_EVENT_CONTROL_GRANT    0x2
103 #define NOTIFICATION_MULTI_HOST_EVENT_CONTROL_RELEASE  0x3
104 
105 #define NOTIFICATION_MULTI_HOST_STATUS_READY           0x0
106 #define NOTIFICATION_MULTI_HOST_STATUS_PREVENT         0x1
107 
108 #define NOTIFICATION_MULTI_HOST_PRIORITY_NO_REQUESTS   0x0
109 #define NOTIFICATION_MULTI_HOST_PRIORITY_LOW           0x1
110 #define NOTIFICATION_MULTI_HOST_PRIORITY_MEDIUM        0x2
111 #define NOTIFICATION_MULTI_HOST_PRIORITY_HIGH          0x3
112 
113 #define NOTIFICATION_BUSY_EVENT_NO_EVENT            0x0
114 #define NOTIFICATION_BUSY_EVENT_NO_CHANGE           0x0
115 #define NOTIFICATION_BUSY_EVENT_BUSY                0x1
116 #define NOTIFICATION_BUSY_EVENT_LO_CHANGE           0x2
117 
118 #define NOTIFICATION_BUSY_STATUS_NO_EVENT           0x0
119 #define NOTIFICATION_BUSY_STATUS_POWER              0x1
120 #define NOTIFICATION_BUSY_STATUS_IMMEDIATE          0x2
121 #define NOTIFICATION_BUSY_STATUS_DEFERRED           0x3
122 
123 #define DVD_FORMAT_LEAD_IN          0x00
124 #define DVD_FORMAT_COPYRIGHT        0x01
125 #define DVD_FORMAT_DISK_KEY         0x02
126 #define DVD_FORMAT_BCA              0x03
127 #define DVD_FORMAT_MANUFACTURING    0x04
128 
129 #define DVD_REPORT_AGID            0x00
130 #define DVD_CHALLENGE_KEY          0x01
131 #define DVD_KEY_1                  0x02
132 #define DVD_KEY_2                  0x03
133 #define DVD_TITLE_KEY              0x04
134 #define DVD_REPORT_ASF             0x05
135 #define DVD_INVALIDATE_AGID        0x3F
136 
137 #define BLANK_FULL              0x0
138 #define BLANK_MINIMAL           0x1
139 #define BLANK_TRACK             0x2
140 #define BLANK_UNRESERVE_TRACK   0x3
141 #define BLANK_TAIL              0x4
142 #define BLANK_UNCLOSE_SESSION   0x5
143 #define BLANK_SESSION           0x6
144 
145 #define CD_EXPECTED_SECTOR_ANY          0x0
146 #define CD_EXPECTED_SECTOR_CDDA         0x1
147 #define CD_EXPECTED_SECTOR_MODE1        0x2
148 #define CD_EXPECTED_SECTOR_MODE2        0x3
149 #define CD_EXPECTED_SECTOR_MODE2_FORM1  0x4
150 #define CD_EXPECTED_SECTOR_MODE2_FORM2  0x5
151 
152 #define DISK_STATUS_EMPTY       0x00
153 #define DISK_STATUS_INCOMPLETE  0x01
154 #define DISK_STATUS_COMPLETE    0x02
155 #define DISK_STATUS_OTHERS      0x03
156 
157 #define LAST_SESSION_EMPTY              0x00
158 #define LAST_SESSION_INCOMPLETE         0x01
159 #define LAST_SESSION_RESERVED_DAMAGED   0x02
160 #define LAST_SESSION_COMPLETE           0x03
161 
162 #define DISK_TYPE_CDDA          0x00
163 #define DISK_TYPE_CDI           0x10
164 #define DISK_TYPE_XA            0x20
165 #define DISK_TYPE_UNDEFINED     0xFF
166 
167 #define DISC_BGFORMAT_STATE_NONE        0x0
168 #define DISC_BGFORMAT_STATE_INCOMPLETE  0x1
169 #define DISC_BGFORMAT_STATE_RUNNING     0x2
170 #define DISC_BGFORMAT_STATE_COMPLETE    0x3
171 
172 #define DATA_BLOCK_MODE0    0x0
173 #define DATA_BLOCK_MODE1    0x1
174 #define DATA_BLOCK_MODE2    0x2
175 
176 /* READ_TOC formats */
177 #define READ_TOC_FORMAT_TOC         0x00
178 #define READ_TOC_FORMAT_SESSION     0x01
179 #define READ_TOC_FORMAT_FULL_TOC    0x02
180 #define READ_TOC_FORMAT_PMA         0x03
181 #define READ_TOC_FORMAT_ATIP        0x04
182 
183 #define CDB6GENERIC_LENGTH                   6
184 #define CDB10GENERIC_LENGTH                  10
185 #define CDB12GENERIC_LENGTH                  12
186 
187 #define SETBITON                             1
188 #define SETBITOFF                            0
189 
190 /* Mode Sense/Select page constants */
191 #define MODE_PAGE_VENDOR_SPECIFIC       0x00
192 #define MODE_PAGE_ERROR_RECOVERY        0x01
193 #define MODE_PAGE_DISCONNECT            0x02
194 #define MODE_PAGE_FORMAT_DEVICE         0x03
195 #define MODE_PAGE_MRW                   0x03
196 #define MODE_PAGE_RIGID_GEOMETRY        0x04
197 #define MODE_PAGE_FLEXIBILE             0x05
198 #define MODE_PAGE_WRITE_PARAMETERS      0x05
199 #define MODE_PAGE_VERIFY_ERROR          0x07
200 #define MODE_PAGE_CACHING               0x08
201 #define MODE_PAGE_PERIPHERAL            0x09
202 #define MODE_PAGE_CONTROL               0x0A
203 #define MODE_PAGE_MEDIUM_TYPES          0x0B
204 #define MODE_PAGE_NOTCH_PARTITION       0x0C
205 #define MODE_PAGE_CD_AUDIO_CONTROL      0x0E
206 #define MODE_PAGE_DATA_COMPRESS         0x0F
207 #define MODE_PAGE_DEVICE_CONFIG         0x10
208 #define MODE_PAGE_XOR_CONTROL           0x10
209 #define MODE_PAGE_MEDIUM_PARTITION      0x11
210 #define MODE_PAGE_ENCLOSURE_SERVICES_MANAGEMENT 0x14
211 #define MODE_PAGE_EXTENDED              0x15
212 #define MODE_PAGE_EXTENDED_DEVICE_SPECIFIC 0x16
213 #define MODE_PAGE_CDVD_FEATURE_SET      0x18
214 #define MODE_PAGE_PROTOCOL_SPECIFIC_LUN 0x18
215 #define MODE_PAGE_PROTOCOL_SPECIFIC_PORT 0x19
216 #define MODE_PAGE_POWER_CONDITION       0x1A
217 #define MODE_PAGE_LUN_MAPPING           0x1B
218 #define MODE_PAGE_FAULT_REPORTING       0x1C
219 #define MODE_PAGE_CDVD_INACTIVITY       0x1D
220 #define MODE_PAGE_ELEMENT_ADDRESS       0x1D
221 #define MODE_PAGE_TRANSPORT_GEOMETRY    0x1E
222 #define MODE_PAGE_DEVICE_CAPABILITIES   0x1F
223 #define MODE_PAGE_CAPABILITIES          0x2A
224 
225 #define MODE_SENSE_RETURN_ALL           0x3f
226 
227 #define MODE_SENSE_CURRENT_VALUES       0x00
228 #define MODE_SENSE_CHANGEABLE_VALUES    0x40
229 #define MODE_SENSE_DEFAULT_VAULES       0x80
230 #define MODE_SENSE_SAVED_VALUES         0xc0
231 
232 /* SCSI CDB operation codes */
233 #define SCSIOP_TEST_UNIT_READY          0x00
234 #define SCSIOP_REZERO_UNIT              0x01
235 #define SCSIOP_REWIND                   0x01
236 #define SCSIOP_REQUEST_BLOCK_ADDR       0x02
237 #define SCSIOP_REQUEST_SENSE            0x03
238 #define SCSIOP_FORMAT_UNIT              0x04
239 #define SCSIOP_READ_BLOCK_LIMITS        0x05
240 #define SCSIOP_REASSIGN_BLOCKS          0x07
241 #define SCSIOP_INIT_ELEMENT_STATUS      0x07
242 #define SCSIOP_READ6                    0x08
243 #define SCSIOP_RECEIVE                  0x08
244 #define SCSIOP_WRITE6                   0x0A
245 #define SCSIOP_PRINT                    0x0A
246 #define SCSIOP_SEND                     0x0A
247 #define SCSIOP_SEEK6                    0x0B
248 #define SCSIOP_TRACK_SELECT             0x0B
249 #define SCSIOP_SLEW_PRINT               0x0B
250 #define SCSIOP_SET_CAPACITY             0x0B
251 #define SCSIOP_SEEK_BLOCK               0x0C
252 #define SCSIOP_PARTITION                0x0D
253 #define SCSIOP_READ_REVERSE             0x0F
254 #define SCSIOP_WRITE_FILEMARKS          0x10
255 #define SCSIOP_FLUSH_BUFFER             0x10
256 #define SCSIOP_SPACE                    0x11
257 #define SCSIOP_INQUIRY                  0x12
258 #define SCSIOP_VERIFY6                  0x13
259 #define SCSIOP_RECOVER_BUF_DATA         0x14
260 #define SCSIOP_MODE_SELECT              0x15
261 #define SCSIOP_RESERVE_UNIT             0x16
262 #define SCSIOP_RELEASE_UNIT             0x17
263 #define SCSIOP_COPY                     0x18
264 #define SCSIOP_ERASE                    0x19
265 #define SCSIOP_MODE_SENSE               0x1A
266 #define SCSIOP_START_STOP_UNIT          0x1B
267 #define SCSIOP_STOP_PRINT               0x1B
268 #define SCSIOP_LOAD_UNLOAD              0x1B
269 #define SCSIOP_RECEIVE_DIAGNOSTIC       0x1C
270 #define SCSIOP_SEND_DIAGNOSTIC          0x1D
271 #define SCSIOP_MEDIUM_REMOVAL           0x1E
272 
273 #define SCSIOP_READ_FORMATTED_CAPACITY  0x23
274 #define SCSIOP_READ_CAPACITY            0x25
275 #define SCSIOP_READ                     0x28
276 #define SCSIOP_WRITE                    0x2A
277 #define SCSIOP_SEEK                     0x2B
278 #define SCSIOP_LOCATE                   0x2B
279 #define SCSIOP_POSITION_TO_ELEMENT      0x2B
280 #define SCSIOP_WRITE_VERIFY             0x2E
281 #define SCSIOP_VERIFY                   0x2F
282 #define SCSIOP_SEARCH_DATA_HIGH         0x30
283 #define SCSIOP_SEARCH_DATA_EQUAL        0x31
284 #define SCSIOP_SEARCH_DATA_LOW          0x32
285 #define SCSIOP_SET_LIMITS               0x33
286 #define SCSIOP_READ_POSITION            0x34
287 #define SCSIOP_SYNCHRONIZE_CACHE        0x35
288 #define SCSIOP_COMPARE                  0x39
289 #define SCSIOP_COPY_COMPARE             0x3A
290 #define SCSIOP_WRITE_DATA_BUFF          0x3B
291 #define SCSIOP_READ_DATA_BUFF           0x3C
292 #define SCSIOP_WRITE_LONG               0x3F
293 #define SCSIOP_CHANGE_DEFINITION        0x40
294 #define SCSIOP_WRITE_SAME               0x41
295 #define SCSIOP_READ_SUB_CHANNEL         0x42
296 #define SCSIOP_UNMAP                    0x42
297 #define SCSIOP_READ_TOC                 0x43
298 #define SCSIOP_READ_HEADER              0x44
299 #define SCSIOP_REPORT_DENSITY_SUPPORT   0x44
300 #define SCSIOP_PLAY_AUDIO               0x45
301 #define SCSIOP_GET_CONFIGURATION        0x46
302 #define SCSIOP_PLAY_AUDIO_MSF           0x47
303 #define SCSIOP_PLAY_TRACK_INDEX         0x48
304 #define SCSIOP_SANITIZE                 0x48
305 #define SCSIOP_PLAY_TRACK_RELATIVE      0x49
306 #define SCSIOP_GET_EVENT_STATUS         0x4A
307 #define SCSIOP_PAUSE_RESUME             0x4B
308 #define SCSIOP_LOG_SELECT               0x4C
309 #define SCSIOP_LOG_SENSE                0x4D
310 #define SCSIOP_STOP_PLAY_SCAN           0x4E
311 #define SCSIOP_XDWRITE                  0x50
312 #define SCSIOP_XPWRITE                  0x51
313 #define SCSIOP_READ_DISK_INFORMATION    0x51
314 #define SCSIOP_READ_DISC_INFORMATION    0x51
315 #define SCSIOP_READ_TRACK_INFORMATION   0x52
316 #define SCSIOP_XDWRITE_READ             0x53
317 #define SCSIOP_RESERVE_TRACK_RZONE      0x53
318 #define SCSIOP_SEND_OPC_INFORMATION     0x54
319 #define SCSIOP_MODE_SELECT10            0x55
320 #define SCSIOP_RESERVE_UNIT10           0x56
321 #define SCSIOP_RESERVE_ELEMENT          0x56
322 #define SCSIOP_RELEASE_UNIT10           0x57
323 #define SCSIOP_RELEASE_ELEMENT          0x57
324 #define SCSIOP_REPAIR_TRACK             0x58
325 #define SCSIOP_MODE_SENSE10             0x5A
326 #define SCSIOP_CLOSE_TRACK_SESSION      0x5B
327 #define SCSIOP_READ_BUFFER_CAPACITY     0x5C
328 #define SCSIOP_SEND_CUE_SHEET           0x5D
329 #define SCSIOP_PERSISTENT_RESERVE_IN    0x5E
330 #define SCSIOP_PERSISTENT_RESERVE_OUT   0x5F
331 
332 #define SCSIOP_OPERATION32              0x7F
333 
334 #define SCSIOP_XDWRITE_EXTENDED16       0x80
335 #define SCSIOP_WRITE_FILEMARKS16        0x80
336 #define SCSIOP_REBUILD16                0x81
337 #define SCSIOP_READ_REVERSE16           0x81
338 #define SCSIOP_REGENERATE16             0x82
339 #define SCSIOP_EXTENDED_COPY            0x83
340 #define SCSIOP_POPULATE_TOKEN           0x83
341 #define SCSIOP_WRITE_USING_TOKEN        0x83
342 #define SCSIOP_RECEIVE_COPY_RESULTS     0x84
343 #define SCSIOP_RECEIVE_ROD_TOKEN_INFORMATION 0x84
344 #define SCSIOP_ATA_PASSTHROUGH16        0x85
345 #define SCSIOP_ACCESS_CONTROL_IN        0x86
346 #define SCSIOP_ACCESS_CONTROL_OUT       0x87
347 #define SCSIOP_READ16                   0x88
348 #define SCSIOP_COMPARE_AND_WRITE        0x89
349 #define SCSIOP_WRITE16                  0x8A
350 #define SCSIOP_READ_ATTRIBUTES          0x8C
351 #define SCSIOP_WRITE_ATTRIBUTES         0x8D
352 #define SCSIOP_WRITE_VERIFY16           0x8E
353 #define SCSIOP_VERIFY16                 0x8F
354 #define SCSIOP_PREFETCH16               0x90
355 #define SCSIOP_SYNCHRONIZE_CACHE16      0x91
356 #define SCSIOP_SPACE16                  0x91
357 #define SCSIOP_LOCK_UNLOCK_CACHE16      0x92
358 #define SCSIOP_LOCATE16                 0x92
359 #define SCSIOP_WRITE_SAME16             0x93
360 #define SCSIOP_ERASE16                  0x93
361 #define SCSIOP_ZBC_OUT                  0x94
362 #define SCSIOP_ZBC_IN                   0x95
363 #define SCSIOP_READ_DATA_BUFF16         0x9B
364 #define SCSIOP_READ_CAPACITY16          0x9E
365 #define SCSIOP_GET_LBA_STATUS           0x9E
366 #define SCSIOP_GET_PHYSICAL_ELEMENT_STATUS 0x9E
367 #define SCSIOP_REMOVE_ELEMENT_AND_TRUNCATE 0x9E
368 #define SCSIOP_SERVICE_ACTION_IN16      0x9E
369 #define SCSIOP_SERVICE_ACTION_OUT16     0x9F
370 
371 #define SCSIOP_REPORT_LUNS              0xA0
372 #define SCSIOP_BLANK                    0xA1
373 #define SCSIOP_ATA_PASSTHROUGH12        0xA1
374 #define SCSIOP_SEND_EVENT               0xA2
375 #define SCSIOP_SECURITY_PROTOCOL_IN     0xA2
376 #define SCSIOP_SEND_KEY                 0xA3
377 #define SCSIOP_MAINTENANCE_IN           0xA3
378 #define SCSIOP_REPORT_KEY               0xA4
379 #define SCSIOP_MAINTENANCE_OUT          0xA4
380 #define SCSIOP_MOVE_MEDIUM              0xA5
381 #define SCSIOP_LOAD_UNLOAD_SLOT         0xA6
382 #define SCSIOP_EXCHANGE_MEDIUM          0xA6
383 #define SCSIOP_SET_READ_AHEAD           0xA7
384 #define SCSIOP_MOVE_MEDIUM_ATTACHED     0xA7
385 #define SCSIOP_READ12                   0xA8
386 #define SCSIOP_GET_MESSAGE              0xA8
387 #define SCSIOP_SERVICE_ACTION_OUT12     0xA9
388 #define SCSIOP_WRITE12                  0xAA
389 #define SCSIOP_SEND_MESSAGE             0xAB
390 #define SCSIOP_SERVICE_ACTION_IN12      0xAB
391 #define SCSIOP_GET_PERFORMANCE          0xAC
392 #define SCSIOP_READ_DVD_STRUCTURE       0xAD
393 #define SCSIOP_WRITE_VERIFY12           0xAE
394 #define SCSIOP_VERIFY12                 0xAF
395 #define SCSIOP_SEARCH_DATA_HIGH12       0xB0
396 #define SCSIOP_SEARCH_DATA_EQUAL12      0xB1
397 #define SCSIOP_SEARCH_DATA_LOW12        0xB2
398 #define SCSIOP_SET_LIMITS12             0xB3
399 #define SCSIOP_READ_ELEMENT_STATUS_ATTACHED 0xB4
400 #define SCSIOP_REQUEST_VOL_ELEMENT      0xB5
401 #define SCSIOP_SECURITY_PROTOCOL_OUT    0xB5
402 #define SCSIOP_SEND_VOLUME_TAG          0xB6
403 #define SCSIOP_SET_STREAMING            0xB6
404 #define SCSIOP_READ_DEFECT_DATA         0xB7
405 #define SCSIOP_READ_ELEMENT_STATUS      0xB8
406 #define SCSIOP_READ_CD_MSF              0xB9
407 #define SCSIOP_SCAN_CD                  0xBA
408 #define SCSIOP_REDUNDANCY_GROUP_IN      0xBA
409 #define SCSIOP_SET_CD_SPEED             0xBB
410 #define SCSIOP_REDUNDANCY_GROUP_OUT     0xBB
411 #define SCSIOP_PLAY_CD                  0xBC
412 #define SCSIOP_SPARE_IN                 0xBC
413 #define SCSIOP_MECHANISM_STATUS         0xBD
414 #define SCSIOP_SPARE_OUT                0xBD
415 #define SCSIOP_READ_CD                  0xBE
416 #define SCSIOP_VOLUME_SET_IN            0xBE
417 #define SCSIOP_SEND_DVD_STRUCTURE       0xBF
418 #define SCSIOP_VOLUME_SET_OUT           0xBF
419 #define SCSIOP_INIT_ELEMENT_RANGE       0xE7
420 
421 // SCSI operation parameters
422 
423 // SCSIOP_SANITIZE (0x48)
424 
425 #define SERVICE_ACTION_OVERWRITE                                                0x01
426 #define SERVICE_ACTION_BLOCK_ERASE                                              0x02
427 #define SERVICE_ACTION_CRYPTO_ERASE                                             0x03
428 #define SERVICE_ACTION_EXIT_FAILURE                                             0x1f
429 
430 // SCSIOP_OPERATION32 (0x7F)
431 
432 #define SERVICE_ACTION_XDWRITE                                                  0x0004
433 #define SERVICE_ACTION_XPWRITE                                                  0x0006
434 #define SERVICE_ACTION_XDWRITEREAD                                              0x0007
435 #define SERVICE_ACTION_WRITE                                                    0x000B
436 #define SERVICE_ACTION_WRITE_VERIFY                                             0x000C
437 #define SERVICE_ACTION_WRITE_SAME                                               0x000D
438 #define SERVICE_ACTION_ORWRITE                                                  0x000E
439 
440 // SCSIOP_POPULATE_TOKEN, SCSIOP_WRITE_USING_TOKEN (0x83)
441 
442 #define SERVICE_ACTION_POPULATE_TOKEN                                           0x10
443 #define SERVICE_ACTION_WRITE_USING_TOKEN                                        0x11
444 
445 // SCSIOP_RECEIVE_ROD_TOKEN_INFORMATION (0x84)
446 
447 #define SERVICE_ACTION_RECEIVE_TOKEN_INFORMATION                                0x07
448 
449 // SCSIOP_ZBC_OUT (0x94)
450 
451 #define SERVICE_ACTION_CLOSE_ZONE                                               0x01
452 #define SERVICE_ACTION_FINISH_ZONE                                              0x02
453 #define SERVICE_ACTION_OPEN_ZONE                                                0x03
454 #define SERVICE_ACTION_RESET_WRITE_POINTER                                      0x04
455 
456 // SCSIOP_ZBC_IN (0x95)
457 
458 #define SERVICE_ACTION_REPORT_ZONES                                             0x00
459 
460 #define REPORT_ZONES_OPTION_LIST_ALL_ZONES                                      0x00
461 #define REPORT_ZONES_OPTION_LIST_EMPTY_ZONES                                    0x01
462 #define REPORT_ZONES_OPTION_LIST_IMPLICITLY_OPENED_ZONES                        0x02
463 #define REPORT_ZONES_OPTION_LIST_EXPLICITLY_OPENED_ZONES                        0x03
464 #define REPORT_ZONES_OPTION_LIST_CLOSED_ZONES                                   0x04
465 #define REPORT_ZONES_OPTION_LIST_FULL_ZONES                                     0x05
466 #define REPORT_ZONES_OPTION_LIST_READ_ONLY_ZONES                                0x06
467 #define REPORT_ZONES_OPTION_LIST_OFFLINE_ZONES                                  0x07
468 #define REPORT_ZONES_OPTION_LIST_RWP_ZONES                                      0x10
469 #define REPORT_ZONES_OPTION_LIST_NON_SEQUENTIAL_WRITE_RESOURCES_ACTIVE_ZONES    0x11
470 #define REPORT_ZONES_OPTION_LIST_NOT_WRITE_POINTER_ZONES                        0x3F
471 
472 // SCSIOP_SERVICE_ACTION_IN16 (0x9E)
473 
474 #define SERVICE_ACTION_READ_CAPACITY16                                          0x10
475 #define SERVICE_ACTION_GET_LBA_STATUS                                           0x12
476 #define SERVICE_ACTION_GET_PHYSICAL_ELEMENT_STATUS                              0x17
477 #define SERVICE_ACTION_REMOVE_ELEMENT_AND_TRUNCATE                              0x18
478 
479 // SCSIOP_MAINTENANCE_IN (0xA3)
480 
481 #define SERVICE_ACTION_REPORT_TIMESTAMP                                         0x0F
482 
483 // SCSIOP_MAINTENANCE_OUT (0xA4)
484 
485 #define SERVICE_ACTION_SET_TIMESTAMP                                            0x0F
486 
487 #define CDB_RETURN_ON_COMPLETION   0
488 #define CDB_RETURN_IMMEDIATE       1
489 
490 #define CDB_FORCE_MEDIA_ACCESS 0x08
491 
492 #define SCSIOP_DENON_EJECT_DISC    0xE6
493 #define SCSIOP_DENON_STOP_AUDIO    0xE7
494 #define SCSIOP_DENON_PLAY_AUDIO    0xE8
495 #define SCSIOP_DENON_READ_TOC      0xE9
496 #define SCSIOP_DENON_READ_SUBCODE  0xEB
497 
498 #define SCSIMESS_ABORT                0x06
499 #define SCSIMESS_ABORT_WITH_TAG       0x0D
500 #define SCSIMESS_BUS_DEVICE_RESET     0X0C
501 #define SCSIMESS_CLEAR_QUEUE          0X0E
502 #define SCSIMESS_COMMAND_COMPLETE     0X00
503 #define SCSIMESS_DISCONNECT           0X04
504 #define SCSIMESS_EXTENDED_MESSAGE     0X01
505 #define SCSIMESS_IDENTIFY             0X80
506 #define SCSIMESS_IDENTIFY_WITH_DISCON 0XC0
507 #define SCSIMESS_IGNORE_WIDE_RESIDUE  0X23
508 #define SCSIMESS_INITIATE_RECOVERY    0X0F
509 #define SCSIMESS_INIT_DETECTED_ERROR  0X05
510 #define SCSIMESS_LINK_CMD_COMP        0X0A
511 #define SCSIMESS_LINK_CMD_COMP_W_FLAG 0X0B
512 #define SCSIMESS_MESS_PARITY_ERROR    0X09
513 #define SCSIMESS_MESSAGE_REJECT       0X07
514 #define SCSIMESS_NO_OPERATION         0X08
515 #define SCSIMESS_HEAD_OF_QUEUE_TAG    0X21
516 #define SCSIMESS_ORDERED_QUEUE_TAG    0X22
517 #define SCSIMESS_SIMPLE_QUEUE_TAG     0X20
518 #define SCSIMESS_RELEASE_RECOVERY     0X10
519 #define SCSIMESS_RESTORE_POINTERS     0X03
520 #define SCSIMESS_SAVE_DATA_POINTER    0X02
521 #define SCSIMESS_TERMINATE_IO_PROCESS 0X11
522 
523 #define SCSIMESS_MODIFY_DATA_POINTER  0X00
524 #define SCSIMESS_SYNCHRONOUS_DATA_REQ 0X01
525 #define SCSIMESS_WIDE_DATA_REQUEST    0X03
526 
527 #define SCSIMESS_MODIFY_DATA_LENGTH   5
528 #define SCSIMESS_SYNCH_DATA_LENGTH    3
529 #define SCSIMESS_WIDE_DATA_LENGTH     2
530 
531 #define CDB_INQUIRY_EVPD           0x01
532 
533 #define LUN0_FORMAT_SAVING_DEFECT_LIST 0
534 #define USE_DEFAULTMSB 0
535 #define USE_DEFAULTLSB 0
536 
537 #define START_UNIT_CODE 0x01
538 #define STOP_UNIT_CODE 0x00
539 
540 /* INQUIRYDATA.DeviceType constants */
541 #define DIRECT_ACCESS_DEVICE              0x00
542 #define SEQUENTIAL_ACCESS_DEVICE          0x01
543 #define PRINTER_DEVICE                    0x02
544 #define PROCESSOR_DEVICE                  0x03
545 #define WRITE_ONCE_READ_MULTIPLE_DEVICE   0x04
546 #define READ_ONLY_DIRECT_ACCESS_DEVICE    0x05
547 #define SCANNER_DEVICE                    0x06
548 #define OPTICAL_DEVICE                    0x07
549 #define MEDIUM_CHANGER                    0x08
550 #define COMMUNICATION_DEVICE              0x09
551 #define ARRAY_CONTROLLER_DEVICE           0x0C
552 #define SCSI_ENCLOSURE_DEVICE             0x0D
553 #define REDUCED_BLOCK_DEVICE              0x0E
554 #define OPTICAL_CARD_READER_WRITER_DEVICE 0x0F
555 #define BRIDGE_CONTROLLER_DEVICE          0x10
556 #define OBJECT_BASED_STORAGE_DEVICE       0x11
557 #define LOGICAL_UNIT_NOT_PRESENT_DEVICE   0x7F
558 
559 #define DEVICE_QUALIFIER_ACTIVE           0x00
560 #define DEVICE_QUALIFIER_NOT_ACTIVE       0x01
561 #define DEVICE_QUALIFIER_NOT_SUPPORTED    0x03
562 
563 /* INQUIRYDATA.DeviceTypeQualifier constants */
564 #define DEVICE_CONNECTED 0x00
565 
566 #define SCSISTAT_GOOD                     0x00
567 #define SCSISTAT_CHECK_CONDITION          0x02
568 #define SCSISTAT_CONDITION_MET            0x04
569 #define SCSISTAT_BUSY                     0x08
570 #define SCSISTAT_INTERMEDIATE             0x10
571 #define SCSISTAT_INTERMEDIATE_COND_MET    0x14
572 #define SCSISTAT_RESERVATION_CONFLICT     0x18
573 #define SCSISTAT_COMMAND_TERMINATED       0x22
574 #define SCSISTAT_QUEUE_FULL               0x28
575 
576 #define RESERVATION_ACTION_READ_KEYS                    0x00
577 #define RESERVATION_ACTION_READ_RESERVATIONS            0x01
578 
579 #define RESERVATION_ACTION_REGISTER                     0x00
580 #define RESERVATION_ACTION_RESERVE                      0x01
581 #define RESERVATION_ACTION_RELEASE                      0x02
582 #define RESERVATION_ACTION_CLEAR                        0x03
583 #define RESERVATION_ACTION_PREEMPT                      0x04
584 #define RESERVATION_ACTION_PREEMPT_ABORT                0x05
585 #define RESERVATION_ACTION_REGISTER_IGNORE_EXISTING     0x06
586 
587 #define RESERVATION_SCOPE_LU                            0x00
588 #define RESERVATION_SCOPE_ELEMENT                       0x02
589 
590 #define RESERVATION_TYPE_WRITE_EXCLUSIVE                0x01
591 #define RESERVATION_TYPE_EXCLUSIVE                      0x03
592 #define RESERVATION_TYPE_WRITE_EXCLUSIVE_REGISTRANTS    0x05
593 #define RESERVATION_TYPE_EXCLUSIVE_REGISTRANTS          0x06
594 
595 #define SENSE_BUFFER_SIZE sizeof(SENSE_DATA)
596 #define SENSE_BUFFER_SIZE_EX sizeof(SENSE_DATA_EX)
597 
598 #define MAX_SENSE_BUFFER_SIZE          255
599 
600 #define MAX_ADDITIONAL_SENSE_BYTES (MAX_SENSE_BUFFER_SIZE - SENSE_BUFFER_SIZE)
601 #define MAX_ADDITIONAL_SENSE_BYTES_EX (MAX_SENSE_BUFFER_SIZE - SENSE_BUFFER_SIZE_EX)
602 
603 /* Sense codes */
604 #define SCSI_SENSE_NO_SENSE               0x00
605 #define SCSI_SENSE_RECOVERED_ERROR        0x01
606 #define SCSI_SENSE_NOT_READY              0x02
607 #define SCSI_SENSE_MEDIUM_ERROR           0x03
608 #define SCSI_SENSE_HARDWARE_ERROR         0x04
609 #define SCSI_SENSE_ILLEGAL_REQUEST        0x05
610 #define SCSI_SENSE_UNIT_ATTENTION         0x06
611 #define SCSI_SENSE_DATA_PROTECT           0x07
612 #define SCSI_SENSE_BLANK_CHECK            0x08
613 #define SCSI_SENSE_UNIQUE                 0x09
614 #define SCSI_SENSE_COPY_ABORTED           0x0A
615 #define SCSI_SENSE_ABORTED_COMMAND        0x0B
616 #define SCSI_SENSE_EQUAL                  0x0C
617 #define SCSI_SENSE_VOL_OVERFLOW           0x0D
618 #define SCSI_SENSE_MISCOMPARE             0x0E
619 #define SCSI_SENSE_RESERVED               0x0F
620 
621 // Sense Error Codes
622 
623 #define SCSI_SENSE_ERRORCODE_FIXED_CURRENT        0x70
624 #define SCSI_SENSE_ERRORCODE_FIXED_DEFERRED       0x71
625 #define SCSI_SENSE_ERRORCODE_DESCRIPTOR_CURRENT   0x72
626 #define SCSI_SENSE_ERRORCODE_DESCRIPTOR_DEFERRED  0x73
627 
628 // Sense Descriptor Types
629 
630 #define SCSI_SENSE_DESCRIPTOR_TYPE_INFORMATION                  0x00
631 #define SCSI_SENSE_DESCRIPTOR_TYPE_COMMAND_SPECIFIC             0x01
632 #define SCSI_SENSE_DESCRIPTOR_TYPE_SENSE_KEY_SPECIFIC           0x02
633 #define SCSI_SENSE_DESCRIPTOR_TYPE_FIELD_REPLACEABLE_UNIT       0x03
634 #define SCSI_SENSE_DESCRIPTOR_TYPE_STREAM_COMMAND               0x04
635 #define SCSI_SENSE_DESCRIPTOR_TYPE_BLOCK_COMMAND                0x05
636 #define SCSI_SENSE_DESCRIPTOR_TYPE_OSD_OBJECT_IDENTIFICATION    0x06
637 #define SCSI_SENSE_DESCRIPTOR_TYPE_OSD_RESPONSE_INTEGRITY_CHECK 0x07
638 #define SCSI_SENSE_DESCRIPTOR_TYPE_OSD_ATTRIBUTE_IDENTIFICATION 0x08
639 #define SCSI_SENSE_DESCRIPTOR_TYPE_ATA_STATUS_RETURN            0x09
640 #define SCSI_SENSE_DESCRIPTOR_TYPE_PROGRESS_INDICATION          0x0A
641 #define SCSI_SENSE_DESCRIPTOR_TYPE_USER_DATA_SEGMENT_REFERRAL   0x0B
642 
643 /* Additional tape bit */
644 #define SCSI_ILLEGAL_LENGTH               0x20
645 #define SCSI_EOM                          0x40
646 #define SCSI_FILE_MARK                    0x80
647 
648 /* Additional Sense codes */
649 #define SCSI_ADSENSE_NO_SENSE                              0x00
650 #define SCSI_ADSENSE_NO_SEEK_COMPLETE                      0x02
651 #define SCSI_ADSENSE_WRITE                                 0x03
652 #define SCSI_ADSENSE_LUN_NOT_READY                         0x04
653 #define SCSI_ADSENSE_LUN_COMMUNICATION                     0x08
654 #define SCSI_ADSENSE_SERVO_ERROR                           0x09
655 #define SCSI_ADSENSE_WARNING                               0x0B
656 #define SCSI_ADSENSE_WRITE_ERROR                           0x0C
657 #define SCSI_ADSENSE_COPY_TARGET_DEVICE_ERROR              0x0D
658 #define SCSI_ADSENSE_UNRECOVERED_ERROR                     0x11
659 #define SCSI_ADSENSE_TRACK_ERROR                           0x14
660 #define SCSI_ADSENSE_SEEK_ERROR                            0x15
661 #define SCSI_ADSENSE_REC_DATA_NOECC                        0x17
662 #define SCSI_ADSENSE_REC_DATA_ECC                          0x18
663 #define SCSI_ADSENSE_DEFECT_LIST_ERROR                     0x19
664 #define SCSI_ADSENSE_PARAMETER_LIST_LENGTH                 0x1A
665 #define SCSI_ADSENSE_MISCOMPARE_DURING_VERIFY_OPERATION    0x1D
666 #define SCSI_ADSENSE_ILLEGAL_COMMAND                       0x20
667 #define SCSI_ADSENSE_ACCESS_DENIED                         0x20
668 #define SCSI_ADSENSE_ILLEGAL_BLOCK                         0x21
669 #define SCSI_ADSENSE_INVALID_TOKEN                         0x23
670 #define SCSI_ADSENSE_INVALID_CDB                           0x24
671 #define SCSI_ADSENSE_INVALID_LUN                           0x25
672 #define SCSI_ADSENSE_INVALID_FIELD_PARAMETER_LIST          0x26
673 #define SCSI_ADSENSE_WRITE_PROTECT                         0x27
674 #define SCSI_ADSENSE_MEDIUM_CHANGED                        0x28
675 #define SCSI_ADSENSE_BUS_RESET                             0x29
676 #define SCSI_ADSENSE_PARAMETERS_CHANGED                    0x2A
677 #define SCSI_ADSENSE_INSUFFICIENT_TIME_FOR_OPERATION       0x2E
678 #define SCSI_ADSENSE_INVALID_MEDIA                         0x30
679 #define SCSI_ADSENSE_DEFECT_LIST                           0x32
680 #define SCSI_ADSENSE_LB_PROVISIONING                       0x38
681 #define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE                    0x3a
682 #define SCSI_ADSENSE_POSITION_ERROR                        0x3b
683 #define SCSI_ADSENSE_LOGICAL_UNIT_ERROR                    0x3e
684 #define SCSI_ADSENSE_OPERATING_CONDITIONS_CHANGED          0x3f
685 #define SCSI_ADSENSE_DATA_PATH_FAILURE                     0x41
686 #define SCSI_ADSENSE_POWER_ON_SELF_TEST_FAILURE            0x42
687 #define SCSI_ADSENSE_INTERNAL_TARGET_FAILURE               0x44
688 #define SCSI_ADSENSE_DATA_TRANSFER_ERROR                   0x4b
689 #define SCSI_ADSENSE_LUN_FAILED_SELF_CONFIGURATION         0x4c
690 #define SCSI_ADSENSE_RESOURCE_FAILURE                      0x55
691 #define SCSI_ADSENSE_OPERATOR_REQUEST                      0x5a
692 #define SCSI_ADSENSE_FAILURE_PREDICTION_THRESHOLD_EXCEEDED 0x5d
693 #define SCSI_ADSENSE_ILLEGAL_MODE_FOR_THIS_TRACK           0x64
694 #define SCSI_ADSENSE_COPY_PROTECTION_FAILURE               0x6f
695 #define SCSI_ADSENSE_POWER_CALIBRATION_ERROR               0x73
696 #define SCSI_ADSENSE_VENDOR_UNIQUE                         0x80
697 #define SCSI_ADSENSE_MUSIC_AREA                            0xA0
698 #define SCSI_ADSENSE_DATA_AREA                             0xA1
699 #define SCSI_ADSENSE_VOLUME_OVERFLOW                       0xA7
700 
701 #define SCSI_ADWRITE_PROTECT                        SCSI_ADSENSE_WRITE_PROTECT
702 #define SCSI_FAILURE_PREDICTION_THRESHOLD_EXCEEDED  SCSI_ADSENSE_FAILURE_PREDICTION_THRESHOLD_EXCEEDED
703 
704 // ADSENSE additional qualifiers
705 
706 // SCSI_ADSENSE_NO_SENSE (0x00)
707 
708 #define SCSI_SENSEQ_FILEMARK_DETECTED            0x01
709 #define SCSI_SENSEQ_END_OF_MEDIA_DETECTED        0x02
710 #define SCSI_SENSEQ_SETMARK_DETECTED             0x03
711 #define SCSI_SENSEQ_BEGINNING_OF_MEDIA_DETECTED  0x04
712 #define SCSI_SENSEQ_OPERATION_IS_IN_PROGRESS     0x16
713 
714 // SCSI_ADSENSE_WRITE (0x03)
715 
716 #define SCSI_SENSEQ_PERIPHERAL_DEVICE_WRITE_FAULT   0x00
717 #define SCSI_SENSEQ_NO_WRITE_CURRENT                0x01
718 #define SCSI_SENSEQ_EXCESSIVE_WRITE_ERRORS          0x02
719 
720 // SCSI_ADSENSE_LUN_NOT_READY (0x04)
721 
722 #define SCSI_SENSEQ_CAUSE_NOT_REPORTABLE         0x00
723 #define SCSI_SENSEQ_BECOMING_READY               0x01
724 #define SCSI_SENSEQ_INIT_COMMAND_REQUIRED        0x02
725 #define SCSI_SENSEQ_MANUAL_INTERVENTION_REQUIRED 0x03
726 #define SCSI_SENSEQ_FORMAT_IN_PROGRESS           0x04
727 #define SCSI_SENSEQ_REBUILD_IN_PROGRESS          0x05
728 #define SCSI_SENSEQ_RECALCULATION_IN_PROGRESS    0x06
729 #define SCSI_SENSEQ_OPERATION_IN_PROGRESS        0x07
730 #define SCSI_SENSEQ_LONG_WRITE_IN_PROGRESS       0x08
731 #define SCSI_SENSEQ_SPACE_ALLOC_IN_PROGRESS      0x14
732 
733 // SCSI_ADSENSE_LUN_COMMUNICATION (0x08)
734 
735 #define SCSI_SENSEQ_COMM_FAILURE                 0x00
736 #define SCSI_SENSEQ_COMM_TIMEOUT                 0x01
737 #define SCSI_SENSEQ_COMM_PARITY_ERROR            0x02
738 #define SCSI_SESNEQ_COMM_CRC_ERROR               0x03
739 #define SCSI_SENSEQ_UNREACHABLE_TARGET           0x04
740 
741 // SCSI_ADSENSE_SERVO_ERROR (0x09)
742 
743 #define SCSI_SENSEQ_TRACK_FOLLOWING_ERROR   0x00
744 #define SCSI_SENSEQ_TRACKING_SERVO_FAILURE  0x01
745 #define SCSI_SENSEQ_FOCUS_SERVO_FAILURE     0x02
746 #define SCSI_SENSEQ_SPINDLE_SERVO_FAILURE   0x03
747 #define SCSI_SENSEQ_HEAD_SELECT_FAULT       0x04
748 
749 // SCSI_ADSENSE_WARNING (0x0B)
750 
751 #define SCSI_SENSEQ_POWER_LOSS_EXPECTED          0x08
752 
753 // SCSI_ADSENSE_WRITE_ERROR (0x0C)
754 
755 #define SCSI_SENSEQ_LOSS_OF_STREAMING            0x09
756 #define SCSI_SENSEQ_PADDING_BLOCKS_ADDED         0x0A
757 
758 // SCSI_ADSENSE_COPY_TARGET_DEVICE_ERROR (0x0D)
759 
760 #define SCSI_SENSEQ_NOT_REACHABLE                0x02
761 #define SCSI_SENSEQ_DATA_UNDERRUN                0x04
762 
763 // SCSI_ADSENSE_UNRECOVERED_ERROR (0x11)
764 
765 #define SCSI_SENSEQ_UNRECOVERED_READ_ERROR       0x00
766 
767 // SCSI_ADSENSE_SEEK_ERROR (0x15)
768 
769 #define SCSI_SENSEQ_RANDOM_POSITIONING_ERROR                        0x00
770 #define SCSI_SENSEQ_MECHANICAL_POSITIONING_ERROR                    0x01
771 #define SCSI_SENSEQ_POSITIONING_ERROR_DETECTED_BY_READ_OF_MEDIUM    0x02
772 
773 // SCSI_ADSENSE_DEFECT_LIST_ERROR (0x19)
774 
775 #define SCSI_SENSEQ_DEFECT_LIST_ERROR                  0x00
776 #define SCSI_SENSEQ_DEFECT_LIST_NOT_AVAILABLE          0x01
777 #define SCSI_SENSEQ_DEFECT_LIST_ERROR_IN_PRIMARY_LIST  0x02
778 #define SCSI_SENSEQ_DEFECT_LIST_ERROR_IN_GROWN_LIST    0x03
779 
780 // SCSI_ADSENSE_ACCESS_DENIED (0x20)
781 
782 #define SCSI_SENSEQ_NO_ACCESS_RIGHTS             0x02
783 
784 // SCSI_ADSENSE_ILLEGAL_BLOCK (0x21)
785 
786 #define SCSI_SENSEQ_LOGICAL_ADDRESS_OUT_OF_RANGE 0x00
787 #define SCSI_SENSEQ_ILLEGAL_ELEMENT_ADDR         0x01
788 #define SCSI_SENSEQ_INVALID_WRITE_ADDRESS        0x02
789 #define SCSI_SENSEQ_INVALID_WRITE_CROSSING_LAYER_JUMP 0x03
790 #define SCSI_SENSEQ_UNALIGNED_WRITE              0x04
791 #define SCSI_SENSEQ_WRITE_BOUNDARY_VIOLATION     0x05
792 #define SCSI_SENSEQ_READ_INVALID_DATA            0x06
793 #define SCSI_SENSEQ_READ_BOUNDARY_VIOLATION      0x07
794 #define SCSI_SENSEQ_MISALIGNED_WRITE             0x08
795 
796 // SCSI_ADSENSE_INVALID_FIELD_PARAMETER_LIST (0x26)
797 
798 #define SCSI_SENSEQ_INVALID_RELEASE_OF_PERSISTENT_RESERVATION 0x04
799 #define SCSI_SENSEQ_TOO_MANY_SEGMENT_DESCRIPTORS 0x08
800 
801 // SCSI_ADSENSE_WRITE_PROTECT (0x27)
802 
803 #define SCSI_SENSEQ_SPACE_ALLOC_FAILED_WRITE_PROTECT 0x07
804 
805 // SCSI_ADSENSE_PARAMETERS_CHANGED (0x2A)
806 
807 #define SCSI_SENSEQ_CAPACITY_DATA_CHANGED        0x09
808 
809 // SCSI_ADSENSE_POSITION_ERROR (0x3b)
810 
811 #define SCSI_SENSEQ_DESTINATION_FULL             0x0d
812 #define SCSI_SENSEQ_SOURCE_EMPTY                 0x0e
813 
814 // SCSI_ADSENSE_INVALID_MEDIA (0x30)
815 
816 #define SCSI_SENSEQ_INCOMPATIBLE_MEDIA_INSTALLED 0x00
817 #define SCSI_SENSEQ_UNKNOWN_FORMAT 0x01
818 #define SCSI_SENSEQ_INCOMPATIBLE_FORMAT 0x02
819 #define SCSI_SENSEQ_CLEANING_CARTRIDGE_INSTALLED 0x03
820 
821 // SCSI_ADSENSE_DEFECT_LIST (0x32)
822 
823 #define SCSI_SENSEQ_NO_DEFECT_SPARE_LOCATION_AVAILABLE  0x00
824 #define SCSI_SENSEQ_DEFECT_LIST_UPDATE_FAILURE          0x01
825 
826 // SCSI_ADSENSE_LB_PROVISIONING (0x38)
827 
828 #define SCSI_SENSEQ_SOFT_THRESHOLD_REACHED 0x07
829 
830 // SCSI_ADSENSE_LOGICAL_UNIT_ERROR (0x3e)
831 
832 #define SCSI_SENSEQ_LOGICAL_UNIT_HAS_NOT_SELF_CONFIGURED_YET    0x00
833 #define SCSI_SENSEQ_LOGICAL_UNIT_FAILURE                        0x01
834 #define SCSI_SENSEQ_TIMEOUT_ON_LOGICAL_UNIT                     0x02
835 #define SCSI_SENSEQ_LOGICAL_UNIT_FAILED_SELF_TEST               0x03
836 #define SCSI_SENSEQ_LOGICAL_UNIT_FAILED_TO_UPDATE_SELF_TEST_LOG 0x04
837 
838 // SCSI_ADSENSE_OPERATING_CONDITIONS_CHANGED (0x3f)
839 
840 #define SCSI_SENSEQ_TARGET_OPERATING_CONDITIONS_CHANGED 0x00
841 #define SCSI_SENSEQ_MICROCODE_CHANGED                   0x01
842 #define SCSI_SENSEQ_OPERATING_DEFINITION_CHANGED        0x02
843 #define SCSI_SENSEQ_INQUIRY_DATA_CHANGED                0x03
844 #define SCSI_SENSEQ_COMPONENT_DEVICE_ATTACHED           0x04
845 #define SCSI_SENSEQ_DEVICE_IDENTIFIER_CHANGED           0x05
846 #define SCSI_SENSEQ_REDUNDANCY_GROUP_MODIFIED           0x06
847 #define SCSI_SENSEQ_REDUNDANCY_GROUP_DELETED            0x07
848 #define SCSI_SENSEQ_SPARE_MODIFIED                      0x08
849 #define SCSI_SENSEQ_SPARE_DELETED                       0x09
850 #define SCSI_SENSEQ_VOLUME_SET_MODIFIED                 0x0A
851 #define SCSI_SENSEQ_VOLUME_SET_DELETED                  0x0B
852 #define SCSI_SENSEQ_VOLUME_SET_DEASSIGNED               0x0C
853 #define SCSI_SENSEQ_VOLUME_SET_REASSIGNED               0x0D
854 #define SCSI_SENSEQ_REPORTED_LUNS_DATA_CHANGED          0x0E
855 #define SCSI_SENSEQ_ECHO_BUFFER_OVERWRITTEN             0x0F
856 #define SCSI_SENSEQ_MEDIUM_LOADABLE                     0x10
857 #define SCSI_SENSEQ_MEDIUM_AUXILIARY_MEMORY_ACCESSIBLE  0x11
858 
859 // SCSI_ADSENSE_INTERNAL_TARGET_FAILURE (0x44)
860 
861 #define SCSI_SENSEQ_INTERNAL_TARGET_FAILURE                 0x00
862 #define SCSI_SENSEQ_PRESISTENT_RESERVATION_INFORMATION_LOST 0x01
863 #define SCSI_SENSEQ_ATA_DEVICE_FAILED_SET_FEATURES          0x71
864 
865 // SCSI_ADSENSE_DATA_TRANSFER_ERROR (0x4b)
866 
867 #define SCSI_SENSEQ_INITIATOR_RESPONSE_TIMEOUT          0x06
868 
869 // SCSI_ADSENSE_RESOURCE_FAILURE (0x55)
870 
871 #define SCSI_SENSEQ_SYSTEM_RESOURCE_FAILURE             0x00
872 #define SCSI_SENSEQ_SYSTEM_BUFFER_FULL                  0x01
873 #define SCSI_SENSEQ_INSUFFICIENT_RESERVATION_RESOURCES  0x02
874 #define SCSI_SENSEQ_INSUFFICIENT_RESOURCES              0x03
875 
876 // SCSI_ADSENSE_OPERATOR_REQUEST (0x5a)
877 
878 #define SCSI_SENSEQ_STATE_CHANGE_INPUT                  0x00
879 #define SCSI_SENSEQ_MEDIUM_REMOVAL                      0x01
880 #define SCSI_SENSEQ_WRITE_PROTECT_ENABLE                0x02
881 #define SCSI_SENSEQ_WRITE_PROTECT_DISABLE               0x03
882 
883 // SCSI_ADSENSE_FAILURE_PREDICTION_THRESHOLD_EXCEEDED (0x5d)
884 
885 #define SCSI_SENSEQ_FAILURE_PREDICTION_THRESHOLD_EXCEEDED               0x00
886 #define SCSI_SENSEQ_MEDIA_FAILURE_PREDICTION_THRESHOLD_EXCEEDED         0x01
887 #define SCSI_SENSEQ_LUN_FAILURE_PREDICTION_THRESHOLD_EXCEEDED           0x02
888 #define SCSI_SENSEQ_SPARE_AREA_EXHAUSTION_PREDICTION_THRESHOLD_EXCEEDED 0x03
889 #define SCSI_SENSEQ_GENERAL_HARD_DRIVE_FAILURE                          0x10
890 #define SCSI_SENSEQ_DRIVE_ERROR_RATE_TOO_HIGH                           0x11
891 #define SCSI_SENSEQ_DATA_ERROR_RATE_TOO_HIGH                            0x12
892 #define SCSI_SENSEQ_SEEK_ERROR_RATE_TOO_HIGH                            0x13
893 #define SCSI_SENSEQ_TOO_MANY_BLOCK_REASSIGNS                            0x14
894 #define SCSI_SENSEQ_ACCESS_TIMES_TOO_HIGH                               0x15
895 #define SCSI_SENSEQ_START_UNIT_TIMES_TOO_HIGH                           0x16
896 #define SCSI_SENSEQ_CHANNEL_PARAMETRICS                                 0x17
897 #define SCSI_SENSEQ_CONTROLLER_DETECTED                                 0x18
898 #define SCSI_SENSEQ_THROUGHPUT_PERFORMANCE                              0x19
899 #define SCSI_SENSEQ_SEEK_TIME_PERFORMANCE                               0x1A
900 #define SCSI_SENSEQ_SPIN_UP_RETRY_COUNT                                 0x1B
901 #define SCSI_SENSEQ_DRIVE_CALIBRATION_RETRY_COUNT                       0x1C
902 #define SCSI_SENSEQ_DATA_CHANNEL_DATA_ERROR_RATE_TOO_HIGH               0x32
903 #define SCSI_SENSEQ_SERVO_DATA_ERROR_RATE_TOO_HIGH                      0x42
904 #define SCSI_SENSEQ_SERVER_SEEK_ERROR_RATE_TOO_HIGH                     0x43
905 #define SCSI_SENSEQ_FAILURE_PREDICTION_THRESHOLD_EXCEEDED_FALSE         0xFF
906 
907 // SCSI_ADSENSE_COPY_PROTECTION_FAILURE (0x6f)
908 
909 #define SCSI_SENSEQ_AUTHENTICATION_FAILURE                          0x00
910 #define SCSI_SENSEQ_KEY_NOT_PRESENT                                 0x01
911 #define SCSI_SENSEQ_KEY_NOT_ESTABLISHED                             0x02
912 #define SCSI_SENSEQ_READ_OF_SCRAMBLED_SECTOR_WITHOUT_AUTHENTICATION 0x03
913 #define SCSI_SENSEQ_MEDIA_CODE_MISMATCHED_TO_LOGICAL_UNIT           0x04
914 #define SCSI_SENSEQ_LOGICAL_UNIT_RESET_COUNT_ERROR                  0x05
915 
916 // SCSI_ADSENSE_POWER_CALIBRATION_ERROR (0x73)
917 
918 #define SCSI_SENSEQ_POWER_CALIBRATION_AREA_ALMOST_FULL  0x01
919 #define SCSI_SENSEQ_POWER_CALIBRATION_AREA_FULL         0x02
920 #define SCSI_SENSEQ_POWER_CALIBRATION_AREA_ERROR        0x03
921 #define SCSI_SENSEQ_PMA_RMA_UPDATE_FAILURE              0x04
922 #define SCSI_SENSEQ_PMA_RMA_IS_FULL                     0x05
923 #define SCSI_SENSEQ_PMA_RMA_ALMOST_FULL                 0x06
924 
925 #define FILE_DEVICE_SCSI 0x0000001b
926 
927 #define IOCTL_SCSI_EXECUTE_IN ((FILE_DEVICE_SCSI << 16) + 0x0011)
928 #define IOCTL_SCSI_EXECUTE_OUT ((FILE_DEVICE_SCSI << 16) + 0x0012)
929 #define IOCTL_SCSI_EXECUTE_NONE ((FILE_DEVICE_SCSI << 16) + 0x0013)
930 
931 /* SMART support in ATAPI */
932 #define IOCTL_SCSI_MINIPORT_SMART_VERSION               ((FILE_DEVICE_SCSI << 16) + 0x0500)
933 #define IOCTL_SCSI_MINIPORT_IDENTIFY                    ((FILE_DEVICE_SCSI << 16) + 0x0501)
934 #define IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS          ((FILE_DEVICE_SCSI << 16) + 0x0502)
935 #define IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS       ((FILE_DEVICE_SCSI << 16) + 0x0503)
936 #define IOCTL_SCSI_MINIPORT_ENABLE_SMART                ((FILE_DEVICE_SCSI << 16) + 0x0504)
937 #define IOCTL_SCSI_MINIPORT_DISABLE_SMART               ((FILE_DEVICE_SCSI << 16) + 0x0505)
938 #define IOCTL_SCSI_MINIPORT_RETURN_STATUS               ((FILE_DEVICE_SCSI << 16) + 0x0506)
939 #define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE     ((FILE_DEVICE_SCSI << 16) + 0x0507)
940 #define IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES       ((FILE_DEVICE_SCSI << 16) + 0x0508)
941 #define IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS       ((FILE_DEVICE_SCSI << 16) + 0x0509)
942 #define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTO_OFFLINE ((FILE_DEVICE_SCSI << 16) + 0x050a)
943 #define IOCTL_SCSI_MINIPORT_READ_SMART_LOG              ((FILE_DEVICE_SCSI << 16) + 0x050b)
944 #define IOCTL_SCSI_MINIPORT_WRITE_SMART_LOG             ((FILE_DEVICE_SCSI << 16) + 0x050c)
945 
946 /* CLUSTER support */
947 #define IOCTL_SCSI_MINIPORT_NOT_QUORUM_CAPABLE ((FILE_DEVICE_SCSI << 16) + 0x0520)
948 #define IOCTL_SCSI_MINIPORT_NOT_CLUSTER_CAPABLE ((FILE_DEVICE_SCSI << 16) + 0x0521)
949 
950 #define MODE_FD_SINGLE_SIDE               0x01
951 #define MODE_FD_DOUBLE_SIDE               0x02
952 #define MODE_FD_MAXIMUM_TYPE              0x1E
953 #define MODE_DSP_FUA_SUPPORTED            0x10
954 #define MODE_DSP_WRITE_PROTECT            0x80
955 
956 #define CDDA_CHANNEL_MUTED      0x0
957 #define CDDA_CHANNEL_ZERO       0x1
958 #define CDDA_CHANNEL_ONE        0x2
959 #define CDDA_CHANNEL_TWO        0x4
960 #define CDDA_CHANNEL_THREE      0x8
961 
962 #define CDVD_LMT_CADDY              0
963 #define CDVD_LMT_TRAY               1
964 #define CDVD_LMT_POPUP              2
965 #define CDVD_LMT_RESERVED1          3
966 #define CDVD_LMT_CHANGER_INDIVIDUAL 4
967 #define CDVD_LMT_CHANGER_CARTRIDGE  5
968 #define CDVD_LMT_RESERVED2          6
969 #define CDVD_LMT_RESERVED3          7
970 
971 #define LOADING_MECHANISM_CADDY                 0x00
972 #define LOADING_MECHANISM_TRAY                  0x01
973 #define LOADING_MECHANISM_POPUP                 0x02
974 #define LOADING_MECHANISM_INDIVIDUAL_CHANGER    0x04
975 #define LOADING_MECHANISM_CARTRIDGE_CHANGER     0x05
976 
977 #define MODE_BLOCK_DESC_LENGTH        8
978 #define MODE_HEADER_LENGTH            4
979 #define MODE_HEADER_LENGTH10          8
980 
981 /* CDROM audio control */
982 #define CDB_AUDIO_PAUSE                   0x00
983 #define CDB_AUDIO_RESUME                  0x01
984 #define CDB_DEVICE_START                  0x11
985 #define CDB_DEVICE_STOP                   0x10
986 #define CDB_EJECT_MEDIA                   0x10
987 #define CDB_LOAD_MEDIA                    0x01
988 #define CDB_SUBCHANNEL_HEADER             0x00
989 #define CDB_SUBCHANNEL_BLOCK              0x01
990 
991 #define CDROM_AUDIO_CONTROL_PAGE          0x0E
992 #define MODE_SELECT_IMMEDIATE             0x04
993 #define MODE_SELECT_PFBIT                 0x10
994 
995 #define CDB_USE_MSF                       0x01
996 
997 /* Multisession CDROMs */
998 #define GET_LAST_SESSION 0x01
999 #define GET_SESSION_DATA 0x02
1000 
1001 typedef union _CDB {
1002   struct _CDB6GENERIC {
1003     UCHAR OperationCode;
1004     UCHAR Immediate:1;
1005     UCHAR CommandUniqueBits:4;
1006     UCHAR LogicalUnitNumber:3;
1007     UCHAR CommandUniqueBytes[3];
1008     UCHAR Link:1;
1009     UCHAR Flag:1;
1010     UCHAR Reserved:4;
1011     UCHAR VendorUnique:2;
1012   } CDB6GENERIC, *PCDB6GENERIC;
1013   struct _CDB6READWRITE {
1014     UCHAR OperationCode;
1015     UCHAR LogicalBlockMsb1:5;
1016     UCHAR LogicalUnitNumber:3;
1017     UCHAR LogicalBlockMsb0;
1018     UCHAR LogicalBlockLsb;
1019     UCHAR TransferBlocks;
1020     UCHAR Control;
1021   } CDB6READWRITE, *PCDB6READWRITE;
1022   struct _CDB6INQUIRY {
1023     UCHAR OperationCode;
1024     UCHAR Reserved1:5;
1025     UCHAR LogicalUnitNumber:3;
1026     UCHAR PageCode;
1027     UCHAR IReserved;
1028     UCHAR AllocationLength;
1029     UCHAR Control;
1030   } CDB6INQUIRY, *PCDB6INQUIRY;
1031   struct _CDB6INQUIRY3 {
1032     UCHAR OperationCode;
1033     UCHAR EnableVitalProductData:1;
1034     UCHAR CommandSupportData:1;
1035     UCHAR Reserved1:6;
1036     UCHAR PageCode;
1037     UCHAR Reserved2;
1038     UCHAR AllocationLength;
1039     UCHAR Control;
1040   } CDB6INQUIRY3, *PCDB6INQUIRY3;
1041   struct _CDB6VERIFY {
1042     UCHAR OperationCode;
1043     UCHAR Fixed:1;
1044     UCHAR ByteCompare:1;
1045     UCHAR Immediate:1;
1046     UCHAR Reserved:2;
1047     UCHAR LogicalUnitNumber:3;
1048     UCHAR VerificationLength[3];
1049     UCHAR Control;
1050   } CDB6VERIFY, *PCDB6VERIFY;
1051   struct _CDB6FORMAT {
1052     UCHAR OperationCode;
1053     UCHAR FormatControl:5;
1054     UCHAR LogicalUnitNumber:3;
1055     UCHAR FReserved1;
1056     UCHAR InterleaveMsb;
1057     UCHAR InterleaveLsb;
1058     UCHAR FReserved2;
1059   } CDB6FORMAT, *PCDB6FORMAT;
1060   struct _CDB10 {
1061     UCHAR OperationCode;
1062     UCHAR RelativeAddress:1;
1063     UCHAR Reserved1:2;
1064     UCHAR ForceUnitAccess:1;
1065     UCHAR DisablePageOut:1;
1066     UCHAR LogicalUnitNumber:3;
1067     UCHAR LogicalBlockByte0;
1068     UCHAR LogicalBlockByte1;
1069     UCHAR LogicalBlockByte2;
1070     UCHAR LogicalBlockByte3;
1071     UCHAR Reserved2;
1072     UCHAR TransferBlocksMsb;
1073     UCHAR TransferBlocksLsb;
1074     UCHAR Control;
1075   } CDB10, *PCDB10;
1076   struct _CDB12 {
1077     UCHAR OperationCode;
1078     UCHAR RelativeAddress:1;
1079     UCHAR Reserved1:2;
1080     UCHAR ForceUnitAccess:1;
1081     UCHAR DisablePageOut:1;
1082     UCHAR LogicalUnitNumber:3;
1083     UCHAR LogicalBlock[4];
1084     UCHAR TransferLength[4];
1085     UCHAR Reserved2;
1086     UCHAR Control;
1087   } CDB12, *PCDB12;
1088   struct _CDB16 {
1089      UCHAR OperationCode;
1090      UCHAR Reserved1:3;
1091      UCHAR ForceUnitAccess:1;
1092      UCHAR DisablePageOut:1;
1093      UCHAR Protection:3;
1094      UCHAR LogicalBlock[8];
1095      UCHAR TransferLength[4];
1096      UCHAR Reserved2;
1097      UCHAR Control;
1098   } CDB16, *PCDB16;
1099   struct _PAUSE_RESUME {
1100     UCHAR OperationCode;
1101     UCHAR Reserved1:5;
1102     UCHAR LogicalUnitNumber:3;
1103     UCHAR Reserved2[6];
1104     UCHAR Action;
1105     UCHAR Control;
1106   } PAUSE_RESUME, *PPAUSE_RESUME;
1107   struct _READ_TOC {
1108     UCHAR OperationCode;
1109     UCHAR Reserved0:1;
1110     UCHAR Msf:1;
1111     UCHAR Reserved1:3;
1112     UCHAR LogicalUnitNumber:3;
1113     UCHAR Format2:4;
1114     UCHAR Reserved2:4;
1115     UCHAR Reserved3[3];
1116     UCHAR StartingTrack;
1117     UCHAR AllocationLength[2];
1118     UCHAR Control:6;
1119     UCHAR Format:2;
1120   } READ_TOC, *PREAD_TOC;
1121   struct _READ_DISK_INFORMATION {
1122     UCHAR OperationCode;
1123     UCHAR Reserved1:5;
1124     UCHAR Lun:3;
1125     UCHAR Reserved2[5];
1126     UCHAR AllocationLength[2];
1127     UCHAR Control;
1128   } READ_DISK_INFORMATION, *PREAD_DISK_INFORMATION;
1129   struct _READ_TRACK_INFORMATION {
1130     UCHAR OperationCode;
1131     UCHAR Track:1;
1132     UCHAR Reserved1:3;
1133     UCHAR Reserved2:1;
1134     UCHAR Lun:3;
1135     UCHAR BlockAddress[4];
1136     UCHAR Reserved3;
1137     UCHAR AllocationLength[2];
1138     UCHAR Control;
1139   } READ_TRACK_INFORMATION, *PREAD_TRACK_INFORMATION;
1140   struct _RESERVE_TRACK_RZONE {
1141     UCHAR OperationCode;
1142     UCHAR Reserved1[4];
1143     UCHAR ReservationSize[4];
1144     UCHAR Control;
1145   } RESERVE_TRACK_RZONE, *PRESERVE_TRACK_RZONE;
1146   struct _SEND_OPC_INFORMATION {
1147     UCHAR OperationCode;
1148     UCHAR DoOpc:1;
1149     UCHAR Reserved1:7;
1150     UCHAR Exclude0:1;
1151     UCHAR Exclude1:1;
1152     UCHAR Reserved2:6;
1153     UCHAR Reserved3[4];
1154     UCHAR ParameterListLength[2];
1155     UCHAR Reserved4;
1156   } SEND_OPC_INFORMATION, *PSEND_OPC_INFORMATION;
1157   struct _REPAIR_TRACK {
1158     UCHAR OperationCode;
1159     UCHAR Immediate:1;
1160     UCHAR Reserved1:7;
1161     UCHAR Reserved2[2];
1162     UCHAR TrackNumber[2];
1163     UCHAR Reserved3[3];
1164     UCHAR Control;
1165   } REPAIR_TRACK, *PREPAIR_TRACK;
1166   struct _CLOSE_TRACK {
1167     UCHAR OperationCode;
1168     UCHAR Immediate:1;
1169     UCHAR Reserved1:7;
1170     UCHAR Track:1;
1171     UCHAR Session:1;
1172     UCHAR Reserved2:6;
1173     UCHAR Reserved3;
1174     UCHAR TrackNumber[2];
1175     UCHAR Reserved4[3];
1176     UCHAR Control;
1177   } CLOSE_TRACK, *PCLOSE_TRACK;
1178   struct _READ_BUFFER_CAPACITY {
1179     UCHAR OperationCode;
1180     UCHAR BlockInfo:1;
1181     UCHAR Reserved1:7;
1182     UCHAR Reserved2[5];
1183     UCHAR AllocationLength[2];
1184     UCHAR Control;
1185   } READ_BUFFER_CAPACITY, *PREAD_BUFFER_CAPACITY;
1186   struct _SEND_CUE_SHEET {
1187     UCHAR OperationCode;
1188     UCHAR Reserved[5];
1189     UCHAR CueSheetSize[3];
1190     UCHAR Control;
1191   } SEND_CUE_SHEET, *PSEND_CUE_SHEET;
1192   struct _READ_HEADER {
1193     UCHAR OperationCode;
1194     UCHAR Reserved1:1;
1195     UCHAR Msf:1;
1196     UCHAR Reserved2:3;
1197     UCHAR Lun:3;
1198     UCHAR LogicalBlockAddress[4];
1199     UCHAR Reserved3;
1200     UCHAR AllocationLength[2];
1201     UCHAR Control;
1202   } READ_HEADER, *PREAD_HEADER;
1203   struct _PLAY_AUDIO {
1204     UCHAR OperationCode;
1205     UCHAR Reserved1:5;
1206     UCHAR LogicalUnitNumber:3;
1207     UCHAR StartingBlockAddress[4];
1208     UCHAR Reserved2;
1209     UCHAR PlayLength[2];
1210     UCHAR Control;
1211   } PLAY_AUDIO, *PPLAY_AUDIO;
1212   struct _PLAY_AUDIO_MSF {
1213     UCHAR OperationCode;
1214     UCHAR Reserved1:5;
1215     UCHAR LogicalUnitNumber:3;
1216     UCHAR Reserved2;
1217     UCHAR StartingM;
1218     UCHAR StartingS;
1219     UCHAR StartingF;
1220     UCHAR EndingM;
1221     UCHAR EndingS;
1222     UCHAR EndingF;
1223     UCHAR Control;
1224   } PLAY_AUDIO_MSF, *PPLAY_AUDIO_MSF;
1225   struct _BLANK_MEDIA {
1226     UCHAR OperationCode;
1227     UCHAR BlankType:3;
1228     UCHAR Reserved1:1;
1229     UCHAR Immediate:1;
1230     UCHAR Reserved2:3;
1231     UCHAR AddressOrTrack[4];
1232     UCHAR Reserved3[5];
1233     UCHAR Control;
1234   } BLANK_MEDIA, *PBLANK_MEDIA;
1235   struct _PLAY_CD {
1236     UCHAR OperationCode;
1237     UCHAR Reserved1:1;
1238     UCHAR CMSF:1;
1239     UCHAR ExpectedSectorType:3;
1240     UCHAR Lun:3;
1241     _ANONYMOUS_UNION union {
1242       struct _LBA {
1243         UCHAR StartingBlockAddress[4];
1244         UCHAR PlayLength[4];
1245       } LBA;
1246       struct _MSF {
1247         UCHAR Reserved1;
1248         UCHAR StartingM;
1249         UCHAR StartingS;
1250         UCHAR StartingF;
1251         UCHAR EndingM;
1252         UCHAR EndingS;
1253         UCHAR EndingF;
1254         UCHAR Reserved2;
1255       } MSF;
1256     } DUMMYUNIONNAME;
1257     UCHAR Audio:1;
1258     UCHAR Composite:1;
1259     UCHAR Port1:1;
1260     UCHAR Port2:1;
1261     UCHAR Reserved2:3;
1262     UCHAR Speed:1;
1263     UCHAR Control;
1264   } PLAY_CD, *PPLAY_CD;
1265   struct _SCAN_CD {
1266     UCHAR OperationCode;
1267     UCHAR RelativeAddress:1;
1268     UCHAR Reserved1:3;
1269     UCHAR Direct:1;
1270     UCHAR Lun:3;
1271     UCHAR StartingAddress[4];
1272     UCHAR Reserved2[3];
1273     UCHAR Reserved3:6;
1274     UCHAR Type:2;
1275     UCHAR Reserved4;
1276     UCHAR Control;
1277   } SCAN_CD, *PSCAN_CD;
1278   struct _STOP_PLAY_SCAN {
1279     UCHAR OperationCode;
1280     UCHAR Reserved1:5;
1281     UCHAR Lun:3;
1282     UCHAR Reserved2[7];
1283     UCHAR Control;
1284   } STOP_PLAY_SCAN, *PSTOP_PLAY_SCAN;
1285   struct _SUBCHANNEL {
1286     UCHAR OperationCode;
1287     UCHAR Reserved0:1;
1288     UCHAR Msf:1;
1289     UCHAR Reserved1:3;
1290     UCHAR LogicalUnitNumber:3;
1291     UCHAR Reserved2:6;
1292     UCHAR SubQ:1;
1293     UCHAR Reserved3:1;
1294     UCHAR Format;
1295     UCHAR Reserved4[2];
1296     UCHAR TrackNumber;
1297     UCHAR AllocationLength[2];
1298     UCHAR Control;
1299   } SUBCHANNEL, *PSUBCHANNEL;
1300   struct _READ_CD {
1301     UCHAR OperationCode;
1302     UCHAR RelativeAddress:1;
1303     UCHAR Reserved0:1;
1304     UCHAR ExpectedSectorType:3;
1305     UCHAR Lun:3;
1306     UCHAR StartingLBA[4];
1307     UCHAR TransferBlocks[3];
1308     UCHAR Reserved2:1;
1309     UCHAR ErrorFlags:2;
1310     UCHAR IncludeEDC:1;
1311     UCHAR IncludeUserData:1;
1312     UCHAR HeaderCode:2;
1313     UCHAR IncludeSyncData:1;
1314     UCHAR SubChannelSelection:3;
1315     UCHAR Reserved3:5;
1316     UCHAR Control;
1317   } READ_CD, *PREAD_CD;
1318   struct _READ_CD_MSF {
1319     UCHAR OperationCode;
1320     UCHAR RelativeAddress:1;
1321     UCHAR Reserved1:1;
1322     UCHAR ExpectedSectorType:3;
1323     UCHAR Lun:3;
1324     UCHAR Reserved2;
1325     UCHAR StartingM;
1326     UCHAR StartingS;
1327     UCHAR StartingF;
1328     UCHAR EndingM;
1329     UCHAR EndingS;
1330     UCHAR EndingF;
1331     UCHAR Reserved3;
1332     UCHAR Reserved4:1;
1333     UCHAR ErrorFlags:2;
1334     UCHAR IncludeEDC:1;
1335     UCHAR IncludeUserData:1;
1336     UCHAR HeaderCode:2;
1337     UCHAR IncludeSyncData:1;
1338     UCHAR SubChannelSelection:3;
1339     UCHAR Reserved5:5;
1340     UCHAR Control;
1341   } READ_CD_MSF, *PREAD_CD_MSF;
1342   struct _PLXTR_READ_CDDA {
1343     UCHAR OperationCode;
1344     UCHAR Reserved0:5;
1345     UCHAR LogicalUnitNumber:3;
1346     UCHAR LogicalBlockByte0;
1347     UCHAR LogicalBlockByte1;
1348     UCHAR LogicalBlockByte2;
1349     UCHAR LogicalBlockByte3;
1350     UCHAR TransferBlockByte0;
1351     UCHAR TransferBlockByte1;
1352     UCHAR TransferBlockByte2;
1353     UCHAR TransferBlockByte3;
1354     UCHAR SubCode;
1355     UCHAR Control;
1356   } PLXTR_READ_CDDA, *PPLXTR_READ_CDDA;
1357   struct _NEC_READ_CDDA {
1358     UCHAR OperationCode;
1359     UCHAR Reserved0;
1360     UCHAR LogicalBlockByte0;
1361     UCHAR LogicalBlockByte1;
1362     UCHAR LogicalBlockByte2;
1363     UCHAR LogicalBlockByte3;
1364     UCHAR Reserved1;
1365     UCHAR TransferBlockByte0;
1366     UCHAR TransferBlockByte1;
1367     UCHAR Control;
1368   } NEC_READ_CDDA, *PNEC_READ_CDDA;
1369 #if (NTDDI_VERSION >= NTDDI_WIN8)
1370   struct _MODE_SENSE {
1371     UCHAR OperationCode;
1372     UCHAR Reserved1:3;
1373     UCHAR Dbd:1;
1374     UCHAR Reserved2:4;
1375     UCHAR PageCode:6;
1376     UCHAR Pc:2;
1377     UCHAR SubPageCode;
1378     UCHAR AllocationLength;
1379     UCHAR Control;
1380   } MODE_SENSE;
1381   struct _MODE_SENSE10 {
1382     UCHAR OperationCode;
1383     UCHAR Reserved1:3;
1384     UCHAR Dbd:1;
1385     UCHAR LongLBAAccepted:1;
1386     UCHAR Reserved2:3;
1387     UCHAR PageCode:6;
1388     UCHAR Pc:2;
1389     UCHAR SubPageCode;
1390     UCHAR Reserved3[3];
1391     UCHAR AllocationLength[2];
1392     UCHAR Control;
1393   } MODE_SENSE10;
1394 #else
1395   struct _MODE_SENSE {
1396     UCHAR OperationCode;
1397     UCHAR Reserved1:3;
1398     UCHAR Dbd:1;
1399     UCHAR Reserved2:1;
1400     UCHAR LogicalUnitNumber:3;
1401     UCHAR PageCode:6;
1402     UCHAR Pc:2;
1403     UCHAR Reserved3;
1404     UCHAR AllocationLength;
1405     UCHAR Control;
1406   } MODE_SENSE, *PMODE_SENSE;
1407   struct _MODE_SENSE10 {
1408     UCHAR OperationCode;
1409     UCHAR Reserved1:3;
1410     UCHAR Dbd:1;
1411     UCHAR Reserved2:1;
1412     UCHAR LogicalUnitNumber:3;
1413     UCHAR PageCode:6;
1414     UCHAR Pc:2;
1415     UCHAR Reserved3[4];
1416     UCHAR AllocationLength[2];
1417     UCHAR Control;
1418   } MODE_SENSE10, *PMODE_SENSE10;
1419 #endif
1420   struct _MODE_SELECT {
1421     UCHAR OperationCode;
1422     UCHAR SPBit:1;
1423     UCHAR Reserved1:3;
1424     UCHAR PFBit:1;
1425     UCHAR LogicalUnitNumber:3;
1426     UCHAR Reserved2[2];
1427     UCHAR ParameterListLength;
1428     UCHAR Control;
1429   } MODE_SELECT, *PMODE_SELECT;
1430   struct _MODE_SELECT10 {
1431     UCHAR OperationCode;
1432     UCHAR SPBit:1;
1433     UCHAR Reserved1:3;
1434     UCHAR PFBit:1;
1435     UCHAR LogicalUnitNumber:3;
1436     UCHAR Reserved2[5];
1437     UCHAR ParameterListLength[2];
1438     UCHAR Control;
1439   } MODE_SELECT10, *PMODE_SELECT10;
1440   struct _LOCATE {
1441     UCHAR OperationCode;
1442     UCHAR Immediate:1;
1443     UCHAR CPBit:1;
1444     UCHAR BTBit:1;
1445     UCHAR Reserved1:2;
1446     UCHAR LogicalUnitNumber:3;
1447     UCHAR Reserved3;
1448     UCHAR LogicalBlockAddress[4];
1449     UCHAR Reserved4;
1450     UCHAR Partition;
1451     UCHAR Control;
1452   } LOCATE, *PLOCATE;
1453   struct _LOGSENSE {
1454     UCHAR OperationCode;
1455     UCHAR SPBit:1;
1456     UCHAR PPCBit:1;
1457     UCHAR Reserved1:3;
1458     UCHAR LogicalUnitNumber:3;
1459     UCHAR PageCode:6;
1460     UCHAR PCBit:2;
1461     UCHAR Reserved2;
1462     UCHAR Reserved3;
1463     UCHAR ParameterPointer[2];
1464     UCHAR AllocationLength[2];
1465     UCHAR Control;
1466   } LOGSENSE, *PLOGSENSE;
1467   struct _LOGSELECT {
1468     UCHAR OperationCode;
1469     UCHAR SPBit:1;
1470     UCHAR PCRBit:1;
1471     UCHAR Reserved1:3;
1472     UCHAR LogicalUnitNumber:3;
1473     UCHAR Reserved:6;
1474     UCHAR PCBit:2;
1475     UCHAR Reserved2[4];
1476     UCHAR ParameterListLength[2];
1477     UCHAR Control;
1478   } LOGSELECT, *PLOGSELECT;
1479   struct _PRINT {
1480     UCHAR OperationCode;
1481     UCHAR Reserved:5;
1482     UCHAR LogicalUnitNumber:3;
1483     UCHAR TransferLength[3];
1484     UCHAR Control;
1485   } PRINT, *PPRINT;
1486   struct _SEEK {
1487     UCHAR OperationCode;
1488     UCHAR Reserved1:5;
1489     UCHAR LogicalUnitNumber:3;
1490     UCHAR LogicalBlockAddress[4];
1491     UCHAR Reserved2[3];
1492     UCHAR Control;
1493   } SEEK, *PSEEK;
1494   struct _ERASE {
1495     UCHAR OperationCode;
1496     UCHAR Long:1;
1497     UCHAR Immediate:1;
1498     UCHAR Reserved1:3;
1499     UCHAR LogicalUnitNumber:3;
1500     UCHAR Reserved2[3];
1501     UCHAR Control;
1502   } ERASE, *PERASE;
1503   struct _START_STOP {
1504     UCHAR OperationCode;
1505     UCHAR Immediate:1;
1506     UCHAR Reserved1:4;
1507     UCHAR LogicalUnitNumber:3;
1508     UCHAR Reserved2[2];
1509     UCHAR Start:1;
1510     UCHAR LoadEject:1;
1511     UCHAR Reserved3:6;
1512     UCHAR Control;
1513   } START_STOP, *PSTART_STOP;
1514   struct _MEDIA_REMOVAL {
1515     UCHAR OperationCode;
1516     UCHAR Reserved1:5;
1517     UCHAR LogicalUnitNumber:3;
1518     UCHAR Reserved2[2];
1519     UCHAR Prevent:1;
1520     UCHAR Persistant:1;
1521     UCHAR Reserved3:6;
1522     UCHAR Control;
1523   } MEDIA_REMOVAL, *PMEDIA_REMOVAL;
1524   struct _SEEK_BLOCK {
1525     UCHAR OperationCode;
1526     UCHAR Immediate:1;
1527     UCHAR Reserved1:7;
1528     UCHAR BlockAddress[3];
1529     UCHAR Link:1;
1530     UCHAR Flag:1;
1531     UCHAR Reserved2:4;
1532     UCHAR VendorUnique:2;
1533   } SEEK_BLOCK, *PSEEK_BLOCK;
1534   struct _REQUEST_BLOCK_ADDRESS {
1535     UCHAR OperationCode;
1536     UCHAR Reserved1[3];
1537     UCHAR AllocationLength;
1538     UCHAR Link:1;
1539     UCHAR Flag:1;
1540     UCHAR Reserved2:4;
1541     UCHAR VendorUnique:2;
1542   } REQUEST_BLOCK_ADDRESS, *PREQUEST_BLOCK_ADDRESS;
1543   struct _PARTITION {
1544     UCHAR OperationCode;
1545     UCHAR Immediate:1;
1546     UCHAR Sel:1;
1547     UCHAR PartitionSelect:6;
1548     UCHAR Reserved1[3];
1549     UCHAR Control;
1550   } PARTITION, *PPARTITION;
1551   struct _WRITE_TAPE_MARKS {
1552     UCHAR OperationCode;
1553     UCHAR Immediate:1;
1554     UCHAR WriteSetMarks:1;
1555     UCHAR Reserved:3;
1556     UCHAR LogicalUnitNumber:3;
1557     UCHAR TransferLength[3];
1558     UCHAR Control;
1559   } WRITE_TAPE_MARKS, *PWRITE_TAPE_MARKS;
1560   struct _SPACE_TAPE_MARKS {
1561     UCHAR OperationCode;
1562     UCHAR Code:3;
1563     UCHAR Reserved:2;
1564     UCHAR LogicalUnitNumber:3;
1565     UCHAR NumMarksMSB;
1566     UCHAR NumMarks;
1567     UCHAR NumMarksLSB;
1568   union {
1569     UCHAR value;
1570     struct {
1571       UCHAR Link:1;
1572       UCHAR Flag:1;
1573       UCHAR Reserved:4;
1574       UCHAR VendorUnique:2;
1575     } Fields;
1576   } Byte6;
1577   } SPACE_TAPE_MARKS, *PSPACE_TAPE_MARKS;
1578   struct _READ_POSITION {
1579     UCHAR Operation;
1580     UCHAR BlockType:1;
1581     UCHAR Reserved1:4;
1582     UCHAR Lun:3;
1583     UCHAR Reserved2[7];
1584     UCHAR Control;
1585   } READ_POSITION, *PREAD_POSITION;
1586   struct _CDB6READWRITETAPE {
1587     UCHAR OperationCode;
1588     UCHAR VendorSpecific:5;
1589     UCHAR Reserved:3;
1590     UCHAR TransferLenMSB;
1591     UCHAR TransferLen;
1592     UCHAR TransferLenLSB;
1593     UCHAR Link:1;
1594     UCHAR Flag:1;
1595     UCHAR Reserved1:4;
1596     UCHAR VendorUnique:2;
1597   } CDB6READWRITETAPE, *PCDB6READWRITETAPE;
1598   struct _INIT_ELEMENT_STATUS {
1599     UCHAR OperationCode;
1600     UCHAR Reserved1:5;
1601     UCHAR LogicalUnitNubmer:3;
1602     UCHAR Reserved2[3];
1603     UCHAR Reserved3:7;
1604     UCHAR NoBarCode:1;
1605   } INIT_ELEMENT_STATUS, *PINIT_ELEMENT_STATUS;
1606   struct _INITIALIZE_ELEMENT_RANGE {
1607     UCHAR OperationCode;
1608     UCHAR Range:1;
1609     UCHAR Reserved1:4;
1610     UCHAR LogicalUnitNubmer:3;
1611     UCHAR FirstElementAddress[2];
1612     UCHAR Reserved2[2];
1613     UCHAR NumberOfElements[2];
1614     UCHAR Reserved3;
1615     UCHAR Reserved4:7;
1616     UCHAR NoBarCode:1;
1617   } INITIALIZE_ELEMENT_RANGE, *PINITIALIZE_ELEMENT_RANGE;
1618   struct _POSITION_TO_ELEMENT {
1619     UCHAR OperationCode;
1620     UCHAR Reserved1:5;
1621     UCHAR LogicalUnitNumber:3;
1622     UCHAR TransportElementAddress[2];
1623     UCHAR DestinationElementAddress[2];
1624     UCHAR Reserved2[2];
1625     UCHAR Flip:1;
1626     UCHAR Reserved3:7;
1627     UCHAR Control;
1628   } POSITION_TO_ELEMENT, *PPOSITION_TO_ELEMENT;
1629   struct _MOVE_MEDIUM {
1630     UCHAR OperationCode;
1631     UCHAR Reserved1:5;
1632     UCHAR LogicalUnitNumber:3;
1633     UCHAR TransportElementAddress[2];
1634     UCHAR SourceElementAddress[2];
1635     UCHAR DestinationElementAddress[2];
1636     UCHAR Reserved2[2];
1637     UCHAR Flip:1;
1638     UCHAR Reserved3:7;
1639     UCHAR Control;
1640   } MOVE_MEDIUM, *PMOVE_MEDIUM;
1641   struct _EXCHANGE_MEDIUM {
1642     UCHAR OperationCode;
1643     UCHAR Reserved1:5;
1644     UCHAR LogicalUnitNumber:3;
1645     UCHAR TransportElementAddress[2];
1646     UCHAR SourceElementAddress[2];
1647     UCHAR Destination1ElementAddress[2];
1648     UCHAR Destination2ElementAddress[2];
1649     UCHAR Flip1:1;
1650     UCHAR Flip2:1;
1651     UCHAR Reserved3:6;
1652     UCHAR Control;
1653   } EXCHANGE_MEDIUM, *PEXCHANGE_MEDIUM;
1654   struct _READ_ELEMENT_STATUS {
1655     UCHAR OperationCode;
1656     UCHAR ElementType:4;
1657     UCHAR VolTag:1;
1658     UCHAR LogicalUnitNumber:3;
1659     UCHAR StartingElementAddress[2];
1660     UCHAR NumberOfElements[2];
1661     UCHAR Reserved1;
1662     UCHAR AllocationLength[3];
1663     UCHAR Reserved2;
1664     UCHAR Control;
1665   } READ_ELEMENT_STATUS, *PREAD_ELEMENT_STATUS;
1666   struct _SEND_VOLUME_TAG {
1667     UCHAR OperationCode;
1668     UCHAR ElementType:4;
1669     UCHAR Reserved1:1;
1670     UCHAR LogicalUnitNumber:3;
1671     UCHAR StartingElementAddress[2];
1672     UCHAR Reserved2;
1673     UCHAR ActionCode:5;
1674     UCHAR Reserved3:3;
1675     UCHAR Reserved4[2];
1676     UCHAR ParameterListLength[2];
1677     UCHAR Reserved5;
1678     UCHAR Control;
1679   } SEND_VOLUME_TAG, *PSEND_VOLUME_TAG;
1680   struct _REQUEST_VOLUME_ELEMENT_ADDRESS {
1681     UCHAR OperationCode;
1682     UCHAR ElementType:4;
1683     UCHAR VolTag:1;
1684     UCHAR LogicalUnitNumber:3;
1685     UCHAR StartingElementAddress[2];
1686     UCHAR NumberElements[2];
1687     UCHAR Reserved1;
1688     UCHAR AllocationLength[3];
1689     UCHAR Reserved2;
1690     UCHAR Control;
1691   } REQUEST_VOLUME_ELEMENT_ADDRESS, *PREQUEST_VOLUME_ELEMENT_ADDRESS;
1692   struct _LOAD_UNLOAD {
1693     UCHAR OperationCode;
1694     UCHAR Immediate:1;
1695     UCHAR Reserved1:4;
1696     UCHAR Lun:3;
1697     UCHAR Reserved2[2];
1698     UCHAR Start:1;
1699     UCHAR LoadEject:1;
1700     UCHAR Reserved3:6;
1701     UCHAR Reserved4[3];
1702     UCHAR Slot;
1703     UCHAR Reserved5[3];
1704   } LOAD_UNLOAD, *PLOAD_UNLOAD;
1705   struct _MECH_STATUS {
1706     UCHAR OperationCode;
1707     UCHAR Reserved:5;
1708     UCHAR Lun:3;
1709     UCHAR Reserved1[6];
1710     UCHAR AllocationLength[2];
1711     UCHAR Reserved2[1];
1712     UCHAR Control;
1713   } MECH_STATUS, *PMECH_STATUS;
1714   struct _SYNCHRONIZE_CACHE10 {
1715     UCHAR OperationCode;
1716     UCHAR RelAddr:1;
1717     UCHAR Immediate:1;
1718     UCHAR Reserved:3;
1719     UCHAR Lun:3;
1720     UCHAR LogicalBlockAddress[4];
1721     UCHAR Reserved2;
1722     UCHAR BlockCount[2];
1723     UCHAR Control;
1724   } SYNCHRONIZE_CACHE10, *PSYNCHRONIZE_CACHE10;
1725   struct _GET_EVENT_STATUS_NOTIFICATION {
1726     UCHAR OperationCode;
1727     UCHAR Immediate:1;
1728     UCHAR Reserved:4;
1729     UCHAR Lun:3;
1730     UCHAR Reserved2[2];
1731     UCHAR NotificationClassRequest;
1732     UCHAR Reserved3[2];
1733     UCHAR EventListLength[2];
1734     UCHAR Control;
1735   } GET_EVENT_STATUS_NOTIFICATION, *PGET_EVENT_STATUS_NOTIFICATION;
1736   struct _GET_PERFORMANCE {
1737     UCHAR OperationCode;
1738     UCHAR Except:2;
1739     UCHAR Write:1;
1740     UCHAR Tolerance:2;
1741     UCHAR Reserved0:3;
1742     UCHAR StartingLBA[4];
1743     UCHAR Reserved1[2];
1744     UCHAR MaximumNumberOfDescriptors[2];
1745     UCHAR Type;
1746     UCHAR Control;
1747   } GET_PERFORMANCE;
1748   struct _READ_DVD_STRUCTURE {
1749     UCHAR OperationCode;
1750     UCHAR Reserved1:5;
1751     UCHAR Lun:3;
1752     UCHAR RMDBlockNumber[4];
1753     UCHAR LayerNumber;
1754     UCHAR Format;
1755     UCHAR AllocationLength[2];
1756     UCHAR Reserved3:6;
1757     UCHAR AGID:2;
1758     UCHAR Control;
1759   } READ_DVD_STRUCTURE, *PREAD_DVD_STRUCTURE;
1760   struct _SET_STREAMING {
1761     UCHAR OperationCode;
1762     UCHAR Reserved[8];
1763     UCHAR ParameterListLength[2];
1764     UCHAR Control;
1765   } SET_STREAMING;
1766   struct _SEND_DVD_STRUCTURE {
1767     UCHAR OperationCode;
1768     UCHAR Reserved1:5;
1769     UCHAR Lun:3;
1770     UCHAR Reserved2[5];
1771     UCHAR Format;
1772     UCHAR ParameterListLength[2];
1773     UCHAR Reserved3;
1774     UCHAR Control;
1775   } SEND_DVD_STRUCTURE, *PSEND_DVD_STRUCTURE;
1776   struct _SEND_KEY {
1777     UCHAR OperationCode;
1778     UCHAR Reserved1:5;
1779     UCHAR Lun:3;
1780     UCHAR Reserved2[6];
1781     UCHAR ParameterListLength[2];
1782     UCHAR KeyFormat:6;
1783     UCHAR AGID:2;
1784     UCHAR Control;
1785   } SEND_KEY, *PSEND_KEY;
1786   struct _REPORT_KEY {
1787     UCHAR OperationCode;
1788     UCHAR Reserved1:5;
1789     UCHAR Lun:3;
1790     UCHAR LogicalBlockAddress[4];
1791     UCHAR Reserved2[2];
1792     UCHAR AllocationLength[2];
1793     UCHAR KeyFormat:6;
1794     UCHAR AGID:2;
1795     UCHAR Control;
1796   } REPORT_KEY, *PREPORT_KEY;
1797   struct _SET_READ_AHEAD {
1798     UCHAR OperationCode;
1799     UCHAR Reserved1:5;
1800     UCHAR Lun:3;
1801     UCHAR TriggerLBA[4];
1802     UCHAR ReadAheadLBA[4];
1803     UCHAR Reserved2;
1804     UCHAR Control;
1805   } SET_READ_AHEAD, *PSET_READ_AHEAD;
1806   struct _READ_FORMATTED_CAPACITIES {
1807     UCHAR OperationCode;
1808     UCHAR Reserved1:5;
1809     UCHAR Lun:3;
1810     UCHAR Reserved2[5];
1811     UCHAR AllocationLength[2];
1812     UCHAR Control;
1813   } READ_FORMATTED_CAPACITIES, *PREAD_FORMATTED_CAPACITIES;
1814   struct _REPORT_LUNS {
1815     UCHAR OperationCode;
1816     UCHAR Reserved1[5];
1817     UCHAR AllocationLength[4];
1818     UCHAR Reserved2[1];
1819     UCHAR Control;
1820   } REPORT_LUNS, *PREPORT_LUNS;
1821   struct _PERSISTENT_RESERVE_IN {
1822     UCHAR OperationCode;
1823     UCHAR ServiceAction:5;
1824     UCHAR Reserved1:3;
1825     UCHAR Reserved2[5];
1826     UCHAR AllocationLength[2];
1827     UCHAR Control;
1828   } PERSISTENT_RESERVE_IN, *PPERSISTENT_RESERVE_IN;
1829   struct _PERSISTENT_RESERVE_OUT {
1830     UCHAR OperationCode;
1831     UCHAR ServiceAction:5;
1832     UCHAR Reserved1:3;
1833     UCHAR Type:4;
1834     UCHAR Scope:4;
1835     UCHAR Reserved2[4];
1836     UCHAR ParameterListLength[2];
1837     UCHAR Control;
1838   } PERSISTENT_RESERVE_OUT, *PPERSISTENT_RESERVE_OUT;
1839   struct _GET_CONFIGURATION {
1840     UCHAR OperationCode;
1841     UCHAR RequestType:1;
1842     UCHAR Reserved1:7;
1843     UCHAR StartingFeature[2];
1844     UCHAR Reserved2[3];
1845     UCHAR AllocationLength[2];
1846     UCHAR Control;
1847   } GET_CONFIGURATION, *PGET_CONFIGURATION;
1848   struct _SET_CD_SPEED {
1849     UCHAR OperationCode;
1850     _ANONYMOUS_UNION union {
1851       UCHAR Reserved1;
1852       _ANONYMOUS_STRUCT struct {
1853         UCHAR RotationControl:2;
1854         UCHAR Reserved3:6;
1855       } DUMMYSTRUCTNAME;
1856     } DUMMYUNIONNAME;
1857     UCHAR ReadSpeed[2];
1858     UCHAR WriteSpeed[2];
1859     UCHAR Reserved2[5];
1860     UCHAR Control;
1861   } SET_CD_SPEED, *PSET_CD_SPEED;
1862   struct _READ12 {
1863     UCHAR OperationCode;
1864     UCHAR RelativeAddress:1;
1865     UCHAR Reserved1:2;
1866     UCHAR ForceUnitAccess:1;
1867     UCHAR DisablePageOut:1;
1868     UCHAR LogicalUnitNumber:3;
1869     UCHAR LogicalBlock[4];
1870     UCHAR TransferLength[4];
1871     UCHAR Reserved2:7;
1872     UCHAR Streaming:1;
1873     UCHAR Control;
1874   } READ12;
1875   struct _WRITE12 {
1876     UCHAR OperationCode;
1877     UCHAR RelativeAddress:1;
1878     UCHAR Reserved1:1;
1879     UCHAR EBP:1;
1880     UCHAR ForceUnitAccess:1;
1881     UCHAR DisablePageOut:1;
1882     UCHAR LogicalUnitNumber:3;
1883     UCHAR LogicalBlock[4];
1884     UCHAR TransferLength[4];
1885     UCHAR Reserved2:7;
1886     UCHAR Streaming:1;
1887     UCHAR Control;
1888   } WRITE12;
1889   struct _READ16 {
1890     UCHAR OperationCode;
1891     UCHAR Reserved1:3;
1892     UCHAR ForceUnitAccess:1;
1893     UCHAR DisablePageOut:1;
1894     UCHAR ReadProtect:3;
1895     UCHAR LogicalBlock[8];
1896     UCHAR TransferLength[4];
1897     UCHAR Reserved2:7;
1898     UCHAR Streaming:1;
1899     UCHAR Control;
1900   } READ16;
1901   struct _WRITE16 {
1902     UCHAR OperationCode;
1903     UCHAR Reserved1:3;
1904     UCHAR ForceUnitAccess:1;
1905     UCHAR DisablePageOut:1;
1906     UCHAR WriteProtect:3;
1907     UCHAR LogicalBlock[8];
1908     UCHAR TransferLength[4];
1909     UCHAR Reserved2:7;
1910     UCHAR Streaming:1;
1911     UCHAR Control;
1912   } WRITE16;
1913   struct _VERIFY16 {
1914     UCHAR OperationCode;
1915     UCHAR Reserved1:1;
1916     UCHAR ByteCheck:1;
1917     UCHAR BlockVerify:1;
1918     UCHAR Reserved2: 1;
1919     UCHAR DisablePageOut:1;
1920     UCHAR VerifyProtect:3;
1921     UCHAR LogicalBlock[8];
1922     UCHAR VerificationLength[4];
1923     UCHAR Reserved3:7;
1924     UCHAR Streaming:1;
1925     UCHAR Control;
1926   } VERIFY16;
1927   struct _SYNCHRONIZE_CACHE16 {
1928     UCHAR OperationCode;
1929     UCHAR Reserved1:1;
1930     UCHAR Immediate:1;
1931     UCHAR Reserved2:6;
1932     UCHAR LogicalBlock[8];
1933     UCHAR BlockCount[4];
1934     UCHAR Reserved3;
1935     UCHAR Control;
1936   } SYNCHRONIZE_CACHE16;
1937   struct _READ_CAPACITY16 {
1938     UCHAR OperationCode;
1939     UCHAR ServiceAction:5;
1940     UCHAR Reserved1:3;
1941     UCHAR LogicalBlock[8];
1942     UCHAR AllocationLength[4];
1943     UCHAR PMI:1;
1944     UCHAR Reserved2:7;
1945     UCHAR Control;
1946   } READ_CAPACITY16;
1947   struct _TOKEN_OPERATION {
1948     UCHAR OperationCode;
1949     UCHAR ServiceAction:5;
1950     UCHAR Reserved1:3;
1951     UCHAR Reserved2[4];
1952     UCHAR ListIdentifier[4];
1953     UCHAR ParameterListLength[4];
1954     UCHAR GroupNumber:5;
1955     UCHAR Reserved3:3;
1956     UCHAR Control;
1957   } TOKEN_OPERATION;
1958   struct _RECEIVE_TOKEN_INFORMATION {
1959     UCHAR OperationCode;
1960     UCHAR ServiceAction:5;
1961     UCHAR Reserved1:3;
1962     UCHAR ListIdentifier[4];
1963     UCHAR Reserved2[4];
1964     UCHAR AllocationLength[4];
1965     UCHAR Reserved3;
1966     UCHAR Control;
1967   } RECEIVE_TOKEN_INFORMATION;
1968   struct _UNMAP {
1969     UCHAR OperationCode;
1970     UCHAR Anchor:1;
1971     UCHAR Reserved1:7;
1972     UCHAR Reserved2[4];
1973     UCHAR GroupNumber:5;
1974     UCHAR Reserved3:3;
1975     UCHAR AllocationLength[2];
1976     UCHAR Control;
1977   } UNMAP;
1978   struct _GET_LBA_STATUS {
1979     UCHAR OperationCode;
1980     UCHAR ServiceAction:5;
1981     UCHAR Reserved1:3;
1982     UCHAR StartingLBA[8];
1983     UCHAR AllocationLength[4];
1984     UCHAR Reserved2;
1985     UCHAR Control;
1986   } GET_LBA_STATUS;
1987   ULONG AsUlong[4];
1988   UCHAR AsByte[16];
1989 } CDB, *PCDB;
1990 
1991 typedef struct _NOTIFICATION_EVENT_STATUS_HEADER {
1992   UCHAR EventDataLength[2];
1993   UCHAR NotificationClass:3;
1994   UCHAR Reserved:4;
1995   UCHAR NEA:1;
1996   UCHAR SupportedEventClasses;
1997   UCHAR ClassEventData[0];
1998 } NOTIFICATION_EVENT_STATUS_HEADER, *PNOTIFICATION_EVENT_STATUS_HEADER;
1999 
2000 typedef struct _NOTIFICATION_OPERATIONAL_STATUS {
2001   UCHAR OperationalEvent:4;
2002   UCHAR Reserved1:4;
2003   UCHAR OperationalStatus:4;
2004   UCHAR Reserved2:3;
2005   UCHAR PersistentPrevented:1;
2006   UCHAR Operation[2];
2007 } NOTIFICATION_OPERATIONAL_STATUS, *PNOTIFICATION_OPERATIONAL_STATUS;
2008 
2009 typedef struct _NOTIFICATION_POWER_STATUS {
2010   UCHAR PowerEvent:4;
2011   UCHAR Reserved:4;
2012   UCHAR PowerStatus;
2013   UCHAR Reserved2[2];
2014 } NOTIFICATION_POWER_STATUS, *PNOTIFICATION_POWER_STATUS;
2015 
2016 typedef struct _NOTIFICATION_EXTERNAL_STATUS {
2017   UCHAR ExternalEvent:4;
2018   UCHAR Reserved1:4;
2019   UCHAR ExternalStatus:4;
2020   UCHAR Reserved2:3;
2021   UCHAR PersistentPrevented:1;
2022   UCHAR Request[2];
2023 } NOTIFICATION_EXTERNAL_STATUS, *PNOTIFICATION_EXTERNAL_STATUS;
2024 
2025 typedef struct _NOTIFICATION_MEDIA_STATUS {
2026   UCHAR MediaEvent:4;
2027   UCHAR Reserved:4;
2028   _ANONYMOUS_UNION union {
2029     UCHAR PowerStatus;
2030     UCHAR MediaStatus;
2031     _ANONYMOUS_STRUCT struct {
2032       UCHAR DoorTrayOpen:1;
2033       UCHAR MediaPresent:1;
2034       UCHAR ReservedX:6;
2035     } DUMMYSTRUCTNAME;
2036   } DUMMYUNIONNAME;
2037   UCHAR StartSlot;
2038   UCHAR EndSlot;
2039 } NOTIFICATION_MEDIA_STATUS, *PNOTIFICATION_MEDIA_STATUS;
2040 
2041 typedef struct _NOTIFICATION_MULTI_HOST_STATUS {
2042   UCHAR MultiHostEvent:4;
2043   UCHAR Reserved1:4;
2044   UCHAR MultiHostStatus:4;
2045   UCHAR Reserved2:3;
2046   UCHAR PersistentPrevented:1;
2047   UCHAR Priority[2];
2048 } NOTIFICATION_MULTI_HOST_STATUS, *PNOTIFICATION_MULTI_HOST_STATUS;
2049 
2050 typedef struct _NOTIFICATION_BUSY_STATUS {
2051   UCHAR DeviceBusyEvent:4;
2052   UCHAR Reserved:4;
2053   UCHAR DeviceBusyStatus;
2054   UCHAR Time[2];
2055 } NOTIFICATION_BUSY_STATUS, *PNOTIFICATION_BUSY_STATUS;
2056 
2057 typedef struct _READ_DVD_STRUCTURES_HEADER {
2058   UCHAR Length[2];
2059   UCHAR Reserved[2];
2060   UCHAR Data[0];
2061 } READ_DVD_STRUCTURES_HEADER, *PREAD_DVD_STRUCTURES_HEADER;
2062 
2063 typedef struct _CDVD_KEY_HEADER {
2064   UCHAR DataLength[2];
2065   UCHAR Reserved[2];
2066   UCHAR Data[0];
2067 } CDVD_KEY_HEADER, *PCDVD_KEY_HEADER;
2068 
2069 typedef struct _CDVD_REPORT_AGID_DATA {
2070   UCHAR Reserved1[3];
2071   UCHAR Reserved2:6;
2072   UCHAR AGID:2;
2073 } CDVD_REPORT_AGID_DATA, *PCDVD_REPORT_AGID_DATA;
2074 
2075 typedef struct _CDVD_CHALLENGE_KEY_DATA {
2076   UCHAR ChallengeKeyValue[10];
2077   UCHAR Reserved[2];
2078 } CDVD_CHALLENGE_KEY_DATA, *PCDVD_CHALLENGE_KEY_DATA;
2079 
2080 typedef struct _CDVD_KEY_DATA {
2081   UCHAR Key[5];
2082   UCHAR Reserved[3];
2083 } CDVD_KEY_DATA, *PCDVD_KEY_DATA;
2084 
2085 typedef struct _CDVD_REPORT_ASF_DATA {
2086   UCHAR Reserved1[3];
2087   UCHAR Success:1;
2088   UCHAR Reserved2:7;
2089 } CDVD_REPORT_ASF_DATA, *PCDVD_REPORT_ASF_DATA;
2090 
2091 typedef struct _CDVD_TITLE_KEY_HEADER {
2092   UCHAR DataLength[2];
2093   UCHAR Reserved1[1];
2094   UCHAR Reserved2:3;
2095   UCHAR CGMS:2;
2096   UCHAR CP_SEC:1;
2097   UCHAR CPM:1;
2098   UCHAR Zero:1;
2099   CDVD_KEY_DATA TitleKey;
2100 } CDVD_TITLE_KEY_HEADER, *PCDVD_TITLE_KEY_HEADER;
2101 
2102 typedef struct _FORMAT_DESCRIPTOR {
2103   UCHAR NumberOfBlocks[4];
2104   UCHAR FormatSubType:2;
2105   UCHAR FormatType:6;
2106   UCHAR BlockLength[3];
2107 } FORMAT_DESCRIPTOR, *PFORMAT_DESCRIPTOR;
2108 
2109 typedef struct _FORMAT_LIST_HEADER {
2110   UCHAR Reserved;
2111   UCHAR VendorSpecific:1;
2112   UCHAR Immediate:1;
2113   UCHAR TryOut:1;
2114   UCHAR IP:1;
2115   UCHAR STPF:1;
2116   UCHAR DCRT:1;
2117   UCHAR DPRY:1;
2118   UCHAR FOV:1;
2119   UCHAR FormatDescriptorLength[2];
2120   FORMAT_DESCRIPTOR Descriptors[0];
2121 } FORMAT_LIST_HEADER, *PFORMAT_LIST_HEADER;
2122 
2123 typedef struct _FORMATTED_CAPACITY_DESCRIPTOR {
2124   UCHAR NumberOfBlocks[4];
2125   UCHAR Maximum:1;
2126   UCHAR Valid:1;
2127   UCHAR FormatType:6;
2128   UCHAR BlockLength[3];
2129 } FORMATTED_CAPACITY_DESCRIPTOR, *PFORMATTED_CAPACITY_DESCRIPTOR;
2130 
2131 typedef struct _FORMATTED_CAPACITY_LIST {
2132   UCHAR Reserved[3];
2133   UCHAR CapacityListLength;
2134   FORMATTED_CAPACITY_DESCRIPTOR Descriptors[0];
2135 } FORMATTED_CAPACITY_LIST, *PFORMATTED_CAPACITY_LIST;
2136 
2137 typedef struct _OPC_TABLE_ENTRY {
2138   UCHAR Speed[2];
2139   UCHAR OPCValue[6];
2140 } OPC_TABLE_ENTRY, *POPC_TABLE_ENTRY;
2141 
2142 typedef struct _DISC_INFORMATION {
2143   UCHAR Length[2];
2144   UCHAR DiscStatus:2;
2145   UCHAR LastSessionStatus:2;
2146   UCHAR Erasable:1;
2147   UCHAR Reserved1:3;
2148   UCHAR FirstTrackNumber;
2149   UCHAR NumberOfSessionsLsb;
2150   UCHAR LastSessionFirstTrackLsb;
2151   UCHAR LastSessionLastTrackLsb;
2152   UCHAR MrwStatus:2;
2153   UCHAR MrwDirtyBit:1;
2154   UCHAR Reserved2:2;
2155   UCHAR URU:1;
2156   UCHAR DBC_V:1;
2157   UCHAR DID_V:1;
2158   UCHAR DiscType;
2159   UCHAR NumberOfSessionsMsb;
2160   UCHAR LastSessionFirstTrackMsb;
2161   UCHAR LastSessionLastTrackMsb;
2162   UCHAR DiskIdentification[4];
2163   UCHAR LastSessionLeadIn[4];
2164   UCHAR LastPossibleLeadOutStartTime[4];
2165   UCHAR DiskBarCode[8];
2166   UCHAR Reserved4;
2167   UCHAR NumberOPCEntries;
2168   OPC_TABLE_ENTRY OPCTable[1];
2169 } DISC_INFORMATION, *PDISC_INFORMATION;
2170 
2171 typedef struct _DISK_INFORMATION {
2172   UCHAR Length[2];
2173   UCHAR DiskStatus:2;
2174   UCHAR LastSessionStatus:2;
2175   UCHAR Erasable:1;
2176   UCHAR Reserved1:3;
2177   UCHAR FirstTrackNumber;
2178   UCHAR NumberOfSessions;
2179   UCHAR LastSessionFirstTrack;
2180   UCHAR LastSessionLastTrack;
2181   UCHAR Reserved2:5;
2182   UCHAR GEN:1;
2183   UCHAR DBC_V:1;
2184   UCHAR DID_V:1;
2185   UCHAR DiskType;
2186   UCHAR Reserved3[3];
2187   UCHAR DiskIdentification[4];
2188   UCHAR LastSessionLeadIn[4];
2189   UCHAR LastPossibleStartTime[4];
2190   UCHAR DiskBarCode[8];
2191   UCHAR Reserved4;
2192   UCHAR NumberOPCEntries;
2193   OPC_TABLE_ENTRY OPCTable[0];
2194 } DISK_INFORMATION, *PDISK_INFORMATION;
2195 
2196 typedef struct _DATA_BLOCK_HEADER {
2197   UCHAR DataMode;
2198   UCHAR Reserved[4];
2199   _ANONYMOUS_UNION union {
2200     UCHAR LogicalBlockAddress[4];
2201     struct {
2202       UCHAR Reserved;
2203       UCHAR M;
2204       UCHAR S;
2205       UCHAR F;
2206     } MSF;
2207   } DUMMYUNIONNAME;
2208 } DATA_BLOCK_HEADER, *PDATA_BLOCK_HEADER;
2209 
2210 typedef struct _TRACK_INFORMATION {
2211   UCHAR Length[2];
2212   UCHAR TrackNumber;
2213   UCHAR SessionNumber;
2214   UCHAR Reserved1;
2215   UCHAR TrackMode:4;
2216   UCHAR Copy:1;
2217   UCHAR Damage:1;
2218   UCHAR Reserved2:2;
2219   UCHAR DataMode:4;
2220   UCHAR FP:1;
2221   UCHAR Packet:1;
2222   UCHAR Blank:1;
2223   UCHAR RT:1;
2224   UCHAR NWA_V:1;
2225   UCHAR Reserved3:7;
2226   UCHAR TrackStartAddress[4];
2227   UCHAR NextWritableAddress[4];
2228   UCHAR FreeBlocks[4];
2229   UCHAR FixedPacketSize[4];
2230 } TRACK_INFORMATION, *PTRACK_INFORMATION;
2231 
2232 typedef struct _TRACK_INFORMATION2 {
2233   UCHAR Length[2];
2234   UCHAR TrackNumberLsb;
2235   UCHAR SessionNumberLsb;
2236   UCHAR Reserved4;
2237   UCHAR TrackMode:4;
2238   UCHAR Copy:1;
2239   UCHAR Damage:1;
2240   UCHAR Reserved5:2;
2241   UCHAR DataMode:4;
2242   UCHAR FixedPacket:1;
2243   UCHAR Packet:1;
2244   UCHAR Blank:1;
2245   UCHAR ReservedTrack:1;
2246   UCHAR NWA_V:1;
2247   UCHAR LRA_V:1;
2248   UCHAR Reserved6:6;
2249   UCHAR TrackStartAddress[4];
2250   UCHAR NextWritableAddress[4];
2251   UCHAR FreeBlocks[4];
2252   UCHAR FixedPacketSize[4];
2253   UCHAR TrackSize[4];
2254   UCHAR LastRecordedAddress[4];
2255   UCHAR TrackNumberMsb;
2256   UCHAR SessionNumberMsb;
2257   UCHAR Reserved7[2];
2258 } TRACK_INFORMATION2, *PTRACK_INFORMATION2;
2259 
2260 typedef struct _TRACK_INFORMATION3 {
2261   UCHAR Length[2];
2262   UCHAR TrackNumberLsb;
2263   UCHAR SessionNumberLsb;
2264   UCHAR Reserved4;
2265   UCHAR TrackMode:4;
2266   UCHAR Copy:1;
2267   UCHAR Damage:1;
2268   UCHAR Reserved5:2;
2269   UCHAR DataMode:4;
2270   UCHAR FixedPacket:1;
2271   UCHAR Packet:1;
2272   UCHAR Blank:1;
2273   UCHAR ReservedTrack:1;
2274   UCHAR NWA_V:1;
2275   UCHAR LRA_V:1;
2276   UCHAR Reserved6:6;
2277   UCHAR TrackStartAddress[4];
2278   UCHAR NextWritableAddress[4];
2279   UCHAR FreeBlocks[4];
2280   UCHAR FixedPacketSize[4];
2281   UCHAR TrackSize[4];
2282   UCHAR LastRecordedAddress[4];
2283   UCHAR TrackNumberMsb;
2284   UCHAR SessionNumberMsb;
2285   UCHAR Reserved7[2];
2286   UCHAR ReadCompatibilityLba[4];
2287 } TRACK_INFORMATION3, *PTRACK_INFORMATION3;
2288 
2289 typedef struct _PERFORMANCE_DESCRIPTOR {
2290   UCHAR RandomAccess:1;
2291   UCHAR Exact:1;
2292   UCHAR RestoreDefaults:1;
2293   UCHAR WriteRotationControl:2;
2294   UCHAR Reserved1:3;
2295   UCHAR Reserved[3];
2296   UCHAR StartLba[4];
2297   UCHAR EndLba[4];
2298   UCHAR ReadSize[4];
2299   UCHAR ReadTime[4];
2300   UCHAR WriteSize[4];
2301   UCHAR WriteTime[4];
2302 } PERFORMANCE_DESCRIPTOR, *PPERFORMANCE_DESCRIPTOR;
2303 
2304 typedef struct _SCSI_EXTENDED_MESSAGE {
2305   UCHAR InitialMessageCode;
2306   UCHAR MessageLength;
2307   UCHAR MessageType;
2308   union _EXTENDED_ARGUMENTS {
2309     struct {
2310       UCHAR Modifier[4];
2311     } Modify;
2312     struct {
2313       UCHAR TransferPeriod;
2314       UCHAR ReqAckOffset;
2315     } Synchronous;
2316     struct{
2317       UCHAR Width;
2318     } Wide;
2319   } ExtendedArguments;
2320 }SCSI_EXTENDED_MESSAGE, *PSCSI_EXTENDED_MESSAGE;
2321 
2322 #ifndef _INQUIRYDATA_DEFINED /* also in minitape.h */
2323 #define _INQUIRYDATA_DEFINED
2324 
2325 #define INQUIRYDATABUFFERSIZE 36
2326 
2327 #if (NTDDI_VERSION < NTDDI_WINXP)
2328 typedef struct _INQUIRYDATA {
2329   UCHAR DeviceType:5;
2330   UCHAR DeviceTypeQualifier:3;
2331   UCHAR DeviceTypeModifier:7;
2332   UCHAR RemovableMedia:1;
2333   UCHAR Versions;
2334   UCHAR ResponseDataFormat:4;
2335   UCHAR HiSupport:1;
2336   UCHAR NormACA:1;
2337   UCHAR ReservedBit:1;
2338   UCHAR AERC:1;
2339   UCHAR AdditionalLength;
2340   UCHAR Reserved[2];
2341   UCHAR SoftReset:1;
2342   UCHAR CommandQueue:1;
2343   UCHAR Reserved2:1;
2344   UCHAR LinkedCommands:1;
2345   UCHAR Synchronous:1;
2346   UCHAR Wide16Bit:1;
2347   UCHAR Wide32Bit:1;
2348   UCHAR RelativeAddressing:1;
2349   UCHAR VendorId[8];
2350   UCHAR ProductId[16];
2351   UCHAR ProductRevisionLevel[4];
2352   UCHAR VendorSpecific[20];
2353   UCHAR Reserved3[40];
2354 } INQUIRYDATA, *PINQUIRYDATA;
2355 #else
2356 typedef struct _INQUIRYDATA {
2357   UCHAR DeviceType:5;
2358   UCHAR DeviceTypeQualifier:3;
2359   UCHAR DeviceTypeModifier:7;
2360   UCHAR RemovableMedia:1;
2361   _ANONYMOUS_UNION union {
2362     UCHAR Versions;
2363     _ANONYMOUS_STRUCT struct {
2364       UCHAR ANSIVersion:3;
2365       UCHAR ECMAVersion:3;
2366       UCHAR ISOVersion:2;
2367     } DUMMYSTRUCTNAME;
2368   } DUMMYUNIONNAME;
2369   UCHAR ResponseDataFormat:4;
2370   UCHAR HiSupport:1;
2371   UCHAR NormACA:1;
2372   UCHAR TerminateTask:1;
2373   UCHAR AERC:1;
2374   UCHAR AdditionalLength;
2375   UCHAR Reserved;
2376   UCHAR Addr16:1;
2377   UCHAR Addr32:1;
2378   UCHAR AckReqQ:1;
2379   UCHAR MediumChanger:1;
2380   UCHAR MultiPort:1;
2381   UCHAR ReservedBit2:1;
2382   UCHAR EnclosureServices:1;
2383   UCHAR ReservedBit3:1;
2384   UCHAR SoftReset:1;
2385   UCHAR CommandQueue:1;
2386   UCHAR TransferDisable:1;
2387   UCHAR LinkedCommands:1;
2388   UCHAR Synchronous:1;
2389   UCHAR Wide16Bit:1;
2390   UCHAR Wide32Bit:1;
2391   UCHAR RelativeAddressing:1;
2392   UCHAR VendorId[8];
2393   UCHAR ProductId[16];
2394   UCHAR ProductRevisionLevel[4];
2395   UCHAR VendorSpecific[20];
2396   UCHAR Reserved3[40];
2397 } INQUIRYDATA, *PINQUIRYDATA;
2398 #endif /* (NTDDI_VERSION < NTDDI_WINXP) */
2399 
2400 #endif /* _INQUIRYDATA_DEFINED */
2401 
2402 #define VPD_MAX_BUFFER_SIZE                0xff
2403 
2404 #define VPD_SUPPORTED_PAGES                0x00
2405 #define VPD_SERIAL_NUMBER                  0x80
2406 #define VPD_DEVICE_IDENTIFIERS             0x83
2407 #define VPD_MEDIA_SERIAL_NUMBER            0x84
2408 #define VPD_SOFTWARE_INTERFACE_IDENTIFIERS 0x84
2409 #define VPD_NETWORK_MANAGEMENT_ADDRESSES   0x85
2410 #define VPD_EXTENDED_INQUIRY_DATA          0x86
2411 #define VPD_MODE_PAGE_POLICY               0x87
2412 #define VPD_SCSI_PORTS                     0x88
2413 #define VPD_ATA_INFORMATION                0x89
2414 
2415 #define VPD_THIRD_PARTY_COPY               0x8F
2416 #define VPD_BLOCK_LIMITS                   0xB0
2417 #define VPD_BLOCK_DEVICE_CHARACTERISTICS   0xB1
2418 #define VPD_LOGICAL_BLOCK_PROVISIONING     0xB2
2419 #define VPD_ZONED_BLOCK_DEVICE_CHARACTERISTICS  0xB6
2420 
2421 typedef struct _VPD_MEDIA_SERIAL_NUMBER_PAGE {
2422   UCHAR DeviceType:5;
2423   UCHAR DeviceTypeQualifier:3;
2424   UCHAR PageCode;
2425   UCHAR Reserved;
2426   UCHAR PageLength;
2427   UCHAR SerialNumber[0];
2428 } VPD_MEDIA_SERIAL_NUMBER_PAGE, *PVPD_MEDIA_SERIAL_NUMBER_PAGE;
2429 
2430 typedef struct _VPD_SERIAL_NUMBER_PAGE {
2431   UCHAR DeviceType:5;
2432   UCHAR DeviceTypeQualifier:3;
2433   UCHAR PageCode;
2434   UCHAR Reserved;
2435   UCHAR PageLength;
2436   UCHAR SerialNumber[0];
2437 } VPD_SERIAL_NUMBER_PAGE, *PVPD_SERIAL_NUMBER_PAGE;
2438 
2439 typedef enum _VPD_CODE_SET {
2440   VpdCodeSetReserved = 0,
2441   VpdCodeSetBinary = 1,
2442   VpdCodeSetAscii = 2,
2443   VpdCodeSetUTF8 = 3
2444 } VPD_CODE_SET, *PVPD_CODE_SET;
2445 
2446 typedef enum _VPD_ASSOCIATION {
2447   VpdAssocDevice = 0,
2448   VpdAssocPort = 1,
2449   VpdAssocTarget = 2,
2450   VpdAssocReserved1 = 3,
2451   VpdAssocReserved2 = 4
2452 } VPD_ASSOCIATION, *PVPD_ASSOCIATION;
2453 
2454 typedef enum _VPD_IDENTIFIER_TYPE {
2455   VpdIdentifierTypeVendorSpecific = 0,
2456   VpdIdentifierTypeVendorId = 1,
2457   VpdIdentifierTypeEUI64 = 2,
2458   VpdIdentifierTypeFCPHName = 3,
2459   VpdIdentifierTypePortRelative = 4,
2460   VpdIdentifierTypeTargetPortGroup = 5,
2461   VpdIdentifierTypeLogicalUnitGroup = 6,
2462   VpdIdentifierTypeMD5LogicalUnitId = 7,
2463   VpdIdentifierTypeSCSINameString = 8
2464 } VPD_IDENTIFIER_TYPE, *PVPD_IDENTIFIER_TYPE;
2465 
2466 typedef struct _VPD_IDENTIFICATION_DESCRIPTOR {
2467   UCHAR CodeSet:4;
2468   UCHAR Reserved:4;
2469   UCHAR IdentifierType:4;
2470   UCHAR Association:2;
2471   UCHAR Reserved2:2;
2472   UCHAR Reserved3;
2473   UCHAR IdentifierLength;
2474   UCHAR Identifier[0];
2475 } VPD_IDENTIFICATION_DESCRIPTOR, *PVPD_IDENTIFICATION_DESCRIPTOR;
2476 
2477 typedef struct _VPD_IDENTIFICATION_PAGE {
2478   UCHAR DeviceType:5;
2479   UCHAR DeviceTypeQualifier:3;
2480   UCHAR PageCode;
2481   UCHAR Reserved;
2482   UCHAR PageLength;
2483   UCHAR Descriptors[0];
2484 } VPD_IDENTIFICATION_PAGE, *PVPD_IDENTIFICATION_PAGE;
2485 
2486 typedef struct _VPD_ATA_INFORMATION_PAGE {
2487   UCHAR DeviceType:5;
2488   UCHAR DeviceTypeQualifier:3;
2489   UCHAR PageCode;
2490   UCHAR PageLength[2];
2491   UCHAR Reserved0[4];
2492   UCHAR VendorId[8];
2493   UCHAR ProductId[16];
2494   UCHAR ProductRevisionLevel[4];
2495   UCHAR DeviceSignature[20];
2496   UCHAR CommandCode;
2497   UCHAR Reserved1[3];
2498   UCHAR IdentifyDeviceData[512];
2499 } VPD_ATA_INFORMATION_PAGE, *PVPD_ATA_INFORMATION_PAGE;
2500 
2501 #if (NTDDI_VERSION >= NTDDI_WIN8)
2502 typedef struct _VPD_THIRD_PARTY_COPY_PAGE {
2503   UCHAR DeviceType:5;
2504   UCHAR DeviceTypeQualifier:3;
2505   UCHAR PageCode;
2506   UCHAR PageLength[2];
2507 #if !defined(__midl)
2508   UCHAR ThirdPartyCopyDescriptors[ANYSIZE_ARRAY];
2509 #endif
2510 } VPD_THIRD_PARTY_COPY_PAGE, *PVPD_THIRD_PARTY_COPY_PAGE;
2511 
2512 typedef struct _WINDOWS_BLOCK_DEVICE_TOKEN_LIMITS_DESCRIPTOR {
2513   UCHAR DescriptorType[2];
2514   UCHAR DescriptorLength[2];
2515   UCHAR VendorSpecific[6];
2516   UCHAR MaximumRangeDescriptors[2];
2517   UCHAR MaximumInactivityTimer[4];
2518   UCHAR DefaultInactivityTimer[4];
2519   UCHAR MaximumTokenTransferSize[8];
2520   UCHAR OptimalTransferCount[8];
2521 } WINDOWS_BLOCK_DEVICE_TOKEN_LIMITS_DESCRIPTOR, *PWINDOWS_BLOCK_DEVICE_TOKEN_LIMITS_DESCRIPTOR;
2522 
2523 #define BLOCK_DEVICE_TOKEN_LIMITS_DESCRIPTOR_TYPE_WINDOWS       0x00
2524 
2525 #endif /* (NTDDI_VERSION >= NTDDI_WIN8) */
2526 
2527 typedef struct _VPD_BLOCK_LIMITS_PAGE {
2528   UCHAR DeviceType:5;
2529   UCHAR DeviceTypeQualifier:3;
2530   UCHAR PageCode;
2531   UCHAR PageLength[2];
2532   union {
2533     struct {
2534       UCHAR Reserved0;
2535       UCHAR MaximumCompareAndWriteLength;
2536       UCHAR OptimalTransferLengthGranularity[2];
2537       UCHAR MaximumTransferLength[4];
2538       UCHAR OptimalTransferLength[4];
2539       UCHAR MaxPrefetchXDReadXDWriteTransferLength[4];
2540       UCHAR MaximumUnmapLBACount[4];
2541       UCHAR MaximumUnmapBlockDescriptorCount[4];
2542       UCHAR OptimalUnmapGranularity[4];
2543       union {
2544         struct {
2545           UCHAR UnmapGranularityAlignmentByte3:7;
2546           UCHAR UGAValid:1;
2547           UCHAR UnmapGranularityAlignmentByte2;
2548           UCHAR UnmapGranularityAlignmentByte1;
2549           UCHAR UnmapGranularityAlignmentByte0;
2550         };
2551         UCHAR UnmapGranularityAlignment[4];
2552       };
2553       UCHAR Reserved1[28];
2554     };
2555 #if !defined(__midl)
2556   UCHAR Descriptors[0];
2557 #endif
2558   };
2559 } VPD_BLOCK_LIMITS_PAGE, *PVPD_BLOCK_LIMITS_PAGE;
2560 
2561 #define ZONED_CAPABILITIES_NOT_REPORTED       0x0
2562 #define ZONED_CAPABILITIES_HOST_AWARE         0x1
2563 #define ZONED_CAPABILITIES_DEVICE_MANAGED     0x2
2564 
2565 typedef struct _VPD_BLOCK_DEVICE_CHARACTERISTICS_PAGE {
2566   UCHAR DeviceType:5;
2567   UCHAR DeviceTypeQualifier:3;
2568   UCHAR PageCode;
2569   UCHAR Reserved0;
2570   UCHAR PageLength;
2571   UCHAR MediumRotationRateMsb;
2572   UCHAR MediumRotationRateLsb;
2573   UCHAR MediumProductType;
2574   UCHAR NominalFormFactor:4;
2575   UCHAR WACEREQ:2;
2576   UCHAR WABEREQ:2;
2577   UCHAR VBULS:1;
2578   UCHAR FUAB:1;
2579   UCHAR BOCS:1;
2580   UCHAR Reserved1:1;
2581   UCHAR ZONED:2;
2582   UCHAR Reserved2:2;
2583   UCHAR Reserved3[3];
2584   UCHAR DepopulationTime[4];
2585   UCHAR Reserved4[48];
2586 } VPD_BLOCK_DEVICE_CHARACTERISTICS_PAGE, *PVPD_BLOCK_DEVICE_CHARACTERISTICS_PAGE;
2587 
2588 #define PROVISIONING_TYPE_UNKNOWN       0x0
2589 #define PROVISIONING_TYPE_RESOURCE      0x1
2590 #define PROVISIONING_TYPE_THIN          0x2
2591 
2592 typedef struct _VPD_LOGICAL_BLOCK_PROVISIONING_PAGE {
2593   UCHAR DeviceType:5;
2594   UCHAR DeviceTypeQualifier:3;
2595   UCHAR PageCode;
2596   UCHAR PageLength[2];
2597   UCHAR ThresholdExponent;
2598   UCHAR DP:1;
2599   UCHAR ANC_SUP:1;
2600   UCHAR LBPRZ:1;
2601   UCHAR Reserved0:2;
2602   UCHAR LBPWS10:1;
2603   UCHAR LBPWS:1;
2604   UCHAR LBPU:1;
2605   UCHAR ProvisioningType:3;
2606   UCHAR Reserved1:5;
2607   UCHAR Reserved2;
2608 #if !defined(__midl)
2609   UCHAR ProvisioningGroupDescr[0];
2610 #endif
2611 } VPD_LOGICAL_BLOCK_PROVISIONING_PAGE, *PVPD_LOGICAL_BLOCK_PROVISIONING_PAGE;
2612 
2613 typedef struct _VPD_ZONED_BLOCK_DEVICE_CHARACTERISTICS_PAGE {
2614   UCHAR DeviceType:5;
2615   UCHAR DeviceTypeQualifier:3;
2616   UCHAR PageCode;
2617   UCHAR PageLength[2];
2618   UCHAR URSWRZ:1;
2619   UCHAR Reserved1:7;
2620   UCHAR Reserved2[3];
2621   UCHAR OptimalNumberOfOpenSequentialWritePreferredZone[4];
2622   UCHAR OptimalNumberOfNonSequentiallyWrittenSequentialWritePreferredZone[4];
2623   UCHAR MaxNumberOfOpenSequentialWriteRequiredZone[4];
2624   UCHAR Reserved3[44];
2625 } VPD_ZONED_BLOCK_DEVICE_CHARACTERISTICS_PAGE, *PVPD_ZONED_BLOCK_DEVICE_CHARACTERISTICS_PAGE;
2626 
2627 typedef struct _VPD_SUPPORTED_PAGES_PAGE {
2628   UCHAR DeviceType:5;
2629   UCHAR DeviceTypeQualifier:3;
2630   UCHAR PageCode;
2631   UCHAR Reserved;
2632   UCHAR PageLength;
2633   UCHAR SupportedPageList[0];
2634 } VPD_SUPPORTED_PAGES_PAGE, *PVPD_SUPPORTED_PAGES_PAGE;
2635 
2636 typedef struct _PRI_REGISTRATION_LIST {
2637   UCHAR Generation[4];
2638   UCHAR AdditionalLength[4];
2639   UCHAR ReservationKeyList[0][8];
2640 } PRI_REGISTRATION_LIST, *PPRI_REGISTRATION_LIST;
2641 
2642 typedef struct _PRI_RESERVATION_DESCRIPTOR {
2643   UCHAR ReservationKey[8];
2644   UCHAR ScopeSpecificAddress[4];
2645   UCHAR Reserved;
2646   UCHAR Type:4;
2647   UCHAR Scope:4;
2648   UCHAR Obsolete[2];
2649 } PRI_RESERVATION_DESCRIPTOR, *PPRI_RESERVATION_DESCRIPTOR;
2650 
2651 typedef struct _PRI_RESERVATION_LIST {
2652   UCHAR Generation[4];
2653   UCHAR AdditionalLength[4];
2654   PRI_RESERVATION_DESCRIPTOR Reservations[0];
2655 } PRI_RESERVATION_LIST, *PPRI_RESERVATION_LIST;
2656 
2657 typedef struct _PRO_PARAMETER_LIST {
2658   UCHAR ReservationKey[8];
2659   UCHAR ServiceActionReservationKey[8];
2660   UCHAR ScopeSpecificAddress[4];
2661   UCHAR ActivatePersistThroughPowerLoss:1;
2662   UCHAR Reserved1:7;
2663   UCHAR Reserved2;
2664   UCHAR Obsolete[2];
2665 } PRO_PARAMETER_LIST, *PPRO_PARAMETER_LIST;
2666 
2667 typedef struct _SENSE_DATA {
2668   UCHAR ErrorCode:7;
2669   UCHAR Valid:1;
2670   UCHAR SegmentNumber;
2671   UCHAR SenseKey:4;
2672   UCHAR Reserved:1;
2673   UCHAR IncorrectLength:1;
2674   UCHAR EndOfMedia:1;
2675   UCHAR FileMark:1;
2676   UCHAR Information[4];
2677   UCHAR AdditionalSenseLength;
2678   UCHAR CommandSpecificInformation[4];
2679   UCHAR AdditionalSenseCode;
2680   UCHAR AdditionalSenseCodeQualifier;
2681   UCHAR FieldReplaceableUnitCode;
2682   UCHAR SenseKeySpecific[3];
2683 } SENSE_DATA, *PSENSE_DATA;
2684 
2685 typedef struct _SCSI_SENSE_DESCRIPTOR_HEADER {
2686   UCHAR DescriptorType;
2687   UCHAR AdditionalLength;
2688 } SCSI_SENSE_DESCRIPTOR_HEADER, *PSCSI_SENSE_DESCRIPTOR_HEADER;
2689 
2690 typedef struct _SCSI_SENSE_DESCRIPTOR_INFORMATION {
2691   SCSI_SENSE_DESCRIPTOR_HEADER Header;
2692   UCHAR Valid:1;
2693   UCHAR Reserved1:7;
2694   UCHAR Reserved2;
2695   UCHAR Information[8];
2696 } SCSI_SENSE_DESCRIPTOR_INFORMATION, *PSCSI_SENSE_DESCRIPTOR_INFORMATION;
2697 
2698 typedef struct _SCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND {
2699   SCSI_SENSE_DESCRIPTOR_HEADER Header;
2700   UCHAR Reserved1;
2701   UCHAR Reserved2:5;
2702   UCHAR IncorrectLength:1;
2703   UCHAR Reserved3:2;
2704 } SCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND, *PSCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND;
2705 
2706 typedef struct _SCSI_SENSE_DESCRIPTOR_ATA_STATUS_RETURN {
2707   SCSI_SENSE_DESCRIPTOR_HEADER Header;
2708   UCHAR Extend:1;
2709   UCHAR Reserved1:7;
2710   UCHAR Error;
2711   UCHAR SectorCount15_8;
2712   UCHAR SectorCount7_0;
2713   UCHAR LbaLow15_8;
2714   UCHAR LbaLow7_0;
2715   UCHAR LbaMid15_8;
2716   UCHAR LbaMid7_0;
2717   UCHAR LbaHigh15_8;
2718   UCHAR LbaHigh7_0;
2719   UCHAR Device;
2720   UCHAR Status;
2721 } SCSI_SENSE_DESCRIPTOR_ATA_STATUS_RETURN, *PSCSI_SENSE_DESCRIPTOR_ATA_STATUS_RETURN;
2722 
2723 typedef struct _SENSE_DATA FIXED_SENSE_DATA, *PFIXED_SENSE_DATA;
2724 
2725 typedef struct _DESCRIPTOR_SENSE_DATA {
2726   UCHAR ErrorCode:7;
2727   UCHAR Reserved1:1;
2728   UCHAR SenseKey:4;
2729   UCHAR Reserved2:4;
2730   UCHAR AdditionalSenseCode;
2731   UCHAR AdditionalSenseCodeQualifier;
2732   UCHAR Reserved3[3];
2733   UCHAR AdditionalSenseLength;
2734   UCHAR DescriptorBuffer[ANYSIZE_ARRAY];
2735 } DESCRIPTOR_SENSE_DATA, *PDESCRIPTOR_SENSE_DATA;
2736 
2737 typedef union _SENSE_DATA_EX {
2738   FIXED_SENSE_DATA FixedData;
2739   DESCRIPTOR_SENSE_DATA DescriptorData;
2740 } SENSE_DATA_EX, *PSENSE_DATA_EX;
2741 
2742 /* Read Capacity Data. Returned in Big Endian format */
2743 typedef struct _READ_CAPACITY_DATA {
2744   ULONG LogicalBlockAddress;
2745   ULONG BytesPerBlock;
2746 } READ_CAPACITY_DATA, *PREAD_CAPACITY_DATA;
2747 
2748 typedef struct _READ_CAPACITY_DATA_EX {
2749   LARGE_INTEGER LogicalBlockAddress;
2750   ULONG BytesPerBlock;
2751 } READ_CAPACITY_DATA_EX, *PREAD_CAPACITY_DATA_EX;
2752 
2753 #define RC_BASIS_LAST_LBA_NOT_SEQUENTIAL_WRITE_REQUIRED_ZONES       0x0
2754 #define RC_BASIS_LAST_LBA_ON_LOGICAL_UNIT                           0x1
2755 
2756 typedef struct _READ_CAPACITY16_DATA {
2757   LARGE_INTEGER LogicalBlockAddress;
2758   ULONG BytesPerBlock;
2759   UCHAR ProtectionEnable:1;
2760   UCHAR ProtectionType:3;
2761   UCHAR RcBasis:2;
2762   UCHAR Reserved:2;
2763   UCHAR LogicalPerPhysicalExponent:4;
2764   UCHAR ProtectionInfoExponent:4;
2765   UCHAR LowestAlignedBlock_MSB:6;
2766   UCHAR LBPRZ:1;
2767   UCHAR LBPME:1;
2768   UCHAR LowestAlignedBlock_LSB;
2769   UCHAR Reserved3[16];
2770 } READ_CAPACITY16_DATA, *PREAD_CAPACITY16_DATA;
2771 
2772 typedef struct _LBA_STATUS_DESCRIPTOR {
2773   ULONGLONG StartingLBA;
2774   ULONG LogicalBlockCount;
2775   UCHAR ProvisioningStatus:4;
2776   UCHAR Reserved1:4;
2777   UCHAR Reserved2[3];
2778 } LBA_STATUS_DESCRIPTOR, *PLBA_STATUS_DESCRIPTOR;
2779 
2780 typedef struct _LBA_STATUS_LIST_HEADER {
2781   ULONG ParameterLength;
2782   ULONG Reserved;
2783   LBA_STATUS_DESCRIPTOR Descriptors[0];
2784 } LBA_STATUS_LIST_HEADER, *PLBA_STATUS_LIST_HEADER;
2785 
2786 #define LBA_STATUS_MAPPED      0x0
2787 #define LBA_STATUS_DEALLOCATED 0x1
2788 #define LBA_STATUS_ANCHORED    0x2
2789 
2790 /* Read Block Limits Data. Returned in Big Endian format */
2791 typedef struct _READ_BLOCK_LIMITS {
2792   UCHAR Reserved;
2793   UCHAR BlockMaximumSize[3];
2794   UCHAR BlockMinimumSize[2];
2795 } READ_BLOCK_LIMITS_DATA, *PREAD_BLOCK_LIMITS_DATA;
2796 
2797 typedef struct _READ_BUFFER_CAPACITY_DATA {
2798   UCHAR DataLength[2];
2799   UCHAR Reserved1;
2800   UCHAR BlockDataReturned:1;
2801   UCHAR Reserved4:7;
2802   UCHAR TotalBufferSize[4];
2803   UCHAR AvailableBufferSize[4];
2804 } READ_BUFFER_CAPACITY_DATA, *PREAD_BUFFER_CAPACITY_DATA;
2805 
2806 typedef struct _MODE_PARAMETER_HEADER {
2807   UCHAR ModeDataLength;
2808   UCHAR MediumType;
2809   UCHAR DeviceSpecificParameter;
2810   UCHAR BlockDescriptorLength;
2811 } MODE_PARAMETER_HEADER, *PMODE_PARAMETER_HEADER;
2812 
2813 typedef struct _MODE_PARAMETER_HEADER10 {
2814   UCHAR ModeDataLength[2];
2815   UCHAR MediumType;
2816   UCHAR DeviceSpecificParameter;
2817   UCHAR Reserved[2];
2818   UCHAR BlockDescriptorLength[2];
2819 } MODE_PARAMETER_HEADER10, *PMODE_PARAMETER_HEADER10;
2820 
2821 typedef struct _MODE_PARAMETER_BLOCK {
2822   UCHAR DensityCode;
2823   UCHAR NumberOfBlocks[3];
2824   UCHAR Reserved;
2825   UCHAR BlockLength[3];
2826 } MODE_PARAMETER_BLOCK, *PMODE_PARAMETER_BLOCK;
2827 
2828 typedef struct _MODE_DISCONNECT_PAGE {
2829   UCHAR PageCode:6;
2830   UCHAR Reserved:1;
2831   UCHAR PageSavable:1;
2832   UCHAR PageLength;
2833   UCHAR BufferFullRatio;
2834   UCHAR BufferEmptyRatio;
2835   UCHAR BusInactivityLimit[2];
2836   UCHAR BusDisconnectTime[2];
2837   UCHAR BusConnectTime[2];
2838   UCHAR MaximumBurstSize[2];
2839   UCHAR DataTransferDisconnect:2;
2840   UCHAR Reserved2[3];
2841 } MODE_DISCONNECT_PAGE, *PMODE_DISCONNECT_PAGE;
2842 
2843 typedef struct _MODE_CACHING_PAGE {
2844   UCHAR PageCode:6;
2845   UCHAR Reserved:1;
2846   UCHAR PageSavable:1;
2847   UCHAR PageLength;
2848   UCHAR ReadDisableCache:1;
2849   UCHAR MultiplicationFactor:1;
2850   UCHAR WriteCacheEnable:1;
2851   UCHAR Reserved2:5;
2852   UCHAR WriteRetensionPriority:4;
2853   UCHAR ReadRetensionPriority:4;
2854   UCHAR DisablePrefetchTransfer[2];
2855   UCHAR MinimumPrefetch[2];
2856   UCHAR MaximumPrefetch[2];
2857   UCHAR MaximumPrefetchCeiling[2];
2858 } MODE_CACHING_PAGE, *PMODE_CACHING_PAGE;
2859 
2860 typedef struct _MODE_CDROM_WRITE_PARAMETERS_PAGE2 {
2861   UCHAR PageCode:6;
2862   UCHAR Reserved:1;
2863   UCHAR PageSavable:1;
2864   UCHAR PageLength;
2865   UCHAR WriteType:4;
2866   UCHAR TestWrite:1;
2867   UCHAR LinkSizeValid:1;
2868   UCHAR BufferUnderrunFreeEnabled:1;
2869   UCHAR Reserved2:1;
2870   UCHAR TrackMode:4;
2871   UCHAR Copy:1;
2872   UCHAR FixedPacket:1;
2873   UCHAR MultiSession:2;
2874   UCHAR DataBlockType:4;
2875   UCHAR Reserved3:4;
2876   UCHAR LinkSize;
2877   UCHAR Reserved4;
2878   UCHAR HostApplicationCode:6;
2879   UCHAR Reserved5:2;
2880   UCHAR SessionFormat;
2881   UCHAR Reserved6;
2882   UCHAR PacketSize[4];
2883   UCHAR AudioPauseLength[2];
2884   UCHAR MediaCatalogNumber[16];
2885   UCHAR ISRC[16];
2886   UCHAR SubHeaderData[4];
2887 } MODE_CDROM_WRITE_PARAMETERS_PAGE2, *PMODE_CDROM_WRITE_PARAMETERS_PAGE2;
2888 
2889 typedef struct _MODE_MRW_PAGE {
2890   UCHAR PageCode:6;
2891   UCHAR Reserved:1;
2892   UCHAR PageSavable:1;
2893   UCHAR PageLength;
2894   UCHAR Reserved1;
2895   UCHAR LbaSpace:1;
2896   UCHAR Reserved2:7;
2897   UCHAR Reserved3[4];
2898 } MODE_MRW_PAGE, *PMODE_MRW_PAGE;
2899 
2900 typedef struct _MODE_FLEXIBLE_DISK_PAGE {
2901   UCHAR PageCode:6;
2902   UCHAR Reserved:1;
2903   UCHAR PageSavable:1;
2904   UCHAR PageLength;
2905   UCHAR TransferRate[2];
2906   UCHAR NumberOfHeads;
2907   UCHAR SectorsPerTrack;
2908   UCHAR BytesPerSector[2];
2909   UCHAR NumberOfCylinders[2];
2910   UCHAR StartWritePrecom[2];
2911   UCHAR StartReducedCurrent[2];
2912   UCHAR StepRate[2];
2913   UCHAR StepPluseWidth;
2914   UCHAR HeadSettleDelay[2];
2915   UCHAR MotorOnDelay;
2916   UCHAR MotorOffDelay;
2917   UCHAR Reserved2:5;
2918   UCHAR MotorOnAsserted:1;
2919   UCHAR StartSectorNumber:1;
2920   UCHAR TrueReadySignal:1;
2921   UCHAR StepPlusePerCyclynder:4;
2922   UCHAR Reserved3:4;
2923   UCHAR WriteCompenstation;
2924   UCHAR HeadLoadDelay;
2925   UCHAR HeadUnloadDelay;
2926   UCHAR Pin2Usage:4;
2927   UCHAR Pin34Usage:4;
2928   UCHAR Pin1Usage:4;
2929   UCHAR Pin4Usage:4;
2930   UCHAR MediumRotationRate[2];
2931   UCHAR Reserved4[2];
2932 } MODE_FLEXIBLE_DISK_PAGE, *PMODE_FLEXIBLE_DISK_PAGE;
2933 
2934 typedef struct _MODE_FORMAT_PAGE {
2935   UCHAR PageCode:6;
2936   UCHAR Reserved:1;
2937   UCHAR PageSavable:1;
2938   UCHAR PageLength;
2939   UCHAR TracksPerZone[2];
2940   UCHAR AlternateSectorsPerZone[2];
2941   UCHAR AlternateTracksPerZone[2];
2942   UCHAR AlternateTracksPerLogicalUnit[2];
2943   UCHAR SectorsPerTrack[2];
2944   UCHAR BytesPerPhysicalSector[2];
2945   UCHAR Interleave[2];
2946   UCHAR TrackSkewFactor[2];
2947   UCHAR CylinderSkewFactor[2];
2948   UCHAR Reserved2:4;
2949   UCHAR SurfaceFirst:1;
2950   UCHAR RemovableMedia:1;
2951   UCHAR HardSectorFormating:1;
2952   UCHAR SoftSectorFormating:1;
2953   UCHAR Reserved3[3];
2954 } MODE_FORMAT_PAGE, *PMODE_FORMAT_PAGE;
2955 
2956 typedef struct _MODE_RIGID_GEOMETRY_PAGE {
2957   UCHAR PageCode:6;
2958   UCHAR Reserved:1;
2959   UCHAR PageSavable:1;
2960   UCHAR PageLength;
2961   UCHAR NumberOfCylinders[3];
2962   UCHAR NumberOfHeads;
2963   UCHAR StartWritePrecom[3];
2964   UCHAR StartReducedCurrent[3];
2965   UCHAR DriveStepRate[2];
2966   UCHAR LandZoneCyclinder[3];
2967   UCHAR RotationalPositionLock:2;
2968   UCHAR Reserved2:6;
2969   UCHAR RotationOffset;
2970   UCHAR Reserved3;
2971   UCHAR RoataionRate[2];
2972   UCHAR Reserved4[2];
2973 } MODE_RIGID_GEOMETRY_PAGE, *PMODE_RIGID_GEOMETRY_PAGE;
2974 
2975 typedef struct _MODE_READ_WRITE_RECOVERY_PAGE {
2976   UCHAR PageCode:6;
2977   UCHAR Reserved1:1;
2978   UCHAR PSBit:1;
2979   UCHAR PageLength;
2980   UCHAR DCRBit:1;
2981   UCHAR DTEBit:1;
2982   UCHAR PERBit:1;
2983   UCHAR EERBit:1;
2984   UCHAR RCBit:1;
2985   UCHAR TBBit:1;
2986   UCHAR ARRE:1;
2987   UCHAR AWRE:1;
2988   UCHAR ReadRetryCount;
2989   UCHAR Reserved4[4];
2990   UCHAR WriteRetryCount;
2991   UCHAR Reserved5[3];
2992 } MODE_READ_WRITE_RECOVERY_PAGE, *PMODE_READ_WRITE_RECOVERY_PAGE;
2993 
2994 typedef struct _MODE_READ_RECOVERY_PAGE {
2995   UCHAR PageCode:6;
2996   UCHAR Reserved1:1;
2997   UCHAR PSBit:1;
2998   UCHAR PageLength;
2999   UCHAR DCRBit:1;
3000   UCHAR DTEBit:1;
3001   UCHAR PERBit:1;
3002   UCHAR Reserved2:1;
3003   UCHAR RCBit:1;
3004   UCHAR TBBit:1;
3005   UCHAR Reserved3:2;
3006   UCHAR ReadRetryCount;
3007   UCHAR Reserved4[4];
3008 } MODE_READ_RECOVERY_PAGE, *PMODE_READ_RECOVERY_PAGE;
3009 
3010 typedef struct _MODE_INFO_EXCEPTIONS {
3011   UCHAR PageCode:6;
3012   UCHAR Reserved1:1;
3013   UCHAR PSBit:1;
3014   UCHAR PageLength;
3015   _ANONYMOUS_UNION union {
3016     UCHAR Flags;
3017     _ANONYMOUS_STRUCT struct {
3018       UCHAR LogErr:1;
3019       UCHAR Reserved2:1;
3020       UCHAR Test:1;
3021       UCHAR Dexcpt:1;
3022       UCHAR Reserved3:3;
3023       UCHAR Perf:1;
3024     } DUMMYSTRUCTNAME;
3025   } DUMMYUNIONNAME;
3026   UCHAR ReportMethod:4;
3027   UCHAR Reserved4:4;
3028   UCHAR IntervalTimer[4];
3029   UCHAR ReportCount[4];
3030 } MODE_INFO_EXCEPTIONS, *PMODE_INFO_EXCEPTIONS;
3031 
3032 typedef struct _POWER_CONDITION_PAGE {
3033   UCHAR PageCode:6;
3034   UCHAR Reserved:1;
3035   UCHAR PSBit:1;
3036   UCHAR PageLength;
3037   UCHAR Reserved2;
3038   UCHAR Standby:1;
3039   UCHAR Idle:1;
3040   UCHAR Reserved3:6;
3041   UCHAR IdleTimer[4];
3042   UCHAR StandbyTimer[4];
3043 } POWER_CONDITION_PAGE, *PPOWER_CONDITION_PAGE;
3044 
3045 typedef struct _CDDA_OUTPUT_PORT {
3046   UCHAR ChannelSelection:4;
3047   UCHAR Reserved:4;
3048   UCHAR Volume;
3049 } CDDA_OUTPUT_PORT, *PCDDA_OUTPUT_PORT;
3050 
3051 typedef struct _CDAUDIO_CONTROL_PAGE {
3052   UCHAR PageCode:6;
3053   UCHAR Reserved:1;
3054   UCHAR PSBit:1;
3055   UCHAR PageLength;
3056   UCHAR Reserved2:1;
3057   UCHAR StopOnTrackCrossing:1;
3058   UCHAR Immediate:1;
3059   UCHAR Reserved3:5;
3060   UCHAR Reserved4[3];
3061   UCHAR Obsolete[2];
3062   CDDA_OUTPUT_PORT CDDAOutputPorts[4];
3063 } CDAUDIO_CONTROL_PAGE, *PCDAUDIO_CONTROL_PAGE;
3064 
3065 typedef struct _CDVD_FEATURE_SET_PAGE {
3066   UCHAR PageCode:6;
3067   UCHAR Reserved:1;
3068   UCHAR PSBit:1;
3069   UCHAR PageLength;
3070   UCHAR CDAudio[2];
3071   UCHAR EmbeddedChanger[2];
3072   UCHAR PacketSMART[2];
3073   UCHAR PersistantPrevent[2];
3074   UCHAR EventStatusNotification[2];
3075   UCHAR DigitalOutput[2];
3076   UCHAR CDSequentialRecordable[2];
3077   UCHAR DVDSequentialRecordable[2];
3078   UCHAR RandomRecordable[2];
3079   UCHAR KeyExchange[2];
3080   UCHAR Reserved2[2];
3081 } CDVD_FEATURE_SET_PAGE, *PCDVD_FEATURE_SET_PAGE;
3082 
3083 typedef struct _CDVD_INACTIVITY_TIMEOUT_PAGE {
3084   UCHAR PageCode:6;
3085   UCHAR Reserved:1;
3086   UCHAR PSBit:1;
3087   UCHAR PageLength;
3088   UCHAR Reserved2[2];
3089   UCHAR SWPP:1;
3090   UCHAR DISP:1;
3091   UCHAR Reserved3:6;
3092   UCHAR Reserved4;
3093   UCHAR GroupOneMinimumTimeout[2];
3094   UCHAR GroupTwoMinimumTimeout[2];
3095 } CDVD_INACTIVITY_TIMEOUT_PAGE, *PCDVD_INACTIVITY_TIMEOUT_PAGE;
3096 
3097 typedef struct _CDVD_CAPABILITIES_PAGE {
3098   UCHAR PageCode:6;
3099   UCHAR Reserved:1;
3100   UCHAR PSBit:1;
3101   UCHAR PageLength;
3102   UCHAR CDRRead:1;
3103   UCHAR CDERead:1;
3104   UCHAR Method2:1;
3105   UCHAR DVDROMRead:1;
3106   UCHAR DVDRRead:1;
3107   UCHAR DVDRAMRead:1;
3108   UCHAR Reserved2:2;
3109   UCHAR CDRWrite:1;
3110   UCHAR CDEWrite:1;
3111   UCHAR TestWrite:1;
3112   UCHAR Reserved3:1;
3113   UCHAR DVDRWrite:1;
3114   UCHAR DVDRAMWrite:1;
3115   UCHAR Reserved4:2;
3116   UCHAR AudioPlay:1;
3117   UCHAR Composite:1;
3118   UCHAR DigitalPortOne:1;
3119   UCHAR DigitalPortTwo:1;
3120   UCHAR Mode2Form1:1;
3121   UCHAR Mode2Form2:1;
3122   UCHAR MultiSession:1;
3123   UCHAR BufferUnderrunFree:1;
3124   UCHAR CDDA:1;
3125   UCHAR CDDAAccurate:1;
3126   UCHAR RWSupported:1;
3127   UCHAR RWDeinterleaved:1;
3128   UCHAR C2Pointers:1;
3129   UCHAR ISRC:1;
3130   UCHAR UPC:1;
3131   UCHAR ReadBarCodeCapable:1;
3132   UCHAR Lock:1;
3133   UCHAR LockState:1;
3134   UCHAR PreventJumper:1;
3135   UCHAR Eject:1;
3136   UCHAR Reserved6:1;
3137   UCHAR LoadingMechanismType:3;
3138   UCHAR SeparateVolume:1;
3139   UCHAR SeperateChannelMute:1;
3140   UCHAR SupportsDiskPresent:1;
3141   UCHAR SWSlotSelection:1;
3142   UCHAR SideChangeCapable:1;
3143   UCHAR RWInLeadInReadable:1;
3144   UCHAR Reserved7:2;
3145   _ANONYMOUS_UNION union {
3146     UCHAR ReadSpeedMaximum[2];
3147     UCHAR ObsoleteReserved[2];
3148   } DUMMYUNIONNAME;
3149   UCHAR NumberVolumeLevels[2];
3150   UCHAR BufferSize[2];
3151   _ANONYMOUS_UNION union {
3152     UCHAR ReadSpeedCurrent[2];
3153     UCHAR ObsoleteReserved2[2];
3154   } DUMMYUNIONNAME2;
3155   UCHAR ObsoleteReserved3;
3156   UCHAR Reserved8:1;
3157   UCHAR BCK:1;
3158   UCHAR RCK:1;
3159   UCHAR LSBF:1;
3160   UCHAR Length:2;
3161   UCHAR Reserved9:2;
3162   _ANONYMOUS_UNION union {
3163     UCHAR WriteSpeedMaximum[2];
3164     UCHAR ObsoleteReserved4[2];
3165   } DUMMYUNIONNAME3;
3166   _ANONYMOUS_UNION union {
3167     UCHAR WriteSpeedCurrent[2];
3168     UCHAR ObsoleteReserved11[2];
3169   } DUMMYUNIONNAME4;
3170   _ANONYMOUS_UNION union {
3171     UCHAR CopyManagementRevision[2];
3172     UCHAR Reserved10[2];
3173   } DUMMYUNIONNAME5;
3174 } CDVD_CAPABILITIES_PAGE, *PCDVD_CAPABILITIES_PAGE;
3175 
3176 typedef struct _LUN_LIST {
3177   UCHAR LunListLength[4];
3178   UCHAR Reserved[4];
3179   UCHAR Lun[0][8];
3180 } LUN_LIST, *PLUN_LIST;
3181 
3182 typedef struct _MODE_PARM_READ_WRITE {
3183   MODE_PARAMETER_HEADER ParameterListHeader;
3184   MODE_PARAMETER_BLOCK ParameterListBlock;
3185 } MODE_PARM_READ_WRITE_DATA, *PMODE_PARM_READ_WRITE_DATA;
3186 
3187 typedef struct _PORT_OUTPUT {
3188   UCHAR ChannelSelection;
3189   UCHAR Volume;
3190 } PORT_OUTPUT, *PPORT_OUTPUT;
3191 
3192 typedef struct _AUDIO_OUTPUT {
3193   UCHAR CodePage;
3194   UCHAR ParameterLength;
3195   UCHAR Immediate;
3196   UCHAR Reserved[2];
3197   UCHAR LbaFormat;
3198   UCHAR LogicalBlocksPerSecond[2];
3199   PORT_OUTPUT PortOutput[4];
3200 } AUDIO_OUTPUT, *PAUDIO_OUTPUT;
3201 
3202 /* Atapi 2.5 changers */
3203 typedef struct _MECHANICAL_STATUS_INFORMATION_HEADER {
3204   UCHAR CurrentSlot:5;
3205   UCHAR ChangerState:2;
3206   UCHAR Fault:1;
3207   UCHAR Reserved:5;
3208   UCHAR MechanismState:3;
3209   UCHAR CurrentLogicalBlockAddress[3];
3210   UCHAR NumberAvailableSlots;
3211   UCHAR SlotTableLength[2];
3212 } MECHANICAL_STATUS_INFORMATION_HEADER, *PMECHANICAL_STATUS_INFORMATION_HEADER;
3213 
3214 typedef struct _SLOT_TABLE_INFORMATION {
3215   UCHAR DiscChanged:1;
3216   UCHAR Reserved:6;
3217   UCHAR DiscPresent:1;
3218   UCHAR Reserved2[3];
3219 } SLOT_TABLE_INFORMATION, *PSLOT_TABLE_INFORMATION;
3220 
3221 typedef struct _MECHANICAL_STATUS {
3222   MECHANICAL_STATUS_INFORMATION_HEADER MechanicalStatusHeader;
3223   SLOT_TABLE_INFORMATION SlotTableInfo[1];
3224 } MECHANICAL_STATUS, *PMECHANICAL_STATUS;
3225 
3226 /* Tape definitions */
3227 typedef struct _TAPE_POSITION_DATA {
3228   UCHAR Reserved1:2;
3229   UCHAR BlockPositionUnsupported:1;
3230   UCHAR Reserved2:3;
3231   UCHAR EndOfPartition:1;
3232   UCHAR BeginningOfPartition:1;
3233   UCHAR PartitionNumber;
3234   USHORT Reserved3;
3235   UCHAR FirstBlock[4];
3236   UCHAR LastBlock[4];
3237   UCHAR Reserved4;
3238   UCHAR NumberOfBlocks[3];
3239   UCHAR NumberOfBytes[4];
3240 } TAPE_POSITION_DATA, *PTAPE_POSITION_DATA;
3241 
3242 #include <pshpack1.h>
3243 typedef struct _UNMAP_BLOCK_DESCRIPTOR {
3244   UCHAR StartingLba[8];
3245   UCHAR LbaCount[4];
3246   UCHAR Reserved[4];
3247 } UNMAP_BLOCK_DESCRIPTOR, *PUNMAP_BLOCK_DESCRIPTOR;
3248 
3249 typedef struct _UNMAP_LIST_HEADER {
3250   UCHAR DataLength[2];
3251   UCHAR BlockDescrDataLength[2];
3252   UCHAR Reserved[4];
3253 #if !defined(__midl)
3254   UNMAP_BLOCK_DESCRIPTOR Descriptors[0];
3255 #endif
3256 } UNMAP_LIST_HEADER, *PUNMAP_LIST_HEADER;
3257 #include <poppack.h>
3258 
3259 #define LOG_PAGE_CODE_SUPPORTED_LOG_PAGES           0x00
3260 #define LOG_PAGE_CODE_WRITE_ERROR_COUNTERS          0x02
3261 #define LOG_PAGE_CODE_READ_ERROR_COUNTERS           0x03
3262 #define LOG_PAGE_CODE_LOGICAL_BLOCK_PROVISIONING    0x0C
3263 #define LOG_PAGE_CODE_TEMPERATURE                   0x0D
3264 #define LOG_PAGE_CODE_STARTSTOP_CYCLE_COUNTERS      0x0E
3265 #define LOG_PAGE_CODE_SELFTEST_RESULTS              0x10
3266 #define LOG_PAGE_CODE_SOLID_STATE_MEDIA             0x11
3267 #define LOG_PAGE_CODE_BACKGROUND_SCAN_RESULTS       0x15
3268 #define LOG_PAGE_CODE_INFORMATIONAL_EXCEPTIONS      0x2F
3269 
3270 
3271 #include <pshpack1.h>
3272 typedef struct _LOG_PARAMETER_HEADER {
3273   UCHAR ParameterCode[2];
3274   union {
3275     UCHAR ControlByte;
3276     struct {
3277       UCHAR FormatAndLinking:2;
3278       UCHAR TMC:2;
3279       UCHAR ETC:1;
3280       UCHAR TSD:1;
3281       UCHAR Obsolete:1;
3282       UCHAR DU:1;
3283     };
3284   };
3285   UCHAR ParameterLength;
3286 } LOG_PARAMETER_HEADER, *PLOG_PARAMETER_HEADER;
3287 
3288 typedef struct _LOG_PARAMETER {
3289   LOG_PARAMETER_HEADER Header;
3290   union {
3291 #if !defined(__midl)
3292     UCHAR AsByte[0];
3293 #endif
3294     struct _THRESHOLD_RESOURCE_COUNT {
3295       UCHAR ResourceCount[4];
3296       UCHAR Scope : 2;
3297       UCHAR Reserved1 : 6;
3298       UCHAR Reserved2[3];
3299     } THRESHOLD_RESOURCE_COUNT;
3300     struct _TEMPERATURE {
3301       UCHAR Reserved;
3302       UCHAR Temperature;
3303     } TEMPERATURE;
3304     struct _DATE_OF_MANUFACTURE {
3305       UCHAR Year[4];
3306       UCHAR Week[2];
3307     } DATE_OF_MANUFACTURE;
3308     struct _SELF_TEST_RESULTS {
3309       UCHAR SelfTestResults : 4;
3310       UCHAR Reserved1 : 1;
3311       UCHAR SelfTestCode : 3;
3312       UCHAR SelfTestNumber;
3313       UCHAR PowerOnHours[2];
3314       UCHAR AddressOfFirstFailure[8];
3315       UCHAR SenseKey : 4;
3316       UCHAR Reserved2 : 4;
3317       UCHAR AdditionalSenseCode;
3318       UCHAR AdditionalSenseCodeQualifier;
3319       UCHAR VendorSpecific;
3320     } SELF_TEST_RESULTS;
3321 
3322     struct _SOLID_STATE_MEDIA {
3323       UCHAR Reserved[3];
3324       UCHAR PercentageUsed;
3325     } SOLID_STATE_MEDIA;
3326 
3327     struct _BACKGROUND_SCAN_STATUS {
3328       UCHAR PowerOnMinutes[4];
3329       UCHAR Reserved;
3330       UCHAR ScanStatus;
3331       UCHAR ScansPerformed[2];
3332       UCHAR ScanProgress[2];
3333       UCHAR MediumScansPerformed[2];
3334     } BACKGROUND_SCAN_STATUS;
3335 
3336     struct _INFORMATIONAL_EXCEPTIONS {
3337       UCHAR ASC;
3338       UCHAR ASCQ;
3339       UCHAR MostRecentTemperature;
3340       UCHAR VendorSpecific[ANYSIZE_ARRAY];
3341     } INFORMATIONAL_EXCEPTIONS;
3342   };
3343 } LOG_PARAMETER, *PLOG_PARAMETER;
3344 
3345 typedef struct _LOG_PAGE {
3346   UCHAR PageCode:6;
3347   UCHAR SPF:1;
3348   UCHAR DS:1;
3349   UCHAR SubPageCode;
3350   UCHAR PageLength[2];
3351 #if !defined(__midl)
3352   LOG_PARAMETER Parameters[0];
3353 #endif
3354 
3355 } LOG_PAGE, *PLOG_PAGE;
3356 
3357 #include <poppack.h>
3358 
3359 #define LOG_PAGE_LBP_PARAMETER_CODE_AVAILABLE   0x1
3360 #define LOG_PAGE_LBP_PARAMETER_CODE_USED        0x2
3361 
3362 #define LOG_PAGE_LBP_RESOURCE_SCOPE_NOT_REPORTED            0x0
3363 #define LOG_PAGE_LBP_RESOURCE_SCOPE_DEDICATED_TO_LUN        0x1
3364 #define LOG_PAGE_LBP_RESOURCE_SCOPE_NOT_DEDICATED_TO_LUN    0x2
3365 
3366 typedef struct _LOG_PARAMETER_THRESHOLD_RESOURCE_COUNT {
3367   LOG_PARAMETER_HEADER Header;
3368   UCHAR ResourceCount[4];
3369   UCHAR Scope:2;
3370   UCHAR Reserved0:6;
3371   UCHAR Reserved1[3];
3372 } LOG_PARAMETER_THRESHOLD_RESOURCE_COUNT, *PLOG_PARAMETER_THRESHOLD_RESOURCE_COUNT;
3373 
3374 typedef struct _LOG_PAGE_LOGICAL_BLOCK_PROVISIONING {
3375   UCHAR PageCode:6;
3376   UCHAR SPF:1;
3377   UCHAR DS:1;
3378   UCHAR SubPageCode;
3379   UCHAR PageLength[2];
3380 #if !defined(__midl)
3381   LOG_PARAMETER_HEADER Parameters[0];
3382 #endif
3383 } LOG_PAGE_LOGICAL_BLOCK_PROVISIONING, *PLOG_PAGE_LOGICAL_BLOCK_PROVISIONING;
3384 
3385 typedef struct _MODE_CONTROL_PAGE {
3386   UCHAR PageCode:6;
3387   UCHAR Reserved1:1;
3388   UCHAR PageSavable:1;
3389   UCHAR PageLength;
3390   UCHAR RLEC:1;
3391   UCHAR GLTSD:1;
3392   UCHAR D_SENSE:1;
3393   UCHAR DPICZ:1;
3394   UCHAR TMF_ONLY:1;
3395   UCHAR TST:3;
3396   UCHAR Obsolete1:1;
3397   UCHAR QERR:2;
3398   UCHAR NUAR:1;
3399   UCHAR QueueAlgorithmModifier:4;
3400   UCHAR Obsolete2:3;
3401   UCHAR SWP:1;
3402   UCHAR UA_INTLCK_CTRL:2;
3403   UCHAR RAC:1;
3404   UCHAR VS:1;
3405   UCHAR AutoloadMode:3;
3406   UCHAR Reserved2:1;
3407   UCHAR RWWP:1;
3408   UCHAR ATMPE:1;
3409   UCHAR TAS:1;
3410   UCHAR ATO:1;
3411   UCHAR Obsolete3[2];
3412   UCHAR BusyTimeoutPeriod[2];
3413   UCHAR ExtendeSelfTestCompletionTime[2];
3414 } MODE_CONTROL_PAGE, *PMODE_CONTROL_PAGE;
3415 
3416 /* This structure is used to convert little endian ULONGs
3417    to SCSI CDB big endians values. */
3418 typedef union _EIGHT_BYTE {
3419   _ANONYMOUS_STRUCT struct {
3420     UCHAR Byte0;
3421     UCHAR Byte1;
3422     UCHAR Byte2;
3423     UCHAR Byte3;
3424     UCHAR Byte4;
3425     UCHAR Byte5;
3426     UCHAR Byte6;
3427     UCHAR Byte7;
3428   } DUMMYSTRUCTNAME;
3429   ULONGLONG AsULongLong;
3430 } EIGHT_BYTE, *PEIGHT_BYTE;
3431 
3432 typedef union _FOUR_BYTE {
3433   _ANONYMOUS_STRUCT struct {
3434     UCHAR Byte0;
3435     UCHAR Byte1;
3436     UCHAR Byte2;
3437     UCHAR Byte3;
3438   } DUMMYSTRUCTNAME;
3439   ULONG AsULong;
3440 } FOUR_BYTE, *PFOUR_BYTE;
3441 
3442 typedef union _TWO_BYTE {
3443   _ANONYMOUS_STRUCT struct {
3444     UCHAR Byte0;
3445     UCHAR Byte1;
3446   } DUMMYSTRUCTNAME;
3447   USHORT AsUShort;
3448 } TWO_BYTE, *PTWO_BYTE;
3449 
3450 /* Byte reversing macro for converting between
3451    big- and little-endian formats */
3452 #define REVERSE_BYTES_QUAD(Destination, Source) { \
3453   PEIGHT_BYTE _val1 = (PEIGHT_BYTE)(Destination); \
3454   PEIGHT_BYTE _val2 = (PEIGHT_BYTE)(Source); \
3455   _val1->Byte7 = _val2->Byte0; \
3456   _val1->Byte6 = _val2->Byte1; \
3457   _val1->Byte5 = _val2->Byte2; \
3458   _val1->Byte4 = _val2->Byte3; \
3459   _val1->Byte3 = _val2->Byte4; \
3460   _val1->Byte2 = _val2->Byte5; \
3461   _val1->Byte1 = _val2->Byte6; \
3462   _val1->Byte0 = _val2->Byte7; \
3463 }
3464 
3465 #define REVERSE_BYTES(Destination, Source) { \
3466   PFOUR_BYTE _val1 = (PFOUR_BYTE)(Destination); \
3467   PFOUR_BYTE _val2 = (PFOUR_BYTE)(Source); \
3468   _val1->Byte3 = _val2->Byte0; \
3469   _val1->Byte2 = _val2->Byte1; \
3470   _val1->Byte1 = _val2->Byte2; \
3471   _val1->Byte0 = _val2->Byte3; \
3472 }
3473 
3474 #define REVERSE_BYTES_SHORT(Destination, Source) { \
3475   PTWO_BYTE _val1 = (PTWO_BYTE)(Destination); \
3476   PTWO_BYTE _val2 = (PTWO_BYTE)(Source); \
3477   _val1->Byte1 = _val2->Byte0; \
3478   _val1->Byte0 = _val2->Byte1; \
3479 }
3480 
3481 #define REVERSE_SHORT(Short) { \
3482   UCHAR _val; \
3483   PTWO_BYTE _val2 = (PTWO_BYTE)(Short); \
3484   _val = _val2->Byte0; \
3485   _val2->Byte0 = _val2->Byte1; \
3486   _val2->Byte1 = _val; \
3487 }
3488 
3489 #define REVERSE_LONG(Long) { \
3490   UCHAR _val; \
3491   PFOUR_BYTE _val2 = (PFOUR_BYTE)(Long); \
3492   _val = _val2->Byte3; \
3493   _val2->Byte3 = _val2->Byte0; \
3494   _val2->Byte0 = _val; \
3495   _val = _val2->Byte2; \
3496   _val2->Byte2 = _val2->Byte1; \
3497   _val2->Byte1 = _val; \
3498 }
3499 
3500 #define WHICH_BIT(Data, Bit) { \
3501   UCHAR _val; \
3502   for (_val = 0; _val < 32; _val++) { \
3503     if (((Data) >> _val) == 1) { \
3504       break; \
3505     } \
3506   } \
3507   ASSERT(_val != 32); \
3508   (Bit) = _val; \
3509 }
3510 
3511 #if defined(_WIN64)
3512 #define STOR_ADDRESS_ALIGN           DECLSPEC_ALIGN(8)
3513 #else
3514 #define STOR_ADDRESS_ALIGN
3515 #endif
3516 
3517 typedef struct STOR_ADDRESS_ALIGN _STOR_ADDRESS {
3518   USHORT Type;
3519   USHORT Port;
3520   ULONG AddressLength;
3521   _Field_size_bytes_(AddressLength) UCHAR AddressData[ANYSIZE_ARRAY];
3522 } STOR_ADDRESS, *PSTOR_ADDRESS;
3523 
3524 #define STOR_ADDRESS_TYPE_UNKNOWN   0x0
3525 #define STOR_ADDRESS_TYPE_BTL8      0x1
3526 #define STOR_ADDRESS_TYPE_MAX       0xffff
3527 
3528 #define STOR_ADDR_BTL8_ADDRESS_LENGTH    4
3529 
3530 typedef struct STOR_ADDRESS_ALIGN _STOR_ADDR_BTL8 {
3531   _Field_range_(STOR_ADDRESS_TYPE_BTL8, STOR_ADDRESS_TYPE_BTL8)
3532   USHORT Type;
3533   USHORT Port;
3534   _Field_range_(STOR_ADDR_BTL8_ADDRESS_LENGTH, STOR_ADDR_BTL8_ADDRESS_LENGTH)
3535   ULONG AddressLength;
3536   UCHAR Path;
3537   UCHAR Target;
3538   UCHAR Lun;
3539   UCHAR Reserved;
3540 } STOR_ADDR_BTL8, *PSTOR_ADDR_BTL8;
3541 
3542 /* FIXME : This structure doesn't exist in the official header */
3543 typedef struct _MODE_CDROM_WRITE_PARAMETERS_PAGE {
3544   UCHAR PageLength;
3545   UCHAR WriteType:4;
3546   UCHAR TestWrite:1;
3547   UCHAR LinkSizeValid:1;
3548   UCHAR BufferUnderrunFreeEnabled:1;
3549   UCHAR Reserved2:1;
3550   UCHAR TrackMode:4;
3551   UCHAR Copy:1;
3552   UCHAR FixedPacket:1;
3553   UCHAR MultiSession:2;
3554   UCHAR DataBlockType:4;
3555   UCHAR Reserved3:4;
3556   UCHAR LinkSize;
3557   UCHAR Reserved4;
3558   UCHAR HostApplicationCode:6;
3559   UCHAR Reserved5:2;
3560   UCHAR SessionFormat;
3561   UCHAR Reserved6;
3562   UCHAR PacketSize[4];
3563   UCHAR AudioPauseLength[2];
3564   UCHAR Reserved7:7;
3565   UCHAR MediaCatalogNumberValid:1;
3566   UCHAR MediaCatalogNumber[13];
3567   UCHAR MediaCatalogNumberZero;
3568   UCHAR MediaCatalogNumberAFrame;
3569   UCHAR Reserved8:7;
3570   UCHAR ISRCValid:1;
3571   UCHAR ISRCCountry[2];
3572   UCHAR ISRCOwner[3];
3573   UCHAR ISRCRecordingYear[2];
3574   UCHAR ISRCSerialNumber[5];
3575   UCHAR ISRCZero;
3576   UCHAR ISRCAFrame;
3577   UCHAR ISRCReserved;
3578   UCHAR SubHeaderData[4];
3579 } MODE_CDROM_WRITE_PARAMETERS_PAGE, *PMODE_CDROM_WRITE_PARAMETERS_PAGE;
3580 
3581 #if (NTDDI_VERSION >= NTDDI_WIN8)
3582 #include <pshpack1.h>
3583 
3584 #define BLOCK_DEVICE_TOKEN_SIZE         512
3585 
3586 typedef struct {
3587   UCHAR LogicalBlockAddress[8];
3588   UCHAR TransferLength[4];
3589   UCHAR Reserved[4];
3590 } BLOCK_DEVICE_RANGE_DESCRIPTOR, *PBLOCK_DEVICE_RANGE_DESCRIPTOR;
3591 
3592 typedef struct {
3593   UCHAR PopulateTokenDataLength[2];
3594   UCHAR Immediate:1;
3595   UCHAR Reserved1:7;
3596   UCHAR Reserved2;
3597   UCHAR InactivityTimeout[4];
3598   UCHAR Reserved3[6];
3599   UCHAR BlockDeviceRangeDescriptorListLength[2];
3600 #if !defined(__midl)
3601   UCHAR BlockDeviceRangeDescriptor[ANYSIZE_ARRAY];
3602 #endif
3603 } POPULATE_TOKEN_HEADER, *PPOPULATE_TOKEN_HEADER;
3604 
3605 typedef struct {
3606   UCHAR WriteUsingTokenDataLength[2];
3607   UCHAR Immediate:1;
3608   UCHAR Reserved1:7;
3609   UCHAR Reserved2[5];
3610   UCHAR BlockOffsetIntoToken[8];
3611   UCHAR Token[BLOCK_DEVICE_TOKEN_SIZE];
3612   UCHAR Reserved3[6];
3613   UCHAR BlockDeviceRangeDescriptorListLength[2];
3614 #if !defined(__midl)
3615   UCHAR BlockDeviceRangeDescriptor[ANYSIZE_ARRAY];
3616 #endif
3617 } WRITE_USING_TOKEN_HEADER, *PWRITE_USING_TOKEN_HEADER;
3618 
3619 typedef struct {
3620   UCHAR AvailableData[4];
3621   UCHAR ResponseToServiceAction:5;
3622   UCHAR Reserved1:3;
3623   UCHAR OperationStatus:7;
3624   UCHAR Reserved2:1;
3625   UCHAR OperationCounter[2];
3626   UCHAR EstimatedStatusUpdateDelay[4];
3627   UCHAR CompletionStatus;
3628   UCHAR SenseDataFieldLength;
3629   UCHAR SenseDataLength;
3630   UCHAR TransferCountUnits;
3631   UCHAR TransferCount[8];
3632   UCHAR SegmentsProcessed[2];
3633   UCHAR Reserved3[6];
3634 #if !defined(__midl)
3635   UCHAR SenseData[ANYSIZE_ARRAY];
3636 #endif
3637 } RECEIVE_TOKEN_INFORMATION_HEADER, *PRECEIVE_TOKEN_INFORMATION_HEADER;
3638 
3639 typedef struct {
3640   UCHAR TokenDescriptorsLength[4];
3641 #if !defined(__midl)
3642   UCHAR TokenDescriptor[ANYSIZE_ARRAY];
3643 #endif
3644 } RECEIVE_TOKEN_INFORMATION_RESPONSE_HEADER, *PRECEIVE_TOKEN_INFORMATION_RESPONSE_HEADER;
3645 
3646 typedef struct {
3647   UCHAR TokenIdentifier[2];
3648   UCHAR Token[BLOCK_DEVICE_TOKEN_SIZE];
3649 } BLOCK_DEVICE_TOKEN_DESCRIPTOR, *PBLOCK_DEVICE_TOKEN_DESCRIPTOR;
3650 
3651 typedef enum _OPERATION_STATUS {
3652   OPERATION_COMPLETED_WITH_SUCCESS = 0x01,
3653   OPERATION_COMPLETED_WITH_ERROR = 0x02,
3654   OPERATION_COMPLETED_WITH_RESIDUAL_DATA = 0x03,
3655   OPERATION_IN_PROGRESS_IN_FOREGROUND = 0x11,
3656   OPERATION_IN_PROGRESS_IN_BACKGROUND = 0x12,
3657   OPERATION_TERMINATED = 0x60
3658 } OPERATION_STATUS, *POPERATION_STATUS;
3659 
3660 typedef enum _TRANSFER_COUNT_UNITS {
3661   TRANSFER_COUNT_UNITS_BYTES = 0,
3662   TRANSFER_COUNT_UNITS_KIBIBYTES = 1,
3663   TRANSFER_COUNT_UNITS_MEBIBYTES = 2,
3664   TRANSFER_COUNT_UNITS_GIBIBYTES = 3,
3665   TRANSFER_COUNT_UNITS_TEBIBYTES = 4,
3666   TRANSFER_COUNT_UNITS_PEBIBYTES = 5,
3667   TRANSFER_COUNT_UNITS_EXBIBYTES = 6,
3668   TRANSFER_COUNT_UNITS_NUMBER_BLOCKS = 0xF1
3669 } TRANSFER_COUNT_UNITS, *PTRANSFER_COUNT_UNITS;
3670 
3671 #include <poppack.h>
3672 #endif /* (NTDDI_VERSION >= NTDDI_WIN8) */
3673 
3674 // SCSI utility functions
3675 
3676 #define ScsiGetSenseErrorCode(SenseInfoBuffer) (((PUCHAR)(SenseInfoBuffer))[0] & 0x7f)
3677 
3678 #define ScsiGetSenseDescriptorLength(DescriptorBuffer) \
3679             (sizeof(SCSI_SENSE_DESCRIPTOR_HEADER) + ((PSCSI_SENSE_DESCRIPTOR_HEADER)(DescriptorBuffer))->AdditionalLength)
3680 
3681 #define IsFixedSenseDataFormat(SenseInfoBuffer) \
3682             ((ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_FIXED_CURRENT || \
3683              (ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_FIXED_DEFERRED)
3684 
3685 #define IsDescriptorSenseDataFormat(SenseInfoBuffer) \
3686             ((ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_DESCRIPTOR_CURRENT || \
3687              (ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_DESCRIPTOR_DEFERRED)
3688 
3689 #define IsSenseDataCurrentError(SenseInfoBuffer) \
3690             ((ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_FIXED_CURRENT || \
3691              (ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_DESCRIPTOR_CURRENT)
3692 
3693 #define IsSenseDataDeferredError(SenseInfoBuffer) \
3694             ((ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_FIXED_DEFERRED || \
3695              (ScsiGetSenseErrorCode(SenseInfoBuffer)) == SCSI_SENSE_ERRORCODE_DESCRIPTOR_DEFERRED)
3696 
3697 #define IsSenseDataFormatValueValid(SenseInfoBuffer) \
3698             (IsFixedSenseDataFormat(SenseInfoBuffer) || IsDescriptorSenseDataFormat(SenseInfoBuffer))
3699 
3700 _Success_(return != FALSE)
3701 FORCEINLINE
3702 BOOLEAN
ScsiGetTotalSenseByteCountIndicated(_In_reads_bytes_ (SenseInfoBufferLength)PVOID SenseInfoBuffer,_In_ UCHAR SenseInfoBufferLength,_Out_ UCHAR * TotalByteCountIndicated)3703 ScsiGetTotalSenseByteCountIndicated(
3704   _In_reads_bytes_(SenseInfoBufferLength) PVOID SenseInfoBuffer,
3705   _In_ UCHAR SenseInfoBufferLength,
3706   _Out_ UCHAR *TotalByteCountIndicated)
3707 {
3708   BOOLEAN succeed = FALSE;
3709   UCHAR byteCount = 0;
3710   PFIXED_SENSE_DATA senseInfoBuffer = NULL;
3711 
3712   if (SenseInfoBuffer == NULL || SenseInfoBufferLength == 0 || TotalByteCountIndicated == NULL)
3713   {
3714 
3715     return FALSE;
3716   }
3717 
3718   senseInfoBuffer = (PFIXED_SENSE_DATA)SenseInfoBuffer;
3719 
3720   if (RTL_CONTAINS_FIELD(senseInfoBuffer, SenseInfoBufferLength, AdditionalSenseLength))
3721   {
3722 
3723     if (senseInfoBuffer->AdditionalSenseLength <=
3724         (MAX_SENSE_BUFFER_SIZE - RTL_SIZEOF_THROUGH_FIELD(FIXED_SENSE_DATA, AdditionalSenseLength)))
3725     {
3726 
3727       byteCount = senseInfoBuffer->AdditionalSenseLength +
3728                   RTL_SIZEOF_THROUGH_FIELD(FIXED_SENSE_DATA, AdditionalSenseLength);
3729 
3730       *TotalByteCountIndicated = byteCount;
3731 
3732       succeed = TRUE;
3733     }
3734   }
3735 
3736   return succeed;
3737 }
3738 
3739 _Success_(return != FALSE)
3740 FORCEINLINE
3741 BOOLEAN
ScsiGetFixedSenseKeyAndCodes(_In_reads_bytes_ (SenseInfoBufferLength)PVOID SenseInfoBuffer,_In_ UCHAR SenseInfoBufferLength,_Out_opt_ PUCHAR SenseKey,_Out_opt_ PUCHAR AdditionalSenseCode,_Out_opt_ PUCHAR AdditionalSenseCodeQualifier)3742 ScsiGetFixedSenseKeyAndCodes(
3743   _In_reads_bytes_(SenseInfoBufferLength) PVOID SenseInfoBuffer,
3744   _In_ UCHAR SenseInfoBufferLength,
3745   _Out_opt_ PUCHAR SenseKey,
3746   _Out_opt_ PUCHAR AdditionalSenseCode,
3747   _Out_opt_ PUCHAR AdditionalSenseCodeQualifier)
3748 {
3749   PFIXED_SENSE_DATA fixedSenseData = (PFIXED_SENSE_DATA)SenseInfoBuffer;
3750   BOOLEAN succeed = FALSE;
3751   ULONG dataLength = 0;
3752 
3753   if (SenseInfoBuffer == NULL || SenseInfoBufferLength == 0)
3754   {
3755     return FALSE;
3756   }
3757 
3758   if (RTL_CONTAINS_FIELD(fixedSenseData, SenseInfoBufferLength, AdditionalSenseLength))
3759   {
3760 
3761     dataLength = fixedSenseData->AdditionalSenseLength +
3762                  RTL_SIZEOF_THROUGH_FIELD(FIXED_SENSE_DATA, AdditionalSenseLength);
3763 
3764     if (dataLength > SenseInfoBufferLength)
3765     {
3766       dataLength = SenseInfoBufferLength;
3767     }
3768 
3769     if (SenseKey != NULL)
3770     {
3771       *SenseKey = fixedSenseData->SenseKey;
3772     }
3773 
3774     if (AdditionalSenseCode != NULL)
3775     {
3776       *AdditionalSenseCode = RTL_CONTAINS_FIELD(fixedSenseData, dataLength, AdditionalSenseCode)
3777                                  ? fixedSenseData->AdditionalSenseCode
3778                                  : 0;
3779     }
3780 
3781     if (AdditionalSenseCodeQualifier != NULL)
3782     {
3783       *AdditionalSenseCodeQualifier =
3784           RTL_CONTAINS_FIELD(fixedSenseData, dataLength, AdditionalSenseCodeQualifier)
3785               ? fixedSenseData->AdditionalSenseCodeQualifier
3786               : 0;
3787     }
3788 
3789     succeed = TRUE;
3790   }
3791 
3792   return succeed;
3793 }
3794 
3795 _Success_(return != FALSE)
3796 FORCEINLINE
3797 BOOLEAN
ScsiGetDescriptorSenseKeyAndCodes(_In_reads_bytes_ (SenseInfoBufferLength)PVOID SenseInfoBuffer,_In_ UCHAR SenseInfoBufferLength,_Out_opt_ PUCHAR SenseKey,_Out_opt_ PUCHAR AdditionalSenseCode,_Out_opt_ PUCHAR AdditionalSenseCodeQualifier)3798 ScsiGetDescriptorSenseKeyAndCodes(
3799   _In_reads_bytes_(SenseInfoBufferLength) PVOID SenseInfoBuffer,
3800   _In_ UCHAR SenseInfoBufferLength,
3801   _Out_opt_ PUCHAR SenseKey,
3802   _Out_opt_ PUCHAR AdditionalSenseCode,
3803   _Out_opt_ PUCHAR AdditionalSenseCodeQualifier)
3804 {
3805   PDESCRIPTOR_SENSE_DATA descriptorSenseData = (PDESCRIPTOR_SENSE_DATA)SenseInfoBuffer;
3806   BOOLEAN succeed = FALSE;
3807 
3808   if (SenseInfoBuffer == NULL || SenseInfoBufferLength == 0)
3809   {
3810     return FALSE;
3811   }
3812   if (RTL_CONTAINS_FIELD(descriptorSenseData, SenseInfoBufferLength, AdditionalSenseLength))
3813   {
3814 
3815     if (SenseKey)
3816     {
3817       *SenseKey = descriptorSenseData->SenseKey;
3818     }
3819 
3820     if (AdditionalSenseCode != NULL)
3821     {
3822       *AdditionalSenseCode = descriptorSenseData->AdditionalSenseCode;
3823     }
3824 
3825     if (AdditionalSenseCodeQualifier != NULL)
3826     {
3827       *AdditionalSenseCodeQualifier = descriptorSenseData->AdditionalSenseCodeQualifier;
3828     }
3829 
3830     succeed = TRUE;
3831   }
3832 
3833   return succeed;
3834 }
3835 
3836 typedef ULONG SCSI_SENSE_OPTIONS;
3837 
3838 #define SCSI_SENSE_OPTIONS_NONE ((SCSI_SENSE_OPTIONS)0x00000000)
3839 #define SCSI_SENSE_OPTIONS_FIXED_FORMAT_IF_UNKNOWN_FORMAT_INDICATED ((SCSI_SENSE_OPTIONS)0x00000001)
3840 
3841 _Success_(return != FALSE)
3842 FORCEINLINE
3843 BOOLEAN
ScsiGetSenseKeyAndCodes(_In_reads_bytes_ (SenseInfoBufferLength)PVOID SenseInfoBuffer,_In_ UCHAR SenseInfoBufferLength,_In_ SCSI_SENSE_OPTIONS Options,_Out_opt_ PUCHAR SenseKey,_Out_opt_ PUCHAR AdditionalSenseCode,_Out_opt_ PUCHAR AdditionalSenseCodeQualifier)3844 ScsiGetSenseKeyAndCodes(
3845   _In_reads_bytes_(SenseInfoBufferLength) PVOID SenseInfoBuffer,
3846   _In_ UCHAR SenseInfoBufferLength,
3847   _In_ SCSI_SENSE_OPTIONS Options,
3848   _Out_opt_ PUCHAR SenseKey,
3849   _Out_opt_ PUCHAR AdditionalSenseCode,
3850   _Out_opt_ PUCHAR AdditionalSenseCodeQualifier)
3851 {
3852   BOOLEAN succeed = FALSE;
3853 
3854   if (SenseInfoBuffer == NULL || SenseInfoBufferLength == 0)
3855   {
3856     return FALSE;
3857   }
3858 
3859   if (IsDescriptorSenseDataFormat(SenseInfoBuffer))
3860   {
3861     succeed = ScsiGetDescriptorSenseKeyAndCodes(SenseInfoBuffer, SenseInfoBufferLength, SenseKey,
3862                                                 AdditionalSenseCode, AdditionalSenseCodeQualifier);
3863   }
3864   else
3865   {
3866     if ((Options & SCSI_SENSE_OPTIONS_FIXED_FORMAT_IF_UNKNOWN_FORMAT_INDICATED) ||
3867         IsFixedSenseDataFormat(SenseInfoBuffer))
3868     {
3869 
3870       succeed = ScsiGetFixedSenseKeyAndCodes(SenseInfoBuffer, SenseInfoBufferLength, SenseKey,
3871                                              AdditionalSenseCode, AdditionalSenseCodeQualifier);
3872     }
3873   }
3874 
3875   return succeed;
3876 }
3877 
3878 _Success_(return != FALSE)
3879 FORCEINLINE
3880 BOOLEAN
ScsiGetSenseDescriptor(_In_reads_bytes_ (SenseInfoBufferLength)PVOID SenseInfoBuffer,_In_ UCHAR SenseInfoBufferLength,_Outptr_result_bytebuffer_ (* DescriptorBufferLength)PVOID * DescriptorBuffer,_Out_ UCHAR * DescriptorBufferLength)3881 ScsiGetSenseDescriptor(
3882   _In_reads_bytes_(SenseInfoBufferLength) PVOID SenseInfoBuffer,
3883   _In_ UCHAR SenseInfoBufferLength,
3884   _Outptr_result_bytebuffer_(*DescriptorBufferLength) PVOID *DescriptorBuffer,
3885   _Out_ UCHAR *DescriptorBufferLength)
3886 {
3887   PDESCRIPTOR_SENSE_DATA descriptorSenseData;
3888   BOOLEAN succeed = FALSE;
3889   UCHAR dataLength = 0;
3890 
3891   if (SenseInfoBuffer == NULL || SenseInfoBufferLength == 0 || DescriptorBuffer == NULL ||
3892       DescriptorBufferLength == NULL)
3893   {
3894     return FALSE;
3895   }
3896 
3897   *DescriptorBuffer = NULL;
3898   *DescriptorBufferLength = 0;
3899 
3900   if (!IsDescriptorSenseDataFormat(SenseInfoBuffer))
3901   {
3902     return FALSE;
3903   }
3904 
3905   descriptorSenseData = (PDESCRIPTOR_SENSE_DATA)SenseInfoBuffer;
3906 
3907   if (RTL_CONTAINS_FIELD(descriptorSenseData, SenseInfoBufferLength, AdditionalSenseLength))
3908   {
3909     if (descriptorSenseData->AdditionalSenseLength <=
3910         (MAX_SENSE_BUFFER_SIZE -
3911          RTL_SIZEOF_THROUGH_FIELD(DESCRIPTOR_SENSE_DATA, AdditionalSenseLength)))
3912     {
3913       dataLength = descriptorSenseData->AdditionalSenseLength +
3914                    RTL_SIZEOF_THROUGH_FIELD(DESCRIPTOR_SENSE_DATA, AdditionalSenseLength);
3915 
3916       if (dataLength > SenseInfoBufferLength)
3917       {
3918         dataLength = SenseInfoBufferLength;
3919       }
3920 
3921       *DescriptorBufferLength =
3922           dataLength - RTL_SIZEOF_THROUGH_FIELD(DESCRIPTOR_SENSE_DATA, AdditionalSenseLength);
3923 
3924       if (*DescriptorBufferLength > 0)
3925       {
3926         *DescriptorBuffer = (PVOID)(descriptorSenseData->DescriptorBuffer);
3927         succeed = TRUE;
3928       }
3929     }
3930   }
3931 
3932   return succeed;
3933 }
3934 
3935 _Success_(return != FALSE)
3936 FORCEINLINE
3937 BOOLEAN
ScsiValidateInformationSenseDescriptor(_In_reads_bytes_ (DescriptorBufferLength)PVOID DescriptorBuffer,_In_ UCHAR DescriptorBufferLength)3938 ScsiValidateInformationSenseDescriptor(
3939   _In_reads_bytes_(DescriptorBufferLength) PVOID DescriptorBuffer,
3940   _In_ UCHAR DescriptorBufferLength)
3941 {
3942   PSCSI_SENSE_DESCRIPTOR_INFORMATION descriptor;
3943   UCHAR additionalLength;
3944 
3945   if (DescriptorBuffer == NULL ||
3946       DescriptorBufferLength < sizeof(SCSI_SENSE_DESCRIPTOR_INFORMATION))
3947   {
3948     return FALSE;
3949   }
3950 
3951   descriptor = (PSCSI_SENSE_DESCRIPTOR_INFORMATION)DescriptorBuffer;
3952 
3953   if (descriptor->Header.DescriptorType != SCSI_SENSE_DESCRIPTOR_TYPE_INFORMATION)
3954   {
3955     return FALSE;
3956   }
3957 
3958   additionalLength = sizeof(SCSI_SENSE_DESCRIPTOR_INFORMATION) -
3959                      RTL_SIZEOF_THROUGH_FIELD(SCSI_SENSE_DESCRIPTOR_INFORMATION, Header);
3960 
3961   if (descriptor->Header.AdditionalLength != additionalLength)
3962   {
3963     return FALSE;
3964   }
3965 
3966   if (descriptor->Valid == 0)
3967   {
3968     return FALSE;
3969   }
3970 
3971   return TRUE;
3972 }
3973 
3974 _Success_(return != FALSE)
3975 FORCEINLINE
3976 BOOLEAN
ScsiValidateBlockCommandSenseDescriptor(_In_reads_bytes_ (DescriptorBufferLength)PVOID DescriptorBuffer,_In_ UCHAR DescriptorBufferLength)3977 ScsiValidateBlockCommandSenseDescriptor(
3978   _In_reads_bytes_(DescriptorBufferLength) PVOID DescriptorBuffer,
3979   _In_ UCHAR DescriptorBufferLength)
3980 {
3981   PSCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND descriptor;
3982   UCHAR additionalLength;
3983 
3984   if (DescriptorBuffer == NULL ||
3985       DescriptorBufferLength < sizeof(SCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND))
3986   {
3987     return FALSE;
3988   }
3989 
3990   descriptor = (PSCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND)DescriptorBuffer;
3991 
3992   if (descriptor->Header.DescriptorType != SCSI_SENSE_DESCRIPTOR_TYPE_BLOCK_COMMAND)
3993   {
3994     return FALSE;
3995   }
3996 
3997   additionalLength = sizeof(SCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND) -
3998                      RTL_SIZEOF_THROUGH_FIELD(SCSI_SENSE_DESCRIPTOR_BLOCK_COMMAND, Header);
3999 
4000   if (descriptor->Header.AdditionalLength != additionalLength)
4001   {
4002     return FALSE;
4003   }
4004 
4005   return TRUE;
4006 }
4007 
4008 _Success_(return != FALSE)
4009 FORCEINLINE
4010 BOOLEAN
ScsiConvertToFixedSenseFormat(_In_reads_bytes_ (SenseInfoBufferLength)PVOID SenseInfoBuffer,_In_ UCHAR SenseInfoBufferLength,_Out_writes_bytes_ (OutBufferLength)PVOID OutBuffer,_In_ UCHAR OutBufferLength)4011 ScsiConvertToFixedSenseFormat(
4012   _In_reads_bytes_(SenseInfoBufferLength) PVOID SenseInfoBuffer,
4013   _In_ UCHAR SenseInfoBufferLength,
4014   _Out_writes_bytes_(OutBufferLength) PVOID OutBuffer,
4015   _In_ UCHAR OutBufferLength)
4016 {
4017   BOOLEAN succeed = FALSE;
4018   BOOLEAN validSense = FALSE;
4019   UCHAR senseKey = 0;
4020   UCHAR additionalSenseCode = 0;
4021   UCHAR additionalSenseCodeQualifier = 0;
4022   PFIXED_SENSE_DATA outBuffer = (PFIXED_SENSE_DATA)OutBuffer;
4023 
4024   if (SenseInfoBuffer == NULL || SenseInfoBufferLength == 0 || OutBuffer == NULL ||
4025       OutBufferLength < sizeof(FIXED_SENSE_DATA))
4026   {
4027     return FALSE;
4028   }
4029 
4030   if (IsDescriptorSenseDataFormat(SenseInfoBuffer))
4031   {
4032     RtlZeroMemory(OutBuffer, OutBufferLength);
4033 
4034     validSense =
4035         ScsiGetSenseKeyAndCodes(SenseInfoBuffer, SenseInfoBufferLength, SCSI_SENSE_OPTIONS_NONE,
4036                                 &senseKey, &additionalSenseCode, &additionalSenseCodeQualifier);
4037     if (validSense)
4038     {
4039 
4040       if (IsSenseDataCurrentError(SenseInfoBuffer))
4041       {
4042         outBuffer->ErrorCode = SCSI_SENSE_ERRORCODE_FIXED_CURRENT;
4043       }
4044       else
4045       {
4046         outBuffer->ErrorCode = SCSI_SENSE_ERRORCODE_FIXED_DEFERRED;
4047       }
4048       outBuffer->AdditionalSenseLength =
4049           sizeof(FIXED_SENSE_DATA) -
4050           RTL_SIZEOF_THROUGH_FIELD(FIXED_SENSE_DATA, AdditionalSenseLength);
4051       outBuffer->SenseKey = senseKey;
4052       outBuffer->AdditionalSenseCode = additionalSenseCode;
4053       outBuffer->AdditionalSenseCodeQualifier = additionalSenseCodeQualifier;
4054 
4055       succeed = TRUE;
4056     }
4057   }
4058 
4059   return succeed;
4060 }
4061 
4062 _Success_(return != FALSE)
4063 FORCEINLINE
4064 BOOLEAN
ScsiGetNextSenseDescriptorByType(_In_reads_bytes_ (BufferLength)PVOID Buffer,_In_ UCHAR BufferLength,_In_reads_ (TypeListCount)PUCHAR TypeList,_In_ ULONG TypeListCount,_Out_ PUCHAR OutType,_Outptr_result_bytebuffer_ (* OutBufferLength)PVOID * OutBuffer,_Out_ UCHAR * OutBufferLength)4065 ScsiGetNextSenseDescriptorByType(
4066     _In_reads_bytes_(BufferLength) PVOID Buffer,
4067     _In_ UCHAR BufferLength,
4068     _In_reads_(TypeListCount) PUCHAR TypeList,
4069     _In_ ULONG TypeListCount,
4070     _Out_ PUCHAR OutType,
4071     _Outptr_result_bytebuffer_(*OutBufferLength) PVOID *OutBuffer,
4072     _Out_ UCHAR *OutBufferLength)
4073 {
4074   PUCHAR remainingBuffer;
4075   UCHAR remainingBufferLength;
4076   UCHAR type;
4077   ULONG i;
4078   UCHAR descriptorLength;
4079 
4080   if (Buffer == NULL || BufferLength == 0 || TypeList == NULL || TypeListCount == 0 ||
4081       OutType == NULL || OutBuffer == NULL || OutBufferLength == NULL)
4082   {
4083     return FALSE;
4084   }
4085 
4086   *OutBuffer = NULL;
4087   *OutBufferLength = 0;
4088   *OutType = 0;
4089 
4090   remainingBuffer = (PUCHAR)Buffer;
4091   remainingBufferLength = BufferLength;
4092 
4093   while (remainingBufferLength >= sizeof(SCSI_SENSE_DESCRIPTOR_HEADER))
4094   {
4095     for (i = 0; i < TypeListCount; i++)
4096     {
4097       type = TypeList[i];
4098 
4099       if (((PSCSI_SENSE_DESCRIPTOR_HEADER)remainingBuffer)->DescriptorType == type)
4100       {
4101         *OutBuffer = (PVOID)remainingBuffer;
4102         *OutBufferLength = remainingBufferLength;
4103         *OutType = type;
4104         return TRUE;
4105       }
4106     }
4107 
4108     descriptorLength = ScsiGetSenseDescriptorLength(remainingBuffer);
4109 
4110     if (remainingBufferLength > descriptorLength)
4111     {
4112       remainingBuffer += descriptorLength;
4113       remainingBufferLength -= descriptorLength;
4114     }
4115     else
4116     {
4117       break;
4118     }
4119   }
4120 
4121   return FALSE;
4122 }
4123 
4124 #ifdef __cplusplus
4125 }
4126 #endif
4127 
4128 #endif /* _NTSCSI_ */
4129