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