-
Notifications
You must be signed in to change notification settings - Fork 409
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: change MAX_STRING_WCHARS to 126 #627
Conversation
Win32 HID API doc says: For USB devices, the maximum string length is 126 wide characters (not including the terminating NULL character). For certain USB devices, using a buffer larger or equal to 127 wchars results in successful completion of HID API functions, but a broken string is stored in the output buffer. This behaviour persists even if HID API is bypassed and HID IOCTLs are passed to the HID driver directly (IOCTL_HID_GET_MANUFACTURER_STRING, IOCTL_HID_GET_PRODUCT_STRING, etc). So, the buffer MUST NOT exceed 126 wchars.
What kind of USB HID device is showing such problem? Will this PR cause side effects for other HID device like Bluetooth?
Reference: it seems to me Windows API allows the buffer size to be up to 4093 Bytes, |
Is this causing un undefined behavior (like reading uninitialized memory) or just is it more a security consern (getting data from some buffer in the memory which we wheren't supposed to get normally.
Is it specific to driver or specific to device descriptor?
Taking into account size limitation for other buses (e.g. Bluetooth) this parameter probably need to be bus-specific, e.g. have it as is (256) by default, and have it 126 for device bus is known and is USB. |
I can't quite put my finger on what exactly triggers this behaviour, but here's an example (Windows10 Pro 21H2, Version 10.0.19044 Build 19044) Before the patch:
After the patch:
Symptoms are as follows: On return, the output buffer is zeroed except for the first letter; the first letter is pretty much random on every run (sometimes, it matches the first letter of the actual string descriptor). Tried calling I was able to find similar reports from other users, for example: https://stackoverflow.com/questions/2329572/trouble-reading-manufacturer-string-from-hid-device-using-hid-dll-api. In the case of my device, passing a 127 wchars long buffer still results in a broken output (126 wchars work). Please note that all of the above only applies to this particular USB mouse (other HID devices work fine with the original 256 wchars long buffer).
That's a good question. HidD_GetManufacturerString and friends fail if the buffer is not big enough, so the patch could affect devices with string descriptor exceeding 126 wchars (are there even devices like that?). To minimize possible impact, it probably makes sense to make this patch specific to the USB bus (i.e., only limit the buffer size for
Well, the same page also states that USB string descriptors are limited to 126 wchars:
The doc is a bit vague on whether it's OK to pass a 127 wchars long buffer to accommodate the NULL-terminator, but my experiments showed that it's not (fails for 127 wchars, works for 126 wchars). |
It doesn't look like it's actually breaking anything or leading to a crash; just the output buffer is wrong (a random letter, then zeroes).
Can't really tell whether it's caused by a particular device, USB driver, or HID driver (but not the Win32 HID library, because I tried passing HID IOCTLs directly). But again, it's not unique to my mouse -- there are similar reports on the web.
Good point. I'll make the changes and make this limitation specific to the USB bus. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
other then my last commnet - looks good
…_internal_detect_bus_type(...) hid_internal_get_usb_info is now only responsible for detection of the bus type; rename it accordingly. Also, mixing an internal flag and DEV_INST into an ULONGLONG retval feels kinda hackish; use a cleaner approach instead (add an internal flag to help distinguishing between BLUETOOTH and BLE devices, then clear it once we are done).
The |
No worries. I'll override that check when it is time to merge. |
According to the USB 3.2 Revision 1.1 Specification. Section 9.6.9.:
So maximum size in BYTES is 255-2=253. Or 127 WCHARS with NULL-termination. I like the idea of this workaround for possible Windows bug, but do not like this |
I agree this would do good from Single Responsibility principle, |
Win32 HID API doc says: For USB devices, the maximum string length is 126 wide characters (not including the terminating NULL character).
For certain USB devices, using a buffer larger or equal to 127 wchars results in successful completion of HID API functions, but a broken string is stored in the output buffer. This behaviour persists even if HID API is bypassed and HID IOCTLs are passed to the HID driver directly (IOCTL_HID_GET_MANUFACTURER_STRING, IOCTL_HID_GET_PRODUCT_STRING, etc).
So, the buffer MUST NOT exceed 126 wchars.