Skip to content

Commit f7ee9cc

Browse files
xobsQbicz
authored andcommitted
windows: retry open_device() without r/w if it fails
Modern Windows implementations don't allow opening HID devices in READ/WRITE mode if they are claimed by the system. Examples of such devices include keyboards and mice. However, these devices can be opened without READ/WRITE permissions, in order to allow sending and receiving feature reports. If open_device() fails, retry without requesting READ/WRITE permissions. This inverts the logic of the parameter to open_device(). It is a refactor of #44 by @pqu. Signed-off-by: Sean Cross <[email protected]>
1 parent a6a622f commit f7ee9cc

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

windows/hid.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,10 @@ static int lookup_functions()
225225
}
226226
#endif
227227

228-
static HANDLE open_device(const char *path, BOOL enumerate)
228+
static HANDLE open_device(const char *path, BOOL open_rw)
229229
{
230230
HANDLE handle;
231-
DWORD desired_access = (enumerate)? 0: (GENERIC_WRITE | GENERIC_READ);
231+
DWORD desired_access = (open_rw)? (GENERIC_WRITE | GENERIC_READ): 0;
232232
DWORD share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
233233

234234
handle = CreateFileA(path,
@@ -370,7 +370,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
370370
//wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath);
371371

372372
/* Open a handle to the device */
373-
write_handle = open_device(device_interface_detail_data->DevicePath, TRUE);
373+
write_handle = open_device(device_interface_detail_data->DevicePath, FALSE);
374374

375375
/* Check validity of write_handle. */
376376
if (write_handle == INVALID_HANDLE_VALUE) {
@@ -566,13 +566,23 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)
566566
dev = new_hid_device();
567567

568568
/* Open a handle to the device */
569-
dev->device_handle = open_device(path, FALSE);
569+
dev->device_handle = open_device(path, TRUE);
570570

571571
/* Check validity of write_handle. */
572572
if (dev->device_handle == INVALID_HANDLE_VALUE) {
573-
/* Unable to open the device. */
574-
register_error(dev, "CreateFile");
575-
goto err;
573+
/* System devices, such as keyboards and mice, cannot be opened in
574+
read-write mode, because the system takes exclusive control over
575+
them. This is to prevent keyloggers. However, feature reports
576+
can still be sent and received. Retry opening the device, but
577+
without read/write access. */
578+
dev->device_handle = open_device(path, FALSE);
579+
580+
/* Check the validity of the limited device_handle. */
581+
if (dev->device_handle == INVALID_HANDLE_VALUE) {
582+
/* Unable to open the device, even without read-write mode. */
583+
register_error(dev, "CreateFile");
584+
goto err;
585+
}
576586
}
577587

578588
/* Set the Input Report buffer size to 64 reports. */

0 commit comments

Comments
 (0)