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