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.

718 lines
15 KiB

  1. /*++
  2. Copyright (c) 1990, 1991, 1992, 1993, 1994 - 1998 Microsoft Corporation
  3. Module Name:
  4. kbdclass.h
  5. Abstract:
  6. These are the structures and defines that are used in the
  7. keyboard class driver.
  8. Revision History:
  9. --*/
  10. #ifndef _KBDCLASS_
  11. #define _KBDCLASS_
  12. #include <ntddkbd.h>
  13. #include "wmilib.h"
  14. #define KEYBOARD_POOL_TAG 'CdbK'
  15. #undef ExAllocatePool
  16. #define ExAllocatePool(Type, Bytes) ExAllocatePoolWithTag(Type, Bytes, KEYBOARD_POOL_TAG)
  17. //
  18. // Define the default number of elements in the class input data queue.
  19. //
  20. #define DATA_QUEUE_SIZE 100
  21. #define MAXIMUM_PORTS_SERVICED 10
  22. #define NAME_MAX 256
  23. #define DUMP_COUNT 4
  24. #define DEFAULT_DEBUG_LEVEL 0
  25. #define MAX(a,b) (((a) < (b)) ? (b) : (a))
  26. #if DBG
  27. #define KbdPrint(x) KbdDebugPrint x
  28. #else
  29. #define KbdPrint(x)
  30. #endif
  31. #define KEYBOARD_POWER_LIGHT_TIME L"PowerLightTime"
  32. #define KEYBOARD_WAIT_WAKE_ENABLE L"WaitWakeEnabled"
  33. #define KEYBOARD_ALLOW_DISABLE L"AllowDisable"
  34. #define IS_TRUSTED_FILE_FOR_READ(x) (&DriverEntry == (x)->FsContext2)
  35. #define SET_TRUSTED_FILE_FOR_READ(x) ((x)->FsContext2 = &DriverEntry)
  36. #define CLEAR_TRUSTED_FILE_FOR_READ(x) ((x)->FsContext2 = NULL)
  37. #define ALLOW_OVERFLOW TRUE
  38. //
  39. // Port description
  40. //
  41. // Used only with the
  42. // allforoneandoneforall turned off (AKA ConnectOneClassToOnePort
  43. // turned on). This is the file sent to the ports.
  44. //
  45. typedef struct _PORT {
  46. //
  47. // The file Pointer to the port;
  48. //
  49. PFILE_OBJECT File;
  50. //
  51. // The port itself
  52. //
  53. struct _DEVICE_EXTENSION * Port;
  54. //
  55. // Port flags
  56. //
  57. BOOLEAN Enabled;
  58. BOOLEAN Reserved [2];
  59. BOOLEAN Free;
  60. } PORT, *PPORT;
  61. #define PORT_WORKING(port) ((port)->Enabled && !(port)->Free)
  62. //
  63. // Class device extension.
  64. //
  65. typedef struct _DEVICE_EXTENSION {
  66. //
  67. // Back pointer to the Device Object created for this port.
  68. //
  69. PDEVICE_OBJECT Self;
  70. //
  71. // Pointer to the active Class DeviceObject;
  72. // If the AFOAOFA (all for one and one for all) switch is on then this
  73. // points to the device object named as the first keyboard.
  74. //
  75. PDEVICE_OBJECT TrueClassDevice;
  76. //
  77. // The Target port device Object to which all IRPs are sent.
  78. //
  79. PDEVICE_OBJECT TopPort;
  80. //
  81. // The PDO if applicable.
  82. //
  83. PDEVICE_OBJECT PDO;
  84. //
  85. // A remove lock to keep track of outstanding I/Os to prevent the device
  86. // object from leaving before such time as all I/O has been completed.
  87. //
  88. IO_REMOVE_LOCK RemoveLock;
  89. //
  90. // If this port a Plug and Play port
  91. //
  92. BOOLEAN PnP;
  93. BOOLEAN Started;
  94. BOOLEAN AllowDisable;
  95. KSPIN_LOCK WaitWakeSpinLock;
  96. //
  97. // Is the Trusted Subsystem Connected
  98. //
  99. ULONG TrustedSubsystemCount;
  100. //
  101. // Number of input data items currently in the InputData queue.
  102. //
  103. ULONG InputCount;
  104. //
  105. // A Unicode string pointing to the symbolic link for the Device Interface
  106. // of this device object.
  107. //
  108. UNICODE_STRING SymbolicLinkName;
  109. //
  110. // Start of the class input data queue (really a circular buffer).
  111. //
  112. PKEYBOARD_INPUT_DATA InputData;
  113. //
  114. // Insertion pointer for InputData.
  115. //
  116. PKEYBOARD_INPUT_DATA DataIn;
  117. //
  118. // Removal pointer for InputData.
  119. //
  120. PKEYBOARD_INPUT_DATA DataOut;
  121. //
  122. // Keyboard attributes.
  123. //
  124. KEYBOARD_ATTRIBUTES KeyboardAttributes;
  125. //
  126. // A saved state of indicator lights
  127. //
  128. KEYBOARD_INDICATOR_PARAMETERS IndicatorParameters;
  129. //
  130. // Spinlock used to synchronize access to the input data queue and its
  131. // insertion/removal pointers.
  132. //
  133. KSPIN_LOCK SpinLock;
  134. //
  135. // Queue of pended read requests sent to this port. Access to this queue is
  136. // guarded by SpinLock
  137. //
  138. LIST_ENTRY ReadQueue;
  139. //
  140. // Request sequence number (used for error logging).
  141. //
  142. ULONG SequenceNumber;
  143. //
  144. // The "D" and "S" states of the current device
  145. //
  146. DEVICE_POWER_STATE DeviceState;
  147. SYSTEM_POWER_STATE SystemState;
  148. ULONG UnitId;
  149. //
  150. // WMI Information
  151. //
  152. WMILIB_CONTEXT WmiLibInfo;
  153. //
  154. // Mapping of system to device states when a wait wake irp is active
  155. //
  156. DEVICE_POWER_STATE SystemToDeviceState[PowerSystemHibernate];
  157. //
  158. // Minimum amount of power needed to wake the device
  159. //
  160. DEVICE_POWER_STATE MinDeviceWakeState;
  161. //
  162. // Lowest system state that the machine can be in and have the device wake it up
  163. //
  164. SYSTEM_POWER_STATE MinSystemWakeState;
  165. //
  166. // Actual wait wake irp
  167. //
  168. PIRP WaitWakeIrp;
  169. //
  170. // Duplicate wait wake irp getting completed because another was queued.
  171. //
  172. PIRP ExtraWaitWakeIrp;
  173. //
  174. // Target Device Notification Handle
  175. //
  176. PVOID TargetNotifyHandle;
  177. //
  178. // Only used for a legacy port device
  179. //
  180. LIST_ENTRY Link;
  181. //
  182. // Used only for a legacy port device when grand master mode is off
  183. //
  184. PFILE_OBJECT File;
  185. //
  186. // Used for a legacy port device
  187. //
  188. BOOLEAN Enabled;
  189. //
  190. // Indicates whether it is okay to log overflow errors.
  191. //
  192. BOOLEAN OkayToLogOverflow;
  193. //
  194. // Indicates whether it is okay to send wait wake irps down the stack
  195. // (does NOT reflect if the bus can implement or not)
  196. //
  197. BOOLEAN WaitWakeEnabled;
  198. //
  199. // Indicates whether we have received a surprise removed irp
  200. //
  201. BOOLEAN SurpriseRemoved;
  202. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
  203. //
  204. // On some busses, we can power down the bus, but not the system, in this case
  205. // we still need to allow the device to wake said bus, therefore
  206. // waitwake-supported should not rely on systemstate.
  207. //
  208. // #define WAITWAKE_SUPPORTED(port) ((port)->MinDeviceWakeState > PowerDeviceUnspecified) && \
  209. // (port)->MinSystemWakeState > PowerSystemWorking)
  210. #define WAITWAKE_SUPPORTED(port) ((port)->MinDeviceWakeState > PowerDeviceD0 && \
  211. (port)->MinSystemWakeState > PowerSystemWorking)
  212. // #define WAITWAKE_ON(port) ((port)->WaitWakeIrp != 0)
  213. #define WAITWAKE_ON(port) \
  214. (InterlockedCompareExchangePointer(&(port)->WaitWakeIrp, NULL, NULL) != NULL)
  215. #define SHOULD_SEND_WAITWAKE(port) (WAITWAKE_SUPPORTED(port) && \
  216. !WAITWAKE_ON(port) && \
  217. KeyboardClassCheckWaitWakeEnabled(port))
  218. //
  219. // Global shared data
  220. //
  221. typedef struct _GLOBALS {
  222. //
  223. // Declare the global debug flag for this driver.
  224. //
  225. ULONG Debug;
  226. //
  227. // If ConnectOneClassToOnePort is off aka we want "All for one and one for
  228. // all behavior" then we need to create the one Master DO to which all
  229. // the goods go.
  230. //
  231. PDEVICE_EXTENSION GrandMaster;
  232. //
  233. // List of ClassDevices that associated with the same name
  234. // aka the all for one and one for all flag is set
  235. //
  236. PPORT AssocClassList;
  237. ULONG NumAssocClass;
  238. LONG Opens;
  239. ULONG NumberLegacyPorts;
  240. FAST_MUTEX Mutex;
  241. //
  242. // Specifies the type of class-port connection to make. A '1'
  243. // indicates a 1:1 relationship between class device objects and
  244. // port device objects. A '0' indicates a 1:many relationship.
  245. //
  246. ULONG ConnectOneClassToOnePort;
  247. //
  248. // When kbdclass receives an output command (EG set LEDs) this flag
  249. // instructs it to transmit that command to all attached ports,
  250. // regardless of the unit ID which was specified.
  251. //
  252. ULONG SendOutputToAllPorts;
  253. //
  254. // Number of port drivers serviced by this class driver.
  255. //
  256. ULONG PortsServiced;
  257. //
  258. //
  259. // IntialDevice Extension
  260. //
  261. DEVICE_EXTENSION InitExtension;
  262. //
  263. // A list of the registry path to the service parameters.
  264. //
  265. UNICODE_STRING RegistryPath;
  266. //
  267. // The base name for all class objects created as mice.
  268. //
  269. UNICODE_STRING BaseClassName;
  270. WCHAR BaseClassBuffer[NAME_MAX];
  271. //
  272. // Linked list of all the legacy device objects that were created in
  273. // DriverEntry or FindMorePorts. We maintain this list so we can delete
  274. // them when we unload.
  275. //
  276. LIST_ENTRY LegacyDeviceList;
  277. } GLOBALS, *PGLOBALS;
  278. typedef struct _KBD_CALL_ALL_PORTS {
  279. //
  280. // Number of ports to call
  281. //
  282. ULONG Len;
  283. //
  284. // Current Called port;
  285. //
  286. ULONG Current;
  287. //
  288. // Array of Ports to call
  289. //
  290. PORT Port[];
  291. } KBD_CALL_ALL_PORTS, *PKBD_CALL_ALL_PORTS;
  292. //
  293. // Keyboard configuration information.
  294. //
  295. typedef struct _KEYBOARD_CONFIGURATION_INFORMATION {
  296. //
  297. // Maximum size of class input data queue, in bytes.
  298. //
  299. ULONG DataQueueSize;
  300. } KEYBOARD_CONFIGURATION_INFORMATION, *PKEYBOARD_CONFIGURATION_INFORMATION;
  301. typedef struct _KEYBOARD_WORK_ITEM_DATA {
  302. PIRP Irp;
  303. PDEVICE_EXTENSION Data;
  304. PIO_WORKITEM Item;
  305. BOOLEAN WaitWakeState;
  306. } KEYBOARD_WORK_ITEM_DATA, *PKEYBOARD_WORK_ITEM_DATA;
  307. #define KeyboardClassDeleteLegacyDevice(de) \
  308. { \
  309. if (de->InputData) { \
  310. ExFreePool (de->InputData); \
  311. de->InputData = de->DataIn = de->DataOut = NULL; \
  312. } \
  313. IoDeleteDevice (de->Self); \
  314. de = NULL; \
  315. }
  316. //
  317. // Function Declarations
  318. //
  319. NTSTATUS
  320. KeyboardAddDeviceEx(
  321. IN PDEVICE_EXTENSION NewDeviceObject,
  322. IN PWCHAR FullClassName,
  323. IN PFILE_OBJECT File
  324. );
  325. NTSTATUS
  326. KeyboardAddDevice(
  327. IN PDRIVER_OBJECT DriverObject,
  328. IN PDEVICE_OBJECT PhysicalDeviceObject
  329. );
  330. void
  331. KeyboardClassGetWaitWakeEnableState(
  332. IN PDEVICE_EXTENSION Data
  333. );
  334. NTSTATUS
  335. DriverEntry(
  336. IN PDRIVER_OBJECT DriverObject,
  337. IN PUNICODE_STRING RegistryPath
  338. );
  339. NTSTATUS
  340. KeyboardClassPassThrough(
  341. IN PDEVICE_OBJECT DeviceObject,
  342. IN PIRP Irp
  343. );
  344. VOID
  345. KeyboardClassCancel(
  346. IN PDEVICE_OBJECT DeviceObject,
  347. IN PIRP Irp
  348. );
  349. NTSTATUS
  350. KeyboardClassCleanup(
  351. IN PDEVICE_OBJECT DeviceObject,
  352. IN PIRP Irp
  353. );
  354. NTSTATUS
  355. KeyboardClassDeviceControl(
  356. IN PDEVICE_OBJECT DeviceObject,
  357. IN PIRP Irp
  358. );
  359. NTSTATUS
  360. KeyboardClassFlush(
  361. IN PDEVICE_OBJECT DeviceObject,
  362. IN PIRP Irp
  363. );
  364. NTSTATUS
  365. KeyboardClassCreate(
  366. IN PDEVICE_OBJECT DeviceObject,
  367. IN PIRP Irp
  368. );
  369. NTSTATUS
  370. KeyboardClassClose(
  371. IN PDEVICE_OBJECT DeviceObject,
  372. IN PIRP Irp
  373. );
  374. NTSTATUS
  375. KeyboardClassRead(
  376. IN PDEVICE_OBJECT DeviceObject,
  377. IN PIRP Irp
  378. );
  379. NTSTATUS
  380. KeyboardClassReadCopyData(
  381. IN PDEVICE_EXTENSION DeviceExtension,
  382. IN PIRP Irp
  383. );
  384. PIRP
  385. KeyboardClassDequeueRead(
  386. IN PDEVICE_EXTENSION DeviceExtension
  387. );
  388. PIRP
  389. KeyboardClassDequeueReadByFileObject(
  390. IN PDEVICE_EXTENSION DeviceExtension,
  391. IN PFILE_OBJECT FileObject
  392. );
  393. BOOLEAN
  394. KeyboardClassCheckWaitWakeEnabled(
  395. IN PDEVICE_EXTENSION Data
  396. );
  397. BOOLEAN
  398. KeyboardClassCreateWaitWakeIrp (
  399. IN PDEVICE_EXTENSION Data
  400. );
  401. NTSTATUS
  402. KeyboardClassPower(
  403. IN PDEVICE_OBJECT DeviceObject,
  404. IN PIRP Irp
  405. );
  406. NTSTATUS
  407. KeyboardSendIrpSynchronously (
  408. IN PDEVICE_OBJECT DeviceObject,
  409. IN PIRP Irp,
  410. IN BOOLEAN CopyToNext
  411. );
  412. NTSTATUS
  413. KeyboardPnP (
  414. IN PDEVICE_OBJECT DeviceObject,
  415. IN PIRP Irp
  416. );
  417. VOID
  418. KeyboardClassServiceCallback(
  419. IN PDEVICE_OBJECT DeviceObject,
  420. IN PKEYBOARD_INPUT_DATA InputDataStart,
  421. IN PKEYBOARD_INPUT_DATA InputDataEnd,
  422. IN OUT PULONG InputDataConsumed
  423. );
  424. VOID
  425. KeyboardClassStartIo(
  426. IN PDEVICE_OBJECT DeviceObject,
  427. IN PIRP Irp
  428. );
  429. VOID
  430. KeyboardClassUnload(
  431. IN PDRIVER_OBJECT DriverObject
  432. );
  433. BOOLEAN
  434. KbdCancelRequest(
  435. IN PVOID Context
  436. );
  437. VOID
  438. KbdConfiguration();
  439. NTSTATUS
  440. KbdCreateClassObject(
  441. IN PDRIVER_OBJECT DriverObject,
  442. IN PDEVICE_EXTENSION TmpDeviceExtension,
  443. OUT PDEVICE_OBJECT * ClassDeviceObject,
  444. OUT PWCHAR * FullDeviceName,
  445. IN BOOLEAN Legacy
  446. );
  447. VOID
  448. KbdDebugPrint(
  449. ULONG DebugPrintLevel,
  450. PCCHAR DebugMessage,
  451. ...
  452. );
  453. NTSTATUS
  454. KbdDeterminePortsServiced(
  455. IN PUNICODE_STRING BasePortName,
  456. IN OUT PULONG NumberPortsServiced
  457. );
  458. NTSTATUS
  459. KbdDeviceMapQueryCallback(
  460. IN PWSTR ValueName,
  461. IN ULONG ValueType,
  462. IN PVOID ValueData,
  463. IN ULONG ValueLength,
  464. IN PVOID Context,
  465. IN PVOID EntryContext
  466. );
  467. NTSTATUS
  468. KbdEnableDisablePort(
  469. IN BOOLEAN EnableFlag,
  470. IN PIRP Irp,
  471. IN PDEVICE_EXTENSION Port,
  472. IN PFILE_OBJECT * File
  473. );
  474. NTSTATUS
  475. KbdSendConnectRequest(
  476. IN PDEVICE_EXTENSION ClassData,
  477. IN PVOID ServiceCallback
  478. );
  479. VOID
  480. KbdInitializeDataQueue(
  481. IN PVOID Context
  482. );
  483. NTSTATUS
  484. KeyboardCallAllPorts (
  485. PDEVICE_OBJECT Device,
  486. PIRP Irp,
  487. PVOID
  488. );
  489. NTSTATUS
  490. KeyboardClassEnableGlobalPort(
  491. IN PDEVICE_EXTENSION Port,
  492. IN BOOLEAN Enabled
  493. );
  494. NTSTATUS
  495. KeyboardClassPlugPlayNotification(
  496. IN PVOID NotificationStructure,
  497. IN PDEVICE_EXTENSION Port
  498. );
  499. VOID
  500. KeyboardClassLogError(
  501. PVOID Object,
  502. ULONG ErrorCode,
  503. ULONG UniqueErrorValue,
  504. NTSTATUS FinalStatus,
  505. ULONG DumpCount,
  506. ULONG *DumpData,
  507. UCHAR MajorFunction
  508. );
  509. BOOLEAN
  510. KeyboardClassCreateWaitWakeIrp (
  511. IN PDEVICE_EXTENSION Data
  512. );
  513. void
  514. KeyboardClassCreateWaitWakeIrpWorker (
  515. IN PDEVICE_OBJECT DeviceObject,
  516. IN PKEYBOARD_WORK_ITEM_DATA ItemData
  517. );
  518. NTSTATUS
  519. KeyboardToggleWaitWake(
  520. PDEVICE_EXTENSION Data,
  521. BOOLEAN WaitWakeState
  522. );
  523. void
  524. KeyboardToggleWaitWakeWorker (
  525. IN PDEVICE_OBJECT DeviceObject,
  526. PKEYBOARD_WORK_ITEM_DATA ItemData
  527. );
  528. NTSTATUS
  529. KeyboardQueryDeviceKey (
  530. IN HANDLE Handle,
  531. IN PWCHAR ValueNameString,
  532. OUT PVOID Data,
  533. IN ULONG DataLength
  534. );
  535. VOID
  536. KeyboardClassFindMorePorts(
  537. PDRIVER_OBJECT DriverObject,
  538. PVOID Context,
  539. ULONG Count
  540. );
  541. NTSTATUS
  542. KeyboardClassSystemControl(
  543. IN PDEVICE_OBJECT DeviceObject,
  544. IN PIRP Irp
  545. );
  546. NTSTATUS
  547. KeyboardClassSetWmiDataItem(
  548. IN PDEVICE_OBJECT DeviceObject,
  549. IN PIRP Irp,
  550. IN ULONG GuidIndex,
  551. IN ULONG InstanceIndex,
  552. IN ULONG DataItemId,
  553. IN ULONG BufferSize,
  554. IN PUCHAR Buffer
  555. );
  556. NTSTATUS
  557. KeyboardClassSetWmiDataBlock(
  558. IN PDEVICE_OBJECT DeviceObject,
  559. IN PIRP Irp,
  560. IN ULONG GuidIndex,
  561. IN ULONG InstanceIndex,
  562. IN ULONG BufferSize,
  563. IN PUCHAR Buffer
  564. );
  565. NTSTATUS
  566. KeyboardClassQueryWmiDataBlock(
  567. IN PDEVICE_OBJECT DeviceObject,
  568. IN PIRP Irp,
  569. IN ULONG GuidIndex,
  570. IN ULONG InstanceIndex,
  571. IN ULONG InstanceCount,
  572. IN OUT PULONG InstanceLengthArray,
  573. IN ULONG BufferAvail,
  574. OUT PUCHAR Buffer
  575. );
  576. NTSTATUS
  577. KeyboardClassQueryWmiRegInfo(
  578. IN PDEVICE_OBJECT DeviceObject,
  579. OUT ULONG *RegFlags,
  580. OUT PUNICODE_STRING InstanceName,
  581. OUT PUNICODE_STRING *RegistryPath,
  582. OUT PUNICODE_STRING MofResourceName,
  583. OUT PDEVICE_OBJECT *Pdo
  584. );
  585. #endif // _KBDCLASS_