diff --git a/channels/urbdrc/client/data_transfer.c b/channels/urbdrc/client/data_transfer.c index 17d6a0b4b..f88528482 100644 --- a/channels/urbdrc/client/data_transfer.c +++ b/channels/urbdrc/client/data_transfer.c @@ -1752,6 +1752,13 @@ static UINT urbdrc_process_transfer_request(IUDEVICE* pdev, URBDRC_CHANNEL_CALLB break; } + if (error) + { + WLog_Print(urbdrc->log, WLOG_WARN, + "USB transfer request URB Function %08" PRIx32 " failed with %08" PRIx32, + URB_Function, error); + } + return error; } diff --git a/channels/urbdrc/client/libusb/libusb_udevice.c b/channels/urbdrc/client/libusb/libusb_udevice.c index 4360a6f40..c6527dfdc 100644 --- a/channels/urbdrc/client/libusb/libusb_udevice.c +++ b/channels/urbdrc/client/libusb/libusb_udevice.c @@ -501,17 +501,19 @@ static LIBUSB_DEVICE* udev_get_libusb_dev(libusb_context* context, uint8_t bus_n for (i = 0; i < total_device; i++) { - uint8_t cbus = libusb_get_bus_number(libusb_list[i]); - uint8_t caddr = libusb_get_device_address(libusb_list[i]); - - if ((bus_number == cbus) && (dev_number == caddr)) + LIBUSB_DEVICE* dev = libusb_list[i]; + if ((bus_number == libusb_get_bus_number(dev)) && + (dev_number == libusb_get_device_address(dev))) { - device = libusb_list[i]; - break; + device = dev; + } + else + { + libusb_unref_device(dev); } } - libusb_free_device_list(libusb_list, 1); + libusb_free_device_list(libusb_list, 0); return device; } @@ -533,7 +535,6 @@ static LIBUSB_DEVICE_DESCRIPTOR* udev_new_descript(URBDRC_PLUGIN* urbdrc, LIBUSB return descriptor; } - static int libusb_udev_select_interface(IUDEVICE* idev, BYTE InterfaceNumber, BYTE AlternateSetting) { int error = 0, diff = 0; @@ -1023,6 +1024,9 @@ static BOOL libusb_udev_detach_kernel_driver(IUDEVICE* idev) if (!pdev || !pdev->LibusbConfig || !pdev->libusb_handle || !pdev->urbdrc) return FALSE; +#ifdef _WIN32 + return TRUE; +#else urbdrc = pdev->urbdrc; if ((pdev->status & URBDRC_DEVICE_DETACH_KERNEL) == 0) @@ -1043,6 +1047,7 @@ static BOOL libusb_udev_detach_kernel_driver(IUDEVICE* idev) } return TRUE; +#endif } static BOOL libusb_udev_attach_kernel_driver(IUDEVICE* idev) @@ -1059,12 +1064,14 @@ static BOOL libusb_udev_attach_kernel_driver(IUDEVICE* idev) log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG, "libusb_release_interface", err); +#ifndef _WIN32 if (err != LIBUSB_ERROR_NO_DEVICE) { err = libusb_attach_kernel_driver(pdev->libusb_handle, i); log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG, "libusb_attach_kernel_driver if=%d", err, i); } +#endif } return TRUE; @@ -1485,6 +1492,7 @@ static void udev_free(IUDEVICE* idev) ArrayList_Free(udev->request_queue); /* free the config descriptor that send from windows */ msusb_msconfig_free(udev->MsConfig); + libusb_unref_device(udev->libusb_dev); libusb_close(udev->libusb_handle); libusb_close(udev->hub_handle); free(udev->devDescriptor); @@ -1533,8 +1541,8 @@ static void udev_load_interface(UDEVICE* pdev) pdev->iface.free = udev_free; } -static int udev_get_hub_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVICE* pdev, - UINT16 bus_number, UINT16 dev_number) +static int udev_get_device_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVICE* pdev, + UINT16 bus_number, UINT16 dev_number) { int error; ssize_t i, total_device; @@ -1546,21 +1554,19 @@ static int udev_get_hub_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVI for (i = 0; i < total_device; i++) { - LIBUSB_DEVICE_HANDLE* handle; - uint8_t cbus = libusb_get_bus_number(libusb_list[i]); - uint8_t caddr = libusb_get_device_address(libusb_list[i]); + LIBUSB_DEVICE* dev = libusb_list[i]; - if ((bus_number != cbus) || (dev_number != caddr)) + if ((bus_number != libusb_get_bus_number(dev)) || + (dev_number != libusb_get_device_address(dev))) continue; - error = libusb_open(libusb_list[i], &handle); + error = libusb_open(dev, &pdev->libusb_handle); if (log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_open", error)) break; /* get port number */ - error = libusb_get_port_numbers(libusb_list[i], port_numbers, sizeof(port_numbers)); - libusb_close(handle); + error = libusb_get_port_numbers(dev, port_numbers, sizeof(port_numbers)); if (error < 1) { @@ -1578,29 +1584,40 @@ static int udev_get_hub_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVI WLog_Print(urbdrc->log, WLOG_DEBUG, " DevPath: %s", pdev->path); break; } + libusb_free_device_list(libusb_list, 1); + + if (error < 0) + return -1; + return 0; +} + +static int udev_get_hub_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVICE* pdev, + UINT16 bus_number, UINT16 dev_number) +{ + int error; + ssize_t i, total_device; + LIBUSB_DEVICE** libusb_list; + LIBUSB_DEVICE_HANDLE* handle; + total_device = libusb_get_device_list(ctx, &libusb_list); /* Look for device hub. */ - if (error == 0) + error = -1; + + for (i = 0; i < total_device; i++) { - error = -1; + LIBUSB_DEVICE* dev = libusb_list[i]; - for (i = 0; i < total_device; i++) - { - LIBUSB_DEVICE_HANDLE* handle; - uint8_t cbus = libusb_get_bus_number(libusb_list[i]); - uint8_t caddr = libusb_get_device_address(libusb_list[i]); + if ((bus_number != libusb_get_bus_number(dev)) || + (1 != libusb_get_device_address(dev))) /* Root hub allways first on bus. */ + continue; - if ((bus_number != cbus) || (1 != caddr)) /* Root hub allways first on bus. */ - continue; + WLog_Print(urbdrc->log, WLOG_DEBUG, " Open hub: %" PRIu16 "", bus_number); + error = libusb_open(dev, &handle); - WLog_Print(urbdrc->log, WLOG_DEBUG, " Open hub: %" PRIu16 "", bus_number); - error = libusb_open(libusb_list[i], &handle); + if (!log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_open", error)) + pdev->hub_handle = handle; - if (!log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_open", error)) - pdev->hub_handle = handle; - - break; - } + break; } libusb_free_device_list(libusb_list, 1); @@ -1651,30 +1668,26 @@ static IUDEVICE* udev_init(URBDRC_PLUGIN* urbdrc, libusb_context* context, LIBUS if (urbdrc->listener_callback) udev_set_channelManager(&pdev->iface, urbdrc->listener_callback->channel_mgr); + /* Get DEVICE handle */ + status = udev_get_device_handle(urbdrc, context, pdev, bus_number, dev_number); + if (status != LIBUSB_SUCCESS) + { + struct libusb_device_descriptor desc; + const uint8_t port = libusb_get_port_number(pdev->libusb_dev); + libusb_get_device_descriptor(pdev->libusb_dev, &desc); + + log_libusb_result(urbdrc->log, WLOG_ERROR, + "libusb_open [b=0x%02X,p=0x%02X,a=0x%02X,VID=0x%04X,PID=0x%04X]", status, + bus_number, port, dev_number, desc.idVendor, desc.idProduct); + goto fail; + } + /* Get HUB handle */ status = udev_get_hub_handle(urbdrc, context, pdev, bus_number, dev_number); if (status < 0) pdev->hub_handle = NULL; - { - struct libusb_device_descriptor desc; - const uint8_t bus = libusb_get_bus_number(pdev->libusb_dev); - const uint8_t port = libusb_get_port_number(pdev->libusb_dev); - const uint8_t addr = libusb_get_device_address(pdev->libusb_dev); - libusb_get_device_descriptor(pdev->libusb_dev, &desc); - - status = libusb_open(pdev->libusb_dev, &pdev->libusb_handle); - - if (status != LIBUSB_SUCCESS) - { - log_libusb_result(urbdrc->log, WLOG_ERROR, - "libusb_open [b=0x%02X,p=0x%02X,a=0x%02X,VID=0x%04X,PID=0x%04X]", - status, bus, port, addr, desc.idVendor, desc.idProduct); - goto fail; - } - } - pdev->devDescriptor = udev_new_descript(urbdrc, pdev->libusb_dev); if (!pdev->devDescriptor) @@ -1745,8 +1758,6 @@ size_t udev_new_by_id(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UINT16 idVendo { LIBUSB_DEVICE** libusb_list; UDEVICE** array; - UINT16 bus_number; - UINT16 dev_number; ssize_t i, total_device; size_t num = 0; @@ -1763,23 +1774,27 @@ size_t udev_new_by_id(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UINT16 idVendo for (i = 0; i < total_device; i++) { - LIBUSB_DEVICE_DESCRIPTOR* descriptor = udev_new_descript(urbdrc, libusb_list[i]); + LIBUSB_DEVICE* dev = libusb_list[i]; + LIBUSB_DEVICE_DESCRIPTOR* descriptor = udev_new_descript(urbdrc, dev); if ((descriptor->idVendor == idVendor) && (descriptor->idProduct == idProduct)) { - bus_number = libusb_get_bus_number(libusb_list[i]); - dev_number = libusb_get_device_address(libusb_list[i]); - array[num] = (PUDEVICE)udev_init(urbdrc, ctx, libusb_list[i], bus_number, dev_number); + array[num] = (PUDEVICE)udev_init(urbdrc, ctx, dev, libusb_get_bus_number(dev), + libusb_get_device_address(dev)); if (array[num] != NULL) num++; } + else + { + libusb_unref_device(dev); + } free(descriptor); } fail: - libusb_free_device_list(libusb_list, 1); + libusb_free_device_list(libusb_list, 0); *devArray = (IUDEVICE**)array; return num; } diff --git a/channels/urbdrc/client/libusb/libusb_udevman.c b/channels/urbdrc/client/libusb/libusb_udevman.c index afbb333ae..c609f6b9a 100644 --- a/channels/urbdrc/client/libusb/libusb_udevman.c +++ b/channels/urbdrc/client/libusb/libusb_udevman.c @@ -195,6 +195,12 @@ static size_t udevman_register_udevice(IUDEVMAN* idevman, BYTE bus_number, BYTE /* register all device that match pid vid */ num = udev_new_by_id(urbdrc, udevman->context, idVendor, idProduct, &devArray); + if (num == 0) + { + WLog_Print(urbdrc->log, WLOG_WARN, + "Could not find or redirect any usb devices by id %04x:%04x", idVendor, idProduct); + } + for (i = 0; i < num; i++) { UINT32 id; @@ -835,7 +841,7 @@ static BOOL poll_libusb_events(UDEVMAN* udevman) { int rc = LIBUSB_SUCCESS; struct timeval tv = { 0, 500 }; - if (libusb_try_lock_events(udevman->context)) + if (libusb_try_lock_events(udevman->context) == 0) { if (libusb_event_handling_ok(udevman->context)) { @@ -924,7 +930,7 @@ UINT freerdp_urbdrc_client_subsystem_entry(PFREERDP_URBDRC_SERVICE_ENTRY_POINTS udevman->next_device_id = BASE_USBDEVICE_NUM; udevman->iface.plugin = pEntryPoints->plugin; rc = libusb_init(&udevman->context); - + if (rc != LIBUSB_SUCCESS) goto fail;