16 #define max(a,b) (((a) > (b)) ? (a) : (b))
17 #define min(a,b) (((a) < (b)) ? (a) : (b))
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
24 #define ASSERT_FDO(x) \
25 ASSERT(((PCOMMON_DEVICE_EXTENSION) (x)->DeviceExtension)->IsFdo)
27 #define ASSERT_PDO(x) \
28 ASSERT(!(((PCOMMON_DEVICE_EXTENSION) (x)->DeviceExtension)->IsFdo))
30 #define IS_CLEANUP_REQUEST(majorFunction) \
31 ((majorFunction == IRP_MJ_CLOSE) || \
32 (majorFunction == IRP_MJ_CLEANUP) || \
33 (majorFunction == IRP_MJ_SHUTDOWN))
35 #define DO_MCD(fdoExtension) \
36 (((fdoExtension)->MediaChangeDetectionInfo != NULL) && \
37 ((fdoExtension)->MediaChangeDetectionInfo->MediaChangeDetectionDisableCount == 0))
39 #define IS_SCSIOP_READ(opCode) \
40 ((opCode == SCSIOP_READ6) || \
41 (opCode == SCSIOP_READ) || \
42 (opCode == SCSIOP_READ12) || \
43 (opCode == SCSIOP_READ16))
45 #define IS_SCSIOP_WRITE(opCode) \
46 ((opCode == SCSIOP_WRITE6) || \
47 (opCode == SCSIOP_WRITE) || \
48 (opCode == SCSIOP_WRITE12) || \
49 (opCode == SCSIOP_WRITE16))
51 #define IS_SCSIOP_READWRITE(opCode) (IS_SCSIOP_READ(opCode) || IS_SCSIOP_WRITE(opCode))
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; \
59 fdoExt->CdbForceUnitAccess = FALSE; \
63 #define FREE_POOL(_PoolPtr) \
64 if (_PoolPtr != NULL) { \
65 ExFreePool(_PoolPtr); \
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')
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'
89 #define MAXIMUM_RETRIES 4
91 #define CLASS_DRIVER_EXTENSION_KEY ((PVOID) ClassInitialize)
94 #define REMOVE_PENDING 1
95 #define REMOVE_COMPLETE 2
97 #define ClassAcquireRemoveLock(devobj, tag) \
98 ClassAcquireRemoveLockEx(devobj, tag, __FILE__, __LINE__)
112 #define LEAVE goto __tryLabel;
113 #define FINALLY __tryLabel:
115 #if defined DebugPrint
120 #define DebugPrint(x) ClassDebugPrint x
122 #define DebugPrint(x)
125 #define DEBUG_BUFFER_LENGTH 256
127 #define START_UNIT_TIMEOUT (60 * 4)
129 #define MEDIA_CHANGE_DEFAULT_TIME 1
130 #define MEDIA_CHANGE_TIMEOUT_TIME 300
132 #ifdef ALLOCATE_SRB_FROM_POOL
134 #define ClasspAllocateSrb(ext) \
135 ExAllocatePoolWithTag(NonPagedPool, \
136 sizeof(SCSI_REQUEST_BLOCK), \
139 #define ClasspFreeSrb(ext, srb) ExFreePool((srb));
141 #else /* ALLOCATE_SRB_FROM_POOL */
143 #define ClasspAllocateSrb(ext) \
144 ExAllocateFromNPagedLookasideList( \
145 &((ext)->CommonExtension.SrbLookasideList))
147 #define ClasspFreeSrb(ext, srb) \
148 ExFreeToNPagedLookasideList( \
149 &((ext)->CommonExtension.SrbLookasideList), \
152 #endif /* ALLOCATE_SRB_FROM_POOL */
154 #define SET_FLAG(Flags, Bit) ((Flags) |= (Bit))
155 #define CLEAR_FLAG(Flags, Bit) ((Flags) &= ~(Bit))
156 #define TEST_FLAG(Flags, Bit) (((Flags) & (Bit)) != 0)
158 #define CLASS_WORKING_SET_MAXIMUM 2048
160 #define CLASS_INTERPRET_SENSE_INFO2_MAXIMUM_HISTORY_COUNT 30000
162 #define CLASS_SPECIAL_DISABLE_SPIN_DOWN 0x00000001
163 #define CLASS_SPECIAL_DISABLE_SPIN_UP 0x00000002
164 #define CLASS_SPECIAL_NO_QUEUE_LOCK 0x00000008
165 #define CLASS_SPECIAL_DISABLE_WRITE_CACHE 0x00000010
166 #define CLASS_SPECIAL_CAUSE_NOT_REPORTABLE_HACK 0x00000020
167 #if ((NTDDI_VERSION == NTDDI_WIN2KSP3) || (OSVER(NTDDI_VERSION) == NTDDI_WINXP))
168 #define CLASS_SPECIAL_DISABLE_WRITE_CACHE_NOT_SUPPORTED 0x00000040
170 #define CLASS_SPECIAL_MODIFY_CACHE_UNSUCCESSFUL 0x00000040
171 #define CLASS_SPECIAL_FUA_NOT_SUPPORTED 0x00000080
172 #define CLASS_SPECIAL_VALID_MASK 0x000000FB
173 #define CLASS_SPECIAL_RESERVED (~CLASS_SPECIAL_VALID_MASK)
175 #define DEV_WRITE_CACHE 0x00000001
176 #define DEV_USE_SCSI1 0x00000002
177 #define DEV_SAFE_START_UNIT 0x00000004
178 #define DEV_NO_12BYTE_CDB 0x00000008
179 #define DEV_POWER_PROTECTED 0x00000010
180 #define DEV_USE_16BYTE_CDB 0x00000020
182 #define GUID_CLASSPNP_QUERY_REGINFOEX {0x00e34b11, 0x2444, 0x4745, {0xa5, 0x3d, 0x62, 0x01, 0x00, 0xcd, 0x82, 0xf7}}
183 #define GUID_CLASSPNP_SENSEINFO2 {0x509a8c5f, 0x71d7, 0x48f6, {0x82, 0x1e, 0x17, 0x3c, 0x49, 0xbf, 0x2f, 0x18}}
184 #define GUID_CLASSPNP_WORKING_SET {0x105701b0, 0x9e9b, 0x47cb, {0x97, 0x80, 0x81, 0x19, 0x8a, 0xf7, 0xb5, 0x24}}
186 #define DEFAULT_FAILURE_PREDICTION_PERIOD 60 * 60 * 1
188 #define MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS (0x3b9aca00)
190 static inline ULONG
CountOfSetBitsUChar(UCHAR _X
)
191 { ULONG i
= 0; while (_X
) { _X
&= _X
- 1; i
++; } return i
; }
192 static inline ULONG
CountOfSetBitsULong(ULONG _X
)
193 { ULONG i
= 0; while (_X
) { _X
&= _X
- 1; i
++; } return i
; }
194 static inline ULONG
CountOfSetBitsULong32(ULONG32 _X
)
195 { ULONG i
= 0; while (_X
) { _X
&= _X
- 1; i
++; } return i
; }
196 static inline ULONG
CountOfSetBitsULong64(ULONG64 _X
)
197 { ULONG i
= 0; while (_X
) { _X
&= _X
- 1; i
++; } return i
; }
198 static inline ULONG
CountOfSetBitsUlongPtr(ULONG_PTR _X
)
199 { ULONG i
= 0; while (_X
) { _X
&= _X
- 1; i
++; } return i
; }
201 typedef enum _MEDIA_CHANGE_DETECTION_STATE
{
206 } MEDIA_CHANGE_DETECTION_STATE
, *PMEDIA_CHANGE_DETECTION_STATE
;
208 typedef enum _CLASS_DEBUG_LEVEL
{
210 ClassDebugWarning
= 1,
213 ClassDebugMediaLocks
= 8,
215 ClassDebugDelayedRetry
= 10,
216 ClassDebugSenseInfo
= 11,
217 ClassDebugRemoveLock
= 12,
218 ClassDebugExternal4
= 13,
219 ClassDebugExternal3
= 14,
220 ClassDebugExternal2
= 15,
221 ClassDebugExternal1
= 16
222 } CLASS_DEBUG_LEVEL
, *PCLASS_DEBUG_LEVEL
;
227 } CLASSENABLEDISABLEFUNCTION
;
230 FailurePredictionNone
= 0,
231 FailurePredictionIoctl
,
232 FailurePredictionSmart
,
233 FailurePredictionSense
234 } FAILURE_PREDICTION_METHOD
, *PFAILURE_PREDICTION_METHOD
;
237 PowerDownDeviceInitial
,
238 PowerDownDeviceLocked
,
239 PowerDownDeviceStopped
,
241 PowerDownDeviceUnlocked
242 } CLASS_POWER_DOWN_STATE
;
245 PowerDownDeviceInitial2
,
246 PowerDownDeviceLocked2
,
247 PowerDownDeviceFlushed2
,
248 PowerDownDeviceStopped2
,
250 PowerDownDeviceUnlocked2
251 } CLASS_POWER_DOWN_STATE2
;
254 PowerUpDeviceInitial
,
257 PowerUpDeviceStarted
,
258 PowerUpDeviceUnlocked
259 } CLASS_POWER_UP_STATE
;
261 struct _CLASS_INIT_DATA
;
262 typedef struct _CLASS_INIT_DATA CLASS_INIT_DATA
, *PCLASS_INIT_DATA
;
264 struct _CLASS_PRIVATE_FDO_DATA
;
265 typedef struct _CLASS_PRIVATE_FDO_DATA CLASS_PRIVATE_FDO_DATA
, *PCLASS_PRIVATE_FDO_DATA
;
267 struct _CLASS_PRIVATE_PDO_DATA
;
268 typedef struct _CLASS_PRIVATE_PDO_DATA CLASS_PRIVATE_PDO_DATA
, *PCLASS_PRIVATE_PDO_DATA
;
270 struct _CLASS_PRIVATE_COMMON_DATA
;
271 typedef struct _CLASS_PRIVATE_COMMON_DATA CLASS_PRIVATE_COMMON_DATA
, *PCLASS_PRIVATE_COMMON_DATA
;
273 struct _MEDIA_CHANGE_DETECTION_INFO
;
274 typedef struct _MEDIA_CHANGE_DETECTION_INFO MEDIA_CHANGE_DETECTION_INFO
, *PMEDIA_CHANGE_DETECTION_INFO
;
276 typedef struct _DICTIONARY
{
278 struct _DICTIONARY_HEADER
* List
;
280 } DICTIONARY
, *PDICTIONARY
;
282 typedef struct _CLASSPNP_SCAN_FOR_SPECIAL_INFO
{
285 PCHAR ProductRevision
;
287 } CLASSPNP_SCAN_FOR_SPECIAL_INFO
, *PCLASSPNP_SCAN_FOR_SPECIAL_INFO
;
289 _IRQL_requires_max_(DISPATCH_LEVEL
)
291 (NTAPI
*PCLASS_ERROR
)(
292 _In_ PDEVICE_OBJECT DeviceObject
,
293 _In_ PSCSI_REQUEST_BLOCK Srb
,
294 _Out_ NTSTATUS
*Status
,
295 _Inout_ BOOLEAN
*Retry
);
297 _IRQL_requires_max_(PASSIVE_LEVEL
)
299 (NTAPI
*PCLASS_ADD_DEVICE
)(
300 _In_ PDRIVER_OBJECT DriverObject
,
301 _In_ PDEVICE_OBJECT Pdo
);
304 (NTAPI
*PCLASS_POWER_DEVICE
)(
305 _In_ PDEVICE_OBJECT DeviceObject
,
308 _IRQL_requires_max_(PASSIVE_LEVEL
)
310 (NTAPI
*PCLASS_START_DEVICE
)(
311 _In_ PDEVICE_OBJECT DeviceObject
);
313 _IRQL_requires_max_(PASSIVE_LEVEL
)
315 (NTAPI
*PCLASS_STOP_DEVICE
)(
316 _In_ PDEVICE_OBJECT DeviceObject
,
319 _IRQL_requires_max_(PASSIVE_LEVEL
)
321 (NTAPI
*PCLASS_INIT_DEVICE
)(
322 _In_ PDEVICE_OBJECT DeviceObject
);
324 _IRQL_requires_max_(PASSIVE_LEVEL
)
326 (NTAPI
*PCLASS_ENUM_DEVICE
)(
327 _In_ PDEVICE_OBJECT DeviceObject
);
329 _IRQL_requires_max_(DISPATCH_LEVEL
)
331 (NTAPI
*PCLASS_READ_WRITE
)(
332 _In_ PDEVICE_OBJECT DeviceObject
,
335 _IRQL_requires_max_(DISPATCH_LEVEL
)
337 (NTAPI
*PCLASS_DEVICE_CONTROL
)(
338 _In_ PDEVICE_OBJECT DeviceObject
,
341 _IRQL_requires_max_(DISPATCH_LEVEL
)
343 (NTAPI
*PCLASS_SHUTDOWN_FLUSH
)(
344 _In_ PDEVICE_OBJECT DeviceObject
,
347 _IRQL_requires_max_(PASSIVE_LEVEL
)
349 (NTAPI
*PCLASS_CREATE_CLOSE
)(
350 _In_ PDEVICE_OBJECT DeviceObject
,
353 _IRQL_requires_max_(PASSIVE_LEVEL
)
355 (NTAPI
*PCLASS_QUERY_ID
)(
356 _In_ PDEVICE_OBJECT DeviceObject
,
357 _In_ BUS_QUERY_ID_TYPE IdType
,
358 _In_ PUNICODE_STRING IdString
);
360 _IRQL_requires_max_(PASSIVE_LEVEL
)
362 (NTAPI
*PCLASS_REMOVE_DEVICE
)(
363 _In_ PDEVICE_OBJECT DeviceObject
,
366 _IRQL_requires_max_(PASSIVE_LEVEL
)
368 (NTAPI
*PCLASS_UNLOAD
)(
369 _In_ PDRIVER_OBJECT DriverObject
);
371 _IRQL_requires_max_(PASSIVE_LEVEL
)
373 (NTAPI
*PCLASS_QUERY_PNP_CAPABILITIES
)(
374 _In_ PDEVICE_OBJECT PhysicalDeviceObject
,
375 _In_ PDEVICE_CAPABILITIES Capabilities
);
377 _IRQL_requires_(DISPATCH_LEVEL
)
379 (NTAPI
*PCLASS_TICK
)(
380 _In_ PDEVICE_OBJECT DeviceObject
);
382 _IRQL_requires_max_(PASSIVE_LEVEL
)
384 (NTAPI
*PCLASS_QUERY_WMI_REGINFO_EX
)(
385 _In_ PDEVICE_OBJECT DeviceObject
,
386 _Out_ ULONG
*RegFlags
,
387 _Out_ PUNICODE_STRING Name
,
388 _Out_ PUNICODE_STRING MofResourceName
);
390 _IRQL_requires_max_(PASSIVE_LEVEL
)
392 (NTAPI
*PCLASS_QUERY_WMI_REGINFO
)(
393 _In_ PDEVICE_OBJECT DeviceObject
,
394 _Out_ ULONG
*RegFlags
,
395 _Out_ PUNICODE_STRING Name
);
397 _IRQL_requires_max_(PASSIVE_LEVEL
)
399 (NTAPI
*PCLASS_QUERY_WMI_DATABLOCK
)(
400 _In_ PDEVICE_OBJECT DeviceObject
,
402 _In_ ULONG GuidIndex
,
403 _In_ ULONG BufferAvail
,
404 _Out_writes_bytes_(BufferAvail
) PUCHAR Buffer
);
406 _IRQL_requires_max_(PASSIVE_LEVEL
)
408 (NTAPI
*PCLASS_SET_WMI_DATABLOCK
)(
409 _In_ PDEVICE_OBJECT DeviceObject
,
411 _In_ ULONG GuidIndex
,
412 _In_ ULONG BufferSize
,
413 _In_reads_bytes_(BufferSize
) PUCHAR Buffer
);
415 _IRQL_requires_max_(PASSIVE_LEVEL
)
417 (NTAPI
*PCLASS_SET_WMI_DATAITEM
)(
418 _In_ PDEVICE_OBJECT DeviceObject
,
420 _In_ ULONG GuidIndex
,
421 _In_ ULONG DataItemId
,
422 _In_ ULONG BufferSize
,
423 _In_reads_bytes_(BufferSize
) PUCHAR Buffer
);
425 _IRQL_requires_max_(PASSIVE_LEVEL
)
427 (NTAPI
*PCLASS_EXECUTE_WMI_METHOD
)(
428 _In_ PDEVICE_OBJECT DeviceObject
,
430 _In_ ULONG GuidIndex
,
432 _In_ ULONG InBufferSize
,
433 _In_ ULONG OutBufferSize
,
434 _In_reads_(_Inexpressible_(max(InBufferSize
, OutBufferSize
))) PUCHAR Buffer
);
436 _IRQL_requires_max_(PASSIVE_LEVEL
)
438 (NTAPI
*PCLASS_WMI_FUNCTION_CONTROL
)(
439 _In_ PDEVICE_OBJECT DeviceObject
,
441 _In_ ULONG GuidIndex
,
442 _In_ CLASSENABLEDISABLEFUNCTION Function
,
443 _In_ BOOLEAN Enable
);
445 typedef struct _SRB_HISTORY_ITEM
{
446 LARGE_INTEGER TickCountSent
;
447 LARGE_INTEGER TickCountCompleted
;
448 ULONG MillisecondsDelayOnRetry
;
449 SENSE_DATA NormalizedSenseData
;
451 UCHAR ClassDriverUse
;
452 } SRB_HISTORY_ITEM
, *PSRB_HISTORY_ITEM
;
454 typedef struct _SRB_HISTORY
{
455 ULONG_PTR ClassDriverUse
[4];
456 _Field_range_(1,30000) ULONG TotalHistoryCount
;
457 _Field_range_(0,TotalHistoryCount
) ULONG UsedHistoryCount
;
458 _Field_size_part_(TotalHistoryCount
, UsedHistoryCount
) SRB_HISTORY_ITEM History
[1];
459 } SRB_HISTORY
, *PSRB_HISTORY
;
461 _IRQL_requires_max_(DISPATCH_LEVEL
)
463 (NTAPI
*PCLASS_INTERPRET_SENSE_INFO
)(
464 _In_ PDEVICE_OBJECT Fdo
,
465 _In_opt_ PIRP OriginalRequest
,
466 _In_ PSCSI_REQUEST_BLOCK Srb
,
467 _In_ UCHAR MajorFunctionCode
,
468 _In_ ULONG IoDeviceCode
,
469 _In_ ULONG PreviousRetryCount
,
470 _In_opt_ SRB_HISTORY
*RequestHistory
,
471 _Out_ NTSTATUS
*Status
,
472 _Out_
_Deref_out_range_(0,MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS
)
473 LONGLONG
*RetryIn100nsUnits
);
475 _IRQL_requires_max_(DISPATCH_LEVEL
)
476 _At_(RequestHistory
->UsedHistoryCount
, _Pre_equal_to_(RequestHistory
->TotalHistoryCount
)
477 _Out_range_(0, RequestHistory
->TotalHistoryCount
- 1))
479 (NTAPI
*PCLASS_COMPRESS_RETRY_HISTORY_DATA
)(
480 _In_ PDEVICE_OBJECT DeviceObject
,
481 _Inout_ PSRB_HISTORY RequestHistory
);
487 } GUIDREGINFO
, *PGUIDREGINFO
;
489 typedef struct _CLASS_WMI_INFO
{
491 PGUIDREGINFO GuidRegInfo
;
492 PCLASS_QUERY_WMI_REGINFO ClassQueryWmiRegInfo
;
493 PCLASS_QUERY_WMI_DATABLOCK ClassQueryWmiDataBlock
;
494 PCLASS_SET_WMI_DATABLOCK ClassSetWmiDataBlock
;
495 PCLASS_SET_WMI_DATAITEM ClassSetWmiDataItem
;
496 PCLASS_EXECUTE_WMI_METHOD ClassExecuteWmiMethod
;
497 PCLASS_WMI_FUNCTION_CONTROL ClassWmiFunctionControl
;
498 } CLASS_WMI_INFO
, *PCLASS_WMI_INFO
;
500 typedef struct _CLASS_DEV_INFO
{
501 ULONG DeviceExtensionSize
;
502 DEVICE_TYPE DeviceType
;
504 ULONG DeviceCharacteristics
;
505 PCLASS_ERROR ClassError
;
506 PCLASS_READ_WRITE ClassReadWriteVerification
;
507 PCLASS_DEVICE_CONTROL ClassDeviceControl
;
508 PCLASS_SHUTDOWN_FLUSH ClassShutdownFlush
;
509 PCLASS_CREATE_CLOSE ClassCreateClose
;
510 PCLASS_INIT_DEVICE ClassInitDevice
;
511 PCLASS_START_DEVICE ClassStartDevice
;
512 PCLASS_POWER_DEVICE ClassPowerDevice
;
513 PCLASS_STOP_DEVICE ClassStopDevice
;
514 PCLASS_REMOVE_DEVICE ClassRemoveDevice
;
515 PCLASS_QUERY_PNP_CAPABILITIES ClassQueryPnpCapabilities
;
516 CLASS_WMI_INFO ClassWmiInfo
;
517 } CLASS_DEV_INFO
, *PCLASS_DEV_INFO
;
519 struct _CLASS_INIT_DATA
{
520 ULONG InitializationDataSize
;
521 CLASS_DEV_INFO FdoData
;
522 CLASS_DEV_INFO PdoData
;
523 PCLASS_ADD_DEVICE ClassAddDevice
;
524 PCLASS_ENUM_DEVICE ClassEnumerateDevice
;
525 PCLASS_QUERY_ID ClassQueryId
;
526 PDRIVER_STARTIO ClassStartIo
;
527 PCLASS_UNLOAD ClassUnload
;
528 PCLASS_TICK ClassTick
;
531 typedef struct _FILE_OBJECT_EXTENSION
{
532 PFILE_OBJECT FileObject
;
533 PDEVICE_OBJECT DeviceObject
;
535 ULONG McnDisableCount
;
536 } FILE_OBJECT_EXTENSION
, *PFILE_OBJECT_EXTENSION
;
538 typedef struct _CLASS_WORKING_SET
{
539 _Field_range_(sizeof(CLASS_WORKING_SET
),sizeof(CLASS_WORKING_SET
)) ULONG Size
;
540 _Field_range_(0,2048) ULONG XferPacketsWorkingSetMaximum
;
541 _Field_range_(0,2048) ULONG XferPacketsWorkingSetMinimum
;
542 } CLASS_WORKING_SET
, *PCLASS_WORKING_SET
;
544 typedef struct _CLASS_INTERPRET_SENSE_INFO2
{
545 _Field_range_(sizeof(CLASS_INTERPRET_SENSE_INFO
),sizeof(CLASS_INTERPRET_SENSE_INFO
))
547 _Field_range_(1,30000) ULONG HistoryCount
;
548 __callback PCLASS_COMPRESS_RETRY_HISTORY_DATA Compress
;
549 __callback PCLASS_INTERPRET_SENSE_INFO Interpret
;
550 } CLASS_INTERPRET_SENSE_INFO2
, *PCLASS_INTERPRET_SENSE_INFO2
;
552 C_ASSERT((MAXULONG
- sizeof(SRB_HISTORY
)) / 30000 >= sizeof(SRB_HISTORY_ITEM
));
554 typedef struct _CLASS_DRIVER_EXTENSION
{
555 UNICODE_STRING RegistryPath
;
556 CLASS_INIT_DATA InitData
;
558 #if (NTDDI_VERSION >= NTDDI_WINXP)
559 PCLASS_QUERY_WMI_REGINFO_EX ClassFdoQueryWmiRegInfoEx
;
560 PCLASS_QUERY_WMI_REGINFO_EX ClassPdoQueryWmiRegInfoEx
;
562 #if (NTDDI_VERSION >= NTDDI_VISTA)
564 PDRIVER_DISPATCH DeviceMajorFunctionTable
[IRP_MJ_MAXIMUM_FUNCTION
+ 1];
565 PDRIVER_DISPATCH MpDeviceMajorFunctionTable
[IRP_MJ_MAXIMUM_FUNCTION
+ 1];
566 PCLASS_INTERPRET_SENSE_INFO2 InterpretSenseInfo
;
567 PCLASS_WORKING_SET WorkingSet
;
569 } CLASS_DRIVER_EXTENSION
, *PCLASS_DRIVER_EXTENSION
;
571 typedef struct _COMMON_DEVICE_EXTENSION
{
573 PDEVICE_OBJECT DeviceObject
;
574 PDEVICE_OBJECT LowerDeviceObject
;
575 struct _FUNCTIONAL_DEVICE_EXTENSION
*PartitionZeroExtension
;
576 PCLASS_DRIVER_EXTENSION DriverExtension
;
579 KSPIN_LOCK RemoveTrackingSpinlock
;
580 PVOID RemoveTrackingList
;
581 LONG RemoveTrackingUntrackedCount
;
583 _ANONYMOUS_STRUCT
struct {
585 BOOLEAN IsInitialized
:1;
586 BOOLEAN IsSrbLookasideListInitialized
:1;
591 UNICODE_STRING DeviceName
;
592 struct _PHYSICAL_DEVICE_EXTENSION
*ChildList
;
593 ULONG PartitionNumber
;
594 LARGE_INTEGER PartitionLength
;
595 LARGE_INTEGER StartingOffset
;
596 PCLASS_DEV_INFO DevInfo
;
597 ULONG PagingPathCount
;
599 ULONG HibernationPathCount
;
600 KEVENT PathCountEvent
;
601 #ifndef ALLOCATE_SRB_FROM_POOL
602 NPAGED_LOOKASIDE_LIST SrbLookasideList
;
604 UNICODE_STRING MountedDeviceInterfaceName
;
606 PGUIDREGINFO GuidRegInfo
;
607 DICTIONARY FileObjectDictionary
;
608 #if (NTDDI_VERSION >= NTDDI_WINXP)
609 PCLASS_PRIVATE_COMMON_DATA PrivateCommonData
;
613 #if (NTDDI_VERSION >= NTDDI_VISTA)
614 PDRIVER_DISPATCH
*DispatchTable
;
620 } COMMON_DEVICE_EXTENSION
, *PCOMMON_DEVICE_EXTENSION
;
622 typedef struct _PHYSICAL_DEVICE_EXTENSION
{
623 _ANONYMOUS_UNION
union {
624 _ANONYMOUS_STRUCT
struct {
626 PDEVICE_OBJECT DeviceObject
;
628 COMMON_DEVICE_EXTENSION CommonExtension
;
631 BOOLEAN IsEnumerated
;
632 #if (NTDDI_VERSION >= NTDDI_WINXP)
633 PCLASS_PRIVATE_PDO_DATA PrivatePdoData
;
640 } PHYSICAL_DEVICE_EXTENSION
, *PPHYSICAL_DEVICE_EXTENSION
;
642 typedef struct _CLASS_POWER_OPTIONS
{
645 ULONG HandleSpinDown
:1;
646 ULONG HandleSpinUp
:1;
648 } CLASS_POWER_OPTIONS
, *PCLASS_POWER_OPTIONS
;
650 typedef struct _CLASS_POWER_CONTEXT
{
652 CLASS_POWER_DOWN_STATE PowerDown
;
653 CLASS_POWER_DOWN_STATE2 PowerDown2
;
654 CLASS_POWER_UP_STATE PowerUp
;
656 CLASS_POWER_OPTIONS Options
;
659 NTSTATUS FinalStatus
;
662 PIO_COMPLETION_ROUTINE CompletionRoutine
;
663 PDEVICE_OBJECT DeviceObject
;
665 SCSI_REQUEST_BLOCK Srb
;
666 } CLASS_POWER_CONTEXT
, *PCLASS_POWER_CONTEXT
;
668 typedef struct _COMPLETION_CONTEXT
{
669 PDEVICE_OBJECT DeviceObject
;
670 SCSI_REQUEST_BLOCK Srb
;
671 } COMPLETION_CONTEXT
, *PCOMPLETION_CONTEXT
;
673 _IRQL_requires_max_(PASSIVE_LEVEL
)
674 _Must_inspect_result_
679 _In_ PVOID Argument1
,
680 _In_ PVOID Argument2
,
681 _In_ PCLASS_INIT_DATA InitializationData
);
683 typedef struct _CLASS_QUERY_WMI_REGINFO_EX_LIST
{
685 __callback PCLASS_QUERY_WMI_REGINFO_EX ClassFdoQueryWmiRegInfoEx
;
686 __callback PCLASS_QUERY_WMI_REGINFO_EX ClassPdoQueryWmiRegInfoEx
;
687 } CLASS_QUERY_WMI_REGINFO_EX_LIST
, *PCLASS_QUERY_WMI_REGINFO_EX_LIST
;
689 typedef struct _FUNCTIONAL_DEVICE_EXTENSION
{
690 _ANONYMOUS_UNION
union {
691 _ANONYMOUS_STRUCT
struct {
693 PDEVICE_OBJECT DeviceObject
;
695 COMMON_DEVICE_EXTENSION CommonExtension
;
697 PDEVICE_OBJECT LowerPdo
;
698 PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor
;
699 PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
;
700 DEVICE_POWER_STATE DevicePowerState
;
704 DISK_GEOMETRY DiskGeometry
;
705 PSENSE_DATA SenseData
;
711 LONG ProtectedLockCount
;
712 LONG InternalLockCount
;
713 KEVENT EjectSynchronizationEvent
;
716 #if (NTDDI_VERSION >= NTDDI_VISTA)
717 UCHAR CdbForceUnitAccess
;
721 PMEDIA_CHANGE_DETECTION_INFO MediaChangeDetectionInfo
;
724 FILE_OBJECT_EXTENSION KernelModeMcnContext
;
725 ULONG MediaChangeCount
;
726 HANDLE DeviceDirectory
;
727 KSPIN_LOCK ReleaseQueueSpinLock
;
728 PIRP ReleaseQueueIrp
;
729 SCSI_REQUEST_BLOCK ReleaseQueueSrb
;
730 BOOLEAN ReleaseQueueNeeded
;
731 BOOLEAN ReleaseQueueInProgress
;
732 BOOLEAN ReleaseQueueIrpFromPool
;
733 BOOLEAN FailurePredicted
;
735 struct _FAILURE_PREDICTION_INFO
* FailurePredictionInfo
;
736 BOOLEAN PowerDownInProgress
;
737 ULONG EnumerationInterlock
;
739 PKTHREAD ChildLockOwner
;
740 ULONG ChildLockAcquisitionCount
;
741 ULONG ScanForSpecialFlags
;
743 KTIMER PowerRetryTimer
;
744 CLASS_POWER_CONTEXT PowerContext
;
746 #if (NTDDI_VERSION <= NTDDI_WIN2K)
748 #if (SPVER(NTDDI_VERSION) < 2))
754 ULONG CompletionSuccessCount
;
756 ULONG SavedErrorCount
;
760 #else /* (NTDDI_VERSION <= NTDDI_WIN2K) */
762 PCLASS_PRIVATE_FDO_DATA PrivateFdoData
;
767 #endif /* (NTDDI_VERSION <= NTDDI_WIN2K) */
769 } FUNCTIONAL_DEVICE_EXTENSION
, *PFUNCTIONAL_DEVICE_EXTENSION
;
771 _IRQL_requires_max_(PASSIVE_LEVEL
)
772 _Must_inspect_result_
777 _In_ PDRIVER_OBJECT DriverObject
,
781 _IRQL_requires_max_(PASSIVE_LEVEL
)
782 _Must_inspect_result_
783 _Post_satisfies_(return <= 0)
787 ClassCreateDeviceObject(
788 _In_ PDRIVER_OBJECT DriverObject
,
789 _In_z_ PCCHAR ObjectNameBuffer
,
790 _In_ PDEVICE_OBJECT LowerDeviceObject
,
792 _Outptr_result_nullonfailure_
_At_(*DeviceObject
, __drv_allocatesMem(Mem
) __drv_aliasesMem
)
793 PDEVICE_OBJECT
*DeviceObject
);
795 _Must_inspect_result_
799 ClassReadDriveCapacity(
800 _In_ PDEVICE_OBJECT DeviceObject
);
806 _In_ PDEVICE_OBJECT DeviceObject
);
812 _In_ PDEVICE_OBJECT DeviceObject
,
814 _In_ ULONG MaximumBytes
);
820 _In_ PDEVICE_OBJECT DeviceObject
,
827 PDEVICE_OBJECT DeviceObject
,
834 ClassIoCompleteAssociated(
835 PDEVICE_OBJECT DeviceObject
,
842 ClassInterpretSenseInfo(
843 _In_ PDEVICE_OBJECT DeviceObject
,
844 _In_ PSCSI_REQUEST_BLOCK Srb
,
845 _In_ UCHAR MajorFunctionCode
,
846 _In_ ULONG IoDeviceCode
,
847 _In_ ULONG RetryCount
,
848 _Out_ NTSTATUS
*Status
,
849 _Out_opt_
_Deref_out_range_(0,100) ULONG
*RetryInterval
);
853 ClassSendDeviceIoControlSynchronous(
854 _In_ ULONG IoControlCode
,
855 _In_ PDEVICE_OBJECT TargetDeviceObject
,
856 _Inout_updates_opt_(_Inexpressible_(max(InputBufferLength
, OutputBufferLength
)))
858 _In_ ULONG InputBufferLength
,
859 _In_ ULONG OutputBufferLength
,
860 _In_ BOOLEAN InternalDeviceIoControl
,
861 _Out_ PIO_STATUS_BLOCK IoStatus
);
866 ClassSendIrpSynchronous(
867 _In_ PDEVICE_OBJECT TargetDeviceObject
,
873 ClassForwardIrpSynchronous(
874 _In_ PCOMMON_DEVICE_EXTENSION CommonExtension
,
880 ClassSendSrbSynchronous(
881 _In_ PDEVICE_OBJECT DeviceObject
,
882 _Inout_ PSCSI_REQUEST_BLOCK Srb
,
883 _In_reads_bytes_opt_(BufferLength
) PVOID BufferAddress
,
884 _In_ ULONG BufferLength
,
885 _In_ BOOLEAN WriteToDevice
);
890 ClassSendSrbAsynchronous(
891 _In_ PDEVICE_OBJECT DeviceObject
,
892 _Inout_ PSCSI_REQUEST_BLOCK Srb
,
894 _In_reads_bytes_opt_(BufferLength
) __drv_aliasesMem PVOID BufferAddress
,
895 _In_ ULONG BufferLength
,
896 _In_ BOOLEAN WriteToDevice
);
902 _In_ PDEVICE_OBJECT DeviceObject
,
909 _In_ PDEVICE_OBJECT DeviceObject
,
910 _In_reads_bytes_(Length
) PCHAR ModeSenseBuffer
,
912 _In_ UCHAR PageMode
);
918 _In_reads_bytes_(Length
) PCHAR ModeSenseBuffer
,
921 _In_ BOOLEAN Use6Byte
);
923 _IRQL_requires_max_(PASSIVE_LEVEL
)
928 _In_ PDEVICE_OBJECT LowerDeviceObject
,
929 _In_ BOOLEAN Release
);
934 ClassInternalIoControl(
935 PDEVICE_OBJECT DeviceObject
,
938 _IRQL_requires_max_(PASSIVE_LEVEL
)
942 ClassInitializeSrbLookasideList(
943 _Inout_ PCOMMON_DEVICE_EXTENSION CommonExtension
,
944 _In_ ULONG NumberElements
);
946 _IRQL_requires_max_(PASSIVE_LEVEL
)
950 ClassDeleteSrbLookasideList(
951 _Inout_ PCOMMON_DEVICE_EXTENSION CommonExtension
);
953 _IRQL_requires_max_(PASSIVE_LEVEL
)
957 ClassQueryTimeOutRegistryValue(
958 _In_ PDEVICE_OBJECT DeviceObject
);
960 _IRQL_requires_max_(PASSIVE_LEVEL
)
965 _In_ PDEVICE_OBJECT DeviceObject
,
966 _In_ PSTORAGE_PROPERTY_ID PropertyId
,
967 _Outptr_ PSTORAGE_DESCRIPTOR_HEADER
*Descriptor
);
969 _IRQL_requires_max_(PASSIVE_LEVEL
)
973 ClassInvalidateBusRelations(
974 _In_ PDEVICE_OBJECT Fdo
);
976 _IRQL_requires_max_(PASSIVE_LEVEL
)
980 ClassMarkChildrenMissing(
981 _In_ PFUNCTIONAL_DEVICE_EXTENSION Fdo
);
983 _IRQL_requires_max_(PASSIVE_LEVEL
)
987 ClassMarkChildMissing(
988 _In_ PPHYSICAL_DEVICE_EXTENSION PdoExtension
,
989 _In_ BOOLEAN AcquireChildLock
);
994 _In_ CLASS_DEBUG_LEVEL DebugPrintLevel
,
995 _In_z_ PCCHAR DebugMessage
,
999 _IRQL_requires_max_(DISPATCH_LEVEL
)
1001 PCLASS_DRIVER_EXTENSION
1003 ClassGetDriverExtension(
1004 _In_ PDRIVER_OBJECT DriverObject
);
1009 ClassCompleteRequest(
1010 _In_ PDEVICE_OBJECT DeviceObject
,
1012 _In_ CCHAR PriorityBoost
);
1017 ClassReleaseRemoveLock(
1018 _In_ PDEVICE_OBJECT DeviceObject
,
1024 ClassAcquireRemoveLockEx(
1025 _In_ PDEVICE_OBJECT DeviceObject
,
1030 _IRQL_requires_max_(PASSIVE_LEVEL
)
1034 ClassUpdateInformationInRegistry(
1035 _In_ PDEVICE_OBJECT Fdo
,
1036 _In_ PCHAR DeviceName
,
1037 _In_ ULONG DeviceNumber
,
1038 _In_reads_bytes_opt_(InquiryDataLength
) PINQUIRYDATA InquiryData
,
1039 _In_ ULONG InquiryDataLength
);
1044 ClassWmiCompleteRequest(
1045 _In_ PDEVICE_OBJECT DeviceObject
,
1047 _In_ NTSTATUS Status
,
1048 _In_ ULONG BufferUsed
,
1049 _In_ CCHAR PriorityBoost
);
1051 _IRQL_requires_max_(DISPATCH_LEVEL
)
1056 _In_ PDEVICE_OBJECT DeviceObject
,
1058 _In_ ULONG InstanceIndex
,
1059 _In_ ULONG EventDataSize
,
1060 _In_reads_bytes_(EventDataSize
) PVOID EventData
);
1065 ClassResetMediaChangeTimer(
1066 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
);
1068 _IRQL_requires_max_(PASSIVE_LEVEL
)
1072 ClassInitializeMediaChangeDetection(
1073 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
,
1074 _In_ PUCHAR EventPrefix
);
1076 _IRQL_requires_max_(PASSIVE_LEVEL
)
1080 ClassInitializeTestUnitPolling(
1081 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
,
1082 _In_ BOOLEAN AllowDriveToSleep
);
1088 _In_ PDEVICE_OBJECT DeviceObject
);
1093 ClassSpinDownPowerHandler(
1094 _In_ PDEVICE_OBJECT DeviceObject
,
1099 ClassStopUnitPowerHandler(
1100 _In_ PDEVICE_OBJECT DeviceObject
,
1103 _IRQL_requires_max_(PASSIVE_LEVEL
)
1106 ClassSetFailurePredictionPoll(
1107 _Inout_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
,
1108 _In_ FAILURE_PREDICTION_METHOD FailurePredictionMethod
,
1109 _In_ ULONG PollingPeriod
);
1111 _IRQL_requires_max_(DISPATCH_LEVEL
)
1114 ClassNotifyFailurePredicted(
1115 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
,
1116 _In_reads_bytes_(BufferSize
) PUCHAR Buffer
,
1117 _In_ ULONG BufferSize
,
1118 _In_ BOOLEAN LogError
,
1119 _In_ ULONG UniqueErrorValue
,
1121 _In_ UCHAR TargetId
,
1124 _IRQL_requires_max_(PASSIVE_LEVEL
)
1128 ClassAcquireChildLock(
1129 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
);
1134 ClassReleaseChildLock(
1135 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
);
1137 IO_COMPLETION_ROUTINE ClassSignalCompletion
;
1142 _In_ PDEVICE_OBJECT DeviceObject
);
1144 _IRQL_requires_max_(PASSIVE_LEVEL
)
1149 _In_ PDEVICE_OBJECT DeviceObject
,
1150 _In_ UCHAR RemoveType
);
1155 ClassAsynchronousCompletion(
1156 PDEVICE_OBJECT DeviceObject
,
1163 ClassCheckMediaState(
1164 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
);
1169 ClassCheckVerifyComplete(
1170 PDEVICE_OBJECT DeviceObject
,
1174 _IRQL_requires_max_(PASSIVE_LEVEL
)
1178 ClassSetMediaChangeState(
1179 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
,
1180 _In_ MEDIA_CHANGE_DETECTION_STATE State
,
1183 _IRQL_requires_max_(PASSIVE_LEVEL
)
1187 ClassEnableMediaChangeDetection(
1188 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
);
1190 _IRQL_requires_max_(PASSIVE_LEVEL
)
1194 ClassDisableMediaChangeDetection(
1195 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
);
1197 _IRQL_requires_max_(PASSIVE_LEVEL
)
1201 ClassCleanupMediaChangeDetection(
1202 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
);
1204 _IRQL_requires_max_(PASSIVE_LEVEL
)
1207 ClassGetDeviceParameter(
1208 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
,
1209 _In_opt_ PWSTR SubkeyName
,
1210 _In_ PWSTR ParameterName
,
1211 _Inout_ PULONG ParameterValue
);
1213 _IRQL_requires_max_(PASSIVE_LEVEL
)
1216 ClassSetDeviceParameter(
1217 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
,
1218 _In_opt_ PWSTR SubkeyName
,
1219 _In_ PWSTR ParameterName
,
1220 _In_ ULONG ParameterValue
);
1222 #if (NTDDI_VERSION >= NTDDI_VISTA)
1224 _IRQL_requires_max_(PASSIVE_LEVEL
)
1225 PFILE_OBJECT_EXTENSION
1228 _In_ PCOMMON_DEVICE_EXTENSION CommonExtension
,
1229 _In_ PFILE_OBJECT FileObject
);
1231 _IRQL_requires_max_(DISPATCH_LEVEL
)
1234 ClassSendNotification(
1235 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
,
1236 _In_
const GUID
*Guid
,
1237 _In_ ULONG ExtraDataSize
,
1238 _In_reads_bytes_opt_(ExtraDataSize
) PVOID ExtraData
);
1240 #endif /* (NTDDI_VERSION >= NTDDI_VISTA) */
1244 PORT_ALLOCATED_SENSE(
1245 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
,
1246 _In_ PSCSI_REQUEST_BLOCK Srb
)
1248 return ((BOOLEAN
)((TEST_FLAG(Srb
->SrbFlags
, SRB_FLAGS_PORT_DRIVER_ALLOCSENSE
) &&
1249 TEST_FLAG(Srb
->SrbFlags
, SRB_FLAGS_FREE_SENSE_BUFFER
)) &&
1250 (Srb
->SenseInfoBuffer
!= FdoExtension
->SenseData
)));
1255 FREE_PORT_ALLOCATED_SENSE_BUFFER(
1256 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
,
1257 _In_ PSCSI_REQUEST_BLOCK Srb
)
1259 ASSERT(TEST_FLAG(Srb
->SrbFlags
, SRB_FLAGS_PORT_DRIVER_ALLOCSENSE
));
1260 ASSERT(TEST_FLAG(Srb
->SrbFlags
, SRB_FLAGS_FREE_SENSE_BUFFER
));
1261 ASSERT(Srb
->SenseInfoBuffer
!= FdoExtension
->SenseData
);
1263 ExFreePool(Srb
->SenseInfoBuffer
);
1264 Srb
->SenseInfoBuffer
= FdoExtension
->SenseData
;
1265 Srb
->SenseInfoBufferLength
= SENSE_BUFFER_SIZE
;
1266 CLEAR_FLAG(Srb
->SrbFlags
, SRB_FLAGS_FREE_SENSE_BUFFER
);
1270 _IRQL_requires_max_(PASSIVE_LEVEL
)
1272 (NTAPI
*PCLASS_SCAN_FOR_SPECIAL_HANDLER
)(
1273 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
,
1274 _In_ ULONG_PTR Data
);
1276 _IRQL_requires_max_(PASSIVE_LEVEL
)
1279 ClassScanForSpecial(
1280 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
,
1281 _In_ CLASSPNP_SCAN_FOR_SPECIAL_INFO DeviceList
[],
1282 _In_ PCLASS_SCAN_FOR_SPECIAL_HANDLER Function
);