Fix #5910: USB hotplug added device wrong

When a USB device was added via hotplug add_device was called
with wrong arguments.
This commit is contained in:
Armin Novak
2020-02-26 12:24:25 +01:00
committed by akallabeth
parent efde89607b
commit acb77391a2
8 changed files with 291 additions and 120 deletions

View File

@@ -348,7 +348,6 @@ static UINT urbdrc_process_query_device_text(IUDEVICE* pdev, URBDRC_CHANNEL_CALL
if (!pdev || !callback || !s || !udevman)
return ERROR_INVALID_PARAMETER;
if (Stream_GetRemainingLength(s) < 8)
return ERROR_INVALID_DATA;
@@ -1816,5 +1815,10 @@ UINT urbdrc_process_udev_data_transfer(URBDRC_CHANNEL_CALLBACK* callback, URBDRC
}
fail:
if (error)
{
WLog_WARN(TAG, "USB request failed with %08" PRIx32, error);
}
return error;
}

View File

@@ -81,6 +81,51 @@ struct _ASYNC_TRANSFER_USER_DATA
#endif
};
const char* usb_interface_class_to_string(uint8_t class)
{
switch (class)
{
case LIBUSB_CLASS_PER_INTERFACE:
return "LIBUSB_CLASS_PER_INTERFACE";
case LIBUSB_CLASS_AUDIO:
return "LIBUSB_CLASS_AUDIO";
case LIBUSB_CLASS_COMM:
return "LIBUSB_CLASS_COMM";
case LIBUSB_CLASS_HID:
return "LIBUSB_CLASS_HID";
case LIBUSB_CLASS_PHYSICAL:
return "LIBUSB_CLASS_PHYSICAL";
case LIBUSB_CLASS_PRINTER:
return "LIBUSB_CLASS_PRINTER";
case LIBUSB_CLASS_IMAGE:
return "LIBUSB_CLASS_IMAGE";
case LIBUSB_CLASS_MASS_STORAGE:
return "LIBUSB_CLASS_MASS_STORAGE";
case LIBUSB_CLASS_HUB:
return "LIBUSB_CLASS_HUB";
case LIBUSB_CLASS_DATA:
return "LIBUSB_CLASS_DATA";
case LIBUSB_CLASS_SMART_CARD:
return "LIBUSB_CLASS_SMART_CARD";
case LIBUSB_CLASS_CONTENT_SECURITY:
return "LIBUSB_CLASS_CONTENT_SECURITY";
case LIBUSB_CLASS_VIDEO:
return "LIBUSB_CLASS_VIDEO";
case LIBUSB_CLASS_PERSONAL_HEALTHCARE:
return "LIBUSB_CLASS_PERSONAL_HEALTHCARE";
case LIBUSB_CLASS_DIAGNOSTIC_DEVICE:
return "LIBUSB_CLASS_DIAGNOSTIC_DEVICE";
case LIBUSB_CLASS_WIRELESS:
return "LIBUSB_CLASS_WIRELESS";
case LIBUSB_CLASS_APPLICATION:
return "LIBUSB_CLASS_APPLICATION";
case LIBUSB_CLASS_VENDOR_SPEC:
return "LIBUSB_CLASS_VENDOR_SPEC";
default:
return "UNKNOWN_DEVICE_CLASS";
}
}
static ASYNC_TRANSFER_USER_DATA* async_transfer_user_data_new(IUDEVICE* idev, UINT32 MessageId,
size_t offset, size_t BufferSize,
size_t packetSize, BOOL NoAck,
@@ -375,21 +420,28 @@ static int func_claim_all_interface(URBDRC_PLUGIN* urbdrc, LIBUSB_DEVICE_HANDLE*
return 0;
}
static LIBUSB_DEVICE* udev_get_libusb_dev(int bus_number, int dev_number)
static LIBUSB_DEVICE* udev_get_libusb_dev(libusb_context* context, uint8_t bus_number,
uint8_t dev_number)
{
ssize_t i, total_device;
LIBUSB_DEVICE** libusb_list;
total_device = libusb_get_device_list(NULL, &libusb_list);
LIBUSB_DEVICE* device = NULL;
total_device = libusb_get_device_list(context, &libusb_list);
for (i = 0; i < total_device; i++)
{
if ((bus_number == libusb_get_bus_number(libusb_list[i])) &&
(dev_number == libusb_get_device_address(libusb_list[i])))
return libusb_list[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))
{
device = libusb_list[i];
break;
}
}
libusb_free_device_list(libusb_list, 1);
return NULL;
return device;
}
static LIBUSB_DEVICE_DESCRIPTOR* udev_new_descript(URBDRC_PLUGIN* urbdrc, LIBUSB_DEVICE* libusb_dev)
@@ -901,12 +953,14 @@ static BOOL libusb_udev_detach_kernel_driver(IUDEVICE* idev)
for (i = 0; i < pdev->LibusbConfig->bNumInterfaces; i++)
{
err = libusb_kernel_driver_active(pdev->libusb_handle, i);
WLog_Print(urbdrc->log, WLOG_DEBUG, "libusb_kernel_driver_active = %d", err);
WLog_Print(urbdrc->log, WLOG_DEBUG, "libusb_kernel_driver_active = %s [%d]",
libusb_error_name(err), err);
if (err)
{
err = libusb_detach_kernel_driver(pdev->libusb_handle, i);
WLog_Print(urbdrc->log, WLOG_DEBUG, "libusb_detach_kernel_driver = %d", err);
WLog_Print(urbdrc->log, WLOG_DEBUG, "libusb_detach_kernel_driver = %s [%d]",
libusb_error_name(err), err);
}
}
@@ -981,23 +1035,30 @@ static int libusb_udev_is_already_send(IUDEVICE* idev)
static void libusb_udev_channel_closed(IUDEVICE* idev)
{
UDEVICE* pdev = (UDEVICE*)idev;
const UINT16 idVendor = (UINT16)idev->query_device_descriptor(idev, ID_VENDOR);
const UINT16 idProduct = (UINT16)idev->query_device_descriptor(idev, ID_PRODUCT);
const uint8_t busNr = idev->get_bus_number(idev);
const uint8_t devNr = idev->get_dev_number(idev);
IWTSVirtualChannel* channel =
pdev->channelManager->FindChannelById(pdev->channelManager, pdev->channelID);
pdev->status |= URBDRC_DEVICE_CHANNEL_CLOSED;
if (channel)
if (pdev)
{
URBDRC_PLUGIN* urbdrc = pdev->urbdrc;
USB_SEARCHMAN* searchman = urbdrc->searchman;
const UINT16 idVendor = (UINT16)idev->query_device_descriptor(idev, ID_VENDOR);
const UINT16 idProduct = (UINT16)idev->query_device_descriptor(idev, ID_PRODUCT);
const uint8_t busNr = idev->get_bus_number(idev);
const uint8_t devNr = idev->get_dev_number(idev);
IWTSVirtualChannel* channel = NULL;
/* Notify the server the device is no longer available. */
channel->Write(channel, 0, NULL, NULL);
urbdrc->udevman->unregister_udevice(urbdrc->udevman, busNr, devNr);
searchman->add(searchman, idVendor, idProduct);
if (pdev->channelManager)
channel = IFCALLRESULT(NULL, pdev->channelManager->FindChannelById,
pdev->channelManager, pdev->channelID);
pdev->status |= URBDRC_DEVICE_CHANNEL_CLOSED;
if (channel)
{
URBDRC_PLUGIN* urbdrc = pdev->urbdrc;
USB_SEARCHMAN* searchman = urbdrc->searchman;
/* Notify the server the device is no longer available. */
channel->Write(channel, 0, NULL, NULL);
urbdrc->udevman->unregister_udevice(urbdrc->udevman, busNr, devNr);
searchman->add(searchman, idVendor, idProduct);
}
}
}
@@ -1013,11 +1074,6 @@ static char* libusb_udev_get_path(IUDEVICE* idev)
return pdev->path;
}
static BOOL libusb_udev_wait_for_detach(IUDEVICE* idev)
{
return TRUE;
}
static int libusb_udev_query_device_port_status(IUDEVICE* idev, UINT32* UsbdStatus,
UINT32* BufferSize, BYTE* Buffer)
{
@@ -1350,7 +1406,7 @@ static void udev_free(IUDEVICE* idev)
if (rc != LIBUSB_SUCCESS)
{
WLog_Print(urbdrc->log, WLOG_ERROR, "libusb_reset_device: error %s [%d[",
WLog_Print(urbdrc->log, WLOG_ERROR, "libusb_reset_device: error %s [%d]",
libusb_error_name(rc), rc);
}
}
@@ -1404,27 +1460,27 @@ static void udev_load_interface(UDEVICE* pdev)
pdev->iface.detach_kernel_driver = libusb_udev_detach_kernel_driver;
pdev->iface.attach_kernel_driver = libusb_udev_attach_kernel_driver;
pdev->iface.query_device_port_status = libusb_udev_query_device_port_status;
pdev->iface.wait_for_detach = libusb_udev_wait_for_detach;
pdev->iface.free = udev_free;
}
static int udev_get_hub_handle(URBDRC_PLUGIN* urbdrc, UDEVICE* pdev, UINT16 bus_number,
UINT16 dev_number)
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;
uint8_t port_numbers[16];
LIBUSB_DEVICE** libusb_list;
total_device = libusb_get_device_list(NULL, &libusb_list);
total_device = libusb_get_device_list(ctx, &libusb_list);
/* Look for device. */
error = -1;
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(libusb_list[i])) ||
(dev_number != libusb_get_device_address(libusb_list[i])))
if ((bus_number != cbus) || (dev_number != caddr))
continue;
error = libusb_open(libusb_list[i], &handle);
@@ -1465,10 +1521,10 @@ static int udev_get_hub_handle(URBDRC_PLUGIN* urbdrc, UDEVICE* pdev, UINT16 bus_
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(libusb_list[i])) ||
(1 !=
libusb_get_device_address(libusb_list[i]))) /* Root hub allways first on bus. */
if ((bus_number != cbus) || (1 != caddr)) /* Root hub allways first on bus. */
continue;
WLog_Print(urbdrc->log, WLOG_DEBUG, " Open hub: %" PRIu16 "", bus_number);
@@ -1503,11 +1559,11 @@ static void request_free(void* value)
async_transfer_user_data_free(user_data);
}
static IUDEVICE* udev_init(URBDRC_PLUGIN* urbdrc, LIBUSB_DEVICE* device, BYTE bus_number,
BYTE dev_number)
static IUDEVICE* udev_init(URBDRC_PLUGIN* urbdrc, libusb_context* context, LIBUSB_DEVICE* device,
BYTE bus_number, BYTE dev_number)
{
UDEVICE* pdev;
int status;
int status = LIBUSB_ERROR_OTHER;
LIBUSB_DEVICE_DESCRIPTOR* devDescriptor;
LIBUSB_CONFIG_DESCRIPTOR* config_temp;
LIBUSB_INTERFACE_DESCRIPTOR interface_temp;
@@ -1522,26 +1578,39 @@ static IUDEVICE* udev_init(URBDRC_PLUGIN* urbdrc, LIBUSB_DEVICE* device, BYTE bu
if (device)
pdev->libusb_dev = device;
else
pdev->libusb_dev = udev_get_libusb_dev(bus_number, dev_number);
pdev->libusb_dev = udev_get_libusb_dev(context, bus_number, dev_number);
if (pdev->libusb_dev == NULL)
goto fail;
status = libusb_open(pdev->libusb_dev, &pdev->libusb_handle);
if (status < 0)
{
WLog_Print(urbdrc->log, WLOG_ERROR, "libusb_open error: %i - %s", status,
libusb_error_name(status));
goto fail;
}
if (urbdrc->listener_callback)
udev_set_channelManager(&pdev->iface, urbdrc->listener_callback->channel_mgr);
/* Get HUB handle */
status = udev_get_hub_handle(urbdrc, pdev, bus_number, dev_number);
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)
{
WLog_Print(
urbdrc->log, WLOG_ERROR,
"libusb_open error: %i - %s [b=0x%02X,p=0x%02X,a=0x%02X,VID=0x%04X,PID=0x%04X]",
status, libusb_error_name(status), bus, port, addr, desc.idVendor, desc.idProduct);
goto fail;
}
}
pdev->devDescriptor = udev_new_descript(urbdrc, pdev->libusb_dev);
if (!pdev->devDescriptor)
@@ -1560,19 +1629,20 @@ static IUDEVICE* udev_init(URBDRC_PLUGIN* urbdrc, LIBUSB_DEVICE* device, BYTE bu
interface_temp = config_temp->interface[0].altsetting[0];
WLog_Print(urbdrc->log, WLOG_DEBUG,
"Registered Device: Vid: 0x%04" PRIX16 " Pid: 0x%04" PRIX16 ""
" InterfaceClass = 0x%02" PRIX8 "",
" InterfaceClass = %s",
pdev->devDescriptor->idVendor, pdev->devDescriptor->idProduct,
interface_temp.bInterfaceClass);
usb_interface_class_to_string(interface_temp.bInterfaceClass));
/* Check composite device */
devDescriptor = pdev->devDescriptor;
if ((devDescriptor->bNumConfigurations == 1) && (config_temp->bNumInterfaces > 1) &&
(devDescriptor->bDeviceClass == 0x0))
(devDescriptor->bDeviceClass == LIBUSB_CLASS_PER_INTERFACE))
{
pdev->isCompositeDevice = 1;
}
else if ((devDescriptor->bDeviceClass == 0xef) && (devDescriptor->bDeviceSubClass == 0x02) &&
(devDescriptor->bDeviceProtocol == 0x01))
else if ((devDescriptor->bDeviceClass == LIBUSB_CLASS_APPLICATION) &&
(devDescriptor->bDeviceSubClass == LIBUSB_CLASS_COMM) &&
(devDescriptor->bDeviceProtocol == LIBUSB_CLASS_AUDIO))
{
pdev->isCompositeDevice = 1;
}
@@ -1606,7 +1676,7 @@ fail:
return NULL;
}
size_t udev_new_by_id(URBDRC_PLUGIN* urbdrc, UINT16 idVendor, UINT16 idProduct,
size_t udev_new_by_id(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UINT16 idVendor, UINT16 idProduct,
IUDEVICE*** devArray)
{
LIBUSB_DEVICE** libusb_list;
@@ -1626,7 +1696,7 @@ size_t udev_new_by_id(URBDRC_PLUGIN* urbdrc, UINT16 idVendor, UINT16 idProduct,
if (!array)
return 0;
total_device = libusb_get_device_list(NULL, &libusb_list);
total_device = libusb_get_device_list(ctx, &libusb_list);
for (i = 0; i < total_device; i++)
{
@@ -1636,7 +1706,7 @@ size_t udev_new_by_id(URBDRC_PLUGIN* urbdrc, UINT16 idVendor, UINT16 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, libusb_list[i], bus_number, dev_number);
array[num] = (PUDEVICE)udev_init(urbdrc, ctx, libusb_list[i], bus_number, dev_number);
if (array[num] != NULL)
num++;
@@ -1650,8 +1720,9 @@ size_t udev_new_by_id(URBDRC_PLUGIN* urbdrc, UINT16 idVendor, UINT16 idProduct,
return num;
}
IUDEVICE* udev_new_by_addr(URBDRC_PLUGIN* urbdrc, BYTE bus_number, BYTE dev_number)
IUDEVICE* udev_new_by_addr(URBDRC_PLUGIN* urbdrc, libusb_context* context, BYTE bus_number,
BYTE dev_number)
{
WLog_Print(urbdrc->log, WLOG_DEBUG, "bus:%d dev:%d", bus_number, dev_number);
return udev_init(urbdrc, NULL, bus_number, dev_number);
return udev_init(urbdrc, context, NULL, bus_number, dev_number);
}

View File

@@ -69,8 +69,10 @@ struct _UDEVICE
};
typedef UDEVICE* PUDEVICE;
size_t udev_new_by_id(URBDRC_PLUGIN* urbdrc, UINT16 idVendor, UINT16 idProduct,
size_t udev_new_by_id(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UINT16 idVendor, UINT16 idProduct,
IUDEVICE*** devArray);
IUDEVICE* udev_new_by_addr(URBDRC_PLUGIN* urbdrc, BYTE bus_number, BYTE dev_number);
IUDEVICE* udev_new_by_addr(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, BYTE bus_number,
BYTE dev_number);
const char* usb_interface_class_to_string(uint8_t class);
#endif /* FREERDP_CHANNEL_URBDRC_CLIENT_LIBUSB_UDEVICE_H */

View File

@@ -151,7 +151,7 @@ static size_t udevman_register_udevice(IUDEVMAN* idevman, BYTE bus_number, BYTE
if (flag == UDEVMAN_FLAG_ADD_BY_ADDR)
{
IUDEVICE* tdev = udev_new_by_addr(urbdrc, bus_number, dev_number);
IUDEVICE* tdev = udev_new_by_addr(urbdrc, udevman->context, bus_number, dev_number);
if (tdev == NULL)
return 0;
@@ -180,7 +180,7 @@ static size_t udevman_register_udevice(IUDEVMAN* idevman, BYTE bus_number, BYTE
{
addnum = 0;
/* register all device that match pid vid */
num = udev_new_by_id(urbdrc, idVendor, idProduct, &devArray);
num = udev_new_by_id(urbdrc, udevman->context, idVendor, idProduct, &devArray);
for (i = 0; i < num; i++)
{
@@ -435,14 +435,6 @@ static BOOL udevman_parse_device_pid_vid(const char* str, size_t maxLen, UINT16*
return TRUE;
}
static int udevman_check_device_exist_by_id(IUDEVMAN* idevman, UINT16 idVendor, UINT16 idProduct)
{
if (libusb_open_device_with_vid_pid(NULL, idVendor, idProduct))
return 1;
return 0;
}
static int udevman_is_auto_add(IUDEVMAN* idevman)
{
UDEVMAN* udevman = (UDEVMAN*)idevman;
@@ -520,27 +512,131 @@ static void udevman_free(IUDEVMAN* idevman)
free(udevman);
}
static BOOL filter_by_class(uint8_t bDeviceClass, uint8_t bDeviceSubClass)
{
switch (bDeviceClass)
{
case LIBUSB_CLASS_AUDIO:
case LIBUSB_CLASS_HID:
case LIBUSB_CLASS_MASS_STORAGE:
case LIBUSB_CLASS_HUB:
case LIBUSB_CLASS_SMART_CARD:
return TRUE;
default:
break;
}
switch (bDeviceSubClass)
{
default:
break;
}
return FALSE;
}
static BOOL append(char* dst, size_t length, const char* src)
{
size_t slen = strlen(src);
size_t dlen = strnlen(dst, length);
if (dlen + slen >= length)
return FALSE;
strcat(dst, src);
return TRUE;
}
static BOOL device_is_filtered(struct libusb_device* dev,
const struct libusb_device_descriptor* desc,
libusb_hotplug_event event)
{
char buffer[8192] = { 0 };
char* what;
BOOL filtered = FALSE;
append(buffer, sizeof(buffer), usb_interface_class_to_string(desc->bDeviceClass));
if (filter_by_class(desc->bDeviceClass, desc->bDeviceSubClass))
filtered = TRUE;
switch (desc->bDeviceClass)
{
case LIBUSB_CLASS_PER_INTERFACE:
{
struct libusb_config_descriptor* config = NULL;
int rc = libusb_get_active_config_descriptor(dev, &config);
if (rc == LIBUSB_SUCCESS)
{
uint8_t x;
for (x = 0; x < config->bNumInterfaces; x++)
{
uint8_t y;
const struct libusb_interface* ifc = &config->interface[x];
for (y = 0; y < ifc->num_altsetting; y++)
{
const struct libusb_interface_descriptor* const alt = &ifc->altsetting[y];
if (filter_by_class(alt->bInterfaceClass, alt->bInterfaceSubClass))
filtered = TRUE;
append(buffer, sizeof(buffer), "|");
append(buffer, sizeof(buffer),
usb_interface_class_to_string(alt->bInterfaceClass));
}
}
}
libusb_free_config_descriptor(config);
}
break;
default:
break;
}
if (filtered)
what = "Filtered";
else
{
switch (event)
{
case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT:
what = "Hotplug remove";
break;
case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED:
what = "Hotplug add";
break;
default:
what = "Hotplug unknown";
break;
}
}
WLog_DBG(TAG, "%s device VID=0x%04X,PID=0x%04X class %s", what, desc->idVendor, desc->idProduct,
buffer);
return filtered;
}
static int hotplug_callback(struct libusb_context* ctx, struct libusb_device* dev,
libusb_hotplug_event event, void* user_data)
{
int rc;
struct libusb_device_descriptor desc;
IUDEVMAN* idevman = (IUDEVMAN*)user_data;
const uint8_t bus = libusb_get_bus_number(dev);
const uint8_t addr = libusb_get_device_address(dev);
rc = libusb_get_device_descriptor(dev, &desc);
int rc = libusb_get_device_descriptor(dev, &desc);
WINPR_UNUSED(ctx);
if (rc != LIBUSB_SUCCESS)
return rc;
if (device_is_filtered(dev, &desc, event))
return 0;
switch (event)
{
case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED:
add_device(idevman, bus, addr, desc.iManufacturer, desc.iProduct);
add_device(idevman, bus, addr, desc.idVendor, desc.idProduct);
break;
case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT:
del_device(idevman, bus, addr, desc.iManufacturer, desc.iProduct);
del_device(idevman, bus, addr, desc.idVendor, desc.idProduct);
break;
default:
@@ -573,7 +669,6 @@ static void udevman_load_interface(UDEVMAN* udevman)
udevman->iface.unregister_udevice = udevman_unregister_udevice;
udevman->iface.get_udevice_by_UsbDevice = udevman_get_udevice_by_UsbDevice;
/* Extension */
udevman->iface.check_device_exist_by_id = udevman_check_device_exist_by_id;
udevman->iface.isAutoAdd = udevman_is_auto_add;
/* Basic state */
BASIC_STATE_FUNC_REGISTER(defUsbDevice, udevman);

View File

@@ -33,22 +33,42 @@ static void searchman_rewind(USB_SEARCHMAN* searchman)
searchman->idev = searchman->head;
}
static int searchman_has_next(USB_SEARCHMAN* searchman)
{
if (searchman->idev == NULL)
return 0;
else
return 1;
}
static USB_SEARCHDEV* searchman_get_next(USB_SEARCHMAN* searchman)
{
USB_SEARCHDEV* search;
if (!searchman)
return NULL;
search = searchman->idev;
if (!search)
return NULL;
searchman->idev = (USB_SEARCHDEV*)searchman->idev->next;
return search;
}
static USB_SEARCHDEV* searchman_get_by_vid_pid(USB_SEARCHMAN* searchman, UINT16 idVendor,
UINT16 idProduct)
{
USB_SEARCHDEV* dev;
if (!searchman)
return NULL;
searchman->rewind(searchman);
while ((dev = searchman->get_next(searchman)) != NULL)
{
if ((dev->idVendor == idVendor) && (dev->idProduct == idProduct))
{
WLog_VRB(TAG, "Searchman Find Device: %04" PRIx16 ":%04" PRIx16 "", dev->idVendor,
dev->idProduct);
return dev;
}
}
return NULL;
}
static BOOL searchman_list_add(USB_SEARCHMAN* searchman, UINT16 idVendor, UINT16 idProduct)
{
USB_SEARCHDEV* search;
@@ -84,11 +104,9 @@ static int searchman_list_remove(USB_SEARCHMAN* searchman, UINT16 idVendor, UINT
USB_SEARCHDEV* point;
searchman_rewind(searchman);
while (searchman_has_next(searchman) != 0)
while ((point = searchman_get_next(searchman)) != NULL)
{
point = searchman_get_next(searchman);
if (point->idVendor == idVendor && point->idProduct == idProduct)
if ((point->idVendor == idVendor) && (point->idProduct == idProduct))
{
/* set previous device to point to next device */
search = point;
@@ -143,9 +161,8 @@ static void searchman_list_show(USB_SEARCHMAN* self)
WLog_Print(urbdrc->log, WLOG_DEBUG, "=========== Usb Search List =========");
self->rewind(self);
while (self->has_next(self))
while ((usb = self->get_next(self)) != NULL)
{
usb = self->get_next(self);
WLog_Print(urbdrc->log, WLOG_DEBUG, " USB %d: ", num++);
WLog_Print(urbdrc->log, WLOG_DEBUG, " idVendor: 0x%04" PRIX16 "", usb->idVendor);
WLog_Print(urbdrc->log, WLOG_DEBUG, " idProduct: 0x%04" PRIX16 "", usb->idProduct);
@@ -183,8 +200,8 @@ USB_SEARCHMAN* searchman_new(void* urbdrc, UINT32 UsbDevice)
searchman->remove = searchman_list_remove;
searchman->rewind = searchman_rewind;
searchman->get_next = searchman_get_next;
searchman->has_next = searchman_has_next;
searchman->show = searchman_list_show;
searchman->get_next_by_vid_pid = searchman_get_by_vid_pid;
searchman->free = searchman_free;
return searchman;
}

View File

@@ -55,10 +55,11 @@ struct _USB_SEARCHMAN
BOOL (*add)(USB_SEARCHMAN* seachman, UINT16 idVendor, UINT16 idProduct);
/* remove a usb device from list */
int (*remove)(USB_SEARCHMAN* searchman, UINT16 idVendor, UINT16 idProduct);
/* check list has next device*/
int (*has_next)(USB_SEARCHMAN* seachman);
/* get the device from list*/
USB_SEARCHDEV* (*get_next)(USB_SEARCHMAN* seachman);
/* get the device by vendor and product */
USB_SEARCHDEV* (*get_next_by_vid_pid)(USB_SEARCHMAN* seachman, UINT16 idVendor,
UINT16 idProduct);
/* free! */
void (*free)(USB_SEARCHMAN* searchman);
};

View File

@@ -825,42 +825,27 @@ BOOL add_device(IUDEVMAN* idevman, BYTE busnum, BYTE devnum, UINT16 idVendor, UI
if (!searchman)
return FALSE;
searchman->rewind(searchman);
sdev = searchman->get_next_by_vid_pid(searchman, idVendor, idProduct);
while (searchman->has_next(searchman))
{
USB_SEARCHDEV* dev = searchman->get_next(searchman);
if (dev->idVendor == idVendor && dev->idProduct == idProduct)
{
WLog_Print(urbdrc->log, WLOG_TRACE,
"Searchman Find Device: %04" PRIx16 ":%04" PRIx16 "", dev->idVendor,
dev->idProduct);
found = TRUE;
sdev = dev;
break;
}
}
if (!found && idevman->isAutoAdd(idevman))
if (!sdev && idevman->isAutoAdd(idevman))
{
WLog_Print(urbdrc->log, WLOG_TRACE, "Auto Find Device: %04x:%04x ", idVendor, idProduct);
found = TRUE;
}
if (found)
if (sdev || found)
{
success = idevman->register_udevice(idevman, busnum, devnum, searchman->UsbDevice, 0, 0,
UDEVMAN_FLAG_ADD_BY_ADDR);
}
if (success)
if (success > 0)
{
searchman->UsbDevice++;
urdbrc_send_virtual_channel_add(idevman->plugin, get_channel(idevman),
5 + searchman->UsbDevice);
if (found && sdev)
if (sdev)
searchman->remove(searchman, sdev->idVendor, sdev->idProduct);
}

View File

@@ -163,9 +163,6 @@ struct _IUDEVICE
BOOL (*attach_kernel_driver)(IUDEVICE* idev);
/* Wait for 5 sec */
BOOL (*wait_for_detach)(IUDEVICE* idev);
int (*query_device_port_status)(IUDEVICE* idev, UINT32* UsbdStatus, UINT32* BufferSize,
BYTE* Buffer);
@@ -213,7 +210,6 @@ struct _IUDEVMAN
IUDEVICE* (*get_udevice_by_UsbDevice)(IUDEVMAN* idevman, UINT32 UsbDevice);
/* Extension */
int (*check_device_exist_by_id)(IUDEVMAN* idevman, UINT16 idVendor, UINT16 idProduct);
int (*isAutoAdd)(IUDEVMAN* idevman);
/* Basic state */