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);