ReactOS  0.4.15-dev-3181-g4acf100
fxusbinterface.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxUsbInterface.cpp
8 
9 Abstract:
10 
11 Author:
12 
13 Environment:
14 
15  Both kernel and user mode
16 
17 Revision History:
18 
19 --*/
20 
21 #include "fxusbpch.hpp"
22 
23 extern "C" {
24 #include "FxUsbInterface.tmh"
25 }
26 
28  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
31  ) :
33  m_UsbDevice(UsbDevice)
34 {
35  m_UsbDevice->ADDREF(this);
36 
37  m_InterfaceNumber = InterfaceDescriptor->bInterfaceNumber;
38  m_Protocol = InterfaceDescriptor->bInterfaceProtocol;
39  m_Class = InterfaceDescriptor->bInterfaceClass;
40  m_SubClass = InterfaceDescriptor->bInterfaceSubClass;
41 
43  m_NumSettings = 0;
46  m_Settings = NULL;
47 
49 }
50 
52 {
53  ULONG i;
54 
56 
57  for (i = 0; i < m_NumberOfConfiguredPipes; i++) {
59  }
60 
61  if (m_ConfiguredPipes != NULL) {
64  }
65 
67 
68  if (m_Settings != NULL) {
69  FxPoolFree(m_Settings);
70  m_Settings = NULL;
71  }
72 
73  //
74  // Release the reference taken in the constructor
75  //
76  m_UsbDevice->RELEASE(this);
77 }
78 
79 VOID
81  __in BOOLEAN Failure
82  )
83 /*++
84 
85 Routine Description:
86  Deletes the pipes contained on the interface.
87 
88 Arguments:
89  Failure - if TRUE, the pipes were never exposed to the client, so any attributes
90  are cleared before deletion (via DeleteFromFailedCreate)
91 
92 Assumes:
93  FxUsbDevice::InterfaceIterationLock is held by the caller
94 
95 Return Value:
96  None
97 
98  --*/
99 {
100  FxUsbPipe** pPipes;
101  ULONG numPipes;
102  KIRQL irql;
103  ULONG i;
104 
105  //
106  // Capture the values, clear them out of the object and then clean them up
107  // outside of the lock.
108  //
109  m_UsbDevice->Lock(&irql);
110 
111  pPipes = m_ConfiguredPipes;
112  numPipes = m_NumberOfConfiguredPipes;
113 
116 
117  m_UsbDevice->Unlock(irql);
118 
119  if (pPipes != NULL) {
120  for (i = 0; i < numPipes; i++) {
121  if (pPipes[i] != NULL) {
122  if (Failure) {
123  //
124  // FxIoTarget::Remove will be called in FxIoTarget::Dispose()
125  //
126  pPipes[i]->DeleteFromFailedCreate();
127  }
128  else {
129  pPipes[i]->DeleteObject();
130  }
131  }
132  else {
133  //
134  // No more pointers to delete, break out of the loop
135  //
136  break;
137  }
138  }
139 
140  FxPoolFree(pPipes);
141  pPipes = NULL;
142  }
143 }
144 
145 VOID
148  )
149 {
150  ULONG i;
151 
152  if (m_ConfiguredPipes == NULL) {
153  return;
154  }
155 
156  for (i = 0; i < m_NumberOfConfiguredPipes; i++) {
157  if (m_ConfiguredPipes[i] == Pipe) {
159  return;
160  }
161  }
162 }
163 
164 VOID
166  __in PUSBD_INTERFACE_INFORMATION InterfaceInfo
167  )
168 /*++
169 
170 Routine Description:
171  Captures the alternate from the interface information into this structure
172  and then assigns info to all the created pipes.
173 
174 Arguments:
175  InterfaceInfo - info to capture
176 
177 Return Value:
178  None
179 
180  --*/
181 {
182  UCHAR i;
183 
184  ASSERT(m_InterfaceNumber == InterfaceInfo->InterfaceNumber);
185 
186  m_CurAlternateSetting = InterfaceInfo->AlternateSetting;
187 
188  for (i = 0; i < m_NumberOfConfiguredPipes ; i++) {
189  m_ConfiguredPipes[i]->InitPipe(&InterfaceInfo->Pipes[i],
190  InterfaceInfo->InterfaceNumber,
191  this);
192  }
193 }
194 
196 NTSTATUS
198  VOID
199  )
200 /*++
201 
202 Routine Description:
203  1) Find the max number of settings for the interface
204  2) Allocate an array for the settings
205  3) Create a setting object for each setting and initialize
206 
207 Arguments:
208  None
209 
210 Return Value:
211  NTSTATUS
212 
213  --*/
214 {
215  PUSB_INTERFACE_DESCRIPTOR pDescriptor;
216  ULONG size;
217  UCHAR i;
218 
219  //
220  // No need to validate the size of the interface descriptor since FxUsbDevice::CreateInterfaces
221  // has already done so
222  //
228  );
229 
230  //
231  // Calculate the number of settings for this interface
232  //
233  while (pDescriptor != NULL) {
234  if (m_InterfaceNumber == pDescriptor->bInterfaceNumber) {
235  m_NumSettings++;
236  }
240  WDF_PTR_ADD_OFFSET(pDescriptor, pDescriptor->bLength),
242  );
243  }
245  m_Settings = (FxUsbInterfaceSetting *) FxPoolAllocate(
247 
248  if (m_Settings == NULL) {
251  "Could not allocate memory for %d settings for bInterfaceNumber %d "
252  "(Protocol %d, Class %d, SubClass %d), %!STATUS!",
255 
257  }
258 
259  RtlZeroMemory(m_Settings, size);
260 
261  //
262  // Add all the settings for this interface
263  //
269  );
270 
271  while (pDescriptor != NULL) {
272  if (m_InterfaceNumber == pDescriptor->bInterfaceNumber) {
273  if (pDescriptor->bAlternateSetting < m_NumSettings) {
274  m_Settings[pDescriptor->bAlternateSetting].InterfaceDescriptor = pDescriptor;
275  }
276  else {
279  "Interface Number %d does not have contiguous alternate settings,"
280  "expected %d settings, found alt setting %d, %!STATUS!",
281  pDescriptor->bInterfaceNumber, m_NumSettings,
283 
285  }
286  }
287 
291  WDF_PTR_ADD_OFFSET(pDescriptor, pDescriptor->bLength),
293  );
294  }
295 
296  for (i = 0; i < m_NumSettings; i++) {
297 
298  if (m_Settings[i].InterfaceDescriptor == NULL) {
301  "Interface Number %d does not have contiguous alternate settings,"
302  "expected consecutive %d settings, but alt setting %d missing "
303  "%!STATUS!", m_InterfaceNumber, m_NumSettings, i,
305 
307  }
308 
309  //
310  // Only validate the endpoints if the interface reports it has some. We don't
311  // want to validate EP descriptors that may be after the interface descriptor
312  // that are never used because bNumEndpoints doesn't indicate they are present.
313  //
314  if (m_Settings[i].InterfaceDescriptor->bNumEndpoints > 0) {
315  PVOID pRelativeEnd;
317 
318  //
319  // Validate that each endpoint descriptor is the correct size for this alt setting.
320  // We will use the next inteface descriptor as the end, and if this is the last
321  // interface descriptor, use the end of the config descriptor as our end.
322  //
323  pRelativeEnd = FxUsbFindDescriptorType(
326  m_Settings[i].InterfaceDescriptor,
328  );
329 
330  if (pRelativeEnd == NULL) {
331  //
332  // This is the last alt setting in the config descriptor, use the end of the
333  // config descriptor as our end
334  //
337  }
338 
339  //
340  // Limit the number of endpoints validated to bNumEndpoints. In theory
341  // there could be EP descriptors after N EP descriptors that are never
342  // used, thus we don't want to risk valdiating them and failing them
343  // (ie an app compat concern, in a perfect world we would validate them)
344  //
348  m_Settings[i].InterfaceDescriptor,
349  pRelativeEnd,
351  sizeof(USB_ENDPOINT_DESCRIPTOR),
353  m_Settings[i].InterfaceDescriptor->bNumEndpoints
354  );
355 
356  if (!NT_SUCCESS(status)) {
359  "Interface Number %d does not have a valid endpoint descriptor,"
360  "%!STATUS!", m_InterfaceNumber, status);
361 
362  return status;
363  }
364  }
365  }
366 
367  return STATUS_SUCCESS;
368 }
369 
371 NTSTATUS
375  )
376 /*++
377 
378 Routine Description:
379  Setlects a setting by alternate setting index.
380 
381 Arguments:
382  PipesAttributes - optional attributes to apply to each of the created pipes
383 
384  SettingIndex - alternate setting index to use
385 
386 Return Value:
387  NTSTATUS
388 
389  --*/
390 {
391 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
392  PURB urb;
393 #elif (FX_CORE_MODE == FX_CORE_USER_MODE)
394  UMURB urb;
395  PUSB_INTERFACE_DESCRIPTOR interfaceDesc;
396 #endif
398  UCHAR numEP;
400  USHORT size;
401 
403 
404  //
405  // We should have at least 1 setting on the interface
406  //
407  ASSERT(m_NumSettings != 0);
408 
409  //
410  // If m_NumberOfConfiguredPipes == 0 then it also tells us that
411  // the interface wasn't configured. So it can keep track of configuredness
412  // of the interface. Could there be a case when the selected setting has 0
413  // EP's. Due to the above case we use m_InterfaceConfigured.
414  //
416  return STATUS_SUCCESS;
417  }
418 
419  //
420  // Check for an invalid alternate setting
421  //
422  if (SettingIndex >= m_NumSettings){
424  }
425 
426  RtlCopyMemory(&entry, &m_Settings[SettingIndex], sizeof(entry));
427 
428  //
429  // Create the configured pipes
430  //
431  numEP = entry.InterfaceDescriptor->bNumEndpoints;
432 
434 
435 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
436  urb = (PURB) FxPoolAllocate(GetDriverGlobals(), NonPagedPool, size);
437 
438  if (urb == NULL) {
440  }
441  else {
443 
445 
446  FxPoolFree(urb);
447  urb = NULL;
448  }
449 #elif (FX_CORE_MODE == FX_CORE_USER_MODE)
450  RtlZeroMemory(&urb, sizeof(UMURB));
451 
452  urb.UmUrbSelectInterface.Hdr.InterfaceHandle = m_WinUsbHandle;
454  urb.UmUrbSelectInterface.Hdr.Length = sizeof(_UMURB_SELECT_INTERFACE);
455 
456  urb.UmUrbSelectInterface.AlternateSetting = SettingIndex;
457 
458  status = m_UsbDevice->SendSyncUmUrb(&urb, 2);
459 
460  if (NT_SUCCESS(status)) {
461  RtlZeroMemory(&urb, sizeof(UMURB));
462 
463  urb.UmUrbInterfaceInformation.Hdr.InterfaceHandle = m_WinUsbHandle;
466 
467  urb.UmUrbInterfaceInformation.AlternateSetting = SettingIndex;
468 
469  status = m_UsbDevice->SendSyncUmUrb(&urb, 2);
470 
471  if (NT_SUCCESS(status)) {
472  interfaceDesc = &urb.UmUrbInterfaceInformation.UsbInterfaceDescriptor;
473 
474  m_Settings[SettingIndex].InterfaceDescriptorAlloc = *interfaceDesc;
475 
477 
479  }
480  }
481 #endif
482 
483  return status;
484 }
485 
487 NTSTATUS
491  )
492 /*++
493 
494 Routine Description:
495  Selects an alternate setting by using a USB interface descriptor
496 
497 Arguments:
498  PipesAttributes - optional attributes to apply to each of the created pipes
499 
500 Return Value:
501  NTSTATUS
502 
503  --*/
504 {
505  PURB urb;
507  USHORT size;
508 
509  if (IsInterfaceConfigured() &&
510  (m_CurAlternateSetting == InterfaceDescriptor->bAlternateSetting)) {
511  //
512  // Don't do anything
513  //
514  return STATUS_SUCCESS;
515  }
516 
517  if (InterfaceDescriptor->bInterfaceNumber != m_InterfaceNumber) {
519 
522  "WDFUSBINTERFACE %p has interface num %d, select setting by "
523  "descriptor specified interface num %d, %!STATUS!",
525  InterfaceDescriptor->bInterfaceNumber, status
526  );
527 
528  return status;
529  }
530 
532 
533  urb = (PURB) FxPoolAllocate(GetDriverGlobals(), NonPagedPool, size);
534 
535  if (urb == NULL) {
537  }
538  else {
540  urb,
541  InterfaceDescriptor->bNumEndpoints,
542  InterfaceDescriptor->bAlternateSetting
543  );
544 
546 
547  FxPoolFree(urb);
548  }
549 
550  return status;
551 }
552 
554 NTSTATUS
557  )
558 /*++
559 
560 Routine Description:
561  Checks if the give SettingIndex is the current alternate setting
562  and if not, selects that setting
563 
564 Arguments:
565  SettingIndex - Alternate setting
566 
567 Return Value:
568  NTSTATUS
569 
570  --*/
571 {
573  return SelectSettingByIndex(NULL,
574  SettingIndex);
575  }
576  else {
577  return STATUS_SUCCESS;
578  }
579 }
580 
582 NTSTATUS
585  __in PURB Urb
586  )
587 /*++
588 
589 Routine Description:
590  Worker function which all top level SelectSetting DDIs call into. This will
591  1) preallocate all required objects so that we can return failure before
592  we make any undoable changes to the device's state
593  2) send the select interface URB to the device
594  3) initialize all created objects
595 
596 Arguments:
597  PipesAttributes - optional attributes to apply to all created pipes
598 
599  Urb - Urb to send to the device
600 
601 Return Value:
602  NTSTATUS
603 
604  --*/
605 {
606  FxSyncRequest request(GetDriverGlobals(), NULL);
607  LIST_ENTRY pendHead;
608  FxUsbPipe* pPipe;
610  UCHAR iPipe, numPipes;
612  FxUsbPipe ** ppPipes;
613  ULONG size;
614 
615  //
616  // FxSyncRequest always succeesds for KM but can fail for UM.
617  //
618  status = request.Initialize();
619  if (!NT_SUCCESS(status)) {
621  "Failed to initialize FxSyncRequest");
622  return status;
623  }
624 
625  //
626  // Subtract the size of the embedded pipe.
627  //
628  const ULONG interfaceStructSize = sizeof(Urb->UrbSelectInterface.Interface) -
629  sizeof(USBD_PIPE_INFORMATION);
630 
631  //
632  // This check will happen twice for SelectSettingByInterface/Descriptor.
633  //
634  // We could just do it here, but the above two functions will unnecessarily
635  // have to build an URB.
636  //
637  if (IsInterfaceConfigured() &&
639  Urb->UrbSelectInterface.Interface.AlternateSetting) {
640  //
641  // don't do anything
642  //
643  return STATUS_SUCCESS;
644  }
645 
646  InitializeListHead(&pendHead);
647  numPipes = 0;
648  ppPipes = NULL;
649 
650  if (Urb->UrbSelectInterface.Hdr.Length < interfaceStructSize) {
654  "Urb header length 0x%x is less than expected 0x%x"
655  "%!STATUS!", Urb->UrbSelectInterface.Hdr.Length, interfaceStructSize,status
656  );
657  return status;
658  }
659 
660  status = request.m_TrueRequest->ValidateTarget(m_UsbDevice);
661  if (!NT_SUCCESS(status)) {
662  goto Done;
663  }
664 
665  //
666  // Urb->UrbSelectInterface.Interface.NumberOfPipes is set when the URB
667  // completes. So, we must compute the number of pipes being requested based
668  // on the size of the structure and its Length (as set by the caller).
669  // To calculate the number of pipes we need to account for the
670  // embedded pipe in the structure.
671  //
672  numPipes = (UCHAR) ((Urb->UrbSelectInterface.Interface.Length -
673  interfaceStructSize) /
674  sizeof(USBD_PIPE_INFORMATION)
675  );
676 
677  if (numPipes > 0) {
678  size = numPipes * sizeof(FxUsbPipe *);
679  }
680  else {
681  //
682  // It is valid to have an interface with zero pipes in it. In that
683  // case, we just allocate one entry so that we have a valid array
684  // and keep the remaining code simple.
685  //
686  size = sizeof(FxUsbPipe*);
687  }
688 
689  //
690  // If the interface is already configured don't do anything with the old
691  // settings till we allocate new.
692  //
693  ppPipes = (FxUsbPipe **) FxPoolAllocate(GetDriverGlobals(), NonPagedPool, size);
694 
695  if (ppPipes == NULL) {
699  "Unable to allocate memory %!STATUS!"
700  , status);
701  goto Done;
702  }
703 
704  RtlZeroMemory(ppPipes, size);
705 
706  for (iPipe = 0; iPipe < numPipes; iPipe++) {
707  ppPipes[iPipe] = new (GetDriverGlobals(), PipesAttributes)
709 
710  if (ppPipes[iPipe] == NULL) {
714  "Unable to allocate memory for the pipes %!STATUS!", status);
715  goto Done;
716  }
717 
718  pPipe = ppPipes[iPipe];
719 
720  status = pPipe->Init(m_UsbDevice->m_Device);
721  if (!NT_SUCCESS(status)) {
724  "Init pipe failed %!STATUS!", status);
725  goto Done;
726  }
727 
728  status = pPipe->Commit(PipesAttributes, NULL, this);
729 
730  if (!NT_SUCCESS(status)) {
733  "Commit pipe failed %!STATUS!", status);
734  goto Done;
735  }
736  }
737 
738  if (IsInterfaceConfigured()) {
739  //
740  // Delete the old pipes
741  //
743  }
744 
745 
748 
750 
751  FxFormatUsbRequest(request.m_TrueRequest, Urb, FxUrbTypeLegacy, NULL);
752  status = m_UsbDevice->SubmitSync(request.m_TrueRequest, &options, NULL);
753 
754  //
755  // If select interface URB fails we are at the point of no return and we
756  // will end up with no configured pipes.
757  //
758  if (NT_SUCCESS(status)) {
759  SetNumConfiguredPipes(numPipes);
760  SetConfiguredPipes(ppPipes);
761  SetInfo(&Urb->UrbSelectInterface.Interface);
762  }
763 
764 Done:
765  if (!NT_SUCCESS(status)) {
766  if (ppPipes != NULL) {
767  ASSERT(ppPipes != m_ConfiguredPipes);
768 
769  for (iPipe = 0; iPipe < numPipes; iPipe++) {
770  if (ppPipes[iPipe] != NULL) {
771  ppPipes[iPipe]->DeleteFromFailedCreate();
772  }
773  }
774 
775  FxPoolFree(ppPipes);
776  ppPipes = NULL;
777  }
778  }
779 
780  return status;
781 }
782 
783 VOID
786  __in USHORT NumEndpoints,
787  __in UCHAR SettingNumber
788  )
789 /*++
790 
791 Routine Description:
792  Format a URB for selecting an interface's new setting. Note this will setup
793  the URB header and all pipes' information in the URB's array of pipe infos.
794 
795  This function exists as a method of FxUsbDevice instead of FxUsbInterface
796  because in the case of a select config where we manually select setting 0
797  on interfaces 2...N we don't have an FxUsbInterface pointer
798 
799 Arguments:
800  Urb - the URB to format. It is assumed the caller allocated a large enough
801  URB to contain NumEndpoints
802 
803  NumEndpoints - number of endpoints in the new setting
804 
805  InterfaceNum - interface number for the interface
806 
807  SettingNumber - setting number on the interface
808 
809  --*/
810 {
811  ULONG defaultMaxTransferSize;
812  USHORT size;
813  UCHAR i;
814 
815  size = GET_SELECT_INTERFACE_REQUEST_SIZE(NumEndpoints);
816 
817  RtlZeroMemory(Urb, size);
818 
819  //
820  // Setup the URB, format the request, and send it
821  //
823  size,
826  SettingNumber);
827 
828  defaultMaxTransferSize = m_UsbDevice->GetDefaultMaxTransferSize();
829 
830  Urb->UrbSelectInterface.Interface.Length =
831  GET_USBD_INTERFACE_SIZE(NumEndpoints);
832 
833  Urb->UrbSelectInterface.Interface.NumberOfPipes = NumEndpoints;
834 
835  for (i = 0; i < NumEndpoints; i++) {
836 
837  //
838  // Make sure that the Interface Length conveys the exact number of EP's
839  //
840  ASSERT(
841  &Urb->UrbSelectInterface.Interface.Pipes[i] <
842  WDF_PTR_ADD_OFFSET(&Urb->UrbSelectInterface.Interface,
843  Urb->UrbSelectInterface.Interface.Length)
844  );
845 
846  Urb->UrbSelectInterface.Interface.Pipes[i].PipeFlags = 0x0;
847  Urb->UrbSelectInterface.Interface.Pipes[i].MaximumTransferSize =
848  defaultMaxTransferSize;
849  }
850 }
851 
852 VOID
857  )
858 /*++
859 
860 Routine Description:
861  The layout of the config descriptor is such that each interface+setting pair
862  is followed by the endpoints for that interface+setting pair. Keep track of
863  the index.
864 
865 Arguments:
866  SettingIndex - alternate setting to get info for
867 
868  EndpointIndex - index into the number endpoints for this interface+setting
869 
870  PipeInfo - Info to return
871 
872 Return Value:
873  None
874 
875  --*/
876 {
877  PUCHAR pEnd, pCur;
878  PUSB_INTERFACE_DESCRIPTOR pInterfaceDesc;
879  PUSB_ENDPOINT_DESCRIPTOR pEndpointDesc;
880  UCHAR curEndpointIndex;
881  BOOLEAN endPointFound;
882 
883  pInterfaceDesc = NULL;
884  curEndpointIndex = 0;
885  endPointFound = FALSE;
886 
887  //
888  // Extract the interface descriptor for the alternate setting for the interface
889  //
890  pInterfaceDesc = GetSettingDescriptor(SettingIndex);
891 
892  if (pInterfaceDesc == NULL) {
893  return;
894  }
895 
896  pEnd = (PUCHAR) WDF_PTR_ADD_OFFSET(
899  );
900 
901  //
902  // Start from the descriptor after current one
903  //
904  pCur = (PUCHAR) WDF_PTR_ADD_OFFSET(pInterfaceDesc, pInterfaceDesc->bLength);
905 
906  //
907  // Iterate through the list of EP descriptors following the interface descriptor
908  // we just found and get the endpoint descriptor which matches the endpoint
909  // index or we hit another interface descriptor
910  //
911  // We have already validated that the descriptor headers are well formed and within
912  // the config descriptor bounds
913  //
914  while (pCur < pEnd) {
916 
917  //
918  // If we hit the next interface no way we can find the EndPoint
919  //
920  if (pCommonDesc->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) {
921  break;
922  }
923 
924  if (pCommonDesc->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE) {
925  //
926  // Size of pEndpointDesc has been validated by CreateSettings() and
927  // is within the config descriptor
928  //
929  pEndpointDesc = (PUSB_ENDPOINT_DESCRIPTOR) pCommonDesc;
930 
931  if (EndpointIndex == curEndpointIndex) {
933  pEndpointDesc,
934  SettingIndex);
935  break;
936  }
937 
938  curEndpointIndex++;
939  }
940 
941  //
942  // Advance past this descriptor
943  //
944  pCur += pCommonDesc->bLength;
945  }
946 }
947 
948 ULONG
950  VOID
951  )
952 /*++
953 
954 Routine Description:
955  Returns the maximum transfer size of an endpoint
956 
957 Arguments:
958  None
959 
960 Return Value:
961  max transfer size
962 
963  --*/
964 {
967  }
968  else {
970  }
971 }
972 
973 VOID
976  __in PUSB_ENDPOINT_DESCRIPTOR EndpointDesc,
978  )
979 /*++
980 
981 Routine Description:
982  Copy informatoin out of the usb endpoint descriptor into this object
983 
984 Arguments:
985  PipeInfo - information to return
986 
987  EndpointDesc - descriptor to copy from
988 
989  SettingIndex - alternate setting this information is for
990 
991 Return Value:
992  None
993 
994  --*/
995 {
996  PipeInfo->MaximumPacketSize = EndpointDesc->wMaxPacketSize;
997  PipeInfo->EndpointAddress = EndpointDesc->bEndpointAddress;
998  PipeInfo->Interval = EndpointDesc->bInterval;
999 
1000  //
1001  // Extract the lower 2 bits which contain the EP type
1002  //
1004  (USBD_PIPE_TYPE) (EndpointDesc->bmAttributes & 0x03)
1005  );
1006 
1007  //
1008  // Filling in a default value since the EndpointDescriptor doesn't contain it
1009  //
1010  if (PipeInfo->PipeType == WdfUsbPipeTypeControl) {
1011  PipeInfo->MaximumTransferSize = FxUsbPipeControlMaxTransferSize;
1012  }
1013  else {
1014  PipeInfo->MaximumTransferSize = DetermineDefaultMaxTransferSize();
1015  }
1016 
1017  PipeInfo->SettingIndex = SettingIndex;
1018 }
1019 
1020 WDFUSBPIPE
1024  )
1025 /*++
1026 
1027 Routine Description:
1028  Return the WDFUSBPIPE for the given index
1029 
1030 Arguments:
1031  PipeIndex - index into the number of configured pipes for the interface
1032 
1033  PipeInfo - optional information to return about the returned pipe
1034 
1035 Return Value:
1036  valid WDFUSBPIPE handle or NULL on error
1037 
1038  --*/
1039 {
1041  return NULL;
1042  }
1043  else {
1044  if (PipeInfo != NULL) {
1046  }
1047 
1049  }
1050 }
1051 
1052 VOID
1054  __in PUSB_INTERFACE_DESCRIPTOR UsbInterfaceDescriptor,
1056  )
1057 /*++
1058 
1059 Routine Description:
1060  Copies the descriptor back to the caller
1061 
1062 Arguments:
1063  UsbInterfaceDescriptor - descriptor pointer to fill in
1064 
1065  SettingIndex - alternate setting that the caller is interested in
1066 
1067 Return Value:
1068  None
1069 
1070  --*/
1071 {
1072  if (SettingIndex >= m_NumSettings) {
1073  RtlZeroMemory(UsbInterfaceDescriptor,
1074  sizeof(*UsbInterfaceDescriptor));
1075  }
1076  else {
1077  RtlCopyMemory(UsbInterfaceDescriptor,
1078  m_Settings[SettingIndex].InterfaceDescriptor,
1079  sizeof(*UsbInterfaceDescriptor));
1080  }
1081 }
1082 
1083 UCHAR
1085  VOID
1086  )
1087 /*++
1088 
1089 Routine Description:
1090  Returns the currently configured setting index for the interface
1091 
1092 Arguments:
1093  None
1094 
1095 Return Value:
1096  Currently configured Index
1097 
1098  --*/
1099 
1100 {
1101  if (IsInterfaceConfigured()) {
1102  return m_CurAlternateSetting;
1103  }
1104  else {
1107  "WDFUSBINTERFACE %p not configured, cannot retrieve configured "
1108  "setting index", GetHandle());
1109 
1111 
1112  return 0;
1113  }
1114 }
1115 
1116 UCHAR
1119  )
1120 /*++
1121 
1122 Routine Description:
1123  Returns the number of endpoints on a given alternate interface
1124 
1125 Arguments:
1126  SettingIndex - index of the alternate setting
1127 
1128 Return Value:
1129  Number of endpoints or 0 on error
1130 
1131  --*/
1132 {
1133  if (SettingIndex >= m_NumSettings) {
1134  return 0;
1135  }
1136  else {
1137  return m_Settings[SettingIndex].InterfaceDescriptor->bNumEndpoints;
1138  }
1139 }
1140 
1143  __in UCHAR Setting
1144  )
1145 /*++
1146 
1147 Routine Description:
1148  Returns the device's interface descriptor for the given alternate setting
1149 
1150 Arguments:
1151  Setting - AlternateSetting desired
1152 
1153 Return Value:
1154  USB interface descriptor or NULL on failure
1155 
1156  --*/
1157 {
1158  UCHAR i;
1159 
1160  for (i = 0; i < m_NumSettings; i++) {
1161  if (m_Settings[i].InterfaceDescriptor->bAlternateSetting == Setting) {
1162  return m_Settings[i].InterfaceDescriptor;
1163  }
1164  }
1165 
1166  return NULL;
1167 }
1168 
CfxDevice * m_Device
Definition: fxobject.hpp:329
#define __in_bcount(x)
Definition: dbghelp.h:41
FORCEINLINE VOID WDF_REQUEST_SEND_OPTIONS_INIT(_Out_ PWDF_REQUEST_SEND_OPTIONS Options, _In_ ULONG Flags)
Definition: wdfrequest.h:409
virtual VOID DeleteObject(VOID)
WINUSB_INTERFACE_HANDLE m_WinUsbHandle
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
FxUsbDevice * m_UsbDevice
_Must_inspect_result_ NTSTATUS Commit(__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
Definition: fxobject.cpp:904
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
#define WDF_PTR_ADD_OFFSET(_ptr, _offset)
Definition: wdfcore.h:144
VOID GetDescriptor(__in PUSB_INTERFACE_DESCRIPTOR UsbInterfaceDescriptor, __in UCHAR SettingIndex)
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
unsigned char * PUCHAR
Definition: retypes.h:3
_In_ WDFUSBINTERFACE _In_ UCHAR _Out_ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
Definition: wdfusb.h:2329
_Must_inspect_result_ NTSTATUS SendSyncUmUrb(__inout PUMURB Urb, __in ULONGLONG Time, __in_opt WDFREQUEST Request=NULL, __in_opt PWDF_REQUEST_SEND_OPTIONS Options=NULL)
WDFUSBPIPE GetConfiguredPipe(__in UCHAR PipeIndex, __out_opt PWDF_USB_PIPE_INFORMATION PipeInfo)
LONG NTSTATUS
Definition: precomp.h:26
#define GET_SELECT_INTERFACE_REQUEST_SIZE(totalPipes)
Definition: usbdlib.h:117
_Must_inspect_result_ NTSTATUS SelectSettingByDescriptor(__in PWDF_OBJECT_ATTRIBUTES PipesAttributes, __in PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor)
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define UMURB_FUNCTION_SELECT_INTERFACE
Definition: umusb.h:9
FxUsbPipe ** m_ConfiguredPipes
_Must_inspect_result_ NTSTATUS SubmitSync(__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS Options=NULL, __out_opt PULONG Action=NULL)
VOID SetNumConfiguredPipes(__in UCHAR NumberOfPipes)
KIRQL irql
Definition: wave.h:1
VOID SetConfiguredPipes(__in FxUsbPipe **ppPipes)
struct _USB_INTERFACE_DESCRIPTOR * PUSB_INTERFACE_DESCRIPTOR
ULONG GetDefaultMaxTransferSize(VOID)
_Must_inspect_result_ NTSTATUS SelectSettingByIndex(__in PWDF_OBJECT_ATTRIBUTES PipesAttributes, __in UCHAR SettingIndex)
PUSB_COMMON_DESCRIPTOR FxUsbFindDescriptorType(__in PVOID Buffer, __in size_t BufferLength, __in PVOID Start, __in LONG DescriptorType)
Definition: usbutil.cpp:174
enum _USBD_PIPE_TYPE USBD_PIPE_TYPE
VOID CopyEndpointFieldsFromDescriptor(__in PWDF_USB_PIPE_INFORMATION PipeInfo, __in PUSB_ENDPOINT_DESCRIPTOR EndpointDesc, __in UCHAR SettingIndex)
VOID FormatSelectSettingUrb(__in_bcount(GET_SELECT_INTERFACE_REQUEST_SIZE(NumEndpoints)) PURB Urb, __in USHORT NumEndpoints, __in UCHAR SettingNumber)
UCHAR KIRQL
Definition: env_spec_w32.h:591
Definition: umusb.h:173
FxRequest * request
_In_ WDFUSBINTERFACE _In_ UCHAR PipeIndex
Definition: wdfusb.h:2538
#define __out_opt
Definition: dbghelp.h:65
UCHAR m_NumberOfConfiguredPipes
#define FALSE
Definition: types.h:117
VOID SetInfo(__in PUSBD_INTERFACE_INFORMATION Interface)
unsigned char BOOLEAN
#define USB_INTERFACE_DESCRIPTOR_TYPE
Definition: usb100.h:52
FxUsbInterface(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals, _In_ FxUsbDevice *UsbDevice, _In_ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor)
ULONG DetermineDefaultMaxTransferSize(VOID)
VOID GetInformation(__out PWDF_USB_PIPE_INFORMATION PipeInformation)
VOID GetEndpointInformation(__in UCHAR SettingIndex, __in UCHAR PipeIndex, __in PWDF_USB_PIPE_INFORMATION PipeInfo)
struct _USB_ENDPOINT_DESCRIPTOR * PUSB_ENDPOINT_DESCRIPTOR
int options
Definition: main.c:106
_Must_inspect_result_ NTSTATUS SelectSetting(__in PWDF_OBJECT_ATTRIBUTES PipesAttributes, __in PURB Urb)
PUSB_INTERFACE_DESCRIPTOR GetSettingDescriptor(__in UCHAR Setting)
#define UMURB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE
Definition: umusb.h:40
VOID CleanUpAndDelete(__in BOOLEAN ClearDestroyCallback)
GLsizeiptr size
Definition: glext.h:5919
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
WDFUSBPIPE GetHandle(VOID)
Definition: fxusbpipe.hpp:504
struct _USB_COMMON_DESCRIPTOR * PUSB_COMMON_DESCRIPTOR
UCHAR GetNumEndpoints(__in UCHAR SettingIndex)
PUSB_CONFIGURATION_DESCRIPTOR m_ConfigDescriptor
_Must_inspect_result_ _In_ WDFDEVICE _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFUSBDEVICE * UsbDevice
Definition: wdfusb.h:901
#define GET_USBD_INTERFACE_SIZE(numEndpoints)
Definition: usbdlib.h:121
WDFUSBINTERFACE GetHandle(VOID)
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID CleanupInterfacePipesAndDelete(__in FxUsbInterface *UsbInterface)
_Must_inspect_result_ _In_ WDFUSBINTERFACE _In_opt_ PWDF_OBJECT_ATTRIBUTES PipesAttributes
Definition: wdfusb.h:2388
_In_ WDFUSBPIPE Pipe
Definition: wdfusb.h:1741
#define USB_ENDPOINT_DESCRIPTOR_TYPE
Definition: usb100.h:53
uint32_t entry
Definition: isohybrid.c:63
UCHAR GetConfiguredSettingIndex(VOID)
VOID MarkNoDeleteDDI(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1118
VOID RemoveDeletedInterface(__in FxUsbInterface *Interface)
Definition: typedefs.h:119
#define _Must_inspect_result_
Definition: ms_sal.h:558
_In_ WDFUSBINTERFACE _In_ UCHAR _Out_opt_ PWDF_USB_PIPE_INFORMATION PipeInfo
Definition: wdfusb.h:2538
struct _UMURB_INTERFACE_INFORMATION UmUrbInterfaceInformation
Definition: umusb.h:241
_Must_inspect_result_ NTSTATUS Init(__in CfxDeviceBase *Device)
struct _URB * PURB
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
FORCEINLINE LONGLONG WDF_REL_TIMEOUT_IN_SEC(_In_ ULONGLONG Time)
Definition: wdfcore.h:62
NTSTATUS MakeAndConfigurePipes(__in PWDF_OBJECT_ATTRIBUTES PipesAttributes, __in UCHAR NumPipes)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
BOOLEAN IsInterfaceConfigured(VOID)
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
VOID RemoveDeletedPipe(__in FxUsbPipe *Pipe)
unsigned short USHORT
Definition: pedump.c:61
SINGLE_LIST_ENTRY * pCur
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
struct _USBD_PIPE_INFORMATION USBD_PIPE_INFORMATION
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
_Must_inspect_result_ NTSTATUS CreateSettings(VOID)
Definition: tftpd.h:85
#define UsbBuildSelectInterfaceRequest(urb, length, configurationHandle, interfaceNumber, alternateSetting)
Definition: usbdlib.h:59
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
USBD_CONFIGURATION_HANDLE m_ConfigHandle
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
struct _UMURB_SELECT_INTERFACE UmUrbSelectInterface
Definition: umusb.h:178
NTSTATUS FxUsbValidateDescriptorType(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor, __in PVOID Start, __in PVOID End, __in LONG DescriptorType, __in size_t SizeToValidate, __in FxUsbValidateDescriptorOp Op, __in ULONG MaximumNumDescriptorsToValidate)
Definition: usbutil.cpp:207
#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
NTSTATUS CheckAndSelectSettingByIndex(__in UCHAR SettingIndex)
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
#define __in
Definition: dbghelp.h:35
static SERVICE_STATUS status
Definition: service.c:31
_In_ WDFUSBINTERFACE _In_ UCHAR _In_ UCHAR EndpointIndex
Definition: wdfusb.h:2422
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
FxVerifierDbgBreakPoint(pFxDriverGlobals)
static WDF_USB_PIPE_TYPE _UsbdPipeTypeToWdf(__in USBD_PIPE_TYPE UsbdPipeType)
Definition: fxusbpipe.hpp:643
_In_ WDFUSBINTERFACE _In_ UCHAR SettingIndex
Definition: wdfusb.h:2300
VOID InitPipe(__in PUSBD_PIPE_INFORMATION PipeInfo, __in UCHAR InterfaceNumber, __in FxUsbInterface *UsbInterface)
Definition: fxusbpipe.cpp:1073
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