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