Allow REG_MULTI_SZ strings with multiple GUIDs, and use the first GUID
for enumerating the device interfaces.
This solves issues with e.g. a composite device with four WinUSB
interfaces, where the device implements "Extended Properties OS Feature
Descriptor" with multiple GUIDs. An attempt to open the device fails
with an error LIBUSB_ERROR_NOT_FOUND (-5).
Fixes#1307
Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
If initialization fails before hotplug can be set up then libusb_init will crash when it calls libusb_exit to clean up. This commit fixes the issue by only tearing down hotplug if it has been initialized.
Closes#1275
Signed-off-by: Nathan Hjelm <hjelmn@google.com>
I spent some time trying to figure out why, when I run this example,
it's not showing any events, until I looked into the code and saw it has
some hardcoded VID:PID.
Most people probably don't have the specific device hardcoded here, and
it seems better to default to showing events for any device unless
overridden.
While at it, also updated device detached message to match the attached
one to show VID:PID.
Closes#1350
[Tormod: Print error strings on failures]
Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
A messed-up descriptor could potentially cause an infinite loop.
Also applied to an instance in the Linux backend.
Closes#1308
[Tormod: Rephrase error messages]
Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
This commit essentially reverts commit eb164d75 (from 2018, pre 1.0.23).
Commit eb164d75 was made with the assumption that when a device is not
configured (i.e. it returns CurrentConfigurationValue == 0 during
init_device), then it is only a temporary condition caused by Windows
already listing the device but not having completed its setup yet. The
commit added a delay of up to 1 second (20 x 50ms) for re-obtaining
information and checking until CurrentConfigurationValue would
eventually change to a value > 0. The commit also forced libusb internal
structure to contain 1 as the active configuration even if the wait
failed to retrieve an active configuration, creating a discrepancy in
between the value seen from libusb and actual value managed by Windows.
There is a problem with the above because devices could be in the
unconfigured state for permanent reasons. For instance when a device is
disabled by Windows (either manually using Device Manager or
automatically because of a resource conflict). In this case the device
is listed with CurrentConfigurationValue == 0. Therefore init_device
will add a 1 second delay for each disabled device, at every device
enumeration.
A device which is not configured has no active interface nor available
endpoint. Therefore it cannot be used (except for standard request on
endpoint 0) and therefore shall not be returned by libusb as an active
device. It is the responsibility of the OS to bring the device to a
configured state. When libusb returns active configuration == 1 to a
user, the behavior of actually using this device is not defined.
The potential gain of being able to wait for Windows actually completing
device setup is not in par with the delay caused by the waiting which
has high-level impact (for instance in GUI listing devices) for standard
scenarios.
The initial problem addressed by commit eb164d75 is simply a race
condition occurring (rarely) when libusb enumeration happens exactly at
the instant when Windows is not yet done loading the driver etc. for an
enabled device. Calling init_device slightly earlier would have return
no result for this device, and slightly later would have return a fully
active device. In the first case a new enumeration would be necessary
anyway. Given hot-plug is not supported under Windows it is a good
practice to re-enumerate devices to detect newly plugged ones anyway, so
the race condition could be easily solved by simply enumerating
regularly.
To summarize: This commit reverts to handling the described race
condition by ignoring any non-configured device (not returning them from
get_device_list), instead of waiting for them to maybe get an active
configuration at a later time. The benefit is to avoid introducing
arbitrary large delay in common scenarios where some devices are
disabled at the OS level.
Moreover this commit reverts assigning a wrong value to
priv->active_config, and returning such device from get_device_list,
preventing the risk of later misuse of not configured devices.
Note: Disabled devices might not necessarily be listed under USB devices
in Windows Device Manager, but can be other system peripherals, one
example being Bluetooth chips with HCI USB interfaces.
Closes#1270
Define and assign bus number to root hubs during the hub pass of winusb
libusb_get_device_list, using the definition of a root hub as being a
hub without parent at port 0.
Note: Assigned bus number values for a given setup are not guaranteed to
remain constant when migrating from the previous implementation.
The rationale behind this change:
- Implementation using CM_Get_Child from HCD to get root hub devInst is
not working when using "FabulaTech Virtual USB Host Controller"
(USB-Ethernet bridge) under Hyper-V virtual machine.
- This new way of enumerating is inspired by "USB Device Viewer" Microsoft
driver sample code which is capable of correctly enumerating hubs and
devices in the above mentioned configuration as well as in regular
configurations.
Closes#1202
This could possibly scribble the arg union for other options
although it wouldn't happen with our current set of options.
Fixup of commit 84ac0b0
References #1265
Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
The error is:
core.c:2451:8: error: no member named 'debug' in 'struct libusb_context'
_ctx->debug = LIBUSB_LOG_LEVEL_NONE;
~~~~ ^
Signed-off-by: Ludovic Rousseau <ludovic.rousseau@free.fr>
This commit effectively deprecates libusb_set_log_cb by adding support for
setting the callback in either libusb_set_option or libusb_init_context. Since
the libusb_set_log_cb is already in use we can not easily deprecate it without
first incrementing the major version. We may do that in the future.
Closes#1265
Signed-off-by: Nathan Hjelm <hjelmn@google.com>
These functions are used in a lot of existing downstream code
and the deprecation makes -Werror builds fail.
It seems reasonable to keep these functions supported at least until a
major API overhaul.
Closes#990Closes#1236
The behavior of libusb_set_option was not matching the documentation
when the log level was set in the environment. This has been fixed but a
regression test is needed to ensure the behavior does not deviate. This
commit adds a set of unit tests to cover some of the functionality of
libusb_set_option.
Closes#1245
Signed-off-by: Nathan Hjelm <hjelmn@google.com>
[Xiaofan: Add Windows setenv/unsetenv wrappers]
Signed-off-by: Xiaofan Chen <xiaofanc@gmail.com>
[Tormod: Fix test_no_discovery() build on Linux, add msvc build]
Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
This commit updates the actual semantics of:
libusb_set_option(_, LIBUSB_OPTION_LOG_LEVEL, _)
to match the documentation. The documentation states that if the
LIBUSB_DEBUG environment variable is set then that level overrides the
value set by libusb_set_option.
Signed-off-by: Nathan Hjelm <hjelmn@google.com>
Do not show an uninitialized Max LUN value if the pipe stalled.
As suggested by the code comment (but not the old code), set a default
zero value only on pipe stall. On other errors simply error out.
References #1181Closes#1239
Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
Only keep it for Cygwin.
Clang doesn't support this option, and it seems only needed for
Cygwin since MinGW predefines e.g. the _WIN32 macro anyway.
From GCC documentation: -mwin32 This option is available for Cygwin
and MinGW targets. It specifies that the typical Microsoft Windows
predefined macros are to be set in the pre-processor, but does not
influence the choice of runtime library/startup code.
References #1192
Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
Several API changes targeted for 1.0.27
New API functions:
- libusb_init_context
- libusb_get_max_alt_packet_size
- libusb_get_interface_association_descriptors
- libusb_get_active_interface_association_descriptors
- libusb_free_interface_association_descriptors
- libusb_get_platform_descriptor
- libusb_free_platform_descriptor
(and their associated structures)
New option LIBUSB_OPTION_WINUSB_RAW_IO
NetBSD bus/address changes (not strictly part of API)
Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
NetBSD's udi_bus/udi_addr values in struct usb_device_info start from 0.
However, libusb's bus_number/device_address in struct libusb_device use
0 to represent a missing value and the libusb API states that a value of
0 returned by libusb_get_bus_number() or libusb_get_device_address()
means "not available" so applications may refuse to match on zero
values.
Adjust between the two worlds by adding an offset of 1.
Closes#1230
Add support for enabling or disabling the WinUSB RAW_IO pipe policy for
a given endpoint, which is documented here:
https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/winusb-functions-for-pipe-policy-modification
This is necessary to increase performance. Without this option the
WinUSB backend will only queue one inbound operation at a time, even if
the libusb async API is used to submit multiple transfers.
For real-time sampling devices with high sample rates and small buffers,
the use of RAW_IO combined with queued async transfers is essential to
maintaining the necessary throughput and avoiding lost samples or buffer
overruns.
Examples of devices affected include Cypress FX2 based logic analyzers
accessed using Sigrok, and the HackRF software defined radio.
The new option must be set by calling libusb_set_option with the arguments:
libusb_set_option(ctx, LIBUSB_OPTION_WINUSB_RAW_IO, dev_handle,
endpoint_address, enable, max_transfer_size_ptr)
where the types of the variadic arguments are:
libusb_device_handle *dev_handle;
unsigned int endpoint_address;
unsigned int enable;
unsigned int *max_transfer_size_ptr;
The dev_handle and endpoint_address parameters must identify a valid IN
endpoint on an open device. If enable is nonzero, RAW_IO is enabled,
otherwise it is disabled. Unless max_transfer_size_ptr is NULL, then on
a successful call to enable RAW_IO, the pointer destination will be
written with the MAXIMUM_TRANSFER_SIZE value for the endpoint.
Whilst RAW_IO is enabled for an endpoint, all transfers on that endpoint
must meet the following two requirements:
- The buffer length must be a multiple of the maximum endpoint packet size.
- The length must be less than or equal to the MAXIMUM_TRANSFER_SIZE value.
This option should not be changed when any transfer is in progress on
the specified endpoint.
This option only affects the WinUSB backend. On other backends it is
ignored and returns LIBUSB_ERROR_NOT_SUPPORTED, without modifying the
value pointed to by max_transfer_size_ptr.
A great deal of credit is due to Petteri Aimonen and Patrick Stewart for
previous work, and to everyone else who participated in discussions.
Fixes#490Closes#1208
This commit updates all test and example code to use the newer
libusb_init_context() function instead of libusb_init().
Signed-off-by: Nathan Hjelm <hjelmn@google.com>
[Tormod: Update umockdev.c as well]
Signed-off-by: Tormod Volden <debian.tormod@gmail.com>
The new initialization function addresses some shortcomings of the
libusb_set_option() interface. Namely, it allows setting the
no-enumeration option (and others) on only the contexts where it is
requested. The old initialization function (libusb_init()) is deprecated
and will be removed in a future release. For now it translates to a call
to libusb_init_context() with no options specified.
Closes#1026
Signed-off-by: Nathan Hjelm <hjelmn@google.com>
[Tormod: Doxygen description of libusb_init_option structure]
Signed-off-by: Tormod Volden <debian.tormod@gmail.com>