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>
33#include "libusb_udevice.h"
35#include "../common/urbdrc_types.h"
37#define BASIC_STATE_FUNC_DEFINED(_arg, _type) \
38 static _type udev_get_##_arg(IUDEVICE* idev) \
40 UDEVICE* pdev = (UDEVICE*)idev; \
43 static void udev_set_##_arg(IUDEVICE* idev, _type _t) \
45 UDEVICE* pdev = (UDEVICE*)idev; \
49#define BASIC_POINT_FUNC_DEFINED(_arg, _type) \
50 static _type udev_get_p_##_arg(IUDEVICE* idev) \
52 UDEVICE* pdev = (UDEVICE*)idev; \
55 static void udev_set_p_##_arg(IUDEVICE* idev, _type _t) \
57 UDEVICE* pdev = (UDEVICE*)idev; \
61#define BASIC_STATE_FUNC_REGISTER(_arg, _dev) \
62 _dev->iface.get_##_arg = udev_get_##_arg; \
63 (_dev)->iface.set_##_arg = udev_set_##_arg
65#if LIBUSB_API_VERSION >= 0x01000103
66#define HAVE_STREAM_ID_API 1
77 UINT32 OutputBufferSize;
81 t_isoch_transfer_cb cb;
83#if !defined(HAVE_STREAM_ID_API)
86} ASYNC_TRANSFER_USER_DATA;
88static void request_free(
void* value);
90static struct libusb_transfer* list_contains(wArrayList* list, UINT32 streamID)
95 count = ArrayList_Count(list);
96 for (
size_t x = 0; x < count; x++)
98 struct libusb_transfer* transfer = ArrayList_GetItem(list, x);
100#if defined(HAVE_STREAM_ID_API)
101 const UINT32 currentID = libusb_transfer_get_stream_id(transfer);
103 const ASYNC_TRANSFER_USER_DATA* user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
104 const UINT32 currentID = user_data->streamID;
106 if (currentID == streamID)
112static UINT32 stream_id_from_buffer(
struct libusb_transfer* transfer)
116#if defined(HAVE_STREAM_ID_API)
117 return libusb_transfer_get_stream_id(transfer);
119 ASYNC_TRANSFER_USER_DATA* user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
122 return user_data->streamID;
126static void set_stream_id_for_buffer(
struct libusb_transfer* transfer, UINT32 streamID)
128#if defined(HAVE_STREAM_ID_API)
129 libusb_transfer_set_stream_id(transfer, streamID);
131 ASYNC_TRANSFER_USER_DATA* user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
134 user_data->streamID = streamID;
138WINPR_ATTR_FORMAT_ARG(3, 8)
139static BOOL log_libusb_result_(wLog* log, DWORD lvl, WINPR_FORMAT_ARG const
char* fmt,
140 const
char* fkt, const
char* file,
size_t line,
int error, ...)
146 char buffer[8192] = WINPR_C_ARRAY_INIT;
147 va_list ap = WINPR_C_ARRAY_INIT;
149 (void)vsnprintf(buffer,
sizeof(buffer), fmt, ap);
152 WLog_Print(log, lvl,
"[%s:%" PRIuz
"]: %s: error %s[%d]", fkt, line, buffer,
153 libusb_error_name(error), error);
159#define log_libusb_result(log, lvl, fmt, error, ...) \
160 log_libusb_result_((log), (lvl), (fmt), __func__, __FILE__, __LINE__, error, ##__VA_ARGS__)
162const char* usb_interface_class_to_string(uint8_t c_class)
166 case LIBUSB_CLASS_PER_INTERFACE:
167 return "LIBUSB_CLASS_PER_INTERFACE";
168 case LIBUSB_CLASS_AUDIO:
169 return "LIBUSB_CLASS_AUDIO";
170 case LIBUSB_CLASS_COMM:
171 return "LIBUSB_CLASS_COMM";
172 case LIBUSB_CLASS_HID:
173 return "LIBUSB_CLASS_HID";
174 case LIBUSB_CLASS_PHYSICAL:
175 return "LIBUSB_CLASS_PHYSICAL";
176 case LIBUSB_CLASS_PRINTER:
177 return "LIBUSB_CLASS_PRINTER";
178 case LIBUSB_CLASS_IMAGE:
179 return "LIBUSB_CLASS_IMAGE";
180 case LIBUSB_CLASS_MASS_STORAGE:
181 return "LIBUSB_CLASS_MASS_STORAGE";
182 case LIBUSB_CLASS_HUB:
183 return "LIBUSB_CLASS_HUB";
184 case LIBUSB_CLASS_DATA:
185 return "LIBUSB_CLASS_DATA";
186 case LIBUSB_CLASS_SMART_CARD:
187 return "LIBUSB_CLASS_SMART_CARD";
188 case LIBUSB_CLASS_CONTENT_SECURITY:
189 return "LIBUSB_CLASS_CONTENT_SECURITY";
190 case LIBUSB_CLASS_VIDEO:
191 return "LIBUSB_CLASS_VIDEO";
192 case LIBUSB_CLASS_PERSONAL_HEALTHCARE:
193 return "LIBUSB_CLASS_PERSONAL_HEALTHCARE";
194 case LIBUSB_CLASS_DIAGNOSTIC_DEVICE:
195 return "LIBUSB_CLASS_DIAGNOSTIC_DEVICE";
196 case LIBUSB_CLASS_WIRELESS:
197 return "LIBUSB_CLASS_WIRELESS";
198 case LIBUSB_CLASS_APPLICATION:
199 return "LIBUSB_CLASS_APPLICATION";
200 case LIBUSB_CLASS_VENDOR_SPEC:
201 return "LIBUSB_CLASS_VENDOR_SPEC";
203 return "UNKNOWN_DEVICE_CLASS";
207static ASYNC_TRANSFER_USER_DATA*
208async_transfer_user_data_new(IUDEVICE* idev, UINT32 MessageId,
size_t offset,
size_t BufferSize,
209 const BYTE* data,
size_t packetSize, BOOL NoAck,
int transferDir,
212 ASYNC_TRANSFER_USER_DATA* user_data =
nullptr;
215 if (BufferSize > UINT32_MAX)
218 user_data = calloc(1,
sizeof(ASYNC_TRANSFER_USER_DATA));
222 user_data->data = Stream_New(
nullptr, offset + BufferSize + packetSize);
224 if (!user_data->data)
230 Stream_Seek(user_data->data, offset);
232 memcpy(Stream_Pointer(user_data->data), data, BufferSize);
234 user_data->noack = NoAck;
235 user_data->transferDir = transferDir;
237 user_data->callback = callback;
238 user_data->idev = idev;
239 user_data->MessageId = MessageId;
241 user_data->queue = pdev->request_queue;
246static void async_transfer_user_data_free(ASYNC_TRANSFER_USER_DATA* user_data)
250 Stream_Free(user_data->data, TRUE);
255static void LIBUSB_CALL func_iso_callback(
struct libusb_transfer* transfer)
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;
261 ArrayList_Lock(list);
262 switch (transfer->status)
264 case LIBUSB_TRANSFER_COMPLETED:
267 BYTE* dataStart = Stream_Pointer(user_data->data);
268 if (!Stream_SetPosition(user_data->data,
272 for (uint32_t i = 0; i < WINPR_ASSERTING_INT_CAST(uint32_t, transfer->num_iso_packets);
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);
280 if (transfer->iso_packet_desc[i].status != USBD_STATUS_SUCCESS)
281 user_data->ErrorCount++;
284 const unsigned char* packetBuffer =
285 libusb_get_iso_packet_buffer_simple(transfer, i);
286 BYTE* data = dataStart + index;
288 if (data != packetBuffer)
289 memmove(data, packetBuffer, act_len);
294 user_data->OutputBufferSize = index;
298 case LIBUSB_TRANSFER_CANCELLED:
301 case LIBUSB_TRANSFER_TIMED_OUT:
304 case LIBUSB_TRANSFER_ERROR:
306 const UINT32 InterfaceId =
307 ((STREAM_ID_PROXY << 30) | user_data->idev->get_ReqCompletion(user_data->idev));
309 if (list_contains(list, streamID))
311 if (!user_data->noack)
313 const UINT32 RequestID = streamID & INTERFACE_ID_MASK;
314 user_data->cb(user_data->idev, user_data->callback, user_data->data,
315 InterfaceId, user_data->noack, user_data->MessageId, RequestID,
316 WINPR_ASSERTING_INT_CAST(uint32_t, transfer->num_iso_packets),
317 transfer->status, user_data->StartFrame, user_data->ErrorCount,
318 user_data->OutputBufferSize, user_data->transferDir);
319 user_data->data =
nullptr;
321 ArrayList_Remove(list, transfer);
328 ArrayList_Unlock(list);
331static const LIBUSB_ENDPOINT_DESCEIPTOR* func_get_ep_desc(LIBUSB_CONFIG_DESCRIPTOR* LibusbConfig,
333 UINT32 EndpointAddress)
336 const LIBUSB_INTERFACE*
interface = LibusbConfig->interface;
338 for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
340 if (inum >= LibusbConfig->bNumInterfaces)
343 const LIBUSB_INTERFACE* ifc = &interface[inum];
344 BYTE alt = MsInterfaces[inum]->AlternateSetting;
345 if (alt >= ifc->num_altsetting)
348 const struct libusb_interface_descriptor* altifc = &ifc->altsetting[alt];
349 const LIBUSB_ENDPOINT_DESCEIPTOR* endpoint = altifc->endpoint;
351 for (UINT32 pnum = 0; pnum < MsInterfaces[inum]->NumberOfPipes; pnum++)
353 if (pnum >= altifc->bNumEndpoints)
356 if (endpoint[pnum].bEndpointAddress == EndpointAddress)
358 return &endpoint[pnum];
366static void LIBUSB_CALL func_bulk_transfer_cb(
struct libusb_transfer* transfer)
368 ASYNC_TRANSFER_USER_DATA* user_data =
nullptr;
369 uint32_t streamID = 0;
370 wArrayList* list =
nullptr;
372 user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
375 WLog_ERR(TAG,
"Invalid transfer->user_data!");
378 list = user_data->queue;
379 ArrayList_Lock(list);
380 streamID = stream_id_from_buffer(transfer);
382 if (list_contains(list, streamID))
384 const UINT32 InterfaceId =
385 ((STREAM_ID_PROXY << 30) | user_data->idev->get_ReqCompletion(user_data->idev));
386 const UINT32 RequestID = streamID & INTERFACE_ID_MASK;
388 user_data->cb(user_data->idev, user_data->callback, user_data->data, InterfaceId,
389 user_data->noack, user_data->MessageId, RequestID,
390 WINPR_ASSERTING_INT_CAST(uint32_t, transfer->num_iso_packets),
391 transfer->status, user_data->StartFrame, user_data->ErrorCount,
392 WINPR_ASSERTING_INT_CAST(uint32_t, transfer->actual_length),
393 user_data->transferDir);
394 user_data->data =
nullptr;
395 ArrayList_Remove(list, transfer);
397 ArrayList_Unlock(list);
403 if (!urbdrc || !status)
409 *status = USBD_STATUS_SUCCESS;
412 case LIBUSB_ERROR_IO:
413 *status = USBD_STATUS_STALL_PID;
416 case LIBUSB_ERROR_INVALID_PARAM:
417 *status = USBD_STATUS_INVALID_PARAMETER;
420 case LIBUSB_ERROR_ACCESS:
421 *status = USBD_STATUS_NOT_ACCESSED;
424 case LIBUSB_ERROR_NO_DEVICE:
425 *status = USBD_STATUS_DEVICE_GONE;
429 if (!(pdev->status & URBDRC_DEVICE_NOT_FOUND))
430 pdev->status |= URBDRC_DEVICE_NOT_FOUND;
435 case LIBUSB_ERROR_NOT_FOUND:
436 *status = USBD_STATUS_STALL_PID;
439 case LIBUSB_ERROR_BUSY:
440 *status = USBD_STATUS_STALL_PID;
443 case LIBUSB_ERROR_TIMEOUT:
444 *status = USBD_STATUS_TIMEOUT;
447 case LIBUSB_ERROR_OVERFLOW:
448 *status = USBD_STATUS_STALL_PID;
451 case LIBUSB_ERROR_PIPE:
452 *status = USBD_STATUS_STALL_PID;
455 case LIBUSB_ERROR_INTERRUPTED:
456 *status = USBD_STATUS_STALL_PID;
459 case LIBUSB_ERROR_NO_MEM:
460 *status = USBD_STATUS_NO_MEMORY;
463 case LIBUSB_ERROR_NOT_SUPPORTED:
464 *status = USBD_STATUS_NOT_SUPPORTED;
467 case LIBUSB_ERROR_OTHER:
468 *status = USBD_STATUS_STALL_PID;
472 *status = USBD_STATUS_SUCCESS;
479static int func_config_release_all_interface(
URBDRC_PLUGIN* urbdrc,
480 LIBUSB_DEVICE_HANDLE* libusb_handle,
481 UINT32 NumInterfaces)
483 if (NumInterfaces > INT32_MAX)
485 for (INT32 i = 0; i < (INT32)NumInterfaces; i++)
487 int ret = libusb_release_interface(libusb_handle, i);
489 if (log_libusb_result(urbdrc->log, WLOG_WARN,
"libusb_release_interface", ret))
496static int func_claim_all_interface(
URBDRC_PLUGIN* urbdrc, LIBUSB_DEVICE_HANDLE* libusb_handle,
501 for (
int i = 0; i < NumInterfaces; i++)
503 ret = libusb_claim_interface(libusb_handle, i);
505 if (log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_claim_interface", ret))
512static LIBUSB_DEVICE* udev_get_libusb_dev(libusb_context* context, uint8_t bus_number,
515 LIBUSB_DEVICE** libusb_list =
nullptr;
516 LIBUSB_DEVICE* device =
nullptr;
517 const ssize_t total_device = libusb_get_device_list(context, &libusb_list);
519 for (ssize_t i = 0; i < total_device; i++)
521 LIBUSB_DEVICE* dev = libusb_list[i];
522 if ((bus_number == libusb_get_bus_number(dev)) &&
523 (dev_number == libusb_get_device_address(dev)))
526 libusb_unref_device(dev);
529 libusb_free_device_list(libusb_list, 0);
533static LIBUSB_DEVICE_DESCRIPTOR* udev_new_descript(
URBDRC_PLUGIN* urbdrc, LIBUSB_DEVICE* libusb_dev)
536 LIBUSB_DEVICE_DESCRIPTOR* descriptor =
537 (LIBUSB_DEVICE_DESCRIPTOR*)calloc(1,
sizeof(LIBUSB_DEVICE_DESCRIPTOR));
540 ret = libusb_get_device_descriptor(libusb_dev, descriptor);
542 if (log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_get_device_descriptor", ret))
551static int libusb_udev_select_interface(IUDEVICE* idev, BYTE InterfaceNumber, BYTE AlternateSetting)
555 if (!pdev || !pdev->urbdrc)
561 libusb_set_interface_alt_setting(pdev->libusb_handle, InterfaceNumber, AlternateSetting);
563 log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_set_interface_alt_setting", error);
572 UINT32 MsOutSize = 0;
574 if (!pdev || !pdev->LibusbConfig || !pdev->urbdrc || !MsConfig)
578 LIBUSB_CONFIG_DESCRIPTOR* LibusbConfig = pdev->LibusbConfig;
580 if (LibusbConfig->bNumInterfaces != MsConfig->NumInterfaces)
582 WLog_Print(urbdrc->log, WLOG_ERROR,
583 "Select Configuration: Libusb NumberInterfaces(%" PRIu8
") is different "
584 "with MsConfig NumberInterfaces(%" PRIu32
")",
585 LibusbConfig->bNumInterfaces, MsConfig->NumInterfaces);
592 for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
595 if (MsInterface->InterfaceNumber >= MsConfig->NumInterfaces)
597 WLog_Print(urbdrc->log, WLOG_ERROR,
598 "MSUSB_CONFIG_DESCRIPTOR::NumInterfaces (%" PRIu32
599 " <= MSUSB_INTERFACE_DESCRIPTOR::InterfaceNumber( %" PRIu8
")",
600 MsConfig->NumInterfaces, MsInterface->InterfaceNumber);
604 const LIBUSB_INTERFACE* LibusbInterface =
605 &LibusbConfig->interface[MsInterface->InterfaceNumber];
606 if (MsInterface->AlternateSetting >= LibusbInterface->num_altsetting)
608 WLog_Print(urbdrc->log, WLOG_ERROR,
609 "LIBUSB_INTERFACE::num_altsetting (%" PRId32
610 " <= MSUSB_INTERFACE_DESCRIPTOR::AlternateSetting( %" PRIu8
")",
611 LibusbInterface->num_altsetting, MsInterface->AlternateSetting);
616 for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
621 const LIBUSB_INTERFACE* LibusbInterface =
622 &LibusbConfig->interface[MsInterface->InterfaceNumber];
623 const LIBUSB_INTERFACE_DESCRIPTOR* LibusbAltsetting =
624 &LibusbInterface->altsetting[MsInterface->AlternateSetting];
625 const BYTE LibusbNumEndpoint = LibusbAltsetting->bNumEndpoints;
629 for (UINT32 pnum = 0; pnum < LibusbNumEndpoint; pnum++)
634 if (pnum < MsInterface->NumberOfPipes && MsInterface->MsPipes)
637 t_MsPipe->MaximumPacketSize = MsPipe->MaximumPacketSize;
638 t_MsPipe->MaximumTransferSize = MsPipe->MaximumTransferSize;
639 t_MsPipe->PipeFlags = MsPipe->PipeFlags;
643 t_MsPipe->MaximumPacketSize = 0;
644 t_MsPipe->MaximumTransferSize = 0xffffffff;
645 t_MsPipe->PipeFlags = 0;
648 t_MsPipe->PipeHandle = 0;
649 t_MsPipe->bEndpointAddress = 0;
650 t_MsPipe->bInterval = 0;
651 t_MsPipe->PipeType = 0;
652 t_MsPipe->InitCompleted = 0;
653 t_MsPipes[pnum] = t_MsPipe;
656 msusb_mspipes_replace(MsInterface, t_MsPipes, LibusbNumEndpoint);
667 MsConfig->ConfigurationHandle = (uint32_t)MsConfig->bConfigurationValue |
668 ((uint32_t)pdev->bus_number << 24) |
669 (((uint32_t)pdev->dev_number << 16) & 0xFF0000);
670 MsInterfaces = MsConfig->MsInterfaces;
672 for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
677 const LIBUSB_INTERFACE* LibusbInterface =
678 &LibusbConfig->interface[MsInterface->InterfaceNumber];
679 const LIBUSB_INTERFACE_DESCRIPTOR* LibusbAltsetting =
680 &LibusbInterface->altsetting[MsInterface->AlternateSetting];
687 MsInterface->InterfaceHandle =
688 WINPR_ASSERTING_INT_CAST(UINT32, (LibusbAltsetting->bInterfaceNumber |
689 (LibusbAltsetting->bAlternateSetting << 8) |
690 (pdev->dev_number << 16) | (pdev->bus_number << 24)));
691 const size_t len = 16 + (MsInterface->NumberOfPipes * 20);
692 MsInterface->Length = WINPR_ASSERTING_INT_CAST(UINT16, len);
693 MsInterface->bInterfaceClass = LibusbAltsetting->bInterfaceClass;
694 MsInterface->bInterfaceSubClass = LibusbAltsetting->bInterfaceSubClass;
695 MsInterface->bInterfaceProtocol = LibusbAltsetting->bInterfaceProtocol;
696 MsInterface->InitCompleted = 1;
698 const BYTE LibusbNumEndpoint = LibusbAltsetting->bNumEndpoints;
700 for (UINT32 pnum = 0; pnum < LibusbNumEndpoint; pnum++)
706 const LIBUSB_ENDPOINT_DESCEIPTOR* LibusbEndpoint = &LibusbAltsetting->endpoint[pnum];
713 MsPipe->PipeHandle = LibusbEndpoint->bEndpointAddress |
714 (((uint32_t)pdev->dev_number << 16) & 0xFF0000) |
715 (((uint32_t)pdev->bus_number << 24) & 0xFF000000);
717 unsigned max = LibusbEndpoint->wMaxPacketSize & 0x07ff;
718 BYTE attr = LibusbEndpoint->bmAttributes;
720 if ((attr & 0x3) == 1 || (attr & 0x3) == 3)
722 max *= (1 + ((LibusbEndpoint->wMaxPacketSize >> 11) & 3));
725 MsPipe->MaximumPacketSize = WINPR_ASSERTING_INT_CAST(uint16_t, max);
726 MsPipe->bEndpointAddress = LibusbEndpoint->bEndpointAddress;
727 MsPipe->bInterval = LibusbEndpoint->bInterval;
728 MsPipe->PipeType = attr & 0x3;
729 MsPipe->InitCompleted = 1;
733 MsConfig->MsOutSize = WINPR_ASSERTING_INT_CAST(
int, MsOutSize);
734 MsConfig->InitCompleted = 1;
737 if (MsConfig != pdev->MsConfig)
739 msusb_msconfig_free(pdev->MsConfig);
740 pdev->MsConfig = MsConfig;
746static int libusb_udev_select_configuration(IUDEVICE* idev, UINT32 bConfigurationValue)
750 LIBUSB_DEVICE_HANDLE* libusb_handle =
nullptr;
751 LIBUSB_DEVICE* libusb_dev =
nullptr;
753 LIBUSB_CONFIG_DESCRIPTOR** LibusbConfig =
nullptr;
756 if (!pdev || !pdev->MsConfig || !pdev->LibusbConfig || !pdev->urbdrc)
759 urbdrc = pdev->urbdrc;
760 MsConfig = pdev->MsConfig;
761 libusb_handle = pdev->libusb_handle;
762 libusb_dev = pdev->libusb_dev;
763 LibusbConfig = &pdev->LibusbConfig;
765 if (MsConfig->InitCompleted)
767 func_config_release_all_interface(pdev->urbdrc, libusb_handle,
768 (*LibusbConfig)->bNumInterfaces);
772 if (bConfigurationValue == 0)
773 ret = libusb_set_configuration(libusb_handle, -1);
775 ret = libusb_set_configuration(libusb_handle,
776 WINPR_ASSERTING_INT_CAST(
int, bConfigurationValue));
778 if (log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_set_configuration", ret))
780 func_claim_all_interface(urbdrc, libusb_handle, (*LibusbConfig)->bNumInterfaces);
785 ret = libusb_get_active_config_descriptor(libusb_dev, LibusbConfig);
787 if (log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_set_configuration", ret))
789 func_claim_all_interface(urbdrc, libusb_handle, (*LibusbConfig)->bNumInterfaces);
794 func_claim_all_interface(urbdrc, libusb_handle, (*LibusbConfig)->bNumInterfaces);
798static int libusb_udev_control_pipe_request(IUDEVICE* idev, WINPR_ATTR_UNUSED UINT32 RequestId,
799 UINT32 EndpointAddress, UINT32* UsbdStatus,
int command)
804 WINPR_ASSERT(EndpointAddress <= UINT8_MAX);
812 idev->cancel_all_transfer_request(idev);
818 error = libusb_control_transfer(pdev->libusb_handle,
819 (uint8_t)LIBUSB_ENDPOINT_OUT |
820 (uint8_t)LIBUSB_RECIPIENT_ENDPOINT,
821 LIBUSB_REQUEST_SET_FEATURE, ENDPOINT_HALT,
822 (uint16_t)EndpointAddress,
nullptr, 0, 1000);
826 idev->cancel_all_transfer_request(idev);
827 error = libusb_clear_halt(pdev->libusb_handle, (uint8_t)EndpointAddress);
840static UINT32 libusb_udev_control_query_device_text(IUDEVICE* idev, UINT32 TextType,
841 UINT16 LocaleId, UINT8* BufferSize,
845 LIBUSB_DEVICE_DESCRIPTOR* devDescriptor =
nullptr;
846 const char strDesc[] =
"Generic Usb String";
847 char deviceLocation[25] = WINPR_C_ARRAY_INIT;
849 BYTE device_address = 0;
852 WCHAR* text = WINPR_PACKED_ALIGN_CAST(WCHAR*, Buffer);
855 const UINT8 inSize = *BufferSize;
858 if (!pdev || !pdev->devDescriptor || !pdev->urbdrc)
859 return ERROR_INVALID_DATA;
861 urbdrc = pdev->urbdrc;
862 devDescriptor = pdev->devDescriptor;
866 case DeviceTextDescription:
868 BYTE data[0x100] = WINPR_C_ARRAY_INIT;
869 ret = libusb_get_string_descriptor(pdev->libusb_handle, devDescriptor->iProduct,
870 LocaleId, data, 0xFF);
879 if ((ret <= 0) || (ret <= 4) || (slen <= 4) || (locale != LIBUSB_DT_STRING) ||
882 const char* msg =
"SHORT_DESCRIPTOR";
884 msg = libusb_error_name(ret);
885 WLog_Print(urbdrc->log, WLOG_DEBUG,
886 "libusb_get_string_descriptor: "
887 "%s [%d], iProduct: %" PRIu8
"!",
888 msg, ret, devDescriptor->iProduct);
890 size_t len = MIN(
sizeof(strDesc), inSize);
891 for (
size_t i = 0; i < len; i++)
892 text[i] = (WCHAR)strDesc[i];
894 *BufferSize = (BYTE)(len *
sizeof(WCHAR));
898 size_t maxlen = inSize;
900 if (inSize >
sizeof(WCHAR))
902 maxlen -=
sizeof(WCHAR);
910 _wcsnlen((WCHAR*)&data[2], (
sizeof(data) /
sizeof(WCHAR)) - 1);
911 len = MIN((BYTE)ret - 2, slen);
912 len = MIN(len, rchar *
sizeof(WCHAR));
913 len = MIN(len, maxlen);
915 memcpy(Buffer, &data[2], len);
919 if (Buffer[len] !=
'\0')
921 Buffer[len++] =
'\0';
922 Buffer[len++] =
'\0';
925 *BufferSize = (BYTE)len;
930 case DeviceTextLocationInformation:
932 bus_number = libusb_get_bus_number(pdev->libusb_dev);
933 device_address = libusb_get_device_address(pdev->libusb_dev);
934 (void)sprintf_s(deviceLocation,
sizeof(deviceLocation),
935 "Port_#%04" PRIu8
".Hub_#%04" PRIu8
"", device_address, bus_number);
937 size_t len = strnlen(deviceLocation,
938 MIN(
sizeof(deviceLocation), (inSize > 0) ? inSize - 1U : 0));
939 for (
size_t i = 0; i < len; i++)
940 text[i] = (WCHAR)deviceLocation[i];
942 *BufferSize = (UINT8)(len *
sizeof(WCHAR));
947 WLog_Print(urbdrc->log, WLOG_DEBUG,
"Query Text: unknown TextType %" PRIu32
"",
949 return ERROR_INVALID_DATA;
955static int libusb_udev_os_feature_descriptor_request(IUDEVICE* idev,
956 WINPR_ATTR_UNUSED UINT32 RequestId,
957 BYTE Recipient, BYTE InterfaceNumber,
958 BYTE Ms_PageIndex, UINT16 Ms_featureDescIndex,
959 UINT32* UsbdStatus, UINT32* BufferSize,
960 BYTE* Buffer, UINT32 Timeout)
963 BYTE ms_string_desc[0x13] = WINPR_C_ARRAY_INIT;
967 WINPR_ASSERT(pdev->urbdrc);
968 WINPR_ASSERT(UsbdStatus);
969 WINPR_ASSERT(BufferSize);
971 if (*BufferSize > UINT16_MAX)
973 WLog_Print(pdev->urbdrc->log, WLOG_ERROR,
"BufferSize %" PRIu32
" > %d", *BufferSize,
978 const UINT16 requestedSize = WINPR_ASSERTING_INT_CAST(UINT16, *BufferSize);
984 error = libusb_control_transfer(pdev->libusb_handle, LIBUSB_ENDPOINT_IN | Recipient,
985 LIBUSB_REQUEST_GET_DESCRIPTOR, 0x03ee, 0, ms_string_desc, 0x12,
988 log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG,
"libusb_control_transfer", error);
992 const BYTE bMS_Vendorcode = ms_string_desc[16];
994 error = libusb_control_transfer(
996 (uint8_t)LIBUSB_ENDPOINT_IN | (uint8_t)LIBUSB_REQUEST_TYPE_VENDOR | Recipient,
997 bMS_Vendorcode, (UINT16)((InterfaceNumber << 8) | Ms_PageIndex), Ms_featureDescIndex,
998 Buffer, requestedSize, Timeout);
999 log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG,
"libusb_control_transfer", error);
1002 *BufferSize = (UINT32)error;
1006 *UsbdStatus = USBD_STATUS_STALL_PID;
1008 *UsbdStatus = USBD_STATUS_SUCCESS;
1010 return ERROR_SUCCESS;
1013static enum device_speed libusb_udev_query_device_speed(IUDEVICE* idev)
1017 if (!pdev || !pdev->libusb_dev)
1018 return DEVICE_SPEED_UNKNOWN;
1020 switch (libusb_get_device_speed(pdev->libusb_dev))
1022 case LIBUSB_SPEED_LOW:
1023 return DEVICE_SPEED_LOW;
1025 case LIBUSB_SPEED_FULL:
1026 return DEVICE_SPEED_FULL;
1028 case LIBUSB_SPEED_HIGH:
1029 return DEVICE_SPEED_HIGH;
1031 case LIBUSB_SPEED_SUPER:
1032 return DEVICE_SPEED_SUPER;
1034#if LIBUSB_API_VERSION >= 0x01000106
1035 case LIBUSB_SPEED_SUPER_PLUS:
1036 return DEVICE_SPEED_SUPER_PLUS;
1040 return DEVICE_SPEED_UNKNOWN;
1044static int libusb_udev_query_device_descriptor(IUDEVICE* idev,
int offset)
1051 return pdev->devDescriptor->bLength;
1053 case B_DESCRIPTOR_TYPE:
1054 return pdev->devDescriptor->bDescriptorType;
1057 return pdev->devDescriptor->bcdUSB;
1059 case B_DEVICE_CLASS:
1060 return pdev->devDescriptor->bDeviceClass;
1062 case B_DEVICE_SUBCLASS:
1063 return pdev->devDescriptor->bDeviceSubClass;
1065 case B_DEVICE_PROTOCOL:
1066 return pdev->devDescriptor->bDeviceProtocol;
1068 case B_MAX_PACKET_SIZE0:
1069 return pdev->devDescriptor->bMaxPacketSize0;
1072 return pdev->devDescriptor->idVendor;
1075 return pdev->devDescriptor->idProduct;
1078 return pdev->devDescriptor->bcdDevice;
1080 case I_MANUFACTURER:
1081 return pdev->devDescriptor->iManufacturer;
1084 return pdev->devDescriptor->iProduct;
1086 case I_SERIAL_NUMBER:
1087 return pdev->devDescriptor->iSerialNumber;
1089 case B_NUM_CONFIGURATIONS:
1090 return pdev->devDescriptor->bNumConfigurations;
1097static BOOL libusb_udev_detach_kernel_driver(IUDEVICE* idev)
1103 if (!pdev || !pdev->LibusbConfig || !pdev->libusb_handle || !pdev->urbdrc)
1109 urbdrc = pdev->urbdrc;
1111 if ((pdev->status & URBDRC_DEVICE_DETACH_KERNEL) == 0)
1113 for (
int i = 0; i < pdev->LibusbConfig->bNumInterfaces; i++)
1115 err = libusb_kernel_driver_active(pdev->libusb_handle, i);
1116 log_libusb_result(urbdrc->log, WLOG_DEBUG,
"libusb_kernel_driver_active", err);
1120 err = libusb_detach_kernel_driver(pdev->libusb_handle, i);
1121 log_libusb_result(urbdrc->log, WLOG_DEBUG,
"libusb_detach_kernel_driver", err);
1125 pdev->status |= URBDRC_DEVICE_DETACH_KERNEL;
1132static BOOL libusb_udev_attach_kernel_driver(IUDEVICE* idev)
1137 if (!pdev || !pdev->LibusbConfig || !pdev->libusb_handle || !pdev->urbdrc)
1140 for (
int i = 0; i < pdev->LibusbConfig->bNumInterfaces && err != LIBUSB_ERROR_NO_DEVICE; i++)
1142 err = libusb_release_interface(pdev->libusb_handle, i);
1144 log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG,
"libusb_release_interface", err);
1147 if (err != LIBUSB_ERROR_NO_DEVICE)
1149 err = libusb_attach_kernel_driver(pdev->libusb_handle, i);
1150 log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG,
"libusb_attach_kernel_driver if=%d",
1159static int libusb_udev_is_composite_device(IUDEVICE* idev)
1162 return pdev->isCompositeDevice;
1165static int libusb_udev_is_exist(IUDEVICE* idev)
1168 return (pdev->status & URBDRC_DEVICE_NOT_FOUND) ? 0 : 1;
1171static int libusb_udev_is_channel_closed(IUDEVICE* idev)
1174 IUDEVMAN* udevman =
nullptr;
1175 if (!pdev || !pdev->urbdrc)
1178 udevman = pdev->urbdrc->udevman;
1181 if (udevman->status & URBDRC_DEVICE_CHANNEL_CLOSED)
1185 if (pdev->status & URBDRC_DEVICE_CHANNEL_CLOSED)
1191static int libusb_udev_is_already_send(IUDEVICE* idev)
1194 return (pdev->status & URBDRC_DEVICE_ALREADY_SEND) ? 1 : 0;
1199static void libusb_udev_mark_channel_closed(IUDEVICE* idev)
1202 if (pdev && ((pdev->status & URBDRC_DEVICE_CHANNEL_CLOSED) == 0))
1205 const uint8_t busNr = idev->get_bus_number(idev);
1206 const uint8_t devNr = idev->get_dev_number(idev);
1208 pdev->status |= URBDRC_DEVICE_CHANNEL_CLOSED;
1209 pdev->iface.cancel_all_transfer_request(&pdev->iface);
1210 if (!urbdrc->udevman->unregister_udevice(urbdrc->udevman, busNr, devNr))
1212 WLog_Print(pdev->urbdrc->log, WLOG_WARN,
"unregister_udevice failed for %d, %d", busNr,
1220static void libusb_udev_channel_closed(IUDEVICE* idev)
1223 if (pdev && ((pdev->status & URBDRC_DEVICE_CHANNEL_CLOSED) == 0))
1226 const uint8_t busNr = idev->get_bus_number(idev);
1227 const uint8_t devNr = idev->get_dev_number(idev);
1228 IWTSVirtualChannel* channel =
nullptr;
1230 if (pdev->channelManager)
1231 channel = IFCALLRESULT(
nullptr, pdev->channelManager->FindChannelById,
1232 pdev->channelManager, pdev->channelID);
1234 pdev->status |= URBDRC_DEVICE_CHANNEL_CLOSED;
1238 const UINT rc = channel->Write(channel, 0,
nullptr,
nullptr);
1239 if (rc != CHANNEL_RC_OK)
1240 WLog_Print(urbdrc->log, WLOG_WARN,
"channel->Write failed with %" PRIu32, rc);
1243 if (!urbdrc->udevman->unregister_udevice(urbdrc->udevman, busNr, devNr))
1244 WLog_Print(urbdrc->log, WLOG_WARN,
"unregister_udevice failed for %d, %d", busNr,
1249static void libusb_udev_set_already_send(IUDEVICE* idev)
1252 pdev->status |= URBDRC_DEVICE_ALREADY_SEND;
1255static char* libusb_udev_get_path(IUDEVICE* idev)
1261static int libusb_udev_query_device_port_status(IUDEVICE* idev, UINT32* UsbdStatus,
1262 UINT32* BufferSize, BYTE* Buffer)
1269 WINPR_ASSERT(BufferSize);
1271 if (!pdev || !pdev->urbdrc)
1274 urbdrc = pdev->urbdrc;
1276 if (pdev->hub_handle !=
nullptr)
1278 ret = idev->control_transfer(
1280 (uint8_t)LIBUSB_ENDPOINT_IN | (uint8_t)LIBUSB_REQUEST_TYPE_CLASS |
1281 (uint8_t)LIBUSB_RECIPIENT_OTHER,
1282 LIBUSB_REQUEST_GET_STATUS, 0, pdev->port_number, UsbdStatus, BufferSize, Buffer, 1000);
1284 if (log_libusb_result(urbdrc->log, WLOG_DEBUG,
"libusb_control_transfer", ret))
1288 WLog_Print(urbdrc->log, WLOG_DEBUG,
1289 "PORT STATUS:0x%02" PRIx8
"%02" PRIx8
"%02" PRIx8
"%02" PRIx8
"", Buffer[3],
1290 Buffer[2], Buffer[1], Buffer[0]);
1299 UINT32 MessageId, UINT32 RequestId, UINT32 EndpointAddress,
1300 WINPR_ATTR_UNUSED UINT32 TransferFlags, UINT32 StartFrame,
1301 UINT32 ErrorCount, BOOL NoAck,
1302 WINPR_ATTR_UNUSED
const BYTE* packetDescriptorData,
1303 UINT32 NumberOfPackets, UINT32 BufferSize,
const BYTE* Buffer,
1304 int transferDir, t_isoch_transfer_cb cb, UINT32 Timeout)
1307 UINT32 iso_packet_size = 0;
1309 ASYNC_TRANSFER_USER_DATA* user_data =
nullptr;
1310 struct libusb_transfer* iso_transfer =
nullptr;
1312 size_t outSize = (12ULL * NumberOfPackets);
1313 uint32_t streamID = 0x40000000 | RequestId;
1315 if (!pdev || !pdev->urbdrc)
1318 urbdrc = pdev->urbdrc;
1319 user_data = async_transfer_user_data_new(idev, MessageId, 48, BufferSize, Buffer,
1320 outSize + 1024, NoAck, transferDir, cb, callback);
1325 user_data->ErrorCount = ErrorCount;
1326 user_data->StartFrame = StartFrame;
1329 Stream_Seek(user_data->data, (12ULL * NumberOfPackets));
1331 if (NumberOfPackets > 0)
1333 iso_packet_size = BufferSize / NumberOfPackets;
1334 iso_transfer = libusb_alloc_transfer((
int)NumberOfPackets);
1337 if (iso_transfer ==
nullptr)
1339 WLog_Print(urbdrc->log, WLOG_ERROR,
1340 "Error: libusb_alloc_transfer [NumberOfPackets=%" PRIu32
", BufferSize=%" PRIu32
1342 NumberOfPackets, BufferSize);
1343 async_transfer_user_data_free(user_data);
1348 libusb_fill_iso_transfer(
1349 iso_transfer, pdev->libusb_handle, WINPR_ASSERTING_INT_CAST(uint8_t, EndpointAddress),
1350 Stream_Pointer(user_data->data), WINPR_ASSERTING_INT_CAST(
int, BufferSize),
1351 WINPR_ASSERTING_INT_CAST(
int, NumberOfPackets), func_iso_callback, user_data, Timeout);
1352 set_stream_id_for_buffer(iso_transfer, streamID);
1353 libusb_set_iso_packet_lengths(iso_transfer, iso_packet_size);
1355 if (!ArrayList_Append(pdev->request_queue, iso_transfer))
1357 WLog_Print(urbdrc->log, WLOG_WARN,
1358 "Failed to queue iso transfer, streamID %08" PRIx32
" already in use!",
1360 request_free(iso_transfer);
1363 rc = libusb_submit_transfer(iso_transfer);
1364 if (log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_submit_transfer", rc))
1369static BOOL libusb_udev_control_transfer(IUDEVICE* idev, WINPR_ATTR_UNUSED UINT32 RequestId,
1370 WINPR_ATTR_UNUSED UINT32 EndpointAddress,
1371 WINPR_ATTR_UNUSED UINT32 TransferFlags, BYTE bmRequestType,
1372 BYTE Request, UINT16 Value, UINT16 Index,
1373 UINT32* UrbdStatus, UINT32* BufferSize, BYTE* Buffer,
1379 WINPR_ASSERT(BufferSize);
1381 if (!pdev || !pdev->urbdrc)
1384 if (*BufferSize > UINT16_MAX)
1386 WLog_Print(pdev->urbdrc->log, WLOG_ERROR,
"BufferSize %" PRIu32
" > %d", *BufferSize,
1392 libusb_control_transfer(pdev->libusb_handle, bmRequestType, Request, Value, Index, Buffer,
1393 WINPR_ASSERTING_INT_CAST(UINT16, *BufferSize), Timeout);
1396 *BufferSize = (UINT32)status;
1400 log_libusb_result(pdev->urbdrc->log, WLOG_ERROR,
"libusb_control_transfer", status);
1403 if (!func_set_usbd_status(pdev->urbdrc, pdev, UrbdStatus, status))
1409static int libusb_udev_bulk_or_interrupt_transfer(
1411 UINT32 EndpointAddress, UINT32 TransferFlags, BOOL NoAck, UINT32 BufferSize,
const BYTE* data,
1412 int transferDir, t_isoch_transfer_cb cb, UINT32 Timeout)
1415 UINT32 transfer_type = 0;
1417 const LIBUSB_ENDPOINT_DESCEIPTOR* ep_desc =
nullptr;
1418 struct libusb_transfer* transfer =
nullptr;
1420 ASYNC_TRANSFER_USER_DATA* user_data =
nullptr;
1421 uint32_t streamID = 0x80000000 | RequestId;
1423 if (!pdev || !pdev->LibusbConfig || !pdev->urbdrc)
1426 urbdrc = pdev->urbdrc;
1427 user_data = async_transfer_user_data_new(idev, MessageId, 36, BufferSize, data, 0, NoAck,
1428 transferDir, cb, callback);
1434 transfer = libusb_alloc_transfer(0);
1437 async_transfer_user_data_free(user_data);
1440 transfer->user_data = user_data;
1442 ep_desc = func_get_ep_desc(pdev->LibusbConfig, pdev->MsConfig, EndpointAddress);
1446 WLog_Print(urbdrc->log, WLOG_ERROR,
"func_get_ep_desc: endpoint 0x%" PRIx32
" not found",
1448 request_free(transfer);
1452 transfer_type = (ep_desc->bmAttributes) & 0x3;
1453 WLog_Print(urbdrc->log, WLOG_DEBUG,
1454 "urb_bulk_or_interrupt_transfer: ep:0x%" PRIx32
" "
1455 "transfer_type %" PRIu32
" flag:%" PRIu32
" OutputBufferSize:0x%" PRIx32
"",
1456 EndpointAddress, transfer_type, TransferFlags, BufferSize);
1458 switch (transfer_type)
1462 libusb_fill_bulk_transfer(
1463 transfer, pdev->libusb_handle, WINPR_ASSERTING_INT_CAST(uint8_t, EndpointAddress),
1464 Stream_Pointer(user_data->data), WINPR_ASSERTING_INT_CAST(
int, BufferSize),
1465 func_bulk_transfer_cb, user_data, Timeout);
1468 case INTERRUPT_TRANSFER:
1470 libusb_fill_interrupt_transfer(
1471 transfer, pdev->libusb_handle, WINPR_ASSERTING_INT_CAST(uint8_t, EndpointAddress),
1472 Stream_Pointer(user_data->data), WINPR_ASSERTING_INT_CAST(
int, BufferSize),
1473 func_bulk_transfer_cb, user_data, Timeout);
1477 WLog_Print(urbdrc->log, WLOG_DEBUG,
1478 "urb_bulk_or_interrupt_transfer:"
1479 " other transfer type 0x%" PRIX32
"",
1481 request_free(transfer);
1485 set_stream_id_for_buffer(transfer, streamID);
1487 if (!ArrayList_Append(pdev->request_queue, transfer))
1489 WLog_Print(urbdrc->log, WLOG_WARN,
1490 "Failed to queue transfer, streamID %08" PRIx32
" already in use!", streamID);
1491 request_free(transfer);
1494 rc = libusb_submit_transfer(transfer);
1495 if (log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_submit_transfer", rc))
1500static int func_cancel_xact_request(
URBDRC_PLUGIN* urbdrc,
struct libusb_transfer* transfer)
1504 if (!urbdrc || !transfer)
1507 status = libusb_cancel_transfer(transfer);
1509 if (log_libusb_result(urbdrc->log, WLOG_WARN,
"libusb_cancel_transfer", status))
1511 if (status == LIBUSB_ERROR_NOT_FOUND)
1520static void libusb_udev_cancel_all_transfer_request(IUDEVICE* idev)
1525 if (!pdev || !pdev->request_queue || !pdev->urbdrc)
1528 ArrayList_Lock(pdev->request_queue);
1529 count = ArrayList_Count(pdev->request_queue);
1531 for (
size_t x = 0; x < count; x++)
1533 struct libusb_transfer* transfer = ArrayList_GetItem(pdev->request_queue, x);
1534 func_cancel_xact_request(pdev->urbdrc, transfer);
1537 ArrayList_Unlock(pdev->request_queue);
1540static int libusb_udev_cancel_transfer_request(IUDEVICE* idev, UINT32 RequestId)
1544 struct libusb_transfer* transfer =
nullptr;
1545 uint32_t cancelID1 = 0x40000000 | RequestId;
1546 uint32_t cancelID2 = 0x80000000 | RequestId;
1548 if (!idev || !pdev->urbdrc || !pdev->request_queue)
1551 ArrayList_Lock(pdev->request_queue);
1552 transfer = list_contains(pdev->request_queue, cancelID1);
1554 transfer = list_contains(pdev->request_queue, cancelID2);
1560 rc = func_cancel_xact_request(urbdrc, transfer);
1562 ArrayList_Unlock(pdev->request_queue);
1566BASIC_STATE_FUNC_DEFINED(channelManager, IWTSVirtualChannelManager*)
1567BASIC_STATE_FUNC_DEFINED(channelID, UINT32)
1568BASIC_STATE_FUNC_DEFINED(ReqCompletion, UINT32)
1569BASIC_STATE_FUNC_DEFINED(bus_number, BYTE)
1570BASIC_STATE_FUNC_DEFINED(dev_number, BYTE)
1571BASIC_STATE_FUNC_DEFINED(port_number, UINT8)
1574BASIC_POINT_FUNC_DEFINED(udev,
void*)
1575BASIC_POINT_FUNC_DEFINED(prev,
void*)
1576BASIC_POINT_FUNC_DEFINED(next,
void*)
1578static UINT32 udev_get_UsbDevice(IUDEVICE* idev)
1585 return pdev->UsbDevice;
1588static void udev_set_UsbDevice(IUDEVICE* idev, UINT32 val)
1595 pdev->UsbDevice = val;
1598static void udev_free(IUDEVICE* idev)
1604 if (!idev || !udev->urbdrc)
1607 urbdrc = udev->urbdrc;
1609 libusb_udev_cancel_all_transfer_request(&udev->iface);
1610 if (udev->libusb_handle)
1612 rc = libusb_reset_device(udev->libusb_handle);
1614 log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_reset_device", rc);
1623 if (!udev->iface.attach_kernel_driver(idev))
1624 WLog_Print(udev->urbdrc->log, WLOG_WARN,
"attach_kernel_driver failed for device");
1625 ArrayList_Free(udev->request_queue);
1627 msusb_msconfig_free(udev->MsConfig);
1628 libusb_unref_device(udev->libusb_dev);
1629 libusb_close(udev->libusb_handle);
1630 libusb_close(udev->hub_handle);
1631 free(udev->devDescriptor);
1635static void udev_load_interface(
UDEVICE* pdev)
1641 BASIC_STATE_FUNC_REGISTER(channelManager, pdev);
1642 BASIC_STATE_FUNC_REGISTER(channelID, pdev);
1643 BASIC_STATE_FUNC_REGISTER(UsbDevice, pdev);
1644 BASIC_STATE_FUNC_REGISTER(ReqCompletion, pdev);
1645 BASIC_STATE_FUNC_REGISTER(bus_number, pdev);
1646 BASIC_STATE_FUNC_REGISTER(dev_number, pdev);
1647 BASIC_STATE_FUNC_REGISTER(port_number, pdev);
1648 BASIC_STATE_FUNC_REGISTER(MsConfig, pdev);
1649 BASIC_STATE_FUNC_REGISTER(p_udev, pdev);
1650 BASIC_STATE_FUNC_REGISTER(p_prev, pdev);
1651 BASIC_STATE_FUNC_REGISTER(p_next, pdev);
1652 pdev->iface.isCompositeDevice = libusb_udev_is_composite_device;
1653 pdev->iface.isExist = libusb_udev_is_exist;
1654 pdev->iface.isAlreadySend = libusb_udev_is_already_send;
1655 pdev->iface.isChannelClosed = libusb_udev_is_channel_closed;
1656 pdev->iface.setAlreadySend = libusb_udev_set_already_send;
1657 pdev->iface.setChannelClosed = libusb_udev_channel_closed;
1658 pdev->iface.markChannelClosed = libusb_udev_mark_channel_closed;
1659 pdev->iface.getPath = libusb_udev_get_path;
1661 pdev->iface.isoch_transfer = libusb_udev_isoch_transfer;
1662 pdev->iface.control_transfer = libusb_udev_control_transfer;
1663 pdev->iface.bulk_or_interrupt_transfer = libusb_udev_bulk_or_interrupt_transfer;
1664 pdev->iface.select_interface = libusb_udev_select_interface;
1665 pdev->iface.select_configuration = libusb_udev_select_configuration;
1666 pdev->iface.complete_msconfig_setup = libusb_udev_complete_msconfig_setup;
1667 pdev->iface.control_pipe_request = libusb_udev_control_pipe_request;
1668 pdev->iface.control_query_device_text = libusb_udev_control_query_device_text;
1669 pdev->iface.os_feature_descriptor_request = libusb_udev_os_feature_descriptor_request;
1670 pdev->iface.cancel_all_transfer_request = libusb_udev_cancel_all_transfer_request;
1671 pdev->iface.cancel_transfer_request = libusb_udev_cancel_transfer_request;
1672 pdev->iface.query_device_descriptor = libusb_udev_query_device_descriptor;
1673 pdev->iface.query_device_speed = libusb_udev_query_device_speed;
1674 pdev->iface.detach_kernel_driver = libusb_udev_detach_kernel_driver;
1675 pdev->iface.attach_kernel_driver = libusb_udev_attach_kernel_driver;
1676 pdev->iface.query_device_port_status = libusb_udev_query_device_port_status;
1677 pdev->iface.free = udev_free;
1681 UINT16 bus_number, UINT16 dev_number)
1684 uint8_t port_numbers[16] = WINPR_C_ARRAY_INIT;
1685 LIBUSB_DEVICE** libusb_list =
nullptr;
1686 const ssize_t total_device = libusb_get_device_list(ctx, &libusb_list);
1688 WINPR_ASSERT(urbdrc);
1691 for (ssize_t i = 0; i < total_device; i++)
1693 LIBUSB_DEVICE* dev = libusb_list[i];
1695 if ((bus_number != libusb_get_bus_number(dev)) ||
1696 (dev_number != libusb_get_device_address(dev)))
1697 libusb_unref_device(dev);
1700 error = libusb_open(dev, &pdev->libusb_handle);
1702 if (log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_open", error))
1704 libusb_unref_device(dev);
1709 error = libusb_get_port_numbers(dev, port_numbers,
sizeof(port_numbers));
1713 log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_get_port_numbers", error);
1714 libusb_unref_device(dev);
1718 pdev->port_number = port_numbers[(error - 1)];
1720 WLog_Print(urbdrc->log, WLOG_DEBUG,
" Port: %" PRIu8, pdev->port_number);
1722 (void)_snprintf(pdev->path,
sizeof(pdev->path),
"%" PRIu16
"-%d", bus_number,
1725 WLog_Print(urbdrc->log, WLOG_DEBUG,
" DevPath: %s", pdev->path);
1728 libusb_free_device_list(libusb_list, 0);
1736 UINT16 bus_number, WINPR_ATTR_UNUSED UINT16 dev_number)
1739 LIBUSB_DEVICE** libusb_list =
nullptr;
1740 LIBUSB_DEVICE_HANDLE* handle =
nullptr;
1741 const ssize_t total_device = libusb_get_device_list(ctx, &libusb_list);
1743 WINPR_ASSERT(urbdrc);
1746 for (ssize_t i = 0; i < total_device; i++)
1748 LIBUSB_DEVICE* dev = libusb_list[i];
1750 if ((bus_number != libusb_get_bus_number(dev)) ||
1751 (1 != libusb_get_device_address(dev)))
1752 libusb_unref_device(dev);
1755 WLog_Print(urbdrc->log, WLOG_DEBUG,
" Open hub: %" PRIu16
"", bus_number);
1756 error = libusb_open(dev, &handle);
1758 if (!log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_open", error))
1759 pdev->hub_handle = handle;
1761 libusb_unref_device(dev);
1765 libusb_free_device_list(libusb_list, 0);
1773static void request_free(
void* value)
1775 ASYNC_TRANSFER_USER_DATA* user_data =
nullptr;
1776 struct libusb_transfer* transfer = (
struct libusb_transfer*)value;
1780 user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
1781 async_transfer_user_data_free(user_data);
1782 transfer->user_data =
nullptr;
1783 libusb_free_transfer(transfer);
1786static IUDEVICE* udev_init(
URBDRC_PLUGIN* urbdrc, libusb_context* context, LIBUSB_DEVICE* device,
1787 BYTE bus_number, BYTE dev_number)
1790 int status = LIBUSB_ERROR_OTHER;
1791 LIBUSB_DEVICE_DESCRIPTOR* devDescriptor =
nullptr;
1792 LIBUSB_CONFIG_DESCRIPTOR* config_temp =
nullptr;
1793 LIBUSB_INTERFACE_DESCRIPTOR interface_temp;
1795 WINPR_ASSERT(urbdrc);
1802 pdev->urbdrc = urbdrc;
1803 udev_load_interface(pdev);
1806 pdev->libusb_dev = device;
1808 pdev->libusb_dev = udev_get_libusb_dev(context, bus_number, dev_number);
1810 if (pdev->libusb_dev ==
nullptr)
1813 if (urbdrc->listener_callback)
1814 udev_set_channelManager(&pdev->iface, urbdrc->listener_callback->channel_mgr);
1817 status = udev_get_device_handle(urbdrc, context, pdev, bus_number, dev_number);
1818 if (status != LIBUSB_SUCCESS)
1820 struct libusb_device_descriptor desc;
1821 const uint8_t port = libusb_get_port_number(pdev->libusb_dev);
1822 libusb_get_device_descriptor(pdev->libusb_dev, &desc);
1824 log_libusb_result(urbdrc->log, WLOG_ERROR,
1825 "libusb_open [b=0x%02X,p=0x%02X,a=0x%02X,VID=0x%04X,PID=0x%04X]", status,
1826 bus_number, port, dev_number, desc.idVendor, desc.idProduct);
1831 status = udev_get_hub_handle(urbdrc, context, pdev, bus_number, dev_number);
1834 pdev->hub_handle =
nullptr;
1836 pdev->devDescriptor = udev_new_descript(urbdrc, pdev->libusb_dev);
1838 if (!pdev->devDescriptor)
1841 status = libusb_get_active_config_descriptor(pdev->libusb_dev, &pdev->LibusbConfig);
1843 if (status == LIBUSB_ERROR_NOT_FOUND)
1844 status = libusb_get_config_descriptor(pdev->libusb_dev, 0, &pdev->LibusbConfig);
1848 log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_get_config_descriptor", status);
1852 config_temp = pdev->LibusbConfig;
1854 interface_temp = config_temp->interface[0].altsetting[0];
1855 WLog_Print(urbdrc->log, WLOG_DEBUG,
1856 "Registered Device: Vid: 0x%04" PRIX16
" Pid: 0x%04" PRIX16
""
1857 " InterfaceClass = %s",
1858 pdev->devDescriptor->idVendor, pdev->devDescriptor->idProduct,
1859 usb_interface_class_to_string(interface_temp.bInterfaceClass));
1861 devDescriptor = pdev->devDescriptor;
1863 if ((devDescriptor->bNumConfigurations == 1) && (config_temp->bNumInterfaces > 1) &&
1864 (devDescriptor->bDeviceClass == LIBUSB_CLASS_PER_INTERFACE))
1866 pdev->isCompositeDevice = 1;
1868 else if ((devDescriptor->bDeviceClass == 0xef) &&
1869 (devDescriptor->bDeviceSubClass == LIBUSB_CLASS_COMM) &&
1870 (devDescriptor->bDeviceProtocol == 0x01))
1872 pdev->isCompositeDevice = 1;
1875 pdev->isCompositeDevice = 0;
1878 devDescriptor->bDeviceClass = interface_temp.bInterfaceClass;
1879 devDescriptor->bDeviceSubClass = interface_temp.bInterfaceSubClass;
1880 devDescriptor->bDeviceProtocol = interface_temp.bInterfaceProtocol;
1882 pdev->bus_number = bus_number;
1883 pdev->dev_number = dev_number;
1884 pdev->request_queue = ArrayList_New(TRUE);
1886 if (!pdev->request_queue)
1889 ArrayList_Object(pdev->request_queue)->
fnObjectFree = request_free;
1892 pdev->MsConfig = msusb_msconfig_new();
1894 if (!pdev->MsConfig)
1898 return &pdev->iface;
1900 pdev->iface.free(&pdev->iface);
1904size_t udev_new_by_id(
URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UINT16 idVendor, UINT16 idProduct,
1905 IUDEVICE*** devArray)
1907 WINPR_ASSERT(urbdrc);
1908 WINPR_ASSERT(devArray);
1911 LIBUSB_DEVICE** libusb_list =
nullptr;
1913 *devArray =
nullptr;
1915 WLog_Print(urbdrc->log, WLOG_INFO,
"VID: 0x%04" PRIX16
", PID: 0x%04" PRIX16
"", idVendor,
1917 const ssize_t total_device = libusb_get_device_list(ctx, &libusb_list);
1918 if (total_device < 0)
1920 WLog_Print(urbdrc->log, WLOG_ERROR,
"libusb_get_device_list -> [%" PRIdz
"]", total_device);
1923 if (total_device == 0)
1925 WLog_Print(urbdrc->log, WLOG_WARN,
"libusb_get_device_list -> [%" PRIdz
"]", total_device);
1934 for (ssize_t i = 0; i < total_device; i++)
1936 LIBUSB_DEVICE* dev = libusb_list[i];
1937 LIBUSB_DEVICE_DESCRIPTOR* descriptor = udev_new_descript(urbdrc, dev);
1939 if ((descriptor->idVendor == idVendor) && (descriptor->idProduct == idProduct))
1941 const uint8_t nr = libusb_get_bus_number(dev);
1942 const uint8_t addr = libusb_get_device_address(dev);
1943 array[num] = (
PUDEVICE)udev_init(urbdrc, ctx, dev, nr, addr);
1945 if (array[num] !=
nullptr)
1949 WLog_Print(urbdrc->log, WLOG_WARN,
1950 "udev_init(nr=%" PRIu8
", addr=%" PRIu8
") failed", nr, addr);
1954 libusb_unref_device(dev);
1960 libusb_free_device_list(libusb_list, 0);
1961 *devArray = (IUDEVICE**)array;
1965IUDEVICE* udev_new_by_addr(
URBDRC_PLUGIN* urbdrc, libusb_context* context, BYTE bus_number,
1968 WLog_Print(urbdrc->log, WLOG_DEBUG,
"bus:%d dev:%d", bus_number, dev_number);
1969 return udev_init(urbdrc, context,
nullptr, bus_number, dev_number);
OBJECT_FREE_FN fnObjectFree