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.

412 lines
12 KiB

  1. /*++ BUILD Version: 0001 // Increment this if a change has global effects
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. ntdd8042.h
  5. Abstract:
  6. This is the include file that defines all constants and types for hooking
  7. i8042 devices.
  8. Author:
  9. Doron J. Holan (doronh) 17-Dec-1997
  10. Revision History:
  11. --*/
  12. #ifndef _NTDD8042_
  13. #define _NTDD8042_
  14. #if _MSC_VER > 1000
  15. #pragma once
  16. #endif
  17. #ifdef __cplusplus
  18. extern "C" {
  19. #endif
  20. //
  21. // Internal IOCTLs used to find who is in the chain of notification
  22. //
  23. #define IOCTL_INTERNAL_I8042_HOOK_KEYBOARD CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0FF0, METHOD_NEITHER, FILE_ANY_ACCESS)
  24. #define IOCTL_INTERNAL_I8042_HOOK_MOUSE CTL_CODE(FILE_DEVICE_MOUSE, 0x0FF0, METHOD_NEITHER, FILE_ANY_ACCESS)
  25. //
  26. // Internal IOCTLs used to write data to either device
  27. //
  28. // The IOCTL will be completed when the write has been completed. If the write
  29. // time out, the Cancel Routine of the Irp will be ignored and the Irp will still
  30. // be completed successfully with a status of STATUS_IO_TIMEOUT instead of
  31. // STATUS_SUCCESS
  32. //
  33. #define IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0FF1, METHOD_NEITHER, FILE_ANY_ACCESS)
  34. #define IOCTL_INTERNAL_I8042_MOUSE_WRITE_BUFFER CTL_CODE(FILE_DEVICE_MOUSE, 0x0FF1, METHOD_NEITHER, FILE_ANY_ACCESS)
  35. //
  36. // Can only be sent down the keyboard stack
  37. //
  38. #define IOCTL_INTERNAL_I8042_CONTROLLER_WRITE_BUFFER CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0FF2, METHOD_NEITHER, FILE_ANY_ACCESS)
  39. //
  40. // The keyboard / mouse will send this down the stack so that the upper device
  41. // filter has a device object to synch against.
  42. //
  43. #define IOCTL_INTERNAL_I8042_KEYBOARD_START_INFORMATION CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0FF3, METHOD_NEITHER, FILE_ANY_ACCESS)
  44. #define IOCTL_INTERNAL_I8042_MOUSE_START_INFORMATION CTL_CODE(FILE_DEVICE_MOUSE, 0x0FF3, METHOD_NEITHER, FILE_ANY_ACCESS)
  45. //
  46. // Valid bits for the PowerCapabilities REG_DWORD that can be put in the devnode
  47. // indicating the presence of their respecitve power keys on the device
  48. //
  49. #define I8042_POWER_SYS_BUTTON 0x0001
  50. #define I8042_SLEEP_SYS_BUTTON 0x0002
  51. #define I8042_WAKE_SYS_BUTTON 0x0004
  52. #define I8042_SYS_BUTTONS (I8042_POWER_SYS_BUTTON | \
  53. I8042_SLEEP_SYS_BUTTON | \
  54. I8042_WAKE_SYS_BUTTON)
  55. //
  56. // Synchronous reads and writes during kb initialization
  57. //
  58. #if 0
  59. typedef enum _I8042_PORT_TYPE {
  60. PortTypeData = 0,
  61. PortTypeCommand
  62. } I8042_PORT_TYPE;
  63. #endif
  64. typedef
  65. NTSTATUS
  66. (*PI8042_SYNCH_READ_PORT) (
  67. IN PVOID Context,
  68. PUCHAR Value,
  69. BOOLEAN WaitForACK
  70. );
  71. /*++
  72. Routine Description:
  73. This routine sends a command or data byte to the keyboard
  74. in polling mode. It waits for acknowledgment and resends
  75. the command/data if WaitForACK is true.
  76. Arguments:
  77. Context - Function specific context
  78. PortType - If PortTypeCommand, send the byte to the command register,
  79. otherwise send it to the data register.
  80. WaitForACK - If true, wait for an ACK back from the hardware.
  81. AckDeviceType - Indicates which device we expect to get the ACK back
  82. from.
  83. Value - The byte to send to the hardware.
  84. Return Value:
  85. STATUS_IO_TIMEOUT - The hardware was not ready for input or did not
  86. respond.
  87. STATUS_SUCCESS - The byte was successfully sent to the hardware.
  88. --*/
  89. typedef
  90. NTSTATUS
  91. (*PI8042_SYNCH_WRITE_PORT) (
  92. IN PVOID Context,
  93. UCHAR Value,
  94. BOOLEAN WaitForACK
  95. );
  96. //
  97. // These functions (PI8042_ISR_WRITE_PORT, PI8042_QUEUE_PACKET) are only valid
  98. // when called with the context of the ISR hook
  99. //
  100. typedef
  101. VOID
  102. (*PI8042_ISR_WRITE_PORT) (
  103. IN PVOID Context,
  104. IN UCHAR Value
  105. );
  106. //
  107. // Call this function when an input packet has been fully formed and is ready to
  108. // be queued to the class driver above of us in the stack
  109. //
  110. typedef
  111. VOID
  112. (*PI8042_QUEUE_PACKET) (
  113. IN PVOID Context
  114. );
  115. //
  116. // Current state of writing to a device
  117. //
  118. typedef enum _TRANSMIT_STATE {
  119. Idle = 0,
  120. SendingBytes
  121. } TRANSMIT_STATE;
  122. //
  123. // Current state of writing to the device. If State != Idle, then a write is in
  124. // progress
  125. //
  126. typedef struct _OUTPUT_PACKET {
  127. PUCHAR Bytes;
  128. ULONG CurrentByte;
  129. ULONG ByteCount;
  130. TRANSMIT_STATE State;
  131. } OUTPUT_PACKET, *POUTPUT_PACKET;
  132. typedef enum _MOUSE_STATE {
  133. MouseIdle, // expecting byte 1
  134. XMovement, // expecting byte 2
  135. YMovement, // expecting byte 3
  136. ZMovement, // expecting byte 4 (if a wheel mouse)
  137. MouseExpectingACK, // expecting ACK from Enable Mouse cmd
  138. MouseResetting // reset substate
  139. } MOUSE_STATE, *PMOUSE_STATE;
  140. /*--
  141. Normal reset process
  142. Step Transition into
  143. Send Reset to mouse ExpectingReset (ie, 0xAA)
  144. Got reset ExpectingResetId
  145. Got reset id, send get device id ExpectingGetDeviceIdACK
  146. Got get dev id ack, ExpectingGetDeviceIdValue
  147. Got dev id ExpectingSetResolutionACK
  148. Got ACK for set res ExpectingSetResolutionValueAck
  149. Got ACK for value ExpectingSetScaling1to1ACK
  150. Got ACK for set scaling ExpectingSetScaling1to1ACK2
  151. Got ACK for set scaling ExpectingSetScaling1to1ACK3
  152. EnableWheelDetection (via registry) ==
  153. 0 send set sampling rate,
  154. ExpectingSetSamplingRateDefaultACK
  155. 1 StartPnPIdDetection
  156. 2 EnableWheel
  157. StartPnPIdDetection, send series ExpectingPnpIdByte1 after setting complete
  158. of set sampling rate commands
  159. ExpectingPnpIdByte7 compare pnp id to list, if valid,
  160. EnableWheel, else set def sampling rate
  161. EnableWheel, send series of send get device id after done,
  162. set sampling rate commands ExpectingSetSamplingRateDefaultACK
  163. got set sampling ack send sampling value
  164. got sampling value ack mouse idle
  165. ++*/
  166. typedef enum _MOUSE_RESET_SUBSTATE {
  167. ExpectingReset = 0,
  168. ExpectingResetId, /* 1 */
  169. ExpectingGetDeviceIdACK, /* 2 */
  170. ExpectingGetDeviceIdValue, /* 3 */
  171. ExpectingSetResolutionDefaultACK, /* 4 */
  172. ExpectingSetResolutionDefaultValueACK, /* 5 */
  173. ExpectingSetResolutionACK, /* 6 */
  174. ExpectingSetResolutionValueACK, /* 7 */
  175. ExpectingSetScaling1to1ACK, /* 8 */
  176. ExpectingSetScaling1to1ACK2, /* 9 */
  177. ExpectingSetScaling1to1ACK3, /* 10 */
  178. ExpectingReadMouseStatusACK, /* 11 */
  179. ExpectingReadMouseStatusByte1, /* 12 */
  180. ExpectingReadMouseStatusByte2, /* 13 */
  181. ExpectingReadMouseStatusByte3, /* 14 */
  182. StartPnPIdDetection, /* 15 */
  183. ExpectingLoopSetSamplingRateACK, /* 16 */
  184. ExpectingLoopSetSamplingRateValueACK, /* 17 */
  185. ExpectingPnpIdByte1, /* 18 */
  186. ExpectingPnpIdByte2, /* 19 */
  187. ExpectingPnpIdByte3, /* 20 */
  188. ExpectingPnpIdByte4, /* 21 */
  189. ExpectingPnpIdByte5, /* 22 */
  190. ExpectingPnpIdByte6, /* 23 */
  191. ExpectingPnpIdByte7, /* 24 */
  192. EnableWheel, /* 25 */
  193. Enable5Buttons, /* 26 */
  194. ExpectingGetDeviceId2ACK, /* 27 */
  195. ExpectingGetDeviceId2Value, /* 28 */
  196. ExpectingSetSamplingRateACK, /* 29 */
  197. ExpectingSetSamplingRateValueACK, /* 30 */
  198. ExpectingEnableACK, /* 31 */
  199. ExpectingFinalResolutionACK, /* 32 */
  200. ExpectingFinalResolutionValueACK, /* 33 */
  201. ExpectingGetDeviceIdDetectACK, /* 34 */
  202. ExpectingGetDeviceIdDetectValue, /* 35 */
  203. CustomHookStateMinimum = 100,
  204. CustomHookStateMaximum = 999,
  205. I8042ReservedMinimum = 1000
  206. } MOUSE_RESET_SUBSTATE, *PMOUSE_RESET_SUBSTATE;
  207. /*--
  208. IsrContext -- user provided context
  209. CurrentInput -- current packet to being assembled
  210. StatusByte -- byte reported by the command port
  211. Byte -- byte reported by the mouse (ie, the data port)
  212. MouseState -- current state of the i8042prt ISR
  213. ResetSubState -- current reset sub state, only valid when
  214. MouseState == MouseResetting (otherwise null)
  215. ContinueProcessing -- if TRUE, the i8042prt ISR will continue executing after
  216. calling the hook
  217. ++*/
  218. typedef
  219. BOOLEAN
  220. (*PI8042_MOUSE_ISR) (
  221. PVOID IsrContext,
  222. PMOUSE_INPUT_DATA CurrentInput,
  223. POUTPUT_PACKET CurrentOutput,
  224. UCHAR StatusByte,
  225. PUCHAR Byte,
  226. PBOOLEAN ContinueProcessing,
  227. PMOUSE_STATE MouseState,
  228. PMOUSE_RESET_SUBSTATE ResetSubState
  229. );
  230. typedef struct _INTERNAL_I8042_HOOK_MOUSE {
  231. //
  232. // Context variable for IsrRoutine, CancelRoutine
  233. //
  234. OUT PVOID Context;
  235. //
  236. // Routine to call when a byte is received via the interrupt
  237. //
  238. OUT PI8042_MOUSE_ISR IsrRoutine;
  239. //
  240. // Write function, will automatically write to the command port saying the
  241. // next byte is directed towards the auxilliary device.
  242. //
  243. // NB: May only called within the context of the IsrRoutine provided above
  244. // The mouse's response to the write will passed to the IsrRoutine when
  245. // it is received (ie, if 0xF4 (enable) was written using this function,
  246. // an 0xFA (ACK) will be passed to IsrRoutine if the enable was
  247. // successful)
  248. //
  249. IN PI8042_ISR_WRITE_PORT IsrWritePort;
  250. //
  251. // Queue the current packet (ie the one passed into the isr callback hook)
  252. // to be reported to the class driver
  253. //
  254. IN PI8042_QUEUE_PACKET QueueMousePacket;
  255. //
  256. // Context for IsrWritePort, QueueMousePacket
  257. //
  258. IN PVOID CallContext;
  259. } INTERNAL_I8042_HOOK_MOUSE, *PINTERNAL_I8042_HOOK_MOUSE;
  260. //
  261. // Define the keyboard scan code input states.
  262. //
  263. typedef enum _KEYBOARD_SCAN_STATE {
  264. Normal,
  265. GotE0,
  266. GotE1
  267. } KEYBOARD_SCAN_STATE, *PKEYBOARD_SCAN_STATE;
  268. typedef
  269. NTSTATUS
  270. (*PI8042_KEYBOARD_INITIALIZATION_ROUTINE) (
  271. IN PVOID InitializationContext,
  272. IN PVOID SynchFuncContext,
  273. IN PI8042_SYNCH_READ_PORT ReadPort,
  274. IN PI8042_SYNCH_WRITE_PORT WritePort,
  275. OUT PBOOLEAN TurnTranslationOn
  276. );
  277. typedef
  278. BOOLEAN
  279. (*PI8042_KEYBOARD_ISR) (
  280. PVOID IsrContext,
  281. PKEYBOARD_INPUT_DATA CurrentInput,
  282. POUTPUT_PACKET CurrentOutput,
  283. UCHAR StatusByte,
  284. PUCHAR Byte,
  285. PBOOLEAN ContinueProcessing,
  286. PKEYBOARD_SCAN_STATE ScanState
  287. );
  288. typedef struct _INTERNAL_I8042_HOOK_KEYBOARD {
  289. //
  290. // Context variable for all callback routines
  291. //
  292. OUT PVOID Context;
  293. //
  294. // Routine to call after the mouse is reset
  295. //
  296. OUT PI8042_KEYBOARD_INITIALIZATION_ROUTINE InitializationRoutine;
  297. //
  298. // Routine to call when a byte is received via the interrupt
  299. //
  300. OUT PI8042_KEYBOARD_ISR IsrRoutine;
  301. //
  302. // Write function
  303. //
  304. IN PI8042_ISR_WRITE_PORT IsrWritePort;
  305. //
  306. // Queue the current packet (ie the one passed into the isr callback hook)
  307. // to be reported to the class driver
  308. //
  309. IN PI8042_QUEUE_PACKET QueueKeyboardPacket;
  310. //
  311. // Context for IsrWritePort, QueueKeyboardPacket
  312. //
  313. IN PVOID CallContext;
  314. } INTERNAL_I8042_HOOK_KEYBOARD, *PINTERNAL_I8042_HOOK_KEYBOARD;
  315. typedef struct _INTERNAL_I8042_START_INFORMATION {
  316. //
  317. // Size of this structure
  318. //
  319. ULONG Size;
  320. //
  321. // Interrupt object for the device. Should only be used for calls to
  322. // KeSynchronizeExecution
  323. //
  324. PKINTERRUPT InterruptObject;
  325. //
  326. // Future use
  327. //
  328. ULONG Reserved[8];
  329. } INTERNAL_I8042_START_INFORMATION, *PINTERNAL_I8042_START_INFORMATION;
  330. #ifdef __cplusplus
  331. }
  332. #endif
  333. #endif // _NTDD8042_