1
2 #pragma once
3
4 #define _CLASS_
5
6 #include <ntdddisk.h>
7 #include <ntddcdrm.h>
8 #include <ntddtape.h>
9 #include <ntddscsi.h>
10 #include <ntddstor.h>
11
12 #include <stdio.h>
13
14 #include <scsi.h>
15
16 #define max(a,b) (((a) > (b)) ? (a) : (b))
17 #define min(a,b) (((a) < (b)) ? (a) : (b))
18
19 #define SRB_CLASS_FLAGS_LOW_PRIORITY 0x10000000
20 #define SRB_CLASS_FLAGS_PERSISTANT 0x20000000
21 #define SRB_CLASS_FLAGS_PAGING 0x40000000
22 #define SRB_CLASS_FLAGS_FREE_MDL 0x80000000
23
24 #define ASSERT_FDO(x) \
25 ASSERT(((PCOMMON_DEVICE_EXTENSION) (x)->DeviceExtension)->IsFdo)
26
27 #define ASSERT_PDO(x) \
28 ASSERT(!(((PCOMMON_DEVICE_EXTENSION) (x)->DeviceExtension)->IsFdo))
29
30 #define IS_CLEANUP_REQUEST(majorFunction) \
31 ((majorFunction == IRP_MJ_CLOSE) || \
32 (majorFunction == IRP_MJ_CLEANUP) || \
33 (majorFunction == IRP_MJ_SHUTDOWN))
34
35 #define DO_MCD(fdoExtension) \
36 (((fdoExtension)->MediaChangeDetectionInfo != NULL) && \
37 ((fdoExtension)->MediaChangeDetectionInfo->MediaChangeDetectionDisableCount == 0))
38
39 #define IS_SCSIOP_READ(opCode) \
40 ((opCode == SCSIOP_READ6) || \
41 (opCode == SCSIOP_READ) || \
42 (opCode == SCSIOP_READ12) || \
43 (opCode == SCSIOP_READ16))
44
45 #define IS_SCSIOP_WRITE(opCode) \
46 ((opCode == SCSIOP_WRITE6) || \
47 (opCode == SCSIOP_WRITE) || \
48 (opCode == SCSIOP_WRITE12) || \
49 (opCode == SCSIOP_WRITE16))
50
51 #define IS_SCSIOP_READWRITE(opCode) (IS_SCSIOP_READ(opCode) || IS_SCSIOP_WRITE(opCode))
52
53 #define ADJUST_FUA_FLAG(fdoExt) { \
54 if (TEST_FLAG(fdoExt->DeviceFlags, DEV_WRITE_CACHE) && \
55 !TEST_FLAG(fdoExt->DeviceFlags, DEV_POWER_PROTECTED) && \
56 !TEST_FLAG(fdoExt->ScanForSpecialFlags, CLASS_SPECIAL_FUA_NOT_SUPPORTED) ) { \
57 fdoExt->CdbForceUnitAccess = TRUE; \
58 } else { \
59 fdoExt->CdbForceUnitAccess = FALSE; \
60 } \
61 }
62
63 #define FREE_POOL(_PoolPtr) \
64 if (_PoolPtr != NULL) { \
65 ExFreePool(_PoolPtr); \
66 _PoolPtr = NULL; \
67 }
68
69 #ifdef POOL_TAGGING
70 #undef ExAllocatePool
71 #undef ExAllocatePoolWithQuota
72 #define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'nUcS')
73 //#define ExAllocatePool(a,b) #assert(0)
74 #define ExAllocatePoolWithQuota(a,b) ExAllocatePoolWithQuotaTag(a,b,'nUcS')
75 #endif
76
77 #define CLASS_TAG_AUTORUN_DISABLE 'ALcS'
78 #define CLASS_TAG_FILE_OBJECT_EXTENSION 'FLcS'
79 #define CLASS_TAG_MEDIA_CHANGE_DETECTION 'MLcS'
80 #define CLASS_TAG_MOUNT 'mLcS'
81 #define CLASS_TAG_RELEASE_QUEUE 'qLcS'
82 #define CLASS_TAG_POWER 'WLcS'
83 #define CLASS_TAG_WMI 'wLcS'
84 #define CLASS_TAG_FAILURE_PREDICT 'fLcS'
85 #define CLASS_TAG_DEVICE_CONTROL 'OIcS'
86 #define CLASS_TAG_MODE_DATA 'oLcS'
87 #define CLASS_TAG_MULTIPATH 'mPcS'
88 #define CLASS_TAG_LOCK_TRACKING 'TLcS'
89 #define CLASS_TAG_LB_PROVISIONING 'PLcS'
90 #define CLASS_TAG_MANAGE_DATASET 'MDcS'
91
92 #define MAXIMUM_RETRIES 4
93
94 #define CLASS_DRIVER_EXTENSION_KEY ((PVOID) ClassInitialize)
95
96 #define NO_REMOVE 0
97 #define REMOVE_PENDING 1
98 #define REMOVE_COMPLETE 2
99
100 #define ClassAcquireRemoveLock(devobj, tag) \
101 ClassAcquireRemoveLockEx(devobj, tag, __FILE__, __LINE__)
102
103 #ifdef TRY
104 #undef TRY
105 #endif
106 #ifdef LEAVE
107 #undef LEAVE
108 #endif
109
110 #ifdef FINALLY
111 #undef FINALLY
112 #endif
113
114 #define TRY
115 #define LEAVE goto __tryLabel;
116 #define FINALLY __tryLabel:
117
118 #if defined DebugPrint
119 #undef DebugPrint
120 #endif
121
122 #if DBG
123 #define DebugPrint(x) ClassDebugPrint x
124 #else
125 #define DebugPrint(x)
126 #endif
127
128 #define DEBUG_BUFFER_LENGTH 256
129
130 #define START_UNIT_TIMEOUT (60 * 4)
131
132 #define MEDIA_CHANGE_DEFAULT_TIME 1
133 #define MEDIA_CHANGE_TIMEOUT_TIME 300
134
135 #ifdef ALLOCATE_SRB_FROM_POOL
136
137 #define ClasspAllocateSrb(ext) \
138 ExAllocatePoolWithTag(NonPagedPool, \
139 sizeof(SCSI_REQUEST_BLOCK), \
140 'sBRS')
141
142 #define ClasspFreeSrb(ext, srb) ExFreePool((srb));
143
144 #else /* ALLOCATE_SRB_FROM_POOL */
145
146 #define ClasspAllocateSrb(ext) \
147 ExAllocateFromNPagedLookasideList( \
148 &((ext)->CommonExtension.SrbLookasideList))
149
150 #define ClasspFreeSrb(ext, srb) \
151 ExFreeToNPagedLookasideList( \
152 &((ext)->CommonExtension.SrbLookasideList), \
153 (srb))
154
155 #endif /* ALLOCATE_SRB_FROM_POOL */
156
157 #define SET_FLAG(Flags, Bit) ((Flags) |= (Bit))
158 #define CLEAR_FLAG(Flags, Bit) ((Flags) &= ~(Bit))
159 #define TEST_FLAG(Flags, Bit) (((Flags) & (Bit)) != 0)
160
161 #define CLASS_WORKING_SET_MAXIMUM 2048
162
163 #define CLASS_INTERPRET_SENSE_INFO2_MAXIMUM_HISTORY_COUNT 30000
164
165 #define CLASS_SPECIAL_DISABLE_SPIN_DOWN 0x00000001
166 #define CLASS_SPECIAL_DISABLE_SPIN_UP 0x00000002
167 #define CLASS_SPECIAL_NO_QUEUE_LOCK 0x00000008
168 #define CLASS_SPECIAL_DISABLE_WRITE_CACHE 0x00000010
169 #define CLASS_SPECIAL_CAUSE_NOT_REPORTABLE_HACK 0x00000020
170 #if ((NTDDI_VERSION == NTDDI_WIN2KSP3) || (OSVER(NTDDI_VERSION) == NTDDI_WINXP))
171 #define CLASS_SPECIAL_DISABLE_WRITE_CACHE_NOT_SUPPORTED 0x00000040
172 #endif
173 #define CLASS_SPECIAL_MODIFY_CACHE_UNSUCCESSFUL 0x00000040
174 #define CLASS_SPECIAL_FUA_NOT_SUPPORTED 0x00000080
175 #define CLASS_SPECIAL_VALID_MASK 0x000000FB
176 #define CLASS_SPECIAL_RESERVED (~CLASS_SPECIAL_VALID_MASK)
177
178 #define DEV_WRITE_CACHE 0x00000001
179 #define DEV_USE_SCSI1 0x00000002
180 #define DEV_SAFE_START_UNIT 0x00000004
181 #define DEV_NO_12BYTE_CDB 0x00000008
182 #define DEV_POWER_PROTECTED 0x00000010
183 #define DEV_USE_16BYTE_CDB 0x00000020
184
185 #define GUID_CLASSPNP_QUERY_REGINFOEX {0x00e34b11, 0x2444, 0x4745, {0xa5, 0x3d, 0x62, 0x01, 0x00, 0xcd, 0x82, 0xf7}}
186 #define GUID_CLASSPNP_SENSEINFO2 {0x509a8c5f, 0x71d7, 0x48f6, {0x82, 0x1e, 0x17, 0x3c, 0x49, 0xbf, 0x2f, 0x18}}
187 #define GUID_CLASSPNP_WORKING_SET {0x105701b0, 0x9e9b, 0x47cb, {0x97, 0x80, 0x81, 0x19, 0x8a, 0xf7, 0xb5, 0x24}}
188 #define GUID_CLASSPNP_SRB_SUPPORT {0x0a483941, 0xbdfd, 0x4f7b, {0xbe, 0x95, 0xce, 0xe2, 0xa2, 0x16, 0x09, 0x0c}}
189
190 #define DEFAULT_FAILURE_PREDICTION_PERIOD 60 * 60 * 1
191
192 #define MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS (0x3b9aca00)
193
CountOfSetBitsUChar(UCHAR _X)194 static inline ULONG CountOfSetBitsUChar(UCHAR _X)
195 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
CountOfSetBitsULong(ULONG _X)196 static inline ULONG CountOfSetBitsULong(ULONG _X)
197 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
CountOfSetBitsULong32(ULONG32 _X)198 static inline ULONG CountOfSetBitsULong32(ULONG32 _X)
199 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
CountOfSetBitsULong64(ULONG64 _X)200 static inline ULONG CountOfSetBitsULong64(ULONG64 _X)
201 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
CountOfSetBitsUlongPtr(ULONG_PTR _X)202 static inline ULONG CountOfSetBitsUlongPtr(ULONG_PTR _X)
203 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; }
204
205 typedef enum _MEDIA_CHANGE_DETECTION_STATE {
206 MediaUnknown,
207 MediaPresent,
208 MediaNotPresent,
209 MediaUnavailable
210 } MEDIA_CHANGE_DETECTION_STATE, *PMEDIA_CHANGE_DETECTION_STATE;
211
212 typedef enum _CLASS_DEBUG_LEVEL {
213 ClassDebugError = 0,
214 ClassDebugWarning = 1,
215 ClassDebugTrace = 2,
216 ClassDebugInfo = 3,
217 ClassDebugMediaLocks = 8,
218 ClassDebugMCN = 9,
219 ClassDebugDelayedRetry = 10,
220 ClassDebugSenseInfo = 11,
221 ClassDebugRemoveLock = 12,
222 ClassDebugExternal4 = 13,
223 ClassDebugExternal3 = 14,
224 ClassDebugExternal2 = 15,
225 ClassDebugExternal1 = 16
226 } CLASS_DEBUG_LEVEL, *PCLASS_DEBUG_LEVEL;
227
228 typedef enum {
229 EventGeneration,
230 DataBlockCollection
231 } CLASSENABLEDISABLEFUNCTION;
232
233 typedef enum {
234 FailurePredictionNone = 0,
235 FailurePredictionIoctl,
236 FailurePredictionSmart,
237 FailurePredictionSense
238 } FAILURE_PREDICTION_METHOD, *PFAILURE_PREDICTION_METHOD;
239
240 typedef enum {
241 PowerDownDeviceInitial,
242 PowerDownDeviceLocked,
243 PowerDownDeviceStopped,
244 PowerDownDeviceOff,
245 PowerDownDeviceUnlocked
246 } CLASS_POWER_DOWN_STATE;
247
248 typedef enum {
249 PowerDownDeviceInitial2,
250 PowerDownDeviceLocked2,
251 PowerDownDeviceFlushed2,
252 PowerDownDeviceStopped2,
253 PowerDownDeviceOff2,
254 PowerDownDeviceUnlocked2
255 } CLASS_POWER_DOWN_STATE2;
256
257 typedef enum {
258 PowerDownDeviceInitial3 = 0,
259 PowerDownDeviceLocked3,
260 PowerDownDeviceQuiesced3,
261 PowerDownDeviceFlushed3,
262 PowerDownDeviceStopped3,
263 PowerDownDeviceOff3,
264 PowerDownDeviceUnlocked3
265 } CLASS_POWER_DOWN_STATE3;
266
267 typedef enum {
268 PowerUpDeviceInitial,
269 PowerUpDeviceLocked,
270 PowerUpDeviceOn,
271 PowerUpDeviceStarted,
272 PowerUpDeviceUnlocked
273 } CLASS_POWER_UP_STATE;
274
275 struct _CLASS_INIT_DATA;
276 typedef struct _CLASS_INIT_DATA CLASS_INIT_DATA, *PCLASS_INIT_DATA;
277
278 struct _CLASS_PRIVATE_FDO_DATA;
279 typedef struct _CLASS_PRIVATE_FDO_DATA CLASS_PRIVATE_FDO_DATA, *PCLASS_PRIVATE_FDO_DATA;
280
281 struct _CLASS_PRIVATE_PDO_DATA;
282 typedef struct _CLASS_PRIVATE_PDO_DATA CLASS_PRIVATE_PDO_DATA, *PCLASS_PRIVATE_PDO_DATA;
283
284 struct _CLASS_PRIVATE_COMMON_DATA;
285 typedef struct _CLASS_PRIVATE_COMMON_DATA CLASS_PRIVATE_COMMON_DATA, *PCLASS_PRIVATE_COMMON_DATA;
286
287 struct _MEDIA_CHANGE_DETECTION_INFO;
288 typedef struct _MEDIA_CHANGE_DETECTION_INFO MEDIA_CHANGE_DETECTION_INFO, *PMEDIA_CHANGE_DETECTION_INFO;
289
290 struct _DICTIONARY_HEADER;
291 typedef struct _DICTIONARY_HEADER DICTIONARY_HEADER, *PDICTIONARY_HEADER;
292
293 typedef struct _DICTIONARY {
294 ULONGLONG Signature;
295 struct _DICTIONARY_HEADER* List;
296 KSPIN_LOCK SpinLock;
297 } DICTIONARY, *PDICTIONARY;
298
299 typedef struct _CLASSPNP_SCAN_FOR_SPECIAL_INFO {
300 PCHAR VendorId;
301 PCHAR ProductId;
302 PCHAR ProductRevision;
303 ULONG_PTR Data;
304 } CLASSPNP_SCAN_FOR_SPECIAL_INFO, *PCLASSPNP_SCAN_FOR_SPECIAL_INFO;
305
306 _IRQL_requires_max_(DISPATCH_LEVEL)
307 typedef VOID
308 (NTAPI *PCLASS_ERROR)(
309 _In_ PDEVICE_OBJECT DeviceObject,
310 _In_ PSCSI_REQUEST_BLOCK Srb,
311 _Out_ NTSTATUS *Status,
312 _Inout_ BOOLEAN *Retry);
313
314 _IRQL_requires_max_(PASSIVE_LEVEL)
315 typedef NTSTATUS
316 (NTAPI *PCLASS_ADD_DEVICE)(
317 _In_ PDRIVER_OBJECT DriverObject,
318 _In_ PDEVICE_OBJECT Pdo);
319
320 typedef NTSTATUS
321 (NTAPI *PCLASS_POWER_DEVICE)(
322 _In_ PDEVICE_OBJECT DeviceObject,
323 _In_ PIRP Irp);
324
325 _IRQL_requires_max_(PASSIVE_LEVEL)
326 typedef NTSTATUS
327 (NTAPI *PCLASS_START_DEVICE)(
328 _In_ PDEVICE_OBJECT DeviceObject);
329
330 _IRQL_requires_max_(PASSIVE_LEVEL)
331 typedef NTSTATUS
332 (NTAPI *PCLASS_STOP_DEVICE)(
333 _In_ PDEVICE_OBJECT DeviceObject,
334 _In_ UCHAR Type);
335
336 _IRQL_requires_max_(PASSIVE_LEVEL)
337 typedef NTSTATUS
338 (NTAPI *PCLASS_INIT_DEVICE)(
339 _In_ PDEVICE_OBJECT DeviceObject);
340
341 _IRQL_requires_max_(PASSIVE_LEVEL)
342 typedef NTSTATUS
343 (NTAPI *PCLASS_ENUM_DEVICE)(
344 _In_ PDEVICE_OBJECT DeviceObject);
345
346 _IRQL_requires_max_(DISPATCH_LEVEL)
347 typedef NTSTATUS
348 (NTAPI *PCLASS_READ_WRITE)(
349 _In_ PDEVICE_OBJECT DeviceObject,
350 _In_ PIRP Irp);
351
352 _IRQL_requires_max_(DISPATCH_LEVEL)
353 typedef NTSTATUS
354 (NTAPI *PCLASS_DEVICE_CONTROL)(
355 _In_ PDEVICE_OBJECT DeviceObject,
356 _In_ PIRP Irp);
357
358 _IRQL_requires_max_(DISPATCH_LEVEL)
359 typedef NTSTATUS
360 (NTAPI *PCLASS_SHUTDOWN_FLUSH)(
361 _In_ PDEVICE_OBJECT DeviceObject,
362 _In_ PIRP Irp);
363
364 _IRQL_requires_max_(PASSIVE_LEVEL)
365 typedef NTSTATUS
366 (NTAPI *PCLASS_CREATE_CLOSE)(
367 _In_ PDEVICE_OBJECT DeviceObject,
368 _In_ PIRP Irp);
369
370 _IRQL_requires_max_(PASSIVE_LEVEL)
371 typedef NTSTATUS
372 (NTAPI *PCLASS_QUERY_ID)(
373 _In_ PDEVICE_OBJECT DeviceObject,
374 _In_ BUS_QUERY_ID_TYPE IdType,
375 _In_ PUNICODE_STRING IdString);
376
377 _IRQL_requires_max_(PASSIVE_LEVEL)
378 typedef NTSTATUS
379 (NTAPI *PCLASS_REMOVE_DEVICE)(
380 _In_ PDEVICE_OBJECT DeviceObject,
381 _In_ UCHAR Type);
382
383 _IRQL_requires_max_(PASSIVE_LEVEL)
384 typedef VOID
385 (NTAPI *PCLASS_UNLOAD)(
386 _In_ PDRIVER_OBJECT DriverObject);
387
388 _IRQL_requires_max_(PASSIVE_LEVEL)
389 typedef NTSTATUS
390 (NTAPI *PCLASS_QUERY_PNP_CAPABILITIES)(
391 _In_ PDEVICE_OBJECT PhysicalDeviceObject,
392 _In_ PDEVICE_CAPABILITIES Capabilities);
393
394 _IRQL_requires_(DISPATCH_LEVEL)
395 typedef VOID
396 (NTAPI *PCLASS_TICK)(
397 _In_ PDEVICE_OBJECT DeviceObject);
398
399 _IRQL_requires_max_(PASSIVE_LEVEL)
400 typedef NTSTATUS
401 (NTAPI *PCLASS_QUERY_WMI_REGINFO_EX)(
402 _In_ PDEVICE_OBJECT DeviceObject,
403 _Out_ ULONG *RegFlags,
404 _Out_ PUNICODE_STRING Name,
405 _Out_ PUNICODE_STRING MofResourceName);
406
407 _IRQL_requires_max_(PASSIVE_LEVEL)
408 typedef NTSTATUS
409 (NTAPI *PCLASS_QUERY_WMI_REGINFO)(
410 _In_ PDEVICE_OBJECT DeviceObject,
411 _Out_ ULONG *RegFlags,
412 _Out_ PUNICODE_STRING Name);
413
414 _IRQL_requires_max_(PASSIVE_LEVEL)
415 typedef NTSTATUS
416 (NTAPI *PCLASS_QUERY_WMI_DATABLOCK)(
417 _In_ PDEVICE_OBJECT DeviceObject,
418 _In_ PIRP Irp,
419 _In_ ULONG GuidIndex,
420 _In_ ULONG BufferAvail,
421 _Out_writes_bytes_(BufferAvail) PUCHAR Buffer);
422
423 _IRQL_requires_max_(PASSIVE_LEVEL)
424 typedef NTSTATUS
425 (NTAPI *PCLASS_SET_WMI_DATABLOCK)(
426 _In_ PDEVICE_OBJECT DeviceObject,
427 _In_ PIRP Irp,
428 _In_ ULONG GuidIndex,
429 _In_ ULONG BufferSize,
430 _In_reads_bytes_(BufferSize) PUCHAR Buffer);
431
432 _IRQL_requires_max_(PASSIVE_LEVEL)
433 typedef NTSTATUS
434 (NTAPI *PCLASS_SET_WMI_DATAITEM)(
435 _In_ PDEVICE_OBJECT DeviceObject,
436 _In_ PIRP Irp,
437 _In_ ULONG GuidIndex,
438 _In_ ULONG DataItemId,
439 _In_ ULONG BufferSize,
440 _In_reads_bytes_(BufferSize) PUCHAR Buffer);
441
442 _IRQL_requires_max_(PASSIVE_LEVEL)
443 typedef NTSTATUS
444 (NTAPI *PCLASS_EXECUTE_WMI_METHOD)(
445 _In_ PDEVICE_OBJECT DeviceObject,
446 _In_ PIRP Irp,
447 _In_ ULONG GuidIndex,
448 _In_ ULONG MethodId,
449 _In_ ULONG InBufferSize,
450 _In_ ULONG OutBufferSize,
451 _In_reads_(_Inexpressible_(max(InBufferSize, OutBufferSize))) PUCHAR Buffer);
452
453 _IRQL_requires_max_(PASSIVE_LEVEL)
454 typedef NTSTATUS
455 (NTAPI *PCLASS_WMI_FUNCTION_CONTROL)(
456 _In_ PDEVICE_OBJECT DeviceObject,
457 _In_ PIRP Irp,
458 _In_ ULONG GuidIndex,
459 _In_ CLASSENABLEDISABLEFUNCTION Function,
460 _In_ BOOLEAN Enable);
461
462 typedef struct _SRB_HISTORY_ITEM {
463 LARGE_INTEGER TickCountSent;
464 LARGE_INTEGER TickCountCompleted;
465 ULONG MillisecondsDelayOnRetry;
466 SENSE_DATA NormalizedSenseData;
467 UCHAR SrbStatus;
468 UCHAR ClassDriverUse;
469 } SRB_HISTORY_ITEM, *PSRB_HISTORY_ITEM;
470
471 typedef struct _SRB_HISTORY {
472 ULONG_PTR ClassDriverUse[4];
473 _Field_range_(1,30000) ULONG TotalHistoryCount;
474 _Field_range_(0,TotalHistoryCount) ULONG UsedHistoryCount;
475 _Field_size_part_(TotalHistoryCount, UsedHistoryCount) SRB_HISTORY_ITEM History[1];
476 } SRB_HISTORY, *PSRB_HISTORY;
477
478 _IRQL_requires_max_(DISPATCH_LEVEL)
479 typedef BOOLEAN
480 (NTAPI *PCLASS_INTERPRET_SENSE_INFO)(
481 _In_ PDEVICE_OBJECT Fdo,
482 _In_opt_ PIRP OriginalRequest,
483 _In_ PSCSI_REQUEST_BLOCK Srb,
484 _In_ UCHAR MajorFunctionCode,
485 _In_ ULONG IoDeviceCode,
486 _In_ ULONG PreviousRetryCount,
487 _In_opt_ SRB_HISTORY *RequestHistory,
488 _Out_ NTSTATUS *Status,
489 _Out_ _Deref_out_range_(0,MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS)
490 LONGLONG *RetryIn100nsUnits);
491
492 _IRQL_requires_max_(DISPATCH_LEVEL)
493 _At_(RequestHistory->UsedHistoryCount, _Pre_equal_to_(RequestHistory->TotalHistoryCount)
494 _Out_range_(0, RequestHistory->TotalHistoryCount - 1))
495 typedef VOID
496 (NTAPI *PCLASS_COMPRESS_RETRY_HISTORY_DATA)(
497 _In_ PDEVICE_OBJECT DeviceObject,
498 _Inout_ PSRB_HISTORY RequestHistory);
499
500 typedef struct {
501 GUID Guid;
502 ULONG InstanceCount;
503 ULONG Flags;
504 } GUIDREGINFO, *PGUIDREGINFO;
505
506 typedef struct _CLASS_WMI_INFO {
507 ULONG GuidCount;
508 PGUIDREGINFO GuidRegInfo;
509 PCLASS_QUERY_WMI_REGINFO ClassQueryWmiRegInfo;
510 PCLASS_QUERY_WMI_DATABLOCK ClassQueryWmiDataBlock;
511 PCLASS_SET_WMI_DATABLOCK ClassSetWmiDataBlock;
512 PCLASS_SET_WMI_DATAITEM ClassSetWmiDataItem;
513 PCLASS_EXECUTE_WMI_METHOD ClassExecuteWmiMethod;
514 PCLASS_WMI_FUNCTION_CONTROL ClassWmiFunctionControl;
515 } CLASS_WMI_INFO, *PCLASS_WMI_INFO;
516
517 typedef struct _CLASS_DEV_INFO {
518 ULONG DeviceExtensionSize;
519 DEVICE_TYPE DeviceType;
520 UCHAR StackSize;
521 ULONG DeviceCharacteristics;
522 PCLASS_ERROR ClassError;
523 PCLASS_READ_WRITE ClassReadWriteVerification;
524 PCLASS_DEVICE_CONTROL ClassDeviceControl;
525 PCLASS_SHUTDOWN_FLUSH ClassShutdownFlush;
526 PCLASS_CREATE_CLOSE ClassCreateClose;
527 PCLASS_INIT_DEVICE ClassInitDevice;
528 PCLASS_START_DEVICE ClassStartDevice;
529 PCLASS_POWER_DEVICE ClassPowerDevice;
530 PCLASS_STOP_DEVICE ClassStopDevice;
531 PCLASS_REMOVE_DEVICE ClassRemoveDevice;
532 PCLASS_QUERY_PNP_CAPABILITIES ClassQueryPnpCapabilities;
533 CLASS_WMI_INFO ClassWmiInfo;
534 } CLASS_DEV_INFO, *PCLASS_DEV_INFO;
535
536 struct _CLASS_INIT_DATA {
537 ULONG InitializationDataSize;
538 CLASS_DEV_INFO FdoData;
539 CLASS_DEV_INFO PdoData;
540 PCLASS_ADD_DEVICE ClassAddDevice;
541 PCLASS_ENUM_DEVICE ClassEnumerateDevice;
542 PCLASS_QUERY_ID ClassQueryId;
543 PDRIVER_STARTIO ClassStartIo;
544 PCLASS_UNLOAD ClassUnload;
545 PCLASS_TICK ClassTick;
546 };
547
548 typedef struct _FILE_OBJECT_EXTENSION {
549 PFILE_OBJECT FileObject;
550 PDEVICE_OBJECT DeviceObject;
551 ULONG LockCount;
552 ULONG McnDisableCount;
553 } FILE_OBJECT_EXTENSION, *PFILE_OBJECT_EXTENSION;
554
555 typedef struct _CLASS_WORKING_SET {
556 _Field_range_(sizeof(CLASS_WORKING_SET),sizeof(CLASS_WORKING_SET)) ULONG Size;
557 _Field_range_(0,2048) ULONG XferPacketsWorkingSetMaximum;
558 _Field_range_(0,2048) ULONG XferPacketsWorkingSetMinimum;
559 } CLASS_WORKING_SET, *PCLASS_WORKING_SET;
560
561 typedef struct _CLASS_INTERPRET_SENSE_INFO2 {
562 _Field_range_(sizeof(CLASS_INTERPRET_SENSE_INFO),sizeof(CLASS_INTERPRET_SENSE_INFO))
563 ULONG Size;
564 _Field_range_(1,30000) ULONG HistoryCount;
565 __callback PCLASS_COMPRESS_RETRY_HISTORY_DATA Compress;
566 __callback PCLASS_INTERPRET_SENSE_INFO Interpret;
567 } CLASS_INTERPRET_SENSE_INFO2, *PCLASS_INTERPRET_SENSE_INFO2;
568
569 C_ASSERT((MAXULONG - sizeof(SRB_HISTORY)) / 30000 >= sizeof(SRB_HISTORY_ITEM));
570
571 // for SrbSupport
572 #define CLASS_SRB_SCSI_REQUEST_BLOCK 0x1
573 #define CLASS_SRB_STORAGE_REQUEST_BLOCK 0x2
574
575 typedef struct _CLASS_DRIVER_EXTENSION {
576 UNICODE_STRING RegistryPath;
577 CLASS_INIT_DATA InitData;
578 ULONG DeviceCount;
579 #if (NTDDI_VERSION >= NTDDI_WINXP)
580 PCLASS_QUERY_WMI_REGINFO_EX ClassFdoQueryWmiRegInfoEx;
581 PCLASS_QUERY_WMI_REGINFO_EX ClassPdoQueryWmiRegInfoEx;
582 #endif
583 #if (NTDDI_VERSION >= NTDDI_VISTA)
584 REGHANDLE EtwHandle;
585 PDRIVER_DISPATCH DeviceMajorFunctionTable[IRP_MJ_MAXIMUM_FUNCTION + 1];
586 PDRIVER_DISPATCH MpDeviceMajorFunctionTable[IRP_MJ_MAXIMUM_FUNCTION + 1];
587 PCLASS_INTERPRET_SENSE_INFO2 InterpretSenseInfo;
588 PCLASS_WORKING_SET WorkingSet;
589 #endif
590 #if (NTDDI_VERSION >= NTDDI_WIN8)
591 ULONG SrbSupport;
592 #endif
593 } CLASS_DRIVER_EXTENSION, *PCLASS_DRIVER_EXTENSION;
594
595 typedef struct _COMMON_DEVICE_EXTENSION {
596 ULONG Version;
597 PDEVICE_OBJECT DeviceObject;
598 PDEVICE_OBJECT LowerDeviceObject;
599 struct _FUNCTIONAL_DEVICE_EXTENSION *PartitionZeroExtension;
600 PCLASS_DRIVER_EXTENSION DriverExtension;
601 LONG RemoveLock;
602 KEVENT RemoveEvent;
603 KSPIN_LOCK RemoveTrackingSpinlock;
604 PVOID RemoveTrackingList;
605 LONG RemoveTrackingUntrackedCount;
606 PVOID DriverData;
607 _ANONYMOUS_STRUCT struct {
608 BOOLEAN IsFdo:1;
609 BOOLEAN IsInitialized:1;
610 BOOLEAN IsSrbLookasideListInitialized:1;
611 } DUMMYSTRUCTNAME;
612 UCHAR PreviousState;
613 UCHAR CurrentState;
614 ULONG IsRemoved;
615 UNICODE_STRING DeviceName;
616 struct _PHYSICAL_DEVICE_EXTENSION *ChildList;
617 ULONG PartitionNumber;
618 LARGE_INTEGER PartitionLength;
619 LARGE_INTEGER StartingOffset;
620 PCLASS_DEV_INFO DevInfo;
621 ULONG PagingPathCount;
622 ULONG DumpPathCount;
623 ULONG HibernationPathCount;
624 KEVENT PathCountEvent;
625 #ifndef ALLOCATE_SRB_FROM_POOL
626 NPAGED_LOOKASIDE_LIST SrbLookasideList;
627 #endif
628 UNICODE_STRING MountedDeviceInterfaceName;
629 ULONG GuidCount;
630 PGUIDREGINFO GuidRegInfo;
631 DICTIONARY FileObjectDictionary;
632 #if (NTDDI_VERSION >= NTDDI_WINXP)
633 PCLASS_PRIVATE_COMMON_DATA PrivateCommonData;
634 #else
635 ULONG_PTR Reserved1;
636 #endif
637 #if (NTDDI_VERSION >= NTDDI_VISTA)
638 PDRIVER_DISPATCH *DispatchTable;
639 #else
640 ULONG_PTR Reserved2;
641 #endif
642 ULONG_PTR Reserved3;
643 ULONG_PTR Reserved4;
644 } COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
645
646 typedef struct _PHYSICAL_DEVICE_EXTENSION {
647 _ANONYMOUS_UNION union {
648 _ANONYMOUS_STRUCT struct {
649 ULONG Version;
650 PDEVICE_OBJECT DeviceObject;
651 } DUMMYSTRUCTNAME;
652 COMMON_DEVICE_EXTENSION CommonExtension;
653 } DUMMYUNIONNAME;
654 BOOLEAN IsMissing;
655 BOOLEAN IsEnumerated;
656 #if (NTDDI_VERSION >= NTDDI_WINXP)
657 PCLASS_PRIVATE_PDO_DATA PrivatePdoData;
658 #else
659 ULONG_PTR Reserved1;
660 #endif
661 ULONG_PTR Reserved2;
662 ULONG_PTR Reserved3;
663 ULONG_PTR Reserved4;
664 } PHYSICAL_DEVICE_EXTENSION, *PPHYSICAL_DEVICE_EXTENSION;
665
666 typedef struct _CLASS_POWER_OPTIONS {
667 ULONG PowerDown:1;
668 ULONG LockQueue:1;
669 ULONG HandleSpinDown:1;
670 ULONG HandleSpinUp:1;
671 ULONG Reserved:27;
672 } CLASS_POWER_OPTIONS, *PCLASS_POWER_OPTIONS;
673
674 typedef struct _CLASS_POWER_CONTEXT {
675 union {
676 CLASS_POWER_DOWN_STATE PowerDown;
677 CLASS_POWER_DOWN_STATE2 PowerDown2;
678 CLASS_POWER_DOWN_STATE3 PowerDown3;
679 CLASS_POWER_UP_STATE PowerUp;
680 } PowerChangeState;
681 CLASS_POWER_OPTIONS Options;
682 BOOLEAN InUse;
683 BOOLEAN QueueLocked;
684 NTSTATUS FinalStatus;
685 ULONG RetryCount;
686 ULONG RetryInterval;
687 PIO_COMPLETION_ROUTINE CompletionRoutine;
688 PDEVICE_OBJECT DeviceObject;
689 PIRP Irp;
690 SCSI_REQUEST_BLOCK Srb;
691 } CLASS_POWER_CONTEXT, *PCLASS_POWER_CONTEXT;
692
693 #if (NTDDI_VERSION >= NTDDI_WIN8)
694
695 #define CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE (sizeof(STORAGE_REQUEST_BLOCK) + sizeof(STOR_ADDR_BTL8) + sizeof(SRBEX_DATA_SCSI_CDB16))
696 #define CLASS_SRBEX_NO_SRBEX_DATA_BUFFER_SIZE (sizeof(STORAGE_REQUEST_BLOCK) + sizeof(STOR_ADDR_BTL8))
697
698 #endif
699
700 typedef struct _COMPLETION_CONTEXT {
701 PDEVICE_OBJECT DeviceObject;
702 #if (NTDDI_VERSION >= NTDDI_WIN8)
703 union
704 {
705 SCSI_REQUEST_BLOCK Srb;
706 STORAGE_REQUEST_BLOCK SrbEx;
707 UCHAR SrbExBuffer[CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE];
708 } Srb;
709 #else
710 SCSI_REQUEST_BLOCK Srb;
711 #endif
712 } COMPLETION_CONTEXT, *PCOMPLETION_CONTEXT;
713
714 _IRQL_requires_max_(PASSIVE_LEVEL)
715 _Must_inspect_result_
716 SCSIPORT_API
717 ULONG
718 NTAPI
719 ClassInitialize(
720 _In_ PVOID Argument1,
721 _In_ PVOID Argument2,
722 _In_ PCLASS_INIT_DATA InitializationData);
723
724 typedef struct _CLASS_QUERY_WMI_REGINFO_EX_LIST {
725 ULONG Size;
726 __callback PCLASS_QUERY_WMI_REGINFO_EX ClassFdoQueryWmiRegInfoEx;
727 __callback PCLASS_QUERY_WMI_REGINFO_EX ClassPdoQueryWmiRegInfoEx;
728 } CLASS_QUERY_WMI_REGINFO_EX_LIST, *PCLASS_QUERY_WMI_REGINFO_EX_LIST;
729
730 typedef enum
731 {
732 SupportUnknown = 0,
733 Supported,
734 NotSupported
735 } CLASS_FUNCTION_SUPPORT;
736
737 typedef struct _CLASS_VPD_B1_DATA
738 {
739 NTSTATUS CommandStatus;
740 USHORT MediumRotationRate;
741 UCHAR NominalFormFactor;
742 UCHAR Zoned;
743 ULONG MediumProductType;
744 ULONG DepopulationTime;
745 } CLASS_VPD_B1_DATA, *PCLASS_VPD_B1_DATA;
746
747 typedef struct _CLASS_VPD_B0_DATA
748 {
749 NTSTATUS CommandStatus;
750 ULONG MaxUnmapLbaCount;
751 ULONG MaxUnmapBlockDescrCount;
752 ULONG OptimalUnmapGranularity;
753 ULONG UnmapGranularityAlignment;
754 BOOLEAN UGAVALID;
755 UCHAR Reserved0;
756 USHORT OptimalTransferLengthGranularity;
757 ULONG MaximumTransferLength;
758 ULONG OptimalTransferLength;
759 } CLASS_VPD_B0_DATA, *PCLASS_VPD_B0_DATA;
760
761 #ifdef _MSC_VER
762 #pragma warning(push)
763 #pragma warning(disable:4214)
764 #endif
765 typedef struct _CLASS_VPD_B2_DATA
766 {
767 NTSTATUS CommandStatus;
768 UCHAR ThresholdExponent;
769 UCHAR DP:1;
770 UCHAR ANC_SUP:1;
771 UCHAR Reserved0:2;
772 UCHAR LBPRZ:1;
773 UCHAR LBPWS10:1;
774 UCHAR LBPWS:1;
775 UCHAR LBPU:1;
776 UCHAR ProvisioningType:3;
777 UCHAR Reserved1:5;
778 ULONG SoftThresholdEventPending;
779 } CLASS_VPD_B2_DATA, *PCLASS_VPD_B2_DATA;
780 #ifdef _MSC_VER
781 #pragma warning(pop)
782 #endif
783
784 typedef struct _CLASS_READ_CAPACITY16_DATA
785 {
786 NTSTATUS CommandStatus;
787 ULONG BytesPerLogicalSector;
788 ULONG BytesPerPhysicalSector;
789 ULONG BytesOffsetForSectorAlignment;
790 BOOLEAN LBProvisioningEnabled;
791 BOOLEAN LBProvisioningReadZeros;
792 UCHAR Reserved0[2];
793 ULONG Reserved1;
794 } CLASS_READ_CAPACITY16_DATA, *PCLASS_READ_CAPACITY16_DATA;
795
796 typedef struct _CLASS_VPD_ECOP_BLOCK_DEVICE_ROD_LIMITS
797 {
798 NTSTATUS CommandStatus;
799 USHORT MaximumRangeDescriptors;
800 UCHAR Restricted;
801 UCHAR Reserved;
802 ULONG MaximumInactivityTimer;
803 ULONG DefaultInactivityTimer;
804 ULONGLONG MaximumTokenTransferSize;
805 ULONGLONG OptimalTransferCount;
806 } CLASS_VPD_ECOP_BLOCK_DEVICE_ROD_LIMITS, *PCLASS_VPD_ECOP_BLOCK_DEVICE_ROD_LIMITS;
807
808 #ifdef _MSC_VER
809 #pragma warning(push)
810 #pragma warning(disable:4214)
811 #endif
812 typedef struct _CLASS_FUNCTION_SUPPORT_INFO
813 {
814 KSPIN_LOCK SyncLock;
815 ULONG GenerationCount;
816 volatile ULONG ChangeRequestCount;
817 struct
818 {
819 ULONG BlockLimits:1;
820 ULONG BlockDeviceCharacteristics:1;
821 ULONG LBProvisioning:1;
822 ULONG BlockDeviceRODLimits:1;
823 ULONG ZonedBlockDeviceCharacteristics:1;
824 ULONG Reserved:22;
825 ULONG DeviceType:5;
826 } ValidInquiryPages;
827 struct
828 {
829 CLASS_FUNCTION_SUPPORT SeekPenaltyProperty;
830 CLASS_FUNCTION_SUPPORT AccessAlignmentProperty;
831 CLASS_FUNCTION_SUPPORT TrimProperty;
832 CLASS_FUNCTION_SUPPORT TrimProcess;
833 } LowerLayerSupport;
834 BOOLEAN RegAccessAlignmentQueryNotSupported;
835 BOOLEAN AsynchronousNotificationSupported;
836 #if (NTDDI_VERSION >= NTDDI_WIN10_RS2)
837 BOOLEAN UseModeSense10;
838 UCHAR Reserved;
839 #else
840 UCHAR Reserved[2];
841 #endif
842 CLASS_VPD_B0_DATA BlockLimitsData;
843 CLASS_VPD_B1_DATA DeviceCharacteristicsData;
844 CLASS_VPD_B2_DATA LBProvisioningData;
845 CLASS_READ_CAPACITY16_DATA ReadCapacity16Data;
846 CLASS_VPD_ECOP_BLOCK_DEVICE_ROD_LIMITS BlockDeviceRODLimitsData;
847 struct
848 {
849 ULONG D3ColdSupported:1;
850 ULONG DeviceWakeable:1;
851 ULONG IdlePowerEnabled:1;
852 ULONG D3IdleTimeoutOverridden:1;
853 ULONG NoVerifyDuringIdlePower:1;
854 ULONG Reserved2:27;
855 ULONG D3IdleTimeout;
856 } IdlePower;
857
858 #if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
859 CLASS_FUNCTION_SUPPORT HwFirmwareGetInfoSupport;
860 PSTORAGE_HW_FIRMWARE_INFO HwFirmwareInfo;
861 #endif
862 } CLASS_FUNCTION_SUPPORT_INFO, *PCLASS_FUNCTION_SUPPORT_INFO;
863 #ifdef _MSC_VER
864 #pragma warning(pop)
865 #endif
866
867 typedef struct _FUNCTIONAL_DEVICE_EXTENSION {
868 _ANONYMOUS_UNION union {
869 _ANONYMOUS_STRUCT struct {
870 ULONG Version;
871 PDEVICE_OBJECT DeviceObject;
872 } DUMMYSTRUCTNAME;
873 COMMON_DEVICE_EXTENSION CommonExtension;
874 } DUMMYUNIONNAME;
875 PDEVICE_OBJECT LowerPdo;
876 PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor;
877 PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor;
878 DEVICE_POWER_STATE DevicePowerState;
879 ULONG DMByteSkew;
880 ULONG DMSkew;
881 BOOLEAN DMActive;
882 #if (NTDDI_VERSION >= NTDDI_WIN8)
883 UCHAR SenseDataLength;
884 #else
885 UCHAR Reserved;
886 #endif
887 UCHAR Reserved0[2];
888 DISK_GEOMETRY DiskGeometry;
889 PSENSE_DATA SenseData;
890 ULONG TimeOutValue;
891 ULONG DeviceNumber;
892 ULONG SrbFlags;
893 ULONG ErrorCount;
894 LONG LockCount;
895 LONG ProtectedLockCount;
896 LONG InternalLockCount;
897 KEVENT EjectSynchronizationEvent;
898 USHORT DeviceFlags;
899 UCHAR SectorShift;
900 #if (NTDDI_VERSION >= NTDDI_VISTA)
901 UCHAR CdbForceUnitAccess;
902 #else
903 UCHAR ReservedByte;
904 #endif
905 PMEDIA_CHANGE_DETECTION_INFO MediaChangeDetectionInfo;
906 PKEVENT Unused1;
907 HANDLE Unused2;
908 FILE_OBJECT_EXTENSION KernelModeMcnContext;
909 ULONG MediaChangeCount;
910 HANDLE DeviceDirectory;
911 KSPIN_LOCK ReleaseQueueSpinLock;
912 PIRP ReleaseQueueIrp;
913 SCSI_REQUEST_BLOCK ReleaseQueueSrb;
914 BOOLEAN ReleaseQueueNeeded;
915 BOOLEAN ReleaseQueueInProgress;
916 BOOLEAN ReleaseQueueIrpFromPool;
917 BOOLEAN FailurePredicted;
918 ULONG FailureReason;
919 struct _FAILURE_PREDICTION_INFO* FailurePredictionInfo;
920 BOOLEAN PowerDownInProgress;
921 ULONG EnumerationInterlock;
922 KEVENT ChildLock;
923 PKTHREAD ChildLockOwner;
924 ULONG ChildLockAcquisitionCount;
925 ULONG ScanForSpecialFlags;
926 KDPC PowerRetryDpc;
927 KTIMER PowerRetryTimer;
928 CLASS_POWER_CONTEXT PowerContext;
929
930 #if (NTDDI_VERSION <= NTDDI_WIN2K)
931
932 #if (SPVER(NTDDI_VERSION) < 2))
933 ULONG_PTR Reserved1;
934 ULONG_PTR Reserved2;
935 ULONG_PTR Reserved3;
936 ULONG_PTR Reserved4;
937 #else
938 ULONG CompletionSuccessCount;
939 ULONG SavedSrbFlags;
940 ULONG SavedErrorCount;
941 ULONG_PTR Reserved1;
942 #endif /* (SPVER(NTDDI_VERSION) < 2) */
943
944 #else /* (NTDDI_VERSION <= NTDDI_WIN2K) */
945
946 PCLASS_PRIVATE_FDO_DATA PrivateFdoData;
947 #if (NTDDI_VERSION >= NTDDI_WIN8)
948 PCLASS_FUNCTION_SUPPORT_INFO FunctionSupportInfo;
949 PSTORAGE_MINIPORT_DESCRIPTOR MiniportDescriptor;
950 #else
951 ULONG_PTR Reserved2;
952 ULONG_PTR Reserved3;
953 #endif
954
955 #if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
956 PADDITIONAL_FDO_DATA AdditionalFdoData;
957 #else
958 ULONG_PTR Reserved4;
959 #endif
960 #endif /* (NTDDI_VERSION <= NTDDI_WIN2K) */
961
962 } FUNCTIONAL_DEVICE_EXTENSION, *PFUNCTIONAL_DEVICE_EXTENSION;
963
964 _IRQL_requires_max_(PASSIVE_LEVEL)
965 _Must_inspect_result_
966 SCSIPORT_API
967 ULONG
968 NTAPI
969 ClassInitializeEx(
970 _In_ PDRIVER_OBJECT DriverObject,
971 _In_ LPGUID Guid,
972 _In_ PVOID Data);
973
974 _IRQL_requires_max_(PASSIVE_LEVEL)
975 _Must_inspect_result_
976 _Post_satisfies_(return <= 0)
977 SCSIPORT_API
978 NTSTATUS
979 NTAPI
980 ClassCreateDeviceObject(
981 _In_ PDRIVER_OBJECT DriverObject,
982 _In_z_ PCCHAR ObjectNameBuffer,
983 _In_ PDEVICE_OBJECT LowerDeviceObject,
984 _In_ BOOLEAN IsFdo,
985 _Outptr_result_nullonfailure_ _At_(*DeviceObject, __drv_allocatesMem(Mem) __drv_aliasesMem)
986 PDEVICE_OBJECT *DeviceObject);
987
988 _Must_inspect_result_
989 SCSIPORT_API
990 NTSTATUS
991 NTAPI
992 ClassReadDriveCapacity(
993 _In_ PDEVICE_OBJECT DeviceObject);
994
995 SCSIPORT_API
996 VOID
997 NTAPI
998 ClassReleaseQueue(
999 _In_ PDEVICE_OBJECT DeviceObject);
1000
1001 SCSIPORT_API
1002 VOID
1003 NTAPI
1004 ClassSplitRequest(
1005 _In_ PDEVICE_OBJECT DeviceObject,
1006 _In_ PIRP Irp,
1007 _In_ ULONG MaximumBytes);
1008
1009 SCSIPORT_API
1010 NTSTATUS
1011 NTAPI
1012 ClassDeviceControl(
1013 _In_ PDEVICE_OBJECT DeviceObject,
1014 _Inout_ PIRP Irp);
1015
1016 SCSIPORT_API
1017 NTSTATUS
1018 NTAPI
1019 ClassIoComplete(
1020 PDEVICE_OBJECT DeviceObject,
1021 PIRP Irp,
1022 PVOID Context);
1023
1024 SCSIPORT_API
1025 NTSTATUS
1026 NTAPI
1027 ClassIoCompleteAssociated(
1028 PDEVICE_OBJECT DeviceObject,
1029 PIRP Irp,
1030 PVOID Context);
1031
1032 SCSIPORT_API
1033 BOOLEAN
1034 NTAPI
1035 ClassInterpretSenseInfo(
1036 _In_ PDEVICE_OBJECT DeviceObject,
1037 _In_ PSCSI_REQUEST_BLOCK Srb,
1038 _In_ UCHAR MajorFunctionCode,
1039 _In_ ULONG IoDeviceCode,
1040 _In_ ULONG RetryCount,
1041 _Out_ NTSTATUS *Status,
1042 _Out_opt_ _Deref_out_range_(0,100) ULONG *RetryInterval);
1043
1044 VOID
1045 NTAPI
1046 ClassSendDeviceIoControlSynchronous(
1047 _In_ ULONG IoControlCode,
1048 _In_ PDEVICE_OBJECT TargetDeviceObject,
1049 _Inout_updates_opt_(_Inexpressible_(max(InputBufferLength, OutputBufferLength)))
1050 PVOID Buffer,
1051 _In_ ULONG InputBufferLength,
1052 _In_ ULONG OutputBufferLength,
1053 _In_ BOOLEAN InternalDeviceIoControl,
1054 _Out_ PIO_STATUS_BLOCK IoStatus);
1055
1056 SCSIPORT_API
1057 NTSTATUS
1058 NTAPI
1059 ClassSendIrpSynchronous(
1060 _In_ PDEVICE_OBJECT TargetDeviceObject,
1061 _In_ PIRP Irp);
1062
1063 SCSIPORT_API
1064 NTSTATUS
1065 NTAPI
1066 ClassForwardIrpSynchronous(
1067 _In_ PCOMMON_DEVICE_EXTENSION CommonExtension,
1068 _In_ PIRP Irp);
1069
1070 SCSIPORT_API
1071 NTSTATUS
1072 NTAPI
1073 ClassSendSrbSynchronous(
1074 _In_ PDEVICE_OBJECT DeviceObject,
1075 _Inout_ PSCSI_REQUEST_BLOCK Srb,
1076 _In_reads_bytes_opt_(BufferLength) PVOID BufferAddress,
1077 _In_ ULONG BufferLength,
1078 _In_ BOOLEAN WriteToDevice);
1079
1080 SCSIPORT_API
1081 NTSTATUS
1082 NTAPI
1083 ClassSendSrbAsynchronous(
1084 _In_ PDEVICE_OBJECT DeviceObject,
1085 _Inout_ PSCSI_REQUEST_BLOCK Srb,
1086 _In_ PIRP Irp,
1087 _In_reads_bytes_opt_(BufferLength) __drv_aliasesMem PVOID BufferAddress,
1088 _In_ ULONG BufferLength,
1089 _In_ BOOLEAN WriteToDevice);
1090
1091 SCSIPORT_API
1092 NTSTATUS
1093 NTAPI
1094 ClassBuildRequest(
1095 _In_ PDEVICE_OBJECT DeviceObject,
1096 _In_ PIRP Irp);
1097
1098 SCSIPORT_API
1099 ULONG
1100 NTAPI
1101 ClassModeSense(
1102 _In_ PDEVICE_OBJECT DeviceObject,
1103 _In_reads_bytes_(Length) PCHAR ModeSenseBuffer,
1104 _In_ ULONG Length,
1105 _In_ UCHAR PageMode);
1106
1107 SCSIPORT_API
1108 PVOID
1109 NTAPI
1110 ClassFindModePage(
1111 _In_reads_bytes_(Length) PCHAR ModeSenseBuffer,
1112 _In_ ULONG Length,
1113 _In_ UCHAR PageMode,
1114 _In_ BOOLEAN Use6Byte);
1115
1116 _IRQL_requires_max_(PASSIVE_LEVEL)
1117 SCSIPORT_API
1118 NTSTATUS
1119 NTAPI
1120 ClassClaimDevice(
1121 _In_ PDEVICE_OBJECT LowerDeviceObject,
1122 _In_ BOOLEAN Release);
1123
1124 SCSIPORT_API
1125 NTSTATUS
1126 NTAPI
1127 ClassInternalIoControl(
1128 PDEVICE_OBJECT DeviceObject,
1129 PIRP Irp);
1130
1131 _IRQL_requires_max_(PASSIVE_LEVEL)
1132 SCSIPORT_API
1133 VOID
1134 NTAPI
1135 ClassInitializeSrbLookasideList(
1136 _Inout_ PCOMMON_DEVICE_EXTENSION CommonExtension,
1137 _In_ ULONG NumberElements);
1138
1139 _IRQL_requires_max_(PASSIVE_LEVEL)
1140 SCSIPORT_API
1141 VOID
1142 NTAPI
1143 ClassDeleteSrbLookasideList(
1144 _Inout_ PCOMMON_DEVICE_EXTENSION CommonExtension);
1145
1146 _IRQL_requires_max_(PASSIVE_LEVEL)
1147 SCSIPORT_API
1148 ULONG
1149 NTAPI
1150 ClassQueryTimeOutRegistryValue(
1151 _In_ PDEVICE_OBJECT DeviceObject);
1152
1153 _IRQL_requires_max_(PASSIVE_LEVEL)
1154 SCSIPORT_API
1155 NTSTATUS
1156 NTAPI
1157 ClassGetDescriptor(
1158 _In_ PDEVICE_OBJECT DeviceObject,
1159 _In_ PSTORAGE_PROPERTY_ID PropertyId,
1160 _Outptr_ PVOID *Descriptor);
1161
1162 _IRQL_requires_max_(PASSIVE_LEVEL)
1163 SCSIPORT_API
1164 VOID
1165 NTAPI
1166 ClassInvalidateBusRelations(
1167 _In_ PDEVICE_OBJECT Fdo);
1168
1169 _IRQL_requires_max_(PASSIVE_LEVEL)
1170 SCSIPORT_API
1171 VOID
1172 NTAPI
1173 ClassMarkChildrenMissing(
1174 _In_ PFUNCTIONAL_DEVICE_EXTENSION Fdo);
1175
1176 _IRQL_requires_max_(PASSIVE_LEVEL)
1177 SCSIPORT_API
1178 BOOLEAN
1179 NTAPI
1180 ClassMarkChildMissing(
1181 _In_ PPHYSICAL_DEVICE_EXTENSION PdoExtension,
1182 _In_ BOOLEAN AcquireChildLock);
1183
1184 SCSIPORT_API
1185 VOID
1186 ClassDebugPrint(
1187 _In_ CLASS_DEBUG_LEVEL DebugPrintLevel,
1188 _In_z_ PCCHAR DebugMessage,
1189 ...);
1190
1191 __drv_aliasesMem
1192 _IRQL_requires_max_(DISPATCH_LEVEL)
1193 SCSIPORT_API
1194 PCLASS_DRIVER_EXTENSION
1195 NTAPI
1196 ClassGetDriverExtension(
1197 _In_ PDRIVER_OBJECT DriverObject);
1198
1199 SCSIPORT_API
1200 VOID
1201 NTAPI
1202 ClassCompleteRequest(
1203 _In_ PDEVICE_OBJECT DeviceObject,
1204 _In_ PIRP Irp,
1205 _In_ CCHAR PriorityBoost);
1206
1207 SCSIPORT_API
1208 VOID
1209 NTAPI
1210 ClassReleaseRemoveLock(
1211 _In_ PDEVICE_OBJECT DeviceObject,
1212 PIRP Tag);
1213
1214 SCSIPORT_API
1215 ULONG
1216 NTAPI
1217 ClassAcquireRemoveLockEx(
1218 _In_ PDEVICE_OBJECT DeviceObject,
1219 PVOID Tag,
1220 _In_ PCSTR File,
1221 _In_ ULONG Line);
1222
1223 _IRQL_requires_max_(PASSIVE_LEVEL)
1224 SCSIPORT_API
1225 VOID
1226 NTAPI
1227 ClassUpdateInformationInRegistry(
1228 _In_ PDEVICE_OBJECT Fdo,
1229 _In_ PCHAR DeviceName,
1230 _In_ ULONG DeviceNumber,
1231 _In_reads_bytes_opt_(InquiryDataLength) PINQUIRYDATA InquiryData,
1232 _In_ ULONG InquiryDataLength);
1233
1234 SCSIPORT_API
1235 NTSTATUS
1236 NTAPI
1237 ClassWmiCompleteRequest(
1238 _In_ PDEVICE_OBJECT DeviceObject,
1239 _Inout_ PIRP Irp,
1240 _In_ NTSTATUS Status,
1241 _In_ ULONG BufferUsed,
1242 _In_ CCHAR PriorityBoost);
1243
1244 _IRQL_requires_max_(DISPATCH_LEVEL)
1245 SCSIPORT_API
1246 NTSTATUS
1247 NTAPI
1248 ClassWmiFireEvent(
1249 _In_ PDEVICE_OBJECT DeviceObject,
1250 _In_ LPGUID Guid,
1251 _In_ ULONG InstanceIndex,
1252 _In_ ULONG EventDataSize,
1253 _In_reads_bytes_(EventDataSize) PVOID EventData);
1254
1255 SCSIPORT_API
1256 VOID
1257 NTAPI
1258 ClassResetMediaChangeTimer(
1259 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
1260
1261 _IRQL_requires_max_(PASSIVE_LEVEL)
1262 SCSIPORT_API
1263 VOID
1264 NTAPI
1265 ClassInitializeMediaChangeDetection(
1266 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1267 _In_ PUCHAR EventPrefix);
1268
1269 _IRQL_requires_max_(PASSIVE_LEVEL)
1270 SCSIPORT_API
1271 NTSTATUS
1272 NTAPI
1273 ClassInitializeTestUnitPolling(
1274 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1275 _In_ BOOLEAN AllowDriveToSleep);
1276
1277 SCSIPORT_API
1278 PVPB
1279 NTAPI
1280 ClassGetVpb(
1281 _In_ PDEVICE_OBJECT DeviceObject);
1282
1283 SCSIPORT_API
1284 NTSTATUS
1285 NTAPI
1286 ClassSpinDownPowerHandler(
1287 _In_ PDEVICE_OBJECT DeviceObject,
1288 _In_ PIRP Irp);
1289
1290 NTSTATUS
1291 NTAPI
1292 ClassStopUnitPowerHandler(
1293 _In_ PDEVICE_OBJECT DeviceObject,
1294 _In_ PIRP Irp);
1295
1296 _IRQL_requires_max_(PASSIVE_LEVEL)
1297 NTSTATUS
1298 NTAPI
1299 ClassSetFailurePredictionPoll(
1300 _Inout_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1301 _In_ FAILURE_PREDICTION_METHOD FailurePredictionMethod,
1302 _In_ ULONG PollingPeriod);
1303
1304 _IRQL_requires_max_(DISPATCH_LEVEL)
1305 VOID
1306 NTAPI
1307 ClassNotifyFailurePredicted(
1308 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1309 _In_reads_bytes_(BufferSize) PUCHAR Buffer,
1310 _In_ ULONG BufferSize,
1311 _In_ BOOLEAN LogError,
1312 _In_ ULONG UniqueErrorValue,
1313 _In_ UCHAR PathId,
1314 _In_ UCHAR TargetId,
1315 _In_ UCHAR Lun);
1316
1317 _IRQL_requires_max_(PASSIVE_LEVEL)
1318 SCSIPORT_API
1319 VOID
1320 NTAPI
1321 ClassAcquireChildLock(
1322 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
1323
1324 SCSIPORT_API
1325 VOID
1326 NTAPI
1327 ClassReleaseChildLock(
1328 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
1329
1330 IO_COMPLETION_ROUTINE ClassSignalCompletion;
1331
1332 VOID
1333 NTAPI
1334 ClassSendStartUnit(
1335 _In_ PDEVICE_OBJECT DeviceObject);
1336
1337 _IRQL_requires_max_(PASSIVE_LEVEL)
1338 SCSIPORT_API
1339 NTSTATUS
1340 NTAPI
1341 ClassRemoveDevice(
1342 _In_ PDEVICE_OBJECT DeviceObject,
1343 _In_ UCHAR RemoveType);
1344
1345 SCSIPORT_API
1346 NTSTATUS
1347 NTAPI
1348 ClassAsynchronousCompletion(
1349 PDEVICE_OBJECT DeviceObject,
1350 PIRP Irp,
1351 PVOID Event);
1352
1353 SCSIPORT_API
1354 VOID
1355 NTAPI
1356 ClassCheckMediaState(
1357 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
1358
1359 SCSIPORT_API
1360 NTSTATUS
1361 NTAPI
1362 ClassCheckVerifyComplete(
1363 PDEVICE_OBJECT DeviceObject,
1364 PIRP Irp,
1365 PVOID Context);
1366
1367 _IRQL_requires_max_(PASSIVE_LEVEL)
1368 SCSIPORT_API
1369 VOID
1370 NTAPI
1371 ClassSetMediaChangeState(
1372 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1373 _In_ MEDIA_CHANGE_DETECTION_STATE State,
1374 _In_ BOOLEAN Wait);
1375
1376 _IRQL_requires_max_(PASSIVE_LEVEL)
1377 SCSIPORT_API
1378 VOID
1379 NTAPI
1380 ClassEnableMediaChangeDetection(
1381 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
1382
1383 _IRQL_requires_max_(PASSIVE_LEVEL)
1384 SCSIPORT_API
1385 VOID
1386 NTAPI
1387 ClassDisableMediaChangeDetection(
1388 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
1389
1390 _IRQL_requires_max_(PASSIVE_LEVEL)
1391 SCSIPORT_API
1392 VOID
1393 NTAPI
1394 ClassCleanupMediaChangeDetection(
1395 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension);
1396
1397 _IRQL_requires_max_(PASSIVE_LEVEL)
1398 VOID
1399 NTAPI
1400 ClassGetDeviceParameter(
1401 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1402 _In_opt_ PWSTR SubkeyName,
1403 _In_ PWSTR ParameterName,
1404 _Inout_ PULONG ParameterValue);
1405
1406 _IRQL_requires_max_(PASSIVE_LEVEL)
1407 NTSTATUS
1408 NTAPI
1409 ClassSetDeviceParameter(
1410 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1411 _In_opt_ PWSTR SubkeyName,
1412 _In_ PWSTR ParameterName,
1413 _In_ ULONG ParameterValue);
1414
1415 #if (NTDDI_VERSION >= NTDDI_VISTA)
1416
1417 _IRQL_requires_max_(PASSIVE_LEVEL)
1418 PFILE_OBJECT_EXTENSION
1419 NTAPI
1420 ClassGetFsContext(
1421 _In_ PCOMMON_DEVICE_EXTENSION CommonExtension,
1422 _In_ PFILE_OBJECT FileObject);
1423
1424 _IRQL_requires_max_(DISPATCH_LEVEL)
1425 VOID
1426 NTAPI
1427 ClassSendNotification(
1428 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1429 _In_ const GUID *Guid,
1430 _In_ ULONG ExtraDataSize,
1431 _In_reads_bytes_opt_(ExtraDataSize) PVOID ExtraData);
1432
1433 #endif /* (NTDDI_VERSION >= NTDDI_VISTA) */
1434
1435 FORCEINLINE
1436 UCHAR
GET_FDO_EXTENSON_SENSE_DATA_LENGTH(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)1437 GET_FDO_EXTENSON_SENSE_DATA_LENGTH (
1438 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
1439 {
1440 UCHAR SenseDataLength = 0;
1441
1442 if (FdoExtension->SenseData != NULL)
1443 {
1444 #if (NTDDI_VERSION >= NTDDI_WIN8)
1445 if (FdoExtension->SenseDataLength > 0)
1446 {
1447 SenseDataLength = FdoExtension->SenseDataLength;
1448 }
1449 else
1450 {
1451 // For backward compatibility with Windows 7 and earlier
1452 SenseDataLength = SENSE_BUFFER_SIZE;
1453 }
1454 #else
1455 SenseDataLength = SENSE_BUFFER_SIZE;
1456 #endif
1457 }
1458
1459 return SenseDataLength;
1460 }
1461
1462 static __inline
1463 BOOLEAN
PORT_ALLOCATED_SENSE(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,_In_ PSCSI_REQUEST_BLOCK Srb)1464 PORT_ALLOCATED_SENSE(
1465 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1466 _In_ PSCSI_REQUEST_BLOCK Srb)
1467 {
1468 return ((BOOLEAN)((TEST_FLAG(Srb->SrbFlags, SRB_FLAGS_PORT_DRIVER_ALLOCSENSE) &&
1469 TEST_FLAG(Srb->SrbFlags, SRB_FLAGS_FREE_SENSE_BUFFER)) &&
1470 (Srb->SenseInfoBuffer != FdoExtension->SenseData)));
1471 }
1472
1473 static __inline
1474 VOID
FREE_PORT_ALLOCATED_SENSE_BUFFER(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,_In_ PSCSI_REQUEST_BLOCK Srb)1475 FREE_PORT_ALLOCATED_SENSE_BUFFER(
1476 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1477 _In_ PSCSI_REQUEST_BLOCK Srb)
1478 {
1479 ASSERT(TEST_FLAG(Srb->SrbFlags, SRB_FLAGS_PORT_DRIVER_ALLOCSENSE));
1480 ASSERT(TEST_FLAG(Srb->SrbFlags, SRB_FLAGS_FREE_SENSE_BUFFER));
1481 ASSERT(Srb->SenseInfoBuffer != FdoExtension->SenseData);
1482
1483 ExFreePool(Srb->SenseInfoBuffer);
1484 Srb->SenseInfoBuffer = FdoExtension->SenseData;
1485 Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
1486 CLEAR_FLAG(Srb->SrbFlags, SRB_FLAGS_FREE_SENSE_BUFFER);
1487 return;
1488 }
1489
1490 _IRQL_requires_max_(PASSIVE_LEVEL)
1491 typedef VOID
1492 (NTAPI *PCLASS_SCAN_FOR_SPECIAL_HANDLER)(
1493 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1494 _In_ ULONG_PTR Data);
1495
1496 _IRQL_requires_max_(PASSIVE_LEVEL)
1497 VOID
1498 NTAPI
1499 ClassScanForSpecial(
1500 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
1501 _In_ CLASSPNP_SCAN_FOR_SPECIAL_INFO DeviceList[],
1502 _In_ PCLASS_SCAN_FOR_SPECIAL_HANDLER Function);
1503