While digging around in usbview, i came up with an elegant patch that doesn't
rely on strings being in the right format. In windows_get_device_list we
already query for SPDRP_DRIVER which gets us the DriverKey, you can query each
of the ports on the USB hub as well for this DriverKey, If we do the following
1) Modify init_device to take this DriverKey instead of a port number.
2) Add a function that takes a devicepath to the parent hub device and the
driverkey to search for that loops over all ports on the hub and locates the
proper port.
3) Set this port number in init_device.
This should get us the proper port without having to worry about parsing some
creepy string.
```
Index: libusb/os/windows_usb.c
===================================================================
--- libusb/os/windows_usb.c (revision 1153)
+++ libusb/os/windows_usb.c (working copy)
@@ -1070,11 +1070,46 @@
return LIBUSB_SUCCESS;
}
+ static int find_port(struct libusb_context *ctx,char* hubDevicePath, char*
deviceKey, uint8_t *port_number)
+ {
+ USB_NODE_INFORMATION node_information;
+ USB_NODE_CONNECTION_NAME_FIXED driver_key;
+ char driverKey[MAX_PATH_LENGTH];
+ HANDLE handle;
+ DWORD bytes_read;
+ int curPort;
+ int Result = LIBUSB_ERROR_IO;
+ handle = CreateFileA(hubDevicePath, GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,FILE_FLAG_OVERLAPPED, NULL);
+ if (handle == INVALID_HANDLE_VALUE) {
+ usbi_warn(ctx, "could not open hub %s: %s",
hubDevicePath, windows_error_str(0));
+ return LIBUSB_ERROR_ACCESS;
+ }
+
+ node_information.NodeType = UsbHub ;
+ if (DeviceIoControl(handle, IOCTL_USB_GET_NODE_INFORMATION,
&node_information,sizeof(node_information),
&node_information,sizeof(node_information), &bytes_read,NULL)) {
+ for (curPort=1; curPort <=
node_information.u.HubInformation.HubDescriptor.bNumberOfPorts; curPort++)
+ {
+ driver_key.ConnectionIndex = curPort;
+ if (DeviceIoControl(handle,
IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, &driver_key,sizeof(driver_key),
&driver_key,sizeof(driver_key), &bytes_read,NULL)) {
+ wchar_to_utf8_ms(driver_key.NodeName,
driverKey,sizeof(driverKey));
+ if (strcmp(driverKey, deviceKey) == 0) {
+ *port_number=(uint8_t) curPort;
+ Result = LIBUSB_SUCCESS;
+ break;
+ }
+ }
+ }
+ }
+
+ CloseHandle(handle);
+ return Result;
+ }
+
/*
* Populate a libusbx device structure
*/
static int init_device(struct libusb_device* dev, struct libusb_device*
parent_dev,
- uint8_t port_number, char*
device_id, DWORD devinst)
+ char* deviceKey, char* device_id,
DWORD devinst)
{
HANDLE handle;
DWORD size;
@@ -1083,17 +1118,19 @@
struct libusb_context *ctx = DEVICE_CTX(dev);
struct libusb_device* tmp_dev;
unsigned i;
+ uint8_t port_number=0;
if ((dev == NULL) || (parent_dev == NULL)) {
return LIBUSB_ERROR_NOT_FOUND;
}
priv = _device_priv(dev);
parent_priv = _device_priv(parent_dev);
+
if (parent_priv->apib->id != USB_API_HUB) {
usbi_warn(ctx, "parent for device '%s' is not a hub",
device_id);
return LIBUSB_ERROR_NOT_FOUND;
}
-
+
// It is possible for the parent hub not to have been initialized yet
// If that's the case, lookup the ancestors to set the bus number
if (parent_dev->bus_number == 0) {
@@ -1113,10 +1150,20 @@
usbi_err(ctx, "program assertion failed: unable to find
ancestor bus number for '%s'", device_id);
return LIBUSB_ERROR_NOT_FOUND;
}
+
+ priv->depth = parent_priv->depth + 1;
+
+ if (priv->depth != 0) {
+ if (find_port(ctx,parent_priv->path, deviceKey,&port_number) !=
LIBUSB_SUCCESS) {
+ usbi_err(ctx, "program assertion failed: unable to find
port number number for '%s'", device_id);
+ return LIBUSB_ERROR_NOT_FOUND;
+ }
+ }
+
dev->bus_number = parent_dev->bus_number;
priv->port = port_number;
dev->port_number = port_number;
- priv->depth = parent_priv->depth + 1;
+
priv->parent_dev = parent_dev;
dev->parent_dev = parent_dev;
@@ -1347,6 +1394,7 @@
size_t class_index = 0;
unsigned int nb_guids, pass, i, j, ancestor;
char path[MAX_PATH_LENGTH];
+
char strbuf[MAX_PATH_LENGTH];
struct libusb_device *dev, *parent_dev;
struct windows_device_priv *priv, *parent_priv;
@@ -1627,7 +1675,7 @@
}
break;
case GEN_PASS:
- r = init_device(dev, parent_dev,
(uint8_t)port_nr, dev_id_path, dev_info_data.DevInst);
+ r = init_device(dev, parent_dev, strbuf,
dev_id_path, dev_info_data.DevInst);
if (r == LIBUSB_SUCCESS) {
// Append device to the list of
discovered devices
discdevs =
discovered_devs_append(*_discdevs, dev);
Index: libusb/os/windows_usb.h
===================================================================
--- libusb/os/windows_usb.h (revision 1153)
+++ libusb/os/windows_usb.h (working copy)
@@ -352,6 +352,7 @@
#define USB_GET_NODE_INFORMATION 258
#define USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 260
#define USB_GET_NODE_CONNECTION_NAME 261
+#define USB_GET_NODE_CONNECTION_DRIVERKEY_NAME 264
#define USB_GET_HUB_CAPABILITIES 271
#if !defined(USB_GET_NODE_CONNECTION_INFORMATION_EX)
#define USB_GET_NODE_CONNECTION_INFORMATION_EX 274
@@ -425,6 +426,12 @@
#define IOCTL_USB_GET_NODE_CONNECTION_NAME \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_NAME, METHOD_BUFFERED,
FILE_ANY_ACCESS)
+#define IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME \
+ CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,
METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+
+
+
// Most of the structures below need to be packed
#pragma pack(push, 1)
```
---
Reply to this email directly or view it on GitHub:
https://github.com/libusbx/libusbx/issues/147#issuecomment-25288736
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk
_______________________________________________
libusbx-devel mailing list
libusbx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusbx-devel