ReactOS  0.4.15-dev-1632-g4e289ce
fxusbdevicekm.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxUsbDeviceKm.cpp
8 
9 Abstract:
10 
11 Author:
12 
13 Environment:
14 
15  kernel mode only
16 
17 Revision History:
18 
19 --*/
20 
21 extern "C" {
22 #include <initguid.h>
23 }
24 
25 #include "fxusbpch.hpp"
26 
27 
28 extern "C" {
29 #include "FxUsbDeviceKm.tmh"
30 }
31 
32 
33 
34 
35 
36 
37 
38 #define UCHAR_MAX (0xff)
39 
40 
44  __in ULONG USBDClientContractVersionForWdfClient
45  )
46 {
47  URB urb;
48  FxSyncRequest request(GetDriverGlobals(), NULL);
51  ULONG size;
52 
53  RtlZeroMemory(&urb, sizeof(urb));
54 
55  if (USBDClientContractVersionForWdfClient != USBD_CLIENT_CONTRACT_VERSION_INVALID) {
56 
57  //
58  // Register with USBDEX.lib
59  //
62  USBDClientContractVersionForWdfClient,
64  &m_USBDHandle);
65 
66  if (!NT_SUCCESS(status)) {
69  "USBD_CreateHandle failed, %!STATUS!", status);
70  goto Done;
71  }
72 
74  }
75 
76  status = request.m_TrueRequest->ValidateTarget(this);
77  if (!NT_SUCCESS(status)) {
78  goto Done;
79  }
80 
82  sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
84  0,
85  0,
87  NULL,
88  sizeof(m_DeviceDescriptor),
89  NULL);
90 
91  FxFormatUsbRequest(request.m_TrueRequest, &urb, FxUrbTypeLegacy, NULL);
92 
95 
96  status = SubmitSync(request.m_TrueRequest, &options);
97  if (!NT_SUCCESS(status)) {
100  "Could not retrieve device descriptor, %!STATUS!", status);
101  goto Done;
102  }
103 
104  //
105  // After successfully completing any default control URB, USBD/usbport fills
106  // in the PipeHandle field of the URB (it is the same offset in every URB,
107  // which this CASSERT verifies. Since USBD_DEFAULT_PIPE_TRANSFER is not
108  // supported by USBD (it is by USBPORT), this is the prescribed way of getting
109  // the default control pipe so that you can set the PipeHandle field in
110  // _URB_CONTROL_TRANSFER.
111  //
114 
116 
118 
119  RtlZeroMemory(&config, sizeof(config));
120  size = sizeof(config);
121 
125  0,
126  0,
127  &config,
128  NULL,
129  size,
130  NULL);
131 
132  request.m_TrueRequest->GetSubmitFxIrp()->Reuse(STATUS_SUCCESS);
133  request.m_TrueRequest->ClearFieldsForReuse();
134  FxFormatUsbRequest(request.m_TrueRequest, &urb, FxUrbTypeLegacy, NULL);
135 
136  status = SubmitSync(request.m_TrueRequest, &options);
137  if (!NT_SUCCESS(status)) {
140  "Could not retrieve config descriptor size, %!STATUS!", status);
141  goto Done;
142  }
143  else if (urb.UrbControlDescriptorRequest.TransferBufferLength == 0) {
144  //
145  // Not enough info returned
146  //
148 
151  "Could not retrieve config descriptor size, zero bytes transferred, "
152  " %!STATUS!", status);
153 
154  goto Done;
155  }
156  else if (config.wTotalLength < size) {
157  //
158  // Not enough info returned
159  //
161 
164  "Could not retrieve config descriptor size, config.wTotalLength %d < "
165  "sizeof(config descriptor) (%d), %!STATUS!",
166  config.wTotalLength, size, status);
167 
168  goto Done;
169  }
170 
171  //
172  // Allocate an additional memory at the end of the buffer so if we
173  // accidentily access fields beyond the end of the buffer we don't crash
174 
175  //
176 
177 
178 
179 
180 
181  size = config.wTotalLength;
182  ULONG paddedSize = size + sizeof(USB_DEVICE_DESCRIPTOR);
183 
185  FxPoolAllocate(GetDriverGlobals(),
186  NonPagedPool,
187  paddedSize);
188 
189  if (m_ConfigDescriptor == NULL) {
191 
194  "Could not allocate %d bytes for config descriptor, %!STATUS!",
195  paddedSize, status);
196 
197  goto Done;
198  }
199 
200  RtlZeroMemory(m_ConfigDescriptor, paddedSize);
201 
205  0,
206  0,
208  NULL,
209  size,
210  NULL);
211 
212  request.m_TrueRequest->GetSubmitFxIrp()->Reuse(STATUS_SUCCESS);
213  request.m_TrueRequest->ClearFieldsForReuse();
214  FxFormatUsbRequest(request.m_TrueRequest, &urb, FxUrbTypeLegacy, NULL);
215 
216  status = SubmitSync(request.m_TrueRequest, &options);
217  if (!NT_SUCCESS(status)) {
220  "Could not retrieve config descriptor, %!STATUS!", status);
221  goto Done;
222  } else if(m_ConfigDescriptor->wTotalLength != size) {
223  //
224  // Invalid wTotalLength
225  //
229  "Defective USB device reported two different config descriptor "
230  "wTotalLength values: %d and %d, %!STATUS!",
232  goto Done;
233  }
234 
235  //
236  // Check to see if we are wait wake capable
237  //
240  }
241 
242  //
243  // Check to see if we are self or bus powered
244  //
245  USHORT deviceStatus;
246 
249  0,
250  &deviceStatus,
251  NULL,
252  NULL);
253 
254  request.m_TrueRequest->GetSubmitFxIrp()->Reuse(STATUS_SUCCESS);
255  request.m_TrueRequest->ClearFieldsForReuse();
256  FxFormatUsbRequest(request.m_TrueRequest, &urb, FxUrbTypeLegacy, NULL);
257 
258  status = SubmitSync(request.m_TrueRequest, &options);
259  if (NT_SUCCESS(status) && (deviceStatus & USB_GETSTATUS_SELF_POWERED)) {
261  }
262 
263  //
264  // Revert back to success b/c we don't care if the usb device get status
265  // fails
266  //
268 
270 
271  RtlZeroMemory(&busIf, sizeof(busIf));
272 
273  //
274  // All PNP irps must have this initial status
275  //
276  request.m_TrueRequest->GetSubmitFxIrp()->Reuse(STATUS_NOT_SUPPORTED);
277  request.m_TrueRequest->ClearFieldsForReuse();
278 
280  request.m_TrueRequest->GetSubmitFxIrp()->GetIrp(),
281  &USB_BUS_INTERFACE_USBDI_GUID,
282  (PINTERFACE) &busIf,
283  sizeof(busIf),
285 
286  request.m_TrueRequest->VerifierSetFormatted();
287 
288  status = SubmitSync(request.m_TrueRequest);
289 
290  if (!NT_SUCCESS(status)) {
291  //
292  // Retry with the older interface
293  //
294  RtlZeroMemory(&busIf, sizeof(busIf));
295 
296  //
297  // All PNP irps must have this initial status
298  //
299 
300  request.m_TrueRequest->GetSubmitFxIrp()->Reuse(STATUS_NOT_SUPPORTED);
301  request.m_TrueRequest->ClearFieldsForReuse();
302 
304  request.m_TrueRequest->GetSubmitFxIrp()->GetIrp(),
305  &USB_BUS_INTERFACE_USBDI_GUID,
306  (PINTERFACE) &busIf,
309 
310  request.m_TrueRequest->VerifierSetFormatted();
311 
312  status = SubmitSync(request.m_TrueRequest);
313  }
314 
315  if (NT_SUCCESS(status)) {
316  //
317  // Need to check for NULL b/c we may have only retrieved the V0 interface
318  //
319  if (busIf.IsDeviceHighSpeed != NULL &&
320  busIf.IsDeviceHighSpeed(busIf.BusContext)) {
322  }
323 
324  //
325  // Stash these off for later
326  //
330 
331  ASSERT(busIf.GetUSBDIVersion != NULL);
332  busIf.GetUSBDIVersion(busIf.BusContext,
335  }
336  else if (status == STATUS_NOT_SUPPORTED) {
337  //
338  // We will only use m_ControlPipe on stacks which do not support
339  // USBD_DEFAULT_PIPE_TRANSFER. If all the QIs failed, then we know
340  // definitively that we are running on USBD and we need m_ControlPipe
341  // to be != NULL for later control transfers
342  //
344 
345  m_OnUSBD = TRUE;
346 
347  //
348  // The QI failed with not supported, do not return error
349  //
351  }
352  else {
355  "Query Interface for bus returned error, %!STATUS!", status);
356  }
357 
358 Done:
359 
360  return status;
361 }
362 
364 NTSTATUS
370  __in_opt WDFREQUEST Request,
372  )
373 {
374  PUSB_STRING_DESCRIPTOR pDescriptor;
375  PVOID buffer;
378  USB_COMMON_DESCRIPTOR common;
379  ULONG length;
381 
382  FxSyncRequest request(GetDriverGlobals(), NULL, Request);
383 
384  //
385  // FxSyncRequest always succeesds for KM.
386  //
387  status = request.Initialize();
388  if (!NT_SUCCESS(status)) {
390  "Failed to initialize FxSyncRequest");
391  return status;
392  }
393 
394  buffer = NULL;
395 
396  status = request.m_TrueRequest->ValidateTarget(this);
397  if (!NT_SUCCESS(status)) {
398  goto Done;
399  }
400 
401  RtlZeroMemory(&urb, sizeof(urb));
402 
403  if (String != NULL) {
404  length = sizeof(USB_STRING_DESCRIPTOR) + (*NumCharacters - 1) * sizeof(WCHAR);
405 
406  buffer = FxPoolAllocate(GetDriverGlobals(),
407  NonPagedPool,
408  length);
409 
410  if (buffer == NULL) {
412  goto Done;
413  }
414 
416  pDescriptor = (PUSB_STRING_DESCRIPTOR) buffer;
417  }
418  else {
419  RtlZeroMemory(&common, sizeof(common));
420 
421  length = sizeof(USB_COMMON_DESCRIPTOR);
422  pDescriptor = (PUSB_STRING_DESCRIPTOR) &common;
423  }
424 
428  StringIndex,
429  LangID,
430  pDescriptor,
431  NULL,
432  length,
433  NULL);
434 
435  if (Options != NULL) {
436  pOptions = Options;
437  }
438  else {
442 
443  pOptions = &options;
444  }
445 #pragma prefast(suppress: __WARNING_BUFFER_OVERFLOW, "this annotation change in usb.h is communicated to usb team")
446  FxFormatUsbRequest(request.m_TrueRequest, (PURB) &urb, FxUrbTypeLegacy, NULL);
447  status = SubmitSync(request.m_TrueRequest, pOptions);
448 
449  if (NT_SUCCESS(status)) {
451 
452  //
453  // Make sure we got an even number of bytes and that we got a header
454  //
455  if ((pDescriptor->bLength & 0x1) ||
456  pDescriptor->bLength < sizeof(USB_COMMON_DESCRIPTOR)) {
458  }
459  else {
460  //
461  // bLength is the length of the entire descriptor. Subtract off
462  // the descriptor header and then divide by the size of a WCHAR.
463  //
464  numChars =
465  (pDescriptor->bLength - sizeof(USB_COMMON_DESCRIPTOR)) / sizeof(WCHAR);
466 
467  if (String != NULL) {
468  if (*NumCharacters >= numChars) {
469  length = numChars * sizeof(WCHAR);
470  }
471  else {
472  length = *NumCharacters * sizeof(WCHAR);
474  }
475 
477  RtlCopyMemory(String, pDescriptor->bString, length);
478  }
479  else {
481  }
482  }
483  }
484 
485  if (buffer != NULL) {
487  }
488 
489 Done:
490 
491  return status;
492 }
493 
495 NTSTATUS
498  __in FxRequestBuffer *RequestBuffer,
501  )
502 /*++
503 
504 Routine Description:
505  Formats a request to retrieve a string from a string descriptor
506 
507 Arguments:
508  Request - request to format
509 
510  RequestBuffer - Buffer to be filled in when the request has completed
511 
512  StringIndex - index of the string
513 
514  LandID - language ID of the string to be retrieved
515 
516 Return Value:
517  NTSTATUS
518 
519  --*/
520 {
521  FxUsbDeviceStringContext* pContext;
523  FX_URB_TYPE urbType;
524 
525  status = Request->ValidateTarget(this);
526  if (!NT_SUCCESS(status)) {
528  "WDFUSBDEVICE %p, Request %p, setting target failed, "
529  "%!STATUS!", GetHandle(), Request, status);
530 
531  return status;
532  }
533 
534  if (Request->HasContextType(FX_RCT_USB_STRING_REQUEST)) {
535  pContext = (FxUsbDeviceStringContext*) Request->GetContext();
536  }
537  else {
538 
539  urbType = GetFxUrbTypeForRequest(Request);
540  pContext = new(GetDriverGlobals()) FxUsbDeviceStringContext(urbType);
541  if (pContext == NULL) {
543  }
544 
545  if (urbType == FxUrbTypeUsbdAllocated) {
546  status = pContext->AllocateUrb(m_USBDHandle);
547  if (!NT_SUCCESS(status)) {
549  "FxUsbDeviceStringContext::AllocateUrb failed, %!STATUS!", status);
550  delete pContext;
551  return status;
552  }
553 
554  //
555  // Since the AllocateUrb routine calls USBD_xxxUrbAllocate APIs to allocate an Urb, it is
556  // important to release those resorces before the devnode is removed. Those
557  // resoruces are removed at the time Request is disposed.
558  //
559  Request->EnableContextDisposeNotification();
560  }
561 
562  Request->SetContext(pContext);
563  }
564 
566  RequestBuffer->GetBufferLength());
567  if (!NT_SUCCESS(status)) {
568  return status;
569  }
570 
571  pContext->StoreAndReferenceMemory(RequestBuffer);
572  pContext->SetUrbInfo(StringIndex, LangID);
573 
574  if (pContext->m_Urb == &pContext->m_UrbLegacy) {
575  urbType = FxUrbTypeLegacy;
576  }
577  else {
578  urbType = FxUrbTypeUsbdAllocated;
579  }
580 
581  FxFormatUsbRequest(Request, (PURB)pContext->m_Urb, urbType, m_USBDHandle);
582 
583  return STATUS_SUCCESS;
584 }
585 
587 NTSTATUS
591  __in FxRequestBuffer *RequestBuffer
592  )
593 {
594  FxUsbDeviceControlContext* pContext;
596  size_t bufferSize;
597  FX_URB_TYPE urbType;
598 
599  bufferSize = RequestBuffer->GetBufferLength();
600 
601  //
602  // We can only transfer 2 bytes worth of data, so if the buffer is larger,
603  // fail here.
604  //
605  if (bufferSize > 0xFFFF) {
608  "Control transfer buffer is limited to 0xFFFF bytes in size, "
609  "%I64d requested ", bufferSize);
610 
612  }
613 
614  status = Request->ValidateTarget(this);
615  if (!NT_SUCCESS(status)) {
617  "WDFUSBDEVICE %p, Request %p, setting target failed, "
618  "%!STATUS!", GetHandle(), Request, status);
619 
620  return status;
621  }
622 
623  if (Request->HasContextType(FX_RCT_USB_CONTROL_REQUEST)) {
624  pContext = (FxUsbDeviceControlContext*) Request->GetContext();
625  }
626  else {
627 
628  urbType = GetFxUrbTypeForRequest(Request);
629  pContext = new(GetDriverGlobals()) FxUsbDeviceControlContext(urbType);
630  if (pContext == NULL) {
632  }
633 
634  if (urbType == FxUrbTypeUsbdAllocated) {
635  status = pContext->AllocateUrb(m_USBDHandle);
636  if (!NT_SUCCESS(status)) {
638  "FxUsbDeviceControlContext::AllocateUrb Failed, %!STATUS!", status);
639 
640  delete pContext;
641  return status;
642  }
643  //
644  // Since the AllocateUrb routine calls USBD_xxxUrbAllocate APIs to allocate an Urb, it is
645  // important to release those resorces before the devnode is removed. Those
646  // resoruces are removed at the time Request is disposed.
647  //
648  Request->EnableContextDisposeNotification();
649  }
650 
651  Request->SetContext(pContext);
652  }
653 
654  if (RequestBuffer->HasMdl()) {
655  PMDL pMdl;
656 
657  pMdl = NULL;
658  ASSERT(pContext->m_PartialMdl == NULL);
659 
660  status = RequestBuffer->GetOrAllocateMdl(GetDriverGlobals(),
661  &pMdl,
662  &pContext->m_PartialMdl,
663  &pContext->m_UnlockPages,
665 
666  if (!NT_SUCCESS(status)) {
667  return status;
668  }
669 
670  ASSERT(pMdl != NULL);
671  }
672 
673  pContext->StoreAndReferenceMemory(this, RequestBuffer, SetupPacket);
674 
675  if (pContext->m_Urb == &pContext->m_UrbLegacy) {
676  urbType = FxUrbTypeLegacy;
677  }
678  else {
679  urbType = FxUrbTypeUsbdAllocated;
680  }
681 
682  FxFormatUsbRequest(Request, (PURB)pContext->m_Urb, urbType, m_USBDHandle);
683 
684  return STATUS_SUCCESS;
685 }
686 
687 VOID
692  )
693 {
695 
696  RtlZeroMemory(m_Urb, sizeof(*m_Urb));
697 
699  m_Urb->Hdr.Length = sizeof(*m_Urb);
700 
702 
703  //
704  // Set the values using what is stored in the buffer
705  //
706  Buffer->AssignValues(&m_Urb->TransferBuffer,
709 
711  &SetupPacket->Generic.Bytes[0],
712  sizeof(m_Urb->SetupPacket));
713 
714  //
715  // also indicate the length of the buffer in the header
716  //
717  ((PWDF_USB_CONTROL_SETUP_PACKET) &m_Urb->SetupPacket[0])->Packet.wLength =
719 
720  //
721  // Control transfers are always short OK. USBD_TRANSFER_DIRECTION_IN may
722  // be OR'ed in later.
723  //
725 
726  //
727  // Get the direction out of the setup packet
728  //
729  if (SetupPacket->Packet.bm.Request.Dir == BMREQUEST_DEVICE_TO_HOST) {
731  }
732 
733  if (Device->OnUSBD()) {
734  m_Urb->PipeHandle = Device->GetControlPipeHandle();
735  }
736  else {
737  //
738  // USBPORT supports this flag
739  //
741  }
742 
743  //
744  // If we have built a partial MDL, use that instead. TransferBufferLength
745  // is still valid because the Offsets or length in Buffer will have been
746  // used to create this PartialMdl by the caller.
747  //
748  if (m_PartialMdl != NULL) {
750  }
751 }
752 
754 NTSTATUS
756  __in
758  __in
763  PVOID CapabilityBuffer,
764  __out_opt
767  )
768 {
770 
771  if (ResultLength != NULL) {
772  *ResultLength = 0;
773  }
774 
775  if (GetUSBDHandle() == NULL) {
777 
780  "WDFUSBDEVICE must have been created using WdfUsbTargetDeviceCreateWithParameters, %!STATUS!",
781  status);
782 
783  return status;
784  }
785 
789  (PUCHAR) CapabilityBuffer,
790  ResultLength);
791 
792  if (!NT_SUCCESS(status)) {
795  "Could not retrieve capability %!GUID!, %!STATUS!",
797  goto exit;
798  }
799 
800 exit:
801  return status;
802 }
803 
805 NTSTATUS
809  )
810 /*++
811 
812 Routine Description:
813  This will configure the single inteface case and pick up the first available
814  setting. If there are multiple settings on a single interface device
815  and the driver wants to pick one then the driver should use the multinterface
816  option to initialize.
817 
818  This takes care of the simplest case only. Configuring a multi interface
819  device as a single interface device would be treated as an error. There is
820  duplication of code with the multi case but it is better to keep these two
821  separate especially if more gets added.
822 
823 Arguments:
824 
825 
826 Return Value:
827  NTSTATUS
828 
829  --*/
830 {
831  //
832  // The array needs an extra element which is zero'd out to mark the end
833  //
834  USBD_INTERFACE_LIST_ENTRY listEntry[2];
835  PURB urb;
837 
838  RtlZeroMemory(&Params->Types.SingleInterface,
839  sizeof(Params->Types.SingleInterface));
840 
841  if (m_NumInterfaces > 1) {
843 
846  "WDFUSBDEVICE %p cannot be auto configured for a single interface "
847  "since there are %d interfaces on the device, %!STATUS!",
849 
850  return status;
851  }
852 
853  RtlZeroMemory(&listEntry[0], sizeof(listEntry));
854 
855  //
856  // Use AlternateSetting 0 by default
857  //
859 
860  if (listEntry[0].InterfaceDescriptor == NULL) {
863  "WDFUSBDEVICE %p could not retrieve AlternateSetting 0 for "
864  "bInterfaceNumber %d", GetHandle(),
865  m_Interfaces[0]->m_InterfaceNumber);
866 
868  }
869 
872  &listEntry[0],
874 
875  if (urb == NULL) {
877  }
878  else {
880 
881  if (NT_SUCCESS(status)) {
882  Params->Types.SingleInterface.NumberConfiguredPipes =
884 
885  Params->Types.SingleInterface.ConfiguredUsbInterface =
886  m_Interfaces[0]->GetHandle();
887  }
888 
889  FxPoolFree(urb);
890  urb = NULL;
891  }
892 
893  return status;
894 }
895 
897 NTSTATUS
901  )
902 /*++
903 
904 Routine Description:
905  Selects the configuration as described by the parameter Params. If there is a
906  previous active configuration, the WDFUSBPIPEs for it are stopped and
907  destroyed before the new configuration is selected
908 
909 Arguments:
910  PipesAttributes - object attributes to apply to each created WDFUSBPIPE
911 
912  Params -
913 
914 Return Value:
915  NTSTATUS
916 
917  --*/
918 {
920  PURB urb;
922  ULONG size;
923  UCHAR i;
925 
927 
928  Params->Types.MultiInterface.NumberOfConfiguredInterfaces = 0;
929 
930  //
931  // The array needs an extra element which is zero'd out to mark the end
932  //
934  pList = (PUSBD_INTERFACE_LIST_ENTRY) FxPoolAllocate(
936  NonPagedPool,
937  size
938  );
939 
940  if (pList == NULL) {
942  }
943 
945 
947  for (i = 0; i < m_NumInterfaces; i++) {
948  pList[i].InterfaceDescriptor =
950 
951  if (pList[i].InterfaceDescriptor == NULL) {
954  "WDFUSBDEVICE %p could not retrieve AlternateSetting 0 for "
955  "bInterfaceNumber %d", GetHandle(),
956  m_Interfaces[i]->m_InterfaceNumber);
957 
959  goto Done;
960  }
961  }
962  }
963  else {
964  //
965  // Type is WdfUsbTargetDeviceSelectConfigTypeInterfacesPairs
966  //
967  UCHAR interfacePairsNum = 0;
968  UCHAR bitArray[UCHAR_MAX/sizeof(UCHAR)];
969 
970  //
971  // initialize the bit array
972  //
973  RtlZeroMemory(bitArray, sizeof(bitArray));
974  //
975  // Build a list of descriptors from the Setting pairs
976  // passed in by the user. There could be interfaces not
977  // covered in the setting/interface pairs array passed.
978  // If that is the case return STATUS_INVALID_PARAMETER
979  //
980  for (i = 0; i < Params->Types.MultiInterface.NumberInterfaces ; i++) {
982  UCHAR interfaceNumber;
983  UCHAR altSettingIndex;
984 
985  settingPair = &Params->Types.MultiInterface.Pairs[i];
986 
988  settingPair->UsbInterface,
989  &interfaceNumber
990  );
991 
992  //
993  //convert the interface handle to interface number
994  //
995  if (NT_SUCCESS(status)) {
996  altSettingIndex = settingPair->SettingIndex;
997 
998  //
999  // do the following only if the bit is not already set
1000  //
1001  if (FxBitArraySet(&bitArray[0], interfaceNumber) == FALSE) {
1002  pList[interfacePairsNum].InterfaceDescriptor =
1005  interfaceNumber,
1006  altSettingIndex
1007  );
1008 
1009  if (pList[interfacePairsNum].InterfaceDescriptor == NULL) {
1014  "WDFUSBDEVICE %p could not retrieve "
1015  "AlternateSetting %d for "
1016  "bInterfaceNumber %d, returning %!STATUS!",
1017  GetHandle(),
1018  altSettingIndex, interfaceNumber, status);
1019  goto Done;
1020  }
1021 
1022  interfacePairsNum++;
1023  }
1024  }
1025  else {
1026  goto Done;
1027  }
1028  }
1029 
1030  //
1031  // Check if there are any interfaces not specified by the array. If
1032  // there are, then select setting 0 for them.
1033  //
1034  if (m_NumInterfaces > interfacePairsNum) {
1038  "WDFUSBDEVICE %p interface pairs set (%d) is not equal to actual "
1039  "# of interfaces (%d) reported by the device, %!STATUS!",
1040  GetObjectHandle(), interfacePairsNum, m_NumInterfaces, status);
1041  goto Done;
1042  }
1043  } //WdfUsbTargetDeviceSelectConfigTypeInterfacesPairs
1044 
1046  GetDriverGlobals(),
1048  pList,
1050  );
1051 
1052  if (urb == NULL) {
1054  }
1055  else {
1056  status = SelectConfig(
1058  urb,
1060  &Params->Types.MultiInterface.NumberOfConfiguredInterfaces);
1061 
1062  FxPoolFree(urb);
1063  urb = NULL;
1064  }
1065 
1066 Done:
1067  FxPoolFree(pList);
1068  pList = NULL;
1069 
1070  return status;
1071 }
1072 
1074 NTSTATUS
1076  VOID
1077  )
1078 {
1080  FxSyncRequest request(GetDriverGlobals(), &context);
1081  FxRequestBuffer emptyBuffer;
1082  NTSTATUS status;
1083 
1084  //
1085  // FxSyncRequest always succeesds for KM.
1086  //
1087  status = request.Initialize();
1088  if (!NT_SUCCESS(status)) {
1090  "Failed to initialize FxSyncRequest");
1091  return status;
1092  }
1093 
1094  status = FormatIoctlRequest(request.m_TrueRequest,
1096  TRUE,
1097  &emptyBuffer,
1098  &emptyBuffer);
1099  if (NT_SUCCESS(status)) {
1100  CancelSentIo();
1102  }
1103 
1104  return status;
1105 }
1106 
1107 
_URB_CONTROL_DESCRIPTOR_REQUEST m_UrbLegacy
FORCEINLINE VOID WDF_REQUEST_SEND_OPTIONS_INIT(_Out_ PWDF_REQUEST_SEND_OPTIONS Options, _In_ ULONG Flags)
Definition: wdfrequest.h:409
MdDeviceObject m_TargetDevice
Definition: fxiotarget.hpp:910
struct _USB_DEVICE_DESCRIPTOR USB_DEVICE_DESCRIPTOR
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_ CONST GUID * CapabilityType
Definition: wdfusb.h:1611
return STATUS_NOT_SUPPORTED
FX_URB_TYPE GetFxUrbTypeForRequest(__in FxRequestBase *Request)
#define _Must_inspect_result_
Definition: no_sal2.h:62
struct _USBD_INTERFACE_LIST_ENTRY USBD_INTERFACE_LIST_ENTRY
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct config_s config
_URB_CONTROL_DESCRIPTOR_REQUEST * m_Urb
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_ CONST GUID _In_ ULONG CapabilityBufferLength
Definition: wdfusb.h:1611
#define UsbBuildGetStatusRequest(urb, op, index, transferBuffer, transferBufferMDL, link)
Definition: usbdlib.h:35
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:306
VOID SetUrbInfo(__in UCHAR StringIndex, __in USHORT LangID)
Definition: http.c:7251
#define __out_bcount(x)
Definition: dbghelp.h:68
#define USB_BUSIF_USBDI_VERSION_1
Definition: usbbusif.h:74
#define __in_opt
Definition: dbghelp.h:38
FX_URB_TYPE m_UrbType
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ NTSTATUS SelectConfig(__in PWDF_OBJECT_ATTRIBUTES PipesAttributes, __in PURB Urb, __in FX_URB_TYPE FxUrbType, __out_opt PUCHAR NumConfiguredInterfaces)
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _In_ PWDF_USB_CONTROL_SETUP_PACKET SetupPacket
Definition: wdfusb.h:1331
WDFCASSERT(sizeof(WDF_DRIVER_CONFIG_V1_0)==sizeof(WDF_DRIVER_CONFIG_V1_1))
struct _USBD_INTERFACE_LIST_ENTRY * PUSBD_INTERFACE_LIST_ENTRY
unsigned char * PUCHAR
Definition: retypes.h:3
_In_ WDFUSBINTERFACE _In_ UCHAR _Out_ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
Definition: wdfusb.h:2329
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
_Must_inspect_result_ NTSTATUS SelectConfigSingle(__in PWDF_OBJECT_ATTRIBUTES PipeAttributes, __in PWDF_USB_DEVICE_SELECT_CONFIG_PARAMS Params)
PUSB_INTERFACE_DESCRIPTOR FxUsbParseConfigurationDescriptor(__in PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc, __in UCHAR InterfaceNumber, __in UCHAR AlternateSetting)
Definition: usbutil.cpp:307
LONG NTSTATUS
Definition: precomp.h:26
PUSB_BUSIFFN_GETUSBDI_VERSION GetUSBDIVersion
Definition: usbbusif.h:99
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
#define USB_BUSIF_USBDI_VERSION_0
Definition: usbbusif.h:73
USBD_HANDLE GetUSBDHandle(VOID)
_Must_inspect_result_ NTSTATUS Reset(VOID)
struct _USB_COMMON_DESCRIPTOR USB_COMMON_DESCRIPTOR
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ PWDF_OBJECT_ATTRIBUTES PipeAttributes
Definition: wdfusb.h:1240
GLuint buffer
Definition: glext.h:5915
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT _In_ UCHAR StringIndex
Definition: wdfusb.h:1075
BOOLEAN __inline FxBitArraySet(__inout_xcount((BitNumber/sizeof(UCHAR))+1) PUCHAR BitArray, __in UCHAR BitNumber)
Definition: usbutil.hpp:9
_Must_inspect_result_ NTSTATUS SubmitSync(__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS Options=NULL, __out_opt PULONG Action=NULL)
ULONG GetDefaultMaxTransferSize(VOID)
#define UsbBuildGetDescriptorRequest(urb, length, descriptorType, descriptorIndex, languageId, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:23
_Must_inspect_result_ NTSTATUS FormatControlRequest(__in FxRequestBase *Request, __in PWDF_USB_CONTROL_SETUP_PACKET Packet, __in FxRequestBuffer *RequestBuffer)
_Must_inspect_result_ NTSTATUS FormatStringRequest(__in FxRequestBase *Request, __in FxRequestBuffer *RequestBuffer, __in UCHAR StringIndex, __in USHORT LangID)
#define USB_STRING_DESCRIPTOR_TYPE
Definition: usb100.h:51
PINTERFACE_DEREFERENCE InterfaceDereference
Definition: usbbusif.h:98
UCHAR m_NumInterfaces
VOID CancelSentIo(VOID)
enum _FX_URB_TYPE FX_URB_TYPE
VOID StoreAndReferenceMemory(__in FxUsbDevice *Device, __in FxRequestBuffer *Buffer, __in PWDF_USB_CONTROL_SETUP_PACKET SetupPacket)
_Must_inspect_result_ __in WDFIOTARGET __in DEVICE_REGISTRY_PROPERTY __in ULONG __out_opt PVOID __deref_out_range(<=, BufferLength) PULONG ResultLength)
_Must_inspect_result_ NTSTATUS SelectConfigMulti(__in PWDF_OBJECT_ATTRIBUTES PipeAttributes, __in PWDF_USB_DEVICE_SELECT_CONFIG_PARAMS Params)
MdDeviceObject m_InStackDevice
Definition: fxiotarget.hpp:905
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
struct _USB_CONFIGURATION_DESCRIPTOR * PUSB_CONFIGURATION_DESCRIPTOR
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT NumCharacters
Definition: wdfusb.h:1075
WDFIOTARGET GetHandle(VOID)
Definition: fxiotarget.hpp:307
Definition: usbdlib.h:7
FxRequest * request
_Must_inspect_result_ NTSTATUS SubmitSyncRequestIgnoreTargetState(__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS RequestOptions)
#define __out_opt
Definition: dbghelp.h:65
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
#define USB_DEVICE_DESCRIPTOR_TYPE
Definition: usb100.h:49
struct _URB_HEADER Hdr
Definition: usb.h:467
#define FALSE
Definition: types.h:117
FxChildList * pList
PINTERFACE_DEREFERENCE m_BusInterfaceDereference
#define BMREQUEST_DEVICE_TO_HOST
Definition: usb100.h:32
VOID SetUsbType(__in WDF_USB_REQUEST_TYPE Type)
#define USB_CONFIGURATION_DESCRIPTOR_TYPE
Definition: usb100.h:50
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
struct _USB_STRING_DESCRIPTOR USB_STRING_DESCRIPTOR
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
_Must_inspect_result_ __in WDFUSBDEVICE __in CONST GUID __in ULONG __out_bcount_part_opt(CapabilityBufferLength, *ResultLength)) PVOID CapabilityBuffer
USBD_PIPE_HANDLE m_ControlPipe
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
Definition: bufpool.h:45
struct _INTERFACE * PINTERFACE
USHORT numChars
int options
Definition: main.c:106
#define UCHAR_MAX
UCHAR GetNumConfiguredPipes(VOID)
PUSB_INTERFACE_DESCRIPTOR GetSettingDescriptor(__in UCHAR Setting)
PMDL TransferBufferMDL
Definition: usb.h:472
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3531
GLsizeiptr size
Definition: glext.h:5919
PFX_DRIVER_GLOBALS pFxDriverGlobals
#define ASSERT(a)
Definition: mode.c:45
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PUSB_BUSIFFN_QUERY_BUS_TIME QueryBusTime
Definition: usbbusif.h:100
#define USB_CONFIG_REMOTE_WAKEUP
Definition: usb100.h:71
NTSTATUS USBD_QueryUsbCapability(_In_ USBD_HANDLE USBDHandle, _In_ const GUID *CapabilityType, _In_ ULONG OutputBufferLength, _When_(OutputBufferLength==0, _Pre_null_) _When_(OutputBufferLength !=0 &&ResultLength==NULL, _Out_writes_bytes_(OutputBufferLength)) _When_(OutputBufferLength !=0 &&ResultLength !=NULL, _Out_writes_bytes_to_opt_(OutputBufferLength, *ResultLength)) PUCHAR OutputBuffer, _Out_opt_ _When_(ResultLength !=NULL, _Deref_out_range_(<=, OutputBufferLength)) PULONG ResultLength)
Definition: usbstubum.cpp:111
#define __drv_when(cond, annotes)
Definition: driverspecs.h:317
PUSB_CONFIGURATION_DESCRIPTOR m_ConfigDescriptor
BOOLEAN m_OnUSBD
ULONG m_HcdPortCapabilities
_In_opt_ PVOID _In_ ULONG _In_ PVOID context
Definition: wdfdriver.h:113
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
PVOID m_BusInterfaceContext
WDFUSBINTERFACE GetHandle(VOID)
unsigned char UCHAR
Definition: xmlstorage.h:181
FxUsbInterface ** m_Interfaces
size_t bufferSize
_Must_inspect_result_ NTSTATUS FormatIoctlRequest(__in FxRequestBase *Request, __in ULONG Ioctl, __in BOOLEAN Internal, __in FxRequestBuffer *InputBuffer, __in FxRequestBuffer *OutputBuffer, __in_opt FxFileObject *FileObject=NULL)
_Must_inspect_result_ _In_ WDFUSBINTERFACE _In_opt_ PWDF_OBJECT_ATTRIBUTES PipesAttributes
Definition: wdfusb.h:2388
_Must_inspect_result_ NTSTATUS InitDevice(__in ULONG USBDClientContractVersionForWdfClient)
WDFUSBINTERFACE UsbInterface
Definition: wdfusb.h:522
virtual VOID StoreAndReferenceMemory(__in FxRequestBuffer *Buffer)
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
#define USB_GETSTATUS_SELF_POWERED
Definition: usb100.h:45
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4061
_Must_inspect_result_ NTSTATUS AllocateDescriptor(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in size_t BufferSize)
PURB FxUsbCreateConfigRequest(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc, __in PUSBD_INTERFACE_LIST_ENTRY InterfaceList, __in ULONG DefaultMaxPacketSize)
Definition: usbutil.cpp:364
__checkReturn NTSTATUS AllocateUrb(__in USBD_HANDLE USBDHandle)
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define USBD_CLIENT_CONTRACT_VERSION_INVALID
Definition: usbdlib.h:99
_Must_inspect_result_ __in WDFKEY __in PCUNICODE_STRING __in ULONG __in ULONG __in_ecount(ValueLength) PVOID Value)
_URB_CONTROL_TRANSFER * m_Urb
Definition: fxusbdevice.hpp:86
FORCEINLINE LONGLONG WDF_REL_TIMEOUT_IN_SEC(_In_ ULONGLONG Time)
Definition: wdfcore.h:62
#define USBD_SHORT_TRANSFER_OK
Definition: usb.h:154
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
struct _USB_STRING_DESCRIPTOR * PUSB_STRING_DESCRIPTOR
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
Definition: usbdlib.h:8
UCHAR SetupPacket[8]
Definition: usb.h:475
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: usb.h:529
PUSB_BUSIFFN_IS_DEVICE_HIGH_SPEED IsDeviceHighSpeed
Definition: usbbusif.h:103
__checkReturn NTSTATUS AllocateUrb(__in USBD_HANDLE USBDHandle)
Definition: fxusbdevice.cpp:66
unsigned short USHORT
Definition: pedump.c:61
_Must_inspect_result_ NTSTATUS QueryUsbCapability(__in CONST GUID *CapabilityType, __in ULONG CapabilityBufferLength, __drv_when(CapabilityBufferLength==0, __out_opt) __drv_when(CapabilityBufferLength !=0 &&ResultLength==NULL, __out_bcount(CapabilityBufferLength)) __drv_when(CapabilityBufferLength !=0 &&ResultLength !=NULL, __out_bcount_part_opt(CapabilityBufferLength, *ResultLength)) PVOID CapabilityBuffer, __out_opt __drv_when(ResultLength !=NULL, __deref_out_range(<=, CapabilityBufferLength)) PULONG ResultLength)
USBD_PIPE_HANDLE PipeHandle
Definition: usb.h:468
USBD_HANDLE m_USBDHandle
#define USBD_DEFAULT_PIPE_TRANSFER
Definition: usb.h:156
PUSB_BUSIFFN_QUERY_BUS_TIME m_QueryBusTime
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned int * PULONG
Definition: retypes.h:1
static HANDLE PipeHandle
Definition: dhcpcsvc.c:21
#define NULL
Definition: types.h:112
#define URB_FUNCTION_GET_STATUS_FROM_DEVICE
Definition: usb.h:105
union _WDF_USB_CONTROL_SETUP_PACKET * PWDF_USB_CONTROL_SETUP_PACKET
static VOID _FormatIrp(__in PIRP Irp, __in const GUID *InterfaceGuid, __out PINTERFACE Interface, __in USHORT InterfaceSize, __in USHORT InterfaceVersion, __in_opt PVOID InterfaceSpecificData=NULL)
_Must_inspect_result_ NTSTATUS GetInterfaceNumberFromInterface(__in WDFUSBINTERFACE UsbInterface, __out PUCHAR InterfaceNumber)
#define IOCTL_INTERNAL_USB_RESET_PORT
Definition: usbioctl.h:35
Definition: tftpd.h:85
_URB_CONTROL_TRANSFER m_UrbLegacy
Definition: fxusbdevice.hpp:81
_Must_inspect_result_ NTSTATUS GetString(__in_ecount(*NumCharacters) PUSHORT String, __in PUSHORT NumCharacters, __in UCHAR StringIndex, __in_opt USHORT LangID, __in_opt WDFREQUEST Request=NULL, __in_opt PWDF_REQUEST_SEND_OPTIONS Options=NULL)
#define URB_FUNCTION_CONTROL_TRANSFER
Definition: usb.h:94
ULONG TransferFlags
Definition: usb.h:469
unsigned int ULONG
Definition: retypes.h:1
USB_DEVICE_DESCRIPTOR m_DeviceDescriptor
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
USBD_VERSION_INFORMATION m_UsbdVersionInformation
#define STATUS_SUCCESS
Definition: shellext.h:65
FORCEINLINE VOID WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(_Inout_ PWDF_REQUEST_SEND_OPTIONS Options, _In_ LONGLONG Timeout)
Definition: wdfrequest.h:421
struct _URB_CONTROL_DESCRIPTOR_REQUEST UrbControlDescriptorRequest
Definition: usb.h:545
void exit(int exitcode)
Definition: _exit.c:33
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT _In_ UCHAR _In_opt_ USHORT LangID
Definition: wdfusb.h:1075
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
#define __in
Definition: dbghelp.h:35
PVOID TransferBuffer
Definition: usb.h:471
static SERVICE_STATUS status
Definition: service.c:31
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
unsigned short * PUSHORT
Definition: retypes.h:2
#define CONST
Definition: pedump.c:81
ULONG TransferBufferLength
Definition: usb.h:470
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
NTSTATUS USBD_CreateHandle(_In_ PDEVICE_OBJECT DeviceObject, _In_ PDEVICE_OBJECT TargetDeviceObject, _In_ ULONG USBDClientContractVersion, _In_ ULONG PoolTag, _Out_ USBD_HANDLE *USBDHandle)
Definition: usbstubum.cpp:90
VOID FxFormatUsbRequest(__in FxRequestBase *Request, __in PURB Urb, __in FX_URB_TYPE FxUrbType, __drv_when(FxUrbType==FxUrbTypeUsbdAllocated, __in) __drv_when(FxUrbType !=FxUrbTypeUsbdAllocated, __in_opt) USBD_HANDLE UsbdHandle)
Definition: usbutil.cpp:29
Definition: ps.c:97