25 #include <winpr/sysinfo.h>
27 #include <urbdrc_helpers.h>
29 #include "urbdrc_types.h"
30 #include "data_transfer.h"
32 static void usb_process_get_port_status(IUDEVICE* pdev,
wStream* out)
34 int bcdUSB = pdev->query_device_descriptor(pdev, BCD_USB);
39 Stream_Write_UINT32(out, 0x303);
43 Stream_Write_UINT32(out, 0x103);
48 Stream_Write_UINT32(out, 0x503);
54 wStream* out, UINT32 InterfaceId, UINT32 MessageId,
55 UINT32 RequestId, UINT32 usbd_status, UINT32 OutputBufferSize)
58 return ERROR_INVALID_PARAMETER;
60 if (Stream_Capacity(out) < OutputBufferSize + 36)
62 Stream_Free(out, TRUE);
63 return ERROR_INVALID_PARAMETER;
66 Stream_SetPosition(out, 0);
67 Stream_Write_UINT32(out, InterfaceId);
68 Stream_Write_UINT32(out, MessageId);
70 if (OutputBufferSize != 0)
71 Stream_Write_UINT32(out, URB_COMPLETION);
73 Stream_Write_UINT32(out, URB_COMPLETION_NO_DATA);
75 Stream_Write_UINT32(out, RequestId);
76 Stream_Write_UINT32(out, 8);
78 Stream_Write_UINT16(out, 8);
79 Stream_Write_UINT16(out, 0);
80 Stream_Write_UINT32(out, usbd_status);
81 Stream_Write_UINT32(out, 0);
82 Stream_Write_UINT32(out, OutputBufferSize);
83 Stream_Seek(out, OutputBufferSize);
86 return stream_write_and_free(callback->plugin, callback->channel, out);
88 Stream_Free(out, TRUE);
93 static wStream* urb_create_iocompletion(UINT32 InterfaceField, UINT32 MessageId, UINT32 RequestId,
94 UINT32 OutputBufferSize)
96 const UINT32 InterfaceId = (STREAM_ID_PROXY << 30) | (InterfaceField & 0x3FFFFFFF);
98 #if UINT32_MAX >= SIZE_MAX
99 if (OutputBufferSize > UINT32_MAX - 28ull)
103 wStream* out = Stream_New(NULL, OutputBufferSize + 28ull);
108 Stream_Write_UINT32(out, InterfaceId);
109 Stream_Write_UINT32(out, MessageId);
110 Stream_Write_UINT32(out, IOCONTROL_COMPLETION);
111 Stream_Write_UINT32(out, RequestId);
112 Stream_Write_UINT32(out, USBD_STATUS_SUCCESS);
113 Stream_Write_UINT32(out, OutputBufferSize);
114 Stream_Write_UINT32(out, OutputBufferSize);
118 static UINT urbdrc_process_register_request_callback(IUDEVICE* pdev,
122 UINT32 NumRequestCompletion = 0;
123 UINT32 RequestCompletion = 0;
125 if (!callback || !s || !udevman || !pdev)
126 return ERROR_INVALID_PARAMETER;
131 return ERROR_INVALID_PARAMETER;
133 WLog_Print(urbdrc->log, WLOG_DEBUG,
"urbdrc_process_register_request_callback");
135 if (Stream_GetRemainingLength(s) >= 8)
137 Stream_Read_UINT32(s, NumRequestCompletion);
140 Stream_Read_UINT32(s, RequestCompletion);
141 pdev->set_ReqCompletion(pdev, RequestCompletion);
143 else if (Stream_GetRemainingLength(s) >= 4)
145 Stream_Read_UINT32(s, RequestCompletion);
147 if (pdev->get_ReqCompletion(pdev) == RequestCompletion)
148 pdev->setChannelClosed(pdev);
151 return ERROR_INVALID_DATA;
153 return ERROR_SUCCESS;
156 static UINT urbdrc_process_cancel_request(IUDEVICE* pdev,
wStream* s, IUDEVMAN* udevman)
161 if (!s || !udevman || !pdev)
162 return ERROR_INVALID_PARAMETER;
166 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
167 return ERROR_INVALID_DATA;
169 Stream_Read_UINT32(s, CancelId);
170 WLog_Print(urbdrc->log, WLOG_DEBUG,
"CANCEL_REQUEST: CancelId=%08" PRIx32
"", CancelId);
172 if (pdev->cancel_transfer_request(pdev, CancelId) < 0)
173 return ERROR_INTERNAL_ERROR;
175 return ERROR_SUCCESS;
178 static UINT urbdrc_process_retract_device_request(IUDEVICE* pdev,
wStream* s, IUDEVMAN* udevman)
184 return ERROR_INVALID_PARAMETER;
189 return ERROR_INVALID_PARAMETER;
191 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
192 return ERROR_INVALID_DATA;
194 Stream_Read_UINT32(s, Reason);
198 case UsbRetractReason_BlockedByPolicy:
199 WLog_Print(urbdrc->log, WLOG_DEBUG,
200 "UsbRetractReason_BlockedByPolicy: now it is not support");
201 return ERROR_ACCESS_DENIED;
204 WLog_Print(urbdrc->log, WLOG_DEBUG,
205 "urbdrc_process_retract_device_request: Unknown Reason %" PRIu32
"", Reason);
206 return ERROR_ACCESS_DENIED;
209 return ERROR_SUCCESS;
213 wStream* s, UINT32 MessageId, IUDEVMAN* udevman)
215 UINT32 InterfaceId = 0;
216 UINT32 IoControlCode = 0;
217 UINT32 InputBufferSize = 0;
218 UINT32 OutputBufferSize = 0;
219 UINT32 RequestId = 0;
220 UINT32 usbd_status = USBD_STATUS_SUCCESS;
225 if (!callback || !s || !udevman || !pdev)
226 return ERROR_INVALID_PARAMETER;
231 return ERROR_INVALID_PARAMETER;
233 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
234 return ERROR_INVALID_DATA;
236 Stream_Read_UINT32(s, IoControlCode);
237 Stream_Read_UINT32(s, InputBufferSize);
239 if (!Stream_SafeSeek(s, InputBufferSize))
240 return ERROR_INVALID_DATA;
241 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ULL))
242 return ERROR_INVALID_DATA;
244 Stream_Read_UINT32(s, OutputBufferSize);
245 Stream_Read_UINT32(s, RequestId);
247 if (OutputBufferSize > UINT32_MAX - 4)
248 return ERROR_INVALID_DATA;
250 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
251 out = urb_create_iocompletion(InterfaceId, MessageId, RequestId, OutputBufferSize + 4);
254 return ERROR_OUTOFMEMORY;
256 switch (IoControlCode)
258 case IOCTL_INTERNAL_USB_SUBMIT_URB:
259 WLog_Print(urbdrc->log, WLOG_DEBUG,
"ioctl: IOCTL_INTERNAL_USB_SUBMIT_URB");
260 WLog_Print(urbdrc->log, WLOG_ERROR,
261 " Function IOCTL_INTERNAL_USB_SUBMIT_URB: Unchecked");
264 case IOCTL_INTERNAL_USB_RESET_PORT:
265 WLog_Print(urbdrc->log, WLOG_DEBUG,
"ioctl: IOCTL_INTERNAL_USB_RESET_PORT");
268 case IOCTL_INTERNAL_USB_GET_PORT_STATUS:
269 WLog_Print(urbdrc->log, WLOG_DEBUG,
"ioctl: IOCTL_INTERNAL_USB_GET_PORT_STATUS");
270 success = pdev->query_device_port_status(pdev, &usbd_status, &OutputBufferSize,
271 Stream_Pointer(out));
275 if (!Stream_SafeSeek(out, OutputBufferSize))
277 Stream_Free(out, TRUE);
278 return ERROR_INVALID_DATA;
281 if (pdev->isExist(pdev) == 0)
282 Stream_Write_UINT32(out, 0);
284 usb_process_get_port_status(pdev, out);
289 case IOCTL_INTERNAL_USB_CYCLE_PORT:
290 WLog_Print(urbdrc->log, WLOG_DEBUG,
"ioctl: IOCTL_INTERNAL_USB_CYCLE_PORT");
291 WLog_Print(urbdrc->log, WLOG_ERROR,
292 " Function IOCTL_INTERNAL_USB_CYCLE_PORT: Unchecked");
295 case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
296 WLog_Print(urbdrc->log, WLOG_DEBUG,
297 "ioctl: IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION");
298 WLog_Print(urbdrc->log, WLOG_ERROR,
299 " Function IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: Unchecked");
303 WLog_Print(urbdrc->log, WLOG_DEBUG,
304 "urbdrc_process_io_control: unknown IoControlCode 0x%" PRIX32
"",
306 Stream_Free(out, TRUE);
307 return ERROR_INVALID_OPERATION;
310 return stream_write_and_free(callback->plugin, callback->channel, out);
314 wStream* s, UINT32 MessageId, IUDEVMAN* udevman)
317 UINT32 IoControlCode = 0;
318 UINT32 InterfaceId = 0;
319 UINT32 InputBufferSize = 0;
320 UINT32 OutputBufferSize = 0;
321 UINT32 RequestId = 0;
324 if (!pdev || !callback || !s || !udevman)
325 return ERROR_INVALID_PARAMETER;
327 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
328 return ERROR_INVALID_DATA;
330 Stream_Read_UINT32(s, IoControlCode);
331 Stream_Read_UINT32(s, InputBufferSize);
333 if (!Stream_SafeSeek(s, InputBufferSize))
334 return ERROR_INVALID_DATA;
335 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ULL))
336 return ERROR_INVALID_DATA;
337 Stream_Read_UINT32(s, OutputBufferSize);
338 Stream_Read_UINT32(s, RequestId);
339 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
342 frames = GetTickCount();
343 out = urb_create_iocompletion(InterfaceId, MessageId, RequestId, 4);
346 return ERROR_OUTOFMEMORY;
348 Stream_Write_UINT32(out, frames);
349 return stream_write_and_free(callback->plugin, callback->channel, out);
353 wStream* s, UINT32 MessageId, IUDEVMAN* udevman)
358 UINT32 InterfaceId = 0;
359 UINT8 bufferSize = 0xFF;
362 BYTE DeviceDescription[0x100] = { 0 };
364 if (!pdev || !callback || !s || !udevman)
365 return ERROR_INVALID_PARAMETER;
366 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
367 return ERROR_INVALID_DATA;
369 Stream_Read_UINT32(s, TextType);
370 Stream_Read_UINT32(s, LocaleId);
371 if (LocaleId > UINT16_MAX)
372 return ERROR_INVALID_DATA;
374 hr = pdev->control_query_device_text(pdev, TextType, (UINT16)LocaleId, &bufferSize,
376 InterfaceId = ((STREAM_ID_STUB << 30) | pdev->get_UsbDevice(pdev));
377 out_size = 16 + bufferSize;
382 out = Stream_New(NULL, out_size);
385 return ERROR_OUTOFMEMORY;
387 Stream_Write_UINT32(out, InterfaceId);
388 Stream_Write_UINT32(out, MessageId);
389 Stream_Write_UINT32(out, bufferSize / 2);
390 Stream_Write(out, DeviceDescription, bufferSize);
391 Stream_Write_UINT32(out, hr);
392 return stream_write_and_free(callback->plugin, callback->channel, out);
395 static void func_select_all_interface_for_msconfig(IUDEVICE* pdev,
399 BYTE InterfaceNumber = 0;
400 BYTE AlternateSetting = 0;
401 UINT32 NumInterfaces = MsConfig->NumInterfaces;
403 for (UINT32 inum = 0; inum < NumInterfaces; inum++)
405 InterfaceNumber = MsInterfaces[inum]->InterfaceNumber;
406 AlternateSetting = MsInterfaces[inum]->AlternateSetting;
407 pdev->select_interface(pdev, InterfaceNumber, AlternateSetting);
412 UINT32 RequestField, UINT32 MessageId, IUDEVMAN* udevman,
417 UINT32 InterfaceId = 0;
418 UINT32 NumInterfaces = 0;
419 UINT32 usbd_status = 0;
420 BYTE ConfigurationDescriptorIsValid = 0;
424 const BOOL noAck = (RequestField & 0x80000000U) != 0;
425 const UINT32 RequestId = RequestField & 0x7FFFFFFF;
427 if (!callback || !s || !udevman || !pdev)
428 return ERROR_INVALID_PARAMETER;
433 return ERROR_INVALID_PARAMETER;
435 if (transferDir == 0)
437 WLog_Print(urbdrc->log, WLOG_ERROR,
"urb_select_configuration: unsupported transfer out");
438 return ERROR_INVALID_PARAMETER;
441 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
442 return ERROR_INVALID_DATA;
444 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
445 Stream_Read_UINT8(s, ConfigurationDescriptorIsValid);
447 Stream_Read_UINT32(s, NumInterfaces);
450 if (ConfigurationDescriptorIsValid)
453 MsConfig = msusb_msconfig_read(s, NumInterfaces);
456 return ERROR_INVALID_DATA;
459 pdev->select_configuration(pdev, MsConfig->bConfigurationValue);
461 func_select_all_interface_for_msconfig(pdev, MsConfig);
463 if (!pdev->complete_msconfig_setup(pdev, MsConfig))
465 msusb_msconfig_free(MsConfig);
471 MsOutSize = MsConfig->MsOutSize;
475 if ((
size_t)MsOutSize > SIZE_MAX - 36)
476 return ERROR_INVALID_DATA;
478 out_size = 36 + MsOutSize;
483 out = Stream_New(NULL, out_size);
486 return ERROR_OUTOFMEMORY;
488 Stream_Write_UINT32(out, InterfaceId);
489 Stream_Write_UINT32(out, MessageId);
490 Stream_Write_UINT32(out, URB_COMPLETION_NO_DATA);
491 Stream_Write_UINT32(out, RequestId);
496 Stream_Write_UINT32(out, 8U + (UINT32)MsOutSize);
498 Stream_Write_UINT16(out, 8U + (UINT32)MsOutSize);
502 Stream_Write_UINT32(out, 16);
503 Stream_Write_UINT16(out, 16);
507 Stream_Write_UINT16(out, TS_URB_SELECT_CONFIGURATION);
508 Stream_Write_UINT32(out, usbd_status);
512 msusb_msconfig_write(MsConfig, out);
515 Stream_Write_UINT32(out, 0);
516 Stream_Write_UINT32(out, NumInterfaces);
519 Stream_Write_UINT32(out, 0);
520 Stream_Write_UINT32(out, 0);
523 return stream_write_and_free(callback->plugin, callback->channel, out);
525 Stream_Free(out, TRUE);
527 return ERROR_SUCCESS;
531 UINT32 RequestField, UINT32 MessageId, IUDEVMAN* udevman,
537 UINT32 InterfaceId = 0;
538 UINT32 ConfigurationHandle = 0;
539 UINT32 OutputBufferSize = 0;
540 BYTE InterfaceNumber = 0;
542 UINT32 interface_size = 0;
544 const BOOL noAck = (RequestField & 0x80000000U) != 0;
545 const UINT32 RequestId = RequestField & 0x7FFFFFFF;
547 if (!callback || !s || !udevman || !pdev)
548 return ERROR_INVALID_PARAMETER;
553 return ERROR_INVALID_PARAMETER;
555 if (transferDir == 0)
557 WLog_Print(urbdrc->log, WLOG_ERROR,
"urb_select_interface: not support transfer out");
558 return ERROR_INVALID_PARAMETER;
561 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
562 return ERROR_INVALID_DATA;
564 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
565 Stream_Read_UINT32(s, ConfigurationHandle);
566 MsInterface = msusb_msinterface_read(s);
568 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4) || !MsInterface)
570 msusb_msinterface_free(MsInterface);
571 return ERROR_INVALID_DATA;
574 Stream_Read_UINT32(s, OutputBufferSize);
575 pdev->select_interface(pdev, MsInterface->InterfaceNumber, MsInterface->AlternateSetting);
577 MsConfig = pdev->get_MsConfig(pdev);
578 InterfaceNumber = MsInterface->InterfaceNumber;
579 if (!msusb_msinterface_replace(MsConfig, InterfaceNumber, MsInterface))
581 msusb_msconfig_free(MsConfig);
582 return ERROR_BAD_CONFIGURATION;
585 if (!pdev->complete_msconfig_setup(pdev, MsConfig))
587 msusb_msconfig_free(MsConfig);
588 return ERROR_BAD_CONFIGURATION;
590 MsInterface = MsConfig->MsInterfaces[InterfaceNumber];
591 interface_size = 16 + (MsInterface->NumberOfPipes * 20);
592 out_size = 36 + interface_size;
593 out = Stream_New(NULL, out_size);
596 return ERROR_OUTOFMEMORY;
598 Stream_Write_UINT32(out, InterfaceId);
599 Stream_Write_UINT32(out, MessageId);
600 Stream_Write_UINT32(out, URB_COMPLETION_NO_DATA);
601 Stream_Write_UINT32(out, RequestId);
602 Stream_Write_UINT32(out, 8 + interface_size);
604 Stream_Write_UINT16(out, 8 + interface_size);
606 Stream_Write_UINT16(out, TS_URB_SELECT_INTERFACE);
607 Stream_Write_UINT32(out, USBD_STATUS_SUCCESS);
609 msusb_msinterface_write(MsInterface, out);
610 Stream_Write_UINT32(out, 0);
611 Stream_Write_UINT32(out, 0);
614 return stream_write_and_free(callback->plugin, callback->channel, out);
616 Stream_Free(out, TRUE);
618 return ERROR_SUCCESS;
622 UINT32 RequestField, UINT32 MessageId, IUDEVMAN* udevman,
623 int transferDir,
int External)
626 UINT32 InterfaceId = 0;
627 UINT32 EndpointAddress = 0;
628 UINT32 PipeHandle = 0;
629 UINT32 TransferFlags = 0;
630 UINT32 OutputBufferSize = 0;
631 UINT32 usbd_status = 0;
633 BYTE bmRequestType = 0;
641 const BOOL noAck = (RequestField & 0x80000000U) != 0;
642 const UINT32 RequestId = RequestField & 0x7FFFFFFF;
644 if (!callback || !s || !udevman || !pdev)
645 return ERROR_INVALID_PARAMETER;
650 return ERROR_INVALID_PARAMETER;
652 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
653 return ERROR_INVALID_DATA;
655 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
656 Stream_Read_UINT32(s, PipeHandle);
657 Stream_Read_UINT32(s, TransferFlags);
658 EndpointAddress = (PipeHandle & 0x000000ff);
663 case URB_CONTROL_TRANSFER_EXTERNAL:
664 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
665 return ERROR_INVALID_DATA;
667 Stream_Read_UINT32(s, Timeout);
670 case URB_CONTROL_TRANSFER_NONEXTERNAL:
677 if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
678 return ERROR_INVALID_DATA;
680 Stream_Read_UINT8(s, bmRequestType);
681 Stream_Read_UINT8(s, Request);
682 Stream_Read_UINT16(s, Value);
683 Stream_Read_UINT16(s, Index);
684 Stream_Read_UINT16(s, length);
685 Stream_Read_UINT32(s, OutputBufferSize);
687 if (length != OutputBufferSize)
689 WLog_Print(urbdrc->log, WLOG_ERROR,
"urb_control_transfer ERROR: buf != length");
690 return ERROR_INVALID_DATA;
693 out_size = 36 + OutputBufferSize;
694 out = Stream_New(NULL, out_size);
697 return ERROR_OUTOFMEMORY;
699 Stream_Seek(out, 36);
701 buffer = Stream_Pointer(out);
703 if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
705 if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
707 Stream_Free(out, TRUE);
708 return ERROR_INVALID_DATA;
710 Stream_Copy(s, out, OutputBufferSize);
714 if (!pdev->control_transfer(pdev, RequestId, EndpointAddress, TransferFlags, bmRequestType,
715 Request, Value, Index, &usbd_status, &OutputBufferSize, buffer,
718 WLog_Print(urbdrc->log, WLOG_ERROR,
"control_transfer failed");
719 Stream_Free(out, TRUE);
720 return ERROR_INTERNAL_ERROR;
723 return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
724 usbd_status, OutputBufferSize);
728 UINT32 InterfaceId, BOOL noAck, UINT32 MessageId, UINT32 RequestId,
729 UINT32 NumberOfPackets, UINT32 status, UINT32 StartFrame,
730 UINT32 ErrorCount, UINT32 OutputBufferSize)
732 if (!pdev->isChannelClosed(pdev))
733 urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId, status,
736 Stream_Free(out, TRUE);
740 wStream* s, UINT32 RequestField, UINT32 MessageId,
741 IUDEVMAN* udevman,
int transferDir)
743 UINT32 EndpointAddress = 0;
744 UINT32 PipeHandle = 0;
745 UINT32 TransferFlags = 0;
746 UINT32 OutputBufferSize = 0;
747 const BOOL noAck = (RequestField & 0x80000000U) != 0;
748 const UINT32 RequestId = RequestField & 0x7FFFFFFF;
750 if (!pdev || !callback || !s || !udevman)
751 return ERROR_INVALID_PARAMETER;
753 if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
754 return ERROR_INVALID_DATA;
756 Stream_Read_UINT32(s, PipeHandle);
757 Stream_Read_UINT32(s, TransferFlags);
758 Stream_Read_UINT32(s, OutputBufferSize);
759 EndpointAddress = (PipeHandle & 0x000000ff);
761 if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
763 if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
765 return ERROR_INVALID_DATA;
770 return pdev->bulk_or_interrupt_transfer(
771 pdev, callback, MessageId, RequestId, EndpointAddress, TransferFlags, noAck,
772 OutputBufferSize, (transferDir == USBD_TRANSFER_DIRECTION_OUT) ? Stream_Pointer(s) : NULL,
773 urb_bulk_transfer_cb, 10000);
777 UINT32 InterfaceId, BOOL noAck, UINT32 MessageId,
778 UINT32 RequestId, UINT32 NumberOfPackets, UINT32 status,
779 UINT32 StartFrame, UINT32 ErrorCount, UINT32 OutputBufferSize)
783 UINT32 packetSize = (status == 0) ? NumberOfPackets * 12 : 0;
784 Stream_SetPosition(out, 0);
786 Stream_Write_UINT32(out, InterfaceId);
787 Stream_Write_UINT32(out, MessageId);
789 if (OutputBufferSize == 0)
790 Stream_Write_UINT32(out, URB_COMPLETION_NO_DATA);
792 Stream_Write_UINT32(out, URB_COMPLETION);
794 Stream_Write_UINT32(out, RequestId);
795 Stream_Write_UINT32(out, 20 + packetSize);
797 Stream_Write_UINT16(out, 20 + packetSize);
798 Stream_Write_UINT16(out, 0);
799 Stream_Write_UINT32(out, status);
800 Stream_Write_UINT32(out, StartFrame);
805 Stream_Write_UINT32(out, NumberOfPackets);
806 Stream_Write_UINT32(out, ErrorCount);
807 Stream_Seek(out, packetSize);
811 Stream_Write_UINT32(out, 0);
812 Stream_Write_UINT32(out, ErrorCount);
815 Stream_Write_UINT32(out, 0);
816 Stream_Write_UINT32(out, OutputBufferSize);
817 Stream_Seek(out, OutputBufferSize);
819 stream_write_and_free(callback->plugin, callback->channel, out);
824 UINT32 RequestField, UINT32 MessageId, IUDEVMAN* udevman,
828 UINT32 EndpointAddress = 0;
829 UINT32 PipeHandle = 0;
830 UINT32 TransferFlags = 0;
831 UINT32 StartFrame = 0;
832 UINT32 NumberOfPackets = 0;
833 UINT32 ErrorCount = 0;
834 UINT32 OutputBufferSize = 0;
835 BYTE* packetDescriptorData = NULL;
836 const BOOL noAck = (RequestField & 0x80000000U) != 0;
837 const UINT32 RequestId = RequestField & 0x7FFFFFFF;
839 if (!pdev || !callback || !udevman)
840 return ERROR_INVALID_PARAMETER;
842 if (!Stream_CheckAndLogRequiredLength(TAG, s, 20))
843 return ERROR_INVALID_DATA;
845 Stream_Read_UINT32(s, PipeHandle);
846 EndpointAddress = (PipeHandle & 0x000000ff);
847 Stream_Read_UINT32(s, TransferFlags);
848 Stream_Read_UINT32(s, StartFrame);
849 Stream_Read_UINT32(s, NumberOfPackets);
850 Stream_Read_UINT32(s, ErrorCount);
852 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, NumberOfPackets, 12ull))
853 return ERROR_INVALID_DATA;
855 packetDescriptorData = Stream_Pointer(s);
856 Stream_Seek(s, 12ULL * NumberOfPackets);
858 if (!Stream_CheckAndLogRequiredLength(TAG, s,
sizeof(UINT32)))
859 return ERROR_INVALID_DATA;
860 Stream_Read_UINT32(s, OutputBufferSize);
862 if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
864 if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
865 return ERROR_INVALID_DATA;
868 rc = pdev->isoch_transfer(
869 pdev, callback, MessageId, RequestId, EndpointAddress, TransferFlags, StartFrame,
870 ErrorCount, noAck, packetDescriptorData, NumberOfPackets, OutputBufferSize,
871 (transferDir == USBD_TRANSFER_DIRECTION_OUT) ? Stream_Pointer(s) : NULL,
872 urb_isoch_transfer_cb, 2000);
875 return ERROR_INTERNAL_ERROR;
880 wStream* s, UINT32 RequestField, UINT32 MessageId,
881 IUDEVMAN* udevman, BYTE func_recipient,
int transferDir)
884 UINT32 InterfaceId = 0;
885 UINT32 OutputBufferSize = 0;
886 UINT32 usbd_status = 0;
887 BYTE bmRequestType = 0;
893 const BOOL noAck = (RequestField & 0x80000000U) != 0;
894 const UINT32 RequestId = RequestField & 0x7FFFFFFF;
896 if (!callback || !s || !udevman || !pdev)
897 return ERROR_INVALID_PARAMETER;
902 return ERROR_INVALID_PARAMETER;
904 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
905 return ERROR_INVALID_DATA;
907 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
908 Stream_Read_UINT8(s, desc_index);
909 Stream_Read_UINT8(s, desc_type);
910 Stream_Read_UINT16(s, langId);
911 Stream_Read_UINT32(s, OutputBufferSize);
912 if (OutputBufferSize > UINT32_MAX - 36)
913 return ERROR_INVALID_DATA;
914 if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
916 if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
917 return ERROR_INVALID_DATA;
920 out_size = 36ULL + OutputBufferSize;
921 out = Stream_New(NULL, out_size);
924 return ERROR_OUTOFMEMORY;
926 Stream_Seek(out, 36);
927 bmRequestType = func_recipient;
931 case USBD_TRANSFER_DIRECTION_IN:
932 bmRequestType |= 0x80;
935 case USBD_TRANSFER_DIRECTION_OUT:
936 bmRequestType |= 0x00;
937 Stream_Copy(s, out, OutputBufferSize);
938 Stream_Rewind(out, OutputBufferSize);
942 WLog_Print(urbdrc->log, WLOG_DEBUG,
"get error transferDir");
943 OutputBufferSize = 0;
944 usbd_status = USBD_STATUS_STALL_PID;
949 if (!pdev->control_transfer(pdev, RequestId, 0, 0, bmRequestType,
951 (desc_type << 8) | desc_index, langId, &usbd_status,
952 &OutputBufferSize, Stream_Pointer(out), 1000))
954 WLog_Print(urbdrc->log, WLOG_ERROR,
"get_descriptor failed");
955 Stream_Free(out, TRUE);
956 return ERROR_INTERNAL_ERROR;
959 return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
960 usbd_status, OutputBufferSize);
964 wStream* s, UINT32 RequestField, UINT32 MessageId,
965 IUDEVMAN* udevman, BYTE func_recipient,
int transferDir)
968 UINT32 InterfaceId = 0;
969 UINT32 OutputBufferSize = 0;
970 UINT32 usbd_status = 0;
972 BYTE bmRequestType = 0;
975 const BOOL noAck = (RequestField & 0x80000000U) != 0;
976 const UINT32 RequestId = RequestField & 0x7FFFFFFF;
978 if (!callback || !s || !udevman || !pdev)
979 return ERROR_INVALID_PARAMETER;
984 return ERROR_INVALID_PARAMETER;
986 if (transferDir == 0)
988 WLog_Print(urbdrc->log, WLOG_DEBUG,
989 "urb_control_get_status_request: transfer out not supported");
990 return ERROR_INVALID_PARAMETER;
993 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
994 return ERROR_INVALID_DATA;
996 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
997 Stream_Read_UINT16(s, Index);
999 Stream_Read_UINT32(s, OutputBufferSize);
1000 if (OutputBufferSize > UINT32_MAX - 36)
1001 return ERROR_INVALID_DATA;
1002 out_size = 36ULL + OutputBufferSize;
1003 out = Stream_New(NULL, out_size);
1006 return ERROR_OUTOFMEMORY;
1008 Stream_Seek(out, 36);
1009 bmRequestType = func_recipient | 0x80;
1011 if (!pdev->control_transfer(pdev, RequestId, 0, 0, bmRequestType, 0x00,
1012 0, Index, &usbd_status, &OutputBufferSize, Stream_Pointer(out),
1015 WLog_Print(urbdrc->log, WLOG_ERROR,
"control_transfer failed");
1016 Stream_Free(out, TRUE);
1017 return ERROR_INTERNAL_ERROR;
1020 return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
1021 usbd_status, OutputBufferSize);
1025 wStream* s, UINT32 RequestField, UINT32 MessageId,
1026 IUDEVMAN* udevman, BYTE func_type,
1027 BYTE func_recipient,
int transferDir)
1029 UINT32 out_size = 0;
1030 UINT32 InterfaceId = 0;
1031 UINT32 TransferFlags = 0;
1032 UINT32 usbd_status = 0;
1033 UINT32 OutputBufferSize = 0;
1034 BYTE ReqTypeReservedBits = 0;
1036 BYTE bmRequestType = 0;
1041 const BOOL noAck = (RequestField & 0x80000000U) != 0;
1042 const UINT32 RequestId = RequestField & 0x7FFFFFFF;
1044 if (!callback || !s || !udevman || !pdev)
1045 return ERROR_INVALID_PARAMETER;
1050 return ERROR_INVALID_PARAMETER;
1052 if (!Stream_CheckAndLogRequiredLength(TAG, s, 16))
1053 return ERROR_INVALID_DATA;
1055 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
1056 Stream_Read_UINT32(s, TransferFlags);
1057 Stream_Read_UINT8(s, ReqTypeReservedBits);
1058 Stream_Read_UINT8(s, Request);
1059 Stream_Read_UINT16(s, Value);
1060 Stream_Read_UINT16(s, Index);
1061 Stream_Seek_UINT16(s);
1062 Stream_Read_UINT32(s, OutputBufferSize);
1063 if (OutputBufferSize > UINT32_MAX - 36)
1064 return ERROR_INVALID_DATA;
1066 if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
1068 if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
1069 return ERROR_INVALID_DATA;
1072 out_size = 36ULL + OutputBufferSize;
1073 out = Stream_New(NULL, out_size);
1076 return ERROR_OUTOFMEMORY;
1078 Stream_Seek(out, 36);
1081 if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
1083 Stream_Copy(s, out, OutputBufferSize);
1084 Stream_Rewind(out, OutputBufferSize);
1088 bmRequestType = func_type | func_recipient;
1090 if (TransferFlags & USBD_TRANSFER_DIRECTION)
1091 bmRequestType |= 0x80;
1093 WLog_Print(urbdrc->log, WLOG_DEBUG,
1094 "RequestId 0x%" PRIx32
" TransferFlags: 0x%" PRIx32
" ReqTypeReservedBits: 0x%" PRIx8
1096 "Request:0x%" PRIx8
" Value: 0x%" PRIx16
" Index: 0x%" PRIx16
1097 " OutputBufferSize: 0x%" PRIx32
" bmRequestType: 0x%" PRIx8,
1098 RequestId, TransferFlags, ReqTypeReservedBits, Request, Value, Index,
1099 OutputBufferSize, bmRequestType);
1101 if (!pdev->control_transfer(pdev, RequestId, 0, 0, bmRequestType, Request, Value, Index,
1102 &usbd_status, &OutputBufferSize, Stream_Pointer(out), 2000))
1104 WLog_Print(urbdrc->log, WLOG_ERROR,
"control_transfer failed");
1105 Stream_Free(out, TRUE);
1106 return ERROR_INTERNAL_ERROR;
1109 return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
1110 usbd_status, OutputBufferSize);
1114 wStream* s, UINT32 RequestField, UINT32 MessageId,
1115 IUDEVMAN* udevman,
int transferDir)
1117 size_t out_size = 0;
1118 UINT32 InterfaceId = 0;
1119 UINT32 OutputBufferSize = 0;
1120 UINT32 usbd_status = 0;
1122 BYTE InterfaceNumber = 0;
1123 BYTE Ms_PageIndex = 0;
1124 UINT16 Ms_featureDescIndex = 0;
1128 const BOOL noAck = (RequestField & 0x80000000U) != 0;
1129 const UINT32 RequestId = RequestField & 0x7FFFFFFF;
1131 if (!callback || !s || !udevman || !pdev)
1132 return ERROR_INVALID_PARAMETER;
1137 return ERROR_INVALID_PARAMETER;
1139 if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
1140 return ERROR_INVALID_DATA;
1143 Stream_Read_UINT8(s, Recipient);
1144 Recipient = (Recipient & 0x1f);
1145 Stream_Read_UINT8(s, InterfaceNumber);
1146 Stream_Read_UINT8(s, Ms_PageIndex);
1147 Stream_Read_UINT16(s, Ms_featureDescIndex);
1149 Stream_Read_UINT32(s, OutputBufferSize);
1150 if (OutputBufferSize > UINT32_MAX - 36)
1151 return ERROR_INVALID_DATA;
1153 switch (transferDir)
1155 case USBD_TRANSFER_DIRECTION_OUT:
1156 if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
1157 return ERROR_INVALID_DATA;
1165 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
1166 out_size = 36ULL + OutputBufferSize;
1167 out = Stream_New(NULL, out_size);
1170 return ERROR_OUTOFMEMORY;
1172 Stream_Seek(out, 36);
1174 switch (transferDir)
1176 case USBD_TRANSFER_DIRECTION_OUT:
1177 Stream_Copy(s, out, OutputBufferSize);
1178 Stream_Rewind(out, OutputBufferSize);
1181 case USBD_TRANSFER_DIRECTION_IN:
1187 WLog_Print(urbdrc->log, WLOG_DEBUG,
1188 "Ms descriptor arg: Recipient:0x%" PRIx8
", "
1189 "InterfaceNumber:0x%" PRIx8
", Ms_PageIndex:0x%" PRIx8
", "
1190 "Ms_featureDescIndex:0x%" PRIx16
", OutputBufferSize:0x%" PRIx32
"",
1191 Recipient, InterfaceNumber, Ms_PageIndex, Ms_featureDescIndex, OutputBufferSize);
1193 ret = pdev->os_feature_descriptor_request(pdev, RequestId, Recipient, InterfaceNumber,
1194 Ms_PageIndex, Ms_featureDescIndex, &usbd_status,
1195 &OutputBufferSize, Stream_Pointer(out), 1000);
1198 WLog_Print(urbdrc->log, WLOG_DEBUG,
"os_feature_descriptor_request: error num %d", ret);
1200 return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
1201 usbd_status, OutputBufferSize);
1205 UINT32 RequestField, UINT32 MessageId, IUDEVMAN* udevman,
1206 int transferDir,
int action)
1208 UINT32 out_size = 0;
1209 UINT32 InterfaceId = 0;
1210 UINT32 PipeHandle = 0;
1211 UINT32 EndpointAddress = 0;
1212 UINT32 OutputBufferSize = 0;
1213 UINT32 usbd_status = 0;
1215 UINT32 ret = USBD_STATUS_REQUEST_FAILED;
1218 const BOOL noAck = (RequestField & 0x80000000U) != 0;
1219 const UINT32 RequestId = RequestField & 0x7FFFFFFF;
1221 if (!callback || !s || !udevman || !pdev)
1222 return ERROR_INVALID_PARAMETER;
1227 return ERROR_INVALID_PARAMETER;
1229 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1230 return ERROR_INVALID_DATA;
1232 if (transferDir == 0)
1234 WLog_Print(urbdrc->log, WLOG_DEBUG,
"urb_pipe_request: not support transfer out");
1235 return ERROR_INVALID_PARAMETER;
1238 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
1239 Stream_Read_UINT32(s, PipeHandle);
1240 Stream_Read_UINT32(s, OutputBufferSize);
1241 EndpointAddress = (PipeHandle & 0x000000ff);
1246 rc = pdev->control_pipe_request(pdev, RequestId, EndpointAddress, &usbd_status,
1250 WLog_Print(urbdrc->log, WLOG_DEBUG,
"PIPE SET HALT: error %d", ret);
1252 ret = USBD_STATUS_SUCCESS;
1257 WLog_Print(urbdrc->log, WLOG_DEBUG,
"urb_pipe_request: PIPE_RESET ep 0x%" PRIx32
"",
1259 rc = pdev->control_pipe_request(pdev, RequestId, EndpointAddress, &usbd_status,
1263 WLog_Print(urbdrc->log, WLOG_DEBUG,
"PIPE RESET: error %d", ret);
1265 ret = USBD_STATUS_SUCCESS;
1270 WLog_Print(urbdrc->log, WLOG_DEBUG,
"urb_pipe_request action: %d not supported",
1272 ret = USBD_STATUS_INVALID_URB_FUNCTION;
1278 out = Stream_New(NULL, out_size);
1281 return ERROR_OUTOFMEMORY;
1283 return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId, ret,
1288 wStream* s, UINT32 RequestField, UINT32 MessageId,
1289 IUDEVMAN* udevman,
int transferDir)
1291 UINT32 out_size = 0;
1292 UINT32 InterfaceId = 0;
1293 UINT32 OutputBufferSize = 0;
1294 UINT32 dummy_frames = 0;
1297 const BOOL noAck = (RequestField & 0x80000000U) != 0;
1298 const UINT32 RequestId = RequestField & 0x7FFFFFFF;
1300 if (!callback || !s || !udevman || !pdev)
1301 return ERROR_INVALID_PARAMETER;
1306 return ERROR_INVALID_PARAMETER;
1308 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1309 return ERROR_INVALID_DATA;
1311 if (transferDir == 0)
1313 WLog_Print(urbdrc->log, WLOG_DEBUG,
1314 "urb_get_current_frame_number: not support transfer out");
1315 return ERROR_INVALID_PARAMETER;
1318 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
1319 Stream_Read_UINT32(s, OutputBufferSize);
1321 dummy_frames = GetTickCount();
1323 out = Stream_New(NULL, out_size);
1326 return ERROR_OUTOFMEMORY;
1328 Stream_Write_UINT32(out, InterfaceId);
1329 Stream_Write_UINT32(out, MessageId);
1330 Stream_Write_UINT32(out, URB_COMPLETION_NO_DATA);
1331 Stream_Write_UINT32(out, RequestId);
1332 Stream_Write_UINT32(out, 12);
1334 Stream_Write_UINT16(out, 12);
1336 Stream_Write_UINT16(out, TS_URB_GET_CURRENT_FRAME_NUMBER);
1337 Stream_Write_UINT32(out, USBD_STATUS_SUCCESS);
1338 Stream_Write_UINT32(out, dummy_frames);
1339 Stream_Write_UINT32(out, 0);
1340 Stream_Write_UINT32(out, 0);
1343 return stream_write_and_free(callback->plugin, callback->channel, out);
1345 Stream_Free(out, TRUE);
1347 return ERROR_SUCCESS;
1351 static UINT urb_control_get_configuration_request(IUDEVICE* pdev,
1353 UINT32 RequestField, UINT32 MessageId,
1354 IUDEVMAN* udevman,
int transferDir)
1356 size_t out_size = 0;
1357 UINT32 InterfaceId = 0;
1358 UINT32 OutputBufferSize = 0;
1359 UINT32 usbd_status = 0;
1362 const BOOL noAck = (RequestField & 0x80000000U) != 0;
1363 const UINT32 RequestId = RequestField & 0x7FFFFFFF;
1365 if (!callback || !s || !udevman || !pdev)
1366 return ERROR_INVALID_PARAMETER;
1371 return ERROR_INVALID_PARAMETER;
1373 if (transferDir == 0)
1375 WLog_Print(urbdrc->log, WLOG_DEBUG,
1376 "urb_control_get_configuration_request:"
1377 " not support transfer out");
1378 return ERROR_INVALID_PARAMETER;
1381 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1382 return ERROR_INVALID_DATA;
1384 Stream_Read_UINT32(s, OutputBufferSize);
1385 if (OutputBufferSize > UINT32_MAX - 36)
1386 return ERROR_INVALID_DATA;
1387 out_size = 36ULL + OutputBufferSize;
1388 out = Stream_New(NULL, out_size);
1391 return ERROR_OUTOFMEMORY;
1393 Stream_Seek(out, 36);
1394 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
1396 if (!pdev->control_transfer(pdev, RequestId, 0, 0, 0x80 | 0x00,
1398 0, 0, &usbd_status, &OutputBufferSize, Stream_Pointer(out), 1000))
1400 WLog_Print(urbdrc->log, WLOG_DEBUG,
"control_transfer failed");
1401 Stream_Free(out, TRUE);
1402 return ERROR_INTERNAL_ERROR;
1405 return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
1406 usbd_status, OutputBufferSize);
1411 wStream* s, UINT32 RequestField, UINT32 MessageId,
1412 IUDEVMAN* udevman,
int transferDir)
1414 size_t out_size = 0;
1415 UINT32 InterfaceId = 0;
1416 UINT32 OutputBufferSize = 0;
1417 UINT32 usbd_status = 0;
1418 UINT16 InterfaceNr = 0;
1421 const BOOL noAck = (RequestField & 0x80000000U) != 0;
1422 const UINT32 RequestId = RequestField & 0x7FFFFFFF;
1424 if (!callback || !s || !udevman || !pdev)
1425 return ERROR_INVALID_PARAMETER;
1430 return ERROR_INVALID_PARAMETER;
1432 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1433 return ERROR_INVALID_DATA;
1435 if (transferDir == 0)
1437 WLog_Print(urbdrc->log, WLOG_DEBUG,
1438 "urb_control_get_interface_request: not support transfer out");
1439 return ERROR_INVALID_PARAMETER;
1442 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
1443 Stream_Read_UINT16(s, InterfaceNr);
1445 Stream_Read_UINT32(s, OutputBufferSize);
1446 if (OutputBufferSize > UINT32_MAX - 36)
1447 return ERROR_INVALID_DATA;
1448 out_size = 36ULL + OutputBufferSize;
1449 out = Stream_New(NULL, out_size);
1452 return ERROR_OUTOFMEMORY;
1454 Stream_Seek(out, 36);
1456 if (!pdev->control_transfer(
1457 pdev, RequestId, 0, 0, 0x80 | 0x01, 0x0A,
1458 0, InterfaceNr, &usbd_status, &OutputBufferSize, Stream_Pointer(out), 1000))
1460 WLog_Print(urbdrc->log, WLOG_DEBUG,
"control_transfer failed");
1461 Stream_Free(out, TRUE);
1462 return ERROR_INTERNAL_ERROR;
1465 return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
1466 usbd_status, OutputBufferSize);
1470 wStream* s, UINT32 RequestField, UINT32 MessageId,
1471 IUDEVMAN* udevman, BYTE func_recipient, BYTE command,
1474 UINT32 InterfaceId = 0;
1475 UINT32 OutputBufferSize = 0;
1476 UINT32 usbd_status = 0;
1477 UINT16 FeatureSelector = 0;
1479 BYTE bmRequestType = 0;
1483 const BOOL noAck = (RequestField & 0x80000000U) != 0;
1484 const UINT32 RequestId = RequestField & 0x7FFFFFFF;
1486 if (!callback || !s || !udevman || !pdev)
1487 return ERROR_INVALID_PARAMETER;
1492 return ERROR_INVALID_PARAMETER;
1494 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1495 return ERROR_INVALID_DATA;
1497 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
1498 Stream_Read_UINT16(s, FeatureSelector);
1499 Stream_Read_UINT16(s, Index);
1500 Stream_Read_UINT32(s, OutputBufferSize);
1501 if (OutputBufferSize > UINT32_MAX - 36)
1502 return ERROR_INVALID_DATA;
1503 switch (transferDir)
1505 case USBD_TRANSFER_DIRECTION_OUT:
1506 if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
1507 return ERROR_INVALID_DATA;
1515 out = Stream_New(NULL, 36ULL + OutputBufferSize);
1518 return ERROR_OUTOFMEMORY;
1520 Stream_Seek(out, 36);
1521 bmRequestType = func_recipient;
1523 switch (transferDir)
1525 case USBD_TRANSFER_DIRECTION_OUT:
1526 WLog_Print(urbdrc->log, WLOG_ERROR,
1527 "Function urb_control_feature_request: OUT Unchecked");
1528 Stream_Copy(s, out, OutputBufferSize);
1529 Stream_Rewind(out, OutputBufferSize);
1530 bmRequestType |= 0x00;
1533 case USBD_TRANSFER_DIRECTION_IN:
1534 bmRequestType |= 0x80;
1542 case URB_SET_FEATURE:
1546 case URB_CLEAR_FEATURE:
1551 WLog_Print(urbdrc->log, WLOG_ERROR,
1552 "urb_control_feature_request: Error Command 0x%02" PRIx8
"", command);
1553 Stream_Free(out, TRUE);
1554 return ERROR_INTERNAL_ERROR;
1557 if (!pdev->control_transfer(pdev, RequestId, 0, 0, bmRequestType, bmRequest, FeatureSelector,
1558 Index, &usbd_status, &OutputBufferSize, Stream_Pointer(out), 1000))
1560 WLog_Print(urbdrc->log, WLOG_DEBUG,
"feature control transfer failed");
1561 Stream_Free(out, TRUE);
1562 return ERROR_INTERNAL_ERROR;
1565 return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
1566 usbd_status, OutputBufferSize);
1570 wStream* s, UINT32 MessageId, IUDEVMAN* udevman,
1575 UINT16 URB_Function = 0;
1576 UINT32 RequestId = 0;
1577 UINT error = ERROR_INTERNAL_ERROR;
1580 if (!callback || !s || !udevman || !pdev)
1581 return ERROR_INVALID_PARAMETER;
1586 return ERROR_INVALID_PARAMETER;
1588 if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
1589 return ERROR_INVALID_DATA;
1591 Stream_Read_UINT32(s, CbTsUrb);
1592 Stream_Read_UINT16(s, Size);
1593 Stream_Read_UINT16(s, URB_Function);
1594 Stream_Read_UINT32(s, RequestId);
1595 WLog_Print(urbdrc->log, WLOG_DEBUG,
"URB %s[%" PRIu16
"]", urb_function_string(URB_Function),
1598 switch (URB_Function)
1600 case TS_URB_SELECT_CONFIGURATION:
1601 error = urb_select_configuration(pdev, callback, s, RequestId, MessageId, udevman,
1605 case TS_URB_SELECT_INTERFACE:
1607 urb_select_interface(pdev, callback, s, RequestId, MessageId, udevman, transferDir);
1610 case TS_URB_PIPE_REQUEST:
1611 error = urb_pipe_request(pdev, callback, s, RequestId, MessageId, udevman, transferDir,
1615 case TS_URB_TAKE_FRAME_LENGTH_CONTROL:
1621 case TS_URB_RELEASE_FRAME_LENGTH_CONTROL:
1627 case TS_URB_GET_FRAME_LENGTH:
1633 case TS_URB_SET_FRAME_LENGTH:
1639 case TS_URB_GET_CURRENT_FRAME_NUMBER:
1640 error = urb_get_current_frame_number(pdev, callback, s, RequestId, MessageId, udevman,
1644 case TS_URB_CONTROL_TRANSFER:
1645 error = urb_control_transfer(pdev, callback, s, RequestId, MessageId, udevman,
1646 transferDir, URB_CONTROL_TRANSFER_NONEXTERNAL);
1649 case TS_URB_BULK_OR_INTERRUPT_TRANSFER:
1650 error = urb_bulk_or_interrupt_transfer(pdev, callback, s, RequestId, MessageId, udevman,
1654 case TS_URB_ISOCH_TRANSFER:
1656 urb_isoch_transfer(pdev, callback, s, RequestId, MessageId, udevman, transferDir);
1659 case TS_URB_GET_DESCRIPTOR_FROM_DEVICE:
1660 error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
1664 case TS_URB_SET_DESCRIPTOR_TO_DEVICE:
1665 error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
1669 case TS_URB_SET_FEATURE_TO_DEVICE:
1670 error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1671 0x00, URB_SET_FEATURE, transferDir);
1674 case TS_URB_SET_FEATURE_TO_INTERFACE:
1675 error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1676 0x01, URB_SET_FEATURE, transferDir);
1679 case TS_URB_SET_FEATURE_TO_ENDPOINT:
1680 error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1681 0x02, URB_SET_FEATURE, transferDir);
1684 case TS_URB_CLEAR_FEATURE_TO_DEVICE:
1685 error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1686 0x00, URB_CLEAR_FEATURE, transferDir);
1689 case TS_URB_CLEAR_FEATURE_TO_INTERFACE:
1690 error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1691 0x01, URB_CLEAR_FEATURE, transferDir);
1694 case TS_URB_CLEAR_FEATURE_TO_ENDPOINT:
1695 error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1696 0x02, URB_CLEAR_FEATURE, transferDir);
1699 case TS_URB_GET_STATUS_FROM_DEVICE:
1700 error = urb_control_get_status_request(pdev, callback, s, RequestId, MessageId, udevman,
1704 case TS_URB_GET_STATUS_FROM_INTERFACE:
1705 error = urb_control_get_status_request(pdev, callback, s, RequestId, MessageId, udevman,
1709 case TS_URB_GET_STATUS_FROM_ENDPOINT:
1710 error = urb_control_get_status_request(pdev, callback, s, RequestId, MessageId, udevman,
1714 case TS_URB_RESERVED_0X0016:
1717 case TS_URB_VENDOR_DEVICE:
1718 error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1719 udevman, (0x02 << 5),
1723 case TS_URB_VENDOR_INTERFACE:
1724 error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1725 udevman, (0x02 << 5),
1729 case TS_URB_VENDOR_ENDPOINT:
1730 error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1731 udevman, (0x02 << 5),
1735 case TS_URB_CLASS_DEVICE:
1736 error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1737 udevman, (0x01 << 5),
1741 case TS_URB_CLASS_INTERFACE:
1742 error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1743 udevman, (0x01 << 5),
1747 case TS_URB_CLASS_ENDPOINT:
1748 error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1749 udevman, (0x01 << 5),
1753 case TS_URB_RESERVE_0X001D:
1756 case TS_URB_SYNC_RESET_PIPE_AND_CLEAR_STALL:
1757 error = urb_pipe_request(pdev, callback, s, RequestId, MessageId, udevman, transferDir,
1761 case TS_URB_CLASS_OTHER:
1762 error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1763 udevman, (0x01 << 5),
1767 case TS_URB_VENDOR_OTHER:
1768 error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1769 udevman, (0x02 << 5),
1773 case TS_URB_GET_STATUS_FROM_OTHER:
1774 error = urb_control_get_status_request(pdev, callback, s, RequestId, MessageId, udevman,
1778 case TS_URB_CLEAR_FEATURE_TO_OTHER:
1779 error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1780 0x03, URB_CLEAR_FEATURE, transferDir);
1783 case TS_URB_SET_FEATURE_TO_OTHER:
1784 error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1785 0x03, URB_SET_FEATURE, transferDir);
1788 case TS_URB_GET_DESCRIPTOR_FROM_ENDPOINT:
1789 error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
1793 case TS_URB_SET_DESCRIPTOR_TO_ENDPOINT:
1794 error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
1798 case TS_URB_CONTROL_GET_CONFIGURATION_REQUEST:
1799 error = urb_control_get_configuration_request(pdev, callback, s, RequestId, MessageId,
1800 udevman, transferDir);
1803 case TS_URB_CONTROL_GET_INTERFACE_REQUEST:
1804 error = urb_control_get_interface_request(pdev, callback, s, RequestId, MessageId,
1805 udevman, transferDir);
1808 case TS_URB_GET_DESCRIPTOR_FROM_INTERFACE:
1809 error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
1813 case TS_URB_SET_DESCRIPTOR_TO_INTERFACE:
1814 error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
1818 case TS_URB_GET_OS_FEATURE_DESCRIPTOR_REQUEST:
1819 error = urb_os_feature_descriptor_request(pdev, callback, s, RequestId, MessageId,
1820 udevman, transferDir);
1823 case TS_URB_RESERVE_0X002B:
1824 case TS_URB_RESERVE_0X002C:
1825 case TS_URB_RESERVE_0X002D:
1826 case TS_URB_RESERVE_0X002E:
1827 case TS_URB_RESERVE_0X002F:
1831 case TS_URB_SYNC_RESET_PIPE:
1832 error = urb_pipe_request(pdev, callback, s, RequestId, MessageId, udevman, transferDir,
1836 case TS_URB_SYNC_CLEAR_STALL:
1837 urb_pipe_request(pdev, callback, s, RequestId, MessageId, udevman, transferDir,
1841 case TS_URB_CONTROL_TRANSFER_EX:
1842 error = urb_control_transfer(pdev, callback, s, RequestId, MessageId, udevman,
1843 transferDir, URB_CONTROL_TRANSFER_EXTERNAL);
1847 WLog_Print(urbdrc->log, WLOG_DEBUG,
"URB_Func: %" PRIx16
" is not found!",
1854 WLog_Print(urbdrc->log, WLOG_WARN,
1855 "USB transfer request URB Function '%s' [0x%08x] failed with %08" PRIx32,
1856 urb_function_string(URB_Function), URB_Function, error);
1863 IUDEVMAN* udevman,
wStream* data)
1865 UINT32 InterfaceId = 0;
1866 UINT32 MessageId = 0;
1867 UINT32 FunctionId = 0;
1868 IUDEVICE* pdev = NULL;
1869 UINT error = ERROR_INTERNAL_ERROR;
1871 if (!urbdrc || !data || !callback || !udevman)
1874 if (!Stream_CheckAndLogRequiredLength(TAG, data, 8))
1877 Stream_Rewind_UINT32(data);
1879 Stream_Read_UINT32(data, InterfaceId);
1880 Stream_Read_UINT32(data, MessageId);
1881 Stream_Read_UINT32(data, FunctionId);
1883 pdev = udevman->get_udevice_by_UsbDevice(udevman, InterfaceId);
1888 error = ERROR_SUCCESS;
1893 if (pdev->isChannelClosed(pdev))
1895 error = ERROR_SUCCESS;
1900 pdev->detach_kernel_driver(pdev);
1904 case CANCEL_REQUEST:
1905 error = urbdrc_process_cancel_request(pdev, data, udevman);
1908 case REGISTER_REQUEST_CALLBACK:
1909 error = urbdrc_process_register_request_callback(pdev, callback, data, udevman);
1913 error = urbdrc_process_io_control(pdev, callback, data, MessageId, udevman);
1916 case INTERNAL_IO_CONTROL:
1917 error = urbdrc_process_internal_io_control(pdev, callback, data, MessageId, udevman);
1920 case QUERY_DEVICE_TEXT:
1921 error = urbdrc_process_query_device_text(pdev, callback, data, MessageId, udevman);
1924 case TRANSFER_IN_REQUEST:
1925 error = urbdrc_process_transfer_request(pdev, callback, data, MessageId, udevman,
1926 USBD_TRANSFER_DIRECTION_IN);
1929 case TRANSFER_OUT_REQUEST:
1930 error = urbdrc_process_transfer_request(pdev, callback, data, MessageId, udevman,
1931 USBD_TRANSFER_DIRECTION_OUT);
1934 case RETRACT_DEVICE:
1935 error = urbdrc_process_retract_device_request(pdev, data, udevman);
1939 WLog_Print(urbdrc->log, WLOG_WARN,
1940 "urbdrc_process_udev_data_transfer:"
1941 " unknown FunctionId 0x%" PRIX32
"",
1949 WLog_WARN(TAG,
"USB request failed with %08" PRIx32, error);