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 194 static inline ULONG CountOfSetBitsUChar(UCHAR _X) 195 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; } 196 static inline ULONG CountOfSetBitsULong(ULONG _X) 197 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; } 198 static inline ULONG CountOfSetBitsULong32(ULONG32 _X) 199 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; } 200 static inline ULONG CountOfSetBitsULong64(ULONG64 _X) 201 { ULONG i = 0; while (_X) { _X &= _X - 1; i++; } return i; } 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 __inline 1436 UCHAR 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 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 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