20#include <freerdp/config.h> 
   22#include "urbdrc_helpers.h" 
   23#include "urbdrc_types.h" 
   24#include <winpr/print.h> 
   26const char* mask_to_string(UINT32 mask)
 
   31      return "STREAM_ID_NONE";
 
   34      return "STREAM_ID_PROXY";
 
   37      return "STREAM_ID_STUB";
 
   43const char* interface_to_string(UINT32 
id)
 
   47    case CAPABILITIES_NEGOTIATOR:
 
   48      return "CAPABILITIES_NEGOTIATOR";
 
   50    case SERVER_CHANNEL_NOTIFICATION:
 
   51      return "SERVER_CHANNEL_NOTIFICATION";
 
   53    case CLIENT_CHANNEL_NOTIFICATION:
 
   54      return "CLIENT_CHANNEL_NOTIFICATION";
 
   57      return "DEVICE_MESSAGE";
 
   61static const char* call_to_string_none(BOOL client, UINT32 interfaceId, UINT32 functionId)
 
   63  WINPR_UNUSED(interfaceId);
 
   66    return "RIM_EXCHANGE_CAPABILITY_RESPONSE  [none |client]";
 
   71      case RIM_EXCHANGE_CAPABILITY_REQUEST:
 
   72        return "RIM_EXCHANGE_CAPABILITY_REQUEST   [none |server]";
 
   75        return "RIMCALL_RELEASE                   [none |server]";
 
   77      case RIMCALL_QUERYINTERFACE:
 
   78        return "RIMCALL_QUERYINTERFACE            [none |server]";
 
   81        return "UNKNOWN                           [none |server]";
 
   86static const char* call_to_string_proxy_server(UINT32 functionId)
 
   90    case QUERY_DEVICE_TEXT:
 
   91      return "QUERY_DEVICE_TEXT                 [proxy|server]";
 
   93    case INTERNAL_IO_CONTROL:
 
   94      return "INTERNAL_IO_CONTROL               [proxy|server]";
 
   97      return "IO_CONTROL                        [proxy|server]";
 
   99    case REGISTER_REQUEST_CALLBACK:
 
  100      return "REGISTER_REQUEST_CALLBACK         [proxy|server]";
 
  103      return "CANCEL_REQUEST                    [proxy|server]";
 
  106      return "RETRACT_DEVICE                    [proxy|server]";
 
  108    case TRANSFER_IN_REQUEST:
 
  109      return "TRANSFER_IN_REQUEST               [proxy|server]";
 
  111    case TRANSFER_OUT_REQUEST:
 
  112      return "TRANSFER_OUT_REQUEST              [proxy|server]";
 
  115      return "UNKNOWN                           [proxy|server]";
 
  119static const char* call_to_string_proxy_client(UINT32 functionId)
 
  123    case URB_COMPLETION_NO_DATA:
 
  124      return "URB_COMPLETION_NO_DATA            [proxy|client]";
 
  127      return "URB_COMPLETION                    [proxy|client]";
 
  129    case IOCONTROL_COMPLETION:
 
  130      return "IOCONTROL_COMPLETION              [proxy|client]";
 
  132    case TRANSFER_OUT_REQUEST:
 
  133      return "TRANSFER_OUT_REQUEST              [proxy|client]";
 
  136      return "UNKNOWN                           [proxy|client]";
 
  140static const char* call_to_string_proxy(BOOL client, UINT32 interfaceId, UINT32 functionId)
 
  142  switch (interfaceId & INTERFACE_ID_MASK)
 
  144    case CLIENT_DEVICE_SINK:
 
  147        case ADD_VIRTUAL_CHANNEL:
 
  148          return "ADD_VIRTUAL_CHANNEL               [proxy|sink  ]";
 
  151          return "ADD_DEVICE                        [proxy|sink  ]";
 
  152        case RIMCALL_RELEASE:
 
  153          return "RIMCALL_RELEASE                   [proxy|sink  ]";
 
  155        case RIMCALL_QUERYINTERFACE:
 
  156          return "RIMCALL_QUERYINTERFACE            [proxy|sink  ]";
 
  158          return "UNKNOWN                           [proxy|sink  ]";
 
  161    case SERVER_CHANNEL_NOTIFICATION:
 
  164        case CHANNEL_CREATED:
 
  165          return "CHANNEL_CREATED                   [proxy|server]";
 
  167        case RIMCALL_RELEASE:
 
  168          return "RIMCALL_RELEASE                   [proxy|server]";
 
  170        case RIMCALL_QUERYINTERFACE:
 
  171          return "RIMCALL_QUERYINTERFACE            [proxy|server]";
 
  174          return "UNKNOWN                           [proxy|server]";
 
  177    case CLIENT_CHANNEL_NOTIFICATION:
 
  180        case CHANNEL_CREATED:
 
  181          return "CHANNEL_CREATED                   [proxy|client]";
 
  182        case RIMCALL_RELEASE:
 
  183          return "RIMCALL_RELEASE                   [proxy|client]";
 
  184        case RIMCALL_QUERYINTERFACE:
 
  185          return "RIMCALL_QUERYINTERFACE            [proxy|client]";
 
  187          return "UNKNOWN                           [proxy|client]";
 
  192        return call_to_string_proxy_client(functionId);
 
  194        return call_to_string_proxy_server(functionId);
 
  198static const char* call_to_string_stub(WINPR_ATTR_UNUSED BOOL client,
 
  199                                       WINPR_ATTR_UNUSED UINT32 interfaceNr,
 
  200                                       WINPR_ATTR_UNUSED UINT32 functionId)
 
  202  return "QUERY_DEVICE_TEXT_RSP             [stub  |client]";
 
  205const char* call_to_string(BOOL client, UINT32 interfaceNr, UINT32 functionId)
 
  207  const UINT32 mask = (interfaceNr & STREAM_ID_MASK) >> 30;
 
  208  const UINT32 interfaceId = interfaceNr & INTERFACE_ID_MASK;
 
  213      return call_to_string_none(client, interfaceId, functionId);
 
  215    case STREAM_ID_PROXY:
 
  216      return call_to_string_proxy(client, interfaceId, functionId);
 
  219      return call_to_string_stub(client, interfaceId, functionId);
 
  222      return "UNKNOWN[mask]";
 
  226const char* urb_function_string(UINT16 urb)
 
  230    case TS_URB_SELECT_CONFIGURATION:
 
  231      return "TS_URB_SELECT_CONFIGURATION";
 
  233    case TS_URB_SELECT_INTERFACE:
 
  234      return "TS_URB_SELECT_INTERFACE";
 
  236    case TS_URB_PIPE_REQUEST:
 
  237      return "TS_URB_PIPE_REQUEST";
 
  239    case TS_URB_TAKE_FRAME_LENGTH_CONTROL:
 
  240      return "TS_URB_TAKE_FRAME_LENGTH_CONTROL";
 
  242    case TS_URB_RELEASE_FRAME_LENGTH_CONTROL:
 
  243      return "TS_URB_RELEASE_FRAME_LENGTH_CONTROL";
 
  245    case TS_URB_GET_FRAME_LENGTH:
 
  246      return "TS_URB_GET_FRAME_LENGTH";
 
  248    case TS_URB_SET_FRAME_LENGTH:
 
  249      return "TS_URB_SET_FRAME_LENGTH";
 
  251    case TS_URB_GET_CURRENT_FRAME_NUMBER:
 
  252      return "TS_URB_GET_CURRENT_FRAME_NUMBER";
 
  254    case TS_URB_CONTROL_TRANSFER:
 
  255      return "TS_URB_CONTROL_TRANSFER";
 
  257    case TS_URB_BULK_OR_INTERRUPT_TRANSFER:
 
  258      return "TS_URB_BULK_OR_INTERRUPT_TRANSFER";
 
  260    case TS_URB_ISOCH_TRANSFER:
 
  261      return "TS_URB_ISOCH_TRANSFER";
 
  263    case TS_URB_GET_DESCRIPTOR_FROM_DEVICE:
 
  264      return "TS_URB_GET_DESCRIPTOR_FROM_DEVICE";
 
  266    case TS_URB_SET_DESCRIPTOR_TO_DEVICE:
 
  267      return "TS_URB_SET_DESCRIPTOR_TO_DEVICE";
 
  269    case TS_URB_SET_FEATURE_TO_DEVICE:
 
  270      return "TS_URB_SET_FEATURE_TO_DEVICE";
 
  272    case TS_URB_SET_FEATURE_TO_INTERFACE:
 
  273      return "TS_URB_SET_FEATURE_TO_INTERFACE";
 
  275    case TS_URB_SET_FEATURE_TO_ENDPOINT:
 
  276      return "TS_URB_SET_FEATURE_TO_ENDPOINT";
 
  278    case TS_URB_CLEAR_FEATURE_TO_DEVICE:
 
  279      return "TS_URB_CLEAR_FEATURE_TO_DEVICE";
 
  281    case TS_URB_CLEAR_FEATURE_TO_INTERFACE:
 
  282      return "TS_URB_CLEAR_FEATURE_TO_INTERFACE";
 
  284    case TS_URB_CLEAR_FEATURE_TO_ENDPOINT:
 
  285      return "TS_URB_CLEAR_FEATURE_TO_ENDPOINT";
 
  287    case TS_URB_GET_STATUS_FROM_DEVICE:
 
  288      return "TS_URB_GET_STATUS_FROM_DEVICE";
 
  290    case TS_URB_GET_STATUS_FROM_INTERFACE:
 
  291      return "TS_URB_GET_STATUS_FROM_INTERFACE";
 
  293    case TS_URB_GET_STATUS_FROM_ENDPOINT:
 
  294      return "TS_URB_GET_STATUS_FROM_ENDPOINT";
 
  296    case TS_URB_RESERVED_0X0016:
 
  297      return "TS_URB_RESERVED_0X0016";
 
  299    case TS_URB_VENDOR_DEVICE:
 
  300      return "TS_URB_VENDOR_DEVICE";
 
  302    case TS_URB_VENDOR_INTERFACE:
 
  303      return "TS_URB_VENDOR_INTERFACE";
 
  305    case TS_URB_VENDOR_ENDPOINT:
 
  306      return "TS_URB_VENDOR_ENDPOINT";
 
  308    case TS_URB_CLASS_DEVICE:
 
  309      return "TS_URB_CLASS_DEVICE";
 
  311    case TS_URB_CLASS_INTERFACE:
 
  312      return "TS_URB_CLASS_INTERFACE";
 
  314    case TS_URB_CLASS_ENDPOINT:
 
  315      return "TS_URB_CLASS_ENDPOINT";
 
  317    case TS_URB_RESERVE_0X001D:
 
  318      return "TS_URB_RESERVE_0X001D";
 
  320    case TS_URB_SYNC_RESET_PIPE_AND_CLEAR_STALL:
 
  321      return "TS_URB_SYNC_RESET_PIPE_AND_CLEAR_STALL";
 
  323    case TS_URB_CLASS_OTHER:
 
  324      return "TS_URB_CLASS_OTHER";
 
  326    case TS_URB_VENDOR_OTHER:
 
  327      return "TS_URB_VENDOR_OTHER";
 
  329    case TS_URB_GET_STATUS_FROM_OTHER:
 
  330      return "TS_URB_GET_STATUS_FROM_OTHER";
 
  332    case TS_URB_CLEAR_FEATURE_TO_OTHER:
 
  333      return "TS_URB_CLEAR_FEATURE_TO_OTHER";
 
  335    case TS_URB_SET_FEATURE_TO_OTHER:
 
  336      return "TS_URB_SET_FEATURE_TO_OTHER";
 
  338    case TS_URB_GET_DESCRIPTOR_FROM_ENDPOINT:
 
  339      return "TS_URB_GET_DESCRIPTOR_FROM_ENDPOINT";
 
  341    case TS_URB_SET_DESCRIPTOR_TO_ENDPOINT:
 
  342      return "TS_URB_SET_DESCRIPTOR_TO_ENDPOINT";
 
  344    case TS_URB_CONTROL_GET_CONFIGURATION_REQUEST:
 
  345      return "TS_URB_CONTROL_GET_CONFIGURATION_REQUEST";
 
  347    case TS_URB_CONTROL_GET_INTERFACE_REQUEST:
 
  348      return "TS_URB_CONTROL_GET_INTERFACE_REQUEST";
 
  350    case TS_URB_GET_DESCRIPTOR_FROM_INTERFACE:
 
  351      return "TS_URB_GET_DESCRIPTOR_FROM_INTERFACE";
 
  353    case TS_URB_SET_DESCRIPTOR_TO_INTERFACE:
 
  354      return "TS_URB_SET_DESCRIPTOR_TO_INTERFACE";
 
  356    case TS_URB_GET_OS_FEATURE_DESCRIPTOR_REQUEST:
 
  357      return "TS_URB_GET_OS_FEATURE_DESCRIPTOR_REQUEST";
 
  359    case TS_URB_RESERVE_0X002B:
 
  360      return "TS_URB_RESERVE_0X002B";
 
  362    case TS_URB_RESERVE_0X002C:
 
  363      return "TS_URB_RESERVE_0X002C";
 
  365    case TS_URB_RESERVE_0X002D:
 
  366      return "TS_URB_RESERVE_0X002D";
 
  368    case TS_URB_RESERVE_0X002E:
 
  369      return "TS_URB_RESERVE_0X002E";
 
  371    case TS_URB_RESERVE_0X002F:
 
  372      return "TS_URB_RESERVE_0X002F";
 
  374    case TS_URB_SYNC_RESET_PIPE:
 
  375      return "TS_URB_SYNC_RESET_PIPE";
 
  377    case TS_URB_SYNC_CLEAR_STALL:
 
  378      return "TS_URB_SYNC_CLEAR_STALL";
 
  380    case TS_URB_CONTROL_TRANSFER_EX:
 
  381      return "TS_URB_CONTROL_TRANSFER_EX";
 
  388void urbdrc_dump_message(wLog* log, BOOL client, BOOL write, 
wStream* s)
 
  390  const char* type = write ? 
"WRITE" : 
"READ";
 
  391  UINT32 InterfaceId = 0;
 
  392  UINT32 MessageId = 0;
 
  393  UINT32 FunctionId = 0;
 
  397  pos = Stream_GetPosition(s);
 
  401    Stream_SetPosition(s, 0);
 
  404    length = Stream_GetRemainingLength(s);
 
  409  Stream_Read_UINT32(s, InterfaceId);
 
  410  Stream_Read_UINT32(s, MessageId);
 
  411  Stream_Read_UINT32(s, FunctionId);
 
  412  Stream_SetPosition(s, pos);
 
  414  WLog_Print(log, WLOG_DEBUG,
 
  415             "[%-5s] %s [%08" PRIx32 
"] InterfaceId=%08" PRIx32 
", MessageId=%08" PRIx32
 
  416             ", FunctionId=%08" PRIx32 
", length=%" PRIuz,
 
  417             type, call_to_string(client, InterfaceId, FunctionId), FunctionId, InterfaceId,
 
  418             MessageId, FunctionId, length);
 
  419#if defined(WITH_DEBUG_URBDRC) 
  421    WLog_Print(log, WLOG_TRACE, 
"-------------------------- URBDRC sent: ---");
 
  423    WLog_Print(log, WLOG_TRACE, 
"-------------------------- URBDRC received:");
 
  424  winpr_HexLogDump(log, WLOG_TRACE, Stream_Buffer(s), length);
 
  425  WLog_Print(log, WLOG_TRACE, 
"-------------------------- URBDRC end -----");
 
  430BOOL write_shared_message_header_with_functionid(
wStream* s, UINT32 InterfaceId, UINT32 MessageId,
 
  433  if (!Stream_EnsureRemainingCapacity(s, 12))
 
  436  Stream_Write_UINT32(s, InterfaceId);
 
  437  Stream_Write_UINT32(s, MessageId);
 
  438  Stream_Write_UINT32(s, FunctionId);
 
  442wStream* create_shared_message_header_with_functionid(UINT32 InterfaceId, UINT32 MessageId,
 
  443                                                      UINT32 FunctionId, 
size_t OutputSize)
 
  445  wStream* out = Stream_New(NULL, 12ULL + OutputSize);
 
  448  (void)write_shared_message_header_with_functionid(out, InterfaceId, MessageId, FunctionId);