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 89 #define MAXIMUM_RETRIES 4 90 91 #define CLASS_DRIVER_EXTENSION_KEY ((PVOID) ClassInitialize) 92 93 #define NO_REMOVE 0 94 #define REMOVE_PENDING 1 95 #define REMOVE_COMPLETE 2 96 97 #define ClassAcquireRemoveLock(devobj, tag) \ 98 ClassAcquireRemoveLockEx(devobj, tag, __FILE__, __LINE__) 99 100 #ifdef TRY 101 #undef TRY 102 #endif 103 #ifdef LEAVE 104 #undef LEAVE 105 #endif 106 107 #ifdef FINALLY 108 #undef FINALLY 109 #endif 110 111 #define TRY 112 #define LEAVE goto __tryLabel; 113 #define FINALLY __tryLabel: 114 115 #if defined DebugPrint 116 #undef DebugPrint 117 #endif 118 119 #if DBG 120 #define DebugPrint(x) ClassDebugPrint x 121 #else 122 #define DebugPrint(x) 123 #endif 124 125 #define DEBUG_BUFFER_LENGTH 256 126 127 #define START_UNIT_TIMEOUT (60 * 4) 128 129 #define MEDIA_CHANGE_DEFAULT_TIME 1 130 #define MEDIA_CHANGE_TIMEOUT_TIME 300 131 132 #define MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS 0x3b9aca00 133 134 #ifdef ALLOCATE_SRB_FROM_POOL 135 136 #define ClasspAllocateSrb(ext) \ 137 ExAllocatePoolWithTag(NonPagedPool, \ 138 sizeof(SCSI_REQUEST_BLOCK), \ 139 'sBRS') 140 141 #define ClasspFreeSrb(ext, srb) ExFreePool((srb)); 142 143 #else /* ALLOCATE_SRB_FROM_POOL */ 144 145 #define ClasspAllocateSrb(ext) \ 146 ExAllocateFromNPagedLookasideList( \ 147 &((ext)->CommonExtension.SrbLookasideList)) 148 149 #define ClasspFreeSrb(ext, srb) \ 150 ExFreeToNPagedLookasideList( \ 151 &((ext)->CommonExtension.SrbLookasideList), \ 152 (srb)) 153 154 #endif /* ALLOCATE_SRB_FROM_POOL */ 155 156 #define SET_FLAG(Flags, Bit) ((Flags) |= (Bit)) 157 #define CLEAR_FLAG(Flags, Bit) ((Flags) &= ~(Bit)) 158 #define TEST_FLAG(Flags, Bit) (((Flags) & (Bit)) != 0) 159 160 #define CLASS_WORKING_SET_MAXIMUM 2048 161 162 #define CLASS_INTERPRET_SENSE_INFO2_MAXIMUM_HISTORY_COUNT 30000 163 164 #define CLASS_SPECIAL_DISABLE_SPIN_DOWN 0x00000001 165 #define CLASS_SPECIAL_DISABLE_SPIN_UP 0x00000002 166 #define CLASS_SPECIAL_NO_QUEUE_LOCK 0x00000008 167 #define CLASS_SPECIAL_DISABLE_WRITE_CACHE 0x00000010 168 #define CLASS_SPECIAL_CAUSE_NOT_REPORTABLE_HACK 0x00000020 169 #if ((NTDDI_VERSION == NTDDI_WIN2KSP3) || (OSVER(NTDDI_VERSION) == NTDDI_WINXP)) 170 #define CLASS_SPECIAL_DISABLE_WRITE_CACHE_NOT_SUPPORTED 0x00000040 171 #endif 172 #define CLASS_SPECIAL_MODIFY_CACHE_UNSUCCESSFUL 0x00000040 173 #define CLASS_SPECIAL_FUA_NOT_SUPPORTED 0x00000080 174 #define CLASS_SPECIAL_VALID_MASK 0x000000FB 175 #define CLASS_SPECIAL_RESERVED (~CLASS_SPECIAL_VALID_MASK) 176 177 #define DEV_WRITE_CACHE 0x00000001 178 #define DEV_USE_SCSI1 0x00000002 179 #define DEV_SAFE_START_UNIT 0x00000004 180 #define DEV_NO_12BYTE_CDB 0x00000008 181 #define DEV_POWER_PROTECTED 0x00000010 182 #define DEV_USE_16BYTE_CDB 0x00000020 183 184 #define GUID_CLASSPNP_QUERY_REGINFOEX {0x00e34b11, 0x2444, 0x4745, {0xa5, 0x3d, 0x62, 0x01, 0x00, 0xcd, 0x82, 0xf7}} 185 #define GUID_CLASSPNP_SENSEINFO2 {0x509a8c5f, 0x71d7, 0x48f6, {0x82, 0x1e, 0x17, 0x3c, 0x49, 0xbf, 0x2f, 0x18}} 186 #define GUID_CLASSPNP_WORKING_SET {0x105701b0, 0x9e9b, 0x47cb, {0x97, 0x80, 0x81, 0x19, 0x8a, 0xf7, 0xb5, 0x24}} 187 188 #define DEFAULT_FAILURE_PREDICTION_PERIOD 60 * 60 * 1 189 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; } 200 201 typedef enum _MEDIA_CHANGE_DETECTION_STATE { 202 MediaUnknown, 203 MediaPresent, 204 MediaNotPresent, 205 MediaUnavailable 206 } MEDIA_CHANGE_DETECTION_STATE, *PMEDIA_CHANGE_DETECTION_STATE; 207 208 typedef enum _CLASS_DEBUG_LEVEL { 209 ClassDebugError = 0, 210 ClassDebugWarning = 1, 211 ClassDebugTrace = 2, 212 ClassDebugInfo = 3, 213 ClassDebugMediaLocks = 8, 214 ClassDebugMCN = 9, 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; 223 224 typedef enum { 225 EventGeneration, 226 DataBlockCollection 227 } CLASSENABLEDISABLEFUNCTION; 228 229 typedef enum { 230 FailurePredictionNone = 0, 231 FailurePredictionIoctl, 232 FailurePredictionSmart, 233 FailurePredictionSense 234 } FAILURE_PREDICTION_METHOD, *PFAILURE_PREDICTION_METHOD; 235 236 typedef enum { 237 PowerDownDeviceInitial, 238 PowerDownDeviceLocked, 239 PowerDownDeviceStopped, 240 PowerDownDeviceOff, 241 PowerDownDeviceUnlocked 242 } CLASS_POWER_DOWN_STATE; 243 244 typedef enum { 245 PowerDownDeviceInitial2, 246 PowerDownDeviceLocked2, 247 PowerDownDeviceFlushed2, 248 PowerDownDeviceStopped2, 249 PowerDownDeviceOff2, 250 PowerDownDeviceUnlocked2 251 } CLASS_POWER_DOWN_STATE2; 252 253 typedef enum { 254 PowerUpDeviceInitial, 255 PowerUpDeviceLocked, 256 PowerUpDeviceOn, 257 PowerUpDeviceStarted, 258 PowerUpDeviceUnlocked 259 } CLASS_POWER_UP_STATE; 260 261 struct _CLASS_INIT_DATA; 262 typedef struct _CLASS_INIT_DATA CLASS_INIT_DATA, *PCLASS_INIT_DATA; 263 264 struct _CLASS_PRIVATE_FDO_DATA; 265 typedef struct _CLASS_PRIVATE_FDO_DATA CLASS_PRIVATE_FDO_DATA, *PCLASS_PRIVATE_FDO_DATA; 266 267 struct _CLASS_PRIVATE_PDO_DATA; 268 typedef struct _CLASS_PRIVATE_PDO_DATA CLASS_PRIVATE_PDO_DATA, *PCLASS_PRIVATE_PDO_DATA; 269 270 struct _CLASS_PRIVATE_COMMON_DATA; 271 typedef struct _CLASS_PRIVATE_COMMON_DATA CLASS_PRIVATE_COMMON_DATA, *PCLASS_PRIVATE_COMMON_DATA; 272 273 struct _MEDIA_CHANGE_DETECTION_INFO; 274 typedef struct _MEDIA_CHANGE_DETECTION_INFO MEDIA_CHANGE_DETECTION_INFO, *PMEDIA_CHANGE_DETECTION_INFO; 275 276 typedef struct _DICTIONARY { 277 ULONGLONG Signature; 278 struct _DICTIONARY_HEADER* List; 279 KSPIN_LOCK SpinLock; 280 } DICTIONARY, *PDICTIONARY; 281 282 typedef struct _CLASSPNP_SCAN_FOR_SPECIAL_INFO { 283 PCHAR VendorId; 284 PCHAR ProductId; 285 PCHAR ProductRevision; 286 ULONG_PTR Data; 287 } CLASSPNP_SCAN_FOR_SPECIAL_INFO, *PCLASSPNP_SCAN_FOR_SPECIAL_INFO; 288 289 typedef VOID 290 (NTAPI *PCLASS_ERROR)( 291 PDEVICE_OBJECT DeviceObject, 292 PSCSI_REQUEST_BLOCK Srb, 293 NTSTATUS *Status, 294 BOOLEAN *Retry); 295 296 typedef NTSTATUS 297 (NTAPI *PCLASS_ADD_DEVICE)( 298 PDRIVER_OBJECT DriverObject, 299 PDEVICE_OBJECT Pdo); 300 301 typedef NTSTATUS 302 (NTAPI *PCLASS_POWER_DEVICE)( 303 PDEVICE_OBJECT DeviceObject, 304 PIRP Irp); 305 306 typedef NTSTATUS 307 (NTAPI *PCLASS_START_DEVICE)( 308 PDEVICE_OBJECT DeviceObject); 309 310 typedef NTSTATUS 311 (NTAPI *PCLASS_STOP_DEVICE)( 312 PDEVICE_OBJECT DeviceObject, 313 UCHAR Type); 314 315 typedef NTSTATUS 316 (NTAPI *PCLASS_INIT_DEVICE)( 317 PDEVICE_OBJECT DeviceObject); 318 319 typedef NTSTATUS 320 (NTAPI *PCLASS_ENUM_DEVICE)( 321 PDEVICE_OBJECT DeviceObject); 322 323 typedef NTSTATUS 324 (NTAPI *PCLASS_READ_WRITE)( 325 PDEVICE_OBJECT DeviceObject, 326 PIRP Irp); 327 328 typedef NTSTATUS 329 (NTAPI *PCLASS_DEVICE_CONTROL)( 330 PDEVICE_OBJECT DeviceObject, 331 PIRP Irp); 332 333 typedef NTSTATUS 334 (NTAPI *PCLASS_SHUTDOWN_FLUSH)( 335 PDEVICE_OBJECT DeviceObject, 336 PIRP Irp); 337 338 typedef NTSTATUS 339 (NTAPI *PCLASS_CREATE_CLOSE)( 340 PDEVICE_OBJECT DeviceObject, 341 PIRP Irp); 342 343 typedef NTSTATUS 344 (NTAPI *PCLASS_QUERY_ID)( 345 PDEVICE_OBJECT DeviceObject, 346 BUS_QUERY_ID_TYPE IdType, 347 PUNICODE_STRING IdString); 348 349 typedef NTSTATUS 350 (NTAPI *PCLASS_REMOVE_DEVICE)( 351 PDEVICE_OBJECT DeviceObject, 352 UCHAR Type); 353 354 typedef VOID 355 (NTAPI *PCLASS_UNLOAD)( 356 PDRIVER_OBJECT DriverObject); 357 358 typedef NTSTATUS 359 (NTAPI *PCLASS_QUERY_PNP_CAPABILITIES)( 360 PDEVICE_OBJECT PhysicalDeviceObject, 361 PDEVICE_CAPABILITIES Capabilities); 362 363 typedef VOID 364 (NTAPI *PCLASS_TICK)( 365 PDEVICE_OBJECT DeviceObject); 366 367 typedef NTSTATUS 368 (NTAPI *PCLASS_QUERY_WMI_REGINFO_EX)( 369 PDEVICE_OBJECT DeviceObject, 370 ULONG *RegFlags, 371 PUNICODE_STRING Name, 372 PUNICODE_STRING MofResouceName); 373 374 typedef NTSTATUS 375 (NTAPI *PCLASS_QUERY_WMI_REGINFO)( 376 PDEVICE_OBJECT DeviceObject, 377 ULONG *RegFlags, 378 PUNICODE_STRING Name); 379 380 typedef NTSTATUS 381 (NTAPI *PCLASS_QUERY_WMI_DATABLOCK)( 382 PDEVICE_OBJECT DeviceObject, 383 PIRP Irp, 384 ULONG GuidIndex, 385 ULONG BufferAvail, 386 PUCHAR Buffer); 387 388 typedef NTSTATUS 389 (NTAPI *PCLASS_SET_WMI_DATABLOCK)( 390 PDEVICE_OBJECT DeviceObject, 391 PIRP Irp, 392 ULONG GuidIndex, 393 ULONG BufferSize, 394 PUCHAR Buffer); 395 396 typedef NTSTATUS 397 (NTAPI *PCLASS_SET_WMI_DATAITEM)( 398 PDEVICE_OBJECT DeviceObject, 399 PIRP Irp, 400 ULONG GuidIndex, 401 ULONG DataItemId, 402 ULONG BufferSize, 403 PUCHAR Buffer); 404 405 typedef NTSTATUS 406 (NTAPI *PCLASS_EXECUTE_WMI_METHOD)( 407 PDEVICE_OBJECT DeviceObject, 408 PIRP Irp, 409 ULONG GuidIndex, 410 ULONG MethodId, 411 ULONG InBufferSize, 412 ULONG OutBufferSize, 413 PUCHAR Buffer); 414 415 typedef NTSTATUS 416 (NTAPI *PCLASS_WMI_FUNCTION_CONTROL)( 417 PDEVICE_OBJECT DeviceObject, 418 PIRP Irp, 419 ULONG GuidIndex, 420 CLASSENABLEDISABLEFUNCTION Function, 421 BOOLEAN Enable); 422 423 typedef struct _SRB_HISTORY_ITEM { 424 LARGE_INTEGER TickCountSent; 425 LARGE_INTEGER TickCountCompleted; 426 ULONG MillisecondsDelayOnRetry; 427 SENSE_DATA NormalizedSenseData; 428 UCHAR SrbStatus; 429 UCHAR ClassDriverUse; 430 } SRB_HISTORY_ITEM, *PSRB_HISTORY_ITEM; 431 432 typedef struct _SRB_HISTORY { 433 ULONG_PTR ClassDriverUse[4]; 434 ULONG TotalHistoryCount; 435 ULONG UsedHistoryCount; 436 SRB_HISTORY_ITEM History[1]; 437 } SRB_HISTORY, *PSRB_HISTORY; 438 439 typedef BOOLEAN 440 (NTAPI *PCLASS_INTERPRET_SENSE_INFO)( 441 PDEVICE_OBJECT Fdo, 442 PIRP OriginalRequest, 443 PSCSI_REQUEST_BLOCK Srb, 444 UCHAR MajorFunctionCode, 445 ULONG IoDeviceCode, 446 ULONG PreviousRetryCount, 447 SRB_HISTORY *RequestHistory, 448 NTSTATUS *Status, 449 LONGLONG *RetryIn100nsUnits); 450 451 typedef VOID 452 (NTAPI *PCLASS_COMPRESS_RETRY_HISTORY_DATA)( 453 PDEVICE_OBJECT DeviceObject, 454 PSRB_HISTORY RequestHistory); 455 456 typedef struct { 457 GUID Guid; 458 ULONG InstanceCount; 459 ULONG Flags; 460 } GUIDREGINFO, *PGUIDREGINFO; 461 462 typedef struct _CLASS_WMI_INFO { 463 ULONG GuidCount; 464 PGUIDREGINFO GuidRegInfo; 465 PCLASS_QUERY_WMI_REGINFO ClassQueryWmiRegInfo; 466 PCLASS_QUERY_WMI_DATABLOCK ClassQueryWmiDataBlock; 467 PCLASS_SET_WMI_DATABLOCK ClassSetWmiDataBlock; 468 PCLASS_SET_WMI_DATAITEM ClassSetWmiDataItem; 469 PCLASS_EXECUTE_WMI_METHOD ClassExecuteWmiMethod; 470 PCLASS_WMI_FUNCTION_CONTROL ClassWmiFunctionControl; 471 } CLASS_WMI_INFO, *PCLASS_WMI_INFO; 472 473 typedef struct _CLASS_DEV_INFO { 474 ULONG DeviceExtensionSize; 475 DEVICE_TYPE DeviceType; 476 UCHAR StackSize; 477 ULONG DeviceCharacteristics; 478 PCLASS_ERROR ClassError; 479 PCLASS_READ_WRITE ClassReadWriteVerification; 480 PCLASS_DEVICE_CONTROL ClassDeviceControl; 481 PCLASS_SHUTDOWN_FLUSH ClassShutdownFlush; 482 PCLASS_CREATE_CLOSE ClassCreateClose; 483 PCLASS_INIT_DEVICE ClassInitDevice; 484 PCLASS_START_DEVICE ClassStartDevice; 485 PCLASS_POWER_DEVICE ClassPowerDevice; 486 PCLASS_STOP_DEVICE ClassStopDevice; 487 PCLASS_REMOVE_DEVICE ClassRemoveDevice; 488 PCLASS_QUERY_PNP_CAPABILITIES ClassQueryPnpCapabilities; 489 CLASS_WMI_INFO ClassWmiInfo; 490 } CLASS_DEV_INFO, *PCLASS_DEV_INFO; 491 492 struct _CLASS_INIT_DATA { 493 ULONG InitializationDataSize; 494 CLASS_DEV_INFO FdoData; 495 CLASS_DEV_INFO PdoData; 496 PCLASS_ADD_DEVICE ClassAddDevice; 497 PCLASS_ENUM_DEVICE ClassEnumerateDevice; 498 PCLASS_QUERY_ID ClassQueryId; 499 PDRIVER_STARTIO ClassStartIo; 500 PCLASS_UNLOAD ClassUnload; 501 PCLASS_TICK ClassTick; 502 }; 503 504 typedef struct _FILE_OBJECT_EXTENSION { 505 PFILE_OBJECT FileObject; 506 PDEVICE_OBJECT DeviceObject; 507 ULONG LockCount; 508 ULONG McnDisableCount; 509 } FILE_OBJECT_EXTENSION, *PFILE_OBJECT_EXTENSION; 510 511 typedef struct _CLASS_WORKING_SET { 512 ULONG Size; 513 ULONG XferPacketsWorkingSetMaximum; 514 ULONG XferPacketsWorkingSetMinimum; 515 } CLASS_WORKING_SET, *PCLASS_WORKING_SET; 516 517 typedef struct _CLASS_INTERPRET_SENSE_INFO2 { 518 ULONG Size; 519 ULONG HistoryCount; 520 PCLASS_COMPRESS_RETRY_HISTORY_DATA Compress; 521 PCLASS_INTERPRET_SENSE_INFO Interpret; 522 } CLASS_INTERPRET_SENSE_INFO2, *PCLASS_INTERPRET_SENSE_INFO2; 523 524 C_ASSERT((MAXULONG - sizeof(SRB_HISTORY)) / 30000 >= sizeof(SRB_HISTORY_ITEM)); 525 526 typedef struct _CLASS_DRIVER_EXTENSION { 527 UNICODE_STRING RegistryPath; 528 CLASS_INIT_DATA InitData; 529 ULONG DeviceCount; 530 #if (NTDDI_VERSION >= NTDDI_WINXP) 531 PCLASS_QUERY_WMI_REGINFO_EX ClassFdoQueryWmiRegInfoEx; 532 PCLASS_QUERY_WMI_REGINFO_EX ClassPdoQueryWmiRegInfoEx; 533 #endif 534 #if (NTDDI_VERSION >= NTDDI_VISTA) 535 REGHANDLE EtwHandle; 536 PDRIVER_DISPATCH DeviceMajorFunctionTable[IRP_MJ_MAXIMUM_FUNCTION + 1]; 537 PDRIVER_DISPATCH MpDeviceMajorFunctionTable[IRP_MJ_MAXIMUM_FUNCTION + 1]; 538 PCLASS_INTERPRET_SENSE_INFO2 InterpretSenseInfo; 539 PCLASS_WORKING_SET WorkingSet; 540 #endif 541 } CLASS_DRIVER_EXTENSION, *PCLASS_DRIVER_EXTENSION; 542 543 typedef struct _COMMON_DEVICE_EXTENSION { 544 ULONG Version; 545 PDEVICE_OBJECT DeviceObject; 546 PDEVICE_OBJECT LowerDeviceObject; 547 struct _FUNCTIONAL_DEVICE_EXTENSION *PartitionZeroExtension; 548 PCLASS_DRIVER_EXTENSION DriverExtension; 549 LONG RemoveLock; 550 KEVENT RemoveEvent; 551 KSPIN_LOCK RemoveTrackingSpinlock; 552 PVOID RemoveTrackingList; 553 LONG RemoveTrackingUntrackedCount; 554 PVOID DriverData; 555 _ANONYMOUS_STRUCT struct { 556 BOOLEAN IsFdo:1; 557 BOOLEAN IsInitialized:1; 558 BOOLEAN IsSrbLookasideListInitialized:1; 559 } DUMMYSTRUCTNAME; 560 UCHAR PreviousState; 561 UCHAR CurrentState; 562 ULONG IsRemoved; 563 UNICODE_STRING DeviceName; 564 struct _PHYSICAL_DEVICE_EXTENSION *ChildList; 565 ULONG PartitionNumber; 566 LARGE_INTEGER PartitionLength; 567 LARGE_INTEGER StartingOffset; 568 PCLASS_DEV_INFO DevInfo; 569 ULONG PagingPathCount; 570 ULONG DumpPathCount; 571 ULONG HibernationPathCount; 572 KEVENT PathCountEvent; 573 #ifndef ALLOCATE_SRB_FROM_POOL 574 NPAGED_LOOKASIDE_LIST SrbLookasideList; 575 #endif 576 UNICODE_STRING MountedDeviceInterfaceName; 577 ULONG GuidCount; 578 PGUIDREGINFO GuidRegInfo; 579 DICTIONARY FileObjectDictionary; 580 #if (NTDDI_VERSION >= NTDDI_WINXP) 581 PCLASS_PRIVATE_COMMON_DATA PrivateCommonData; 582 #else 583 ULONG_PTR Reserved1; 584 #endif 585 #if (NTDDI_VERSION >= NTDDI_VISTA) 586 PDRIVER_DISPATCH *DispatchTable; 587 #else 588 ULONG_PTR Reserved2; 589 #endif 590 ULONG_PTR Reserved3; 591 ULONG_PTR Reserved4; 592 } COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION; 593 594 typedef struct _PHYSICAL_DEVICE_EXTENSION { 595 _ANONYMOUS_UNION union { 596 _ANONYMOUS_STRUCT struct { 597 ULONG Version; 598 PDEVICE_OBJECT DeviceObject; 599 } DUMMYSTRUCTNAME; 600 COMMON_DEVICE_EXTENSION CommonExtension; 601 } DUMMYUNIONNAME; 602 BOOLEAN IsMissing; 603 BOOLEAN IsEnumerated; 604 #if (NTDDI_VERSION >= NTDDI_WINXP) 605 PCLASS_PRIVATE_PDO_DATA PrivatePdoData; 606 #else 607 ULONG_PTR Reserved1; 608 #endif 609 ULONG_PTR Reserved2; 610 ULONG_PTR Reserved3; 611 ULONG_PTR Reserved4; 612 } PHYSICAL_DEVICE_EXTENSION, *PPHYSICAL_DEVICE_EXTENSION; 613 614 typedef struct _CLASS_POWER_OPTIONS { 615 ULONG PowerDown:1; 616 ULONG LockQueue:1; 617 ULONG HandleSpinDown:1; 618 ULONG HandleSpinUp:1; 619 ULONG Reserved:27; 620 } CLASS_POWER_OPTIONS, *PCLASS_POWER_OPTIONS; 621 622 typedef struct _CLASS_POWER_CONTEXT { 623 union { 624 CLASS_POWER_DOWN_STATE PowerDown; 625 CLASS_POWER_DOWN_STATE2 PowerDown2; 626 CLASS_POWER_UP_STATE PowerUp; 627 } PowerChangeState; 628 CLASS_POWER_OPTIONS Options; 629 BOOLEAN InUse; 630 BOOLEAN QueueLocked; 631 NTSTATUS FinalStatus; 632 ULONG RetryCount; 633 ULONG RetryInterval; 634 PIO_COMPLETION_ROUTINE CompletionRoutine; 635 PDEVICE_OBJECT DeviceObject; 636 PIRP Irp; 637 SCSI_REQUEST_BLOCK Srb; 638 } CLASS_POWER_CONTEXT, *PCLASS_POWER_CONTEXT; 639 640 typedef struct _COMPLETION_CONTEXT { 641 PDEVICE_OBJECT DeviceObject; 642 SCSI_REQUEST_BLOCK Srb; 643 } COMPLETION_CONTEXT, *PCOMPLETION_CONTEXT; 644 645 SCSIPORTAPI 646 ULONG 647 NTAPI 648 ClassInitialize( 649 PVOID Argument1, 650 PVOID Argument2, 651 PCLASS_INIT_DATA InitializationData); 652 653 typedef struct _CLASS_QUERY_WMI_REGINFO_EX_LIST { 654 ULONG Size; 655 PCLASS_QUERY_WMI_REGINFO_EX ClassFdoQueryWmiRegInfoEx; 656 PCLASS_QUERY_WMI_REGINFO_EX ClassPdoQueryWmiRegInfoEx; 657 } CLASS_QUERY_WMI_REGINFO_EX_LIST, *PCLASS_QUERY_WMI_REGINFO_EX_LIST; 658 659 typedef struct _FUNCTIONAL_DEVICE_EXTENSION { 660 _ANONYMOUS_UNION union { 661 _ANONYMOUS_STRUCT struct { 662 ULONG Version; 663 PDEVICE_OBJECT DeviceObject; 664 } DUMMYSTRUCTNAME; 665 COMMON_DEVICE_EXTENSION CommonExtension; 666 } DUMMYUNIONNAME; 667 PDEVICE_OBJECT LowerPdo; 668 PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor; 669 PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor; 670 DEVICE_POWER_STATE DevicePowerState; 671 ULONG DMByteSkew; 672 ULONG DMSkew; 673 BOOLEAN DMActive; 674 DISK_GEOMETRY DiskGeometry; 675 PSENSE_DATA SenseData; 676 ULONG TimeOutValue; 677 ULONG DeviceNumber; 678 ULONG SrbFlags; 679 ULONG ErrorCount; 680 LONG LockCount; 681 LONG ProtectedLockCount; 682 LONG InternalLockCount; 683 KEVENT EjectSynchronizationEvent; 684 USHORT DeviceFlags; 685 UCHAR SectorShift; 686 #if (NTDDI_VERSION >= NTDDI_VISTA) 687 UCHAR CdbForceUnitAccess; 688 #else 689 UCHAR ReservedByte; 690 #endif 691 PMEDIA_CHANGE_DETECTION_INFO MediaChangeDetectionInfo; 692 PKEVENT Unused1; 693 HANDLE Unused2; 694 FILE_OBJECT_EXTENSION KernelModeMcnContext; 695 ULONG MediaChangeCount; 696 HANDLE DeviceDirectory; 697 KSPIN_LOCK ReleaseQueueSpinLock; 698 PIRP ReleaseQueueIrp; 699 SCSI_REQUEST_BLOCK ReleaseQueueSrb; 700 BOOLEAN ReleaseQueueNeeded; 701 BOOLEAN ReleaseQueueInProgress; 702 BOOLEAN ReleaseQueueIrpFromPool; 703 BOOLEAN FailurePredicted; 704 ULONG FailureReason; 705 struct _FAILURE_PREDICTION_INFO* FailurePredictionInfo; 706 BOOLEAN PowerDownInProgress; 707 ULONG EnumerationInterlock; 708 KEVENT ChildLock; 709 PKTHREAD ChildLockOwner; 710 ULONG ChildLockAcquisitionCount; 711 ULONG ScanForSpecialFlags; 712 KDPC PowerRetryDpc; 713 KTIMER PowerRetryTimer; 714 CLASS_POWER_CONTEXT PowerContext; 715 716 #if (NTDDI_VERSION <= NTDDI_WIN2K) 717 718 #if (SPVER(NTDDI_VERSION) < 2)) 719 ULONG_PTR Reserved1; 720 ULONG_PTR Reserved2; 721 ULONG_PTR Reserved3; 722 ULONG_PTR Reserved4; 723 #else 724 ULONG CompletionSuccessCount; 725 ULONG SavedSrbFlags; 726 ULONG SavedErrorCount; 727 ULONG_PTR Reserved1; 728 #endif 729 730 #else /* (NTDDI_VERSION <= NTDDI_WIN2K) */ 731 732 PCLASS_PRIVATE_FDO_DATA PrivateFdoData; 733 ULONG_PTR Reserved2; 734 ULONG_PTR Reserved3; 735 ULONG_PTR Reserved4; 736 737 #endif /* (NTDDI_VERSION <= NTDDI_WIN2K) */ 738 739 } FUNCTIONAL_DEVICE_EXTENSION, *PFUNCTIONAL_DEVICE_EXTENSION; 740 741 SCSIPORTAPI 742 ULONG 743 NTAPI 744 ClassInitializeEx( 745 PDRIVER_OBJECT DriverObject, 746 LPGUID Guid, 747 PVOID Data); 748 749 SCSIPORTAPI 750 NTSTATUS 751 NTAPI 752 ClassCreateDeviceObject( 753 PDRIVER_OBJECT DriverObject, 754 PCCHAR ObjectNameBuffer, 755 PDEVICE_OBJECT LowerDeviceObject, 756 BOOLEAN IsFdo, 757 PDEVICE_OBJECT *DeviceObject); 758 759 SCSIPORTAPI 760 NTSTATUS 761 NTAPI 762 ClassReadDriveCapacity( 763 PDEVICE_OBJECT DeviceObject); 764 765 SCSIPORTAPI 766 VOID 767 NTAPI 768 ClassReleaseQueue( 769 PDEVICE_OBJECT DeviceObject); 770 771 SCSIPORTAPI 772 VOID 773 NTAPI 774 ClassSplitRequest( 775 PDEVICE_OBJECT DeviceObject, 776 PIRP Irp, 777 ULONG MaximumBytes); 778 779 SCSIPORTAPI 780 NTSTATUS 781 NTAPI 782 ClassDeviceControl( 783 PDEVICE_OBJECT DeviceObject, 784 PIRP Irp); 785 786 SCSIPORTAPI 787 NTSTATUS 788 NTAPI 789 ClassIoComplete( 790 PDEVICE_OBJECT DeviceObject, 791 PIRP Irp, 792 PVOID Context); 793 794 SCSIPORTAPI 795 NTSTATUS 796 NTAPI 797 ClassIoCompleteAssociated( 798 PDEVICE_OBJECT DeviceObject, 799 PIRP Irp, 800 PVOID Context); 801 802 SCSIPORTAPI 803 BOOLEAN 804 NTAPI 805 ClassInterpretSenseInfo( 806 PDEVICE_OBJECT DeviceObject, 807 PSCSI_REQUEST_BLOCK Srb, 808 UCHAR MajorFunctionCode, 809 ULONG IoDeviceCode, 810 ULONG RetryCount, 811 NTSTATUS *Status, 812 ULONG *RetryInterval); 813 814 VOID 815 NTAPI 816 ClassSendDeviceIoControlSynchronous( 817 ULONG IoControlCode, 818 PDEVICE_OBJECT TargetDeviceObject, 819 PVOID Buffer, 820 ULONG InputBufferLength, 821 ULONG OutputBufferLength, 822 BOOLEAN InternalDeviceIoControl, 823 PIO_STATUS_BLOCK IoStatus); 824 825 SCSIPORTAPI 826 NTSTATUS 827 NTAPI 828 ClassSendIrpSynchronous( 829 PDEVICE_OBJECT TargetDeviceObject, 830 PIRP Irp); 831 832 SCSIPORTAPI 833 NTSTATUS 834 NTAPI 835 ClassForwardIrpSynchronous( 836 PCOMMON_DEVICE_EXTENSION CommonExtension, 837 PIRP Irp); 838 839 SCSIPORTAPI 840 NTSTATUS 841 NTAPI 842 ClassSendSrbSynchronous( 843 PDEVICE_OBJECT DeviceObject, 844 PSCSI_REQUEST_BLOCK Srb, 845 PVOID BufferAddress, 846 ULONG BufferLength, 847 BOOLEAN WriteToDevice); 848 849 SCSIPORTAPI 850 NTSTATUS 851 NTAPI 852 ClassSendSrbAsynchronous( 853 PDEVICE_OBJECT DeviceObject, 854 PSCSI_REQUEST_BLOCK Srb, 855 PIRP Irp, 856 PVOID BufferAddress, 857 ULONG BufferLength, 858 BOOLEAN WriteToDevice); 859 860 SCSIPORTAPI 861 NTSTATUS 862 NTAPI 863 ClassBuildRequest( 864 PDEVICE_OBJECT DeviceObject, 865 PIRP Irp); 866 867 SCSIPORTAPI 868 ULONG 869 NTAPI 870 ClassModeSense( 871 PDEVICE_OBJECT DeviceObject, 872 PCHAR ModeSenseBuffer, 873 ULONG Length, 874 UCHAR PageMode); 875 876 SCSIPORTAPI 877 PVOID 878 NTAPI 879 ClassFindModePage( 880 PCHAR ModeSenseBuffer, 881 ULONG Length, 882 UCHAR PageMode, 883 BOOLEAN Use6Byte); 884 885 SCSIPORTAPI 886 NTSTATUS 887 NTAPI 888 ClassClaimDevice( 889 PDEVICE_OBJECT LowerDeviceObject, 890 BOOLEAN Release); 891 892 SCSIPORTAPI 893 NTSTATUS 894 NTAPI 895 ClassInternalIoControl ( 896 PDEVICE_OBJECT DeviceObject, 897 PIRP Irp); 898 899 SCSIPORTAPI 900 VOID 901 NTAPI 902 ClassInitializeSrbLookasideList( 903 PCOMMON_DEVICE_EXTENSION CommonExtension, 904 ULONG NumberElements); 905 906 SCSIPORTAPI 907 VOID 908 NTAPI 909 ClassDeleteSrbLookasideList( 910 PCOMMON_DEVICE_EXTENSION CommonExtension); 911 912 SCSIPORTAPI 913 ULONG 914 NTAPI 915 ClassQueryTimeOutRegistryValue( 916 PDEVICE_OBJECT DeviceObject); 917 918 SCSIPORTAPI 919 NTSTATUS 920 NTAPI 921 ClassGetDescriptor( 922 PDEVICE_OBJECT DeviceObject, 923 PSTORAGE_PROPERTY_ID PropertyId, 924 PSTORAGE_DESCRIPTOR_HEADER *Descriptor); 925 926 SCSIPORTAPI 927 VOID 928 NTAPI 929 ClassInvalidateBusRelations( 930 PDEVICE_OBJECT Fdo); 931 932 SCSIPORTAPI 933 VOID 934 NTAPI 935 ClassMarkChildrenMissing( 936 PFUNCTIONAL_DEVICE_EXTENSION Fdo); 937 938 SCSIPORTAPI 939 BOOLEAN 940 NTAPI 941 ClassMarkChildMissing( 942 PPHYSICAL_DEVICE_EXTENSION PdoExtension, 943 BOOLEAN AcquireChildLock); 944 945 SCSIPORTAPI 946 VOID 947 ClassDebugPrint( 948 CLASS_DEBUG_LEVEL DebugPrintLevel, 949 PCCHAR DebugMessage, 950 ...); 951 952 SCSIPORTAPI 953 PCLASS_DRIVER_EXTENSION 954 NTAPI 955 ClassGetDriverExtension( 956 PDRIVER_OBJECT DriverObject); 957 958 SCSIPORTAPI 959 VOID 960 NTAPI 961 ClassCompleteRequest( 962 PDEVICE_OBJECT DeviceObject, 963 PIRP Irp, 964 CCHAR PriorityBoost); 965 966 SCSIPORTAPI 967 VOID 968 NTAPI 969 ClassReleaseRemoveLock( 970 PDEVICE_OBJECT DeviceObject, 971 PIRP Tag); 972 973 SCSIPORTAPI 974 ULONG 975 NTAPI 976 ClassAcquireRemoveLockEx( 977 PDEVICE_OBJECT DeviceObject, 978 PVOID Tag, 979 PCSTR File, 980 ULONG Line); 981 982 SCSIPORTAPI 983 VOID 984 NTAPI 985 ClassUpdateInformationInRegistry( 986 PDEVICE_OBJECT Fdo, 987 PCHAR DeviceName, 988 ULONG DeviceNumber, 989 PINQUIRYDATA InquiryData, 990 ULONG InquiryDataLength); 991 992 SCSIPORTAPI 993 NTSTATUS 994 NTAPI 995 ClassWmiCompleteRequest( 996 PDEVICE_OBJECT DeviceObject, 997 PIRP Irp, 998 NTSTATUS Status, 999 ULONG BufferUsed, 1000 CCHAR PriorityBoost); 1001 1002 SCSIPORTAPI 1003 NTSTATUS 1004 NTAPI 1005 ClassWmiFireEvent( 1006 PDEVICE_OBJECT DeviceObject, 1007 LPGUID Guid, 1008 ULONG InstanceIndex, 1009 ULONG EventDataSize, 1010 PVOID EventData); 1011 1012 SCSIPORTAPI 1013 VOID 1014 NTAPI 1015 ClassResetMediaChangeTimer( 1016 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension); 1017 1018 SCSIPORTAPI 1019 VOID 1020 NTAPI 1021 ClassInitializeMediaChangeDetection( 1022 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1023 PUCHAR EventPrefix); 1024 1025 SCSIPORTAPI 1026 NTSTATUS 1027 NTAPI 1028 ClassInitializeTestUnitPolling( 1029 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1030 BOOLEAN AllowDriveToSleep); 1031 1032 SCSIPORTAPI 1033 PVPB 1034 NTAPI 1035 ClassGetVpb( 1036 PDEVICE_OBJECT DeviceObject); 1037 1038 SCSIPORTAPI 1039 NTSTATUS 1040 NTAPI 1041 ClassSpinDownPowerHandler( 1042 PDEVICE_OBJECT DeviceObject, 1043 PIRP Irp); 1044 1045 NTSTATUS 1046 NTAPI 1047 ClassStopUnitPowerHandler( 1048 PDEVICE_OBJECT DeviceObject, 1049 PIRP Irp); 1050 1051 NTSTATUS 1052 NTAPI 1053 ClassSetFailurePredictionPoll( 1054 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1055 FAILURE_PREDICTION_METHOD FailurePredictionMethod, 1056 ULONG PollingPeriod); 1057 1058 VOID 1059 NTAPI 1060 ClassNotifyFailurePredicted( 1061 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1062 PUCHAR Buffer, 1063 ULONG BufferSize, 1064 BOOLEAN LogError, 1065 ULONG UniqueErrorValue, 1066 UCHAR PathId, 1067 UCHAR TargetId, 1068 UCHAR Lun); 1069 1070 SCSIPORTAPI 1071 VOID 1072 NTAPI 1073 ClassAcquireChildLock( 1074 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension); 1075 1076 SCSIPORTAPI 1077 VOID 1078 NTAPI 1079 ClassReleaseChildLock( 1080 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension); 1081 1082 NTSTATUS 1083 NTAPI 1084 ClassSignalCompletion( 1085 PDEVICE_OBJECT DeviceObject, 1086 PIRP Irp, 1087 PKEVENT Event); 1088 1089 VOID 1090 NTAPI 1091 ClassSendStartUnit( 1092 PDEVICE_OBJECT DeviceObject); 1093 1094 SCSIPORTAPI 1095 NTSTATUS 1096 NTAPI 1097 ClassRemoveDevice( 1098 PDEVICE_OBJECT DeviceObject, 1099 UCHAR RemoveType); 1100 1101 SCSIPORTAPI 1102 NTSTATUS 1103 NTAPI 1104 ClassAsynchronousCompletion( 1105 PDEVICE_OBJECT DeviceObject, 1106 PIRP Irp, 1107 PVOID Event); 1108 1109 SCSIPORTAPI 1110 VOID 1111 NTAPI 1112 ClassCheckMediaState( 1113 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension); 1114 1115 SCSIPORTAPI 1116 NTSTATUS 1117 NTAPI 1118 ClassCheckVerifyComplete( 1119 PDEVICE_OBJECT DeviceObject, 1120 PIRP Irp, 1121 PVOID Context); 1122 1123 SCSIPORTAPI 1124 VOID 1125 NTAPI 1126 ClassSetMediaChangeState( 1127 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1128 MEDIA_CHANGE_DETECTION_STATE State, 1129 BOOLEAN Wait); 1130 1131 SCSIPORTAPI 1132 VOID 1133 NTAPI 1134 ClassEnableMediaChangeDetection( 1135 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension); 1136 1137 SCSIPORTAPI 1138 VOID 1139 NTAPI 1140 ClassDisableMediaChangeDetection( 1141 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension); 1142 1143 SCSIPORTAPI 1144 VOID 1145 NTAPI 1146 ClassCleanupMediaChangeDetection( 1147 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension); 1148 1149 VOID 1150 NTAPI 1151 ClassGetDeviceParameter( 1152 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1153 PWSTR SubkeyName, 1154 PWSTR ParameterName, 1155 PULONG ParameterValue); 1156 1157 NTSTATUS 1158 NTAPI 1159 ClassSetDeviceParameter( 1160 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1161 PWSTR SubkeyName, 1162 PWSTR ParameterName, 1163 ULONG ParameterValue); 1164 1165 #if (NTDDI_VERSION >= NTDDI_VISTA) 1166 1167 PFILE_OBJECT_EXTENSION 1168 NTAPI 1169 ClassGetFsContext( 1170 PCOMMON_DEVICE_EXTENSION CommonExtension, 1171 PFILE_OBJECT FileObject); 1172 1173 VOID 1174 NTAPI 1175 ClassSendNotification( 1176 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1177 const GUID *Guid, 1178 ULONG ExtraDataSize, 1179 PVOID ExtraData); 1180 1181 #endif /* (NTDDI_VERSION >= NTDDI_VISTA) */ 1182 1183 static __inline 1184 BOOLEAN 1185 PORT_ALLOCATED_SENSE( 1186 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1187 PSCSI_REQUEST_BLOCK Srb) 1188 { 1189 return ((BOOLEAN)((TEST_FLAG(Srb->SrbFlags, SRB_FLAGS_PORT_DRIVER_ALLOCSENSE) && 1190 TEST_FLAG(Srb->SrbFlags, SRB_FLAGS_FREE_SENSE_BUFFER)) && 1191 (Srb->SenseInfoBuffer != FdoExtension->SenseData))); 1192 } 1193 1194 static __inline 1195 VOID 1196 FREE_PORT_ALLOCATED_SENSE_BUFFER( 1197 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1198 PSCSI_REQUEST_BLOCK Srb) 1199 { 1200 ASSERT(TEST_FLAG(Srb->SrbFlags, SRB_FLAGS_PORT_DRIVER_ALLOCSENSE)); 1201 ASSERT(TEST_FLAG(Srb->SrbFlags, SRB_FLAGS_FREE_SENSE_BUFFER)); 1202 ASSERT(Srb->SenseInfoBuffer != FdoExtension->SenseData); 1203 1204 ExFreePool(Srb->SenseInfoBuffer); 1205 Srb->SenseInfoBuffer = FdoExtension->SenseData; 1206 Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE; 1207 CLEAR_FLAG(Srb->SrbFlags, SRB_FLAGS_FREE_SENSE_BUFFER); 1208 return; 1209 } 1210 1211 typedef VOID 1212 (NTAPI *PCLASS_SCAN_FOR_SPECIAL_HANDLER)( 1213 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1214 ULONG_PTR Data); 1215 1216 VOID 1217 NTAPI 1218 ClassScanForSpecial( 1219 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1220 CLASSPNP_SCAN_FOR_SPECIAL_INFO DeviceList[], 1221 PCLASS_SCAN_FOR_SPECIAL_HANDLER Function); 1222