ReactOS  0.4.15-dev-2361-g32428a3
fxusbdevice.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxUsbDevice.cpp
8 
9 Abstract:
10 
11 Author:
12 
13 Environment:
14 
15  kernel mode only
16 
17 Revision History:
18 
19 --*/
20 
21 extern "C" {
22 #include <initguid.h>
23 }
24 
25 #include "fxusbpch.hpp"
26 
27 
28 extern "C" {
29 #include "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) {
46  m_Urb = &m_UrbLegacy;
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 
83 Done:
84  return status;
85 }
86 
87 VOID
89  VOID
90  )
91 {
92  if (m_Urb && (m_Urb != &m_UrbLegacy)){
94  m_Urb = NULL;
96  }
97 }
98 
99 VOID
102  )
103 {
104 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
107 #elif (FX_CORE_MODE == FX_CORE_USER_MODE)
110 #endif
112 }
113 
114 VOID
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
131  m_PartialMdl = NULL;
132  }
133 
135 }
136 
139  VOID
140  )
141 {
142  return m_Urb->Hdr.Status;
143 }
144 
146  __in FX_URB_TYPE FxUrbType
147  ) :
149 {
150  m_USBDHandle = NULL;
154 
155  if (FxUrbType == FxUrbTypeLegacy) {
156  m_Urb = &m_UrbLegacy;
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;
179  m_USBDHandle = NULL;
180 }
181 
183 NTSTATUS
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 
205 Done:
206  return status;
207 }
208 
209 VOID
211  VOID
212  )
213 {
214  if (m_Urb && (m_Urb != &m_UrbLegacy)){
216  m_Urb = NULL;
217  m_USBDHandle = NULL;
218  }
219 
220 }
221 
222 VOID
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 
268 VOID
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 
302 NTSTATUS
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]) +
317  BufferSize;
318 
319  pDescriptor = (PUSB_STRING_DESCRIPTOR) FxPoolAllocate(
320  FxDriverGlobals,
321  NonPagedPool,
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 
357 BOOLEAN
359  VOID
360  )
361 {
363  ASSERT(m_pBuffer != NULL);
365  m_pBuffer = NULL;
366  m_USBDHandle = NULL;
367 
368  return FxMemoryBufferPreallocated::Dispose(); // __super call
369 }
370 
372  __in PFX_DRIVER_GLOBALS FxDriverGlobals
373  ) :
375 {
378 
379  m_OnUSBD = FALSE;
380  m_Interfaces = NULL;;
381  m_NumInterfaces = 0;
382 
383  m_Traits = 0;
391 
393 
394  m_USBDHandle = NULL;
396 
397 #if (FX_CORE_MODE == FX_CORE_USER_MODE)
400 #endif
401 
403 }
404 
405 BOOLEAN
407  VOID
408  )
409 {
410 #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
412 #endif
413 
414  if (m_USBDHandle) {
416  m_USBDHandle = NULL;
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++) {
450  ASSERT(m_Interfaces[i] == NULL);
451  }
452 
453  if (m_Interfaces != NULL){
455  m_Interfaces = NULL;
456  }
457 
458  m_NumInterfaces = 0;
459 }
460 
461 VOID
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) {
474  m_Interfaces[i] = NULL;
475  return;
476  }
477  }
478 }
479 
480 VOID
483  )
484 {
485  Information->Traits = m_Traits;
486  Information->HcdPortCapabilities = m_HcdPortCapabilities;
487 
488  RtlCopyMemory(&Information->UsbdVersionInformation,
490  sizeof(m_UsbdVersionInformation));
491 }
492 
493 ULONG
495  VOID
496  )
497 /*++
498 
499 Routine 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 
512 Arguments:
513  None
514 
515 Return 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 
529 NTSTATUS
531  VOID
532  )
533 {
535 
537 
538  if (NT_SUCCESS(status)) {
540  LIST_ENTRY head, *ple;
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 
580  ple = RemoveHeadList(&head);
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 
600 VOID
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 
693 VOID
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 
791 VOID
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 
812 VOID
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 
897 NTSTATUS
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 
948  sizeof(USB_INTERFACE_DESCRIPTOR),
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 
1031  status = pInterface->Commit(WDF_NO_OBJECT_ATTRIBUTES, NULL, this);
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 
1124 Done:
1125  return status;
1126 }
1127 
1128 
1130 NTSTATUS
1133  )
1134 {
1135  NTSTATUS status;
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 
1174 BOOLEAN
1176  VOID
1177  )
1178 {
1179  NTSTATUS status;
1180  ULONG portStatus;
1181  BOOLEAN enabled;
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 
1201 NTSTATUS
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)
1213  NTSTATUS status;
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 
1226 NTSTATUS
1228  VOID
1229  )
1230 {
1232  FxSyncRequest request(GetDriverGlobals(), &context);
1233  NTSTATUS status;
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 
1260 NTSTATUS
1263  )
1264 {
1265  FxRequestBuffer emptyBuffer;
1266 
1267  return FormatIoctlRequest(Request,
1269  TRUE,
1270  &emptyBuffer,
1271  &emptyBuffer);
1272 }
1273 
1275 NTSTATUS
1279  )
1280 {
1281  NTSTATUS status;
1282  USHORT copyLength;
1283 
1284  if (ConfigDescriptor == NULL) {
1285  //
1286  // Caller wants length to allocate
1287  //
1289  return STATUS_BUFFER_TOO_SMALL;
1290  }
1291 
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 
1316 NTSTATUS
1320  )
1321 {
1322  PUSBD_INTERFACE_LIST_ENTRY pInterfaces;
1323  PURB urb;
1324  NTSTATUS status;
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) {
1339  return STATUS_INVALID_PARAMETER;
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 
1423 NTSTATUS
1426  __in PURB Urb,
1427  __in FX_URB_TYPE FxUrbType,
1428  __out_opt PUCHAR NumConfiguredInterfaces
1429  )
1430 /*++
1431 
1432 Routine 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 
1437 Arguments:
1438  PipesAttributes - object attributes to apply to each created WDFUSBPIPE
1439 
1440  Urb - the URB describing the configuration to select
1441 
1442 Return Value:
1443  NTSTATUS
1444 
1445  --*/
1446 {
1448  PUCHAR pCur, pEnd;
1450  FxUsbPipe* pPipe;
1451  PURB pSelectUrb;
1452  NTSTATUS status;
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  //
1507  size = sizeof(FxInterfacePipeInformation);
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 
1546  pIface = (PUSBD_INTERFACE_INFORMATION) pCur;
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(
1592  NonPagedPool,
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)
1618  FxUsbPipe(GetDriverGlobals(),this);
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) {
1671  size = GET_SELECT_INTERFACE_REQUEST_SIZE(maxNumPipes);
1672 
1673  pSelectUrb = (PURB) FxPoolAllocate(GetDriverGlobals(),
1674  NonPagedPool,
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;
1746  pIface = (PUSBD_INTERFACE_INFORMATION) pCur;
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")
1756  pIface = (PUSBD_INTERFACE_INFORMATION) pCur;
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 
1833 Done:
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 
1876 NTSTATUS
1878  VOID
1879  )
1880 {
1883 
1884  FxSyncRequest request(GetDriverGlobals(), NULL);
1885  NTSTATUS status;
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 
1923 NTSTATUS
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;
1933  NTSTATUS status;
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) {
1954  return STATUS_INVALID_PARAMETER;
1955  }
1956  }
1957 
1958  pInterfaces = (PUSBD_INTERFACE_LIST_ENTRY) FxPoolAllocate(
1960  NonPagedPool,
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 {
2010  return m_Interfaces[InterfaceIndex];
2011  }
2012 
2013  return NULL;
2014 }
2015 
2017 NTSTATUS
2019  __in WDFUSBINTERFACE UsbInterface,
2021  )
2022 {
2024 
2026  UsbInterface,
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 
2051 VOID
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 
2094 VOID
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 
2121 NTSTATUS
2123  __in_opt
2125  __out
2126  WDFMEMORY* UrbMemory,
2127  __deref_opt_out_bcount(sizeof(URB))
2128  PURB* Urb
2129  )
2130 {
2131  NTSTATUS status;
2132  PURB urbLocal = NULL;
2134  FxUsbUrb * pUrb = NULL;
2135  WDFMEMORY hMemory;
2136  FxObject* pParent;
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,
2150  &pFxDriverGlobals);
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 
2218 Done:
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 
2236 NTSTATUS
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 {
2248  NTSTATUS status;
2249  PURB urbLocal = NULL;
2251  FxUsbUrb * pUrb = NULL;
2252  WDFMEMORY hMemory;
2253  ULONG size;
2254  FxObject* pParent;
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,
2268  &pFxDriverGlobals);
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 
2338 Done:
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 
2355 BOOLEAN
2358  )
2359 /*++
2360 
2361 Routine 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 
2369 Arguments:
2370 
2371  Object - The Object being checked
2372 
2373 Return 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 
2439 Routine 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 
2451 Arguments:
2452 
2453  Request - FxRequest
2454 
2455 Return Value:
2456 
2457  FxUrbTypeUsbdAllocated, or FxUrbTypeLegacy
2458 
2459  --*/
2460 {
2461  if (m_UrbType == FxUrbTypeLegacy) {
2462  return FxUrbTypeLegacy;
2463  }
2464 
2465  if (Request->IsAllocatedFromIo()) {
2466  return FxUrbTypeUsbdAllocated;
2467  }
2468 
2470  return FxUrbTypeUsbdAllocated;
2471  }
2472 
2473  return FxUrbTypeLegacy;
2474 }
2475 
FxIoTarget * pTarget
Definition: fxdeviceapi.cpp:97
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
_URB_CONTROL_DESCRIPTOR_REQUEST m_UrbLegacy
CfxDevice * m_Device
Definition: fxobject.hpp:329
IFxMemory * m_RequestMemory
#define __in_bcount(x)
Definition: dbghelp.h:41
FORCEINLINE VOID WDF_REQUEST_SEND_OPTIONS_INIT(_Out_ PWDF_REQUEST_SEND_OPTIONS Options, _In_ ULONG Flags)
Definition: wdfrequest.h:409
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
#define RtlSizeTToULong
_Must_inspect_result_ NTSTATUS CreateInterfaces(VOID)
enum _WDF_IO_TARGET_PURGE_IO_ACTION WDF_IO_TARGET_PURGE_IO_ACTION
struct _UMURB_CONTROL_TRANSFER UmUrbControlTransfer
Definition: umusb.h:200
friend FxUsbPipe
FX_URB_TYPE GetFxUrbTypeForRequest(__in FxRequestBase *Request)
#define _Must_inspect_result_
Definition: no_sal2.h:62
_In_ WDFUSBDEVICE _In_ UCHAR InterfaceIndex
Definition: wdfusb.h:2459
FxUsbInterface * GetInterfaceFromIndex(__in UCHAR InterfaceIndex)
virtual VOID CopyParameters(__in FxRequestBase *Request)
#define UsbBuildSelectConfigurationRequest(urb, length, configurationDescriptor)
Definition: usbdlib.h:53
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ NTSTATUS GetConfigDescriptor(__out PVOID ConfigDescriptor, __inout PUSHORT ConfigDescriptorLength)
VOID CompletePendedRequestList(__in PLIST_ENTRY RequestListHead)
Definition: fxiotarget.cpp:520
#define __checkReturn
Definition: sal.h:2873
_URB_CONTROL_DESCRIPTOR_REQUEST * m_Urb
friend FxUsbInterface
struct _WDF_USB_REQUEST_COMPLETION_PARAMS::@3691::@3692 DeviceString
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:306
_Must_inspect_result_ NTSTATUS Commit(__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
Definition: fxobject.cpp:904
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
__checkReturn NTSTATUS CreateUrb(__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out WDFMEMORY *UrbMemory, __deref_opt_out_bcount(sizeof(URB)) PURB *Urb)
Definition: ntbasedef.h:628
VOID SetUrbInfo(__in UCHAR StringIndex, __in USHORT LangID)
Definition: http.c:7251
#define WDF_PTR_ADD_OFFSET(_ptr, _offset)
Definition: wdfcore.h:144
struct outqueuenode * head
Definition: adnsresfilter.c:66
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
~FxUsbDevice(VOID)
#define __in_opt
Definition: dbghelp.h:38
FX_URB_TYPE m_UrbType
#define USBD_PORT_ENABLED
Definition: usbioctl.h:41
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ NTSTATUS SelectConfig(__in PWDF_OBJECT_ATTRIBUTES PipesAttributes, __in PURB Urb, __in FX_URB_TYPE FxUrbType, __out_opt PUCHAR NumConfiguredInterfaces)
virtual BOOLEAN Dispose(VOID)
Definition: fxiotarget.cpp:154
virtual _Must_inspect_result_ NTSTATUS GotoStartState(__in PLIST_ENTRY RequestListHead, __in BOOLEAN Lock=TRUE)
Definition: fxusbpipe.cpp:1133
return pUsbInterface GetInterfaceNumber()
__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)
struct _USBD_INTERFACE_LIST_ENTRY * PUSBD_INTERFACE_LIST_ENTRY
_Must_inspect_result_ NTSTATUS FormatInternalIoctlOthersRequest(__in FxRequestBase *Request, __in ULONG Ioctl, __in FxRequestBuffer *Buffers)
unsigned char * PUCHAR
Definition: retypes.h:3
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ WDFUSBDEVICE _Out_writes_bytes_to_opt_ ConfigDescriptorLength PVOID _Inout_ PUSHORT ConfigDescriptorLength
Definition: wdfusb.h:1036
#define GET_SELECT_INTERFACE_REQUEST_SIZE(totalPipes)
Definition: usbdlib.h:117
struct _USBD_INTERFACE_INFORMATION * PUSBD_INTERFACE_INFORMATION
FxRequest * pRequest
#define FX_REQUEST_NUM_OTHER_PARAMS
Definition: fxirp.hpp:28
struct _USB_COMMON_DESCRIPTOR USB_COMMON_DESCRIPTOR
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT _In_ UCHAR StringIndex
Definition: wdfusb.h:1075
FxUsbPipe ** m_ConfiguredPipes
BOOLEAN __inline FxBitArraySet(__inout_xcount((BitNumber/sizeof(UCHAR))+1) PUCHAR BitArray, __in UCHAR BitNumber)
Definition: usbutil.hpp:9
_Must_inspect_result_ NTSTATUS SubmitSync(__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS Options=NULL, __out_opt PULONG Action=NULL)
VOID SetNumConfiguredPipes(__in UCHAR NumberOfPipes)
KIRQL irql
Definition: wave.h:1
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Fdo, FX_TYPE_DEVICE,(PVOID *)&pFdo)
_Must_inspect_result_ NTSTATUS GetPortStatus(__out PULONG PortStatus)
VOID SetConfiguredPipes(__in FxUsbPipe **ppPipes)
struct _USB_INTERFACE_DESCRIPTOR * PUSB_INTERFACE_DESCRIPTOR
ULONG GetDefaultMaxTransferSize(VOID)
PINTERFACE pInterface
VOID CompletePendedRequest(__in FxRequestBase *Request)
Definition: fxiotarget.cpp:508
if(dx==0 &&dy==0)
Definition: linetemp.h:174
virtual VOID Purge(__in WDF_IO_TARGET_PURGE_IO_ACTION Action)
Definition: match.c:390
#define USB_STRING_DESCRIPTOR_TYPE
Definition: usb100.h:51
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1044
PUSB_COMMON_DESCRIPTOR FxUsbFindDescriptorType(__in PVOID Buffer, __in size_t BufferLength, __in PVOID Start, __in LONG DescriptorType)
Definition: usbutil.cpp:174
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glext.h:7750
UCHAR m_NumInterfaces
VOID CancelSentIo(VOID)
enum _FX_URB_TYPE FX_URB_TYPE
virtual VOID CopyParameters(__in FxRequestBase *Request)
WDF_IO_TARGET_STATE m_State
Definition: fxiotarget.hpp:928
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
FxUsbInterface * pUsbInterface
GLsizei GLsizei GLuint * obj
Definition: glext.h:6042
PSINGLE_LIST_ENTRY ple
BOOLEAN IsObjectDisposedOnRemove(__in FxObject *Object)
enum _WDF_IO_TARGET_SENT_IO_ACTION WDF_IO_TARGET_SENT_IO_ACTION
WINUSB_INTERFACE_HANDLE m_WinUsbHandle
VOID FormatSelectSettingUrb(__in_bcount(GET_SELECT_INTERFACE_REQUEST_SIZE(NumEndpoints)) PURB Urb, __in USHORT NumEndpoints, __in UCHAR SettingNumber)
WDFIOTARGET GetHandle(VOID)
Definition: fxiotarget.hpp:307
UCHAR KIRQL
Definition: env_spec_w32.h:591
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
Definition: usbdlib.h:7
FxRequest * request
_Must_inspect_result_ NTSTATUS SubmitSyncRequestIgnoreTargetState(__in FxRequestBase *Request, __in_opt PWDF_REQUEST_SEND_OPTIONS RequestOptions)
#define __out_opt
Definition: dbghelp.h:65
#define GET_ISO_URB_SIZE(n)
Definition: usbdlib.h:125
UCHAR m_NumberOfConfiguredPipes
struct _URB_HEADER Hdr
Definition: usb.h:467
#define FALSE
Definition: types.h:117
USBD_HANDLE m_USBDHandle
VOID SetInfo(__in PUSBD_INTERFACE_INFORMATION Interface)
Definition: devices.h:37
PINTERFACE_DEREFERENCE m_BusInterfaceDereference
USBD_STATUS GetUsbdStatus(VOID)
VOID SetUsbType(__in WDF_USB_REQUEST_TYPE Type)
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
struct _USB_STRING_DESCRIPTOR USB_STRING_DESCRIPTOR
_Must_inspect_result_ NTSTATUS __inline FxValidateObjectAttributesForParentHandle(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in ULONG Flags=FX_VALIDATE_OPTION_NONE_SPECIFIED)
VOID MarkDisposeOverride(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1101
VOID USBD_CloseHandle(_In_ USBD_HANDLE USBDHandle)
Definition: usbstubum.cpp:80
#define __out
Definition: dbghelp.h:62
#define UCHAR_MAX
Definition: fxusbdevice.cpp:33
struct _URB_HEADER Hdr
Definition: usb.h:341
virtual VOID ReleaseAndRestore(__in FxRequestBase *Request)
unsigned char BOOLEAN
#define USB_INTERFACE_DESCRIPTOR_TYPE
Definition: usb100.h:52
_Must_inspect_result_ NTSTATUS SelectConfigDescriptor(__in PWDF_OBJECT_ATTRIBUTES PipeAttributes, __in PWDF_USB_DEVICE_SELECT_CONFIG_PARAMS Params)
USBD_PIPE_HANDLE m_ControlPipe
VOID CancelSentIo(VOID)
_Must_inspect_result_ _In_ WDFUSBDEVICE _Out_writes_bytes_to_opt_ ConfigDescriptorLength PVOID ConfigDescriptor
Definition: wdfusb.h:1036
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
#define SAFE_RELEASE(p)
Definition: bufpool.h:45
FxUsbDeviceControlContext(__in FX_URB_TYPE FxUrbType)
Definition: fxusbdevice.cpp:36
_Must_inspect_result_ NTSTATUS FormatCycleRequest(__in FxRequestBase *Request)
virtual VOID Dispose(VOID)
int options
Definition: main.c:106
#define IOCTL_INTERNAL_USB_CYCLE_PORT
Definition: usbioctl.h:53
FxUsbInterface * GetInterfaceFromNumber(__in UCHAR InterfaceNumber)
_In_ PVOID _In_ LONG InterfaceNumber
Definition: usbdlib.h:168
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
VOID CleanUpAndDelete(__in BOOLEAN ClearDestroyCallback)
UCHAR GetInterfaceNumber(VOID)
GLsizeiptr size
Definition: glext.h:5919
PFX_DRIVER_GLOBALS pFxDriverGlobals
#define ASSERT(a)
Definition: mode.c:45
r parent
Definition: btrfs.c:2944
virtual VOID Stop(__in WDF_IO_TARGET_SENT_IO_ACTION Action)
_In_ WDFUSBINTERFACE UsbInterface
Definition: wdfusb.h:2276
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
USBD_STATUS GetUsbdStatus(VOID)
#define for
Definition: utility.h:88
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
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
PUSB_CONFIGURATION_DESCRIPTOR m_ConfigDescriptor
static __inline KIRQL MxGetCurrentIrql()
Definition: mxgeneralkm.h:86
__inline FxIoTarget * GetTarget(VOID)
BOOLEAN m_OnUSBD
struct _UMURB_DESCRIPTOR_REQUEST UmUrbDescriptorRequest
Definition: umusb.h:245
ULONG m_HcdPortCapabilities
_In_opt_ PVOID _In_ ULONG _In_ PVOID context
Definition: wdfdriver.h:113
VOID PipesGotoRemoveState(__in BOOLEAN ForceRemovePipes)
FxUsbDeviceStringContext(__in FX_URB_TYPE FxUrbType)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static VOID _CleanupPipesRequests(__in PLIST_ENTRY PendHead, __in PSINGLE_LIST_ENTRY SentHead)
PVOID m_BusInterfaceContext
unsigned char UCHAR
Definition: xmlstorage.h:181
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
VOID USBD_UrbFree(_In_ USBD_HANDLE USBDHandle, _In_ PURB Urb)
Definition: usbstubum.cpp:33
FxUsbInterface ** m_Interfaces
_Must_inspect_result_ NTSTATUS FxValidateObjectAttributes(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in ULONG Flags=FX_VALIDATE_OPTION_NONE_SPECIFIED)
VOID __inline FxMdlFree(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PMDL Mdl)
Definition: fxmdl.h:60
LONG USBD_STATUS
Definition: usb.h:165
VOID CleanupInterfacePipesAndDelete(__in FxUsbInterface *UsbInterface)
_Must_inspect_result_ NTSTATUS FormatIoctlRequest(__in FxRequestBase *Request, __in ULONG Ioctl, __in BOOLEAN Internal, __in FxRequestBuffer *InputBuffer, __in FxRequestBuffer *OutputBuffer, __in_opt FxFileObject *FileObject=NULL)
_Must_inspect_result_ _In_ WDFUSBINTERFACE _In_opt_ PWDF_OBJECT_ATTRIBUTES PipesAttributes
Definition: wdfusb.h:2388
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ ULONG NumberOfIsochPackets
Definition: wdfusb.h:1699
CfxDeviceBase * m_DeviceBase
Definition: fxobject.hpp:328
virtual BOOLEAN Dispose(VOID)
BOOLEAN IsEnabled(VOID)
virtual _Must_inspect_result_ NTSTATUS Start(VOID)
VOID RemoveDeletedInterface(__in FxUsbInterface *Interface)
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
NTSTATUS FxUsbValidateConfigDescriptorHeaders(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor, __in size_t ConfigDescriptorLength)
Definition: usbutil.cpp:111
#define __inout
Definition: dbghelp.h:50
Definition: typedefs.h:119
WDF_USB_REQUEST_COMPLETION_PARAMS m_UsbParameters
#define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
Definition: usb.h:97
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
Definition: hubbusif.h:40
virtual VOID CopyParameters(__in FxRequestBase *Request)
_Must_inspect_result_ NTSTATUS Init(__in CfxDeviceBase *Device)
WDFMEMORY hMemory
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
virtual VOID WaitForSentIoToComplete(VOID)
Definition: fxiotarget.hpp:676
struct _URB * PURB
_Must_inspect_result_ NTSTATUS AllocateDescriptor(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in size_t BufferSize)
PURB FxUsbCreateConfigRequest(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PUSB_CONFIGURATION_DESCRIPTOR ConfigDesc, __in PUSBD_INTERFACE_LIST_ENTRY InterfaceList, __in ULONG DefaultMaxPacketSize)
Definition: usbutil.cpp:364
__checkReturn NTSTATUS AllocateUrb(__in USBD_HANDLE USBDHandle)
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define USBD_PORT_CONNECTED
Definition: usbioctl.h:42
BOOLEAN m_MismatchedInterfacesInConfigDescriptor
_Must_inspect_result_ __in WDFKEY __in PCUNICODE_STRING __in ULONG __in ULONG __in_ecount(ValueLength) PVOID Value)
_URB_CONTROL_TRANSFER * m_Urb
Definition: fxusbdevice.hpp:86
#define USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE
Definition: usb.h:236
FORCEINLINE LONGLONG WDF_REL_TIMEOUT_IN_SEC(_In_ ULONGLONG Time)
Definition: wdfcore.h:62
FxUsbDevice(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
virtual BOOLEAN Dispose(VOID)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
BOOLEAN IsInterfaceConfigured(VOID)
struct _USB_STRING_DESCRIPTOR * PUSB_STRING_DESCRIPTOR
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
Definition: usbdlib.h:8
static __inline VOID MxUnlockPages(__in PMDL Mdl)
Definition: mxgeneralkm.h:357
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
_Must_inspect_result_ NTSTATUS CyclePort(VOID)
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:361
Definition: usb.h:529
__checkReturn NTSTATUS AllocateUrb(__in USBD_HANDLE USBDHandle)
Definition: fxusbdevice.cpp:66
unsigned short USHORT
Definition: pedump.c:61
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:506
SINGLE_LIST_ENTRY * pCur
USBD_HANDLE m_USBDHandle
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
WDF_REQUEST_COMPLETION_PARAMS m_CompletionParams
PUSB_BUSIFFN_QUERY_BUS_TIME m_QueryBusTime
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define __deref_opt_out_bcount(size)
Definition: sal.h:2812
unsigned int * PULONG
Definition: retypes.h:1
#define STATUS_WDF_PARENT_NOT_SPECIFIED
Definition: wdfstatus.h:252
#define NULL
Definition: types.h:112
VOID Reuse(__in NTSTATUS Status=STATUS_SUCCESS)
Definition: fxirpum.cpp:661
_Must_inspect_result_ NTSTATUS GetInterfaceNumberFromInterface(__in WDFUSBINTERFACE UsbInterface, __out PUCHAR InterfaceNumber)
#define IOCTL_INTERNAL_USB_GET_PORT_STATUS
Definition: usbioctl.h:44
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105
static VOID _CancelSentRequests(__in PSINGLE_LIST_ENTRY RequestListHead)
Definition: fxiotarget.cpp:550
VOID SubmitPendedRequest(__in FxRequestBase *Request)
Definition: fxiotarget.cpp:206
Definition: tftpd.h:85
_URB_CONTROL_TRANSFER m_UrbLegacy
Definition: fxusbdevice.hpp:81
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
_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)
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
virtual VOID ReleaseAndRestore(__in FxRequestBase *Request)
USBD_CONFIGURATION_HANDLE m_ConfigHandle
unsigned int ULONG
Definition: retypes.h:1
USB_DEVICE_DESCRIPTOR m_DeviceDescriptor
FxObject * pParent
Definition: fxdpcapi.cpp:86
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Device, FX_TYPE_DEVICE,(PVOID *)&pDevice, &pFxDriverGlobals)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
IWudfFile * m_pHostTargetFile
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_ WDFREQUEST _In_ WDFMEMORY UrbMemory
Definition: wdfusb.h:1572
PUSB_STRING_DESCRIPTOR m_StringDescriptor
static __inline FxRequestBase * _FromListEntry(__in PLIST_ENTRY Entry)
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
USBD_VERSION_INFORMATION m_UsbdVersionInformation
#define STATUS_SUCCESS
Definition: shellext.h:65
FORCEINLINE VOID WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(_Inout_ PWDF_REQUEST_SEND_OPTIONS Options, _In_ LONGLONG Timeout)
Definition: wdfrequest.h:421
struct _WDF_USB_REQUEST_COMPLETION_PARAMS::@3691::@3693 DeviceControlTransfer
union _WDF_USB_REQUEST_COMPLETION_PARAMS::@3691 Parameters
FxUsbUrb(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in USBD_HANDLE USBDHandle, __in_bcount(BufferSize) PVOID Buffer, __in size_t BufferSize)
virtual BOOLEAN Dispose(VOID)
VOID GetInformation(__out PWDF_USB_DEVICE_INFORMATION Information)
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT _In_ UCHAR _In_opt_ USHORT LangID
Definition: wdfusb.h:1075
_Must_inspect_result_ NTSTATUS IsConnected(VOID)
NTSTATUS USBD_UrbAllocate(_In_ USBD_HANDLE USBDHandle, _Outptr_result_bytebuffer_(sizeof(URB)) PURB *Urb)
Definition: usbstubum.cpp:46
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
#define __in
Definition: dbghelp.h:35
static SERVICE_STATUS status
Definition: service.c:31
VOID NTAPI KeFlushQueuedDpcs(VOID)
Definition: dpc.c:918
#define TRACINGIOTARGET
Definition: dbgtrace.h:72
virtual size_t GetBufferSize(VOID)=0
unsigned short * PUSHORT
Definition: retypes.h:2
ULONG TransferBufferLength
Definition: usb.h:470
FxIrp * irp
_Must_inspect_result_ NTSTATUS Deconfig(VOID)
virtual VOID Dispose(VOID)
Definition: fxusbdevice.cpp:88
struct _URB_SELECT_INTERFACE UrbSelectInterface
Definition: usb.h:532
virtual VOID Stop(__in WDF_IO_TARGET_SENT_IO_ACTION Action)
Definition: fxiotarget.cpp:748
#define BufferSize
Definition: mmc.h:75
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
virtual PVOID GetBuffer(VOID)=0
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:251
#define FxPointerNotNull(FxDriverGlobals, Ptr)
Definition: fxmacros.hpp:253
__inline BOOLEAN FxObjectCheckType(__in FxObject *Object, __in WDFTYPE Type)
Definition: fxhandle.h:240
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
virtual VOID WaitForSentIoToComplete(VOID)
Definition: fxusbpipe.cpp:1419
VOID FxFormatUsbRequest(__in FxRequestBase *Request, __in PURB Urb, __in FX_URB_TYPE FxUrbType, __drv_when(FxUrbType==FxUrbTypeUsbdAllocated, __in) __drv_when(FxUrbType !=FxUrbTypeUsbdAllocated, __in_opt) USBD_HANDLE UsbdHandle)
Definition: usbutil.cpp:29
Definition: ps.c:97