1 /**
2  * FreeRDP: A Remote Desktop Protocol Implementation
3  * RemoteFX USB Redirection
4  *
5  * Copyright 2012 Atrust corp.
6  * Copyright 2012 Alfred Liu <alfred.liu@atruscorp.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 
26 #include <winpr/crt.h>
27 #include <winpr/cmdline.h>
28 #include <winpr/collections.h>
29 
30 #include <freerdp/addin.h>
31 
32 #include "urbdrc_types.h"
33 #include "urbdrc_main.h"
34 
35 #include "libusb_udevice.h"
36 
37 #include <libusb.h>
38 
39 #if !defined(LIBUSB_HOTPLUG_NO_FLAGS)
40 #define LIBUSB_HOTPLUG_NO_FLAGS 0
41 #endif
42 
43 #define BASIC_STATE_FUNC_DEFINED(_arg, _type)                   \
44 	static _type udevman_get_##_arg(IUDEVMAN* idevman)          \
45 	{                                                           \
46 		UDEVMAN* udevman = (UDEVMAN*)idevman;                   \
47 		return udevman->_arg;                                   \
48 	}                                                           \
49 	static void udevman_set_##_arg(IUDEVMAN* idevman, _type _t) \
50 	{                                                           \
51 		UDEVMAN* udevman = (UDEVMAN*)idevman;                   \
52 		udevman->_arg = _t;                                     \
53 	}
54 
55 #define BASIC_STATE_FUNC_REGISTER(_arg, _man)    \
56 	_man->iface.get_##_arg = udevman_get_##_arg; \
57 	_man->iface.set_##_arg = udevman_set_##_arg
58 
59 typedef struct _VID_PID_PAIR VID_PID_PAIR;
60 
61 struct _VID_PID_PAIR
62 {
63 	UINT16 vid;
64 	UINT16 pid;
65 };
66 
67 typedef struct _UDEVMAN UDEVMAN;
68 
69 struct _UDEVMAN
70 {
71 	IUDEVMAN iface;
72 
73 	IUDEVICE* idev; /* iterator device */
74 	IUDEVICE* head; /* head device in linked list */
75 	IUDEVICE* tail; /* tail device in linked list */
76 
77 	LPSTR devices_vid_pid;
78 	LPSTR devices_addr;
79 	wArrayList* hotplug_vid_pids;
80 	UINT16 flags;
81 	UINT32 device_num;
82 	UINT32 next_device_id;
83 	UINT32 channel_id;
84 
85 	HANDLE devman_loading;
86 	libusb_context* context;
87 	HANDLE thread;
88 	BOOL running;
89 };
90 typedef UDEVMAN* PUDEVMAN;
91 
92 static BOOL poll_libusb_events(UDEVMAN* udevman);
93 
udevman_rewind(IUDEVMAN * idevman)94 static void udevman_rewind(IUDEVMAN* idevman)
95 {
96 	UDEVMAN* udevman = (UDEVMAN*)idevman;
97 	udevman->idev = udevman->head;
98 }
99 
udevman_has_next(IUDEVMAN * idevman)100 static BOOL udevman_has_next(IUDEVMAN* idevman)
101 {
102 	UDEVMAN* udevman = (UDEVMAN*)idevman;
103 
104 	if (!udevman || !udevman->idev)
105 		return FALSE;
106 	else
107 		return TRUE;
108 }
109 
udevman_get_next(IUDEVMAN * idevman)110 static IUDEVICE* udevman_get_next(IUDEVMAN* idevman)
111 {
112 	UDEVMAN* udevman = (UDEVMAN*)idevman;
113 	IUDEVICE* pdev;
114 	pdev = udevman->idev;
115 	udevman->idev = (IUDEVICE*)((UDEVICE*)udevman->idev)->next;
116 	return pdev;
117 }
118 
udevman_get_udevice_by_addr(IUDEVMAN * idevman,BYTE bus_number,BYTE dev_number)119 static IUDEVICE* udevman_get_udevice_by_addr(IUDEVMAN* idevman, BYTE bus_number, BYTE dev_number)
120 {
121 	IUDEVICE* dev = NULL;
122 
123 	if (!idevman)
124 		return NULL;
125 
126 	idevman->loading_lock(idevman);
127 	idevman->rewind(idevman);
128 
129 	while (idevman->has_next(idevman))
130 	{
131 		IUDEVICE* pdev = idevman->get_next(idevman);
132 
133 		if ((pdev->get_bus_number(pdev) == bus_number) &&
134 		    (pdev->get_dev_number(pdev) == dev_number))
135 		{
136 			dev = pdev;
137 			break;
138 		}
139 	}
140 
141 	idevman->loading_unlock(idevman);
142 	return dev;
143 }
144 
udevman_register_udevice(IUDEVMAN * idevman,BYTE bus_number,BYTE dev_number,UINT16 idVendor,UINT16 idProduct,UINT32 flag)145 static size_t udevman_register_udevice(IUDEVMAN* idevman, BYTE bus_number, BYTE dev_number,
146                                        UINT16 idVendor, UINT16 idProduct, UINT32 flag)
147 {
148 	UDEVMAN* udevman = (UDEVMAN*)idevman;
149 	IUDEVICE* pdev = NULL;
150 	IUDEVICE** devArray;
151 	URBDRC_PLUGIN* urbdrc;
152 	size_t i, num, addnum = 0;
153 
154 	if (!idevman || !idevman->plugin)
155 		return 0;
156 
157 	urbdrc = (URBDRC_PLUGIN*)idevman->plugin;
158 	pdev = (IUDEVICE*)udevman_get_udevice_by_addr(idevman, bus_number, dev_number);
159 
160 	if (pdev != NULL)
161 		return 0;
162 
163 	if (flag & UDEVMAN_FLAG_ADD_BY_ADDR)
164 	{
165 		UINT32 id;
166 		IUDEVICE* tdev = udev_new_by_addr(urbdrc, udevman->context, bus_number, dev_number);
167 
168 		if (tdev == NULL)
169 			return 0;
170 
171 		id = idevman->get_next_device_id(idevman);
172 		tdev->set_UsbDevice(tdev, id);
173 		idevman->loading_lock(idevman);
174 
175 		if (udevman->head == NULL)
176 		{
177 			/* linked list is empty */
178 			udevman->head = tdev;
179 			udevman->tail = tdev;
180 		}
181 		else
182 		{
183 			/* append device to the end of the linked list */
184 			udevman->tail->set_p_next(udevman->tail, tdev);
185 			tdev->set_p_prev(tdev, udevman->tail);
186 			udevman->tail = tdev;
187 		}
188 
189 		udevman->device_num += 1;
190 		idevman->loading_unlock(idevman);
191 	}
192 	else if (flag & UDEVMAN_FLAG_ADD_BY_VID_PID)
193 	{
194 		addnum = 0;
195 		/* register all device that match pid vid */
196 		num = udev_new_by_id(urbdrc, udevman->context, idVendor, idProduct, &devArray);
197 
198 		for (i = 0; i < num; i++)
199 		{
200 			UINT32 id;
201 			IUDEVICE* tdev = devArray[i];
202 
203 			if (udevman_get_udevice_by_addr(idevman, tdev->get_bus_number(tdev),
204 			                                tdev->get_dev_number(tdev)) != NULL)
205 			{
206 				tdev->free(tdev);
207 				devArray[i] = NULL;
208 				continue;
209 			}
210 
211 			id = idevman->get_next_device_id(idevman);
212 			tdev->set_UsbDevice(tdev, id);
213 			idevman->loading_lock(idevman);
214 
215 			if (udevman->head == NULL)
216 			{
217 				/* linked list is empty */
218 				udevman->head = tdev;
219 				udevman->tail = tdev;
220 			}
221 			else
222 			{
223 				/* append device to the end of the linked list */
224 				udevman->tail->set_p_next(udevman->tail, tdev);
225 				tdev->set_p_prev(tdev, udevman->tail);
226 				udevman->tail = tdev;
227 			}
228 
229 			udevman->device_num += 1;
230 			idevman->loading_unlock(idevman);
231 			addnum++;
232 		}
233 
234 		free(devArray);
235 		return addnum;
236 	}
237 	else
238 	{
239 		WLog_Print(urbdrc->log, WLOG_ERROR, "udevman_register_udevice: Invalid flag=%08 " PRIx32,
240 		           flag);
241 		return 0;
242 	}
243 
244 	return 1;
245 }
246 
udevman_unregister_udevice(IUDEVMAN * idevman,BYTE bus_number,BYTE dev_number)247 static BOOL udevman_unregister_udevice(IUDEVMAN* idevman, BYTE bus_number, BYTE dev_number)
248 {
249 	UDEVMAN* udevman = (UDEVMAN*)idevman;
250 	UDEVICE* pdev;
251 	UDEVICE* dev = (UDEVICE*)udevman_get_udevice_by_addr(idevman, bus_number, dev_number);
252 
253 	if (!dev || !idevman)
254 		return FALSE;
255 
256 	idevman->loading_lock(idevman);
257 	idevman->rewind(idevman);
258 
259 	while (idevman->has_next(idevman))
260 	{
261 		pdev = (UDEVICE*)idevman->get_next(idevman);
262 
263 		if (pdev == dev) /* device exists */
264 		{
265 			/* set previous device to point to next device */
266 			if (dev->prev != NULL)
267 			{
268 				/* unregistered device is not the head */
269 				pdev = dev->prev;
270 				pdev->next = dev->next;
271 			}
272 			else
273 			{
274 				/* unregistered device is the head, update head */
275 				udevman->head = (IUDEVICE*)dev->next;
276 			}
277 
278 			/* set next device to point to previous device */
279 
280 			if (dev->next != NULL)
281 			{
282 				/* unregistered device is not the tail */
283 				pdev = (UDEVICE*)dev->next;
284 				pdev->prev = dev->prev;
285 			}
286 			else
287 			{
288 				/* unregistered device is the tail, update tail */
289 				udevman->tail = (IUDEVICE*)dev->prev;
290 			}
291 
292 			udevman->device_num--;
293 			break;
294 		}
295 	}
296 
297 	idevman->loading_unlock(idevman);
298 
299 	if (dev)
300 	{
301 		dev->iface.free(&dev->iface);
302 		return TRUE; /* unregistration successful */
303 	}
304 
305 	/* if we reach this point, the device wasn't found */
306 	return FALSE;
307 }
308 
udevman_unregister_all_udevices(IUDEVMAN * idevman)309 static BOOL udevman_unregister_all_udevices(IUDEVMAN* idevman)
310 {
311 	UDEVMAN* udevman = (UDEVMAN*)idevman;
312 
313 	if (!idevman)
314 		return FALSE;
315 
316 	if (!udevman->head)
317 		return TRUE;
318 
319 	idevman->loading_lock(idevman);
320 	idevman->rewind(idevman);
321 
322 	while (idevman->has_next(idevman))
323 	{
324 		UDEVICE* dev = (UDEVICE*)idevman->get_next(idevman);
325 
326 		if (!dev)
327 			continue;
328 
329 		/* set previous device to point to next device */
330 		if (dev->prev != NULL)
331 		{
332 			/* unregistered device is not the head */
333 			UDEVICE* pdev = dev->prev;
334 			pdev->next = dev->next;
335 		}
336 		else
337 		{
338 			/* unregistered device is the head, update head */
339 			udevman->head = (IUDEVICE*)dev->next;
340 		}
341 
342 		/* set next device to point to previous device */
343 
344 		if (dev->next != NULL)
345 		{
346 			/* unregistered device is not the tail */
347 			UDEVICE* pdev = (UDEVICE*)dev->next;
348 			pdev->prev = dev->prev;
349 		}
350 		else
351 		{
352 			/* unregistered device is the tail, update tail */
353 			udevman->tail = (IUDEVICE*)dev->prev;
354 		}
355 
356 		dev->iface.free(&dev->iface);
357 		udevman->device_num--;
358 	}
359 
360 	idevman->loading_unlock(idevman);
361 
362 	return TRUE;
363 }
364 
udevman_is_auto_add(IUDEVMAN * idevman)365 static int udevman_is_auto_add(IUDEVMAN* idevman)
366 {
367 	UDEVMAN* udevman = (UDEVMAN*)idevman;
368 	return (udevman->flags & UDEVMAN_FLAG_ADD_BY_AUTO) ? 1 : 0;
369 }
370 
udevman_get_udevice_by_UsbDevice(IUDEVMAN * idevman,UINT32 UsbDevice)371 static IUDEVICE* udevman_get_udevice_by_UsbDevice(IUDEVMAN* idevman, UINT32 UsbDevice)
372 {
373 	UDEVICE* pdev;
374 	URBDRC_PLUGIN* urbdrc;
375 
376 	if (!idevman || !idevman->plugin)
377 		return NULL;
378 
379 	/* Mask highest 2 bits, must be ignored */
380 	UsbDevice = UsbDevice & INTERFACE_ID_MASK;
381 	urbdrc = (URBDRC_PLUGIN*)idevman->plugin;
382 	idevman->loading_lock(idevman);
383 	idevman->rewind(idevman);
384 
385 	while (idevman->has_next(idevman))
386 	{
387 		pdev = (UDEVICE*)idevman->get_next(idevman);
388 
389 		if (pdev->UsbDevice == UsbDevice)
390 		{
391 			idevman->loading_unlock(idevman);
392 			return (IUDEVICE*)pdev;
393 		}
394 	}
395 
396 	idevman->loading_unlock(idevman);
397 	WLog_Print(urbdrc->log, WLOG_WARN, "Failed to find a USB device mapped to deviceId=%08" PRIx32,
398 	           UsbDevice);
399 	return NULL;
400 }
401 
udevman_get_udevice_by_ChannelID(IUDEVMAN * idevman,UINT32 channelID)402 static IUDEVICE* udevman_get_udevice_by_ChannelID(IUDEVMAN* idevman, UINT32 channelID)
403 {
404 	UDEVICE* pdev;
405 	URBDRC_PLUGIN* urbdrc;
406 
407 	if (!idevman || !idevman->plugin)
408 		return NULL;
409 
410 	/* Mask highest 2 bits, must be ignored */
411 	urbdrc = (URBDRC_PLUGIN*)idevman->plugin;
412 	idevman->loading_lock(idevman);
413 	idevman->rewind(idevman);
414 
415 	while (idevman->has_next(idevman))
416 	{
417 		pdev = (UDEVICE*)idevman->get_next(idevman);
418 
419 		if (pdev->channelID == channelID)
420 		{
421 			idevman->loading_unlock(idevman);
422 			return (IUDEVICE*)pdev;
423 		}
424 	}
425 
426 	idevman->loading_unlock(idevman);
427 	WLog_Print(urbdrc->log, WLOG_WARN, "Failed to find a USB device mapped to channelID=%08" PRIx32,
428 	           channelID);
429 	return NULL;
430 }
431 
udevman_loading_lock(IUDEVMAN * idevman)432 static void udevman_loading_lock(IUDEVMAN* idevman)
433 {
434 	UDEVMAN* udevman = (UDEVMAN*)idevman;
435 	WaitForSingleObject(udevman->devman_loading, INFINITE);
436 }
437 
udevman_loading_unlock(IUDEVMAN * idevman)438 static void udevman_loading_unlock(IUDEVMAN* idevman)
439 {
440 	UDEVMAN* udevman = (UDEVMAN*)idevman;
441 	ReleaseMutex(udevman->devman_loading);
442 }
443 
BASIC_STATE_FUNC_DEFINED(device_num,UINT32)444 BASIC_STATE_FUNC_DEFINED(device_num, UINT32)
445 
446 static UINT32 udevman_get_next_device_id(IUDEVMAN* idevman)
447 {
448 	UDEVMAN* udevman = (UDEVMAN*)idevman;
449 	return udevman->next_device_id++;
450 }
451 
udevman_set_next_device_id(IUDEVMAN * idevman,UINT32 _t)452 static void udevman_set_next_device_id(IUDEVMAN* idevman, UINT32 _t)
453 {
454 	UDEVMAN* udevman = (UDEVMAN*)idevman;
455 	udevman->next_device_id = _t;
456 }
457 
udevman_free(IUDEVMAN * idevman)458 static void udevman_free(IUDEVMAN* idevman)
459 {
460 	UDEVMAN* udevman = (UDEVMAN*)idevman;
461 
462 	if (!udevman)
463 		return;
464 
465 	udevman->running = FALSE;
466 	if (udevman->thread)
467 	{
468 		WaitForSingleObject(udevman->thread, INFINITE);
469 		CloseHandle(udevman->thread);
470 	}
471 
472 	udevman_unregister_all_udevices(idevman);
473 
474 	if (udevman->devman_loading)
475 		CloseHandle(udevman->devman_loading);
476 
477 	libusb_exit(udevman->context);
478 
479 	ArrayList_Free(udevman->hotplug_vid_pids);
480 	free(udevman);
481 }
482 
filter_by_class(uint8_t bDeviceClass,uint8_t bDeviceSubClass)483 static BOOL filter_by_class(uint8_t bDeviceClass, uint8_t bDeviceSubClass)
484 {
485 	switch (bDeviceClass)
486 	{
487 		case LIBUSB_CLASS_AUDIO:
488 		case LIBUSB_CLASS_HID:
489 		case LIBUSB_CLASS_MASS_STORAGE:
490 		case LIBUSB_CLASS_HUB:
491 		case LIBUSB_CLASS_SMART_CARD:
492 			return TRUE;
493 		default:
494 			break;
495 	}
496 
497 	switch (bDeviceSubClass)
498 	{
499 		default:
500 			break;
501 	}
502 
503 	return FALSE;
504 }
505 
append(char * dst,size_t length,const char * src)506 static BOOL append(char* dst, size_t length, const char* src)
507 {
508 	size_t slen = strlen(src);
509 	size_t dlen = strnlen(dst, length);
510 	if (dlen + slen >= length)
511 		return FALSE;
512 	strcat(dst, src);
513 	return TRUE;
514 }
515 
device_is_filtered(struct libusb_device * dev,const struct libusb_device_descriptor * desc,libusb_hotplug_event event)516 static BOOL device_is_filtered(struct libusb_device* dev,
517                                const struct libusb_device_descriptor* desc,
518                                libusb_hotplug_event event)
519 {
520 	char buffer[8192] = { 0 };
521 	char* what;
522 	BOOL filtered = FALSE;
523 	append(buffer, sizeof(buffer), usb_interface_class_to_string(desc->bDeviceClass));
524 	if (filter_by_class(desc->bDeviceClass, desc->bDeviceSubClass))
525 		filtered = TRUE;
526 
527 	switch (desc->bDeviceClass)
528 	{
529 		case LIBUSB_CLASS_PER_INTERFACE:
530 		{
531 			struct libusb_config_descriptor* config = NULL;
532 			int rc = libusb_get_active_config_descriptor(dev, &config);
533 			if (rc == LIBUSB_SUCCESS)
534 			{
535 				uint8_t x;
536 
537 				for (x = 0; x < config->bNumInterfaces; x++)
538 				{
539 					int y;
540 					const struct libusb_interface* ifc = &config->interface[x];
541 					for (y = 0; y < ifc->num_altsetting; y++)
542 					{
543 						const struct libusb_interface_descriptor* const alt = &ifc->altsetting[y];
544 						if (filter_by_class(alt->bInterfaceClass, alt->bInterfaceSubClass))
545 							filtered = TRUE;
546 
547 						append(buffer, sizeof(buffer), "|");
548 						append(buffer, sizeof(buffer),
549 						       usb_interface_class_to_string(alt->bInterfaceClass));
550 					}
551 				}
552 			}
553 			libusb_free_config_descriptor(config);
554 		}
555 		break;
556 		default:
557 			break;
558 	}
559 
560 	if (filtered)
561 		what = "Filtered";
562 	else
563 	{
564 		switch (event)
565 		{
566 			case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT:
567 				what = "Hotplug remove";
568 				break;
569 			case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED:
570 				what = "Hotplug add";
571 				break;
572 			default:
573 				what = "Hotplug unknown";
574 				break;
575 		}
576 	}
577 
578 	WLog_DBG(TAG, "%s device VID=0x%04X,PID=0x%04X class %s", what, desc->idVendor, desc->idProduct,
579 	         buffer);
580 	return filtered;
581 }
582 
hotplug_callback(struct libusb_context * ctx,struct libusb_device * dev,libusb_hotplug_event event,void * user_data)583 static int hotplug_callback(struct libusb_context* ctx, struct libusb_device* dev,
584                             libusb_hotplug_event event, void* user_data)
585 {
586 	VID_PID_PAIR pair;
587 	struct libusb_device_descriptor desc;
588 	UDEVMAN* udevman = (UDEVMAN*)user_data;
589 	const uint8_t bus = libusb_get_bus_number(dev);
590 	const uint8_t addr = libusb_get_device_address(dev);
591 	int rc = libusb_get_device_descriptor(dev, &desc);
592 
593 	WINPR_UNUSED(ctx);
594 
595 	if (rc != LIBUSB_SUCCESS)
596 		return rc;
597 
598 	switch (event)
599 	{
600 		case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED:
601 			pair.vid = desc.idVendor;
602 			pair.pid = desc.idProduct;
603 			if ((ArrayList_Contains(udevman->hotplug_vid_pids, &pair)) ||
604 			    (udevman->iface.isAutoAdd(&udevman->iface) &&
605 			     !device_is_filtered(dev, &desc, event)))
606 			{
607 				add_device(&udevman->iface, DEVICE_ADD_FLAG_ALL, bus, addr, desc.idVendor,
608 				           desc.idProduct);
609 			}
610 			break;
611 
612 		case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT:
613 			del_device(&udevman->iface, DEVICE_ADD_FLAG_ALL, bus, addr, desc.idVendor,
614 			           desc.idProduct);
615 			break;
616 
617 		default:
618 			break;
619 	}
620 
621 	return 0;
622 }
623 
udevman_initialize(IUDEVMAN * idevman,UINT32 channelId)624 static BOOL udevman_initialize(IUDEVMAN* idevman, UINT32 channelId)
625 {
626 	UDEVMAN* udevman = (UDEVMAN*)idevman;
627 
628 	if (!udevman)
629 		return FALSE;
630 
631 	idevman->status &= ~URBDRC_DEVICE_CHANNEL_CLOSED;
632 	idevman->controlChannelId = channelId;
633 	return TRUE;
634 }
635 
udevman_vid_pid_pair_equals(const void * objA,const void * objB)636 static BOOL udevman_vid_pid_pair_equals(const void* objA, const void* objB)
637 {
638 	const VID_PID_PAIR* a = objA;
639 	const VID_PID_PAIR* b = objB;
640 
641 	return (a->vid == b->vid) && (a->pid == b->pid);
642 }
643 
udevman_parse_device_id_addr(const char ** str,UINT16 * id1,UINT16 * id2,UINT16 max,char split_sign,char delimiter)644 static BOOL udevman_parse_device_id_addr(const char** str, UINT16* id1, UINT16* id2, UINT16 max,
645                                          char split_sign, char delimiter)
646 {
647 	char* mid;
648 	char* end;
649 	unsigned long rc;
650 
651 	rc = strtoul(*str, &mid, 16);
652 
653 	if ((mid == *str) || (*mid != split_sign) || (rc > max))
654 		return FALSE;
655 
656 	*id1 = (UINT16)rc;
657 	rc = strtoul(++mid, &end, 16);
658 
659 	if ((end == mid) || (rc > max))
660 		return FALSE;
661 
662 	*id2 = (UINT16)rc;
663 
664 	*str += end - *str;
665 	if (*end == '\0')
666 		return TRUE;
667 	if (*end == delimiter)
668 	{
669 		(*str)++;
670 		return TRUE;
671 	}
672 
673 	return FALSE;
674 }
675 
urbdrc_udevman_register_devices(UDEVMAN * udevman,const char * devices,BOOL add_by_addr)676 static BOOL urbdrc_udevman_register_devices(UDEVMAN* udevman, const char* devices, BOOL add_by_addr)
677 {
678 	const char* pos = devices;
679 	VID_PID_PAIR* idpair;
680 	UINT16 id1, id2;
681 
682 	while (*pos != '\0')
683 	{
684 		if (!udevman_parse_device_id_addr(&pos, &id1, &id2, (add_by_addr) ? UINT8_MAX : UINT16_MAX,
685 		                                  ':', '#'))
686 		{
687 			WLog_ERR(TAG, "Invalid device argument: \"%s\"", devices);
688 			return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
689 		}
690 
691 		if (add_by_addr)
692 		{
693 			add_device(&udevman->iface, DEVICE_ADD_FLAG_BUS | DEVICE_ADD_FLAG_DEV, (UINT8)id1,
694 			           (UINT8)id2, 0, 0);
695 		}
696 		else
697 		{
698 			idpair = calloc(1, sizeof(VID_PID_PAIR));
699 			if (!idpair)
700 				return CHANNEL_RC_NO_MEMORY;
701 			idpair->vid = id1;
702 			idpair->pid = id2;
703 			if (ArrayList_Add(udevman->hotplug_vid_pids, idpair) == -1)
704 			{
705 				free(idpair);
706 				return CHANNEL_RC_NO_MEMORY;
707 			}
708 
709 			add_device(&udevman->iface, DEVICE_ADD_FLAG_VENDOR | DEVICE_ADD_FLAG_PRODUCT, 0, 0, id1,
710 			           id2);
711 		}
712 	}
713 
714 	return CHANNEL_RC_OK;
715 }
716 
urbdrc_udevman_parse_addin_args(UDEVMAN * udevman,ADDIN_ARGV * args)717 static UINT urbdrc_udevman_parse_addin_args(UDEVMAN* udevman, ADDIN_ARGV* args)
718 {
719 	int status;
720 	LPSTR devices = NULL;
721 	COMMAND_LINE_ARGUMENT_A* arg;
722 	COMMAND_LINE_ARGUMENT_A urbdrc_udevman_args[] = {
723 		{ "dbg", COMMAND_LINE_VALUE_FLAG, "", NULL, BoolValueFalse, -1, NULL, "debug" },
724 		{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<devices>", NULL, NULL, -1, NULL, "device list" },
725 		{ "id", COMMAND_LINE_VALUE_OPTIONAL, "", NULL, BoolValueFalse, -1, NULL,
726 		  "FLAG_ADD_BY_VID_PID" },
727 		{ "addr", COMMAND_LINE_VALUE_OPTIONAL, "", NULL, BoolValueFalse, -1, NULL,
728 		  "FLAG_ADD_BY_ADDR" },
729 		{ "auto", COMMAND_LINE_VALUE_FLAG, "", NULL, BoolValueFalse, -1, NULL, "FLAG_ADD_BY_AUTO" },
730 		{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
731 	};
732 
733 	status = CommandLineParseArgumentsA(args->argc, args->argv, urbdrc_udevman_args,
734 	                                    COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON,
735 	                                    udevman, NULL, NULL);
736 
737 	if (status != CHANNEL_RC_OK)
738 		return status;
739 
740 	arg = urbdrc_udevman_args;
741 
742 	do
743 	{
744 		if (!(arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT))
745 			continue;
746 
747 		CommandLineSwitchStart(arg) CommandLineSwitchCase(arg, "dbg")
748 		{
749 			WLog_SetLogLevel(WLog_Get(TAG), WLOG_TRACE);
750 		}
751 		CommandLineSwitchCase(arg, "dev")
752 		{
753 			devices = arg->Value;
754 		}
755 		CommandLineSwitchCase(arg, "id")
756 		{
757 			if (arg->Value)
758 				udevman->devices_vid_pid = arg->Value;
759 			else
760 				udevman->flags = UDEVMAN_FLAG_ADD_BY_VID_PID;
761 		}
762 		CommandLineSwitchCase(arg, "addr")
763 		{
764 			if (arg->Value)
765 				udevman->devices_addr = arg->Value;
766 			else
767 				udevman->flags = UDEVMAN_FLAG_ADD_BY_ADDR;
768 		}
769 		CommandLineSwitchCase(arg, "auto")
770 		{
771 			udevman->flags |= UDEVMAN_FLAG_ADD_BY_AUTO;
772 		}
773 		CommandLineSwitchDefault(arg)
774 		{
775 		}
776 		CommandLineSwitchEnd(arg)
777 	} while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
778 
779 	if (devices)
780 	{
781 		if (udevman->flags & UDEVMAN_FLAG_ADD_BY_VID_PID)
782 			udevman->devices_vid_pid = devices;
783 		else if (udevman->flags & UDEVMAN_FLAG_ADD_BY_ADDR)
784 			udevman->devices_addr = devices;
785 	}
786 
787 	return CHANNEL_RC_OK;
788 }
789 
udevman_listener_created_callback(IUDEVMAN * iudevman)790 static UINT udevman_listener_created_callback(IUDEVMAN* iudevman)
791 {
792 	UINT status;
793 	UDEVMAN* udevman = (UDEVMAN*)iudevman;
794 
795 	if (udevman->devices_vid_pid)
796 	{
797 		status = urbdrc_udevman_register_devices(udevman, udevman->devices_vid_pid, FALSE);
798 		if (status != CHANNEL_RC_OK)
799 			return status;
800 	}
801 
802 	if (udevman->devices_addr)
803 		return urbdrc_udevman_register_devices(udevman, udevman->devices_addr, TRUE);
804 
805 	return CHANNEL_RC_OK;
806 }
807 
udevman_load_interface(UDEVMAN * udevman)808 static void udevman_load_interface(UDEVMAN* udevman)
809 {
810 	/* standard */
811 	udevman->iface.free = udevman_free;
812 	/* manage devices */
813 	udevman->iface.rewind = udevman_rewind;
814 	udevman->iface.get_next = udevman_get_next;
815 	udevman->iface.has_next = udevman_has_next;
816 	udevman->iface.register_udevice = udevman_register_udevice;
817 	udevman->iface.unregister_udevice = udevman_unregister_udevice;
818 	udevman->iface.get_udevice_by_UsbDevice = udevman_get_udevice_by_UsbDevice;
819 	udevman->iface.get_udevice_by_ChannelID = udevman_get_udevice_by_ChannelID;
820 	/* Extension */
821 	udevman->iface.isAutoAdd = udevman_is_auto_add;
822 	/* Basic state */
823 	BASIC_STATE_FUNC_REGISTER(device_num, udevman);
824 	BASIC_STATE_FUNC_REGISTER(next_device_id, udevman);
825 
826 	/* control semaphore or mutex lock */
827 	udevman->iface.loading_lock = udevman_loading_lock;
828 	udevman->iface.loading_unlock = udevman_loading_unlock;
829 	udevman->iface.initialize = udevman_initialize;
830 	udevman->iface.listener_created_callback = udevman_listener_created_callback;
831 }
832 
poll_libusb_events(UDEVMAN * udevman)833 static BOOL poll_libusb_events(UDEVMAN* udevman)
834 {
835 	int rc = LIBUSB_SUCCESS;
836 	struct timeval tv = { 0, 500 };
837 	if (libusb_try_lock_events(udevman->context))
838 	{
839 		if (libusb_event_handling_ok(udevman->context))
840 		{
841 			rc = libusb_handle_events_locked(udevman->context, &tv);
842 			if (rc != LIBUSB_SUCCESS)
843 				WLog_WARN(TAG, "libusb_handle_events_locked %d", rc);
844 		}
845 		libusb_unlock_events(udevman->context);
846 	}
847 	else
848 	{
849 		libusb_lock_event_waiters(udevman->context);
850 		if (libusb_event_handler_active(udevman->context))
851 		{
852 			rc = libusb_wait_for_event(udevman->context, &tv);
853 			if (rc < LIBUSB_SUCCESS)
854 				WLog_WARN(TAG, "libusb_wait_for_event %d", rc);
855 		}
856 		libusb_unlock_event_waiters(udevman->context);
857 	}
858 
859 	return rc > 0;
860 }
861 
poll_thread(LPVOID lpThreadParameter)862 static DWORD poll_thread(LPVOID lpThreadParameter)
863 {
864 	libusb_hotplug_callback_handle handle;
865 	UDEVMAN* udevman = (UDEVMAN*)lpThreadParameter;
866 	BOOL hasHotplug = TRUE;
867 
868 	if (hasHotplug)
869 	{
870 		int rc = libusb_hotplug_register_callback(
871 		    udevman->context,
872 		    LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
873 		    LIBUSB_HOTPLUG_NO_FLAGS, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY,
874 		    LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, udevman, &handle);
875 
876 		if (rc != LIBUSB_SUCCESS)
877 			udevman->running = FALSE;
878 	}
879 	else
880 		WLog_WARN(TAG, "Platform does not support libusb hotplug. USB devices plugged in later "
881 		               "will not be detected.");
882 
883 	while (udevman->running)
884 	{
885 		poll_libusb_events(udevman);
886 	}
887 
888 	if (hasHotplug)
889 		libusb_hotplug_deregister_callback(udevman->context, handle);
890 
891 	/* Process remaining usb events */
892 	while (poll_libusb_events(udevman))
893 		;
894 
895 	ExitThread(0);
896 	return 0;
897 }
898 
899 #ifdef BUILTIN_CHANNELS
900 #define freerdp_urbdrc_client_subsystem_entry libusb_freerdp_urbdrc_client_subsystem_entry
901 #else
902 #define freerdp_urbdrc_client_subsystem_entry FREERDP_API freerdp_urbdrc_client_subsystem_entry
903 #endif
freerdp_urbdrc_client_subsystem_entry(PFREERDP_URBDRC_SERVICE_ENTRY_POINTS pEntryPoints)904 UINT freerdp_urbdrc_client_subsystem_entry(PFREERDP_URBDRC_SERVICE_ENTRY_POINTS pEntryPoints)
905 {
906 	UINT rc;
907 	UINT status;
908 	UDEVMAN* udevman;
909 	ADDIN_ARGV* args = pEntryPoints->args;
910 	udevman = (PUDEVMAN)calloc(1, sizeof(UDEVMAN));
911 
912 	if (!udevman)
913 		goto fail;
914 
915 	udevman->hotplug_vid_pids = ArrayList_New(TRUE);
916 	if (!udevman->hotplug_vid_pids)
917 		goto fail;
918 	ArrayList_Object(udevman->hotplug_vid_pids)->fnObjectFree = free;
919 	ArrayList_Object(udevman->hotplug_vid_pids)->fnObjectEquals = udevman_vid_pid_pair_equals;
920 
921 	udevman->next_device_id = BASE_USBDEVICE_NUM;
922 	udevman->iface.plugin = pEntryPoints->plugin;
923 	rc = libusb_init(&udevman->context);
924 
925 	if (rc != LIBUSB_SUCCESS)
926 		goto fail;
927 
928 #ifdef _WIN32
929 #if LIBUSB_API_VERSION >= 0x01000106
930 	/* Prefer usbDK backend on windows. Not supported on other platforms. */
931 	rc = libusb_set_option(udevman->context, LIBUSB_OPTION_USE_USBDK);
932 	switch (rc)
933 	{
934 		case LIBUSB_SUCCESS:
935 			break;
936 		case LIBUSB_ERROR_NOT_FOUND:
937 		case LIBUSB_ERROR_NOT_SUPPORTED:
938 			WLog_WARN(TAG, "LIBUSB_OPTION_USE_USBDK %s [%d]", libusb_strerror(rc), rc);
939 			break;
940 		default:
941 			WLog_ERR(TAG, "LIBUSB_OPTION_USE_USBDK %s [%d]", libusb_strerror(rc), rc);
942 			goto fail;
943 	}
944 #endif
945 #endif
946 
947 	udevman->flags = UDEVMAN_FLAG_ADD_BY_VID_PID;
948 	udevman->devman_loading = CreateMutexA(NULL, FALSE, "devman_loading");
949 
950 	if (!udevman->devman_loading)
951 		goto fail;
952 
953 	/* load usb device service management */
954 	udevman_load_interface(udevman);
955 	status = urbdrc_udevman_parse_addin_args(udevman, args);
956 
957 	if (status != CHANNEL_RC_OK)
958 		goto fail;
959 
960 	udevman->running = TRUE;
961 	udevman->thread = CreateThread(NULL, 0, poll_thread, udevman, 0, NULL);
962 
963 	if (!udevman->thread)
964 		goto fail;
965 
966 	if (!pEntryPoints->pRegisterUDEVMAN(pEntryPoints->plugin, (IUDEVMAN*)udevman))
967 		goto fail;
968 
969 	WLog_DBG(TAG, "UDEVMAN device registered.");
970 	return 0;
971 fail:
972 	udevman_free(&udevman->iface);
973 	return ERROR_INTERNAL_ERROR;
974 }
975