ReactOS 0.4.16-dev-197-g92996da
fxusbdevice.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxUsbDevice.cpp
8
9Abstract:
10
11Author:
12
13Environment:
14
15 kernel mode only
16
17Revision History:
18
19--*/
20
21extern "C" {
22#include <initguid.h>
23}
24
25#include "fxusbpch.hpp"
26
27
28extern "C" {
29#include "FxUsbDevice.tmh"
30}
31
32#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
33#define UCHAR_MAX (0xff)
34#endif
35
37 __in FX_URB_TYPE FxUrbType
38 ) :
40{
44
45 if (FxUrbType == FxUrbTypeLegacy) {
47 }
48 else {
49 m_Urb = NULL;
50 }
51}
52
54 VOID
55 )
56{
57 if (m_Urb && (m_Urb != &m_UrbLegacy)) {
59 }
60 m_Urb = NULL;
62}
63
67 __in USBD_HANDLE USBDHandle
68 )
69{
71
72 ASSERT(USBDHandle != NULL);
73 ASSERT(m_Urb == NULL);
74
75 status = USBD_UrbAllocate(USBDHandle, (PURB*)&m_Urb);
76
77 if (!NT_SUCCESS(status)) {
78 goto Done;
79 }
80
81 m_USBDHandle = USBDHandle;
82
83Done:
84 return status;
85}
86
87VOID
89 VOID
90 )
91{
92 if (m_Urb && (m_Urb != &m_UrbLegacy)){
94 m_Urb = NULL;
96 }
97}
98
99VOID
102 )
103{
104#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
107#elif (FX_CORE_MODE == FX_CORE_USER_MODE)
110#endif
112}
113
114VOID
117 )
118{
119 //
120 // Check now because Init will NULL out the field
121 //
122 if (m_PartialMdl != NULL) {
123 if (m_UnlockPages) {
126 }
127
128#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
129 FxMdlFree(Request->GetDriverGlobals(), m_PartialMdl);
130#endif
132 }
133
135}
136
139 VOID
140 )
141{
142 return m_Urb->Hdr.Status;
143}
144
146 __in FX_URB_TYPE FxUrbType
147 ) :
149{
154
155 if (FxUrbType == FxUrbTypeLegacy) {
158 m_Urb->Hdr.Length = sizeof(*m_Urb);
160 }
161 else {
162 m_Urb = NULL;
163 }
164}
165
167 VOID
168 )
169{
170 if (m_StringDescriptor != NULL) {
173 }
174
175 if (m_Urb && (m_Urb != &m_UrbLegacy)){
177 }
178 m_Urb = NULL;
180}
181
185 __in USBD_HANDLE USBDHandle
186 )
187{
189
190 ASSERT(USBDHandle != NULL);
191 ASSERT(m_Urb == NULL);
192
193 status = USBD_UrbAllocate(USBDHandle, (PURB*)&m_Urb);
194
195 if (!NT_SUCCESS(status)) {
196 goto Done;
197 }
198
199 m_USBDHandle = USBDHandle;
200
202 m_Urb->Hdr.Length = sizeof(*m_Urb);
204
205Done:
206 return status;
207}
208
209VOID
211 VOID
212 )
213{
214 if (m_Urb && (m_Urb != &m_UrbLegacy)){
216 m_Urb = NULL;
218 }
219
220}
221
222VOID
225 )
226{
227 //
228 // Make sure we got an even number of bytes and that we got a header
229 //
230 if ((m_StringDescriptor->bLength & 0x1) ||
233 }
234 else if (NT_SUCCESS(Request->GetSubmitFxIrp()->GetStatus())) {
235 //
236 // No matter what, indicate the required size to the caller
237 //
240
241 if (m_UsbParameters.Parameters.DeviceString.RequiredSize >
243 //
244 // Too much string to fit into the buffer supplied by the client.
245 // Morph the status into a warning. Copy as much as we can.
246 //
251 }
252 else {
253 //
254 // Everything fits, copy it over
255 //
258
262 }
263 }
264
266}
267
268VOID
272 )
273{
275
277
278#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
281
284#elif (FX_CORE_MODE == FX_CORE_USER_MODE)
287
290#endif
291}
292
295 VOID
296 )
297{
298 return m_Urb->Hdr.Status;
299}
300
304 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
305 __in size_t BufferSize
306 )
307{
308 PUSB_STRING_DESCRIPTOR pDescriptor;
309 size_t length;
311
313 return STATUS_SUCCESS;
314 }
315
316 length = sizeof(USB_STRING_DESCRIPTOR) - sizeof(pDescriptor->bString[0]) +
318
319 pDescriptor = (PUSB_STRING_DESCRIPTOR) FxPoolAllocate(
320 FxDriverGlobals,
322 length);
323
324 if (pDescriptor == NULL) {
326 }
327
328 if (m_StringDescriptor != NULL) {
330 }
331
332 RtlZeroMemory(pDescriptor, length);
333
334 m_StringDescriptor = pDescriptor;
335
337
338 return status;
339}
340
342 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
343 __in USBD_HANDLE USBDHandle,
345 __in size_t BufferSize
346 ) :
347 FxMemoryBufferPreallocated(FxDriverGlobals, sizeof(*this), Buffer, BufferSize),
348 m_USBDHandle(USBDHandle)
349{
351}
352
354{
355}
356
359 VOID
360 )
361{
365 m_pBuffer = NULL;
367
368 return FxMemoryBufferPreallocated::Dispose(); // __super call
369}
370
372 __in PFX_DRIVER_GLOBALS FxDriverGlobals
373 ) :
375{
378
379 m_OnUSBD = FALSE;
381 m_NumInterfaces = 0;
382
383 m_Traits = 0;
391
393
396
397#if (FX_CORE_MODE == FX_CORE_USER_MODE)
400#endif
401
403}
404
407 VOID
408 )
409{
410#if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
411 KeFlushQueuedDpcs();
412#endif
413
414 if (m_USBDHandle) {
417 }
418
419#if (FX_CORE_MODE == FX_CORE_USER_MODE)
420 IWudfDevice* device = NULL;
421 IWudfDeviceStack* devstack = NULL;
422
424 devstack = device->GetDeviceStackInterface();
425
426 if (m_pHostTargetFile) {
427 devstack->CloseFile(m_pHostTargetFile);
429 }
430#endif
431
432 return FxIoTarget::Dispose(); // __super call
433}
434
436{
437 UCHAR i;
438
442 }
443
444 if (m_ConfigDescriptor != NULL) {
447 }
448
449 for (i = 0; i < m_NumInterfaces; i++) {
451 }
452
453 if (m_Interfaces != NULL){
456 }
457
458 m_NumInterfaces = 0;
459}
460
461VOID
464 )
465{
466 UCHAR i;
467
468 if (m_Interfaces == NULL) {
469 return;
470 }
471
472 for (i = 0; i < m_NumInterfaces; i++) {
473 if (m_Interfaces[i] == Interface) {
475 return;
476 }
477 }
478}
479
480VOID
483 )
484{
485 Information->Traits = m_Traits;
486 Information->HcdPortCapabilities = m_HcdPortCapabilities;
487
488 RtlCopyMemory(&Information->UsbdVersionInformation,
491}
492
493ULONG
495 VOID
496 )
497/*++
498
499Routine Description:
500 Determines the default max transfer size based on the usb host controller
501 and OS we are running on. What it boils down to is that on XP and later
502 the usb core ignores the default max transfer size, but it does use the
503 value on Windows 2000. To make life fun, there is only one definition of
504 USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE whose value changes depending on header
505 versioning. Since we are versioned for the latest OS, we do not pick up the
506 Win2k value by using the #define, rather we have to use the value that we
507 *would* have picked up if we were header versioned for Win2k.
508
509 NOTE: we could be on win2k with a usbport serviced stack. in this case,
510 usbport doesn't care about max transfer sizes
511
512Arguments:
513 None
514
515Return Value:
516 usb core and OS appropriate default max transfer size.
517
518 --*/
519{
520 //
521 // On a usbport serviced stack (which can be running on Win2k) or on a
522 // usbd stack on XP and later. In any case, always use the current max
523 // transfer size definition.
524 //
526}
527
531 VOID
532 )
533{
535
537
538 if (NT_SUCCESS(status)) {
541 ULONG i, iInterface;
543 KIRQL irql;
544
546
547 Lock(&irql);
548
549 //
550 // Iterate over all of the interfaces. For each pipe on each interface,
551 // grab all pended i/o for later submission.
552 //
553 for (iInterface = 0; iInterface < m_NumInterfaces; iInterface++){
554
555 pUsbInterface = m_Interfaces[iInterface];
556
557 for (i = 0; i < pUsbInterface->m_NumberOfConfiguredPipes; i++) {
559 }
560 }
561 Unlock(irql);
562
563 //
564 // Since we are going to reference the FxUsbPipe's outside of the
565 // lock and the interface can go away in the meantime, add a reference
566 // (multiple times perhaps) to each FxUsbPipe to make sure it sticks
567 // around.
568 //
569 for (ple = head.Flink; ple != &head; ple = ple->Flink) {
571 pRequest->GetTarget()->ADDREF(this);
572 }
573
574 //
575 // Drain the list of pended requests.
576 //
577 while (!IsListEmpty(&head)) {
579
581
583
585
587
588 //
589 // Release the reference taken above when accumulating pended i/o.
590 //
591 pTarget->RELEASE(this);
592 }
593 }
594
595 return status;
596}
597
598#define STOP_TAG (PVOID) 'pots'
599
600VOID
603 )
604{
607 ULONG iPipe, iInterface;
608 KIRQL irql;
609
610 head.Next = NULL;
611
612 //
613 // Stop all of our own I/O first
614 //
616
617 //
618 // if we are just canceling i/o, then we just acquire the spin lock b/c
619 // we can be called at dispatch level for this action code.
620 //
623
624 AcquireInterfaceIterationLock();
625 }
626
627 //
628 // Since we don't have to synchronize on the I/O already sent, just set
629 // each pipe's state to stop.
630 //
631 Lock(&irql);
632
633 for (iInterface = 0; iInterface < m_NumInterfaces; iInterface++) {
634 pUsbInterface = m_Interfaces[iInterface];
635
637 for (iPipe = 0;
639 iPipe++) {
640
641 if (pUsbInterface->m_ConfiguredPipes[iPipe] != NULL) {
642 BOOLEAN wait;
643
644 wait = FALSE;
645
647 Action,
648 &head,
649 &wait,
650 TRUE
651 );
652 }
653 }
654 }
655 }
656 Unlock(irql);
657
658 //
659 // If we are leaving sent IO pending, the io target will set the IO
660 // completion event during stop even if there is still outstanding IO.
661 //
662
663 if (head.Next != NULL) {
665 }
666
667 for (iInterface = 0; iInterface < m_NumInterfaces; iInterface++) {
668 pUsbInterface = m_Interfaces[iInterface];
669
671 //
672 // Iterate over the pipes and clean each one up
673 //
674 for (iPipe = 0;
676 iPipe++) {
677 //
678 // Same reason as above
679 //
680 if (pUsbInterface->m_ConfiguredPipes[iPipe] != NULL) {
683 }
684 }
685 }
686 }
687
689 ReleaseInterfaceIterationLock();
690 }
691}
692
693VOID
696 )
697{
699 SINGLE_LIST_ENTRY sentHead;
700 ULONG iPipe, iInterface;
701 KIRQL irql;
702
703 sentHead.Next = NULL;
704
705 //
706 // Purge all of our own I/O first
707 //
709
710 //
711 // if we are just canceling i/o, then we just acquire the spin lock b/c
712 // we can be called at dispatch level for this action code.
713 //
714 if (Action != WdfIoTargetPurgeIo) {
716
717 AcquireInterfaceIterationLock();
718 }
719
720 //
721 // Since we don't have to synchronize on the I/O already sent, just set
722 // each pipe's state to purged.
723 //
724 Lock(&irql);
725
726 for (iInterface = 0; iInterface < m_NumInterfaces; iInterface++) {
727 pUsbInterface = m_Interfaces[iInterface];
728
730 for (iPipe = 0;
732 iPipe++) {
733
734 if (pUsbInterface->m_ConfiguredPipes[iPipe] != NULL) {
735 BOOLEAN wait;
736 LIST_ENTRY pendedHead;
737
738 wait = FALSE;
739 InitializeListHead(&pendedHead);
740
742 Action,
743 &pendedHead,
744 &sentHead,
745 &wait,
746 TRUE
747 );
748
749 //
750 // Complete any requests pulled off from this pipe.
751 //
753 CompletePendedRequestList(&pendedHead);
754 }
755 }
756 }
757 }
758 Unlock(irql);
759
760 //
761 // Cancel all sent requests.
762 //
763 _CancelSentRequests(&sentHead);
764
765 for (iInterface = 0; iInterface < m_NumInterfaces; iInterface++) {
766 pUsbInterface = m_Interfaces[iInterface];
767
769 //
770 // Iterate over the pipes and clean each one up
771 //
772 for (iPipe = 0;
774 iPipe++) {
775 //
776 // Same reason as above
777 //
778 if (pUsbInterface->m_ConfiguredPipes[iPipe] != NULL) {
781 }
782 }
783 }
784 }
785
786 if (Action != WdfIoTargetPurgeIo) {
787 ReleaseInterfaceIterationLock();
788 }
789}
790
791VOID
793 __in PLIST_ENTRY PendHead,
794 __in PSINGLE_LIST_ENTRY SentHead
795 )
796{
797 while (!IsListEmpty(PendHead)) {
800
801 ple = RemoveHeadList(PendHead);
802
804
807 }
808
809 _CancelSentRequests(SentHead);
810}
811
812VOID
814 __in BOOLEAN ForceRemovePipes
815 )
816{
817 SINGLE_LIST_ENTRY sentHead;
818 LIST_ENTRY pendHead, interfaceHead;
820 ULONG iPipe, intfIndex;
821 KIRQL irql;
822
823 sentHead.Next = NULL;
824 InitializeListHead(&pendHead);
825 InitializeListHead(&interfaceHead);
826
827 AcquireInterfaceIterationLock();
828
829 Lock(&irql);
830 for (intfIndex = 0; intfIndex < m_NumInterfaces; intfIndex++ ) {
831 pUsbInterface = m_Interfaces[intfIndex];
832
834 for (iPipe = 0;
836 iPipe++) {
837 BOOLEAN wait;
838
839 wait = FALSE;
840
841 //
842 // Pipe can be NULL if the interface is half initialized
843 //
844 if (pUsbInterface->m_ConfiguredPipes[iPipe] != NULL) {
847 &pendHead,
848 &sentHead,
849 TRUE,
850 &wait);
851
852 }
853 }
854 }
855 }
856 Unlock(irql);
857
858 //
859 // We cleanup requests no matter what the new state is because we complete all
860 // pended requests in the surprise removed case.
861 //
862 _CleanupPipesRequests(&pendHead, &sentHead);
863
864 //
865 // Only destroy child pipe objects when the parent is going away or the
866 // caller indicates that this is the desired action.
867 //
868 if (m_State == WdfIoTargetDeleted || ForceRemovePipes) {
869 for (intfIndex = 0; intfIndex < m_NumInterfaces; intfIndex++) {
870 pUsbInterface = m_Interfaces[intfIndex];
871
873 //
874 // Iterate over the pipes and clean each one up
875 //
876 for (iPipe = 0;
878 iPipe++) {
879 //
880 // Same reason as above
881 //
882 if (pUsbInterface->m_ConfiguredPipes[iPipe] != NULL) {
885 }
886 }
887 }
888
890 }
891 }
892
893 ReleaseInterfaceIterationLock();
894}
895
899 VOID
900 )
901{
903 UCHAR descCountBitMap[UCHAR_MAX / sizeof(UCHAR)];
904 PUSB_INTERFACE_DESCRIPTOR pInterfaceDescriptor;
905 UCHAR iInterface, numFound;
907 ULONG size;
908 ULONG totalLength;
909
912 totalLength = m_ConfigDescriptor->wTotalLength;
913
914 //
915 // Make sure each PCOMMON_DESCRIPTOR_HEADER within the entire config descriptor is well formed.
916 // If successful, we can walk the config descriptor using common headers without any more top
917 // level error checking. Task specific checking of the specialized header types must still occur.
918 //
923 );
924
925 if (!NT_SUCCESS(status)) {
928 "Validation of the config descriptor failed due to a bad common descriptor header, %!STATUS!",
929 status);
930 return status;
931 }
932
933 //
934 // Validate all interface descriptors in config descriptor are at least
935 // sizeof(USB_INTERFACE_DESCRIPTOR).
936 //
937
938
939
940
941
950 0
951 );
952
953 if (!NT_SUCCESS(status)) {
956 "Validation of interface descriptors in config descriptor failed, %!STATUS!",
957 status);
958
959 return status;
960 }
961
963 //
964 // Use an array of one in the zero case
965 //
966 size = sizeof(FxUsbInterface*);
967 }
968 else {
970 }
971
972 //
973 // Allocate an array large enough to hold pointers to interfaces
974 //
976 FxPoolAllocate(pFxDriverGlobals, NonPagedPool, size);
977
978 if (m_Interfaces == NULL) {
980
983 "Could not allocate memory for %d interfaces, %!STATUS!",
985
986 goto Done;
987 }
988
991
992 //
993 // Iterate over the desciptors again, this time allocating an FxUsbInterface
994 // for each one and capturing the interface information.
995 //
996 RtlZeroMemory(descCountBitMap, sizeof(descCountBitMap));
997 iInterface = 0;
998 numFound = 0;
999
1000 pInterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR) FxUsbFindDescriptorType(
1005 );
1006
1007 while (pInterfaceDescriptor != NULL &&
1008 iInterface < m_ConfigDescriptor->bNumInterfaces) {
1009
1010 //
1011 // This function will retun false if the bit wasn't already set
1012 //
1013 if (FxBitArraySet(descCountBitMap,
1014 pInterfaceDescriptor->bInterfaceNumber) == FALSE) {
1016
1019 this,
1020 pInterfaceDescriptor);
1021
1022 if (pInterface == NULL) {
1026 "Could not allocate memory for interface object #%d, %!STATUS!",
1027 iInterface, status);
1028 goto Done;
1029 }
1030
1032
1033 //
1034 // This should never fail
1035 //
1037
1038 if (!NT_SUCCESS(status)) {
1039 goto Done;
1040 }
1041
1042 status = pInterface->CreateSettings();
1043 if (!NT_SUCCESS(status)) {
1044 goto Done;
1045 }
1046
1047#if (FX_CORE_MODE == FX_CORE_USER_MODE)
1048 status = pInterface->SetWinUsbHandle(iInterface);
1049 if (!NT_SUCCESS(status)) {
1050 goto Done;
1051 }
1052
1053 status = pInterface->MakeAndConfigurePipes(WDF_NO_OBJECT_ATTRIBUTES,
1054 pInterfaceDescriptor->bNumEndpoints);
1055 if (!NT_SUCCESS(status)) {
1056 goto Done;
1057 }
1058#endif
1059
1060 m_Interfaces[iInterface] = pInterface;
1061
1062 iInterface++;
1063 }
1064
1065 pInterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR) FxUsbFindDescriptorType(
1067 totalLength,
1068 WDF_PTR_ADD_OFFSET(pInterfaceDescriptor,
1069 pInterfaceDescriptor->bLength),
1071 );
1072 }
1073
1074 //
1075 // We cannot check for the error case of
1076 //
1077 // pInterfaceDescriptor != NULL &&
1078 // iInterface == m_ConfigDescriptor->bNumInterfaces
1079 //
1080 // Because if there are multiple alternative settings for the last interface
1081 // in the config descriptor, we will have hit the limit of interfaces
1082 // (correctly), but have found another pInterfaceDescriptor (the next alt
1083 // setting).
1084 //
1085
1086 //
1087 // We already logged and found the case where iInterface >= m_NumInterfaces.
1088 // Check for the case where we found too few interfaces and when we found
1089 // no interfaces even though the config descriptor says otherwise.
1090 //
1091 //
1092 if (iInterface == 0 && m_NumInterfaces > 0) {
1094
1097 "Config descriptor indicated there were %d interfaces, but did not "
1098 "find any interface descriptors in config descriptor %p, %!STATUS!",
1100 }
1101 else if (pInterfaceDescriptor != NULL && m_NumInterfaces == 0) {
1104 "Config descriptor indicated there were 0 interfaces, but an interface "
1105 "descriptor was found");
1106
1108 }
1109 else if (iInterface < m_NumInterfaces) {
1112 "Config descriptor indicated there were %d interfaces, only found "
1113 "%d interfaces", m_NumInterfaces, iInterface);
1114
1115 //
1116 // Instead of considering this an error, just use the number found.
1117 // This will not have an adverse affect elsewhere and since the framework
1118 // is probably more strict then previous USB code, this would have not
1119 // been found earlier by a WDM driver.
1120 //
1121 m_NumInterfaces = iInterface;
1122 }
1123
1124Done:
1125 return status;
1126}
1127
1128
1133 )
1134{
1136
1139 FxSyncRequest syncRequest(GetDriverGlobals(), &context);
1140
1141 //
1142 // FxSyncRequest always succeesds for KM.
1143 //
1144 status = syncRequest.Initialize();
1145 if (!NT_SUCCESS(status)) {
1147 "Failed to initialize FxSyncRequest");
1148 return status;
1149 }
1150
1151 *PortStatus = 0;
1152 args[0].SetBuffer(PortStatus, 0);
1153 args[1].SetBuffer(NULL, 0);
1154 args[2].SetBuffer(NULL, 0);
1155
1156 status = FormatInternalIoctlOthersRequest(syncRequest.m_TrueRequest,
1158 args);
1159
1160 if (NT_SUCCESS(status)) {
1162
1165
1166 status = SubmitSync(syncRequest.m_TrueRequest, &options);
1167 }
1168
1169 return status;
1170}
1171
1172
1173
1174BOOLEAN
1176 VOID
1177 )
1178{
1180 ULONG portStatus;
1182
1183 enabled = TRUE;
1184 status = GetPortStatus(&portStatus);
1185
1186 //
1187 // Inability to get STATUS_SUCCESS from GetPortStatus is more likely a resource
1188 // issue rather than a device issue so return FALSE from this function only if
1189 // we were able to read the PortStatus and the port was disabled.
1190 // What you don't want is to continuosly reset the device (by returning FALSE)
1191 // instead of resetting pipe (by returning TRUE) under low memory conditions.
1192 //
1193 if (NT_SUCCESS(status) && (portStatus & USBD_PORT_ENABLED) == 0) {
1194 enabled = FALSE;
1195 }
1196
1197 return enabled;
1198}
1199
1203 VOID
1204 )
1205{
1206#if (FX_CORE_MODE == FX_CORE_USER_MODE)
1207
1208
1209
1210
1211 return STATUS_UNSUCCESSFUL;
1212#elif (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
1214 ULONG portStatus;
1215
1216 status = GetPortStatus(&portStatus);
1217 if (NT_SUCCESS(status) && (portStatus & USBD_PORT_CONNECTED) == 0) {
1219 }
1220
1221 return status;
1222#endif
1223}
1224
1228 VOID
1229 )
1230{
1232 FxSyncRequest request(GetDriverGlobals(), &context);
1234
1235 //
1236 // FxSyncRequest always succeesds for KM.
1237 //
1238 status = request.Initialize();
1239 if (!NT_SUCCESS(status)) {
1241 "Failed to initialize FxSyncRequest");
1242 return status;
1243 }
1244
1245 status = FormatCycleRequest(request.m_TrueRequest);
1246
1247 if (NT_SUCCESS(status)) {
1248 CancelSentIo();
1250 //
1251 // NOTE: CyclePort causes the device to be removed and re-enumerated so
1252 // don't do anymore operations after this point.
1253 //
1254 }
1255
1256 return status;
1257}
1258
1263 )
1264{
1265 FxRequestBuffer emptyBuffer;
1266
1269 TRUE,
1270 &emptyBuffer,
1271 &emptyBuffer);
1272}
1273
1279 )
1280{
1282 USHORT copyLength;
1283
1284 if (ConfigDescriptor == NULL) {
1285 //
1286 // Caller wants length to allocate
1287 //
1290 }
1291
1292 if (*ConfigDescriptorLength < m_ConfigDescriptor->wTotalLength) {
1293 //
1294 // Valid ConfigDescriptor passed in, but its too small. Copy as many
1295 // bytes as we can.
1296 //
1297 copyLength = *ConfigDescriptorLength;
1299 }
1300 else {
1301 copyLength = m_ConfigDescriptor->wTotalLength;
1303 }
1304
1305 //
1306 // Always indicate to the caller the number of required bytes or the
1307 // number of bytes we copied.
1308 //
1311
1312 return status;
1313}
1314
1320 )
1321{
1322 PUSBD_INTERFACE_LIST_ENTRY pInterfaces;
1323 PURB urb;
1325 ULONG i, size;
1326 PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor;
1327 PUSB_INTERFACE_DESCRIPTOR* interfaceDescriptors;
1328 ULONG numInterfaces;
1330
1332
1333 configurationDescriptor = Params->Types.Descriptor.ConfigurationDescriptor;
1334 interfaceDescriptors = Params->Types.Descriptor.InterfaceDescriptors;
1335 numInterfaces = Params->Types.Descriptor.NumInterfaceDescriptors;
1336
1337 for (i = 0; i < numInterfaces; i++) {
1338 if (interfaceDescriptors[i] == NULL) {
1340 }
1341 }
1342
1343 //
1344 // eventually size = sizeof(USBD_INTERFACE_LIST_ENTRY) * (numInterfaces + 1)
1345 //
1346 status = RtlULongAdd(numInterfaces, 1, &size);
1347 if (!NT_SUCCESS(status)) {
1348 return status;
1349 }
1350
1351 status = RtlULongMult(size, sizeof(USBD_INTERFACE_LIST_ENTRY), &size);
1352 if (!NT_SUCCESS(status)) {
1353 return status;
1354 }
1355
1356 pInterfaces = (PUSBD_INTERFACE_LIST_ENTRY) FxPoolAllocate(
1358
1359 if (pInterfaces == NULL) {
1361
1364 "Could not allocate array of USBD_INTERFACE_LIST_ENTRY, %!STATUS!",
1365 status);
1366
1367 return status;
1368 }
1369
1370 RtlZeroMemory(pInterfaces, size);
1371
1372 for (i = 0; i < numInterfaces; i++) {
1373 pInterfaces[i].InterfaceDescriptor = interfaceDescriptors[i];
1374 }
1375
1376 if (configurationDescriptor == NULL) {
1377 configurationDescriptor = m_ConfigDescriptor;
1378 }
1379
1380 //
1381 // NOTE:
1382 //
1383 // Creating a config request using the caller's config descriptor does not
1384 // currently work if the provided config descriptor is not the same as the
1385 // descriptor reported by the device. It does not work because we try to
1386 // validate the interface number in the URB against an existing
1387 // FxUsbInterface (which is based on the config descriptor described by the
1388 // device, not the provided one), and if that validation fails, we return
1389 // !NT_SUCCESS from SelectConfig().
1390 //
1392 configurationDescriptor,
1393 pInterfaces,
1395 if (urb == NULL) {
1397 }
1398 else {
1400 FxPoolFree(urb);
1401 urb = NULL;
1402 }
1403
1404 FxPoolFree(pInterfaces);
1405 pInterfaces = NULL;
1406
1407 return status;
1408}
1409
1411 //
1412 // Array of pipes
1413 //
1415
1416 //
1417 // Number of entries in Pipes
1418 //
1420};
1421
1426 __in PURB Urb,
1427 __in FX_URB_TYPE FxUrbType,
1428 __out_opt PUCHAR NumConfiguredInterfaces
1429 )
1430/*++
1431
1432Routine Description:
1433 Selects the configuration as described by the parameter Urb. If there is a
1434 previous active configuration, the WDFUSBPIPEs for it are stopped and
1435 destroyed before the new configuration is selected
1436
1437Arguments:
1438 PipesAttributes - object attributes to apply to each created WDFUSBPIPE
1439
1440 Urb - the URB describing the configuration to select
1441
1442Return Value:
1443 NTSTATUS
1444
1445 --*/
1446{
1448 PUCHAR pCur, pEnd;
1450 FxUsbPipe* pPipe;
1451 PURB pSelectUrb;
1453 ULONG iPipe;
1454 USHORT maxNumPipes, size;
1455 UCHAR numPipes;
1456 FxInterfacePipeInformation* pPipeInfo;
1459 UCHAR intfIndex;
1460 FxIrp* irp;
1461
1463 FxSyncRequest request(GetDriverGlobals(), NULL);
1464
1465 pIface = NULL;
1466 maxNumPipes = 0;
1467 size = 0;
1468 pPipeInfo = NULL;
1469 pSelectUrb = NULL;
1470
1471 //
1472 // Callers to this function have guaranteed that there are interfaces
1473 // reported on this device.
1474 //
1475 ASSERT(m_NumInterfaces != 0);
1476
1477 if (NumConfiguredInterfaces != NULL) {
1478 *NumConfiguredInterfaces = 0;
1479 }
1480
1481 //
1482 // FxSyncRequest always succeesds for KM but can fail for UM.
1483 //
1484 status = request.Initialize();
1485 if (!NT_SUCCESS(status)) {
1487 "Failed to initialize FxSyncRequest");
1488 goto Done;
1489 }
1490
1491 //
1492 // Allocate a PIRP for the select config and possible select interface(s)
1493 //
1494 status = request.m_TrueRequest->ValidateTarget(this);
1495 if (!NT_SUCCESS(status)) {
1496 goto Done;
1497 }
1498
1499 //
1500 // Allocate a pool for storing the FxUsbPipe ** before we
1501 // assign them to the Interfaces just in case all doesn't go well.
1502 //
1503 if (m_NumInterfaces == 0) {
1504 //
1505 // Use one in the zero case to make the logic simpler
1506 //
1508 }
1509 else {
1511 }
1512
1513 pPipeInfo = (FxInterfacePipeInformation*) FxPoolAllocate(
1515 );
1516
1517 if (pPipeInfo == NULL) {
1521 "Could not internal allocate tracking info for selecting a config on "
1522 "WDFUSBDEVICE 0x%p, %!STATUS!", GetHandle(), status);
1523 goto Done;
1524 }
1525
1526 RtlZeroMemory(pPipeInfo, size);
1527
1528 //
1529 // The following code and the one in select setting have a lot in common
1530 // but can't leverage on that as that sends the select interface URB down
1531 // Our goal is allocate the resources -- the pipes and the select setting URB
1532 // before sending down the select config URB so that the tear down is simpler.
1533 //
1534
1535 //
1536 // Each FxUsbInterface will need a FxUsbPipe* for each pipe contained in
1537 // the interface.
1538 //
1539 pCur = (PUCHAR) &Urb->UrbSelectConfiguration.Interface;
1540 pEnd = ((PUCHAR) Urb) + Urb->UrbSelectConfiguration.Hdr.Length;
1541 intfIndex = 0;
1542
1543 for ( ; pCur < pEnd; pCur += pIface->Length, intfIndex++) {
1544 FxUsbPipe** ppPipes;
1545
1547 if (pIface->NumberOfPipes > UCHAR_MAX) {
1551 "WDFUSBDEVICE supports a maximum of %d pipes per interface, "
1552 "USBD_INTERFACE_INFORMATION %p specified %d, %!STATUS!",
1553 UCHAR_MAX, pIface, pIface->NumberOfPipes, status);
1554 goto Done;
1555 }
1556
1558 if (pUsbInterface == NULL) {
1562 "Could not find an instance of an interface descriptor with "
1563 "InterfaceNumber %d, %!STATUS!",
1564 pIface->InterfaceNumber, status);
1565 goto Done;
1566 }
1567
1568 numPipes = (UCHAR) pIface->NumberOfPipes;
1569
1570 //
1571 // Track the maximum number of pipes we have seen in an interface in
1572 // case we need to allocate a select interface URB.
1573 //
1574 if (numPipes > maxNumPipes) {
1575 maxNumPipes = (USHORT) numPipes;
1576 }
1577
1578 if (numPipes > 0) {
1579 size = numPipes * sizeof(FxUsbPipe *);
1580 }
1581 else {
1582 //
1583 // It is valid to have an interface with zero pipes in it. In that
1584 // case, we just allocate one entry so that we have a valid array
1585 // and keep the remaining code simple.
1586 //
1587 size = sizeof(FxUsbPipe*);
1588 }
1589
1590 ppPipes = (FxUsbPipe**) FxPoolAllocate(
1593 size
1594 );
1595
1596 if (ppPipes == NULL) {
1600 "Could not allocate memory for Pipes "
1601 "InterfaceNumber %d, %!STATUS!",
1602 pIface->InterfaceNumber, status);
1603 goto Done;
1604 }
1605
1606 RtlZeroMemory(ppPipes, size);
1607
1608 //
1609 // We store the pointer to the newly allocated arary in a temporary b/c
1610 // we can still fail and we don't want a half baked interface.
1611 //
1612
1613 pPipeInfo[intfIndex].Pipes = ppPipes;
1614 pPipeInfo[intfIndex].NumPipes = numPipes;
1615
1616 for (iPipe = 0; iPipe < numPipes; iPipe++) {
1617 ppPipes[iPipe] = new (GetDriverGlobals(), PipesAttributes)
1619
1620 if (ppPipes[iPipe] == NULL) {
1624 "Could not allocate a pipe object, %!STATUS!", status);
1625 goto Done;
1626 }
1627
1628 pPipe = ppPipes[iPipe];
1629 status = pPipe->Init(m_Device);
1630 if (!NT_SUCCESS(status)) {
1633 "Could not Init the pipe object, %!STATUS!", status);
1634 goto Done;
1635 }
1636
1638 if (!NT_SUCCESS(status)) {
1641 "Could not commit the pipe object, %!STATUS!", status);
1642 goto Done;
1643 }
1644 }
1645
1646
1647
1648
1649
1650
1651
1652
1653
1656 }
1657 }
1658
1659 //
1660 // If we are selecting more then one interface and at least one of them
1661 // has pipes in them, allocate a select interface URB that will be used
1662 // after the select config to select each interface. The select interface
1663 // URB will be big enough to select the largest interface in the group.
1664 //
1665 // The select interface URB is allocated before the select config so that
1666 // we know once the select config has completed successfully, we can be
1667 // guaranteed that we can select the interfaces we want and not have to
1668 // handle undoing the select config upon URB allocation failure.
1669 //
1670 if (m_NumInterfaces > 1 && maxNumPipes > 0) {
1672
1673 pSelectUrb = (PURB) FxPoolAllocate(GetDriverGlobals(),
1675 size
1676 );
1677
1678 if (pSelectUrb == NULL) {
1682 "Could not allocate a select interface URB, %!STATUS!", status);
1683 goto Done;
1684 }
1685
1686 RtlZeroMemory(pSelectUrb, size);
1687 }
1688
1689 //
1690 // Send the select config to the usb core
1691 //
1695
1696 FxFormatUsbRequest(request.m_TrueRequest, Urb, FxUrbType, m_USBDHandle);
1697 status = SubmitSync(request.m_TrueRequest, &options);
1698
1699 if (NT_SUCCESS(status)) {
1700 //
1701 // Save the config handle and store off all the pipes
1702 //
1703 m_ConfigHandle = Urb->UrbSelectConfiguration.ConfigurationHandle;
1704
1705 //
1706 // Initialize the first interface
1707 //
1708 pIface = &Urb->UrbSelectConfiguration.Interface;
1709
1712
1713 //
1714 // The interface now owns the array of pipes
1715 //
1716 pUsbInterface->SetConfiguredPipes(pPipeInfo[0].Pipes);
1717 pPipeInfo[0].Pipes = NULL;
1718 pPipeInfo[0].NumPipes = 0;
1719
1720 pUsbInterface->SetInfo(pIface);
1721
1722 //
1723 // Since this could be the only interface, set the index now, so if we
1724 // return the number of configured interfaces, it will be valid for the
1725 // single interface case.
1726 //
1727 intfIndex = 1;
1728
1729 //
1730 // If we have a more then one interface, we must select each of the addtional
1731 // interfaces after the select config because usbccgp (the generic parent
1732 // driver) didn't fill out all of the pipe info for IAD (interface
1733 // association descriptor) devices. The first interface is filled out
1734 // property, it is 2->N that are left blank.
1735 //
1736 // pSelectUrb can be equal to NULL and have more then one interface if
1737 // all interfaces have no pipes associated with them. In that case, we
1738 // still want to iterate over the remaining pipes so that we can
1739 // initialize our structures properly.
1740 //
1741 if (m_NumInterfaces > 1) {
1742 //
1743 // Loop over the interfaces again.
1744 //
1745 pCur = (PUCHAR) &Urb->UrbSelectConfiguration.Interface;
1747 pEnd = ((PUCHAR) Urb) + Urb->UrbSelectConfiguration.Hdr.Length;
1748
1749 //
1750 // Start at the 2nd one since the first is already selected
1751 //
1752 pCur += pIface->Length;
1753
1754 for ( ; pCur < pEnd; pCur += pIface->Length, intfIndex++) {
1755#pragma prefast(suppress: __WARNING_UNUSED_POINTER_ASSIGNMENT, "pIface is used in the for loop in many places. It looks like a false positive")
1757 ASSERT(pIface->NumberOfPipes <= maxNumPipes);
1758
1761
1762 //
1763 // Valid to have an interface with no pipes. If there are no
1764 // pipes, GET_SELECT_INTERFACE_REQUEST_SIZE will compute value
1765 // too small of a size to pass validation.
1766 //
1767 if (pIface->NumberOfPipes > 0) {
1768
1770 pSelectUrb,
1771 (USHORT) pIface->NumberOfPipes,
1772 pIface->AlternateSetting
1773 );
1774 irp = request.m_TrueRequest->GetSubmitFxIrp();
1776
1777 request.m_TrueRequest->ClearFieldsForReuse();
1778 FxFormatUsbRequest(request.m_TrueRequest,
1779 pSelectUrb,
1781 NULL);
1782
1783 status = SubmitSync(request.m_TrueRequest, &options);
1784 if (!NT_SUCCESS(status)) {
1787 "USB core failed Select Interface URB, %!STATUS!",
1788 status);
1789 goto Done;
1790 }
1791
1792 //
1793 // Copy the info back into the original select config URB
1794 //
1795
1796 RtlCopyMemory(pIface,
1797 &pSelectUrb->UrbSelectInterface.Interface,
1798 pSelectUrb->UrbSelectInterface.Interface.Length);
1799 }
1800
1801 //
1802 // Update the pointer to point to the new pipes with the pointer
1803 // to the pipes stored earlier.
1804 //
1805 ASSERT(pPipeInfo[intfIndex].NumPipes == pIface->NumberOfPipes);
1807
1808 //
1809 // The interface now owns the array of pipes
1810 //
1811 pUsbInterface->SetConfiguredPipes(pPipeInfo[intfIndex].Pipes);
1812 pPipeInfo[intfIndex].Pipes = NULL;
1813 pPipeInfo[intfIndex].NumPipes = 0;
1814
1815 //
1816 // SetInfo only after a successful select config so that we can
1817 // copy the USBD_PIPE_INFORMATION .
1818 //
1819 pUsbInterface->SetInfo(pIface);
1820 }
1821 }
1822
1823 if (NumConfiguredInterfaces != NULL) {
1824 *NumConfiguredInterfaces = intfIndex;
1825 }
1826 }
1827 else {
1830 "USB core failed Select Configuration, %!STATUS!", status);
1831 }
1832
1833Done:
1834 if (pSelectUrb != NULL) {
1835 FxPoolFree(pSelectUrb);
1836 pSelectUrb = NULL;
1837 }
1838
1839 if (pPipeInfo != NULL) {
1840 //
1841 // Free all arrays that may have been allocated
1842 //
1843 for (intfIndex = 0; intfIndex < m_NumInterfaces; intfIndex++) {
1844 //
1845 // We can have NumPipes == 0 and still have an allocated array, so
1846 // use the array != NULL as the check.
1847 //
1848 if (pPipeInfo[intfIndex].Pipes != NULL) {
1849 //
1850 // Delete any pipes that might have been created
1851 //
1852 for (iPipe = 0; iPipe < pPipeInfo[intfIndex].NumPipes; iPipe++) {
1853 if (pPipeInfo[intfIndex].Pipes[iPipe] != NULL) {
1854 pPipeInfo[intfIndex].Pipes[iPipe]->DeleteFromFailedCreate();
1855 pPipeInfo[intfIndex].Pipes[iPipe] = NULL;
1856 }
1857 }
1858
1859 //
1860 // Now free the array itself and clear out the count
1861 //
1862 FxPoolFree(pPipeInfo[intfIndex].Pipes);
1863 pPipeInfo[intfIndex].Pipes = NULL;
1864 pPipeInfo[intfIndex].NumPipes = 0;
1865 }
1866 }
1867
1868 FxPoolFree(pPipeInfo);
1869 pPipeInfo = NULL;
1870 }
1871
1872 return status;
1873}
1874
1878 VOID
1879 )
1880{
1883
1884 FxSyncRequest request(GetDriverGlobals(), NULL);
1886
1887 //
1888 // FxSyncRequest always succeesds for KM but can fail for UM.
1889 //
1890 status = request.Initialize();
1891 if (!NT_SUCCESS(status)) {
1893 "Failed to initialize FxSyncRequest");
1894 return status;
1895 }
1896
1897 status = request.m_TrueRequest->ValidateTarget(this);
1898 if (!NT_SUCCESS(status)) {
1899 return status;
1900 }
1901
1902 //
1903 // This will remove and free all interfaces and associated pipes
1904 //
1906
1907 RtlZeroMemory(&urb, sizeof(urb));
1908
1909#pragma prefast(suppress: __WARNING_BUFFER_OVERFLOW, "this annotation change in usb.h is communicated to usb team");
1910 UsbBuildSelectConfigurationRequest((PURB) &urb, sizeof(urb), NULL);
1911#pragma prefast(suppress: __WARNING_BUFFER_OVERFLOW, "this annotation change in usb.h is communicated to usb team");
1912 FxFormatUsbRequest(request.m_TrueRequest, (PURB) &urb, FxUrbTypeLegacy, NULL);
1913
1916
1917 status = SubmitSync(request.m_TrueRequest, &options);
1918
1919 return status;
1920}
1921
1926 __in PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
1927 __in_ecount(NumInterfaces) PUSB_INTERFACE_DESCRIPTOR* InterfaceDescriptors,
1928 __in ULONG NumInterfaces
1929 )
1930{
1931 PUSBD_INTERFACE_LIST_ENTRY pInterfaces;
1932 PURB urb;
1934 ULONG i, size;
1936
1938
1939 //
1940 // eventually size = sizeof(USBD_INTERFACE_LIST_ENTRY) * (NumInterfaces + 1)
1941 //
1942 status = RtlULongAdd(NumInterfaces, 1, &size);
1943 if (!NT_SUCCESS(status)) {
1944 return status;
1945 }
1946
1947 status = RtlULongMult(size, sizeof(USBD_INTERFACE_LIST_ENTRY), &size);
1948 if (!NT_SUCCESS(status)) {
1949 return status;
1950 }
1951
1952 for (i = 0; i < NumInterfaces; i++) {
1953 if (InterfaceDescriptors[i] == NULL) {
1955 }
1956 }
1957
1958 pInterfaces = (PUSBD_INTERFACE_LIST_ENTRY) FxPoolAllocate(
1961 size
1962 );
1963
1964 if (pInterfaces == NULL) {
1966
1969 "Could not allocate array of USBD_INTERFACE_LIST_ENTRY, %!STATUS!",
1970 status);
1971
1972 return status;
1973 }
1974
1975 RtlZeroMemory(pInterfaces, size);
1976
1977 for (i = 0; i < NumInterfaces; i++) {
1978 pInterfaces[i].InterfaceDescriptor = InterfaceDescriptors[i];
1979 }
1980
1981 if (ConfigurationDescriptor == NULL) {
1982 ConfigurationDescriptor = m_ConfigDescriptor;
1983 }
1984
1986 ConfigurationDescriptor,
1987 pInterfaces,
1989 if (urb == NULL) {
1991 }
1992 else {
1994 FxPoolFree(urb);
1995 urb = NULL;
1996 }
1997
1998 FxPoolFree(pInterfaces);
1999 pInterfaces = NULL;
2000
2001 return status;
2002}
2003
2007 )
2008{
2011 }
2012
2013 return NULL;
2014}
2015
2019 __in WDFUSBINTERFACE UsbInterface,
2021 )
2022{
2024
2028 (PVOID*) &pUsbInterface);
2029
2031
2032 return STATUS_SUCCESS;
2033}
2034
2038 )
2039{
2040 ULONG i;
2041
2042 for (i = 0; i < m_NumInterfaces; i++) {
2044 return m_Interfaces[i];
2045 }
2046 }
2047
2048 return NULL;
2049}
2050
2051VOID
2054 )
2055{
2056 SINGLE_LIST_ENTRY sentHead;
2057 LIST_ENTRY pendHead;
2058 ULONG iPipe;
2059 FxUsbPipe *pPipe;
2060 KIRQL irql;
2061
2062 sentHead.Next = NULL;
2063 InitializeListHead(&pendHead);
2064
2065 AcquireInterfaceIterationLock();
2066
2067 Lock(&irql);
2068 for (iPipe = 0; iPipe < UsbInterface->m_NumberOfConfiguredPipes; iPipe++) {
2069 BOOLEAN wait;
2070
2071 wait = FALSE;
2072 pPipe = UsbInterface->m_ConfiguredPipes[iPipe];
2073 pPipe->GotoRemoveState(
2075 &pendHead,
2076 &sentHead,
2077 TRUE,
2078 &wait);
2079 }
2080 Unlock(irql);
2081
2082 _CleanupPipesRequests(&pendHead, &sentHead);
2083
2084 for (iPipe = 0; iPipe < UsbInterface->m_NumberOfConfiguredPipes; iPipe++) {
2085 pPipe = UsbInterface->m_ConfiguredPipes[iPipe];
2086 pPipe->WaitForSentIoToComplete();
2087 }
2088
2089 UsbInterface->CleanUpAndDelete(FALSE);
2090
2091 ReleaseInterfaceIterationLock();
2092}
2093
2094VOID
2096 VOID
2097 )
2098{
2100 ULONG iInterface, iPipe;
2101
2102 for (iInterface = 0; iInterface < m_NumInterfaces; iInterface++) {
2103 pUsbInterface = m_Interfaces[iInterface];
2104
2106 for (iPipe = 0;
2108 iPipe++) {
2109
2110 if (pUsbInterface->m_ConfiguredPipes[iPipe] != NULL) {
2112 }
2113
2114 }
2115 }
2116 }
2117 FxIoTarget::CancelSentIo(); // __super call
2118}
2119
2123 __in_opt
2125 __out
2126 WDFMEMORY* UrbMemory,
2128 PURB* Urb
2129 )
2130{
2132 PURB urbLocal = NULL;
2134 FxUsbUrb * pUrb = NULL;
2135 WDFMEMORY hMemory;
2137
2138 //
2139 // Get the parent's globals if it is present, else use the ones for FxUsbDevice
2140 //
2143
2144 if (NT_SUCCESS(status)) {
2145
2147 Attributes->ParentObject,
2149 (PVOID*)&pParent,
2151
2155 "Urb must be parented to FxDevice or an IoAllocated Request");
2157 goto Done;
2158 }
2159
2160 }
2162
2164 pParent = this;
2166
2167 }
2168 else {
2169
2170 goto Done;
2171 }
2172
2174 if (!NT_SUCCESS(status)) {
2175 goto Done;
2176 }
2177
2179
2180 *UrbMemory = NULL;
2181
2182 status = USBD_UrbAllocate(m_USBDHandle, &urbLocal);
2183
2184 if (!NT_SUCCESS(status)) {
2185
2186 urbLocal = NULL;
2189 "USBDEVICE Must have been created with Client Contract Version Info, %!STATUS!",
2190 status);
2191
2192 goto Done;
2193
2194 }
2195
2196 pUrb = new(pFxDriverGlobals, Attributes)
2197 FxUsbUrb(pFxDriverGlobals, m_USBDHandle, urbLocal, sizeof(URB));
2198
2199 if (pUrb == NULL) {
2201 goto Done;
2202 }
2203
2204 urbLocal = NULL;
2205
2207
2208 if (!NT_SUCCESS(status)) {
2209 goto Done;
2210 }
2211
2212 *UrbMemory = hMemory;
2213
2214 if (Urb) {
2215 *Urb = (PURB) pUrb->GetBuffer();
2216 }
2217
2218Done:
2219
2220 if (!NT_SUCCESS(status)) {
2221
2222 if (pUrb) {
2223 pUrb->DeleteFromFailedCreate();
2224 }
2225
2226 if (urbLocal) {
2227 USBD_UrbFree(m_USBDHandle, urbLocal);
2228 }
2229
2230 }
2231
2232 return status;
2233}
2234
2238 __in_opt
2240 __in
2242 __out
2243 WDFMEMORY* UrbMemory,
2244 __deref_opt_out_bcount(GET_ISOCH_URB_SIZE(NumberOfIsochPackets))
2245 PURB* Urb
2246 )
2247{
2249 PURB urbLocal = NULL;
2251 FxUsbUrb * pUrb = NULL;
2252 WDFMEMORY hMemory;
2253 ULONG size;
2255
2256 //
2257 // Get the parent's globals if it is present, else use the ones for FxUsbDevice
2258 //
2261
2262 if (NT_SUCCESS(status)) {
2263
2265 Attributes->ParentObject,
2267 (PVOID*)&pParent,
2269
2273 "Urb must be parented to FxDevice or IoAllocated Request");
2275 goto Done;
2276 }
2277
2278 }
2280
2282 pParent = this;
2284
2285 }
2286 else {
2287
2288 goto Done;
2289 }
2290
2292 if (!NT_SUCCESS(status)) {
2293 goto Done;
2294 }
2295
2297
2298 *UrbMemory = NULL;
2299
2301
2302 if (!NT_SUCCESS(status)) {
2303
2304 urbLocal = NULL;
2307 "USBDEVICE Must have been created with Client Contract Version Info, %!STATUS!",
2308 status);
2309
2310 goto Done;
2311
2312 }
2313
2315
2316 pUrb = new(pFxDriverGlobals, Attributes)
2318
2319 if (pUrb == NULL) {
2321 goto Done;
2322 }
2323
2324 urbLocal = NULL;
2325
2327
2328 if (!NT_SUCCESS(status)) {
2329 goto Done;
2330 }
2331
2332 *UrbMemory = hMemory;
2333
2334 if (Urb) {
2335 *Urb = (PURB) pUrb->GetBuffer();
2336 }
2337
2338Done:
2339
2340 if (!NT_SUCCESS(status)) {
2341
2342 if (pUrb) {
2343 pUrb->DeleteFromFailedCreate();
2344 }
2345
2346 if (urbLocal) {
2347 USBD_UrbFree(m_USBDHandle, urbLocal);
2348 }
2349
2350 }
2351
2352 return status;
2353}
2354
2355BOOLEAN
2358 )
2359/*++
2360
2361Routine Description:
2362 This routine determines if the Object being passed is guranteed to be disposed on a
2363 Pnp remove operation.
2364
2365 The object will be disposed on Pnp remove operation if it is a somewhere in the child
2366 tree of the FxDevice assocaited with this FxUsbDevice object, or in the child tree of an
2367 Io Allocated Request.
2368
2369Arguments:
2370
2371 Object - The Object being checked
2372
2373Return Value:
2374
2375 TRUE if the Object is guranteed to be disposed on a pnp remove operation
2376 FALSE otherwise.
2377
2378 --*/
2379{
2380 FxObject * obj;
2381 FxObject * parent;
2382 BOOLEAN isObjectDisposedOnRemove = FALSE;
2383
2384 obj = Object;
2385
2386 //
2387 // By adding a reference now, we simulate what GetParentObjectReferenced
2388 // does later, thus allowing simple logic on when/how to release the
2389 // reference on exit.
2390 //
2391 obj->ADDREF(Object);
2392
2393 while (obj != NULL) {
2394
2395 if (obj == (FxObject*) m_Device) {
2396
2397 isObjectDisposedOnRemove = TRUE;
2398 break;
2399 }
2400
2402
2404 if (request->IsAllocatedFromIo()) {
2405
2406 isObjectDisposedOnRemove = TRUE;
2407 break;
2408 }
2409 }
2410
2411 parent = obj->GetParentObjectReferenced(Object);
2412
2413 //
2414 // Release the reference previously taken by the top of the function
2415 // or GetParentObjectReferenced in a previous pass in the loop.
2416 //
2417 obj->RELEASE(Object);
2418 obj = parent;
2419 }
2420
2421 if (obj != NULL) {
2422
2423 //
2424 // Release the reference previously taken by the top of the function
2425 // or GetParentObjectReferenced in a last pass in the loop.
2426 //
2427 obj->RELEASE(Object);
2428 }
2429
2430 return isObjectDisposedOnRemove;
2431}
2432
2436 )
2437/*++
2438
2439Routine Description:
2440 This routine essentially determines whether this routine can use a urb allocated by
2441 the USBD_xxxUrbAllocate APIs
2442
2443 The USBD_xxxUrbAllocate APIs are only used for those requests that could be disposed at the
2444 time the client driver devnode is being removed.
2445
2446 If we cannot make that gurantee about that request, FxUrbTypeLegacy is returned and the
2447 USBD_xxxUrbAllocate api's must not be used to allocate an Urb.
2448
2449 Else FxUrbTypeUsbdAllocated is returned.
2450
2451Arguments:
2452
2453 Request - FxRequest
2454
2455Return Value:
2456
2457 FxUrbTypeUsbdAllocated, or FxUrbTypeLegacy
2458
2459 --*/
2460{
2461 if (m_UrbType == FxUrbTypeLegacy) {
2462 return FxUrbTypeLegacy;
2463 }
2464
2465 if (Request->IsAllocatedFromIo()) {
2467 }
2468
2471 }
2472
2473 return FxUrbTypeLegacy;
2474}
2475
unsigned char BOOLEAN
struct outqueuenode * head
Definition: adnsresfilter.c:66
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
virtual VOID Stop(__in WDF_IO_TARGET_SENT_IO_ACTION Action)
Definition: fxiotarget.cpp:748
VOID CancelSentIo(VOID)
_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 SubmitSyncRequestIgnoreTargetState(__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS RequestOptions)
_Must_inspect_result_ NTSTATUS Init(__in CfxDeviceBase *Device)
virtual BOOLEAN Dispose(VOID)
Definition: fxiotarget.cpp:154
WDF_IO_TARGET_STATE m_State
Definition: fxiotarget.hpp:928
VOID CompletePendedRequest(__in FxRequestBase *Request)
Definition: fxiotarget.cpp:508
VOID CompletePendedRequestList(__in PLIST_ENTRY RequestListHead)
Definition: fxiotarget.cpp:520
_Must_inspect_result_ NTSTATUS FormatInternalIoctlOthersRequest(__in FxRequestBase *Request, __in ULONG Ioctl, __in FxRequestBuffer *Buffers)
static VOID _CancelSentRequests(__in PSINGLE_LIST_ENTRY RequestListHead)
Definition: fxiotarget.cpp:550
VOID SubmitPendedRequest(__in FxRequestBase *Request)
Definition: fxiotarget.cpp:206
_Must_inspect_result_ NTSTATUS FormatIoctlRequest(__in FxRequestBase *Request, __in ULONG Ioctl, __in BOOLEAN Internal, __in FxRequestBuffer *InputBuffer, __in FxRequestBuffer *OutputBuffer, __in_opt FxFileObject *FileObject=NULL)
virtual VOID Purge(__in WDF_IO_TARGET_PURGE_IO_ACTION Action)
Definition: fxiotarget.cpp:918
virtual _Must_inspect_result_ NTSTATUS Start(VOID)
Definition: fxiotarget.cpp:282
virtual VOID WaitForSentIoToComplete(VOID)
Definition: fxiotarget.hpp:676
Definition: fxirp.hpp:28
VOID Reuse(__in NTSTATUS Status=STATUS_SUCCESS)
Definition: fxirpum.cpp:661
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
CfxDevice * m_Device
Definition: fxobject.hpp:329
CfxDeviceBase * m_DeviceBase
Definition: fxobject.hpp:328
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
virtual BOOLEAN Dispose(VOID)
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
VOID MarkDisposeOverride(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1101
_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
static __inline FxRequestBase * _FromListEntry(__in PLIST_ENTRY Entry)
__inline FxIoTarget * GetTarget(VOID)
_Must_inspect_result_ NTSTATUS CreateInterfaces(VOID)
virtual VOID Purge(__in WDF_IO_TARGET_PURGE_IO_ACTION Action)
virtual BOOLEAN Dispose(VOID)
WINUSB_INTERFACE_HANDLE m_WinUsbHandle
VOID PipesGotoRemoveState(__in BOOLEAN ForceRemovePipes)
USBD_PIPE_HANDLE m_ControlPipe
VOID GetInformation(__out PWDF_USB_DEVICE_INFORMATION Information)
_Must_inspect_result_ NTSTATUS SelectConfig(__in PWDF_OBJECT_ATTRIBUTES PipesAttributes, __in PURB Urb, __in FX_URB_TYPE FxUrbType, __out_opt PUCHAR NumConfiguredInterfaces)
virtual VOID Stop(__in WDF_IO_TARGET_SENT_IO_ACTION Action)
VOID CleanupInterfacePipesAndDelete(__in FxUsbInterface *UsbInterface)
USB_DEVICE_DESCRIPTOR m_DeviceDescriptor
_Must_inspect_result_ NTSTATUS FormatCycleRequest(__in FxRequestBase *Request)
virtual _Must_inspect_result_ NTSTATUS Start(VOID)
_Must_inspect_result_ NTSTATUS IsConnected(VOID)
PINTERFACE_DEREFERENCE m_BusInterfaceDereference
PUSB_BUSIFFN_QUERY_BUS_TIME m_QueryBusTime
USBD_VERSION_INFORMATION m_UsbdVersionInformation
_Must_inspect_result_ NTSTATUS GetPortStatus(__out PULONG PortStatus)
USBD_HANDLE m_USBDHandle
IWudfFile * m_pHostTargetFile
~FxUsbDevice(VOID)
VOID RemoveDeletedInterface(__in FxUsbInterface *Interface)
ULONG GetDefaultMaxTransferSize(VOID)
BOOLEAN IsObjectDisposedOnRemove(__in FxObject *Object)
FxUsbDevice(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
static VOID _CleanupPipesRequests(__in PLIST_ENTRY PendHead, __in PSINGLE_LIST_ENTRY SentHead)
__checkReturn NTSTATUS CreateUrb(__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out WDFMEMORY *UrbMemory, __deref_opt_out_bcount(sizeof(URB)) PURB *Urb)
_Must_inspect_result_ NTSTATUS CyclePort(VOID)
friend FxUsbPipe
FxUsbInterface * GetInterfaceFromIndex(__in UCHAR InterfaceIndex)
_Must_inspect_result_ NTSTATUS GetConfigDescriptor(__out PVOID ConfigDescriptor, __inout PUSHORT ConfigDescriptorLength)
PUSB_CONFIGURATION_DESCRIPTOR m_ConfigDescriptor
_Must_inspect_result_ NTSTATUS SelectConfigInterfaces(__in PWDF_OBJECT_ATTRIBUTES PipesAttributes, __in PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, __in_ecount(NumInterfaces) PUSB_INTERFACE_DESCRIPTOR *InterfaceDescriptors, __in ULONG NumInterfaces)
FX_URB_TYPE m_UrbType
BOOLEAN IsEnabled(VOID)
UCHAR m_NumInterfaces
friend FxUsbInterface
VOID CancelSentIo(VOID)
ULONG m_HcdPortCapabilities
__checkReturn NTSTATUS CreateIsochUrb(__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __in ULONG NumberOfIsochPackets, __out WDFMEMORY *UrbMemory, __deref_opt_out_bcount(GET_ISOCH_URB_SIZE(NumberOfIsochPackets)) PURB *Urb)
PVOID m_BusInterfaceContext
_Must_inspect_result_ NTSTATUS GetInterfaceNumberFromInterface(__in WDFUSBINTERFACE UsbInterface, __out PUCHAR InterfaceNumber)
FX_URB_TYPE GetFxUrbTypeForRequest(__in FxRequestBase *Request)
_Must_inspect_result_ NTSTATUS Deconfig(VOID)
FxUsbInterface ** m_Interfaces
FxUsbInterface * GetInterfaceFromNumber(__in UCHAR InterfaceNumber)
_Must_inspect_result_ NTSTATUS SelectConfigDescriptor(__in PWDF_OBJECT_ATTRIBUTES PipeAttributes, __in PWDF_USB_DEVICE_SELECT_CONFIG_PARAMS Params)
BOOLEAN m_OnUSBD
USBD_CONFIGURATION_HANDLE m_ConfigHandle
BOOLEAN m_MismatchedInterfacesInConfigDescriptor
FxUsbPipe ** m_ConfiguredPipes
VOID FormatSelectSettingUrb(__in_bcount(GET_SELECT_INTERFACE_REQUEST_SIZE(NumEndpoints)) PURB Urb, __in USHORT NumEndpoints, __in UCHAR SettingNumber)
VOID CleanUpAndDelete(__in BOOLEAN ClearDestroyCallback)
VOID SetConfiguredPipes(__in FxUsbPipe **ppPipes)
UCHAR GetInterfaceNumber(VOID)
BOOLEAN IsInterfaceConfigured(VOID)
UCHAR m_NumberOfConfiguredPipes
VOID SetInfo(__in PUSBD_INTERFACE_INFORMATION Interface)
VOID SetNumConfiguredPipes(__in UCHAR NumberOfPipes)
VOID GotoPurgeState(__in WDF_IO_TARGET_PURGE_IO_ACTION Action, __in PLIST_ENTRY PendedRequestListHead, __in PSINGLE_LIST_ENTRY SentRequestListHead, __out PBOOLEAN Wait, __in BOOLEAN LockSelf)
Definition: fxusbpipe.cpp:1294
virtual VOID GotoStopState(__in WDF_IO_TARGET_SENT_IO_ACTION Action, __in PSINGLE_LIST_ENTRY SentRequestListHead, __out PBOOLEAN Wait, __in BOOLEAN LockSelf)
Definition: fxusbpipe.cpp:1217
virtual VOID GotoRemoveState(__in WDF_IO_TARGET_STATE NewState, __in PLIST_ENTRY PendedRequestListHead, __in PSINGLE_LIST_ENTRY SentRequestListHead, __in BOOLEAN Lock, __out PBOOLEAN Wait)
Definition: fxusbpipe.cpp:1367
virtual VOID WaitForSentIoToComplete(VOID)
Definition: fxusbpipe.cpp:1419
virtual _Must_inspect_result_ NTSTATUS GotoStartState(__in PLIST_ENTRY RequestListHead, __in BOOLEAN Lock=TRUE)
Definition: fxusbpipe.cpp:1133
USBD_HANDLE m_USBDHandle
virtual BOOLEAN Dispose(VOID)
FxUsbUrb(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in USBD_HANDLE USBDHandle, __in_bcount(BufferSize) PVOID Buffer, __in size_t BufferSize)
virtual size_t GetBufferSize(VOID)=0
virtual PVOID GetBuffer(VOID)=0
static __inline VOID MxUnlockPages(__in PMDL Mdl)
Definition: mxgeneralkm.h:357
static __inline KIRQL MxGetCurrentIrql()
Definition: mxgeneralkm.h:86
#define __out_opt
Definition: dbghelp.h:65
#define __in_ecount(x)
Definition: dbghelp.h:47
#define __in
Definition: dbghelp.h:35
#define __in_bcount(x)
Definition: dbghelp.h:41
#define __inout
Definition: dbghelp.h:50
#define __in_opt
Definition: dbghelp.h:38
#define __out
Definition: dbghelp.h:62
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
#define BufferSize
Definition: mmc.h:75
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
r parent
Definition: btrfs.c:3010
KIRQL irql
Definition: wave.h:1
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#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)
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Device, FX_TYPE_DEVICE,(PVOID *)&pDevice, &pFxDriverGlobals)
PFX_DRIVER_GLOBALS pFxDriverGlobals
FxIoTarget * pTarget
Definition: fxdeviceapi.cpp:97
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Fdo, FX_TYPE_DEVICE,(PVOID *)&pFdo)
SINGLE_LIST_ENTRY * pCur
PSINGLE_LIST_ENTRY ple
FxRequest * pRequest
FxObject * pParent
Definition: fxdpcapi.cpp:86
__inline BOOLEAN FxObjectCheckType(__in FxObject *Object, __in WDFTYPE Type)
Definition: fxhandle.h:240
WDFMEMORY hMemory
#define FxPointerNotNull(FxDriverGlobals, Ptr)
Definition: fxmacros.hpp:253
VOID __inline FxMdlFree(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PMDL Mdl)
Definition: fxmdl.h:60
@ ObjectDoNotLock
Definition: fxobject.hpp:128
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
PINTERFACE pInterface
#define RtlSizeTToULong
FxIrp * irp
#define FX_REQUEST_NUM_OTHER_PARAMS
@ FX_RCT_USB_CONTROL_REQUEST
@ FX_RCT_USB_STRING_REQUEST
@ FX_TYPE_USB_INTERFACE
Definition: fxtypes.h:104
@ FX_TYPE_OBJECT
Definition: fxtypes.h:45
@ FX_TYPE_REQUEST
Definition: fxtypes.h:53
@ FX_TYPE_IO_TARGET_USB_DEVICE
Definition: fxtypes.h:102
@ FxUrbTypeLegacy
Definition: fxusbdevice.hpp:27
@ FxUrbTypeUsbdAllocated
Definition: fxusbdevice.hpp:28
enum _FX_URB_TYPE FX_URB_TYPE
FxUsbInterface * pUsbInterface
return pUsbInterface GetInterfaceNumber()
_Must_inspect_result_ NTSTATUS __inline FxValidateObjectAttributesForParentHandle(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in ULONG Flags=FX_VALIDATE_OPTION_NONE_SPECIFIED)
_Must_inspect_result_ NTSTATUS FxValidateObjectAttributes(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in ULONG Flags=FX_VALIDATE_OPTION_NONE_SPECIFIED)
GLsizeiptr size
Definition: glext.h:5919
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glext.h:7750
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
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
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
Definition: hubbusif.h:42
#define UCHAR_MAX
Definition: limits.h:25
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define for
Definition: utility.h:88
#define __checkReturn
Definition: ms_sal.h:2873
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define __deref_opt_out_bcount(size)
Definition: ms_sal.h:2812
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
virtual VOID ReleaseAndRestore(__in FxRequestBase *Request)
WDF_REQUEST_COMPLETION_PARAMS m_CompletionParams
IFxMemory * m_RequestMemory
_URB_CONTROL_TRANSFER * m_Urb
Definition: fxusbdevice.hpp:86
virtual VOID ReleaseAndRestore(__in FxRequestBase *Request)
FxUsbDeviceControlContext(__in FX_URB_TYPE FxUrbType)
Definition: fxusbdevice.cpp:36
USBD_STATUS GetUsbdStatus(VOID)
_URB_CONTROL_TRANSFER m_UrbLegacy
Definition: fxusbdevice.hpp:81
virtual VOID CopyParameters(__in FxRequestBase *Request)
__checkReturn NTSTATUS AllocateUrb(__in USBD_HANDLE USBDHandle)
Definition: fxusbdevice.cpp:66
virtual VOID Dispose(VOID)
Definition: fxusbdevice.cpp:88
virtual VOID Dispose(VOID)
FxUsbDeviceStringContext(__in FX_URB_TYPE FxUrbType)
VOID SetUrbInfo(__in UCHAR StringIndex, __in USHORT LangID)
PUSB_STRING_DESCRIPTOR m_StringDescriptor
virtual VOID CopyParameters(__in FxRequestBase *Request)
_Must_inspect_result_ NTSTATUS AllocateDescriptor(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in size_t BufferSize)
USBD_STATUS GetUsbdStatus(VOID)
__checkReturn NTSTATUS AllocateUrb(__in USBD_HANDLE USBDHandle)
_URB_CONTROL_DESCRIPTOR_REQUEST m_UrbLegacy
_URB_CONTROL_DESCRIPTOR_REQUEST * m_Urb
VOID SetUsbType(__in WDF_USB_REQUEST_TYPE Type)
WDF_USB_REQUEST_COMPLETION_PARAMS m_UsbParameters
virtual VOID CopyParameters(__in FxRequestBase *Request)
Definition: typedefs.h:120
Definition: ntbasedef.h:628
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
struct _UMURB_CONTROL_TRANSFER UmUrbControlTransfer
Definition: umusb.h:200
struct _UMURB_DESCRIPTOR_REQUEST UmUrbDescriptorRequest
Definition: umusb.h:245
struct _URB_HEADER Hdr
Definition: usb.h:341
ULONG TransferBufferLength
Definition: usb.h:470
struct _URB_HEADER Hdr
Definition: usb.h:467
Definition: usb.h:529
struct _URB_SELECT_INTERFACE UrbSelectInterface
Definition: usb.h:532
Definition: usbdlib.h:7
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
Definition: usbdlib.h:8
struct _WDF_USB_REQUEST_COMPLETION_PARAMS::@3903::@3905 DeviceControlTransfer
union _WDF_USB_REQUEST_COMPLETION_PARAMS::@3903 Parameters
struct _WDF_USB_REQUEST_COMPLETION_PARAMS::@3903::@3904 DeviceString
Definition: match.c:390
Definition: http.c:7252
Definition: devices.h:37
Definition: tftpd.h:86
Definition: ps.c:97
#define GetHandle(h)
Definition: treelist.c:116
uint32_t * PULONG
Definition: typedefs.h:59
uint16_t * PUSHORT
Definition: typedefs.h:56
#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_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _USB_STRING_DESCRIPTOR * PUSB_STRING_DESCRIPTOR
struct _USB_INTERFACE_DESCRIPTOR * PUSB_INTERFACE_DESCRIPTOR
#define USB_STRING_DESCRIPTOR_TYPE
Definition: usb100.h:51
struct _USB_STRING_DESCRIPTOR USB_STRING_DESCRIPTOR
#define USB_INTERFACE_DESCRIPTOR_TYPE
Definition: usb100.h:52
struct _USB_COMMON_DESCRIPTOR USB_COMMON_DESCRIPTOR
struct _USBD_INTERFACE_INFORMATION * PUSBD_INTERFACE_INFORMATION
struct _URB * PURB
#define USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE
Definition: usb.h:236
LONG USBD_STATUS
Definition: usb.h:165
#define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
Definition: usb.h:97
#define UsbBuildSelectConfigurationRequest(urb, length, configurationDescriptor)
Definition: usbdlib.h:53
#define GET_SELECT_INTERFACE_REQUEST_SIZE(totalPipes)
Definition: usbdlib.h:117
struct _USBD_INTERFACE_LIST_ENTRY * PUSBD_INTERFACE_LIST_ENTRY
#define GET_ISO_URB_SIZE(n)
Definition: usbdlib.h:125
_In_ PVOID _In_ LONG InterfaceNumber
Definition: usbdlib.h:169
#define IOCTL_INTERNAL_USB_CYCLE_PORT
Definition: usbioctl.h:53
#define USBD_PORT_ENABLED
Definition: usbioctl.h:41
#define USBD_PORT_CONNECTED
Definition: usbioctl.h:42
#define IOCTL_INTERNAL_USB_GET_PORT_STATUS
Definition: usbioctl.h:44
NTSTATUS USBD_UrbAllocate(_In_ USBD_HANDLE USBDHandle, _Outptr_result_bytebuffer_(sizeof(URB)) PURB *Urb)
Definition: usbstubum.cpp:46
NTSTATUS USBD_IsochUrbAllocate(_In_ USBD_HANDLE USBDHandle, _In_ ULONG NumberOfIsochPacket, _Outptr_result_bytebuffer_(sizeof(struct _URB_ISOCH_TRANSFER)+(NumberOfIsochPackets *sizeof(USBD_ISO_PACKET_DESCRIPTOR)) - sizeof(USBD_ISO_PACKET_DESCRIPTOR)) PURB *Urb)
Definition: usbstubum.cpp:60
VOID USBD_CloseHandle(_In_ USBD_HANDLE USBDHandle)
Definition: usbstubum.cpp:80
VOID USBD_UrbFree(_In_ USBD_HANDLE USBDHandle, _In_ PURB Urb)
Definition: usbstubum.cpp:33
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
NTSTATUS FxUsbValidateConfigDescriptorHeaders(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor, __in size_t ConfigDescriptorLength)
Definition: usbutil.cpp:111
PURB FxUsbCreateConfigRequest(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc, __in PUSBD_INTERFACE_LIST_ENTRY InterfaceList, __in ULONG DefaultMaxPacketSize)
Definition: usbutil.cpp:364
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
BOOLEAN __inline FxBitArraySet(__inout_xcount((BitNumber/sizeof(UCHAR))+1) PUCHAR BitArray, __in UCHAR BitNumber)
Definition: usbutil.hpp:9
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
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
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE Interface
Definition: wdffdo.h:465
enum _WDF_IO_TARGET_PURGE_IO_ACTION WDF_IO_TARGET_PURGE_IO_ACTION
@ WdfIoTargetLeaveSentIoPending
Definition: wdfiotarget.h:73
enum _WDF_IO_TARGET_SENT_IO_ACTION WDF_IO_TARGET_SENT_IO_ACTION
@ WdfIoTargetDeleted
Definition: wdfiotarget.h:57
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
@ WdfIoTargetPurgeIo
Definition: wdfiotarget.h:79
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
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
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308
FORCEINLINE VOID WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(_Inout_ PWDF_REQUEST_SEND_OPTIONS Options, _In_ LONGLONG Timeout)
Definition: wdfrequest.h:421
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
#define STATUS_WDF_PARENT_NOT_SPECIFIED
Definition: wdfstatus.h:252
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105
_In_ WDFUSBINTERFACE UsbInterface
Definition: wdfusb.h:2276
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_ WDFREQUEST _In_ WDFMEMORY UrbMemory
Definition: wdfusb.h:1576
_Must_inspect_result_ _In_ WDFUSBDEVICE _Out_writes_bytes_to_opt_ ConfigDescriptorLength PVOID ConfigDescriptor
Definition: wdfusb.h:1036
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ ULONG NumberOfIsochPackets
Definition: wdfusb.h:1703
_Must_inspect_result_ _In_ WDFUSBDEVICE _Out_writes_bytes_to_opt_ ConfigDescriptorLength PVOID _Inout_ PUSHORT ConfigDescriptorLength
Definition: wdfusb.h:1040
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT _In_ UCHAR StringIndex
Definition: wdfusb.h:1080
@ WdfUsbRequestTypeDeviceString
Definition: wdfusb.h:89
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT _In_ UCHAR _In_opt_ USHORT LangID
Definition: wdfusb.h:1083
_In_ WDFUSBDEVICE _In_ UCHAR InterfaceIndex
Definition: wdfusb.h:2462
_Must_inspect_result_ _In_ WDFUSBINTERFACE _In_opt_ PWDF_OBJECT_ATTRIBUTES PipesAttributes
Definition: wdfusb.h:2390
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
#define SAFE_RELEASE(p)
unsigned char UCHAR
Definition: xmlstorage.h:181