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