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