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

Reply via email to