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