ReactOS  0.4.13-dev-73-gcfe54aa
usbhub.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS USB Hub Driver
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: USBHub main driver functions
5  * COPYRIGHT: Copyright 2017 Vadim Galyant <vgal@rambler.ru>
6  */
7 
8 #include "usbhub.h"
9 
10 #define NDEBUG
11 #include <debug.h>
12 
13 #define NDEBUG_USBHUB_SCE
14 #define NDEBUG_USBHUB_PNP
15 #include "dbg_uhub.h"
16 
17 #include <ntddstor.h>
18 
20 
22 NTAPI
23 USBH_Wait(IN ULONG Milliseconds)
24 {
26 
27  DPRINT("USBH_Wait: Milliseconds - %x\n", Milliseconds);
28  Interval.QuadPart = -10000LL * Milliseconds - ((ULONGLONG)KeQueryTimeIncrement() - 1);
30 }
31 
33 NTAPI
40 {
42 
43  DPRINT("USBHUB_GetConfigValue: ... \n");
44 
45  if (ValueType == REG_BINARY)
46  {
48  }
49  else if (ValueType == REG_DWORD)
50  {
52  }
53  else
54  {
56  }
57 
58  return Status;
59 }
60 
61 VOID
62 NTAPI
64  IN NTSTATUS CompleteStatus)
65 {
66  if (CompleteStatus != STATUS_SUCCESS)
67  {
68  DPRINT1("USBH_CompleteIrp: Irp - %p, CompleteStatus - %X\n",
69  Irp,
70  CompleteStatus);
71  }
72 
73  Irp->IoStatus.Status = CompleteStatus;
75 }
76 
78 NTAPI
80  IN PIRP Irp)
81 {
82  DPRINT_PNP("USBH_PassIrp: DeviceObject - %p, Irp - %p\n",
84  Irp);
85 
87  return IoCallDriver(DeviceObject, Irp);
88 }
89 
91 NTAPI
93  IN PIRP Irp,
95 {
96  PUSBHUB_URB_TIMEOUT_CONTEXT HubTimeoutContext;
97  KIRQL OldIrql;
99 
100  DPRINT("USBH_SyncIrpComplete: ... \n");
101 
102  HubTimeoutContext = Context;
103 
104  KeAcquireSpinLock(&HubTimeoutContext->UrbTimeoutSpinLock, &OldIrql);
105  HubTimeoutContext->IsNormalCompleted = TRUE;
106  TimerCancelled = KeCancelTimer(&HubTimeoutContext->UrbTimeoutTimer);
107  KeReleaseSpinLock(&HubTimeoutContext->UrbTimeoutSpinLock, OldIrql);
108 
109  if (TimerCancelled)
110  {
111  KeSetEvent(&HubTimeoutContext->UrbTimeoutEvent,
113  FALSE);
114  }
115 
116  return STATUS_SUCCESS;
117 }
118 
119 BOOLEAN
120 NTAPI
121 IsBitSet(IN PUCHAR BitMapAddress,
122  IN USHORT Bit)
123 {
124  BOOLEAN IsSet;
125 
126  IsSet = (BitMapAddress[Bit / 8] & (1 << (Bit & 7))) != 0;
127  DPRINT("IsBitSet: Bit - %lX, IsSet - %x\n", Bit, IsSet);
128  return IsSet;
129 }
130 
132 NTAPI
134 {
136 
137  DPRINT("PdoExt: DeviceObject - %p\n", DeviceObject);
138 
139  if (DeviceObject)
140  {
142  }
143  else
144  {
145  PdoExtension = NULL;
146  }
147 
149 }
150 
151 NTSTATUS
152 NTAPI
154  IN ULONG FailReason)
155 {
159 
160  DPRINT("USBH_WriteFailReason: ID - %x\n", FailReason);
161 
165  &KeyHandle);
166 
167  if (NT_SUCCESS(Status))
168  {
169  ZwSetValueKey(KeyHandle,
170  &ValueName,
171  0,
172  REG_DWORD,
173  &FailReason,
174  sizeof(FailReason));
175 
177  }
178 
179  return Status;
180 }
181 
182 VOID
183 NTAPI
188 {
189  PUSBHUB_URB_TIMEOUT_CONTEXT HubTimeoutContext;
190  KIRQL OldIrql;
191  BOOL IsCompleted;
192 
193  DPRINT("USBH_TimeoutDPC ... \n");
194 
195  HubTimeoutContext = DeferredContext;
196 
197  KeAcquireSpinLock(&HubTimeoutContext->UrbTimeoutSpinLock, &OldIrql);
198  IsCompleted = HubTimeoutContext->IsNormalCompleted;
199  KeReleaseSpinLock(&HubTimeoutContext->UrbTimeoutSpinLock, OldIrql);
200 
201  if (!IsCompleted)
202  {
203  IoCancelIrp(HubTimeoutContext->Irp);
204  }
205 
206  KeSetEvent(&HubTimeoutContext->UrbTimeoutEvent,
208  FALSE);
209 }
210 
211 NTSTATUS
212 NTAPI
215  IN PVOID Data,
216  IN ULONG DataSize,
217  IN ULONG Type,
219 {
221  UNICODE_STRING ValueNameString;
223 
224  DPRINT("USBH_SetPdoRegistryParameter ... \n");
225 
226  RtlInitUnicodeString(&ValueNameString, ValueName);
227 
231  &KeyHandle);
232 
233  if (NT_SUCCESS(Status))
234  {
235  ZwSetValueKey(KeyHandle,
236  &ValueNameString,
237  0,
238  Type,
239  Data,
240  DataSize);
241 
243  }
244 
245  return Status;
246 }
247 
248 NTSTATUS
249 NTAPI
251  IN PURB Urb)
252 {
253  KEVENT Event;
255  PIRP Irp;
256  PIO_STACK_LOCATION IoStack;
257  PUSBHUB_URB_TIMEOUT_CONTEXT HubTimeoutContext;
258  BOOLEAN IsWaitTimeout = FALSE;
261 
262  DPRINT("USBH_SyncSubmitUrb: ... \n");
263 
264  Urb->UrbHeader.UsbdDeviceHandle = NULL;
265 
267 
269  DeviceObject,
270  NULL,
271  0,
272  NULL,
273  0,
274  TRUE,
275  &Event,
276  &IoStatusBlock);
277 
278  if (!Irp)
279  {
281  }
282 
283  IoStack = IoGetNextIrpStackLocation(Irp);
284  IoStack->Parameters.Others.Argument1 = Urb;
285 
286  HubTimeoutContext = ExAllocatePoolWithTag(NonPagedPool,
288  USB_HUB_TAG);
289 
290  if (HubTimeoutContext)
291  {
292  RtlZeroMemory(HubTimeoutContext, sizeof(USBHUB_URB_TIMEOUT_CONTEXT));
293 
294  HubTimeoutContext->Irp = Irp;
295  HubTimeoutContext->IsNormalCompleted = FALSE;
296 
297  KeInitializeEvent(&HubTimeoutContext->UrbTimeoutEvent,
299  FALSE);
300 
301  KeInitializeSpinLock(&HubTimeoutContext->UrbTimeoutSpinLock);
302  KeInitializeTimer(&HubTimeoutContext->UrbTimeoutTimer);
303 
304  KeInitializeDpc(&HubTimeoutContext->UrbTimeoutDPC,
306  HubTimeoutContext);
307 
308  DueTime.QuadPart = -5000 * 10000; // Timeout 5 sec.
309 
310  KeSetTimer(&HubTimeoutContext->UrbTimeoutTimer,
311  DueTime,
312  &HubTimeoutContext->UrbTimeoutDPC);
313 
316  HubTimeoutContext,
317  TRUE,
318  TRUE,
319  TRUE);
320 
321  IsWaitTimeout = TRUE;
322  }
323 
325 
326  if (Status == STATUS_PENDING)
327  {
329  Suspended,
330  KernelMode,
331  FALSE,
332  NULL);
333  }
334  else
335  {
337  }
338 
339  if (IsWaitTimeout)
340  {
341  KeWaitForSingleObject(&HubTimeoutContext->UrbTimeoutEvent,
342  Suspended,
343  KernelMode,
344  FALSE,
345  NULL);
346 
347  ExFreePoolWithTag(HubTimeoutContext, USB_HUB_TAG);
348  }
349 
350  return IoStatusBlock.Status;
351 }
352 
353 NTSTATUS
354 NTAPI
356  IN PURB Urb)
357 {
358  PUSBHUB_FDO_EXTENSION HubExtension;
359 
360  DPRINT("USBH_FdoSyncSubmitUrb: FdoDevice - %p, Urb - %p\n",
361  FdoDevice,
362  Urb);
363 
364  HubExtension = FdoDevice->DeviceExtension;
365  return USBH_SyncSubmitUrb(HubExtension->LowerDevice, Urb);
366 }
367 
368 NTSTATUS
369 NTAPI
371  IN PVOID TransferBuffer,
372  IN ULONG BufferLen,
373  IN BOOLEAN IsDeviceToHost,
375  IN BM_REQUEST_TYPE RequestType,
376  IN UCHAR Request,
377  IN USHORT RequestValue,
378  IN USHORT RequestIndex)
379 {
382  PVOID Buffer = NULL;
383  ULONG Length;
385 
386  DPRINT("USBH_Transact: ... \n");
387 
388  if (BufferLen)
389  {
390  Length = ALIGN_DOWN_BY(BufferLen + sizeof(ULONG), sizeof(ULONG));
391 
393 
394  if (!Buffer)
395  {
397  }
398 
400  }
401 
404  USB_HUB_TAG);
405 
406  if (!Urb)
407  {
408  if (Buffer)
409  {
411  }
412 
414  }
415 
417 
418  if (IsDeviceToHost)
419  {
420  if (BufferLen)
421  {
422  RtlZeroMemory(TransferBuffer, BufferLen);
423  }
424 
426  }
427  else
428  {
429  if (BufferLen)
430  {
431  RtlCopyMemory(Buffer, TransferBuffer, BufferLen);
432  }
433 
435  }
436 
437  Urb->Hdr.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
438  Urb->Hdr.Function = Function;
439  Urb->Hdr.UsbdDeviceHandle = NULL;
440 
442  Urb->TransferBuffer = BufferLen != 0 ? Buffer : NULL;
443  Urb->TransferBufferLength = BufferLen;
444  Urb->TransferBufferMDL = NULL;
445  Urb->UrbLink = NULL;
446 
447  Urb->RequestTypeReservedBits = RequestType.B;
448  Urb->Request = Request;
449  Urb->Value = RequestValue;
450  Urb->Index = RequestIndex;
451 
452  Status = USBH_FdoSyncSubmitUrb(HubExtension->Common.SelfDevice, (PURB)Urb);
453 
454  if (IsDeviceToHost && BufferLen)
455  {
456  RtlCopyMemory(TransferBuffer, Buffer, BufferLen);
457  }
458 
459  if (Buffer)
460  {
462  }
463 
465 
466  return Status;
467 }
468 
469 NTSTATUS
470 NTAPI
472  IN USHORT Port)
473 {
475  KEVENT Event;
477  ULONG ResetRetry = 0;
479 
480  DPRINT("USBH_SyncResetPort: Port - %x\n", Port);
481 
482  InterlockedIncrement(&HubExtension->PendingRequestCount);
483 
484  KeWaitForSingleObject(&HubExtension->HubPortSemaphore,
485  Executive,
486  KernelMode,
487  FALSE,
488  NULL);
489 
490  Status = USBH_SyncGetPortStatus(HubExtension,
491  Port,
492  &PortStatus,
494 
495  if (NT_SUCCESS(Status) &&
496  (PortStatus.PortStatus.Usb20PortStatus.CurrentConnectStatus == 0))
497  {
499  goto Exit;
500  }
501 
502  HubExtension->HubFlags |= USBHUB_FDO_FLAG_RESET_PORT_LOCK;
503 
504  while (TRUE)
505  {
506  BM_REQUEST_TYPE RequestType;
507 
509 
510  InterlockedExchangePointer((PVOID)&HubExtension->pResetPortEvent,
511  &Event);
512 
513  RequestType.B = 0;
514  RequestType.Recipient = BMREQUEST_TO_DEVICE;
515  RequestType.Type = BMREQUEST_CLASS;
516  RequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
517 
518  Status = USBH_Transact(HubExtension,
519  NULL,
520  0,
523  RequestType,
526  Port);
527 
528  Timeout.QuadPart = -5000 * 10000;
529 
530  if (!NT_SUCCESS(Status))
531  {
532  InterlockedExchangePointer((PVOID)&HubExtension->pResetPortEvent,
533  NULL);
534 
535  USBH_Wait(10);
536  HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_RESET_PORT_LOCK;
537 
538  goto Exit;
539  }
540 
542  Suspended,
543  KernelMode,
544  FALSE,
545  &Timeout);
546 
547  if (Status != STATUS_TIMEOUT)
548  {
549  break;
550  }
551 
552  Status = USBH_SyncGetPortStatus(HubExtension,
553  Port,
554  &PortStatus,
556 
557  if (!NT_SUCCESS(Status) ||
558  (PortStatus.PortStatus.Usb20PortStatus.CurrentConnectStatus == 0) ||
559  ResetRetry >= USBHUB_RESET_PORT_MAX_RETRY)
560  {
561  InterlockedExchangePointer((PVOID)&HubExtension->pResetPortEvent,
562  NULL);
563 
564  USBH_Wait(10);
565  HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_RESET_PORT_LOCK;
566 
568  goto Exit;
569  }
570 
571  ResetRetry++;
572  }
573 
574  Status = USBH_SyncGetPortStatus(HubExtension,
575  Port,
576  &PortStatus,
578 
579  if ((PortStatus.PortStatus.Usb20PortStatus.CurrentConnectStatus == 0) &&
580  NT_SUCCESS(Status) &&
581  HubExtension->HubFlags & USBHUB_FDO_FLAG_USB20_HUB)
582  {
584  }
585 
586  USBH_Wait(10);
587  HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_RESET_PORT_LOCK;
588 
589 Exit:
590 
591  KeReleaseSemaphore(&HubExtension->HubPortSemaphore,
593  1,
594  FALSE);
595 
596  if (!InterlockedDecrement(&HubExtension->PendingRequestCount))
597  {
598  KeSetEvent(&HubExtension->PendingRequestEvent,
600  FALSE);
601  }
602 
603  return Status;
604 }
605 
606 NTSTATUS
607 NTAPI
610  OUT USB_DEVICE_TYPE * OutDeviceType)
611 {
616  ULONG dummy;
618 
619  DPRINT("USBH_GetDeviceType: ... \n");
620 
621  QueryDeviceInformation = HubExtension->BusInterface.QueryDeviceInformation;
622 
624  {
625  DPRINT1("USBH_GetDeviceType: no QueryDeviceInformation()\n");
626  return STATUS_NOT_IMPLEMENTED;
627  }
628 
630 
631  while (TRUE)
632  {
635  USB_HUB_TAG);
636 
637  if (!DeviceInfo)
638  {
639  DPRINT1("USBH_GetDeviceType: ExAllocatePoolWithTag() failed\n");
641  break;
642  }
643 
645 
646  DeviceInfo->InformationLevel = 0;
647 
648  Status = QueryDeviceInformation(HubExtension->BusInterface.BusContext,
649  DeviceHandle,
650  DeviceInfo,
652  &dummy);
653 
655  {
656  if (NT_SUCCESS(Status))
657  {
658  DeviceType = DeviceInfo->DeviceType;
659  }
660 
662  break;
663  }
664 
667  }
668 
669  if (OutDeviceType)
670  {
671  *OutDeviceType = DeviceType;
672  DPRINT("USBH_GetDeviceType: DeviceType - %x\n", DeviceType);
673  }
674 
675  return Status;
676 }
677 
678 NTSTATUS
679 NTAPI
681  IN PUSB_EXTHUB_INFORMATION_0 HubInfoBuffer)
682 {
683  PUSB_BUSIFFN_GET_EXTENDED_HUB_INFO GetExtendedHubInformation;
684  ULONG dummy = 0;
685 
686  DPRINT("USBHUB_GetExtendedHubInfo: ... \n");
687 
688  GetExtendedHubInformation = HubExtension->BusInterface.GetExtendedHubInformation;
689 
690  return GetExtendedHubInformation(HubExtension->BusInterface.BusContext,
691  HubExtension->LowerPDO,
692  HubInfoBuffer,
693  sizeof(USB_EXTHUB_INFORMATION_0),
694  &dummy);
695 }
696 
698 NTAPI
700 {
702  PUSBHUB_FDO_EXTENSION RootHubExtension;
703 
704  DPRINT("USBH_GetRootHubExtension: HubExtension - %p\n", HubExtension);
705 
706  RootHubExtension = HubExtension;
707 
708  if (HubExtension->LowerPDO != HubExtension->RootHubPdo)
709  {
710  Device = HubExtension->RootHubPdo;
711 
712  do
713  {
714  Device = Device->AttachedDevice;
715  }
716  while (Device->DriverObject != HubExtension->Common.SelfDevice->DriverObject);
717 
718  RootHubExtension = Device->DeviceExtension;
719  }
720 
721  DPRINT("USBH_GetRootHubExtension: RootHubExtension - %p\n", RootHubExtension);
722 
723  return RootHubExtension;
724 }
725 
726 NTSTATUS
727 NTAPI
729  IN OUT PDEVICE_OBJECT * OutPdo1,
730  IN OUT PDEVICE_OBJECT * OutPdo2)
731 {
732  KEVENT Event;
734  PIRP Irp;
735  PIO_STACK_LOCATION IoStack;
737 
738  DPRINT("USBH_SyncGetRootHubPdo: ... \n");
739 
741 
743  DeviceObject,
744  NULL,
745  0,
746  NULL,
747  0,
748  TRUE,
749  &Event,
750  &IoStatusBlock);
751 
752  if (!Irp)
753  {
755  }
756 
757  IoStack = IoGetNextIrpStackLocation(Irp);
758  IoStack->Parameters.Others.Argument1 = OutPdo1;
759  IoStack->Parameters.Others.Argument2 = OutPdo2;
760 
762 
763  if (Status == STATUS_PENDING)
764  {
766  Suspended,
767  KernelMode,
768  FALSE,
769  NULL);
770  }
771  else
772  {
774  }
775 
776  return IoStatusBlock.Status;
777 }
778 
779 NTSTATUS
780 NTAPI
782  IN OUT PULONG OutHubCount)
783 {
784  KEVENT Event;
786  PIRP Irp;
787  PIO_STACK_LOCATION IoStack;
789 
790  DPRINT("USBH_SyncGetHubCount: *OutHubCount - %x\n", *OutHubCount);
791 
793 
795  DeviceObject,
796  NULL,
797  0,
798  NULL,
799  0,
800  TRUE,
801  &Event,
802  &IoStatusBlock);
803 
804  if (!Irp)
805  {
807  }
808 
809  IoStack = IoGetNextIrpStackLocation(Irp);
810  IoStack->Parameters.Others.Argument1 = OutHubCount;
811 
813 
814  if (Status == STATUS_PENDING)
815  {
817  Suspended,
818  KernelMode,
819  FALSE,
820  NULL);
821  }
822  else
823  {
825  }
826 
827  return IoStatusBlock.Status;
828 }
829 
831 NTAPI
833 {
834  PIRP Irp;
835  KEVENT Event;
838  PIO_STACK_LOCATION IoStack;
839 
840  DPRINT("USBH_SyncGetDeviceHandle: ... \n");
841 
843 
844  Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE,
845  DeviceObject,
846  NULL,
847  0,
848  NULL,
849  0,
850  TRUE,
851  &Event,
852  &IoStatusBlock);
853 
854  if (!Irp)
855  {
856  DPRINT1("USBH_SyncGetDeviceHandle: Irp - NULL!\n");
857  return NULL;
858  }
859 
860  IoStack = IoGetNextIrpStackLocation(Irp);
861  IoStack->Parameters.Others.Argument1 = &DeviceHandle;
862 
864  {
866  Suspended,
867  KernelMode,
868  FALSE,
869  NULL);
870  }
871 
872  return DeviceHandle;
873 }
874 
875 NTSTATUS
876 NTAPI
878  IN PUSB_DEVICE_DESCRIPTOR HubDeviceDescriptor)
879 {
880  struct _URB_CONTROL_DESCRIPTOR_REQUEST * Urb;
882 
883  DPRINT("USBH_GetDeviceDescriptor: ... \n");
884 
886  sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
887  USB_HUB_TAG);
888 
889  if (!Urb)
890  {
891  DPRINT1("USBH_SyncGetDeviceHandle: Urb - NULL!\n");
893  }
894 
895  RtlZeroMemory(Urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
896 
898  Urb->Hdr.Length = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
899 
901  Urb->TransferBuffer = HubDeviceDescriptor;
903 
905 
907 
908  return Status;
909 }
910 
911 NTSTATUS
912 NTAPI
914  IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor,
916  IN PULONG OutLength)
917 {
918  PCOMMON_DEVICE_EXTENSION DeviceExtension;
919  struct _URB_CONTROL_DESCRIPTOR_REQUEST * Urb;
921 
922  DPRINT("USBH_SyncGetDeviceConfigurationDescriptor: ... \n");
923 
924  DeviceExtension = DeviceObject->DeviceExtension;
925 
926  if (OutLength)
927  {
928  *OutLength = 0;
929  }
930 
932  sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
933  USB_HUB_TAG);
934 
935  if (!Urb)
936  {
938  }
939 
940  RtlZeroMemory(Urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
941 
943  Urb->Hdr.Length = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
944 
946  Urb->TransferBuffer = ConfigDescriptor;
948 
949  if (DeviceExtension->ExtensionType == USBH_EXTENSION_TYPE_HUB ||
950  DeviceExtension->ExtensionType == USBH_EXTENSION_TYPE_PARENT)
951  {
953  }
954  else
955  {
957  }
958 
959  if (OutLength)
960  {
961  *OutLength = Urb->TransferBufferLength;
962  }
963 
964  if (Urb)
965  {
967  }
968 
969  return Status;
970 }
971 
972 NTSTATUS
973 NTAPI
975  IN PUSB_CONFIGURATION_DESCRIPTOR * OutDescriptor)
976 {
977  PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor;
978  ULONG ReturnedLen;
979  SIZE_T DescriptorLen;
981 
982  DPRINT("USBH_GetConfigurationDescriptor: ... \n");
983 
984  DescriptorLen = MAXUCHAR;
985 
986  while (TRUE)
987  {
988  ConfigDescriptor = ExAllocatePoolWithTag(NonPagedPool,
989  DescriptorLen,
990  USB_HUB_TAG);
991 
992  if (!ConfigDescriptor)
993  {
995  break;
996  }
997 
999  ConfigDescriptor,
1000  DescriptorLen,
1001  &ReturnedLen);
1002 
1003  if (ReturnedLen < sizeof(USB_CONFIGURATION_DESCRIPTOR))
1004  {
1006  }
1007 
1008  if (!NT_SUCCESS(Status))
1009  {
1010  break;
1011  }
1012 
1013  *OutDescriptor = ConfigDescriptor;
1014 
1015  if (ConfigDescriptor->wTotalLength <= DescriptorLen)
1016  {
1017  break;
1018  }
1019 
1020  DescriptorLen = ConfigDescriptor->wTotalLength;
1021 
1022  ExFreePool(ConfigDescriptor);
1023  *OutDescriptor = NULL;
1024  }
1025 
1026  if (NT_SUCCESS(Status))
1027  {
1028  if (ReturnedLen < ConfigDescriptor->wTotalLength)
1029  {
1031  }
1032  }
1033  else
1034  {
1035  if (ConfigDescriptor)
1036  {
1037  ExFreePool(ConfigDescriptor);
1038  }
1039 
1040  *OutDescriptor = NULL;
1041  }
1042 
1043  return Status;
1044 }
1045 
1046 NTSTATUS
1047 NTAPI
1049 {
1050  PUSB_EXTHUB_INFORMATION_0 ExtendedHubInfo;
1051  ULONG NumberPorts;
1052  PUSBHUB_PORT_DATA PortData;
1053  USHORT RequestValue;
1055  NTSTATUS Status;
1056  PUSB_HUB_DESCRIPTOR HubDescriptor = NULL;
1057  ULONG ix;
1058  ULONG Retry;
1059 
1060  DPRINT("USBH_SyncGetHubDescriptor: ... \n");
1061 
1062  ExtendedHubInfo = ExAllocatePoolWithTag(NonPagedPool,
1063  sizeof(USB_EXTHUB_INFORMATION_0),
1064  USB_HUB_TAG);
1065 
1066  if (!ExtendedHubInfo)
1067  {
1069  goto ErrorExit;
1070  }
1071 
1072  RtlZeroMemory(ExtendedHubInfo, sizeof(USB_EXTHUB_INFORMATION_0));
1073 
1074  Status = USBHUB_GetExtendedHubInfo(HubExtension, ExtendedHubInfo);
1075 
1076  if (!NT_SUCCESS(Status))
1077  {
1078  ExFreePoolWithTag(ExtendedHubInfo, USB_HUB_TAG);
1079  ExtendedHubInfo = NULL;
1080  }
1081 
1083 
1084  HubDescriptor = ExAllocatePoolWithTag(NonPagedPool,
1085  NumberOfBytes,
1086  USB_HUB_TAG);
1087 
1088  if (!HubDescriptor)
1089  {
1091  goto ErrorExit;
1092  }
1093 
1094  RtlZeroMemory(HubDescriptor, NumberOfBytes);
1095 
1096  RequestValue = 0;
1097  Retry = 0;
1098 
1099  while (TRUE)
1100  {
1101  while (Retry <= 5)
1102  {
1103  BM_REQUEST_TYPE RequestType;
1104 
1105  RequestType.B = 0;
1106  RequestType.Recipient = BMREQUEST_TO_DEVICE;
1107  RequestType.Type = BMREQUEST_STANDARD;
1108  RequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
1109 
1110  Status = USBH_Transact(HubExtension,
1111  HubDescriptor,
1112  NumberOfBytes,
1115  RequestType,
1117  RequestValue,
1118  0);
1119 
1120  if (NT_SUCCESS(Status))
1121  {
1122  break;
1123  }
1124 
1125  RequestValue = 0x2900; // Hub DescriptorType - 0x29
1126 
1127  Retry++;
1128  }
1129 
1130  if (HubDescriptor->bDescriptorLength <= NumberOfBytes)
1131  {
1132  break;
1133  }
1134 
1135  NumberOfBytes = HubDescriptor->bDescriptorLength;
1136  ExFreePoolWithTag(HubDescriptor, USB_HUB_TAG);
1137 
1138  if (Retry >= 5)
1139  {
1141  HubDescriptor = NULL;
1142  goto ErrorExit;
1143  }
1144 
1145  HubDescriptor = ExAllocatePoolWithTag(NonPagedPool,
1146  NumberOfBytes,
1147  USB_HUB_TAG);
1148 
1149  if (!HubDescriptor)
1150  {
1152  goto ErrorExit;
1153  }
1154 
1155  RtlZeroMemory(HubDescriptor, NumberOfBytes);
1156  }
1157 
1158  NumberPorts = HubDescriptor->bNumberOfPorts;
1159 
1160  if (HubExtension->PortData)
1161  {
1162  PortData = HubExtension->PortData;
1163 
1164  for (ix = 0; ix < NumberPorts; ix++)
1165  {
1166  PortData[ix].PortStatus.AsUlong32 = 0;
1167 
1168  if (ExtendedHubInfo)
1169  {
1170  PortData[ix].PortAttributes = ExtendedHubInfo->Port[ix].PortAttributes;
1171  }
1172  else
1173  {
1174  PortData[ix].PortAttributes = 0;
1175  }
1176 
1177  PortData[ix].ConnectionStatus = NoDeviceConnected;
1178 
1179  if (PortData[ix].DeviceObject != NULL)
1180  {
1181  PortData[ix].ConnectionStatus = DeviceConnected;
1182  }
1183  }
1184  }
1185  else
1186  {
1187  PortData = NULL;
1188 
1189  if (HubDescriptor->bNumberOfPorts)
1190  {
1192  NumberPorts * sizeof(USBHUB_PORT_DATA),
1193  USB_HUB_TAG);
1194  }
1195 
1196  if (!PortData)
1197  {
1199  goto ErrorExit;
1200  }
1201 
1202  RtlZeroMemory(PortData, NumberPorts * sizeof(USBHUB_PORT_DATA));
1203 
1204  for (ix = 0; ix < NumberPorts; ix++)
1205  {
1206  PortData[ix].ConnectionStatus = NoDeviceConnected;
1207 
1208  if (ExtendedHubInfo)
1209  {
1210  PortData[ix].PortAttributes = ExtendedHubInfo->Port[ix].PortAttributes;
1211  }
1212  }
1213  }
1214 
1215  if (!NT_SUCCESS(Status))
1216  {
1217  goto ErrorExit;
1218  }
1219 
1220  HubExtension->HubDescriptor = HubDescriptor;
1221 
1222  HubExtension->PortData = PortData;
1223 
1224  if (ExtendedHubInfo)
1225  {
1226  ExFreePoolWithTag(ExtendedHubInfo, USB_HUB_TAG);
1227  }
1228 
1229  return Status;
1230 
1231 ErrorExit:
1232 
1233  if (HubDescriptor)
1234  {
1235  ExFreePoolWithTag(HubDescriptor, USB_HUB_TAG);
1236  }
1237 
1238  if (ExtendedHubInfo)
1239  {
1240  ExFreePoolWithTag(ExtendedHubInfo, USB_HUB_TAG);
1241  }
1242 
1243  return Status;
1244 }
1245 
1246 NTSTATUS
1247 NTAPI
1249  IN UCHAR Index,
1253  IN PULONG OutLength,
1254  IN BOOLEAN IsValidateLength)
1255 {
1256  struct _URB_CONTROL_DESCRIPTOR_REQUEST * Urb;
1257  ULONG TransferedLength;
1258  NTSTATUS Status;
1259 
1260  DPRINT("USBH_SyncGetStringDescriptor: Index - %x, LanguageId - %x\n",
1261  Index,
1262  LanguageId);
1263 
1265  sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
1266  USB_HUB_TAG);
1267 
1268  if (!Urb)
1269  {
1271  }
1272 
1273  RtlZeroMemory(Urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
1274 
1276  Urb->Hdr.Length = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
1277 
1278  Urb->TransferBuffer = Descriptor;
1280 
1281  Urb->Index = Index;
1283  Urb->LanguageId = LanguageId;
1284 
1286 
1287  if (!NT_SUCCESS(Status))
1288  {
1290  return Status;
1291  }
1292 
1293  TransferedLength = Urb->TransferBufferLength;
1294 
1295  if (TransferedLength > NumberOfBytes)
1296  {
1298  }
1299 
1300  if (!NT_SUCCESS(Status))
1301  {
1303  return Status;
1304  }
1305 
1306  if (OutLength)
1307  {
1308  *OutLength = TransferedLength;
1309  }
1310 
1311  if (IsValidateLength && TransferedLength != Descriptor->bLength)
1312  {
1314  }
1315 
1317 
1318  return Status;
1319 }
1320 
1321 NTSTATUS
1322 NTAPI
1324  IN PUSHORT OutStatus,
1325  IN USHORT Function,
1326  IN USHORT RequestIndex)
1327 {
1328  struct _URB_CONTROL_GET_STATUS_REQUEST * Urb;
1329  NTSTATUS NtStatus;
1330  USHORT UsbStatus;
1331 
1332  DPRINT("USBH_SyncGetStatus: ... \n");
1333 
1335  sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST),
1336  USB_HUB_TAG);
1337 
1338  if (!Urb)
1339  {
1341  }
1342 
1343  RtlZeroMemory(Urb, sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST));
1344 
1345  Urb->Hdr.Length = sizeof(struct _URB_CONTROL_GET_STATUS_REQUEST);
1346  Urb->Hdr.Function = Function;
1347 
1348  Urb->TransferBuffer = &UsbStatus;
1349  Urb->TransferBufferLength = sizeof(UsbStatus);
1350  Urb->Index = RequestIndex;
1351 
1352  NtStatus = USBH_FdoSyncSubmitUrb(DeviceObject, (PURB)Urb);
1353 
1354  *OutStatus = UsbStatus;
1355 
1357 
1358  return NtStatus;
1359 }
1360 
1361 NTSTATUS
1362 NTAPI
1364  IN USHORT Port,
1366  IN ULONG Length)
1367 {
1368  BM_REQUEST_TYPE RequestType;
1369 
1370  DPRINT("USBH_SyncGetPortStatus: Port - %x\n", Port);
1371 
1372  RequestType.B = 0;
1373  RequestType.Recipient = BMREQUEST_TO_OTHER;
1374  RequestType.Type = BMREQUEST_CLASS;
1375  RequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
1376 
1377  return USBH_Transact(HubExtension,
1378  PortStatus,
1379  Length,
1382  RequestType,
1384  0,
1385  Port);
1386 }
1387 
1388 
1389 NTSTATUS
1390 NTAPI
1392  IN USHORT Port,
1393  IN USHORT RequestValue)
1394 {
1395  BM_REQUEST_TYPE RequestType;
1396 
1397  DPRINT("USBH_SyncClearPortStatus: Port - %x, RequestValue - %x\n",
1398  Port,
1399  RequestValue);
1400 
1401  RequestType.B = 0;
1402  RequestType.Recipient = BMREQUEST_TO_DEVICE;
1403  RequestType.Type = BMREQUEST_CLASS;
1404  RequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
1405 
1406  return USBH_Transact(HubExtension,
1407  NULL,
1408  0,
1411  RequestType,
1413  RequestValue,
1414  Port);
1415 }
1416 
1417 NTSTATUS
1418 NTAPI
1420  IN USHORT Port,
1421  IN BOOLEAN IsWait)
1422 {
1423  PUSBHUB_PORT_DATA PortData;
1424  PUSB_HUB_DESCRIPTOR HubDescriptor;
1426  BM_REQUEST_TYPE RequestType;
1428 
1429  DPRINT("USBH_SyncPowerOnPort: Port - %x, IsWait - %x\n", Port, IsWait);
1430 
1431  ASSERT(Port > 0);
1432  PortData = &HubExtension->PortData[Port - 1];
1433  PortStatus = &PortData->PortStatus;
1434 
1435  if (PortStatus->PortStatus.Usb20PortStatus.CurrentConnectStatus == 1)
1436  {
1437  return Status;
1438  }
1439 
1440  RequestType.B = 0;
1441  RequestType.Recipient = BMREQUEST_TO_DEVICE;
1442  RequestType.Type = BMREQUEST_CLASS;
1443  RequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
1444 
1445  Status = USBH_Transact(HubExtension,
1446  NULL,
1447  0,
1450  RequestType,
1453  Port);
1454 
1455  if (NT_SUCCESS(Status))
1456  {
1457  if (IsWait)
1458  {
1459  HubDescriptor = HubExtension->HubDescriptor;
1460  USBH_Wait(2 * HubDescriptor->bPowerOnToPowerGood);
1461  }
1462 
1463  PortStatus->PortStatus.Usb20PortStatus.CurrentConnectStatus = 1;
1464  }
1465 
1466  return Status;
1467 }
1468 
1469 NTSTATUS
1470 NTAPI
1472 {
1473  PUSB_HUB_DESCRIPTOR HubDescriptor;
1475  USHORT Port;
1477 
1478  DPRINT("USBH_SyncPowerOnPorts: ... \n");
1479 
1480  HubDescriptor = HubExtension->HubDescriptor;
1481  NumberOfPorts = HubDescriptor->bNumberOfPorts;
1482 
1483  for (Port = 1; Port <= NumberOfPorts; ++Port)
1484  {
1485  Status = USBH_SyncPowerOnPort(HubExtension, Port, 0);
1486 
1487  if (!NT_SUCCESS(Status))
1488  {
1489  DPRINT1("USBH_SyncPowerOnPorts: USBH_SyncPowerOnPort() failed - %lX\n",
1490  Status);
1491  break;
1492  }
1493  }
1494 
1495  USBH_Wait(2 * HubDescriptor->bPowerOnToPowerGood);
1496 
1497  return Status;
1498 }
1499 
1500 NTSTATUS
1501 NTAPI
1503  IN USHORT Port)
1504 {
1505  PUSBHUB_PORT_DATA PortData;
1506  NTSTATUS Status;
1507  BM_REQUEST_TYPE RequestType;
1508 
1509  DPRINT("USBH_SyncDisablePort ... \n");
1510 
1511  PortData = &HubExtension->PortData[Port - 1];
1512 
1513  RequestType.B = 0;
1514  RequestType.Recipient = BMREQUEST_TO_DEVICE;
1515  RequestType.Type = BMREQUEST_CLASS;
1516  RequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
1517 
1518  Status = USBH_Transact(HubExtension,
1519  NULL,
1520  0,
1523  RequestType,
1526  Port);
1527 
1528  if (NT_SUCCESS(Status))
1529  {
1531  }
1532 
1533  return Status;
1534 }
1535 
1536 BOOLEAN
1537 NTAPI
1539  IN PUSB_CONFIGURATION_DESCRIPTOR HubConfigDescriptor)
1540 {
1541  BOOLEAN Result;
1542  USHORT UsbStatus;
1543  NTSTATUS Status;
1544 
1545  DPRINT("USBH_HubIsBusPowered: ... \n");
1546 
1548  &UsbStatus,
1550  0);
1551 
1552  if (!NT_SUCCESS(Status))
1553  {
1554  Result = (HubConfigDescriptor->bmAttributes & USB_CONFIG_POWERED_MASK)
1556  }
1557  else
1558  {
1559  Result = (UsbStatus & USB_GETSTATUS_SELF_POWERED) == 0;
1560  }
1561 
1562  return Result;
1563 }
1564 
1565 NTSTATUS
1566 NTAPI
1568  IN PIRP Irp,
1569  IN PVOID Context)
1570 {
1571  PUSBHUB_FDO_EXTENSION HubExtension;
1572  PVOID Event;
1573  USHORT Port;
1574 
1575  HubExtension = Context;
1576 
1577  DPRINT_SCE("USBH_ChangeIndicationAckChangeComplete: ... \n");
1578 
1579  ASSERT(HubExtension->Port > 0);
1580  Port = HubExtension->Port - 1;
1581 
1582  HubExtension->PortData[Port].PortStatus = HubExtension->PortStatus;
1583 
1585  NULL);
1586 
1587  if (Event)
1588  {
1590  }
1591 
1592  USBH_SubmitStatusChangeTransfer(HubExtension);
1593 
1594  if (!InterlockedDecrement(&HubExtension->ResetRequestCount))
1595  {
1596  KeSetEvent(&HubExtension->ResetEvent,
1598  FALSE);
1599  }
1600 
1602 }
1603 
1604 NTSTATUS
1605 NTAPI
1607  IN PIRP Irp,
1609  IN USHORT Port,
1610  IN USHORT RequestValue)
1611 {
1612  PIO_STACK_LOCATION IoStack;
1613  BM_REQUEST_TYPE RequestType;
1614 
1615  DPRINT_SCE("USBH_ChangeIndicationAckChange: ... \n");
1616 
1617  Urb->Hdr.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
1618  Urb->Hdr.Function = URB_FUNCTION_CLASS_OTHER;
1619  Urb->Hdr.UsbdDeviceHandle = NULL;
1620 
1621  Urb->TransferFlags = USBD_SHORT_TRANSFER_OK;
1622  Urb->TransferBufferLength = 0;
1623  Urb->TransferBuffer = NULL;
1624  Urb->TransferBufferMDL = NULL;
1625  Urb->UrbLink = NULL;
1626 
1627  RequestType.B = 0;
1628  RequestType.Recipient = BMREQUEST_TO_OTHER;
1629  RequestType.Type = BMREQUEST_CLASS;
1630  RequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
1631 
1632  Urb->RequestTypeReservedBits = RequestType.B;
1633  Urb->Request = USB_REQUEST_CLEAR_FEATURE;
1634  Urb->Index = Port;
1635  Urb->Value = RequestValue;
1636 
1638  IoSizeOfIrp(HubExtension->LowerDevice->StackSize),
1639  HubExtension->LowerDevice->StackSize);
1640 
1641  IoStack = IoGetNextIrpStackLocation(Irp);
1642 
1644  IoStack->Parameters.Others.Argument1 = Urb;
1645  IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
1646 
1649  HubExtension,
1650  TRUE,
1651  TRUE,
1652  TRUE);
1653 
1654  return IoCallDriver(HubExtension->LowerDevice, Irp);
1655 }
1656 
1657 NTSTATUS
1658 NTAPI
1660  IN PIRP Irp,
1661  IN PVOID Context)
1662 {
1663  PUSBHUB_FDO_EXTENSION HubExtension;
1664  PUSBHUB_IO_WORK_ITEM WorkItem;
1665  USHORT RequestValue;
1666 
1667  HubExtension = Context;
1668 
1669  DPRINT_SCE("USBH_ChangeIndicationProcessChange: PortStatus - %lX\n",
1670  HubExtension->PortStatus.AsUlong32);
1671 
1672  if ((NT_SUCCESS(Irp->IoStatus.Status) ||
1673  USBD_SUCCESS(HubExtension->SCEWorkerUrb.Hdr.Status)) &&
1676  {
1677  if (!InterlockedDecrement(&HubExtension->PendingRequestCount))
1678  {
1679  KeSetEvent(&HubExtension->PendingRequestEvent,
1681  FALSE);
1682  }
1683 
1684  USBH_FreeWorkItem(HubExtension->WorkItemToQueue);
1685 
1686  HubExtension->WorkItemToQueue = NULL;
1687 
1689  {
1690  RequestValue = USBHUB_FEATURE_C_PORT_RESET;
1691  }
1692  else
1693  {
1694  RequestValue = USBHUB_FEATURE_C_PORT_ENABLE;
1695  }
1696 
1697  USBH_ChangeIndicationAckChange(HubExtension,
1698  HubExtension->ResetPortIrp,
1699  &HubExtension->SCEWorkerUrb,
1700  HubExtension->Port,
1701  RequestValue);
1702  }
1703  else
1704  {
1705  ASSERT(HubExtension->WorkItemToQueue != NULL);
1706 
1707  WorkItem = HubExtension->WorkItemToQueue;
1708  HubExtension->WorkItemToQueue = NULL;
1709 
1710  USBH_QueueWorkItem(HubExtension, WorkItem);
1711  }
1712 
1714 }
1715 
1716 NTSTATUS
1717 NTAPI
1719  IN PIRP Irp,
1721  IN USHORT Port)
1722 {
1723  PUSBHUB_IO_WORK_ITEM WorkItem;
1724  NTSTATUS Status;
1725  PIO_STACK_LOCATION IoStack;
1726  BM_REQUEST_TYPE RequestType;
1727 
1728  DPRINT_SCE("USBH_ChangeIndicationQueryChange: Port - %x\n", Port);
1729 
1730  InterlockedIncrement(&HubExtension->PendingRequestCount);
1731 
1732  if (!Port)
1733  {
1734  ASSERT(HubExtension->WorkItemToQueue != NULL);
1735 
1736  WorkItem = HubExtension->WorkItemToQueue;
1737  HubExtension->WorkItemToQueue = NULL;
1738 
1739  USBH_QueueWorkItem(HubExtension, WorkItem);
1740 
1741  return STATUS_SUCCESS;
1742  }
1743 
1744  Urb->Hdr.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
1745  Urb->Hdr.UsbdDeviceHandle = NULL;
1746  Urb->Hdr.Function = URB_FUNCTION_CLASS_OTHER;
1747 
1748  Urb->TransferFlags = USBD_SHORT_TRANSFER_OK | USBD_TRANSFER_DIRECTION_IN;
1749  Urb->TransferBuffer = &HubExtension->PortStatus;
1750  Urb->TransferBufferLength = sizeof(HubExtension->PortStatus);
1751  Urb->TransferBufferMDL = NULL;
1752  Urb->UrbLink = NULL;
1753 
1754  RequestType.B = 0;
1755  RequestType.Recipient = BMREQUEST_TO_OTHER;
1756  RequestType.Type = BMREQUEST_CLASS;
1757  RequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
1758 
1759  Urb->RequestTypeReservedBits = RequestType.B;
1760  Urb->Request = USB_REQUEST_GET_STATUS;
1761  Urb->Value = 0;
1762  Urb->Index = Port;
1763 
1764  HubExtension->Port = Port;
1765 
1767  IoSizeOfIrp(HubExtension->LowerDevice->StackSize),
1768  HubExtension->LowerDevice->StackSize);
1769 
1770  IoStack = IoGetNextIrpStackLocation(Irp);
1771 
1773  IoStack->Parameters.Others.Argument1 = Urb;
1774  IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
1775 
1778  HubExtension,
1779  TRUE,
1780  TRUE,
1781  TRUE);
1782 
1783  Status = IoCallDriver(HubExtension->LowerDevice, Irp);
1784 
1785  return Status;
1786 }
1787 
1788 VOID
1789 NTAPI
1791  IN USHORT Port,
1793 {
1794  PUSBHUB_PORT_DATA PortData;
1795  USB_20_PORT_CHANGE PortStatusChange;
1796  PDEVICE_OBJECT PortDevice;
1797  PUSBHUB_PORT_PDO_EXTENSION PortExtension;
1800  USHORT RequestValue;
1801  KIRQL Irql;
1802 
1803  DPRINT_SCE("USBH_ProcessPortStateChange ... \n");
1804 
1805  ASSERT(Port > 0);
1806  PortData = &HubExtension->PortData[Port - 1];
1807 
1808  PortStatusChange = PortStatus->PortChange.Usb20PortChange;
1809 
1810  if (PortStatusChange.ConnectStatusChange)
1811  {
1812  PortData->PortStatus = *PortStatus;
1813 
1814  USBH_SyncClearPortStatus(HubExtension,
1815  Port,
1817 
1818  PortData = &HubExtension->PortData[Port - 1];
1819 
1820  PortDevice = PortData->DeviceObject;
1821 
1822  if (!PortDevice)
1823  {
1824  IoInvalidateDeviceRelations(HubExtension->LowerPDO, BusRelations);
1825  return;
1826  }
1827 
1828  PortExtension = PortDevice->DeviceExtension;
1829 
1830  if (PortExtension->PortPdoFlags & USBHUB_PDO_FLAG_OVERCURRENT_PORT)
1831  {
1832  return;
1833  }
1834 
1835  KeAcquireSpinLock(&HubExtension->RelationsWorkerSpinLock, &Irql);
1836 
1837  if (PortExtension->PortPdoFlags & USBHUB_PDO_FLAG_POWER_D3)
1838  {
1839  KeReleaseSpinLock(&HubExtension->RelationsWorkerSpinLock, Irql);
1840  IoInvalidateDeviceRelations(HubExtension->LowerPDO, BusRelations);
1841  return;
1842  }
1843 
1844  PortData->DeviceObject = NULL;
1845  PortData->ConnectionStatus = NoDeviceConnected;
1846 
1847  HubExtension->HubFlags |= USBHUB_FDO_FLAG_STATE_CHANGING;
1848 
1849  InsertTailList(&HubExtension->PdoList, &PortExtension->PortLink);
1850 
1851  KeReleaseSpinLock(&HubExtension->RelationsWorkerSpinLock, Irql);
1852 
1854  NULL);
1855 
1856  if (SerialNumber)
1857  {
1859  }
1860 
1862  NULL);
1863 
1864  if (DeviceHandle)
1865  {
1866  USBD_RemoveDeviceEx(HubExtension, DeviceHandle, 0);
1867  USBH_SyncDisablePort(HubExtension, Port);
1868  }
1869 
1870  IoInvalidateDeviceRelations(HubExtension->LowerPDO, BusRelations);
1871  }
1872  else if (PortStatusChange.PortEnableDisableChange)
1873  {
1874  RequestValue = USBHUB_FEATURE_C_PORT_ENABLE;
1875  PortData->PortStatus = *PortStatus;
1876  USBH_SyncClearPortStatus(HubExtension, Port, RequestValue);
1877  return;
1878  }
1879  else if (PortStatusChange.SuspendChange)
1880  {
1881  DPRINT1("USBH_ProcessPortStateChange: SuspendChange UNIMPLEMENTED. FIXME\n");
1882  DbgBreakPoint();
1883  }
1884  else if (PortStatusChange.OverCurrentIndicatorChange)
1885  {
1886  DPRINT1("USBH_ProcessPortStateChange: OverCurrentIndicatorChange UNIMPLEMENTED. FIXME\n");
1887  DbgBreakPoint();
1888  }
1889  else if (PortStatusChange.ResetChange)
1890  {
1891  RequestValue = USBHUB_FEATURE_C_PORT_RESET;
1892  PortData->PortStatus = *PortStatus;
1893  USBH_SyncClearPortStatus(HubExtension, Port, RequestValue);
1894  }
1895 }
1896 
1897 NTSTATUS
1898 NTAPI
1901 {
1902  PIRP Irp;
1903  PIO_STACK_LOCATION IoStack;
1904  NTSTATUS Status;
1905  KEVENT Event;
1907 
1908  DPRINT("USBH_GetPortStatus ... \n");
1909 
1910  *PortStatus = 0;
1911 
1913 
1915  HubExtension->LowerDevice,
1916  NULL,
1917  0,
1918  NULL,
1919  0,
1920  TRUE,
1921  &Event,
1922  &IoStatusBlock);
1923 
1924  if (!Irp)
1925  {
1927  }
1928 
1929  IoStack = IoGetNextIrpStackLocation(Irp);
1930  IoStack->Parameters.Others.Argument1 = PortStatus;
1931 
1932  Status = IoCallDriver(HubExtension->LowerDevice, Irp);
1933 
1934  if (Status == STATUS_PENDING)
1935  {
1937  Suspended,
1938  KernelMode,
1939  FALSE,
1940  NULL);
1941  }
1942  else
1943  {
1945  }
1946 
1947  return IoStatusBlock.Status;
1948 }
1949 
1950 NTSTATUS
1951 NTAPI
1953 {
1954  PIRP Irp;
1955  NTSTATUS Status;
1956  KEVENT Event;
1958 
1959  DPRINT("USBH_EnableParentPort ... \n");
1960 
1962 
1964  HubExtension->LowerDevice,
1965  NULL,
1966  0,
1967  NULL,
1968  0,
1969  TRUE,
1970  &Event,
1971  &IoStatusBlock);
1972 
1973  if (!Irp)
1974  {
1976  }
1977 
1978  Status = IoCallDriver(HubExtension->LowerDevice, Irp);
1979 
1980  if (Status == STATUS_PENDING)
1981  {
1983  Suspended,
1984  KernelMode,
1985  FALSE,
1986  NULL);
1987  }
1988  else
1989  {
1991  }
1992 
1993  return IoStatusBlock.Status;
1994 }
1995 
1996 NTSTATUS
1997 NTAPI
1999 {
2000  struct _URB_PIPE_REQUEST * Urb;
2001  NTSTATUS Status;
2002 
2003  DPRINT("USBH_ResetInterruptPipe ... \n");
2004 
2006  sizeof(struct _URB_PIPE_REQUEST),
2007  USB_HUB_TAG);
2008 
2009  if (Urb)
2010  {
2011  RtlZeroMemory(Urb, sizeof(struct _URB_PIPE_REQUEST));
2012 
2013  Urb->Hdr.Length = sizeof(struct _URB_PIPE_REQUEST);
2015  Urb->PipeHandle = HubExtension->PipeInfo.PipeHandle;
2016 
2017  Status = USBH_FdoSyncSubmitUrb(HubExtension->Common.SelfDevice,
2018  (PURB)Urb);
2019 
2021  }
2022  else
2023  {
2025  }
2026 
2027  if (NT_SUCCESS(Status))
2028  {
2029  HubExtension->RequestErrors = 0;
2030  }
2031 
2032  return Status;
2033 }
2034 
2035 NTSTATUS
2036 NTAPI
2038 {
2039  NTSTATUS Status;
2040  ULONG PortStatusFlags = 0;
2041 
2042  DPRINT("USBH_ResetHub: ... \n");
2043 
2044  Status = USBH_GetPortStatus(HubExtension, &PortStatusFlags);
2045 
2046  if (!NT_SUCCESS(Status))
2047  {
2048  return Status;
2049  }
2050 
2051  if (!(PortStatusFlags & USBD_PORT_ENABLED))
2052  {
2053  if (PortStatusFlags & USBD_PORT_CONNECTED)
2054  {
2055  USBH_EnableParentPort(HubExtension);
2056  }
2057  }
2058 
2059  Status = USBH_ResetInterruptPipe(HubExtension);
2060 
2061  return Status;
2062 }
2063 
2064 VOID
2065 NTAPI
2067  IN PVOID Context)
2068 {
2069  PUSBHUB_FDO_EXTENSION LowerHubExtension;
2070  PUSBHUB_PORT_PDO_EXTENSION LowerPortExtension;
2073  NTSTATUS Status;
2074  USHORT Port = 0;
2075 
2076  DPRINT_SCE("USBH_ChangeIndicationWorker ... \n");
2077 
2078  WorkItem = Context;
2079 
2080  KeWaitForSingleObject(&HubExtension->HubSemaphore,
2081  Executive,
2082  KernelMode,
2083  FALSE,
2084  NULL);
2085 
2086  if (HubExtension->HubFlags & USBHUB_FDO_FLAG_DEVICE_STOPPING)
2087  {
2088  KeSetEvent(&HubExtension->StatusChangeEvent,
2090  FALSE);
2091 
2092  goto Exit;
2093  }
2094 
2095  if (!HubExtension->RequestErrors)
2096  {
2097  goto Enum;
2098  }
2099 
2100  DPRINT_SCE("USBH_ChangeIndicationWorker: RequestErrors - %x\n",
2101  HubExtension->RequestErrors);
2102 
2103  if (HubExtension->LowerPDO == HubExtension->RootHubPdo)
2104  {
2105  goto Enum;
2106  }
2107 
2108  LowerPortExtension = HubExtension->LowerPDO->DeviceExtension;
2109 
2110  if (LowerPortExtension->PortPdoFlags & USBHUB_PDO_FLAG_POWER_D1_OR_D2)
2111  {
2112  goto Enum;
2113  }
2114 
2115  LowerHubExtension = LowerPortExtension->HubExtension;
2116 
2117  if (!LowerHubExtension)
2118  {
2119  goto Enum;
2120  }
2121 
2122  Status = USBH_SyncGetPortStatus(LowerHubExtension,
2123  LowerPortExtension->PortNumber,
2124  &PortStatus,
2125  sizeof(USB_PORT_STATUS_AND_CHANGE));
2126 
2127  if (!NT_SUCCESS(Status) ||
2128  !PortStatus.PortStatus.Usb20PortStatus.CurrentConnectStatus)
2129  {
2130  HubExtension->HubFlags |= USBHUB_FDO_FLAG_DEVICE_REMOVED;
2131 
2132  KeSetEvent(&HubExtension->StatusChangeEvent,
2134  FALSE);
2135 
2136  goto Exit;
2137  }
2138 
2139  if (!(HubExtension->HubFlags & USBHUB_FDO_FLAG_ESD_RECOVERING))
2140  {
2141  HubExtension->HubFlags |= USBHUB_FDO_FLAG_ESD_RECOVERING;
2142 
2143  DPRINT1("USBH_ChangeIndicationWorker: USBHUB_FDO_FLAG_ESD_RECOVERING FIXME\n");
2144  DbgBreakPoint();
2145 
2146  goto Exit;
2147  }
2148 
2149 Enum:
2150 
2151  if (WorkItem->IsRequestErrors)
2152  {
2153  USBH_ResetHub(HubExtension);
2154  }
2155  else
2156  {
2157  for (Port = 0;
2158  Port < HubExtension->HubDescriptor->bNumberOfPorts;
2159  Port++)
2160  {
2161  if (IsBitSet((PUCHAR)(WorkItem + 1), Port))
2162  {
2163  break;
2164  }
2165  }
2166 
2167  if (Port)
2168  {
2169  Status = USBH_SyncGetPortStatus(HubExtension,
2170  Port,
2171  &PortStatus,
2172  sizeof(USB_PORT_STATUS_AND_CHANGE));
2173  }
2174  else
2175  {
2176  DPRINT1("USBH_ChangeIndicationWorker: USBH_SyncGetHubStatus() UNIMPLEMENTED. FIXME\n");
2177  DbgBreakPoint();
2179  }
2180 
2181  if (NT_SUCCESS(Status))
2182  {
2183  if (Port)
2184  {
2185  USBH_ProcessPortStateChange(HubExtension,
2186  Port,
2187  &PortStatus);
2188  }
2189  else
2190  {
2191  DPRINT1("USBH_ChangeIndicationWorker: USBH_ProcessHubStateChange() UNIMPLEMENTED. FIXME\n");
2192  DbgBreakPoint();
2193  }
2194  }
2195  else
2196  {
2197  HubExtension->RequestErrors++;
2198 
2199  if (HubExtension->RequestErrors > USBHUB_MAX_REQUEST_ERRORS)
2200  {
2201  HubExtension->HubFlags |= USBHUB_FDO_FLAG_DEVICE_FAILED;
2202  goto Exit;
2203  }
2204  }
2205  }
2206 
2207  USBH_SubmitStatusChangeTransfer(HubExtension);
2208 
2209 Exit:
2210 
2211  KeReleaseSemaphore(&HubExtension->HubSemaphore,
2213  1,
2214  FALSE);
2215 
2216  if (!InterlockedDecrement(&HubExtension->PendingRequestCount))
2217  {
2218  KeSetEvent(&HubExtension->PendingRequestEvent,
2220  FALSE);
2221  }
2222 
2223  if (!InterlockedDecrement((PLONG)&HubExtension->ResetRequestCount))
2224  {
2225  KeSetEvent(&HubExtension->ResetEvent,
2227  FALSE);
2228 
2229  if (HubExtension->HubFlags & USBHUB_FDO_FLAG_DEFER_CHECK_IDLE)
2230  {
2231  USBH_CheckHubIdle(HubExtension);
2232  }
2233  }
2234 }
2235 
2236 NTSTATUS
2237 NTAPI
2239  IN PIRP Irp,
2240  IN PVOID Context)
2241 {
2242  PUSBHUB_FDO_EXTENSION HubExtension;
2243  USBD_STATUS UrbStatus;
2244  BOOLEAN IsErrors = FALSE;
2245  PUSBHUB_IO_WORK_ITEM HubWorkItem;
2246  PUSBHUB_STATUS_CHANGE_CONTEXT HubWorkItemBuffer;
2247  USHORT NumPorts;
2248  USHORT Port;
2249  NTSTATUS Status;
2250  PVOID Bitmap;
2252 
2253  HubExtension = Context;
2254  UrbStatus = HubExtension->SCEWorkerUrb.Hdr.Status;
2255 
2256  DPRINT_SCE("USBH_ChangeIndication: IrpStatus - %x, UrbStatus - %x, HubFlags - %lX\n",
2257  Irp->IoStatus.Status,
2258  UrbStatus,
2259  HubExtension->HubFlags);
2260 
2261  if (NT_ERROR(Irp->IoStatus.Status) || USBD_ERROR(UrbStatus) ||
2262  (HubExtension->HubFlags & USBHUB_FDO_FLAG_DEVICE_FAILED) ||
2263  (HubExtension->HubFlags & USBHUB_FDO_FLAG_DEVICE_STOPPING))
2264  {
2265  HubExtension->RequestErrors++;
2266 
2267  IsErrors = TRUE;
2268 
2269  KeSetEvent(&HubExtension->StatusChangeEvent,
2271  FALSE);
2272 
2273  if (HubExtension->HubFlags & USBHUB_FDO_FLAG_DEVICE_STOPPING ||
2274  HubExtension->HubFlags & USBHUB_FDO_FLAG_DEVICE_FAILED ||
2275  HubExtension->RequestErrors > USBHUB_MAX_REQUEST_ERRORS ||
2276  Irp->IoStatus.Status == STATUS_DELETE_PENDING)
2277  {
2278  DPRINT_SCE("USBH_ChangeIndication: HubExtension->RequestErrors - %x\n",
2279  HubExtension->RequestErrors);
2280 
2282  }
2283 
2284  DPRINT_SCE("USBH_ChangeIndication: HubExtension->RequestErrors - %x\n",
2285  HubExtension->RequestErrors);
2286  }
2287  else
2288  {
2289  HubExtension->RequestErrors = 0;
2290  }
2291 
2293  HubExtension->SCEBitmapLength;
2294 
2295  Status = USBH_AllocateWorkItem(HubExtension,
2296  &HubWorkItem,
2298  BufferLength,
2299  (PVOID *)&HubWorkItemBuffer,
2301 
2302  if (!NT_SUCCESS(Status))
2303  {
2305  }
2306 
2307  RtlZeroMemory(HubWorkItemBuffer, BufferLength);
2308 
2309  HubWorkItemBuffer->IsRequestErrors = FALSE;
2310 
2311  if (IsErrors)
2312  {
2313  HubWorkItemBuffer->IsRequestErrors = TRUE;
2314  }
2315 
2316  if (InterlockedIncrement(&HubExtension->ResetRequestCount) == 1)
2317  {
2318  KeClearEvent(&HubExtension->ResetEvent);
2319  }
2320 
2321  HubWorkItemBuffer->HubExtension = HubExtension;
2322 
2323  HubExtension->WorkItemToQueue = HubWorkItem;
2324 
2325  Bitmap = HubWorkItemBuffer + 1;
2326 
2328  HubExtension->SCEBitmap,
2329  HubExtension->SCEBitmapLength);
2330 
2331  NumPorts = HubExtension->HubDescriptor->bNumberOfPorts;
2332 
2333  for (Port = 0; Port <= NumPorts; ++Port)
2334  {
2335  if (IsBitSet(Bitmap, Port))
2336  {
2337  break;
2338  }
2339  }
2340 
2341  if (Port > NumPorts)
2342  {
2343  Port = 0;
2344  }
2345 
2347  HubExtension->ResetPortIrp,
2348  &HubExtension->SCEWorkerUrb,
2349  Port);
2350 
2351  if (NT_ERROR(Status))
2352  {
2353  HubExtension->HubFlags |= USBHUB_FDO_FLAG_DEVICE_FAILED;
2354  }
2355 
2357 }
2358 
2359 NTSTATUS
2360 NTAPI
2362 {
2363  PIRP Irp;
2364  NTSTATUS Status;
2365  struct _URB_BULK_OR_INTERRUPT_TRANSFER * Urb;
2366  PIO_STACK_LOCATION IoStack;
2367 
2368  DPRINT_SCE("USBH_SubmitStatusChangeTransfer: HubExtension - %p, SCEIrp - %p\n",
2369  HubExtension,
2370  HubExtension->SCEIrp);
2371 
2372  if (HubExtension->HubFlags & USBHUB_FDO_FLAG_NOT_D0_STATE)
2373  {
2374  DPRINT_SCE("USBH_SubmitStatusChangeTransfer: USBHUB_FDO_FLAG_NOT_D0_STATE\n");
2375  DPRINT_SCE("USBH_SubmitStatusChangeTransfer: HubFlags - %lX\n",
2376  HubExtension->HubFlags);
2377 
2379  }
2380 
2381  Irp = HubExtension->SCEIrp;
2382 
2383  if (!Irp)
2384  {
2386  }
2387 
2388  Urb = (struct _URB_BULK_OR_INTERRUPT_TRANSFER *)&HubExtension->SCEWorkerUrb;
2389 
2390  Urb->Hdr.Length = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
2392  Urb->Hdr.UsbdDeviceHandle = NULL;
2393 
2394  Urb->PipeHandle = HubExtension->PipeInfo.PipeHandle;
2396  Urb->TransferBuffer = HubExtension->SCEBitmap;
2397  Urb->TransferBufferLength = HubExtension->SCEBitmapLength;
2398  Urb->TransferBufferMDL = NULL;
2399  Urb->UrbLink = NULL;
2400 
2402  IoSizeOfIrp(HubExtension->LowerDevice->StackSize),
2403  HubExtension->LowerDevice->StackSize);
2404 
2405  IoStack = IoGetNextIrpStackLocation(Irp);
2406 
2408  IoStack->Parameters.Others.Argument1 = &HubExtension->SCEWorkerUrb;
2409  IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
2410 
2413  HubExtension,
2414  TRUE,
2415  TRUE,
2416  TRUE);
2417 
2418  KeClearEvent(&HubExtension->StatusChangeEvent);
2419 
2420  Status = IoCallDriver(HubExtension->LowerDevice, Irp);
2421 
2422  return Status;
2423 }
2424 
2425 NTSTATUS
2426 NTAPI
2428  IN PUSB_DEVICE_HANDLE * OutDeviceHandle,
2429  IN USB_PORT_STATUS UsbPortStatus,
2430  IN USHORT Port)
2431 {
2433  PUSB_BUSIFFN_CREATE_USB_DEVICE CreateUsbDevice;
2434 
2435  DPRINT("USBD_CreateDeviceEx: Port - %x, UsbPortStatus - 0x%04X\n",
2436  Port,
2437  UsbPortStatus.AsUshort16);
2438 
2439  CreateUsbDevice = HubExtension->BusInterface.CreateUsbDevice;
2440 
2441  if (!CreateUsbDevice)
2442  {
2443  return STATUS_NOT_IMPLEMENTED;
2444  }
2445 
2446  HubDeviceHandle = USBH_SyncGetDeviceHandle(HubExtension->LowerDevice);
2447 
2448  return CreateUsbDevice(HubExtension->BusInterface.BusContext,
2449  OutDeviceHandle,
2451  UsbPortStatus.AsUshort16,
2452  Port);
2453 }
2454 
2455 NTSTATUS
2456 NTAPI
2459  IN ULONG Flags)
2460 {
2461  PUSB_BUSIFFN_REMOVE_USB_DEVICE RemoveUsbDevice;
2462 
2463  DPRINT("USBD_RemoveDeviceEx: DeviceHandle - %p, Flags - %X\n",
2464  DeviceHandle,
2465  Flags);
2466 
2467  RemoveUsbDevice = HubExtension->BusInterface.RemoveUsbDevice;
2468 
2469  if (!RemoveUsbDevice)
2470  {
2471  return STATUS_NOT_IMPLEMENTED;
2472  }
2473 
2474  return RemoveUsbDevice(HubExtension->BusInterface.BusContext,
2475  DeviceHandle,
2476  Flags);
2477 }
2478 
2479 NTSTATUS
2480 NTAPI
2487 {
2488  NTSTATUS Status;
2489  PUSB_BUSIFFN_INITIALIZE_USB_DEVICE InitializeUsbDevice;
2490  PUSB_BUSIFFN_GET_USB_DESCRIPTORS GetUsbDescriptors;
2491 
2492  DPRINT("USBD_InitializeDeviceEx: ... \n");
2493 
2494  InitializeUsbDevice = HubExtension->BusInterface.InitializeUsbDevice;
2495  GetUsbDescriptors = HubExtension->BusInterface.GetUsbDescriptors;
2496 
2497  if (!InitializeUsbDevice || !GetUsbDescriptors)
2498  {
2499  return STATUS_NOT_IMPLEMENTED;
2500  }
2501 
2502  Status = InitializeUsbDevice(HubExtension->BusInterface.BusContext,
2503  DeviceHandle);
2504 
2505  if (!NT_SUCCESS(Status))
2506  {
2507  return Status;
2508  }
2509 
2510  return GetUsbDescriptors(HubExtension->BusInterface.BusContext,
2511  DeviceHandle,
2516 }
2517 
2518 VOID
2519 NTAPI
2523 {
2524  PUSB_BUSIFFN_SET_DEVHANDLE_DATA SetDeviceHandleData;
2525 
2526  DPRINT("USBHUB_SetDeviceHandleData ... \n");
2527 
2528  SetDeviceHandleData = HubExtension->BusInterface.SetDeviceHandleData;
2529 
2530  if (!SetDeviceHandleData)
2531  {
2532  return;
2533  }
2534 
2535  SetDeviceHandleData(HubExtension->BusInterface.BusContext,
2536  DeviceHandle,
2537  UsbDevicePdo);
2538 }
2539 
2540 VOID
2541 NTAPI
2543 {
2544  PUSB_BUSIFFN_FLUSH_TRANSFERS FlushTransfers;
2545 
2546  DPRINT("USBHUB_FlushAllTransfers ... \n");
2547 
2548  FlushTransfers = HubExtension->BusInterface.FlushTransfers;
2549 
2550  if (FlushTransfers)
2551  {
2552  FlushTransfers(HubExtension->BusInterface.BusContext, NULL);
2553  }
2554 }
2555 
2556 NTSTATUS
2557 NTAPI
2559  IN PUSBHUB_FDO_EXTENSION HubExtension,
2560  IN PUSB_NODE_CONNECTION_INFORMATION_EX Info,
2561  IN ULONG Length,
2563 {
2566  SIZE_T DeviceInfoLength;
2567  PUSB_NODE_CONNECTION_INFORMATION_EX NodeInfo;
2568  SIZE_T NodeInfoLength;
2569  ULONG PipeNumber;
2570  ULONG dummy;
2571  NTSTATUS Status;
2572 
2573  DPRINT("USBD_GetDeviceInformationEx ... \n");
2574 
2575  QueryDeviceInformation = HubExtension->BusInterface.QueryDeviceInformation;
2576 
2578  {
2580  return Status;
2581  }
2582 
2583  DeviceInfoLength = sizeof(USB_DEVICE_INFORMATION_0);
2584 
2585  while (TRUE)
2586  {
2588  DeviceInfoLength,
2589  USB_HUB_TAG);
2590 
2591  if (!DeviceInfo)
2592  {
2594  }
2595 
2596  RtlZeroMemory(DeviceInfo, DeviceInfoLength);
2597 
2598  DeviceInfo->InformationLevel = 0;
2599 
2600  Status = QueryDeviceInformation(HubExtension->BusInterface.BusContext,
2601  DeviceHandle,
2602  DeviceInfo,
2603  DeviceInfoLength,
2604  &dummy);
2605 
2607  {
2608  break;
2609  }
2610 
2611  DeviceInfoLength = DeviceInfo->ActualLength;
2612 
2614  }
2615 
2616  NodeInfo = NULL;
2617  NodeInfoLength = 0;
2618 
2619  if (NT_SUCCESS(Status))
2620  {
2621  NodeInfoLength = (sizeof(USB_NODE_CONNECTION_INFORMATION_EX) - sizeof(USB_PIPE_INFO)) +
2622  DeviceInfo->NumberOfOpenPipes * sizeof(USB_PIPE_INFO);
2623 
2624  NodeInfo = ExAllocatePoolWithTag(PagedPool, NodeInfoLength, USB_HUB_TAG);
2625 
2626  if (!NodeInfo)
2627  {
2630  }
2631 
2632  RtlZeroMemory(NodeInfo, NodeInfoLength);
2633 
2634  NodeInfo->ConnectionIndex = Info->ConnectionIndex;
2635 
2636  RtlCopyMemory(&NodeInfo->DeviceDescriptor,
2637  &DeviceInfo->DeviceDescriptor,
2638  sizeof(USB_DEVICE_DESCRIPTOR));
2639 
2640  NodeInfo->CurrentConfigurationValue = DeviceInfo->CurrentConfigurationValue;
2641  NodeInfo->Speed = DeviceInfo->DeviceSpeed;
2642  NodeInfo->DeviceIsHub = PortExtension->PortPdoFlags & USBHUB_PDO_FLAG_HUB_DEVICE;
2643  NodeInfo->DeviceAddress = DeviceInfo->DeviceAddress;
2644  NodeInfo->NumberOfOpenPipes = DeviceInfo->NumberOfOpenPipes;
2645  NodeInfo->ConnectionStatus = Info->ConnectionStatus;
2646 
2647  for (PipeNumber = 0;
2648  PipeNumber < DeviceInfo->NumberOfOpenPipes;
2649  PipeNumber++)
2650  {
2651  RtlCopyMemory(&NodeInfo->PipeList[PipeNumber],
2652  &DeviceInfo->PipeList[PipeNumber],
2653  sizeof(USB_PIPE_INFO));
2654  }
2655  }
2656 
2658 
2659  if (NodeInfo)
2660  {
2661  if (NodeInfoLength <= Length)
2662  {
2663  Length = NodeInfoLength;
2664  }
2665  else
2666  {
2668  }
2669 
2670  RtlCopyMemory(Info, NodeInfo, Length);
2671 
2672  ExFreePoolWithTag(NodeInfo, USB_HUB_TAG);
2673  }
2674 
2675  return Status;
2676 }
2677 
2678 NTSTATUS
2679 NTAPI
2683 {
2684  PUSB_BUSIFFN_RESTORE_DEVICE RestoreUsbDevice;
2685  NTSTATUS Status;
2686 
2687  DPRINT("USBD_RestoreDeviceEx: HubExtension - %p, OldDeviceHandle - %p, NewDeviceHandle - %p\n",
2688  HubExtension,
2690  NewDeviceHandle);
2691 
2692  RestoreUsbDevice = HubExtension->BusInterface.RestoreUsbDevice;
2693 
2694  if (RestoreUsbDevice)
2695  {
2696  Status = RestoreUsbDevice(HubExtension->BusInterface.BusContext,
2698  NewDeviceHandle);
2699  }
2700  else
2701  {
2703  }
2704 
2705  return Status;
2706 }
2707 
2708 NTSTATUS
2709 NTAPI
2711  PUSBHUB_IO_WORK_ITEM * OutHubIoWorkItem,
2714  PVOID * OutHubWorkItemBuffer,
2716 {
2717  PUSBHUB_IO_WORK_ITEM HubIoWorkItem;
2718  PIO_WORKITEM WorkItem;
2719  PVOID WorkItemBuffer;
2720 
2721  DPRINT("USBH_AllocateWorkItem: ... \n");
2722 
2723  if (!(HubExtension->HubFlags & USBHUB_FDO_FLAG_WITEM_INIT))
2724  {
2725  return STATUS_INVALID_PARAMETER;
2726  }
2727 
2728  HubIoWorkItem = ExAllocatePoolWithTag(NonPagedPool,
2729  sizeof(USBHUB_IO_WORK_ITEM),
2730  USB_HUB_TAG);
2731 
2732  if (!HubIoWorkItem)
2733  {
2735  }
2736 
2737  RtlZeroMemory(HubIoWorkItem, sizeof(USBHUB_IO_WORK_ITEM));
2738 
2739  WorkItem = IoAllocateWorkItem(HubExtension->Common.SelfDevice);
2740 
2741  HubIoWorkItem->HubWorkItem = WorkItem;
2742 
2743  if (!WorkItem)
2744  {
2745  ExFreePoolWithTag(HubIoWorkItem, USB_HUB_TAG);
2747  }
2748 
2749  if (BufferLength && OutHubWorkItemBuffer)
2750  {
2751  WorkItemBuffer = ExAllocatePoolWithTag(NonPagedPool,
2752  BufferLength,
2753  USB_HUB_TAG);
2754 
2755  HubIoWorkItem->HubWorkItemBuffer = WorkItemBuffer;
2756 
2757  if (!WorkItemBuffer)
2758  {
2759  IoFreeWorkItem(HubIoWorkItem->HubWorkItem);
2760  ExFreePoolWithTag(HubIoWorkItem, USB_HUB_TAG);
2761 
2763  }
2764 
2765  RtlZeroMemory(WorkItemBuffer, BufferLength);
2766  }
2767  else
2768  {
2769  HubIoWorkItem->HubWorkItemBuffer = NULL;
2770  }
2771 
2772  HubIoWorkItem->HubWorkItemType = Type;
2773  HubIoWorkItem->HubExtension = HubExtension;
2774  HubIoWorkItem->HubWorkerRoutine = WorkerRoutine;
2775 
2776  if (OutHubIoWorkItem)
2777  {
2778  *OutHubIoWorkItem = HubIoWorkItem;
2779  }
2780 
2781  if (OutHubWorkItemBuffer)
2782  {
2783  *OutHubWorkItemBuffer = HubIoWorkItem->HubWorkItemBuffer;
2784  }
2785 
2786  return STATUS_SUCCESS;
2787 }
2788 
2789 VOID
2790 NTAPI
2792  IN PVOID Context)
2793 {
2794  PUSBHUB_IO_WORK_ITEM HubIoWorkItem;
2795  PUSBHUB_FDO_EXTENSION HubExtension;
2796  KIRQL OldIrql;
2797  PIO_WORKITEM WorkItem;
2798 
2799  DPRINT("USBH_Worker: HubIoWorkItem - %p\n", Context);
2800 
2801  HubIoWorkItem = Context;
2802 
2803  InterlockedDecrement(&HubIoWorkItem->HubWorkerQueued);
2804 
2805  HubExtension = HubIoWorkItem->HubExtension;
2806  WorkItem = HubIoWorkItem->HubWorkItem;
2807 
2808  HubIoWorkItem->HubWorkerRoutine(HubIoWorkItem->HubExtension,
2809  HubIoWorkItem->HubWorkItemBuffer);
2810 
2811  KeAcquireSpinLock(&HubExtension->WorkItemSpinLock, &OldIrql);
2812  RemoveEntryList(&HubIoWorkItem->HubWorkItemLink);
2813  KeReleaseSpinLock(&HubExtension->WorkItemSpinLock, OldIrql);
2814 
2815  if (HubIoWorkItem->HubWorkItemBuffer)
2816  {
2818  }
2819 
2820  ExFreePoolWithTag(HubIoWorkItem, USB_HUB_TAG);
2821 
2822  if (!InterlockedDecrement(&HubExtension->PendingRequestCount))
2823  {
2824  KeSetEvent(&HubExtension->PendingRequestEvent,
2826  FALSE);
2827  }
2828 
2829  IoFreeWorkItem(WorkItem);
2830 
2831  DPRINT("USBH_Worker: HubIoWorkItem %p complete\n", Context);
2832 }
2833 
2834 VOID
2835 NTAPI
2837  IN PUSBHUB_IO_WORK_ITEM HubIoWorkItem)
2838 {
2839  DPRINT("USBH_QueueWorkItem: ... \n");
2840 
2841  InterlockedIncrement(&HubExtension->PendingRequestCount);
2842  InterlockedIncrement(&HubIoWorkItem->HubWorkerQueued);
2843 
2844  ExInterlockedInsertTailList(&HubExtension->WorkItemList,
2845  &HubIoWorkItem->HubWorkItemLink,
2846  &HubExtension->WorkItemSpinLock);
2847 
2848  IoQueueWorkItem(HubIoWorkItem->HubWorkItem,
2849  USBH_Worker,
2850  HubIoWorkItem->HubWorkItemType,
2851  HubIoWorkItem);
2852 }
2853 
2854 VOID
2855 NTAPI
2857 {
2858  PIO_WORKITEM WorkItem;
2859 
2860  DPRINT("USBH_FreeWorkItem: ... \n");
2861 
2862  WorkItem = HubIoWorkItem->HubWorkItem;
2863 
2864  if (HubIoWorkItem->HubWorkItemBuffer)
2865  {
2866  ExFreePoolWithTag(HubIoWorkItem->HubWorkItemBuffer, USB_HUB_TAG);
2867  }
2868 
2869  ExFreePoolWithTag(HubIoWorkItem, USB_HUB_TAG);
2870 
2871  IoFreeWorkItem(WorkItem);
2872 }
2873 
2874 VOID
2875 NTAPI
2877 {
2878  PUSBHUB_FDO_EXTENSION HubExtension;
2879 
2880  DPRINT("USBHUB_RootHubCallBack: ... \n");
2881 
2882  HubExtension = Context;
2883 
2884  if (HubExtension->SCEIrp)
2885  {
2886  HubExtension->HubFlags |= (USBHUB_FDO_FLAG_DO_ENUMERATION |
2888 
2889  USBH_SubmitStatusChangeTransfer(HubExtension);
2890 
2892  }
2893  else
2894  {
2895  HubExtension->HubFlags |= USBHUB_FDO_FLAG_DO_ENUMERATION;
2896  }
2897 
2898  KeSetEvent(&HubExtension->RootHubNotificationEvent,
2900  FALSE);
2901 }
2902 
2903 NTSTATUS
2904 NTAPI
2906 {
2907  PUSB_BUSIFFN_ROOTHUB_INIT_NOTIFY RootHubInitNotification;
2908 
2909  DPRINT("USBD_RegisterRootHubCallBack: ... \n");
2910 
2911  RootHubInitNotification = HubExtension->BusInterface.RootHubInitNotification;
2912 
2913  if (!RootHubInitNotification)
2914  {
2915  return STATUS_NOT_IMPLEMENTED;
2916  }
2917 
2918  KeClearEvent(&HubExtension->RootHubNotificationEvent);
2919 
2920  return RootHubInitNotification(HubExtension->BusInterface.BusContext,
2921  HubExtension,
2923 }
2924 
2925 NTSTATUS
2926 NTAPI
2928 {
2929  PUSB_BUSIFFN_ROOTHUB_INIT_NOTIFY RootHubInitNotification;
2930  NTSTATUS Status;
2931 
2932  DPRINT("USBD_UnRegisterRootHubCallBack ... \n");
2933 
2934  RootHubInitNotification = HubExtension->BusInterface.RootHubInitNotification;
2935 
2936  if (!RootHubInitNotification)
2937  {
2938  return STATUS_NOT_IMPLEMENTED;
2939  }
2940 
2941  Status = RootHubInitNotification(HubExtension->BusInterface.BusContext,
2942  NULL,
2943  NULL);
2944 
2945  if (!NT_SUCCESS(Status))
2946  {
2947  KeWaitForSingleObject(&HubExtension->RootHubNotificationEvent,
2948  Executive,
2949  KernelMode,
2950  FALSE,
2951  NULL);
2952  }
2953 
2954  return Status;
2955 }
2956 
2957 VOID
2958 NTAPI
2962  IN PVOID Context,
2964 {
2965  DPRINT("USBH_HubSetDWakeCompletion: ... \n");
2967 }
2968 
2969 VOID
2970 NTAPI
2972  IN PLIST_ENTRY IdleList)
2973 {
2974  PDEVICE_OBJECT PortDevice;
2975  PUSBHUB_PORT_PDO_EXTENSION PortExtension;
2976  PIRP IdleIrp;
2977  PIRP HubIdleIrp;
2978  ULONG NumPorts;
2979  ULONG Port;
2980  KIRQL Irql;
2981 
2982  DPRINT("USBH_HubQueuePortIdleIrps ... \n");
2983 
2984  InitializeListHead(IdleList);
2985 
2987 
2988  NumPorts = HubExtension->HubDescriptor->bNumberOfPorts;
2989 
2990  for (Port = 0; Port < NumPorts; ++Port)
2991  {
2992  PortDevice = HubExtension->PortData[Port].DeviceObject;
2993 
2994  if (PortDevice)
2995  {
2996  PortExtension = PortDevice->DeviceExtension;
2997 
2998  IdleIrp = PortExtension->IdleNotificationIrp;
2999  PortExtension->IdleNotificationIrp = NULL;
3000 
3001  if (IdleIrp && IoSetCancelRoutine(IdleIrp, NULL))
3002  {
3003  DPRINT1("USBH_HubQueuePortIdleIrps: IdleIrp != NULL. FIXME\n");
3004  DbgBreakPoint();
3005  }
3006  }
3007  }
3008 
3009  if (HubExtension->HubFlags & USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST)
3010  {
3011  HubIdleIrp = HubExtension->PendingIdleIrp;
3012  HubExtension->PendingIdleIrp = NULL;
3013  }
3014  else
3015  {
3016  HubIdleIrp = NULL;
3017  }
3018 
3020 
3021  if (HubIdleIrp)
3022  {
3023  USBH_HubCancelIdleIrp(HubExtension, HubIdleIrp);
3024  }
3025 }
3026 
3027 VOID
3028 NTAPI
3030  IN PLIST_ENTRY IdleList,
3031  IN NTSTATUS NtStatus)
3032 {
3033  DPRINT("USBH_HubCompleteQueuedPortIdleIrps ... \n");
3034 
3035  while (!IsListEmpty(IdleList))
3036  {
3037  DPRINT1("USBH_HubCompleteQueuedPortIdleIrps: IdleList not Empty. FIXME\n");
3038  DbgBreakPoint();
3039  }
3040 }
3041 
3042 VOID
3043 NTAPI
3045 {
3046  PDEVICE_OBJECT PortDevice;
3047  PUSBHUB_PORT_PDO_EXTENSION PortExtension;
3049  ULONG Port;
3050 
3051  DPRINT("USBH_FlushPortPwrList ... \n");
3052 
3053  InterlockedIncrement((PLONG)&HubExtension->PendingRequestCount);
3054 
3055  KeWaitForSingleObject(&HubExtension->ResetDeviceSemaphore,
3056  Executive,
3057  KernelMode,
3058  FALSE,
3059  NULL);
3060 
3061  for (Port = 0; Port < HubExtension->HubDescriptor->bNumberOfPorts; ++Port)
3062  {
3063  PortDevice = HubExtension->PortData[Port].DeviceObject;
3064 
3065  if (!PortDevice)
3066  {
3067  continue;
3068  }
3069 
3070  PortExtension = PortDevice->DeviceExtension;
3071 
3072  InterlockedExchange((PLONG)&PortExtension->StateBehindD2, 0);
3073 
3074  while (TRUE)
3075  {
3077  &PortExtension->PortPowerListSpinLock);
3078 
3079  if (!Entry)
3080  {
3081  break;
3082  }
3083 
3084  DPRINT1("USBH_FlushPortPwrList: PortPowerList FIXME\n");
3085  DbgBreakPoint();
3086  }
3087  }
3088 
3089  KeReleaseSemaphore(&HubExtension->ResetDeviceSemaphore,
3091  1,
3092  FALSE);
3093 
3094  if (!InterlockedDecrement((PLONG)&HubExtension->PendingRequestCount))
3095  {
3096  KeSetEvent(&HubExtension->PendingRequestEvent,
3098  FALSE);
3099  }
3100 }
3101 
3102 VOID
3103 NTAPI
3105  IN NTSTATUS NtStatus)
3106 {
3107  LIST_ENTRY IdleList;
3108 
3109  DPRINT("USBH_HubCompletePortIdleIrps ... \n");
3110 
3111  if (HubExtension->HubFlags & USBHUB_FDO_FLAG_DEVICE_STARTED)
3112  {
3113  USBH_HubQueuePortIdleIrps(HubExtension, &IdleList);
3114 
3116  &IdleList,
3117  NtStatus);
3118 
3119  USBH_FlushPortPwrList(HubExtension);
3120  }
3121 }
3122 
3123 VOID
3124 NTAPI
3126  IN PIRP IdleIrp)
3127 {
3128  DPRINT("USBH_HubCancelIdleIrp ... \n");
3129 
3130  IoCancelIrp(IdleIrp);
3131 
3132  if (InterlockedExchange(&HubExtension->IdleRequestLock, 1))
3133  {
3134  IoFreeIrp(IdleIrp);
3135  }
3136 }
3137 
3138 BOOLEAN
3139 NTAPI
3141  IN BOOLEAN IsWait,
3142  IN BOOLEAN IsExtCheck)
3143 {
3144  PDEVICE_OBJECT PdoDevice;
3145  PUSBHUB_PORT_PDO_EXTENSION PortExtension;
3146  PUSBHUB_PORT_DATA PortData;
3147  ULONG Port;
3148  BOOLEAN Result = FALSE;
3149 
3150  DPRINT("USBH_CheckIdleAbort: ... \n");
3151 
3152  InterlockedIncrement(&HubExtension->PendingRequestCount);
3153 
3154  if (IsWait == TRUE)
3155  {
3156  KeWaitForSingleObject(&HubExtension->ResetDeviceSemaphore,
3157  Executive,
3158  KernelMode,
3159  FALSE,
3160  NULL);
3161  }
3162 
3163  PortData = HubExtension->PortData;
3164 
3165  for (Port = 0; Port < HubExtension->HubDescriptor->bNumberOfPorts; Port++)
3166  {
3167  PdoDevice = PortData[Port].DeviceObject;
3168 
3169  if (PdoDevice)
3170  {
3171  PortExtension = PdoDevice->DeviceExtension;
3172 
3173  if (PortExtension->PoRequestCounter)
3174  {
3175  Result = TRUE;
3176  goto Wait;
3177  }
3178  }
3179  }
3180 
3181  if (IsExtCheck == TRUE)
3182  {
3183  PortData = HubExtension->PortData;
3184 
3185  for (Port = 0;
3186  Port < HubExtension->HubDescriptor->bNumberOfPorts;
3187  Port++)
3188  {
3189  PdoDevice = PortData[Port].DeviceObject;
3190 
3191  if (PdoDevice)
3192  {
3193  PortExtension = PdoDevice->DeviceExtension;
3194  InterlockedExchange(&PortExtension->StateBehindD2, 0);
3195  }
3196  }
3197  }
3198 
3199 Wait:
3200 
3201  if (IsWait == TRUE)
3202  {
3203  KeReleaseSemaphore(&HubExtension->ResetDeviceSemaphore,
3205  1,
3206  FALSE);
3207  }
3208 
3209  if (!InterlockedDecrement(&HubExtension->PendingRequestCount))
3210  {
3211  KeSetEvent(&HubExtension->PendingRequestEvent,
3213  FALSE);
3214  }
3215 
3216  return Result;
3217 }
3218 
3219 VOID
3220 NTAPI
3224  IN PVOID Context,
3226 {
3227  DPRINT("USBH_FdoWaitWakeIrpCompletion ... \n");
3228 }
3229 
3230 NTSTATUS
3231 NTAPI
3233 {
3235  NTSTATUS Status;
3236  PIRP Irp = NULL;
3237  KIRQL Irql;
3238 
3239  DPRINT("USBH_FdoSubmitWaitWakeIrp: ... \n");
3240 
3241  PowerState.SystemState = HubExtension->SystemWake;
3242  HubExtension->HubFlags |= USBHUB_FDO_FLAG_PENDING_WAKE_IRP;
3243 
3244  InterlockedIncrement(&HubExtension->PendingRequestCount);
3245  InterlockedExchange(&HubExtension->FdoWaitWakeLock, 0);
3246 
3247  Status = PoRequestPowerIrp(HubExtension->LowerPDO,
3249  PowerState,
3251  HubExtension,
3252  &Irp);
3253 
3255 
3256  if (Status == STATUS_PENDING)
3257  {
3258  if (HubExtension->HubFlags & USBHUB_FDO_FLAG_PENDING_WAKE_IRP)
3259  {
3260  HubExtension->PendingWakeIrp = Irp;
3261  DPRINT("USBH_FdoSubmitWaitWakeIrp: PendingWakeIrp - %p\n",
3262  HubExtension->PendingWakeIrp);
3263  }
3264  }
3265  else
3266  {
3267  HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_PENDING_WAKE_IRP;
3268 
3269  if (!InterlockedDecrement(&HubExtension->PendingRequestCount))
3270  {
3271  KeSetEvent(&HubExtension->PendingRequestEvent,
3273  FALSE);
3274  }
3275  }
3276 
3278 
3279  return Status;
3280 }
3281 
3282 VOID
3283 NTAPI
3285 {
3286  PUSBHUB_FDO_EXTENSION HubExtension;
3287  PUSBHUB_PORT_DATA PortData;
3288  PDEVICE_OBJECT PortDevice;
3289  PUSBHUB_PORT_PDO_EXTENSION PortExtension;
3290  PIRP Irp = NULL;
3291  PIRP IdleIrp;
3293  KEVENT Event;
3294  ULONG Port;
3295  PIO_STACK_LOCATION IoStack;
3296  PUSB_IDLE_CALLBACK_INFO CallbackInfo;
3297  BOOLEAN IsReady;
3298  KIRQL OldIrql;
3299  NTSTATUS Status;
3300 
3301  HubExtension = Context;
3302 
3303  DPRINT("USBH_FdoIdleNotificationCallback: HubExtension - %p, HubFlags - %lX\n",
3304  HubExtension,
3305  HubExtension->HubFlags);
3306 
3307  if (HubExtension->HubFlags & (USBHUB_FDO_FLAG_ENUM_POST_RECOVER |
3314  {
3315  DbgBreakPoint();
3316  return;
3317  }
3318 
3319  HubExtension->HubFlags |= USBHUB_FDO_FLAG_GOING_IDLE;
3320 
3321  if (!(HubExtension->HubFlags & USBHUB_FDO_FLAG_PENDING_WAKE_IRP))
3322  {
3323  Status = USBH_FdoSubmitWaitWakeIrp(HubExtension);
3324 
3325  if (Status != STATUS_PENDING)
3326  {
3327  DPRINT("Status != STATUS_PENDING. DbgBreakPoint()\n");
3328  DbgBreakPoint();
3329  HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_GOING_IDLE;
3330  return;
3331  }
3332  }
3333 
3334  InterlockedIncrement(&HubExtension->PendingRequestCount);
3335 
3337  Executive,
3338  KernelMode,
3339  FALSE,
3340  NULL);
3341 
3342  PortData = HubExtension->PortData;
3343  IsReady = TRUE;
3344 
3345  for (Port = 0;
3346  Port < HubExtension->HubDescriptor->bNumberOfPorts;
3347  Port++)
3348  {
3349  PortDevice = PortData[Port].DeviceObject;
3350 
3351  if (PortDevice)
3352  {
3353  PortExtension = PortDevice->DeviceExtension;
3354 
3355  IdleIrp = PortExtension->IdleNotificationIrp;
3356 
3357  if (!IdleIrp)
3358  {
3359  IsReady = FALSE;
3360  goto IdleHub;
3361  }
3362 
3363  IoStack = IoGetCurrentIrpStackLocation(IdleIrp);
3364 
3365  CallbackInfo = IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
3366 
3367  if (!CallbackInfo)
3368  {
3369  IsReady = FALSE;
3370  goto IdleHub;
3371  }
3372 
3373  if (!CallbackInfo->IdleCallback)
3374  {
3375  IsReady = FALSE;
3376  goto IdleHub;
3377  }
3378 
3379  if (PortExtension->PendingSystemPoRequest)
3380  {
3381  IsReady = FALSE;
3382  goto IdleHub;
3383  }
3384 
3385  if (InterlockedCompareExchange(&PortExtension->StateBehindD2,
3386  1,
3387  0))
3388  {
3389  IsReady = FALSE;
3390  goto IdleHub;
3391  }
3392 
3393  DPRINT("USBH_FdoIdleNotificationCallback: IdleContext - %p\n",
3394  CallbackInfo->IdleContext);
3395 
3396  CallbackInfo->IdleCallback(CallbackInfo->IdleContext);
3397 
3398  if (PortExtension->CurrentPowerState.DeviceState == PowerDeviceD0)
3399  {
3400  IsReady = FALSE;
3401  goto IdleHub;
3402  }
3403  }
3404  }
3405 
3406  if (!(HubExtension->HubFlags & USBHUB_FDO_FLAG_DEVICE_STOPPING) &&
3407  (USBH_CheckIdleAbort(HubExtension, FALSE, FALSE) == TRUE))
3408  {
3409  IsReady = FALSE;
3410  }
3411 
3412 IdleHub:
3413 
3416  1,
3417  FALSE);
3418 
3419  if (!InterlockedDecrement(&HubExtension->PendingRequestCount))
3420  {
3421  KeSetEvent(&HubExtension->PendingRequestEvent,
3423  FALSE);
3424  }
3425 
3426  if (!IsReady ||
3427  (HubExtension->HubFlags & USBHUB_FDO_FLAG_DEVICE_SUSPENDED))
3428  {
3429  DPRINT1("USBH_FdoIdleNotificationCallback: HubFlags - %lX\n",
3430  HubExtension->HubFlags);
3431 
3432  HubExtension->HubFlags &= ~(USBHUB_FDO_FLAG_DEVICE_SUSPENDED |
3434 
3435  /* Aborting Idle for Hub */
3437 
3438  if (HubExtension->PendingIdleIrp)
3439  {
3440  Irp = HubExtension->PendingIdleIrp;
3441  HubExtension->PendingIdleIrp = NULL;
3442  }
3443 
3445 
3446  if (Irp)
3447  {
3448  USBH_HubCancelIdleIrp(HubExtension, Irp);
3449  }
3450 
3451  DbgBreakPoint();
3453  }
3454  else
3455  {
3456  PowerState.DeviceState = HubExtension->DeviceWake;
3457 
3458  KeWaitForSingleObject(&HubExtension->IdleSemaphore,
3459  Executive,
3460  KernelMode,
3461  FALSE,
3462  NULL);
3463 
3464  HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_GOING_IDLE;
3465  HubExtension->HubFlags |= USBHUB_FDO_FLAG_DO_SUSPENSE;
3466 
3468 
3469  DPRINT("USBH_FdoIdleNotificationCallback: LowerPdo - %p\n",
3470  HubExtension->LowerPDO);
3471 
3472  DPRINT("USBH_FdoIdleNotificationCallback: PowerState.DeviceState - %x\n",
3474 
3475  Status = PoRequestPowerIrp(HubExtension->LowerPDO,
3477  PowerState,
3479  &Event,
3480  NULL);
3481 
3482  if (Status == STATUS_PENDING)
3483  {
3485  Executive,
3486  KernelMode,
3487  FALSE,
3488  NULL);
3489  }
3490  }
3491 }
3492 
3493 VOID
3494 NTAPI
3496  IN PVOID Context)
3497 {
3498  PUSBHUB_IDLE_PORT_CONTEXT IdlePortContext;
3499  NTSTATUS NtStatus;
3500  NTSTATUS Status;
3501  BOOLEAN IsFlush = FALSE;
3502 
3503  DPRINT("USBH_CompletePortIdleIrpsWorker ... \n");
3504 
3505  IdlePortContext = Context;
3506  NtStatus = IdlePortContext->Status;
3507 
3509  &IdlePortContext->PwrList,
3510  NtStatus);
3511 
3512  DPRINT1("USBH_CompletePortIdleIrpsWorker: USBH_RegQueryFlushPortPowerIrpsFlag() UNIMPLEMENTED. FIXME\n");
3513  Status = STATUS_NOT_IMPLEMENTED;// USBH_RegQueryFlushPortPowerIrpsFlag(&IsFlush);
3514 
3515  if (NT_SUCCESS(Status))
3516  {
3517  if (IsFlush)
3518  {
3519  USBH_FlushPortPwrList(HubExtension);
3520  }
3521  }
3522 }
3523 
3524 VOID
3525 NTAPI
3527  IN PVOID Context)
3528 {
3529  PUSBHUB_IDLE_HUB_CONTEXT HubWorkItemBuffer;
3530 
3531  DPRINT("USBH_IdleCompletePowerHubWorker ... \n");
3532 
3533  if (HubExtension &&
3534  HubExtension->CurrentPowerState.DeviceState != PowerDeviceD0 &&
3535  HubExtension->HubFlags & USBHUB_FDO_FLAG_DEVICE_STARTED)
3536  {
3537  USBH_HubSetD0(HubExtension);
3538  }
3539 
3540  HubWorkItemBuffer = Context;
3541 
3542  USBH_HubCompletePortIdleIrps(HubExtension, HubWorkItemBuffer->Status);
3543 
3544 }
3545 
3546 NTSTATUS
3547 NTAPI
3549  IN PIRP Irp,
3550  IN PVOID Context)
3551 {
3552  PUSBHUB_FDO_EXTENSION HubExtension;
3553  NTSTATUS NtStatus;
3554  PVOID IdleIrp;
3555  KIRQL Irql;
3556  NTSTATUS Status;
3557  PUSBHUB_IO_WORK_ITEM HubIoWorkItem;
3558 
3560 
3561  HubExtension = Context;
3562  HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST;
3563 
3564  IdleIrp = InterlockedExchangePointer((PVOID)&HubExtension->PendingIdleIrp,
3565  NULL);
3566 
3567  DPRINT("USBH_FdoIdleNotificationRequestComplete: IdleIrp - %p\n", IdleIrp);
3568 
3569  if (!InterlockedDecrement(&HubExtension->PendingRequestCount))
3570  {
3572  }
3573 
3575 
3576  NtStatus = Irp->IoStatus.Status;
3577 
3578  DPRINT("USBH_FdoIdleNotificationRequestComplete: NtStatus - %lX\n",
3579  NtStatus);
3580 
3581  if (!NT_SUCCESS(NtStatus) &&
3582  NtStatus != STATUS_POWER_STATE_INVALID &&
3583  !(HubExtension->HubFlags & USBHUB_FDO_FLAG_DEVICE_REMOVED) &&
3584  !(HubExtension->HubFlags & USBHUB_FDO_FLAG_DEVICE_STOPPED))
3585  {
3586  DPRINT("USBH_FdoIdleNotificationRequestComplete: DeviceState - %x\n",
3587  HubExtension->CurrentPowerState.DeviceState);
3588 
3589  if (HubExtension->CurrentPowerState.DeviceState == PowerDeviceD0)
3590  {
3591  PUSBHUB_IDLE_PORT_CONTEXT HubWorkItemBuffer;
3592 
3593  Status = USBH_AllocateWorkItem(HubExtension,
3594  &HubIoWorkItem,
3596  sizeof(USBHUB_IDLE_PORT_CONTEXT),
3597  (PVOID *)&HubWorkItemBuffer,
3599 
3600  if (NT_SUCCESS(Status))
3601  {
3602  HubWorkItemBuffer->Status = NtStatus;
3603 
3604  USBH_HubQueuePortIdleIrps(HubExtension,
3605  &HubWorkItemBuffer->PwrList);
3606 
3607  USBH_QueueWorkItem(HubExtension, HubIoWorkItem);
3608  }
3609  }
3610  else
3611  {
3612  PUSBHUB_IDLE_HUB_CONTEXT HubWorkItemBuffer;
3613 
3614  Status = USBH_AllocateWorkItem(HubExtension,
3615  &HubIoWorkItem,
3617  sizeof(USBHUB_IDLE_HUB_CONTEXT),
3618  (PVOID *)&HubWorkItemBuffer,
3620 
3621  if (NT_SUCCESS(Status))
3622  {
3623  HubWorkItemBuffer->Status = NtStatus;
3624  USBH_QueueWorkItem(HubExtension, HubIoWorkItem);
3625  }
3626  }
3627  }
3628 
3629  if (IdleIrp ||
3630  InterlockedExchange((PLONG)&HubExtension->IdleRequestLock, 1))
3631  {
3632  DPRINT("USBH_FdoIdleNotificationRequestComplete: Irp - %p\n", Irp);
3633  IoFreeIrp(Irp);
3634  }
3635 
3637 }
3638 
3639 NTSTATUS
3640 NTAPI
3642 {
3643  NTSTATUS Status;
3644  ULONG HubFlags;
3645  PDEVICE_OBJECT LowerPDO;
3646  PIRP Irp;
3647  PIO_STACK_LOCATION IoStack;
3648  KIRQL Irql;
3649 
3650  DPRINT("USBH_FdoSubmitIdleRequestIrp: HubExtension - %p, PendingIdleIrp - %p\n",
3651  HubExtension,
3652  HubExtension->PendingIdleIrp);
3653 
3654  if (HubExtension->PendingIdleIrp)
3655  {
3657  KeSetEvent(&HubExtension->IdleEvent, EVENT_INCREMENT, FALSE);
3658  return Status;
3659  }
3660 
3661  HubFlags = HubExtension->HubFlags;
3662 
3663  if (HubFlags & USBHUB_FDO_FLAG_DEVICE_STOPPING ||
3664  HubFlags & USBHUB_FDO_FLAG_DEVICE_REMOVED)
3665  {
3666  HubExtension->HubFlags = HubFlags & ~USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST;
3667  KeSetEvent(&HubExtension->IdleEvent, EVENT_INCREMENT, FALSE);
3668  return STATUS_DEVICE_REMOVED;
3669  }
3670 
3671  LowerPDO = HubExtension->LowerPDO;
3672 
3673  HubExtension->IdleCallbackInfo.IdleCallback = USBH_FdoIdleNotificationCallback;
3674  HubExtension->IdleCallbackInfo.IdleContext = HubExtension;
3675 
3676  Irp = IoAllocateIrp(LowerPDO->StackSize, FALSE);
3677 
3678  if (!Irp)
3679  {
3680  HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST;
3682 
3683  KeSetEvent(&HubExtension->IdleEvent, EVENT_INCREMENT, FALSE);
3684  return Status;
3685  }
3686 
3687  IoStack = IoGetNextIrpStackLocation(Irp);
3688 
3690 
3691  IoStack->Parameters.DeviceIoControl.InputBufferLength = sizeof(USB_IDLE_CALLBACK_INFO);
3692  IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION;
3693  IoStack->Parameters.DeviceIoControl.Type3InputBuffer = &HubExtension->IdleCallbackInfo;
3694 
3697  HubExtension,
3698  TRUE,
3699  TRUE,
3700  TRUE);
3701 
3702  InterlockedIncrement(&HubExtension->PendingRequestCount);
3703  InterlockedExchange(&HubExtension->IdleRequestLock, 0);
3704 
3705  HubExtension->HubFlags &= ~(USBHUB_FDO_FLAG_DEVICE_SUSPENDED |
3707 
3708  Status = IoCallDriver(HubExtension->LowerPDO, Irp);
3709 
3711 
3712  if (Status == STATUS_PENDING &&
3713  HubExtension->HubFlags & USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST)
3714  {
3715  HubExtension->PendingIdleIrp = Irp;
3716  }
3717 
3719 
3720  KeSetEvent(&HubExtension->IdleEvent, EVENT_INCREMENT, FALSE);
3721 
3722  return Status;
3723 }
3724 
3725 VOID
3726 NTAPI
3728 {
3729  PDEVICE_OBJECT PdoDevice;
3730  PUSBHUB_PORT_PDO_EXTENSION PortExtension;
3731  PUSBHUB_PORT_DATA PortData;
3732  ULONG HubFlags;
3733  ULONG Port;
3734  KIRQL Irql;
3735  BOOLEAN IsHubIdle = FALSE;
3736  BOOLEAN IsAllPortsIdle;
3737  BOOLEAN IsHubCheck = TRUE;
3738 
3739  DPRINT("USBH_CheckHubIdle: FIXME !!! HubExtension - %p\n", HubExtension);
3740 
3741 return; //HACK: delete it line after fixing Power Manager!!!
3742 
3743  KeAcquireSpinLock(&HubExtension->CheckIdleSpinLock, &Irql);
3744 
3745  if (HubExtension->HubFlags & USBHUB_FDO_FLAG_CHECK_IDLE_LOCK)
3746  {
3747  KeReleaseSpinLock(&HubExtension->CheckIdleSpinLock, Irql);
3748  return;
3749  }
3750 
3751  HubExtension->HubFlags |= USBHUB_FDO_FLAG_CHECK_IDLE_LOCK;
3752  KeReleaseSpinLock(&HubExtension->CheckIdleSpinLock, Irql);
3753 
3754  if (USBH_GetRootHubExtension(HubExtension)->SystemPowerState.SystemState != PowerSystemWorking)
3755  {
3756  KeAcquireSpinLock(&HubExtension->CheckIdleSpinLock, &Irql);
3757  HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_CHECK_IDLE_LOCK;
3758  KeReleaseSpinLock(&HubExtension->CheckIdleSpinLock, Irql);
3759  return;
3760  }
3761 
3762  HubFlags = HubExtension->HubFlags;
3763  DPRINT("USBH_CheckHubIdle: HubFlags - %lX\n", HubFlags);
3764 
3765  if (!(HubFlags & USBHUB_FDO_FLAG_DEVICE_STARTED) ||
3766  !(HubFlags & USBHUB_FDO_FLAG_DO_ENUMERATION))
3767  {
3768  goto Exit;
3769  }
3770 
3771  if (HubFlags & USBHUB_FDO_FLAG_NOT_ENUMERATED ||
3772  HubFlags & USBHUB_FDO_FLAG_ENUM_POST_RECOVER ||
3773  HubFlags & USBHUB_FDO_FLAG_DEVICE_FAILED ||
3774  HubFlags & USBHUB_FDO_FLAG_DEVICE_STOPPING ||
3775  HubFlags & USBHUB_FDO_FLAG_DEVICE_REMOVED ||
3776  HubFlags & USBHUB_FDO_FLAG_STATE_CHANGING ||
3777  HubFlags & USBHUB_FDO_FLAG_WAKEUP_START ||
3778  HubFlags & USBHUB_FDO_FLAG_ESD_RECOVERING)
3779  {
3780  goto Exit;
3781  }
3782 
3783  if (HubExtension->ResetRequestCount)
3784  {
3785  HubExtension->HubFlags |= USBHUB_FDO_FLAG_DEFER_CHECK_IDLE;
3786  goto Exit;
3787  }
3788 
3789  HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_DEFER_CHECK_IDLE;
3790 
3791  InterlockedIncrement(&HubExtension->PendingRequestCount);
3792 
3793  KeWaitForSingleObject(&HubExtension->ResetDeviceSemaphore,
3794  Executive,
3795  KernelMode,
3796  FALSE,
3797  NULL);
3798 
3800 
3801  IsAllPortsIdle = TRUE;
3802 
3803  PortData = HubExtension->PortData;
3804 
3805  for (Port = 0;
3806  Port < HubExtension->HubDescriptor->bNumberOfPorts;
3807  Port++)
3808  {
3809  PdoDevice = PortData[Port].DeviceObject;
3810 
3811  if (PdoDevice)
3812  {
3813  PortExtension = PdoDevice->DeviceExtension;
3814 
3815  if (!PortExtension->IdleNotificationIrp)
3816  {
3817  DPRINT("USBH_CheckHubIdle: PortExtension - %p\n",
3818  PortExtension);
3819 
3820  IsAllPortsIdle = FALSE;
3821  IsHubCheck = FALSE;
3822 
3823  break;
3824  }
3825  }
3826  }
3827 
3828  if (IsHubCheck &&
3829  !(HubExtension->HubFlags & USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST))
3830  {
3831  KeClearEvent(&HubExtension->IdleEvent);
3832  HubExtension->HubFlags |= USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST;
3833  IsHubIdle = TRUE;
3834  }
3835 
3837 
3838  KeReleaseSemaphore(&HubExtension->ResetDeviceSemaphore,
3840  1,
3841  FALSE);
3842 
3843  if (!InterlockedDecrement(&HubExtension->PendingRequestCount))
3844  {
3845  KeSetEvent(&HubExtension->PendingRequestEvent,
3847  FALSE);
3848  }
3849 
3850  DPRINT("USBH_CheckHubIdle: IsAllPortsIdle - %x, IsHubIdle - %x\n",
3851  IsAllPortsIdle,
3852  IsHubIdle);
3853 
3854  if (IsAllPortsIdle && IsHubIdle)
3855  {
3856  USBH_FdoSubmitIdleRequestIrp(HubExtension);
3857  }
3858 
3859 Exit:
3860  KeAcquireSpinLock(&HubExtension->CheckIdleSpinLock, &Irql);
3861  HubExtension->HubFlags &= ~USBHUB_FDO_FLAG_CHECK_IDLE_LOCK;
3862  KeReleaseSpinLock(&HubExtension->CheckIdleSpinLock, Irql);
3863 }
3864 
3865 VOID
3866 NTAPI
3868  IN PVOID Context)
3869 {
3870  DPRINT("USBH_CheckIdleWorker: ... \n");
3871  USBH_CheckHubIdle(HubExtension);
3872 }
3873 
3874 VOID
3875 NTAPI
3877 {
3878  PUSBHUB_IO_WORK_ITEM HubIoWorkItem;
3879  NTSTATUS Status;
3880 
3881  DPRINT("USBH_CheckIdleDeferred: HubExtension - %p\n", HubExtension);
3882 
3883  Status = USBH_AllocateWorkItem(HubExtension,
3884  &HubIoWorkItem,
3886  0,
3887  NULL,
3889 
3890  DPRINT("USBH_CheckIdleDeferred: HubIoWorkItem - %p\n", HubIoWorkItem);
3891 
3892  if (NT_SUCCESS(Status))
3893  {
3894  USBH_QueueWorkItem(HubExtension, HubIoWorkItem);
3895  }
3896 }
3897 
3898 VOID
3899 NTAPI
3901 {
3902  PUSBHUB_FDO_EXTENSION HubExtension;
3903  ULONG State;
3905  PDEVICE_POWER_STATE pDeviceState;
3906 
3907  DPRINT("USBH_PdoSetCapabilities ... \n");
3908 
3909  HubExtension = PortExtension->HubExtension;
3910 
3911  PortExtension->Capabilities.Size = 64;
3912  PortExtension->Capabilities.Version = 1;
3913 
3914  PortExtension->Capabilities.Removable = 1;
3915  PortExtension->Capabilities.Address = PortExtension->PortNumber;
3916 
3917  if (PortExtension->SerialNumber)
3918  {
3919  PortExtension->Capabilities.UniqueID = 1;
3920  }
3921  else
3922  {
3923  PortExtension->Capabilities.UniqueID = 0;
3924  }
3925 
3926  PortExtension->Capabilities.RawDeviceOK = 0;
3927 
3928  RtlCopyMemory(PortExtension->Capabilities.DeviceState,
3929  HubExtension->DeviceState,
3930  (PowerSystemMaximum + 2) * sizeof(POWER_STATE));
3931 
3932  PortExtension->Capabilities.DeviceState[1] = PowerDeviceD0;
3933 
3934  if (PortExtension->PortPdoFlags & USBHUB_PDO_FLAG_REMOTE_WAKEUP)
3935  {
3936  PortExtension->Capabilities.DeviceWake = PowerDeviceD2;
3937 
3938  PortExtension->Capabilities.DeviceD1 = 1;
3939  PortExtension->Capabilities.DeviceD2 = 1;
3940 
3941  PortExtension->Capabilities.WakeFromD0 = 1;
3942  PortExtension->Capabilities.WakeFromD1 = 1;
3943  PortExtension->Capabilities.WakeFromD2 = 1;
3944 
3945  pDeviceState = &PortExtension->Capabilities.DeviceState[2];
3946 
3947  for (State = 2; State <= 5; State++)
3948  {
3950 
3951  if (PortExtension->Capabilities.SystemWake < SystemPowerState)
3952  {
3953  *pDeviceState = PowerDeviceD3;
3954  }
3955  else
3956  {
3957  *pDeviceState = PowerDeviceD2;
3958  }
3959 
3960  ++pDeviceState;
3961  }
3962  }
3963  else
3964  {
3965  PortExtension->Capabilities.DeviceWake = PowerDeviceD0;
3966  PortExtension->Capabilities.DeviceState[2] = PowerDeviceD3;
3967  PortExtension->Capabilities.DeviceState[3] = PowerDeviceD3;
3968  PortExtension->Capabilities.DeviceState[4] = PowerDeviceD3;
3969  PortExtension->Capabilities.DeviceState[5] = PowerDeviceD3;
3970  }
3971 }
3972 
3973 NTSTATUS
3974 NTAPI
3976 {
3978  PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor;
3979  NTSTATUS Status;
3980 
3981  DPRINT("USBH_ProcessDeviceInformation ... \n");
3982 
3983  ConfigDescriptor = NULL;
3984 
3985  RtlZeroMemory(&PortExtension->InterfaceDescriptor,
3986  sizeof(PortExtension->InterfaceDescriptor));
3987 
3988  PortExtension->PortPdoFlags &= ~USBHUB_PDO_FLAG_HUB_DEVICE;
3989 
3990  Status = USBH_GetConfigurationDescriptor(PortExtension->Common.SelfDevice,
3991  &ConfigDescriptor);
3992 
3993  if (!NT_SUCCESS(Status))
3994  {
3995  if (ConfigDescriptor)
3996  {
3997  ExFreePool(ConfigDescriptor);
3998  }
3999 
4000  return Status;
4001  }
4002 
4003  PortExtension->PortPdoFlags &= ~USBHUB_PDO_FLAG_REMOTE_WAKEUP;
4004 
4005  if (ConfigDescriptor->bmAttributes & 0x20)
4006  {
4007  /* device configuration supports remote wakeup */
4008  PortExtension->PortPdoFlags |= USBHUB_PDO_FLAG_REMOTE_WAKEUP;
4009  }
4010 
4011  USBHUB_DumpingDeviceDescriptor(&PortExtension->DeviceDescriptor);
4012  USBHUB_DumpingConfiguration(ConfigDescriptor);
4013 
4014  DPRINT_PNP("USBH_ProcessDeviceInformation: Class - %x, SubClass - %x, Protocol - %x\n",
4015  PortExtension->DeviceDescriptor.bDeviceClass,
4016  PortExtension->DeviceDescriptor.bDeviceSubClass,
4017  PortExtension->DeviceDescriptor.bDeviceProtocol);
4018 
4019  DPRINT_PNP("USBH_ProcessDeviceInformation: bNumConfigurations - %x, bNumInterfaces - %x\n",
4020  PortExtension->DeviceDescriptor.bNumConfigurations,
4021  ConfigDescriptor->bNumInterfaces);
4022 
4023 
4024  /* Enumeration of USB Composite Devices (msdn):
4025  1) The device class field of the device descriptor (bDeviceClass) must contain a value of zero,
4026  or the class (bDeviceClass), subclass (bDeviceSubClass), and protocol (bDeviceProtocol)
4027  fields of the device descriptor must have the values 0xEF, 0x02 and 0x01 respectively,
4028  as explained in USB Interface Association Descriptor.
4029  2) The device must have multiple interfaces
4030  3) The device must have a single configuration.
4031  */
4032 
4033  if (((PortExtension->DeviceDescriptor.bDeviceClass == USB_DEVICE_CLASS_RESERVED) ||
4034  (PortExtension->DeviceDescriptor.bDeviceClass == USB_DEVICE_CLASS_MISCELLANEOUS &&
4035  PortExtension->DeviceDescriptor.bDeviceSubClass == 0x02 &&
4036  PortExtension->DeviceDescriptor.bDeviceProtocol == 0x01)) &&
4037  (ConfigDescriptor->bNumInterfaces > 1) &&
4038  (PortExtension->DeviceDescriptor.bNumConfigurations < 2))
4039  {
4040  DPRINT("USBH_ProcessDeviceInformation: Multi-Interface configuration\n");
4041 
4042  PortExtension->PortPdoFlags |= USBHUB_PDO_FLAG_MULTI_INTERFACE;
4043 
4044  if (ConfigDescriptor)
4045  {
4046  ExFreePool(ConfigDescriptor);
4047  }
4048 
4049  return Status;
4050  }
4051 
4052  Pid = USBD_ParseConfigurationDescriptorEx(ConfigDescriptor,
4053  ConfigDescriptor,
4054  -1,
4055  -1,
4056  -1,
4057  -1,
4058  -1);
4059  if (Pid)
4060  {
4061  RtlCopyMemory(&PortExtension->InterfaceDescriptor,
4062  Pid,
4063  sizeof(PortExtension->InterfaceDescriptor));
4064 
4066  {
4067  PortExtension->PortPdoFlags |= (USBHUB_PDO_FLAG_HUB_DEVICE |
4069  }
4070  }
4071  else
4072  {
4074  }
4075 
4076  if (ConfigDescriptor)
4077  {
4078  ExFreePool(ConfigDescriptor);
4079  }
4080 
4081  return Status;
4082 }
4083 
4084 BOOLEAN
4085 NTAPI
4087  IN USHORT idVendor,
4088  IN USHORT idProduct,
4090  IN USHORT SN_DescriptorLength)
4091 {
4092  PDEVICE_OBJECT PortDevice;
4093  PUSBHUB_PORT_PDO_EXTENSION PortExtension;
4094  ULONG Port;
4095  SIZE_T NumberBytes;
4096 
4097  DPRINT("USBH_CheckDeviceIDUnique: idVendor - 0x%04X, idProduct - 0x%04X\n",
4098  idVendor,
4099  idProduct);
4100 
4101  if (!HubExtension->HubDescriptor->bNumberOfPorts)
4102  {
4103  return TRUE;
4104  }
4105 
4106  for (Port = 0; Port < HubExtension->HubDescriptor->bNumberOfPorts; Port++)
4107  {
4108  PortDevice = HubExtension->PortData[Port].DeviceObject;
4109 
4110  if (PortDevice)
4111  {
4112  PortExtension = PortDevice->DeviceExtension;
4113 
4114  if (PortExtension->DeviceDescriptor.idVendor == idVendor &&
4115  PortExtension->DeviceDescriptor.idProduct == idProduct &&
4116  PortExtension->SN_DescriptorLength == SN_DescriptorLength)
4117  {
4118  if (PortExtension->SerialNumber)
4119  {
4120  NumberBytes = RtlCompareMemory(PortExtension->SerialNumber,
4121  SerialNumber,
4122  SN_DescriptorLength);
4123 
4124  if (NumberBytes == SN_DescriptorLength)
4125  {
4126  return FALSE;
4127  }
4128  }
4129  }
4130  }
4131  }
4132 
4133  return TRUE;
4134 }
4135 
4136 BOOLEAN
4137 NTAPI
4139 {
4140  USHORT ix;
4141  USHORT Symbol;
4142 
4143  DPRINT("USBH_ValidateSerialNumberString: ... \n");
4144 
4145  for (ix = 0; SerialNumberString[ix] != UNICODE_NULL; ix++)
4146  {
4147  Symbol = SerialNumberString[ix];
4148 
4149  if (Symbol < 0x20 || Symbol > 0x7F || Symbol == 0x2C) // ','
4150  {
4151  return FALSE;
4152  }
4153  }
4154 
4155  return TRUE;
4156 }
4157 
4158 
4159 NTSTATUS
4160 NTAPI
4162  IN USHORT LanguageId)
4163 {
4165  NTSTATUS Status;
4166  ULONG NumSymbols;
4167  ULONG ix;
4168  PWCHAR pSymbol;
4169  ULONG Length;
4170 
4171  DPRINT("USBH_CheckDeviceLanguage: LanguageId - 0x%04X\n", LanguageId);
4172 
4175  USB_HUB_TAG);
4176 
4177  if (!Descriptor)
4178  {
4180  }
4181 
4183 
4185  0,
4186  0,
4187  Descriptor,
4189  &Length,
4190  TRUE);
4191 
4192  if (!NT_SUCCESS(Status) ||
4193  Length < sizeof(USB_COMMON_DESCRIPTOR))
4194  {
4195  goto Exit;
4196  }
4197 
4198  NumSymbols = (Length -
4199  FIELD_OFFSET(USB_STRING_DESCRIPTOR, bString)) / sizeof(WCHAR);
4200 
4201  pSymbol = Descriptor->bString;
4202 
4203  for (ix = 1; ix < NumSymbols; ix++)
4204  {
4205  if (*pSymbol == (WCHAR)LanguageId)
4206  {
4208  goto Exit;
4209  }
4210 
4211  pSymbol++;
4212  }
4213 
4215 
4216 Exit:
4218  return Status;
4219 }
4220 
4221 NTSTATUS
4222 NTAPI
4224  IN LPWSTR * OutSerialNumber,
4225  IN PUSHORT OutDescriptorLength,
4226  IN USHORT LanguageId,
4227  IN UCHAR Index)
4228 {
4230  NTSTATUS Status;
4231  LPWSTR SerialNumberBuffer = NULL;
4232  UCHAR StringLength;
4233  UCHAR Length;
4234 
4235  DPRINT("USBH_GetSerialNumberString: ... \n");
4236 
4237  *OutSerialNumber = NULL;
4238  *OutDescriptorLength = 0;
4239 
4242  USB_HUB_TAG);
4243 
4244  if (!Descriptor)
4245  {
4247  }
4248 
4250 
4252 
4253  if (!NT_SUCCESS(Status))
4254  {
4255  goto Exit;
4256  }
4257 
4259  Index,
4260  LanguageId,
4261  Descriptor,
4263  NULL,
4264  TRUE);
4265 
4266  if (!NT_SUCCESS(Status) ||
4267  Descriptor->bLength <= sizeof(USB_COMMON_DESCRIPTOR))
4268  {
4270  goto Exit;
4271  }
4272 
4273  StringLength = Descriptor->bLength -
4275 
4276  Length = StringLength + sizeof(UNICODE_NULL);
4277 
4278  SerialNumberBuffer = ExAllocatePoolWithTag(PagedPool, Length, USB_HUB_TAG);
4279 
4280  if (!SerialNumberBuffer)
4281  {
4282  goto Exit;
4283  }
4284 
4285  RtlZeroMemory(SerialNumberBuffer, Length);
4286  RtlCopyMemory(SerialNumberBuffer, Descriptor->bString, StringLength);
4287 
4288  *OutSerialNumber = SerialNumberBuffer;
4289  *OutDescriptorLength = Length;
4290 
4291 Exit:
4293  return Status;
4294 }
4295 
4296 NTSTATUS
4297 NTAPI
4299  IN USHORT Port,
4300  IN USB_PORT_STATUS UsbPortStatus,
4301  IN ULONG IsWait)
4302 {
4303  ULONG PdoNumber = 0;
4304  WCHAR CharDeviceName[64];
4307  PUSBHUB_PORT_PDO_EXTENSION PortExtension;
4309  LPWSTR SerialNumberBuffer;
4310  BOOLEAN IsHsDevice;
4311  BOOLEAN IsLsDevice;
4312  BOOLEAN IgnoringHwSerial = FALSE;
4313  NTSTATUS Status;
4315 
4316  DPRINT("USBH_CreateDevice: Port - %x, UsbPortStatus - %lX\n",
4317  Port,
4318  UsbPortStatus.AsUshort16);
4319 
4320  do
4321  {
4322  RtlStringCbPrintfW(CharDeviceName,
4323  sizeof(CharDeviceName),
4324  L"\\Device\\USBPDO-%d",
4325  PdoNumber);
4326 
4327  RtlInitUnicodeString(&DeviceName, CharDeviceName);
4328 
4329  Status = IoCreateDevice(HubExtension->Common.SelfDevice->DriverObject,
4330  sizeof(USBHUB_PORT_PDO_EXTENSION),
4331  &DeviceName,
4333  0,
4334  FALSE,
4335  &DeviceObject);
4336 
4337  ++PdoNumber;
4338  }
4340 
4341  if (!NT_SUCCESS(Status))
4342  {
4343  ASSERT(Port > 0);
4344  HubExtension->PortData[Port-1].DeviceObject = DeviceObject;
4345  return Status;
4346  }
4347 
4348  DeviceObject->StackSize = HubExtension->RootHubPdo2->StackSize;
4349 
4350  PortExtension = DeviceObject->DeviceExtension;
4351 
4352  DPRINT("USBH_CreateDevice: PortDevice - %p, <%wZ>\n", DeviceObject, &DeviceName);
4353  DPRINT("USBH_CreateDevice: PortExtension - %p\n", PortExtension);
4354 
4355  RtlZeroMemory(PortExtension, sizeof(USBHUB_PORT_PDO_EXTENSION));
4356 
4357  PortExtension->Common.ExtensionType = USBH_EXTENSION_TYPE_PORT;
4358  PortExtension->Common.SelfDevice = DeviceObject;
4359 
4360  PortExtension->HubExtension = HubExtension;
4361  PortExtension->RootHubExtension = HubExtension;
4362 
4363  PortExtension->PortNumber = Port;
4364  PortExtension->CurrentPowerState.DeviceState = PowerDeviceD0;
4365  PortExtension->IgnoringHwSerial = FALSE;
4366 
4367  KeInitializeSpinLock(&PortExtension->PortTimeoutSpinLock);
4368 
4369  InitializeListHead(&PortExtension->PortPowerList);
4371 
4372  PortExtension->PoRequestCounter = 0;
4373  PortExtension->PendingSystemPoRequest = 0;
4374  PortExtension->PendingDevicePoRequest = 0;
4375  PortExtension->StateBehindD2 = 0;
4376 
4377  SerialNumberBuffer = NULL;
4378 
4379  IsHsDevice = UsbPortStatus.Usb20PortStatus.HighSpeedDeviceAttached;
4380  IsLsDevice = UsbPortStatus.Usb20PortStatus.LowSpeedDeviceAttached;
4381 
4382  if (IsLsDevice == 0)
4383  {
4384  if (IsHsDevice)
4385  {
4387  }
4388  }
4389  else
4390  {
4392  }
4393 
4394  /* Initialize PortExtension->InstanceID */
4396  DestinationString.MaximumLength = 4 * sizeof(WCHAR);
4398 
4401 
4402  if (!NT_SUCCESS(Status))
4403  {
4404  DPRINT1("USBH_CreateDevice: IoCreateDevice() failed - %lX\n", Status);
4405  goto ErrorExit;
4406  }
4407 
4408  Status = USBD_CreateDeviceEx(HubExtension,
4409  &PortExtension->DeviceHandle,
4410  UsbPortStatus,
4411  Port);
4412 
4413  if (!NT_SUCCESS(Status))
4414  {
4415  DPRINT1("USBH_CreateDevice: USBD_CreateDeviceEx() failed - %lX\n", Status);
4416  goto ErrorExit;
4417  }
4418 
4419  Status = USBH_SyncResetPort(HubExtension, Port);
4420 
4421  if (!NT_SUCCESS(Status))
4422  {
4423  DPRINT1("USBH_CreateDevice: USBH_SyncResetPort() failed - %lX\n", Status);
4424  goto ErrorExit;
4425  }
4426 
4427  if (IsWait)
4428  {
4429  USBH_Wait(50);
4430  }
4431 
4432  Status = USBD_InitializeDeviceEx(HubExtension,
4433  PortExtension->DeviceHandle,
4434  (PUCHAR)&PortExtension->DeviceDescriptor,
4435  sizeof(USB_DEVICE_DESCRIPTOR),
4436  (PUCHAR)&PortExtension->ConfigDescriptor,
4438 
4439  if (!NT_SUCCESS(Status))
4440  {
4441  DPRINT1("USBH_CreateDevice: USBD_InitializeDeviceEx() failed - %lX\n", Status);
4442  PortExtension->DeviceHandle = NULL;
4443  goto ErrorExit;
4444  }
4445 
4446  DPRINT1("USBH_RegQueryDeviceIgnoreHWSerNumFlag UNIMPLEMENTED. FIXME\n");
4447  //Status = USBH_RegQueryDeviceIgnoreHWSerNumFlag(PortExtension->DeviceDescriptor.idVendor,
4448  // PortExtension->DeviceDescriptor.idProduct,
4449  // &IgnoringHwSerial);
4450 
4451  if (TRUE)//Status == STATUS_OBJECT_NAME_NOT_FOUND)
4452  {
4453  IgnoringHwSerial = FALSE;
4454  }
4455 
4456  if (IgnoringHwSerial)
4457  {
4458  PortExtension->IgnoringHwSerial = TRUE;
4459  }
4460 
4461  if (PortExtension->DeviceDescriptor.iSerialNumber &&
4462  !PortExtension->IgnoringHwSerial)
4463  {
4465 
4466  USBH_GetSerialNumberString(PortExtension->Common.SelfDevice,
4467  &SerialNumberBuffer,
4468  &PortExtension->SN_DescriptorLength,
4470  PortExtension->DeviceDescriptor.iSerialNumber);
4471 
4472  if (SerialNumberBuffer)
4473  {
4474  if (!USBH_ValidateSerialNumberString((PUSHORT)SerialNumberBuffer))
4475  {
4476  ExFreePoolWithTag(SerialNumberBuffer, USB_HUB_TAG);
4477  SerialNumberBuffer = NULL;
4478  }
4479 
4480  if (SerialNumberBuffer &&
4481  !USBH_CheckDeviceIDUnique(HubExtension,
4482  PortExtension->DeviceDescriptor.idVendor,
4483  PortExtension->DeviceDescriptor.idProduct,
4484  SerialNumberBuffer,
4485  PortExtension->SN_DescriptorLength))
4486  {
4487  ExFreePoolWithTag(SerialNumberBuffer, USB_HUB_TAG);
4488  SerialNumberBuffer = NULL;
4489  }
4490  }
4491 
4493  SerialNumberBuffer);
4494  }
4495 
4496  Status = USBH_ProcessDeviceInformation(PortExtension);
4497 
4498  USBH_PdoSetCapabilities(PortExtension);
4499 
4500  if (NT_SUCCESS(Status))
4501  {
4502  goto Exit;
4503  }
4504 
4505 ErrorExit:
4506 
4508 
4510  NULL);
4511 
4512  if (DeviceHandle)
4513  {
4514  USBD_RemoveDeviceEx(HubExtension, DeviceHandle, 0);
4515  }
4516 
4517  SerialNumberBuffer = InterlockedExchangePointer((PVOID)&PortExtension->SerialNumber,
4518  NULL);
4519 
4520  if (SerialNumberBuffer)
4521  {
4522  ExFreePoolWithTag(SerialNumberBuffer, USB_HUB_TAG);
4523  }
4524 
4525 Exit:
4526 
4527  ASSERT(Port > 0);
4528  HubExtension->PortData[Port-1].DeviceObject = DeviceObject;
4529  return Status;
4530 }
4531 
4532 NTSTATUS
4533 NTAPI
4535  IN USHORT Port,
4536  IN BOOLEAN IsKeepDeviceData,
4537  IN BOOLEAN IsWait)
4538 {
4539  NTSTATUS Status;
4540  PUSBHUB_PORT_DATA PortData;
4541  PDEVICE_OBJECT PortDevice;
4542  PUSBHUB_PORT_PDO_EXTENSION PortExtension;
4544  PVOID Handle;
4548 
4549  DPRINT("USBH_ResetDevice: HubExtension - %p, Port - %x, IsKeepDeviceData - %x, IsWait - %x\n",
4550  HubExtension,
4551  Port,
4552  IsKeepDeviceData,
4553  IsWait);
4554 
4555  Status = USBH_SyncGetPortStatus(HubExtension,
4556  Port,
4557  &PortStatus,
4558  sizeof(USB_PORT_STATUS_AND_CHANGE));
4559 
4560  if (!NT_SUCCESS(Status) ||
4561  !(PortStatus.PortStatus.Usb20PortStatus.CurrentConnectStatus))
4562  {
4563  return STATUS_UNSUCCESSFUL;
4564  }
4565 
4566  InterlockedIncrement(&HubExtension->PendingRequestCount);
4567 
4568  KeWaitForSingleObject(&HubExtension->ResetDeviceSemaphore,
4569  Executive,
4570  KernelMode,
4571  FALSE,
4572  NULL);
4573 
4574  ASSERT(Port > 0);
4575  PortData = &HubExtension->PortData[Port-1];
4576 
4577  PortDevice = PortData->DeviceObject;
4578 
4579  if (!PortDevice)
4580  {
4582 
4583  KeReleaseSemaphore(&HubExtension->ResetDeviceSemaphore,
4585  1,
4586  FALSE);
4587 
4588  if (!InterlockedDecrement(&HubExtension->PendingRequestCount))
4589  {
4590  KeSetEvent(&HubExtension->PendingRequestEvent,
4592  FALSE);
4593  }
4594 
4595  return Status;
4596  }
4597 
4598  PortExtension = PortDevice->DeviceExtension;
4599  DeviceHandle = &PortExtension->DeviceHandle;
4600 
4602  NULL);
4603 
4604  if (OldDeviceHandle)
4605  {
4606  if (!(PortExtension->PortPdoFlags & USBHUB_PDO_FLAG_REMOVING_PORT_PDO))
4607  {
4608  Status = USBD_RemoveDeviceEx(HubExtension,
4610  IsKeepDeviceData);
4611 
4613  }
4614  }
4615  else
4616  {
4618  }
4619 
4620  if (!NT_SUCCESS(Status))
4621  {
4622  goto ErrorExit;
4623  }
4624 
4625  Status = USBH_SyncResetPort(HubExtension, Port);
4626 
4627  if (!NT_SUCCESS(Status))
4628  {
4629  goto ErrorExit;
4630  }
4631 
4632  Status = USBH_SyncGetPortStatus(HubExtension,
4633  Port,
4634  &PortStatus,
4635  sizeof(USB_PORT_STATUS_AND_CHANGE));
4636 
4637  if (!NT_SUCCESS(Status))
4638  {
4639  goto ErrorExit;
4640  }
4641 
4642  Status = USBD_CreateDeviceEx(HubExtension,
4643  DeviceHandle,
4644  PortStatus.PortStatus,
4645  Port);
4646 
4647  if (!NT_SUCCESS(Status))
4648  {
4649  goto ErrorExit;
4650  }
4651 
4652  Status = USBH_SyncResetPort(HubExtension, Port);
4653 
4654  if (IsWait)
4655  {
4656  USBH_Wait(50);
4657  }
4658 
4659  if (!NT_SUCCESS(Status))
4660  {
4661  goto ErrorExit;
4662  }
4663 
4664  Status = USBD_InitializeDeviceEx(HubExtension,
4665  *DeviceHandle,
4666  &PortExtension->DeviceDescriptor.bLength,
4667  sizeof(PortExtension->DeviceDescriptor),
4668  &PortExtension->ConfigDescriptor.bLength,
4669  sizeof(PortExtension->ConfigDescriptor));
4670 
4671  if (NT_SUCCESS(Status))
4672  {
4673  if (IsKeepDeviceData)
4674  {
4675  Status = USBD_RestoreDeviceEx(HubExtension,
4677  *DeviceHandle);
4678 
4679  if (!NT_SUCCESS(Status))
4680  {
4682 
4683  USBD_RemoveDeviceEx(HubExtension, Handle, 0);
4684  USBH_SyncDisablePort(HubExtension, Port);
4685 
4687  }
4688  }
4689  else
4690  {
4692  }
4693 
4694  goto Exit;
4695  }
4696 
4697  *DeviceHandle = NULL;
4698 
4699 ErrorExit:
4700 
4702  OldDeviceHandle);
4703 
4704  if (NewDeviceHandle)
4705  {
4706  Status = USBD_RemoveDeviceEx(HubExtension, NewDeviceHandle, 0);
4707  }
4708 
4709 Exit:
4710 
4711  KeReleaseSemaphore(&HubExtension->ResetDeviceSemaphore,
4713  1,
4714  FALSE);
4715 
4716  if (!InterlockedDecrement(&HubExtension->PendingRequestCount))
4717  {
4718  KeSetEvent(&HubExtension->PendingRequestEvent,
4720  FALSE);
4721  }
4722 
4723  return Status;
4724 }
4725 
4726 NTSTATUS
4727 NTAPI
4729  IN PIRP Irp)
4730 {
4731  PIO_STACK_LOCATION IoStack;
4732  UCHAR MajorFunction;
4733  BOOLEAN ShouldCompleteIrp;
4735  NTSTATUS Status;
4736 
4737  IoStack = IoGetCurrentIrpStackLocation(Irp);
4738  MajorFunction = IoStack->MajorFunction;
4739 
4740  switch (MajorFunction)
4741  {
4742  case IRP_MJ_CREATE:
4743  case IRP_MJ_CLOSE:
4744  DPRINT("USBH_PdoDispatch: IRP_MJ_CREATE / IRP_MJ_CLOSE (%d)\n",
4745  MajorFunction);
4748  break;
4749 
4750  case IRP_MJ_DEVICE_CONTROL:
4751  ControlCode = IoStack->Parameters.DeviceIoControl.IoControlCode;
4752  DPRINT("USBH_PdoDispatch: IRP_MJ_DEVICE_CONTROL ControlCode - %x\n",
4753  ControlCode);
4754 
4756  {
4759  break;
4760  }
4761 
4763  {
4764  DPRINT1("USBH_PdoDispatch: IOCTL_KS_PROPERTY FIXME\n");
4765  DbgBreakPoint();
4768  break;
4769  }
4770 
4771  Status = Irp->IoStatus.Status;
4773  break;
4774 
4776  Status = USBH_PdoInternalControl(PortExtension, Irp);
4777  break;
4778 
4779  case IRP_MJ_PNP:
4780  Status = USBH_PdoPnP(PortExtension,
4781  Irp,
4782  IoStack->MinorFunction,
4783  &ShouldCompleteIrp);
4784 
4785  if (ShouldCompleteIrp)
4786  {
4788  }
4789 
4790  break;
4791 
4792  case IRP_MJ_POWER:
4793  Status = USBH_PdoPower(PortExtension, Irp, IoStack->MinorFunction);
4794  break;
4795 
4796  case IRP_MJ_SYSTEM_CONTROL:
4797  DPRINT1("USBH_PdoDispatch: USBH_SystemControl() UNIMPLEMENTED. FIXME\n");
4798  //USBH_PortSystemControl(PortExtension, Irp);
4799  Status = Irp->IoStatus.Status;
4801  break;
4802 
4803  default:
4804  DPRINT("USBH_PdoDispatch: Unhandled MajorFunction - %d\n", MajorFunction);
4805  Status = Irp->IoStatus.Status;
4807  break;
4808  }
4809 
4810  return Status;
4811 }
4812 
4813 NTSTATUS
4814 NTAPI
4816  IN PIRP Irp)
4817 {
4818  PIO_STACK_LOCATION IoStack;
4819  UCHAR MajorFunction;
4820  NTSTATUS Status;
4821 
4822  IoStack = IoGetCurrentIrpStackLocation(Irp);
4823 
4824  DPRINT("USBH_FdoDispatch: HubExtension - %p, Irp - %p, MajorFunction - %X\n",
4825  HubExtension,
4826  Irp,
4827  IoStack->MajorFunction);
4828 
4829  MajorFunction = IoStack->MajorFunction;
4830 
4831  switch (MajorFunction)
4832  {
4833  case IRP_MJ_CREATE:
4834  case IRP_MJ_CLOSE:
4837  break;
4838 
4839  case IRP_MJ_DEVICE_CONTROL:
4840  Status = USBH_DeviceControl(HubExtension, Irp);
4841  break;
4842 
4843  case IRP_MJ_PNP:
4844  Status = USBH_FdoPnP(HubExtension, Irp, IoStack->MinorFunction);
4845  break;
4846 
4847  case IRP_MJ_POWER:
4848  Status = USBH_FdoPower(HubExtension, Irp, IoStack->MinorFunction);
4849  break;
4850 
4851  case IRP_MJ_SYSTEM_CONTROL:
4852  DPRINT1("USBH_FdoDispatch: USBH_SystemControl() UNIMPLEMENTED. FIXME\n");
4853  /* fall through */
4854 
4856  default:
4857  Status = USBH_PassIrp(HubExtension->LowerDevice, Irp);
4858  break;
4859  }
4860 
4861  return Status;
4862 }
4863 
4864 NTSTATUS
4865 NTAPI
4867  IN PDEVICE_OBJECT LowerPDO)
4868 {
4870  NTSTATUS Status;
4871  PUSBHUB_FDO_EXTENSION HubExtension;
4872  PDEVICE_OBJECT LowerDevice;
4873 
4874  DPRINT("USBH_AddDevice: DriverObject - %p, LowerPDO - %p\n",
4875  DriverObject,
4876  LowerPDO);
4877 
4878  DeviceObject = NULL;
4879 
4881  sizeof(USBHUB_FDO_EXTENSION),
4882  NULL,
4883  0x8600,
4885  FALSE,
4886  &DeviceObject);
4887 
4888  if (!NT_SUCCESS(Status))
4889  {
4890  DPRINT1("USBH_AddDevice: IoCreateDevice() fail\n");
4891 
4892  if (DeviceObject)
4893  {
4895  }
4896 
4897  return Status;
4898  }
4899 
4900  DPRINT("USBH_AddDevice: DeviceObject - %p\n", DeviceObject);
4901 
4902  HubExtension = DeviceObject->DeviceExtension;
4903  RtlZeroMemory(HubExtension, sizeof(USBHUB_FDO_EXTENSION));
4904 
4905  HubExtension->Common.ExtensionType = USBH_EXTENSION_TYPE_HUB;
4906 
4907  LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, LowerPDO);
4908 
4909  if (!LowerDevice)
4910  {
4911  DPRINT1("USBH_AddDevice: IoAttachDeviceToDeviceStack() fail\n");
4912 
4913  if (DeviceObject)
4914  {
4916  }
4917 
4918  return STATUS_UNSUCCESSFUL;
4919  }
4920 
4921  DPRINT("USBH_AddDevice: LowerDevice - %p\n", LowerDevice);
4922 
4923  HubExtension->Common.SelfDevice = DeviceObject;
4924 
4925  HubExtension->LowerPDO = LowerPDO;
4926  HubExtension->LowerDevice = LowerDevice;
4927 
4928  KeInitializeSemaphore(&HubExtension->IdleSemaphore, 1, 1);
4929 
4932 
4933  DPRINT("USBH_AddDevice: call IoWMIRegistrationControl() UNIMPLEMENTED. FIXME\n");
4934 
4935  return Status;
4936 }
4937 
4938 VOID
4939 NTAPI
4941 {
4942  DPRINT("USBH_DriverUnload: UNIMPLEMENTED\n");
4943 
4945  {
4948  }
4949 }
4950 
4951 NTSTATUS
4952 NTAPI
4954  IN PIRP Irp)
4955 {
4956  PCOMMON_DEVICE_EXTENSION DeviceExtension;
4957  ULONG ExtensionType;
4958  NTSTATUS Status;
4959 
4960 
4961  DeviceExtension = DeviceObject->DeviceExtension;
4962  ExtensionType = DeviceExtension->ExtensionType;
4963 
4964  if (ExtensionType == USBH_EXTENSION_TYPE_HUB)
4965  {
4966  DPRINT("USBH_HubDispatch: DeviceObject - %p, Irp - %p\n",
4967  DeviceObject,
4968  Irp);
4969 
4970  Status = USBH_FdoDispatch((PUSBHUB_FDO_EXTENSION)DeviceExtension, Irp);
4971  }
4972  else if (ExtensionType == USBH_EXTENSION_TYPE_PORT)
4973  {
4975  UCHAR MajorFunction = IoStack->MajorFunction;
4976  BOOLEAN IsDprint = TRUE;
4977 
4978  if (MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL)
4979  {
4980  ULONG ControlCode = IoStack->Parameters.DeviceIoControl.IoControlCode;
4981 
4983  {
4984  IsDprint = FALSE;
4985  }
4986  }
4987 
4988  if (IsDprint)
4989  {
4990  DPRINT("USBH_HubDispatch: DeviceObject - %p, Irp - %p\n",
4991  DeviceObject,
4992  Irp);
4993  }
4994 
4996  }
4997  else
4998  {
4999  DPRINT1("USBH_HubDispatch: Unknown ExtensionType - %x\n", ExtensionType);
5000  DbgBreakPoint();
5002  }
5003 
5004  return Status;
5005 }
5006 
5007 NTSTATUS
5008 NTAPI
5010 {
5012 
5013  DPRINT("USBH_RegQueryGenericUSBDeviceString ... \n");
5014 
5016 
5019  QueryTable[0].Name = L"GenericUSBDeviceString";
5020  QueryTable[0].EntryContext = USBDeviceString;
5022  QueryTable[0].DefaultData = 0;
5023  QueryTable[0].DefaultLength = 0;
5024 
5026  L"usbflags",
5027  QueryTable,
5028  NULL,
5029  NULL);
5030 }
5031 
5032 NTSTATUS
5033 NTAPI
5036 {
5037  DPRINT("USBHUB: DriverEntry - %wZ\n", RegistryPath);
5038 
5041 
5044 
5047 
5051 
5053 
5054  return STATUS_SUCCESS;
5055 }
5056 
NTSTATUS NTAPI USBH_PassIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: usbhub.c:79
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
enum _USB_DEVICE_TYPE USB_DEVICE_TYPE
#define USBHUB_FDO_FLAG_DO_SUSPENSE
Definition: usbhub.h:56
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
PUSBHUB_FDO_EXTENSION HubExtension
Definition: usbhub.h:137
USB_20_PORT_STATUS Usb20PortStatus
Definition: usb200.h:223
NTSTATUS NTAPI USBH_ChangeIndication(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: usbhub.c:2238
VOID NTAPI USBH_UrbTimeoutDPC(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: usbhub.c:184
#define DO_POWER_PAGABLE
#define USBHUB_FEATURE_PORT_ENABLE
Definition: usbhub.h:92
VOID NTAPI USBH_HubCompletePortIdleIrps(IN PUSBHUB_FDO_EXTENSION HubExtension, IN NTSTATUS NtStatus)
Definition: usbhub.c:3104
struct _USB_DEVICE_DESCRIPTOR USB_DEVICE_DESCRIPTOR
#define USBH_EXTENSION_TYPE_PORT
Definition: usbhub.h:29
#define IOCTL_KS_PROPERTY
Definition: ks.h:150
CPPORT Port[4]
Definition: headless.c:34
const uint16_t * PCWSTR
Definition: typedefs.h:55
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:3988
#define IN
Definition: typedefs.h:38
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:308
#define STATUS_DEVICE_REMOVED
Definition: ntstatus.h:795
UCHAR bDescriptorLength
Definition: usb100.h:171
PUSB_DEVICE_HANDLE DeviceHandle
Definition: usbhub.h:211
#define USBHUB_PDO_FLAG_INIT_PORT_FAILED
Definition: usbhub.h:63
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI USBH_FdoIdleNotificationRequestComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: usbhub.c:3548
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
_In_ UCHAR _In_ POWER_STATE PowerState
Definition: pofuncs.h:42
_Inout_ PUSB_DEVICE_HANDLE _Out_writes_bytes_to_ DeviceDescriptorBufferLength PUCHAR _Inout_ PULONG _Out_writes_bytes_to_ ConfigDescriptorBufferLength PUCHAR ConfigDescriptorBuffer
Definition: hubbusif.h:151
PWSTR GenericUSBDeviceString
Definition: usbhub.c:19
NTSTATUS NTAPI USBH_SyncGetStatus(IN PDEVICE_OBJECT DeviceObject, IN PUSHORT OutStatus, IN USHORT Function, IN USHORT RequestIndex)
Definition: usbhub.c:1323
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define LL
Definition: tui.h:72
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
NTSTATUS NTAPI USBH_FdoSubmitWaitWakeIrp(IN PUSBHUB_FDO_EXTENSION HubExtension)
Definition: usbhub.c:3232
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS NTAPI USBH_SyncPowerOnPort(IN PUSBHUB_FDO_EXTENSION HubExtension, IN USHORT Port, IN BOOLEAN IsWait)
Definition: usbhub.c:1419
NTSTATUS NTAPI USBH_CheckDeviceLanguage(IN PDEVICE_OBJECT DeviceObject, IN USHORT LanguageId)
Definition: usbhub.c:4161
DEVICE_POWER_STATE DeviceWake
Definition: usbhub.h:159
_Inout_ PUSB_DEVICE_HANDLE DeviceHandle
Definition: hubbusif.h:121
NTSTATUS NTAPI USBH_ResetDevice(IN PUSBHUB_FDO_EXTENSION HubExtension, IN USHORT Port, IN BOOLEAN IsKeepDeviceData, IN BOOLEAN IsWait)
Definition: usbhub.c:4534
USB_BUSIFFN_REMOVE_USB_DEVICE * PUSB_BUSIFFN_REMOVE_USB_DEVICE
Definition: hubbusif.h:140
WORK_QUEUE_TYPE HubWorkItemType
Definition: usbhub.h:136
Type
Definition: Type.h:6
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2020
#define USBHUB_FDO_FLAG_PENDING_WAKE_IRP
Definition: usbhub.h:39
NTSTATUS NTAPI USBH_ChangeIndicationAckChange(IN PUSBHUB_FDO_EXTENSION HubExtension, IN PIRP Irp, IN struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *Urb, IN USHORT Port, IN USHORT RequestValue)
Definition: usbhub.c:1606
struct _Entry Entry
Definition: kefuncs.h:640
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
VOID NTAPI USBH_HubCompleteQueuedPortIdleIrps(IN PUSBHUB_FDO_EXTENSION HubExtension, IN PLIST_ENTRY IdleList, IN NTSTATUS NtStatus)
Definition: usbhub.c:3029
struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST SCEWorkerUrb
Definition: usbhub.h:175
#define USBHUB_FDO_FLAG_WAKEUP_START
Definition: usbhub.h:49
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4693
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
PUSBHUB_PORT_PDO_EXTENSION NTAPI PdoExt(IN PDEVICE_OBJECT DeviceObject)
Definition: usbhub.c:133
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
PUSBHUB_FDO_EXTENSION HubExtension
Definition: usbhub.h:249
VOID NTAPI USBH_HubQueuePortIdleIrps(IN PUSBHUB_FDO_EXTENSION HubExtension, IN PLIST_ENTRY IdleList)
Definition: usbhub.c:2971
#define USBHUB_FDO_FLAG_DEVICE_STOPPED
Definition: usbhub.h:37
NTSTATUS NTAPI USBH_WriteFailReasonID(IN PDEVICE_OBJECT DeviceObject, IN ULONG FailReason)
Definition: usbhub.c:153
NTSTATUS NTAPI USBH_GetSerialNumberString(IN PDEVICE_OBJECT DeviceObject, IN LPWSTR *OutSerialNumber, IN PUSHORT OutDescriptorLength, IN USHORT LanguageId, IN UCHAR Index)
Definition: usbhub.c:4223
#define REG_BINARY
Definition: nt_native.h:1496
#define PLUGPLAY_REGKEY_DEVICE
Definition: iofuncs.h:2738
VOID(NTAPI * PUSBHUB_WORKER_ROUTINE)(IN PUSBHUB_FDO_EXTENSION HubExtension, IN PVOID Context)
Definition: usbhub.h:127
_In_ PIRP Irp
Definition: csq.h:116
#define USBD_PORT_ENABLED
Definition: usbioctl.h:41
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ LARGE_INTEGER DueTime
Definition: kefuncs.h:524
#define USBHUB_PDO_FLAG_POWER_D1_OR_D2
Definition: usbhub.h:74
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
USB_PORT_STATUS_AND_CHANGE PortStatus
Definition: usbhub.h:118
DeviceType
Definition: mmdrv.h:41
#define IOCTL_INTERNAL_USB_ENABLE_PORT
Definition: usbioctl.h:47
_In_ ULONG DevInstKeyType
Definition: iofuncs.h:1123
NTSTATUS NTAPI USBH_RegQueryGenericUSBDeviceString(PVOID USBDeviceString)
Definition: usbhub.c:5009