26 #include <winpr/crt.h>
27 #include <winpr/cmdline.h>
28 #include <winpr/collections.h>
30 #include <freerdp/addin.h>
32 #include "urbdrc_types.h"
33 #include "urbdrc_main.h"
35 #include "libusb_udevice.h"
39 #if !defined(LIBUSB_HOTPLUG_NO_FLAGS)
40 #define LIBUSB_HOTPLUG_NO_FLAGS 0
43 #define BASIC_STATE_FUNC_DEFINED(_arg, _type) \
44 static _type udevman_get_##_arg(IUDEVMAN* idevman) \
46 UDEVMAN* udevman = (UDEVMAN*)idevman; \
47 return udevman->_arg; \
49 static void udevman_set_##_arg(IUDEVMAN* idevman, _type _t) \
51 UDEVMAN* udevman = (UDEVMAN*)idevman; \
55 #define BASIC_STATE_FUNC_REGISTER(_arg, _man) \
56 _man->iface.get_##_arg = udevman_get_##_arg; \
57 (_man)->iface.set_##_arg = udevman_set_##_arg
73 LPCSTR devices_vid_pid;
75 wArrayList* hotplug_vid_pids;
78 UINT32 next_device_id;
81 HANDLE devman_loading;
82 libusb_context* context;
86 typedef UDEVMAN* PUDEVMAN;
88 static BOOL poll_libusb_events(UDEVMAN* udevman);
90 static void udevman_rewind(IUDEVMAN* idevman)
92 UDEVMAN* udevman = (UDEVMAN*)idevman;
93 udevman->idev = udevman->head;
96 static BOOL udevman_has_next(IUDEVMAN* idevman)
98 UDEVMAN* udevman = (UDEVMAN*)idevman;
100 if (!udevman || !udevman->idev)
106 static IUDEVICE* udevman_get_next(IUDEVMAN* idevman)
108 UDEVMAN* udevman = (UDEVMAN*)idevman;
109 IUDEVICE* pdev = NULL;
110 pdev = udevman->idev;
111 udevman->idev = (IUDEVICE*)((
UDEVICE*)udevman->idev)->next;
115 static IUDEVICE* udevman_get_udevice_by_addr(IUDEVMAN* idevman, BYTE bus_number, BYTE dev_number)
117 IUDEVICE* dev = NULL;
122 idevman->loading_lock(idevman);
123 idevman->rewind(idevman);
125 while (idevman->has_next(idevman))
127 IUDEVICE* pdev = idevman->get_next(idevman);
129 if ((pdev->get_bus_number(pdev) == bus_number) &&
130 (pdev->get_dev_number(pdev) == dev_number))
137 idevman->loading_unlock(idevman);
141 static size_t udevman_register_udevice(IUDEVMAN* idevman, BYTE bus_number, BYTE dev_number,
142 UINT16 idVendor, UINT16 idProduct, UINT32 flag)
144 UDEVMAN* udevman = (UDEVMAN*)idevman;
145 IUDEVICE* pdev = NULL;
146 IUDEVICE** devArray = NULL;
151 if (!idevman || !idevman->plugin)
155 pdev = udevman_get_udevice_by_addr(idevman, bus_number, dev_number);
160 if (flag & UDEVMAN_FLAG_ADD_BY_ADDR)
163 IUDEVICE* tdev = udev_new_by_addr(urbdrc, udevman->context, bus_number, dev_number);
168 id = idevman->get_next_device_id(idevman);
169 tdev->set_UsbDevice(tdev,
id);
170 idevman->loading_lock(idevman);
172 if (udevman->head == NULL)
175 udevman->head = tdev;
176 udevman->tail = tdev;
181 udevman->tail->set_p_next(udevman->tail, tdev);
182 tdev->set_p_prev(tdev, udevman->tail);
183 udevman->tail = tdev;
186 udevman->device_num += 1;
187 idevman->loading_unlock(idevman);
189 else if (flag & UDEVMAN_FLAG_ADD_BY_VID_PID)
193 num = udev_new_by_id(urbdrc, udevman->context, idVendor, idProduct, &devArray);
197 WLog_Print(urbdrc->log, WLOG_WARN,
198 "Could not find or redirect any usb devices by id %04x:%04x", idVendor,
202 for (
size_t i = 0; i < num; i++)
205 IUDEVICE* tdev = devArray[i];
207 if (udevman_get_udevice_by_addr(idevman, tdev->get_bus_number(tdev),
208 tdev->get_dev_number(tdev)) != NULL)
215 id = idevman->get_next_device_id(idevman);
216 tdev->set_UsbDevice(tdev,
id);
217 idevman->loading_lock(idevman);
219 if (udevman->head == NULL)
222 udevman->head = tdev;
223 udevman->tail = tdev;
228 udevman->tail->set_p_next(udevman->tail, tdev);
229 tdev->set_p_prev(tdev, udevman->tail);
230 udevman->tail = tdev;
233 udevman->device_num += 1;
234 idevman->loading_unlock(idevman);
243 WLog_Print(urbdrc->log, WLOG_ERROR,
"udevman_register_udevice: Invalid flag=%08" PRIx32,
251 static BOOL udevman_unregister_udevice(IUDEVMAN* idevman, BYTE bus_number, BYTE dev_number)
253 UDEVMAN* udevman = (UDEVMAN*)idevman;
255 UDEVICE* dev = (
UDEVICE*)udevman_get_udevice_by_addr(idevman, bus_number, dev_number);
257 if (!dev || !idevman)
260 idevman->loading_lock(idevman);
261 idevman->rewind(idevman);
263 while (idevman->has_next(idevman))
265 pdev = (
UDEVICE*)idevman->get_next(idevman);
270 if (dev->prev != NULL)
274 pdev->next = dev->next;
279 udevman->head = (IUDEVICE*)dev->next;
284 if (dev->next != NULL)
288 pdev->prev = dev->prev;
293 udevman->tail = (IUDEVICE*)dev->prev;
296 udevman->device_num--;
301 idevman->loading_unlock(idevman);
305 dev->iface.free(&dev->iface);
313 static BOOL udevman_unregister_all_udevices(IUDEVMAN* idevman)
315 UDEVMAN* udevman = (UDEVMAN*)idevman;
323 idevman->loading_lock(idevman);
324 idevman->rewind(idevman);
326 while (idevman->has_next(idevman))
334 if (dev->prev != NULL)
338 pdev->next = dev->next;
343 udevman->head = (IUDEVICE*)dev->next;
348 if (dev->next != NULL)
352 pdev->prev = dev->prev;
357 udevman->tail = (IUDEVICE*)dev->prev;
360 dev->iface.free(&dev->iface);
361 udevman->device_num--;
364 idevman->loading_unlock(idevman);
369 static int udevman_is_auto_add(IUDEVMAN* idevman)
371 UDEVMAN* udevman = (UDEVMAN*)idevman;
372 return (udevman->flags & UDEVMAN_FLAG_ADD_BY_AUTO) ? 1 : 0;
375 static IUDEVICE* udevman_get_udevice_by_UsbDevice(IUDEVMAN* idevman, UINT32 UsbDevice)
380 if (!idevman || !idevman->plugin)
384 UsbDevice = UsbDevice & INTERFACE_ID_MASK;
386 idevman->loading_lock(idevman);
387 idevman->rewind(idevman);
389 while (idevman->has_next(idevman))
391 pdev = (
UDEVICE*)idevman->get_next(idevman);
393 if (pdev->UsbDevice == UsbDevice)
395 idevman->loading_unlock(idevman);
396 return (IUDEVICE*)pdev;
400 idevman->loading_unlock(idevman);
401 WLog_Print(urbdrc->log, WLOG_WARN,
"Failed to find a USB device mapped to deviceId=%08" PRIx32,
406 static IUDEVICE* udevman_get_udevice_by_ChannelID(IUDEVMAN* idevman, UINT32 channelID)
411 if (!idevman || !idevman->plugin)
416 idevman->loading_lock(idevman);
417 idevman->rewind(idevman);
419 while (idevman->has_next(idevman))
421 pdev = (
UDEVICE*)idevman->get_next(idevman);
423 if (pdev->channelID == channelID)
425 idevman->loading_unlock(idevman);
426 return (IUDEVICE*)pdev;
430 idevman->loading_unlock(idevman);
431 WLog_Print(urbdrc->log, WLOG_WARN,
"Failed to find a USB device mapped to channelID=%08" PRIx32,
436 static void udevman_loading_lock(IUDEVMAN* idevman)
438 UDEVMAN* udevman = (UDEVMAN*)idevman;
439 (void)WaitForSingleObject(udevman->devman_loading, INFINITE);
442 static void udevman_loading_unlock(IUDEVMAN* idevman)
444 UDEVMAN* udevman = (UDEVMAN*)idevman;
445 (void)ReleaseMutex(udevman->devman_loading);
448 BASIC_STATE_FUNC_DEFINED(device_num, UINT32)
450 static UINT32 udevman_get_next_device_id(IUDEVMAN* idevman)
452 UDEVMAN* udevman = (UDEVMAN*)idevman;
453 return udevman->next_device_id++;
456 static void udevman_set_next_device_id(IUDEVMAN* idevman, UINT32 _t)
458 UDEVMAN* udevman = (UDEVMAN*)idevman;
459 udevman->next_device_id = _t;
462 static void udevman_free(IUDEVMAN* idevman)
464 UDEVMAN* udevman = (UDEVMAN*)idevman;
469 udevman->running = FALSE;
472 (void)WaitForSingleObject(udevman->thread, INFINITE);
473 (void)CloseHandle(udevman->thread);
476 udevman_unregister_all_udevices(idevman);
478 if (udevman->devman_loading)
479 (void)CloseHandle(udevman->devman_loading);
481 libusb_exit(udevman->context);
483 ArrayList_Free(udevman->hotplug_vid_pids);
487 static BOOL filter_by_class(uint8_t bDeviceClass, uint8_t bDeviceSubClass)
489 switch (bDeviceClass)
491 case LIBUSB_CLASS_AUDIO:
492 case LIBUSB_CLASS_HID:
493 case LIBUSB_CLASS_MASS_STORAGE:
494 case LIBUSB_CLASS_HUB:
495 case LIBUSB_CLASS_SMART_CARD:
501 switch (bDeviceSubClass)
510 static BOOL append(
char* dst,
size_t length,
const char* src)
512 return winpr_str_append(src, dst, length, NULL);
515 static BOOL device_is_filtered(
struct libusb_device* dev,
516 const struct libusb_device_descriptor* desc,
517 libusb_hotplug_event event)
519 char buffer[8192] = { 0 };
521 BOOL filtered = FALSE;
522 append(buffer,
sizeof(buffer), usb_interface_class_to_string(desc->bDeviceClass));
523 if (filter_by_class(desc->bDeviceClass, desc->bDeviceSubClass))
526 switch (desc->bDeviceClass)
528 case LIBUSB_CLASS_PER_INTERFACE:
530 struct libusb_config_descriptor* config = NULL;
531 int rc = libusb_get_active_config_descriptor(dev, &config);
532 if (rc == LIBUSB_SUCCESS)
534 for (uint8_t x = 0; x < config->bNumInterfaces; x++)
536 const struct libusb_interface* ifc = &config->interface[x];
537 for (
int y = 0; y < ifc->num_altsetting; y++)
539 const struct libusb_interface_descriptor*
const alt = &ifc->altsetting[y];
540 if (filter_by_class(alt->bInterfaceClass, alt->bInterfaceSubClass))
543 append(buffer,
sizeof(buffer),
"|");
544 append(buffer,
sizeof(buffer),
545 usb_interface_class_to_string(alt->bInterfaceClass));
549 libusb_free_config_descriptor(config);
562 case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT:
563 what =
"Hotplug remove";
565 case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED:
566 what =
"Hotplug add";
569 what =
"Hotplug unknown";
574 WLog_DBG(TAG,
"%s device VID=0x%04X,PID=0x%04X class %s", what, desc->idVendor, desc->idProduct,
579 static int LIBUSB_CALL hotplug_callback(
struct libusb_context* ctx,
struct libusb_device* dev,
580 libusb_hotplug_event event,
void* user_data)
583 struct libusb_device_descriptor desc;
584 UDEVMAN* udevman = (UDEVMAN*)user_data;
585 const uint8_t bus = libusb_get_bus_number(dev);
586 const uint8_t addr = libusb_get_device_address(dev);
587 int rc = libusb_get_device_descriptor(dev, &desc);
591 if (rc != LIBUSB_SUCCESS)
596 case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED:
597 pair.vid = desc.idVendor;
598 pair.pid = desc.idProduct;
599 if ((ArrayList_Contains(udevman->hotplug_vid_pids, &pair)) ||
600 (udevman->iface.isAutoAdd(&udevman->iface) &&
601 !device_is_filtered(dev, &desc, event)))
603 add_device(&udevman->iface, DEVICE_ADD_FLAG_ALL, bus, addr, desc.idVendor,
608 case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT:
609 del_device(&udevman->iface, DEVICE_ADD_FLAG_ALL, bus, addr, desc.idVendor,
620 static BOOL udevman_initialize(IUDEVMAN* idevman, UINT32 channelId)
622 UDEVMAN* udevman = (UDEVMAN*)idevman;
627 idevman->status &= ~URBDRC_DEVICE_CHANNEL_CLOSED;
628 idevman->controlChannelId = channelId;
632 static BOOL udevman_vid_pid_pair_equals(
const void* objA,
const void* objB)
634 const VID_PID_PAIR* a = objA;
635 const VID_PID_PAIR* b = objB;
637 return (a->vid == b->vid) && (a->pid == b->pid);
640 static BOOL udevman_parse_device_id_addr(
const char** str, UINT16* id1, UINT16* id2, UINT16 max,
641 char split_sign,
char delimiter)
645 unsigned long rc = 0;
647 rc = strtoul(*str, &mid, 16);
649 if ((mid == *str) || (*mid != split_sign) || (rc > max))
653 rc = strtoul(++mid, &end, 16);
655 if ((end == mid) || (rc > max))
663 if (*end == delimiter)
672 static BOOL urbdrc_udevman_register_devices(UDEVMAN* udevman,
const char* devices, BOOL add_by_addr)
674 const char* pos = devices;
675 VID_PID_PAIR* idpair = NULL;
681 if (!udevman_parse_device_id_addr(&pos, &id1, &id2, (add_by_addr) ? UINT8_MAX : UINT16_MAX,
684 WLog_ERR(TAG,
"Invalid device argument: \"%s\"", devices);
690 add_device(&udevman->iface, DEVICE_ADD_FLAG_BUS | DEVICE_ADD_FLAG_DEV, (UINT8)id1,
695 idpair = calloc(1,
sizeof(VID_PID_PAIR));
697 return CHANNEL_RC_NO_MEMORY;
700 if (!ArrayList_Append(udevman->hotplug_vid_pids, idpair))
703 return CHANNEL_RC_NO_MEMORY;
706 add_device(&udevman->iface, DEVICE_ADD_FLAG_VENDOR | DEVICE_ADD_FLAG_PRODUCT, 0, 0, id1,
712 return CHANNEL_RC_OK;
715 static UINT urbdrc_udevman_parse_addin_args(UDEVMAN* udevman,
const ADDIN_ARGV* args)
717 LPCSTR devices = NULL;
719 for (
int x = 0; x < args->argc; x++)
721 const char* arg = args->argv[x];
722 if (strcmp(arg,
"dbg") == 0)
724 WLog_SetLogLevel(WLog_Get(TAG), WLOG_TRACE);
726 else if (_strnicmp(arg,
"device:", 7) == 0)
729 const char* val = &arg[7];
730 const size_t len = strlen(val);
731 if (strcmp(val,
"*") == 0)
733 udevman->flags |= UDEVMAN_FLAG_ADD_BY_AUTO;
735 else if (_strnicmp(arg,
"USBInstanceID:", 14) == 0)
739 else if ((val[0] ==
'{') && (val[len - 1] ==
'}'))
744 else if (_strnicmp(arg,
"dev:", 4) == 0)
748 else if (_strnicmp(arg,
"id", 2) == 0)
750 const char* p = strchr(arg,
':');
752 udevman->devices_vid_pid = p + 1;
754 udevman->flags = UDEVMAN_FLAG_ADD_BY_VID_PID;
756 else if (_strnicmp(arg,
"addr", 4) == 0)
758 const char* p = strchr(arg,
':');
760 udevman->devices_addr = p + 1;
762 udevman->flags = UDEVMAN_FLAG_ADD_BY_ADDR;
764 else if (strcmp(arg,
"auto") == 0)
766 udevman->flags |= UDEVMAN_FLAG_ADD_BY_AUTO;
770 const size_t len = strlen(arg);
771 if ((arg[0] ==
'{') && (arg[len - 1] ==
'}'))
779 if (udevman->flags & UDEVMAN_FLAG_ADD_BY_VID_PID)
780 udevman->devices_vid_pid = devices;
781 else if (udevman->flags & UDEVMAN_FLAG_ADD_BY_ADDR)
782 udevman->devices_addr = devices;
785 return CHANNEL_RC_OK;
788 static UINT udevman_listener_created_callback(IUDEVMAN* iudevman)
791 UDEVMAN* udevman = (UDEVMAN*)iudevman;
793 if (udevman->devices_vid_pid)
795 status = urbdrc_udevman_register_devices(udevman, udevman->devices_vid_pid, FALSE);
796 if (status != CHANNEL_RC_OK)
800 if (udevman->devices_addr)
801 return urbdrc_udevman_register_devices(udevman, udevman->devices_addr, TRUE);
803 return CHANNEL_RC_OK;
806 static void udevman_load_interface(UDEVMAN* udevman)
809 udevman->iface.free = udevman_free;
811 udevman->iface.rewind = udevman_rewind;
812 udevman->iface.get_next = udevman_get_next;
813 udevman->iface.has_next = udevman_has_next;
814 udevman->iface.register_udevice = udevman_register_udevice;
815 udevman->iface.unregister_udevice = udevman_unregister_udevice;
816 udevman->iface.get_udevice_by_UsbDevice = udevman_get_udevice_by_UsbDevice;
817 udevman->iface.get_udevice_by_ChannelID = udevman_get_udevice_by_ChannelID;
819 udevman->iface.isAutoAdd = udevman_is_auto_add;
821 BASIC_STATE_FUNC_REGISTER(device_num, udevman);
822 BASIC_STATE_FUNC_REGISTER(next_device_id, udevman);
825 udevman->iface.loading_lock = udevman_loading_lock;
826 udevman->iface.loading_unlock = udevman_loading_unlock;
827 udevman->iface.initialize = udevman_initialize;
828 udevman->iface.listener_created_callback = udevman_listener_created_callback;
831 static BOOL poll_libusb_events(UDEVMAN* udevman)
833 int rc = LIBUSB_SUCCESS;
834 struct timeval tv = { 0, 500 };
835 if (libusb_try_lock_events(udevman->context) == 0)
837 if (libusb_event_handling_ok(udevman->context))
839 rc = libusb_handle_events_locked(udevman->context, &tv);
840 if (rc != LIBUSB_SUCCESS)
841 WLog_WARN(TAG,
"libusb_handle_events_locked %d", rc);
843 libusb_unlock_events(udevman->context);
847 libusb_lock_event_waiters(udevman->context);
848 if (libusb_event_handler_active(udevman->context))
850 rc = libusb_wait_for_event(udevman->context, &tv);
851 if (rc < LIBUSB_SUCCESS)
852 WLog_WARN(TAG,
"libusb_wait_for_event %d", rc);
854 libusb_unlock_event_waiters(udevman->context);
860 static DWORD WINAPI poll_thread(LPVOID lpThreadParameter)
862 libusb_hotplug_callback_handle handle = 0;
863 UDEVMAN* udevman = (UDEVMAN*)lpThreadParameter;
864 BOOL hasHotplug = libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG);
868 int rc = libusb_hotplug_register_callback(
870 LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
871 LIBUSB_HOTPLUG_NO_FLAGS, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY,
872 LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, udevman, &handle);
874 if (rc != LIBUSB_SUCCESS)
875 udevman->running = FALSE;
878 WLog_WARN(TAG,
"Platform does not support libusb hotplug. USB devices plugged in later "
879 "will not be detected.");
881 while (udevman->running)
883 poll_libusb_events(udevman);
887 libusb_hotplug_deregister_callback(udevman->context, handle);
890 while (poll_libusb_events(udevman))
897 FREERDP_ENTRY_POINT(UINT VCAPITYPE libusb_freerdp_urbdrc_client_subsystem_entry(
903 UDEVMAN* udevman = NULL;
905 udevman = (PUDEVMAN)calloc(1,
sizeof(UDEVMAN));
910 udevman->hotplug_vid_pids = ArrayList_New(TRUE);
911 if (!udevman->hotplug_vid_pids)
913 obj = ArrayList_Object(udevman->hotplug_vid_pids);
914 obj->fnObjectFree = free;
915 obj->fnObjectEquals = udevman_vid_pid_pair_equals;
917 udevman->next_device_id = BASE_USBDEVICE_NUM;
918 udevman->iface.plugin = pEntryPoints->plugin;
919 rc = libusb_init(&udevman->context);
921 if (rc != LIBUSB_SUCCESS)
925 #if LIBUSB_API_VERSION >= 0x01000106
927 rc = libusb_set_option(udevman->context, LIBUSB_OPTION_USE_USBDK);
932 case LIBUSB_ERROR_NOT_FOUND:
933 case LIBUSB_ERROR_NOT_SUPPORTED:
934 WLog_WARN(TAG,
"LIBUSB_OPTION_USE_USBDK %s [%d]", libusb_strerror(rc), rc);
937 WLog_ERR(TAG,
"LIBUSB_OPTION_USE_USBDK %s [%d]", libusb_strerror(rc), rc);
943 udevman->flags = UDEVMAN_FLAG_ADD_BY_VID_PID;
944 udevman->devman_loading = CreateMutexA(NULL, FALSE,
"devman_loading");
946 if (!udevman->devman_loading)
950 udevman_load_interface(udevman);
951 status = urbdrc_udevman_parse_addin_args(udevman, args);
953 if (status != CHANNEL_RC_OK)
956 udevman->running = TRUE;
957 udevman->thread = CreateThread(NULL, 0, poll_thread, udevman, 0, NULL);
959 if (!udevman->thread)
962 if (!pEntryPoints->pRegisterUDEVMAN(pEntryPoints->plugin, (IUDEVMAN*)udevman))
965 WLog_DBG(TAG,
"UDEVMAN device registered.");
968 udevman_free(&udevman->iface);
969 return ERROR_INTERNAL_ERROR;
This struct contains function pointer to initialize/free objects.