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