daynix / UsbDk

Usb Drivers Development Kit for Windows
Apache License 2.0
535 stars 142 forks source link

Regression: DeviceIoControl failed from libusb_open immediately after libusb_close on Windows 10 #43

Closed xlz closed 7 years ago

xlz commented 7 years ago

Our users started to get this error on Windows:

libusb_open returned: -99

First-chance exception at 0x00007FFDB1743C58 in Protonect.exe: Microsoft C++ exception: UsbDkDriverFileException at memory location 0x00000095014FDA30. Driver file operation error. DeviceIoControl failed (The system cannot find the file specified. Error code = 2)

First-chance exception at 0x00007FFEC5F83C58 in Protonect.exe: Microsoft C++ exception: UsbDkDriverFileException at memory location 0x000000900C59D3F0. Driver file operation error. DeviceIoControl failed (The system cannot find the file specified. Error code = 2) https://github.com/OpenKinect/libfreenect2/issues/812#issuecomment-293617474

The error can be reproduced by libusb_open() immediately after libusb_close() and would go away if there is some time delay between the two calls.

The error is only reproduced with v1.0.17 and not v1.0.16.

dmitryfleytman commented 7 years ago

This is by design. On libusb_close() UsbDk initiates device reset and client have to wait until reset completion in order to open it again.

Commit 848bb79ac2379c1ce0681088320f4ae504f2bce3 introduced between versions 1.0.16 and 1.0.17 increased amount of time client application has to wait for device re-appearance, therefore you hit this issue more frequently.

In order to resolve the issue properly, you should either wait for hotplug event related to the device in question or wait for the device in question to re-appear in libusb device list. After that, libusb_open() will work as expected.

xlz commented 7 years ago

libusb API provides:

Devices are reference counted with libusb_ref_device() and libusb_unref_device(), and are freed when the reference count reaches 0.

The bug happens when the reference count is 1.

libusb_get_device_descriptor, ref=1
libusb_open, ref=2
libusb_close, ref=1
libusb_open <-- bug

Presumably the device should not even be reset when libusb_get_device_descriptor() still holds onto it.

dmitryfleytman commented 7 years ago

UsbDk resets physical USB device on close, this does not affect libusb device structure, it remains valid.