Leaked source code of windows server 2003
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.

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