Open zardini123 opened 6 months ago
Some of these are unfortunatly not supported:
The Windows.Devices.HumanInterfaceDevice API supports most HID devices. However, it blocks the top-level application collection represented by the following usage pages, to prevent conflict with other Windows APIs and OS behavior:
HID_USAGE_PAGE_UNDEFINED HID_USAGE_PAGE_GENERIC HID_USAGE_GENERIC_KEYBOARD HID_USAGE_GENERIC_KEYPAD HID_USAGE_GENERIC_SYSTEM_CTL HID_USAGE_PAGE_KEYBOARD HID_USAGE_PAGE_CONSUMER HID_USAGE_PAGE_DIGITIZER HID_USAGE_PAGE_SENSOR HID_USAGE_PAGE_BARCODE_SCANNER HID_USAGE_PAGE_WEIGHING_DEVICE HID_USAGE_PAGE_MAGNETIC_STRIPE_READER HID_USAGE_PAGE_TELEPHONY
This is the relevent section of hidapi:
let handle = open_device(&device_path, true)
// System devices, such as keyboards and mice, cannot be opened in
// read-write mode, because the system takes exclusive control over
// them. This is to prevent keyloggers. However, feature reports
// can still be sent and received. Retry opening the device, but
// without read/write access.
.or_else(|_| open_device(&device_path, false))?;
I don't think it's possible to replicate with winrt as FileAccessMode
can only be Read
or ReadWrite
Thanks for your response! I have some follow-up questions.
Some of these are unfortunatly not supported:
This still begs the question why my gamepads (PS4, PS5) aren't opening. Is there something I am missing when calling your API?
This is the relevent section of hidapi:
Where can I find the source of this section? I am having troubles finding it.
I don't think it's possible to replicate with winrt as
FileAccessMode
can only beRead
orReadWrite
What would be the ultimate solution be then for these devices? Does hidapi
use a different windows API that is different to acquire access?
Just for clarification: Are you trying to open the gamepad in read or read/write mode?
Where can I find the source of this section? I am having troubles finding it.
Original C code: https://github.com/libusb/hidapi/blob/d0732cda906ad07b7e1ef93f1919035643620435/windows/hid.c#L991
My Rust port: https://github.com/ruabmbua/hidapi-rs/blob/2f37587cc7d7d56f2cdf3c948abffac860d63b5c/src/windows_native/mod.rs#L398
(hidapi
could use either depending on if you activated the windows_native
feature)
Does hidapi use a different windows API that is different to acquire access?
Yes. What hidapi essentially uses the win32 way of opening devices, while this library uses the higher level winrt classes (virtually no unsafe
, automatic async, at lot less code). The reason the backend is called winrt
instead of windows
is because I thought that it might become nessecary to add a second Windows backend (win32
).
Just for clarification: Are you trying to open the gamepad in read or read/write mode?
Read/write mode :)
(
hidapi
could use either depending on if you activated thewindows_native
feature)
Thanks for the links! From my brief scan of the windows-native
section of async-hid
, it seems the implementation is similar to the winrt
implementation of this library, but synchronized. So is the windows_native
part of hidapi
using winrt
, and the C implementation is using win32
?
Yes. What hidapi essentially uses the win32 way of opening devices, while this library uses the higher level winrt classes (virtually no
unsafe
, automatic async, at lot less code). The reason the backend is calledwinrt
instead ofwindows
is because I thought that it might become nessecary to add a second Windows backend (win32
).
Oh, that is really interesting! I appreciate the forward-thinking on the backend organization.
My thought is until the win32
backend is implemented, I think it would be useful to notify users why those devices are not opening is because it is inherit to the winrt
backend. Would it be possible to check if the HID_USAGE
for the device attempting to be opened is any of those usage types you mentioned, and then throw a more crafted error for this scenario?
So is the windows_native part of hidapi using winrt, and the C implementation is using win32?
No both of them are using win32. The windows-native section is more or less a one-to-one port of the C implementation.
A lot of these restrictions are not really inherent to winrt but Windows as a whole. Other operating systems have other restrictions. On Linux for example you can't open any device unless you're either running your program as root or installed the appropriate udev rules. On MacOS you'll get a permission popup for the user, that can be denied and probably more. With WASM/WebHID (not yet in main) you'll have to manually ask for a similar permission popup before you can even enumerate devices and enumerate will only find devices that the user granted access to.
When trying the example
read_write
on some devices I own, every time the process does not exit successfully with the error:I tried opening with ReadWrite on my mouse, keyboard, PS4, and PS5 controllers, and all failed. I have integrated
async-hid
into a personal project andasync-hid
has an identical problem there.The only AccessMode that works is
Read
. I can successfully acquire read reports with all my devices listed.Opening devices for read/write on Windows does not happen when using
hidapi
.Any help would be greatly appreciated. Thanks!