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.

1026 lines
40 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. local.h
  5. Abstract
  6. Definitions that are private to the hid class driver code appear here.
  7. Author:
  8. Ervin P.
  9. Environment:
  10. Kernel mode only
  11. Revision History:
  12. --*/
  13. typedef struct _HID_DESCRIPTOR *PHID_DESCRIPTOR;
  14. typedef struct _HIDCLASS_COLLECTION *PHIDCLASS_COLLECTION;
  15. typedef struct _HIDCLASS_DEVICE_EXTENSION *PHIDCLASS_DEVICE_EXTENSION;
  16. typedef struct _HIDCLASS_DRIVER_EXTENSION *PHIDCLASS_DRIVER_EXTENSION;
  17. typedef struct _HIDCLASS_FILE_EXTENSION *PHIDCLASS_FILE_EXTENSION;
  18. typedef struct _HIDCLASS_PINGPONG *PHIDCLASS_PINGPONG;
  19. typedef struct _HIDCLASS_REPORT *PHIDCLASS_REPORT;
  20. typedef struct _FDO_EXTENSION *PFDO_EXTENSION;
  21. typedef struct _PDO_EXTENSION *PPDO_EXTENSION;
  22. #if DBG
  23. #define LockFileExtension( f, i ) \
  24. { \
  25. KeAcquireSpinLock( &(f)->ListSpinLock, (i) ); \
  26. (f)->ListSpinLockTaken = TRUE; \
  27. }
  28. #define UnlockFileExtension(f, i) \
  29. { \
  30. (f)->ListSpinLockTaken = FALSE; \
  31. KeReleaseSpinLock( &(f)->ListSpinLock, (i) ); \
  32. }
  33. VOID DbgLogIntStart();
  34. VOID DbgLogIntEnd();
  35. #define DBGLOG_INTSTART() DbgLogIntStart();
  36. #define DBGLOG_INTEND() DbgLogIntEnd();
  37. VOID DbgTestGetDeviceString(PFDO_EXTENSION fdoExt);
  38. VOID DbgTestGetIndexedString(PFDO_EXTENSION fdoExt);
  39. #else
  40. #define LockFileExtension(f, i) KeAcquireSpinLock(&(f)->ListSpinLock, (i));
  41. #define UnlockFileExtension(f, i) KeReleaseSpinLock(&(f)->ListSpinLock, (i));
  42. #define DBGLOG_INTSTART()
  43. #define DBGLOG_INTEND()
  44. #endif
  45. #define HIDCLASS_POOL_TAG 'CdiH'
  46. #define ALLOCATEPOOL(poolType, size) ExAllocatePoolWithTag((poolType), (size), HIDCLASS_POOL_TAG)
  47. //
  48. // On some busses, we can power down the bus, but not the system, in this case
  49. // we still need to allow the device to wake said bus, therefore
  50. // waitwake-supported should not rely on systemstate.
  51. //
  52. #define WAITWAKE_SUPPORTED(fdoExt) ((fdoExt)->deviceCapabilities.DeviceWake > PowerDeviceD0 && \
  53. (fdoExt)->deviceCapabilities.SystemWake > PowerSystemWorking)
  54. // #define WAITWAKE_ON(port) ((port)->WaitWakeIrp != 0)
  55. #define REMOTEWAKE_ON(port) \
  56. (InterlockedCompareExchangePointer(&(port)->remoteWakeIrp, NULL, NULL) != NULL)
  57. BOOLEAN
  58. HidpCheckRemoteWakeEnabled(
  59. IN PPDO_EXTENSION PdoExt
  60. );
  61. #define SHOULD_SEND_WAITWAKE(pdoExt) (!(pdoExt)->MouseOrKeyboard && \
  62. WAITWAKE_SUPPORTED(&(pdoExt)->deviceFdoExt->fdoExt) && \
  63. !REMOTEWAKE_ON(pdoExt) && \
  64. HidpCheckRemoteWakeEnabled(pdoExt))
  65. /*
  66. * String constants for use in compatible-id multi-string.
  67. */
  68. // 0123456789 123456789 1234
  69. #define HIDCLASS_COMPATIBLE_ID_STANDARD_NAME L"HID_DEVICE\0"
  70. #define HIDCLASS_COMPATIBLE_ID_GENERIC_NAME L"HID_DEVICE_UP:%04x_U:%04x\0"
  71. #define HIDCLASS_COMPATIBLE_ID_PAGE_OFFSET 14
  72. #define HIDCLASS_COMPATIBLE_ID_USAGE_OFFSET 21
  73. #define HIDCLASS_COMPATIBLE_ID_STANDARD_LENGTH 11
  74. #define HIDCLASS_COMPATIBLE_ID_GENERIC_LENGTH 26
  75. // 0123456789 123456789 123456
  76. #define HIDCLASS_SYSTEM_KEYBOARD L"HID_DEVICE_SYSTEM_KEYBOARD\0"
  77. #define HIDCLASS_SYSTEM_MOUSE L"HID_DEVICE_SYSTEM_MOUSE\0"
  78. #define HIDCLASS_SYSTEM_GAMING_DEVICE L"HID_DEVICE_SYSTEM_GAME\0"
  79. #define HIDCLASS_SYSTEM_CONTROL L"HID_DEVICE_SYSTEM_CONTROL\0"
  80. #define HIDCLASS_SYSTEM_CONSUMER_DEVICE L"HID_DEVICE_SYSTEM_CONSUMER\0"
  81. //
  82. // String constant used to find out if selective suspend
  83. // is supported on this device.
  84. //
  85. #define HIDCLASS_SELECTIVE_SUSPEND_ENABLED L"SelectiveSuspendEnabled\0"
  86. #define HIDCLASS_SELECTIVE_SUSPEND_ON L"SelectiveSuspendOn\0"
  87. #define HIDCLASS_REMOTE_WAKE_ENABLE L"RemoteWakeEnabled"
  88. #define NO_STATUS 0x80000000 // this will never be a STATUS_xxx constant in NTSTATUS.H
  89. #define HID_DEFAULT_IDLE_TIME 5 // in seconds
  90. //
  91. // Valid values for HIDCLASS_DEVICE_EXTENSION.state
  92. //
  93. enum deviceState {
  94. DEVICE_STATE_INITIALIZED = 1,
  95. DEVICE_STATE_STARTING,
  96. DEVICE_STATE_START_SUCCESS,
  97. DEVICE_STATE_START_FAILURE,
  98. DEVICE_STATE_STOPPING,
  99. DEVICE_STATE_STOPPED,
  100. DEVICE_STATE_REMOVING,
  101. DEVICE_STATE_REMOVED
  102. };
  103. enum collectionState {
  104. COLLECTION_STATE_UNINITIALIZED = 1,
  105. COLLECTION_STATE_INITIALIZED,
  106. COLLECTION_STATE_RUNNING,
  107. COLLECTION_STATE_STOPPING,
  108. COLLECTION_STATE_STOPPED,
  109. COLLECTION_STATE_REMOVING
  110. };
  111. //
  112. // _HIDCLASS_DRIVER_EXTENSION contains per-minidriver extension information
  113. // for the class driver. It is created upon a HidRegisterMinidriver() call.
  114. //
  115. typedef struct _HIDCLASS_DRIVER_EXTENSION {
  116. //
  117. // Pointer to the minidriver's driver object.
  118. //
  119. PDRIVER_OBJECT MinidriverObject;
  120. //
  121. // RegistryPath is a copy of the minidriver's RegistryPath that it
  122. // received as a DriverEntry() parameter.
  123. //
  124. UNICODE_STRING RegistryPath;
  125. //
  126. // DeviceExtensionSize is the size of the minidriver's per-device
  127. // extension.
  128. //
  129. ULONG DeviceExtensionSize;
  130. //
  131. // Dispatch routines for the minidriver. These are the only dispatch
  132. // routines that the minidriver should ever care about, no others will
  133. // be forwarded.
  134. //
  135. PDRIVER_DISPATCH MajorFunction[ IRP_MJ_MAXIMUM_FUNCTION + 1 ];
  136. /*
  137. * These are the minidriver's original entrypoints,
  138. * to which we chain.
  139. */
  140. PDRIVER_ADD_DEVICE AddDevice;
  141. PDRIVER_UNLOAD DriverUnload;
  142. //
  143. // Number of pointers to this structure that we've handed out
  144. //
  145. LONG ReferenceCount;
  146. //
  147. // Linkage onto our global list of driver extensions
  148. //
  149. LIST_ENTRY ListEntry;
  150. /*
  151. * Either all or none of the devices driven by a given minidriver are polled.
  152. */
  153. BOOLEAN DevicesArePolled;
  154. #if DBG
  155. ULONG Signature;
  156. #endif
  157. } HIDCLASS_DRIVER_EXTENSION;
  158. #if DBG
  159. #define HID_DRIVER_EXTENSION_SIG 'EdiH'
  160. #endif
  161. #define MIN_POLL_INTERVAL_MSEC 1
  162. #define MAX_POLL_INTERVAL_MSEC 10000
  163. #define DEFAULT_POLL_INTERVAL_MSEC 5
  164. /*
  165. * Device-specific flags
  166. */
  167. // Nanao depends on a Win98G bug that allows GetFeature on input collection
  168. #define DEVICE_FLAG_ALLOW_FEATURE_ON_NON_FEATURE_COLLECTION (1 << 0)
  169. //
  170. // HIDCLASS_COLLECTION is where we keep our per-collection information.
  171. //
  172. typedef struct _HIDCLASS_COLLECTION {
  173. ULONG CollectionNumber;
  174. ULONG CollectionIndex;
  175. //
  176. // NumOpens is a count of open handles against this collection.
  177. //
  178. ULONG NumOpens;
  179. // Number of pending reads for all clients on this collection.
  180. ULONG numPendingReads;
  181. //
  182. // FileExtensionList is the head of a list of file extensions, i.e.
  183. // open instances against this collection.
  184. //
  185. LIST_ENTRY FileExtensionList;
  186. KSPIN_LOCK FileExtensionListSpinLock;
  187. /*
  188. * For polled devices, we only read from the device
  189. * once every poll interval. We queue read IRPs
  190. * here until the poll timer expiration.
  191. *
  192. * Note: for a polled device, we keep a separate background
  193. * loop for each collection. This way, queued-up read IRPs
  194. * remain associated with the right collection.
  195. * Also, this will keep the number of reads we do on each
  196. * timer period roughly equal to the number of collections.
  197. */
  198. ULONG PollInterval_msec;
  199. KTIMER polledDeviceTimer;
  200. KDPC polledDeviceTimerDPC;
  201. LIST_ENTRY polledDeviceReadQueue;
  202. KSPIN_LOCK polledDeviceReadQueueSpinLock;
  203. /*
  204. * We save old reports on polled devices for
  205. * "opportunistic" readers who want to get a result right away.
  206. * The polledDataIsStale flag indicates that the saved report
  207. * is at least one poll interval old (so we should not use it).
  208. */
  209. PUCHAR savedPolledReportBuf;
  210. ULONG savedPolledReportLen;
  211. BOOLEAN polledDataIsStale;
  212. UNICODE_STRING SymbolicLinkName;
  213. UNICODE_STRING SymbolicLinkName_SystemControl;
  214. /*
  215. * HID collection information descriptor for this collection.
  216. */
  217. HID_COLLECTION_INFORMATION hidCollectionInfo;
  218. PHIDP_PREPARSED_DATA phidDescriptor;
  219. /*
  220. * This buffer is used to "cook" a raw report when it's been received.
  221. * This is only used for non-polled (interrupt) devices.
  222. */
  223. PUCHAR cookedInterruptReportBuf;
  224. /*
  225. * This is an IRP that we queue and complete
  226. * when a read report contains a power event.
  227. *
  228. * The powerEventIrp field retains an IRP
  229. * so it needs a spinlock to synchronize cancellation.
  230. */
  231. PIRP powerEventIrp;
  232. KSPIN_LOCK powerEventSpinLock;
  233. ULONG secureReadMode;
  234. KSPIN_LOCK secureReadLock;
  235. #if DBG
  236. ULONG Signature;
  237. #endif
  238. } HIDCLASS_COLLECTION;
  239. #if DBG
  240. #define HIDCLASS_COLLECTION_SIG 'EccH'
  241. #endif
  242. //
  243. // For HID devices that have at least one interrupt-style collection, we
  244. // try to keep a set of "ping-pong" report-read IRPs pending in the minidriver
  245. // in the event we get a report.
  246. //
  247. // HIDCLASS_PINGPONG contains a pointer to an IRP as well as an event
  248. // and status block. Each device has a pointer to an array of these structures,
  249. // the array size depending on the number of such IRPs we want to keep in
  250. // motion.
  251. //
  252. // Right now the default number is 2.
  253. //
  254. #define MIN_PINGPONG_IRPS 2
  255. //
  256. // Flags to indicate whether read completed synchronously or asynchronously
  257. //
  258. #define PINGPONG_START_READ 0x01
  259. #define PINGPONG_END_READ 0x02
  260. #define PINGPONG_IMMEDIATE_READ 0x03
  261. typedef struct _HIDCLASS_PINGPONG {
  262. #define PINGPONG_SIG (ULONG)'gnoP'
  263. ULONG sig;
  264. //
  265. // Read interlock value to protect us from running out of stack space
  266. //
  267. ULONG ReadInterlock;
  268. PIRP irp;
  269. PUCHAR reportBuffer;
  270. LONG weAreCancelling;
  271. KEVENT sentEvent; // When a read has been sent.
  272. KEVENT pumpDoneEvent; // When the read loop is finally exitting.
  273. PFDO_EXTENSION myFdoExt;
  274. /*
  275. * Timeout context for back-off algorithm applied to broken devices.
  276. */
  277. KTIMER backoffTimer;
  278. KDPC backoffTimerDPC;
  279. LARGE_INTEGER backoffTimerPeriod; // in negative 100-nsec units
  280. } HIDCLASS_PINGPONG;
  281. #if DBG
  282. #define HIDCLASS_REPORT_BUFFER_GUARD 'draG'
  283. #endif
  284. //
  285. // All possible idle states.
  286. //
  287. #define IdleUninitialized 0x0
  288. #define IdleDisabled 0x1
  289. #define IdleWaiting 0x2
  290. #define IdleIrpSent 0x3
  291. #define IdleCallbackReceived 0x4
  292. #define IdleComplete 0x5
  293. /*
  294. * Stores information about a Functional Device Object (FDO) which HIDCLASS attaches
  295. * to the top of the Physical Device Object (PDO) that it get from the minidriver below.
  296. */
  297. typedef struct _FDO_EXTENSION {
  298. //
  299. // Back pointer to the functional device object
  300. //
  301. PDEVICE_OBJECT fdo;
  302. //
  303. // HidDriverExtension is a pointer to our driver extension for the
  304. // minidriver that gave us the PDO.
  305. //
  306. PHIDCLASS_DRIVER_EXTENSION driverExt;
  307. //
  308. // Hid descriptor that we get from the device.
  309. //
  310. HID_DESCRIPTOR hidDescriptor; // 9 bytes
  311. //
  312. // The attributes of this hid device.
  313. //
  314. HID_DEVICE_ATTRIBUTES hidDeviceAttributes; // 0x20 bytes
  315. //
  316. // Pointer to and length of the raw report descriptor.
  317. //
  318. PUCHAR rawReportDescription;
  319. ULONG rawReportDescriptionLength;
  320. //
  321. // This device has one or more collections. We store the count and
  322. // pointer to an array of our HIDCLASS_COLLECTION structures (one per
  323. // collection) here.
  324. //
  325. PHIDCLASS_COLLECTION classCollectionArray;
  326. /*
  327. * This is initialized for us by HIDPARSE's HidP_GetCollectionDescription().
  328. * It includes an array of HIDP_COLLECTION_DESC structs corresponding
  329. * the classCollectionArray declared above.
  330. */
  331. HIDP_DEVICE_DESC deviceDesc; // 0x30 bytes
  332. BOOLEAN devDescInitialized;
  333. //
  334. // The maximum input size amongst ALL report types.
  335. //
  336. ULONG maxReportSize;
  337. //
  338. // For devices that have at least one interrupt collection, we keep
  339. // a couple of ping-pong IRPs and associated structures.
  340. // The ping-pong IRPs ferry data up from the USB hub.
  341. //
  342. ULONG numPingPongs;
  343. PHIDCLASS_PINGPONG pingPongs;
  344. //
  345. // OpenCount represents the number of file objects aimed at this device
  346. //
  347. ULONG openCount;
  348. /*
  349. * This is the number of IRPs still outstanding in the minidriver.
  350. */
  351. ULONG outstandingRequests;
  352. enum deviceState prevState;
  353. enum deviceState state;
  354. UNICODE_STRING name;
  355. /*
  356. * deviceRelations contains an array of client PDO pointers.
  357. *
  358. * As the HID bus driver, HIDCLASS produces this data structure to report
  359. * collection-PDOs to the system.
  360. */
  361. PDEVICE_RELATIONS deviceRelations;
  362. /*
  363. * This is an array of device extensions for the collection-PDOs of this
  364. * device-FDO.
  365. */
  366. PHIDCLASS_DEVICE_EXTENSION *collectionPdoExtensions;
  367. /*
  368. * This includes a
  369. * table mapping system power states to device power states.
  370. */
  371. DEVICE_CAPABILITIES deviceCapabilities;
  372. /*
  373. * Track both current system and device power state
  374. */
  375. SYSTEM_POWER_STATE systemPowerState;
  376. DEVICE_POWER_STATE devicePowerState;
  377. /*
  378. * Wait Wake Irp sent to parent PDO
  379. */
  380. PIRP waitWakeIrp;
  381. KSPIN_LOCK waitWakeSpinLock;
  382. BOOLEAN isWaitWakePending;
  383. /*
  384. * Queue of delayed requests due to the stack being in low power
  385. */
  386. KSPIN_LOCK collectionPowerDelayedIrpQueueSpinLock;
  387. LIST_ENTRY collectionPowerDelayedIrpQueue;
  388. ULONG numPendingPowerDelayedIrps;
  389. BOOLEAN isOutputOnlyDevice;
  390. //
  391. // Selective suspend idling context.
  392. //
  393. HID_SUBMIT_IDLE_NOTIFICATION_CALLBACK_INFO idleCallbackInfo;
  394. LONG idleState;
  395. PULONG idleTimeoutValue;
  396. KSPIN_LOCK idleNotificationSpinLock;
  397. PIRP idleNotificationRequest;
  398. BOOLEAN idleCancelling;
  399. BOOLEAN idleEnabledInRegistry;
  400. BOOLEAN idleEnabled;
  401. KSPIN_LOCK idleSpinLock;
  402. KEVENT idleDoneEvent; // When the idle notification irp has been cancelled successfully.
  403. LONG numIdlePdos;
  404. /*
  405. * This is a list of WaitWake IRPs sent to the collection-PDOs
  406. * on this device, which we just save and complete when the
  407. * base device's WaitWake IRP completes.
  408. */
  409. LIST_ENTRY collectionWaitWakeIrpQueue;
  410. KSPIN_LOCK collectionWaitWakeIrpQueueSpinLock;
  411. struct _FDO_EXTENSION *nextFdoExt;
  412. /*
  413. * Device-specific flags (DEVICE_FLAG_xxx).
  414. */
  415. ULONG deviceSpecificFlags;
  416. /*
  417. * This is our storage space for the systemState IRP that we need to hold
  418. * on to and complete in DevicePowerRequestCompletion.
  419. */
  420. PIRP currentSystemStateIrp;
  421. /*
  422. * Unique number assigned to identify this HID bus.
  423. */
  424. ULONG BusNumber;
  425. //
  426. // WMI Information
  427. //
  428. WMILIB_CONTEXT WmiLibInfo;
  429. #if DBG
  430. WCHAR dbgDriverKeyName[64];
  431. #endif
  432. } FDO_EXTENSION;
  433. /*
  434. * Stores information about a Physical Device Object (PDO) which HIDCLASS creates
  435. * for each HID device-collection.
  436. */
  437. typedef struct _PDO_EXTENSION {
  438. enum collectionState prevState;
  439. enum collectionState state;
  440. ULONG collectionNum;
  441. ULONG collectionIndex;
  442. //
  443. // A remove lock to keep track of outstanding I/Os to prevent the device
  444. // object from leaving before such time as all I/O has been completed.
  445. //
  446. IO_REMOVE_LOCK removeLock;
  447. // represents a collection on the HID "bus"
  448. PDEVICE_OBJECT pdo;
  449. PUNICODE_STRING name;
  450. /*
  451. * This is a back-pointer to the original FDO's extension.
  452. */
  453. PHIDCLASS_DEVICE_EXTENSION deviceFdoExt;
  454. /*
  455. * Track both current system and device power state
  456. */
  457. SYSTEM_POWER_STATE systemPowerState;
  458. DEVICE_POWER_STATE devicePowerState;
  459. BOOLEAN remoteWakeEnabled;
  460. KSPIN_LOCK remoteWakeSpinLock;
  461. PIRP remoteWakeIrp;
  462. PIRP waitWakeIrp;
  463. /*
  464. * The status change function that was registered thru query interface
  465. * NOTE: Can currently only register one.
  466. */
  467. PHID_STATUS_CHANGE StatusChangeFn;
  468. PVOID StatusChangeContext;
  469. /*
  470. * Access protection information.
  471. * We count the number of opens for read and write on the collection.
  472. * We also count the number of opens which RESTRICT future
  473. * read/write opens on the collection.
  474. *
  475. * Note that desired access is independent of restriction.
  476. * A client may, for example, do an open-for-read-only but
  477. * (by not setting the FILE_SHARE_WRITE bit)
  478. * restrict other clients from doing an open-for-write.
  479. */
  480. ULONG openCount;
  481. ULONG opensForRead;
  482. ULONG opensForWrite;
  483. ULONG restrictionsForRead;
  484. ULONG restrictionsForWrite;
  485. ULONG restrictionsForAnyOpen;
  486. BOOLEAN MouseOrKeyboard;
  487. //
  488. // WMI Information
  489. //
  490. WMILIB_CONTEXT WmiLibInfo;
  491. } PDO_EXTENSION;
  492. /*
  493. * This contains info about either a device FDO or a device-collection PDO.
  494. * Some of the same functions process both, so we need one structure.
  495. */
  496. typedef struct _HIDCLASS_DEVICE_EXTENSION {
  497. /*
  498. * This is the public part of a HID FDO device extension, and
  499. * must be the first entry in this structure.
  500. */
  501. HID_DEVICE_EXTENSION hidExt; // size== 0x0C.
  502. /*
  503. * Determines whether this is a device extension for a device-FDO or a
  504. * device-collection-PDO; this resolves the following union.
  505. */
  506. BOOLEAN isClientPdo;
  507. /*
  508. * Include this signature for both debug and retail --
  509. * kenray's debug extensions look for this.
  510. */
  511. #define HID_DEVICE_EXTENSION_SIG 'EddH'
  512. ULONG Signature;
  513. union {
  514. FDO_EXTENSION fdoExt;
  515. PDO_EXTENSION pdoExt;
  516. };
  517. } HIDCLASS_DEVICE_EXTENSION;
  518. //
  519. // HIDCLASS_FILE_EXTENSION is private data we keep per file object.
  520. //
  521. typedef struct _HIDCLASS_FILE_EXTENSION {
  522. //
  523. // CollectionNumber is the ordinal of the collection in the device
  524. //
  525. ULONG CollectionNumber;
  526. PFDO_EXTENSION fdoExt;
  527. //
  528. // PendingIrpList is a list of READ IRPs currently waiting to be satisfied.
  529. //
  530. LIST_ENTRY PendingIrpList;
  531. //
  532. // ReportList is a list of reports waiting to be read on this handle.
  533. //
  534. LIST_ENTRY ReportList;
  535. //
  536. // FileList provides a way to link all of a collection's
  537. // file extensions together.
  538. //
  539. LIST_ENTRY FileList;
  540. //
  541. // Both PendingIrpList and ReportList are protected by the same spinlock,
  542. // ListSpinLock.
  543. //
  544. KSPIN_LOCK ListSpinLock;
  545. //
  546. // MaximumInputReportAge is only applicable for polled collections.
  547. // It represents the maximum acceptable input report age for this handle.
  548. // There is a value in the HIDCLASS_COLLECTION,
  549. // CurrentMaximumInputReportAge, that represents the current minimum value
  550. // of all of the file extensions open against the collection.
  551. //
  552. LARGE_INTEGER MaximumInputReportAge;
  553. //
  554. // CurrentInputReportQueueSize is the current size of the report input
  555. // queue.
  556. //
  557. ULONG CurrentInputReportQueueSize;
  558. /*
  559. * This is the maximum number of reports that will be queued for the file extension.
  560. * This starts at a default value and can be adjusted (within a fixed range) by an IOCTL.
  561. */
  562. ULONG MaximumInputReportQueueSize;
  563. #define MIN_INPUT_REPORT_QUEUE_SIZE MIN_PINGPONG_IRPS
  564. #define MAX_INPUT_REPORT_QUEUE_SIZE (MIN_INPUT_REPORT_QUEUE_SIZE*256)
  565. #define DEFAULT_INPUT_REPORT_QUEUE_SIZE (MIN_INPUT_REPORT_QUEUE_SIZE*16)
  566. //
  567. // Back pointer to the file object that this extension is for
  568. //
  569. PFILE_OBJECT FileObject;
  570. /*
  571. * File-attributes passed in irpSp->Parameters.Create.FileAttributes
  572. * when this open was made.
  573. */
  574. USHORT FileAttributes;
  575. ACCESS_MASK accessMask;
  576. USHORT shareMask;
  577. //
  578. // Closing is set when this file object is closing and will be removed
  579. // shortly. Don't queue any more reports or IRPs to this object
  580. // when this flag is set.
  581. //
  582. BOOLEAN Closing;
  583. //
  584. // Security has been checked.
  585. //
  586. BOOLEAN SecurityCheck;
  587. //
  588. // DWORD allignment
  589. //
  590. BOOLEAN Reserved [2];
  591. /*
  592. * This flag indicates that this client does irregular, opportunistic
  593. * reads on the device, which is a polled device.
  594. * Instead of waiting for the background timer-driven read loop,
  595. * this client should have his reads completed immediately.
  596. */
  597. BOOLEAN isOpportunisticPolledDeviceReader;
  598. ULONG nowCompletingIrpForOpportunisticReader;
  599. /*
  600. * haveReadPrivilege TRUE indicates that the client has full
  601. * permissions on the device, including read.
  602. */
  603. BOOLEAN haveReadPrivilege;
  604. //
  605. // Memphis Blue Screen info
  606. //
  607. BLUESCREEN BlueScreenData;
  608. BOOLEAN isSecureOpen;
  609. ULONG SecureReadMode;
  610. /*
  611. * If a read fails, some clients reissue the read on the same thread.
  612. * If this happens repeatedly, we can run out of stack space.
  613. * So we keep track of the depth
  614. */
  615. #define INSIDE_READCOMPLETE_MAX 4
  616. ULONG insideReadCompleteCount;
  617. #if DBG
  618. BOOLEAN ListSpinLockTaken;
  619. ULONG dbgNumReportsDroppedSinceLastRead;
  620. ULONG Signature;
  621. #endif
  622. } HIDCLASS_FILE_EXTENSION;
  623. #if DBG
  624. #define HIDCLASS_FILE_EXTENSION_SIG 'efcH'
  625. #endif
  626. typedef struct {
  627. #define ASYNC_COMPLETE_CONTEXT_SIG 'cnsA'
  628. ULONG sig;
  629. WORK_QUEUE_ITEM workItem;
  630. PIRP irp;
  631. PDEVICE_OBJECT devObj;
  632. } ASYNC_COMPLETE_CONTEXT;
  633. //
  634. // HIDCLASS_REPORT is the structure we use to track a report returned from
  635. // the minidriver.
  636. //
  637. typedef struct _HIDCLASS_REPORT {
  638. //
  639. // ListEntry queues this report onto a file extension.
  640. //
  641. LIST_ENTRY ListEntry;
  642. ULONG reportLength;
  643. //
  644. // UnparsedReport is a data area for the unparsed report data as returned
  645. // from the minidriver. The lengths of all input reports for a given
  646. // class are the same, so we don't need to store the length in each
  647. // report.
  648. //
  649. UCHAR UnparsedReport[];
  650. } HIDCLASS_REPORT;
  651. typedef struct _HIDCLASS_WORK_ITEM_DATA {
  652. PIRP Irp;
  653. PDO_EXTENSION *PdoExt;
  654. PIO_WORKITEM Item;
  655. BOOLEAN RemoteWakeState;
  656. } HIDCLASS_WORK_ITEM_DATA, *PHIDCLASS_WORK_ITEM_DATA;
  657. //
  658. // Internal shared function prototypes
  659. //
  660. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
  661. NTSTATUS HidpAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject);
  662. VOID HidpDriverUnload(IN struct _DRIVER_OBJECT *minidriverObject);
  663. NTSTATUS HidpCallDriver(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
  664. NTSTATUS HidpCallDriverSynchronous(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
  665. NTSTATUS HidpCopyInputReportToUser(IN PHIDCLASS_FILE_EXTENSION fdoExtension, IN PUCHAR ReportData, IN OUT PULONG UserBufferLen, OUT PUCHAR UserBuffer);
  666. NTSTATUS HidpCreateSymbolicLink(IN PDO_EXTENSION *pdoExtension, IN ULONG collectionNum, IN BOOLEAN Create, IN PDEVICE_OBJECT Pdo);
  667. NTSTATUS HidpCreateClientPDOs(PHIDCLASS_DEVICE_EXTENSION hidClassExtension);
  668. ULONG HidpSetMaxReportSize(IN FDO_EXTENSION *fdoExtension);
  669. VOID EnqueueInterruptReport(PHIDCLASS_FILE_EXTENSION fileExtension, PHIDCLASS_REPORT report);
  670. PHIDCLASS_REPORT DequeueInterruptReport(PHIDCLASS_FILE_EXTENSION fileExtension, LONG maxLen);
  671. VOID HidpDestroyFileExtension(PHIDCLASS_COLLECTION collection, PHIDCLASS_FILE_EXTENSION FileExtension);
  672. VOID HidpFlushReportQueue(IN PHIDCLASS_FILE_EXTENSION FileExtension);
  673. NTSTATUS HidpGetCollectionDescriptor(IN FDO_EXTENSION *fdoExtension, IN ULONG collectionId, IN PVOID Buffer, IN OUT PULONG BufferSize);
  674. NTSTATUS HidpGetCollectionInformation(IN FDO_EXTENSION *fdoExtension, IN ULONG collectionNumber, IN PVOID Buffer, IN OUT PULONG BufferSize);
  675. NTSTATUS HidpGetDeviceDescriptor(FDO_EXTENSION *fdoExtension);
  676. BOOLEAN HidpStartIdleTimeout(FDO_EXTENSION *fdoExt, BOOLEAN DeviceStart);
  677. VOID HidpCancelIdleNotification(FDO_EXTENSION *fdoExt, BOOLEAN removing);
  678. VOID HidpIdleTimeWorker(PDEVICE_OBJECT DeviceObject, PIO_WORKITEM Item);
  679. VOID HidpIdleNotificationCallback(PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension);
  680. NTSTATUS HidpRegisterDeviceForIdleDetection(PDEVICE_OBJECT DeviceObject, ULONG IdleTime, PULONG *);
  681. VOID HidpSetDeviceBusy(FDO_EXTENSION *fdoExt);
  682. NTSTATUS HidpCheckIdleState(PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension,PIRP Irp);
  683. NTSTATUS HidpGetRawDeviceDescriptor(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, OUT PULONG RawDeviceDescriptorLength, OUT PUCHAR *RawDeviceDescriptor);
  684. NTSTATUS HidpInitializePingPongIrps(FDO_EXTENSION *fdoExtension);
  685. NTSTATUS HidpReallocPingPongIrps(FDO_EXTENSION *fdoExtension, ULONG newNumBufs);
  686. NTSTATUS HidpIrpMajorPnpComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);
  687. NTSTATUS HidpMajorHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  688. NTSTATUS HidpParseAndBuildLinks(FDO_EXTENSION *fdoExtension);
  689. NTSTATUS HidpFdoPowerCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);
  690. BOOLEAN EnqueueDriverExt(PHIDCLASS_DRIVER_EXTENSION driverExt);
  691. PHIDCLASS_DRIVER_EXTENSION RefDriverExt(IN PDRIVER_OBJECT MinidriverObject);
  692. PHIDCLASS_DRIVER_EXTENSION DerefDriverExt(IN PDRIVER_OBJECT MinidriverObject);
  693. NTSTATUS HidpStartAllPingPongs(FDO_EXTENSION *fdoExtension);
  694. ULONG HidiGetClassCollectionOrdinal(IN PHIDCLASS_COLLECTION ClassCollection);
  695. PHIDP_COLLECTION_DESC HidiGetHidCollectionByClassCollection(IN PHIDCLASS_COLLECTION ClassCollection);
  696. PHIDP_REPORT_IDS GetReportIdentifier(FDO_EXTENSION *fdoExtension, ULONG reportId);
  697. PHIDP_COLLECTION_DESC GetCollectionDesc(FDO_EXTENSION *fdoExtension, ULONG collectionId);
  698. PHIDCLASS_COLLECTION GetHidclassCollection(FDO_EXTENSION *fdoExtension, ULONG collectionId);
  699. //NTSTATUS HidpGetSetFeature(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp, IN ULONG controlCode, OUT BOOLEAN *sentIrp);
  700. NTSTATUS HidpGetSetReport(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp, IN ULONG controlCode, OUT BOOLEAN *sentIrp);
  701. NTSTATUS HidpGetDeviceString(IN FDO_EXTENSION *fdoExt, IN OUT PIRP Irp, IN ULONG stringId, IN ULONG languageId);
  702. NTSTATUS HidpGetPhysicalDescriptor(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
  703. NTSTATUS HidpIrpMajorRead(IN PHIDCLASS_DEVICE_EXTENSION, IN OUT PIRP Irp);
  704. NTSTATUS HidpIrpMajorCreate(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
  705. NTSTATUS HidpIrpMajorWrite(IN PHIDCLASS_DEVICE_EXTENSION, IN OUT PIRP Irp);
  706. NTSTATUS HidpIrpMajorPnp(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
  707. NTSTATUS HidpPdoPnp(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
  708. NTSTATUS HidpFdoPnp(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
  709. NTSTATUS HidpIrpMajorPower(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
  710. NTSTATUS HidpIrpMajorClose(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
  711. NTSTATUS HidpIrpMajorDeviceControl(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
  712. NTSTATUS HidpIrpMajorINTERNALDeviceControl(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
  713. NTSTATUS HidpIrpMajorClose(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
  714. NTSTATUS HidpIrpMajorDefault(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
  715. NTSTATUS HidpInterruptReadComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);
  716. NTSTATUS HidpQueryDeviceRelations(IN PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, IN OUT PIRP Irp);
  717. NTSTATUS HidpQueryCollectionCapabilities(PDO_EXTENSION *pdoExt, IN OUT PIRP Irp);
  718. NTSTATUS HidpQueryIdForClientPdo(IN PHIDCLASS_DEVICE_EXTENSION hidClassExtension, IN OUT PIRP Irp);
  719. NTSTATUS HidpQueryInterface(IN PHIDCLASS_DEVICE_EXTENSION hidClassExtension, IN OUT PIRP Irp);
  720. PVOID MemDup(POOL_TYPE PoolType, PVOID dataPtr, ULONG length);
  721. BOOLEAN AllClientPDOsInitialized(FDO_EXTENSION *fdoExtension, BOOLEAN initialized);
  722. BOOLEAN AnyClientPDOsInitialized(FDO_EXTENSION *fdoExtension, BOOLEAN initialized);
  723. NTSTATUS ClientPdoCompletion(PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, PIRP Irp);
  724. BOOLEAN HidpDeleteDeviceObjects(FDO_EXTENSION *fdoExt);
  725. VOID HidpCancelReadIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp);
  726. VOID CancelAllPingPongIrps(FDO_EXTENSION *fdoExt);
  727. VOID HidpCleanUpFdo(FDO_EXTENSION *fdoExt);
  728. NTSTATUS HidpRemoveDevice(FDO_EXTENSION *fdoExt, IN PIRP Irp);
  729. VOID HidpRemoveCollection(FDO_EXTENSION *fdoExt, PDO_EXTENSION *pdoExt, IN PIRP Irp);
  730. VOID HidpDestroyCollection(FDO_EXTENSION *fdoExt, PHIDCLASS_COLLECTION Collection);
  731. VOID CollectionPowerRequestCompletion(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus);
  732. VOID DevicePowerRequestCompletion(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus);
  733. NTSTATUS HidpQueryCapsCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);
  734. NTSTATUS HidpQueryDeviceCapabilities(IN PDEVICE_OBJECT PdoDeviceObject, IN PDEVICE_CAPABILITIES DeviceCapabilities);
  735. VOID DestroyPingPongs(FDO_EXTENSION *fdoExt);
  736. VOID CheckReportPowerEvent(FDO_EXTENSION *fdoExt, PHIDCLASS_COLLECTION collection, PUCHAR report, ULONG reportLen);
  737. BOOLEAN StartPollingLoop(FDO_EXTENSION *fdoExt, PHIDCLASS_COLLECTION hidCollection, BOOLEAN freshQueue);
  738. VOID StopPollingLoop(PHIDCLASS_COLLECTION hidCollection, BOOLEAN flushQueue);
  739. BOOLEAN ReadPolledDevice(PDO_EXTENSION *pdoExt, BOOLEAN isTimerDrivenRead);
  740. VOID PolledReadCancelRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  741. VOID EnqueueFdoExt(FDO_EXTENSION *fdoExt);
  742. VOID DequeueFdoExt(FDO_EXTENSION *fdoExt);
  743. NTSTATUS AllocDeviceResources(FDO_EXTENSION *fdoExt);
  744. VOID FreeDeviceResources(FDO_EXTENSION *fdoExt);
  745. NTSTATUS AllocCollectionResources(FDO_EXTENSION *fdoExt, ULONG collectionNum);
  746. VOID FreeCollectionResources(FDO_EXTENSION *fdoExt, ULONG collectionNum);
  747. NTSTATUS InitializeCollection(FDO_EXTENSION *fdoExt, ULONG collectionIndex);
  748. NTSTATUS HidpStartCollectionPDO(FDO_EXTENSION *fdoExt, PDO_EXTENSION *pdoExt, PIRP Irp);
  749. NTSTATUS HidpStartDevice(PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, PIRP Irp);
  750. PWCHAR SubstituteBusNames(PWCHAR oldIDs, FDO_EXTENSION *fdoExt, PDO_EXTENSION *pdoExt);
  751. PWSTR BuildCompatibleID(PHIDCLASS_DEVICE_EXTENSION hidClassExtension);
  752. PUNICODE_STRING MakeClientPDOName(PUNICODE_STRING fdoName, ULONG collectionId);
  753. VOID HidpPingpongBackoffTimerDpc(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2);
  754. BOOLEAN WStrCompareN(PWCHAR str1, PWCHAR str2, ULONG maxChars);
  755. NTSTATUS SubmitWaitWakeIrp(PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension);
  756. BOOLEAN HidpIsWaitWakePending(FDO_EXTENSION *fdoExt, BOOLEAN setIfNotPending);
  757. NTSTATUS HidpWaitWakeComplete(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus);
  758. NTSTATUS HidpGetIndexedString(IN FDO_EXTENSION *fdoExt, IN OUT PIRP Irp, IN ULONG stringIndex, IN ULONG languageId);
  759. VOID CompleteAllPendingReadsForCollection(PHIDCLASS_COLLECTION Collection);
  760. VOID CompleteAllPendingReadsForFileExtension(PHIDCLASS_COLLECTION Collection, PHIDCLASS_FILE_EXTENSION fileExtension);
  761. VOID CompleteAllPendingReadsForDevice(FDO_EXTENSION *fdoExt);
  762. BOOLEAN MyPrivilegeCheck(PIRP Irp);
  763. NTSTATUS QueuePowerEventIrp(PHIDCLASS_COLLECTION hidCollection, PIRP Irp);
  764. VOID PowerEventCancelRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  765. NTSTATUS HidpPolledReadComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);
  766. NTSTATUS HidpPolledReadComplete_TimerDriven(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);
  767. VOID CollectionWaitWakeIrpCancelRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  768. VOID CompleteAllCollectionWaitWakeIrps(FDO_EXTENSION *fdoExt, NTSTATUS status);
  769. VOID PowerDelayedCancelRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  770. NTSTATUS EnqueuePowerDelayedIrp(PHIDCLASS_DEVICE_EXTENSION HidDeviceExtension, PIRP Irp);
  771. PIRP DequeuePowerDelayedIrp(FDO_EXTENSION *fdoExt);
  772. ULONG DequeueAllPdoPowerDelayedIrps(PDO_EXTENSION *pdoExt, PLIST_ENTRY dequeue);
  773. VOID ReadDeviceFlagsFromRegistry(FDO_EXTENSION *fdoExt, PDEVICE_OBJECT pdo);
  774. LONG WStrNCmpI(PWCHAR s1, PWCHAR s2, ULONG n);
  775. ULONG LAtoX(PWCHAR wHexString);
  776. ULONG WStrNCpy(PWCHAR dest, PWCHAR src, ULONG n);
  777. NTSTATUS OpenSubkey(OUT PHANDLE Handle, IN HANDLE BaseHandle, IN PUNICODE_STRING KeyName, IN ACCESS_MASK DesiredAccess);
  778. void HidpNumberToString(PWCHAR String, USHORT Number, USHORT stringLen);
  779. NTSTATUS GetHIDRawReportDescriptor(FDO_EXTENSION *fdoExt, PIRP irp, ULONG descriptorLen);
  780. VOID WorkItemCallback_CompleteIrpAsynchronously(PVOID context);
  781. NTSTATUS EnqueueInterruptReadIrp(PHIDCLASS_COLLECTION collection, PHIDCLASS_FILE_EXTENSION fileExtension, PIRP Irp);
  782. PIRP DequeueInterruptReadIrp(PHIDCLASS_COLLECTION collection, PHIDCLASS_FILE_EXTENSION fileExtension);
  783. NTSTATUS EnqueuePolledReadIrp(PHIDCLASS_COLLECTION collection, PIRP Irp);
  784. PIRP DequeuePolledReadSystemIrp(PHIDCLASS_COLLECTION collection);
  785. PIRP DequeuePolledReadIrp(PHIDCLASS_COLLECTION collection);
  786. NTSTATUS HidpProcessInterruptReport(PHIDCLASS_COLLECTION collection, PHIDCLASS_FILE_EXTENSION FileExtension, PUCHAR Report, ULONG ReportLength, PIRP *irpToComplete);
  787. VOID HidpFreePowerEventIrp(PHIDCLASS_COLLECTION Collection);
  788. NTSTATUS HidpGetMsGenreDescriptor(IN FDO_EXTENSION *fdoExt, IN OUT PIRP Irp);
  789. NTSTATUS DllUnload(VOID);
  790. NTSTATUS DllInitialize (PUNICODE_STRING RegistryPath);
  791. VOID HidpPowerUpPdos(IN PFDO_EXTENSION fdoExt);
  792. NTSTATUS HidpDelayedPowerPoRequestComplete(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus);
  793. NTSTATUS HidpIrpMajorSystemControl(PHIDCLASS_DEVICE_EXTENSION DeviceObject, PIRP Irp);
  794. NTSTATUS HidpSetWmiDataItem(PDEVICE_OBJECT DeviceObject, PIRP Irp, ULONG GuidIndex, ULONG InstanceIndex, ULONG DataItemId, ULONG BufferSize, PUCHAR Buffer);
  795. NTSTATUS HidpSetWmiDataBlock(PDEVICE_OBJECT DeviceObject, PIRP Irp, ULONG GuidIndex, ULONG InstanceIndex, ULONG BufferSize, PUCHAR Buffer);
  796. NTSTATUS HidpQueryWmiDataBlock( PDEVICE_OBJECT DeviceObject, PIRP Irp, ULONG GuidIndex, ULONG InstanceIndex, ULONG InstanceCount, OUT PULONG InstanceLengthArray, ULONG BufferAvail, PUCHAR Buffer);
  797. NTSTATUS HidpQueryWmiRegInfo( PDEVICE_OBJECT DeviceObject, ULONG *RegFlags, PUNICODE_STRING InstanceName, PUNICODE_STRING *RegistryPath, PUNICODE_STRING MofResourceName, PDEVICE_OBJECT *Pdo);
  798. BOOLEAN HidpCreateRemoteWakeIrp (PDO_EXTENSION *PdoExt);
  799. void HidpCreateRemoteWakeIrpWorker (PDEVICE_OBJECT DeviceObject, PHIDCLASS_WORK_ITEM_DATA ItemData);
  800. NTSTATUS HidpToggleRemoteWake(PDO_EXTENSION *PdoExt, BOOLEAN RemoteWakeState);
  801. #if DBG
  802. VOID InitFdoExtDebugInfo(PHIDCLASS_DEVICE_EXTENSION hidclassExt);
  803. #endif
  804. extern ULONG HidpNextHidNumber;
  805. extern FDO_EXTENSION *allFdoExtensions;
  806. extern KSPIN_LOCK allFdoExtensionsSpinLock;
  807. PVOID
  808. HidpGetSystemAddressForMdlSafe(PMDL MdlAddress);