FreeRDP
data_transfer.c
1 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include <winpr/sysinfo.h>
26 #include <winpr/cast.h>
27 
28 #include <urbdrc_helpers.h>
29 
30 #include "urbdrc_types.h"
31 #include "data_transfer.h"
32 
33 static void usb_process_get_port_status(IUDEVICE* pdev, wStream* out)
34 {
35  int bcdUSB = pdev->query_device_descriptor(pdev, BCD_USB);
36 
37  switch (bcdUSB)
38  {
39  case USB_v1_0:
40  Stream_Write_UINT32(out, 0x303);
41  break;
42 
43  case USB_v1_1:
44  Stream_Write_UINT32(out, 0x103);
45  break;
46 
47  case USB_v2_0:
48  default:
49  Stream_Write_UINT32(out, 0x503);
50  break;
51  }
52 }
53 
54 static UINT urb_write_completion(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback, BOOL noAck,
55  wStream* out, UINT32 InterfaceId, UINT32 MessageId,
56  UINT32 RequestId, UINT32 usbd_status, UINT32 OutputBufferSize)
57 {
58  if (!out)
59  return ERROR_INVALID_PARAMETER;
60 
61  if (Stream_Capacity(out) < OutputBufferSize + 36)
62  {
63  Stream_Free(out, TRUE);
64  return ERROR_INVALID_PARAMETER;
65  }
66 
67  Stream_SetPosition(out, 0);
68  Stream_Write_UINT32(out, InterfaceId);
69  Stream_Write_UINT32(out, MessageId);
71  if (OutputBufferSize != 0)
72  Stream_Write_UINT32(out, URB_COMPLETION);
73  else
74  Stream_Write_UINT32(out, URB_COMPLETION_NO_DATA);
75 
76  Stream_Write_UINT32(out, RequestId);
77  Stream_Write_UINT32(out, 8);
79  Stream_Write_UINT16(out, 8);
80  Stream_Write_UINT16(out, 0); /* Padding */
81  Stream_Write_UINT32(out, usbd_status);
82  Stream_Write_UINT32(out, 0);
83  Stream_Write_UINT32(out, OutputBufferSize);
84  Stream_Seek(out, OutputBufferSize);
85 
86  if (!noAck)
87  return stream_write_and_free(callback->plugin, callback->channel, out);
88  else
89  Stream_Free(out, TRUE);
90 
91  return ERROR_SUCCESS;
92 }
93 
94 static wStream* urb_create_iocompletion(UINT32 InterfaceField, UINT32 MessageId, UINT32 RequestId,
95  UINT32 OutputBufferSize)
96 {
97  const UINT32 InterfaceId = (STREAM_ID_PROXY << 30) | (InterfaceField & 0x3FFFFFFF);
98 
99 #if UINT32_MAX >= SIZE_MAX
100  if (OutputBufferSize > UINT32_MAX - 28ull)
101  return NULL;
102 #endif
103 
104  wStream* out = Stream_New(NULL, OutputBufferSize + 28ull);
105 
106  if (!out)
107  return NULL;
108 
109  Stream_Write_UINT32(out, InterfaceId);
110  Stream_Write_UINT32(out, MessageId);
111  Stream_Write_UINT32(out, IOCONTROL_COMPLETION);
112  Stream_Write_UINT32(out, RequestId);
113  Stream_Write_UINT32(out, USBD_STATUS_SUCCESS);
114  Stream_Write_UINT32(out, OutputBufferSize);
115  Stream_Write_UINT32(out, OutputBufferSize);
116  return out;
117 }
118 
119 static UINT urbdrc_process_register_request_callback(IUDEVICE* pdev,
120  GENERIC_CHANNEL_CALLBACK* callback, wStream* s,
121  IUDEVMAN* udevman)
122 {
123  UINT32 NumRequestCompletion = 0;
124  UINT32 RequestCompletion = 0;
125 
126  if (!callback || !s || !udevman || !pdev)
127  return ERROR_INVALID_PARAMETER;
128 
129  URBDRC_PLUGIN* urbdrc = (URBDRC_PLUGIN*)callback->plugin;
130 
131  if (!urbdrc)
132  return ERROR_INVALID_PARAMETER;
133 
134  WLog_Print(urbdrc->log, WLOG_DEBUG, "urbdrc_process_register_request_callback");
135 
136  if (Stream_GetRemainingLength(s) >= 8)
137  {
138  Stream_Read_UINT32(s, NumRequestCompletion);
141  Stream_Read_UINT32(s, RequestCompletion);
142  pdev->set_ReqCompletion(pdev, RequestCompletion);
143  }
144  else if (Stream_GetRemainingLength(s) >= 4)
145  {
146  Stream_Read_UINT32(s, RequestCompletion);
147 
148  if (pdev->get_ReqCompletion(pdev) == RequestCompletion)
149  pdev->setChannelClosed(pdev);
150  }
151  else
152  return ERROR_INVALID_DATA;
153 
154  return ERROR_SUCCESS;
155 }
156 
157 static UINT urbdrc_process_cancel_request(IUDEVICE* pdev, wStream* s, IUDEVMAN* udevman)
158 {
159  UINT32 CancelId = 0;
160  URBDRC_PLUGIN* urbdrc = NULL;
161 
162  if (!s || !udevman || !pdev)
163  return ERROR_INVALID_PARAMETER;
164 
165  urbdrc = (URBDRC_PLUGIN*)udevman->plugin;
166 
167  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
168  return ERROR_INVALID_DATA;
169 
170  Stream_Read_UINT32(s, CancelId);
171  WLog_Print(urbdrc->log, WLOG_DEBUG, "CANCEL_REQUEST: CancelId=%08" PRIx32 "", CancelId);
172 
173  if (pdev->cancel_transfer_request(pdev, CancelId) < 0)
174  return ERROR_INTERNAL_ERROR;
175 
176  return ERROR_SUCCESS;
177 }
178 
179 static UINT urbdrc_process_retract_device_request(IUDEVICE* pdev, wStream* s, IUDEVMAN* udevman)
180 {
181  UINT32 Reason = 0;
182  URBDRC_PLUGIN* urbdrc = NULL;
183 
184  if (!s || !udevman)
185  return ERROR_INVALID_PARAMETER;
186 
187  urbdrc = (URBDRC_PLUGIN*)udevman->plugin;
188 
189  if (!urbdrc)
190  return ERROR_INVALID_PARAMETER;
191 
192  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
193  return ERROR_INVALID_DATA;
194 
195  Stream_Read_UINT32(s, Reason);
197  switch (Reason)
198  {
199  case UsbRetractReason_BlockedByPolicy:
200  WLog_Print(urbdrc->log, WLOG_DEBUG,
201  "UsbRetractReason_BlockedByPolicy: now it is not support");
202  return ERROR_ACCESS_DENIED;
203 
204  default:
205  WLog_Print(urbdrc->log, WLOG_DEBUG,
206  "urbdrc_process_retract_device_request: Unknown Reason %" PRIu32 "", Reason);
207  return ERROR_ACCESS_DENIED;
208  }
209 
210  return ERROR_SUCCESS;
211 }
212 
213 static UINT urbdrc_process_io_control(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback,
214  wStream* s, UINT32 MessageId, IUDEVMAN* udevman)
215 {
216  UINT32 InterfaceId = 0;
217  UINT32 IoControlCode = 0;
218  UINT32 InputBufferSize = 0;
219  UINT32 OutputBufferSize = 0;
220  UINT32 RequestId = 0;
221  UINT32 usbd_status = USBD_STATUS_SUCCESS;
222  wStream* out = NULL;
223  int success = 0;
224  URBDRC_PLUGIN* urbdrc = NULL;
225 
226  if (!callback || !s || !udevman || !pdev)
227  return ERROR_INVALID_PARAMETER;
228 
229  urbdrc = (URBDRC_PLUGIN*)callback->plugin;
230 
231  if (!urbdrc)
232  return ERROR_INVALID_PARAMETER;
233 
234  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
235  return ERROR_INVALID_DATA;
236 
237  Stream_Read_UINT32(s, IoControlCode);
238  Stream_Read_UINT32(s, InputBufferSize);
239 
240  if (!Stream_SafeSeek(s, InputBufferSize))
241  return ERROR_INVALID_DATA;
242  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ULL))
243  return ERROR_INVALID_DATA;
244 
245  Stream_Read_UINT32(s, OutputBufferSize);
246  Stream_Read_UINT32(s, RequestId);
247 
248  if (OutputBufferSize > UINT32_MAX - 4)
249  return ERROR_INVALID_DATA;
250 
251  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
252  out = urb_create_iocompletion(InterfaceId, MessageId, RequestId, OutputBufferSize + 4);
253 
254  if (!out)
255  return ERROR_OUTOFMEMORY;
256 
257  switch (IoControlCode)
258  {
259  case IOCTL_INTERNAL_USB_SUBMIT_URB:
260  WLog_Print(urbdrc->log, WLOG_DEBUG, "ioctl: IOCTL_INTERNAL_USB_SUBMIT_URB");
261  WLog_Print(urbdrc->log, WLOG_ERROR,
262  " Function IOCTL_INTERNAL_USB_SUBMIT_URB: Unchecked");
263  break;
264 
265  case IOCTL_INTERNAL_USB_RESET_PORT:
266  WLog_Print(urbdrc->log, WLOG_DEBUG, "ioctl: IOCTL_INTERNAL_USB_RESET_PORT");
267  break;
268 
269  case IOCTL_INTERNAL_USB_GET_PORT_STATUS:
270  WLog_Print(urbdrc->log, WLOG_DEBUG, "ioctl: IOCTL_INTERNAL_USB_GET_PORT_STATUS");
271  success = pdev->query_device_port_status(pdev, &usbd_status, &OutputBufferSize,
272  Stream_Pointer(out));
273 
274  if (success)
275  {
276  if (!Stream_SafeSeek(out, OutputBufferSize))
277  {
278  Stream_Free(out, TRUE);
279  return ERROR_INVALID_DATA;
280  }
281 
282  if (pdev->isExist(pdev) == 0)
283  Stream_Write_UINT32(out, 0);
284  else
285  usb_process_get_port_status(pdev, out);
286  }
287 
288  break;
289 
290  case IOCTL_INTERNAL_USB_CYCLE_PORT:
291  WLog_Print(urbdrc->log, WLOG_DEBUG, "ioctl: IOCTL_INTERNAL_USB_CYCLE_PORT");
292  WLog_Print(urbdrc->log, WLOG_ERROR,
293  " Function IOCTL_INTERNAL_USB_CYCLE_PORT: Unchecked");
294  break;
295 
296  case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
297  WLog_Print(urbdrc->log, WLOG_DEBUG,
298  "ioctl: IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION");
299  WLog_Print(urbdrc->log, WLOG_ERROR,
300  " Function IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: Unchecked");
301  break;
302 
303  default:
304  WLog_Print(urbdrc->log, WLOG_DEBUG,
305  "urbdrc_process_io_control: unknown IoControlCode 0x%" PRIX32 "",
306  IoControlCode);
307  Stream_Free(out, TRUE);
308  return ERROR_INVALID_OPERATION;
309  }
310 
311  return stream_write_and_free(callback->plugin, callback->channel, out);
312 }
313 
314 static UINT urbdrc_process_internal_io_control(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback,
315  wStream* s, UINT32 MessageId, IUDEVMAN* udevman)
316 {
317  wStream* out = NULL;
318  UINT32 IoControlCode = 0;
319  UINT32 InterfaceId = 0;
320  UINT32 InputBufferSize = 0;
321  UINT32 OutputBufferSize = 0;
322  UINT32 RequestId = 0;
323  UINT32 frames = 0;
324 
325  if (!pdev || !callback || !s || !udevman)
326  return ERROR_INVALID_PARAMETER;
327 
328  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
329  return ERROR_INVALID_DATA;
330 
331  Stream_Read_UINT32(s, IoControlCode);
332  Stream_Read_UINT32(s, InputBufferSize);
333 
334  if (!Stream_SafeSeek(s, InputBufferSize))
335  return ERROR_INVALID_DATA;
336  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8ULL))
337  return ERROR_INVALID_DATA;
338  Stream_Read_UINT32(s, OutputBufferSize);
339  Stream_Read_UINT32(s, RequestId);
340  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
341  // TODO: Implement control code.
343  frames = GetTickCount();
344  out = urb_create_iocompletion(InterfaceId, MessageId, RequestId, 4);
345 
346  if (!out)
347  return ERROR_OUTOFMEMORY;
348 
349  Stream_Write_UINT32(out, frames);
350  return stream_write_and_free(callback->plugin, callback->channel, out);
351 }
352 
353 static UINT urbdrc_process_query_device_text(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback,
354  wStream* s, UINT32 MessageId, IUDEVMAN* udevman)
355 {
356  UINT32 out_size = 0;
357  UINT32 TextType = 0;
358  UINT32 LocaleId = 0;
359  UINT32 InterfaceId = 0;
360  UINT8 bufferSize = 0xFF;
361  UINT32 hr = 0;
362  wStream* out = NULL;
363  BYTE DeviceDescription[0x100] = { 0 };
364 
365  if (!pdev || !callback || !s || !udevman)
366  return ERROR_INVALID_PARAMETER;
367  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
368  return ERROR_INVALID_DATA;
369 
370  Stream_Read_UINT32(s, TextType);
371  Stream_Read_UINT32(s, LocaleId);
372  if (LocaleId > UINT16_MAX)
373  return ERROR_INVALID_DATA;
374 
375  hr = pdev->control_query_device_text(pdev, TextType, (UINT16)LocaleId, &bufferSize,
376  DeviceDescription);
377  InterfaceId = ((STREAM_ID_STUB << 30) | pdev->get_UsbDevice(pdev));
378  out_size = 16 + bufferSize;
379 
380  if (bufferSize != 0)
381  out_size += 2;
382 
383  out = Stream_New(NULL, out_size);
384 
385  if (!out)
386  return ERROR_OUTOFMEMORY;
387 
388  Stream_Write_UINT32(out, InterfaceId);
389  Stream_Write_UINT32(out, MessageId);
390  Stream_Write_UINT32(out, bufferSize / 2);
391  Stream_Write(out, DeviceDescription, bufferSize); /* '\0' terminated unicode */
392  Stream_Write_UINT32(out, hr);
393  return stream_write_and_free(callback->plugin, callback->channel, out);
394 }
395 
396 static void func_select_all_interface_for_msconfig(IUDEVICE* pdev,
397  MSUSB_CONFIG_DESCRIPTOR* MsConfig)
398 {
399  MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = MsConfig->MsInterfaces;
400  BYTE InterfaceNumber = 0;
401  BYTE AlternateSetting = 0;
402  UINT32 NumInterfaces = MsConfig->NumInterfaces;
403 
404  for (UINT32 inum = 0; inum < NumInterfaces; inum++)
405  {
406  InterfaceNumber = MsInterfaces[inum]->InterfaceNumber;
407  AlternateSetting = MsInterfaces[inum]->AlternateSetting;
408  pdev->select_interface(pdev, InterfaceNumber, AlternateSetting);
409  }
410 }
411 
412 static UINT urb_select_configuration(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback, wStream* s,
413  UINT32 RequestField, UINT32 MessageId, IUDEVMAN* udevman,
414  int transferDir)
415 {
416  MSUSB_CONFIG_DESCRIPTOR* MsConfig = NULL;
417  size_t out_size = 0;
418  UINT32 InterfaceId = 0;
419  UINT32 NumInterfaces = 0;
420  UINT32 usbd_status = 0;
421  BYTE ConfigurationDescriptorIsValid = 0;
422  wStream* out = NULL;
423  size_t MsOutSize = 0;
424  URBDRC_PLUGIN* urbdrc = NULL;
425  const BOOL noAck = (RequestField & 0x80000000U) != 0;
426  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
427 
428  if (!callback || !s || !udevman || !pdev)
429  return ERROR_INVALID_PARAMETER;
430 
431  urbdrc = (URBDRC_PLUGIN*)callback->plugin;
432 
433  if (!urbdrc)
434  return ERROR_INVALID_PARAMETER;
435 
436  if (transferDir == 0)
437  {
438  WLog_Print(urbdrc->log, WLOG_ERROR, "urb_select_configuration: unsupported transfer out");
439  return ERROR_INVALID_PARAMETER;
440  }
441 
442  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
443  return ERROR_INVALID_DATA;
444 
445  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
446  Stream_Read_UINT8(s, ConfigurationDescriptorIsValid);
447  Stream_Seek(s, 3); /* Padding */
448  Stream_Read_UINT32(s, NumInterfaces);
449 
451  if (ConfigurationDescriptorIsValid)
452  {
453  /* parser data for struct config */
454  MsConfig = msusb_msconfig_read(s, NumInterfaces);
455 
456  if (!MsConfig)
457  return ERROR_INVALID_DATA;
458 
459  /* select config */
460  pdev->select_configuration(pdev, MsConfig->bConfigurationValue);
461  /* select all interface */
462  func_select_all_interface_for_msconfig(pdev, MsConfig);
463  /* complete configuration setup */
464  if (!pdev->complete_msconfig_setup(pdev, MsConfig))
465  {
466  msusb_msconfig_free(MsConfig);
467  MsConfig = NULL;
468  }
469  }
470 
471  if (MsConfig)
472  MsOutSize = WINPR_ASSERTING_INT_CAST(size_t, MsConfig->MsOutSize);
473 
474  if (MsOutSize > 0)
475  {
476  if (MsOutSize > SIZE_MAX - 36)
477  return ERROR_INVALID_DATA;
478 
479  out_size = 36 + MsOutSize;
480  }
481  else
482  out_size = 44;
483 
484  out = Stream_New(NULL, out_size);
485 
486  if (!out)
487  return ERROR_OUTOFMEMORY;
488 
489  Stream_Write_UINT32(out, InterfaceId);
490  Stream_Write_UINT32(out, MessageId);
491  Stream_Write_UINT32(out, URB_COMPLETION_NO_DATA);
492  Stream_Write_UINT32(out, RequestId);
494  if (MsOutSize > 0)
495  {
497  Stream_Write_UINT32(out, 8U + (UINT32)MsOutSize);
499  Stream_Write_UINT16(out, WINPR_ASSERTING_INT_CAST(uint16_t, 8U + (UINT32)MsOutSize));
500  }
501  else
502  {
503  Stream_Write_UINT32(out, 16);
504  Stream_Write_UINT16(out, 16);
505  }
506 
508  Stream_Write_UINT16(out, TS_URB_SELECT_CONFIGURATION);
509  Stream_Write_UINT32(out, usbd_status);
512  if (MsOutSize > 0)
513  msusb_msconfig_write(MsConfig, out);
514  else
515  {
516  Stream_Write_UINT32(out, 0);
517  Stream_Write_UINT32(out, NumInterfaces);
518  }
519 
520  Stream_Write_UINT32(out, 0);
521  Stream_Write_UINT32(out, 0);
523  if (!noAck)
524  return stream_write_and_free(callback->plugin, callback->channel, out);
525  else
526  Stream_Free(out, TRUE);
527 
528  return ERROR_SUCCESS;
529 }
530 
531 static UINT urb_select_interface(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback, wStream* s,
532  UINT32 RequestField, UINT32 MessageId, IUDEVMAN* udevman,
533  int transferDir)
534 {
535  MSUSB_CONFIG_DESCRIPTOR* MsConfig = NULL;
536  MSUSB_INTERFACE_DESCRIPTOR* MsInterface = NULL;
537  UINT32 out_size = 0;
538  UINT32 InterfaceId = 0;
539  UINT32 ConfigurationHandle = 0;
540  UINT32 OutputBufferSize = 0;
541  BYTE InterfaceNumber = 0;
542  wStream* out = NULL;
543  UINT32 interface_size = 0;
544  URBDRC_PLUGIN* urbdrc = NULL;
545  const BOOL noAck = (RequestField & 0x80000000U) != 0;
546  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
547 
548  if (!callback || !s || !udevman || !pdev)
549  return ERROR_INVALID_PARAMETER;
550 
551  urbdrc = (URBDRC_PLUGIN*)callback->plugin;
552 
553  if (!urbdrc)
554  return ERROR_INVALID_PARAMETER;
555 
556  if (transferDir == 0)
557  {
558  WLog_Print(urbdrc->log, WLOG_ERROR, "urb_select_interface: not support transfer out");
559  return ERROR_INVALID_PARAMETER;
560  }
561 
562  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
563  return ERROR_INVALID_DATA;
564 
565  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
566  Stream_Read_UINT32(s, ConfigurationHandle);
567  MsInterface = msusb_msinterface_read(s);
568 
569  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4) || !MsInterface)
570  {
571  msusb_msinterface_free(MsInterface);
572  return ERROR_INVALID_DATA;
573  }
574 
575  Stream_Read_UINT32(s, OutputBufferSize);
576  pdev->select_interface(pdev, MsInterface->InterfaceNumber, MsInterface->AlternateSetting);
577  /* replace device's MsInterface */
578  MsConfig = pdev->get_MsConfig(pdev);
579  InterfaceNumber = MsInterface->InterfaceNumber;
580  if (!msusb_msinterface_replace(MsConfig, InterfaceNumber, MsInterface))
581  {
582  msusb_msconfig_free(MsConfig);
583  return ERROR_BAD_CONFIGURATION;
584  }
585  /* complete configuration setup */
586  if (!pdev->complete_msconfig_setup(pdev, MsConfig))
587  {
588  msusb_msconfig_free(MsConfig);
589  return ERROR_BAD_CONFIGURATION;
590  }
591  MsInterface = MsConfig->MsInterfaces[InterfaceNumber];
592  interface_size = 16 + (MsInterface->NumberOfPipes * 20);
593  out_size = 36 + interface_size;
594  out = Stream_New(NULL, out_size);
595 
596  if (!out)
597  return ERROR_OUTOFMEMORY;
598 
599  Stream_Write_UINT32(out, InterfaceId);
600  Stream_Write_UINT32(out, MessageId);
601  Stream_Write_UINT32(out, URB_COMPLETION_NO_DATA);
602  Stream_Write_UINT32(out, RequestId);
603  Stream_Write_UINT32(out, 8 + interface_size);
605  Stream_Write_UINT16(out, WINPR_ASSERTING_INT_CAST(uint16_t, 8 + interface_size));
607  Stream_Write_UINT16(out, TS_URB_SELECT_INTERFACE);
608  Stream_Write_UINT32(out, USBD_STATUS_SUCCESS);
610  msusb_msinterface_write(MsInterface, out);
611  Stream_Write_UINT32(out, 0);
612  Stream_Write_UINT32(out, 0);
614  if (!noAck)
615  return stream_write_and_free(callback->plugin, callback->channel, out);
616  else
617  Stream_Free(out, TRUE);
618 
619  return ERROR_SUCCESS;
620 }
621 
622 static UINT urb_control_transfer(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback, wStream* s,
623  UINT32 RequestField, UINT32 MessageId, IUDEVMAN* udevman,
624  int transferDir, int External)
625 {
626  UINT32 out_size = 0;
627  UINT32 InterfaceId = 0;
628  UINT32 EndpointAddress = 0;
629  UINT32 PipeHandle = 0;
630  UINT32 TransferFlags = 0;
631  UINT32 OutputBufferSize = 0;
632  UINT32 usbd_status = 0;
633  UINT32 Timeout = 0;
634  BYTE bmRequestType = 0;
635  BYTE Request = 0;
636  UINT16 Value = 0;
637  UINT16 Index = 0;
638  UINT16 length = 0;
639  BYTE* buffer = NULL;
640  wStream* out = NULL;
641  URBDRC_PLUGIN* urbdrc = NULL;
642  const BOOL noAck = (RequestField & 0x80000000U) != 0;
643  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
644 
645  if (!callback || !s || !udevman || !pdev)
646  return ERROR_INVALID_PARAMETER;
647 
648  urbdrc = (URBDRC_PLUGIN*)callback->plugin;
649 
650  if (!urbdrc)
651  return ERROR_INVALID_PARAMETER;
652 
653  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
654  return ERROR_INVALID_DATA;
655 
656  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
657  Stream_Read_UINT32(s, PipeHandle);
658  Stream_Read_UINT32(s, TransferFlags);
659  EndpointAddress = (PipeHandle & 0x000000ff);
660  Timeout = 2000;
661 
662  switch (External)
663  {
664  case URB_CONTROL_TRANSFER_EXTERNAL:
665  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
666  return ERROR_INVALID_DATA;
667 
668  Stream_Read_UINT32(s, Timeout);
669  break;
670 
671  case URB_CONTROL_TRANSFER_NONEXTERNAL:
672  break;
673  default:
674  break;
675  }
676 
678  if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
679  return ERROR_INVALID_DATA;
680 
681  Stream_Read_UINT8(s, bmRequestType);
682  Stream_Read_UINT8(s, Request);
683  Stream_Read_UINT16(s, Value);
684  Stream_Read_UINT16(s, Index);
685  Stream_Read_UINT16(s, length);
686  Stream_Read_UINT32(s, OutputBufferSize);
687 
688  if (length != OutputBufferSize)
689  {
690  WLog_Print(urbdrc->log, WLOG_ERROR, "urb_control_transfer ERROR: buf != length");
691  return ERROR_INVALID_DATA;
692  }
693 
694  out_size = 36 + OutputBufferSize;
695  out = Stream_New(NULL, out_size);
696 
697  if (!out)
698  return ERROR_OUTOFMEMORY;
699 
700  Stream_Seek(out, 36);
702  buffer = Stream_Pointer(out);
703 
704  if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
705  {
706  if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
707  {
708  Stream_Free(out, TRUE);
709  return ERROR_INVALID_DATA;
710  }
711  Stream_Copy(s, out, OutputBufferSize);
712  }
713 
715  if (!pdev->control_transfer(pdev, RequestId, EndpointAddress, TransferFlags, bmRequestType,
716  Request, Value, Index, &usbd_status, &OutputBufferSize, buffer,
717  Timeout))
718  {
719  WLog_Print(urbdrc->log, WLOG_ERROR, "control_transfer failed");
720  Stream_Free(out, TRUE);
721  return ERROR_INTERNAL_ERROR;
722  }
723 
724  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
725  usbd_status, OutputBufferSize);
726 }
727 
728 static void urb_bulk_transfer_cb(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback, wStream* out,
729  UINT32 InterfaceId, BOOL noAck, UINT32 MessageId, UINT32 RequestId,
730  UINT32 NumberOfPackets, UINT32 status, UINT32 StartFrame,
731  UINT32 ErrorCount, UINT32 OutputBufferSize)
732 {
733  if (!pdev->isChannelClosed(pdev))
734  urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId, status,
735  OutputBufferSize);
736  else
737  Stream_Free(out, TRUE);
738 }
739 
740 static UINT urb_bulk_or_interrupt_transfer(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback,
741  wStream* s, UINT32 RequestField, UINT32 MessageId,
742  IUDEVMAN* udevman, int transferDir)
743 {
744  UINT32 EndpointAddress = 0;
745  UINT32 PipeHandle = 0;
746  UINT32 TransferFlags = 0;
747  UINT32 OutputBufferSize = 0;
748  const BOOL noAck = (RequestField & 0x80000000U) != 0;
749  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
750 
751  if (!pdev || !callback || !s || !udevman)
752  return ERROR_INVALID_PARAMETER;
753 
754  if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
755  return ERROR_INVALID_DATA;
756 
757  Stream_Read_UINT32(s, PipeHandle);
758  Stream_Read_UINT32(s, TransferFlags);
759  Stream_Read_UINT32(s, OutputBufferSize);
760  EndpointAddress = (PipeHandle & 0x000000ff);
761 
762  if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
763  {
764  if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
765  {
766  return ERROR_INVALID_DATA;
767  }
768  }
769 
771  const int rc = pdev->bulk_or_interrupt_transfer(
772  pdev, callback, MessageId, RequestId, EndpointAddress, TransferFlags, noAck,
773  OutputBufferSize, (transferDir == USBD_TRANSFER_DIRECTION_OUT) ? Stream_Pointer(s) : NULL,
774  urb_bulk_transfer_cb, 10000);
775 
776  return (uint32_t)rc;
777 }
778 
779 static void urb_isoch_transfer_cb(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback, wStream* out,
780  UINT32 InterfaceId, BOOL noAck, UINT32 MessageId,
781  UINT32 RequestId, UINT32 NumberOfPackets, UINT32 status,
782  UINT32 StartFrame, UINT32 ErrorCount, UINT32 OutputBufferSize)
783 {
784  if (!noAck)
785  {
786  UINT32 packetSize = (status == 0) ? NumberOfPackets * 12 : 0;
787  Stream_SetPosition(out, 0);
788  /* fill the send data */
789  Stream_Write_UINT32(out, InterfaceId);
790  Stream_Write_UINT32(out, MessageId);
792  if (OutputBufferSize == 0)
793  Stream_Write_UINT32(out, URB_COMPLETION_NO_DATA);
794  else
795  Stream_Write_UINT32(out, URB_COMPLETION);
797  Stream_Write_UINT32(out, RequestId);
798  Stream_Write_UINT32(out, 20 + packetSize);
800  Stream_Write_UINT16(out, WINPR_ASSERTING_INT_CAST(uint16_t, 20 + packetSize));
801  Stream_Write_UINT16(out, 0); /* Padding */
802  Stream_Write_UINT32(out, status);
803  Stream_Write_UINT32(out, StartFrame);
805  if (status == 0)
806  {
808  Stream_Write_UINT32(out, NumberOfPackets);
809  Stream_Write_UINT32(out, ErrorCount);
810  Stream_Seek(out, packetSize);
811  }
812  else
813  {
814  Stream_Write_UINT32(out, 0);
815  Stream_Write_UINT32(out, ErrorCount);
816  }
817 
818  Stream_Write_UINT32(out, 0);
819  Stream_Write_UINT32(out, OutputBufferSize);
820  Stream_Seek(out, OutputBufferSize);
821 
822  stream_write_and_free(callback->plugin, callback->channel, out);
823  }
824 }
825 
826 static UINT urb_isoch_transfer(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback, wStream* s,
827  UINT32 RequestField, UINT32 MessageId, IUDEVMAN* udevman,
828  int transferDir)
829 {
830  int rc = 0;
831  UINT32 EndpointAddress = 0;
832  UINT32 PipeHandle = 0;
833  UINT32 TransferFlags = 0;
834  UINT32 StartFrame = 0;
835  UINT32 NumberOfPackets = 0;
836  UINT32 ErrorCount = 0;
837  UINT32 OutputBufferSize = 0;
838  BYTE* packetDescriptorData = NULL;
839  const BOOL noAck = (RequestField & 0x80000000U) != 0;
840  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
841 
842  if (!pdev || !callback || !udevman)
843  return ERROR_INVALID_PARAMETER;
844 
845  if (!Stream_CheckAndLogRequiredLength(TAG, s, 20))
846  return ERROR_INVALID_DATA;
847 
848  Stream_Read_UINT32(s, PipeHandle);
849  EndpointAddress = (PipeHandle & 0x000000ff);
850  Stream_Read_UINT32(s, TransferFlags);
851  Stream_Read_UINT32(s, StartFrame);
852  Stream_Read_UINT32(s, NumberOfPackets);
853  Stream_Read_UINT32(s, ErrorCount);
855  if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, NumberOfPackets, 12ull))
856  return ERROR_INVALID_DATA;
857 
858  packetDescriptorData = Stream_Pointer(s);
859  Stream_Seek(s, 12ULL * NumberOfPackets);
860 
861  if (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(UINT32)))
862  return ERROR_INVALID_DATA;
863  Stream_Read_UINT32(s, OutputBufferSize);
864 
865  if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
866  {
867  if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
868  return ERROR_INVALID_DATA;
869  }
870 
871  rc = pdev->isoch_transfer(
872  pdev, callback, MessageId, RequestId, EndpointAddress, TransferFlags, StartFrame,
873  ErrorCount, noAck, packetDescriptorData, NumberOfPackets, OutputBufferSize,
874  (transferDir == USBD_TRANSFER_DIRECTION_OUT) ? Stream_Pointer(s) : NULL,
875  urb_isoch_transfer_cb, 2000);
876 
877  if (rc < 0)
878  return ERROR_INTERNAL_ERROR;
879  return (UINT)rc;
880 }
881 
882 static UINT urb_control_descriptor_request(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback,
883  wStream* s, UINT32 RequestField, UINT32 MessageId,
884  IUDEVMAN* udevman, BYTE func_recipient, int transferDir)
885 {
886  size_t out_size = 0;
887  UINT32 InterfaceId = 0;
888  UINT32 OutputBufferSize = 0;
889  UINT32 usbd_status = 0;
890  BYTE bmRequestType = 0;
891  BYTE desc_index = 0;
892  BYTE desc_type = 0;
893  UINT16 langId = 0;
894  wStream* out = NULL;
895  URBDRC_PLUGIN* urbdrc = NULL;
896  const BOOL noAck = (RequestField & 0x80000000U) != 0;
897  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
898 
899  if (!callback || !s || !udevman || !pdev)
900  return ERROR_INVALID_PARAMETER;
901 
902  urbdrc = (URBDRC_PLUGIN*)callback->plugin;
903 
904  if (!urbdrc)
905  return ERROR_INVALID_PARAMETER;
906 
907  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
908  return ERROR_INVALID_DATA;
909 
910  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
911  Stream_Read_UINT8(s, desc_index);
912  Stream_Read_UINT8(s, desc_type);
913  Stream_Read_UINT16(s, langId);
914  Stream_Read_UINT32(s, OutputBufferSize);
915  if (OutputBufferSize > UINT32_MAX - 36)
916  return ERROR_INVALID_DATA;
917  if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
918  {
919  if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
920  return ERROR_INVALID_DATA;
921  }
922 
923  out_size = 36ULL + OutputBufferSize;
924  out = Stream_New(NULL, out_size);
925 
926  if (!out)
927  return ERROR_OUTOFMEMORY;
928 
929  Stream_Seek(out, 36);
930  bmRequestType = func_recipient;
931 
932  switch (transferDir)
933  {
934  case USBD_TRANSFER_DIRECTION_IN:
935  bmRequestType |= 0x80;
936  break;
937 
938  case USBD_TRANSFER_DIRECTION_OUT:
939  bmRequestType |= 0x00;
940  Stream_Copy(s, out, OutputBufferSize);
941  Stream_Rewind(out, OutputBufferSize);
942  break;
943 
944  default:
945  WLog_Print(urbdrc->log, WLOG_DEBUG, "get error transferDir");
946  OutputBufferSize = 0;
947  usbd_status = USBD_STATUS_STALL_PID;
948  break;
949  }
950 
952  if (!pdev->control_transfer(pdev, RequestId, 0, 0, bmRequestType,
953  0x06, /* REQUEST_GET_DESCRIPTOR */
954  WINPR_ASSERTING_INT_CAST(UINT16, ((desc_type << 8) | desc_index)),
955  langId, &usbd_status, &OutputBufferSize, Stream_Pointer(out), 1000))
956  {
957  WLog_Print(urbdrc->log, WLOG_ERROR, "get_descriptor failed");
958  Stream_Free(out, TRUE);
959  return ERROR_INTERNAL_ERROR;
960  }
961 
962  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
963  usbd_status, OutputBufferSize);
964 }
965 
966 static UINT urb_control_get_status_request(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback,
967  wStream* s, UINT32 RequestField, UINT32 MessageId,
968  IUDEVMAN* udevman, BYTE func_recipient, int transferDir)
969 {
970  size_t out_size = 0;
971  UINT32 InterfaceId = 0;
972  UINT32 OutputBufferSize = 0;
973  UINT32 usbd_status = 0;
974  UINT16 Index = 0;
975  BYTE bmRequestType = 0;
976  wStream* out = NULL;
977  URBDRC_PLUGIN* urbdrc = NULL;
978  const BOOL noAck = (RequestField & 0x80000000U) != 0;
979  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
980 
981  if (!callback || !s || !udevman || !pdev)
982  return ERROR_INVALID_PARAMETER;
983 
984  urbdrc = (URBDRC_PLUGIN*)callback->plugin;
985 
986  if (!urbdrc)
987  return ERROR_INVALID_PARAMETER;
988 
989  if (transferDir == 0)
990  {
991  WLog_Print(urbdrc->log, WLOG_DEBUG,
992  "urb_control_get_status_request: transfer out not supported");
993  return ERROR_INVALID_PARAMETER;
994  }
995 
996  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
997  return ERROR_INVALID_DATA;
998 
999  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
1000  Stream_Read_UINT16(s, Index);
1001  Stream_Seek(s, 2);
1002  Stream_Read_UINT32(s, OutputBufferSize);
1003  if (OutputBufferSize > UINT32_MAX - 36)
1004  return ERROR_INVALID_DATA;
1005  out_size = 36ULL + OutputBufferSize;
1006  out = Stream_New(NULL, out_size);
1007 
1008  if (!out)
1009  return ERROR_OUTOFMEMORY;
1010 
1011  Stream_Seek(out, 36);
1012  bmRequestType = func_recipient | 0x80;
1013 
1014  if (!pdev->control_transfer(pdev, RequestId, 0, 0, bmRequestType, 0x00, /* REQUEST_GET_STATUS */
1015  0, Index, &usbd_status, &OutputBufferSize, Stream_Pointer(out),
1016  1000))
1017  {
1018  WLog_Print(urbdrc->log, WLOG_ERROR, "control_transfer failed");
1019  Stream_Free(out, TRUE);
1020  return ERROR_INTERNAL_ERROR;
1021  }
1022 
1023  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
1024  usbd_status, OutputBufferSize);
1025 }
1026 
1027 static UINT urb_control_vendor_or_class_request(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback,
1028  wStream* s, UINT32 RequestField, UINT32 MessageId,
1029  IUDEVMAN* udevman, BYTE func_type,
1030  BYTE func_recipient, int transferDir)
1031 {
1032  UINT32 out_size = 0;
1033  UINT32 InterfaceId = 0;
1034  UINT32 TransferFlags = 0;
1035  UINT32 usbd_status = 0;
1036  UINT32 OutputBufferSize = 0;
1037  BYTE ReqTypeReservedBits = 0;
1038  BYTE Request = 0;
1039  BYTE bmRequestType = 0;
1040  UINT16 Value = 0;
1041  UINT16 Index = 0;
1042  wStream* out = NULL;
1043  URBDRC_PLUGIN* urbdrc = NULL;
1044  const BOOL noAck = (RequestField & 0x80000000U) != 0;
1045  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
1046 
1047  if (!callback || !s || !udevman || !pdev)
1048  return ERROR_INVALID_PARAMETER;
1049 
1050  urbdrc = (URBDRC_PLUGIN*)callback->plugin;
1051 
1052  if (!urbdrc)
1053  return ERROR_INVALID_PARAMETER;
1054 
1055  if (!Stream_CheckAndLogRequiredLength(TAG, s, 16))
1056  return ERROR_INVALID_DATA;
1057 
1058  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
1059  Stream_Read_UINT32(s, TransferFlags);
1060  Stream_Read_UINT8(s, ReqTypeReservedBits);
1061  Stream_Read_UINT8(s, Request);
1062  Stream_Read_UINT16(s, Value);
1063  Stream_Read_UINT16(s, Index);
1064  Stream_Seek_UINT16(s);
1065  Stream_Read_UINT32(s, OutputBufferSize);
1066  if (OutputBufferSize > UINT32_MAX - 36)
1067  return ERROR_INVALID_DATA;
1068 
1069  if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
1070  {
1071  if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
1072  return ERROR_INVALID_DATA;
1073  }
1074 
1075  out_size = 36ULL + OutputBufferSize;
1076  out = Stream_New(NULL, out_size);
1077 
1078  if (!out)
1079  return ERROR_OUTOFMEMORY;
1080 
1081  Stream_Seek(out, 36);
1082 
1084  if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
1085  {
1086  Stream_Copy(s, out, OutputBufferSize);
1087  Stream_Rewind(out, OutputBufferSize);
1088  }
1089 
1091  bmRequestType = func_type | func_recipient;
1092 
1093  if (TransferFlags & USBD_TRANSFER_DIRECTION)
1094  bmRequestType |= 0x80;
1095 
1096  WLog_Print(urbdrc->log, WLOG_DEBUG,
1097  "RequestId 0x%" PRIx32 " TransferFlags: 0x%" PRIx32 " ReqTypeReservedBits: 0x%" PRIx8
1098  " "
1099  "Request:0x%" PRIx8 " Value: 0x%" PRIx16 " Index: 0x%" PRIx16
1100  " OutputBufferSize: 0x%" PRIx32 " bmRequestType: 0x%" PRIx8,
1101  RequestId, TransferFlags, ReqTypeReservedBits, Request, Value, Index,
1102  OutputBufferSize, bmRequestType);
1103 
1104  if (!pdev->control_transfer(pdev, RequestId, 0, 0, bmRequestType, Request, Value, Index,
1105  &usbd_status, &OutputBufferSize, Stream_Pointer(out), 2000))
1106  {
1107  WLog_Print(urbdrc->log, WLOG_ERROR, "control_transfer failed");
1108  Stream_Free(out, TRUE);
1109  return ERROR_INTERNAL_ERROR;
1110  }
1111 
1112  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
1113  usbd_status, OutputBufferSize);
1114 }
1115 
1116 static UINT urb_os_feature_descriptor_request(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback,
1117  wStream* s, UINT32 RequestField, UINT32 MessageId,
1118  IUDEVMAN* udevman, int transferDir)
1119 {
1120  size_t out_size = 0;
1121  UINT32 InterfaceId = 0;
1122  UINT32 OutputBufferSize = 0;
1123  UINT32 usbd_status = 0;
1124  BYTE Recipient = 0;
1125  BYTE InterfaceNumber = 0;
1126  BYTE Ms_PageIndex = 0;
1127  UINT16 Ms_featureDescIndex = 0;
1128  wStream* out = NULL;
1129  int ret = 0;
1130  URBDRC_PLUGIN* urbdrc = NULL;
1131  const BOOL noAck = (RequestField & 0x80000000U) != 0;
1132  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
1133 
1134  if (!callback || !s || !udevman || !pdev)
1135  return ERROR_INVALID_PARAMETER;
1136 
1137  urbdrc = (URBDRC_PLUGIN*)callback->plugin;
1138 
1139  if (!urbdrc)
1140  return ERROR_INVALID_PARAMETER;
1141 
1142  if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
1143  return ERROR_INVALID_DATA;
1144 
1145  /* 2.2.9.15 TS_URB_OS_FEATURE_DESCRIPTOR_REQUEST */
1146  Stream_Read_UINT8(s, Recipient);
1147  Recipient = (Recipient & 0x1f); /* Mask out Padding1 */
1148  Stream_Read_UINT8(s, InterfaceNumber);
1149  Stream_Read_UINT8(s, Ms_PageIndex);
1150  Stream_Read_UINT16(s, Ms_featureDescIndex);
1151  Stream_Seek(s, 3); /* Padding 2 */
1152  Stream_Read_UINT32(s, OutputBufferSize);
1153  if (OutputBufferSize > UINT32_MAX - 36)
1154  return ERROR_INVALID_DATA;
1155 
1156  switch (transferDir)
1157  {
1158  case USBD_TRANSFER_DIRECTION_OUT:
1159  if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
1160  return ERROR_INVALID_DATA;
1161 
1162  break;
1163 
1164  default:
1165  break;
1166  }
1167 
1168  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
1169  out_size = 36ULL + OutputBufferSize;
1170  out = Stream_New(NULL, out_size);
1171 
1172  if (!out)
1173  return ERROR_OUTOFMEMORY;
1174 
1175  Stream_Seek(out, 36);
1176 
1177  switch (transferDir)
1178  {
1179  case USBD_TRANSFER_DIRECTION_OUT:
1180  Stream_Copy(s, out, OutputBufferSize);
1181  Stream_Rewind(out, OutputBufferSize);
1182  break;
1183 
1184  case USBD_TRANSFER_DIRECTION_IN:
1185  break;
1186  default:
1187  break;
1188  }
1189 
1190  WLog_Print(urbdrc->log, WLOG_DEBUG,
1191  "Ms descriptor arg: Recipient:0x%" PRIx8 ", "
1192  "InterfaceNumber:0x%" PRIx8 ", Ms_PageIndex:0x%" PRIx8 ", "
1193  "Ms_featureDescIndex:0x%" PRIx16 ", OutputBufferSize:0x%" PRIx32 "",
1194  Recipient, InterfaceNumber, Ms_PageIndex, Ms_featureDescIndex, OutputBufferSize);
1196  ret = pdev->os_feature_descriptor_request(pdev, RequestId, Recipient, InterfaceNumber,
1197  Ms_PageIndex, Ms_featureDescIndex, &usbd_status,
1198  &OutputBufferSize, Stream_Pointer(out), 1000);
1199 
1200  if (ret < 0)
1201  WLog_Print(urbdrc->log, WLOG_DEBUG, "os_feature_descriptor_request: error num %d", ret);
1202 
1203  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
1204  usbd_status, OutputBufferSize);
1205 }
1206 
1207 static UINT urb_pipe_request(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback, wStream* s,
1208  UINT32 RequestField, UINT32 MessageId, IUDEVMAN* udevman,
1209  int transferDir, int action)
1210 {
1211  UINT32 out_size = 0;
1212  UINT32 InterfaceId = 0;
1213  UINT32 PipeHandle = 0;
1214  UINT32 EndpointAddress = 0;
1215  UINT32 OutputBufferSize = 0;
1216  UINT32 usbd_status = 0;
1217  wStream* out = NULL;
1218  UINT32 ret = USBD_STATUS_REQUEST_FAILED;
1219  int rc = 0;
1220  URBDRC_PLUGIN* urbdrc = NULL;
1221  const BOOL noAck = (RequestField & 0x80000000U) != 0;
1222  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
1223 
1224  if (!callback || !s || !udevman || !pdev)
1225  return ERROR_INVALID_PARAMETER;
1226 
1227  urbdrc = (URBDRC_PLUGIN*)callback->plugin;
1228 
1229  if (!urbdrc)
1230  return ERROR_INVALID_PARAMETER;
1231 
1232  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1233  return ERROR_INVALID_DATA;
1234 
1235  if (transferDir == 0)
1236  {
1237  WLog_Print(urbdrc->log, WLOG_DEBUG, "urb_pipe_request: not support transfer out");
1238  return ERROR_INVALID_PARAMETER;
1239  }
1240 
1241  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
1242  Stream_Read_UINT32(s, PipeHandle);
1243  Stream_Read_UINT32(s, OutputBufferSize);
1244  EndpointAddress = (PipeHandle & 0x000000ff);
1245 
1246  switch (action)
1247  {
1248  case PIPE_CANCEL:
1249  rc = pdev->control_pipe_request(pdev, RequestId, EndpointAddress, &usbd_status,
1250  PIPE_CANCEL);
1251 
1252  if (rc < 0)
1253  WLog_Print(urbdrc->log, WLOG_DEBUG, "PIPE SET HALT: error %d", ret);
1254  else
1255  ret = USBD_STATUS_SUCCESS;
1256 
1257  break;
1258 
1259  case PIPE_RESET:
1260  WLog_Print(urbdrc->log, WLOG_DEBUG, "urb_pipe_request: PIPE_RESET ep 0x%" PRIx32 "",
1261  EndpointAddress);
1262  rc = pdev->control_pipe_request(pdev, RequestId, EndpointAddress, &usbd_status,
1263  PIPE_RESET);
1264 
1265  if (rc < 0)
1266  WLog_Print(urbdrc->log, WLOG_DEBUG, "PIPE RESET: error %d", ret);
1267  else
1268  ret = USBD_STATUS_SUCCESS;
1269 
1270  break;
1271 
1272  default:
1273  WLog_Print(urbdrc->log, WLOG_DEBUG, "urb_pipe_request action: %d not supported",
1274  action);
1275  ret = USBD_STATUS_INVALID_URB_FUNCTION;
1276  break;
1277  }
1278 
1280  out_size = 36;
1281  out = Stream_New(NULL, out_size);
1282 
1283  if (!out)
1284  return ERROR_OUTOFMEMORY;
1285 
1286  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId, ret,
1287  0);
1288 }
1289 
1290 static UINT urb_get_current_frame_number(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback,
1291  wStream* s, UINT32 RequestField, UINT32 MessageId,
1292  IUDEVMAN* udevman, int transferDir)
1293 {
1294  UINT32 out_size = 0;
1295  UINT32 InterfaceId = 0;
1296  UINT32 OutputBufferSize = 0;
1297  UINT32 dummy_frames = 0;
1298  wStream* out = NULL;
1299  URBDRC_PLUGIN* urbdrc = NULL;
1300  const BOOL noAck = (RequestField & 0x80000000U) != 0;
1301  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
1302 
1303  if (!callback || !s || !udevman || !pdev)
1304  return ERROR_INVALID_PARAMETER;
1305 
1306  urbdrc = (URBDRC_PLUGIN*)callback->plugin;
1307 
1308  if (!urbdrc)
1309  return ERROR_INVALID_PARAMETER;
1310 
1311  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1312  return ERROR_INVALID_DATA;
1313 
1314  if (transferDir == 0)
1315  {
1316  WLog_Print(urbdrc->log, WLOG_DEBUG,
1317  "urb_get_current_frame_number: not support transfer out");
1318  return ERROR_INVALID_PARAMETER;
1319  }
1320 
1321  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
1322  Stream_Read_UINT32(s, OutputBufferSize);
1324  dummy_frames = GetTickCount();
1325  out_size = 40;
1326  out = Stream_New(NULL, out_size);
1327 
1328  if (!out)
1329  return ERROR_OUTOFMEMORY;
1330 
1331  Stream_Write_UINT32(out, InterfaceId);
1332  Stream_Write_UINT32(out, MessageId);
1333  Stream_Write_UINT32(out, URB_COMPLETION_NO_DATA);
1334  Stream_Write_UINT32(out, RequestId);
1335  Stream_Write_UINT32(out, 12);
1337  Stream_Write_UINT16(out, 12);
1339  Stream_Write_UINT16(out, TS_URB_GET_CURRENT_FRAME_NUMBER);
1340  Stream_Write_UINT32(out, USBD_STATUS_SUCCESS);
1341  Stream_Write_UINT32(out, dummy_frames);
1342  Stream_Write_UINT32(out, 0);
1343  Stream_Write_UINT32(out, 0);
1345  if (!noAck)
1346  return stream_write_and_free(callback->plugin, callback->channel, out);
1347  else
1348  Stream_Free(out, TRUE);
1349 
1350  return ERROR_SUCCESS;
1351 }
1352 
1353 /* Unused function for current server */
1354 static UINT urb_control_get_configuration_request(IUDEVICE* pdev,
1355  GENERIC_CHANNEL_CALLBACK* callback, wStream* s,
1356  UINT32 RequestField, UINT32 MessageId,
1357  IUDEVMAN* udevman, int transferDir)
1358 {
1359  size_t out_size = 0;
1360  UINT32 InterfaceId = 0;
1361  UINT32 OutputBufferSize = 0;
1362  UINT32 usbd_status = 0;
1363  wStream* out = NULL;
1364  URBDRC_PLUGIN* urbdrc = NULL;
1365  const BOOL noAck = (RequestField & 0x80000000U) != 0;
1366  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
1367 
1368  if (!callback || !s || !udevman || !pdev)
1369  return ERROR_INVALID_PARAMETER;
1370 
1371  urbdrc = (URBDRC_PLUGIN*)callback->plugin;
1372 
1373  if (!urbdrc)
1374  return ERROR_INVALID_PARAMETER;
1375 
1376  if (transferDir == 0)
1377  {
1378  WLog_Print(urbdrc->log, WLOG_DEBUG,
1379  "urb_control_get_configuration_request:"
1380  " not support transfer out");
1381  return ERROR_INVALID_PARAMETER;
1382  }
1383 
1384  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1385  return ERROR_INVALID_DATA;
1386 
1387  Stream_Read_UINT32(s, OutputBufferSize);
1388  if (OutputBufferSize > UINT32_MAX - 36)
1389  return ERROR_INVALID_DATA;
1390  out_size = 36ULL + OutputBufferSize;
1391  out = Stream_New(NULL, out_size);
1392 
1393  if (!out)
1394  return ERROR_OUTOFMEMORY;
1395 
1396  Stream_Seek(out, 36);
1397  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
1398 
1399  if (!pdev->control_transfer(pdev, RequestId, 0, 0, 0x80 | 0x00,
1400  0x08, /* REQUEST_GET_CONFIGURATION */
1401  0, 0, &usbd_status, &OutputBufferSize, Stream_Pointer(out), 1000))
1402  {
1403  WLog_Print(urbdrc->log, WLOG_DEBUG, "control_transfer failed");
1404  Stream_Free(out, TRUE);
1405  return ERROR_INTERNAL_ERROR;
1406  }
1407 
1408  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
1409  usbd_status, OutputBufferSize);
1410 }
1411 
1412 /* Unused function for current server */
1413 static UINT urb_control_get_interface_request(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback,
1414  wStream* s, UINT32 RequestField, UINT32 MessageId,
1415  IUDEVMAN* udevman, int transferDir)
1416 {
1417  size_t out_size = 0;
1418  UINT32 InterfaceId = 0;
1419  UINT32 OutputBufferSize = 0;
1420  UINT32 usbd_status = 0;
1421  UINT16 InterfaceNr = 0;
1422  wStream* out = NULL;
1423  URBDRC_PLUGIN* urbdrc = NULL;
1424  const BOOL noAck = (RequestField & 0x80000000U) != 0;
1425  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
1426 
1427  if (!callback || !s || !udevman || !pdev)
1428  return ERROR_INVALID_PARAMETER;
1429 
1430  urbdrc = (URBDRC_PLUGIN*)callback->plugin;
1431 
1432  if (!urbdrc)
1433  return ERROR_INVALID_PARAMETER;
1434 
1435  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1436  return ERROR_INVALID_DATA;
1437 
1438  if (transferDir == 0)
1439  {
1440  WLog_Print(urbdrc->log, WLOG_DEBUG,
1441  "urb_control_get_interface_request: not support transfer out");
1442  return ERROR_INVALID_PARAMETER;
1443  }
1444 
1445  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
1446  Stream_Read_UINT16(s, InterfaceNr);
1447  Stream_Seek(s, 2);
1448  Stream_Read_UINT32(s, OutputBufferSize);
1449  if (OutputBufferSize > UINT32_MAX - 36)
1450  return ERROR_INVALID_DATA;
1451  out_size = 36ULL + OutputBufferSize;
1452  out = Stream_New(NULL, out_size);
1453 
1454  if (!out)
1455  return ERROR_OUTOFMEMORY;
1456 
1457  Stream_Seek(out, 36);
1458 
1459  if (!pdev->control_transfer(
1460  pdev, RequestId, 0, 0, 0x80 | 0x01, 0x0A, /* REQUEST_GET_INTERFACE */
1461  0, InterfaceNr, &usbd_status, &OutputBufferSize, Stream_Pointer(out), 1000))
1462  {
1463  WLog_Print(urbdrc->log, WLOG_DEBUG, "control_transfer failed");
1464  Stream_Free(out, TRUE);
1465  return ERROR_INTERNAL_ERROR;
1466  }
1467 
1468  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
1469  usbd_status, OutputBufferSize);
1470 }
1471 
1472 static UINT urb_control_feature_request(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback,
1473  wStream* s, UINT32 RequestField, UINT32 MessageId,
1474  IUDEVMAN* udevman, BYTE func_recipient, BYTE command,
1475  int transferDir)
1476 {
1477  UINT32 InterfaceId = 0;
1478  UINT32 OutputBufferSize = 0;
1479  UINT32 usbd_status = 0;
1480  UINT16 FeatureSelector = 0;
1481  UINT16 Index = 0;
1482  BYTE bmRequestType = 0;
1483  BYTE bmRequest = 0;
1484  wStream* out = NULL;
1485  URBDRC_PLUGIN* urbdrc = NULL;
1486  const BOOL noAck = (RequestField & 0x80000000U) != 0;
1487  const UINT32 RequestId = RequestField & 0x7FFFFFFF;
1488 
1489  if (!callback || !s || !udevman || !pdev)
1490  return ERROR_INVALID_PARAMETER;
1491 
1492  urbdrc = (URBDRC_PLUGIN*)callback->plugin;
1493 
1494  if (!urbdrc)
1495  return ERROR_INVALID_PARAMETER;
1496 
1497  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1498  return ERROR_INVALID_DATA;
1499 
1500  InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
1501  Stream_Read_UINT16(s, FeatureSelector);
1502  Stream_Read_UINT16(s, Index);
1503  Stream_Read_UINT32(s, OutputBufferSize);
1504  if (OutputBufferSize > UINT32_MAX - 36)
1505  return ERROR_INVALID_DATA;
1506  switch (transferDir)
1507  {
1508  case USBD_TRANSFER_DIRECTION_OUT:
1509  if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
1510  return ERROR_INVALID_DATA;
1511 
1512  break;
1513 
1514  default:
1515  break;
1516  }
1517 
1518  out = Stream_New(NULL, 36ULL + OutputBufferSize);
1519 
1520  if (!out)
1521  return ERROR_OUTOFMEMORY;
1522 
1523  Stream_Seek(out, 36);
1524  bmRequestType = func_recipient;
1525 
1526  switch (transferDir)
1527  {
1528  case USBD_TRANSFER_DIRECTION_OUT:
1529  WLog_Print(urbdrc->log, WLOG_ERROR,
1530  "Function urb_control_feature_request: OUT Unchecked");
1531  Stream_Copy(s, out, OutputBufferSize);
1532  Stream_Rewind(out, OutputBufferSize);
1533  bmRequestType |= 0x00;
1534  break;
1535 
1536  case USBD_TRANSFER_DIRECTION_IN:
1537  bmRequestType |= 0x80;
1538  break;
1539  default:
1540  break;
1541  }
1542 
1543  switch (command)
1544  {
1545  case URB_SET_FEATURE:
1546  bmRequest = 0x03; /* REQUEST_SET_FEATURE */
1547  break;
1548 
1549  case URB_CLEAR_FEATURE:
1550  bmRequest = 0x01; /* REQUEST_CLEAR_FEATURE */
1551  break;
1552 
1553  default:
1554  WLog_Print(urbdrc->log, WLOG_ERROR,
1555  "urb_control_feature_request: Error Command 0x%02" PRIx8 "", command);
1556  Stream_Free(out, TRUE);
1557  return ERROR_INTERNAL_ERROR;
1558  }
1559 
1560  if (!pdev->control_transfer(pdev, RequestId, 0, 0, bmRequestType, bmRequest, FeatureSelector,
1561  Index, &usbd_status, &OutputBufferSize, Stream_Pointer(out), 1000))
1562  {
1563  WLog_Print(urbdrc->log, WLOG_DEBUG, "feature control transfer failed");
1564  Stream_Free(out, TRUE);
1565  return ERROR_INTERNAL_ERROR;
1566  }
1567 
1568  return urb_write_completion(pdev, callback, noAck, out, InterfaceId, MessageId, RequestId,
1569  usbd_status, OutputBufferSize);
1570 }
1571 
1572 static UINT urbdrc_process_transfer_request(IUDEVICE* pdev, GENERIC_CHANNEL_CALLBACK* callback,
1573  wStream* s, UINT32 MessageId, IUDEVMAN* udevman,
1574  int transferDir)
1575 {
1576  UINT32 CbTsUrb = 0;
1577  UINT16 Size = 0;
1578  UINT16 URB_Function = 0;
1579  UINT32 RequestId = 0;
1580  UINT error = ERROR_INTERNAL_ERROR;
1581  URBDRC_PLUGIN* urbdrc = NULL;
1582 
1583  if (!callback || !s || !udevman || !pdev)
1584  return ERROR_INVALID_PARAMETER;
1585 
1586  urbdrc = (URBDRC_PLUGIN*)callback->plugin;
1587 
1588  if (!urbdrc)
1589  return ERROR_INVALID_PARAMETER;
1590 
1591  if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
1592  return ERROR_INVALID_DATA;
1593 
1594  Stream_Read_UINT32(s, CbTsUrb);
1595  Stream_Read_UINT16(s, Size);
1596  Stream_Read_UINT16(s, URB_Function);
1597  Stream_Read_UINT32(s, RequestId);
1598  WLog_Print(urbdrc->log, WLOG_DEBUG, "URB %s[%" PRIu16 "]", urb_function_string(URB_Function),
1599  URB_Function);
1600 
1601  switch (URB_Function)
1602  {
1603  case TS_URB_SELECT_CONFIGURATION:
1604  error = urb_select_configuration(pdev, callback, s, RequestId, MessageId, udevman,
1605  transferDir);
1606  break;
1607 
1608  case TS_URB_SELECT_INTERFACE:
1609  error =
1610  urb_select_interface(pdev, callback, s, RequestId, MessageId, udevman, transferDir);
1611  break;
1612 
1613  case TS_URB_PIPE_REQUEST:
1614  error = urb_pipe_request(pdev, callback, s, RequestId, MessageId, udevman, transferDir,
1615  PIPE_CANCEL);
1616  break;
1617 
1618  case TS_URB_TAKE_FRAME_LENGTH_CONTROL:
1622  break;
1623 
1624  case TS_URB_RELEASE_FRAME_LENGTH_CONTROL:
1628  break;
1629 
1630  case TS_URB_GET_FRAME_LENGTH:
1634  break;
1635 
1636  case TS_URB_SET_FRAME_LENGTH:
1640  break;
1641 
1642  case TS_URB_GET_CURRENT_FRAME_NUMBER:
1643  error = urb_get_current_frame_number(pdev, callback, s, RequestId, MessageId, udevman,
1644  transferDir);
1645  break;
1646 
1647  case TS_URB_CONTROL_TRANSFER:
1648  error = urb_control_transfer(pdev, callback, s, RequestId, MessageId, udevman,
1649  transferDir, URB_CONTROL_TRANSFER_NONEXTERNAL);
1650  break;
1651 
1652  case TS_URB_BULK_OR_INTERRUPT_TRANSFER:
1653  error = urb_bulk_or_interrupt_transfer(pdev, callback, s, RequestId, MessageId, udevman,
1654  transferDir);
1655  break;
1656 
1657  case TS_URB_ISOCH_TRANSFER:
1658  error =
1659  urb_isoch_transfer(pdev, callback, s, RequestId, MessageId, udevman, transferDir);
1660  break;
1661 
1662  case TS_URB_GET_DESCRIPTOR_FROM_DEVICE:
1663  error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
1664  0x00, transferDir);
1665  break;
1666 
1667  case TS_URB_SET_DESCRIPTOR_TO_DEVICE:
1668  error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
1669  0x00, transferDir);
1670  break;
1671 
1672  case TS_URB_SET_FEATURE_TO_DEVICE:
1673  error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1674  0x00, URB_SET_FEATURE, transferDir);
1675  break;
1676 
1677  case TS_URB_SET_FEATURE_TO_INTERFACE:
1678  error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1679  0x01, URB_SET_FEATURE, transferDir);
1680  break;
1681 
1682  case TS_URB_SET_FEATURE_TO_ENDPOINT:
1683  error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1684  0x02, URB_SET_FEATURE, transferDir);
1685  break;
1686 
1687  case TS_URB_CLEAR_FEATURE_TO_DEVICE:
1688  error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1689  0x00, URB_CLEAR_FEATURE, transferDir);
1690  break;
1691 
1692  case TS_URB_CLEAR_FEATURE_TO_INTERFACE:
1693  error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1694  0x01, URB_CLEAR_FEATURE, transferDir);
1695  break;
1696 
1697  case TS_URB_CLEAR_FEATURE_TO_ENDPOINT:
1698  error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1699  0x02, URB_CLEAR_FEATURE, transferDir);
1700  break;
1701 
1702  case TS_URB_GET_STATUS_FROM_DEVICE:
1703  error = urb_control_get_status_request(pdev, callback, s, RequestId, MessageId, udevman,
1704  0x00, transferDir);
1705  break;
1706 
1707  case TS_URB_GET_STATUS_FROM_INTERFACE:
1708  error = urb_control_get_status_request(pdev, callback, s, RequestId, MessageId, udevman,
1709  0x01, transferDir);
1710  break;
1711 
1712  case TS_URB_GET_STATUS_FROM_ENDPOINT:
1713  error = urb_control_get_status_request(pdev, callback, s, RequestId, MessageId, udevman,
1714  0x02, transferDir);
1715  break;
1716 
1717  case TS_URB_RESERVED_0X0016:
1718  break;
1719 
1720  case TS_URB_VENDOR_DEVICE:
1721  error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1722  udevman, (0x02 << 5), /* vendor type */
1723  0x00, transferDir);
1724  break;
1725 
1726  case TS_URB_VENDOR_INTERFACE:
1727  error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1728  udevman, (0x02 << 5), /* vendor type */
1729  0x01, transferDir);
1730  break;
1731 
1732  case TS_URB_VENDOR_ENDPOINT:
1733  error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1734  udevman, (0x02 << 5), /* vendor type */
1735  0x02, transferDir);
1736  break;
1737 
1738  case TS_URB_CLASS_DEVICE:
1739  error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1740  udevman, (0x01 << 5), /* class type */
1741  0x00, transferDir);
1742  break;
1743 
1744  case TS_URB_CLASS_INTERFACE:
1745  error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1746  udevman, (0x01 << 5), /* class type */
1747  0x01, transferDir);
1748  break;
1749 
1750  case TS_URB_CLASS_ENDPOINT:
1751  error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1752  udevman, (0x01 << 5), /* class type */
1753  0x02, transferDir);
1754  break;
1755 
1756  case TS_URB_RESERVE_0X001D:
1757  break;
1758 
1759  case TS_URB_SYNC_RESET_PIPE_AND_CLEAR_STALL:
1760  error = urb_pipe_request(pdev, callback, s, RequestId, MessageId, udevman, transferDir,
1761  PIPE_RESET);
1762  break;
1763 
1764  case TS_URB_CLASS_OTHER:
1765  error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1766  udevman, (0x01 << 5), /* class type */
1767  0x03, transferDir);
1768  break;
1769 
1770  case TS_URB_VENDOR_OTHER:
1771  error = urb_control_vendor_or_class_request(pdev, callback, s, RequestId, MessageId,
1772  udevman, (0x02 << 5), /* vendor type */
1773  0x03, transferDir);
1774  break;
1775 
1776  case TS_URB_GET_STATUS_FROM_OTHER:
1777  error = urb_control_get_status_request(pdev, callback, s, RequestId, MessageId, udevman,
1778  0x03, transferDir);
1779  break;
1780 
1781  case TS_URB_CLEAR_FEATURE_TO_OTHER:
1782  error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1783  0x03, URB_CLEAR_FEATURE, transferDir);
1784  break;
1785 
1786  case TS_URB_SET_FEATURE_TO_OTHER:
1787  error = urb_control_feature_request(pdev, callback, s, RequestId, MessageId, udevman,
1788  0x03, URB_SET_FEATURE, transferDir);
1789  break;
1790 
1791  case TS_URB_GET_DESCRIPTOR_FROM_ENDPOINT:
1792  error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
1793  0x02, transferDir);
1794  break;
1795 
1796  case TS_URB_SET_DESCRIPTOR_TO_ENDPOINT:
1797  error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
1798  0x02, transferDir);
1799  break;
1800 
1801  case TS_URB_CONTROL_GET_CONFIGURATION_REQUEST:
1802  error = urb_control_get_configuration_request(pdev, callback, s, RequestId, MessageId,
1803  udevman, transferDir);
1804  break;
1805 
1806  case TS_URB_CONTROL_GET_INTERFACE_REQUEST:
1807  error = urb_control_get_interface_request(pdev, callback, s, RequestId, MessageId,
1808  udevman, transferDir);
1809  break;
1810 
1811  case TS_URB_GET_DESCRIPTOR_FROM_INTERFACE:
1812  error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
1813  0x01, transferDir);
1814  break;
1815 
1816  case TS_URB_SET_DESCRIPTOR_TO_INTERFACE:
1817  error = urb_control_descriptor_request(pdev, callback, s, RequestId, MessageId, udevman,
1818  0x01, transferDir);
1819  break;
1820 
1821  case TS_URB_GET_OS_FEATURE_DESCRIPTOR_REQUEST:
1822  error = urb_os_feature_descriptor_request(pdev, callback, s, RequestId, MessageId,
1823  udevman, transferDir);
1824  break;
1825 
1826  case TS_URB_RESERVE_0X002B:
1827  case TS_URB_RESERVE_0X002C:
1828  case TS_URB_RESERVE_0X002D:
1829  case TS_URB_RESERVE_0X002E:
1830  case TS_URB_RESERVE_0X002F:
1831  break;
1832 
1834  case TS_URB_SYNC_RESET_PIPE:
1835  error = urb_pipe_request(pdev, callback, s, RequestId, MessageId, udevman, transferDir,
1836  PIPE_RESET);
1837  break;
1838 
1839  case TS_URB_SYNC_CLEAR_STALL:
1840  urb_pipe_request(pdev, callback, s, RequestId, MessageId, udevman, transferDir,
1841  PIPE_RESET);
1842  break;
1843 
1844  case TS_URB_CONTROL_TRANSFER_EX:
1845  error = urb_control_transfer(pdev, callback, s, RequestId, MessageId, udevman,
1846  transferDir, URB_CONTROL_TRANSFER_EXTERNAL);
1847  break;
1848 
1849  default:
1850  WLog_Print(urbdrc->log, WLOG_DEBUG, "URB_Func: %" PRIx16 " is not found!",
1851  URB_Function);
1852  break;
1853  }
1854 
1855  if (error)
1856  {
1857  WLog_Print(urbdrc->log, WLOG_WARN,
1858  "USB transfer request URB Function '%s' [0x%08x] failed with %08" PRIx32,
1859  urb_function_string(URB_Function), URB_Function, error);
1860  }
1861 
1862  return error;
1863 }
1864 
1865 UINT urbdrc_process_udev_data_transfer(GENERIC_CHANNEL_CALLBACK* callback, URBDRC_PLUGIN* urbdrc,
1866  IUDEVMAN* udevman, wStream* data)
1867 {
1868  UINT32 InterfaceId = 0;
1869  UINT32 MessageId = 0;
1870  UINT32 FunctionId = 0;
1871  IUDEVICE* pdev = NULL;
1872  UINT error = ERROR_INTERNAL_ERROR;
1873 
1874  if (!urbdrc || !data || !callback || !udevman)
1875  goto fail;
1876 
1877  if (!Stream_CheckAndLogRequiredLength(TAG, data, 8))
1878  goto fail;
1879 
1880  Stream_Rewind_UINT32(data);
1881 
1882  Stream_Read_UINT32(data, InterfaceId);
1883  Stream_Read_UINT32(data, MessageId);
1884  Stream_Read_UINT32(data, FunctionId);
1885 
1886  pdev = udevman->get_udevice_by_UsbDevice(udevman, InterfaceId);
1887 
1888  /* Device does not exist, ignore this request. */
1889  if (pdev == NULL)
1890  {
1891  error = ERROR_SUCCESS;
1892  goto fail;
1893  }
1894 
1895  /* Device has been removed, ignore this request. */
1896  if (pdev->isChannelClosed(pdev))
1897  {
1898  error = ERROR_SUCCESS;
1899  goto fail;
1900  }
1901 
1902  /* USB kernel driver detach!! */
1903  pdev->detach_kernel_driver(pdev);
1904 
1905  switch (FunctionId)
1906  {
1907  case CANCEL_REQUEST:
1908  error = urbdrc_process_cancel_request(pdev, data, udevman);
1909  break;
1910 
1911  case REGISTER_REQUEST_CALLBACK:
1912  error = urbdrc_process_register_request_callback(pdev, callback, data, udevman);
1913  break;
1914 
1915  case IO_CONTROL:
1916  error = urbdrc_process_io_control(pdev, callback, data, MessageId, udevman);
1917  break;
1918 
1919  case INTERNAL_IO_CONTROL:
1920  error = urbdrc_process_internal_io_control(pdev, callback, data, MessageId, udevman);
1921  break;
1922 
1923  case QUERY_DEVICE_TEXT:
1924  error = urbdrc_process_query_device_text(pdev, callback, data, MessageId, udevman);
1925  break;
1926 
1927  case TRANSFER_IN_REQUEST:
1928  error = urbdrc_process_transfer_request(pdev, callback, data, MessageId, udevman,
1929  USBD_TRANSFER_DIRECTION_IN);
1930  break;
1931 
1932  case TRANSFER_OUT_REQUEST:
1933  error = urbdrc_process_transfer_request(pdev, callback, data, MessageId, udevman,
1934  USBD_TRANSFER_DIRECTION_OUT);
1935  break;
1936 
1937  case RETRACT_DEVICE:
1938  error = urbdrc_process_retract_device_request(pdev, data, udevman);
1939  break;
1940 
1941  default:
1942  WLog_Print(urbdrc->log, WLOG_WARN,
1943  "urbdrc_process_udev_data_transfer:"
1944  " unknown FunctionId 0x%" PRIX32 "",
1945  FunctionId);
1946  break;
1947  }
1948 
1949 fail:
1950  if (error)
1951  {
1952  WLog_WARN(TAG, "USB request failed with %08" PRIx32, error);
1953  }
1954 
1955  return error;
1956 }