Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

905 lines
22 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1991 - 1999
  3. Module Name:
  4. classp.h
  5. Abstract:
  6. Private header file for classpnp.sys modules. This contains private
  7. structure and function declarations as well as constant values which do
  8. not need to be exported.
  9. Author:
  10. Environment:
  11. kernel mode only
  12. Notes:
  13. Revision History:
  14. --*/
  15. #include <stddef.h>
  16. #include <stdarg.h>
  17. #include <ntddk.h>
  18. #include <scsi.h>
  19. #include <wmidata.h>
  20. #include <classpnp.h>
  21. #if CLASS_INIT_GUID
  22. #include <initguid.h>
  23. #endif
  24. #include <mountdev.h>
  25. #include <ioevent.h>
  26. extern CLASSPNP_SCAN_FOR_SPECIAL_INFO ClassBadItems[];
  27. extern GUID ClassGuidQueryRegInfoEx;
  28. #define CLASSP_REG_SUBKEY_NAME (L"Classpnp")
  29. #define CLASSP_REG_HACK_VALUE_NAME (L"HackMask")
  30. #define CLASSP_REG_MMC_DETECTION_VALUE_NAME (L"MMCDetectionState")
  31. #define CLASSP_REG_WRITE_CACHE_VALUE_NAME (L"WriteCacheEnableOverride")
  32. #define CLASSP_REG_PERF_RESTORE_VALUE_NAME (L"RestorePerfAtCount")
  33. #define CLASSP_REG_REMOVAL_POLICY_VALUE_NAME (L"UserRemovalPolicy")
  34. #define CLASS_PERF_RESTORE_MINIMUM (0x10)
  35. #define CLASS_ERROR_LEVEL_1 (0x4)
  36. #define CLASS_ERROR_LEVEL_2 (0x8)
  37. #define FDO_HACK_CANNOT_LOCK_MEDIA (0x00000001)
  38. #define FDO_HACK_GESN_IS_BAD (0x00000002)
  39. #define FDO_HACK_NO_SYNC_CACHE (0x00000004)
  40. #define FDO_HACK_VALID_FLAGS (0x00000007)
  41. #define FDO_HACK_INVALID_FLAGS (~FDO_HACK_VALID_FLAGS)
  42. /*
  43. * Lots of retries of synchronized SCSI commands that devices may not
  44. * even support really slows down the system (especially while booting).
  45. * (Even GetDriveCapacity may be failed on purpose if an external disk is powered off).
  46. * If a disk cannot return a small initialization buffer at startup
  47. * in two attempts (with delay interval) then we cannot expect it to return
  48. * data consistently with four retries.
  49. * So don't set the retry counts as high here as for data SRBs.
  50. *
  51. * If we find that these requests are failing consecutively,
  52. * despite the retry interval, on otherwise reliable media,
  53. * then we should either increase the retry interval for
  54. * that failure or (by all means) increase these retry counts as appropriate.
  55. */
  56. #define NUM_LOCKMEDIAREMOVAL_RETRIES 1
  57. #define NUM_MODESENSE_RETRIES 1
  58. #define NUM_DRIVECAPACITY_RETRIES 1
  59. #define CLASS_FILE_OBJECT_EXTENSION_KEY 'eteP'
  60. #define CLASSP_VOLUME_VERIFY_CHECKED 0x34
  61. #define CLASS_TAG_PRIVATE_DATA 'CPcS'
  62. #define CLASS_TAG_PRIVATE_DATA_FDO 'FPcS'
  63. #define CLASS_TAG_PRIVATE_DATA_PDO 'PPcS'
  64. typedef struct _MEDIA_CHANGE_DETECTION_INFO {
  65. //
  66. // Mutex to synchronize enable/disable requests and media state changes
  67. //
  68. KMUTEX MediaChangeMutex;
  69. //
  70. // The current state of the media (present, not present, unknown)
  71. // protected by MediaChangeSynchronizationEvent
  72. //
  73. MEDIA_CHANGE_DETECTION_STATE MediaChangeDetectionState;
  74. //
  75. // This is a count of how many time MCD has been disabled. if it is
  76. // set to zero, then we'll poll the device for MCN events with the
  77. // then-current method (ie. TEST UNIT READY or GESN). this is
  78. // protected by MediaChangeMutex
  79. //
  80. LONG MediaChangeDetectionDisableCount;
  81. //
  82. // The timer value to support media change events. This is a countdown
  83. // value used to determine when to poll the device for a media change.
  84. // The max value for the timer is 255 seconds. This is not protected
  85. // by an event -- simply InterlockedExchanged() as needed.
  86. //
  87. LONG MediaChangeCountDown;
  88. //
  89. // recent changes allowed instant retries of the MCN irp. Since this
  90. // could cause an infinite loop, keep a count of how many times we've
  91. // retried immediately so that we can catch if the count exceeds an
  92. // arbitrary limit.
  93. //
  94. LONG MediaChangeRetryCount;
  95. //
  96. // use GESN if it's available
  97. //
  98. struct {
  99. BOOLEAN Supported;
  100. BOOLEAN HackEventMask;
  101. UCHAR EventMask;
  102. UCHAR NoChangeEventMask;
  103. PUCHAR Buffer;
  104. PMDL Mdl;
  105. ULONG BufferSize;
  106. } Gesn;
  107. //
  108. // If this value is one, then the irp is currently in use.
  109. // If this value is zero, then the irp is available.
  110. // Use InterlockedCompareExchange() to set from "available" to "in use".
  111. // ASSERT that InterlockedCompareExchange() showed previous value of
  112. // "in use" when changing back to "available" state.
  113. // This also implicitly protects the MediaChangeSrb and SenseBuffer
  114. //
  115. LONG MediaChangeIrpInUse;
  116. //
  117. // Pointer to the irp to be used for media change detection.
  118. // protected by Interlocked MediaChangeIrpInUse
  119. //
  120. PIRP MediaChangeIrp;
  121. //
  122. // The srb for the media change detection.
  123. // protected by Interlocked MediaChangeIrpInUse
  124. //
  125. SCSI_REQUEST_BLOCK MediaChangeSrb;
  126. PUCHAR SenseBuffer;
  127. ULONG SrbFlags;
  128. //
  129. // Second timer to keep track of how long the media change IRP has been
  130. // in use. If this value exceeds the timeout (#defined) then we should
  131. // print out a message to the user and set the MediaChangeIrpLost flag
  132. // protected by using Interlocked() operations in ClasspSendMediaStateIrp,
  133. // the only routine which should modify this value.
  134. //
  135. LONG MediaChangeIrpTimeInUse;
  136. //
  137. // Set by CdRomTickHandler when we determine that the media change irp has
  138. // been lost
  139. //
  140. BOOLEAN MediaChangeIrpLost;
  141. };
  142. typedef enum {
  143. SimpleMediaLock,
  144. SecureMediaLock,
  145. InternalMediaLock
  146. } MEDIA_LOCK_TYPE, *PMEDIA_LOCK_TYPE;
  147. typedef struct _FAILURE_PREDICTION_INFO {
  148. FAILURE_PREDICTION_METHOD Method;
  149. ULONG CountDown; // Countdown timer
  150. ULONG Period; // Countdown period
  151. PIO_WORKITEM WorkQueueItem;
  152. KEVENT Event;
  153. } FAILURE_PREDICTION_INFO, *PFAILURE_PREDICTION_INFO;
  154. //
  155. // This struct must always fit within four PVOIDs of info,
  156. // as it uses the irp's "PVOID DriverContext[4]" to store
  157. // this info
  158. //
  159. typedef struct _CLASS_RETRY_INFO {
  160. struct _CLASS_RETRY_INFO *Next;
  161. } CLASS_RETRY_INFO, *PCLASS_RETRY_INFO;
  162. typedef struct _CSCAN_LIST {
  163. //
  164. // The current block which has an outstanding request.
  165. //
  166. ULONGLONG BlockNumber;
  167. //
  168. // The list of blocks past the CurrentBlock to which we're going to do
  169. // i/o. This list is maintained in sorted order.
  170. //
  171. LIST_ENTRY CurrentSweep;
  172. //
  173. // The list of blocks behind the current block for which we'll have to
  174. // wait until the next scan across the disk. This is kept as a stack,
  175. // the cost of sorting it is taken when it's moved over to be the
  176. // running list.
  177. //
  178. LIST_ENTRY NextSweep;
  179. } CSCAN_LIST, *PCSCAN_LIST;
  180. //
  181. // add to the front of this structure to help prevent illegal
  182. // snooping by other utilities.
  183. //
  184. typedef enum _CLASS_DETECTION_STATE {
  185. ClassDetectionUnknown = 0,
  186. ClassDetectionUnsupported = 1,
  187. ClassDetectionSupported = 2
  188. } CLASS_DETECTION_STATE, *PCLASS_DETECTION_STATE;
  189. typedef struct _CLASS_ERROR_LOG_DATA {
  190. LARGE_INTEGER TickCount; // Offset 0x00
  191. ULONG PortNumber; // Offset 0x08
  192. UCHAR ErrorPaging : 1; // Offset 0x0c
  193. UCHAR ErrorRetried : 1;
  194. UCHAR ErrorUnhandled : 1;
  195. UCHAR ErrorReserved : 5;
  196. UCHAR Reserved[3];
  197. SCSI_REQUEST_BLOCK Srb; // Offset 0x10
  198. /*
  199. * We define the SenseData as the default length.
  200. * Since the sense data returned by the port driver may be longer,
  201. * SenseData must be at the end of this structure.
  202. * For our internal error log, we only log the default length.
  203. */
  204. SENSE_DATA SenseData; // Offset 0x50 for x86 (or 0x68 for ia64) (ULONG32 Alignment required!)
  205. } CLASS_ERROR_LOG_DATA, *PCLASS_ERROR_LOG_DATA;
  206. #define NUM_ERROR_LOG_ENTRIES 16
  207. typedef struct _TRANSFER_PACKET {
  208. LIST_ENTRY AllPktsListEntry; // entry in fdoData's static AllTransferPacketsList
  209. SINGLE_LIST_ENTRY SlistEntry; // for when in free list (use fast slist)
  210. PIRP Irp;
  211. PDEVICE_OBJECT Fdo;
  212. /*
  213. * This is the client IRP that this TRANSFER_PACKET is currently
  214. * servicing.
  215. */
  216. PIRP OriginalIrp;
  217. BOOLEAN CompleteOriginalIrpWhenLastPacketCompletes;
  218. /*
  219. * Stuff for retrying the transfer.
  220. */
  221. ULONG NumRetries;
  222. KTIMER RetryTimer;
  223. KDPC RetryTimerDPC;
  224. ULONG RetryIntervalSec;
  225. /*
  226. * Event for synchronizing the transfer (optional).
  227. * (Note that we can't have the event in the packet itself because
  228. * by the time a thread waits on an event the packet may have
  229. * been completed and re-issued.
  230. */
  231. PKEVENT SyncEventPtr;
  232. /*
  233. * Stuff for retrying during extreme low-memory stress
  234. * (when we retry 1 page at a time).
  235. */
  236. BOOLEAN InLowMemRetry;
  237. PUCHAR LowMemRetry_remainingBufPtr;
  238. ULONG LowMemRetry_remainingBufLen;
  239. LARGE_INTEGER LowMemRetry_nextChunkTargetLocation;
  240. /*
  241. * Fields used for cancelling the packet.
  242. */
  243. // BOOLEAN Cancelled;
  244. // KEVENT CancelledEvent;
  245. /*
  246. * We keep the buffer and length values here as well
  247. * as in the SRB because some miniports return
  248. * the transferred length in SRB.DataTransferLength,
  249. * and if the SRB failed we need that value again for the retry.
  250. * We don't trust the lower stack to preserve any of these values in the SRB.
  251. */
  252. PUCHAR BufPtrCopy;
  253. ULONG BufLenCopy;
  254. LARGE_INTEGER TargetLocationCopy;
  255. /*
  256. * This is a standard SCSI structure that receives a detailed
  257. * report about a SCSI error on the hardware.
  258. */
  259. SENSE_DATA SrbErrorSenseData;
  260. /*
  261. * This is the SRB block for this TRANSFER_PACKET.
  262. * For IOCTLs, the SRB block includes two DWORDs for
  263. * device object and ioctl code; so these must
  264. * immediately follow the SRB block.
  265. */
  266. SCSI_REQUEST_BLOCK Srb;
  267. // ULONG SrbIoctlDevObj; // not handling ioctls yet
  268. // ULONG SrbIoctlCode;
  269. } TRANSFER_PACKET, *PTRANSFER_PACKET;
  270. /*
  271. * MIN_INITIAL_TRANSFER_PACKETS is the minimum number of packets that
  272. * we preallocate at startup for each device (we need at least one packet
  273. * to guarantee forward progress during memory stress).
  274. * MIN_WORKINGSET_TRANSFER_PACKETS is the number of TRANSFER_PACKETs
  275. * we allow to build up and remain for each device;
  276. * we _lazily_ work down to this number when they're not needed.
  277. * MAX_WORKINGSET_TRANSFER_PACKETS is the number of TRANSFER_PACKETs
  278. * that we _immediately_ reduce to when they are not needed.
  279. *
  280. * The absolute maximum number of packets that we will allocate is
  281. * whatever is required by the current activity, up to the memory limit;
  282. * as soon as stress ends, we snap down to MAX_WORKINGSET_TRANSFER_PACKETS;
  283. * we then lazily work down to MIN_WORKINGSET_TRANSFER_PACKETS.
  284. */
  285. #define MIN_INITIAL_TRANSFER_PACKETS 1
  286. #define MIN_WORKINGSET_TRANSFER_PACKETS_Consumer 4
  287. #define MAX_WORKINGSET_TRANSFER_PACKETS_Consumer 64
  288. #define MIN_WORKINGSET_TRANSFER_PACKETS_Server 64
  289. #define MAX_WORKINGSET_TRANSFER_PACKETS_Server 1024
  290. #define MIN_WORKINGSET_TRANSFER_PACKETS_Enterprise 256
  291. #define MAX_WORKINGSET_TRANSFER_PACKETS_Enterprise 2048
  292. //
  293. // add to the front of this structure to help prevent illegal
  294. // snooping by other utilities.
  295. //
  296. struct _CLASS_PRIVATE_FDO_DATA {
  297. //
  298. // this private structure allows us to
  299. // dynamically re-enable the perf benefits
  300. // lost due to transient error conditions.
  301. // in w2k, a reboot was required. :(
  302. //
  303. struct {
  304. ULONG OriginalSrbFlags;
  305. ULONG SuccessfulIO;
  306. ULONG ReEnableThreshhold; // 0 means never
  307. } Perf;
  308. ULONG_PTR HackFlags;
  309. STORAGE_HOTPLUG_INFO HotplugInfo;
  310. // Legacy. Still used by obsolete legacy code.
  311. struct {
  312. LARGE_INTEGER Delta; // in ticks
  313. LARGE_INTEGER Tick; // when it should fire
  314. PCLASS_RETRY_INFO ListHead; // singly-linked list
  315. ULONG Granularity; // static
  316. KSPIN_LOCK Lock; // protective spin lock
  317. KDPC Dpc; // DPC routine object
  318. KTIMER Timer; // timer to fire DPC
  319. } Retry;
  320. BOOLEAN TimerStarted;
  321. BOOLEAN LoggedTURFailureSinceLastIO;
  322. //
  323. // privately allocated release queue irp
  324. // protected by fdoExtension->ReleaseQueueSpinLock
  325. //
  326. BOOLEAN ReleaseQueueIrpAllocated;
  327. PIRP ReleaseQueueIrp;
  328. /*
  329. * Queues for TRANSFER_PACKETs that contextualize the IRPs and SRBs
  330. * that we send down to the port driver.
  331. * (The free list is an slist so that we can use fast
  332. * interlocked operations on it; but the relatively-static
  333. * AllTransferPacketsList list has to be
  334. * a doubly-linked list since we have to dequeue from the middle).
  335. */
  336. LIST_ENTRY AllTransferPacketsList;
  337. SLIST_HEADER FreeTransferPacketsList;
  338. ULONG NumFreeTransferPackets;
  339. ULONG NumTotalTransferPackets;
  340. ULONG DbgPeakNumTransferPackets;
  341. /*
  342. * Queue for deferred client irps
  343. */
  344. LIST_ENTRY DeferredClientIrpList;
  345. /*
  346. * Precomputed maximum transfer length for the hardware.
  347. */
  348. ULONG HwMaxXferLen;
  349. /*
  350. * SCSI_REQUEST_BLOCK template preconfigured with the constant values.
  351. * This is slapped into the SRB in the TRANSFER_PACKET for each transfer.
  352. */
  353. SCSI_REQUEST_BLOCK SrbTemplate;
  354. KSPIN_LOCK SpinLock;
  355. /*
  356. * Circular array of timestamped logs of errors that occurred on this device.
  357. */
  358. ULONG ErrorLogNextIndex;
  359. CLASS_ERROR_LOG_DATA ErrorLogs[NUM_ERROR_LOG_ENTRIES];
  360. };
  361. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  362. #define MAX(a, b) ((a) > (b) ? (a) : (b))
  363. #define NOT_READY_RETRY_INTERVAL 10
  364. #define MINIMUM_RETRY_UNITS ((LONGLONG)32)
  365. /*
  366. * Simple singly-linked-list queuing macros, with no synchronization.
  367. */
  368. __inline VOID SimpleInitSlistHdr(SINGLE_LIST_ENTRY *SListHdr)
  369. {
  370. SListHdr->Next = NULL;
  371. }
  372. __inline VOID SimplePushSlist(SINGLE_LIST_ENTRY *SListHdr, SINGLE_LIST_ENTRY *SListEntry)
  373. {
  374. SListEntry->Next = SListHdr->Next;
  375. SListHdr->Next = SListEntry;
  376. }
  377. __inline SINGLE_LIST_ENTRY *SimplePopSlist(SINGLE_LIST_ENTRY *SListHdr)
  378. {
  379. SINGLE_LIST_ENTRY *sListEntry = SListHdr->Next;
  380. if (sListEntry){
  381. SListHdr->Next = sListEntry->Next;
  382. sListEntry->Next = NULL;
  383. }
  384. return sListEntry;
  385. }
  386. __inline BOOLEAN SimpleIsSlistEmpty(SINGLE_LIST_ENTRY *SListHdr)
  387. {
  388. return (SListHdr->Next == NULL);
  389. }
  390. NTSTATUS
  391. DriverEntry(
  392. IN PDRIVER_OBJECT DriverObject,
  393. IN PUNICODE_STRING RegistryPath
  394. );
  395. VOID
  396. ClassUnload(
  397. IN PDRIVER_OBJECT DriverObject
  398. );
  399. NTSTATUS
  400. ClassCreateClose(
  401. IN PDEVICE_OBJECT DeviceObject,
  402. IN PIRP Irp
  403. );
  404. NTSTATUS
  405. ClasspCreateClose(
  406. IN PDEVICE_OBJECT DeviceObject,
  407. IN PIRP Irp
  408. );
  409. VOID
  410. ClasspCleanupProtectedLocks(
  411. IN PFILE_OBJECT_EXTENSION FsContext
  412. );
  413. NTSTATUS
  414. ClasspEjectionControl(
  415. IN PDEVICE_OBJECT Fdo,
  416. IN PIRP Irp,
  417. IN MEDIA_LOCK_TYPE LockType,
  418. IN BOOLEAN Lock
  419. );
  420. NTSTATUS
  421. ClassReadWrite(
  422. IN PDEVICE_OBJECT DeviceObject,
  423. IN PIRP Irp
  424. );
  425. NTSTATUS
  426. ClassDeviceControlDispatch(
  427. PDEVICE_OBJECT DeviceObject,
  428. PIRP Irp
  429. );
  430. NTSTATUS
  431. ClassDeviceControl(
  432. PDEVICE_OBJECT DeviceObject,
  433. PIRP Irp
  434. );
  435. NTSTATUS
  436. ClassDispatchPnp(
  437. PDEVICE_OBJECT DeviceObject,
  438. PIRP Irp
  439. );
  440. NTSTATUS
  441. ClassPnpStartDevice(
  442. IN PDEVICE_OBJECT DeviceObject
  443. );
  444. NTSTATUS
  445. ClassInternalIoControl (
  446. IN PDEVICE_OBJECT DeviceObject,
  447. IN PIRP Irp
  448. );
  449. NTSTATUS
  450. ClassShutdownFlush(
  451. IN PDEVICE_OBJECT DeviceObject,
  452. IN PIRP Irp
  453. );
  454. NTSTATUS
  455. ClassSystemControl(
  456. IN PDEVICE_OBJECT DeviceObject,
  457. IN PIRP Irp
  458. );
  459. //
  460. // Class internal routines
  461. //
  462. NTSTATUS
  463. ClassAddDevice(
  464. IN PDRIVER_OBJECT DriverObject,
  465. IN OUT PDEVICE_OBJECT PhysicalDeviceObject
  466. );
  467. NTSTATUS
  468. ClasspSendSynchronousCompletion(
  469. IN PDEVICE_OBJECT DeviceObject,
  470. IN PIRP Irp,
  471. IN PVOID Context
  472. );
  473. VOID
  474. RetryRequest(
  475. PDEVICE_OBJECT DeviceObject,
  476. PIRP Irp,
  477. PSCSI_REQUEST_BLOCK Srb,
  478. BOOLEAN Associated,
  479. ULONG RetryInterval
  480. );
  481. NTSTATUS
  482. ClassIoCompletion(
  483. IN PDEVICE_OBJECT DeviceObject,
  484. IN PIRP Irp,
  485. IN PVOID Context
  486. );
  487. NTSTATUS
  488. ClassPnpQueryFdoRelations(
  489. IN PDEVICE_OBJECT Fdo,
  490. IN PIRP Irp
  491. );
  492. NTSTATUS
  493. ClassRetrieveDeviceRelations(
  494. IN PDEVICE_OBJECT Fdo,
  495. IN DEVICE_RELATION_TYPE RelationType,
  496. OUT PDEVICE_RELATIONS *DeviceRelations
  497. );
  498. NTSTATUS
  499. ClassGetPdoId(
  500. IN PDEVICE_OBJECT Pdo,
  501. IN BUS_QUERY_ID_TYPE IdType,
  502. IN PUNICODE_STRING IdString
  503. );
  504. NTSTATUS
  505. ClassQueryPnpCapabilities(
  506. IN PDEVICE_OBJECT PhysicalDeviceObject,
  507. IN PDEVICE_CAPABILITIES Capabilities
  508. );
  509. VOID
  510. ClasspStartIo(
  511. IN PDEVICE_OBJECT DeviceObject,
  512. IN PIRP Irp
  513. );
  514. NTSTATUS
  515. ClasspPagingNotificationCompletion(
  516. IN PDEVICE_OBJECT DeviceObject,
  517. IN PIRP Irp,
  518. IN PDEVICE_OBJECT RealDeviceObject
  519. );
  520. NTSTATUS
  521. ClasspMediaChangeCompletion(
  522. PDEVICE_OBJECT DeviceObject,
  523. PIRP Irp,
  524. PVOID Context
  525. );
  526. PFILE_OBJECT_EXTENSION
  527. ClasspGetFsContext(
  528. IN PCOMMON_DEVICE_EXTENSION CommonExtension,
  529. IN PFILE_OBJECT FileObject
  530. );
  531. NTSTATUS
  532. ClasspMcnControl(
  533. IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
  534. IN PIRP Irp,
  535. IN PSCSI_REQUEST_BLOCK Srb
  536. );
  537. VOID
  538. ClasspRegisterMountedDeviceInterface(
  539. IN PDEVICE_OBJECT DeviceObject
  540. );
  541. NTSTATUS
  542. ClasspDisableTimer(
  543. PDEVICE_OBJECT DeviceObject
  544. );
  545. NTSTATUS
  546. ClasspEnableTimer(
  547. PDEVICE_OBJECT DeviceObject
  548. );
  549. //
  550. // routines for dictionary list support
  551. //
  552. VOID
  553. InitializeDictionary(
  554. IN PDICTIONARY Dictionary
  555. );
  556. BOOLEAN
  557. TestDictionarySignature(
  558. IN PDICTIONARY Dictionary
  559. );
  560. NTSTATUS
  561. AllocateDictionaryEntry(
  562. IN PDICTIONARY Dictionary,
  563. IN ULONGLONG Key,
  564. IN ULONG Size,
  565. IN ULONG Tag,
  566. OUT PVOID *Entry
  567. );
  568. PVOID
  569. GetDictionaryEntry(
  570. IN PDICTIONARY Dictionary,
  571. IN ULONGLONG Key
  572. );
  573. VOID
  574. FreeDictionaryEntry(
  575. IN PDICTIONARY Dictionary,
  576. IN PVOID Entry
  577. );
  578. NTSTATUS
  579. ClasspAllocateReleaseRequest(
  580. IN PDEVICE_OBJECT Fdo
  581. );
  582. VOID
  583. ClasspFreeReleaseRequest(
  584. IN PDEVICE_OBJECT Fdo
  585. );
  586. NTSTATUS
  587. ClassReleaseQueueCompletion(
  588. IN PDEVICE_OBJECT DeviceObject,
  589. IN PIRP Irp,
  590. IN PVOID Context
  591. );
  592. VOID
  593. ClasspReleaseQueue(
  594. IN PDEVICE_OBJECT DeviceObject,
  595. IN PIRP ReleaseQueueIrp
  596. );
  597. VOID
  598. ClasspDisablePowerNotification(
  599. PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
  600. );
  601. //
  602. // class power routines
  603. //
  604. NTSTATUS
  605. ClassDispatchPower(
  606. IN PDEVICE_OBJECT DeviceObject,
  607. IN PIRP Irp
  608. );
  609. NTSTATUS
  610. ClassMinimalPowerHandler(
  611. IN PDEVICE_OBJECT DeviceObject,
  612. IN PIRP Irp
  613. );
  614. //
  615. // Child list routines
  616. //
  617. VOID
  618. ClassAddChild(
  619. IN PFUNCTIONAL_DEVICE_EXTENSION Parent,
  620. IN PPHYSICAL_DEVICE_EXTENSION Child,
  621. IN BOOLEAN AcquireLock
  622. );
  623. PPHYSICAL_DEVICE_EXTENSION
  624. ClassRemoveChild(
  625. IN PFUNCTIONAL_DEVICE_EXTENSION Parent,
  626. IN PPHYSICAL_DEVICE_EXTENSION Child,
  627. IN BOOLEAN AcquireLock
  628. );
  629. VOID
  630. ClasspRetryDpcTimer(
  631. IN PCLASS_PRIVATE_FDO_DATA FdoData
  632. );
  633. VOID
  634. ClasspRetryRequestDpc(
  635. IN PKDPC Dpc,
  636. IN PDEVICE_OBJECT DeviceObject,
  637. IN PVOID Arg1,
  638. IN PVOID Arg2
  639. );
  640. VOID
  641. ClassFreeOrReuseSrb(
  642. IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
  643. IN PSCSI_REQUEST_BLOCK Srb
  644. );
  645. VOID
  646. ClassRetryRequest(
  647. IN PDEVICE_OBJECT SelfDeviceObject,
  648. IN PIRP Irp,
  649. IN LARGE_INTEGER TimeDelta100ns // in 100ns units
  650. );
  651. VOID
  652. ClasspBuildRequestEx(
  653. IN PFUNCTIONAL_DEVICE_EXTENSION Fdo,
  654. IN PIRP Irp,
  655. IN PSCSI_REQUEST_BLOCK Srb
  656. );
  657. NTSTATUS
  658. ClasspAllocateReleaseQueueIrp(
  659. IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
  660. );
  661. NTSTATUS
  662. ClasspInitializeGesn(
  663. IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
  664. IN PMEDIA_CHANGE_DETECTION_INFO Info
  665. );
  666. VOID
  667. ClasspSendNotification(
  668. IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
  669. IN const GUID * Guid,
  670. IN ULONG ExtraDataSize,
  671. IN PVOID ExtraData
  672. );
  673. VOID
  674. ClassSendEjectionNotification(
  675. IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
  676. );
  677. VOID
  678. ClasspScanForSpecialInRegistry(
  679. IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
  680. );
  681. VOID
  682. ClasspScanForClassHacks(
  683. IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
  684. IN ULONG_PTR Data
  685. );
  686. NTSTATUS
  687. ClasspInitializeHotplugInfo(
  688. IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
  689. );
  690. VOID
  691. ClasspPerfIncrementErrorCount(
  692. IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
  693. );
  694. VOID
  695. ClasspPerfIncrementSuccessfulIo(
  696. IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
  697. );
  698. PTRANSFER_PACKET NewTransferPacket(PDEVICE_OBJECT Fdo);
  699. VOID DestroyTransferPacket(PTRANSFER_PACKET Pkt);
  700. VOID EnqueueFreeTransferPacket(PDEVICE_OBJECT Fdo, PTRANSFER_PACKET Pkt);
  701. PTRANSFER_PACKET DequeueFreeTransferPacket(PDEVICE_OBJECT Fdo, BOOLEAN AllocIfNeeded);
  702. VOID SetupReadWriteTransferPacket(PTRANSFER_PACKET pkt, PVOID Buf, ULONG Len, LARGE_INTEGER DiskLocation, PIRP OriginalIrp);
  703. VOID SubmitTransferPacket(PTRANSFER_PACKET Pkt);
  704. NTSTATUS TransferPktComplete(IN PDEVICE_OBJECT NullFdo, IN PIRP Irp, IN PVOID Context);
  705. VOID ServiceTransferRequest(PDEVICE_OBJECT Fdo, PIRP Irp);
  706. VOID TransferPacketRetryTimerDpc(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2);
  707. BOOLEAN InterpretTransferPacketError(PTRANSFER_PACKET Pkt);
  708. BOOLEAN RetryTransferPacket(PTRANSFER_PACKET Pkt);
  709. VOID EnqueueDeferredClientIrp(PCLASS_PRIVATE_FDO_DATA FdoData, PIRP Irp);
  710. PIRP DequeueDeferredClientIrp(PCLASS_PRIVATE_FDO_DATA FdoData);
  711. VOID InitLowMemRetry(PTRANSFER_PACKET Pkt, PVOID BufPtr, ULONG Len, LARGE_INTEGER TargetLocation);
  712. BOOLEAN StepLowMemRetry(PTRANSFER_PACKET Pkt);
  713. VOID SetupEjectionTransferPacket(TRANSFER_PACKET *Pkt, BOOLEAN PreventMediaRemoval, PKEVENT SyncEventPtr, PIRP OriginalIrp);
  714. VOID SetupModeSenseTransferPacket(TRANSFER_PACKET *Pkt, PKEVENT SyncEventPtr, PVOID ModeSenseBuffer, UCHAR ModeSenseBufferLen, UCHAR PageMode, PIRP OriginalIrp);
  715. VOID SetupDriveCapacityTransferPacket(TRANSFER_PACKET *Pkt, PVOID ReadCapacityBuffer, ULONG ReadCapacityBufferLen, PKEVENT SyncEventPtr, PIRP OriginalIrp);
  716. PMDL BuildDeviceInputMdl(PVOID Buffer, ULONG BufferLen);
  717. VOID FreeDeviceInputMdl(PMDL Mdl);
  718. NTSTATUS InitializeTransferPackets(PDEVICE_OBJECT Fdo);
  719. VOID DestroyAllTransferPackets(PDEVICE_OBJECT Fdo);