1 /*++ 2 3 Copyright (C) Microsoft Corporation, 1991 - 2010 4 5 Module Name: 6 7 classp.h 8 9 Abstract: 10 11 Private header file for classpnp.sys modules. This contains private 12 structure and function declarations as well as constant values which do 13 not need to be exported. 14 15 Author: 16 17 Environment: 18 19 kernel mode only 20 21 Notes: 22 23 24 Revision History: 25 26 --*/ 27 28 #define RTL_USE_AVL_TABLES 0 29 30 #include <stddef.h> 31 #include <stdarg.h> 32 #include <stdlib.h> 33 34 #include <ntddk.h> 35 36 #ifdef __REACTOS__ 37 #include <pseh/pseh2.h> 38 #endif 39 40 #include <scsi.h> 41 42 #include <wmidata.h> 43 #include <classpnp.h> 44 #include <storduid.h> 45 46 #if CLASS_INIT_GUID 47 #include <initguid.h> 48 #endif 49 50 #include <mountdev.h> 51 #include <ioevent.h> 52 #include <ntstrsafe.h> 53 #include <ntintsafe.h> 54 55 #include <wdmguid.h> 56 57 #if (NTDDI_VERSION >= NTDDI_WIN8) 58 59 #include <ntpoapi.h> 60 61 #include <srbhelper.h> 62 63 #endif 64 65 #ifdef __REACTOS__ 66 #undef MdlMappingNoExecute 67 #define MdlMappingNoExecute 0 68 #define NonPagedPoolNx NonPagedPool 69 #define NonPagedPoolNxCacheAligned NonPagedPoolCacheAligned 70 #undef POOL_NX_ALLOCATION 71 #define POOL_NX_ALLOCATION 0 72 #endif 73 74 // 75 // Set component ID for DbgPrintEx calls 76 // 77 #ifndef DEBUG_COMP_ID 78 #define DEBUG_COMP_ID DPFLTR_CLASSPNP_ID 79 #endif 80 81 // 82 // Include header file and setup GUID for tracing 83 // 84 #include <storswtr.h> 85 #define WPP_GUID_CLASSPNP (FA8DE7C4, ACDE, 4443, 9994, C4E2359A9EDB) 86 #ifndef WPP_CONTROL_GUIDS 87 #define WPP_CONTROL_GUIDS WPP_CONTROL_GUIDS_NORMAL_FLAGS(WPP_GUID_CLASSPNP) 88 #endif 89 90 /* 91 * IA64 requires 8-byte alignment for pointers, but the IA64 NT kernel expects 16-byte alignment 92 */ 93 #ifdef _WIN64 94 #define PTRALIGN DECLSPEC_ALIGN(16) 95 #else 96 #define PTRALIGN 97 #endif 98 99 100 extern CLASSPNP_SCAN_FOR_SPECIAL_INFO ClassBadItems[]; 101 102 extern GUID ClassGuidQueryRegInfoEx; 103 extern GUID ClassGuidSenseInfo2; 104 extern GUID ClassGuidWorkingSet; 105 extern GUID ClassGuidSrbSupport; 106 107 extern ULONG ClassMaxInterleavePerCriticalIo; 108 109 110 #define Add2Ptr(P,I) ((PVOID)((PUCHAR)(P) + (I))) 111 112 #define CLASSP_REG_SUBKEY_NAME (L"Classpnp") 113 114 #define CLASSP_REG_HACK_VALUE_NAME (L"HackMask") 115 #define CLASSP_REG_MMC_DETECTION_VALUE_NAME (L"MMCDetectionState") 116 #define CLASSP_REG_WRITE_CACHE_VALUE_NAME (L"WriteCacheEnableOverride") 117 #define CLASSP_REG_PERF_RESTORE_VALUE_NAME (L"RestorePerfAtCount") 118 #define CLASSP_REG_REMOVAL_POLICY_VALUE_NAME (L"UserRemovalPolicy") 119 #define CLASSP_REG_IDLE_INTERVAL_NAME (L"IdleInterval") 120 #define CLASSP_REG_IDLE_ACTIVE_MAX (L"IdleOutstandingIoMax") 121 #define CLASSP_REG_IDLE_PRIORITY_SUPPORTED (L"IdlePrioritySupported") 122 #define CLASSP_REG_ACCESS_ALIGNMENT_NOT_SUPPORTED (L"AccessAlignmentQueryNotSupported") 123 #define CLASSP_REG_DISBALE_IDLE_POWER_NAME (L"DisableIdlePowerManagement") 124 #define CLASSP_REG_IDLE_TIMEOUT_IN_SECONDS (L"IdleTimeoutInSeconds") 125 #define CLASSP_REG_DISABLE_D3COLD (L"DisableD3Cold") 126 #define CLASSP_REG_QERR_OVERRIDE_MODE (L"QERROverrideMode") 127 #define CLASSP_REG_LEGACY_ERROR_HANDLING (L"LegacyErrorHandling") 128 #define CLASSP_REG_COPY_OFFLOAD_MAX_TARGET_DURATION (L"CopyOffloadMaxTargetDuration") 129 130 #define CLASS_PERF_RESTORE_MINIMUM (0x10) 131 #define CLASS_ERROR_LEVEL_1 (0x4) 132 #define CLASS_ERROR_LEVEL_2 (0x8) 133 #define CLASS_MAX_INTERLEAVE_PER_CRITICAL_IO (0x4) 134 135 #define FDO_HACK_CANNOT_LOCK_MEDIA (0x00000001) 136 #define FDO_HACK_GESN_IS_BAD (0x00000002) 137 #define FDO_HACK_NO_SYNC_CACHE (0x00000004) 138 #define FDO_HACK_NO_RESERVE6 (0x00000008) 139 #define FDO_HACK_GESN_IGNORE_OPCHANGE (0x00000010) 140 141 #define FDO_HACK_VALID_FLAGS (0x0000001F) 142 #define FDO_HACK_INVALID_FLAGS (~FDO_HACK_VALID_FLAGS) 143 144 /* 145 * Lots of retries of synchronized SCSI commands that devices may not 146 * even support really slows down the system (especially while booting). 147 * (Even GetDriveCapacity may be failed on purpose if an external disk is powered off). 148 * If a disk cannot return a small initialization buffer at startup 149 * in two attempts (with delay interval) then we cannot expect it to return 150 * data consistently with four retries. 151 * So don't set the retry counts as high here as for data SRBs. 152 * 153 * If we find that these requests are failing consecutively, 154 * despite the retry interval, on otherwise reliable media, 155 * then we should either increase the retry interval for 156 * that failure or (by all means) increase these retry counts as appropriate. 157 */ 158 #define NUM_LOCKMEDIAREMOVAL_RETRIES 1 159 #define NUM_MODESENSE_RETRIES 1 160 #define NUM_MODESELECT_RETRIES 1 161 #define NUM_DRIVECAPACITY_RETRIES 1 162 #define NUM_THIN_PROVISIONING_RETRIES 32 163 164 #if (NTDDI_VERSION >= NTDDI_WINBLUE) 165 166 // 167 // New code should use the MAXIMUM_RETRIES value. 168 // 169 #define NUM_IO_RETRIES MAXIMUM_RETRIES 170 #define LEGACY_NUM_IO_RETRIES 8 171 172 #else 173 174 /* 175 * We retry failed I/O requests at 1-second intervals. 176 * In the case of a failure due to bus reset, we want to make sure that we retry after the allowable 177 * reset time. For SCSI, the allowable reset time is 5 seconds. ScsiPort queues requests during 178 * a bus reset, which should cause us to retry after the reset is over; but the requests queued in 179 * the miniport are failed all the way back to us immediately. In any event, in order to make 180 * extra sure that our retries span the allowable reset time, we should retry more than 5 times. 181 */ 182 #define NUM_IO_RETRIES 8 183 184 #endif // NTDDI_VERSION >= NTDDI_WINBLUE 185 186 #define CLASS_FILE_OBJECT_EXTENSION_KEY 'eteP' 187 #define CLASSP_VOLUME_VERIFY_CHECKED 0x34 188 189 #define CLASS_TAG_PRIVATE_DATA 'CPcS' 190 #define CLASS_TAG_SENSE2 '2ScS' 191 #define CLASS_TAG_WORKING_SET 'sWcS' 192 #define CLASSPNP_POOL_TAG_GENERIC 'pCcS' 193 #define CLASSPNP_POOL_TAG_TOKEN_OPERATION 'oTcS' 194 #define CLASSPNP_POOL_TAG_SRB 'rScS' 195 #define CLASSPNP_POOL_TAG_VPD 'pVcS' 196 #define CLASSPNP_POOL_TAG_LOG_MESSAGE 'mlcS' 197 #define CLASSPNP_POOL_TAG_ADDITIONAL_DATA 'DAcS' 198 #define CLASSPNP_POOL_TAG_FIRMWARE 'wFcS' 199 200 // 201 // Macros related to Token Operation commands 202 // 203 #define MAX_LIST_IDENTIFIER MAXULONG 204 #define NUM_POPULATE_TOKEN_RETRIES 1 205 #define NUM_WRITE_USING_TOKEN_RETRIES 2 206 #define NUM_RECEIVE_TOKEN_INFORMATION_RETRIES 2 207 #define MAX_TOKEN_OPERATION_PARAMETER_DATA_LENGTH MAXUSHORT 208 #define MAX_RECEIVE_TOKEN_INFORMATION_PARAMETER_DATA_LENGTH MAXULONG 209 #define MAX_TOKEN_TRANSFER_SIZE MAXULONGLONG 210 #define MAX_NUMBER_BLOCKS_PER_BLOCK_DEVICE_RANGE_DESCRIPTOR MAXULONG 211 #define DEFAULT_MAX_TARGET_DURATION 4 // 4sec 212 #define DEFAULT_MAX_NUMBER_BYTES_PER_SYNC_WRITE_USING_TOKEN (64ULL * 1024 * 1024) // 64MB 213 #define MAX_NUMBER_BYTES_PER_SYNC_WRITE_USING_TOKEN (256ULL * 1024 * 1024) // 256MB 214 #define MIN_TOKEN_LIST_IDENTIFIERS 256 215 #define MAX_TOKEN_LIST_IDENTIFIERS MAXULONG 216 #define MAX_NUMBER_BLOCK_DEVICE_DESCRIPTORS 64 217 218 #define REG_DISK_CLASS_CONTROL L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\DISK" 219 #define REG_MAX_LIST_IDENTIFIER_VALUE L"MaximumListIdentifier" 220 221 #define VPD_PAGE_HEADER_SIZE 0x04 222 223 224 // 225 // Number of times to retry get LBA status in case of an error 226 // that can be caused by VPD data change 227 // 228 229 #define GET_LBA_STATUS_RETRY_COUNT_MAX (2) 230 231 extern ULONG MaxTokenOperationListIdentifier; 232 extern volatile ULONG TokenOperationListIdentifier; 233 234 extern LIST_ENTRY IdlePowerFDOList; 235 extern PVOID PowerSettingNotificationHandle; 236 extern PVOID ScreenStateNotificationHandle; 237 extern BOOLEAN ClasspScreenOff; 238 extern KGUARDED_MUTEX IdlePowerFDOListMutex; 239 extern ULONG DiskIdleTimeoutInMS; 240 241 // 242 // Definitions from ntos\rtl\time.c 243 // 244 245 extern CONST LARGE_INTEGER Magic10000; 246 #define SHIFT10000 13 247 248 // 249 // Constant to help wih various time conversions 250 // 251 #define CONST_MSECS_PER_SEC 1000 252 253 #define Convert100nsToMilliseconds(LARGE_INTEGER) \ 254 ( \ 255 RtlExtendedMagicDivide((LARGE_INTEGER), Magic10000, SHIFT10000) \ 256 ) 257 258 #define ConvertMillisecondsTo100ns(MILLISECONDS) ( \ 259 RtlExtendedIntegerMultiply ((MILLISECONDS), 10000) \ 260 ) 261 262 typedef struct _MEDIA_CHANGE_DETECTION_INFO { 263 264 // 265 // Mutex to synchronize enable/disable requests and media state changes 266 // 267 268 KMUTEX MediaChangeMutex; 269 270 // 271 // The current state of the media (present, not present, unknown) 272 // protected by MediaChangeSynchronizationEvent 273 // 274 275 MEDIA_CHANGE_DETECTION_STATE MediaChangeDetectionState; 276 277 // 278 // This is a count of how many time MCD has been disabled. if it is 279 // set to zero, then we'll poll the device for MCN events with the 280 // then-current method (ie. TEST UNIT READY or GESN). this is 281 // protected by MediaChangeMutex 282 // 283 284 LONG MediaChangeDetectionDisableCount; 285 286 287 // 288 // The timer value to support media change events. This is a countdown 289 // value used to determine when to poll the device for a media change. 290 // The max value for the timer is 255 seconds. This is not protected 291 // by an event -- simply InterlockedExchanged() as needed. 292 // 293 294 LONG MediaChangeCountDown; 295 296 // 297 // recent changes allowed instant retries of the MCN irp. Since this 298 // could cause an infinite loop, keep a count of how many times we've 299 // retried immediately so that we can catch if the count exceeds an 300 // arbitrary limit. 301 // 302 303 LONG MediaChangeRetryCount; 304 305 // 306 // use GESN if it's available 307 // 308 309 struct { 310 BOOLEAN Supported; 311 BOOLEAN HackEventMask; 312 UCHAR EventMask; 313 UCHAR NoChangeEventMask; 314 PUCHAR Buffer; 315 PMDL Mdl; 316 ULONG BufferSize; 317 } Gesn; 318 319 // 320 // If this value is one, then the irp is currently in use. 321 // If this value is zero, then the irp is available. 322 // Use InterlockedCompareExchange() to set from "available" to "in use". 323 // ASSERT that InterlockedCompareExchange() showed previous value of 324 // "in use" when changing back to "available" state. 325 // This also implicitly protects the MediaChangeSrb and SenseBuffer 326 // 327 328 LONG MediaChangeIrpInUse; 329 330 // 331 // Pointer to the irp to be used for media change detection. 332 // protected by Interlocked MediaChangeIrpInUse 333 // 334 335 PIRP MediaChangeIrp; 336 337 // 338 // The srb for the media change detection. 339 // protected by Interlocked MediaChangeIrpInUse 340 // 341 342 #if (NTDDI_VERSION >= NTDDI_WIN8) 343 union { 344 SCSI_REQUEST_BLOCK Srb; 345 STORAGE_REQUEST_BLOCK SrbEx; 346 UCHAR SrbExBuffer[CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE]; 347 } MediaChangeSrb; 348 #else 349 SCSI_REQUEST_BLOCK MediaChangeSrb; 350 #endif 351 PUCHAR SenseBuffer; 352 ULONG SrbFlags; 353 354 // 355 // Second timer to keep track of how long the media change IRP has been 356 // in use. If this value exceeds the timeout (#defined) then we should 357 // print out a message to the user and set the MediaChangeIrpLost flag 358 // protected by using Interlocked() operations in ClasspSendMediaStateIrp, 359 // the only routine which should modify this value. 360 // 361 362 LONG MediaChangeIrpTimeInUse; 363 364 // 365 // Set by CdRomTickHandler when we determine that the media change irp has 366 // been lost 367 // 368 369 BOOLEAN MediaChangeIrpLost; 370 371 // 372 // Buffer size of SenseBuffer 373 // 374 UCHAR SenseBufferLength; 375 376 } MEDIA_CHANGE_DETECTION_INFO, *PMEDIA_CHANGE_DETECTION_INFO; 377 378 typedef enum { 379 SimpleMediaLock, 380 SecureMediaLock, 381 InternalMediaLock 382 } MEDIA_LOCK_TYPE, *PMEDIA_LOCK_TYPE; 383 384 typedef struct _FAILURE_PREDICTION_INFO { 385 FAILURE_PREDICTION_METHOD Method; 386 ULONG CountDown; // Countdown timer 387 ULONG Period; // Countdown period 388 389 PIO_WORKITEM WorkQueueItem; 390 391 KEVENT Event; 392 393 // 394 // Timestamp of last time the failure prediction info was queried. 395 // 396 LARGE_INTEGER LastFailurePredictionQueryTime; 397 398 } FAILURE_PREDICTION_INFO, *PFAILURE_PREDICTION_INFO; 399 400 401 402 // 403 // This struct must always fit within four PVOIDs of info, 404 // as it uses the irp's "PVOID DriverContext[4]" to store 405 // this info 406 // 407 typedef struct _CLASS_RETRY_INFO { 408 struct _CLASS_RETRY_INFO *Next; 409 } CLASS_RETRY_INFO, *PCLASS_RETRY_INFO; 410 411 typedef struct _CSCAN_LIST { 412 413 // 414 // The current block which has an outstanding request. 415 // 416 417 ULONGLONG BlockNumber; 418 419 // 420 // The list of blocks past the CurrentBlock to which we're going to do 421 // i/o. This list is maintained in sorted order. 422 // 423 424 LIST_ENTRY CurrentSweep; 425 426 // 427 // The list of blocks behind the current block for which we'll have to 428 // wait until the next scan across the disk. This is kept as a stack, 429 // the cost of sorting it is taken when it's moved over to be the 430 // running list. 431 // 432 433 LIST_ENTRY NextSweep; 434 435 } CSCAN_LIST, *PCSCAN_LIST; 436 437 // 438 // add to the front of this structure to help prevent illegal 439 // snooping by other utilities. 440 // 441 442 443 444 typedef enum _CLASS_DETECTION_STATE { 445 ClassDetectionUnknown = 0, 446 ClassDetectionUnsupported = 1, 447 ClassDetectionSupported = 2 448 } CLASS_DETECTION_STATE, *PCLASS_DETECTION_STATE; 449 450 #if _MSC_VER >= 1600 451 #pragma warning(push) 452 #pragma warning(disable:4214) // bit field types other than int 453 #endif 454 // 455 // CLASS_ERROR_LOG_DATA will still use SCSI_REQUEST_BLOCK even 456 // when using extended SRB as an extended SRB is too large to 457 // fit into. Should revisit this code once classpnp starts to 458 // use greater than 16 byte CDB. 459 // 460 typedef struct _CLASS_ERROR_LOG_DATA { 461 LARGE_INTEGER TickCount; // Offset 0x00 462 ULONG PortNumber; // Offset 0x08 463 464 UCHAR ErrorPaging : 1; // Offset 0x0c 465 UCHAR ErrorRetried : 1; 466 UCHAR ErrorUnhandled : 1; 467 UCHAR ErrorReserved : 5; 468 469 UCHAR Reserved[3]; 470 471 SCSI_REQUEST_BLOCK Srb; // Offset 0x10 472 473 /* 474 * We define the SenseData as the default length. 475 * Since the sense data returned by the port driver may be longer, 476 * SenseData must be at the end of this structure. 477 * For our internal error log, we only log the default length. 478 */ 479 SENSE_DATA SenseData; // Offset 0x50 for x86 (or 0x68 for ia64) (ULONG32 Alignment required!) 480 481 } CLASS_ERROR_LOG_DATA, *PCLASS_ERROR_LOG_DATA; 482 #if _MSC_VER >= 1600 483 #pragma warning(pop) 484 #endif 485 486 #define NUM_ERROR_LOG_ENTRIES 16 487 #define DBG_NUM_PACKET_LOG_ENTRIES (64*2) // 64 send&receive's 488 489 #if (NTDDI_VERSION >= NTDDI_WIN8) 490 typedef 491 VOID 492 (*PCONTINUATION_ROUTINE)( 493 _In_ PVOID Context 494 ); 495 #endif 496 497 typedef struct _TRANSFER_PACKET { 498 499 LIST_ENTRY AllPktsListEntry; // entry in fdoData's static AllTransferPacketsList 500 SLIST_ENTRY SlistEntry; // for when in free list (use fast slist) 501 502 PIRP Irp; 503 PDEVICE_OBJECT Fdo; 504 505 /* 506 * This is the client IRP that this TRANSFER_PACKET is currently 507 * servicing. 508 */ 509 PIRP OriginalIrp; 510 BOOLEAN CompleteOriginalIrpWhenLastPacketCompletes; 511 512 /* 513 * Stuff for retrying the transfer. 514 */ 515 #if (NTDDI_VERSION >= NTDDI_WINBLUE) 516 UCHAR NumRetries; // Total number of retries remaining. 517 UCHAR NumThinProvisioningRetries; //Number of retries carried out so far for a request failed with THIN_PROVISIONING_SOFT_THRESHOLD_ERROR 518 UCHAR NumIoTimeoutRetries; // Number of retries remaining for a timed-out request. 519 UCHAR TimedOut; // Indicates if this packet has timed-out. 520 #else 521 ULONG NumRetries; 522 #endif 523 KTIMER RetryTimer; 524 KDPC RetryTimerDPC; 525 526 _Field_range_(0,MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS) 527 LONGLONG RetryIn100nsUnits; 528 529 /* 530 * Event for synchronizing the transfer (optional). 531 * (Note that we can't have the event in the packet itself because 532 * by the time a thread waits on an event the packet may have 533 * been completed and re-issued. 534 */ 535 PKEVENT SyncEventPtr; 536 537 /* 538 * Stuff for retrying during extreme low-memory stress 539 * (when we retry 1 page at a time). 540 * NOTE: These fields are also used for StartIO-based 541 * class drivers, even when not in low memory conditions. 542 */ 543 BOOLEAN DriverUsesStartIO; // if this is set, then the below low-mem flags are always used 544 BOOLEAN InLowMemRetry; 545 PUCHAR LowMemRetry_remainingBufPtr; 546 ULONG LowMemRetry_remainingBufLen; 547 LARGE_INTEGER LowMemRetry_nextChunkTargetLocation; 548 549 /* 550 * Fields used for cancelling the packet. 551 */ 552 // BOOLEAN Cancelled; 553 // KEVENT CancelledEvent; 554 555 /* 556 * We keep the buffer and length values here as well 557 * as in the SRB because some miniports return 558 * the transferred length in SRB.DataTransferLength, 559 * and if the SRB failed we need that value again for the retry. 560 * We don't trust the lower stack to preserve any of these values in the SRB. 561 */ 562 PUCHAR BufPtrCopy; 563 ULONG BufLenCopy; 564 LARGE_INTEGER TargetLocationCopy; 565 566 /* 567 * This is a standard SCSI structure that receives a detailed 568 * report about a SCSI error on the hardware. 569 */ 570 SENSE_DATA_EX SrbErrorSenseData; 571 572 /* 573 * This is the SRB block for this TRANSFER_PACKET. 574 * For IOCTLs, the SRB block includes two DWORDs for 575 * device object and ioctl code; so these must 576 * immediately follow the SRB block. 577 */ 578 579 #if (NTDDI_VERSION >= NTDDI_WIN8) 580 PSTORAGE_REQUEST_BLOCK_HEADER Srb; 581 #else 582 SCSI_REQUEST_BLOCK Srb; 583 #endif 584 // ULONG SrbIoctlDevObj; // not handling ioctls yet 585 // ULONG SrbIoctlCode; 586 587 #if DBG 588 LARGE_INTEGER DbgTimeSent; 589 LARGE_INTEGER DbgTimeReturned; 590 ULONG DbgPktId; 591 IRP DbgOriginalIrpCopy; 592 MDL DbgMdlCopy; 593 #endif 594 595 BOOLEAN UsePartialMdl; 596 PMDL PartialMdl; 597 598 PSRB_HISTORY RetryHistory; 599 600 // The time at which this request was sent to port driver. 601 ULONGLONG RequestStartTime; 602 603 #if (NTDDI_VERSION >= NTDDI_WIN8) 604 // ActivityId that is associated with the IRP that this transfer packet services. 605 GUID ActivityId; 606 607 // If non-NULL, called at packet completion with this context. 608 PCONTINUATION_ROUTINE ContinuationRoutine; 609 PVOID ContinuationContext; 610 ULONGLONG TransferCount; 611 ULONG AllocateNode; 612 #endif 613 } TRANSFER_PACKET, *PTRANSFER_PACKET; 614 615 /* 616 * MIN_INITIAL_TRANSFER_PACKETS is the minimum number of packets that 617 * we preallocate at startup for each device (we need at least one packet 618 * to guarantee forward progress during memory stress). 619 * MIN_WORKINGSET_TRANSFER_PACKETS is the number of TRANSFER_PACKETs 620 * we allow to build up and remain for each device; 621 * we _lazily_ work down to this number when they're not needed. 622 * MAX_WORKINGSET_TRANSFER_PACKETS is the number of TRANSFER_PACKETs 623 * that we _immediately_ reduce to when they are not needed. 624 * 625 * The absolute maximum number of packets that we will allocate is 626 * whatever is required by the current activity, up to the memory limit; 627 * as soon as stress ends, we snap down to MAX_WORKINGSET_TRANSFER_PACKETS; 628 * we then lazily work down to MIN_WORKINGSET_TRANSFER_PACKETS. 629 */ 630 #define MIN_INITIAL_TRANSFER_PACKETS 1 631 #define MIN_WORKINGSET_TRANSFER_PACKETS_Client 16 632 #define MAX_WORKINGSET_TRANSFER_PACKETS_Client 32 633 #define MIN_WORKINGSET_TRANSFER_PACKETS_Server_UpperBound 256 634 #define MIN_WORKINGSET_TRANSFER_PACKETS_Server_LowerBound 32 635 #define MAX_WORKINGSET_TRANSFER_PACKETS_Server 1024 636 #define MIN_WORKINGSET_TRANSFER_PACKETS_SPACES 512 637 #define MAX_WORKINGSET_TRANSFER_PACKETS_SPACES 2048 638 #define MAX_OUTSTANDING_IO_PER_LUN_DEFAULT 16 639 #define MAX_CLEANUP_TRANSFER_PACKETS_AT_ONCE 8192 640 641 642 643 typedef struct _PNL_SLIST_HEADER { 644 DECLSPEC_CACHEALIGN SLIST_HEADER SListHeader; 645 DECLSPEC_CACHEALIGN ULONG NumFreeTransferPackets; 646 ULONG NumTotalTransferPackets; 647 ULONG DbgPeakNumTransferPackets; 648 } PNL_SLIST_HEADER, *PPNL_SLIST_HEADER; 649 650 // 651 // !!! WARNING !!! 652 // DO NOT use the following structure in code outside of classpnp 653 // as structure will not be guaranteed between OS versions. 654 // 655 // add to the front of this structure to help prevent illegal 656 // snooping by other utilities. 657 // 658 struct _CLASS_PRIVATE_FDO_DATA { 659 660 // 661 // The amount of time allowed for a target to complete a copy offload 662 // operation, in seconds. Default is 4s, but it can be modified via 663 // registry key. 664 // 665 ULONG CopyOffloadMaxTargetDuration; 666 667 668 #if (NTDDI_VERSION >= NTDDI_WIN8) 669 670 // 671 // Periodic timer for polling for media change detection, failure prediction 672 // and class tick function. 673 // 674 675 #if (NTDDI_VERSION >= NTDDI_WINBLUE) 676 PEX_TIMER TickTimer; 677 LONGLONG CurrentNoWakeTolerance; 678 #else 679 KTIMER TickTimer; 680 KDPC TickTimerDpc; 681 #endif // (NTDDI_VERSION >= NTDDI_WINBLUE) 682 683 // 684 // Power related and release queue SRBs 685 // 686 union { 687 STORAGE_REQUEST_BLOCK SrbEx; 688 UCHAR PowerSrbBuffer[CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE]; 689 } PowerSrb; 690 691 union { 692 STORAGE_REQUEST_BLOCK SrbEx; 693 UCHAR ReleaseQueueSrbBuffer[CLASS_SRBEX_NO_SRBEX_DATA_BUFFER_SIZE]; 694 } ReleaseQueueSrb; 695 696 #endif 697 698 ULONG TrackingFlags; 699 700 /* 701 * Flag to detect recursion caused by devices 702 * reporting different capacity per each request 703 */ 704 ULONG UpdateDiskPropertiesWorkItemActive; 705 706 // 707 // Local equivalents of MinWorkingSetTransferPackets and MaxWorkingSetTransferPackets. 708 // These values are initialized by the global equivalents but are then adjusted as 709 // requested by the class driver. 710 // 711 ULONG LocalMinWorkingSetTransferPackets; 712 ULONG LocalMaxWorkingSetTransferPackets; 713 714 #if DBG 715 716 ULONG MaxOutstandingIOPerLUN; 717 718 #endif 719 720 /* 721 * Entry in static list used by debug extension to quickly find all class FDOs. 722 */ 723 LIST_ENTRY AllFdosListEntry; 724 725 // 726 // this private structure allows us to 727 // dynamically re-enable the perf benefits 728 // lost due to transient error conditions. 729 // in w2k, a reboot was required. :( 730 // 731 struct { 732 ULONG OriginalSrbFlags; 733 ULONG SuccessfulIO; 734 ULONG ReEnableThreshhold; // 0 means never 735 } Perf; 736 737 ULONG_PTR HackFlags; 738 739 STORAGE_HOTPLUG_INFO HotplugInfo; 740 741 // Legacy. Still used by obsolete legacy code. 742 struct { 743 LARGE_INTEGER Delta; // in ticks 744 LARGE_INTEGER Tick; // when it should fire 745 PCLASS_RETRY_INFO ListHead; // singly-linked list 746 ULONG Granularity; // static 747 KSPIN_LOCK Lock; // protective spin lock 748 KDPC Dpc; // DPC routine object 749 KTIMER Timer; // timer to fire DPC 750 } Retry; 751 752 BOOLEAN TimerInitialized; 753 BOOLEAN LoggedTURFailureSinceLastIO; 754 BOOLEAN LoggedSYNCFailure; 755 756 // 757 // privately allocated release queue irp 758 // protected by fdoExtension->ReleaseQueueSpinLock 759 // 760 BOOLEAN ReleaseQueueIrpAllocated; 761 PIRP ReleaseQueueIrp; 762 763 /* 764 * Queues for TRANSFER_PACKETs that contextualize the IRPs and SRBs 765 * that we send down to the port driver. 766 * (The free list is an slist so that we can use fast 767 * interlocked operations on it; but the relatively-static 768 * AllTransferPacketsList list has to be 769 * a doubly-linked list since we have to dequeue from the middle). 770 */ 771 LIST_ENTRY AllTransferPacketsList; 772 PPNL_SLIST_HEADER FreeTransferPacketsLists; 773 774 /* 775 * Queue for deferred client irps 776 */ 777 LIST_ENTRY DeferredClientIrpList; 778 779 /* 780 * Precomputed maximum transfer length for the hardware. 781 */ 782 ULONG HwMaxXferLen; 783 784 /* 785 * SCSI_REQUEST_BLOCK template preconfigured with the constant values. 786 * This is slapped into the SRB in the TRANSFER_PACKET for each transfer. 787 */ 788 789 #if (NTDDI_VERSION >= NTDDI_WIN8) 790 PSTORAGE_REQUEST_BLOCK_HEADER SrbTemplate; 791 #else 792 SCSI_REQUEST_BLOCK SrbTemplate; 793 #endif 794 795 KSPIN_LOCK SpinLock; 796 797 /* 798 * For non-removable media, we read the drive capacity at start time and cache it. 799 * This is so that ReadDriveCapacity failures at runtime (e.g. due to memory stress) 800 * don't cause I/O on the paging disk to start failing. 801 */ 802 READ_CAPACITY_DATA_EX LastKnownDriveCapacityData; 803 BOOLEAN IsCachedDriveCapDataValid; 804 805 // 806 // Idle priority support flag 807 // 808 BOOLEAN IdlePrioritySupported; 809 810 // 811 // Tick timer enabled 812 // 813 BOOLEAN TickTimerEnabled; 814 815 BOOLEAN ReservedBoolean; 816 817 /* 818 * Circular array of timestamped logs of errors that occurred on this device. 819 */ 820 ULONG ErrorLogNextIndex; 821 CLASS_ERROR_LOG_DATA ErrorLogs[NUM_ERROR_LOG_ENTRIES]; 822 823 // 824 // Number of outstanding critical Io requests from Mm 825 // 826 ULONG NumHighPriorityPagingIo; 827 828 // 829 // Maximum number of normal Io requests that can be interleaved with the critical ones 830 // 831 ULONG MaxInterleavedNormalIo; 832 833 // 834 // The timestamp when entering throttle mode 835 // 836 LARGE_INTEGER ThrottleStartTime; 837 838 // 839 // The timestamp when exiting throttle mode 840 // 841 LARGE_INTEGER ThrottleStopTime; 842 843 // 844 // The longest time ever spent in throttle mode 845 // 846 LARGE_INTEGER LongestThrottlePeriod; 847 848 #if DBG 849 ULONG DbgMaxPktId; 850 851 /* 852 * Logging fields for ForceUnitAccess and Flush 853 */ 854 BOOLEAN DbgInitFlushLogging; // must reset this to 1 for each logging session 855 ULONG DbgNumIORequests; 856 ULONG DbgNumFUAs; // num I/O requests with ForceUnitAccess bit set 857 ULONG DbgNumFlushes; // num SRB_FUNCTION_FLUSH_QUEUE 858 ULONG DbgIOsSinceFUA; 859 ULONG DbgIOsSinceFlush; 860 ULONG DbgAveIOsToFUA; // average number of I/O requests between FUAs 861 ULONG DbgAveIOsToFlush; // ... 862 ULONG DbgMaxIOsToFUA; 863 ULONG DbgMaxIOsToFlush; 864 ULONG DbgMinIOsToFUA; 865 ULONG DbgMinIOsToFlush; 866 867 /* 868 * Debug log of previously sent packets (including retries). 869 */ 870 ULONG DbgPacketLogNextIndex; 871 TRANSFER_PACKET DbgPacketLogs[DBG_NUM_PACKET_LOG_ENTRIES]; 872 #endif 873 874 // 875 // Spin lock for low priority I/O list 876 // 877 KSPIN_LOCK IdleListLock; 878 879 // 880 // Queue for low priority I/O 881 // 882 LIST_ENTRY IdleIrpList; 883 884 // 885 // Timer for low priority I/O 886 // 887 KTIMER IdleTimer; 888 889 // 890 // DPC for low priority I/O 891 // 892 KDPC IdleDpc; 893 894 #if (NTDDI_VERSION >= NTDDI_WIN8) 895 896 // 897 // Time (ms) since the completion of the last non-idle request before the 898 // first idle request should be issued. Due to the coarseness of the idle 899 // timer frequency, some variability in the idle interval will be tolerated 900 // such that it is the desired idle interval on average. 901 // 902 USHORT IdleInterval; 903 904 // 905 // Max number of active idle requests. 906 // 907 USHORT IdleActiveIoMax; 908 909 #endif 910 911 // 912 // Idle duration required to process idle request 913 // to avoid starvation 914 // 915 USHORT StarvationDuration; 916 917 // 918 // Idle I/O count 919 // 920 ULONG IdleIoCount; 921 922 // 923 // Flag to indicate timer status 924 // 925 LONG IdleTimerStarted; 926 927 // 928 // Time when the Idle timer was started 929 // 930 LARGE_INTEGER AntiStarvationStartTime; 931 932 // 933 // Normal priority I/O time 934 // 935 LARGE_INTEGER LastNonIdleIoTime; 936 937 // 938 // Time when the last IO of any priority completed. 939 // 940 LARGE_INTEGER LastIoCompletionTime; 941 942 // 943 // Count of active normal priority I/O 944 // 945 LONG ActiveIoCount; 946 947 // 948 // Count of active idle priority I/O 949 // 950 LONG ActiveIdleIoCount; 951 952 // 953 // Support for class drivers to extend 954 // the interpret sense information routine 955 // and retry history per-packet. Copy of 956 // values in driver extension. 957 // 958 PCLASS_INTERPRET_SENSE_INFO2 InterpretSenseInfo; 959 960 // 961 // power process parameters. they work closely with CLASS_POWER_CONTEXT structure. 962 // 963 ULONG MaxPowerOperationRetryCount; 964 PIRP PowerProcessIrp; 965 966 // 967 // Indicates legacy error handling should be used. 968 // This means: 969 // - Max number of retries for an IO request is 8 (instead of 4). 970 // 971 BOOLEAN LegacyErrorHandling; 972 973 // 974 // Maximum number of retries allowed for IO requests for this device. 975 // 976 UCHAR MaxNumberOfIoRetries; 977 978 // 979 // Disable All Throttling in case of Error 980 // 981 BOOLEAN DisableThrottling; 982 983 }; 984 985 // 986 // !!! WARNING !!! 987 // DO NOT use the following structure in code outside of classpnp 988 // as structure will not be guaranteed between OS versions. 989 // 990 // EX_RUNDOWN_REF_CACHE_AWARE is variable size and follows 991 // RemoveLockFailAcquire. EX_RUNDOWN_REF_CACHE_AWARE must be part 992 // of the device extension allocation to avoid issues with a device 993 // that has been PNP remove but still has outstanding references. 994 // In this case, the removed object may still receive incoming requests. 995 // 996 // There are code dependencies on the structure layout. To minimize 997 // code changes, new fields to _CLASS_PRIVATE_COMMON_DATA should be 998 // added based on the following guidance. 999 // - Fixed size: beginning of _CLASS_PRIVATE_COMMON_DATA 1000 // - Variable size: at the end of _CLASS_PRIVATE_COMMON_DATA after the 1001 // last variable size field. 1002 // 1003 1004 struct _CLASS_PRIVATE_COMMON_DATA { 1005 1006 // 1007 // Cacheaware rundown lock reference 1008 // 1009 1010 LONG RemoveLockFailAcquire; 1011 1012 // 1013 // N.B. EX_RUNDOWN_REF_CACHE_AWARE begins with a pointer-sized item that is 1014 // accessed interlocked, and must be aligned on ARM platforms. In order 1015 // for this to work on ARM64, an additional 32-bit slot must be allocated. 1016 // 1017 1018 #if defined(_WIN64) 1019 LONG Align; 1020 #endif 1021 1022 // EX_RUNDOWN_REF_CACHE_AWARE (variable size) follows 1023 1024 }; 1025 1026 // 1027 // Verify that the size of _CLASS_PRIVATE_COMMON_DATA is pointer size aligned 1028 // to ensure the EX_RUNDOWN_REF_CACHE_AWARE following it is properly aligned. 1029 // 1030 1031 C_ASSERT((sizeof(struct _CLASS_PRIVATE_COMMON_DATA) % sizeof(PVOID)) == 0); 1032 1033 typedef struct _IDLE_POWER_FDO_LIST_ENTRY { 1034 LIST_ENTRY ListEntry; 1035 PDEVICE_OBJECT Fdo; 1036 } IDLE_POWER_FDO_LIST_ENTRY, *PIDLE_POWER_FDO_LIST_ENTRY; 1037 1038 typedef struct _OFFLOAD_READ_CONTEXT { 1039 1040 PDEVICE_OBJECT Fdo; 1041 1042 // 1043 // Upper offload read DSM irp. 1044 // 1045 1046 PIRP OffloadReadDsmIrp; 1047 1048 // 1049 // A pseudo-irp is used despite the operation being async. This is in 1050 // contrast to normal read and write, which let TransferPktComplete() 1051 // complete the upper IRP directly. Offload requests are enough different 1052 // that it makes more sense to let them manage their own async steps with 1053 // minimal help from TransferPktComplete() (just a continuation function 1054 // call during TransferPktComplete()). 1055 // 1056 1057 IRP PseudoIrp; 1058 1059 // 1060 // The offload read context tracks one packet in flight at a time - it'll be 1061 // the POPULATE TOKEN packet first, then RECEIVE ROD TOKEN INFORMATION. 1062 // 1063 // This field exists only for debug purposes. 1064 // 1065 1066 PTRANSFER_PACKET Pkt; 1067 1068 PMDL PopulateTokenMdl; 1069 1070 ULONG BufferLength; 1071 1072 ULONG ListIdentifier; 1073 1074 ULONG ReceiveTokenInformationBufferLength; 1075 1076 // 1077 // Total sectors that the operation is attempting to process. 1078 // 1079 1080 ULONGLONG TotalSectorsToProcess; 1081 1082 // 1083 // Total sectors actually processed. 1084 // 1085 1086 ULONGLONG TotalSectorsProcessed; 1087 1088 // 1089 // Total upper request size in bytes. 1090 // 1091 1092 ULONGLONG EntireXferLen; 1093 1094 // 1095 // Just a cached copy of what was in the transfer packet. 1096 // 1097 1098 SCSI_REQUEST_BLOCK Srb; 1099 1100 // 1101 // Pointer into the token part of the SCSI buffer (the buffer immediately 1102 // after this struct), for easy reference. 1103 // 1104 1105 PUCHAR Token; 1106 1107 // The SCSI buffer (in/out buffer, not CDB) for the commands immediately 1108 // follows this struct, so no need to have a field redundantly pointing to 1109 // the buffer. 1110 } OFFLOAD_READ_CONTEXT, *POFFLOAD_READ_CONTEXT; 1111 1112 1113 typedef struct _OFFLOAD_WRITE_CONTEXT { 1114 1115 PDEVICE_OBJECT Fdo; 1116 1117 PIRP OffloadWriteDsmIrp; 1118 1119 ULONGLONG EntireXferLen; 1120 ULONGLONG TotalRequestSizeSectors; 1121 1122 ULONG DataSetRangesCount; 1123 1124 PDEVICE_MANAGE_DATA_SET_ATTRIBUTES DsmAttributes; 1125 PDEVICE_DATA_SET_RANGE DataSetRanges; 1126 PDEVICE_DSM_OFFLOAD_WRITE_PARAMETERS OffloadWriteParameters; 1127 ULONGLONG LogicalBlockOffset; 1128 1129 ULONG MaxBlockDescrCount; 1130 ULONGLONG MaxLbaCount; 1131 1132 ULONG BufferLength; 1133 ULONG ReceiveTokenInformationBufferLength; 1134 1135 IRP PseudoIrp; 1136 1137 PMDL WriteUsingTokenMdl; 1138 1139 ULONGLONG TotalSectorsProcessedSuccessfully; 1140 ULONG DataSetRangeIndex; 1141 ULONGLONG DataSetRangeByteOffset; 1142 1143 PTRANSFER_PACKET Pkt; 1144 1145 // 1146 // Per-WUT (WRITE USING TOKEN), not overall. 1147 // 1148 1149 ULONGLONG TotalSectorsToProcess; 1150 ULONGLONG TotalSectorsProcessed; 1151 1152 ULONG ListIdentifier; 1153 1154 BOOLEAN TokenInvalidated; 1155 1156 // 1157 // Just a cached copy of what was in the transfer packet. 1158 // 1159 1160 SCSI_REQUEST_BLOCK Srb; 1161 1162 ULONGLONG OperationStartTime; 1163 1164 } OFFLOAD_WRITE_CONTEXT, *POFFLOAD_WRITE_CONTEXT; 1165 1166 1167 typedef struct _OPCODE_SENSE_DATA_IO_LOG_MESSAGE_CONTEXT_HEADER { 1168 PIO_WORKITEM WorkItem; 1169 PVOID SenseData; 1170 ULONG SenseDataSize; 1171 UCHAR SrbStatus; 1172 UCHAR ScsiStatus; 1173 UCHAR OpCode; 1174 UCHAR Reserved; 1175 ULONG ErrorCode; 1176 } OPCODE_SENSE_DATA_IO_LOG_MESSAGE_CONTEXT_HEADER, *POPCODE_SENSE_DATA_IO_LOG_MESSAGE_CONTEXT_HEADER; 1177 1178 typedef struct _IO_RETRIED_LOG_MESSAGE_CONTEXT { 1179 OPCODE_SENSE_DATA_IO_LOG_MESSAGE_CONTEXT_HEADER ContextHeader; 1180 LARGE_INTEGER Lba; 1181 ULONG DeviceNumber; 1182 } IO_RETRIED_LOG_MESSAGE_CONTEXT, *PIO_RETRIED_LOG_MESSAGE_CONTEXT; 1183 1184 1185 #define QERR_SET_ZERO_ODX_OR_TP_ONLY 0 1186 #define QERR_SET_ZERO_ALWAYS 1 1187 #define QERR_SET_ZERO_NEVER 2 1188 1189 1190 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 1191 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 1192 1193 1194 #define NOT_READY_RETRY_INTERVAL 10 1195 #define MINIMUM_RETRY_UNITS ((LONGLONG)32) 1196 #define MODE_PAGE_DATA_SIZE 192 1197 1198 #define CLASS_IDLE_INTERVAL_MIN 12 // 12 milliseconds 1199 #define CLASS_IDLE_INTERVAL 12 // 12 milliseconds 1200 #define CLASS_STARVATION_INTERVAL 500 // 500 milliseconds 1201 1202 // 1203 // Value of 50 milliseconds in 100 nanoseconds units 1204 // 1205 #define FIFTY_MS_IN_100NS_UNITS 50 * 100 1206 1207 1208 /* 1209 * Simple singly-linked-list queuing macros, with no synchronization. 1210 */ 1211 FORCEINLINE VOID SimpleInitSlistHdr(SINGLE_LIST_ENTRY *SListHdr) 1212 { 1213 SListHdr->Next = NULL; 1214 } 1215 FORCEINLINE VOID SimplePushSlist(SINGLE_LIST_ENTRY *SListHdr, SINGLE_LIST_ENTRY *SListEntry) 1216 { 1217 SListEntry->Next = SListHdr->Next; 1218 SListHdr->Next = SListEntry; 1219 } 1220 FORCEINLINE SINGLE_LIST_ENTRY *SimplePopSlist(SINGLE_LIST_ENTRY *SListHdr) 1221 { 1222 SINGLE_LIST_ENTRY *sListEntry = SListHdr->Next; 1223 if (sListEntry){ 1224 SListHdr->Next = sListEntry->Next; 1225 sListEntry->Next = NULL; 1226 } 1227 return sListEntry; 1228 } 1229 FORCEINLINE BOOLEAN SimpleIsSlistEmpty(SINGLE_LIST_ENTRY *SListHdr) 1230 { 1231 return (SListHdr->Next == NULL); 1232 } 1233 1234 FORCEINLINE 1235 BOOLEAN 1236 ClasspIsIdleRequestSupported( 1237 PCLASS_PRIVATE_FDO_DATA FdoData, 1238 PIRP Irp 1239 ) 1240 { 1241 #ifndef __REACTOS__ 1242 IO_PRIORITY_HINT ioPriority = IoGetIoPriorityHint(Irp); 1243 return ((ioPriority <= IoPriorityLow) && (FdoData->IdlePrioritySupported == TRUE)); 1244 #else 1245 return (FdoData->IdlePrioritySupported == TRUE); 1246 #endif 1247 } 1248 1249 FORCEINLINE 1250 VOID 1251 ClasspMarkIrpAsIdle( 1252 PIRP Irp, 1253 BOOLEAN Idle 1254 ) 1255 { 1256 #ifndef __REACTOS__ 1257 // truncation is not an issue for this use case 1258 // nonstandard extension used is not an issue for this use case 1259 #pragma warning(suppress:4305; suppress:4213) 1260 ((BOOLEAN)Irp->Tail.Overlay.DriverContext[1]) = Idle; 1261 #else 1262 ((PULONG_PTR)Irp->Tail.Overlay.DriverContext)[1] = Idle; 1263 #endif 1264 } 1265 1266 FORCEINLINE 1267 BOOLEAN 1268 ClasspIsIdleRequest( 1269 PIRP Irp 1270 ) 1271 { 1272 #ifdef _MSC_VER 1273 #pragma warning(suppress:4305) // truncation is not an issue for this use case 1274 #endif 1275 return ((BOOLEAN)Irp->Tail.Overlay.DriverContext[1]); 1276 } 1277 1278 FORCEINLINE 1279 LARGE_INTEGER 1280 ClasspGetCurrentTime( 1281 VOID 1282 ) 1283 { 1284 LARGE_INTEGER currentTime; 1285 1286 #ifndef __REACTOS__ 1287 currentTime.QuadPart = KeQueryUnbiasedInterruptTimePrecise((ULONG64*)¤tTime.QuadPart); 1288 #else 1289 currentTime = KeQueryPerformanceCounter(NULL); 1290 #endif 1291 1292 return currentTime; 1293 } 1294 1295 FORCEINLINE 1296 ULONGLONG 1297 ClasspTimeDiffToMs( 1298 ULONGLONG TimeDiff 1299 ) 1300 { 1301 TimeDiff /= (10 * 1000); 1302 1303 return TimeDiff; 1304 } 1305 1306 FORCEINLINE 1307 BOOLEAN 1308 ClasspSupportsUnmap( 1309 _In_ PCLASS_FUNCTION_SUPPORT_INFO SupportInfo 1310 ) 1311 { 1312 return SupportInfo->LBProvisioningData.LBPU; 1313 } 1314 1315 FORCEINLINE 1316 BOOLEAN 1317 ClasspIsThinProvisioned( 1318 _In_ PCLASS_FUNCTION_SUPPORT_INFO SupportInfo 1319 ) 1320 { 1321 // 1322 // We only support thinly provisioned devices that also support UNMAP. 1323 // 1324 if (SupportInfo->LBProvisioningData.ProvisioningType == PROVISIONING_TYPE_THIN && 1325 SupportInfo->LBProvisioningData.LBPU == TRUE) 1326 { 1327 return TRUE; 1328 } 1329 1330 return FALSE; 1331 } 1332 1333 FORCEINLINE 1334 BOOLEAN 1335 ClasspIsObsoletePortDriver( 1336 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 1337 ) 1338 { 1339 if ( (FdoExtension->MiniportDescriptor != NULL) && 1340 (FdoExtension->MiniportDescriptor->Portdriver == StoragePortCodeSetSCSIport) ) { 1341 return TRUE; 1342 } 1343 1344 return FALSE; 1345 } 1346 1347 1348 ULONG 1349 ClasspCalculateLogicalSectorSize ( 1350 _In_ PDEVICE_OBJECT Fdo, 1351 _In_ ULONG BytesPerBlockInBigEndian 1352 ); 1353 1354 DRIVER_INITIALIZE DriverEntry; 1355 1356 DRIVER_UNLOAD ClassUnload; 1357 1358 _Dispatch_type_(IRP_MJ_CREATE) 1359 _Dispatch_type_(IRP_MJ_CLOSE) 1360 DRIVER_DISPATCH ClassCreateClose; 1361 1362 NTSTATUS 1363 ClasspCreateClose( 1364 IN PDEVICE_OBJECT DeviceObject, 1365 IN PIRP Irp 1366 ); 1367 1368 VOID 1369 ClasspCleanupProtectedLocks( 1370 IN PFILE_OBJECT_EXTENSION FsContext 1371 ); 1372 1373 NTSTATUS 1374 ClasspEjectionControl( 1375 IN PDEVICE_OBJECT Fdo, 1376 IN PIRP Irp, 1377 IN MEDIA_LOCK_TYPE LockType, 1378 IN BOOLEAN Lock 1379 ); 1380 1381 _Dispatch_type_(IRP_MJ_READ) 1382 _Dispatch_type_(IRP_MJ_WRITE) 1383 DRIVER_DISPATCH ClassReadWrite; 1384 1385 _Dispatch_type_(IRP_MJ_DEVICE_CONTROL) 1386 DRIVER_DISPATCH ClassDeviceControlDispatch; 1387 1388 _Dispatch_type_(IRP_MJ_PNP) 1389 DRIVER_DISPATCH ClassDispatchPnp; 1390 1391 NTSTATUS 1392 ClassPnpStartDevice( 1393 IN PDEVICE_OBJECT DeviceObject 1394 ); 1395 1396 _Dispatch_type_(IRP_MJ_SHUTDOWN) 1397 _Dispatch_type_(IRP_MJ_FLUSH_BUFFERS) 1398 DRIVER_DISPATCH ClassShutdownFlush; 1399 1400 _Dispatch_type_(IRP_MJ_SYSTEM_CONTROL) 1401 DRIVER_DISPATCH ClassSystemControl; 1402 1403 1404 // 1405 // Class internal routines 1406 // 1407 1408 DRIVER_ADD_DEVICE ClassAddDevice; 1409 1410 IO_COMPLETION_ROUTINE ClasspSendSynchronousCompletion; 1411 1412 VOID 1413 RetryRequest( 1414 PDEVICE_OBJECT DeviceObject, 1415 PIRP Irp, 1416 PSCSI_REQUEST_BLOCK Srb, 1417 BOOLEAN Associated, 1418 LONGLONG TimeDelta100ns 1419 ); 1420 1421 NTSTATUS 1422 ClassIoCompletion( 1423 IN PDEVICE_OBJECT DeviceObject, 1424 IN PIRP Irp, 1425 IN PVOID Context 1426 ); 1427 1428 NTSTATUS 1429 ClassPnpQueryFdoRelations( 1430 IN PDEVICE_OBJECT Fdo, 1431 IN PIRP Irp 1432 ); 1433 1434 NTSTATUS 1435 ClassRetrieveDeviceRelations( 1436 IN PDEVICE_OBJECT Fdo, 1437 IN DEVICE_RELATION_TYPE RelationType, 1438 OUT PDEVICE_RELATIONS *DeviceRelations 1439 ); 1440 1441 NTSTATUS 1442 ClassGetPdoId( 1443 IN PDEVICE_OBJECT Pdo, 1444 IN BUS_QUERY_ID_TYPE IdType, 1445 IN PUNICODE_STRING IdString 1446 ); 1447 1448 NTSTATUS 1449 ClassQueryPnpCapabilities( 1450 IN PDEVICE_OBJECT PhysicalDeviceObject, 1451 IN PDEVICE_CAPABILITIES Capabilities 1452 ); 1453 1454 DRIVER_STARTIO ClasspStartIo; 1455 1456 NTSTATUS 1457 ClasspPagingNotificationCompletion( 1458 IN PDEVICE_OBJECT DeviceObject, 1459 IN PIRP Irp, 1460 IN PDEVICE_OBJECT RealDeviceObject 1461 ); 1462 1463 NTSTATUS 1464 ClasspMediaChangeCompletion( 1465 PDEVICE_OBJECT DeviceObject, 1466 PIRP Irp, 1467 PVOID Context 1468 ); 1469 1470 NTSTATUS 1471 ClasspMcnControl( 1472 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1473 IN PIRP Irp, 1474 IN PSCSI_REQUEST_BLOCK Srb 1475 ); 1476 1477 VOID 1478 ClasspRegisterMountedDeviceInterface( 1479 IN PDEVICE_OBJECT DeviceObject 1480 ); 1481 1482 VOID 1483 ClasspDisableTimer( 1484 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 1485 ); 1486 1487 VOID 1488 ClasspEnableTimer( 1489 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 1490 ); 1491 1492 NTSTATUS 1493 ClasspInitializeTimer( 1494 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 1495 ); 1496 1497 VOID 1498 ClasspDeleteTimer( 1499 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 1500 ); 1501 1502 #if (NTDDI_VERSION >= NTDDI_WINBLUE) 1503 BOOLEAN 1504 ClasspUpdateTimerNoWakeTolerance( 1505 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 1506 ); 1507 #endif 1508 1509 NTSTATUS 1510 ClasspDuidQueryProperty( 1511 PDEVICE_OBJECT DeviceObject, 1512 PIRP Irp 1513 ); 1514 1515 _Dispatch_type_(IRP_MJ_CREATE) 1516 _Dispatch_type_(IRP_MJ_CLOSE) 1517 _Dispatch_type_(IRP_MJ_READ) 1518 _Dispatch_type_(IRP_MJ_WRITE) 1519 _Dispatch_type_(IRP_MJ_SCSI) 1520 _Dispatch_type_(IRP_MJ_DEVICE_CONTROL) 1521 _Dispatch_type_(IRP_MJ_SHUTDOWN) 1522 _Dispatch_type_(IRP_MJ_FLUSH_BUFFERS) 1523 _Dispatch_type_(IRP_MJ_PNP) 1524 _Dispatch_type_(IRP_MJ_POWER) 1525 _Dispatch_type_(IRP_MJ_SYSTEM_CONTROL) 1526 DRIVER_DISPATCH ClassGlobalDispatch; 1527 1528 VOID 1529 ClassInitializeDispatchTables( 1530 PCLASS_DRIVER_EXTENSION DriverExtension 1531 ); 1532 1533 NTSTATUS 1534 ClasspPersistentReserve( 1535 _In_ PDEVICE_OBJECT DeviceObject, 1536 _In_ PIRP Irp, 1537 _Inout_ PSCSI_REQUEST_BLOCK Srb 1538 ); 1539 1540 // 1541 // routines for dictionary list support 1542 // 1543 1544 VOID 1545 InitializeDictionary( 1546 IN PDICTIONARY Dictionary 1547 ); 1548 1549 BOOLEAN 1550 TestDictionarySignature( 1551 IN PDICTIONARY Dictionary 1552 ); 1553 1554 NTSTATUS 1555 AllocateDictionaryEntry( 1556 IN PDICTIONARY Dictionary, 1557 IN ULONGLONG Key, 1558 IN ULONG Size, 1559 IN ULONG Tag, 1560 OUT PVOID *Entry 1561 ); 1562 1563 PVOID 1564 GetDictionaryEntry( 1565 IN PDICTIONARY Dictionary, 1566 IN ULONGLONG Key 1567 ); 1568 1569 VOID 1570 FreeDictionaryEntry( 1571 IN PDICTIONARY Dictionary, 1572 IN PVOID Entry 1573 ); 1574 1575 1576 NTSTATUS 1577 ClasspAllocateReleaseRequest( 1578 IN PDEVICE_OBJECT Fdo 1579 ); 1580 1581 VOID 1582 ClasspFreeReleaseRequest( 1583 IN PDEVICE_OBJECT Fdo 1584 ); 1585 1586 IO_COMPLETION_ROUTINE ClassReleaseQueueCompletion; 1587 1588 VOID 1589 ClasspReleaseQueue( 1590 IN PDEVICE_OBJECT DeviceObject, 1591 IN PIRP ReleaseQueueIrp 1592 ); 1593 1594 VOID 1595 ClasspDisablePowerNotification( 1596 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 1597 ); 1598 1599 // 1600 // class power routines 1601 // 1602 1603 _Dispatch_type_(IRP_MJ_POWER) 1604 DRIVER_DISPATCH ClassDispatchPower; 1605 1606 NTSTATUS 1607 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ 1608 ClassMinimalPowerHandler( 1609 IN PDEVICE_OBJECT DeviceObject, 1610 IN PIRP Irp 1611 ); 1612 1613 _IRQL_requires_same_ 1614 NTSTATUS 1615 ClasspEnableIdlePower( 1616 _In_ PDEVICE_OBJECT DeviceObject 1617 ); 1618 1619 POWER_SETTING_CALLBACK ClasspPowerSettingCallback; 1620 1621 // 1622 // Child list routines 1623 // 1624 1625 VOID 1626 ClassAddChild( 1627 _In_ PFUNCTIONAL_DEVICE_EXTENSION Parent, 1628 _In_ PPHYSICAL_DEVICE_EXTENSION Child, 1629 _In_ BOOLEAN AcquireLock 1630 ); 1631 1632 PPHYSICAL_DEVICE_EXTENSION 1633 ClassRemoveChild( 1634 IN PFUNCTIONAL_DEVICE_EXTENSION Parent, 1635 IN PPHYSICAL_DEVICE_EXTENSION Child, 1636 IN BOOLEAN AcquireLock 1637 ); 1638 1639 VOID 1640 ClasspRetryDpcTimer( 1641 IN PCLASS_PRIVATE_FDO_DATA FdoData 1642 ); 1643 1644 KDEFERRED_ROUTINE ClasspRetryRequestDpc; 1645 1646 VOID 1647 ClassFreeOrReuseSrb( 1648 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1649 IN __drv_freesMem(mem) PSCSI_REQUEST_BLOCK Srb 1650 ); 1651 1652 VOID 1653 ClassRetryRequest( 1654 IN PDEVICE_OBJECT SelfDeviceObject, 1655 IN PIRP Irp, 1656 _In_ _In_range_(0,MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS) // this is 100 seconds; already an assert in classpnp based on this 1657 IN LONGLONG TimeDelta100ns // in 100ns units 1658 ); 1659 1660 VOID 1661 ClasspBuildRequestEx( 1662 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1663 _In_ PIRP Irp, 1664 _In_ __drv_aliasesMem PSCSI_REQUEST_BLOCK Srb 1665 ); 1666 1667 NTSTATUS 1668 ClasspAllocateReleaseQueueIrp( 1669 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 1670 ); 1671 1672 NTSTATUS 1673 ClasspAllocatePowerProcessIrp( 1674 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 1675 ); 1676 1677 NTSTATUS 1678 ClasspInitializeGesn( 1679 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1680 IN PMEDIA_CHANGE_DETECTION_INFO Info 1681 ); 1682 1683 VOID 1684 ClassSendEjectionNotification( 1685 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 1686 ); 1687 1688 VOID 1689 ClasspScanForSpecialInRegistry( 1690 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 1691 ); 1692 1693 VOID 1694 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */ 1695 ClasspScanForClassHacks( 1696 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1697 IN ULONG_PTR Data 1698 ); 1699 1700 NTSTATUS 1701 ClasspInitializeHotplugInfo( 1702 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 1703 ); 1704 1705 VOID 1706 ClasspPerfIncrementErrorCount( 1707 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 1708 ); 1709 VOID 1710 ClasspPerfIncrementSuccessfulIo( 1711 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 1712 ); 1713 1714 IO_WORKITEM_ROUTINE ClasspUpdateDiskProperties; 1715 1716 __drv_allocatesMem(Mem) 1717 PTRANSFER_PACKET NewTransferPacket(PDEVICE_OBJECT Fdo); 1718 VOID DestroyTransferPacket(_In_ __drv_freesMem(mem) PTRANSFER_PACKET Pkt); 1719 VOID EnqueueFreeTransferPacket(PDEVICE_OBJECT Fdo, __drv_aliasesMem PTRANSFER_PACKET Pkt); 1720 PTRANSFER_PACKET DequeueFreeTransferPacket(PDEVICE_OBJECT Fdo, BOOLEAN AllocIfNeeded); 1721 PTRANSFER_PACKET DequeueFreeTransferPacketEx(_In_ PDEVICE_OBJECT Fdo, _In_ BOOLEAN AllocIfNeeded, _In_ ULONG Node); 1722 VOID SetupReadWriteTransferPacket(PTRANSFER_PACKET pkt, PVOID Buf, ULONG Len, LARGE_INTEGER DiskLocation, PIRP OriginalIrp); 1723 NTSTATUS SubmitTransferPacket(PTRANSFER_PACKET Pkt); 1724 IO_COMPLETION_ROUTINE TransferPktComplete; 1725 NTSTATUS ServiceTransferRequest(PDEVICE_OBJECT Fdo, PIRP Irp, BOOLEAN PostToDpc); 1726 VOID TransferPacketQueueRetryDpc(PTRANSFER_PACKET Pkt); 1727 KDEFERRED_ROUTINE TransferPacketRetryTimerDpc; 1728 BOOLEAN InterpretTransferPacketError(PTRANSFER_PACKET Pkt); 1729 BOOLEAN RetryTransferPacket(PTRANSFER_PACKET Pkt); 1730 VOID EnqueueDeferredClientIrp(PDEVICE_OBJECT Fdo, PIRP Irp); 1731 PIRP DequeueDeferredClientIrp(PDEVICE_OBJECT Fdo); 1732 VOID InitLowMemRetry(PTRANSFER_PACKET Pkt, PVOID BufPtr, ULONG Len, LARGE_INTEGER TargetLocation); 1733 BOOLEAN StepLowMemRetry(PTRANSFER_PACKET Pkt); 1734 VOID SetupEjectionTransferPacket(TRANSFER_PACKET *Pkt, BOOLEAN PreventMediaRemoval, PKEVENT SyncEventPtr, PIRP OriginalIrp); 1735 VOID SetupModeSenseTransferPacket(TRANSFER_PACKET *Pkt, PKEVENT SyncEventPtr, PVOID ModeSenseBuffer, UCHAR ModeSenseBufferLen, UCHAR PageMode, UCHAR SubPage, PIRP OriginalIrp, UCHAR PageControl); 1736 VOID SetupModeSelectTransferPacket(TRANSFER_PACKET *Pkt, PKEVENT SyncEventPtr, PVOID ModeSelectBuffer, UCHAR ModeSelectBufferLen, BOOLEAN SavePages, PIRP OriginalIrp); 1737 VOID SetupDriveCapacityTransferPacket(TRANSFER_PACKET *Pkt, PVOID ReadCapacityBuffer, ULONG ReadCapacityBufferLen, PKEVENT SyncEventPtr, PIRP OriginalIrp, BOOLEAN Use16ByteCdb); 1738 PMDL BuildDeviceInputMdl(PVOID Buffer, ULONG BufferLen); 1739 PMDL ClasspBuildDeviceMdl(PVOID Buffer, ULONG BufferLen, BOOLEAN WriteToDevice); 1740 VOID FreeDeviceInputMdl(PMDL Mdl); 1741 VOID ClasspFreeDeviceMdl(PMDL Mdl); 1742 NTSTATUS InitializeTransferPackets(PDEVICE_OBJECT Fdo); 1743 VOID DestroyAllTransferPackets(PDEVICE_OBJECT Fdo); 1744 VOID InterpretCapacityData(PDEVICE_OBJECT Fdo, PREAD_CAPACITY_DATA_EX ReadCapacityData); 1745 IO_WORKITEM_ROUTINE_EX CleanupTransferPacketToWorkingSetSizeWorker; 1746 VOID CleanupTransferPacketToWorkingSetSize(_In_ PDEVICE_OBJECT Fdo, _In_ BOOLEAN LimitNumPktToDelete, _In_ ULONG Node); 1747 1748 _IRQL_requires_max_(APC_LEVEL) 1749 _IRQL_requires_min_(PASSIVE_LEVEL) 1750 _IRQL_requires_same_ 1751 VOID 1752 ClasspSetupPopulateTokenTransferPacket( 1753 _In_ __drv_aliasesMem POFFLOAD_READ_CONTEXT OffloadReadContext, 1754 _In_ PTRANSFER_PACKET Pkt, 1755 _In_ ULONG Length, 1756 _In_reads_bytes_(Length) PUCHAR PopulateTokenBuffer, 1757 _In_ PIRP OriginalIrp, 1758 _In_ ULONG ListIdentifier 1759 ); 1760 1761 _IRQL_requires_max_(APC_LEVEL) 1762 _IRQL_requires_min_(PASSIVE_LEVEL) 1763 _IRQL_requires_same_ 1764 VOID 1765 ClasspSetupReceivePopulateTokenInformationTransferPacket( 1766 _In_ POFFLOAD_READ_CONTEXT OffloadReadContext, 1767 _In_ PTRANSFER_PACKET Pkt, 1768 _In_ ULONG Length, 1769 _In_reads_bytes_(Length) PUCHAR ReceivePopulateTokenInformationBuffer, 1770 _In_ PIRP OriginalIrp, 1771 _In_ ULONG ListIdentifier 1772 ); 1773 1774 _IRQL_requires_max_(APC_LEVEL) 1775 _IRQL_requires_min_(PASSIVE_LEVEL) 1776 _IRQL_requires_same_ 1777 VOID 1778 ClasspSetupWriteUsingTokenTransferPacket( 1779 _In_ __drv_aliasesMem POFFLOAD_WRITE_CONTEXT OffloadWriteContext, 1780 _In_ PTRANSFER_PACKET Pkt, 1781 _In_ ULONG Length, 1782 _In_reads_bytes_(Length) PUCHAR WriteUsingTokenBuffer, 1783 _In_ PIRP OriginalIrp, 1784 _In_ ULONG ListIdentifier 1785 ); 1786 1787 _IRQL_requires_max_(APC_LEVEL) 1788 _IRQL_requires_min_(PASSIVE_LEVEL) 1789 _IRQL_requires_same_ 1790 VOID 1791 ClasspSetupReceiveWriteUsingTokenInformationTransferPacket( 1792 _In_ POFFLOAD_WRITE_CONTEXT OffloadWriteContext, 1793 _In_ PTRANSFER_PACKET Pkt, 1794 _In_ ULONG Length, 1795 _In_reads_bytes_(Length) PUCHAR ReceiveWriteUsingTokenInformationBuffer, 1796 _In_ PIRP OriginalIrp, 1797 _In_ ULONG ListIdentifier 1798 ); 1799 1800 ULONG ClasspModeSense( 1801 _In_ PDEVICE_OBJECT Fdo, 1802 _In_reads_bytes_(Length) PCHAR ModeSenseBuffer, 1803 _In_ ULONG Length, 1804 _In_ UCHAR PageMode, 1805 _In_ UCHAR PageControl 1806 ); 1807 1808 NTSTATUS 1809 ClasspModeSelect( 1810 _In_ PDEVICE_OBJECT Fdo, 1811 _In_reads_bytes_(Length) PCHAR ModeSelectBuffer, 1812 _In_ ULONG Length, 1813 _In_ BOOLEAN SavePages 1814 ); 1815 1816 NTSTATUS ClasspWriteCacheProperty( 1817 _In_ PDEVICE_OBJECT DeviceObject, 1818 _In_ PIRP Irp, 1819 _Inout_ PSCSI_REQUEST_BLOCK Srb 1820 ); 1821 1822 NTSTATUS ClasspAccessAlignmentProperty( 1823 _In_ PDEVICE_OBJECT DeviceObject, 1824 _In_ PIRP Irp, 1825 _Inout_ PSCSI_REQUEST_BLOCK Srb 1826 ); 1827 1828 NTSTATUS ClasspDeviceSeekPenaltyProperty( 1829 _In_ PDEVICE_OBJECT DeviceObject, 1830 _In_ PIRP Irp, 1831 _Inout_ PSCSI_REQUEST_BLOCK Srb 1832 ); 1833 1834 NTSTATUS ClasspDeviceGetLBProvisioningVPDPage( 1835 _In_ PDEVICE_OBJECT DeviceObject, 1836 _Inout_opt_ PSCSI_REQUEST_BLOCK Srb 1837 ); 1838 1839 NTSTATUS ClasspDeviceGetBlockDeviceCharacteristicsVPDPage( 1840 _In_ PFUNCTIONAL_DEVICE_EXTENSION fdoExtension, 1841 _In_ PSCSI_REQUEST_BLOCK Srb 1842 ); 1843 1844 NTSTATUS ClasspDeviceGetBlockLimitsVPDPage( 1845 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 1846 _Inout_bytecount_(SrbSize) PSCSI_REQUEST_BLOCK Srb, 1847 _In_ ULONG SrbSize, 1848 _Out_ PCLASS_VPD_B0_DATA BlockLimitsData 1849 ); 1850 1851 NTSTATUS ClasspDeviceTrimProperty( 1852 _In_ PDEVICE_OBJECT DeviceObject, 1853 _In_ PIRP Irp, 1854 _Inout_ PSCSI_REQUEST_BLOCK Srb 1855 ); 1856 1857 NTSTATUS ClasspDeviceLBProvisioningProperty( 1858 _In_ PDEVICE_OBJECT DeviceObject, 1859 _Inout_ PIRP Irp, 1860 _Inout_ PSCSI_REQUEST_BLOCK Srb 1861 ); 1862 1863 NTSTATUS ClasspDeviceTrimProcess( 1864 _In_ PDEVICE_OBJECT DeviceObject, 1865 _In_ PIRP Irp, 1866 _In_ PGUID ActivityId, 1867 _Inout_ PSCSI_REQUEST_BLOCK Srb 1868 ); 1869 1870 NTSTATUS ClasspDeviceGetLBAStatus( 1871 _In_ PDEVICE_OBJECT DeviceObject, 1872 _Inout_ PIRP Irp, 1873 _Inout_ PSCSI_REQUEST_BLOCK Srb 1874 ); 1875 1876 NTSTATUS ClasspDeviceGetLBAStatusWorker( 1877 _In_ PDEVICE_OBJECT DeviceObject, 1878 _In_ PCLASS_VPD_B0_DATA BlockLimitsData, 1879 _In_ ULONGLONG StartingOffset, 1880 _In_ ULONGLONG LengthInBytes, 1881 _Out_ PDEVICE_MANAGE_DATA_SET_ATTRIBUTES_OUTPUT DsmOutput, 1882 _Inout_ PULONG DsmOutputLength, 1883 _Inout_ PSCSI_REQUEST_BLOCK Srb, 1884 _In_ BOOLEAN ConsolidateableBlocksOnly, 1885 _In_ ULONG OutputVersion, 1886 _Out_ PBOOLEAN BlockLimitsDataMayHaveChanged 1887 ); 1888 1889 VOID ClassQueueThresholdEventWorker( 1890 _In_ PDEVICE_OBJECT DeviceObject 1891 ); 1892 1893 VOID ClassQueueResourceExhaustionEventWorker( 1894 _In_ PDEVICE_OBJECT DeviceObject 1895 ); 1896 1897 VOID ClassQueueCapacityChangedEventWorker( 1898 _In_ PDEVICE_OBJECT DeviceObject 1899 ); 1900 1901 VOID ClassQueueProvisioningTypeChangedEventWorker( 1902 _In_ PDEVICE_OBJECT DeviceObject 1903 ); 1904 1905 IO_WORKITEM_ROUTINE ClasspLogIOEventWithContext; 1906 1907 VOID 1908 ClasspQueueLogIOEventWithContextWorker( 1909 _In_ PDEVICE_OBJECT DeviceObject, 1910 _In_ ULONG SenseBufferSize, 1911 _In_ PVOID SenseData, 1912 _In_ UCHAR SrbStatus, 1913 _In_ UCHAR ScsiStatus, 1914 _In_ ULONG ErrorCode, 1915 _In_ ULONG CdbLength, 1916 _In_opt_ PCDB Cdb, 1917 _In_opt_ PTRANSFER_PACKET Pkt 1918 ); 1919 1920 VOID 1921 ClasspZeroQERR( 1922 _In_ PDEVICE_OBJECT DeviceObject 1923 ); 1924 1925 1926 _IRQL_requires_max_(PASSIVE_LEVEL) 1927 NTSTATUS 1928 ClasspGetMaximumTokenListIdentifier( 1929 _In_ PDEVICE_OBJECT DeviceObject, 1930 _In_z_ PWSTR RegistryPath, 1931 _Out_ PULONG MaximumListIdentifier 1932 ); 1933 1934 _IRQL_requires_max_(PASSIVE_LEVEL) 1935 NTSTATUS 1936 ClasspGetCopyOffloadMaxDuration( 1937 _In_ PDEVICE_OBJECT DeviceObject, 1938 _In_z_ PWSTR RegistryPath, 1939 _Out_ PULONG MaxDuration 1940 ); 1941 1942 _IRQL_requires_max_(APC_LEVEL) 1943 _IRQL_requires_min_(PASSIVE_LEVEL) 1944 _IRQL_requires_same_ 1945 NTSTATUS 1946 ClasspDeviceCopyOffloadProperty( 1947 _In_ PDEVICE_OBJECT DeviceObject, 1948 _Inout_ PIRP Irp, 1949 _Inout_ PSCSI_REQUEST_BLOCK Srb 1950 ); 1951 1952 _IRQL_requires_max_(APC_LEVEL) 1953 _IRQL_requires_min_(PASSIVE_LEVEL) 1954 _IRQL_requires_same_ 1955 NTSTATUS 1956 ClasspValidateOffloadSupported( 1957 _In_ PDEVICE_OBJECT DeviceObject, 1958 _In_ PIRP Irp 1959 ); 1960 1961 _IRQL_requires_max_(APC_LEVEL) 1962 _IRQL_requires_min_(PASSIVE_LEVEL) 1963 _IRQL_requires_same_ 1964 NTSTATUS 1965 ClasspValidateOffloadInputParameters( 1966 _In_ PDEVICE_OBJECT DeviceObject, 1967 _In_ PIRP Irp 1968 ); 1969 1970 _IRQL_requires_same_ 1971 NTSTATUS 1972 ClasspGetTokenOperationCommandBufferLength( 1973 _In_ PDEVICE_OBJECT Fdo, 1974 _In_ ULONG ServiceAction, 1975 _Inout_ PULONG CommandBufferLength, 1976 _Out_opt_ PULONG TokenOperationBufferLength, 1977 _Out_opt_ PULONG ReceiveTokenInformationBufferLength 1978 ); 1979 1980 _IRQL_requires_same_ 1981 NTSTATUS 1982 ClasspGetTokenOperationDescriptorLimits( 1983 _In_ PDEVICE_OBJECT Fdo, 1984 _In_ ULONG ServiceAction, 1985 _In_ ULONG MaxParameterBufferLength, 1986 _Out_ PULONG MaxBlockDescriptorsCount, 1987 _Out_ PULONGLONG MaxBlockDescriptorsLength 1988 ); 1989 1990 _IRQL_requires_max_(APC_LEVEL) 1991 _IRQL_requires_min_(PASSIVE_LEVEL) 1992 _IRQL_requires_same_ 1993 VOID 1994 ClasspConvertDataSetRangeToBlockDescr( 1995 _In_ PDEVICE_OBJECT Fdo, 1996 _In_ PVOID BlockDescr, 1997 _Inout_ PULONG CurrentBlockDescrIndex, 1998 _In_ ULONG MaxBlockDescrCount, 1999 _Inout_ PULONG CurrentLbaCount, 2000 _In_ ULONGLONG MaxLbaCount, 2001 _Inout_ PDEVICE_DATA_SET_RANGE DataSetRange, 2002 _Inout_ PULONGLONG TotalSectorsProcessed 2003 ); 2004 2005 NTSTATUS 2006 ClasspDeviceMediaTypeProperty( 2007 _In_ PDEVICE_OBJECT DeviceObject, 2008 _Inout_ PIRP Irp, 2009 _Inout_ PSCSI_REQUEST_BLOCK Srb 2010 ); 2011 2012 2013 _IRQL_requires_same_ 2014 PUCHAR 2015 ClasspBinaryToAscii( 2016 _In_reads_(Length) PUCHAR HexBuffer, 2017 _In_ ULONG Length, 2018 _Inout_ PULONG UpdateLength 2019 ); 2020 2021 FORCEINLINE 2022 BOOLEAN 2023 ClasspIsTokenOperationComplete( 2024 _In_ ULONG CurrentStatus 2025 ) 2026 { 2027 BOOLEAN operationCompleted = FALSE; 2028 2029 switch (CurrentStatus) { 2030 case OPERATION_COMPLETED_WITH_SUCCESS: 2031 case OPERATION_COMPLETED_WITH_ERROR: 2032 case OPERATION_COMPLETED_WITH_RESIDUAL_DATA: 2033 case OPERATION_TERMINATED: { 2034 2035 operationCompleted = TRUE; 2036 } 2037 } 2038 2039 return operationCompleted; 2040 } 2041 2042 FORCEINLINE 2043 BOOLEAN 2044 ClasspIsTokenOperation( 2045 _In_ PCDB Cdb 2046 ) 2047 { 2048 BOOLEAN tokenOperation = FALSE; 2049 2050 if (Cdb) { 2051 ULONG opCode = Cdb->AsByte[0]; 2052 ULONG serviceAction = Cdb->AsByte[1]; 2053 2054 if ((opCode == SCSIOP_POPULATE_TOKEN && serviceAction == SERVICE_ACTION_POPULATE_TOKEN) || 2055 (opCode == SCSIOP_WRITE_USING_TOKEN && serviceAction == SERVICE_ACTION_WRITE_USING_TOKEN)) { 2056 2057 tokenOperation = TRUE; 2058 } 2059 } 2060 2061 return tokenOperation; 2062 } 2063 2064 FORCEINLINE 2065 BOOLEAN 2066 ClasspIsReceiveTokenInformation( 2067 _In_ PCDB Cdb 2068 ) 2069 { 2070 BOOLEAN receiveTokenInformation = FALSE; 2071 2072 if (Cdb) { 2073 ULONG opCode = Cdb->AsByte[0]; 2074 ULONG serviceAction = Cdb->AsByte[1]; 2075 2076 if (opCode == SCSIOP_RECEIVE_ROD_TOKEN_INFORMATION && serviceAction == SERVICE_ACTION_RECEIVE_TOKEN_INFORMATION) { 2077 2078 receiveTokenInformation = TRUE; 2079 } 2080 } 2081 2082 return receiveTokenInformation; 2083 } 2084 2085 FORCEINLINE 2086 BOOLEAN 2087 ClasspIsOffloadDataTransferCommand( 2088 _In_ PCDB Cdb 2089 ) 2090 { 2091 BOOLEAN offloadCommand = (ClasspIsTokenOperation(Cdb) || ClasspIsReceiveTokenInformation(Cdb)) ? TRUE : FALSE; 2092 2093 return offloadCommand; 2094 } 2095 2096 extern LIST_ENTRY AllFdosList; 2097 2098 2099 VOID 2100 ClasspInitializeIdleTimer( 2101 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 2102 ); 2103 2104 NTSTATUS 2105 ClasspIsPortable( 2106 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 2107 _Out_ PBOOLEAN IsPortable 2108 ); 2109 2110 VOID 2111 ClasspGetInquiryVpdSupportInfo( 2112 _Inout_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 2113 ); 2114 2115 NTSTATUS 2116 ClasspGetLBProvisioningInfo( 2117 _Inout_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 2118 ); 2119 2120 2121 _IRQL_requires_(PASSIVE_LEVEL) 2122 _IRQL_requires_same_ 2123 NTSTATUS 2124 ClassDetermineTokenOperationCommandSupport( 2125 _In_ PDEVICE_OBJECT DeviceObject 2126 ); 2127 2128 _IRQL_requires_same_ 2129 NTSTATUS 2130 ClasspGetBlockDeviceTokenLimitsInfo( 2131 _Inout_ PDEVICE_OBJECT DeviceObject 2132 ); 2133 2134 _IRQL_requires_max_(APC_LEVEL) 2135 _IRQL_requires_min_(PASSIVE_LEVEL) 2136 _IRQL_requires_same_ 2137 NTSTATUS 2138 ClassDeviceProcessOffloadRead( 2139 _In_ PDEVICE_OBJECT DeviceObject, 2140 _In_ PIRP Irp, 2141 _Inout_ PSCSI_REQUEST_BLOCK Srb 2142 ); 2143 2144 _IRQL_requires_max_(APC_LEVEL) 2145 _IRQL_requires_min_(PASSIVE_LEVEL) 2146 _IRQL_requires_same_ 2147 NTSTATUS 2148 ClassDeviceProcessOffloadWrite( 2149 _In_ PDEVICE_OBJECT DeviceObject, 2150 _In_ PIRP Irp, 2151 _Inout_ PSCSI_REQUEST_BLOCK Srb 2152 ); 2153 2154 _IRQL_requires_max_(APC_LEVEL) 2155 _IRQL_requires_min_(PASSIVE_LEVEL) 2156 _IRQL_requires_same_ 2157 NTSTATUS 2158 ClasspServicePopulateTokenTransferRequest( 2159 _In_ PDEVICE_OBJECT Fdo, 2160 _In_ PIRP Irp 2161 ); 2162 2163 _IRQL_requires_same_ 2164 VOID 2165 ClasspReceivePopulateTokenInformation( 2166 _In_ POFFLOAD_READ_CONTEXT OffloadReadContext 2167 ); 2168 2169 _IRQL_requires_max_(APC_LEVEL) 2170 _IRQL_requires_min_(PASSIVE_LEVEL) 2171 _IRQL_requires_same_ 2172 NTSTATUS 2173 ClasspServiceWriteUsingTokenTransferRequest( 2174 _In_ PDEVICE_OBJECT Fdo, 2175 _In_ PIRP Irp 2176 ); 2177 2178 _IRQL_requires_same_ 2179 VOID 2180 ClasspReceiveWriteUsingTokenInformation( 2181 _In_ POFFLOAD_WRITE_CONTEXT OffloadWriteContext 2182 ); 2183 2184 VOID 2185 ClasspCompleteOffloadRequest( 2186 _In_ PDEVICE_OBJECT DeviceObject, 2187 _In_ PIRP Irp, 2188 _In_ NTSTATUS CompletionStatus 2189 ); 2190 2191 VOID 2192 ClasspCleanupOffloadReadContext( 2193 _In_ __drv_freesMem(mem) POFFLOAD_READ_CONTEXT OffloadReadContext 2194 ); 2195 2196 VOID 2197 ClasspCompleteOffloadRead( 2198 _In_ POFFLOAD_READ_CONTEXT OffloadReadContext, 2199 _In_ NTSTATUS CompletionStatus 2200 ); 2201 2202 // PCONTINUATION_ROUTINE 2203 VOID 2204 ClasspPopulateTokenTransferPacketDone( 2205 _In_ PVOID Context 2206 ); 2207 2208 // PCONTINUATION_ROUTINE 2209 VOID 2210 ClasspReceivePopulateTokenInformationTransferPacketDone( 2211 _In_ PVOID Context 2212 ); 2213 2214 VOID 2215 ClasspContinueOffloadWrite( 2216 _In_ __drv_aliasesMem POFFLOAD_WRITE_CONTEXT OffloadWriteContext 2217 ); 2218 2219 VOID 2220 ClasspCleanupOffloadWriteContext( 2221 _In_ __drv_freesMem(mem) POFFLOAD_WRITE_CONTEXT OffloadWriteContext 2222 ); 2223 2224 VOID 2225 ClasspCompleteOffloadWrite( 2226 _In_ __drv_freesMem(Mem) POFFLOAD_WRITE_CONTEXT OffloadWriteContext, 2227 _In_ NTSTATUS CompletionCausingStatus 2228 ); 2229 2230 VOID 2231 ClasspReceiveWriteUsingTokenInformationDone( 2232 _In_ POFFLOAD_WRITE_CONTEXT OffloadWriteContext, 2233 _In_ NTSTATUS CompletionCausingStatus 2234 ); 2235 2236 VOID 2237 ClasspWriteUsingTokenTransferPacketDone( 2238 _In_ PVOID Context 2239 ); 2240 2241 VOID 2242 ClasspReceiveWriteUsingTokenInformationTransferPacketDone( 2243 _In_ POFFLOAD_WRITE_CONTEXT OffloadWriteContext 2244 ); 2245 2246 NTSTATUS 2247 ClasspRefreshFunctionSupportInfo( 2248 _Inout_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 2249 _In_ BOOLEAN ForceQuery 2250 ); 2251 2252 NTSTATUS 2253 ClasspBlockLimitsDataSnapshot( 2254 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 2255 _In_ BOOLEAN ForceQuery, 2256 _Out_ PCLASS_VPD_B0_DATA BlockLimitsData, 2257 _Out_ PULONG GenerationCount 2258 ); 2259 2260 NTSTATUS 2261 InterpretReadCapacity16Data ( 2262 _Inout_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 2263 _In_ PREAD_CAPACITY16_DATA ReadCapacity16Data 2264 ); 2265 2266 NTSTATUS 2267 ClassReadCapacity16 ( 2268 _Inout_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 2269 _Inout_ PSCSI_REQUEST_BLOCK Srb 2270 ); 2271 2272 NTSTATUS 2273 ClassDeviceGetLBProvisioningResources( 2274 _In_ PDEVICE_OBJECT DeviceObject, 2275 _Inout_ PIRP Irp, 2276 _Inout_ PSCSI_REQUEST_BLOCK Srb 2277 ); 2278 2279 _IRQL_requires_same_ 2280 NTSTATUS 2281 ClasspStorageEventNotification( 2282 _In_ PDEVICE_OBJECT DeviceObject, 2283 _In_ PIRP Irp 2284 ); 2285 2286 _IRQL_requires_max_(PASSIVE_LEVEL) 2287 NTSTATUS 2288 ClasspPowerActivateDevice( 2289 _In_ PDEVICE_OBJECT DeviceObject 2290 ); 2291 2292 _IRQL_requires_max_(PASSIVE_LEVEL) 2293 NTSTATUS 2294 ClasspPowerIdleDevice( 2295 _In_ PDEVICE_OBJECT DeviceObject 2296 ); 2297 2298 IO_WORKITEM_ROUTINE ClassLogThresholdEvent; 2299 2300 NTSTATUS 2301 ClasspLogSystemEventWithDeviceNumber( 2302 _In_ PDEVICE_OBJECT DeviceObject, 2303 _In_ NTSTATUS IoErrorCode 2304 ); 2305 2306 IO_WORKITEM_ROUTINE ClassLogResourceExhaustionEvent; 2307 2308 NTSTATUS 2309 ClasspEnqueueIdleRequest( 2310 PDEVICE_OBJECT DeviceObject, 2311 PIRP Irp 2312 ); 2313 2314 VOID 2315 ClasspCompleteIdleRequest( 2316 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 2317 ); 2318 2319 NTSTATUS 2320 ClasspPriorityHint( 2321 PDEVICE_OBJECT DeviceObject, 2322 PIRP Irp 2323 ); 2324 2325 VOID 2326 HistoryInitializeRetryLogs( 2327 _Out_ PSRB_HISTORY History, 2328 ULONG HistoryCount 2329 ); 2330 #define HISTORYINITIALIZERETRYLOGS(_packet) \ 2331 { \ 2332 if (_packet->RetryHistory != NULL) \ 2333 { \ 2334 HistoryInitializeRetryLogs( \ 2335 _packet->RetryHistory, \ 2336 _packet->RetryHistory->TotalHistoryCount \ 2337 ); \ 2338 } \ 2339 } 2340 2341 VOID 2342 HistoryLogSendPacket( 2343 TRANSFER_PACKET *Pkt 2344 ); 2345 #define HISTORYLOGSENDPACKET(_packet) \ 2346 { \ 2347 if (_packet->RetryHistory != NULL) { \ 2348 HistoryLogSendPacket(_packet); \ 2349 } \ 2350 } 2351 2352 VOID 2353 HistoryLogReturnedPacket( 2354 TRANSFER_PACKET *Pkt 2355 ); 2356 2357 #define HISTORYLOGRETURNEDPACKET(_packet) \ 2358 { \ 2359 if (_packet->RetryHistory != NULL) { \ 2360 HistoryLogReturnedPacket(_packet); \ 2361 } \ 2362 } 2363 2364 BOOLEAN 2365 InterpretSenseInfoWithoutHistory( 2366 _In_ PDEVICE_OBJECT Fdo, 2367 _In_opt_ PIRP OriginalRequest, 2368 _In_ PSCSI_REQUEST_BLOCK Srb, 2369 UCHAR MajorFunctionCode, 2370 ULONG IoDeviceCode, 2371 ULONG PreviousRetryCount, 2372 _Out_ NTSTATUS * Status, 2373 _Out_opt_ _Deref_out_range_(0,MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS) 2374 LONGLONG * RetryIn100nsUnits 2375 ); 2376 2377 BOOLEAN 2378 ClasspMyStringMatches( 2379 _In_opt_z_ PCHAR StringToMatch, 2380 _In_z_ PCHAR TargetString 2381 ); 2382 2383 2384 2385 #define TRACKING_FORWARD_PROGRESS_PATH1 (0x00000001) 2386 #define TRACKING_FORWARD_PROGRESS_PATH2 (0x00000002) 2387 #define TRACKING_FORWARD_PROGRESS_PATH3 (0x00000004) 2388 2389 2390 VOID 2391 ClasspInitializeRemoveTracking( 2392 _In_ PDEVICE_OBJECT DeviceObject 2393 ); 2394 2395 VOID 2396 ClasspUninitializeRemoveTracking( 2397 _In_ PDEVICE_OBJECT DeviceObject 2398 ); 2399 2400 RTL_GENERIC_COMPARE_ROUTINE RemoveTrackingCompareRoutine; 2401 2402 RTL_GENERIC_ALLOCATE_ROUTINE RemoveTrackingAllocateRoutine; 2403 2404 RTL_GENERIC_FREE_ROUTINE RemoveTrackingFreeRoutine; 2405 2406 #if (NTDDI_VERSION >= NTDDI_WIN8) 2407 2408 typedef PVOID 2409 (*PSRB_ALLOCATE_ROUTINE) ( 2410 _In_ CLONG ByteSize 2411 ); 2412 2413 PVOID 2414 DefaultStorageRequestBlockAllocateRoutine( 2415 _In_ CLONG ByteSize 2416 ); 2417 2418 2419 NTSTATUS 2420 CreateStorageRequestBlock( 2421 _Inout_ PSTORAGE_REQUEST_BLOCK *Srb, 2422 _In_ USHORT AddressType, 2423 _In_opt_ PSRB_ALLOCATE_ROUTINE AllocateRoutine, 2424 _Inout_opt_ ULONG *ByteSize, 2425 _In_ ULONG NumSrbExData, 2426 ... 2427 ); 2428 2429 NTSTATUS 2430 InitializeStorageRequestBlock( 2431 _Inout_bytecount_(ByteSize) PSTORAGE_REQUEST_BLOCK Srb, 2432 _In_ USHORT AddressType, 2433 _In_ ULONG ByteSize, 2434 _In_ ULONG NumSrbExData, 2435 ... 2436 ); 2437 2438 VOID 2439 ClasspConvertToScsiRequestBlock( 2440 _Out_ PSCSI_REQUEST_BLOCK Srb, 2441 _In_ PSTORAGE_REQUEST_BLOCK SrbEx 2442 ); 2443 2444 FORCEINLINE PCDB 2445 ClasspTransferPacketGetCdb( 2446 _In_ PTRANSFER_PACKET Pkt 2447 ) 2448 { 2449 return SrbGetCdb(Pkt->Srb); 2450 } 2451 2452 // 2453 // This inline function calculates number of retries already happened till now for known operation codes 2454 // and set the out parameter - TimesAlreadyRetried with the value, returns True 2455 // 2456 // For unknown operation codes this function will return false and will set TimesAlreadyRetried with zero 2457 // 2458 FORCEINLINE BOOLEAN 2459 ClasspTransferPacketGetNumberOfRetriesDone( 2460 _In_ PTRANSFER_PACKET Pkt, 2461 _In_ PCDB Cdb, 2462 _Out_ PULONG TimesAlreadyRetried 2463 ) 2464 { 2465 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Pkt->Fdo->DeviceExtension; 2466 PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData; 2467 2468 if (Cdb->MEDIA_REMOVAL.OperationCode == SCSIOP_MEDIUM_REMOVAL) 2469 { 2470 *TimesAlreadyRetried = NUM_LOCKMEDIAREMOVAL_RETRIES - Pkt->NumRetries; 2471 } 2472 else if ((Cdb->MODE_SENSE.OperationCode == SCSIOP_MODE_SENSE) || 2473 (Cdb->MODE_SENSE.OperationCode == SCSIOP_MODE_SENSE10)) 2474 { 2475 *TimesAlreadyRetried = NUM_MODESENSE_RETRIES - Pkt->NumRetries; 2476 } 2477 else if ((Cdb->CDB10.OperationCode == SCSIOP_READ_CAPACITY) || 2478 (Cdb->CDB16.OperationCode == SCSIOP_READ_CAPACITY16)) 2479 { 2480 *TimesAlreadyRetried = NUM_DRIVECAPACITY_RETRIES - Pkt->NumRetries; 2481 } 2482 else if (IS_SCSIOP_READWRITE(Cdb->CDB10.OperationCode)) 2483 { 2484 *TimesAlreadyRetried = fdoData->MaxNumberOfIoRetries - Pkt->NumRetries; 2485 } 2486 else if (Cdb->TOKEN_OPERATION.OperationCode == SCSIOP_POPULATE_TOKEN && 2487 Cdb->TOKEN_OPERATION.ServiceAction == SERVICE_ACTION_POPULATE_TOKEN) 2488 { 2489 *TimesAlreadyRetried = NUM_POPULATE_TOKEN_RETRIES - Pkt->NumRetries; 2490 } 2491 else if (Cdb->TOKEN_OPERATION.OperationCode == SCSIOP_WRITE_USING_TOKEN && 2492 Cdb->TOKEN_OPERATION.ServiceAction == SERVICE_ACTION_WRITE_USING_TOKEN) 2493 { 2494 *TimesAlreadyRetried = NUM_WRITE_USING_TOKEN_RETRIES - Pkt->NumRetries; 2495 } 2496 else if (ClasspIsReceiveTokenInformation(Cdb)) 2497 { 2498 *TimesAlreadyRetried = NUM_RECEIVE_TOKEN_INFORMATION_RETRIES - Pkt->NumRetries; 2499 } 2500 2501 else 2502 { 2503 *TimesAlreadyRetried = 0; 2504 return FALSE; 2505 } 2506 2507 2508 return TRUE; 2509 } 2510 2511 2512 FORCEINLINE PVOID 2513 ClasspTransferPacketGetSenseInfoBuffer( 2514 _In_ PTRANSFER_PACKET Pkt 2515 ) 2516 { 2517 return SrbGetSenseInfoBuffer(Pkt->Srb); 2518 } 2519 2520 FORCEINLINE UCHAR 2521 ClasspTransferPacketGetSenseInfoBufferLength( 2522 _In_ PTRANSFER_PACKET Pkt 2523 ) 2524 { 2525 return SrbGetSenseInfoBufferLength(Pkt->Srb); 2526 } 2527 2528 2529 FORCEINLINE VOID 2530 ClasspSrbSetOriginalIrp( 2531 _In_ PSTORAGE_REQUEST_BLOCK_HEADER Srb, 2532 _In_ PIRP Irp 2533 ) 2534 { 2535 if (Srb->Function == SRB_FUNCTION_STORAGE_REQUEST_BLOCK) 2536 { 2537 ((PSTORAGE_REQUEST_BLOCK)Srb)->MiniportContext = (PVOID)Irp; 2538 } 2539 else 2540 { 2541 ((PSCSI_REQUEST_BLOCK)Srb)->SrbExtension = (PVOID)Irp; 2542 } 2543 } 2544 2545 FORCEINLINE 2546 BOOLEAN 2547 PORT_ALLOCATED_SENSE_EX( 2548 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 2549 _In_ PSTORAGE_REQUEST_BLOCK_HEADER Srb 2550 ) 2551 { 2552 return ((BOOLEAN)((TEST_FLAG(SrbGetSrbFlags(Srb), SRB_FLAGS_PORT_DRIVER_ALLOCSENSE) && 2553 TEST_FLAG(SrbGetSrbFlags(Srb), SRB_FLAGS_FREE_SENSE_BUFFER)) && 2554 (SrbGetSenseInfoBuffer(Srb) != FdoExtension->SenseData)) 2555 ); 2556 } 2557 2558 FORCEINLINE 2559 VOID 2560 FREE_PORT_ALLOCATED_SENSE_BUFFER_EX( 2561 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, 2562 _In_ PSTORAGE_REQUEST_BLOCK_HEADER Srb 2563 ) 2564 { 2565 NT_ASSERT(TEST_FLAG(SrbGetSrbFlags(Srb), SRB_FLAGS_PORT_DRIVER_ALLOCSENSE)); 2566 NT_ASSERT(TEST_FLAG(SrbGetSrbFlags(Srb), SRB_FLAGS_FREE_SENSE_BUFFER)); 2567 NT_ASSERT(SrbGetSenseInfoBuffer(Srb) != FdoExtension->SenseData); 2568 2569 ExFreePool(SrbGetSenseInfoBuffer(Srb)); 2570 SrbSetSenseInfoBuffer(Srb, FdoExtension->SenseData); 2571 SrbSetSenseInfoBufferLength(Srb, GET_FDO_EXTENSON_SENSE_DATA_LENGTH(FdoExtension)); 2572 SrbClearSrbFlags(Srb, SRB_FLAGS_FREE_SENSE_BUFFER); 2573 return; 2574 } 2575 2576 #endif //NTDDI_WIN8 2577 2578 BOOLEAN 2579 ClasspFailurePredictionPeriodMissed( 2580 _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension 2581 ); 2582 2583 FORCEINLINE 2584 ULONG 2585 ClasspGetMaxUsableBufferLengthFromOffset( 2586 _In_ PVOID BaseAddress, 2587 _In_ ULONG OffsetInBytes, 2588 _In_ ULONG BaseStructureSizeInBytes 2589 ) 2590 /*++ 2591 2592 Routine Description: 2593 2594 This routine returns the maximum size of a buffer that starts at a given offset, 2595 based on the size of the containing structure. 2596 2597 Arguments: 2598 2599 BaseAddress - The base address of the structure. The offset is computed relative to this. 2600 2601 OffsetInBytes - (BaseAddress + OffsetInBytes) points to the beginning of the buffer. 2602 2603 BaseStructureSizeInBytes - The size of the structure which contains the buffer. 2604 2605 Return Value: 2606 2607 max(BaseStructureSizeInBytes - OffsetInBytes, 0). If any operations wrap around, 2608 the return value is 0. 2609 2610 --*/ 2611 2612 { 2613 2614 ULONG_PTR offsetAddress = ((ULONG_PTR)BaseAddress + OffsetInBytes); 2615 2616 if (offsetAddress < (ULONG_PTR)BaseAddress) { 2617 // 2618 // This means BaseAddress + OffsetInBytes > ULONG_PTR_MAX. 2619 // 2620 return 0; 2621 } 2622 2623 if (OffsetInBytes > BaseStructureSizeInBytes) { 2624 return 0; 2625 } 2626 2627 return BaseStructureSizeInBytes - OffsetInBytes; 2628 } 2629 2630 2631 BOOLEAN 2632 ClasspIsThinProvisioningError ( 2633 _In_ PSCSI_REQUEST_BLOCK _Srb 2634 ); 2635 2636 FORCEINLINE 2637 BOOLEAN 2638 ClasspLowerLayerNotSupport ( 2639 _In_ NTSTATUS Status 2640 ) 2641 { 2642 return ((Status == STATUS_NOT_SUPPORTED) || 2643 (Status == STATUS_NOT_IMPLEMENTED) || 2644 (Status == STATUS_INVALID_DEVICE_REQUEST) || 2645 (Status == STATUS_INVALID_PARAMETER_1)); 2646 } 2647 2648 #if defined(__REACTOS__) && (NTDDI_VERSION >= NTDDI_WINBLUE) 2649 FORCEINLINE 2650 BOOLEAN 2651 ClasspSrbTimeOutStatus ( 2652 _In_ PSTORAGE_REQUEST_BLOCK_HEADER Srb 2653 ) 2654 { 2655 UCHAR srbStatus = SrbGetSrbStatus(Srb); 2656 return ((srbStatus == SRB_STATUS_BUS_RESET) || 2657 (srbStatus == SRB_STATUS_TIMEOUT) || 2658 (srbStatus == SRB_STATUS_COMMAND_TIMEOUT) || 2659 (srbStatus == SRB_STATUS_ABORTED)); 2660 } 2661 #endif 2662 2663 NTSTATUS 2664 ClassDeviceHwFirmwareGetInfoProcess( 2665 _In_ PDEVICE_OBJECT DeviceObject, 2666 _Inout_ PIRP Irp 2667 ); 2668 2669 NTSTATUS 2670 ClassDeviceHwFirmwareDownloadProcess( 2671 _In_ PDEVICE_OBJECT DeviceObject, 2672 _Inout_ PIRP Irp, 2673 _Inout_ PSCSI_REQUEST_BLOCK Srb 2674 ); 2675 2676 NTSTATUS 2677 ClassDeviceHwFirmwareActivateProcess( 2678 _In_ PDEVICE_OBJECT DeviceObject, 2679 _Inout_ PIRP Irp, 2680 _Inout_ PSCSI_REQUEST_BLOCK Srb 2681 ); 2682 2683