/Utilities/AHK HID Analyzer.ahk

https://github.com/xToK3x/ScottoHotKey · AutoHotKey · 300 lines · 221 code · 49 blank · 30 comment · 27 complexity · e81e5f91b89f345a6ad2e62d842cfbec MD5 · raw file

  1. ; Source: http://www.autohotkey.com/forum/topic39574.html
  2. ;
  3. ; List all of the "Raw Input" devices available for use and allow
  4. ; capture of output
  5. ;
  6. ; There may be more than one 'raw' device per device actually attached
  7. ; to the system. This is because these devices generally represent
  8. ; "HID Collections", and there may be more than one HID collection per
  9. ; USB device. For example, the Natural Keyboard 4000 supports a normal
  10. ; keyboard HID collection, plus an additional HID collection that can
  11. ; be used for the zoom slider and other important buttons
  12. ; Replace any previous instance
  13. #SingleInstance force
  14. DetectHiddenWindows, on
  15. OnMessage(0x00FF, "InputMessage")
  16. SizeofRawInputDeviceList := 8
  17. SizeofRidDeviceInfo := 32
  18. SizeofRawInputDevice := 12
  19. RIM_TYPEMOUSE := 0
  20. RIM_TYPEKEYBOARD := 1
  21. RIM_TYPEHID := 2
  22. RIDI_DEVICENAME := 0x20000007
  23. RIDI_DEVICEINFO := 0x2000000b
  24. RIDEV_INPUTSINK := 0x00000100
  25. RID_INPUT := 0x10000003
  26. DoCapture := 0
  27. DoCaptureHID := 0
  28. Gui, Add, Edit, HScroll w400 h140 x10 y10 vInfoOut -Wrap ReadOnly HwndInfoHwnd
  29. Gui, Add, Edit, HScroll w400 h440 x10 y150 vEditOut -Wrap ReadOnly HwndEditHwnd
  30. Gui, Add, Edit, VScroll HScroll w400 h600 x420 y10 vCodeOut -Wrap HwndCodeHwnd
  31. Gui, Add, Button, Default gCapture vCaptureButton x10 y620, &Capture ALL Devices
  32. Gui, Add, Button, gCaptureHID vCaptureHIDButton x+10, Capture &HID Devices Only
  33. GUI, Add, Button, gClearOutput x+80, Clear Output
  34. Gui, Show, , HIDList
  35. HWND := WinExist("HIDList")
  36. Res := DllCall("GetRawInputDeviceList", UInt, 0, "UInt *", Count, UInt, SizeofRawInputDeviceList)
  37. InfoOutput("There are " . Count . " raw input devices`r`n`r`n")
  38. CodeOutput("#Include AHK HID Register.ahk`r`n")
  39. VarSetCapacity(RawInputList, SizeofRawInputDeviceList * Count)
  40. Res := DllCall("GetRawInputDeviceList", UInt, &RawInputList, "UInt *", Count, UInt, SizeofRawInputDeviceList)
  41. MouseRegistered := 0
  42. KeyboardRegistered := 0
  43. Loop %Count% {
  44. Handle := NumGet(RawInputList, (A_Index - 1) * SizeofRawInputDeviceList)
  45. Type := NumGet(RawInputList, (A_Index - 1) * SizeofRawInputDeviceList + 4)
  46. if (Type = RIM_TYPEMOUSE)
  47. TypeName := "RIM_TYPEMOUSE"
  48. else if (Type = RIM_TYPEKEYBOARD)
  49. TypeName := "RIM_TYPEKEYBOARD"
  50. else if (Type = RIM_TYPEHID)
  51. TypeName := "RIM_TYPEHID"
  52. else
  53. TypeName := "RIM_OTHER"
  54. ; Get the name length
  55. Res := DllCall("GetRawInputDeviceInfo", UInt, Handle, UInt, RIDI_DEVICENAME, UInt, 0, "UInt *", Length)
  56. ; Get the name
  57. VarSetCapacity(Name, Length + 2)
  58. Res := DllCall("GetRawInputDeviceInfo", UInt, Handle, UInt, RIDI_DEVICENAME, "Str", Name, "UInt *", Length)
  59. ; Get the extended info
  60. VarSetCapacity(Info, SizeofRidDeviceInfo)
  61. NumPut(SizeofRidDeviceInfo, Info, 0)
  62. Length := SizeofRidDeviceInfo
  63. Res := DllCall("GetRawInputDeviceInfo", UInt, Handle, UInt, RIDI_DEVICEINFO, UInt, &Info, "UInt *", SizeofRidDeviceInfo)
  64. ; Append some of the obtained data to the output window:
  65. output = Device #%A_Index%:`t Handle: %Handle% `t Type: %Type% (%TypeName%) `t
  66. InfoOutput(output)
  67. if (Type = RIM_TYPEMOUSE)
  68. InfoOutput("Buttons: " . NumGet(Info, 4 * 3) . "`t Sample rate " . NumGet(Info, 4 * 4))
  69. else if (Type = RIM_TYPEKEYBOARD)
  70. InfoOutput("Mode: " . NumGet(Info, 4 * 4) . "`t Function keys: " . NumGet(Info, 4 * 5))
  71. else if (Type = RIM_TYPEHID)
  72. {
  73. InfoOutput("VendorID: " . NumGet(Info, 4 * 2) . "`t ProductID: " . NumGet(Info, 4 * 3) . "`t Version: " . NumGet(Info, 4 * 4))
  74. UsagePage := NumGet(Info, (4 * 5), "UShort")
  75. Usage := NumGet(Info, (4 * 5) + 2, "UShort")
  76. InfoOutput("`t UsagePage: " . UsagePage . "`t Usage: " . Usage)
  77. CodeOutput("RegisterRawInputDevice(" . UsagePage . ", " . Usage . ") `; Registers the device with the Handle`: " . Handle . "`r`n")
  78. }
  79. InfoOutput("`t`t`t Name " . Name . "`r`n")
  80. ; Keyboards are always Usage 6, Usage Page 1, Mice are Usage 2, Usage Page 1,
  81. ; HID devices specify their top level collection in the info block
  82. VarSetCapacity(RawDevice, SizeofRawInputDevice)
  83. NumPut(RIDEV_INPUTSINK, RawDevice, 4)
  84. NumPut(HWND, RawDevice, 8)
  85. DoRegister := 0
  86. if (Type = RIM_TYPEMOUSE && MouseRegistered = 0)
  87. {
  88. DoRegister := 1
  89. ; Mice are Usage 2, Usage Page 1
  90. NumPut(1, RawDevice, 0, "UShort")
  91. NumPut(2, RawDevice, 2, "UShort")
  92. MouseRegistered := 1
  93. }
  94. else if (Type = RIM_TYPEKEYBOARD && KeyboardRegistered = 0)
  95. {
  96. DoRegister := 1
  97. ; Keyboards are always Usage 6, Usage Page 1
  98. NumPut(1, RawDevice, 0, "UShort")
  99. NumPut(6, RawDevice, 2, "UShort")
  100. KeyboardRegistered := 1
  101. }
  102. else if (Type = RIM_TYPEHID)
  103. {
  104. DoRegister := 1
  105. NumPut(UsagePage, RawDevice, 0, "UShort")
  106. NumPut(Usage, RawDevice, 2, "UShort")
  107. }
  108. if (DoRegister)
  109. {
  110. Res := DllCall("RegisterRawInputDevices", "UInt", &RawDevice, UInt, 1, UInt, SizeofRawInputDevice)
  111. ;~ if (Res = 0)
  112. ;~ InfoOutput("Failed to register for this device!`r`n")
  113. ;~ else
  114. ;~ InfoOutput("Registered for this device`r`n")
  115. }
  116. }
  117. Count := 1
  118. InputMessage(wParam, lParam, msg, hwnd)
  119. {
  120. global DoCapture, DoCaptureHID
  121. global RIM_TYPEMOUSE, RIM_TYPEKEYBOARD, RIM_TYPEHID
  122. global RID_INPUT
  123. if (DoCapture = 0)
  124. return
  125. Res := DllCall("GetRawInputData", UInt, lParam, UInt, RID_INPUT, UInt, 0, "UInt *", Size, UInt, 16)
  126. VarSetCapacity(Buffer, Size)
  127. Res := DllCall("GetRawInputData", UInt, lParam, UInt, RID_INPUT, UInt, &Buffer, "UInt *", Size, UInt, 16)
  128. ; AppendOutput(Mem2Hex(&Buffer, Size))
  129. Type := NumGet(Buffer, 0 * 4)
  130. Size := NumGet(Buffer, 1 * 4)
  131. Handle := NumGet(Buffer, 2 * 4)
  132. if (Type = RIM_TYPEHID)
  133. {
  134. SizeHid := NumGet(Buffer, (16 + 0))
  135. InputCount := NumGet(Buffer, (16 + 4))
  136. ;AppendOutput("HND " . Handle . " HID Size " . SizeHid . " Count " . InputCount . " Ptr " . &Buffer . "`r`n")
  137. Loop %InputCount% {
  138. Addr := &Buffer + 24 + ((A_Index - 1) * SizeHid)
  139. BAddr := &Buffer
  140. ;MsgBox, BAddr %BAddr% Addr %Addr%
  141. ;AppendOutput("Input " . Mem2Hex(Addr, SizeHid) . "`r`n")
  142. AppendOutput(Mem2Hex(Addr, SizeHid) . "`: `; Captured from Handle " . Handle . "`r`n")
  143. CodeOutput(Mem2Hex(Addr, SizeHid) . "`: `; Captured from Handle " . Handle . "`r`n`t `; Write code here`r`nReturn`r`n`r`n")
  144. }
  145. }
  146. else if (DoCaptureHID != 1) {
  147. if (Type = RIM_TYPEMOUSE)
  148. {
  149. LastX := NumGet(Buffer, (16 + (4 * 3)), "Int")
  150. LastY := NumGet(Buffer, (16 + (4 * 4)), "Int")
  151. AppendOutput("HND " . Handle . " MOUSE LastX " . LastX . " LastY " . LastY . "`r`n")
  152. }
  153. else if (Type = RIM_TYPEKEYBOARD)
  154. {
  155. ScanCode := NumGet(Buffer, (16 + 0), "UShort")
  156. VKey := NumGet(Buffer, (16 + 6), "UShort")
  157. Message := NumGet(Buffer, (16 + 8))
  158. AppendOutput("HND " . Handle . " KBD ScanCode " . ScanCode . " VKey " . VKey . " Msg " . Message . "`r`n")
  159. }
  160. else
  161. {
  162. AppendOutput("HND " . Handle . " Unknown Type " . Type)
  163. }
  164. }
  165. return
  166. }
  167. return
  168. Exit
  169. Capture:
  170. {
  171. if (DoCapture = 0)
  172. {
  173. GuiControl, , CaptureButton, Stop &Capture
  174. DoCapture := 1
  175. DoCaptureHID := 0
  176. }
  177. else
  178. {
  179. GuiControl, , CaptureButton, &Capture ALL Devices
  180. DoCapture := 0
  181. }
  182. return
  183. }
  184. CaptureHID:
  185. {
  186. If (DoCaptureHID = 0)
  187. {
  188. GuiControl, , CaptureHIDButton, &Stop Capture
  189. DoCapture := 1
  190. DoCaptureHID := 1
  191. }
  192. Else
  193. {
  194. GuiControl, , CaptureHIDButton, Capture &HID Devices Only
  195. DoCapture := 0
  196. DoCaptureHID := 0
  197. }
  198. return
  199. }
  200. GuiClose:
  201. ExitApp
  202. Mem2Hex( pointer, len )
  203. {
  204. A_FI := A_FormatInteger
  205. SetFormat, Integer, Hex
  206. Loop, %len% {
  207. Hex := *Pointer+0
  208. StringReplace, Hex, Hex, 0x, 0x0
  209. StringRight Hex, Hex, 2
  210. hexDump := hexDump . hex
  211. Pointer ++
  212. }
  213. SetFormat, Integer, %A_FI%
  214. StringUpper, hexDump, hexDump
  215. Return hexDump
  216. }
  217. InfoOutput(Text)
  218. {
  219. global InfoHwnd
  220. GuiControlGet, InfoOut
  221. NewText := InfoOut . Text
  222. GuiControl, , InfoOut, %NewText%
  223. return
  224. }
  225. CodeOutput(Text)
  226. {
  227. GuiControlGet, CodeOut
  228. IfNotInString, CodeOut, %Text%
  229. {
  230. NewText := CodeOut . Text
  231. GuiControl, , CodeOut, %NewText%
  232. }
  233. return
  234. }
  235. AppendOutput(Text)
  236. {
  237. global EditHwnd
  238. GuiControlGet, EditOut
  239. NewText := EditOut . Text
  240. GuiControl, , EditOut, %NewText%
  241. ; WM_VSCROLL (0x115), SB_BOTTOM (7)
  242. ;MsgBox, %EditHwnd%
  243. SendMessage, 0x115, 0x0000007, 0, , ahk_id %EditHwnd%
  244. return
  245. }
  246. ClearOutput:
  247. GuiControlGet, EditOut
  248. GuiControl, , EditOut,
  249. SendMessage, 0x115, 0x0000007, 0, , ahk_id %EditHwnd%
  250. Return
  251. F10::Reload