FreeRDP
Loading...
Searching...
No Matches
libusb_udevice.c
1
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25#include <winpr/assert.h>
26#include <winpr/cast.h>
27#include <winpr/wtypes.h>
28#include <winpr/sysinfo.h>
29#include <winpr/collections.h>
30
31#include <errno.h>
32
33#include "libusb_udevice.h"
34#include "msusb.h"
35#include "../common/urbdrc_types.h"
36
37#define BASIC_STATE_FUNC_DEFINED(_arg, _type) \
38 WINPR_ATTR_NODISCARD \
39 static _type udev_get_##_arg(IUDEVICE* idev) \
40 { \
41 UDEVICE* pdev = (UDEVICE*)idev; \
42 return pdev->_arg; \
43 } \
44 static void udev_set_##_arg(IUDEVICE* idev, _type _t) \
45 { \
46 UDEVICE* pdev = (UDEVICE*)idev; \
47 pdev->_arg = _t; \
48 }
49
50#define BASIC_POINT_FUNC_DEFINED(_arg, _type) \
51 WINPR_ATTR_NODISCARD \
52 static _type udev_get_p_##_arg(IUDEVICE* idev) \
53 { \
54 UDEVICE* pdev = (UDEVICE*)idev; \
55 return pdev->_arg; \
56 } \
57 static void udev_set_p_##_arg(IUDEVICE* idev, _type _t) \
58 { \
59 UDEVICE* pdev = (UDEVICE*)idev; \
60 pdev->_arg = _t; \
61 }
62
63#define BASIC_STATE_FUNC_REGISTER(_arg, _dev) \
64 _dev->iface.get_##_arg = udev_get_##_arg; \
65 (_dev)->iface.set_##_arg = udev_set_##_arg
66
67#if LIBUSB_API_VERSION >= 0x01000103
68#define HAVE_STREAM_ID_API 1
69#endif
70
71typedef struct
72{
73 wStream* data;
74 BOOL noack;
75 UINT32 MessageId;
76 UINT32 StartFrame;
77 UINT32 ErrorCount;
78 IUDEVICE* idev;
79 UINT32 OutputBufferSize;
80 /* Completion framing depends on the outer RDPEUSB request direction. */
81 int transferDir;
83 t_isoch_transfer_cb cb;
84 wArrayList* queue;
85#if !defined(HAVE_STREAM_ID_API)
86 UINT32 streamID;
87#endif
88} ASYNC_TRANSFER_USER_DATA;
89
90static void request_free(void* value);
91
92WINPR_ATTR_NODISCARD
93static struct libusb_transfer* list_contains(wArrayList* list, UINT32 streamID)
94{
95 size_t count = 0;
96 if (!list)
97 return nullptr;
98 count = ArrayList_Count(list);
99 for (size_t x = 0; x < count; x++)
100 {
101 struct libusb_transfer* transfer = ArrayList_GetItem(list, x);
102
103#if defined(HAVE_STREAM_ID_API)
104 const UINT32 currentID = libusb_transfer_get_stream_id(transfer);
105#else
106 const ASYNC_TRANSFER_USER_DATA* user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
107 const UINT32 currentID = user_data->streamID;
108#endif
109 if (currentID == streamID)
110 return transfer;
111 }
112 return nullptr;
113}
114
115WINPR_ATTR_NODISCARD
116static UINT32 stream_id_from_buffer(struct libusb_transfer* transfer)
117{
118 if (!transfer)
119 return 0;
120#if defined(HAVE_STREAM_ID_API)
121 return libusb_transfer_get_stream_id(transfer);
122#else
123 ASYNC_TRANSFER_USER_DATA* user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
124 if (!user_data)
125 return 0;
126 return user_data->streamID;
127#endif
128}
129
130static void set_stream_id_for_buffer(struct libusb_transfer* transfer, UINT32 streamID)
131{
132#if defined(HAVE_STREAM_ID_API)
133 libusb_transfer_set_stream_id(transfer, streamID);
134#else
135 ASYNC_TRANSFER_USER_DATA* user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
136 if (!user_data)
137 return;
138 user_data->streamID = streamID;
139#endif
140}
141
142WINPR_ATTR_FORMAT_ARG(3, 8)
143static BOOL log_libusb_result_(wLog* log, DWORD lvl, WINPR_FORMAT_ARG const char* fmt,
144 const char* fkt, const char* file, size_t line, int error, ...)
145{
146 WINPR_UNUSED(file);
147
148 if (error < 0)
149 {
150 char buffer[8192] = WINPR_C_ARRAY_INIT;
151 va_list ap = WINPR_C_ARRAY_INIT;
152 va_start(ap, error);
153 (void)vsnprintf(buffer, sizeof(buffer), fmt, ap);
154 va_end(ap);
155
156 WLog_Print(log, lvl, "[%s:%" PRIuz "]: %s: error %s[%d]", fkt, line, buffer,
157 libusb_error_name(error), error);
158 return TRUE;
159 }
160 return FALSE;
161}
162
163#define log_libusb_result(log, lvl, fmt, error, ...) \
164 log_libusb_result_((log), (lvl), (fmt), __func__, __FILE__, __LINE__, error, ##__VA_ARGS__)
165
166WINPR_ATTR_NODISCARD
167const char* usb_interface_class_to_string(uint8_t c_class)
168{
169 switch (c_class)
170 {
171 case LIBUSB_CLASS_PER_INTERFACE:
172 return "LIBUSB_CLASS_PER_INTERFACE";
173 case LIBUSB_CLASS_AUDIO:
174 return "LIBUSB_CLASS_AUDIO";
175 case LIBUSB_CLASS_COMM:
176 return "LIBUSB_CLASS_COMM";
177 case LIBUSB_CLASS_HID:
178 return "LIBUSB_CLASS_HID";
179 case LIBUSB_CLASS_PHYSICAL:
180 return "LIBUSB_CLASS_PHYSICAL";
181 case LIBUSB_CLASS_PRINTER:
182 return "LIBUSB_CLASS_PRINTER";
183 case LIBUSB_CLASS_IMAGE:
184 return "LIBUSB_CLASS_IMAGE";
185 case LIBUSB_CLASS_MASS_STORAGE:
186 return "LIBUSB_CLASS_MASS_STORAGE";
187 case LIBUSB_CLASS_HUB:
188 return "LIBUSB_CLASS_HUB";
189 case LIBUSB_CLASS_DATA:
190 return "LIBUSB_CLASS_DATA";
191 case LIBUSB_CLASS_SMART_CARD:
192 return "LIBUSB_CLASS_SMART_CARD";
193 case LIBUSB_CLASS_CONTENT_SECURITY:
194 return "LIBUSB_CLASS_CONTENT_SECURITY";
195 case LIBUSB_CLASS_VIDEO:
196 return "LIBUSB_CLASS_VIDEO";
197 case LIBUSB_CLASS_PERSONAL_HEALTHCARE:
198 return "LIBUSB_CLASS_PERSONAL_HEALTHCARE";
199 case LIBUSB_CLASS_DIAGNOSTIC_DEVICE:
200 return "LIBUSB_CLASS_DIAGNOSTIC_DEVICE";
201 case LIBUSB_CLASS_WIRELESS:
202 return "LIBUSB_CLASS_WIRELESS";
203 case LIBUSB_CLASS_APPLICATION:
204 return "LIBUSB_CLASS_APPLICATION";
205 case LIBUSB_CLASS_VENDOR_SPEC:
206 return "LIBUSB_CLASS_VENDOR_SPEC";
207 default:
208 return "UNKNOWN_DEVICE_CLASS";
209 }
210}
211
212static void async_transfer_user_data_free(ASYNC_TRANSFER_USER_DATA* user_data)
213{
214 if (user_data)
215 {
216 Stream_Free(user_data->data, TRUE);
217 free(user_data);
218 }
219}
220
221WINPR_ATTR_MALLOC(async_transfer_user_data_free, 1)
222static ASYNC_TRANSFER_USER_DATA*
223async_transfer_user_data_new(IUDEVICE* idev, UINT32 MessageId, size_t offset, size_t BufferSize,
224 const BYTE* data, size_t packetSize, BOOL NoAck, int transferDir,
225 t_isoch_transfer_cb cb, GENERIC_CHANNEL_CALLBACK* callback)
226{
227 ASYNC_TRANSFER_USER_DATA* user_data = nullptr;
228 UDEVICE* pdev = (UDEVICE*)idev;
229
230 if (BufferSize > UINT32_MAX)
231 return nullptr;
232
233 user_data = calloc(1, sizeof(ASYNC_TRANSFER_USER_DATA));
234 if (!user_data)
235 return nullptr;
236
237 user_data->data = Stream_New(nullptr, offset + BufferSize + packetSize);
238
239 if (!user_data->data)
240 {
241 free(user_data);
242 return nullptr;
243 }
244
245 Stream_Seek(user_data->data, offset); /* Skip header offset */
246 if (data)
247 memcpy(Stream_Pointer(user_data->data), data, BufferSize);
248
249 user_data->noack = NoAck;
250 user_data->transferDir = transferDir;
251 user_data->cb = cb;
252 user_data->callback = callback;
253 user_data->idev = idev;
254 user_data->MessageId = MessageId;
255
256 user_data->queue = pdev->request_queue;
257
258 return user_data;
259}
260
261static void LIBUSB_CALL func_iso_callback(struct libusb_transfer* transfer)
262{
263 ASYNC_TRANSFER_USER_DATA* user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
264 const UINT32 streamID = stream_id_from_buffer(transfer);
265 wArrayList* list = user_data->queue;
266
267 ArrayList_Lock(list);
268 switch (transfer->status)
269 {
270 case LIBUSB_TRANSFER_COMPLETED:
271 {
272 UINT32 index = 0;
273 BYTE* dataStart = Stream_Pointer(user_data->data);
274 if (!Stream_SetPosition(user_data->data,
275 40)) /* TS_URB_ISOCH_TRANSFER_RESULT IsoPacket offset */
276 break;
277
278 for (uint32_t i = 0; i < WINPR_ASSERTING_INT_CAST(uint32_t, transfer->num_iso_packets);
279 i++)
280 {
281 const UINT32 act_len = transfer->iso_packet_desc[i].actual_length;
282 Stream_Write_UINT32(user_data->data, index);
283 Stream_Write_UINT32(user_data->data, act_len);
284 Stream_Write_UINT32(user_data->data, transfer->iso_packet_desc[i].status);
285
286 if (transfer->iso_packet_desc[i].status != USBD_STATUS_SUCCESS)
287 user_data->ErrorCount++;
288 else
289 {
290 const unsigned char* packetBuffer =
291 libusb_get_iso_packet_buffer_simple(transfer, i);
292 BYTE* data = dataStart + index;
293
294 if (data != packetBuffer)
295 memmove(data, packetBuffer, act_len);
296
297 index += act_len;
298 }
299 }
300 user_data->OutputBufferSize = index;
301 }
302 /* fallthrough */
303 WINPR_FALLTHROUGH
304 case LIBUSB_TRANSFER_CANCELLED:
305 /* fallthrough */
306 WINPR_FALLTHROUGH
307 case LIBUSB_TRANSFER_TIMED_OUT:
308 /* fallthrough */
309 WINPR_FALLTHROUGH
310 case LIBUSB_TRANSFER_ERROR:
311 /* fallthrough */
312 WINPR_FALLTHROUGH
313 default:
314 {
315 /* The transfer is finished in any case, always dequeue it */
316 const UINT32 InterfaceId =
317 ((STREAM_ID_PROXY << 30) | user_data->idev->get_ReqCompletion(user_data->idev));
318
319 if (list_contains(list, streamID))
320 {
321 if (!user_data->noack)
322 {
323 const UINT32 RequestID = streamID & INTERFACE_ID_MASK;
324 user_data->cb(user_data->idev, user_data->callback, user_data->data,
325 InterfaceId, user_data->noack, user_data->MessageId, RequestID,
326 WINPR_ASSERTING_INT_CAST(uint32_t, transfer->num_iso_packets),
327 transfer->status, user_data->StartFrame, user_data->ErrorCount,
328 user_data->OutputBufferSize, user_data->transferDir);
329 user_data->data = nullptr;
330 }
331 ArrayList_Remove(list, transfer);
332 }
333 }
334 break;
335 }
336 ArrayList_Unlock(list);
337}
338
339WINPR_ATTR_NODISCARD
340static int func_get_interface_number(const LIBUSB_CONFIG_DESCRIPTOR* config, unsigned index)
341{
342 if (!config || !config->interface || (index >= config->bNumInterfaces))
343 return LIBUSB_ERROR_NOT_FOUND;
344
345 const LIBUSB_INTERFACE* interface = &config->interface[index];
346 if (!interface->altsetting || (interface->num_altsetting <= 0))
347 return LIBUSB_ERROR_NOT_FOUND;
348 return interface->altsetting[0].bInterfaceNumber;
349}
350
351WINPR_ATTR_NODISCARD
352static const LIBUSB_INTERFACE_DESCRIPTOR*
353func_get_interface_descriptor(const LIBUSB_CONFIG_DESCRIPTOR* config, BYTE number, BYTE alternate)
354{
355 if (!config || !config->interface)
356 return nullptr;
357
358 for (int index = 0; index < config->bNumInterfaces; index++)
359 {
360 const LIBUSB_INTERFACE* interface = &config->interface[index];
361 if (!interface->altsetting)
362 continue;
363 for (int alt = 0; alt < interface->num_altsetting; alt++)
364 {
365 const LIBUSB_INTERFACE_DESCRIPTOR* descriptor = &interface->altsetting[alt];
366 if ((descriptor->bInterfaceNumber == number) &&
367 (descriptor->bAlternateSetting == alternate))
368 return descriptor;
369 }
370 }
371 return nullptr;
372}
373
374WINPR_ATTR_NODISCARD
375static const LIBUSB_ENDPOINT_DESCEIPTOR* func_get_ep_desc(LIBUSB_CONFIG_DESCRIPTOR* LibusbConfig,
376 MSUSB_CONFIG_DESCRIPTOR* MsConfig,
377 UINT32 EndpointAddress)
378{
379 MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = MsConfig->MsInterfaces;
380 const LIBUSB_INTERFACE* interface = LibusbConfig->interface;
381
382 for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
383 {
384 if (inum >= LibusbConfig->bNumInterfaces)
385 continue;
386
387 const LIBUSB_INTERFACE* ifc = &interface[inum];
388 BYTE alt = MsInterfaces[inum]->AlternateSetting;
389 if (alt >= ifc->num_altsetting)
390 continue;
391
392 const struct libusb_interface_descriptor* altifc = &ifc->altsetting[alt];
393 const LIBUSB_ENDPOINT_DESCEIPTOR* endpoint = altifc->endpoint;
394
395 for (UINT32 pnum = 0; pnum < MsInterfaces[inum]->NumberOfPipes; pnum++)
396 {
397 if (pnum >= altifc->bNumEndpoints)
398 continue;
399
400 if (endpoint[pnum].bEndpointAddress == EndpointAddress)
401 {
402 return &endpoint[pnum];
403 }
404 }
405 }
406
407 return nullptr;
408}
409
410static void LIBUSB_CALL func_bulk_transfer_cb(struct libusb_transfer* transfer)
411{
412 uint32_t streamID = 0;
413
414 ASYNC_TRANSFER_USER_DATA* user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
415 if (!user_data)
416 {
417 WLog_ERR(TAG, "Invalid transfer->user_data!");
418 return;
419 }
420 wArrayList* list = user_data->queue;
421 ArrayList_Lock(list);
422 streamID = stream_id_from_buffer(transfer);
423
424 if (list_contains(list, streamID))
425 {
426 const UINT32 InterfaceId =
427 ((STREAM_ID_PROXY << 30) | user_data->idev->get_ReqCompletion(user_data->idev));
428 const UINT32 RequestID = streamID & INTERFACE_ID_MASK;
429
430 UINT32 status = USBD_STATUS_SUCCESS;
431 switch (transfer->status)
432 {
433 case LIBUSB_TRANSFER_COMPLETED:
434 status = USBD_STATUS_SUCCESS;
435 break;
436
437 case LIBUSB_TRANSFER_ERROR:
438 status = USBD_STATUS_CANCELED;
439 break;
440
441 case LIBUSB_TRANSFER_TIMED_OUT:
442 status = USBD_STATUS_TIMEOUT;
443 break;
444
445 /* complete with a non error status */
446 case LIBUSB_TRANSFER_CANCELLED:
447 status = USBD_STATUS_SUCCESS;
448 break;
449
450 case LIBUSB_TRANSFER_STALL:
451 status = USBD_STATUS_STALL_PID;
452 break;
453
454 case LIBUSB_TRANSFER_NO_DEVICE:
455 status = USBD_STATUS_DEVICE_GONE;
456 break;
457
458 case LIBUSB_TRANSFER_OVERFLOW:
459 status = USBD_STATUS_BABBLE_DETECTED;
460 break;
461
462 default:
463 status = USBD_STATUS_CANCELED;
464 break;
465 }
466
467 user_data->cb(user_data->idev, user_data->callback, user_data->data, InterfaceId,
468 user_data->noack, user_data->MessageId, RequestID,
469 WINPR_ASSERTING_INT_CAST(uint32_t, transfer->num_iso_packets), status,
470 user_data->StartFrame, user_data->ErrorCount,
471 WINPR_ASSERTING_INT_CAST(uint32_t, transfer->actual_length),
472 user_data->transferDir);
473 user_data->data = nullptr;
474 ArrayList_Remove(list, transfer);
475 }
476 ArrayList_Unlock(list);
477}
478
479WINPR_ATTR_NODISCARD
480static BOOL func_set_usbd_status(URBDRC_PLUGIN* urbdrc, UDEVICE* pdev, UINT32* status,
481 int err_result)
482{
483 if (!urbdrc || !status)
484 return FALSE;
485
486 switch (err_result)
487 {
488 case LIBUSB_SUCCESS:
489 *status = USBD_STATUS_SUCCESS;
490 break;
491
492 case LIBUSB_ERROR_IO:
493 *status = USBD_STATUS_STALL_PID;
494 break;
495
496 case LIBUSB_ERROR_INVALID_PARAM:
497 *status = USBD_STATUS_INVALID_PARAMETER;
498 break;
499
500 case LIBUSB_ERROR_ACCESS:
501 *status = USBD_STATUS_NOT_ACCESSED;
502 break;
503
504 case LIBUSB_ERROR_NO_DEVICE:
505 *status = USBD_STATUS_DEVICE_GONE;
506
507 if (pdev)
508 {
509 if (!(pdev->status & URBDRC_DEVICE_NOT_FOUND))
510 pdev->status |= URBDRC_DEVICE_NOT_FOUND;
511 }
512
513 break;
514
515 case LIBUSB_ERROR_NOT_FOUND:
516 *status = USBD_STATUS_STALL_PID;
517 break;
518
519 case LIBUSB_ERROR_BUSY:
520 *status = USBD_STATUS_STALL_PID;
521 break;
522
523 case LIBUSB_ERROR_TIMEOUT:
524 *status = USBD_STATUS_TIMEOUT;
525 break;
526
527 case LIBUSB_ERROR_OVERFLOW:
528 *status = USBD_STATUS_STALL_PID;
529 break;
530
531 case LIBUSB_ERROR_PIPE:
532 *status = USBD_STATUS_STALL_PID;
533 break;
534
535 case LIBUSB_ERROR_INTERRUPTED:
536 *status = USBD_STATUS_STALL_PID;
537 break;
538
539 case LIBUSB_ERROR_NO_MEM:
540 *status = USBD_STATUS_NO_MEMORY;
541 break;
542
543 case LIBUSB_ERROR_NOT_SUPPORTED:
544 *status = USBD_STATUS_NOT_SUPPORTED;
545 break;
546
547 case LIBUSB_ERROR_OTHER:
548 *status = USBD_STATUS_STALL_PID;
549 break;
550
551 default:
552 *status = USBD_STATUS_SUCCESS;
553 break;
554 }
555
556 return TRUE;
557}
558
559static int func_config_release_all_interface(URBDRC_PLUGIN* urbdrc,
560 LIBUSB_DEVICE_HANDLE* libusb_handle,
561 const LIBUSB_CONFIG_DESCRIPTOR* config)
562{
563 WINPR_ASSERT(urbdrc);
564 if (!config)
565 {
566 (void)log_libusb_result(urbdrc->log, WLOG_ERROR,
567 "func_config_release_all_interface(config=nullptr)",
568 LIBUSB_ERROR_INVALID_PARAM);
569 return -1;
570 }
571 for (unsigned index = 0; index < config->bNumInterfaces; index++)
572 {
573 const int number = func_get_interface_number(config, index);
574 if (number < 0)
575 return -1;
576 const int ret = libusb_release_interface(libusb_handle, number);
577 if (log_libusb_result(urbdrc->log, WLOG_WARN, "libusb_release_interface", ret))
578 return -1;
579 }
580 return 0;
581}
582
583static int func_claim_all_interface(URBDRC_PLUGIN* urbdrc, LIBUSB_DEVICE_HANDLE* libusb_handle,
584 const LIBUSB_CONFIG_DESCRIPTOR* config)
585{
586 WINPR_ASSERT(urbdrc);
587 if (!config)
588 {
589 (void)log_libusb_result(urbdrc->log, WLOG_ERROR, "func_claim_all_interface(config=nullptr)",
590 LIBUSB_ERROR_INVALID_PARAM);
591 return -1;
592 }
593 for (unsigned index = 0; index < config->bNumInterfaces; index++)
594 {
595 const int number = func_get_interface_number(config, index);
596 if (number < 0)
597 return -1;
598 int ret = libusb_claim_interface(libusb_handle, number);
599 if (log_libusb_result(urbdrc->log, WLOG_DEBUG, "libusb_claim_interface", ret))
600 {
601 /* With auto detach enabled the claim also fails when the kernel driver
602 * cannot be detached, e.g. on FreeBSD where that requires root.
603 * Retry without it, as claiming worked before auto detach was enabled. */
604 if (libusb_set_auto_detach_kernel_driver(libusb_handle, 0) == LIBUSB_SUCCESS)
605 ret = libusb_claim_interface(libusb_handle, number);
606 if (log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_claim_interface", ret))
607 return -1;
608 }
609 }
610 return 0;
611}
612
613WINPR_ATTR_NODISCARD
614static LIBUSB_DEVICE* udev_get_libusb_dev(libusb_context* context, uint8_t bus_number,
615 uint8_t dev_number)
616{
617 LIBUSB_DEVICE** libusb_list = nullptr;
618 LIBUSB_DEVICE* device = nullptr;
619 const ssize_t total_device = libusb_get_device_list(context, &libusb_list);
620
621 for (ssize_t i = 0; i < total_device; i++)
622 {
623 LIBUSB_DEVICE* dev = libusb_list[i];
624 if ((bus_number == libusb_get_bus_number(dev)) &&
625 (dev_number == libusb_get_device_address(dev)))
626 device = dev;
627 else
628 libusb_unref_device(dev);
629 }
630
631 libusb_free_device_list(libusb_list, 0);
632 return device;
633}
634
635WINPR_ATTR_MALLOC(free, 1)
636static LIBUSB_DEVICE_DESCRIPTOR* udev_new_descript(URBDRC_PLUGIN* urbdrc, LIBUSB_DEVICE* libusb_dev)
637{
638 int ret = 0;
639 LIBUSB_DEVICE_DESCRIPTOR* descriptor =
640 (LIBUSB_DEVICE_DESCRIPTOR*)calloc(1, sizeof(LIBUSB_DEVICE_DESCRIPTOR));
641 if (!descriptor)
642 return nullptr;
643 ret = libusb_get_device_descriptor(libusb_dev, descriptor);
644
645 if (log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_get_device_descriptor", ret))
646 {
647 free(descriptor);
648 return nullptr;
649 }
650
651 return descriptor;
652}
653
654WINPR_ATTR_NODISCARD
655static int libusb_udev_select_interface(IUDEVICE* idev, BYTE InterfaceNumber, BYTE AlternateSetting)
656{
657 UDEVICE* pdev = (UDEVICE*)idev;
658
659 if (!pdev || !pdev->urbdrc)
660 return -1;
661
662 URBDRC_PLUGIN* urbdrc = pdev->urbdrc;
663
664 const int error =
665 libusb_set_interface_alt_setting(pdev->libusb_handle, InterfaceNumber, AlternateSetting);
666
667 log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_set_interface_alt_setting", error);
668
669 return error;
670}
671
672WINPR_ATTR_NODISCARD
674libusb_udev_complete_msconfig_setup(IUDEVICE* idev, MSUSB_CONFIG_DESCRIPTOR* MsConfig)
675{
676 UDEVICE* pdev = (UDEVICE*)idev;
677 UINT32 MsOutSize = 0;
678
679 if (!pdev || !pdev->LibusbConfig || !pdev->urbdrc || !MsConfig)
680 return nullptr;
681
682 URBDRC_PLUGIN* urbdrc = pdev->urbdrc;
683 LIBUSB_CONFIG_DESCRIPTOR* LibusbConfig = pdev->LibusbConfig;
684
685 if (LibusbConfig->bNumInterfaces != MsConfig->NumInterfaces)
686 {
687 WLog_Print(urbdrc->log, WLOG_ERROR,
688 "Select Configuration: Libusb NumberInterfaces(%" PRIu8 ") is different "
689 "with MsConfig NumberInterfaces(%" PRIu32 ")",
690 LibusbConfig->bNumInterfaces, MsConfig->NumInterfaces);
691 return nullptr;
692 }
693
694 /* replace MsPipes for libusb */
695 MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = MsConfig->MsInterfaces;
696
697 if (!MsInterfaces)
698 return nullptr;
699 for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
700 {
701 const MSUSB_INTERFACE_DESCRIPTOR* MsInterface = MsInterfaces[inum];
702 if (!MsInterface)
703 return nullptr;
704 if (!func_get_interface_descriptor(LibusbConfig, MsInterface->InterfaceNumber,
705 MsInterface->AlternateSetting))
706 {
707 WLog_Print(urbdrc->log, WLOG_ERROR,
708 "USB interface %" PRIu8 " alternate setting %" PRIu8 " not found",
709 MsInterface->InterfaceNumber, MsInterface->AlternateSetting);
710 return nullptr;
711 }
712 }
713
714 for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
715 {
716 MSUSB_INTERFACE_DESCRIPTOR* MsInterface = MsInterfaces[inum];
717
718 /* get libusb's number of endpoints */
719 const LIBUSB_INTERFACE_DESCRIPTOR* LibusbAltsetting = func_get_interface_descriptor(
720 LibusbConfig, MsInterface->InterfaceNumber, MsInterface->AlternateSetting);
721 WINPR_ASSERT(LibusbAltsetting);
722 const BYTE LibusbNumEndpoint = LibusbAltsetting->bNumEndpoints;
723 MSUSB_PIPE_DESCRIPTOR** t_MsPipes =
724 (MSUSB_PIPE_DESCRIPTOR**)calloc(LibusbNumEndpoint, sizeof(MSUSB_PIPE_DESCRIPTOR*));
725
726 for (UINT32 pnum = 0; pnum < LibusbNumEndpoint; pnum++)
727 {
728 MSUSB_PIPE_DESCRIPTOR* t_MsPipe =
729 (MSUSB_PIPE_DESCRIPTOR*)calloc(1, sizeof(MSUSB_PIPE_DESCRIPTOR));
730
731 if (pnum < MsInterface->NumberOfPipes && MsInterface->MsPipes)
732 {
733 MSUSB_PIPE_DESCRIPTOR* MsPipe = MsInterface->MsPipes[pnum];
734 t_MsPipe->MaximumPacketSize = MsPipe->MaximumPacketSize;
735 t_MsPipe->MaximumTransferSize = MsPipe->MaximumTransferSize;
736 t_MsPipe->PipeFlags = MsPipe->PipeFlags;
737 }
738 else
739 {
740 t_MsPipe->MaximumPacketSize = 0;
741 t_MsPipe->MaximumTransferSize = 0xffffffff;
742 t_MsPipe->PipeFlags = 0;
743 }
744
745 t_MsPipe->PipeHandle = 0;
746 t_MsPipe->bEndpointAddress = 0;
747 t_MsPipe->bInterval = 0;
748 t_MsPipe->PipeType = 0;
749 t_MsPipe->InitCompleted = 0;
750 t_MsPipes[pnum] = t_MsPipe;
751 }
752
753 msusb_mspipes_replace(MsInterface, t_MsPipes, LibusbNumEndpoint);
754 }
755
756 /* setup configuration */
757 MsOutSize = 8;
758 /* ConfigurationHandle: 4 bytes
759 * ---------------------------------------------------------------
760 * ||<<< 1 byte >>>|<<< 1 byte >>>|<<<<<<<<<< 2 byte >>>>>>>>>>>||
761 * || bus_number | dev_number | bConfigurationValue ||
762 * ---------------------------------------------------------------
763 * ***********************/
764 MsConfig->ConfigurationHandle = (uint32_t)MsConfig->bConfigurationValue |
765 ((uint32_t)pdev->bus_number << 24) |
766 (((uint32_t)pdev->dev_number << 16) & 0xFF0000);
767 MsInterfaces = MsConfig->MsInterfaces;
768
769 for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
770 {
771 MsOutSize += 16;
772 MSUSB_INTERFACE_DESCRIPTOR* MsInterface = MsInterfaces[inum];
773 /* get libusb's interface */
774 const LIBUSB_INTERFACE_DESCRIPTOR* LibusbAltsetting = func_get_interface_descriptor(
775 LibusbConfig, MsInterface->InterfaceNumber, MsInterface->AlternateSetting);
776 WINPR_ASSERT(LibusbAltsetting);
777 /* InterfaceHandle: 4 bytes
778 * ---------------------------------------------------------------
779 * ||<<< 1 byte >>>|<<< 1 byte >>>|<<< 1 byte >>>|<<< 1 byte >>>||
780 * || bus_number | dev_number | altsetting | interfaceNum ||
781 * ---------------------------------------------------------------
782 * ***********************/
783 MsInterface->InterfaceHandle =
784 WINPR_ASSERTING_INT_CAST(UINT32, (LibusbAltsetting->bInterfaceNumber |
785 (LibusbAltsetting->bAlternateSetting << 8) |
786 (pdev->dev_number << 16) | (pdev->bus_number << 24)));
787 const size_t len = 16 + (MsInterface->NumberOfPipes * 20);
788 MsInterface->Length = WINPR_ASSERTING_INT_CAST(UINT16, len);
789 MsInterface->bInterfaceClass = LibusbAltsetting->bInterfaceClass;
790 MsInterface->bInterfaceSubClass = LibusbAltsetting->bInterfaceSubClass;
791 MsInterface->bInterfaceProtocol = LibusbAltsetting->bInterfaceProtocol;
792 MsInterface->InitCompleted = 1;
793 MSUSB_PIPE_DESCRIPTOR** MsPipes = MsInterface->MsPipes;
794 const BYTE LibusbNumEndpoint = LibusbAltsetting->bNumEndpoints;
795
796 for (UINT32 pnum = 0; pnum < LibusbNumEndpoint; pnum++)
797 {
798 MsOutSize += 20;
799
800 MSUSB_PIPE_DESCRIPTOR* MsPipe = MsPipes[pnum];
801 /* get libusb's endpoint */
802 const LIBUSB_ENDPOINT_DESCEIPTOR* LibusbEndpoint = &LibusbAltsetting->endpoint[pnum];
803 /* PipeHandle: 4 bytes
804 * ---------------------------------------------------------------
805 * ||<<< 1 byte >>>|<<< 1 byte >>>|<<<<<<<<<< 2 byte >>>>>>>>>>>||
806 * || bus_number | dev_number | bEndpointAddress ||
807 * ---------------------------------------------------------------
808 * ***********************/
809 MsPipe->PipeHandle = LibusbEndpoint->bEndpointAddress |
810 (((uint32_t)pdev->dev_number << 16) & 0xFF0000) |
811 (((uint32_t)pdev->bus_number << 24) & 0xFF000000);
812 /* count endpoint max packet size */
813 unsigned max = LibusbEndpoint->wMaxPacketSize & 0x07ff;
814 BYTE attr = LibusbEndpoint->bmAttributes;
815
816 if ((attr & 0x3) == 1 || (attr & 0x3) == 3)
817 {
818 max *= (1 + ((LibusbEndpoint->wMaxPacketSize >> 11) & 3));
819 }
820
821 MsPipe->MaximumPacketSize = WINPR_ASSERTING_INT_CAST(uint16_t, max);
822 MsPipe->bEndpointAddress = LibusbEndpoint->bEndpointAddress;
823 MsPipe->bInterval = LibusbEndpoint->bInterval;
824 MsPipe->PipeType = attr & 0x3;
825 MsPipe->InitCompleted = 1;
826 }
827 }
828
829 MsConfig->MsOutSize = WINPR_ASSERTING_INT_CAST(int, MsOutSize);
830 MsConfig->InitCompleted = 1;
831
832 /* replace device's MsConfig */
833 if (MsConfig != pdev->MsConfig)
834 {
835 msusb_msconfig_free(pdev->MsConfig);
836 pdev->MsConfig = MsConfig;
837 }
838
839 return MsConfig;
840}
841
842WINPR_ATTR_NODISCARD
843static BOOL libusb_udev_detach_kernel_driver(IUDEVICE* idev);
844
845WINPR_ATTR_NODISCARD
846static int libusb_udev_select_configuration(IUDEVICE* idev, UINT32 bConfigurationValue)
847{
848 UDEVICE* pdev = (UDEVICE*)idev;
849 MSUSB_CONFIG_DESCRIPTOR* MsConfig = nullptr;
850 LIBUSB_DEVICE_HANDLE* libusb_handle = nullptr;
851 LIBUSB_DEVICE* libusb_dev = nullptr;
852 URBDRC_PLUGIN* urbdrc = nullptr;
853 LIBUSB_CONFIG_DESCRIPTOR** LibusbConfig = nullptr;
854 int ret = 0;
855
856 if (!pdev || !pdev->MsConfig || !pdev->LibusbConfig || !pdev->urbdrc)
857 return -1;
858
859 urbdrc = pdev->urbdrc;
860 MsConfig = pdev->MsConfig;
861 libusb_handle = pdev->libusb_handle;
862 libusb_dev = pdev->libusb_dev;
863 LibusbConfig = &pdev->LibusbConfig;
864
865 if (MsConfig->InitCompleted)
866 {
867 func_config_release_all_interface(pdev->urbdrc, libusb_handle, *LibusbConfig);
868 }
869
870 /* A kernel driver may have bound after the one-time detach done when the device was
871 * announced: with hotplug the device is added on arrival, while usb-storage, uvcvideo or
872 * snd-usb-audio probe a moment later. The kernel then rejects the configuration change
873 * with EBUSY ("interface claimed by usb-storage while 'xfreerdp3' sets config") and the
874 * device stays with the local driver. Detach again before changing the configuration. */
875 pdev->status &= (UINT16)~URBDRC_DEVICE_DETACH_KERNEL;
876 if (!libusb_udev_detach_kernel_driver(idev))
877 WLog_Print(urbdrc->log, WLOG_WARN, "libusb_udev_detach_kernel_driver failed, ignoring");
878
879 /* The configuration value -1 is mean to put the device in unconfigured state. */
880 if (bConfigurationValue == 0)
881 ret = libusb_set_configuration(libusb_handle, -1);
882 else
883 ret = libusb_set_configuration(libusb_handle,
884 WINPR_ASSERTING_INT_CAST(int, bConfigurationValue));
885
886 if (log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_set_configuration", ret))
887 {
888 func_claim_all_interface(urbdrc, libusb_handle, *LibusbConfig);
889 return -1;
890 }
891 else
892 {
893 ret = libusb_get_active_config_descriptor(libusb_dev, LibusbConfig);
894
895 if (log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_set_configuration", ret))
896 {
897 func_claim_all_interface(urbdrc, libusb_handle, *LibusbConfig);
898 return -1;
899 }
900 }
901
902 return func_claim_all_interface(urbdrc, libusb_handle, *LibusbConfig);
903}
904
905WINPR_ATTR_NODISCARD
906static int libusb_udev_control_pipe_request(IUDEVICE* idev, WINPR_ATTR_UNUSED UINT32 RequestId,
907 UINT32 EndpointAddress, UINT32* UsbdStatus, int command)
908{
909 int error = 0;
910 UDEVICE* pdev = (UDEVICE*)idev;
911
912 WINPR_ASSERT(EndpointAddress <= UINT8_MAX);
913 /*
914 pdev->request_queue->register_request(pdev->request_queue, RequestId, nullptr, 0);
915 */
916 switch (command)
917 {
918 case PIPE_CANCEL:
920 idev->cancel_all_transfer_request(idev);
921 // dummy_wait_s_obj(1);
923 /*
924 uint8_t request_type, uint8_t bRequest,
925 */
926 error = libusb_control_transfer(pdev->libusb_handle,
927 (uint8_t)LIBUSB_ENDPOINT_OUT |
928 (uint8_t)LIBUSB_RECIPIENT_ENDPOINT,
929 LIBUSB_REQUEST_SET_FEATURE, ENDPOINT_HALT,
930 (uint16_t)EndpointAddress, nullptr, 0, 1000);
931 break;
932
933 case PIPE_RESET:
934 idev->cancel_all_transfer_request(idev);
935 error = libusb_clear_halt(pdev->libusb_handle, (uint8_t)EndpointAddress);
936 // func_set_usbd_status(pdev, UsbdStatus, error);
937 break;
938
939 default:
940 error = -0xff;
941 break;
942 }
943
944 *UsbdStatus = 0;
945 return error;
946}
947
948WINPR_ATTR_NODISCARD
949static UINT32 libusb_udev_control_query_device_text(IUDEVICE* idev, UINT32 TextType,
950 UINT16 LocaleId, UINT8* BufferSize,
951 BYTE* Buffer)
952{
953 UDEVICE* pdev = (UDEVICE*)idev;
954 LIBUSB_DEVICE_DESCRIPTOR* devDescriptor = nullptr;
955 const char strDesc[] = "Generic Usb String";
956 char deviceLocation[25] = WINPR_C_ARRAY_INIT;
957 BYTE bus_number = 0;
958 BYTE device_address = 0;
959 int ret = 0;
960 URBDRC_PLUGIN* urbdrc = nullptr;
961 WCHAR* text = WINPR_PACKED_ALIGN_CAST(WCHAR*, Buffer);
962 BYTE slen = 0;
963 BYTE locale = 0;
964 const UINT8 inSize = *BufferSize;
965
966 *BufferSize = 0;
967 if (!pdev || !pdev->devDescriptor || !pdev->urbdrc)
968 return ERROR_INVALID_DATA;
969
970 urbdrc = pdev->urbdrc;
971 devDescriptor = pdev->devDescriptor;
972
973 switch (TextType)
974 {
975 case DeviceTextDescription:
976 {
977 BYTE data[0x100] = WINPR_C_ARRAY_INIT;
978 ret = libusb_get_string_descriptor(pdev->libusb_handle, devDescriptor->iProduct,
979 LocaleId, data, 0xFF);
980 /* The returned data in the buffer is:
981 * 1 byte length of following data
982 * 1 byte descriptor type, must be 0x03 for strings
983 * n WCHAR unicode string (of length / 2 characters) including '\0'
984 */
985 slen = data[0];
986 locale = data[1];
987
988 if ((ret <= 0) || (ret <= 4) || (slen <= 4) || (locale != LIBUSB_DT_STRING) ||
989 (ret > UINT8_MAX))
990 {
991 const char* msg = "SHORT_DESCRIPTOR";
992 if (ret < 0)
993 msg = libusb_error_name(ret);
994 WLog_Print(urbdrc->log, WLOG_DEBUG,
995 "libusb_get_string_descriptor: "
996 "%s [%d], iProduct: %" PRIu8 "!",
997 msg, ret, devDescriptor->iProduct);
998
999 size_t len = MIN(sizeof(strDesc), inSize);
1000 for (size_t i = 0; i < len; i++)
1001 text[i] = (WCHAR)strDesc[i];
1002
1003 *BufferSize = (BYTE)(len * sizeof(WCHAR));
1004 }
1005 else
1006 {
1007 size_t maxlen = inSize;
1008 size_t len = 0;
1009 if (inSize > sizeof(WCHAR))
1010 {
1011 maxlen -= sizeof(WCHAR);
1012
1013 /* ret and slen should be equals, but you never know creativity
1014 * of device manufacturers...
1015 * So also check the string length returned as server side does
1016 * not honor strings with multi '\0' characters well.
1017 */
1018 const size_t rchar =
1019 _wcsnlen((WCHAR*)&data[2], (sizeof(data) / sizeof(WCHAR)) - 1);
1020 len = MIN((BYTE)ret - 2, slen);
1021 len = MIN(len, rchar * sizeof(WCHAR));
1022 len = MIN(len, maxlen);
1023
1024 memcpy(Buffer, &data[2], len);
1025
1026 /* Just as above, the returned WCHAR string should be '\0'
1027 * terminated, but never trust hardware to conform to specs... */
1028 if (Buffer[len] != '\0')
1029 {
1030 Buffer[len++] = '\0';
1031 Buffer[len++] = '\0';
1032 }
1033 }
1034 *BufferSize = (BYTE)len;
1035 }
1036 }
1037 break;
1038
1039 case DeviceTextLocationInformation:
1040 {
1041 bus_number = libusb_get_bus_number(pdev->libusb_dev);
1042 device_address = libusb_get_device_address(pdev->libusb_dev);
1043 (void)sprintf_s(deviceLocation, sizeof(deviceLocation),
1044 "Port_#%04" PRIu8 ".Hub_#%04" PRIu8 "", device_address, bus_number);
1045
1046 size_t len = strnlen(deviceLocation,
1047 MIN(sizeof(deviceLocation), (inSize > 0) ? inSize - 1U : 0));
1048 for (size_t i = 0; i < len; i++)
1049 text[i] = (WCHAR)deviceLocation[i];
1050 text[len++] = '\0';
1051 *BufferSize = (UINT8)(len * sizeof(WCHAR));
1052 }
1053 break;
1054
1055 default:
1056 WLog_Print(urbdrc->log, WLOG_DEBUG, "Query Text: unknown TextType %" PRIu32 "",
1057 TextType);
1058 return ERROR_INVALID_DATA;
1059 }
1060
1061 return S_OK;
1062}
1063
1064WINPR_ATTR_NODISCARD
1065static int libusb_udev_os_feature_descriptor_request(IUDEVICE* idev,
1066 WINPR_ATTR_UNUSED UINT32 RequestId,
1067 BYTE Recipient, BYTE InterfaceNumber,
1068 BYTE Ms_PageIndex, UINT16 Ms_featureDescIndex,
1069 UINT32* UsbdStatus, UINT32* BufferSize,
1070 BYTE* Buffer, UINT32 Timeout)
1071{
1072 UDEVICE* pdev = (UDEVICE*)idev;
1073 BYTE ms_string_desc[0x13] = WINPR_C_ARRAY_INIT;
1074 int error = 0;
1075
1076 WINPR_ASSERT(pdev);
1077 WINPR_ASSERT(pdev->urbdrc);
1078 WINPR_ASSERT(UsbdStatus);
1079 WINPR_ASSERT(BufferSize);
1080
1081 if (*BufferSize > UINT16_MAX)
1082 {
1083 WLog_Print(pdev->urbdrc->log, WLOG_ERROR, "BufferSize %" PRIu32 " > %d", *BufferSize,
1084 UINT16_MAX);
1085 return -1;
1086 }
1087
1088 const UINT16 requestedSize = WINPR_ASSERTING_INT_CAST(UINT16, *BufferSize);
1089 *BufferSize = 0;
1090
1091 /*
1092 pdev->request_queue->register_request(pdev->request_queue, RequestId, nullptr, 0);
1093 */
1094 error = libusb_control_transfer(pdev->libusb_handle, LIBUSB_ENDPOINT_IN | Recipient,
1095 LIBUSB_REQUEST_GET_DESCRIPTOR, 0x03ee, 0, ms_string_desc, 0x12,
1096 Timeout);
1097
1098 log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG, "libusb_control_transfer", error);
1099
1100 if (error > 0)
1101 {
1102 const BYTE bMS_Vendorcode = ms_string_desc[16];
1104 error = libusb_control_transfer(
1105 pdev->libusb_handle,
1106 (uint8_t)LIBUSB_ENDPOINT_IN | (uint8_t)LIBUSB_REQUEST_TYPE_VENDOR | Recipient,
1107 bMS_Vendorcode, (UINT16)((InterfaceNumber << 8) | Ms_PageIndex), Ms_featureDescIndex,
1108 Buffer, requestedSize, Timeout);
1109 log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG, "libusb_control_transfer", error);
1110
1111 if (error >= 0)
1112 *BufferSize = (UINT32)error;
1113 }
1114
1115 if (error < 0)
1116 *UsbdStatus = USBD_STATUS_STALL_PID;
1117 else
1118 *UsbdStatus = USBD_STATUS_SUCCESS;
1119
1120 return ERROR_SUCCESS;
1121}
1122
1123WINPR_ATTR_NODISCARD
1124static enum device_speed libusb_udev_query_device_speed(IUDEVICE* idev)
1125{
1126 UDEVICE* pdev = (UDEVICE*)idev;
1127
1128 if (!pdev || !pdev->libusb_dev)
1129 return DEVICE_SPEED_UNKNOWN;
1130
1131 switch (libusb_get_device_speed(pdev->libusb_dev))
1132 {
1133 case LIBUSB_SPEED_LOW:
1134 return DEVICE_SPEED_LOW;
1135
1136 case LIBUSB_SPEED_FULL:
1137 return DEVICE_SPEED_FULL;
1138
1139 case LIBUSB_SPEED_HIGH:
1140 return DEVICE_SPEED_HIGH;
1141
1142 case LIBUSB_SPEED_SUPER:
1143 return DEVICE_SPEED_SUPER;
1144
1145#if LIBUSB_API_VERSION >= 0x01000106
1146 case LIBUSB_SPEED_SUPER_PLUS:
1147 return DEVICE_SPEED_SUPER_PLUS;
1148#endif
1149
1150 default:
1151 return DEVICE_SPEED_UNKNOWN;
1152 }
1153}
1154
1155WINPR_ATTR_NODISCARD
1156static int libusb_udev_query_device_descriptor(IUDEVICE* idev, int offset)
1157{
1158 UDEVICE* pdev = (UDEVICE*)idev;
1159
1160 switch (offset)
1161 {
1162 case B_LENGTH:
1163 return pdev->devDescriptor->bLength;
1164
1165 case B_DESCRIPTOR_TYPE:
1166 return pdev->devDescriptor->bDescriptorType;
1167
1168 case BCD_USB:
1169 return pdev->devDescriptor->bcdUSB;
1170
1171 case B_DEVICE_CLASS:
1172 return pdev->devDescriptor->bDeviceClass;
1173
1174 case B_DEVICE_SUBCLASS:
1175 return pdev->devDescriptor->bDeviceSubClass;
1176
1177 case B_DEVICE_PROTOCOL:
1178 return pdev->devDescriptor->bDeviceProtocol;
1179
1180 case B_MAX_PACKET_SIZE0:
1181 return pdev->devDescriptor->bMaxPacketSize0;
1182
1183 case ID_VENDOR:
1184 return pdev->devDescriptor->idVendor;
1185
1186 case ID_PRODUCT:
1187 return pdev->devDescriptor->idProduct;
1188
1189 case BCD_DEVICE:
1190 return pdev->devDescriptor->bcdDevice;
1191
1192 case I_MANUFACTURER:
1193 return pdev->devDescriptor->iManufacturer;
1194
1195 case I_PRODUCT:
1196 return pdev->devDescriptor->iProduct;
1197
1198 case I_SERIAL_NUMBER:
1199 return pdev->devDescriptor->iSerialNumber;
1200
1201 case B_NUM_CONFIGURATIONS:
1202 return pdev->devDescriptor->bNumConfigurations;
1203
1204 default:
1205 return 0;
1206 }
1207}
1208
1209WINPR_ATTR_NODISCARD
1210static BOOL libusb_udev_detach_kernel_driver(IUDEVICE* idev)
1211{
1212 int err = 0;
1213 UDEVICE* pdev = (UDEVICE*)idev;
1214 URBDRC_PLUGIN* urbdrc = nullptr;
1215
1216 if (!pdev || !pdev->LibusbConfig || !pdev->libusb_handle || !pdev->urbdrc)
1217 return FALSE;
1218
1219#ifdef _WIN32
1220 return TRUE;
1221#else
1222 urbdrc = pdev->urbdrc;
1223
1224 if ((pdev->status & URBDRC_DEVICE_DETACH_KERNEL) == 0)
1225 {
1226 for (unsigned i = 0; i < pdev->LibusbConfig->bNumInterfaces; i++)
1227 {
1228 const int number = func_get_interface_number(pdev->LibusbConfig, i);
1229 if (number < 0)
1230 return FALSE;
1231 err = libusb_kernel_driver_active(pdev->libusb_handle, number);
1232 log_libusb_result(urbdrc->log, WLOG_DEBUG, "libusb_kernel_driver_active", err);
1233 // compare to 1 explicitly because 1 means a kernel driver is active
1234 if (err == 1)
1235 {
1236 err = libusb_detach_kernel_driver(pdev->libusb_handle, number);
1237 log_libusb_result(urbdrc->log, WLOG_DEBUG, "libusb_detach_kernel_driver", err);
1238 }
1239 }
1240
1241 pdev->status |= URBDRC_DEVICE_DETACH_KERNEL;
1242 }
1243
1244 return TRUE;
1245#endif
1246}
1247
1248WINPR_ATTR_NODISCARD
1249static BOOL libusb_udev_attach_kernel_driver(IUDEVICE* idev)
1250{
1251 int err = 0;
1252 UDEVICE* pdev = (UDEVICE*)idev;
1253
1254 if (!pdev || !pdev->LibusbConfig || !pdev->libusb_handle || !pdev->urbdrc)
1255 return FALSE;
1256
1257 for (unsigned i = 0; i < pdev->LibusbConfig->bNumInterfaces && err != LIBUSB_ERROR_NO_DEVICE;
1258 i++)
1259 {
1260 const int number = func_get_interface_number(pdev->LibusbConfig, i);
1261 if (number < 0)
1262 return FALSE;
1263 err = libusb_release_interface(pdev->libusb_handle, number);
1264
1265 log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG, "libusb_release_interface", err);
1266
1267#ifndef _WIN32
1268 if (err != LIBUSB_ERROR_NO_DEVICE)
1269 {
1270 err = libusb_attach_kernel_driver(pdev->libusb_handle, number);
1271 log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG, "libusb_attach_kernel_driver if=%d",
1272 err, number);
1273 }
1274#endif
1275 }
1276
1277 return TRUE;
1278}
1279
1280WINPR_ATTR_NODISCARD
1281static int libusb_udev_is_composite_device(IUDEVICE* idev)
1282{
1283 UDEVICE* pdev = (UDEVICE*)idev;
1284 return pdev->isCompositeDevice;
1285}
1286
1287WINPR_ATTR_NODISCARD
1288static int libusb_udev_is_exist(IUDEVICE* idev)
1289{
1290 UDEVICE* pdev = (UDEVICE*)idev;
1291 return (pdev->status & URBDRC_DEVICE_NOT_FOUND) ? 0 : 1;
1292}
1293
1294WINPR_ATTR_NODISCARD
1295static int libusb_udev_is_channel_closed(IUDEVICE* idev)
1296{
1297 UDEVICE* pdev = (UDEVICE*)idev;
1298 IUDEVMAN* udevman = nullptr;
1299 if (!pdev || !pdev->urbdrc)
1300 return 1;
1301
1302 udevman = pdev->urbdrc->udevman;
1303 if (udevman)
1304 {
1305 if (udevman->status & URBDRC_DEVICE_CHANNEL_CLOSED)
1306 return 1;
1307 }
1308
1309 if (pdev->status & URBDRC_DEVICE_CHANNEL_CLOSED)
1310 return 1;
1311
1312 return 0;
1313}
1314
1315WINPR_ATTR_NODISCARD
1316static int libusb_udev_is_already_send(IUDEVICE* idev)
1317{
1318 UDEVICE* pdev = (UDEVICE*)idev;
1319 return (pdev->status & URBDRC_DEVICE_ALREADY_SEND) ? 1 : 0;
1320}
1321
1322/* This is called from channel cleanup code.
1323 * Avoid double free, just remove the device and mark the channel closed. */
1324static void libusb_udev_mark_channel_closed(IUDEVICE* idev)
1325{
1326 UDEVICE* pdev = (UDEVICE*)idev;
1327 if (pdev && ((pdev->status & URBDRC_DEVICE_CHANNEL_CLOSED) == 0))
1328 {
1329 URBDRC_PLUGIN* urbdrc = pdev->urbdrc;
1330 const uint8_t busNr = idev->get_bus_number(idev);
1331 const uint8_t devNr = idev->get_dev_number(idev);
1332
1333 pdev->status |= URBDRC_DEVICE_CHANNEL_CLOSED;
1334 pdev->iface.cancel_all_transfer_request(&pdev->iface);
1335 if (!urbdrc->udevman->unregister_udevice(urbdrc->udevman, busNr, devNr))
1336 {
1337 WLog_Print(pdev->urbdrc->log, WLOG_WARN, "unregister_udevice failed for %d, %d", busNr,
1338 devNr);
1339 }
1340 }
1341}
1342
1343/* This is called by local events where the device is removed or in an error
1344 * state. Remove the device from redirection and close the channel. */
1345static void libusb_udev_channel_closed(IUDEVICE* idev)
1346{
1347 UDEVICE* pdev = (UDEVICE*)idev;
1348 if (pdev && ((pdev->status & URBDRC_DEVICE_CHANNEL_CLOSED) == 0))
1349 {
1350 URBDRC_PLUGIN* urbdrc = pdev->urbdrc;
1351 const uint8_t busNr = idev->get_bus_number(idev);
1352 const uint8_t devNr = idev->get_dev_number(idev);
1353 IWTSVirtualChannel* channel = nullptr;
1354
1355 IUDEVMAN* udevman = pdev->urbdrc->udevman;
1356 WINPR_ASSERT(udevman);
1357
1358 udevman->loading_lock(udevman);
1359 if ((pdev->status & URBDRC_DEVICE_CHANNEL_CLOSED) == 0)
1360 {
1361 if (pdev->channelManager)
1362 channel = IFCALLRESULT(nullptr, pdev->channelManager->FindChannelById,
1363 pdev->channelManager, pdev->channelID);
1364
1365 pdev->status |= URBDRC_DEVICE_CHANNEL_CLOSED;
1366
1367 if (channel)
1368 {
1369 const UINT rc = channel->Write(channel, 0, nullptr, nullptr);
1370 if (rc != CHANNEL_RC_OK)
1371 WLog_Print(urbdrc->log, WLOG_WARN, "channel->Write failed with %" PRIu32, rc);
1372 }
1373 }
1374 udevman->loading_unlock(udevman);
1375
1376 if (!urbdrc->udevman->unregister_udevice(urbdrc->udevman, busNr, devNr))
1377 WLog_Print(urbdrc->log, WLOG_WARN, "unregister_udevice failed for %d, %d", busNr,
1378 devNr);
1379 }
1380}
1381
1382static void libusb_udev_set_already_send(IUDEVICE* idev)
1383{
1384 UDEVICE* pdev = (UDEVICE*)idev;
1385 pdev->status |= URBDRC_DEVICE_ALREADY_SEND;
1386}
1387
1388WINPR_ATTR_NODISCARD
1389static const char* libusb_udev_get_path(IUDEVICE* idev)
1390{
1391 UDEVICE* pdev = (UDEVICE*)idev;
1392 return pdev->path;
1393}
1394
1395WINPR_ATTR_NODISCARD
1396static int libusb_udev_query_device_port_status(IUDEVICE* idev, UINT32* UsbdStatus,
1397 UINT32* BufferSize, BYTE* Buffer)
1398{
1399 UDEVICE* pdev = (UDEVICE*)idev;
1400 int success = 0;
1401 int ret = 0;
1402 URBDRC_PLUGIN* urbdrc = nullptr;
1403
1404 WINPR_ASSERT(BufferSize);
1405
1406 if (!pdev || !pdev->urbdrc)
1407 return -1;
1408
1409 urbdrc = pdev->urbdrc;
1410
1411 if (pdev->hub_handle != nullptr)
1412 {
1413 ret = idev->control_transfer(
1414 idev, 0xffff, 0, 0,
1415 (uint8_t)LIBUSB_ENDPOINT_IN | (uint8_t)LIBUSB_REQUEST_TYPE_CLASS |
1416 (uint8_t)LIBUSB_RECIPIENT_OTHER,
1417 LIBUSB_REQUEST_GET_STATUS, 0, pdev->port_number, UsbdStatus, BufferSize, Buffer, 1000);
1418
1419 if (log_libusb_result(urbdrc->log, WLOG_DEBUG, "libusb_control_transfer", ret))
1420 *BufferSize = 0;
1421 else
1422 {
1423 WLog_Print(urbdrc->log, WLOG_DEBUG,
1424 "PORT STATUS:0x%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "", Buffer[3],
1425 Buffer[2], Buffer[1], Buffer[0]);
1426 success = 1;
1427 }
1428 }
1429
1430 return success;
1431}
1432
1433WINPR_ATTR_NODISCARD
1434static int libusb_udev_reset_device(IUDEVICE* idev)
1435{
1436 UDEVICE* pdev = (UDEVICE*)idev;
1437
1438 if (!pdev || !pdev->urbdrc)
1439 return -1;
1440
1441 URBDRC_PLUGIN* urbdrc = pdev->urbdrc;
1442 const int ret = libusb_reset_device(pdev->libusb_handle);
1443 log_libusb_result(urbdrc->log, WLOG_DEBUG, "libusb_reset_device", ret);
1444 return ret;
1445}
1446
1447WINPR_ATTR_NODISCARD
1448static int libusb_udev_isoch_transfer(IUDEVICE* idev, GENERIC_CHANNEL_CALLBACK* callback,
1449 UINT32 MessageId, UINT32 RequestId, UINT32 EndpointAddress,
1450 WINPR_ATTR_UNUSED UINT32 TransferFlags, UINT32 StartFrame,
1451 UINT32 ErrorCount, BOOL NoAck,
1452 WINPR_ATTR_UNUSED const BYTE* packetDescriptorData,
1453 UINT32 NumberOfPackets, UINT32 BufferSize, const BYTE* Buffer,
1454 int transferDir, t_isoch_transfer_cb cb, UINT32 Timeout)
1455{
1456 int rc = 0;
1457 UINT32 iso_packet_size = 0;
1458 UDEVICE* pdev = (UDEVICE*)idev;
1459 struct libusb_transfer* iso_transfer = nullptr;
1460 size_t outSize = (12ULL * NumberOfPackets);
1461 uint32_t streamID = 0x40000000 | RequestId;
1462
1463 if (!pdev || !pdev->urbdrc)
1464 return -1;
1465
1466 URBDRC_PLUGIN* urbdrc = pdev->urbdrc;
1467
1468 if ((NumberOfPackets > INT32_MAX) || (BufferSize > INT32_MAX))
1469 {
1470 WLog_Print(urbdrc->log, WLOG_ERROR,
1471 "[NumberOfPackets=%" PRIu32 ", BufferSize=%" PRIu32
1472 " ] out of bounds, maximum allowed is %d",
1473 NumberOfPackets, BufferSize, INT32_MAX);
1474 return -1;
1475 }
1476
1477 ASYNC_TRANSFER_USER_DATA* user_data = async_transfer_user_data_new(
1478 idev, MessageId, 48, BufferSize, Buffer, outSize + 1024, NoAck, transferDir, cb, callback);
1479
1480 if (!user_data)
1481 return -1;
1482
1483 user_data->ErrorCount = ErrorCount;
1484 user_data->StartFrame = StartFrame;
1485
1486 if (!Buffer)
1487 Stream_Seek(user_data->data, (12ULL * NumberOfPackets));
1488
1489 if (NumberOfPackets > 0)
1490 {
1491 iso_packet_size = BufferSize / NumberOfPackets;
1492 iso_transfer = libusb_alloc_transfer((int)NumberOfPackets);
1493 }
1494
1495 if (iso_transfer == nullptr)
1496 {
1497 WLog_Print(urbdrc->log, WLOG_ERROR,
1498 "Error: libusb_alloc_transfer [NumberOfPackets=%" PRIu32 ", BufferSize=%" PRIu32
1499 " ]",
1500 NumberOfPackets, BufferSize);
1501 async_transfer_user_data_free(user_data);
1502 return -1;
1503 }
1504
1506 libusb_fill_iso_transfer(
1507 iso_transfer, pdev->libusb_handle, WINPR_ASSERTING_INT_CAST(uint8_t, EndpointAddress),
1508 Stream_Pointer(user_data->data), WINPR_ASSERTING_INT_CAST(int, BufferSize),
1509 WINPR_ASSERTING_INT_CAST(int, NumberOfPackets), func_iso_callback, user_data, Timeout);
1510 set_stream_id_for_buffer(iso_transfer, streamID);
1511 libusb_set_iso_packet_lengths(iso_transfer, iso_packet_size);
1512
1513 if (!ArrayList_Append(pdev->request_queue, iso_transfer))
1514 {
1515 WLog_Print(urbdrc->log, WLOG_WARN,
1516 "Failed to queue iso transfer, streamID %08" PRIx32 " already in use!",
1517 streamID);
1518 request_free(iso_transfer);
1519 return -1;
1520 }
1521 rc = libusb_submit_transfer(iso_transfer);
1522 if (log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_submit_transfer", rc))
1523 {
1524 /* Never submitted, so no completion callback will remove it from the queue */
1525 ArrayList_Remove(pdev->request_queue, iso_transfer);
1526 return -1;
1527 }
1528 return rc;
1529}
1530
1531WINPR_ATTR_NODISCARD
1532static BOOL libusb_udev_control_transfer(IUDEVICE* idev, WINPR_ATTR_UNUSED UINT32 RequestId,
1533 WINPR_ATTR_UNUSED UINT32 EndpointAddress,
1534 WINPR_ATTR_UNUSED UINT32 TransferFlags, BYTE bmRequestType,
1535 BYTE Request, UINT16 Value, UINT16 Index,
1536 UINT32* UrbdStatus, UINT32* BufferSize, BYTE* Buffer,
1537 UINT32 Timeout)
1538{
1539 int status = 0;
1540 UDEVICE* pdev = (UDEVICE*)idev;
1541
1542 WINPR_ASSERT(BufferSize);
1543
1544 if (!pdev || !pdev->urbdrc)
1545 return FALSE;
1546
1547 if (*BufferSize > UINT16_MAX)
1548 {
1549 WLog_Print(pdev->urbdrc->log, WLOG_ERROR, "BufferSize %" PRIu32 " > %d", *BufferSize,
1550 UINT16_MAX);
1551 return FALSE;
1552 }
1553
1554 status =
1555 libusb_control_transfer(pdev->libusb_handle, bmRequestType, Request, Value, Index, Buffer,
1556 WINPR_ASSERTING_INT_CAST(UINT16, *BufferSize), Timeout);
1557
1558 if (status >= 0)
1559 *BufferSize = (UINT32)status;
1560 else
1561 {
1562 *BufferSize = 0;
1563 log_libusb_result(pdev->urbdrc->log, WLOG_ERROR, "libusb_control_transfer", status);
1564 }
1565
1566 if (!func_set_usbd_status(pdev->urbdrc, pdev, UrbdStatus, status))
1567 return FALSE;
1568
1569 return TRUE;
1570}
1571
1572WINPR_ATTR_NODISCARD
1573static int libusb_udev_bulk_or_interrupt_transfer(
1574 IUDEVICE* idev, GENERIC_CHANNEL_CALLBACK* callback, UINT32 MessageId, UINT32 RequestId,
1575 UINT32 EndpointAddress, UINT32 TransferFlags, BOOL NoAck, UINT32 BufferSize, const BYTE* data,
1576 int transferDir, t_isoch_transfer_cb cb, UINT32 Timeout)
1577{
1578 int rc = 0;
1579 UINT32 transfer_type = 0;
1580 UDEVICE* pdev = (UDEVICE*)idev;
1581 const LIBUSB_ENDPOINT_DESCEIPTOR* ep_desc = nullptr;
1582 struct libusb_transfer* transfer = nullptr;
1583 ASYNC_TRANSFER_USER_DATA* user_data = nullptr;
1584 uint32_t streamID = 0x80000000 | RequestId;
1585
1586 if (!pdev || !pdev->LibusbConfig || !pdev->urbdrc)
1587 return -1;
1588
1589 if (BufferSize > INT32_MAX)
1590 return -1;
1591
1592 URBDRC_PLUGIN* urbdrc = pdev->urbdrc;
1593 user_data = async_transfer_user_data_new(idev, MessageId, 36, BufferSize, data, 0, NoAck,
1594 transferDir, cb, callback);
1595
1596 if (!user_data)
1597 return -1;
1598
1599 /* alloc memory for urb transfer */
1600 transfer = libusb_alloc_transfer(0);
1601 if (!transfer)
1602 {
1603 async_transfer_user_data_free(user_data);
1604 return -1;
1605 }
1606 transfer->user_data = user_data;
1607
1608 ep_desc = func_get_ep_desc(pdev->LibusbConfig, pdev->MsConfig, EndpointAddress);
1609
1610 if (!ep_desc)
1611 {
1612 WLog_Print(urbdrc->log, WLOG_ERROR, "func_get_ep_desc: endpoint 0x%" PRIx32 " not found",
1613 EndpointAddress);
1614 request_free(transfer);
1615 return -1;
1616 }
1617
1618 transfer_type = (ep_desc->bmAttributes) & 0x3;
1619 WLog_Print(urbdrc->log, WLOG_DEBUG,
1620 "urb_bulk_or_interrupt_transfer: ep:0x%" PRIx32 " "
1621 "transfer_type %" PRIu32 " flag:%" PRIu32 " OutputBufferSize:0x%" PRIx32 "",
1622 EndpointAddress, transfer_type, TransferFlags, BufferSize);
1623
1624 switch (transfer_type)
1625 {
1626 case BULK_TRANSFER:
1628 libusb_fill_bulk_transfer(
1629 transfer, pdev->libusb_handle, WINPR_ASSERTING_INT_CAST(uint8_t, EndpointAddress),
1630 Stream_Pointer(user_data->data), WINPR_ASSERTING_INT_CAST(int, BufferSize),
1631 func_bulk_transfer_cb, user_data, Timeout);
1632 break;
1633
1634 case INTERRUPT_TRANSFER:
1636 libusb_fill_interrupt_transfer(
1637 transfer, pdev->libusb_handle, WINPR_ASSERTING_INT_CAST(uint8_t, EndpointAddress),
1638 Stream_Pointer(user_data->data), WINPR_ASSERTING_INT_CAST(int, BufferSize),
1639 func_bulk_transfer_cb, user_data, Timeout);
1640 break;
1641
1642 default:
1643 WLog_Print(urbdrc->log, WLOG_DEBUG,
1644 "urb_bulk_or_interrupt_transfer:"
1645 " other transfer type 0x%" PRIX32 "",
1646 transfer_type);
1647 request_free(transfer);
1648 return -1;
1649 }
1650
1651 set_stream_id_for_buffer(transfer, streamID);
1652
1653 if (!ArrayList_Append(pdev->request_queue, transfer))
1654 {
1655 WLog_Print(urbdrc->log, WLOG_WARN,
1656 "Failed to queue transfer, streamID %08" PRIx32 " already in use!", streamID);
1657 request_free(transfer);
1658 return -1;
1659 }
1660 rc = libusb_submit_transfer(transfer);
1661 if (log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_submit_transfer", rc))
1662 {
1663 /* Never submitted, so no completion callback will remove it from the queue */
1664 ArrayList_Remove(pdev->request_queue, transfer);
1665 return -1;
1666 }
1667 return rc;
1668}
1669
1670static int func_cancel_xact_request(URBDRC_PLUGIN* urbdrc, struct libusb_transfer* transfer)
1671{
1672 int status = 0;
1673
1674 if (!urbdrc || !transfer)
1675 return -1;
1676
1677 status = libusb_cancel_transfer(transfer);
1678
1679 if (log_libusb_result(urbdrc->log, WLOG_WARN, "libusb_cancel_transfer", status))
1680 {
1681 if (status == LIBUSB_ERROR_NOT_FOUND)
1682 return -1;
1683 }
1684 else
1685 return 1;
1686
1687 return 0;
1688}
1689
1690static void libusb_udev_cancel_all_transfer_request(IUDEVICE* idev)
1691{
1692 UDEVICE* pdev = (UDEVICE*)idev;
1693 size_t count = 0;
1694
1695 if (!pdev || !pdev->request_queue || !pdev->urbdrc)
1696 return;
1697
1698 ArrayList_Lock(pdev->request_queue);
1699 count = ArrayList_Count(pdev->request_queue);
1700
1701 for (size_t x = 0; x < count; x++)
1702 {
1703 struct libusb_transfer* transfer = ArrayList_GetItem(pdev->request_queue, x);
1704 func_cancel_xact_request(pdev->urbdrc, transfer);
1705 }
1706
1707 ArrayList_Unlock(pdev->request_queue);
1708}
1709
1710WINPR_ATTR_NODISCARD
1711static int libusb_udev_cancel_transfer_request(IUDEVICE* idev, UINT32 RequestId)
1712{
1713 int rc = -1;
1714 UDEVICE* pdev = (UDEVICE*)idev;
1715 struct libusb_transfer* transfer = nullptr;
1716 uint32_t cancelID1 = 0x40000000 | RequestId;
1717 uint32_t cancelID2 = 0x80000000 | RequestId;
1718
1719 if (!idev || !pdev->urbdrc || !pdev->request_queue)
1720 return -1;
1721
1722 ArrayList_Lock(pdev->request_queue);
1723 transfer = list_contains(pdev->request_queue, cancelID1);
1724 if (!transfer)
1725 transfer = list_contains(pdev->request_queue, cancelID2);
1726
1727 if (transfer)
1728 {
1729 URBDRC_PLUGIN* urbdrc = pdev->urbdrc;
1730
1731 rc = func_cancel_xact_request(urbdrc, transfer);
1732 }
1733 ArrayList_Unlock(pdev->request_queue);
1734 return rc;
1735}
1736
1737BASIC_STATE_FUNC_DEFINED(channelManager, IWTSVirtualChannelManager*)
1738BASIC_STATE_FUNC_DEFINED(channelID, UINT32)
1739BASIC_STATE_FUNC_DEFINED(channelCallback, GENERIC_CHANNEL_CALLBACK*)
1740BASIC_STATE_FUNC_DEFINED(ReqCompletion, UINT32)
1741BASIC_STATE_FUNC_DEFINED(bus_number, BYTE)
1742BASIC_STATE_FUNC_DEFINED(dev_number, BYTE)
1743BASIC_STATE_FUNC_DEFINED(port_number, UINT8)
1744BASIC_STATE_FUNC_DEFINED(MsConfig, MSUSB_CONFIG_DESCRIPTOR*)
1745
1746BASIC_POINT_FUNC_DEFINED(udev, void*)
1747BASIC_POINT_FUNC_DEFINED(prev, void*)
1748BASIC_POINT_FUNC_DEFINED(next, void*)
1749
1750WINPR_ATTR_NODISCARD
1751static UINT32 udev_get_UsbDevice(IUDEVICE* idev)
1752{
1753 UDEVICE* pdev = (UDEVICE*)idev;
1754
1755 if (!pdev)
1756 return 0;
1757
1758 return pdev->UsbDevice;
1759}
1760
1761static void udev_set_UsbDevice(IUDEVICE* idev, UINT32 val)
1762{
1763 UDEVICE* pdev = (UDEVICE*)idev;
1764
1765 if (!pdev)
1766 return;
1767
1768 pdev->UsbDevice = val;
1769}
1770
1771static void udev_free(IUDEVICE* idev)
1772{
1773 int rc = 0;
1774 UDEVICE* udev = (UDEVICE*)idev;
1775 URBDRC_PLUGIN* urbdrc = nullptr;
1776
1777 if (!idev || !udev->urbdrc)
1778 return;
1779
1780 urbdrc = udev->urbdrc;
1781
1782 libusb_udev_cancel_all_transfer_request(&udev->iface);
1783 if (udev->libusb_handle)
1784 {
1785 rc = libusb_reset_device(udev->libusb_handle);
1786
1787 log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_reset_device", rc);
1788 }
1789
1790 while (ArrayList_Count(udev->request_queue) > 0)
1791 {
1792 /* HACK: We need to wait until the cancel transfer has been processed by
1793 * poll_libusb_events
1794 */
1795 Sleep(100);
1796 }
1797
1798 /* release all interface and attach kernel driver */
1799 if (!udev->iface.attach_kernel_driver(idev))
1800 WLog_Print(udev->urbdrc->log, WLOG_WARN, "attach_kernel_driver failed for device");
1801 libusb_unref_device(udev->libusb_dev);
1802 libusb_close(udev->libusb_handle);
1803 libusb_close(udev->hub_handle);
1804
1805 ArrayList_Free(udev->request_queue);
1806 /* free the config descriptor that send from windows */
1807 msusb_msconfig_free(udev->MsConfig);
1808 free(udev->devDescriptor);
1809 free(idev);
1810}
1811
1812static void udev_load_interface(UDEVICE* pdev)
1813{
1814 WINPR_ASSERT(pdev);
1815
1816 /* load interface */
1817 /* Basic */
1818 BASIC_STATE_FUNC_REGISTER(channelManager, pdev);
1819 BASIC_STATE_FUNC_REGISTER(channelID, pdev);
1820 BASIC_STATE_FUNC_REGISTER(channelCallback, pdev);
1821 BASIC_STATE_FUNC_REGISTER(UsbDevice, pdev);
1822 BASIC_STATE_FUNC_REGISTER(ReqCompletion, pdev);
1823 BASIC_STATE_FUNC_REGISTER(bus_number, pdev);
1824 BASIC_STATE_FUNC_REGISTER(dev_number, pdev);
1825 BASIC_STATE_FUNC_REGISTER(port_number, pdev);
1826 BASIC_STATE_FUNC_REGISTER(MsConfig, pdev);
1827 BASIC_STATE_FUNC_REGISTER(p_udev, pdev);
1828 BASIC_STATE_FUNC_REGISTER(p_prev, pdev);
1829 BASIC_STATE_FUNC_REGISTER(p_next, pdev);
1830 pdev->iface.isCompositeDevice = libusb_udev_is_composite_device;
1831 pdev->iface.isExist = libusb_udev_is_exist;
1832 pdev->iface.isAlreadySend = libusb_udev_is_already_send;
1833 pdev->iface.isChannelClosed = libusb_udev_is_channel_closed;
1834 pdev->iface.setAlreadySend = libusb_udev_set_already_send;
1835 pdev->iface.setChannelClosed = libusb_udev_channel_closed;
1836 pdev->iface.markChannelClosed = libusb_udev_mark_channel_closed;
1837 pdev->iface.getPath = libusb_udev_get_path;
1838 /* Transfer */
1839 pdev->iface.isoch_transfer = libusb_udev_isoch_transfer;
1840 pdev->iface.control_transfer = libusb_udev_control_transfer;
1841 pdev->iface.bulk_or_interrupt_transfer = libusb_udev_bulk_or_interrupt_transfer;
1842 pdev->iface.select_interface = libusb_udev_select_interface;
1843 pdev->iface.select_configuration = libusb_udev_select_configuration;
1844 pdev->iface.complete_msconfig_setup = libusb_udev_complete_msconfig_setup;
1845 pdev->iface.control_pipe_request = libusb_udev_control_pipe_request;
1846 pdev->iface.control_query_device_text = libusb_udev_control_query_device_text;
1847 pdev->iface.os_feature_descriptor_request = libusb_udev_os_feature_descriptor_request;
1848 pdev->iface.cancel_all_transfer_request = libusb_udev_cancel_all_transfer_request;
1849 pdev->iface.cancel_transfer_request = libusb_udev_cancel_transfer_request;
1850 pdev->iface.query_device_descriptor = libusb_udev_query_device_descriptor;
1851 pdev->iface.query_device_speed = libusb_udev_query_device_speed;
1852 pdev->iface.detach_kernel_driver = libusb_udev_detach_kernel_driver;
1853 pdev->iface.attach_kernel_driver = libusb_udev_attach_kernel_driver;
1854 pdev->iface.query_device_port_status = libusb_udev_query_device_port_status;
1855 pdev->iface.reset_device = libusb_udev_reset_device;
1856 pdev->iface.free = udev_free;
1857}
1858
1859WINPR_ATTR_NODISCARD
1860static int udev_get_device_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVICE* pdev,
1861 UINT16 bus_number, UINT16 dev_number)
1862{
1863 int error = -1;
1864 uint8_t port_numbers[16] = WINPR_C_ARRAY_INIT;
1865 LIBUSB_DEVICE** libusb_list = nullptr;
1866 const ssize_t total_device = libusb_get_device_list(ctx, &libusb_list);
1867
1868 WINPR_ASSERT(urbdrc);
1869
1870 /* Look for device. */
1871 for (ssize_t i = 0; i < total_device; i++)
1872 {
1873 LIBUSB_DEVICE* dev = libusb_list[i];
1874
1875 if ((bus_number != libusb_get_bus_number(dev)) ||
1876 (dev_number != libusb_get_device_address(dev)))
1877 libusb_unref_device(dev);
1878 else
1879 {
1880 error = libusb_open(dev, &pdev->libusb_handle);
1881
1882 if (log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_open", error))
1883 {
1884 libusb_unref_device(dev);
1885 continue;
1886 }
1887
1888 /* also detach a late-bound kernel driver when an interface is claimed */
1889 (void)libusb_set_auto_detach_kernel_driver(pdev->libusb_handle, 1);
1890
1891 /* get port number */
1892 error = libusb_get_port_numbers(dev, port_numbers, sizeof(port_numbers));
1893 if (error < 1)
1894 {
1895 /* Prevent open hub, treat as error. */
1896 log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_get_port_numbers", error);
1897 libusb_unref_device(dev);
1898 continue;
1899 }
1900
1901 pdev->port_number = port_numbers[(error - 1)];
1902 error = 0;
1903 WLog_Print(urbdrc->log, WLOG_DEBUG, " Port: %" PRIu8, pdev->port_number);
1904 /* gen device path */
1905 (void)_snprintf(pdev->path, sizeof(pdev->path), "%" PRIu16 "-%d", bus_number,
1906 pdev->port_number);
1907
1908 WLog_Print(urbdrc->log, WLOG_DEBUG, " DevPath: %s", pdev->path);
1909 }
1910 }
1911 libusb_free_device_list(libusb_list, 0);
1912
1913 if (error < 0)
1914 return -1;
1915 return 0;
1916}
1917
1918WINPR_ATTR_NODISCARD
1919static int udev_get_hub_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVICE* pdev,
1920 UINT16 bus_number, WINPR_ATTR_UNUSED UINT16 dev_number)
1921{
1922 int error = -1;
1923 LIBUSB_DEVICE** libusb_list = nullptr;
1924 LIBUSB_DEVICE_HANDLE* handle = nullptr;
1925 const ssize_t total_device = libusb_get_device_list(ctx, &libusb_list);
1926
1927 WINPR_ASSERT(urbdrc);
1928
1929 /* Look for device hub. */
1930 for (ssize_t i = 0; i < total_device; i++)
1931 {
1932 LIBUSB_DEVICE* dev = libusb_list[i];
1933
1934 if ((bus_number != libusb_get_bus_number(dev)) ||
1935 (1 != libusb_get_device_address(dev))) /* Root hub always first on bus. */
1936 libusb_unref_device(dev);
1937 else
1938 {
1939 WLog_Print(urbdrc->log, WLOG_DEBUG, " Open hub: %" PRIu16 "", bus_number);
1940 error = libusb_open(dev, &handle);
1941
1942 if (!log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_open", error))
1943 pdev->hub_handle = handle;
1944 else
1945 libusb_unref_device(dev);
1946 }
1947 }
1948
1949 libusb_free_device_list(libusb_list, 0);
1950
1951 if (error < 0)
1952 return -1;
1953
1954 return 0;
1955}
1956
1957static void request_free(void* value)
1958{
1959 ASYNC_TRANSFER_USER_DATA* user_data = nullptr;
1960 struct libusb_transfer* transfer = (struct libusb_transfer*)value;
1961 if (!transfer)
1962 return;
1963
1964 user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
1965 async_transfer_user_data_free(user_data);
1966 transfer->user_data = nullptr;
1967 libusb_free_transfer(transfer);
1968}
1969
1970WINPR_ATTR_NODISCARD
1971static IUDEVICE* udev_init(URBDRC_PLUGIN* urbdrc, libusb_context* context, LIBUSB_DEVICE* device,
1972 BYTE bus_number, BYTE dev_number)
1973{
1974 UDEVICE* pdev = nullptr;
1975 int status = LIBUSB_ERROR_OTHER;
1976 LIBUSB_DEVICE_DESCRIPTOR* devDescriptor = nullptr;
1977 LIBUSB_CONFIG_DESCRIPTOR* config_temp = nullptr;
1978 LIBUSB_INTERFACE_DESCRIPTOR interface_temp;
1979
1980 WINPR_ASSERT(urbdrc);
1981
1982 pdev = (PUDEVICE)calloc(1, sizeof(UDEVICE));
1983
1984 if (!pdev)
1985 return nullptr;
1986
1987 pdev->urbdrc = urbdrc;
1988 udev_load_interface(pdev);
1989
1990 if (device)
1991 pdev->libusb_dev = device;
1992 else
1993 pdev->libusb_dev = udev_get_libusb_dev(context, bus_number, dev_number);
1994
1995 if (pdev->libusb_dev == nullptr)
1996 goto fail;
1997
1998 if (urbdrc->listener_callback)
1999 udev_set_channelManager(&pdev->iface, urbdrc->listener_callback->channel_mgr);
2000
2001 /* Get DEVICE handle */
2002 status = udev_get_device_handle(urbdrc, context, pdev, bus_number, dev_number);
2003 if (status != LIBUSB_SUCCESS)
2004 {
2005 struct libusb_device_descriptor desc;
2006 const uint8_t port = libusb_get_port_number(pdev->libusb_dev);
2007 libusb_get_device_descriptor(pdev->libusb_dev, &desc);
2008
2009 log_libusb_result(urbdrc->log, WLOG_ERROR,
2010 "libusb_open [b=0x%02X,p=0x%02X,a=0x%02X,VID=0x%04X,PID=0x%04X]", status,
2011 bus_number, port, dev_number, desc.idVendor, desc.idProduct);
2012 goto fail;
2013 }
2014
2015 /* Get HUB handle */
2016 status = udev_get_hub_handle(urbdrc, context, pdev, bus_number, dev_number);
2017
2018 if (status < 0)
2019 pdev->hub_handle = nullptr;
2020
2021 pdev->devDescriptor = udev_new_descript(urbdrc, pdev->libusb_dev);
2022
2023 if (!pdev->devDescriptor)
2024 goto fail;
2025
2026 status = libusb_get_active_config_descriptor(pdev->libusb_dev, &pdev->LibusbConfig);
2027
2028 if (status == LIBUSB_ERROR_NOT_FOUND)
2029 status = libusb_get_config_descriptor(pdev->libusb_dev, 0, &pdev->LibusbConfig);
2030
2031 if (status < 0)
2032 {
2033 log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_get_config_descriptor", status);
2034 goto fail;
2035 }
2036
2037 config_temp = pdev->LibusbConfig;
2038 /* get the first interface and first altsetting */
2039 interface_temp = config_temp->interface[0].altsetting[0];
2040 WLog_Print(urbdrc->log, WLOG_DEBUG,
2041 "Registered Device: Vid: 0x%04" PRIX16 " Pid: 0x%04" PRIX16 ""
2042 " InterfaceClass = %s",
2043 pdev->devDescriptor->idVendor, pdev->devDescriptor->idProduct,
2044 usb_interface_class_to_string(interface_temp.bInterfaceClass));
2045 /* Check composite device */
2046 devDescriptor = pdev->devDescriptor;
2047
2048 if ((devDescriptor->bNumConfigurations == 1) && (config_temp->bNumInterfaces > 1) &&
2049 (devDescriptor->bDeviceClass == LIBUSB_CLASS_PER_INTERFACE))
2050 {
2051 pdev->isCompositeDevice = 1;
2052 }
2053 else if ((devDescriptor->bDeviceClass == 0xef) &&
2054 (devDescriptor->bDeviceSubClass == LIBUSB_CLASS_COMM) &&
2055 (devDescriptor->bDeviceProtocol == 0x01))
2056 {
2057 pdev->isCompositeDevice = 1;
2058 }
2059 else
2060 pdev->isCompositeDevice = 0;
2061
2062 /* set device class to first interface class */
2063 devDescriptor->bDeviceClass = interface_temp.bInterfaceClass;
2064 devDescriptor->bDeviceSubClass = interface_temp.bInterfaceSubClass;
2065 devDescriptor->bDeviceProtocol = interface_temp.bInterfaceProtocol;
2066 /* initialize pdev */
2067 pdev->bus_number = bus_number;
2068 pdev->dev_number = dev_number;
2069 pdev->request_queue = ArrayList_New(TRUE);
2070
2071 if (!pdev->request_queue)
2072 goto fail;
2073
2074 ArrayList_Object(pdev->request_queue)->fnObjectFree = request_free;
2075
2076 /* set config of windows */
2077 pdev->MsConfig = msusb_msconfig_new();
2078
2079 if (!pdev->MsConfig)
2080 goto fail;
2081
2082 // deb_config_msg(pdev->libusb_dev, config_temp, devDescriptor->bNumConfigurations);
2083 return &pdev->iface;
2084fail:
2085 pdev->iface.free(&pdev->iface);
2086 return nullptr;
2087}
2088
2089size_t udev_new_by_id(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UINT16 idVendor, UINT16 idProduct,
2090 IUDEVICE*** devArray)
2091{
2092 WINPR_ASSERT(urbdrc);
2093 WINPR_ASSERT(devArray);
2094
2095 size_t num = 0;
2096 LIBUSB_DEVICE** libusb_list = nullptr;
2097
2098 *devArray = nullptr;
2099
2100 WLog_Print(urbdrc->log, WLOG_INFO, "VID: 0x%04" PRIX16 ", PID: 0x%04" PRIX16 "", idVendor,
2101 idProduct);
2102 const ssize_t total_device = libusb_get_device_list(ctx, &libusb_list);
2103 if (total_device < 0)
2104 {
2105 WLog_Print(urbdrc->log, WLOG_ERROR, "libusb_get_device_list -> [%" PRIdz "]", total_device);
2106 return 0;
2107 }
2108 if (total_device == 0)
2109 {
2110 WLog_Print(urbdrc->log, WLOG_WARN, "libusb_get_device_list -> [%" PRIdz "]", total_device);
2111 return 0;
2112 }
2113
2114 UDEVICE** array = (UDEVICE**)calloc((size_t)total_device, sizeof(UDEVICE*));
2115
2116 if (!array)
2117 goto fail;
2118
2119 for (ssize_t i = 0; i < total_device; i++)
2120 {
2121 LIBUSB_DEVICE* dev = libusb_list[i];
2122 LIBUSB_DEVICE_DESCRIPTOR* descriptor = udev_new_descript(urbdrc, dev);
2123
2124 if ((descriptor->idVendor == idVendor) && (descriptor->idProduct == idProduct))
2125 {
2126 const uint8_t nr = libusb_get_bus_number(dev);
2127 const uint8_t addr = libusb_get_device_address(dev);
2128 array[num] = (PUDEVICE)udev_init(urbdrc, ctx, dev, nr, addr);
2129
2130 if (array[num] != nullptr)
2131 num++;
2132 else
2133 {
2134 WLog_Print(urbdrc->log, WLOG_WARN,
2135 "udev_init(nr=%" PRIu8 ", addr=%" PRIu8 ") failed", nr, addr);
2136 }
2137 }
2138 else
2139 libusb_unref_device(dev);
2140
2141 free(descriptor);
2142 }
2143
2144fail:
2145 libusb_free_device_list(libusb_list, 0);
2146 *devArray = (IUDEVICE**)array;
2147 return num;
2148}
2149
2150IUDEVICE* udev_new_by_addr(URBDRC_PLUGIN* urbdrc, libusb_context* context, BYTE bus_number,
2151 BYTE dev_number)
2152{
2153 WLog_Print(urbdrc->log, WLOG_DEBUG, "bus:%d dev:%d", bus_number, dev_number);
2154 return udev_init(urbdrc, context, nullptr, bus_number, dev_number);
2155}
OBJECT_FREE_FN fnObjectFree
Definition collections.h:59