ReactOS  0.4.13-dev-66-gc714b7f
hub_controller.cpp
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Universal Serial Bus Bulk Driver Library
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: lib/drivers/libusb/hub_controller.cpp
5  * PURPOSE: USB Common Driver Library.
6  * PROGRAMMERS:
7  * Michael Martin (michael.martin@reactos.org)
8  * Johannes Anderwald (johannes.anderwald@reactos.org)
9  */
10 
11 #include "libusb.h"
12 
13 #define NDEBUG
14 #include <debug.h>
15 
17  PVOID Context);
18 
19 class CHubController : public IHubController,
20  public IDispatchIrp
21 {
22 public:
24 
26  {
28  return m_Ref;
29  }
31  {
33 
34  if (!m_Ref)
35  {
36  delete this;
37  return 0;
38  }
39  return m_Ref;
40  }
41 
42  // IHubController interface functions
44  virtual NTSTATUS GetHubControllerDeviceObject(PDEVICE_OBJECT * HubDeviceObject);
46 
47  // IDispatchIrp interface functions
52 
53  // local functions
61  NTSTATUS AddUsbDevice(PUSBDEVICE UsbDevice);
64  // internal ioctl routines
80 
82 
83  // constructor / destructor
84  CHubController(IUnknown *OuterUnknown){}
85  virtual ~CHubController(){}
86 
87 protected:
93 
96 
99 
102 
104 
111 
112 
113  //Internal Functions
115 };
116 
117 typedef struct
118 {
122 
123 /* Lifted from Linux with slight changes */
125 {
126  0x12, /* bLength; */
127  USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType; Device */
128  0x00, 0x20, /* bcdUSB; v1.1 */
129  USB_DEVICE_CLASS_HUB, /* bDeviceClass; HUB_CLASSCODE */
130  0x01, /* bDeviceSubClass; */
131  0x00, /* bDeviceProtocol; [ low/full speeds only ] */
132  0x08, /* bMaxPacketSize0; 8 Bytes */
133  /* Fill Vendor and Product in when init root hub */
134  0x00, 0x00, /* idVendor; */
135  0x00, 0x00, /* idProduct; */
136  0x00, 0x00, /* bcdDevice */
137  0x00, /* iManufacturer; */
138  0x00, /* iProduct; */
139  0x00, /* iSerialNumber; */
140  0x01 /* bNumConfigurations; */
141 
142 };
143 
145 {
149  1,
150  1,
151  0,
152  0x40, /* self powered */
153  0x0
154 };
155 
157 {
158  sizeof(USB_INTERFACE_DESCRIPTOR), /* bLength */
159  USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType; Interface */
160  0, /* bInterfaceNumber; */
161  0, /* bAlternateSetting; */
162  0x1, /* bNumEndpoints; */
163  0x09, /* bInterfaceClass; HUB_CLASSCODE */
164  0x01, /* bInterfaceSubClass; */
165  0x00, /* bInterfaceProtocol: */
166  0x00, /* iInterface; */
167 };
168 
170 {
171  sizeof(USB_ENDPOINT_DESCRIPTOR), /* bLength */
172  USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
173  0x81, /* bEndPointAddress */
174  USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */
175  0x01, /* wMaxPacketSize */
176  0xC /* bInterval */
177 };
178 
179 //----------------------------------------------------------------------------------------
180 NTSTATUS
183  IN REFIID refiid,
184  OUT PVOID* Output)
185 {
186  return STATUS_UNSUCCESSFUL;
187 }
188 //----------------------------------------------------------------------------------------
189 NTSTATUS
192  IN PHCDCONTROLLER Controller,
194  IN BOOLEAN IsRootHubDevice,
196 {
198  PCOMMON_DEVICE_EXTENSION DeviceExtension;
199  USHORT VendorID, DeviceID;
200  ULONG Dummy1;
201 
202  //
203  // initialize members
204  //
205  m_Controller = Controller;
206  m_Hardware = Device;
207  m_IsRootHubDevice = IsRootHubDevice;
210  m_USBType = m_Hardware->GetUSBType();
213 
214  //
215  // allocate device address bitmap buffer
216  //
219  {
220  //
221  // no memory
222  //
224  }
225 
226  //
227  // initialize device address bitmap
228  //
231 
232  //
233  // create PDO
234  //
236  if (!NT_SUCCESS(Status))
237  {
238  //
239  // failed to create hub device object
240  //
241  return Status;
242  }
243 
244  //
245  // get device extension
246  //
248 
249  //
250  // initialize device extension
251  //
252  DeviceExtension->IsFDO = FALSE;
253  DeviceExtension->IsHub = TRUE; //FIXME
254  DeviceExtension->Dispatcher = PDISPATCHIRP(this);
255 
256  //
257  // intialize device descriptor
258  //
261 
262  if (NT_SUCCESS(m_Hardware->GetDeviceDetails(&VendorID, &DeviceID, &Dummy1, &Dummy1)))
263  {
264  //
265  // update device descriptor
266  //
267  m_DeviceDescriptor.idVendor = VendorID;
269  m_DeviceDescriptor.bcdUSB = 0x200; //FIXME
270  }
271 
272  //
273  // Set the SCE Callback that the Hardware Device will call on port status change
274  //
275  Device->SetStatusChangeEndpointCallBack((PVOID)StatusChangeEndpointCallBack, this);
276 
277  //
278  // clear init flag
279  //
281 
282  return STATUS_SUCCESS;
283 }
284 
285 //
286 // Queries the ports to see if there has been a device connected or removed.
287 //
288 BOOLEAN
290  PIRP Irp)
291 {
292  ULONG PortCount, PortId;
293  PIO_STACK_LOCATION IoStack;
294  USHORT PortStatus, PortChange;
295  PURB Urb;
296  PUCHAR TransferBuffer;
297  UCHAR Changed = FALSE;
298 
299  //
300  // get current stack location
301  //
303  ASSERT(IoStack);
304 
305  //
306  // Get the Urb
307  //
308  Urb = (PURB)IoStack->Parameters.Others.Argument1;
309  ASSERT(Urb);
310 
311  //
312  // Get the number of ports and check each one for device connected
313  //
314  m_Hardware->GetDeviceDetails(NULL, NULL, &PortCount, NULL);
315  DPRINT("[%s] SCE Request %p TransferBufferLength %lu Flags %x MDL %p\n", m_USBType, Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, Urb->UrbBulkOrInterruptTransfer.TransferFlags, Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
316 
317  TransferBuffer = (PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer;
318 
319  //
320  // Loop the ports
321  //
322  for (PortId = 0; PortId < PortCount; PortId++)
323  {
324  m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange);
325 
326  DPRINT("[%s] Port %d: Status %x, Change %x\n", m_USBType, PortId, PortStatus, PortChange);
327 
328 
329  //
330  // If there's a flag in PortChange return TRUE so the SCE Irp will be completed
331  //
332  if (PortChange != 0)
333  {
334  DPRINT1("[%s] Change state on port %d\n", m_USBType, PortId);
335  // Set the value for the port number
336  *TransferBuffer = 1 << ((PortId + 1) & 7);
337  Changed = TRUE;
338  }
339  }
340 
341  return Changed;
342 }
343 
344 //-----------------------------------------------------------------------------------------
345 NTSTATUS
347 {
348  //
349  // store controller object
350  //
351  *HubDeviceObject = m_HubControllerDeviceObject;
352 
353  return STATUS_SUCCESS;
354 }
355 //-----------------------------------------------------------------------------------------
356 NTSTATUS
359  PVOID Buffer,
361 {
362  if (!m_InterfaceEnabled)
363  {
364  //
365  // device interface not yet enabled
366  //
367  return STATUS_UNSUCCESSFUL;
368  }
369 
371  {
372  //
373  // buffer too small
374  // length is without '\??\'
375  //
377 
378  //
379  // done
380  //
381  return STATUS_BUFFER_OVERFLOW;
382  }
383 
384  //
385  // copy symbolic link
386  //
388 
389  //
390  // store length, length is without '\??\'
391  //
393 
394  //
395  // done
396  //
397  return STATUS_SUCCESS;
398 }
399 
400 //-----------------------------------------------------------------------------------------
401 NTSTATUS
404  IN OUT PIRP Irp)
405 {
406  PIO_STACK_LOCATION IoStack;
408  PPNP_BUS_INFORMATION BusInformation;
409  PDEVICE_RELATIONS DeviceRelations;
411  ULONG Index = 0;
412  SIZE_T Length;
413  USHORT VendorID, DeviceID;
414  ULONG HiSpeed, NumPorts;
415  WCHAR Buffer[300];
417 
418  //
419  // get current stack location
420  //
422 
423  switch(IoStack->MinorFunction)
424  {
425  case IRP_MN_START_DEVICE:
426  {
427  DPRINT("[%s] HandlePnp IRP_MN_START_DEVICE\n", m_USBType);
428  //
429  // register device interface
430  //
432  break;
433  }
436  {
437  //
438  // sure
439  //
441  break;
442  }
443  case IRP_MN_QUERY_ID:
444  {
445  DPRINT("[%s] HandlePnp IRP_MN_QUERY_ID Type %x\n", m_USBType, IoStack->Parameters.QueryId.IdType);
446 
447  if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
448  {
449  if (m_Hardware)
450  {
451  //
452  // query device id
453  //
454  Status = m_Hardware->GetDeviceDetails(&VendorID, &DeviceID, &NumPorts, &HiSpeed);
455 
456  if (HiSpeed == 0x200)
457  {
458  //
459  // USB 2.0 hub
460  //
461  swprintf(Buffer, L"USB\\ROOT_HUB20");
462  }
463  else
464  {
465  //
466  // USB 1.1 hub
467  //
468  swprintf(Buffer, L"USB\\ROOT_HUB");
469  }
470 
471  //
472  // calculate length
473  //
474  Length = (wcslen(Buffer) + 1);
475 
476  //
477  // allocate buffer
478  //
480 
481  if (!DeviceName)
482  {
483  //
484  // no memory
485  //
487  break;
488  }
489 
490  //
491  // copy device name
492  //
494 
495  //
496  // store result
497  //
498  Irp->IoStatus.Information = (ULONG_PTR)DeviceName;
500  break;
501  }
503  PC_ASSERT(0);
504  break;
505  }
506 
507  if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
508  {
509  if (m_Hardware)
510  {
511  //
512  // query device id
513  //
514  Status = m_Hardware->GetDeviceDetails(&VendorID, &DeviceID, &NumPorts, &HiSpeed);
515 
516  if (!NT_SUCCESS(Status))
517  {
518  DPRINT1("[%s] HandlePnp> failed to get hardware id %x\n", m_USBType, Status);
519  VendorID = 0x8086;
520  DeviceID = 0x3A37;
521  }
522 
523  if (HiSpeed == 0x200)
524  {
525  //
526  // USB 2.0 hub
527  //
528  Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20&VID%04x&PID%04x&REV0000", VendorID, DeviceID) + 1;
529  Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20&VID%04x&PID%04x", VendorID, DeviceID) + 1;
530  Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20") + 1;
531  }
532  else
533  {
534  //
535  // USB 1.1 hub
536  //
537  Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB&VID%04x&PID%04x&REV0000", VendorID, DeviceID) + 1;
538  Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB&VID%04x&PID%04x", VendorID, DeviceID) + 1;
539  Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB") + 1;
540  }
541 
543  Index++;
544 
545  //
546  // allocate buffer
547  //
549 
550  if (!DeviceName)
551  {
552  //
553  // no memory
554  //
556  break;
557  }
558 
559  //
560  // copy device name
561  //
563 
564  //
565  // store result
566  //
567  Irp->IoStatus.Information = (ULONG_PTR)DeviceName;
569  break;
570  }
571  }
572  // Here we should leave Status as is.
573  Status = Irp->IoStatus.Status;
574  break;
575  }
577  {
578  DPRINT("[%s] HandlePnp IRP_MN_QUERY_CAPABILITIES\n", m_USBType);
579 
580  DeviceCapabilities = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities;
581 
582  DeviceCapabilities->LockSupported = FALSE;
583  DeviceCapabilities->EjectSupported = FALSE;
584  DeviceCapabilities->Removable = FALSE;
585  DeviceCapabilities->DockDevice = FALSE;
586  DeviceCapabilities->UniqueID = FALSE;
587  DeviceCapabilities->SilentInstall = FALSE;
588  DeviceCapabilities->RawDeviceOK = FALSE;
589  DeviceCapabilities->SurpriseRemovalOK = FALSE;
590  DeviceCapabilities->Address = 0;
591  DeviceCapabilities->UINumber = 0;
592  DeviceCapabilities->DeviceD2 = 1;
593 
594  /* FIXME */
595  DeviceCapabilities->HardwareDisabled = FALSE;
596  DeviceCapabilities->NoDisplayInUI = FALSE;
597  DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
599  DeviceCapabilities->DeviceState[Index] = PowerDeviceD3;
601  DeviceCapabilities->D1Latency = 0;
602  DeviceCapabilities->D2Latency = 0;
603  DeviceCapabilities->D3Latency = 0;
604 
606  break;
607  }
609  {
610  DPRINT("[%s] HandlePnp IRP_MN_QUERY_INTERFACE\n", m_USBType);
611 
612  //
613  // handle device interface requests
614  //
615  Status = HandleQueryInterface(IoStack);
616 
617  //
618  // If a bus driver does not export the requested interface, it
619  // should leave Status as is.
620  //
622  Status = Irp->IoStatus.Status;
623 
624  break;
625  }
627  {
628  DPRINT("[%s] HandlePnp IRP_MN_REMOVE_DEVICE\n", m_USBType);
629 
630  //
631  // deactivate device interface for BUS PDO
632  //
634 
635  //
636  // complete the request first
637  //
638  Irp->IoStatus.Status = STATUS_SUCCESS;
640 
641  //
642  // now delete device
643  //
645 
646  //
647  // nullify pointer
648  //
650 
651  //
652  // done
653  //
654  return STATUS_SUCCESS;
655  }
657  {
658  DPRINT("[%s] HandlePnp IRP_MN_QUERY_DEVICE_RELATIONS Type %x\n", m_USBType, IoStack->Parameters.QueryDeviceRelations.Type);
659 
660  if (IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation)
661  {
662  //
663  // allocate device relations
664  //
666  if (!DeviceRelations)
667  {
668  //
669  // no memory
670  //
672  break;
673  }
674 
675  //
676  // initialize device relations
677  //
678  DeviceRelations->Count = 1;
679  DeviceRelations->Objects[0] = DeviceObject;
681 
682  //
683  // done
684  //
686  Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
687  }
688  else
689  {
690  //
691  // not handled
692  //
693  Status = Irp->IoStatus.Status;
694  }
695  break;
696  }
698  {
699  DPRINT("[%s] HandlePnp IRP_MN_QUERY_BUS_INFORMATION\n", m_USBType);
700 
701  //
702  // allocate buffer for bus information
703  //
705  if (BusInformation)
706  {
707  //
708  // copy BUS guid
709  //
710  RtlMoveMemory(&BusInformation->BusTypeGuid, &GUID_BUS_TYPE_USB, sizeof(GUID));
711 
712  //
713  // set bus type
714  //
715  BusInformation->LegacyBusType = PNPBus;
716  BusInformation->BusNumber = 0;
717 
719  Irp->IoStatus.Information = (ULONG_PTR)BusInformation;
720  }
721  else
722  {
723  //
724  // no memory
725  //
727  }
728  break;
729  }
730  case IRP_MN_STOP_DEVICE:
731  {
732  DPRINT("[%s] HandlePnp IRP_MN_STOP_DEVICE\n", m_USBType);
733  //
734  // stop device
735  //
737  break;
738  }
740  {
741  DPRINT("[%s] HandlePnp IRP_MN_SURPRISE_REMOVAL\n", m_USBType);
743  break;
744  }
745  default:
746  {
747  //
748  // ignore request with default status
749  //
750  Status = Irp->IoStatus.Status;
751  break;
752  }
753  }
754 
755  //
756  // complete request
757  //
758  Irp->IoStatus.Status = Status;
760 
761  //
762  // done
763  //
764  return Status;
765 }
766 
767 //-----------------------------------------------------------------------------------------
768 NTSTATUS
771  IN OUT PIRP Irp)
772 {
774  Status = Irp->IoStatus.Status;
777  return Status;
778 }
779 
780 //-----------------------------------------------------------------------------------------
781 NTSTATUS
784  IN OUT PIRP Irp)
785 {
787  Status = Irp->IoStatus.Status;
789  return Status;
790 }
791 
792 //-----------------------------------------------------------------------------------------
793 NTSTATUS
795  IN OUT PIRP Irp,
796  PURB Urb)
797 {
798  PUSBDEVICE UsbDevice;
799  PUSB_ENDPOINT_DESCRIPTOR EndPointDesc = NULL;
800 
801  //
802  // Check PipeHandle to determine if this is a Bulk or Interrupt Transfer Request
803  //
804  EndPointDesc = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbIsochronousTransfer.PipeHandle;
805 
806  if (!EndPointDesc)
807  {
808  DPRINT1("[%s] Error No EndpointDesc\n", m_USBType);
811  }
812 
813  //
814  // sanity checks
815  //
816  ASSERT(EndPointDesc);
817  DPRINT("[%s] HandleIsochronousTransfer EndPointDesc %p Address %x bmAttributes %x\n", m_USBType, EndPointDesc, EndPointDesc->bEndpointAddress, EndPointDesc->bmAttributes);
819 
820  //
821  // check if this is a valid usb device handle
822  //
823  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
824  {
825  DPRINT1("[%s] HandleIsochronousTransfer invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
826 
827  //
828  // invalid device handle
829  //
831  }
832 
833  //
834  // get device
835  //
836  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
837 
838  return UsbDevice->SubmitIrp(Irp);
839 }
840 
841 //-----------------------------------------------------------------------------------------
842 NTSTATUS
844  IN OUT PIRP Irp,
845  PURB Urb)
846 {
847  PUSBDEVICE UsbDevice;
848  PUSB_ENDPOINT EndPointDesc = NULL;
849  //
850  // First check if the request is for the Status Change Endpoint
851  //
852 
853  //
854  // Is the Request for the root hub
855  //
856  if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this) || Urb->UrbHeader.UsbdDeviceHandle == NULL)
857  {
860  {
861  //
862  // We've seen a change already, so return immediately
863  //
864  return STATUS_SUCCESS;
865  }
866 
867  //
868  // Else pend the IRP, to be completed when a device connects or disconnects.
869  //
870  DPRINT("[%s] Pending SCE Irp\n", m_USBType);
873  return STATUS_PENDING;
874  }
875 
876  //
877  // Check PipeHandle to determine if this is a Bulk or Interrupt Transfer Request
878  //
879  EndPointDesc = (PUSB_ENDPOINT)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
880 
881  //
882  // sanity checks
883  //
884  ASSERT(EndPointDesc);
886 
887  //
888  // check if this is a valid usb device handle
889  //
890  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
891  {
892  DPRINT1("[%s] HandleBulkOrInterruptTransfer invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
893 
894  //
895  // invalid device handle
896  //
898  }
899 
900  //
901  // get device
902  //
903  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
904  return UsbDevice->SubmitIrp(Irp);
905 }
906 
907 //-----------------------------------------------------------------------------------------
908 NTSTATUS
910  IN OUT PIRP Irp,
911  PURB Urb)
912 {
914  USHORT PortStatus = 0, PortChange = 0;
915  PUSHORT Buffer;
916  ULONG NumPort;
917  ULONG PortId;
918 
919  DPRINT("[%s] HandleClassOther> Request %x Value %x\n", m_USBType, Urb->UrbControlVendorClassRequest.Request, Urb->UrbControlVendorClassRequest.Value);
920 
921  //
922  // get number of ports available
923  //
924  Status = m_Hardware->GetDeviceDetails(NULL, NULL, &NumPort, NULL);
926 
927  //
928  // sanity check
929  //
930  PC_ASSERT(Urb->UrbControlVendorClassRequest.Index - 1 < (USHORT)NumPort);
931 
932  //
933  // port range reported start from 1 -n
934  // convert back port id so it matches the hardware
935  //
936  PortId = Urb->UrbControlVendorClassRequest.Index - 1;
937 
938  //
939  // check request code
940  //
941  switch(Urb->UrbControlVendorClassRequest.Request)
942  {
944  {
945  //
946  // sanity check
947  //
948  PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength == sizeof(USHORT) * 2);
949  PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer);
950 
951  //
952  // get port status
953  //
954  Status = m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange);
955 
956  if (NT_SUCCESS(Status))
957  {
958  //
959  // request contains buffer of 2 ushort which are used from submitting port status and port change status
960  //
961  DPRINT("[%s] PortId %x PortStatus %x PortChange %x\n", m_USBType, PortId, PortStatus, PortChange);
962  Buffer = (PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer;
963 
964  //
965  // store status, then port change
966  //
967  *Buffer = PortStatus;
968  Buffer++;
969  *Buffer = PortChange;
970  }
971 
972  //
973  // done
974  //
975  break;
976  }
978  {
979  switch (Urb->UrbControlVendorClassRequest.Value)
980  {
981  case C_PORT_CONNECTION:
982  Status = m_Hardware->ClearPortStatus(PortId, C_PORT_CONNECTION);
983  break;
984  case C_PORT_RESET:
985  Status = m_Hardware->ClearPortStatus(PortId, C_PORT_RESET);
986  break;
987  default:
988  DPRINT("[%s] Unknown Value for Clear Feature %x \n", m_USBType, Urb->UrbControlVendorClassRequest.Value);
989  break;
990  }
991 
992  break;
993  }
995  {
996  //
997  // request set feature
998  //
999  switch(Urb->UrbControlVendorClassRequest.Value)
1000  {
1001  case PORT_ENABLE:
1002  {
1003  //
1004  // port enable is a no-op for EHCI
1005  //
1007  break;
1008  }
1009 
1010  case PORT_SUSPEND:
1011  {
1012  //
1013  // set suspend port feature
1014  //
1015  Status = m_Hardware->SetPortFeature(PortId, PORT_SUSPEND);
1016  break;
1017  }
1018  case PORT_POWER:
1019  {
1020  //
1021  // set power feature on port
1022  //
1023  Status = m_Hardware->SetPortFeature(PortId, PORT_POWER);
1024  break;
1025  }
1026 
1027  case PORT_RESET:
1028  {
1029  //
1030  // reset port feature
1031  //
1032  Status = m_Hardware->SetPortFeature(PortId, PORT_RESET);
1034  break;
1035  }
1036  default:
1037  DPRINT1("[%s] Unsupported request id %x\n", m_USBType, Urb->UrbControlVendorClassRequest.Value);
1038  PC_ASSERT(FALSE);
1039  }
1040  break;
1041  }
1042  default:
1043  DPRINT1("[%s] HandleClassOther Unknown request code %x\n", m_USBType, Urb->UrbControlVendorClassRequest.Request);
1044  PC_ASSERT(0);
1046  }
1047  return Status;
1048 }
1049 
1050 //-----------------------------------------------------------------------------------------
1051 NTSTATUS
1053  IN OUT PIRP Irp,
1054  PURB Urb)
1055 {
1056  PUSBDEVICE UsbDevice;
1057  PUSBD_INTERFACE_INFORMATION InterfaceInfo;
1058  NTSTATUS Status;
1059 
1060  //
1061  // is the request for the Root Hub
1062  //
1063  if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
1064  {
1065  //
1066  // FIXME: support setting device to unconfigured state
1067  //
1068  PC_ASSERT(Urb->UrbSelectConfiguration.ConfigurationDescriptor);
1069 
1070  //
1071  // set device handle
1072  //
1073  Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)&ROOTHUB2_CONFIGURATION_DESCRIPTOR;
1074 
1075  //
1076  // copy interface info
1077  //
1078  InterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
1079 
1084  InterfaceInfo->Reserved = 0;
1085 
1086  //
1087  // sanity check
1088  //
1089  PC_ASSERT(InterfaceInfo->NumberOfPipes == 1);
1090 
1091  //
1092  // copy pipe info
1093  //
1098  InterfaceInfo->Pipes[0].PipeHandle = (PVOID)&ROOTHUB2_ENDPOINT_DESCRIPTOR;
1099 
1100  return STATUS_SUCCESS;
1101  }
1102  else
1103  {
1104  //
1105  // check if this is a valid usb device handle
1106  //
1107  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
1108  {
1109  DPRINT1("[%s] HandleSelectConfiguration invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
1110 
1111  //
1112  // invalid device handle
1113  //
1115  }
1116 
1117  //
1118  // get device
1119  //
1120  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
1121 
1122  //
1123  // select configuration
1124  //
1125  Status = UsbDevice->SelectConfiguration(Urb->UrbSelectConfiguration.ConfigurationDescriptor, &Urb->UrbSelectConfiguration.Interface, &Urb->UrbSelectConfiguration.ConfigurationHandle);
1126  if (NT_SUCCESS(Status))
1127  {
1128  // successfully configured device
1129  Urb->UrbSelectConfiguration.Hdr.Status = USBD_STATUS_SUCCESS;
1130  }
1131  return Status;
1132  }
1133 }
1134 
1135 //-----------------------------------------------------------------------------------------
1136 NTSTATUS
1138  IN OUT PIRP Irp,
1139  PURB Urb)
1140 {
1141  PUSBDEVICE UsbDevice;
1142 
1143  //
1144  // sanity check
1145  //
1146  PC_ASSERT(Urb->UrbSelectInterface.ConfigurationHandle);
1147 
1148  //
1149  // is the request for the Root Hub
1150  //
1151  if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
1152  {
1153  //
1154  // no op for root hub
1155  //
1156  return STATUS_SUCCESS;
1157  }
1158  else
1159  {
1160  //
1161  // check if this is a valid usb device handle
1162  //
1163  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
1164  {
1165  DPRINT1("[%s] HandleSelectInterface invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
1166 
1167  //
1168  // invalid device handle
1169  //
1171  }
1172 
1173  //
1174  // get device
1175  //
1176  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
1177 
1178  //
1179  // select interface
1180  //
1181  return UsbDevice->SelectInterface(Urb->UrbSelectInterface.ConfigurationHandle, &Urb->UrbSelectInterface.Interface);
1182  }
1183 }
1184 
1185 //-----------------------------------------------------------------------------------------
1186 NTSTATUS
1188  IN OUT PIRP Irp,
1189  PURB Urb)
1190 {
1191  PUSHORT DeviceStatus;
1193  NTSTATUS Status;
1194  PUSBDEVICE UsbDevice;
1195 
1196  //
1197  // sanity checks
1198  //
1199  PC_ASSERT(Urb->UrbControlGetStatusRequest.TransferBufferLength >= sizeof(USHORT));
1200  PC_ASSERT(Urb->UrbControlGetStatusRequest.TransferBuffer);
1201 
1202  //
1203  // get status buffer
1204  //
1205  DeviceStatus = (PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer;
1206 
1207 
1208  if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this) || Urb->UrbHeader.UsbdDeviceHandle == NULL)
1209  {
1210  //
1211  // FIXME need more flags ?
1212  //
1213  *DeviceStatus = USB_PORT_STATUS_CONNECT;
1214  return STATUS_SUCCESS;
1215  }
1216 
1217  //
1218  // check if this is a valid usb device handle
1219  //
1220  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
1221  {
1222  DPRINT1("[%s] HandleGetStatusFromDevice invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
1223 
1224  //
1225  // invalid device handle
1226  //
1228  }
1229 
1230  //
1231  // get device
1232  //
1233  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
1234 
1235 
1236  //
1237  // generate setup packet
1238  //
1239  CtrlSetup.bRequest = USB_REQUEST_GET_STATUS;
1240  CtrlSetup.wValue.LowByte = 0;
1241  CtrlSetup.wValue.HiByte = 0;
1242  CtrlSetup.wIndex.W = Urb->UrbControlGetStatusRequest.Index;
1243  CtrlSetup.wLength = (USHORT)Urb->UrbControlGetStatusRequest.TransferBufferLength;
1244  CtrlSetup.bmRequestType.B = 0x80;
1245 
1247  {
1248  //
1249  // add interface type
1250  //
1251  CtrlSetup.bmRequestType.B |= 0x01;
1252  }
1253  else if (Urb->UrbHeader.Function == URB_FUNCTION_GET_STATUS_FROM_ENDPOINT)
1254  {
1255  //
1256  // add interface type
1257  //
1258  CtrlSetup.bmRequestType.B |= 0x02;
1259  }
1260 
1261  //
1262  // submit setup packet
1263  //
1264  Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer);
1266  DPRINT1("[%s] HandleGetStatusFromDevice Status %x Length %lu DeviceStatus %x\n", m_USBType, Status, Urb->UrbControlDescriptorRequest.TransferBufferLength, *DeviceStatus);
1267 
1268  //
1269  // done
1270  //
1271  return Status;
1272 }
1273 
1274 //-----------------------------------------------------------------------------------------
1275 NTSTATUS
1277  IN OUT PIRP Irp,
1278  IN OUT PURB Urb)
1279 {
1281  PUSB_HUB_DESCRIPTOR UsbHubDescriptor;
1282  ULONG PortCount, Dummy2;
1283  USHORT Dummy1;
1284  PUSBDEVICE UsbDevice;
1286 
1287  DPRINT("[%s] HandleClassDevice Request %x Class %x\n", m_USBType, Urb->UrbControlVendorClassRequest.Request, Urb->UrbControlVendorClassRequest.Value >> 8);
1288 
1289  //
1290  // check class request type
1291  //
1292  switch(Urb->UrbControlVendorClassRequest.Request)
1293  {
1295  {
1296  //
1297  // check if this is a valid usb device handle
1298  //
1299  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
1300  {
1301  DPRINT1("[%s] HandleClassDevice invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
1302 
1303  //
1304  // invalid device handle
1305  //
1307  }
1308 
1309  //
1310  // get device
1311  //
1312  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
1313 
1314 
1315  //
1316  // generate setup packet
1317  //
1318  CtrlSetup.bRequest = USB_REQUEST_GET_STATUS;
1319  CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
1320  CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
1321  CtrlSetup.wLength = (USHORT)Urb->UrbControlGetStatusRequest.TransferBufferLength;
1322  CtrlSetup.bmRequestType.B = 0xA0;
1323 
1324  //
1325  // submit setup packet
1326  //
1327  Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer);
1329  break;
1330  }
1332  {
1333  switch (Urb->UrbControlVendorClassRequest.Value >> 8)
1334  {
1335  case USB_DEVICE_CLASS_RESERVED: // FALL THROUGH
1336  case USB_DEVICE_CLASS_HUB:
1337  {
1338  if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this) || Urb->UrbHeader.UsbdDeviceHandle == NULL)
1339  {
1340  //
1341  // sanity checks
1342  //
1343  PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer);
1344  PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength >= sizeof(USB_HUB_DESCRIPTOR));
1345 
1346  //
1347  // get hub descriptor
1348  //
1349  UsbHubDescriptor = (PUSB_HUB_DESCRIPTOR)Urb->UrbControlVendorClassRequest.TransferBuffer;
1350 
1351  //
1352  // one hub is handled
1353  //
1354  UsbHubDescriptor->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
1355  Urb->UrbControlVendorClassRequest.TransferBufferLength = sizeof(USB_HUB_DESCRIPTOR);
1356 
1357  //
1358  // type should 0x29 according to msdn
1359  //
1360  UsbHubDescriptor->bDescriptorType = 0x29;
1361 
1362  //
1363  // get port count
1364  //
1365  Status = m_Hardware->GetDeviceDetails(&Dummy1, &Dummy1, &PortCount, &Dummy2);
1367 
1368  //
1369  // FIXME: retrieve values
1370  //
1371  UsbHubDescriptor->bNumberOfPorts = (UCHAR)PortCount;
1372  UsbHubDescriptor->wHubCharacteristics = 0x00;
1373  UsbHubDescriptor->bPowerOnToPowerGood = 0x01;
1374  UsbHubDescriptor->bHubControlCurrent = 0x00;
1375 
1376  //
1377  // done
1378  //
1380  }
1381  else
1382  {
1383  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
1384  {
1385  DPRINT1("[%s] HandleClassDevice invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
1386  //
1387  // invalid device handle
1388  //
1390  }
1391 
1392  //
1393  // FIXME: implement support for real hubs
1394  //
1395  UNIMPLEMENTED;
1397  }
1398  break;
1399  }
1400  default:
1401  DPRINT1("[%s] HandleClassDevice Class %x not implemented\n", m_USBType, Urb->UrbControlVendorClassRequest.Value >> 8);
1402  break;
1403  }
1404  break;
1405  }
1406  default:
1407  {
1408  //
1409  // check if this is a valid usb device handle
1410  //
1411  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
1412  {
1413  DPRINT1("[%s] HandleClassDevice invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
1414 
1415  //
1416  // invalid device handle
1417  //
1419  }
1420 
1421  //
1422  // get device
1423  //
1424  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
1425 
1426  //
1427  // generate setup packet
1428  //
1429  CtrlSetup.bmRequestType.B = 0;
1430  CtrlSetup.bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
1431  CtrlSetup.bmRequestType.Type = BMREQUEST_CLASS;
1432  CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
1433  CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
1434  CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
1435  CtrlSetup.wLength = (USHORT)Urb->UrbControlVendorClassRequest.TransferBufferLength;
1436 
1437  if (Urb->UrbControlVendorClassRequest.TransferFlags & USBD_TRANSFER_DIRECTION_IN)
1438  {
1439  //
1440  // data direction is device to host
1441  //
1442  CtrlSetup.bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
1443  }
1444 
1445  //
1446  // submit setup packet
1447  //
1448  Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer);
1450 
1451  break;
1452  }
1453  }
1454 
1455  return Status;
1456 }
1457 
1458 //-----------------------------------------------------------------------------------------
1459 NTSTATUS
1461  IN OUT PIRP Irp,
1462  IN OUT PURB Urb)
1463 {
1464  PUSBDEVICE UsbDevice;
1466  NTSTATUS Status;
1467 
1468  //
1469  // sanity check
1470  //
1471  ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength);
1472  ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
1473 
1474  //
1475  // check if this is a valid usb device handle
1476  //
1477  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
1478  {
1479  DPRINT1("[%s] HandleGetDescriptorFromInterface invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
1480 
1481  //
1482  // invalid device handle
1483  //
1485  }
1486 
1487  //
1488  // get device
1489  //
1490  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
1491 
1492  //
1493  // generate setup packet
1494  //
1496  CtrlSetup.wValue.LowByte = Urb->UrbControlDescriptorRequest.Index;
1497  CtrlSetup.wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType;
1498  CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId;
1499  CtrlSetup.wLength = (USHORT)Urb->UrbControlDescriptorRequest.TransferBufferLength;
1500  CtrlSetup.bmRequestType.B = 0x81;
1501 
1502  //
1503  // submit setup packet
1504  //
1505  Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer);
1506  if (!NT_SUCCESS(Status))
1507  {
1508  DPRINT1("[%s] HandleGetDescriptorFromInterface failed with %x\n", m_USBType, Status);
1509  }
1510 
1511  //
1512  // done
1513  //
1514  return Status;
1515 }
1516 
1517 //-----------------------------------------------------------------------------------------
1518 NTSTATUS
1520  IN OUT PIRP Irp,
1521  IN OUT PURB Urb)
1522 {
1525  PUCHAR Buffer;
1526  PUSBDEVICE UsbDevice;
1528 
1529  DPRINT("[%s] HandleGetDescriptor Type %x\n", m_USBType, Urb->UrbControlDescriptorRequest.DescriptorType);
1530 
1531  //
1532  // check descriptor type
1533  //
1534  switch(Urb->UrbControlDescriptorRequest.DescriptorType)
1535  {
1537  {
1538  //
1539  // sanity check
1540  //
1541  PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR));
1542  PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
1543 
1544  if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this) || Urb->UrbHeader.UsbdDeviceHandle == NULL)
1545  {
1546  //
1547  // copy root hub device descriptor
1548  //
1549  RtlCopyMemory((PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer, &m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
1550  Irp->IoStatus.Information = sizeof(USB_DEVICE_DESCRIPTOR);
1551  Urb->UrbControlDescriptorRequest.Hdr.Status = USBD_STATUS_SUCCESS;
1553  }
1554  else
1555  {
1556  //
1557  // check if this is a valid usb device handle
1558  //
1559  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
1560  {
1561  DPRINT1("[%s] HandleGetDescriptor invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
1562 
1563  //
1564  // invalid device handle
1565  //
1567  }
1568 
1569  //
1570  // get device
1571  //
1572  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
1573 
1574  //
1575  // retrieve device descriptor from device
1576  //
1577  UsbDevice->GetDeviceDescriptor((PUSB_DEVICE_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer);
1578  Irp->IoStatus.Information = sizeof(USB_DEVICE_DESCRIPTOR);
1579  Urb->UrbControlDescriptorRequest.Hdr.Status = USBD_STATUS_SUCCESS;
1581  }
1582  break;
1583  }
1585  {
1586  //
1587  // sanity checks
1588  //
1589  PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
1590  //
1591  // From MSDN
1592  // The caller must allocate a buffer large enough to hold all of this information or the data is truncated without error.
1593  //
1594  BufferLength = Urb->UrbControlDescriptorRequest.TransferBufferLength;
1595  Buffer = (PUCHAR) Urb->UrbControlDescriptorRequest.TransferBuffer;
1596 
1597  if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this) || Urb->UrbHeader.UsbdDeviceHandle == NULL)
1598  {
1599  //
1600  // request is for the root bus controller
1601  //
1605 
1606  //
1607  // Check if we still have some space left
1608  //
1609  if(Length == BufferLength)
1610  {
1611  //
1612  // We copied all we could
1613  //
1615  break;
1616  }
1617  //
1618  // Go further
1619  //
1620  Buffer += Length;
1621  BufferLength -= Length;
1622 
1623  //
1624  // copy interface descriptor template
1625  //
1629 
1630  //
1631  // Check if we still have some space left
1632  //
1633  if(Length == BufferLength)
1634  {
1635  //
1636  // We copied all we could
1637  //
1639  break;
1640  }
1641  //
1642  // Go further
1643  //
1644  Buffer += Length;
1645  BufferLength -= Length;
1646 
1647 
1648  //
1649  // copy end point descriptor template
1650  //
1654 
1655  //
1656  // done
1657  //
1659 
1660  }
1661  else
1662  {
1663  //
1664  // check if this is a valid usb device handle
1665  //
1666  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
1667  {
1668  DPRINT1("[%s] USB_CONFIGURATION_DESCRIPTOR_TYPE invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
1669 
1670  //
1671  // invalid device handle
1672  //
1674  }
1675 
1676  //
1677  // get device
1678  //
1679  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
1680 
1681  //
1682  // Allocate temporary buffer
1683  //
1684  BufferLength = UsbDevice->GetConfigurationDescriptorsLength();
1686  if(!Buffer)
1687  {
1689  break;
1690  }
1691 
1692  //
1693  // perform work in IUSBDevice
1694  //
1695  UsbDevice->GetConfigurationDescriptors((PUSB_CONFIGURATION_DESCRIPTOR)Buffer, BufferLength, &Length);
1696 
1697  //
1698  // Copy what we can
1699  //
1700  Length = Urb->UrbControlDescriptorRequest.TransferBufferLength > Length ?
1701  Length : Urb->UrbControlDescriptorRequest.TransferBufferLength;
1702  RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, Buffer, Length);
1703 
1704  //
1705  // Free temporary buffer
1706  //
1708 
1709  //
1710  // store result size
1711  //
1712  Irp->IoStatus.Information = Length;
1713  Urb->UrbControlDescriptorRequest.TransferBufferLength = Length;
1714  Urb->UrbControlDescriptorRequest.Hdr.Status = USBD_STATUS_SUCCESS;
1716  }
1717  break;
1718  }
1720  {
1721  //
1722  // sanity check
1723  //
1724  PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
1725  PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength);
1726 
1727 
1728  //
1729  // check if this is a valid usb device handle
1730  //
1731  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
1732  {
1733  DPRINT1("[%s] USB_STRING_DESCRIPTOR_TYPE invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
1734 
1735  //
1736  // invalid device handle
1737  //
1739  }
1740 
1741  //
1742  // get device
1743  //
1744  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
1745 
1746  //
1747  // generate setup packet
1748  //
1750  CtrlSetup.wValue.LowByte = Urb->UrbControlDescriptorRequest.Index;
1751  CtrlSetup.wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType;
1752  CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId;
1753  CtrlSetup.wLength = (USHORT)Urb->UrbControlDescriptorRequest.TransferBufferLength;
1754  CtrlSetup.bmRequestType.B = 0x80;
1755 
1756  //
1757  // submit setup packet
1758  //
1759  Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer);
1760  break;
1761  }
1762  default:
1763  DPRINT1("[%s] CHubController::HandleGetDescriptor DescriptorType %x unimplemented\n", m_USBType, Urb->UrbControlDescriptorRequest.DescriptorType);
1764  break;
1765  }
1766 
1767  //
1768  // done
1769  //
1770  return Status;
1771 }
1772 
1773 //-----------------------------------------------------------------------------------------
1774 NTSTATUS
1776  IN OUT PIRP Irp,
1777  IN OUT PURB Urb)
1778 {
1780  NTSTATUS Status;
1781  PUSBDEVICE UsbDevice;
1782 
1783  //
1784  // sanity check
1785  //
1786  PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer);
1787  PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength);
1788  PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
1789 
1790  //
1791  // check if this is a valid usb device handle
1792  //
1793  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
1794  {
1795  DPRINT1("[%s] HandleClassEndpoint invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
1796 
1797  //
1798  // invalid device handle
1799  //
1801  }
1802 
1803  //
1804  // get device
1805  //
1806  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
1807 
1808 
1809  DPRINT1("URB_FUNCTION_CLASS_ENDPOINT\n");
1810  DPRINT1("TransferFlags %x\n", Urb->UrbControlVendorClassRequest.TransferFlags);
1811  DPRINT1("TransferBufferLength %x\n", Urb->UrbControlVendorClassRequest.TransferBufferLength);
1812  DPRINT1("TransferBuffer %x\n", Urb->UrbControlVendorClassRequest.TransferBuffer);
1813  DPRINT1("TransferBufferMDL %x\n", Urb->UrbControlVendorClassRequest.TransferBufferMDL);
1814  DPRINT1("RequestTypeReservedBits %x\n", Urb->UrbControlVendorClassRequest.RequestTypeReservedBits);
1815  DPRINT1("Request %x\n", Urb->UrbControlVendorClassRequest.Request);
1816  DPRINT1("Value %x\n", Urb->UrbControlVendorClassRequest.Value);
1817  DPRINT1("Index %x\n", Urb->UrbControlVendorClassRequest.Index);
1818 
1819  //
1820  // initialize setup packet
1821  //
1822  CtrlSetup.bmRequestType.B = 0x22; //FIXME: Const.
1823  CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
1824  CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
1825  CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
1826  CtrlSetup.wLength = (USHORT)Urb->UrbControlVendorClassRequest.TransferBufferLength;
1827 
1828  if (Urb->UrbControlVendorClassRequest.TransferFlags & USBD_TRANSFER_DIRECTION_IN)
1829  {
1830  //
1831  // data direction is device to host
1832  //
1833  CtrlSetup.bmRequestType.B |= 0x80;
1834  }
1835 
1836 
1837  //
1838  // issue request
1839  //
1840  Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlVendorClassRequest.TransferBufferLength, Urb->UrbControlVendorClassRequest.TransferBuffer);
1841 
1842  //
1843  // assert on failure
1844  //
1846 
1847 
1848  //
1849  // done
1850  //
1851  return Status;
1852 }
1853 
1854 //-----------------------------------------------------------------------------------------
1855 NTSTATUS
1857  IN OUT PIRP Irp,
1858  IN OUT PURB Urb)
1859 {
1861  PUSBDEVICE UsbDevice;
1863 
1864  //DPRINT("CHubController::HandleVendorDevice Request %x\n", Urb->UrbControlVendorClassRequest.Request);
1865 
1866  //
1867  // sanity check
1868  //
1869  PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
1870 
1871  //
1872  // check if this is a valid usb device handle
1873  //
1874  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
1875  {
1876  DPRINT1("[%s] HandleVendorDevice invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
1877 
1878  //
1879  // invalid device handle
1880  //
1882  }
1883 
1884  //
1885  // get device
1886  //
1887  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
1888 
1889  //
1890  // initialize setup packet
1891  //
1892  CtrlSetup.bmRequestType.B = 0;
1893  CtrlSetup.bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
1894  CtrlSetup.bmRequestType.Type = BMREQUEST_VENDOR;
1895  CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
1896  CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
1897  CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
1898  CtrlSetup.wLength = (USHORT)Urb->UrbControlVendorClassRequest.TransferBufferLength;
1899 
1900  if (Urb->UrbControlVendorClassRequest.TransferFlags & USBD_TRANSFER_DIRECTION_IN)
1901  {
1902  //
1903  // data direction is device to host
1904  //
1905  CtrlSetup.bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
1906  }
1907 
1908  //
1909  // issue request
1910  //
1911  Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlVendorClassRequest.TransferBufferLength, Urb->UrbControlVendorClassRequest.TransferBuffer);
1912  if (NT_SUCCESS(Status))
1913  {
1914  // success
1915  Urb->UrbControlVendorClassRequest.Hdr.Status = USBD_STATUS_SUCCESS;
1916  Irp->IoStatus.Information = Urb->UrbControlVendorClassRequest.TransferBufferLength;
1917  }
1918 
1919  return Status;
1920 }
1921 
1922 //-----------------------------------------------------------------------------------------
1923 NTSTATUS
1925  IN OUT PIRP Irp,
1926  IN OUT PURB Urb)
1927 {
1929  PUSB_ENDPOINT EndpointDescriptor;
1930  ULONG Type;
1931 
1932  //
1933  // sanity check
1934  //
1935  PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
1936  PC_ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST));
1937  PC_ASSERT(Urb->UrbPipeRequest.PipeHandle);
1938 
1939  //
1940  // check if this is a valid usb device handle
1941  //
1942  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
1943  {
1944  DPRINT1("[%s] HandleSyncResetAndClearStall invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
1945 
1946  //
1947  // invalid device handle
1948  //
1950  }
1951 
1952  //
1953  // abort pipe
1954  //
1955  Status = HandleAbortPipe(Irp, Urb);
1956  if (!NT_SUCCESS(Status))
1957  {
1958  //
1959  // failed
1960  //
1961  DPRINT1("[%s] failed to reset pipe %x\n", m_USBType, Status);
1962  }
1963 
1964 
1965  //
1966  // get endpoint descriptor
1967  //
1968  EndpointDescriptor = (PUSB_ENDPOINT)Urb->UrbPipeRequest.PipeHandle;
1969 
1970  //
1971  // get type
1972  //
1973  Type = (EndpointDescriptor->EndPointDescriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK);
1975  {
1976  //
1977  // clear stall
1978  //
1979  Status = HandleClearStall(Irp, Urb);
1980  }
1981  DPRINT1("[%s] URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL Status %x\n", m_USBType, Status);
1982 
1983  //
1984  // reset data toggle
1985  //
1986  if (NT_SUCCESS(Status))
1987  EndpointDescriptor->DataToggle = 0x0;
1988 
1989  //
1990  // done
1991  //
1992  return Status;
1993 }
1994 
1995 //-----------------------------------------------------------------------------------------
1996 NTSTATUS
1998  IN OUT PIRP Irp,
1999  IN OUT PURB Urb)
2000 {
2001  NTSTATUS Status;
2002  PUSBDEVICE UsbDevice;
2003  PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
2004 
2005  //
2006  // sanity check
2007  //
2008  PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
2009  PC_ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST));
2010  PC_ASSERT(Urb->UrbPipeRequest.PipeHandle);
2011 
2012  //
2013  // check if this is a valid usb device handle
2014  //
2015  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
2016  {
2017  DPRINT1("[%s] HandleAbortPipe invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
2018 
2019  //
2020  // invalid device handle
2021  //
2023  }
2024 
2025  //
2026  // get endpoint descriptor
2027  //
2028  EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbPipeRequest.PipeHandle;
2029 
2030  //
2031  // get device
2032  //
2033  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
2034 
2035 
2036  //
2037  // issue request
2038  //
2039  Status = UsbDevice->AbortPipe(EndpointDescriptor);
2040  DPRINT1("[%s] URB_FUNCTION_ABORT_PIPE Status %x\n", m_USBType, Status);
2041 
2042  //
2043  // done
2044  //
2045  return Status;
2046 }
2047 
2048 
2049 //-----------------------------------------------------------------------------------------
2050 NTSTATUS
2052  IN OUT PIRP Irp,
2053  IN OUT PURB Urb)
2054 {
2056  NTSTATUS Status;
2057  PUSBDEVICE UsbDevice;
2058  PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
2059 
2060 
2061  //
2062  // sanity check
2063  //
2064  PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
2065  PC_ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST));
2066  PC_ASSERT(Urb->UrbPipeRequest.PipeHandle);
2067 
2068  //
2069  // check if this is a valid usb device handle
2070  //
2071  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
2072  {
2073  DPRINT1("[%s] HandleClearStall invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
2074 
2075  //
2076  // invalid device handle
2077  //
2079  }
2080 
2081  //
2082  // get endpoint descriptor
2083  //
2084  EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbPipeRequest.PipeHandle;
2085 
2086  //
2087  // get device
2088  //
2089  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
2090  DPRINT1("[%s] URB_FUNCTION_SYNC_CLEAR_STALL\n", m_USBType);
2091 
2092  //
2093  // initialize setup packet
2094  //
2095  CtrlSetup.bmRequestType.B = 0x02;
2096  CtrlSetup.bRequest = USB_REQUEST_CLEAR_FEATURE;
2097  CtrlSetup.wValue.W = USB_FEATURE_ENDPOINT_STALL;
2098  CtrlSetup.wIndex.W = EndpointDescriptor->bEndpointAddress;
2099  CtrlSetup.wLength = 0;
2100  CtrlSetup.wValue.W = 0;
2101 
2102  //
2103  // issue request
2104  //
2105  Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, 0, 0);
2106 
2107  DPRINT1("[%s] URB_FUNCTION_CLEAR_STALL Status %x\n", m_USBType, Status);
2108 
2109  //
2110  // done
2111  //
2112  return Status;
2113 }
2114 
2115 
2116 //-----------------------------------------------------------------------------------------
2117 NTSTATUS
2119  IN OUT PIRP Irp,
2120  IN OUT PURB Urb)
2121 {
2123  NTSTATUS Status;
2124  PUSBDEVICE UsbDevice;
2125 
2126  //
2127  // sanity check
2128  //
2129  //ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer || Urb->UrbControlVendorClassRequest.TransferBufferMDL);
2130  //ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength);
2131  PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
2132 
2133  //
2134  // check if this is a valid usb device handle
2135  //
2136  if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
2137  {
2138  DPRINT1("[%s] HandleClassInterface invalid device handle %p\n", m_USBType, Urb->UrbHeader.UsbdDeviceHandle);
2139 
2140  //
2141  // invalid device handle
2142  //
2144  }
2145 
2146  //
2147  // get device
2148  //
2149  UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
2150 
2151 
2152  DPRINT("URB_FUNCTION_CLASS_INTERFACE\n");
2153  DPRINT("TransferFlags %x\n", Urb->UrbControlVendorClassRequest.TransferFlags);
2154  DPRINT("TransferBufferLength %x\n", Urb->UrbControlVendorClassRequest.TransferBufferLength);
2155  DPRINT("TransferBuffer %x\n", Urb->UrbControlVendorClassRequest.TransferBuffer);
2156  DPRINT("TransferBufferMDL %x\n", Urb->UrbControlVendorClassRequest.TransferBufferMDL);
2157  DPRINT("RequestTypeReservedBits %x\n", Urb->UrbControlVendorClassRequest.RequestTypeReservedBits);
2158  DPRINT("Request %x\n", Urb->UrbControlVendorClassRequest.Request);
2159  DPRINT("Value %x\n", Urb->UrbControlVendorClassRequest.Value);
2160  DPRINT("Index %x\n", Urb->UrbControlVendorClassRequest.Index);
2161 
2162  //
2163  // initialize setup packet
2164  //
2165  CtrlSetup.bmRequestType.B = 0x21;
2166  CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
2167  CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
2168  CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
2169  CtrlSetup.wLength = (USHORT)Urb->UrbControlVendorClassRequest.TransferBufferLength;
2170 
2171  if (Urb->UrbControlVendorClassRequest.TransferFlags & USBD_TRANSFER_DIRECTION_IN)
2172  {
2173  //
2174  // data direction is device to host
2175  //
2176  CtrlSetup.bmRequestType.B |= 0x80;
2177  }
2178 
2179  //
2180  // issue request
2181  //
2182  Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlVendorClassRequest.TransferBufferLength, Urb->UrbControlVendorClassRequest.TransferBuffer);
2183 
2184  //
2185  // assert on failure
2186  //
2187  if (!NT_SUCCESS(Status))
2188  {
2189  //
2190  // display error
2191  //
2192  DPRINT1("[%s] URB_FUNCTION_CLASS_INTERFACE failed with Urb Status %x\n", m_USBType, Urb->UrbHeader.Status);
2193  }
2194 
2195  //
2196  // done
2197  //
2198  return Status;
2199 }
2200 
2201 //-----------------------------------------------------------------------------------------
2202 NTSTATUS
2205  IN OUT PIRP Irp)
2206 {
2207  PIO_STACK_LOCATION IoStack;
2208  PURB Urb;
2210 
2211  //
2212  // get current stack location
2213  //
2214  IoStack = IoGetCurrentIrpStackLocation(Irp);
2215 
2216  //
2217  // determine which request should be performed
2218  //
2219  switch(IoStack->Parameters.DeviceIoControl.IoControlCode)
2220  {
2222  {
2223  //
2224  // get urb
2225  //
2226  Urb = (PURB)IoStack->Parameters.Others.Argument1;
2227  PC_ASSERT(Urb);
2228 
2229  switch (Urb->UrbHeader.Function)
2230  {
2231  case URB_FUNCTION_SYNC_RESET_PIPE:
2234  break;
2236  Status = HandleAbortPipe(Irp, Urb);
2237  break;
2238  case URB_FUNCTION_SYNC_CLEAR_STALL:
2239  Status = HandleClearStall(Irp, Urb);
2240  break;
2243  break;
2245  Status = HandleGetDescriptor(Irp, Urb);
2246  break;
2248  Status = HandleClassDevice(Irp, Urb);
2249  break;
2254  break;
2257  break;
2260  break;
2262  Status = HandleClassOther(Irp, Urb);
2263  break;
2266  break;
2269  break;
2272  break;
2274  Status = HandleClassEndpoint(Irp, Urb);
2275  break;
2277  Status = HandleVendorDevice(Irp, Urb);
2278  break;
2279  default:
2280  DPRINT1("[%s] IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", m_USBType, Urb->UrbHeader.Function);
2281  break;
2282  }
2283  //
2284  // request completed
2285  //
2286  break;
2287  }
2288  case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
2289  {
2290  DPRINT("[%s] IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %p\n", m_USBType, this);
2291 
2292  if (IoStack->Parameters.Others.Argument1)
2293  {
2294  //
2295  // store object as device handle
2296  //
2297  *(PVOID *)IoStack->Parameters.Others.Argument1 = (PVOID)this;
2299  }
2300  else
2301  {
2302  //
2303  // mis-behaving hub driver
2304  //
2306  }
2307 
2308  //
2309  // request completed
2310  //
2311  break;
2312  }
2314  {
2315  DPRINT("[%s] IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO\n", m_USBType);
2316 
2317  //
2318  // this is the first request send, it delivers the PDO to the caller
2319  //
2320  if (IoStack->Parameters.Others.Argument1)
2321  {
2322  //
2323  // store root hub pdo object
2324  //
2325  *(PVOID *)IoStack->Parameters.Others.Argument1 = DeviceObject;
2326  }
2327 
2328  if (IoStack->Parameters.Others.Argument2)
2329  {
2330  //
2331  // documentation claims to deliver the hcd controller object, although it is wrong
2332  //
2333  *(PVOID *)IoStack->Parameters.Others.Argument2 = DeviceObject;
2334  }
2335 
2336  //
2337  // request completed
2338  //
2340  break;
2341  }
2343  {
2344  DPRINT("[%s] IOCTL_INTERNAL_USB_GET_HUB_COUNT\n", m_USBType);
2345 
2346  //
2347  // after IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO is delivered, the usbhub driver
2348  // requests this ioctl to deliver the number of presents.
2349 
2350  if (IoStack->Parameters.Others.Argument1)
2351  {
2352  //
2353  // FIXME / verify: there is only one hub
2354  //
2355  *(PULONG)IoStack->Parameters.Others.Argument1 = 1;
2356  }
2357 
2358  //
2359  // request completed
2360  //
2362  Irp->IoStatus.Information = sizeof(ULONG);
2363  break;
2364  }
2365  case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
2366  {
2367  DPRINT1("[%s] IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION UNIMPLEMENTED\n", m_USBType);
2369  break;
2370  }
2371  default:
2372  {
2373  DPRINT1("[%s] HandleDeviceControl>Type: IoCtl %x InputBufferLength %lu OutputBufferLength %lu NOT IMPLEMENTED\n", m_USBType,
2374  IoStack->Parameters.DeviceIoControl.IoControlCode,
2375  IoStack->Parameters.DeviceIoControl.InputBufferLength,
2376  IoStack->Parameters.DeviceIoControl.OutputBufferLength);
2377  break;
2378  }
2379  }
2380  if (Status != STATUS_PENDING)
2381  {
2382  Irp->IoStatus.Status = Status;
2384  }
2385 
2386  return Status;
2387 }
2388 
2389 //-----------------------------------------------------------------------------------------
2392 {
2393  return m_Hardware;
2394 }
2395 
2396 //-----------------------------------------------------------------------------------------
2397 ULONG
2399 {
2400  KIRQL OldLevel;
2402 
2403  //
2404  // acquire device lock
2405  //
2406  KeAcquireSpinLock(&m_Lock, &OldLevel);
2407 
2408  //
2409  // find address
2410  //
2412  if (DeviceAddress != MAXULONG)
2413  {
2414  //
2415  // reserve address
2416  //
2418 
2419  //
2420  // device addresses start from 0x1 - 0xFF
2421  //
2422  DeviceAddress++;
2423  }
2424 
2425  //
2426  // release spin lock
2427  //
2428  KeReleaseSpinLock(&m_Lock, OldLevel);
2429 
2430  //
2431  // return device address
2432  //
2433  return DeviceAddress;
2434 }
2435 //-----------------------------------------------------------------------------------------
2436 VOID
2439 {
2440  KIRQL OldLevel;
2441 
2442  //
2443  // acquire device lock
2444  //
2445  KeAcquireSpinLock(&m_Lock, &OldLevel);
2446 
2447  //
2448  // sanity check
2449  //
2450  PC_ASSERT(DeviceAddress != 0);
2451 
2452  //
2453  // convert back to bit number
2454  //
2455  DeviceAddress--;
2456 
2457  //
2458  // clear bit
2459  //
2461 
2462  //
2463  // release lock
2464  //
2465  KeReleaseSpinLock(&m_Lock, OldLevel);
2466 }
2467 //-----------------------------------------------------------------------------------------
2468 NTSTATUS
2470  PUSBDEVICE UsbDevice)
2471 {
2472  PUSBDEVICE_ENTRY DeviceEntry;
2475  KIRQL OldLevel;
2476 
2477  //
2478  // acquire lock
2479  //
2480  KeAcquireSpinLock(&m_Lock, &OldLevel);
2481 
2482  //
2483  // point to first entry
2484  //
2486 
2487  //
2488  // find matching entry
2489  //
2490  while(Entry != &m_UsbDeviceList)
2491  {
2492  //
2493  // get entry
2494  //
2496 
2497  //
2498  // is it current entry
2499  //
2500  if (DeviceEntry->Device == UsbDevice)
2501  {
2502  //
2503  // remove entry
2504  //
2506 
2507  //
2508  // free entry
2509  //
2510  ExFreePoolWithTag(DeviceEntry, TAG_USBLIB);
2511 
2512  //
2513  // done
2514  //
2516  break;
2517  }
2518 
2519  //
2520  // goto next device
2521  //
2522  Entry = Entry->Flink;
2523  }
2524 
2525  //
2526  // release lock
2527  //
2528  KeReleaseSpinLock(&m_Lock, OldLevel);
2529 
2530  //
2531  // return result
2532  //
2533  return Status;
2534 }
2535 //-----------------------------------------------------------------------------------------
2536 BOOLEAN
2538 {
2539  PUSBDEVICE_ENTRY DeviceEntry;
2541  KIRQL OldLevel;
2542  BOOLEAN Result = FALSE;
2543 
2544  //
2545  // acquire lock
2546  //
2547  KeAcquireSpinLock(&m_Lock, &OldLevel);
2548 
2549  //
2550  // point to first entry
2551  //
2553 
2554  //
2555  // find matching entry
2556  //
2557  while(Entry != &m_UsbDeviceList)
2558  {
2559  //
2560  // get entry
2561  //
2563 
2564  //
2565  // is it current entry
2566  //
2567  if (DeviceEntry->Device == UsbDevice)
2568  {
2569  //
2570  // device is valid
2571  //
2572  Result = TRUE;
2573  break;
2574  }
2575 
2576  //
2577  // goto next device
2578  //
2579  Entry = Entry->Flink;
2580  }
2581 
2582  //
2583  // release lock
2584  //
2585  KeReleaseSpinLock(&m_Lock, OldLevel);
2586 
2587  //
2588  // return result
2589  //
2590  return Result;
2591 
2592 }
2593 
2594 //-----------------------------------------------------------------------------------------
2595 NTSTATUS
2597  PUSBDEVICE UsbDevice)
2598 {
2599  PUSBDEVICE_ENTRY DeviceEntry;
2600  KIRQL OldLevel;
2601 
2602  //
2603  // allocate device entry
2604  //
2606  if (!DeviceEntry)
2607  {
2608  //
2609  // no memory
2610  //
2612  }
2613 
2614  //
2615  // initialize entry
2616  //
2617  DeviceEntry->Device = UsbDevice;
2618 
2619  //
2620  // acquire lock
2621  //
2622  KeAcquireSpinLock(&m_Lock, &OldLevel);
2623 
2624  //
2625  // insert entry
2626  //
2627  InsertTailList(&m_UsbDeviceList, &DeviceEntry->Entry);
2628 
2629  //
2630  // release spin lock
2631  //
2632  KeReleaseSpinLock(&m_Lock, OldLevel);
2633 
2634  //
2635  // done
2636  //
2637  return STATUS_SUCCESS;
2638 }
2639 
2640 //-----------------------------------------------------------------------------------------
2641 VOID
2645 {
2646  KIRQL OldLevel;
2647 
2648  //
2649  // acquire hub controller lock
2650  //
2651  KeAcquireSpinLock(&m_Lock, &OldLevel);
2652 
2653  //
2654  // now set the callback routine and context of the hub
2655  //
2658 
2659  //
2660  // release hub controller lock
2661  //
2662  KeReleaseSpinLock(&m_Lock, OldLevel);
2663 }
2664 
2665 //=================================================================================================
2666 //
2667 // Generic Interface functions
2668 //
2669 VOID
2672  PVOID BusContext)
2673 {
2674  CHubController * Controller = (CHubController*)BusContext;
2675 
2676  DPRINT("USBI_InterfaceReference\n");
2677 
2678  //
2679  // add reference
2680  //
2681  Controller->AddRef();
2682 }
2683 
2684 VOID
2687  PVOID BusContext)
2688 {
2689  CHubController * Controller = (CHubController*)BusContext;
2690 
2691  DPRINT("USBI_InterfaceDereference\n");
2692 
2693  //
2694  // release
2695  //
2696  Controller->Release();
2697 }
2698 //=================================================================================================
2699 //
2700 // USB Hub Interface functions
2701 //
2702 NTSTATUS
2705  PVOID BusContext,
2706  PUSB_DEVICE_HANDLE *NewDevice,
2710 {
2711  PUSBDEVICE NewUsbDevice;
2712  CHubController * Controller;
2713  NTSTATUS Status;
2714 
2715  DPRINT1("USBHI_CreateUsbDevice\n");
2716 
2717  //
2718  // first get hub controller
2719  //
2720  Controller = (CHubController *)BusContext;
2721 
2722  //
2723  // sanity check
2724  //
2725  PC_ASSERT(Controller);
2726  PC_ASSERT(BusContext == HubDeviceHandle);
2727 
2728  //
2729  // now allocate usb device
2730  //
2731  Status = CreateUSBDevice(&NewUsbDevice);
2732 
2733  //
2734  // check for success
2735  //
2736  if (!NT_SUCCESS(Status))
2737  {
2738  //
2739  // release controller
2740  //
2741  Controller->Release();
2742  DPRINT1("USBHI_CreateUsbDevice: failed to create usb device %x\n", Status);
2743  return Status;
2744  }
2745 
2746  //
2747  // now initialize device
2748  //
2749  Status = NewUsbDevice->Initialize(PHUBCONTROLLER(Controller), Controller->GetUsbHardware(), HubDeviceHandle, PortNumber, PortStatus);
2750 
2751  //
2752  // check for success
2753  //
2754  if (!NT_SUCCESS(Status))
2755  {
2756  //
2757  // release usb device
2758  //
2759  NewUsbDevice->Release();
2760  DPRINT1("USBHI_CreateUsbDevice: failed to initialize usb device %x\n", Status);
2761  return Status;
2762  }
2763 
2764  //
2765  // insert into list
2766  //
2767  Status = Controller->AddUsbDevice(NewUsbDevice);
2768  //
2769  // check for success
2770  //
2771  if (!NT_SUCCESS(Status))
2772  {
2773  //
2774  // release usb device
2775  //
2776  NewUsbDevice->Release();
2777 
2778  DPRINT1("USBHI_CreateUsbDevice: failed to add usb device %x\n", Status);
2779  return Status;
2780  }
2781 
2782  //
2783  // store the handle
2784  //
2785  *NewDevice = NewUsbDevice;
2786 
2787  //
2788  // done
2789  //
2790  return STATUS_SUCCESS;
2791 }
2792 
2793 NTSTATUS
2796  PVOID BusContext,
2798 {
2799  PUSBDEVICE UsbDevice;
2800  CHubController * Controller;
2802  NTSTATUS Status;
2803  ULONG Index = 0;
2804 
2805  DPRINT("USBHI_InitializeUsbDevice\n");
2806 
2807  //
2808  // first get controller
2809  //
2810  Controller = (CHubController *)BusContext;
2811  PC_ASSERT(Controller);
2812 
2813  //
2814  // get device object
2815  //
2816  UsbDevice = (PUSBDEVICE)DeviceHandle;
2817  PC_ASSERT(UsbDevice);
2818 
2819  //
2820  // validate device handle
2821  //
2822  if (!Controller->ValidateUsbDevice(UsbDevice))
2823  {
2824  DPRINT1("USBHI_InitializeUsbDevice invalid device handle %p\n", DeviceHandle);
2825 
2826  //
2827  // invalid device handle
2828  //
2830  }
2831 
2832  //
2833  // now reserve an address
2834  //
2835  DeviceAddress = Controller->AcquireDeviceAddress();
2836 
2837  //
2838  // is the device address valid
2839  //
2840  if (DeviceAddress == MAXULONG)
2841  {
2842  //
2843  // failed to get an device address from the device address pool
2844  //
2845  DPRINT1("USBHI_InitializeUsbDevice failed to get device address\n");
2846  return STATUS_DEVICE_DATA_ERROR;
2847  }
2848 
2849  do
2850  {
2851  //
2852  // now set the device address
2853  //
2854  Status = UsbDevice->SetDeviceAddress((UCHAR)DeviceAddress);
2855 
2856  if (NT_SUCCESS(Status))
2857  break;
2858 
2859  }while(Index++ < 3 );
2860 
2861  //
2862  // check for failure
2863  //
2864  if (!NT_SUCCESS(Status))
2865  {
2866  //
2867  // failed to set device address
2868  //
2869  DPRINT1("USBHI_InitializeUsbDevice failed to set address with %x\n", Status);
2870 
2871  //
2872  // release address
2873  //
2874  Controller->ReleaseDeviceAddress(DeviceAddress);
2875 
2876  //
2877  // return error
2878  //
2879  return STATUS_DEVICE_DATA_ERROR;
2880  }
2881 
2882  //
2883  // done
2884  //
2885  return STATUS_SUCCESS;
2886 }
2887 
2888 NTSTATUS
2891  PVOID BusContext,
2897 {
2898  PUSBDEVICE UsbDevice;
2899  CHubController * Controller;
2900 
2901  DPRINT("USBHI_GetUsbDescriptors\n");
2902 
2903  //
2904  // sanity check
2905  //
2911 
2912  //
2913  // first get controller
2914  //
2915  Controller = (CHubController *)BusContext;
2916  PC_ASSERT(Controller);
2917 
2918 
2919  //
2920  // get device object
2921  //
2922  UsbDevice = (PUSBDEVICE)DeviceHandle;
2923  PC_ASSERT(UsbDevice);
2924 
2925  //
2926  // validate device handle
2927  //
2928  if (!Controller->ValidateUsbDevice(UsbDevice))
2929  {
2930  DPRINT1("USBHI_GetUsbDescriptors invalid device handle %p\n", DeviceHandle);
2931 
2932  //
2933  // invalid device handle
2934  //
2936  }
2937 
2938  //
2939  // get device descriptor
2940  //
2941  UsbDevice->GetDeviceDescriptor((PUSB_DEVICE_DESCRIPTOR)DeviceDescriptorBuffer);
2942 
2943  //
2944  // store result length
2945  //
2947 
2948  //
2949  // get configuration descriptor
2950  //
2952 
2953  //
2954  // complete the request
2955  //
2956  return STATUS_SUCCESS;
2957 }
2958 
2959 NTSTATUS
2962  PVOID BusContext,
2964  ULONG Flags)
2965 {
2966  PUSBDEVICE UsbDevice;
2967  CHubController * Controller;
2968  NTSTATUS Status;
2969 
2970  DPRINT("USBHI_RemoveUsbDevice\n");
2971 
2972  //
2973  // first get controller
2974  //
2975  Controller = (CHubController *)BusContext;
2976  PC_ASSERT(Controller);
2977 
2978  //
2979  // get device object
2980  //
2981  UsbDevice = (PUSBDEVICE)DeviceHandle;
2982  PC_ASSERT(UsbDevice);
2983 
2984  //
2985  // validate device handle
2986  //
2987  if (!Controller->ValidateUsbDevice(UsbDevice))
2988  {
2989  DPRINT1("USBHI_RemoveUsbDevice invalid device handle %p\n", DeviceHandle);
2990 
2991  //
2992  // invalid device handle
2993  //
2995  }
2996 
2997  //
2998  // check if there were flags passed
2999  //
3001  {
3002  //
3003  // ignore flags for now
3004  //
3005  return STATUS_SUCCESS;
3006  }
3007 
3008  //
3009  // remove device
3010  //
3011  Status = Controller->RemoveUsbDevice(UsbDevice);
3012  if (!NT_SUCCESS(Status))
3013  {
3014  //
3015  // invalid device handle
3016  //
3017  DPRINT1("USBHI_RemoveUsbDevice Invalid device handle %p\n", UsbDevice);
3019  }
3020 
3021  //
3022  // release usb device
3023  //
3024  UsbDevice->Release();
3025 
3026  //
3027  // done
3028  //
3029  return STATUS_SUCCESS;
3030 }
3031 
3032 NTSTATUS
3035  PVOID BusContext,
3038 {
3039  PUSBDEVICE OldUsbDevice, NewUsbDevice;
3040  CHubController * Controller;
3041 
3042  DPRINT("USBHI_RestoreUsbDevice\n");
3043 
3044  //
3045  // first get controller
3046  //
3047  Controller = (CHubController *)BusContext;
3048  PC_ASSERT(Controller);
3049 
3050  //
3051  // get device object
3052  //
3053  OldUsbDevice = (PUSBDEVICE)OldDeviceHandle;
3054  NewUsbDevice = (PUSBDEVICE)NewDeviceHandle;
3055  PC_ASSERT(OldUsbDevice);
3057 
3058  //
3059  // validate device handle
3060  //
3061  PC_ASSERT(Controller->ValidateUsbDevice(NewUsbDevice));
3062  PC_ASSERT(Controller->ValidateUsbDevice(OldUsbDevice));
3063 
3064  DPRINT1("NewUsbDevice: DeviceAddress %x\n", NewUsbDevice->GetDeviceAddress());
3065  DPRINT1("OldUsbDevice: DeviceAddress %x\n", OldUsbDevice->GetDeviceAddress());
3066 
3067  //
3068  // remove old device handle
3069  //
3070  USBHI_RemoveUsbDevice(BusContext, OldDeviceHandle, 0);
3071 
3072  return STATUS_SUCCESS;
3073 }
3074 
3075 NTSTATUS
3078  PVOID BusContext,
3080  PVOID DeviceInformationBuffer,
3083 {
3085  PUSBDEVICE UsbDevice;
3086  CHubController * Controller;
3087 
3088  DPRINT("USBHI_QueryDeviceInformation %p\n", BusContext);
3089 
3090  //
3091  // sanity check
3092  //
3094  PC_ASSERT(DeviceInformationBuffer);
3096 
3097  //
3098  // get controller object
3099  //
3100  Controller = (CHubController*)BusContext;
3101  PC_ASSERT(Controller);
3102 
3103  //
3104  // get device object
3105  //
3106  UsbDevice = (PUSBDEVICE)DeviceHandle;
3107  PC_ASSERT(UsbDevice);
3108 
3109  if (BusContext != DeviceHandle)
3110  {
3111  //
3112  // validate device handle
3113  //
3114  if (!Controller->ValidateUsbDevice(UsbDevice))
3115  {
3116  DPRINT1("USBHI_QueryDeviceInformation invalid device handle %p\n", DeviceHandle);
3117 
3118  //
3119  // invalid device handle
3120  //
3122  }
3123 
3124  //
3125  // access information buffer
3126  //
3127  DeviceInfo = (PUSB_DEVICE_INFORMATION_0)DeviceInformationBuffer;
3128 
3129  //
3130  // initialize with default values
3131  //
3132  DeviceInfo->InformationLevel = 0;
3133  DeviceInfo->ActualLength = sizeof(USB_DEVICE_INFORMATION_0);
3134  DeviceInfo->PortNumber = UsbDevice->GetPort();
3135  DeviceInfo->CurrentConfigurationValue = UsbDevice->GetConfigurationValue();
3136  DeviceInfo->DeviceAddress = UsbDevice->GetDeviceAddress();
3137  DeviceInfo->HubAddress = 0; //FIXME
3138  DeviceInfo->DeviceSpeed = UsbDevice->GetSpeed();
3139  DeviceInfo->DeviceType = UsbDevice->GetType();
3140  DeviceInfo->NumberOfOpenPipes = 0; //FIXME
3141 
3142  //
3143  // get device descriptor
3144  //
3145  UsbDevice->GetDeviceDescriptor(&DeviceInfo->DeviceDescriptor);
3146 
3147  //
3148  // FIXME return pipe information
3149  //
3150 
3151  //
3152  // store result length
3153  //
3155 
3156  return STATUS_SUCCESS;
3157  }
3158 
3159  //
3160  // access information buffer
3161  //
3162  DeviceInfo = (PUSB_DEVICE_INFORMATION_0)DeviceInformationBuffer;
3163 
3164  //
3165  // initialize with default values
3166  //
3167  DeviceInfo->InformationLevel = 0;
3168  DeviceInfo->ActualLength = sizeof(USB_DEVICE_INFORMATION_0);
3169  DeviceInfo->PortNumber = 0;
3170  DeviceInfo->CurrentConfigurationValue = 0; //FIXME;
3171  DeviceInfo->DeviceAddress = 0;
3172  DeviceInfo->HubAddress = 0; //FIXME
3173  DeviceInfo->DeviceSpeed = UsbHighSpeed; //FIXME
3174  DeviceInfo->DeviceType = Usb20Device; //FIXME
3175  DeviceInfo->NumberOfOpenPipes = 0; //FIXME
3176 
3177  //
3178  // get device descriptor
3179  //
3181 
3182  //
3183  // FIXME return pipe information
3184  //
3185 
3186  //
3187  // store result length
3188  //
3189 #ifdef _MSC_VER
3190  *LengthReturned = FIELD_OFFSET(USB_DEVICE_INFORMATION_0, PipeList[DeviceInfo->NumberOfOpenPipes]);
3191 #else
3192  *LengthReturned = sizeof(USB_DEVICE_INFORMATION_0) + (DeviceInfo->NumberOfOpenPipes > 1 ? (DeviceInfo->NumberOfOpenPipes - 1) * sizeof(USB_PIPE_INFORMATION_0) : 0);
3193 #endif
3194  //
3195  // done
3196  //
3197  return STATUS_SUCCESS;
3198 }
3199 
3200 NTSTATUS
3203  PVOID BusContext,
3204  PVOID ControllerInformationBuffer,
3207 {
3208  PUSB_CONTROLLER_INFORMATION_0 ControllerInfo;
3209 
3210  DPRINT("USBHI_GetControllerInformation\n");
3211 
3212  //
3213  // sanity checks
3214  //
3215  PC_ASSERT(ControllerInformationBuffer);
3217 
3218  //
3219  // get controller info buffer
3220  //
3221  ControllerInfo = (PUSB_CONTROLLER_INFORMATION_0)ControllerInformationBuffer;
3222 
3223  //
3224  // FIXME only version 0 is supported for now
3225  //
3226  PC_ASSERT(ControllerInfo->InformationLevel == 0);
3227 
3228  //
3229  // fill in information
3230  //
3231  ControllerInfo->ActualLength = sizeof(USB_CONTROLLER_INFORMATION_0);
3232  ControllerInfo->SelectiveSuspendEnabled = FALSE; //FIXME
3233  ControllerInfo->IsHighSpeedController = TRUE;
3234 
3235  //
3236  // set length returned
3237  //
3238  *LengthReturned = ControllerInfo->ActualLength;
3239 
3240  //
3241  // done
3242  //
3243  return STATUS_SUCCESS;
3244 }
3245 
3246 NTSTATUS
3249  PVOID BusContext,
3250  BOOLEAN Enable)
3251 {
3252  UNIMPLEMENTED;
3253  return STATUS_NOT_IMPLEMENTED;
3254 }
3255 
3256 NTSTATUS
3259  PVOID BusContext,
3261  PVOID HubInformationBuffer,
3264 {
3265  PUSB_EXTHUB_INFORMATION_0 HubInfo;
3266  CHubController * Controller;
3267  PUSBHARDWAREDEVICE Hardware;
3268  ULONG Index;
3269  ULONG NumPort, Dummy2;
3270  USHORT Dummy1;
3271  NTSTATUS Status;
3272 
3273  DPRINT("USBHI_GetExtendedHubInformation\n");
3274 
3275  //
3276  // sanity checks
3277  //
3278  PC_ASSERT(HubInformationBuffer);
3281 
3282  //
3283  // get hub controller
3284  //
3285  Controller = (CHubController *)BusContext;
3286  PC_ASSERT(Controller);
3287 
3288  //
3289  // get usb hardware device
3290  //
3291  Hardware = Controller->GetUsbHardware();
3292 
3293  //
3294  // retrieve number of ports
3295  //
3296  Status = Hardware->GetDeviceDetails(&Dummy1, &Dummy1, &NumPort, &Dummy2);
3297  if (!NT_SUCCESS(Status))
3298  {
3299  //
3300  // failed to get hardware details, ouch ;)
3301  //
3302  DPRINT1("USBHI_GetExtendedHubInformation failed to get hardware details with %x\n", Status);
3303  return Status;
3304  }
3305 
3306  //
3307  // get hub information buffer
3308  //
3309  HubInfo = (PUSB_EXTHUB_INFORMATION_0)HubInformationBuffer;
3310 
3311  //
3312  // initialize hub information
3313  //
3314  HubInfo->InformationLevel = 0;
3315 
3316  //
3317  // store port count
3318  //
3319  HubInfo->NumberOfPorts = NumPort;
3320 
3321  //
3322  // initialize port information
3323  //
3324  for(Index = 0; Index < NumPort; Index++)
3325  {
3326  HubInfo->Port[Index].PhysicalPortNumber = Index + 1;
3327  HubInfo->Port[Index].PortLabelNumber = Index + 1;
3328  HubInfo->Port[Index].VidOverride = 0;
3329  HubInfo->Port[Index].PidOverride = 0;
3330  HubInfo->Port[Index].PortAttributes = USB_PORTATTR_SHARED_USB2; //FIXME
3331  }
3332 
3333  //
3334  // store result length
3335  //
3336 #ifdef _MSC_VER
3338 #else
3340 #endif
3341 
3342  //
3343  // done
3344  //
3345  return STATUS_SUCCESS;
3346 }
3347 
3348 NTSTATUS
3351  PVOID BusContext,
3352  PVOID HubSymNameBuffer,
3355 {
3356  UNIMPLEMENTED;
3357  return STATUS_NOT_IMPLEMENTED;
3358 }
3359 
3360 PVOID
3363  PVOID HubBusContext,
3365 {
3366  UNIMPLEMENTED;
3367  return NULL;
3368 }
3369 
3370 NTSTATUS
3373  PVOID BusContext,
3375  ULONG TtCount)
3376 {
3377  DPRINT("USBHI_Initialize20Hub HubDeviceHandle %p UNIMPLEMENTED TtCount %lu\n", HubDeviceHandle, TtCount);
3378  return STATUS_SUCCESS;
3379 }
3380 
3381 
3382 WORKER_THREAD_ROUTINE InitRootHub;
3383 
3384 VOID
3385 NTAPI
3387 {
3388  PINIT_ROOT_HUB_CONTEXT WorkItem;
3389 
3390  //
3391  // get context
3392  //
3393  WorkItem = (PINIT_ROOT_HUB_CONTEXT)Context;
3394 
3395  //
3396  // perform callback
3397  //
3398  WorkItem->CallbackRoutine(WorkItem->CallbackContext);
3399 
3400  //
3401  // free contextg
3402  //
3404 }
3405 
3406 NTSTATUS
3409  PVOID BusContext,
3412 {
3413  CHubController * Controller;
3414  PINIT_ROOT_HUB_CONTEXT WorkItem;
3415 
3416  DPRINT("USBHI_RootHubInitNotification %p \n", CallbackContext);
3417 
3418  //
3419  // get controller object
3420  //
3421  Controller = (CHubController*)BusContext;
3422  PC_ASSERT(Controller);
3423 
3424  //
3425  // set notification routine
3426  //
3428 
3429  //
3430  // Create and initialize work item data
3431  //
3433  if (!WorkItem)
3434  {
3435  DPRINT1("Failed to allocate memory!n");
3437  }
3438 
3439  //
3440  // init context
3441  //
3442  WorkItem->CallbackRoutine = CallbackRoutine;
3443  WorkItem->CallbackContext = CallbackContext;
3444 
3445  //
3446  // Queue the work item to handle initializing the device
3447  //
3448  ExInitializeWorkItem(&WorkItem->WorkItem, InitRootHub, (PVOID)WorkItem);
3449  ExQueueWorkItem(&WorkItem->WorkItem, DelayedWorkQueue);
3450 
3451  //
3452  // done
3453  //
3454  return STATUS_SUCCESS;
3455 }
3456 
3457 VOID
3460  PVOID BusContext,
3462 {
3463  UNIMPLEMENTED;
3464 }
3465 
3466 VOID
3469  PVOID BusContext,
3472 {
3473  PUSBDEVICE UsbDevice;
3474  CHubController * Controller;
3475 
3476  //
3477  // get controller
3478  //
3479  Controller = (CHubController *)BusContext;
3480  PC_ASSERT(Controller);
3481 
3482  //
3483  // get device handle
3484  //
3485  UsbDevice = (PUSBDEVICE)DeviceHandle;
3486 
3487  //
3488  // validate device handle
3489  //
3490  if (!Controller->ValidateUsbDevice(UsbDevice))
3491  {
3492  DPRINT1("USBHI_SetDeviceHandleData DeviceHandle %p is invalid\n", DeviceHandle);
3493 
3494  //
3495  // invalid handle
3496  //
3497  return;
3498  }
3499  else
3500  {
3501  //
3502  // usbhub sends this request as a part of the Pnp startup sequence
3503  // looks like we need apply a dragon voodoo to fixup the device stack
3504  // otherwise usbhub will cause a bugcheck
3505  //
3506  DPRINT1("USBHI_SetDeviceHandleData %p\n", UsbDevicePdo);
3507 
3508  //
3509  // sanity check
3510  //
3511  PC_ASSERT(UsbDevicePdo->AttachedDevice);
3512 
3513  //
3514  // should be usbstor
3515  // fixup device stack voodoo part #2
3516  //
3517  UsbDevicePdo->AttachedDevice->StackSize++;
3518 
3519  //
3520  // set device handle data
3521  //
3522  UsbDevice->SetDeviceHandleData(UsbDevicePdo);
3523  }
3524 }
3525 
3526 //=================================================================================================
3527 //
3528 // USB Device Interface functions
3529 //
3530 
3531 VOID
3534  PVOID BusContext,
3535  PUSBD_VERSION_INFORMATION VersionInformation,
3536  PULONG HcdCapabilites)
3537 {
3538  CHubController * Controller;
3540  ULONG Speed, Dummy2;
3541  USHORT Dummy1;
3542 
3543  DPRINT("USBDI_GetUSBDIVersion\n");
3544 
3545  //
3546  // get controller
3547  //
3548  Controller = (CHubController*)BusContext;
3549 
3550  //
3551  // get usb hardware
3552  //
3553  Device = Controller->GetUsbHardware();
3554  PC_ASSERT(Device);
3555 
3556  if (VersionInformation)
3557  {
3558  //
3559  // windows xp supported
3560  //
3561  VersionInformation->USBDI_Version = 0x00000500;
3562 
3563  //
3564  // get device speed
3565  //
3566  Device->GetDeviceDetails(&Dummy1, &Dummy1, &Dummy2, &Speed);
3567 
3568  //
3569  // store speed details
3570  //
3571  VersionInformation->Supported_USB_Version = Speed;
3572  }
3573 
3574  //
3575  // no flags supported
3576  //
3577  *HcdCapabilites = 0;
3578 }
3579 
3580 NTSTATUS
3583  PVOID BusContext,
3584  PULONG CurrentFrame)
3585 {
3586  UNIMPLEMENTED;
3587  return STATUS_NOT_IMPLEMENTED;
3588 }
3589 
3590 NTSTATUS
3593  PVOID BusContext,
3594  PURB Urb)
3595 {
3596  UNIMPLEMENTED;
3597  return STATUS_NOT_IMPLEMENTED;
3598 }
3599 
3600 NTSTATUS
3603  PVOID BusContext,
3604  ULONG Level,
3605  PVOID BusInformationBuffer,
3606  PULONG BusInformationBufferLength,
3607  PULONG BusInformationActualLength)
3608 {
3609  UNIMPLEMENTED;
3610  return STATUS_NOT_IMPLEMENTED;
3611 }
3612 
3613 BOOLEAN
3616  PVOID BusContext)
3617 {
3618  CHubController * Controller;
3620  ULONG Speed, Dummy2;
3621  USHORT Dummy1;
3622 
3623  DPRINT("USBDI_IsDeviceHighSpeed\n");
3624 
3625  //
3626  // get controller
3627  //
3628  Controller = (CHubController*)BusContext;
3629 
3630  //
3631  // get usb hardware
3632  //
3633  Device = Controller->GetUsbHardware();
3634  PC_ASSERT(Device);
3635 
3636  //
3637  // get device speed
3638  //
3639  Device->GetDeviceDetails(&Dummy1, &Dummy1, &Dummy2, &Speed);
3640 
3641  //
3642  // USB 2.0 equals 0x200
3643  //
3644  return (Speed == 0x200);
3645 }
3646 
3647 NTSTATUS
3650  PVOID BusContext,
3651  ULONG DriverTag,
3652  ULONG EnumTag,
3653  ULONG P1,
3654  ULONG P2)
3655 {
3656  UNIMPLEMENTED;
3657  return STATUS_NOT_IMPLEMENTED;
3658 }
3659 
3660 NTSTATUS
3662  PIO_STACK_LOCATION IoStack)
3663 {
3664  PUSB_BUS_INTERFACE_HUB_V5 InterfaceHub;
3665  PUSB_BUS_INTERFACE_USBDI_V2 InterfaceDI;
3666  UNICODE_STRING GuidBuffer;
3667  NTSTATUS Status;
3668 
3669  if (IsEqualGUIDAligned(*IoStack->Parameters.QueryInterface.InterfaceType, USB_BUS_INTERFACE_HUB_GUID))
3670  {
3671  //
3672  // get request parameters
3673  //
3674  InterfaceHub = (PUSB_BUS_INTERFACE_HUB_V5)IoStack->Parameters.QueryInterface.Interface;
3675  InterfaceHub->Version = IoStack->Parameters.QueryInterface.Version;
3676 
3677  //
3678  // check version
3679  //
3680  if (IoStack->Parameters.QueryInterface.Version >= 6)
3681  {
3682  DPRINT1("USB_BUS_INTERFACE_HUB_GUID version %x not supported!\n", IoStack->Parameters.QueryInterface.Version);
3683 
3684  //
3685  // version not supported
3686  //
3687  return STATUS_NOT_SUPPORTED;
3688  }
3689 
3690  //
3691  // Interface version 0
3692  //
3693  InterfaceHub->Size = IoStack->Parameters.QueryInterface.Size;
3694  InterfaceHub->BusContext = PVOID(this);
3697 
3698  //
3699  // Interface version 1
3700  //
3701  if (IoStack->Parameters.QueryInterface.Version >= 1)
3702  {
3703  InterfaceHub->CreateUsbDevice = USBHI_CreateUsbDevice;
3706  InterfaceHub->RemoveUsbDevice = USBHI_RemoveUsbDevice;
3707  InterfaceHub->RestoreUsbDevice = USBHI_RestoreUsbDevice;
3709  }
3710 
3711  //
3712  // Interface version 2
3713  //
3714  if (IoStack->Parameters.QueryInterface.Version >= 2)
3715  {
3721  InterfaceHub->Initialize20Hub = USBHI_Initialize20Hub;
3722 
3723  }
3724 
3725  //
3726  // Interface version 3
3727  //
3728  if (IoStack->Parameters.QueryInterface.Version >= 3)
3729  {
3731  }
3732 
3733  //
3734  // Interface version 4
3735  //
3736  if (IoStack->Parameters.QueryInterface.Version >= 4)
3737  {
3738  InterfaceHub->FlushTransfers = USBHI_FlushTransfers;
3739  }
3740 
3741  //
3742  // Interface version 5
3743  //
3744  if (IoStack->Parameters.QueryInterface.Version >= 5)
3745  {
3747  }
3748 
3749  InterfaceHub->InterfaceReference(InterfaceHub->BusContext);
3750  //
3751  // request completed
3752  //
3753  return STATUS_SUCCESS;
3754  }
3755  else if (IsEqualGUIDAligned(*IoStack->Parameters.QueryInterface.InterfaceType, USB_BUS_INTERFACE_USBDI_GUID))
3756  {
3757  //
3758  // get request parameters
3759  //
3760  InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2) IoStack->Parameters.QueryInterface.Interface;
3761  InterfaceDI->Version = IoStack->Parameters.QueryInterface.Version;
3762 
3763  //
3764  // check version
3765  //
3766  if (IoStack->Parameters.QueryInterface.Version >= 3)
3767  {
3768  DPRINT1("USB_BUS_INTERFACE_USBDI_GUID version %x not supported!\n", IoStack->Parameters.QueryInterface.Version);
3769 
3770  //
3771  // version not supported
3772  //
3773  return STATUS_NOT_SUPPORTED;
3774  }
3775 
3776  //
3777  // interface version 0
3778  //
3779  InterfaceDI->Size = IoStack->Parameters.QueryInterface.Size;
3780  InterfaceDI->BusContext = PVOID(this);
3783  InterfaceDI->GetUSBDIVersion = USBDI_GetUSBDIVersion;
3784  InterfaceDI->QueryBusTime = USBDI_QueryBusTime;
3785  InterfaceDI->SubmitIsoOutUrb = USBDI_SubmitIsoOutUrb;
3787 
3788  //
3789  // interface version 1
3790  //
3791  if (IoStack->Parameters.QueryInterface.Version >= 1)
3792  {
3794  }
3795 
3796  //
3797  // interface version 2
3798  //
3799  if (IoStack->Parameters.QueryInterface.Version >= 2)
3800  {
3801  InterfaceDI->EnumLogEntry = USBDI_EnumLogEntry;
3802  }
3803 
3804  InterfaceDI->InterfaceReference(InterfaceDI->BusContext);
3805  //
3806  // request completed
3807  //
3808  return STATUS_SUCCESS;
3809  }
3810  else
3811  {
3812  //
3813  // convert guid to string
3814  //
3815  Status = RtlStringFromGUID(*IoStack->Parameters.QueryInterface.InterfaceType, &GuidBuffer);
3816  if (NT_SUCCESS(Status))
3817  {
3818  //
3819  // print interface
3820  //
3821  DPRINT1("HandleQueryInterface UNKNOWN INTERFACE GUID: %wZ Version %x\n", &GuidBuffer, IoStack->Parameters.QueryInterface.Version);
3822 
3823  //
3824  // free guid buffer
3825  //
3826  RtlFreeUnicodeString(&GuidBuffer);
3827  }
3828  }
3829  return STATUS_NOT_SUPPORTED;
3830 }
3831 
3832 NTSTATUS
3834  BOOLEAN Enable)
3835 {
3837 
3838  if (Enable)
3839  {
3840  //
3841  // register device interface
3842  //
3844 
3845  if (NT_SUCCESS(Status))
3846  {
3847  //
3848  // now enable the device interface
3849  //
3851 
3852  //
3853  // enable interface
3854  //
3856  }
3857  }
3858  else if (m_InterfaceEnabled)
3859  {
3860  //
3861  // disable device interface
3862  //
3864 
3865  if (NT_SUCCESS(Status))
3866  {
3867  //
3868  // now delete interface string
3869  //
3871  }
3872 
3873  //
3874  // disable interface
3875  //
3877  }
3878 
3879  //
3880  // done
3881  //
3882  return STATUS_SUCCESS;
3883 }
3884 
3885 NTSTATUS
3888  PDEVICE_OBJECT * OutDeviceObject)
3889 {
3890  WCHAR CharDeviceName[64];
3891  NTSTATUS Status;
3892  ULONG UsbDeviceNumber = 0;
3894 
3895  while (TRUE)
3896  {
3897  //
3898  // construct device name
3899  //
3900  swprintf(CharDeviceName, L"\\Device\\USBPDO-%d", UsbDeviceNumber);
3901 
3902  //
3903  // initialize device name
3904  //
3905  RtlInitUnicodeString(&DeviceName, CharDeviceName);
3906 
3907  //
3908  // create device
3909  //
3911  sizeof(COMMON_DEVICE_EXTENSION),
3912  &DeviceName,
3914  0,
3915  FALSE,
3916  OutDeviceObject);
3917 
3918  /* check for success */
3919  if (NT_SUCCESS(Status))
3920  break;
3921 
3922  //
3923  // is there a device object with that same name
3924  //
3926  {
3927  //
3928  // Try the next name
3929  //
3930  UsbDeviceNumber++;
3931  continue;
3932  }
3933 
3934  //
3935  // bail out on other errors
3936  //
3937  if (!NT_SUCCESS(Status))
3938  {
3939  DPRINT1("CreatePDO: Failed to create %wZ, Status %x\n", &DeviceName, Status);
3940  return Status;
3941  }
3942  }
3943 
3944  DPRINT("CHubController::CreatePDO: DeviceName %wZ\n", &DeviceName);
3945 
3946  //
3947  // fixup device stack voodoo part #1
3948  //
3949  (*OutDeviceObject)->StackSize++;
3950 
3951  /* done */
3952  return Status;
3953 }
3954 
3955 
3956 
3957 NTSTATUS
3958 NTAPI
3960  PHUBCONTROLLER *OutHcdController)
3961 {
3963 
3964  //
3965  // allocate controller
3966  //
3968  if (!This)
3969  {
3970  //
3971  // failed to allocate
3972  //
3974  }
3975 
3976  //
3977  // add reference count
3978  //
3979  This->AddRef();
3980 
3981  //
3982  // return result
3983  //
3984  *OutHcdController = (PHUBCONTROLLER)This;
3985 
3986  //
3987  // done
3988  //
3989  return STATUS_SUCCESS;
3990 }
3991 
3993 {
3995  PIRP Irp;
3997 
3998  ASSERT(This);
3999 
4000  Irp = This->m_PendingSCEIrp;
4001  if (!Irp)
4002  {
4003  DPRINT1("There was no pending IRP for SCE. Did the usb hub 2.0 driver (usbhub2) load?\n");
4004  return;
4005  }
4006 
4007  This->m_PendingSCEIrp = NULL;
4008  This->QueryStatusChangeEndpoint(Irp);
4009 
4010  Irp->IoStatus.Status = STATUS_SUCCESS;
4011  Irp->IoStatus.Information = 0;
4012 
4014 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
_In_ PDEVICE_OBJECT HubPhysicalDeviceObject
Definition: hubbusif.h:209
NTSTATUS HandleClassEndpoint(IN OUT PIRP Irp, PURB Urb)
struct _USB_DEVICE_DESCRIPTOR USB_DEVICE_DESCRIPTOR
CPPORT Port[4]
Definition: headless.c:34
NTSTATUS USB_BUSIFFN USBHI_Initialize20Hub(PVOID BusContext, PUSB_DEVICE_HANDLE HubDeviceHandle, ULONG TtCount)
#define IN
Definition: typedefs.h:38
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
#define PORT_RESET
Definition: usbhub.h:19
struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST UrbControlVendorClassRequest
Definition: usb.h:548
UCHAR bDescriptorLength
Definition: usb100.h:171
#define REFIID
Definition: guiddef.h:113
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSTATUS USB_BUSIFFN USBHI_GetRootHubSymbolicName(PVOID BusContext, PVOID HubSymNameBuffer, ULONG HubSymNameBufferLength, PULONG HubSymNameActualLength)
_Inout_ PUSB_DEVICE_HANDLE _Out_writes_bytes_to_ DeviceDescriptorBufferLength PUCHAR _Inout_ PULONG _Out_writes_bytes_to_ ConfigDescriptorBufferLength PUCHAR ConfigDescriptorBuffer
Definition: hubbusif.h:151
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
UNICODE_STRING m_HubDeviceInterfaceString
#define IRP_MN_REMOVE_DEVICE
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IRP_MN_QUERY_ID
#define C_PORT_CONNECTION
Definition: usbhub.h:22
#define USB_FEATURE_ENDPOINT_STALL
Definition: usb100.h:102
_Inout_ PUSB_DEVICE_HANDLE DeviceHandle
Definition: hubbusif.h:121
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR _In_ ULONGLONG _In_ ULONGLONG _In_opt_ PEVENT_FILTER_DESCRIPTOR _Inout_opt_ PVOID CallbackContext
Definition: wmitypes.h:55
#define USB_PORTATTR_SHARED_USB2
Definition: usb.h:48
#define PC_ASSERT(exp)
Definition: usbehci.h:17
virtual NTSTATUS Initialize(IN PDRIVER_OBJECT DriverObject, IN PHCDCONTROLLER Controller, IN PUSBHARDWAREDEVICE Device, IN BOOLEAN IsRootHubDevice, IN ULONG DeviceAddress)
Type
Definition: Type.h:6
IUSBHardwareDevice * PUSBHARDWAREDEVICE
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2020
const UCHAR ROOTHUB2_DEVICE_DESCRIPTOR[]
PDEVICE_OBJECT m_HubControllerDeviceObject
struct _Entry Entry
Definition: kefuncs.h:640
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
ULONG AcquireDeviceAddress()
NTSTATUS HandleQueryInterface(PIO_STACK_LOCATION IoStack)
_In_ BOOLEAN Release
Definition: classpnp.h:929
struct _USB_EXTPORT_INFORMATION_0 USB_EXTPORT_INFORMATION_0
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
NTSTATUS HandleSyncResetAndClearStall(IN OUT PIRP Irp, PURB Urb)
#define USBD_MARK_DEVICE_BUSY
Definition: hubbusif.h:30
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS USB_BUSIFFN USBHI_GetExtendedHubInformation(PVOID BusContext, PDEVICE_OBJECT HubPhysicalDeviceObject, PVOID HubInformationBuffer, ULONG HubInformationBufferLength, PULONG LengthReturned)
ULONG Supported_USB_Version
Definition: usb.h:241
PUSB_BUSIFFN_RESTORE_DEVICE RestoreUsbDevice
Definition: hubbusif.h:545
NTSTATUS USB_BUSIFFN USBHI_RemoveUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle, ULONG Flags)
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2054
unsigned char * PUCHAR
Definition: retypes.h:3
USBD_PIPE_INFORMATION Pipes[1]
Definition: usb.h:286
union _USB_DEFAULT_PIPE_SETUP_PACKET::_wIndex wIndex
USB_ENDPOINT_DESCRIPTOR EndPointDescriptor
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
PUSB_BUSIFFN_FLUSH_TRANSFERS FlushTransfers
Definition: hubbusif.h:555
#define URB_FUNCTION_CLASS_ENDPOINT
Definition: usb.h:114
#define URB_FUNCTION_VENDOR_DEVICE
Definition: usb.h:109
WORKER_THREAD_ROUTINE InitRootHub
RTL_BITMAP m_DeviceAddressBitmap
NTSTATUS USB_BUSIFFN USBHI_RestoreUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE OldDeviceHandle, PUSB_DEVICE_HANDLE NewDeviceHandle)
_In_ USHORT DeviceID
Definition: iotypes.h:859
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS HandleClassInterface(IN OUT PIRP Irp, PURB Urb)
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:140
VOID USB_BUSIFFN USBHI_FlushTransfers(PVOID BusContext, PVOID DeviceHandle)
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
#define C_PORT_RESET
Definition: usbhub.h:26
NTSTATUS NTAPI CreateUSBDevice(PUSBDEVICE *OutDevice)
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE HubDeviceHandle
Definition: hubbusif.h:40
NTSTATUS USB_BUSIFFN USBHI_RootHubInitNotification(PVOID BusContext, PVOID CallbackContext, PRH_INIT_CALLBACK CallbackRoutine)
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
PUSB_BUSIFFN_SUBMIT_ISO_OUT_URB SubmitIsoOutUrb
Definition: usbbusif.h:114
STDMETHODIMP_(ULONG) Release()
PVOID USB_BUSIFFN USBHI_GetDeviceBusContext(PVOID HubBusContext, PVOID DeviceHandle)
struct _USB_PIPE_INFORMATION_0 USB_PIPE_INFORMATION_0
VOID ReleaseDeviceAddress(ULONG DeviceAddress)
struct _USB_BUS_INTERFACE_HUB_V5 * PUSB_BUS_INTERFACE_HUB_V5
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define InsertTailList(ListHead, Entry)
struct _USB_HUB_DESCRIPTOR USB_HUB_DESCRIPTOR
PINTERFACE_DEREFERENCE InterfaceDereference
Definition: usbbusif.h:111
NTSTATUS USB_BUSIFFN USBDI_SubmitIsoOutUrb(PVOID BusContext, PURB Urb)
PULONG m_DeviceAddressBitmapBuffer
PUSB_BUSIFFN_GET_DEVICE_BUSCONTEXT GetDeviceBusContext
Definition: hubbusif.h:552
#define USB_STRING_DESCRIPTOR_TYPE
Definition: usb100.h:51
struct _USB_DEVICE_INFORMATION_0 * PUSB_DEVICE_INFORMATION_0
NTSTATUS SetDeviceInterface(BOOLEAN bEnable)
enum _USBD_PIPE_TYPE USBD_PIPE_TYPE
virtual NTSTATUS HandleDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:233
#define URB_FUNCTION_CLASS_DEVICE
Definition: usb.h:112
struct _USB_CONTROLLER_INFORMATION_0 USB_CONTROLLER_INFORMATION_0
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define PORT_SUSPEND
Definition: usbhub.h:17
struct _USB_HUB_DESCRIPTOR * PUSB_HUB_DESCRIPTOR
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Must_inspect_result_ _In_ PFLT_GET_OPERATION_STATUS_CALLBACK CallbackRoutine
Definition: fltkernel.h:1035
USHORT wHubCharacteristics
Definition: usb100.h:174
IUSBDevice * PUSBDEVICE
USB_EXTPORT_INFORMATION_0 Port[255]
Definition: hubbusif.h:732
_Inout_ PUSB_DEVICE_HANDLE OldDeviceHandle
Definition: hubbusif.h:161
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ PVOID _In_ PDEVICE_OBJECT UsbDevicePdo
Definition: hubbusif.h:321
#define FILE_DEVICE_CONTROLLER
Definition: winioctl.h:109
struct _USB_DEVICE_INFORMATION_0 USB_DEVICE_INFORMATION_0
NTSTATUS HandleVendorDevice(IN OUT PIRP Irp, PURB Urb)
#define USB_DEVICE_DESCRIPTOR_TYPE
Definition: usb100.h:49
struct _USB_EXTHUB_INFORMATION_0 * PUSB_EXTHUB_INFORMATION_0
#define UNICODE_NULL
PUSB_BUSIFFN_REMOVE_USB_DEVICE RemoveUsbDevice
Definition: hubbusif.h:544
#define IRP_MN_QUERY_REMOVE_DEVICE
_In_ PUSB_DEVICE_HANDLE _Out_ PUSHORT DeviceAddress
Definition: hubbusif.h:359
PUSB_BUSIFFN_IS_DEVICE_HIGH_SPEED IsDeviceHighSpeed
Definition: usbbusif.h:116
long LONG
Definition: pedump.c:60
_In_ ULONG BufferLength
Definition: usbdlib.h:225
NTSTATUS HandleClassDevice(IN OUT PIRP Irp, PURB Urb)
PUSB_BUSIFFN_SET_DEVHANDLE_DATA SetDeviceHandleData
Definition: hubbusif.h:556
PINTERFACE_REFERENCE InterfaceReference
Definition: hubbusif.h:539
#define BMREQUEST_DEVICE_TO_HOST
Definition: usb100.h:32
NTSTATUS USB_BUSIFFN USBDI_EnumLogEntry(PVOID BusContext, ULONG DriverTag, ULONG EnumTag, ULONG P1, ULONG P2)
#define USB_CONFIGURATION_DESCRIPTOR_TYPE
Definition: usb100.h:50
NTSTATUS USB_BUSIFFN USBHI_CreateUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE *NewDevice, PUSB_DEVICE_HANDLE HubDeviceHandle, USHORT PortStatus, USHORT PortNumber)
struct _USB_BUS_INTERFACE_USBDI_V2 * PUSB_BUS_INTERFACE_USBDI_V2
PUSBDEVICE Device
#define STDMETHODIMP
Definition: basetyps.h:43
PRH_INIT_CALLBACK CallbackRoutine
Definition: libusb.h:64
_Inout_ PUSB_DEVICE_HANDLE _Out_writes_bytes_to_ DeviceDescriptorBufferLength PUCHAR DeviceDescriptorBuffer
Definition: hubbusif.h:148
#define USB_BUSIFFN
Definition: hubbusif.h:22
struct _USB_INTERFACE_DESCRIPTOR USB_INTERFACE_DESCRIPTOR
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
ULONG PortNumber
Definition: storport.c:18
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
PVOID DeviceExtension
Definition: env_spec_w32.h:418
virtual ~CHubController()
unsigned char BOOLEAN
#define USB_INTERFACE_DESCRIPTOR_TYPE
Definition: usb100.h:52
NTSTATUS HandleGetDescriptor(IN OUT PIRP Irp, PURB Urb)
smooth NULL
Definition: ftsmooth.c:416
STDMETHODIMP_(ULONG) AddRef()
struct _PNP_BUS_INFORMATION * PPNP_BUS_INFORMATION
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ FILE_INFORMATION_CLASS _Out_opt_ PULONG LengthReturned
Definition: fltkernel.h:1306
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
UCHAR bPowerOnToPowerGood
Definition: usb100.h:175
#define DeviceCapabilities
Definition: wingdi.h:4427
void DPRINT(...)
Definition: polytest.cpp:61
IDispatchIrp * PDISPATCHIRP
_In_ ULONG _Out_ PULONG HubSymNameActualLength
Definition: hubbusif.h:222
Definition: bufpool.h:45
struct _USB_CONTROLLER_INFORMATION_0 * PUSB_CONTROLLER_INFORMATION_0
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
const char * LPCSTR
Definition: xmlstorage.h:183
void * PVOID
Definition: retypes.h:9
NTSTATUS AddUsbDevice(PUSBDEVICE UsbDevice)
struct _USB_ENDPOINT_DESCRIPTOR * PUSB_ENDPOINT_DESCRIPTOR
WORK_QUEUE_ITEM WorkItem
Definition: usbhub.h:38
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
virtual NTSTATUS GetHubControllerDeviceObject(PDEVICE_OBJECT *HubDeviceObject)
USBD_PIPE_HANDLE PipeHandle
Definition: usb.h:264
#define URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL
Definition: usb.h:116
#define URB_FUNCTION_GET_STATUS_FROM_INTERFACE
Definition: usb.h:106
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
PHCDCONTROLLER m_Controller
#define TAG_USBLIB
Definition: libusb.h:70
#define PORT_ENABLE
Definition: usbhub.h:16
VOID USB_BUSIFFN USBI_InterfaceDereference(PVOID BusContext)
#define IRP_MN_QUERY_STOP_DEVICE
NTSTATUS NTAPI CreateHubController(PHUBCONTROLLER *OutHcdController)
#define USBD_KEEP_DEVICE_DATA
Definition: hubbusif.h:29
BOOLEAN m_IsRootHubDevice
NTSTATUS USB_BUSIFFN USBHI_InitializeUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle)
#define USB_ENDPOINT_TYPE_MASK
Definition: usb100.h:61
struct _URB_HEADER UrbHeader
Definition: usb.h:531
NTSYSAPI void WINAPI RtlClearAllBits(PRTL_BITMAP)
BOOLEAN QueryStatusChangeEndpoint(PIRP Irp)
NTSTATUS HandleAbortPipe(IN OUT PIRP Irp, PURB Urb)
#define URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE
Definition: usb.h:126
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
VOID USB_BUSIFFN USBHI_SetDeviceHandleData(PVOID BusContext, PVOID DeviceHandle, PDEVICE_OBJECT UsbDevicePdo)
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
struct _USB_ENDPOINT * PUSB_ENDPOINT
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
NTSTATUS USB_BUSIFFN USBHI_ControllerSelectiveSuspend(PVOID BusContext, BOOLEAN Enable)
NTSTATUS USB_BUSIFFN USBDI_QueryBusInformation(PVOID BusContext, ULONG Level, PVOID BusInformationBuffer, PULONG BusInformationBufferLength, PULONG BusInformationActualLength)
UCHAR bNumberOfPorts
Definition: usb100.h:173
virtual NTSTATUS HandleSystemControl(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
#define IRP_MN_STOP_DEVICE
UCHAR EndpointAddress
Definition: usb.h:261
USB_DEVICE_DESCRIPTOR m_DeviceDescriptor
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define USB_REQUEST_CLEAR_FEATURE
Definition: usb100.h:79
#define STATUS_PENDING
Definition: ntstatus.h:82
#define URB_FUNCTION_GET_STATUS_FROM_ENDPOINT
Definition: usb.h:107
USHORT MaximumPacketSize
Definition: usb.h:260
NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb)
_In_ ULONG ControllerInformationBufferLength
Definition: hubbusif.h:192
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define IRP_MN_START_DEVICE
struct _COMMON_DEVICE_EXTENSION * PCOMMON_DEVICE_EXTENSION
static const UCHAR Index[8]
Definition: usbohci.c:18
struct _DeviceInfo DeviceInfo
struct _USB_ENDPOINT_DESCRIPTOR USB_ENDPOINT_DESCRIPTOR
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
virtual NTSTATUS HandlePower(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
NTSTATUS HandleSelectConfiguration(IN OUT PIRP Irp, PURB Urb)
PUSBHARDWAREDEVICE GetUsbHardware()
#define IOCTL_INTERNAL_USB_GET_HUB_COUNT
Definition: usbioctl.h:50
#define for
Definition: utility.h:88
NTSTATUS HandleGetDescriptorFromInterface(IN OUT PIRP Irp, PURB Urb)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
RH_INIT_CALLBACK * PRH_INIT_CALLBACK
Definition: hubbusif.h:270
#define IRP_MN_QUERY_INTERFACE
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define USB_PORT_STATUS_CONNECT
Definition: usb200.h:151
UCHAR bHubControlCurrent
Definition: usb100.h:176
PUSBHARDWAREDEVICE m_Hardware
friend VOID NTAPI StatusChangeEndpointCallBack(PVOID Context)
#define USB_ENDPOINT_TYPE_ISOCHRONOUS
Definition: usb100.h:63
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define PORT_POWER
Definition: usbhub.h:20
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define USB_REQUEST_GET_DESCRIPTOR
Definition: usb100.h:82
#define USBD_STATUS_SUCCESS
Definition: usb.h:170
_Inout_ PUSB_DEVICE_HANDLE _Out_writes_bytes_to_ DeviceDescriptorBufferLength PUCHAR _Inout_ PULONG DeviceDescriptorBufferLength
Definition: hubbusif.h:148
#define IRP_MN_QUERY_BUS_INFORMATION
PUSB_BUSIFFN_GETUSBDI_VERSION GetUSBDIVersion
Definition: usbbusif.h:112
unsigned char UCHAR
Definition: xmlstorage.h:181
#define BMREQUEST_CLASS
Definition: usb100.h:35
CHubController(IUnknown *OuterUnknown)
#define URB_FUNCTION_SELECT_CONFIGURATION
Definition: usb.h:86
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
NTSTATUS RemoveUsbDevice(PUSBDEVICE UsbDevice)
#define IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO
Definition: usbioctl.h:38
static const WCHAR L[]
Definition: oid.c:1250
#define InterlockedDecrement
Definition: armddk.h:52
NTSTATUS CreatePDO(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT *OutDeviceObject)
PUSB_BUSIFFN_GET_DEVICE_INFORMATION QueryDeviceInformation
Definition: hubbusif.h:547
virtual NTSTATUS GetHubControllerSymbolicLink(ULONG BufferLength, PVOID Buffer, PULONG RequiredLength)
Definition: arc.h:85
const USB_INTERFACE_DESCRIPTOR ROOTHUB2_INTERFACE_DESCRIPTOR
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define USB_ENDPOINT_DESCRIPTOR_TYPE
Definition: usb100.h:53
NTSTATUS USB_BUSIFFN USBDI_QueryBusTime(PVOID BusContext, PULONG CurrentFrame)
BOOLEAN m_InterfaceEnabled
_Inout_ PUSB_DEVICE_HANDLE _Out_writes_bytes_to_ DeviceDescriptorBufferLength PUCHAR _Inout_ PULONG _Out_writes_bytes_to_ ConfigDescriptorBufferLength PUCHAR _Inout_ PULONG ConfigDescriptorBufferLength
Definition: hubbusif.h:151
NTSTATUS HandleClassOther(IN OUT PIRP Irp, PURB Urb)
Definition: typedefs.h:117
NTSTATUS HandleSelectInterface(IN OUT PIRP Irp, PURB Urb)
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
#define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
Definition: usb.h:97
#define USB_ENDPOINT_TYPE_BULK
Definition: usb100.h:64
NTSTATUS USB_BUSIFFN USBHI_GetUsbDescriptors(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle, PUCHAR DeviceDescriptorBuffer, PULONG DeviceDescriptorBufferLength, PUCHAR ConfigDescriptorBuffer, PULONG ConfigDescriptorBufferLength)
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
Definition: hubbusif.h:40
#define USB_DEVICE_CLASS_RESERVED
Definition: usb100.h:90
PINTERFACE_REFERENCE InterfaceReference
Definition: usbbusif.h:110
struct _USB_CONFIGURATION_DESCRIPTOR USB_CONFIGURATION_DESCRIPTOR
PUSB_BUSIFFN_QUERY_BUS_INFORMATION QueryBusInformation
Definition: usbbusif.h:115
#define URB_FUNCTION_SELECT_INTERFACE
Definition: usb.h:87
* PDEVICE_CAPABILITIES
Definition: iotypes.h:927
struct _URB * PURB
Status
Definition: gdiplustypes.h:24
VOID USB_BUSIFFN USBI_InterfaceReference(PVOID BusContext)
#define MAXULONG
Definition: typedefs.h:250
NTSTATUS USB_BUSIFFN USBHI_GetControllerInformation(PVOID BusContext, PVOID ControllerInformationBuffer, ULONG ControllerInformationBufferLength, PULONG LengthReturned)
PUSB_BUSIFFN_GET_ROOTHUB_SYM_NAME GetRootHubSymbolicName
Definition: hubbusif.h:551
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
PUSB_BUSIFFN_ROOTHUB_INIT_NOTIFY RootHubInitNotification
Definition: hubbusif.h:554
ULONG_PTR SIZE_T
Definition: typedefs.h:78
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1250
NTSTATUS HandleGetStatusFromDevice(IN OUT PIRP Irp, PURB Urb)
struct _URB_ISOCH_TRANSFER UrbIsochronousTransfer
Definition: usb.h:544
USBD_INTERFACE_HANDLE InterfaceHandle
Definition: usb.h:284
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
struct _URB_SELECT_CONFIGURATION UrbSelectConfiguration
Definition: usb.h:533
#define USB_REQUEST_GET_STATUS
Definition: usb100.h:78
_In_ BOOL bEnable
Definition: winddi.h:3426
#define InterlockedIncrement
Definition: armddk.h:53
USBD_PIPE_TYPE PipeType
Definition: usb.h:263
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
NTSTATUS HandleIsochronousTransfer(IN OUT PIRP Irp, PURB Urb)
PUSB_BUSIFFN_GET_CONTROLLER_INFORMATION GetControllerInformation
Definition: hubbusif.h:548
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:626
Definition: usb.h:529
VOID SetNotification(PVOID CallbackContext, PRH_INIT_CALLBACK CallbackRoutine)
PUSB_BUSIFFN_INITIALIZE_20HUB Initialize20Hub
Definition: hubbusif.h:553
#define URB_FUNCTION_ISOCH_TRANSFER
Definition: usb.h:96
#define C_ASSERT(e)
Definition: ntstrsafe.h:22
unsigned short USHORT
Definition: pedump.c:61
#define URB_FUNCTION_ABORT_PIPE
Definition: usb.h:88
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:29
NTSTATUS USB_BUSIFFN USBHI_QueryDeviceInformation(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle, PVOID DeviceInformationBuffer, ULONG DeviceInformationBufferLength, PULONG LengthReturned)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define URB_FUNCTION_CLASS_INTERFACE
Definition: usb.h:113
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
PINTERFACE_DEREFERENCE InterfaceDereference
Definition: hubbusif.h:540
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define USB_REQUEST_SET_FEATURE
Definition: usb100.h:80
unsigned int * PULONG
Definition: retypes.h:1
PUSB_BUSIFFN_CREATE_USB_DEVICE CreateUsbDevice
Definition: hubbusif.h:541
BOOLEAN USB_BUSIFFN USBDI_IsDeviceHighSpeed(PVOID BusContext)
PVOID CallbackContext
Definition: libusb.h:63
#define URB_FUNCTION_GET_STATUS_FROM_DEVICE
Definition: usb.h:105
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define IRP_MN_QUERY_DEVICE_RELATIONS
static ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:90
PUSB_BUSIFFN_INITIALIZE_USB_DEVICE InitializeUsbDevice
Definition: hubbusif.h:542
_In_ PUSB_DEVICE_HANDLE _In_ ULONG DeviceInformationBufferLength
Definition: hubbusif.h:181
#define DPRINT1
Definition: precomp.h:8
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
PUSB_BUSIFFN_ENUM_LOG_ENTRY EnumLogEntry
Definition: usbbusif.h:117
_In_ PUSB_DEVICE_HANDLE _In_ ULONG TtCount
Definition: hubbusif.h:239
PRH_INIT_CALLBACK m_HubCallbackRoutine
struct USBDEVICE_ENTRY * PUSBDEVICE_ENTRY
_In_ PDEVICE_OBJECT _In_ ULONG HubInformationBufferLength
Definition: hubbusif.h:212
union _USB_DEFAULT_PIPE_SETUP_PACKET::_wValue wValue
#define USB_DEVICE_CLASS_HUB
Definition: usb100.h:99
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
PUSB_BUSIFFN_CONTROLLER_SELECTIVE_SUSPEND ControllerSelectiveSuspend
Definition: hubbusif.h:549
NTSTATUS HandleClearStall(IN OUT PIRP Irp, PURB Urb)
struct _URB_BULK_OR_INTERRUPT_TRANSFER UrbBulkOrInterruptTransfer
Definition: usb.h:543
struct _WORK_ITEM_DATA * PINIT_ROOT_HUB_CONTEXT
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:114
IHubController * PHUBCONTROLLER
#define ULONG_PTR
Definition: config.h:101
_Outptr_ PUSB_DEVICE_HANDLE * NewDeviceHandle
Definition: hubbusif.h:40
virtual NTSTATUS HandlePnp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define USBD_STATUS_INVALID_PIPE_HANDLE
Definition: usb.h:194
LIST_ENTRY m_UsbDeviceList
struct _URB_CONTROL_DESCRIPTOR_REQUEST UrbControlDescriptorRequest
Definition: usb.h:545
VOID USB_BUSIFFN USBDI_GetUSBDIVersion(PVOID BusContext, PUSBD_VERSION_INFORMATION VersionInformation, PULONG HcdCapabilites)
PUSB_BUSIFFN_GET_USB_DESCRIPTORS GetUsbDescriptors
Definition: hubbusif.h:543
_In_ ULONG HubSymNameBufferLength
Definition: hubbusif.h:222
WCHAR * LPWSTR
Definition: xmlstorage.h:184
LIST_ENTRY Entry
PDRIVER_OBJECT m_DriverObject
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
PVOID USBD_INTERFACE_HANDLE
Definition: usb.h:231
const USB_ENDPOINT_DESCRIPTOR ROOTHUB2_ENDPOINT_DESCRIPTOR
return STATUS_SUCCESS
Definition: btrfs.c:2725
const USB_CONFIGURATION_DESCRIPTOR ROOTHUB2_CONFIGURATION_DESCRIPTOR
BM_REQUEST_TYPE bmRequestType
Definition: usb200.h:72
IoMarkIrpPending(Irp)
VOID NTAPI StatusChangeEndpointCallBack(PVOID Context)
#define URB_FUNCTION_CLASS_OTHER
Definition: usb.h:117
#define BMREQUEST_VENDOR
Definition: usb100.h:36
NTSYSAPI ULONG WINAPI RtlFindClearBits(PCRTL_BITMAP, ULONG, ULONG)
#define BMREQUEST_TO_DEVICE
Definition: usb100.h:38
struct _URB_CONTROL_GET_STATUS_REQUEST UrbControlGetStatusRequest
Definition: usb.h:546
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
unsigned short * PUSHORT
Definition: retypes.h:2
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
INTERFACE_TYPE LegacyBusType
Definition: cmtypes.h:363
base of all file and directory entries
Definition: entries.h:82
#define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
Definition: usb.h:95
PUSB_BUSIFFN_GET_EXTENDED_HUB_INFO GetExtendedHubInformation
Definition: hubbusif.h:550
PUSB_BUSIFFN_QUERY_BUS_TIME QueryBusTime
Definition: usbbusif.h:113
struct _URB_SELECT_INTERFACE UrbSelectInterface
Definition: usb.h:532
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
#define IRP_MN_QUERY_CAPABILITIES
UCHAR bDescriptorType
Definition: usb100.h:172
#define USB_ENDPOINT_TYPE_INTERRUPT
Definition: usb100.h:65
BOOLEAN ValidateUsbDevice(PUSBDEVICE UsbDevice)
IHCDController * PHCDCONTROLLER