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;
79 t_isoch_transfer_cb cb;
81#if !defined(HAVE_STREAM_ID_API)
84} ASYNC_TRANSFER_USER_DATA;
86static void request_free(
void* value);
88static struct libusb_transfer* list_contains(wArrayList* list, UINT32 streamID)
93 count = ArrayList_Count(list);
94 for (
size_t x = 0; x < count; x++)
96 struct libusb_transfer* transfer = ArrayList_GetItem(list, x);
98#if defined(HAVE_STREAM_ID_API)
99 const UINT32 currentID = libusb_transfer_get_stream_id(transfer);
101 const ASYNC_TRANSFER_USER_DATA* user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
102 const UINT32 currentID = user_data->streamID;
104 if (currentID == streamID)
110static UINT32 stream_id_from_buffer(
struct libusb_transfer* transfer)
114#if defined(HAVE_STREAM_ID_API)
115 return libusb_transfer_get_stream_id(transfer);
117 ASYNC_TRANSFER_USER_DATA* user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
120 return user_data->streamID;
124static void set_stream_id_for_buffer(
struct libusb_transfer* transfer, UINT32 streamID)
126#if defined(HAVE_STREAM_ID_API)
127 libusb_transfer_set_stream_id(transfer, streamID);
129 ASYNC_TRANSFER_USER_DATA* user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
132 user_data->streamID = streamID;
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, ...)
144 char buffer[8192] = { 0 };
147 (void)vsnprintf(buffer,
sizeof(buffer), fmt, ap);
150 WLog_Print(log, lvl,
"[%s:%" PRIuz
"]: %s: error %s[%d]", fkt, line, buffer,
151 libusb_error_name(error), error);
157#define log_libusb_result(log, lvl, fmt, error, ...) \
158 log_libusb_result_((log), (lvl), (fmt), __func__, __FILE__, __LINE__, error, ##__VA_ARGS__)
160const char* usb_interface_class_to_string(uint8_t c_class)
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";
201 return "UNKNOWN_DEVICE_CLASS";
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,
211 ASYNC_TRANSFER_USER_DATA* user_data = NULL;
214 if (BufferSize > UINT32_MAX)
217 user_data = calloc(1,
sizeof(ASYNC_TRANSFER_USER_DATA));
221 user_data->data = Stream_New(NULL, offset + BufferSize + packetSize);
223 if (!user_data->data)
229 Stream_Seek(user_data->data, offset);
231 memcpy(Stream_Pointer(user_data->data), data, BufferSize);
233 user_data->OutputBufferSize = (UINT32)BufferSize;
235 user_data->noack = NoAck;
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 Stream_SetPosition(user_data->data,
271 for (uint32_t i = 0; i < WINPR_ASSERTING_INT_CAST(uint32_t, transfer->num_iso_packets);
274 const UINT32 act_len = transfer->iso_packet_desc[i].actual_length;
275 Stream_Write_UINT32(user_data->data, index);
276 Stream_Write_UINT32(user_data->data, act_len);
277 Stream_Write_UINT32(user_data->data, transfer->iso_packet_desc[i].status);
279 if (transfer->iso_packet_desc[i].status != USBD_STATUS_SUCCESS)
280 user_data->ErrorCount++;
283 const unsigned char* packetBuffer =
284 libusb_get_iso_packet_buffer_simple(transfer, i);
285 BYTE* data = dataStart + index;
287 if (data != packetBuffer)
288 memmove(data, packetBuffer, act_len);
296 case LIBUSB_TRANSFER_CANCELLED:
299 case LIBUSB_TRANSFER_TIMED_OUT:
302 case LIBUSB_TRANSFER_ERROR:
304 const UINT32 InterfaceId =
305 ((STREAM_ID_PROXY << 30) | user_data->idev->get_ReqCompletion(user_data->idev));
307 if (list_contains(list, streamID))
309 if (!user_data->noack)
311 const UINT32 RequestID = streamID & INTERFACE_ID_MASK;
312 user_data->cb(user_data->idev, user_data->callback, user_data->data,
313 InterfaceId, user_data->noack, user_data->MessageId, RequestID,
314 WINPR_ASSERTING_INT_CAST(uint32_t, transfer->num_iso_packets),
315 transfer->status, user_data->StartFrame, user_data->ErrorCount,
316 user_data->OutputBufferSize);
317 user_data->data = NULL;
319 ArrayList_Remove(list, transfer);
326 ArrayList_Unlock(list);
329static const LIBUSB_ENDPOINT_DESCEIPTOR* func_get_ep_desc(LIBUSB_CONFIG_DESCRIPTOR* LibusbConfig,
331 UINT32 EndpointAddress)
334 const LIBUSB_INTERFACE*
interface = LibusbConfig->interface;
336 for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
338 BYTE alt = MsInterfaces[inum]->AlternateSetting;
339 const LIBUSB_ENDPOINT_DESCEIPTOR* endpoint = interface[inum].altsetting[alt].endpoint;
341 for (UINT32 pnum = 0; pnum < MsInterfaces[inum]->NumberOfPipes; pnum++)
343 if (endpoint[pnum].bEndpointAddress == EndpointAddress)
345 return &endpoint[pnum];
353static void LIBUSB_CALL func_bulk_transfer_cb(
struct libusb_transfer* transfer)
355 ASYNC_TRANSFER_USER_DATA* user_data = NULL;
356 uint32_t streamID = 0;
357 wArrayList* list = NULL;
359 user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
362 WLog_ERR(TAG,
"Invalid transfer->user_data!");
365 list = user_data->queue;
366 ArrayList_Lock(list);
367 streamID = stream_id_from_buffer(transfer);
369 if (list_contains(list, streamID))
371 const UINT32 InterfaceId =
372 ((STREAM_ID_PROXY << 30) | user_data->idev->get_ReqCompletion(user_data->idev));
373 const UINT32 RequestID = streamID & INTERFACE_ID_MASK;
375 user_data->cb(user_data->idev, user_data->callback, user_data->data, InterfaceId,
376 user_data->noack, user_data->MessageId, RequestID,
377 WINPR_ASSERTING_INT_CAST(uint32_t, transfer->num_iso_packets),
378 transfer->status, user_data->StartFrame, user_data->ErrorCount,
379 WINPR_ASSERTING_INT_CAST(uint32_t, transfer->actual_length));
380 user_data->data = NULL;
381 ArrayList_Remove(list, transfer);
383 ArrayList_Unlock(list);
389 if (!urbdrc || !status)
395 *status = USBD_STATUS_SUCCESS;
398 case LIBUSB_ERROR_IO:
399 *status = USBD_STATUS_STALL_PID;
402 case LIBUSB_ERROR_INVALID_PARAM:
403 *status = USBD_STATUS_INVALID_PARAMETER;
406 case LIBUSB_ERROR_ACCESS:
407 *status = USBD_STATUS_NOT_ACCESSED;
410 case LIBUSB_ERROR_NO_DEVICE:
411 *status = USBD_STATUS_DEVICE_GONE;
415 if (!(pdev->status & URBDRC_DEVICE_NOT_FOUND))
416 pdev->status |= URBDRC_DEVICE_NOT_FOUND;
421 case LIBUSB_ERROR_NOT_FOUND:
422 *status = USBD_STATUS_STALL_PID;
425 case LIBUSB_ERROR_BUSY:
426 *status = USBD_STATUS_STALL_PID;
429 case LIBUSB_ERROR_TIMEOUT:
430 *status = USBD_STATUS_TIMEOUT;
433 case LIBUSB_ERROR_OVERFLOW:
434 *status = USBD_STATUS_STALL_PID;
437 case LIBUSB_ERROR_PIPE:
438 *status = USBD_STATUS_STALL_PID;
441 case LIBUSB_ERROR_INTERRUPTED:
442 *status = USBD_STATUS_STALL_PID;
445 case LIBUSB_ERROR_NO_MEM:
446 *status = USBD_STATUS_NO_MEMORY;
449 case LIBUSB_ERROR_NOT_SUPPORTED:
450 *status = USBD_STATUS_NOT_SUPPORTED;
453 case LIBUSB_ERROR_OTHER:
454 *status = USBD_STATUS_STALL_PID;
458 *status = USBD_STATUS_SUCCESS;
465static int func_config_release_all_interface(
URBDRC_PLUGIN* urbdrc,
466 LIBUSB_DEVICE_HANDLE* libusb_handle,
467 UINT32 NumInterfaces)
469 if (NumInterfaces > INT32_MAX)
471 for (INT32 i = 0; i < (INT32)NumInterfaces; i++)
473 int ret = libusb_release_interface(libusb_handle, i);
475 if (log_libusb_result(urbdrc->log, WLOG_WARN,
"libusb_release_interface", ret))
482static int func_claim_all_interface(
URBDRC_PLUGIN* urbdrc, LIBUSB_DEVICE_HANDLE* libusb_handle,
487 for (
int i = 0; i < NumInterfaces; i++)
489 ret = libusb_claim_interface(libusb_handle, i);
491 if (log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_claim_interface", ret))
498static LIBUSB_DEVICE* udev_get_libusb_dev(libusb_context* context, uint8_t bus_number,
501 LIBUSB_DEVICE** libusb_list = NULL;
502 LIBUSB_DEVICE* device = NULL;
503 const ssize_t total_device = libusb_get_device_list(context, &libusb_list);
505 for (ssize_t i = 0; i < total_device; i++)
507 LIBUSB_DEVICE* dev = libusb_list[i];
508 if ((bus_number == libusb_get_bus_number(dev)) &&
509 (dev_number == libusb_get_device_address(dev)))
512 libusb_unref_device(dev);
515 libusb_free_device_list(libusb_list, 0);
519static LIBUSB_DEVICE_DESCRIPTOR* udev_new_descript(
URBDRC_PLUGIN* urbdrc, LIBUSB_DEVICE* libusb_dev)
522 LIBUSB_DEVICE_DESCRIPTOR* descriptor =
523 (LIBUSB_DEVICE_DESCRIPTOR*)calloc(1,
sizeof(LIBUSB_DEVICE_DESCRIPTOR));
526 ret = libusb_get_device_descriptor(libusb_dev, descriptor);
528 if (log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_get_device_descriptor", ret))
537static int libusb_udev_select_interface(IUDEVICE* idev, BYTE InterfaceNumber, BYTE AlternateSetting)
543 if (!pdev || !pdev->urbdrc)
551 if (InterfaceNumber >= MsConfig->NumInterfaces)
561 WLog_Print(urbdrc->log, WLOG_INFO,
562 "select Interface(%" PRIu8
") curr AlternateSetting(%" PRIu8
563 ") new AlternateSetting(%" PRIu8
")",
564 InterfaceNumber, ifc->AlternateSetting, AlternateSetting);
566 if (ifc->AlternateSetting != AlternateSetting)
574 error = libusb_set_interface_alt_setting(pdev->libusb_handle, InterfaceNumber,
577 log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_set_interface_alt_setting", error);
588 UINT32 MsOutSize = 0;
590 if (!pdev || !pdev->LibusbConfig || !pdev->urbdrc || !MsConfig)
594 LIBUSB_CONFIG_DESCRIPTOR* LibusbConfig = pdev->LibusbConfig;
596 if (LibusbConfig->bNumInterfaces != MsConfig->NumInterfaces)
598 WLog_Print(urbdrc->log, WLOG_ERROR,
599 "Select Configuration: Libusb NumberInterfaces(%" PRIu8
") is different "
600 "with MsConfig NumberInterfaces(%" PRIu32
")",
601 LibusbConfig->bNumInterfaces, MsConfig->NumInterfaces);
608 for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
611 if (MsInterface->InterfaceNumber >= MsConfig->NumInterfaces)
613 WLog_Print(urbdrc->log, WLOG_ERROR,
614 "MSUSB_CONFIG_DESCRIPTOR::NumInterfaces (%" PRIu32
615 " <= MSUSB_INTERFACE_DESCRIPTOR::InterfaceNumber( %" PRIu8
")",
616 MsConfig->NumInterfaces, MsInterface->InterfaceNumber);
620 const LIBUSB_INTERFACE* LibusbInterface =
621 &LibusbConfig->interface[MsInterface->InterfaceNumber];
622 if (MsInterface->AlternateSetting >= LibusbInterface->num_altsetting)
624 WLog_Print(urbdrc->log, WLOG_ERROR,
625 "LIBUSB_INTERFACE::num_altsetting (%" PRId32
626 " <= MSUSB_INTERFACE_DESCRIPTOR::AlternateSetting( %" PRIu8
")",
627 LibusbInterface->num_altsetting, MsInterface->AlternateSetting);
632 for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
637 const LIBUSB_INTERFACE* LibusbInterface =
638 &LibusbConfig->interface[MsInterface->InterfaceNumber];
639 const LIBUSB_INTERFACE_DESCRIPTOR* LibusbAltsetting =
640 &LibusbInterface->altsetting[MsInterface->AlternateSetting];
641 const BYTE LibusbNumEndpoint = LibusbAltsetting->bNumEndpoints;
645 for (UINT32 pnum = 0; pnum < LibusbNumEndpoint; pnum++)
650 if (pnum < MsInterface->NumberOfPipes && MsInterface->MsPipes)
653 t_MsPipe->MaximumPacketSize = MsPipe->MaximumPacketSize;
654 t_MsPipe->MaximumTransferSize = MsPipe->MaximumTransferSize;
655 t_MsPipe->PipeFlags = MsPipe->PipeFlags;
659 t_MsPipe->MaximumPacketSize = 0;
660 t_MsPipe->MaximumTransferSize = 0xffffffff;
661 t_MsPipe->PipeFlags = 0;
664 t_MsPipe->PipeHandle = 0;
665 t_MsPipe->bEndpointAddress = 0;
666 t_MsPipe->bInterval = 0;
667 t_MsPipe->PipeType = 0;
668 t_MsPipe->InitCompleted = 0;
669 t_MsPipes[pnum] = t_MsPipe;
672 msusb_mspipes_replace(MsInterface, t_MsPipes, LibusbNumEndpoint);
683 MsConfig->ConfigurationHandle = (uint32_t)MsConfig->bConfigurationValue |
684 ((uint32_t)pdev->bus_number << 24) |
685 (((uint32_t)pdev->dev_number << 16) & 0xFF0000);
686 MsInterfaces = MsConfig->MsInterfaces;
688 for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
693 const LIBUSB_INTERFACE* LibusbInterface =
694 &LibusbConfig->interface[MsInterface->InterfaceNumber];
695 const LIBUSB_INTERFACE_DESCRIPTOR* LibusbAltsetting =
696 &LibusbInterface->altsetting[MsInterface->AlternateSetting];
703 MsInterface->InterfaceHandle =
704 WINPR_ASSERTING_INT_CAST(UINT32, (LibusbAltsetting->bInterfaceNumber |
705 (LibusbAltsetting->bAlternateSetting << 8) |
706 (pdev->dev_number << 16) | (pdev->bus_number << 24)));
707 const size_t len = 16 + (MsInterface->NumberOfPipes * 20);
708 MsInterface->Length = WINPR_ASSERTING_INT_CAST(UINT16, len);
709 MsInterface->bInterfaceClass = LibusbAltsetting->bInterfaceClass;
710 MsInterface->bInterfaceSubClass = LibusbAltsetting->bInterfaceSubClass;
711 MsInterface->bInterfaceProtocol = LibusbAltsetting->bInterfaceProtocol;
712 MsInterface->InitCompleted = 1;
714 const BYTE LibusbNumEndpoint = LibusbAltsetting->bNumEndpoints;
716 for (UINT32 pnum = 0; pnum < LibusbNumEndpoint; pnum++)
722 const LIBUSB_ENDPOINT_DESCEIPTOR* LibusbEndpoint = &LibusbAltsetting->endpoint[pnum];
729 MsPipe->PipeHandle = LibusbEndpoint->bEndpointAddress |
730 (((uint32_t)pdev->dev_number << 16) & 0xFF0000) |
731 (((uint32_t)pdev->bus_number << 24) & 0xFF000000);
733 unsigned max = LibusbEndpoint->wMaxPacketSize & 0x07ff;
734 BYTE attr = LibusbEndpoint->bmAttributes;
736 if ((attr & 0x3) == 1 || (attr & 0x3) == 3)
738 max *= (1 + ((LibusbEndpoint->wMaxPacketSize >> 11) & 3));
741 MsPipe->MaximumPacketSize = WINPR_ASSERTING_INT_CAST(uint16_t, max);
742 MsPipe->bEndpointAddress = LibusbEndpoint->bEndpointAddress;
743 MsPipe->bInterval = LibusbEndpoint->bInterval;
744 MsPipe->PipeType = attr & 0x3;
745 MsPipe->InitCompleted = 1;
749 MsConfig->MsOutSize = WINPR_ASSERTING_INT_CAST(
int, MsOutSize);
750 MsConfig->InitCompleted = 1;
753 if (MsConfig != pdev->MsConfig)
755 msusb_msconfig_free(pdev->MsConfig);
756 pdev->MsConfig = MsConfig;
762static int libusb_udev_select_configuration(IUDEVICE* idev, UINT32 bConfigurationValue)
766 LIBUSB_DEVICE_HANDLE* libusb_handle = NULL;
767 LIBUSB_DEVICE* libusb_dev = NULL;
769 LIBUSB_CONFIG_DESCRIPTOR** LibusbConfig = NULL;
772 if (!pdev || !pdev->MsConfig || !pdev->LibusbConfig || !pdev->urbdrc)
775 urbdrc = pdev->urbdrc;
776 MsConfig = pdev->MsConfig;
777 libusb_handle = pdev->libusb_handle;
778 libusb_dev = pdev->libusb_dev;
779 LibusbConfig = &pdev->LibusbConfig;
781 if (MsConfig->InitCompleted)
783 func_config_release_all_interface(pdev->urbdrc, libusb_handle,
784 (*LibusbConfig)->bNumInterfaces);
788 if (bConfigurationValue == 0)
789 ret = libusb_set_configuration(libusb_handle, -1);
791 ret = libusb_set_configuration(libusb_handle,
792 WINPR_ASSERTING_INT_CAST(
int, bConfigurationValue));
794 if (log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_set_configuration", ret))
796 func_claim_all_interface(urbdrc, libusb_handle, (*LibusbConfig)->bNumInterfaces);
801 ret = libusb_get_active_config_descriptor(libusb_dev, LibusbConfig);
803 if (log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_set_configuration", ret))
805 func_claim_all_interface(urbdrc, libusb_handle, (*LibusbConfig)->bNumInterfaces);
810 func_claim_all_interface(urbdrc, libusb_handle, (*LibusbConfig)->bNumInterfaces);
814static int libusb_udev_control_pipe_request(IUDEVICE* idev, WINPR_ATTR_UNUSED UINT32 RequestId,
815 UINT32 EndpointAddress, UINT32* UsbdStatus,
int command)
820 WINPR_ASSERT(EndpointAddress <= UINT8_MAX);
828 idev->cancel_all_transfer_request(idev);
834 error = libusb_control_transfer(pdev->libusb_handle,
835 (uint8_t)LIBUSB_ENDPOINT_OUT |
836 (uint8_t)LIBUSB_RECIPIENT_ENDPOINT,
837 LIBUSB_REQUEST_SET_FEATURE, ENDPOINT_HALT,
838 (uint16_t)EndpointAddress, NULL, 0, 1000);
842 idev->cancel_all_transfer_request(idev);
843 error = libusb_clear_halt(pdev->libusb_handle, (uint8_t)EndpointAddress);
856static UINT32 libusb_udev_control_query_device_text(IUDEVICE* idev, UINT32 TextType,
857 UINT16 LocaleId, UINT8* BufferSize,
861 LIBUSB_DEVICE_DESCRIPTOR* devDescriptor = NULL;
862 const char strDesc[] =
"Generic Usb String";
863 char deviceLocation[25] = { 0 };
865 BYTE device_address = 0;
869 WCHAR* text = (WCHAR*)Buffer;
872 const UINT8 inSize = *BufferSize;
875 if (!pdev || !pdev->devDescriptor || !pdev->urbdrc)
876 return ERROR_INVALID_DATA;
878 urbdrc = pdev->urbdrc;
879 devDescriptor = pdev->devDescriptor;
883 case DeviceTextDescription:
885 BYTE data[0x100] = { 0 };
886 ret = libusb_get_string_descriptor(pdev->libusb_handle, devDescriptor->iProduct,
887 LocaleId, data, 0xFF);
896 if ((ret <= 0) || (ret <= 4) || (slen <= 4) || (locale != LIBUSB_DT_STRING) ||
899 const char* msg =
"SHORT_DESCRIPTOR";
901 msg = libusb_error_name(ret);
902 WLog_Print(urbdrc->log, WLOG_DEBUG,
903 "libusb_get_string_descriptor: "
904 "%s [%d], iProduct: %" PRIu8
"!",
905 msg, ret, devDescriptor->iProduct);
907 len = MIN(
sizeof(strDesc), inSize);
908 for (
size_t i = 0; i < len; i++)
909 text[i] = (WCHAR)strDesc[i];
911 *BufferSize = (BYTE)(len * 2);
920 const size_t rchar = _wcsnlen((WCHAR*)&data[2],
sizeof(data) / 2);
921 len = MIN((BYTE)ret - 2, slen);
922 len = MIN(len, inSize);
923 len = MIN(len, rchar * 2 +
sizeof(WCHAR));
924 memcpy(Buffer, &data[2], len);
928 Buffer[len - 2] =
'\0';
929 Buffer[len - 1] =
'\0';
930 *BufferSize = (BYTE)len;
935 case DeviceTextLocationInformation:
936 bus_number = libusb_get_bus_number(pdev->libusb_dev);
937 device_address = libusb_get_device_address(pdev->libusb_dev);
938 (void)sprintf_s(deviceLocation,
sizeof(deviceLocation),
939 "Port_#%04" PRIu8
".Hub_#%04" PRIu8
"", device_address, bus_number);
941 len = strnlen(deviceLocation,
942 MIN(
sizeof(deviceLocation), (inSize > 0) ? inSize - 1U : 0));
943 for (
size_t i = 0; i < len; i++)
944 text[i] = (WCHAR)deviceLocation[i];
946 *BufferSize = (UINT8)(len *
sizeof(WCHAR));
950 WLog_Print(urbdrc->log, WLOG_DEBUG,
"Query Text: unknown TextType %" PRIu32
"",
952 return ERROR_INVALID_DATA;
958static int libusb_udev_os_feature_descriptor_request(IUDEVICE* idev,
959 WINPR_ATTR_UNUSED UINT32 RequestId,
960 BYTE Recipient, BYTE InterfaceNumber,
961 BYTE Ms_PageIndex, UINT16 Ms_featureDescIndex,
962 UINT32* UsbdStatus, UINT32* BufferSize,
963 BYTE* Buffer, UINT32 Timeout)
966 BYTE ms_string_desc[0x13] = { 0 };
970 WINPR_ASSERT(UsbdStatus);
971 WINPR_ASSERT(BufferSize);
972 WINPR_ASSERT(*BufferSize <= UINT16_MAX);
977 error = libusb_control_transfer(pdev->libusb_handle, LIBUSB_ENDPOINT_IN | Recipient,
978 LIBUSB_REQUEST_GET_DESCRIPTOR, 0x03ee, 0, ms_string_desc, 0x12,
981 log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG,
"libusb_control_transfer", error);
985 const BYTE bMS_Vendorcode = ms_string_desc[16];
987 error = libusb_control_transfer(
989 (uint8_t)LIBUSB_ENDPOINT_IN | (uint8_t)LIBUSB_REQUEST_TYPE_VENDOR | Recipient,
990 bMS_Vendorcode, (UINT16)((InterfaceNumber << 8) | Ms_PageIndex), Ms_featureDescIndex,
991 Buffer, (UINT16)*BufferSize, Timeout);
992 log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG,
"libusb_control_transfer", error);
995 *BufferSize = (UINT32)error;
999 *UsbdStatus = USBD_STATUS_STALL_PID;
1001 *UsbdStatus = USBD_STATUS_SUCCESS;
1003 return ERROR_SUCCESS;
1006static int libusb_udev_query_device_descriptor(IUDEVICE* idev,
int offset)
1013 return pdev->devDescriptor->bLength;
1015 case B_DESCRIPTOR_TYPE:
1016 return pdev->devDescriptor->bDescriptorType;
1019 return pdev->devDescriptor->bcdUSB;
1021 case B_DEVICE_CLASS:
1022 return pdev->devDescriptor->bDeviceClass;
1024 case B_DEVICE_SUBCLASS:
1025 return pdev->devDescriptor->bDeviceSubClass;
1027 case B_DEVICE_PROTOCOL:
1028 return pdev->devDescriptor->bDeviceProtocol;
1030 case B_MAX_PACKET_SIZE0:
1031 return pdev->devDescriptor->bMaxPacketSize0;
1034 return pdev->devDescriptor->idVendor;
1037 return pdev->devDescriptor->idProduct;
1040 return pdev->devDescriptor->bcdDevice;
1042 case I_MANUFACTURER:
1043 return pdev->devDescriptor->iManufacturer;
1046 return pdev->devDescriptor->iProduct;
1048 case I_SERIAL_NUMBER:
1049 return pdev->devDescriptor->iSerialNumber;
1051 case B_NUM_CONFIGURATIONS:
1052 return pdev->devDescriptor->bNumConfigurations;
1059static BOOL libusb_udev_detach_kernel_driver(IUDEVICE* idev)
1065 if (!pdev || !pdev->LibusbConfig || !pdev->libusb_handle || !pdev->urbdrc)
1071 urbdrc = pdev->urbdrc;
1073 if ((pdev->status & URBDRC_DEVICE_DETACH_KERNEL) == 0)
1075 for (
int i = 0; i < pdev->LibusbConfig->bNumInterfaces; i++)
1077 err = libusb_kernel_driver_active(pdev->libusb_handle, i);
1078 log_libusb_result(urbdrc->log, WLOG_DEBUG,
"libusb_kernel_driver_active", err);
1082 err = libusb_detach_kernel_driver(pdev->libusb_handle, i);
1083 log_libusb_result(urbdrc->log, WLOG_DEBUG,
"libusb_detach_kernel_driver", err);
1087 pdev->status |= URBDRC_DEVICE_DETACH_KERNEL;
1094static BOOL libusb_udev_attach_kernel_driver(IUDEVICE* idev)
1099 if (!pdev || !pdev->LibusbConfig || !pdev->libusb_handle || !pdev->urbdrc)
1102 for (
int i = 0; i < pdev->LibusbConfig->bNumInterfaces && err != LIBUSB_ERROR_NO_DEVICE; i++)
1104 err = libusb_release_interface(pdev->libusb_handle, i);
1106 log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG,
"libusb_release_interface", err);
1109 if (err != LIBUSB_ERROR_NO_DEVICE)
1111 err = libusb_attach_kernel_driver(pdev->libusb_handle, i);
1112 log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG,
"libusb_attach_kernel_driver if=%d",
1121static int libusb_udev_is_composite_device(IUDEVICE* idev)
1124 return pdev->isCompositeDevice;
1127static int libusb_udev_is_exist(IUDEVICE* idev)
1130 return (pdev->status & URBDRC_DEVICE_NOT_FOUND) ? 0 : 1;
1133static int libusb_udev_is_channel_closed(IUDEVICE* idev)
1136 IUDEVMAN* udevman = NULL;
1137 if (!pdev || !pdev->urbdrc)
1140 udevman = pdev->urbdrc->udevman;
1143 if (udevman->status & URBDRC_DEVICE_CHANNEL_CLOSED)
1147 if (pdev->status & URBDRC_DEVICE_CHANNEL_CLOSED)
1153static int libusb_udev_is_already_send(IUDEVICE* idev)
1156 return (pdev->status & URBDRC_DEVICE_ALREADY_SEND) ? 1 : 0;
1161static void libusb_udev_mark_channel_closed(IUDEVICE* idev)
1164 if (pdev && ((pdev->status & URBDRC_DEVICE_CHANNEL_CLOSED) == 0))
1167 const uint8_t busNr = idev->get_bus_number(idev);
1168 const uint8_t devNr = idev->get_dev_number(idev);
1170 pdev->status |= URBDRC_DEVICE_CHANNEL_CLOSED;
1171 pdev->iface.cancel_all_transfer_request(&pdev->iface);
1172 urbdrc->udevman->unregister_udevice(urbdrc->udevman, busNr, devNr);
1178static void libusb_udev_channel_closed(IUDEVICE* idev)
1181 if (pdev && ((pdev->status & URBDRC_DEVICE_CHANNEL_CLOSED) == 0))
1184 const uint8_t busNr = idev->get_bus_number(idev);
1185 const uint8_t devNr = idev->get_dev_number(idev);
1186 IWTSVirtualChannel* channel = NULL;
1188 if (pdev->channelManager)
1189 channel = IFCALLRESULT(NULL, pdev->channelManager->FindChannelById,
1190 pdev->channelManager, pdev->channelID);
1192 pdev->status |= URBDRC_DEVICE_CHANNEL_CLOSED;
1195 channel->Write(channel, 0, NULL, NULL);
1197 urbdrc->udevman->unregister_udevice(urbdrc->udevman, busNr, devNr);
1201static void libusb_udev_set_already_send(IUDEVICE* idev)
1204 pdev->status |= URBDRC_DEVICE_ALREADY_SEND;
1207static char* libusb_udev_get_path(IUDEVICE* idev)
1213static int libusb_udev_query_device_port_status(IUDEVICE* idev, UINT32* UsbdStatus,
1214 UINT32* BufferSize, BYTE* Buffer)
1221 if (!pdev || !pdev->urbdrc)
1224 urbdrc = pdev->urbdrc;
1226 if (pdev->hub_handle != NULL)
1228 ret = idev->control_transfer(
1230 (uint8_t)LIBUSB_ENDPOINT_IN | (uint8_t)LIBUSB_REQUEST_TYPE_CLASS |
1231 (uint8_t)LIBUSB_RECIPIENT_OTHER,
1232 LIBUSB_REQUEST_GET_STATUS, 0, pdev->port_number, UsbdStatus, BufferSize, Buffer, 1000);
1234 if (log_libusb_result(urbdrc->log, WLOG_DEBUG,
"libusb_control_transfer", ret))
1238 WLog_Print(urbdrc->log, WLOG_DEBUG,
1239 "PORT STATUS:0x%02" PRIx8
"%02" PRIx8
"%02" PRIx8
"%02" PRIx8
"", Buffer[3],
1240 Buffer[2], Buffer[1], Buffer[0]);
1249 UINT32 MessageId, UINT32 RequestId, UINT32 EndpointAddress,
1250 WINPR_ATTR_UNUSED UINT32 TransferFlags, UINT32 StartFrame,
1251 UINT32 ErrorCount, BOOL NoAck,
1252 WINPR_ATTR_UNUSED
const BYTE* packetDescriptorData,
1253 UINT32 NumberOfPackets, UINT32 BufferSize,
const BYTE* Buffer,
1254 t_isoch_transfer_cb cb, UINT32 Timeout)
1257 UINT32 iso_packet_size = 0;
1259 ASYNC_TRANSFER_USER_DATA* user_data = NULL;
1260 struct libusb_transfer* iso_transfer = NULL;
1262 size_t outSize = (12ULL * NumberOfPackets);
1263 uint32_t streamID = 0x40000000 | RequestId;
1265 if (!pdev || !pdev->urbdrc)
1268 urbdrc = pdev->urbdrc;
1269 user_data = async_transfer_user_data_new(idev, MessageId, 48, BufferSize, Buffer,
1270 outSize + 1024, NoAck, cb, callback);
1275 user_data->ErrorCount = ErrorCount;
1276 user_data->StartFrame = StartFrame;
1279 Stream_Seek(user_data->data, (12ULL * NumberOfPackets));
1281 if (NumberOfPackets > 0)
1283 iso_packet_size = BufferSize / NumberOfPackets;
1284 iso_transfer = libusb_alloc_transfer((
int)NumberOfPackets);
1287 if (iso_transfer == NULL)
1289 WLog_Print(urbdrc->log, WLOG_ERROR,
1290 "Error: libusb_alloc_transfer [NumberOfPackets=%" PRIu32
", BufferSize=%" PRIu32
1292 NumberOfPackets, BufferSize);
1293 async_transfer_user_data_free(user_data);
1298 libusb_fill_iso_transfer(
1299 iso_transfer, pdev->libusb_handle, WINPR_ASSERTING_INT_CAST(uint8_t, EndpointAddress),
1300 Stream_Pointer(user_data->data), WINPR_ASSERTING_INT_CAST(
int, BufferSize),
1301 WINPR_ASSERTING_INT_CAST(
int, NumberOfPackets), func_iso_callback, user_data, Timeout);
1302 set_stream_id_for_buffer(iso_transfer, streamID);
1303 libusb_set_iso_packet_lengths(iso_transfer, iso_packet_size);
1305 if (!ArrayList_Append(pdev->request_queue, iso_transfer))
1307 WLog_Print(urbdrc->log, WLOG_WARN,
1308 "Failed to queue iso transfer, streamID %08" PRIx32
" already in use!",
1310 request_free(iso_transfer);
1313 rc = libusb_submit_transfer(iso_transfer);
1314 if (log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_submit_transfer", rc))
1319static BOOL libusb_udev_control_transfer(IUDEVICE* idev, WINPR_ATTR_UNUSED UINT32 RequestId,
1320 WINPR_ATTR_UNUSED UINT32 EndpointAddress,
1321 WINPR_ATTR_UNUSED UINT32 TransferFlags, BYTE bmRequestType,
1322 BYTE Request, UINT16 Value, UINT16 Index,
1323 UINT32* UrbdStatus, UINT32* BufferSize, BYTE* Buffer,
1329 WINPR_ASSERT(BufferSize);
1330 WINPR_ASSERT(*BufferSize <= UINT16_MAX);
1332 if (!pdev || !pdev->urbdrc)
1335 status = libusb_control_transfer(pdev->libusb_handle, bmRequestType, Request, Value, Index,
1336 Buffer, (UINT16)*BufferSize, Timeout);
1339 *BufferSize = (UINT32)status;
1341 log_libusb_result(pdev->urbdrc->log, WLOG_ERROR,
"libusb_control_transfer", status);
1343 if (!func_set_usbd_status(pdev->urbdrc, pdev, UrbdStatus, status))
1349static int libusb_udev_bulk_or_interrupt_transfer(IUDEVICE* idev,
1351 UINT32 MessageId, UINT32 RequestId,
1352 UINT32 EndpointAddress, UINT32 TransferFlags,
1353 BOOL NoAck, UINT32 BufferSize,
const BYTE* data,
1354 t_isoch_transfer_cb cb, UINT32 Timeout)
1357 UINT32 transfer_type = 0;
1359 const LIBUSB_ENDPOINT_DESCEIPTOR* ep_desc = NULL;
1360 struct libusb_transfer* transfer = NULL;
1362 ASYNC_TRANSFER_USER_DATA* user_data = NULL;
1363 uint32_t streamID = 0x80000000 | RequestId;
1365 if (!pdev || !pdev->LibusbConfig || !pdev->urbdrc)
1368 urbdrc = pdev->urbdrc;
1370 async_transfer_user_data_new(idev, MessageId, 36, BufferSize, data, 0, NoAck, cb, callback);
1376 transfer = libusb_alloc_transfer(0);
1379 async_transfer_user_data_free(user_data);
1382 transfer->user_data = user_data;
1384 ep_desc = func_get_ep_desc(pdev->LibusbConfig, pdev->MsConfig, EndpointAddress);
1388 WLog_Print(urbdrc->log, WLOG_ERROR,
"func_get_ep_desc: endpoint 0x%" PRIx32
" not found",
1390 request_free(transfer);
1394 transfer_type = (ep_desc->bmAttributes) & 0x3;
1395 WLog_Print(urbdrc->log, WLOG_DEBUG,
1396 "urb_bulk_or_interrupt_transfer: ep:0x%" PRIx32
" "
1397 "transfer_type %" PRIu32
" flag:%" PRIu32
" OutputBufferSize:0x%" PRIx32
"",
1398 EndpointAddress, transfer_type, TransferFlags, BufferSize);
1400 switch (transfer_type)
1404 libusb_fill_bulk_transfer(
1405 transfer, pdev->libusb_handle, WINPR_ASSERTING_INT_CAST(uint8_t, EndpointAddress),
1406 Stream_Pointer(user_data->data), WINPR_ASSERTING_INT_CAST(
int, BufferSize),
1407 func_bulk_transfer_cb, user_data, Timeout);
1410 case INTERRUPT_TRANSFER:
1412 libusb_fill_interrupt_transfer(
1413 transfer, pdev->libusb_handle, WINPR_ASSERTING_INT_CAST(uint8_t, EndpointAddress),
1414 Stream_Pointer(user_data->data), WINPR_ASSERTING_INT_CAST(
int, BufferSize),
1415 func_bulk_transfer_cb, user_data, Timeout);
1419 WLog_Print(urbdrc->log, WLOG_DEBUG,
1420 "urb_bulk_or_interrupt_transfer:"
1421 " other transfer type 0x%" PRIX32
"",
1423 request_free(transfer);
1427 set_stream_id_for_buffer(transfer, streamID);
1429 if (!ArrayList_Append(pdev->request_queue, transfer))
1431 WLog_Print(urbdrc->log, WLOG_WARN,
1432 "Failed to queue transfer, streamID %08" PRIx32
" already in use!", streamID);
1433 request_free(transfer);
1436 rc = libusb_submit_transfer(transfer);
1437 if (log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_submit_transfer", rc))
1442static int func_cancel_xact_request(
URBDRC_PLUGIN* urbdrc,
struct libusb_transfer* transfer)
1446 if (!urbdrc || !transfer)
1449 status = libusb_cancel_transfer(transfer);
1451 if (log_libusb_result(urbdrc->log, WLOG_WARN,
"libusb_cancel_transfer", status))
1453 if (status == LIBUSB_ERROR_NOT_FOUND)
1462static void libusb_udev_cancel_all_transfer_request(IUDEVICE* idev)
1467 if (!pdev || !pdev->request_queue || !pdev->urbdrc)
1470 ArrayList_Lock(pdev->request_queue);
1471 count = ArrayList_Count(pdev->request_queue);
1473 for (
size_t x = 0; x < count; x++)
1475 struct libusb_transfer* transfer = ArrayList_GetItem(pdev->request_queue, x);
1476 func_cancel_xact_request(pdev->urbdrc, transfer);
1479 ArrayList_Unlock(pdev->request_queue);
1482static int libusb_udev_cancel_transfer_request(IUDEVICE* idev, UINT32 RequestId)
1486 struct libusb_transfer* transfer = NULL;
1487 uint32_t cancelID1 = 0x40000000 | RequestId;
1488 uint32_t cancelID2 = 0x80000000 | RequestId;
1490 if (!idev || !pdev->urbdrc || !pdev->request_queue)
1493 ArrayList_Lock(pdev->request_queue);
1494 transfer = list_contains(pdev->request_queue, cancelID1);
1496 transfer = list_contains(pdev->request_queue, cancelID2);
1502 rc = func_cancel_xact_request(urbdrc, transfer);
1504 ArrayList_Unlock(pdev->request_queue);
1508BASIC_STATE_FUNC_DEFINED(channelManager, IWTSVirtualChannelManager*)
1509BASIC_STATE_FUNC_DEFINED(channelID, UINT32)
1510BASIC_STATE_FUNC_DEFINED(ReqCompletion, UINT32)
1511BASIC_STATE_FUNC_DEFINED(bus_number, BYTE)
1512BASIC_STATE_FUNC_DEFINED(dev_number, BYTE)
1513BASIC_STATE_FUNC_DEFINED(port_number, UINT8)
1516BASIC_POINT_FUNC_DEFINED(udev,
void*)
1517BASIC_POINT_FUNC_DEFINED(prev,
void*)
1518BASIC_POINT_FUNC_DEFINED(next,
void*)
1520static UINT32 udev_get_UsbDevice(IUDEVICE* idev)
1527 return pdev->UsbDevice;
1530static void udev_set_UsbDevice(IUDEVICE* idev, UINT32 val)
1537 pdev->UsbDevice = val;
1540static void udev_free(IUDEVICE* idev)
1546 if (!idev || !udev->urbdrc)
1549 urbdrc = udev->urbdrc;
1551 libusb_udev_cancel_all_transfer_request(&udev->iface);
1552 if (udev->libusb_handle)
1554 rc = libusb_reset_device(udev->libusb_handle);
1556 log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_reset_device", rc);
1565 udev->iface.attach_kernel_driver(idev);
1566 ArrayList_Free(udev->request_queue);
1568 msusb_msconfig_free(udev->MsConfig);
1569 libusb_unref_device(udev->libusb_dev);
1570 libusb_close(udev->libusb_handle);
1571 libusb_close(udev->hub_handle);
1572 free(udev->devDescriptor);
1576static void udev_load_interface(
UDEVICE* pdev)
1582 BASIC_STATE_FUNC_REGISTER(channelManager, pdev);
1583 BASIC_STATE_FUNC_REGISTER(channelID, pdev);
1584 BASIC_STATE_FUNC_REGISTER(UsbDevice, pdev);
1585 BASIC_STATE_FUNC_REGISTER(ReqCompletion, pdev);
1586 BASIC_STATE_FUNC_REGISTER(bus_number, pdev);
1587 BASIC_STATE_FUNC_REGISTER(dev_number, pdev);
1588 BASIC_STATE_FUNC_REGISTER(port_number, pdev);
1589 BASIC_STATE_FUNC_REGISTER(MsConfig, pdev);
1590 BASIC_STATE_FUNC_REGISTER(p_udev, pdev);
1591 BASIC_STATE_FUNC_REGISTER(p_prev, pdev);
1592 BASIC_STATE_FUNC_REGISTER(p_next, pdev);
1593 pdev->iface.isCompositeDevice = libusb_udev_is_composite_device;
1594 pdev->iface.isExist = libusb_udev_is_exist;
1595 pdev->iface.isAlreadySend = libusb_udev_is_already_send;
1596 pdev->iface.isChannelClosed = libusb_udev_is_channel_closed;
1597 pdev->iface.setAlreadySend = libusb_udev_set_already_send;
1598 pdev->iface.setChannelClosed = libusb_udev_channel_closed;
1599 pdev->iface.markChannelClosed = libusb_udev_mark_channel_closed;
1600 pdev->iface.getPath = libusb_udev_get_path;
1602 pdev->iface.isoch_transfer = libusb_udev_isoch_transfer;
1603 pdev->iface.control_transfer = libusb_udev_control_transfer;
1604 pdev->iface.bulk_or_interrupt_transfer = libusb_udev_bulk_or_interrupt_transfer;
1605 pdev->iface.select_interface = libusb_udev_select_interface;
1606 pdev->iface.select_configuration = libusb_udev_select_configuration;
1607 pdev->iface.complete_msconfig_setup = libusb_udev_complete_msconfig_setup;
1608 pdev->iface.control_pipe_request = libusb_udev_control_pipe_request;
1609 pdev->iface.control_query_device_text = libusb_udev_control_query_device_text;
1610 pdev->iface.os_feature_descriptor_request = libusb_udev_os_feature_descriptor_request;
1611 pdev->iface.cancel_all_transfer_request = libusb_udev_cancel_all_transfer_request;
1612 pdev->iface.cancel_transfer_request = libusb_udev_cancel_transfer_request;
1613 pdev->iface.query_device_descriptor = libusb_udev_query_device_descriptor;
1614 pdev->iface.detach_kernel_driver = libusb_udev_detach_kernel_driver;
1615 pdev->iface.attach_kernel_driver = libusb_udev_attach_kernel_driver;
1616 pdev->iface.query_device_port_status = libusb_udev_query_device_port_status;
1617 pdev->iface.free = udev_free;
1621 UINT16 bus_number, UINT16 dev_number)
1624 uint8_t port_numbers[16] = { 0 };
1625 LIBUSB_DEVICE** libusb_list = NULL;
1626 const ssize_t total_device = libusb_get_device_list(ctx, &libusb_list);
1628 WINPR_ASSERT(urbdrc);
1631 for (ssize_t i = 0; i < total_device; i++)
1633 LIBUSB_DEVICE* dev = libusb_list[i];
1635 if ((bus_number != libusb_get_bus_number(dev)) ||
1636 (dev_number != libusb_get_device_address(dev)))
1637 libusb_unref_device(dev);
1640 error = libusb_open(dev, &pdev->libusb_handle);
1642 if (log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_open", error))
1644 libusb_unref_device(dev);
1649 error = libusb_get_port_numbers(dev, port_numbers,
sizeof(port_numbers));
1653 log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_get_port_numbers", error);
1654 libusb_unref_device(dev);
1658 pdev->port_number = port_numbers[(error - 1)];
1660 WLog_Print(urbdrc->log, WLOG_DEBUG,
" Port: %" PRIu8, pdev->port_number);
1662 (void)_snprintf(pdev->path,
sizeof(pdev->path),
"%" PRIu16
"-%d", bus_number,
1665 WLog_Print(urbdrc->log, WLOG_DEBUG,
" DevPath: %s", pdev->path);
1668 libusb_free_device_list(libusb_list, 0);
1676 UINT16 bus_number, WINPR_ATTR_UNUSED UINT16 dev_number)
1679 LIBUSB_DEVICE** libusb_list = NULL;
1680 LIBUSB_DEVICE_HANDLE* handle = NULL;
1681 const ssize_t total_device = libusb_get_device_list(ctx, &libusb_list);
1683 WINPR_ASSERT(urbdrc);
1686 for (ssize_t i = 0; i < total_device; i++)
1688 LIBUSB_DEVICE* dev = libusb_list[i];
1690 if ((bus_number != libusb_get_bus_number(dev)) ||
1691 (1 != libusb_get_device_address(dev)))
1692 libusb_unref_device(dev);
1695 WLog_Print(urbdrc->log, WLOG_DEBUG,
" Open hub: %" PRIu16
"", bus_number);
1696 error = libusb_open(dev, &handle);
1698 if (!log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_open", error))
1699 pdev->hub_handle = handle;
1701 libusb_unref_device(dev);
1705 libusb_free_device_list(libusb_list, 0);
1713static void request_free(
void* value)
1715 ASYNC_TRANSFER_USER_DATA* user_data = NULL;
1716 struct libusb_transfer* transfer = (
struct libusb_transfer*)value;
1720 user_data = (ASYNC_TRANSFER_USER_DATA*)transfer->user_data;
1721 async_transfer_user_data_free(user_data);
1722 transfer->user_data = NULL;
1723 libusb_free_transfer(transfer);
1726static IUDEVICE* udev_init(
URBDRC_PLUGIN* urbdrc, libusb_context* context, LIBUSB_DEVICE* device,
1727 BYTE bus_number, BYTE dev_number)
1730 int status = LIBUSB_ERROR_OTHER;
1731 LIBUSB_DEVICE_DESCRIPTOR* devDescriptor = NULL;
1732 LIBUSB_CONFIG_DESCRIPTOR* config_temp = NULL;
1733 LIBUSB_INTERFACE_DESCRIPTOR interface_temp;
1735 WINPR_ASSERT(urbdrc);
1742 pdev->urbdrc = urbdrc;
1743 udev_load_interface(pdev);
1746 pdev->libusb_dev = device;
1748 pdev->libusb_dev = udev_get_libusb_dev(context, bus_number, dev_number);
1750 if (pdev->libusb_dev == NULL)
1753 if (urbdrc->listener_callback)
1754 udev_set_channelManager(&pdev->iface, urbdrc->listener_callback->channel_mgr);
1757 status = udev_get_device_handle(urbdrc, context, pdev, bus_number, dev_number);
1758 if (status != LIBUSB_SUCCESS)
1760 struct libusb_device_descriptor desc;
1761 const uint8_t port = libusb_get_port_number(pdev->libusb_dev);
1762 libusb_get_device_descriptor(pdev->libusb_dev, &desc);
1764 log_libusb_result(urbdrc->log, WLOG_ERROR,
1765 "libusb_open [b=0x%02X,p=0x%02X,a=0x%02X,VID=0x%04X,PID=0x%04X]", status,
1766 bus_number, port, dev_number, desc.idVendor, desc.idProduct);
1771 status = udev_get_hub_handle(urbdrc, context, pdev, bus_number, dev_number);
1774 pdev->hub_handle = NULL;
1776 pdev->devDescriptor = udev_new_descript(urbdrc, pdev->libusb_dev);
1778 if (!pdev->devDescriptor)
1781 status = libusb_get_active_config_descriptor(pdev->libusb_dev, &pdev->LibusbConfig);
1783 if (status == LIBUSB_ERROR_NOT_FOUND)
1784 status = libusb_get_config_descriptor(pdev->libusb_dev, 0, &pdev->LibusbConfig);
1788 log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_get_config_descriptor", status);
1792 config_temp = pdev->LibusbConfig;
1794 interface_temp = config_temp->interface[0].altsetting[0];
1795 WLog_Print(urbdrc->log, WLOG_DEBUG,
1796 "Registered Device: Vid: 0x%04" PRIX16
" Pid: 0x%04" PRIX16
""
1797 " InterfaceClass = %s",
1798 pdev->devDescriptor->idVendor, pdev->devDescriptor->idProduct,
1799 usb_interface_class_to_string(interface_temp.bInterfaceClass));
1801 devDescriptor = pdev->devDescriptor;
1803 if ((devDescriptor->bNumConfigurations == 1) && (config_temp->bNumInterfaces > 1) &&
1804 (devDescriptor->bDeviceClass == LIBUSB_CLASS_PER_INTERFACE))
1806 pdev->isCompositeDevice = 1;
1808 else if ((devDescriptor->bDeviceClass == 0xef) &&
1809 (devDescriptor->bDeviceSubClass == LIBUSB_CLASS_COMM) &&
1810 (devDescriptor->bDeviceProtocol == 0x01))
1812 pdev->isCompositeDevice = 1;
1815 pdev->isCompositeDevice = 0;
1818 devDescriptor->bDeviceClass = interface_temp.bInterfaceClass;
1819 devDescriptor->bDeviceSubClass = interface_temp.bInterfaceSubClass;
1820 devDescriptor->bDeviceProtocol = interface_temp.bInterfaceProtocol;
1822 pdev->bus_number = bus_number;
1823 pdev->dev_number = dev_number;
1824 pdev->request_queue = ArrayList_New(TRUE);
1826 if (!pdev->request_queue)
1829 ArrayList_Object(pdev->request_queue)->
fnObjectFree = request_free;
1832 pdev->MsConfig = msusb_msconfig_new();
1834 if (!pdev->MsConfig)
1838 return &pdev->iface;
1840 pdev->iface.free(&pdev->iface);
1844size_t udev_new_by_id(
URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UINT16 idVendor, UINT16 idProduct,
1845 IUDEVICE*** devArray)
1847 WINPR_ASSERT(urbdrc);
1848 WINPR_ASSERT(devArray);
1851 LIBUSB_DEVICE** libusb_list = NULL;
1855 WLog_Print(urbdrc->log, WLOG_INFO,
"VID: 0x%04" PRIX16
", PID: 0x%04" PRIX16
"", idVendor,
1857 const ssize_t total_device = libusb_get_device_list(ctx, &libusb_list);
1858 if (total_device < 0)
1860 WLog_Print(urbdrc->log, WLOG_ERROR,
"libusb_get_device_list -> [%" PRIdz
"]", total_device);
1863 if (total_device == 0)
1865 WLog_Print(urbdrc->log, WLOG_WARN,
"libusb_get_device_list -> [%" PRIdz
"]", total_device);
1874 for (ssize_t i = 0; i < total_device; i++)
1876 LIBUSB_DEVICE* dev = libusb_list[i];
1877 LIBUSB_DEVICE_DESCRIPTOR* descriptor = udev_new_descript(urbdrc, dev);
1879 if ((descriptor->idVendor == idVendor) && (descriptor->idProduct == idProduct))
1881 const uint8_t nr = libusb_get_bus_number(dev);
1882 const uint8_t addr = libusb_get_device_address(dev);
1883 array[num] = (
PUDEVICE)udev_init(urbdrc, ctx, dev, nr, addr);
1885 if (array[num] != NULL)
1889 WLog_Print(urbdrc->log, WLOG_WARN,
1890 "udev_init(nr=%" PRIu8
", addr=%" PRIu8
") failed", nr, addr);
1894 libusb_unref_device(dev);
1900 libusb_free_device_list(libusb_list, 0);
1901 *devArray = (IUDEVICE**)array;
1905IUDEVICE* udev_new_by_addr(
URBDRC_PLUGIN* urbdrc, libusb_context* context, BYTE bus_number,
1908 WLog_Print(urbdrc->log, WLOG_DEBUG,
"bus:%d dev:%d", bus_number, dev_number);
1909 return udev_init(urbdrc, context, NULL, bus_number, dev_number);
OBJECT_FREE_FN fnObjectFree