25#include <winpr/sysinfo.h> 
   26#include <winpr/cast.h> 
   28#include <urbdrc_helpers.h> 
   30#include "urbdrc_types.h" 
   31#include "data_transfer.h" 
   34static void usb_process_get_port_status(IUDEVICE* pdev, 
wStream* out)
 
   36  int bcdUSB = pdev->query_device_descriptor(pdev, BCD_USB);
 
   41      Stream_Write_UINT32(out, 0x303);
 
   45      Stream_Write_UINT32(out, 0x103);
 
   50      Stream_Write_UINT32(out, 0x503);
 
   56static BOOL write_urb_result_header(
wStream* s, UINT16 Size, UINT32 status)
 
   58  if (!Stream_EnsureRemainingCapacity(s, 8ULL + Size))
 
   60  Stream_Write_UINT16(s, Size);
 
   61  Stream_Seek_UINT16(s);
 
   62  Stream_Write_UINT32(s, status);
 
   69static wStream* create_urb_completion_message(UINT32 InterfaceId, UINT32 MessageId,
 
   70                                              UINT32 RequestId, UINT32 FunctionId)
 
   73      create_shared_message_header_with_functionid(InterfaceId, MessageId, FunctionId, 4);
 
   77  Stream_Write_UINT32(out, RequestId);
 
   82                                        HRESULT hResult, UINT32 OutputSize, 
const void* data)
 
   84  WINPR_ASSERT(callback);
 
   85  UINT status = ERROR_OUTOFMEMORY;
 
   87  if (!Stream_EnsureRemainingCapacity(out, 8ULL + OutputSize))
 
   90  Stream_Write_INT32(out, hResult);
 
   91  Stream_Write_UINT32(out, OutputSize);
 
   92  Stream_Write(out, data, OutputSize);
 
   93  return stream_write_and_free(callback->plugin, callback->channel, out);
 
   96  Stream_Free(out, TRUE);
 
  100static UINT urb_write_completion(WINPR_ATTR_UNUSED IUDEVICE* pdev,
 
  102                                 UINT32 InterfaceId, UINT32 MessageId, UINT32 RequestId,
 
  103                                 UINT32 usbd_status, UINT32 OutputBufferSize)
 
  106    return ERROR_INVALID_PARAMETER;
 
  108  if (Stream_Capacity(out) < OutputBufferSize + 36)
 
  110    Stream_Free(out, TRUE);
 
  111    return ERROR_INVALID_PARAMETER;
 
  114  Stream_SetPosition(out, 0);
 
  116  const UINT32 FunctionId = (OutputBufferSize != 0) ? URB_COMPLETION : URB_COMPLETION_NO_DATA;
 
  117  if (!write_shared_message_header_with_functionid(out, InterfaceId, MessageId, FunctionId))
 
  119    Stream_Free(out, TRUE);
 
  120    return ERROR_OUTOFMEMORY;
 
  123  Stream_Write_UINT32(out, RequestId); 
 
  124  Stream_Write_UINT32(out, 8);         
 
  126  if (!write_urb_result_header(out, 8, usbd_status))
 
  128    Stream_Free(out, TRUE);
 
  129    return ERROR_OUTOFMEMORY;
 
  132  Stream_Write_UINT32(out, 0);                
 
  133  Stream_Write_UINT32(out, OutputBufferSize); 
 
  134  Stream_Seek(out, OutputBufferSize);
 
  137    return stream_write_and_free(callback->plugin, callback->channel, out);
 
  139    Stream_Free(out, TRUE);
 
  141  return ERROR_SUCCESS;
 
  144static wStream* urb_create_iocompletion(UINT32 InterfaceField, UINT32 MessageId, UINT32 RequestId,
 
  145                                        UINT32 OutputBufferSize)
 
  147  const UINT32 InterfaceId = (STREAM_ID_PROXY << 30) | (InterfaceField & 0x3FFFFFFF);
 
  149#if UINT32_MAX >= SIZE_MAX 
  150  if (OutputBufferSize > UINT32_MAX - 28ull)
 
  154  wStream* out = create_shared_message_header_with_functionid(
 
  155      InterfaceId, MessageId, IOCONTROL_COMPLETION, OutputBufferSize + 16ull);
 
  159  Stream_Write_UINT32(out, RequestId);            
 
  160  Stream_Write_UINT32(out, USBD_STATUS_SUCCESS);  
 
  161  Stream_Write_UINT32(out, OutputBufferSize);     
 
  162  Stream_Write_UINT32(out, OutputBufferSize);     
 
  166static UINT urbdrc_process_register_request_callback(IUDEVICE* pdev,
 
  170  UINT32 NumRequestCompletion = 0;
 
  171  UINT32 RequestCompletion = 0;
 
  173  if (!callback || !s || !udevman || !pdev)
 
  174    return ERROR_INVALID_PARAMETER;
 
  179    return ERROR_INVALID_PARAMETER;
 
  181  WLog_Print(urbdrc->log, WLOG_DEBUG, 
"urbdrc_process_register_request_callback");
 
  183  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4ULL))
 
  184    return ERROR_INVALID_DATA;
 
  186  Stream_Read_UINT32(s, NumRequestCompletion); 
 
  188  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4ULL * NumRequestCompletion))
 
  189    return ERROR_INVALID_DATA;
 
  190  for (uint32_t x = 0; x < NumRequestCompletion; x++)
 
  194    Stream_Read_UINT32(s, RequestCompletion);
 
  195    pdev->set_ReqCompletion(pdev, RequestCompletion);
 
  198  return ERROR_SUCCESS;
 
  201static UINT urbdrc_process_cancel_request(IUDEVICE* pdev, 
wStream* s, IUDEVMAN* udevman)
 
  206  if (!s || !udevman || !pdev)
 
  207    return ERROR_INVALID_PARAMETER;
 
  211  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
 
  212    return ERROR_INVALID_DATA;
 
  214  Stream_Read_UINT32(s, CancelId);
 
  215  WLog_Print(urbdrc->log, WLOG_DEBUG, 
"CANCEL_REQUEST: CancelId=%08" PRIx32 
"", CancelId);
 
  217  if (pdev->cancel_transfer_request(pdev, CancelId) < 0)
 
  218    return ERROR_INTERNAL_ERROR;
 
  220  return ERROR_SUCCESS;
 
  223static UINT urbdrc_process_retract_device_request(WINPR_ATTR_UNUSED IUDEVICE* pdev, 
wStream* s,
 
  230    return ERROR_INVALID_PARAMETER;
 
  235    return ERROR_INVALID_PARAMETER;
 
  237  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
 
  238    return ERROR_INVALID_DATA;
 
  240  Stream_Read_UINT32(s, Reason); 
 
  244    case UsbRetractReason_BlockedByPolicy:
 
  245      WLog_Print(urbdrc->log, WLOG_DEBUG,
 
  246                 "UsbRetractReason_BlockedByPolicy: now it is not support");
 
  247      return ERROR_ACCESS_DENIED;
 
  250      WLog_Print(urbdrc->log, WLOG_DEBUG,
 
  251                 "urbdrc_process_retract_device_request: Unknown Reason %" PRIu32 
"", Reason);
 
  252      return ERROR_ACCESS_DENIED;
 
  255  return ERROR_SUCCESS;
 
  259                                      wStream* s, UINT32 MessageId, IUDEVMAN* udevman)
 
  261  UINT32 InterfaceId = 0;
 
  262  UINT32 IoControlCode = 0;
 
  263  UINT32 InputBufferSize = 0;
 
  264  UINT32 OutputBufferSize = 0;
 
  265  UINT32 RequestId = 0;
 
  266  UINT32 usbd_status = USBD_STATUS_SUCCESS;
 
  271  if (!callback || !s || !udevman || !pdev)
 
  272    return ERROR_INVALID_PARAMETER;
 
  277    return ERROR_INVALID_PARAMETER;
 
  279  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
 
  280    return ERROR_INVALID_DATA;
 
  282  Stream_Read_UINT32(s, IoControlCode);
 
  283  Stream_Read_UINT32(s, InputBufferSize);
 
  285  if (!Stream_SafeSeek(s, InputBufferSize))
 
  286    return ERROR_INVALID_DATA;
 
  287  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ULL))
 
  288    return ERROR_INVALID_DATA;
 
  290  Stream_Read_UINT32(s, OutputBufferSize);
 
  291  Stream_Read_UINT32(s, RequestId);
 
  293  if (OutputBufferSize > UINT32_MAX - 4)
 
  294    return ERROR_INVALID_DATA;
 
  296  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
  297  out = urb_create_iocompletion(InterfaceId, MessageId, RequestId, OutputBufferSize + 4);
 
  300    return ERROR_OUTOFMEMORY;
 
  302  switch (IoControlCode)
 
  304    case IOCTL_INTERNAL_USB_SUBMIT_URB: 
 
  305      WLog_Print(urbdrc->log, WLOG_DEBUG, 
"ioctl: IOCTL_INTERNAL_USB_SUBMIT_URB");
 
  306      WLog_Print(urbdrc->log, WLOG_ERROR,
 
  307                 " Function IOCTL_INTERNAL_USB_SUBMIT_URB: Unchecked");
 
  310    case IOCTL_INTERNAL_USB_RESET_PORT: 
 
  311      WLog_Print(urbdrc->log, WLOG_DEBUG, 
"ioctl: IOCTL_INTERNAL_USB_RESET_PORT");
 
  314    case IOCTL_INTERNAL_USB_GET_PORT_STATUS: 
 
  315      WLog_Print(urbdrc->log, WLOG_DEBUG, 
"ioctl: IOCTL_INTERNAL_USB_GET_PORT_STATUS");
 
  316      success = pdev->query_device_port_status(pdev, &usbd_status, &OutputBufferSize,
 
  317                                               Stream_Pointer(out));
 
  321        if (!Stream_SafeSeek(out, OutputBufferSize))
 
  323          Stream_Free(out, TRUE);
 
  324          return ERROR_INVALID_DATA;
 
  327        if (pdev->isExist(pdev) == 0)
 
  328          Stream_Write_UINT32(out, 0);
 
  330          usb_process_get_port_status(pdev, out);
 
  335    case IOCTL_INTERNAL_USB_CYCLE_PORT: 
 
  336      WLog_Print(urbdrc->log, WLOG_DEBUG, 
"ioctl: IOCTL_INTERNAL_USB_CYCLE_PORT");
 
  337      WLog_Print(urbdrc->log, WLOG_ERROR,
 
  338                 " Function IOCTL_INTERNAL_USB_CYCLE_PORT: Unchecked");
 
  341    case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: 
 
  342      WLog_Print(urbdrc->log, WLOG_DEBUG,
 
  343                 "ioctl: IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION");
 
  344      WLog_Print(urbdrc->log, WLOG_ERROR,
 
  345                 " Function IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: Unchecked");
 
  349      WLog_Print(urbdrc->log, WLOG_DEBUG,
 
  350                 "urbdrc_process_io_control: unknown IoControlCode 0x%" PRIX32 
"",
 
  352      Stream_Free(out, TRUE);
 
  353      return ERROR_INVALID_OPERATION;
 
  356  return stream_write_and_free(callback->plugin, callback->channel, out);
 
  360                                               wStream* s, UINT32 MessageId, IUDEVMAN* udevman)
 
  362  if (!pdev || !callback || !s || !udevman)
 
  363    return ERROR_INVALID_PARAMETER;
 
  366  WINPR_ASSERT(urbdrc);
 
  368  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
 
  369    return ERROR_INVALID_DATA;
 
  371  const UINT32 IoControlCode = Stream_Get_UINT32(s);
 
  372  if (IoControlCode != IOCTL_TSUSBGD_IOCTL_USBDI_QUERY_BUS_TIME)
 
  376        "Invalid [MS-RDPEUSB] 2.2.13 USB Internal IO Control Code::IoControlCode0x%08" PRIx32
 
  377        ", must be IOCTL_TSUSBGD_IOCTL_USBDI_QUERY_BUS_TIME [0x00224000]",
 
  379    return ERROR_INVALID_DATA;
 
  381  const UINT32 InputBufferSize = Stream_Get_UINT32(s);
 
  383  if (!Stream_SafeSeek(s, InputBufferSize))
 
  384    return ERROR_INVALID_DATA;
 
  385  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ULL))
 
  386    return ERROR_INVALID_DATA;
 
  387  const UINT32 OutputBufferSize = Stream_Get_UINT32(s);
 
  388  const UINT32 RequestId = Stream_Get_UINT32(s);
 
  389  const UINT32 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
  392  const UINT32 frames = GetTickCount();
 
  394  if (4 > OutputBufferSize)
 
  396    WLog_Print(urbdrc->log, WLOG_DEBUG, 
"out_size %" PRIu32 
" > OutputBufferSize %" PRIu32, 4u,
 
  398    return ERROR_BAD_CONFIGURATION;
 
  400  wStream* out = urb_create_iocompletion(InterfaceId, MessageId, RequestId, 4);
 
  403    return ERROR_OUTOFMEMORY;
 
  405  Stream_Write_UINT32(out, frames); 
 
  406  return stream_write_and_free(callback->plugin, callback->channel, out);
 
  411                                                   UINT32 InterfaceId, UINT32 MessageId, HRESULT hr,
 
  412                                                   const BYTE* text, uint8_t bytelen)
 
  414  WINPR_ASSERT(callback);
 
  416  const uint8_t charlen = bytelen / 
sizeof(WCHAR);
 
  417  wStream* out = create_shared_message_header_with_functionid(InterfaceId, MessageId, charlen,
 
  421    return ERROR_OUTOFMEMORY;
 
  423  Stream_Write(out, text, bytelen); 
 
  424  Stream_Write_INT32(out, hr);      
 
  425  return stream_write_and_free(callback->plugin, callback->channel, out);
 
  429                                             wStream* s, UINT32 MessageId, IUDEVMAN* udevman)
 
  433  UINT8 bufferSize = 0xFF;
 
  434  BYTE DeviceDescription[0x100] = { 0 };
 
  436  if (!pdev || !callback || !s || !udevman)
 
  437    return ERROR_INVALID_PARAMETER;
 
  438  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
 
  439    return ERROR_INVALID_DATA;
 
  441  Stream_Read_UINT32(s, TextType);
 
  442  Stream_Read_UINT32(s, LocaleId);
 
  443  if (LocaleId > UINT16_MAX)
 
  444    return ERROR_INVALID_DATA;
 
  446  HRESULT hr = (HRESULT)pdev->control_query_device_text(pdev, TextType, (UINT16)LocaleId,
 
  447                                                        &bufferSize, DeviceDescription);
 
  448  const UINT32 InterfaceId = ((STREAM_ID_STUB << 30) | pdev->get_UsbDevice(pdev));
 
  449  return urbdrc_send_query_device_text_response(callback, InterfaceId, MessageId, hr,
 
  450                                                DeviceDescription, bufferSize);
 
  453static void func_select_all_interface_for_msconfig(IUDEVICE* pdev,
 
  457  BYTE InterfaceNumber = 0;
 
  458  BYTE AlternateSetting = 0;
 
  459  UINT32 NumInterfaces = MsConfig->NumInterfaces;
 
  461  for (UINT32 inum = 0; inum < NumInterfaces; inum++)
 
  463    InterfaceNumber = MsInterfaces[inum]->InterfaceNumber;
 
  464    AlternateSetting = MsInterfaces[inum]->AlternateSetting;
 
  465    pdev->select_interface(pdev, InterfaceNumber, AlternateSetting);
 
  471                                                 UINT32 InterfaceId, UINT32 MessageId,
 
  472                                                 UINT32 RequestId, UINT32 UrbStatus,
 
  476      create_urb_completion_message(InterfaceId, MessageId, RequestId, URB_COMPLETION_NO_DATA);
 
  478    return ERROR_OUTOFMEMORY;
 
  480  const int size = 8 + ((MsConfig) ? MsConfig->MsOutSize : 8);
 
  481  const uint16_t usize = WINPR_ASSERTING_INT_CAST(uint16_t, size);
 
  483  if (!Stream_EnsureRemainingCapacity(out, 4))
 
  485  Stream_Write_UINT32(out, usize); 
 
  487  if (!write_urb_result_header(out, usize, UrbStatus))
 
  492    msusb_msconfig_write(MsConfig, out);
 
  495    Stream_Write_UINT32(out, 0); 
 
  496    Stream_Write_UINT32(out, 0); 
 
  499  return send_urb_completion_message(callback, out, 0, 0, NULL);
 
  502  Stream_Free(out, TRUE);
 
  503  return ERROR_OUTOFMEMORY;
 
  507                                     UINT32 RequestField, UINT32 MessageId, IUDEVMAN* udevman,
 
  511  UINT32 NumInterfaces = 0;
 
  512  UINT32 usbd_status = 0;
 
  513  BYTE ConfigurationDescriptorIsValid = 0;
 
  515  const BOOL noAck = (RequestField & 0x80000000U) != 0;
 
  516  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
 
  518  if (!callback || !s || !udevman || !pdev)
 
  519    return ERROR_INVALID_PARAMETER;
 
  524    return ERROR_INVALID_PARAMETER;
 
  526  if (transferDir == 0)
 
  528    WLog_Print(urbdrc->log, WLOG_ERROR, 
"urb_select_configuration: unsupported transfer out");
 
  529    return ERROR_INVALID_PARAMETER;
 
  532  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
 
  533    return ERROR_INVALID_DATA;
 
  535  const UINT32 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
  536  Stream_Read_UINT8(s, ConfigurationDescriptorIsValid);
 
  538  Stream_Read_UINT32(s, NumInterfaces);
 
  541  if (ConfigurationDescriptorIsValid)
 
  544    MsConfig = msusb_msconfig_read(s, NumInterfaces);
 
  547      return ERROR_INVALID_DATA;
 
  550    pdev->select_configuration(pdev, MsConfig->bConfigurationValue);
 
  552    func_select_all_interface_for_msconfig(pdev, MsConfig);
 
  554    if (!pdev->complete_msconfig_setup(pdev, MsConfig))
 
  556      msusb_msconfig_free(MsConfig);
 
  562    return CHANNEL_RC_OK;
 
  563  return send_urb_select_configuration_result(callback, InterfaceId, MessageId, RequestId,
 
  564                                              usbd_status, MsConfig);
 
  569                                        UINT32 InterfaceId, UINT32 MessageId,
 
  571                                        UINT32 ConfigurationHandle)
 
  573  WINPR_ASSERT(callback);
 
  574  WINPR_ASSERT(MsInterface);
 
  576  const UINT32 NumInterfaces = 1;
 
  577  const uint32_t interface_size = 16U + (MsInterface->NumberOfPipes * 20U);
 
  579      create_urb_completion_message(InterfaceId, MessageId, RequestId, URB_COMPLETION_NO_DATA);
 
  582    return ERROR_OUTOFMEMORY;
 
  584  const uint32_t size = 8U + interface_size;
 
  585  const uint16_t usize = WINPR_ASSERTING_INT_CAST(uint16_t, size);
 
  587  if (!Stream_EnsureRemainingCapacity(out, 4))
 
  589  Stream_Write_UINT32(out, usize); 
 
  591  if (!write_urb_result_header(out, usize, USBD_STATUS_SUCCESS))
 
  594  if (!msusb_msinterface_write(MsInterface, out))
 
  597  if (!Stream_EnsureRemainingCapacity(out, 8))
 
  599  Stream_Write_UINT32(out, ConfigurationHandle); 
 
  600  Stream_Write_UINT32(out, NumInterfaces);       
 
  602  for (
size_t x = 0; x < NumInterfaces; x++)
 
  605    if (!msusb_msinterface_write(ifc, out))
 
  609  return send_urb_completion_message(callback, out, 0, 0, NULL);
 
  612  Stream_Free(out, TRUE);
 
  614  return ERROR_INTERNAL_ERROR;
 
  618                                 UINT32 RequestField, UINT32 MessageId, IUDEVMAN* udevman,
 
  621  const BOOL noAck = (RequestField & 0x80000000U) != 0;
 
  622  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
 
  624  if (!callback || !s || !udevman || !pdev)
 
  625    return ERROR_INVALID_PARAMETER;
 
  630    return ERROR_INVALID_PARAMETER;
 
  632  if (transferDir == 0)
 
  634    WLog_Print(urbdrc->log, WLOG_ERROR, 
"urb_select_interface: not support transfer out");
 
  635    return ERROR_INVALID_PARAMETER;
 
  638  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
 
  639    return ERROR_INVALID_DATA;
 
  641  const UINT32 InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
  642  const UINT32 ConfigurationHandle = Stream_Get_UINT32(s);
 
  645  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4) || !MsInterface)
 
  647    msusb_msinterface_free(MsInterface);
 
  648    return ERROR_INVALID_DATA;
 
  651  const UINT32 OutputBufferSize = Stream_Get_UINT32(s);
 
  652  if (OutputBufferSize != 0)
 
  654    WLog_Print(urbdrc->log, WLOG_ERROR,
 
  655               "[MS-RDPEUSB] 2.2.9.3 TS_URB_SELECT_INTERFACE::OutputBufferSize must be 0, got " 
  658    msusb_msinterface_free(MsInterface);
 
  659    return ERROR_INVALID_DATA;
 
  662  pdev->select_interface(pdev, MsInterface->InterfaceNumber, MsInterface->AlternateSetting);
 
  665  const uint8_t InterfaceNumber = MsInterface->InterfaceNumber;
 
  666  if (!msusb_msinterface_replace(MsConfig, InterfaceNumber, MsInterface))
 
  668    msusb_msconfig_free(MsConfig);
 
  669    return ERROR_BAD_CONFIGURATION;
 
  672  if (!pdev->complete_msconfig_setup(pdev, MsConfig))
 
  673    return ERROR_BAD_CONFIGURATION;
 
  676    return CHANNEL_RC_OK;
 
  678  return urb_select_interface_result(callback, RequestId, InterfaceId, MessageId, MsInterface,
 
  679                                     ConfigurationHandle);
 
  683                                 UINT32 RequestField, UINT32 MessageId, IUDEVMAN* udevman,
 
  684                                 int transferDir, 
int External)
 
  687  UINT32 InterfaceId = 0;
 
  688  UINT32 EndpointAddress = 0;
 
  689  UINT32 PipeHandle = 0;
 
  690  UINT32 TransferFlags = 0;
 
  691  UINT32 OutputBufferSize = 0;
 
  692  UINT32 usbd_status = 0;
 
  694  BYTE bmRequestType = 0;
 
  702  const BOOL noAck = (RequestField & 0x80000000U) != 0;
 
  703  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
 
  705  if (!callback || !s || !udevman || !pdev)
 
  706    return ERROR_INVALID_PARAMETER;
 
  711    return ERROR_INVALID_PARAMETER;
 
  713  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
 
  714    return ERROR_INVALID_DATA;
 
  716  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
  717  Stream_Read_UINT32(s, PipeHandle);
 
  718  Stream_Read_UINT32(s, TransferFlags); 
 
  719  EndpointAddress = (PipeHandle & 0x000000ff);
 
  724    case URB_CONTROL_TRANSFER_EXTERNAL:
 
  725      if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
 
  726        return ERROR_INVALID_DATA;
 
  728      Stream_Read_UINT32(s, Timeout); 
 
  731    case URB_CONTROL_TRANSFER_NONEXTERNAL:
 
  738  if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
 
  739    return ERROR_INVALID_DATA;
 
  741  Stream_Read_UINT8(s, bmRequestType);
 
  742  Stream_Read_UINT8(s, Request);
 
  743  Stream_Read_UINT16(s, Value);
 
  744  Stream_Read_UINT16(s, Index);
 
  745  Stream_Read_UINT16(s, length);
 
  746  Stream_Read_UINT32(s, OutputBufferSize);
 
  748  if (length != OutputBufferSize)
 
  750    WLog_Print(urbdrc->log, WLOG_ERROR, 
"urb_control_transfer ERROR: buf != length");
 
  751    return ERROR_INVALID_DATA;
 
  754  out_size = 36 + OutputBufferSize;
 
  755  out = Stream_New(NULL, out_size);
 
  758    return ERROR_OUTOFMEMORY;
 
  760  Stream_Seek(out, 36);
 
  762  buffer = Stream_Pointer(out);
 
  764  if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
 
  766    if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
 
  768      Stream_Free(out, TRUE);
 
  769      return ERROR_INVALID_DATA;
 
  771    Stream_Copy(s, out, OutputBufferSize);
 
  775  if (!pdev->control_transfer(pdev, RequestId, EndpointAddress, TransferFlags, bmRequestType,
 
  776                              Request, Value, Index, &usbd_status, &OutputBufferSize, buffer,
 
  779    WLog_Print(urbdrc->log, WLOG_ERROR, 
"control_transfer failed");
 
  780    Stream_Free(out, TRUE);
 
  781    return ERROR_INTERNAL_ERROR;
 
  784  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
 
  785                              usbd_status, OutputBufferSize);
 
  789                                 UINT32 InterfaceId, BOOL noAck, UINT32 MessageId, UINT32 RequestId,
 
  790                                 WINPR_ATTR_UNUSED UINT32 NumberOfPackets, UINT32 status,
 
  791                                 WINPR_ATTR_UNUSED UINT32 StartFrame,
 
  792                                 WINPR_ATTR_UNUSED UINT32 ErrorCount, UINT32 OutputBufferSize)
 
  794  if (!pdev->isChannelClosed(pdev))
 
  795    urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId, status,
 
  798    Stream_Free(out, TRUE);
 
  802                                           wStream* s, UINT32 RequestField, UINT32 MessageId,
 
  803                                           IUDEVMAN* udevman, 
int transferDir)
 
  805  UINT32 EndpointAddress = 0;
 
  806  UINT32 PipeHandle = 0;
 
  807  UINT32 TransferFlags = 0;
 
  808  UINT32 OutputBufferSize = 0;
 
  809  const BOOL noAck = (RequestField & 0x80000000U) != 0;
 
  810  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
 
  812  if (!pdev || !callback || !s || !udevman)
 
  813    return ERROR_INVALID_PARAMETER;
 
  815  if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
 
  816    return ERROR_INVALID_DATA;
 
  818  Stream_Read_UINT32(s, PipeHandle);
 
  819  Stream_Read_UINT32(s, TransferFlags); 
 
  820  Stream_Read_UINT32(s, OutputBufferSize);
 
  821  EndpointAddress = (PipeHandle & 0x000000ff);
 
  823  if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
 
  825    if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
 
  827      return ERROR_INVALID_DATA;
 
  832  const int rc = pdev->bulk_or_interrupt_transfer(
 
  833      pdev, callback, MessageId, RequestId, EndpointAddress, TransferFlags, noAck,
 
  834      OutputBufferSize, (transferDir == USBD_TRANSFER_DIRECTION_OUT) ? Stream_Pointer(s) : NULL,
 
  835      urb_bulk_transfer_cb, 10000);
 
  840static void urb_isoch_transfer_cb(WINPR_ATTR_UNUSED IUDEVICE* pdev,
 
  842                                  UINT32 InterfaceId, BOOL noAck, UINT32 MessageId,
 
  843                                  UINT32 RequestId, UINT32 NumberOfPackets, UINT32 status,
 
  844                                  UINT32 StartFrame, UINT32 ErrorCount, UINT32 OutputBufferSize)
 
  848    UINT32 packetSize = (status == 0) ? NumberOfPackets * 12 : 0;
 
  849    Stream_SetPosition(out, 0);
 
  851    const UINT32 FunctionId = (OutputBufferSize == 0) ? URB_COMPLETION_NO_DATA : URB_COMPLETION;
 
  852    if (!write_shared_message_header_with_functionid(out, InterfaceId, MessageId, FunctionId))
 
  854      Stream_Free(out, TRUE);
 
  858    Stream_Write_UINT32(out, RequestId);       
 
  859    Stream_Write_UINT32(out, 20 + packetSize); 
 
  860    if (!write_urb_result_header(out, WINPR_ASSERTING_INT_CAST(uint16_t, 20 + packetSize),
 
  863      Stream_Free(out, TRUE);
 
  867    Stream_Write_UINT32(out, StartFrame);      
 
  872      Stream_Write_UINT32(out, NumberOfPackets);
 
  873      Stream_Write_UINT32(out, ErrorCount); 
 
  874      Stream_Seek(out, packetSize);
 
  878      Stream_Write_UINT32(out, 0);          
 
  879      Stream_Write_UINT32(out, ErrorCount); 
 
  882    Stream_Write_UINT32(out, 0);                
 
  883    Stream_Write_UINT32(out, OutputBufferSize); 
 
  884    Stream_Seek(out, OutputBufferSize);
 
  886    stream_write_and_free(callback->plugin, callback->channel, out);
 
  891                               UINT32 RequestField, UINT32 MessageId, IUDEVMAN* udevman,
 
  895  UINT32 EndpointAddress = 0;
 
  896  UINT32 PipeHandle = 0;
 
  897  UINT32 TransferFlags = 0;
 
  898  UINT32 StartFrame = 0;
 
  899  UINT32 NumberOfPackets = 0;
 
  900  UINT32 ErrorCount = 0;
 
  901  UINT32 OutputBufferSize = 0;
 
  902  BYTE* packetDescriptorData = NULL;
 
  903  const BOOL noAck = (RequestField & 0x80000000U) != 0;
 
  904  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
 
  906  if (!pdev || !callback || !udevman)
 
  907    return ERROR_INVALID_PARAMETER;
 
  909  if (!Stream_CheckAndLogRequiredLength(TAG, s, 20))
 
  910    return ERROR_INVALID_DATA;
 
  912  Stream_Read_UINT32(s, PipeHandle);
 
  913  EndpointAddress = (PipeHandle & 0x000000ff);
 
  914  Stream_Read_UINT32(s, TransferFlags);   
 
  915  Stream_Read_UINT32(s, StartFrame);      
 
  916  Stream_Read_UINT32(s, NumberOfPackets); 
 
  917  Stream_Read_UINT32(s, ErrorCount);      
 
  919  if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, NumberOfPackets, 12ull))
 
  920    return ERROR_INVALID_DATA;
 
  922  packetDescriptorData = Stream_Pointer(s);
 
  923  Stream_Seek(s, 12ULL * NumberOfPackets);
 
  925  if (!Stream_CheckAndLogRequiredLength(TAG, s, 
sizeof(UINT32)))
 
  926    return ERROR_INVALID_DATA;
 
  927  Stream_Read_UINT32(s, OutputBufferSize);
 
  929  if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
 
  931    if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
 
  932      return ERROR_INVALID_DATA;
 
  935  rc = pdev->isoch_transfer(
 
  936      pdev, callback, MessageId, RequestId, EndpointAddress, TransferFlags, StartFrame,
 
  937      ErrorCount, noAck, packetDescriptorData, NumberOfPackets, OutputBufferSize,
 
  938      (transferDir == USBD_TRANSFER_DIRECTION_OUT) ? Stream_Pointer(s) : NULL,
 
  939      urb_isoch_transfer_cb, 2000);
 
  942    return ERROR_INTERNAL_ERROR;
 
  947                                           wStream* s, UINT32 RequestField, UINT32 MessageId,
 
  948                                           IUDEVMAN* udevman, BYTE func_recipient, 
int transferDir)
 
  951  UINT32 InterfaceId = 0;
 
  952  UINT32 OutputBufferSize = 0;
 
  953  UINT32 usbd_status = 0;
 
  954  BYTE bmRequestType = 0;
 
  960  const BOOL noAck = (RequestField & 0x80000000U) != 0;
 
  961  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
 
  963  if (!callback || !s || !udevman || !pdev)
 
  964    return ERROR_INVALID_PARAMETER;
 
  969    return ERROR_INVALID_PARAMETER;
 
  971  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
 
  972    return ERROR_INVALID_DATA;
 
  974  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
  975  Stream_Read_UINT8(s, desc_index);
 
  976  Stream_Read_UINT8(s, desc_type);
 
  977  Stream_Read_UINT16(s, langId);
 
  978  Stream_Read_UINT32(s, OutputBufferSize);
 
  979  if (OutputBufferSize > UINT32_MAX - 36)
 
  980    return ERROR_INVALID_DATA;
 
  981  if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
 
  983    if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
 
  984      return ERROR_INVALID_DATA;
 
  987  out_size = 36ULL + OutputBufferSize;
 
  988  out = Stream_New(NULL, out_size);
 
  991    return ERROR_OUTOFMEMORY;
 
  993  Stream_Seek(out, 36);
 
  994  bmRequestType = func_recipient;
 
  998    case USBD_TRANSFER_DIRECTION_IN:
 
  999      bmRequestType |= 0x80;
 
 1002    case USBD_TRANSFER_DIRECTION_OUT:
 
 1003      bmRequestType |= 0x00;
 
 1004      Stream_Copy(s, out, OutputBufferSize);
 
 1005      Stream_Rewind(out, OutputBufferSize);
 
 1009      WLog_Print(urbdrc->log, WLOG_DEBUG, 
"get error transferDir");
 
 1010      OutputBufferSize = 0;
 
 1011      usbd_status = USBD_STATUS_STALL_PID;
 
 1016  if (!pdev->control_transfer(pdev, RequestId, 0, 0, bmRequestType,
 
 1018                              WINPR_ASSERTING_INT_CAST(UINT16, ((desc_type << 8) | desc_index)),
 
 1019                              langId, &usbd_status, &OutputBufferSize, Stream_Pointer(out), 1000))
 
 1021    WLog_Print(urbdrc->log, WLOG_ERROR, 
"get_descriptor failed");
 
 1022    Stream_Free(out, TRUE);
 
 1023    return ERROR_INTERNAL_ERROR;
 
 1026  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
 
 1027                              usbd_status, OutputBufferSize);
 
 1031                                           wStream* s, UINT32 RequestField, UINT32 MessageId,
 
 1032                                           IUDEVMAN* udevman, BYTE func_recipient, 
int transferDir)
 
 1034  size_t out_size = 0;
 
 1035  UINT32 InterfaceId = 0;
 
 1036  UINT32 OutputBufferSize = 0;
 
 1037  UINT32 usbd_status = 0;
 
 1039  BYTE bmRequestType = 0;
 
 1042  const BOOL noAck = (RequestField & 0x80000000U) != 0;
 
 1043  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
 
 1045  if (!callback || !s || !udevman || !pdev)
 
 1046    return ERROR_INVALID_PARAMETER;
 
 1051    return ERROR_INVALID_PARAMETER;
 
 1053  if (transferDir == 0)
 
 1055    WLog_Print(urbdrc->log, WLOG_DEBUG,
 
 1056               "urb_control_get_status_request: transfer out not supported");
 
 1057    return ERROR_INVALID_PARAMETER;
 
 1060  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
 
 1061    return ERROR_INVALID_DATA;
 
 1063  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
 1064  Stream_Read_UINT16(s, Index); 
 
 1066  Stream_Read_UINT32(s, OutputBufferSize);
 
 1067  if (OutputBufferSize > UINT32_MAX - 36)
 
 1068    return ERROR_INVALID_DATA;
 
 1069  out_size = 36ULL + OutputBufferSize;
 
 1070  out = Stream_New(NULL, out_size);
 
 1073    return ERROR_OUTOFMEMORY;
 
 1075  Stream_Seek(out, 36);
 
 1076  bmRequestType = func_recipient | 0x80;
 
 1078  if (!pdev->control_transfer(pdev, RequestId, 0, 0, bmRequestType, 0x00, 
 
 1079                              0, Index, &usbd_status, &OutputBufferSize, Stream_Pointer(out),
 
 1082    WLog_Print(urbdrc->log, WLOG_ERROR, 
"control_transfer failed");
 
 1083    Stream_Free(out, TRUE);
 
 1084    return ERROR_INTERNAL_ERROR;
 
 1087  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
 
 1088                              usbd_status, OutputBufferSize);
 
 1092                                                wStream* s, UINT32 RequestField, UINT32 MessageId,
 
 1093                                                IUDEVMAN* udevman, BYTE func_type,
 
 1094                                                BYTE func_recipient, 
int transferDir)
 
 1096  UINT32 out_size = 0;
 
 1097  UINT32 InterfaceId = 0;
 
 1098  UINT32 TransferFlags = 0;
 
 1099  UINT32 usbd_status = 0;
 
 1100  UINT32 OutputBufferSize = 0;
 
 1101  BYTE ReqTypeReservedBits = 0;
 
 1103  BYTE bmRequestType = 0;
 
 1108  const BOOL noAck = (RequestField & 0x80000000U) != 0;
 
 1109  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
 
 1111  if (!callback || !s || !udevman || !pdev)
 
 1112    return ERROR_INVALID_PARAMETER;
 
 1117    return ERROR_INVALID_PARAMETER;
 
 1119  if (!Stream_CheckAndLogRequiredLength(TAG, s, 16))
 
 1120    return ERROR_INVALID_DATA;
 
 1122  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
 1123  Stream_Read_UINT32(s, TransferFlags);      
 
 1124  Stream_Read_UINT8(s, ReqTypeReservedBits); 
 
 1125  Stream_Read_UINT8(s, Request);             
 
 1126  Stream_Read_UINT16(s, Value);              
 
 1127  Stream_Read_UINT16(s, Index);              
 
 1128  Stream_Seek_UINT16(s);                     
 
 1129  Stream_Read_UINT32(s, OutputBufferSize);
 
 1130  if (OutputBufferSize > UINT32_MAX - 36)
 
 1131    return ERROR_INVALID_DATA;
 
 1133  if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
 
 1135    if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
 
 1136      return ERROR_INVALID_DATA;
 
 1139  out_size = 36ULL + OutputBufferSize;
 
 1140  out = Stream_New(NULL, out_size);
 
 1143    return ERROR_OUTOFMEMORY;
 
 1145  Stream_Seek(out, 36);
 
 1148  if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
 
 1150    Stream_Copy(s, out, OutputBufferSize);
 
 1151    Stream_Rewind(out, OutputBufferSize);
 
 1155  bmRequestType = func_type | func_recipient;
 
 1157  if (TransferFlags & USBD_TRANSFER_DIRECTION)
 
 1158    bmRequestType |= 0x80;
 
 1160  WLog_Print(urbdrc->log, WLOG_DEBUG,
 
 1161             "RequestId 0x%" PRIx32 
" TransferFlags: 0x%" PRIx32 
" ReqTypeReservedBits: 0x%" PRIx8
 
 1163             "Request:0x%" PRIx8 
" Value: 0x%" PRIx16 
" Index: 0x%" PRIx16
 
 1164             " OutputBufferSize: 0x%" PRIx32 
" bmRequestType: 0x%" PRIx8,
 
 1165             RequestId, TransferFlags, ReqTypeReservedBits, Request, Value, Index,
 
 1166             OutputBufferSize, bmRequestType);
 
 1168  if (!pdev->control_transfer(pdev, RequestId, 0, 0, bmRequestType, Request, Value, Index,
 
 1169                              &usbd_status, &OutputBufferSize, Stream_Pointer(out), 2000))
 
 1171    WLog_Print(urbdrc->log, WLOG_ERROR, 
"control_transfer failed");
 
 1172    Stream_Free(out, TRUE);
 
 1173    return ERROR_INTERNAL_ERROR;
 
 1176  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
 
 1177                              usbd_status, OutputBufferSize);
 
 1181                                              wStream* s, UINT32 RequestField, UINT32 MessageId,
 
 1182                                              IUDEVMAN* udevman, 
int transferDir)
 
 1184  size_t out_size = 0;
 
 1185  UINT32 InterfaceId = 0;
 
 1186  UINT32 OutputBufferSize = 0;
 
 1187  UINT32 usbd_status = 0;
 
 1189  BYTE InterfaceNumber = 0;
 
 1190  BYTE Ms_PageIndex = 0;
 
 1191  UINT16 Ms_featureDescIndex = 0;
 
 1195  const BOOL noAck = (RequestField & 0x80000000U) != 0;
 
 1196  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
 
 1198  if (!callback || !s || !udevman || !pdev)
 
 1199    return ERROR_INVALID_PARAMETER;
 
 1204    return ERROR_INVALID_PARAMETER;
 
 1206  if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
 
 1207    return ERROR_INVALID_DATA;
 
 1210  Stream_Read_UINT8(s, Recipient);            
 
 1211  Recipient = (Recipient & 0x1f);             
 
 1212  Stream_Read_UINT8(s, InterfaceNumber);      
 
 1213  Stream_Read_UINT8(s, Ms_PageIndex);         
 
 1214  Stream_Read_UINT16(s, Ms_featureDescIndex); 
 
 1216  Stream_Read_UINT32(s, OutputBufferSize);
 
 1217  if (OutputBufferSize > UINT32_MAX - 36)
 
 1218    return ERROR_INVALID_DATA;
 
 1220  switch (transferDir)
 
 1222    case USBD_TRANSFER_DIRECTION_OUT:
 
 1223      if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
 
 1224        return ERROR_INVALID_DATA;
 
 1232  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
 1233  out_size = 36ULL + OutputBufferSize;
 
 1234  out = Stream_New(NULL, out_size);
 
 1237    return ERROR_OUTOFMEMORY;
 
 1239  Stream_Seek(out, 36);
 
 1241  switch (transferDir)
 
 1243    case USBD_TRANSFER_DIRECTION_OUT:
 
 1244      Stream_Copy(s, out, OutputBufferSize);
 
 1245      Stream_Rewind(out, OutputBufferSize);
 
 1248    case USBD_TRANSFER_DIRECTION_IN:
 
 1254  WLog_Print(urbdrc->log, WLOG_DEBUG,
 
 1255             "Ms descriptor arg: Recipient:0x%" PRIx8 
", " 
 1256             "InterfaceNumber:0x%" PRIx8 
", Ms_PageIndex:0x%" PRIx8 
", " 
 1257             "Ms_featureDescIndex:0x%" PRIx16 
", OutputBufferSize:0x%" PRIx32 
"",
 
 1258             Recipient, InterfaceNumber, Ms_PageIndex, Ms_featureDescIndex, OutputBufferSize);
 
 1260  ret = pdev->os_feature_descriptor_request(pdev, RequestId, Recipient, InterfaceNumber,
 
 1261                                            Ms_PageIndex, Ms_featureDescIndex, &usbd_status,
 
 1262                                            &OutputBufferSize, Stream_Pointer(out), 1000);
 
 1265    WLog_Print(urbdrc->log, WLOG_DEBUG, 
"os_feature_descriptor_request: error num %d", ret);
 
 1267  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
 
 1268                              usbd_status, OutputBufferSize);
 
 1272                             UINT32 RequestField, UINT32 MessageId, IUDEVMAN* udevman,
 
 1273                             int transferDir, 
int action)
 
 1275  UINT32 out_size = 0;
 
 1276  UINT32 InterfaceId = 0;
 
 1277  UINT32 PipeHandle = 0;
 
 1278  UINT32 EndpointAddress = 0;
 
 1279  UINT32 OutputBufferSize = 0;
 
 1280  UINT32 usbd_status = 0;
 
 1282  UINT32 ret = USBD_STATUS_REQUEST_FAILED;
 
 1285  const BOOL noAck = (RequestField & 0x80000000U) != 0;
 
 1286  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
 
 1288  if (!callback || !s || !udevman || !pdev)
 
 1289    return ERROR_INVALID_PARAMETER;
 
 1294    return ERROR_INVALID_PARAMETER;
 
 1296  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
 
 1297    return ERROR_INVALID_DATA;
 
 1299  if (transferDir == 0)
 
 1301    WLog_Print(urbdrc->log, WLOG_DEBUG, 
"urb_pipe_request: not support transfer out");
 
 1302    return ERROR_INVALID_PARAMETER;
 
 1305  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
 1306  Stream_Read_UINT32(s, PipeHandle); 
 
 1307  Stream_Read_UINT32(s, OutputBufferSize);
 
 1308  EndpointAddress = (PipeHandle & 0x000000ff);
 
 1313      rc = pdev->control_pipe_request(pdev, RequestId, EndpointAddress, &usbd_status,
 
 1317        WLog_Print(urbdrc->log, WLOG_DEBUG, 
"PIPE SET HALT: error %u", ret);
 
 1319        ret = USBD_STATUS_SUCCESS;
 
 1324      WLog_Print(urbdrc->log, WLOG_DEBUG, 
"urb_pipe_request: PIPE_RESET ep 0x%" PRIx32 
"",
 
 1326      rc = pdev->control_pipe_request(pdev, RequestId, EndpointAddress, &usbd_status,
 
 1330        WLog_Print(urbdrc->log, WLOG_DEBUG, 
"PIPE RESET: error %u", ret);
 
 1332        ret = USBD_STATUS_SUCCESS;
 
 1337      WLog_Print(urbdrc->log, WLOG_DEBUG, 
"urb_pipe_request action: %d not supported",
 
 1339      ret = USBD_STATUS_INVALID_URB_FUNCTION;
 
 1345  if (out_size > OutputBufferSize)
 
 1347    WLog_Print(urbdrc->log, WLOG_DEBUG, 
"out_size %" PRIu32 
" > OutputBufferSize %" PRIu32,
 
 1348               out_size, OutputBufferSize);
 
 1349    return ERROR_BAD_CONFIGURATION;
 
 1351  out = Stream_New(NULL, out_size);
 
 1354    return ERROR_OUTOFMEMORY;
 
 1356  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId, ret,
 
 1361                                                 UINT32 RequestId, UINT32 MessageId,
 
 1362                                                 UINT32 CompletionId, UINT32 FrameNumber)
 
 1364  WINPR_ASSERT(callback);
 
 1366  const UINT32 InterfaceId = ((STREAM_ID_PROXY << 30) | CompletionId);
 
 1368      create_urb_completion_message(InterfaceId, MessageId, RequestId, URB_COMPLETION_NO_DATA);
 
 1371    return ERROR_OUTOFMEMORY;
 
 1373  Stream_Write_UINT32(out, 12); 
 
 1374  if (!write_urb_result_header(out, 12, USBD_STATUS_SUCCESS))
 
 1376    Stream_Free(out, TRUE);
 
 1377    return ERROR_OUTOFMEMORY;
 
 1380  Stream_Write_UINT32(out, FrameNumber); 
 
 1381  return send_urb_completion_message(callback, out, 0, 0, NULL);
 
 1385                                         wStream* s, UINT32 RequestField, UINT32 MessageId,
 
 1386                                         IUDEVMAN* udevman, 
int transferDir)
 
 1388  const BOOL noAck = (RequestField & 0x80000000U) != 0;
 
 1389  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
 
 1391  if (!callback || !s || !udevman || !pdev)
 
 1392    return ERROR_INVALID_PARAMETER;
 
 1397    return ERROR_INVALID_PARAMETER;
 
 1399  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
 
 1400    return ERROR_INVALID_DATA;
 
 1402  if (transferDir == 0)
 
 1404    WLog_Print(urbdrc->log, WLOG_DEBUG,
 
 1405               "urb_get_current_frame_number: not support transfer out");
 
 1406    return ERROR_INVALID_PARAMETER;
 
 1409  const UINT32 OutputBufferSize = Stream_Get_UINT32(s);
 
 1410  if (OutputBufferSize != 0)
 
 1412    WLog_Print(urbdrc->log, WLOG_WARN, 
"OutputBufferSize=%" PRIu32 
", expected 0",
 
 1416  const UINT32 dummy_frames = GetTickCount();
 
 1417  const UINT32 CompletionId = pdev->get_ReqCompletion(pdev);
 
 1420    return CHANNEL_RC_OK;
 
 1422  return urb_send_current_frame_number_result(callback, RequestId, MessageId, CompletionId,
 
 1427static UINT urb_control_get_configuration_request(IUDEVICE* pdev,
 
 1429                                                  UINT32 RequestField, UINT32 MessageId,
 
 1430                                                  IUDEVMAN* udevman, 
int transferDir)
 
 1432  size_t out_size = 0;
 
 1433  UINT32 InterfaceId = 0;
 
 1434  UINT32 OutputBufferSize = 0;
 
 1435  UINT32 usbd_status = 0;
 
 1438  const BOOL noAck = (RequestField & 0x80000000U) != 0;
 
 1439  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
 
 1441  if (!callback || !s || !udevman || !pdev)
 
 1442    return ERROR_INVALID_PARAMETER;
 
 1447    return ERROR_INVALID_PARAMETER;
 
 1449  if (transferDir == 0)
 
 1451    WLog_Print(urbdrc->log, WLOG_DEBUG,
 
 1452               "urb_control_get_configuration_request:" 
 1453               " not support transfer out");
 
 1454    return ERROR_INVALID_PARAMETER;
 
 1457  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
 
 1458    return ERROR_INVALID_DATA;
 
 1460  Stream_Read_UINT32(s, OutputBufferSize);
 
 1461  if (OutputBufferSize > UINT32_MAX - 36)
 
 1462    return ERROR_INVALID_DATA;
 
 1463  out_size = 36ULL + OutputBufferSize;
 
 1464  out = Stream_New(NULL, out_size);
 
 1467    return ERROR_OUTOFMEMORY;
 
 1469  Stream_Seek(out, 36);
 
 1470  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
 1472  if (!pdev->control_transfer(pdev, RequestId, 0, 0, 0x80 | 0x00,
 
 1474                              0, 0, &usbd_status, &OutputBufferSize, Stream_Pointer(out), 1000))
 
 1476    WLog_Print(urbdrc->log, WLOG_DEBUG, 
"control_transfer failed");
 
 1477    Stream_Free(out, TRUE);
 
 1478    return ERROR_INTERNAL_ERROR;
 
 1481  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
 
 1482                              usbd_status, OutputBufferSize);
 
 1487                                              wStream* s, UINT32 RequestField, UINT32 MessageId,
 
 1488                                              IUDEVMAN* udevman, 
int transferDir)
 
 1490  size_t out_size = 0;
 
 1491  UINT32 InterfaceId = 0;
 
 1492  UINT32 OutputBufferSize = 0;
 
 1493  UINT32 usbd_status = 0;
 
 1494  UINT16 InterfaceNr = 0;
 
 1497  const BOOL noAck = (RequestField & 0x80000000U) != 0;
 
 1498  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
 
 1500  if (!callback || !s || !udevman || !pdev)
 
 1501    return ERROR_INVALID_PARAMETER;
 
 1506    return ERROR_INVALID_PARAMETER;
 
 1508  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
 
 1509    return ERROR_INVALID_DATA;
 
 1511  if (transferDir == 0)
 
 1513    WLog_Print(urbdrc->log, WLOG_DEBUG,
 
 1514               "urb_control_get_interface_request: not support transfer out");
 
 1515    return ERROR_INVALID_PARAMETER;
 
 1518  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
 1519  Stream_Read_UINT16(s, InterfaceNr);
 
 1521  Stream_Read_UINT32(s, OutputBufferSize);
 
 1522  if (OutputBufferSize > UINT32_MAX - 36)
 
 1523    return ERROR_INVALID_DATA;
 
 1524  out_size = 36ULL + OutputBufferSize;
 
 1525  out = Stream_New(NULL, out_size);
 
 1528    return ERROR_OUTOFMEMORY;
 
 1530  Stream_Seek(out, 36);
 
 1532  if (!pdev->control_transfer(
 
 1533          pdev, RequestId, 0, 0, 0x80 | 0x01, 0x0A, 
 
 1534          0, InterfaceNr, &usbd_status, &OutputBufferSize, Stream_Pointer(out), 1000))
 
 1536    WLog_Print(urbdrc->log, WLOG_DEBUG, 
"control_transfer failed");
 
 1537    Stream_Free(out, TRUE);
 
 1538    return ERROR_INTERNAL_ERROR;
 
 1541  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
 
 1542                              usbd_status, OutputBufferSize);
 
 1546                                        wStream* s, UINT32 RequestField, UINT32 MessageId,
 
 1547                                        IUDEVMAN* udevman, BYTE func_recipient, BYTE command,
 
 1550  UINT32 InterfaceId = 0;
 
 1551  UINT32 OutputBufferSize = 0;
 
 1552  UINT32 usbd_status = 0;
 
 1553  UINT16 FeatureSelector = 0;
 
 1555  BYTE bmRequestType = 0;
 
 1559  const BOOL noAck = (RequestField & 0x80000000U) != 0;
 
 1560  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
 
 1562  if (!callback || !s || !udevman || !pdev)
 
 1563    return ERROR_INVALID_PARAMETER;
 
 1568    return ERROR_INVALID_PARAMETER;
 
 1570  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
 
 1571    return ERROR_INVALID_DATA;
 
 1573  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
 
 1574  Stream_Read_UINT16(s, FeatureSelector);
 
 1575  Stream_Read_UINT16(s, Index);
 
 1576  Stream_Read_UINT32(s, OutputBufferSize);
 
 1577  if (OutputBufferSize > UINT32_MAX - 36)
 
 1578    return ERROR_INVALID_DATA;
 
 1579  switch (transferDir)
 
 1581    case USBD_TRANSFER_DIRECTION_OUT:
 
 1582      if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
 
 1583        return ERROR_INVALID_DATA;
 
 1591  out = Stream_New(NULL, 36ULL + OutputBufferSize);
 
 1594    return ERROR_OUTOFMEMORY;
 
 1596  Stream_Seek(out, 36);
 
 1597  bmRequestType = func_recipient;
 
 1599  switch (transferDir)
 
 1601    case USBD_TRANSFER_DIRECTION_OUT:
 
 1602      WLog_Print(urbdrc->log, WLOG_ERROR,
 
 1603                 "Function urb_control_feature_request: OUT Unchecked");
 
 1604      Stream_Copy(s, out, OutputBufferSize);
 
 1605      Stream_Rewind(out, OutputBufferSize);
 
 1606      bmRequestType |= 0x00;
 
 1609    case USBD_TRANSFER_DIRECTION_IN:
 
 1610      bmRequestType |= 0x80;
 
 1618    case URB_SET_FEATURE:
 
 1622    case URB_CLEAR_FEATURE:
 
 1627      WLog_Print(urbdrc->log, WLOG_ERROR,
 
 1628                 "urb_control_feature_request: Error Command 0x%02" PRIx8 
"", command);
 
 1629      Stream_Free(out, TRUE);
 
 1630      return ERROR_INTERNAL_ERROR;
 
 1633  if (!pdev->control_transfer(pdev, RequestId, 0, 0, bmRequestType, bmRequest, FeatureSelector,
 
 1634                              Index, &usbd_status, &OutputBufferSize, Stream_Pointer(out), 1000))
 
 1636    WLog_Print(urbdrc->log, WLOG_DEBUG, 
"feature control transfer failed");
 
 1637    Stream_Free(out, TRUE);
 
 1638    return ERROR_INTERNAL_ERROR;
 
 1641  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
 
 1642                              usbd_status, OutputBufferSize);
 
 1646                                            wStream* s, UINT32 MessageId, IUDEVMAN* udevman,
 
 1651  UINT16 URB_Function = 0;
 
 1652  UINT32 RequestId = 0;
 
 1653  UINT error = ERROR_INTERNAL_ERROR;
 
 1656  if (!callback || !s || !udevman || !pdev)
 
 1657    return ERROR_INVALID_PARAMETER;
 
 1662    return ERROR_INVALID_PARAMETER;
 
 1664  if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
 
 1665    return ERROR_INVALID_DATA;
 
 1667  Stream_Read_UINT32(s, CbTsUrb); 
 
 1668  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4ULL + CbTsUrb))
 
 1669    return ERROR_INVALID_DATA;
 
 1670  Stream_Read_UINT16(s, Size);    
 
 1671  if (Size != CbTsUrb)
 
 1673    const char* section = (transferDir == USBD_TRANSFER_DIRECTION_IN)
 
 1674                              ? 
"2.2.6.7 Transfer In Request (TRANSFER_IN_REQUEST)" 
 1675                              : 
"2.2.6.8 Transfer Out Request (TRANSFER_OUT_REQUEST)";
 
 1677             "[MS-RDPEUSB] 2.2.9.1.1 TS_URB_HEADER::Size 0x04" PRIx16
 
 1678             " != %s::CbTsUrb 0x%08" PRIx32,
 
 1679             Size, section, CbTsUrb);
 
 1680    return ERROR_INVALID_DATA;
 
 1682  Stream_Read_UINT16(s, URB_Function);
 
 1683  Stream_Read_UINT32(s, RequestId);
 
 1684  WLog_Print(urbdrc->log, WLOG_DEBUG, 
"URB %s[%" PRIu16 
"]", urb_function_string(URB_Function),
 
 1687  switch (URB_Function)
 
 1689    case TS_URB_SELECT_CONFIGURATION: 
 
 1690      error = urb_select_configuration(pdev, callback, s, RequestId, MessageId, udevman,
 
 1694    case TS_URB_SELECT_INTERFACE: 
 
 1696          urb_select_interface(pdev, callback, s, RequestId, MessageId, udevman, transferDir);
 
 1699    case TS_URB_PIPE_REQUEST: 
 
 1700      error = urb_pipe_request(pdev, callback, s, RequestId, MessageId, udevman, transferDir,
 
 1704    case TS_URB_TAKE_FRAME_LENGTH_CONTROL: 
 
 1710    case TS_URB_RELEASE_FRAME_LENGTH_CONTROL: 
 
 1716    case TS_URB_GET_FRAME_LENGTH: 
 
 1722    case TS_URB_SET_FRAME_LENGTH: 
 
 1728    case TS_URB_GET_CURRENT_FRAME_NUMBER: 
 
 1729      error = urb_get_current_frame_number(pdev, callback, s, RequestId, MessageId, udevman,
 
 1733    case TS_URB_CONTROL_TRANSFER: 
 
 1734      error = urb_control_transfer(pdev, callback, s, RequestId, MessageId, udevman,
 
 1735                                   transferDir, URB_CONTROL_TRANSFER_NONEXTERNAL);
 
 1738    case TS_URB_BULK_OR_INTERRUPT_TRANSFER: 
 
 1739      error = urb_bulk_or_interrupt_transfer(pdev, callback, s, RequestId, MessageId, udevman,
 
 1743    case TS_URB_ISOCH_TRANSFER: 
 
 1745          urb_isoch_transfer(pdev, callback, s, RequestId, MessageId, udevman, transferDir);
 
 1748    case TS_URB_GET_DESCRIPTOR_FROM_DEVICE: 
 
 1749      error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1753    case TS_URB_SET_DESCRIPTOR_TO_DEVICE: 
 
 1754      error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1758    case TS_URB_SET_FEATURE_TO_DEVICE: 
 
 1759      error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1760                                          0x00, URB_SET_FEATURE, transferDir);
 
 1763    case TS_URB_SET_FEATURE_TO_INTERFACE: 
 
 1764      error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1765                                          0x01, URB_SET_FEATURE, transferDir);
 
 1768    case TS_URB_SET_FEATURE_TO_ENDPOINT: 
 
 1769      error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1770                                          0x02, URB_SET_FEATURE, transferDir);
 
 1773    case TS_URB_CLEAR_FEATURE_TO_DEVICE: 
 
 1774      error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1775                                          0x00, URB_CLEAR_FEATURE, transferDir);
 
 1778    case TS_URB_CLEAR_FEATURE_TO_INTERFACE: 
 
 1779      error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1780                                          0x01, URB_CLEAR_FEATURE, transferDir);
 
 1783    case TS_URB_CLEAR_FEATURE_TO_ENDPOINT: 
 
 1784      error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1785                                          0x02, URB_CLEAR_FEATURE, transferDir);
 
 1788    case TS_URB_GET_STATUS_FROM_DEVICE: 
 
 1789      error = urb_control_get_status_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1793    case TS_URB_GET_STATUS_FROM_INTERFACE: 
 
 1794      error = urb_control_get_status_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1798    case TS_URB_GET_STATUS_FROM_ENDPOINT: 
 
 1799      error = urb_control_get_status_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1803    case TS_URB_RESERVED_0X0016: 
 
 1806    case TS_URB_VENDOR_DEVICE: 
 
 1807      error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
 
 1808                                                  udevman, (0x02 << 5), 
 
 1812    case TS_URB_VENDOR_INTERFACE: 
 
 1813      error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
 
 1814                                                  udevman, (0x02 << 5), 
 
 1818    case TS_URB_VENDOR_ENDPOINT: 
 
 1819      error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
 
 1820                                                  udevman, (0x02 << 5), 
 
 1824    case TS_URB_CLASS_DEVICE: 
 
 1825      error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
 
 1826                                                  udevman, (0x01 << 5), 
 
 1830    case TS_URB_CLASS_INTERFACE: 
 
 1831      error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
 
 1832                                                  udevman, (0x01 << 5), 
 
 1836    case TS_URB_CLASS_ENDPOINT: 
 
 1837      error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
 
 1838                                                  udevman, (0x01 << 5), 
 
 1842    case TS_URB_RESERVE_0X001D: 
 
 1845    case TS_URB_SYNC_RESET_PIPE_AND_CLEAR_STALL: 
 
 1846      error = urb_pipe_request(pdev, callback, s, RequestId, MessageId, udevman, transferDir,
 
 1850    case TS_URB_CLASS_OTHER: 
 
 1851      error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
 
 1852                                                  udevman, (0x01 << 5), 
 
 1856    case TS_URB_VENDOR_OTHER: 
 
 1857      error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
 
 1858                                                  udevman, (0x02 << 5), 
 
 1862    case TS_URB_GET_STATUS_FROM_OTHER: 
 
 1863      error = urb_control_get_status_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1867    case TS_URB_CLEAR_FEATURE_TO_OTHER: 
 
 1868      error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1869                                          0x03, URB_CLEAR_FEATURE, transferDir);
 
 1872    case TS_URB_SET_FEATURE_TO_OTHER: 
 
 1873      error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1874                                          0x03, URB_SET_FEATURE, transferDir);
 
 1877    case TS_URB_GET_DESCRIPTOR_FROM_ENDPOINT: 
 
 1878      error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1882    case TS_URB_SET_DESCRIPTOR_TO_ENDPOINT: 
 
 1883      error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1887    case TS_URB_CONTROL_GET_CONFIGURATION_REQUEST: 
 
 1888      error = urb_control_get_configuration_request(pdev, callback, s, RequestId, MessageId,
 
 1889                                                    udevman, transferDir);
 
 1892    case TS_URB_CONTROL_GET_INTERFACE_REQUEST: 
 
 1893      error = urb_control_get_interface_request(pdev, callback, s, RequestId, MessageId,
 
 1894                                                udevman, transferDir);
 
 1897    case TS_URB_GET_DESCRIPTOR_FROM_INTERFACE: 
 
 1898      error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1902    case TS_URB_SET_DESCRIPTOR_TO_INTERFACE: 
 
 1903      error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
 
 1907    case TS_URB_GET_OS_FEATURE_DESCRIPTOR_REQUEST: 
 
 1908      error = urb_os_feature_descriptor_request(pdev, callback, s, RequestId, MessageId,
 
 1909                                                udevman, transferDir);
 
 1912    case TS_URB_RESERVE_0X002B: 
 
 1913    case TS_URB_RESERVE_0X002C: 
 
 1914    case TS_URB_RESERVE_0X002D: 
 
 1915    case TS_URB_RESERVE_0X002E: 
 
 1916    case TS_URB_RESERVE_0X002F: 
 
 1920    case TS_URB_SYNC_RESET_PIPE: 
 
 1921      error = urb_pipe_request(pdev, callback, s, RequestId, MessageId, udevman, transferDir,
 
 1925    case TS_URB_SYNC_CLEAR_STALL: 
 
 1926      urb_pipe_request(pdev, callback, s, RequestId, MessageId, udevman, transferDir,
 
 1930    case TS_URB_CONTROL_TRANSFER_EX: 
 
 1931      error = urb_control_transfer(pdev, callback, s, RequestId, MessageId, udevman,
 
 1932                                   transferDir, URB_CONTROL_TRANSFER_EXTERNAL);
 
 1936      WLog_Print(urbdrc->log, WLOG_DEBUG, 
"URB_Func: %" PRIx16 
" is not found!",
 
 1943    WLog_Print(urbdrc->log, WLOG_WARN,
 
 1944               "USB transfer request URB Function '%s' [0x%08x] failed with %08" PRIx32,
 
 1945               urb_function_string(URB_Function), URB_Function, error);
 
 1952                                       IUDEVMAN* udevman, 
wStream* data)
 
 1954  UINT32 InterfaceId = 0;
 
 1955  UINT32 MessageId = 0;
 
 1956  UINT32 FunctionId = 0;
 
 1957  IUDEVICE* pdev = NULL;
 
 1958  UINT error = ERROR_INTERNAL_ERROR;
 
 1960  if (!urbdrc || !data || !callback || !udevman)
 
 1963  if (!Stream_CheckAndLogRequiredLength(TAG, data, 8))
 
 1966  Stream_Rewind_UINT32(data);
 
 1968  Stream_Read_UINT32(data, InterfaceId);
 
 1969  Stream_Read_UINT32(data, MessageId);
 
 1970  Stream_Read_UINT32(data, FunctionId);
 
 1972  pdev = udevman->get_udevice_by_UsbDevice(udevman, InterfaceId);
 
 1977    error = ERROR_SUCCESS;
 
 1982  if (pdev->isChannelClosed(pdev))
 
 1984    error = ERROR_SUCCESS;
 
 1989  pdev->detach_kernel_driver(pdev);
 
 1993    case CANCEL_REQUEST:
 
 1994      error = urbdrc_process_cancel_request(pdev, data, udevman);
 
 1997    case REGISTER_REQUEST_CALLBACK:
 
 1998      error = urbdrc_process_register_request_callback(pdev, callback, data, udevman);
 
 2002      error = urbdrc_process_io_control(pdev, callback, data, MessageId, udevman);
 
 2005    case INTERNAL_IO_CONTROL:
 
 2006      error = urbdrc_process_internal_io_control(pdev, callback, data, MessageId, udevman);
 
 2009    case QUERY_DEVICE_TEXT:
 
 2010      error = urbdrc_process_query_device_text(pdev, callback, data, MessageId, udevman);
 
 2013    case TRANSFER_IN_REQUEST:
 
 2014      error = urbdrc_process_transfer_request(pdev, callback, data, MessageId, udevman,
 
 2015                                              USBD_TRANSFER_DIRECTION_IN);
 
 2018    case TRANSFER_OUT_REQUEST:
 
 2019      error = urbdrc_process_transfer_request(pdev, callback, data, MessageId, udevman,
 
 2020                                              USBD_TRANSFER_DIRECTION_OUT);
 
 2023    case RETRACT_DEVICE:
 
 2024      error = urbdrc_process_retract_device_request(pdev, data, udevman);
 
 2028      WLog_Print(urbdrc->log, WLOG_WARN,
 
 2029                 "urbdrc_process_udev_data_transfer:" 
 2030                 " unknown FunctionId 0x%" PRIX32 
"",
 
 2038    WLog_WARN(TAG, 
"USB request failed with %08" PRIx32, error);