Skip to content

Navigation Menu

Sign in
Sign up

Is it possible to send/read data from/to HID-keyboards under Windows? #403

Answered by Youw
xcme asked this question in Q&A
Discussion options

Hello,

The title is the question. I compiled hidtest.exe and it can enumerate devices. I see my keyboard there and I placed its ID to the hid_open function. It then provides some details about the device, but some functions fail:


Unable to send a feature report.
Unable to get a feature report.
Incorrect function.Unable to write()
Error: Incorrect function.
Unable to write() (2)

I heard that Windows allegedly has some limitations for HID keyboards and mices, but this project can work with my keyboard. Thus, it should be possible.

You must be logged in to vote

I see 3 or 4 entries for my keyboard

Windows creates a separate logical HID device for each (top-lelvel) usage_page/usage pair (see official doc: https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/top-level-collections).

The hid_open function has optional 'serial' parameter

hid_open is not sufficient for this purpose. You need to use hid_enumerate, and find a specific device with specific VID+PID+SerialNumber+USAGE+USAGE_PAGE.
E.g.: HID_USAGE_PAGE_GENERIC/(HID_USAGE_GENERIC_MOUSE|HID_USAGE_GENERIC_KEYBOARD) is never allowed direct access using HIDAPI on Windows. That is an OS limitation.

By opening first device (usage_page/usage) there is a high chance you get the Keyboard ...

Replies: 4 comments 4 replies

Comment options

P.S. In the enumerated list I see 3 or 4 entries for my keyboard. Does it matter? I mean if I need somehow to switch between them? If yes, then how can I do that? The hid_open function has optional 'serial' parameter, but it's the same for all entries related to the keyboard.

@CalcProgrammer1, if I'm not mistaken, you had similar problem in past and you solved it by changing the Interface, right?

You must be logged in to vote
0 replies
Comment options

I see 3 or 4 entries for my keyboard

Windows creates a separate logical HID device for each (top-lelvel) usage_page/usage pair (see official doc: https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/top-level-collections).

The hid_open function has optional 'serial' parameter

hid_open is not sufficient for this purpose. You need to use hid_enumerate, and find a specific device with specific VID+PID+SerialNumber+USAGE+USAGE_PAGE.
E.g.: HID_USAGE_PAGE_GENERIC/(HID_USAGE_GENERIC_MOUSE|HID_USAGE_GENERIC_KEYBOARD) is never allowed direct access using HIDAPI on Windows. That is an OS limitation.

By opening first device (usage_page/usage) there is a high chance you get the Keyboard collection and not the RGB, that's why you don't have access to read or write.

but this project can work with my keyboard

It searches for a specific usage_page/usage for each known device: 1, 2.

You must be logged in to vote
0 replies
Answer selected by xcme
Comment options

@Youw, thanks a lot for the explanation!

So, what should I do:

  1. Find the correct usage_page+usage // I've found
  2. Enumerate devices and find the one that matches all there parameters
  3. Remember the path
  4. Open device with that path and work with it in further ( handle = hid_open_path(cur_dev->path); )

Correct? Is it the simplest way?

I did so and see that keyboard can react on my hid_write. Just want to make sure I should use hid_open_path.

You must be logged in to vote
1 reply
Comment options

Youw Mar 30, 2022
Maintainer

Yes, everything is correct.
There is no simpler way.

Comment options

The last, I hope, question. The device still doesn't answer to hid_send_feature_report and hid_get_feature_report, but I'm able now to control RGB zones via hid_write. Actually, that's my goal. Just curious if the feature report should work in that case or it depends on the device?

You must be logged in to vote
3 replies
Comment options

Youw Mar 30, 2022
Maintainer

hid_write sends the output report. It is not the same as feature reports.
Input, output or feature reports - that's more like a "transport" defined by HID standard.

But which specific reports are supported by a specific device - that's, of course, device-specific.

Comment options

@xcme ,
It looks you can control RGB by hid_write. would you mind introduce how is it work? many thanks.

Comment options

@xcme , It looks you can control RGB by hid_write. would you mind introduce how is it work? many thanks.

Hello @JordanChiang,
Yes, it works for me. I use that tool to send the data that I prepare in a batch script. The main thing here is to know what to send exactly. I found a project on GitHub that has data for my keyboard, so I took them and created that simple batch script.

So, if you know the data (any working code for your device would help here), then you can do PoC:

  1. Download hidapitester.exe and issue:
    hidapitester --list
  2. Found your device, remember the "vid" and then request more details for that "vid":
    hidapitester --vidpid XXXX --list-detail
  3. According to the code example you have, pick up the right "usagePage" and "usage". Now you have all the needed parameters: "vid", "pid", "usagePage" and "usage".
  4. Then prepare your data. For my device the data has "controls" (4 constant bytes), "zone" (1 byte), "rgbmode" (1 byte) and "r", "g" and "b" values (1 byte for each). Each byte has to be represented in decimal form and separated by comma (see hidapitester usage examples).
  5. Send your data by command like this:
    hidapitester.exe --vidpid %vid%:%pid% --usagePage %usagepage% --usage %usage% --list-detail --open --send-output %data%.
    It will show something like:
Opening device, vid/pid:0xXXXX/0xXXXX, usagePage/usage: XXXX/XXXX
Device opened
Writing output report of 64-bytes...wrote 20 bytes:
XX XX XX XX...
XX XX XX XX
Closing device

And the device should react on your command.

Hope it helps.

P.S. If you have come experience with C then it's possible to modify some source example from the hidapitester and it would do the same. It means no batch is needed anymore, only small single "exe" does all the job. I've tried it and it worked for me, but I didn't finish that, because I have lack of knowledge about C.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /