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