On 05/14/2012 03:12 PM, Pete Batard wrote:
I addressed this point already. It doesn't matter if you modify libusbx
or add an extra layer on top of it. The issue is you are replicating a
feature that libusbx is planning to provide, and that, as far as I could
see from my tests, unless somebody else provides the same feature as a
layer, in the same fashion as you do, they will not encounter the issue.

In essence what happens from the libusbx pov is:

1) libusbx gets initialized
2) libusb_get_device_list() gets called
3) a new USB device gets plugged in
4) that new device gets the winusb driver bound to it
5) libusb_get_device_list() gets called again

And after 5 we expect libusbx to both know about the device,  and for the
app to be able to use the device through libusbx. This seems like a
reasonable thing to expect to me, even of a not hotplug aware libusbx.
Which it does.

As far as I know, I tested xusb in exactly the fashion highlighted
above, and found no issue. I produced the result from the test I ran as
well as the xusb patch I applied, and it matches your list. I was able
to use the device as expected after the second libusb_get_device_list()
was called. Are you sure you're issuing a libusb_free_device_list before
issuing the second libusb_get_device_list?

Right now, outside of not freeing the list (but in that case, expecting
an enum list to auto-update itself if after it has been generated IS
hotplug), the only way I see for your issue to manifest itself is if the
driver installation ends when we're in the middle of enumeration on
Windows, i.e. we ran an enum pass where the driver was seen as
unsupported (no driver) and later passes see the driver as supported
through WinUSB. But I can only see that happen if someone provides a
custom hotplug implementation.

Now, if you can modify xusb or produce a sample that demonstrates that
your issue occurs in a non custom hotplug scenario, that's a different
story.




Attached kindly find such a patch, together with output with/without the patch. (I also changed -k option's according to vid:pid of a usb disk I'm testing with)

$ xusb -k -d -i

Thanks,
    Uri.

diff --git a/examples/xusb.c b/examples/xusb.c
index 2c0409f..bdac37b 100644
--- a/examples/xusb.c
+++ b/examples/xusb.c
@@ -572,6 +572,80 @@ static void 
read_ms_winsub_feature_descriptors(libusb_device_handle *handle, uin
        }
 }

+
+static void rescan_devices(void)
+{
+       libusb_device **devlist;
+
+       libusb_get_device_list(NULL, &devlist);
+       libusb_free_device_list(devlist, 1);
+}
+
+/* returns a libusb_device if found, NULL if not */
+static libusb_device* find_device_with_vid_pid(uint16_t vid, uint16_t pid)
+{
+       ssize_t nitems, i, r;
+       libusb_device **devlist, *dev = NULL;
+       struct libusb_device_descriptor desc;
+
+       nitems = libusb_get_device_list(NULL, &devlist);
+
+       printf("There are %ld devices plugged into the machine\n", 
(long)nitems);
+
+       for (i=0; (i<nitems) && (devlist[i] != NULL); i++) {
+               r = libusb_get_device_descriptor(devlist[i], &desc);
+               if (r < 0) {
+                       perr("failed to get device descriptor");
+                       break;
+               }
+
+               if ((desc.idVendor == vid) && (desc.idProduct == pid)) {
+                       printf("found the device\n");
+                       dev = libusb_ref_device(devlist[i]);
+                       break;
+               }
+       }
+       libusb_free_device_list(devlist, 1);
+       return dev;
+}
+
+static int test_driver_install(uint16_t vid, uint16_t pid)
+{
+       libusb_device *dev;
+       libusb_device_handle *handle = NULL;
+       int r;
+
+       dev = find_device_with_vid_pid(vid, pid);
+       if (!dev) {
+               perr("Failed to find device 0x%04x:0x%04x\n", vid, pid);
+               return -1;
+       }
+
+       printf("Opening device...\n");
+
+       r = libusb_open(dev, &handle);
+
+       if (r != 0) {
+               perr("Please install driver NOW!\n");
+               while(getchar() != 0x0A);
+               r = libusb_open(dev, &handle);
+               if (r != 0) {
+                       perr("Going to rescan devices\n");
+                       rescan_devices();
+                       r = libusb_open(dev, &handle);
+                       if (r != 0) {
+                               perr("  Open  Failed r=%d\n", r);
+                       }
+               }
+       }
+
+       printf("Closing device...\n");
+       if (handle)
+               libusb_close(handle);
+       libusb_unref_device(dev);
+       return r;
+}
+
 static int test_device(uint16_t vid, uint16_t pid)
 {
        libusb_device_handle *handle;
@@ -756,6 +837,7 @@ int main(int argc, char** argv)
        size_t i, arglen;
        unsigned tmp_vid, tmp_pid;
        uint16_t endian_test = 0xBE00;
+       int is_test_driver_install = 0;

        // Default to generic, expecting VID:PID
        VID = 0;
@@ -793,11 +875,14 @@ int main(int argc, char** argv)
                                                PID = 0x0004;
                                        }
                                        break;
+                               case 'i':
+                                       // test libusb driver install
+                                       is_test_driver_install = 1;
                                case 'k':
                                        // Generic 2 GB USB Key (SCSI 
Transparent/Bulk Only) - 1 interface
                                        if (!VID && !PID) {
                                                VID = 0x0204;
                                                PID = 0x6025;
                                        }
                                        break;
                                // The following tests will force VID:PID if 
already provided
@@ -843,6 +928,7 @@ int main(int argc, char** argv)
                printf("   -b: dump Mass Storage first block to binary file\n");
                printf("   -g: short generic test (default)\n");
                printf("   -k: test generic Mass Storage USB device (using 
WinUSB)\n");
+               printf("   -i: test driver being installed dynamically\n");
                printf("   -j: test FTDI based JTAG device (using WinUSB)\n");
                printf("   -p: test Sony PS3 SixAxis controller (using 
WinUSB)\n");
                printf("   -x: test Microsoft XBox Controller Type S (using 
WinUSB)\n");
@@ -858,7 +944,10 @@ int main(int argc, char** argv)
        // Info = 3, Debug = 4
        libusb_set_debug(NULL, debug_mode?4:3);

-       test_device(VID, PID);
+       if (!is_test_driver_install)
+               test_device(VID, PID);
+       else
+               test_driver_install(VID, PID);

        libusb_exit(NULL);

Using libusbx v1.0.11.10504

[timestamp] [threadID] facility level [function call] <message>
--------------------------------------------------------------------------------
There are 2 devices plugged into the machine
found the device
Opening device...
[ 0.000000] [00000150] libusbx: warning [windows_get_device_list] could not 
retrieve port number for device '\\.\ROOT#SYSTEM#0003', skipping: [13] The data 
is invalid.
Please install driver NOW!
Going to rescan devices
[30.328125] [00000150] libusbx: warning [windows_get_device_list] could not 
retrieve port number for device '\\.\ROOT#SYSTEM#0003', skipping: [13] The data 
is invalid.
  Open  Failed r=-12
Closing device...
Using libusbx v1.0.11.10505

[timestamp] [threadID] facility level [function call] <message>
--------------------------------------------------------------------------------
There are 2 devices plugged into the machine
found the device
Opening device...
[ 0.000000] [000003d4] libusbx: warning [windows_get_device_list] could not 
retrieve port number for device '\\.\ROOT#SYSTEM#0003', skipping: [13] The data 
is invalid.
Please install driver NOW!
Going to rescan devices
[24.140625] [000003d4] libusbx: warning [windows_get_device_list] could not 
retrieve port number for device '\\.\ROOT#SYSTEM#0003', skipping: [13] The data 
is invalid.
Closing device...
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
libusbx-devel mailing list
libusbx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusbx-devel

Reply via email to