Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows version doesn't enumerate devices when exactly one is connected #234

Closed
jm4R opened this issue Jan 20, 2021 · 13 comments · Fixed by #235
Closed

Windows version doesn't enumerate devices when exactly one is connected #234

jm4R opened this issue Jan 20, 2021 · 13 comments · Fixed by #235
Labels
Windows Related to Windows backend

Comments

@jm4R
Copy link
Contributor

jm4R commented Jan 20, 2021

I don't know if this is coincidence, but this is my case:

I plug UPS HID device (CyberPower or APC) as an only HID device in the whole system, and hid_enumerate returns nullptr.

When I plug USB keyboard as a second device, hid_enumerate enumerates both - keyboard and UPS.

On Linux and exactly the same machine it works fine.

@Youw Youw added the Windows Related to Windows backend label Jan 20, 2021
@Youw
Copy link
Member

Youw commented Jan 20, 2021

I assume you're using build 0.10.1.

Can you step-trace a "single device" scenario with a debugger and tell what do you get from SetupDiGetClassDevsA/SetupDiEnumDeviceInterfaces (or after those)?

@jm4R
Copy link
Contributor Author

jm4R commented Jan 20, 2021

driver_name is "Battery" which is weird as in windows device manager the device class shows "HIDClass" as expected.

@Youw
Copy link
Member

Youw commented Jan 20, 2021

And when you have two devices connected?

@todbot
Copy link
Contributor

todbot commented Jan 20, 2021

Yes, I believe on Windows, with the HID Battery driver, that removes it from the list of devices hidapi can access. (as what happens to gamepads) http://batcmd.com/windows/10/services/hidbatt/

@todbot
Copy link
Contributor

todbot commented Jan 20, 2021

I just tested an APC Back-UPS ES 550 on Windows 10 Pro. It appears as both a HID device and as a "Battery" to device driver (see screenshot below). And it appears to hidapi's hid_enumerate just fine (see hidapitester output below, it's using hidapi@0.10.1). Perhaps you have an additional, non-Microsoft driver on the device?

Screen Shot 2021-01-20 at 2 21 44p

Screen Shot 2021-01-20 at 2 33 22p

Oh, wait, but I see, the issue is that if the UPS is the only HID device. Hmmm.

@Youw
Copy link
Member

Youw commented Jan 20, 2021

I think the problem comes if you'd have only this UPS connected, and no other HID devices in the system.

UPD: this conversation looks weird, when we both edit our messages :D

@todbot
Copy link
Contributor

todbot commented Jan 20, 2021

Yes I understand that better now. :) Trying to figure out how to test this since RDP just decided to stop working with a recent Win10 update...

@jm4R
Copy link
Contributor Author

jm4R commented Jan 21, 2021

@Youw when I plug the keyboard and the mouse in, all iterations returns "Keyborad" as a device name. Something is definetely wrong in this code. I found old, open but abandoned pull request that claims that the index passed to the SetupDiEnumDeviceInfo is wrong:

https://github.com/signal11/hidapi/pull/291/files/f453bda38ff17ea28b7b1d59afd8d09e74e5efb5#diff-8162c58f4630fb0f3a6a21f2e094e883L354

It seems that after simillar change the driver_name shows more apriopriate values to the ones that are shown in Windows Device Manager. To sumarise that, it looks like
hid_enumerate enumerates all USB devices if the first on the list is HIDClass or Mouse or Keyboard

This is coincidence that the code works with my UPS because SetupDiEnumDeviceInfo(device_info_set, device_index, &devinfo_data); after the "quickfix" still returns "Battery", but we should somehow retreive the value which is shown by the Windows device manager as on the screenshot:
a

This way, we can expect that we could get rid of the "Keyboard" and "Mouse" exceptions, because for those devices the device manager also shows "HIDClass" value. Yet, I am not very familiar with WinApi so I don't know (yet) how to retrive it using WinApi.

@jm4R
Copy link
Contributor Author

jm4R commented Jan 21, 2021

How about solution straight from Microsoft:

https://github.com/microsoft/Windows-driver-samples/blob/master/hid/hclient/pnp.c#L32

?

It is similar but instead of checking device class name, it just uses HidD_GetHidGuid doc and tries to open it. I will try it and prepare a pull request if it will work.

@Youw
Copy link
Member

Youw commented Jan 21, 2021

I'm afraid, opening a device might cause issue, like described here: #225 (comment)
I'll take a look at this closely

@jm4R
Copy link
Contributor Author

jm4R commented Jan 21, 2021

We already do this:
https://github.com/libusb/hidapi/blob/master/windows/hid.c#L411

It is being open with open_rw set to FALSE, maybe this doesn't make the issue. I won't change it.

@Youw
Copy link
Member

Youw commented Jan 21, 2021

Hmm, right, fair enough.

@jm4R
Copy link
Contributor Author

jm4R commented Jan 21, 2021

The PR works for me, please review. I didn't use HidD_GetHidGuid directly as it would require linking to hid.lib. The hard-coded GUID is the same with the one returned by this function which means the enumeration already filters only HID-class devices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Windows Related to Windows backend
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants