ReactOS 0.4.16-dev-338-g34e76ad
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#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
79VOID
81 __in BOOLEAN Failure
82 )
83/*++
84
85Routine Description:
86 Deletes the pipes contained on the interface.
87
88Arguments:
89 Failure - if TRUE, the pipes were never exposed to the client, so any attributes
90 are cleared before deletion (via DeleteFromFailedCreate)
91
92Assumes:
93 FxUsbDevice::InterfaceIterationLock is held by the caller
94
95Return 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
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
145VOID
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
164VOID
167 )
168/*++
169
170Routine Description:
171 Captures the alternate from the interface information into this structure
172 and then assigns info to all the created pipes.
173
174Arguments:
175 InterfaceInfo - info to capture
176
177Return 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
198 VOID
199 )
200/*++
201
202Routine 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
207Arguments:
208 None
209
210Return 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) {
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,
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
375 )
376/*++
377
378Routine Description:
379 Setlects a setting by alternate setting index.
380
381Arguments:
382 PipesAttributes - optional attributes to apply to each of the created pipes
383
384 SettingIndex - alternate setting index to use
385
386Return 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 //
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;
453 urb.UmUrbSelectInterface.Hdr.Function = UMURB_FUNCTION_SELECT_INTERFACE;
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;
464 urb.UmUrbInterfaceInformation.Hdr.Function = UMURB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE;
465 urb.UmUrbInterfaceInformation.Hdr.Length = sizeof(_UMURB_INTERFACE_INFORMATION);
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
491 )
492/*++
493
494Routine Description:
495 Selects an alternate setting by using a USB interface descriptor
496
497Arguments:
498 PipesAttributes - optional attributes to apply to each of the created pipes
499
500Return 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
557 )
558/*++
559
560Routine Description:
561 Checks if the give SettingIndex is the current alternate setting
562 and if not, selects that setting
563
564Arguments:
565 SettingIndex - Alternate setting
566
567Return Value:
568 NTSTATUS
569
570 --*/
571{
575 }
576 else {
577 return STATUS_SUCCESS;
578 }
579}
580
585 __in PURB Urb
586 )
587/*++
588
589Routine 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
596Arguments:
597 PipesAttributes - optional attributes to apply to all created pipes
598
599 Urb - Urb to send to the device
600
601Return 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) /
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
764Done:
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
783VOID
786 __in USHORT NumEndpoints,
787 __in UCHAR SettingNumber
788 )
789/*++
790
791Routine 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
799Arguments:
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
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
852VOID
857 )
858/*++
859
860Routine 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
865Arguments:
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
872Return 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 //
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,
935 break;
936 }
937
938 curEndpointIndex++;
939 }
940
941 //
942 // Advance past this descriptor
943 //
944 pCur += pCommonDesc->bLength;
945 }
946}
947
948ULONG
950 VOID
951 )
952/*++
953
954Routine Description:
955 Returns the maximum transfer size of an endpoint
956
957Arguments:
958 None
959
960Return Value:
961 max transfer size
962
963 --*/
964{
967 }
968 else {
970 }
971}
972
973VOID
976 __in PUSB_ENDPOINT_DESCRIPTOR EndpointDesc,
978 )
979/*++
980
981Routine Description:
982 Copy informatoin out of the usb endpoint descriptor into this object
983
984Arguments:
985 PipeInfo - information to return
986
987 EndpointDesc - descriptor to copy from
988
989 SettingIndex - alternate setting this information is for
990
991Return 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
1020WDFUSBPIPE
1024 )
1025/*++
1026
1027Routine Description:
1028 Return the WDFUSBPIPE for the given index
1029
1030Arguments:
1031 PipeIndex - index into the number of configured pipes for the interface
1032
1033 PipeInfo - optional information to return about the returned pipe
1034
1035Return 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
1052VOID
1054 __in PUSB_INTERFACE_DESCRIPTOR UsbInterfaceDescriptor,
1056 )
1057/*++
1058
1059Routine Description:
1060 Copies the descriptor back to the caller
1061
1062Arguments:
1063 UsbInterfaceDescriptor - descriptor pointer to fill in
1064
1065 SettingIndex - alternate setting that the caller is interested in
1066
1067Return Value:
1068 None
1069
1070 --*/
1071{
1072 if (SettingIndex >= m_NumSettings) {
1073 RtlZeroMemory(UsbInterfaceDescriptor,
1074 sizeof(*UsbInterfaceDescriptor));
1075 }
1076 else {
1077 RtlCopyMemory(UsbInterfaceDescriptor,
1079 sizeof(*UsbInterfaceDescriptor));
1080 }
1081}
1082
1083UCHAR
1085 VOID
1086 )
1087/*++
1088
1089Routine Description:
1090 Returns the currently configured setting index for the interface
1091
1092Arguments:
1093 None
1094
1095Return 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
1116UCHAR
1119 )
1120/*++
1121
1122Routine Description:
1123 Returns the number of endpoints on a given alternate interface
1124
1125Arguments:
1126 SettingIndex - index of the alternate setting
1127
1128Return 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
1147Routine Description:
1148 Returns the device's interface descriptor for the given alternate setting
1149
1150Arguments:
1151 Setting - AlternateSetting desired
1152
1153Return 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
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:1073
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
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
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
PUSB_COMMON_DESCRIPTOR FxUsbFindDescriptorType(__in PVOID Buffer, __in size_t BufferLength, __in PVOID Start, __in LONG DescriptorType)
Definition: usbutil.cpp:174
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
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
@ 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