ReactOS  0.4.13-dev-455-g28ed234
fdo.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Universal Serial Bus Hub Driver
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: drivers/usb/usbhub/fdo.c
5  * PURPOSE: Handle FDO
6  * PROGRAMMERS:
7  * Michael Martin (michael.martin@reactos.org)
8  * Johannes Anderwald (johannes.anderwald@reactos.org)
9  */
10 
11 #include "usbhub.h"
12 
13 #include <stdio.h>
14 
15 #define NDEBUG
16 #include <debug.h>
17 
21 
24  IN PDEVICE_OBJECT UsbHubDeviceObject,
25  IN LONG PortId,
26  OUT PDEVICE_OBJECT *UsbChildDeviceObject,
28 
31  IN PDEVICE_OBJECT UsbHubDeviceObject,
32  IN LONG PortId);
33 
34 
37  IN PDEVICE_OBJECT RootHubDeviceObject,
38  IN ULONG PortId,
39  OUT PPORT_STATUS_CHANGE StatusChange)
40 {
42  PURB Urb;
43 
44  //
45  // Allocate URB
46  //
48  if (!Urb)
49  {
50  DPRINT1("Failed to allocate memory for URB!\n");
52  }
53 
54  //
55  // Zero it
56  //
57  RtlZeroMemory(Urb, sizeof(URB));
58 
59  //
60  // Initialize URB for getting Port Status
61  //
64  sizeof(Urb->UrbControlVendorClassRequest),
66  0,
68  0,
69  PortId,
70  StatusChange,
71  0,
72  sizeof(PORT_STATUS_CHANGE),
73  0);
74 
75  // FIXME: support usb hubs
76  Urb->UrbHeader.UsbdDeviceHandle = NULL;
77 
78 
79  //
80  // Query the Root Hub
81  //
83 
84  //
85  // Free URB
86  //
87  ExFreePool(Urb);
88 
89  return Status;
90 }
91 
94  IN PDEVICE_OBJECT RootHubDeviceObject,
95  IN ULONG PortId,
96  IN ULONG Feature)
97 {
99  PURB Urb;
100 
101  //
102  // Allocate URB
103  //
105  if (!Urb)
106  {
107  DPRINT1("Failed to allocate memory for URB!\n");
109  }
110 
111  //
112  // Zero it
113  //
114  RtlZeroMemory(Urb, sizeof(URB));
115 
116  //
117  // Initialize URB for Clearing Port Reset
118  //
121  sizeof(Urb->UrbControlVendorClassRequest),
123  0,
125  Feature,
126  PortId,
127  NULL,
128  0,
129  0,
130  0);
131 
132  // FIXME support usbhubs
133  Urb->UrbHeader.UsbdDeviceHandle = NULL;
134 
135  //
136  // Query the Root Hub
137  //
138  Status = SubmitRequestToRootHub(RootHubDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
139 
140  //
141  // Free URB
142  //
143  ExFreePool(Urb);
144 
145  return Status;
146 }
147 
148 NTSTATUS
150  IN PDEVICE_OBJECT RootHubDeviceObject,
151  IN ULONG PortId,
152  IN ULONG Feature)
153 {
155  PURB Urb;
156 
157  //
158  // Allocate a URB
159  //
161  if (!Urb)
162  {
163  DPRINT1("Failed to allocate memory for URB!\n");
165  }
166 
167  //
168  // Zero it
169  //
170  RtlZeroMemory(Urb, sizeof(URB));
171 
172  //
173  // Initialize URB for Clearing Port Reset
174  //
177  sizeof(Urb->UrbControlVendorClassRequest),
179  0,
181  Feature,
182  PortId,
183  NULL,
184  0,
185  0,
186  0);
187 
188  // FIXME: support usb hubs
189  Urb->UrbHeader.UsbdDeviceHandle = NULL;
190 
191  //
192  // Query the Root Hub
193  //
194  Status = SubmitRequestToRootHub(RootHubDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
195 
196  //
197  // Free URB
198  //
199  ExFreePool(Urb);
200 
201  return Status;
202 }
203 
204 VOID NTAPI
206  IN PVOID Context)
207 {
209  PDEVICE_OBJECT DeviceObject, RootHubDeviceObject;
210  PHUB_DEVICE_EXTENSION HubDeviceExtension;
211  PWORK_ITEM_DATA WorkItemData;
213  ULONG PortId;
214  BOOLEAN SignalResetComplete = FALSE;
215 
216  DPRINT("Entered DeviceStatusChangeThread, Context %x\n", Context);
217 
218  WorkItemData = (PWORK_ITEM_DATA)Context;
219  DeviceObject = (PDEVICE_OBJECT)WorkItemData->Context;
220  HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
221  RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
222  //
223  // Loop all ports
224  //
225  for (PortId = 1; PortId <= HubDeviceExtension->UsbExtHubInfo.NumberOfPorts; PortId++)
226  {
227  //
228  // Get Port Status
229  //
230  Status = GetPortStatusAndChange(RootHubDeviceObject, PortId, &PortStatus);
231  if (!NT_SUCCESS(Status))
232  {
233  DPRINT1("Failed to get port status for port %d, Status %x\n", PortId, Status);
234  // FIXME: Do we really want to halt further SCE requests?
235  return;
236  }
237 
238  DPRINT("Port %d Status %x\n", PortId, PortStatus.Status);
239  DPRINT("Port %d Change %x\n", PortId, PortStatus.Change);
240 
241 
242  //
243  // Check for new device connection
244  //
245  if (PortStatus.Change & USB_PORT_STATUS_CONNECT)
246  {
247  //
248  // Clear Port Connect
249  //
250  Status = ClearPortFeature(RootHubDeviceObject, PortId, C_PORT_CONNECTION);
251  if (!NT_SUCCESS(Status))
252  {
253  DPRINT1("Failed to clear connection change for port %d\n", PortId);
254  continue;
255  }
256 
257  //
258  // Is this a connect or disconnect?
259  //
260  if (!(PortStatus.Status & USB_PORT_STATUS_CONNECT))
261  {
262  DPRINT1("Device disconnected from port %d\n", PortId);
263 
265  if (!NT_SUCCESS(Status))
266  {
267  DPRINT1("Failed to delete child device object after disconnect\n");
268  continue;
269  }
270  }
271  else
272  {
273  DPRINT1("Device connected from port %d\n", PortId);
274 
275  // No SCE completion done for clearing C_PORT_CONNECT
276 
277  //
278  // Reset Port
279  //
280  Status = SetPortFeature(RootHubDeviceObject, PortId, PORT_RESET);
281  if (!NT_SUCCESS(Status))
282  {
283  DPRINT1("Failed to reset port %d\n", PortId);
284  SignalResetComplete = TRUE;
285  continue;
286  }
287  }
288  }
289  else if (PortStatus.Change & USB_PORT_STATUS_ENABLE)
290  {
291  //
292  // Clear Enable
293  //
294  Status = ClearPortFeature(RootHubDeviceObject, PortId, C_PORT_ENABLE);
295  if (!NT_SUCCESS(Status))
296  {
297  DPRINT1("Failed to clear enable change on port %d\n", PortId);
298  continue;
299  }
300  }
301  else if (PortStatus.Change & USB_PORT_STATUS_RESET)
302  {
303  //
304  // Request event signalling later
305  //
306  SignalResetComplete = TRUE;
307 
308  //
309  // Clear Reset
310  //
311  Status = ClearPortFeature(RootHubDeviceObject, PortId, C_PORT_RESET);
312  if (!NT_SUCCESS(Status))
313  {
314  DPRINT1("Failed to clear reset change on port %d\n", PortId);
315  continue;
316  }
317 
318  //
319  // Get Port Status
320  //
321  Status = GetPortStatusAndChange(RootHubDeviceObject, PortId, &PortStatus);
322  if (!NT_SUCCESS(Status))
323  {
324  DPRINT1("Failed to get port status for port %d, Status %x\n", PortId, Status);
325  // FIXME: Do we really want to halt further SCE requests?
326  return;
327  }
328 
329  DPRINT("Port %d Status %x\n", PortId, PortStatus.Status);
330  DPRINT("Port %d Change %x\n", PortId, PortStatus.Change);
331 
332  //
333  // Check that reset was cleared
334  //
335  if(PortStatus.Change & USB_PORT_STATUS_RESET)
336  {
337  DPRINT1("Port did not clear reset! Possible Hardware problem!\n");
338  continue;
339  }
340 
341  //
342  // Check if the device is still connected
343  //
344  if (!(PortStatus.Status & USB_PORT_STATUS_CONNECT))
345  {
346  DPRINT1("Device has been disconnected\n");
347  continue;
348  }
349 
350  //
351  // Make sure its Connected and Enabled
352  //
354  {
355  DPRINT1("Usb Device is not connected and enabled!\n");
356  //
357  // Attempt another reset
358  //
359  Status = SetPortFeature(RootHubDeviceObject, PortId, PORT_RESET);
360  if (!NT_SUCCESS(Status))
361  {
362  DPRINT1("Failed to reset port %d\n", PortId);
363  }
364  continue;
365  }
366 
367  //
368  // This is a new device
369  //
371  }
372  }
373 
374  ExFreePool(WorkItemData);
375 
376  //
377  // Send another SCE Request
378  //
379  DPRINT("Sending another SCE!\n");
381 
382  //
383  // Check if a reset event was satisfied
384  //
385  if (SignalResetComplete)
386  {
387  //
388  // Signal anyone waiting on it
389  //
390  KeSetEvent(&HubDeviceExtension->ResetComplete, IO_NO_INCREMENT, FALSE);
391  }
392 }
393 
394 NTSTATUS
395 NTAPI
398  IN PIRP Irp,
399  IN PVOID Context)
400 {
402  PHUB_DEVICE_EXTENSION HubDeviceExtension;
403  PWORK_ITEM_DATA WorkItemData;
404 
406  HubDeviceExtension = (PHUB_DEVICE_EXTENSION)RealDeviceObject->DeviceExtension;
407 
408  //
409  // NOTE: USBPORT frees this IRP
410  //
411  DPRINT("Received Irp %x, HubDeviceExtension->PendingSCEIrp %x\n", Irp, HubDeviceExtension->PendingSCEIrp);
412  //IoFreeIrp(Irp);
413 
414  //
415  // Create and initialize work item data
416  //
418  if (!WorkItemData)
419  {
420  DPRINT1("Failed to allocate memory!n");
422  }
423  WorkItemData->Context = RealDeviceObject;
424 
425  DPRINT("Queuing work item\n");
426 
427  //
428  // Queue the work item to handle initializing the device
429  //
430  ExInitializeWorkItem(&WorkItemData->WorkItem, DeviceStatusChangeThread, (PVOID)WorkItemData);
431  ExQueueWorkItem(&WorkItemData->WorkItem, DelayedWorkQueue);
432 
433  //
434  // Return more processing required so the IO Manger doesn’t try to mess with IRP just freed
435  //
437 }
438 
439 NTSTATUS
442 {
443  PDEVICE_OBJECT RootHubDeviceObject;
444  PIO_STACK_LOCATION Stack;
445  PHUB_DEVICE_EXTENSION HubDeviceExtension;
446  PURB PendingSCEUrb;
447 
448  HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
449  RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
450 
451  //
452  // Allocate a URB
453  //
454  PendingSCEUrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB), USB_HUB_TAG);
455 
456  //
457  // Initialize URB for Status Change Endpoint request
458  //
460  sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
461  HubDeviceExtension->PipeHandle,
462  HubDeviceExtension->PortStatusChange,
463  NULL,
464  sizeof(USHORT) * 2 * HubDeviceExtension->UsbExtHubInfo.NumberOfPorts,
466  NULL);
467 
468  // Set the device handle
469  PendingSCEUrb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
470 
471  //
472  // Allocate an Irp
473  //
474  HubDeviceExtension->PendingSCEIrp = ExAllocatePoolWithTag(NonPagedPool,
475  IoSizeOfIrp(RootHubDeviceObject->StackSize),
476  USB_HUB_TAG);
477 /*
478  HubDeviceExtension->PendingSCEIrp = IoAllocateIrp(RootHubDeviceObject->StackSize,
479  FALSE);
480 */
481  DPRINT("Allocated IRP %x\n", HubDeviceExtension->PendingSCEIrp);
482 
483  if (!HubDeviceExtension->PendingSCEIrp)
484  {
485  DPRINT1("USBHUB: Failed to allocate IRP for SCE request!\n");
487  }
488 
489  //
490  // Initialize the IRP
491  //
492  IoInitializeIrp(HubDeviceExtension->PendingSCEIrp,
493  IoSizeOfIrp(RootHubDeviceObject->StackSize),
494  RootHubDeviceObject->StackSize);
495 
496  HubDeviceExtension->PendingSCEIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
497  HubDeviceExtension->PendingSCEIrp->IoStatus.Information = 0;
498  HubDeviceExtension->PendingSCEIrp->Flags = 0;
499  HubDeviceExtension->PendingSCEIrp->UserBuffer = NULL;
500 
501  //
502  // Get the Next Stack Location and Initialize it
503  //
504  Stack = IoGetNextIrpStackLocation(HubDeviceExtension->PendingSCEIrp);
505  Stack->DeviceObject = DeviceObject;
506  Stack->Parameters.Others.Argument1 = PendingSCEUrb;
507  Stack->Parameters.Others.Argument2 = NULL;
509  Stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
510 
511  //
512  // Set the completion routine for when device is connected to root hub
513  //
514  IoSetCompletionRoutine(HubDeviceExtension->PendingSCEIrp,
516  DeviceObject,
517  TRUE,
518  TRUE,
519  TRUE);
520 
521  //
522  // Send to RootHub
523  //
524  DPRINT("DeviceObject is %x\n", DeviceObject);
525  DPRINT("Iocalldriver %x with irp %x\n", RootHubDeviceObject, HubDeviceExtension->PendingSCEIrp);
526  IoCallDriver(RootHubDeviceObject, HubDeviceExtension->PendingSCEIrp);
527 
528  return STATUS_PENDING;
529 }
530 
531 NTSTATUS
534  IN CONST GUID InterfaceType,
535  IN LONG Size,
536  IN LONG Version,
538 {
539  KEVENT Event;
540  PIRP Irp;
543  PIO_STACK_LOCATION Stack = NULL;
544 
545  //
546  // Initialize the Event used to wait for Irp completion
547  //
549 
550  //
551  // Build Control Request
552  //
554  DeviceObject,
555  NULL,
556  0,
557  NULL,
558  &Event,
559  &IoStatus);
560 
561  //
562  // Get Next Stack Location and Initialize it.
563  //
566  Stack->Parameters.QueryInterface.InterfaceType= &InterfaceType;//USB_BUS_INTERFACE_HUB_GUID;
567  Stack->Parameters.QueryInterface.Size = Size;
568  Stack->Parameters.QueryInterface.Version = Version;
569  Stack->Parameters.QueryInterface.Interface = Interface;
570  Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
571 
572  //
573  // Initialize the status block before sending the IRP
574  //
575  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
576 
578 
579  if (Status == STATUS_PENDING)
580  {
581  DPRINT("Operation pending\n");
583  Status = IoStatus.Status;
584  }
585 
586  return Status;
587 }
588 
589 NTSTATUS
591  IN PDEVICE_OBJECT ChildDeviceObject,
593  IN UCHAR Index,
594  IN USHORT LangId,
595  OUT PVOID TransferBuffer,
596  IN ULONG TransferBufferLength)
597 {
599  PDEVICE_OBJECT RootHubDeviceObject;
600  PURB Urb;
601  PHUB_DEVICE_EXTENSION HubDeviceExtension;
602  PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
603 
604  //
605  // Get the Hubs Device Extension
606  //
607  ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)ChildDeviceObject->DeviceExtension;
608  HubDeviceExtension = (PHUB_DEVICE_EXTENSION) ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
609  RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
610 
611  //
612  // Allocate a URB
613  //
615  if (!Urb)
616  {
617  DPRINT1("Failed to allocate memory for URB!\n");
619  }
620 
621  //
622  // Zero it
623  //
624  RtlZeroMemory(Urb, sizeof(URB));
625 
626  //
627  // Initialize URB for getting device descriptor
628  //
630  sizeof(Urb->UrbControlDescriptorRequest),
632  Index,
633  LangId,
634  TransferBuffer,
635  NULL,
636  TransferBufferLength,
637  NULL);
638 
639  //
640  // Set the device handle
641  //
642  Urb->UrbHeader.UsbdDeviceHandle = (PVOID)ChildDeviceExtension->UsbDeviceHandle;
643 
644  //
645  // Query the Root Hub
646  //
647  Status = SubmitRequestToRootHub(RootHubDeviceObject,
649  Urb,
650  NULL);
651 
652  return Status;
653 }
654 
655 NTSTATUS
657  IN PDEVICE_OBJECT ChildDeviceObject,
658  IN UCHAR Index,
659  IN USHORT LangId,
660  OUT PVOID *TransferBuffer,
661  OUT USHORT *Size)
662 {
664  PUSB_STRING_DESCRIPTOR StringDesc = NULL;
665  ULONG SizeNeeded;
666  LPWSTR Buffer;
667 
668  StringDesc = ExAllocatePoolWithTag(NonPagedPool,
669  sizeof(USB_STRING_DESCRIPTOR),
670  USB_HUB_TAG);
671  if (!StringDesc)
672  {
673  DPRINT1("Failed to allocate buffer for string!\n");
675  }
676 
677  //
678  // Get the index string descriptor length
679  // FIXME: Implement LangIds
680  //
681  Status = GetUsbDeviceDescriptor(ChildDeviceObject,
683  Index,
684  0x0409,
685  StringDesc,
686  sizeof(USB_STRING_DESCRIPTOR));
687  if (!NT_SUCCESS(Status))
688  {
689  DPRINT1("GetUsbDeviceDescriptor failed with status %x\n", Status);
690  ExFreePool(StringDesc);
691  return Status;
692  }
693  DPRINT1("StringDesc->bLength %d\n", StringDesc->bLength);
694 
695  //
696  // Did we get something more than the length of the first two fields of structure?
697  //
698  if (StringDesc->bLength == 2)
699  {
700  DPRINT1("USB Device Error!\n");
701  ExFreePool(StringDesc);
703  }
704  SizeNeeded = StringDesc->bLength + sizeof(WCHAR);
705 
706  //
707  // Free String
708  //
709  ExFreePool(StringDesc);
710 
711  //
712  // Recreate with appropriate size
713  //
714  StringDesc = ExAllocatePoolWithTag(NonPagedPool,
715  SizeNeeded,
716  USB_HUB_TAG);
717  if (!StringDesc)
718  {
719  DPRINT1("Failed to allocate buffer for string!\n");
721  }
722 
723  RtlZeroMemory(StringDesc, SizeNeeded);
724 
725  //
726  // Get the string
727  //
728  Status = GetUsbDeviceDescriptor(ChildDeviceObject,
730  Index,
731  0x0409,
732  StringDesc,
733  SizeNeeded);
734  if (!NT_SUCCESS(Status))
735  {
736  DPRINT1("GetUsbDeviceDescriptor failed with status %x\n", Status);
737  ExFreePool(StringDesc);
738  return Status;
739  }
740 
741  //
742  // Allocate Buffer to return
743  //
745  SizeNeeded,
746  USB_HUB_TAG);
747  if (!Buffer)
748  {
749  DPRINT1("Failed to allocate buffer for string!\n");
750  ExFreePool(StringDesc);
752  }
753 
754  RtlZeroMemory(Buffer, SizeNeeded);
755 
756  //
757  // Copy the string to destination
758  //
759  RtlCopyMemory(Buffer, StringDesc->bString, SizeNeeded - FIELD_OFFSET(USB_STRING_DESCRIPTOR, bString));
760  *Size = SizeNeeded;
761  *TransferBuffer = Buffer;
762 
763  ExFreePool(StringDesc);
764 
765  return STATUS_SUCCESS;
766 }
767 
768 ULONG
771  IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
772 {
773  if (DeviceDescriptor->bNumConfigurations != 1)
774  {
775  //
776  // composite device must have only one configuration
777  //
778  DPRINT1("IsCompositeDevice bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations);
779  return FALSE;
780  }
781 
782  if (ConfigurationDescriptor->bNumInterfaces < 2)
783  {
784  //
785  // composite device must have multiple interfaces
786  //
787  DPRINT1("IsCompositeDevice bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces);
788  return FALSE;
789  }
790 
791  if (DeviceDescriptor->bDeviceClass == 0)
792  {
793  //
794  // composite device
795  //
796  ASSERT(DeviceDescriptor->bDeviceSubClass == 0);
797  ASSERT(DeviceDescriptor->bDeviceProtocol == 0);
798  DPRINT1("IsCompositeDevice: TRUE\n");
799  return TRUE;
800  }
801 
802  if (DeviceDescriptor->bDeviceClass == 0xEF &&
803  DeviceDescriptor->bDeviceSubClass == 0x02 &&
804  DeviceDescriptor->bDeviceProtocol == 0x01)
805  {
806  //
807  // USB-IF association descriptor
808  //
809  DPRINT1("IsCompositeDevice: TRUE\n");
810  return TRUE;
811  }
812 
813  DPRINT1("DeviceDescriptor bDeviceClass %x bDeviceSubClass %x bDeviceProtocol %x\n", DeviceDescriptor->bDeviceClass, DeviceDescriptor->bDeviceSubClass, DeviceDescriptor->bDeviceProtocol);
814 
815  //
816  // not a composite device
817  //
818  return FALSE;
819 }
820 
821 NTSTATUS
823  PDEVICE_OBJECT UsbChildDeviceObject)
824 {
826  ULONG Index = 0;
827  LPWSTR DeviceString;
828  WCHAR Buffer[200];
829  PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
830  PHUB_DEVICE_EXTENSION HubDeviceExtension;
832  PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
833  PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
834 
835  //
836  // get child device extension
837  //
838  UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)UsbChildDeviceObject->DeviceExtension;
839 
840  // get hub device extension
841  HubDeviceExtension = (PHUB_DEVICE_EXTENSION) UsbChildExtension->ParentDeviceObject->DeviceExtension;
842 
843  //
844  // get device descriptor
845  //
846  DeviceDescriptor = &UsbChildExtension->DeviceDesc;
847 
848  //
849  // get configuration descriptor
850  //
851  ConfigurationDescriptor = UsbChildExtension->FullConfigDesc;
852 
853  //
854  // use first interface descriptor available
855  //
856  InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, 0, -1, -1, -1, -1);
857  if (InterfaceDescriptor == NULL)
858  {
859  DPRINT1("Error USBD_ParseConfigurationDescriptorEx failed to parse interface descriptor\n");
861  }
862 
863  ASSERT(InterfaceDescriptor);
864 
865  //
866  // Construct the CompatibleIds
867  //
868  if (IsCompositeDevice(DeviceDescriptor, ConfigurationDescriptor))
869  {
870  //
871  // sanity checks
872  //
873  ASSERT(DeviceDescriptor->bNumConfigurations == 1);
874  ASSERT(ConfigurationDescriptor->bNumInterfaces > 1);
875  Index += swprintf(&Buffer[Index],
876  L"USB\\DevClass_%02x&SubClass_%02x&Prot_%02x",
877  DeviceDescriptor->bDeviceClass, DeviceDescriptor->bDeviceSubClass, DeviceDescriptor->bDeviceProtocol) + 1;
878  Index += swprintf(&Buffer[Index],
879  L"USB\\DevClass_%02x&SubClass_%02x",
880  DeviceDescriptor->bDeviceClass, DeviceDescriptor->bDeviceSubClass) + 1;
881  Index += swprintf(&Buffer[Index],
882  L"USB\\DevClass_%02x",
883  DeviceDescriptor->bDeviceClass) + 1;
884  Index += swprintf(&Buffer[Index],
885  L"USB\\COMPOSITE") + 1;
886  }
887  else
888  {
889  //
890  // FIXME: support multiple configurations
891  //
892  ASSERT(DeviceDescriptor->bNumConfigurations == 1);
893 
894  if (DeviceDescriptor->bDeviceClass == 0)
895  {
896  Index += swprintf(&Buffer[Index],
897  L"USB\\Class_%02x&SubClass_%02x&Prot_%02x",
898  InterfaceDescriptor->bInterfaceClass, InterfaceDescriptor->bInterfaceSubClass, InterfaceDescriptor->bInterfaceProtocol) + 1;
899  Index += swprintf(&Buffer[Index],
900  L"USB\\Class_%02x&SubClass_%02x",
901  InterfaceDescriptor->bInterfaceClass, InterfaceDescriptor->bInterfaceSubClass) + 1;
902  Index += swprintf(&Buffer[Index],
903  L"USB\\Class_%02x",
904  InterfaceDescriptor->bInterfaceClass) + 1;
905  }
906  else
907  {
908  Index += swprintf(&Buffer[Index],
909  L"USB\\Class_%02x&SubClass_%02x&Prot_%02x",
910  DeviceDescriptor->bDeviceClass, DeviceDescriptor->bDeviceSubClass, DeviceDescriptor->bDeviceProtocol) + 1;
911  Index += swprintf(&Buffer[Index],
912  L"USB\\Class_%02x&SubClass_%02x",
913  DeviceDescriptor->bDeviceClass, DeviceDescriptor->bDeviceSubClass) + 1;
914  Index += swprintf(&Buffer[Index],
915  L"USB\\Class_%02x",
916  DeviceDescriptor->bDeviceClass) + 1;
917  }
918  }
919 
920  //
921  // now allocate the buffer
922  //
923  DeviceString = ExAllocatePool(NonPagedPool, (Index + 1) * sizeof(WCHAR));
924  if (!DeviceString)
925  {
926  //
927  // no memory
928  //
930  }
931 
932  //
933  // copy buffer
934  //
935  RtlCopyMemory(DeviceString, Buffer, Index * sizeof(WCHAR));
936  DeviceString[Index] = UNICODE_NULL;
937  UsbChildExtension->usCompatibleIds.Buffer = DeviceString;
938  UsbChildExtension->usCompatibleIds.Length = Index * sizeof(WCHAR);
939  UsbChildExtension->usCompatibleIds.MaximumLength = (Index + 1) * sizeof(WCHAR);
940  DPRINT("usCompatibleIds %wZ\n", &UsbChildExtension->usCompatibleIds);
941 
942  //
943  // Construct DeviceId string
944  //
945  Index = swprintf(Buffer, L"USB\\Vid_%04x&Pid_%04x", UsbChildExtension->DeviceDesc.idVendor, UsbChildExtension->DeviceDesc.idProduct) + 1;
946 
947  //
948  // now allocate the buffer
949  //
950  DeviceString = ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR));
951  if (!DeviceString)
952  {
953  //
954  // no memory
955  //
957  }
958 
959  //
960  // copy buffer
961  //
962  RtlCopyMemory(DeviceString, Buffer, Index * sizeof(WCHAR));
963  UsbChildExtension->usDeviceId.Buffer = DeviceString;
964  UsbChildExtension->usDeviceId.Length = (Index-1) * sizeof(WCHAR);
965  UsbChildExtension->usDeviceId.MaximumLength = Index * sizeof(WCHAR);
966  DPRINT("usDeviceId %wZ\n", &UsbChildExtension->usDeviceId);
967 
968  //
969  // Construct HardwareIds
970  //
971  Index = 0;
972  Index += swprintf(&Buffer[Index],
973  L"USB\\Vid_%04x&Pid_%04x&Rev_%04x",
974  UsbChildExtension->DeviceDesc.idVendor, UsbChildExtension->DeviceDesc.idProduct, UsbChildExtension->DeviceDesc.bcdDevice) + 1;
975  Index += swprintf(&Buffer[Index],
976  L"USB\\Vid_%04x&Pid_%04x",
977  UsbChildExtension->DeviceDesc.idVendor, UsbChildExtension->DeviceDesc.idProduct) + 1;
978 
979  //
980  // now allocate the buffer
981  //
982  DeviceString = ExAllocatePool(NonPagedPool, (Index + 1) * sizeof(WCHAR));
983  if (!DeviceString)
984  {
985  //
986  // no memory
987  //
989  }
990 
991  //
992  // copy buffer
993  //
994  RtlCopyMemory(DeviceString, Buffer, Index * sizeof(WCHAR));
995  DeviceString[Index] = UNICODE_NULL;
996  UsbChildExtension->usHardwareIds.Buffer = DeviceString;
997  UsbChildExtension->usHardwareIds.Length = (Index + 1) * sizeof(WCHAR);
998  UsbChildExtension->usHardwareIds.MaximumLength = (Index + 1) * sizeof(WCHAR);
999  DPRINT("usHardWareIds %wZ\n", &UsbChildExtension->usHardwareIds);
1000 
1001  //
1002  // FIXME: Handle Lang ids
1003  //
1004 
1005  //
1006  // Get the product string if obe provided
1007  //
1008  if (UsbChildExtension->DeviceDesc.iProduct)
1009  {
1010  Status = GetUsbStringDescriptor(UsbChildDeviceObject,
1011  UsbChildExtension->DeviceDesc.iProduct,
1012  0,
1013  (PVOID*)&UsbChildExtension->usTextDescription.Buffer,
1014  &UsbChildExtension->usTextDescription.Length);
1015  if (!NT_SUCCESS(Status))
1016  {
1017  DPRINT1("USBHUB: GetUsbStringDescriptor failed with status %x\n", Status);
1018  RtlInitUnicodeString(&UsbChildExtension->usTextDescription, L"USB Device"); // FIXME NON-NLS
1019  }
1020  else
1021  {
1022  UsbChildExtension->usTextDescription.MaximumLength = UsbChildExtension->usTextDescription.Length;
1023  DPRINT("Usb TextDescription %wZ\n", &UsbChildExtension->usTextDescription);
1024  }
1025  }
1026 
1027  //
1028  // Get the Serial Number string if obe provided
1029  //
1030  if (UsbChildExtension->DeviceDesc.iSerialNumber)
1031  {
1032  LPWSTR SerialBuffer = NULL;
1033 
1034  Status = GetUsbStringDescriptor(UsbChildDeviceObject,
1035  UsbChildExtension->DeviceDesc.iSerialNumber,
1036  0,
1037  (PVOID*)&SerialBuffer,
1038  &UsbChildExtension->usInstanceId.Length);
1039  if (NT_SUCCESS(Status))
1040  {
1041  // construct instance id buffer
1042  Index = swprintf(Buffer, L"%04d&%s", HubDeviceExtension->InstanceCount, SerialBuffer) + 1;
1043 
1044  ExFreePool(SerialBuffer);
1045 
1046  UsbChildExtension->usInstanceId.Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR));
1047  if (UsbChildExtension->usInstanceId.Buffer == NULL)
1048  {
1049  DPRINT1("Error: failed to allocate %lu bytes\n", Index * sizeof(WCHAR));
1051  }
1052 
1053  //
1054  // copy instance id
1055  //
1056  RtlCopyMemory(UsbChildExtension->usInstanceId.Buffer, Buffer, Index * sizeof(WCHAR));
1057  UsbChildExtension->usInstanceId.Length = UsbChildExtension->usInstanceId.MaximumLength = Index * sizeof(WCHAR);
1058 
1059  DPRINT("Usb InstanceId %wZ InstanceCount %x\n", &UsbChildExtension->usInstanceId, HubDeviceExtension->InstanceCount);
1060  return Status;
1061  }
1062  }
1063 
1064  //
1065  // the device did not provide a serial number, or failed to retrieve the serial number
1066  // lets create a pseudo instance id
1067  //
1068  Index = swprintf(Buffer, L"%04d&%04d", HubDeviceExtension->InstanceCount, UsbChildExtension->PortNumber) + 1;
1069  UsbChildExtension->usInstanceId.Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR));
1070  if (UsbChildExtension->usInstanceId.Buffer == NULL)
1071  {
1072  DPRINT1("Error: failed to allocate %lu bytes\n", Index * sizeof(WCHAR));
1074  return Status;
1075  }
1076 
1077  //
1078  // copy instance id
1079  //
1080  RtlCopyMemory(UsbChildExtension->usInstanceId.Buffer, Buffer, Index * sizeof(WCHAR));
1081  UsbChildExtension->usInstanceId.Length = UsbChildExtension->usInstanceId.MaximumLength = Index * sizeof(WCHAR);
1082 
1083  DPRINT("usDeviceId %wZ\n", &UsbChildExtension->usInstanceId);
1084  return STATUS_SUCCESS;
1085 }
1086 
1087 NTSTATUS
1089  IN PDEVICE_OBJECT UsbHubDeviceObject,
1090  IN LONG PortId)
1091 {
1092  PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbHubDeviceObject->DeviceExtension;
1093  PHUB_CHILDDEVICE_EXTENSION UsbChildExtension = NULL;
1094  PDEVICE_OBJECT ChildDeviceObject = NULL;
1095  ULONG Index = 0;
1096 
1097  KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
1098  for (Index = 0; Index < USB_MAXCHILDREN; Index++)
1099  {
1100  if (HubDeviceExtension->ChildDeviceObject[Index])
1101  {
1102  UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)HubDeviceExtension->ChildDeviceObject[Index]->DeviceExtension;
1103 
1104  /* Check if it matches the port ID */
1105  if (UsbChildExtension->PortNumber == PortId)
1106  {
1107  /* We found it */
1108  ChildDeviceObject = HubDeviceExtension->ChildDeviceObject[Index];
1109  break;
1110  }
1111  }
1112  }
1113 
1114  /* Fail the request if the device doesn't exist */
1115  if (!ChildDeviceObject)
1116  {
1117  DPRINT1("Removal request for non-existant device!\n");
1118  KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
1119  return STATUS_UNSUCCESSFUL;
1120  }
1121 
1122  DPRINT("Removing device on port %d (Child index: %d)\n", PortId, Index);
1123 
1124  /* Remove the device from the table */
1125  HubDeviceExtension->ChildDeviceObject[Index] = NULL;
1126 
1127  KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
1128 
1129  /* Invalidate device relations for the root hub */
1131 
1132  /* The rest of the removal process takes place in IRP_MN_REMOVE_DEVICE handling for the PDO */
1133  return STATUS_SUCCESS;
1134 }
1135 
1136 NTSTATUS
1138  IN PDEVICE_OBJECT UsbHubDeviceObject,
1139  IN LONG PortId,
1140  OUT PDEVICE_OBJECT *UsbChildDeviceObject,
1142 {
1143  NTSTATUS Status;
1144  PDEVICE_OBJECT RootHubDeviceObject, NewChildDeviceObject;
1145  PHUB_DEVICE_EXTENSION HubDeviceExtension;
1146  PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
1147  PUSB_BUS_INTERFACE_HUB_V5 HubInterface;
1148  ULONG ChildDeviceCount, UsbDeviceNumber = 0;
1149  WCHAR CharDeviceName[64];
1151  ULONG ConfigDescSize, DeviceDescSize, DeviceInfoSize;
1152  PVOID HubInterfaceBusContext;
1153  USB_CONFIGURATION_DESCRIPTOR ConfigDesc;
1154 
1155  HubDeviceExtension = (PHUB_DEVICE_EXTENSION) UsbHubDeviceObject->DeviceExtension;
1156  HubInterface = &HubDeviceExtension->HubInterface;
1157  RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
1158  HubInterfaceBusContext = HubDeviceExtension->UsbDInterface.BusContext;
1159 
1160  while (TRUE)
1161  {
1162  //
1163  // Create a Device Name
1164  //
1165  swprintf(CharDeviceName, L"\\Device\\USBPDO-%d", UsbDeviceNumber);
1166 
1167  //
1168  // Initialize UnicodeString
1169  //
1170  RtlInitUnicodeString(&DeviceName, CharDeviceName);
1171 
1172  //
1173  // Create a DeviceObject
1174  //
1175  Status = IoCreateDevice(UsbHubDeviceObject->DriverObject,
1176  sizeof(HUB_CHILDDEVICE_EXTENSION),
1177  NULL,
1180  FALSE,
1181  &NewChildDeviceObject);
1182 
1183  //
1184  // Check if the name is already in use
1185  //
1187  {
1188  //
1189  // Try next name
1190  //
1191  UsbDeviceNumber++;
1192  continue;
1193  }
1194 
1195  //
1196  // Check for other errors
1197  //
1198  if (!NT_SUCCESS(Status))
1199  {
1200  DPRINT1("USBHUB: IoCreateDevice failed with status %x\n", Status);
1201  return Status;
1202  }
1203 
1204  DPRINT("USBHUB: Created Device %x\n", NewChildDeviceObject);
1205  break;
1206  }
1207 
1208  NewChildDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE;
1209 
1210  //
1211  // Assign the device extensions
1212  //
1213  UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)NewChildDeviceObject->DeviceExtension;
1214  RtlZeroMemory(UsbChildExtension, sizeof(HUB_CHILDDEVICE_EXTENSION));
1215  UsbChildExtension->ParentDeviceObject = UsbHubDeviceObject;
1216  UsbChildExtension->PortNumber = PortId;
1217 
1218  //
1219  // Create the UsbDeviceObject
1220  //
1221  Status = HubInterface->CreateUsbDevice(HubInterfaceBusContext,
1222  (PVOID)&UsbChildExtension->UsbDeviceHandle,
1223  HubDeviceExtension->RootHubHandle,
1224  PortStatus,
1225  PortId);
1226  if (!NT_SUCCESS(Status))
1227  {
1228  DPRINT1("USBHUB: CreateUsbDevice failed with status %x\n", Status);
1229  goto Cleanup;
1230  }
1231 
1232  //
1233  // Initialize UsbDevice
1234  //
1235  Status = HubInterface->InitializeUsbDevice(HubInterfaceBusContext, UsbChildExtension->UsbDeviceHandle);
1236  if (!NT_SUCCESS(Status))
1237  {
1238  DPRINT1("USBHUB: InitializeUsbDevice failed with status %x\n", Status);
1239  goto Cleanup;
1240  }
1241 
1242  DPRINT("Usb Device Handle %x\n", UsbChildExtension->UsbDeviceHandle);
1243 
1244  ConfigDescSize = sizeof(USB_CONFIGURATION_DESCRIPTOR);
1245  DeviceDescSize = sizeof(USB_DEVICE_DESCRIPTOR);
1246 
1247  //
1248  // Get the descriptors
1249  //
1250  Status = HubInterface->GetUsbDescriptors(HubInterfaceBusContext,
1251  UsbChildExtension->UsbDeviceHandle,
1252  (PUCHAR)&UsbChildExtension->DeviceDesc,
1253  &DeviceDescSize,
1254  (PUCHAR)&ConfigDesc,
1255  &ConfigDescSize);
1256  if (!NT_SUCCESS(Status))
1257  {
1258  DPRINT1("USBHUB: GetUsbDescriptors failed with status %x\n", Status);
1259  goto Cleanup;
1260  }
1261 
1262  //DumpDeviceDescriptor(&UsbChildExtension->DeviceDesc);
1263  //DumpConfigurationDescriptor(&ConfigDesc);
1264 
1265  //
1266  // FIXME: Support more than one configuration and one interface?
1267  //
1268  if (UsbChildExtension->DeviceDesc.bNumConfigurations > 1)
1269  {
1270  DPRINT1("Warning: Device has more than one configuration. Only one configuration (the first) is supported!\n");
1271  }
1272 
1273  if (ConfigDesc.bNumInterfaces > 1)
1274  {
1275  DPRINT1("Warning: Device has more than one interface. Only one interface (the first) is currently supported\n");
1276  }
1277 
1278  ConfigDescSize = ConfigDesc.wTotalLength;
1279 
1280  //
1281  // Allocate memory for the first full descriptor, including interfaces and endpoints.
1282  //
1283  UsbChildExtension->FullConfigDesc = ExAllocatePoolWithTag(PagedPool, ConfigDescSize, USB_HUB_TAG);
1284 
1285  //
1286  // Retrieve the full configuration descriptor
1287  //
1288  Status = GetUsbDeviceDescriptor(NewChildDeviceObject,
1290  0,
1291  0,
1292  UsbChildExtension->FullConfigDesc,
1293  ConfigDescSize);
1294 
1295  if (!NT_SUCCESS(Status))
1296  {
1297  DPRINT1("USBHUB: GetUsbDeviceDescriptor failed with status %x\n", Status);
1298  goto Cleanup;
1299  }
1300 
1301  // query device details
1302  Status = HubInterface->QueryDeviceInformation(HubInterfaceBusContext,
1303  UsbChildExtension->UsbDeviceHandle,
1304  &UsbChildExtension->DeviceInformation,
1305  sizeof(USB_DEVICE_INFORMATION_0),
1306  &DeviceInfoSize);
1307 
1308 
1309  //DumpFullConfigurationDescriptor(UsbChildExtension->FullConfigDesc);
1310 
1311  //
1312  // Construct all the strings that will describe the device to PNP
1313  //
1314  Status = CreateDeviceIds(NewChildDeviceObject);
1315  if (!NT_SUCCESS(Status))
1316  {
1317  DPRINT1("Failed to create strings needed to describe device to PNP.\n");
1318  goto Cleanup;
1319  }
1320 
1321  // copy device interface
1322  RtlCopyMemory(&UsbChildExtension->DeviceInterface, &HubDeviceExtension->UsbDInterface, sizeof(USB_BUS_INTERFACE_USBDI_V2));
1323  UsbChildExtension->DeviceInterface.InterfaceReference(UsbChildExtension->DeviceInterface.BusContext);
1324 
1325  INITIALIZE_PNP_STATE(UsbChildExtension->Common);
1326 
1327  IoInitializeRemoveLock(&UsbChildExtension->Common.RemoveLock, 'pbuH', 0, 0);
1328 
1329  KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
1330 
1331  //
1332  // Find an empty slot in the child device array
1333  //
1334  for (ChildDeviceCount = 0; ChildDeviceCount < USB_MAXCHILDREN; ChildDeviceCount++)
1335  {
1336  if (HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] == NULL)
1337  {
1338  DPRINT("Found unused entry at %d\n", ChildDeviceCount);
1339  break;
1340  }
1341  }
1342 
1343  //
1344  // Check if the limit has been reached for maximum usb devices
1345  //
1346  if (ChildDeviceCount == USB_MAXCHILDREN)
1347  {
1348  DPRINT1("USBHUB: Too many child devices!\n");
1350  KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
1351  UsbChildExtension->DeviceInterface.InterfaceDereference(UsbChildExtension->DeviceInterface.BusContext);
1352  goto Cleanup;
1353  }
1354 
1355  HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] = NewChildDeviceObject;
1356  HubDeviceExtension->InstanceCount++;
1357  KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
1358 
1359  IoInvalidateDeviceRelations(RootHubDeviceObject, BusRelations);
1360  return STATUS_SUCCESS;
1361 
1362 Cleanup:
1363 
1364  //
1365  // Remove the usb device if it was created
1366  //
1367  if (UsbChildExtension->UsbDeviceHandle)
1368  HubInterface->RemoveUsbDevice(HubInterfaceBusContext, UsbChildExtension->UsbDeviceHandle, 0);
1369 
1370  //
1371  // Free full configuration descriptor if one was allocated
1372  //
1373  if (UsbChildExtension->FullConfigDesc)
1374  ExFreePool(UsbChildExtension->FullConfigDesc);
1375 
1376  //
1377  // Free ID buffers if they were allocated in CreateDeviceIds()
1378  //
1379  if (UsbChildExtension->usCompatibleIds.Buffer)
1380  ExFreePool(UsbChildExtension->usCompatibleIds.Buffer);
1381 
1382  if (UsbChildExtension->usDeviceId.Buffer)
1383  ExFreePool(UsbChildExtension->usDeviceId.Buffer);
1384 
1385  if (UsbChildExtension->usHardwareIds.Buffer)
1386  ExFreePool(UsbChildExtension->usHardwareIds.Buffer);
1387 
1388  if (UsbChildExtension->usInstanceId.Buffer)
1389  ExFreePool(UsbChildExtension->usInstanceId.Buffer);
1390 
1391  //
1392  // Delete the device object
1393  //
1394  IoDeleteDevice(NewChildDeviceObject);
1395  return Status;
1396 }
1397 
1398 NTSTATUS
1401  IN PDEVICE_RELATIONS RelationsFromTop,
1402  OUT PDEVICE_RELATIONS* pDeviceRelations)
1403 {
1404  PHUB_DEVICE_EXTENSION HubDeviceExtension;
1405  PDEVICE_RELATIONS DeviceRelations;
1406  ULONG i;
1407  ULONG ChildrenFromTop = 0;
1408  ULONG Children = 0;
1409  ULONG NeededSize;
1410 
1411  HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1412 
1413  KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
1414 
1415  //
1416  // Count the number of children
1417  //
1418  for (i = 0; i < USB_MAXCHILDREN; i++)
1419  {
1420 
1421  if (HubDeviceExtension->ChildDeviceObject[i] == NULL)
1422  {
1423  continue;
1424  }
1425  Children++;
1426  }
1427 
1428  if (RelationsFromTop)
1429  {
1430  ChildrenFromTop = RelationsFromTop->Count;
1431  if (!Children)
1432  {
1433  // We have nothing to add
1434  *pDeviceRelations = RelationsFromTop;
1435  KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
1436  return STATUS_SUCCESS;
1437  }
1438  }
1439 
1440  NeededSize = sizeof(DEVICE_RELATIONS) + (Children + ChildrenFromTop - 1) * sizeof(PDEVICE_OBJECT);
1441 
1442  //
1443  // Allocate DeviceRelations
1444  //
1445  DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool,
1446  NeededSize);
1447 
1448  if (!DeviceRelations)
1449  {
1450  KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
1451  if (!RelationsFromTop)
1453  else
1454  return STATUS_NOT_SUPPORTED;
1455  }
1456  // Copy the objects coming from top
1457  if (ChildrenFromTop)
1458  {
1459  RtlCopyMemory(DeviceRelations->Objects, RelationsFromTop->Objects,
1460  ChildrenFromTop * sizeof(PDEVICE_OBJECT));
1461  }
1462 
1463  DeviceRelations->Count = Children + ChildrenFromTop;
1464  Children = ChildrenFromTop;
1465 
1466  //
1467  // Fill in return structure
1468  //
1469  for (i = 0; i < USB_MAXCHILDREN; i++)
1470  {
1471  if (HubDeviceExtension->ChildDeviceObject[i])
1472  {
1473  // The PnP Manager removes the reference when appropriate.
1474  ObReferenceObject(HubDeviceExtension->ChildDeviceObject[i]);
1475  HubDeviceExtension->ChildDeviceObject[i]->Flags &= ~DO_DEVICE_INITIALIZING;
1476  DeviceRelations->Objects[Children++] = HubDeviceExtension->ChildDeviceObject[i];
1477  }
1478  }
1479 
1480  KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
1481 
1482  // We should do this, because replaced this with our's one
1483  if (RelationsFromTop)
1484  ExFreePool(RelationsFromTop);
1485 
1486  ASSERT(Children == DeviceRelations->Count);
1487  *pDeviceRelations = DeviceRelations;
1488 
1489  return STATUS_SUCCESS;
1490 }
1491 
1492 VOID
1493 NTAPI
1495  PVOID Context)
1496 {
1498  NTSTATUS Status;
1499  ULONG PortId;
1500  PHUB_DEVICE_EXTENSION HubDeviceExtension;
1501  PORT_STATUS_CHANGE StatusChange;
1502 
1503  HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
1504 
1505  DPRINT("RootHubInitCallbackFunction Sending the initial SCE Request %x\n", DeviceObject);
1506 
1507  //
1508  // Send the first SCE Request
1509  //
1511 
1512  for (PortId = 1; PortId <= HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++)
1513  {
1514  //
1515  // get port status
1516  //
1517  Status = GetPortStatusAndChange(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, &StatusChange);
1518  if (NT_SUCCESS(Status))
1519  {
1520  //
1521  // is there a device connected
1522  //
1523  if (StatusChange.Status & USB_PORT_STATUS_CONNECT)
1524  {
1525  //
1526  // reset port
1527  //
1528  Status = SetPortFeature(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, PORT_RESET);
1529  if (!NT_SUCCESS(Status))
1530  {
1531  DPRINT1("Failed to reset on port %d\n", PortId);
1532  }
1533  else
1534  {
1535  //
1536  // wait for the reset to be handled since we want to enumerate synchronously
1537  //
1538  KeWaitForSingleObject(&HubDeviceExtension->ResetComplete,
1539  Executive,
1540  KernelMode,
1541  FALSE,
1542  NULL);
1543  KeClearEvent(&HubDeviceExtension->ResetComplete);
1544  }
1545  }
1546  }
1547  }
1548 }
1549 
1550 BOOLEAN
1553 {
1554  NTSTATUS Status;
1555  PDEVICE_OBJECT RootHubPhysicalDeviceObject = NULL;
1556  PHUB_DEVICE_EXTENSION HubDeviceExtension;
1557 
1558  // get hub device extension
1559  HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
1560 
1561  // Get the Root Hub Pdo
1562  Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
1564  &RootHubPhysicalDeviceObject,
1565  NULL);
1566 
1567  // FIXME handle error
1569 
1570  // physical device object is only obtained for root hubs
1571  return (RootHubPhysicalDeviceObject != NULL);
1572 }
1573 
1574 
1575 NTSTATUS
1578  IN PIRP Irp)
1579 {
1580  PURB Urb;
1582  ULONG Result = 0, PortId;
1584  PURB ConfigUrb = NULL;
1585  ULONG HubStatus;
1587  PHUB_DEVICE_EXTENSION HubDeviceExtension;
1588  PDEVICE_OBJECT RootHubDeviceObject;
1589  PVOID HubInterfaceBusContext;
1590  PORT_STATUS_CHANGE StatusChange;
1591 
1592  // get hub device extension
1593  HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
1594 
1595  DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
1596 
1597  // Allocated size including the sizeof USBD_INTERFACE_LIST_ENTRY
1599  if (!Urb)
1600  {
1601  // no memory
1603  goto cleanup;
1604  }
1605 
1606  // zero urb
1607  RtlZeroMemory(Urb, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY));
1608 
1609  // Get the Root Hub Pdo
1610  Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
1612  &HubDeviceExtension->RootHubPhysicalDeviceObject,
1613  &HubDeviceExtension->RootHubFunctionalDeviceObject);
1614  if (!NT_SUCCESS(Status))
1615  {
1616  // failed to obtain hub pdo
1617  DPRINT1("IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO failed with %x\n", Status);
1618  goto cleanup;
1619  }
1620 
1621  // sanity checks
1622  ASSERT(HubDeviceExtension->RootHubPhysicalDeviceObject);
1623  ASSERT(HubDeviceExtension->RootHubFunctionalDeviceObject);
1624 
1625  // get roothub
1626  RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
1627 
1628  // Send the StartDevice to RootHub
1629  Status = ForwardIrpAndWait(HubDeviceExtension->LowerDeviceObject, Irp);
1630 
1631  if (!NT_SUCCESS(Status))
1632  {
1633  // failed to start pdo
1634  DPRINT1("Failed to start the RootHub PDO\n");
1635  goto cleanup;
1636  }
1637 
1638  // Get the current number of hubs
1639  Status = SubmitRequestToRootHub(RootHubDeviceObject,
1641  &HubDeviceExtension->NumberOfHubs, NULL);
1642  if (!NT_SUCCESS(Status))
1643  {
1644  // failed to get number of hubs
1645  DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT failed with %x\n", Status);
1646  goto cleanup;
1647  }
1648 
1649  // Get the Hub Interface
1650  Status = QueryInterface(RootHubDeviceObject,
1651  USB_BUS_INTERFACE_HUB_GUID,
1652  sizeof(USB_BUS_INTERFACE_HUB_V5),
1654  (PVOID)&HubDeviceExtension->HubInterface);
1655 
1656  if (!NT_SUCCESS(Status))
1657  {
1658  // failed to get root hub interface
1659  DPRINT1("Failed to get HUB_GUID interface with status 0x%08lx\n", Status);
1660  goto cleanup;
1661  }
1662 
1663  HubInterfaceBusContext = HubDeviceExtension->HubInterface.BusContext;
1664 
1665  // Get the USBDI Interface
1666  Status = QueryInterface(RootHubDeviceObject,
1667  USB_BUS_INTERFACE_USBDI_GUID,
1670  (PVOID)&HubDeviceExtension->UsbDInterface);
1671 
1672  if (!NT_SUCCESS(Status))
1673  {
1674  // failed to get usbdi interface
1675  DPRINT1("Failed to get USBDI_GUID interface with status 0x%08lx\n", Status);
1676  goto cleanup;
1677  }
1678 
1679  // Get Root Hub Device Handle
1680  Status = SubmitRequestToRootHub(RootHubDeviceObject,
1681  IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE,
1682  &HubDeviceExtension->RootHubHandle,
1683  NULL);
1684 
1685  if (!NT_SUCCESS(Status))
1686  {
1687  // failed
1688  DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE failed with status 0x%08lx\n", Status);
1689  goto cleanup;
1690  }
1691 
1692  //
1693  // Get Hub Device Information
1694  //
1695  Status = HubDeviceExtension->HubInterface.QueryDeviceInformation(HubInterfaceBusContext,
1696  HubDeviceExtension->RootHubHandle,
1697  &HubDeviceExtension->DeviceInformation,
1698  sizeof(USB_DEVICE_INFORMATION_0),
1699  &Result);
1700 
1701  DPRINT("Status %x, Result 0x%08lx\n", Status, Result);
1702  DPRINT("InformationLevel %x\n", HubDeviceExtension->DeviceInformation.InformationLevel);
1703  DPRINT("ActualLength %x\n", HubDeviceExtension->DeviceInformation.ActualLength);
1704  DPRINT("PortNumber %x\n", HubDeviceExtension->DeviceInformation.PortNumber);
1705  DPRINT("DeviceDescriptor %x\n", HubDeviceExtension->DeviceInformation.DeviceDescriptor);
1706  DPRINT("HubAddress %x\n", HubDeviceExtension->DeviceInformation.HubAddress);
1707  DPRINT("NumberofPipes %x\n", HubDeviceExtension->DeviceInformation.NumberOfOpenPipes);
1708 
1709  // Get Root Hubs Device Descriptor
1711  sizeof(Urb->UrbControlDescriptorRequest),
1713  0,
1714  0,
1715  &HubDeviceExtension->HubDeviceDescriptor,
1716  NULL,
1717  sizeof(USB_DEVICE_DESCRIPTOR),
1718  NULL);
1719 
1720  // set device handle
1721  Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
1722 
1723  // get hub device descriptor
1724  Status = SubmitRequestToRootHub(RootHubDeviceObject,
1726  Urb,
1727  NULL);
1728 
1729  if (!NT_SUCCESS(Status))
1730  {
1731  // failed to get device descriptor of hub
1732  DPRINT1("Failed to get HubDeviceDescriptor!\n");
1733  goto cleanup;
1734  }
1735 
1736  // build configuration request
1738  sizeof(Urb->UrbControlDescriptorRequest),
1740  0,
1741  0,
1742  &HubDeviceExtension->HubConfigDescriptor,
1743  NULL,
1745  NULL);
1746 
1747  // set device handle
1748  Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
1749 
1750  // request configuration descriptor
1751  Status = SubmitRequestToRootHub(RootHubDeviceObject,
1753  Urb,
1754  NULL);
1755 
1756  if (!NT_SUCCESS(Status))
1757  {
1758  // failed to get configuration descriptor
1759  DPRINT1("Failed to get RootHub Configuration with status %x\n", Status);
1760  goto cleanup;
1761  }
1762 
1763  // sanity checks
1766  ASSERT(HubDeviceExtension->HubConfigDescriptor.bLength == sizeof(USB_CONFIGURATION_DESCRIPTOR));
1767  ASSERT(HubDeviceExtension->HubConfigDescriptor.bNumInterfaces == 1);
1768  ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bLength == sizeof(USB_INTERFACE_DESCRIPTOR));
1770  ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bNumEndpoints == 1);
1772  ASSERT(HubDeviceExtension->HubEndPointDescriptor.bLength == sizeof(USB_ENDPOINT_DESCRIPTOR));
1774  ASSERT(HubDeviceExtension->HubEndPointDescriptor.bEndpointAddress == 0x81); // interrupt in
1775 
1776  // get hub information
1777  Status = HubDeviceExtension->HubInterface.GetExtendedHubInformation(HubInterfaceBusContext,
1778  RootHubDeviceObject,
1779  &HubDeviceExtension->UsbExtHubInfo,
1780  sizeof(USB_EXTHUB_INFORMATION_0),
1781  &Result);
1782  if (!NT_SUCCESS(Status))
1783  {
1784  // failed to get hub information
1785  DPRINT1("Failed to extended hub information. Unable to determine the number of ports!\n");
1786  goto cleanup;
1787  }
1788 
1789  if (!HubDeviceExtension->UsbExtHubInfo.NumberOfPorts)
1790  {
1791  // bogus port driver
1792  DPRINT1("Failed to retrieve the number of ports\n");
1794  goto cleanup;
1795  }
1796 
1797  DPRINT("HubDeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", HubDeviceExtension->UsbExtHubInfo.NumberOfPorts);
1798 
1799  // Build hub descriptor request
1802  sizeof(Urb->UrbControlVendorClassRequest),
1804  0,
1807  0,
1808  &HubDeviceExtension->HubDescriptor,
1809  NULL,
1810  sizeof(USB_HUB_DESCRIPTOR),
1811  NULL);
1812 
1813  // set device handle
1814  Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
1815 
1816  // send request
1817  Status = SubmitRequestToRootHub(RootHubDeviceObject,
1819  Urb,
1820  NULL);
1821 
1822  if (!NT_SUCCESS(Status))
1823  {
1824  DPRINT1("Failed to get Hub Descriptor!\n");
1826  goto cleanup;
1827  }
1828 
1829  // sanity checks
1830  ASSERT(HubDeviceExtension->HubDescriptor.bDescriptorLength == sizeof(USB_HUB_DESCRIPTOR));
1831  ASSERT(HubDeviceExtension->HubDescriptor.bNumberOfPorts == HubDeviceExtension->UsbExtHubInfo.NumberOfPorts);
1832  ASSERT(HubDeviceExtension->HubDescriptor.bDescriptorType == 0x29);
1833 
1834  // build get status request
1835  HubStatus = 0;
1838  0,
1839  &HubStatus,
1840  0,
1841  NULL);
1842  // set device handle
1843  Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
1844 
1845  // send request
1846  Status = SubmitRequestToRootHub(RootHubDeviceObject,
1848  Urb,
1849  NULL);
1850  if (!NT_SUCCESS(Status))
1851  {
1852  // failed to get hub status
1853  DPRINT1("Failed to get Hub Status!\n");
1855  goto cleanup;
1856  }
1857 
1858  // Allocate memory for PortStatusChange to hold 2 USHORTs for each port on hub
1859  HubDeviceExtension->PortStatusChange = ExAllocatePoolWithTag(NonPagedPool,
1860  sizeof(ULONG) * HubDeviceExtension->UsbExtHubInfo.NumberOfPorts,
1861  USB_HUB_TAG);
1862 
1863  if (!HubDeviceExtension->PortStatusChange)
1864  {
1865  DPRINT1("Failed to allocate pool for PortStatusChange!\n");
1867  goto cleanup;
1868  }
1869 
1870  // Get the first Configuration Descriptor
1871  Pid = USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor,
1872  &HubDeviceExtension->HubConfigDescriptor,
1873  -1, -1, -1, -1, -1);
1874  if (Pid == NULL)
1875  {
1876  // failed parse hub descriptor
1877  DPRINT1("Failed to parse configuration descriptor\n");
1879  goto cleanup;
1880  }
1881 
1882  // create configuration request
1884  ConfigUrb = USBD_CreateConfigurationRequestEx(&HubDeviceExtension->HubConfigDescriptor,
1886  if (ConfigUrb == NULL)
1887  {
1888  // failed to build urb
1889  DPRINT1("Failed to allocate urb\n");
1891  goto cleanup;
1892  }
1893 
1894  // send request
1895  Status = SubmitRequestToRootHub(RootHubDeviceObject,
1897  ConfigUrb,
1898  NULL);
1899  if (!NT_SUCCESS(Status))
1900  {
1901  // failed to select configuration
1902  DPRINT1("Failed to select configuration with %x\n", Status);
1903  goto cleanup;
1904  }
1905 
1906  // store configuration & pipe handle
1907  HubDeviceExtension->ConfigurationHandle = ConfigUrb->UrbSelectConfiguration.ConfigurationHandle;
1908  HubDeviceExtension->PipeHandle = ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
1909  DPRINT("Configuration Handle %x\n", HubDeviceExtension->ConfigurationHandle);
1910 
1911  // check if function is available
1912  if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed)
1913  {
1914  // is it high speed bus
1915  if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed(HubInterfaceBusContext))
1916  {
1917  // initialize usb 2.0 hub
1918  Status = HubDeviceExtension->HubInterface.Initialize20Hub(HubInterfaceBusContext,
1919  HubDeviceExtension->RootHubHandle, 1);
1920  DPRINT("Status %x\n", Status);
1921 
1922  // FIXME handle error
1924  }
1925  }
1926 
1927 
1928  // Enable power on all ports
1929  DPRINT("Enabling PortPower on all ports!\n");
1930  for (PortId = 1; PortId <= HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++)
1931  {
1932  Status = SetPortFeature(RootHubDeviceObject, PortId, PORT_POWER);
1933  if (!NT_SUCCESS(Status))
1934  DPRINT1("Failed to power on port %d\n", PortId);
1935 
1936  Status = ClearPortFeature(RootHubDeviceObject, PortId, C_PORT_CONNECTION);
1937  if (!NT_SUCCESS(Status))
1938  DPRINT1("Failed to power on port %d\n", PortId);
1939  }
1940 
1941  // init root hub notification
1942  if (HubDeviceExtension->HubInterface.RootHubInitNotification)
1943  {
1944  Status = HubDeviceExtension->HubInterface.RootHubInitNotification(HubInterfaceBusContext,
1945  DeviceObject,
1947  if (!NT_SUCCESS(Status))
1948  {
1949  DPRINT1("Failed to set callback\n");
1950  goto cleanup;
1951  }
1952  }
1953  else
1954  {
1955  // Send the first SCE Request
1957 
1958  //
1959  // reset ports
1960  //
1961  for (PortId = 1; PortId <= HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++)
1962  {
1963  //
1964  // get port status
1965  //
1966  Status = GetPortStatusAndChange(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, &StatusChange);
1967  if (NT_SUCCESS(Status))
1968  {
1969  //
1970  // is there a device connected
1971  //
1972  if (StatusChange.Status & USB_PORT_STATUS_CONNECT)
1973  {
1974  //
1975  // reset port
1976  //
1977  Status = SetPortFeature(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, PORT_RESET);
1978  if (!NT_SUCCESS(Status))
1979  {
1980  DPRINT1("Failed to reset on port %d\n", PortId);
1981  }
1982  else
1983  {
1984  //
1985  // wait for the reset to be handled since we want to enumerate synchronously
1986  //
1987  KeWaitForSingleObject(&HubDeviceExtension->ResetComplete,
1988  Executive,
1989  KernelMode,
1990  FALSE,
1991  NULL);
1992  KeClearEvent(&HubDeviceExtension->ResetComplete);
1993  }
1994  }
1995  }
1996  }
1997  }
1998 
1999  // free urb
2000  ExFreePool(Urb);
2001 
2002  // free ConfigUrb
2003  ExFreePool(ConfigUrb);
2004 
2005  // done
2006  return Status;
2007 
2008 cleanup:
2009  if (Urb)
2010  ExFreePool(Urb);
2011 
2012  // Dereference interfaces
2013  if (HubDeviceExtension->HubInterface.Size)
2014  HubDeviceExtension->HubInterface.InterfaceDereference(HubDeviceExtension->HubInterface.BusContext);
2015 
2016  if (HubDeviceExtension->UsbDInterface.Size)
2017  HubDeviceExtension->UsbDInterface.InterfaceDereference(HubDeviceExtension->UsbDInterface.BusContext);
2018 
2019  if (HubDeviceExtension->PortStatusChange)
2020  ExFreePool(HubDeviceExtension->PortStatusChange);
2021 
2022  if (ConfigUrb)
2023  ExFreePool(ConfigUrb);
2024 
2025  return Status;
2026 }
2027 
2028 NTSTATUS
2031  IN PIRP Irp)
2032 {
2033  PIO_STACK_LOCATION Stack;
2035  PDEVICE_OBJECT ChildDeviceObject;
2036  PHUB_DEVICE_EXTENSION HubDeviceExtension;
2037  PUSB_BUS_INTERFACE_HUB_V5 HubInterface;
2038  PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
2039 
2040  HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
2041 
2042  HubInterface = &HubDeviceExtension->HubInterface;
2044 
2045  Status = IoAcquireRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
2046  if (!NT_SUCCESS(Status))
2047  {
2048  Irp->IoStatus.Status = Status;
2050  return Status;
2051  }
2052 
2053  switch (Stack->MinorFunction)
2054  {
2055  int i;
2056 
2057  case IRP_MN_START_DEVICE:
2058  {
2059  DPRINT("IRP_MN_START_DEVICE\n");
2061  {
2062  // start root hub fdo
2064  }
2065  else
2066  {
2068  }
2069 
2070  SET_NEW_PNP_STATE(HubDeviceExtension->Common, Started);
2071 
2072  Irp->IoStatus.Status = Status;
2074  IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
2075  return Status;
2076  }
2077 
2079  {
2080  switch (Stack->Parameters.QueryDeviceRelations.Type)
2081  {
2082  case BusRelations:
2083  {
2084  PDEVICE_RELATIONS DeviceRelations = NULL;
2085  PDEVICE_RELATIONS RelationsFromTop = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
2086  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
2087 
2088  Status = USBHUB_FdoQueryBusRelations(DeviceObject, RelationsFromTop, &DeviceRelations);
2089 
2090  if (!NT_SUCCESS(Status))
2091  {
2093  {
2094  // We should process this to not lose relations from top.
2095  Irp->IoStatus.Status = STATUS_SUCCESS;
2096  break;
2097  }
2098  // We should fail an IRP
2099  Irp->IoStatus.Status = Status;
2101  IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
2102  return Status;
2103  }
2104 
2105  Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
2106  Irp->IoStatus.Status = Status;
2107  break;
2108  }
2109  case RemovalRelations:
2110  {
2111  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
2112  break;
2113  }
2114  default:
2115  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
2116  Stack->Parameters.QueryDeviceRelations.Type);
2117  break;
2118  }
2119  break;
2120  }
2122  {
2123  //
2124  // We should fail this request, because we're not handling
2125  // IRP_MN_STOP_DEVICE for now.We'll receive this IRP ONLY when
2126  // PnP manager rebalances resources.
2127  //
2128  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
2130  return STATUS_NOT_SUPPORTED;
2131  }
2133  {
2134  // No action is required from FDO because it have nothing to free.
2135  DPRINT("IRP_MN_QUERY_REMOVE_DEVICE\n");
2136 
2137  SET_NEW_PNP_STATE(HubDeviceExtension->Common, RemovePending);
2138 
2139  Irp->IoStatus.Status = STATUS_SUCCESS;
2140  break;
2141  }
2143  {
2144  DPRINT("IRP_MN_CANCEL_REMOVE_DEVICE\n");
2145 
2146  if (HubDeviceExtension->Common.PnPState == RemovePending)
2147  RESTORE_PREVIOUS_PNP_STATE(HubDeviceExtension->Common);
2148 
2149  Irp->IoStatus.Status = STATUS_SUCCESS;
2150  break;
2151  }
2153  {
2154  //
2155  // We'll receive this IRP on HUB unexpected removal, or on USB
2156  // controller removal from PCI port. Here we should "let know" all
2157  // our children that their parent is removed and on next removal
2158  // they also can be removed.
2159  //
2160  SET_NEW_PNP_STATE(HubDeviceExtension->Common, SurpriseRemovePending);
2161 
2162  KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
2163 
2164  for (i = 0; i < USB_MAXCHILDREN; i++)
2165  {
2166  ChildDeviceObject = HubDeviceExtension->ChildDeviceObject[i];
2167  if (ChildDeviceObject)
2168  {
2169  ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)ChildDeviceObject->DeviceObjectExtension;
2170  ChildDeviceExtension->ParentDeviceObject = NULL;
2171  }
2172  }
2173 
2174  KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
2175 
2176  // This IRP can't be failed
2177  Irp->IoStatus.Status = STATUS_SUCCESS;
2178  break;
2179  }
2180  case IRP_MN_REMOVE_DEVICE:
2181  {
2182  DPRINT("IRP_MN_REMOVE_DEVICE\n");
2183 
2184  SET_NEW_PNP_STATE(HubDeviceExtension->Common, Deleted);
2185 
2186  IoReleaseRemoveLockAndWait(&HubDeviceExtension->Common.RemoveLock, Irp);
2187 
2188  //
2189  // Here we should remove all child PDOs. At this point all children
2190  // received and returned from IRP_MN_REMOVE so remove synchronization
2191  // isn't needed here
2192  //
2193 
2194  KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
2195 
2196  for (i = 0; i < USB_MAXCHILDREN; i++)
2197  {
2198  ChildDeviceObject = HubDeviceExtension->ChildDeviceObject[i];
2199  if (ChildDeviceObject)
2200  {
2201  PHUB_CHILDDEVICE_EXTENSION UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)ChildDeviceObject->DeviceExtension;
2202 
2203  SET_NEW_PNP_STATE(UsbChildExtension->Common, Deleted);
2204 
2205  // Remove the usb device
2206  if (UsbChildExtension->UsbDeviceHandle)
2207  {
2208  Status = HubInterface->RemoveUsbDevice(HubInterface->BusContext, UsbChildExtension->UsbDeviceHandle, 0);
2210  }
2211 
2212  // Free full configuration descriptor
2213  if (UsbChildExtension->FullConfigDesc)
2214  ExFreePool(UsbChildExtension->FullConfigDesc);
2215 
2216  // Free ID buffers
2217  if (UsbChildExtension->usCompatibleIds.Buffer)
2218  ExFreePool(UsbChildExtension->usCompatibleIds.Buffer);
2219 
2220  if (UsbChildExtension->usDeviceId.Buffer)
2221  ExFreePool(UsbChildExtension->usDeviceId.Buffer);
2222 
2223  if (UsbChildExtension->usHardwareIds.Buffer)
2224  ExFreePool(UsbChildExtension->usHardwareIds.Buffer);
2225 
2226  if (UsbChildExtension->usInstanceId.Buffer)
2227  ExFreePool(UsbChildExtension->usInstanceId.Buffer);
2228 
2229  DPRINT("Deleting child PDO\n");
2231  ChildDeviceObject = NULL;
2232  }
2233  }
2234 
2235  KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
2236 
2237  Irp->IoStatus.Status = STATUS_SUCCESS;
2239 
2240  IoDetachDevice(HubDeviceExtension->LowerDeviceObject);
2241  DPRINT("Deleting FDO 0x%p\n", DeviceObject);
2243 
2244  return Status;
2245  }
2247  {
2248  // Function drivers and filter drivers do not handle this IRP.
2249  DPRINT("IRP_MN_QUERY_BUS_INFORMATION\n");
2250  break;
2251  }
2252  case IRP_MN_QUERY_ID:
2253  {
2254  DPRINT("IRP_MN_QUERY_ID\n");
2255  // Function drivers and filter drivers do not handle this IRP.
2256  break;
2257  }
2259  {
2260  //
2261  // If a function or filter driver does not handle this IRP, it
2262  // should pass that down.
2263  //
2264  DPRINT("IRP_MN_QUERY_CAPABILITIES\n");
2265  break;
2266  }
2267  default:
2268  {
2269  DPRINT(" IRP_MJ_PNP / unknown minor function 0x%lx\n", Stack->MinorFunction);
2270  break;
2271  }
2272  }
2273 
2275  IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
2276  return Status;
2277 }
2278 
2279 NTSTATUS
2282  IN PIRP Irp)
2283 {
2284  PIO_STACK_LOCATION IoStack;
2286  PUSB_NODE_INFORMATION NodeInformation;
2287  PHUB_DEVICE_EXTENSION HubDeviceExtension;
2288  PUSB_NODE_CONNECTION_INFORMATION NodeConnectionInfo;
2289  PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
2291  PUSB_NODE_CONNECTION_NAME ConnectionName;
2292  ULONG Index, Length;
2293 
2294  // get stack location
2295  IoStack = IoGetCurrentIrpStackLocation(Irp);
2296 
2297  // get device extension
2298  HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
2299 
2300  Status = IoAcquireRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
2301  if (!NT_SUCCESS(Status))
2302  {
2303  Irp->IoStatus.Status = Status;
2305  return Status;
2306  }
2307 
2308  // Prevent handling of control requests in remove pending state
2309  if (HubDeviceExtension->Common.PnPState == RemovePending)
2310  {
2311  DPRINT1("[USBHUB] Request for removed device object %p\n", DeviceObject);
2312  Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED;
2313  Irp->IoStatus.Information = 0;
2315  IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
2317  }
2318 
2319  if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_NODE_INFORMATION)
2320  {
2321  // is the buffer big enough
2322  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(USB_NODE_INFORMATION))
2323  {
2324  // buffer too small
2326  }
2327  else
2328  {
2329  // get buffer
2330  NodeInformation = (PUSB_NODE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2331 
2332  // sanity check
2333  ASSERT(NodeInformation);
2334 
2335  // init buffer
2336  NodeInformation->NodeType = UsbHub;
2337  RtlCopyMemory(&NodeInformation->u.HubInformation.HubDescriptor, &HubDeviceExtension->HubDescriptor, sizeof(USB_HUB_DESCRIPTOR));
2338 
2339  // FIXME is hub powered
2340  NodeInformation->u.HubInformation.HubIsBusPowered = TRUE;
2341 
2342  // done
2343  Irp->IoStatus.Information = sizeof(USB_NODE_INFORMATION);
2345  }
2346 
2347 
2348  }
2349  else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_NODE_CONNECTION_INFORMATION)
2350  {
2351  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(USB_NODE_CONNECTION_INFORMATION))
2352  {
2353  // buffer too small
2355  }
2356  else
2357  {
2358  // get node connection info
2359  NodeConnectionInfo = (PUSB_NODE_CONNECTION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2360 
2361  // sanity checks
2362  ASSERT(NodeConnectionInfo);
2363 
2364  KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
2365  for(Index = 0; Index < USB_MAXCHILDREN; Index++)
2366  {
2367  if (HubDeviceExtension->ChildDeviceObject[Index] == NULL)
2368  continue;
2369 
2370  // get child device extension
2371  ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)HubDeviceExtension->ChildDeviceObject[Index]->DeviceExtension;
2372 
2373  if (ChildDeviceExtension->PortNumber != NodeConnectionInfo->ConnectionIndex)
2374  continue;
2375 
2376  // init node connection info
2377  RtlCopyMemory(&NodeConnectionInfo->DeviceDescriptor, &ChildDeviceExtension->DeviceDesc, sizeof(USB_DEVICE_DESCRIPTOR));
2378  NodeConnectionInfo->CurrentConfigurationValue = ChildDeviceExtension->FullConfigDesc->bConfigurationValue;
2379  NodeConnectionInfo->DeviceIsHub = FALSE; //FIXME support hubs
2380  NodeConnectionInfo->LowSpeed = ChildDeviceExtension->DeviceInformation.DeviceSpeed == UsbLowSpeed;
2381  NodeConnectionInfo->DeviceAddress = ChildDeviceExtension->DeviceInformation.DeviceAddress;
2382  NodeConnectionInfo->NumberOfOpenPipes = ChildDeviceExtension->DeviceInformation.NumberOfOpenPipes;
2383  NodeConnectionInfo->ConnectionStatus = DeviceConnected; //FIXME
2384 
2385  if (NodeConnectionInfo->NumberOfOpenPipes)
2386  {
2387  DPRINT1("Need to copy pipe information\n");
2388  }
2389  break;
2390  }
2391  KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
2392  // done
2393  Irp->IoStatus.Information = sizeof(USB_NODE_INFORMATION);
2395  }
2396  }
2397  else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME)
2398  {
2399  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(USB_NODE_CONNECTION_INFORMATION))
2400  {
2401  // buffer too small
2403  }
2404  else
2405  {
2406  // get node connection info
2407  NodeKey = (PUSB_NODE_CONNECTION_DRIVERKEY_NAME)Irp->AssociatedIrp.SystemBuffer;
2408 
2409  // sanity checks
2410  ASSERT(NodeKey);
2411 
2412  KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
2413  for(Index = 0; Index < USB_MAXCHILDREN; Index++)
2414  {
2415  if (HubDeviceExtension->ChildDeviceObject[Index] == NULL)
2416  continue;
2417 
2418  // get child device extension
2419  ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)HubDeviceExtension->ChildDeviceObject[Index]->DeviceExtension;
2420 
2421  if (ChildDeviceExtension->PortNumber != NodeKey->ConnectionIndex)
2422  continue;
2423 
2424  // get driver key
2426  IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME),
2427  NodeKey->DriverKeyName,
2428  &Length);
2429 
2431  {
2432  // normalize status
2434  }
2435 
2436  if (Length + sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME) > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
2437  {
2438  // terminate node key name
2439  NodeKey->DriverKeyName[0] = UNICODE_NULL;
2440  Irp->IoStatus.Information = sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME);
2441  }
2442  else
2443  {
2444  // result size
2445  Irp->IoStatus.Information = Length + sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME);
2446  }
2447 
2448  // length of driver name
2450  break;
2451  }
2452  KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
2453  }
2454  }
2455  else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_NODE_CONNECTION_NAME)
2456  {
2457  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(USB_NODE_CONNECTION_NAME))
2458  {
2459  // buffer too small
2461  }
2462  else
2463  {
2464  // FIXME support hubs
2465  ConnectionName = (PUSB_NODE_CONNECTION_NAME)Irp->AssociatedIrp.SystemBuffer;
2466  ConnectionName->ActualLength = 0;
2467  ConnectionName->NodeName[0] = UNICODE_NULL;
2468 
2469  // done
2470  Irp->IoStatus.Information = sizeof(USB_NODE_CONNECTION_NAME);
2472  }
2473  }
2474  else
2475  {
2476  DPRINT1("UNIMPLEMENTED FdoHandleDeviceControl IoCtl %x InputBufferLength %x OutputBufferLength %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode,
2477  IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength);
2478  }
2479 
2480  // finish irp
2481  Irp->IoStatus.Status = Status;
2483 
2484  IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
2485  return Status;
2486 }
2487 
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define IRP_MN_CANCEL_REMOVE_DEVICE
struct _USB_DEVICE_DESCRIPTOR USB_DEVICE_DESCRIPTOR
#define IN
Definition: typedefs.h:38
#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION
Definition: usbioctl.h:172
#define PORT_RESET
Definition: usbhub.h:19
WCHAR DriverKeyName[ANYSIZE_ARRAY]
Definition: usbioctl.h:304
struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST UrbControlVendorClassRequest
Definition: usb.h:548
USB_DEVICE_DESCRIPTOR HubDeviceDescriptor
Definition: usbhub.h:122
struct _USB_NODE_CONNECTION_INFORMATION * PUSB_NODE_CONNECTION_INFORMATION
UCHAR bDescriptorLength
Definition: usb100.h:171
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
UNICODE_STRING usHardwareIds
Definition: usbhub.h:89
IN PVOID IN PVOID IN USHORT Version
Definition: pci.h:359
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS GetUsbStringDescriptor(IN PDEVICE_OBJECT ChildDeviceObject, IN UCHAR Index, IN USHORT LangId, OUT PVOID *TransferBuffer, OUT USHORT *Size)
Definition: fdo.c:656
#define IRP_MN_QUERY_ID
#define C_PORT_CONNECTION
Definition: usbhub.h:22
#define USB_PORT_STATUS_ENABLE
Definition: usb200.h:152
USB_HUB_DESCRIPTOR HubDescriptor
Definition: usbhub.h:121
NTSTATUS NTAPI ForwardIrpAndWait(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fdo.c:32
#define UsbBuildGetStatusRequest(urb, op, index, transferBuffer, transferBufferMDL, link)
Definition: usbdlib.h:35
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
USHORT MaximumLength
Definition: env_spec_w32.h:370
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
struct _USB_NODE_INFORMATION * PUSB_NODE_INFORMATION
_In_ PIRP Irp
Definition: csq.h:116
struct _HUB_CHILDDEVICE_EXTENSION * PHUB_CHILDDEVICE_EXTENSION
#define IoInitializeRemoveLock(Lock, AllocateTag, MaxLockedMinutes, HighWatermark)
Definition: iofuncs.h:2785
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
struct _DEVICE_OBJECT * PDEVICE_OBJECT
NTSTATUS CreateDeviceIds(PDEVICE_OBJECT UsbChildDeviceObject)
Definition: fdo.c:822
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2054
unsigned char * PUCHAR
Definition: retypes.h:3
_In_ PUSBD_INTERFACE_LIST_ENTRY InterfaceList
Definition: usbdlib.h:168
USB_ENDPOINT_DESCRIPTOR HubEndPointDescriptor
Definition: usbhub.h:125
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
LONG NTSTATUS
Definition: precomp.h:26
USB_DEVICE_DESCRIPTOR DeviceDesc
Definition: usbhub.h:93
NTSTATUS USBHUB_FdoQueryBusRelations(IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_RELATIONS RelationsFromTop, OUT PDEVICE_RELATIONS *pDeviceRelations)
Definition: fdo.c:1399
BOOLEAN HubIsBusPowered
Definition: usbioctl.h:225
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2716
USB_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: hubbusif.h:692
#define C_PORT_RESET
Definition: usbhub.h:26
NTSTATUS USBHUB_ParentFDOStartDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hub_fdo.c:17
PDEVICE_OBJECT LowerDeviceObject
Definition: usbhub.h:103
#define IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME
Definition: usbioctl.h:187
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1295
union _USB_NODE_INFORMATION::@3130 u
NTSTATUS QueryInterface(IN PDEVICE_OBJECT DeviceObject, IN CONST GUID InterfaceType, IN LONG Size, IN LONG Version, OUT PVOID Interface)
Definition: fdo.c:532
WCHAR DeviceName[]
Definition: adapter.cpp:21
PINTERFACE_DEREFERENCE InterfaceDereference
Definition: usbbusif.h:111
struct _HUB_DEVICE_EXTENSION * PHUB_DEVICE_EXTENSION
#define UsbBuildGetDescriptorRequest(urb, length, descriptorType, descriptorIndex, languageId, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:23
USB_BUS_INTERFACE_USBDI_V2 DeviceInterface
Definition: usbhub.h:96
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
struct _USB_NODE_CONNECTION_DRIVERKEY_NAME USB_NODE_CONNECTION_DRIVERKEY_NAME
VOID NTAPI IoInitializeIrp(IN PIRP Irp, IN USHORT PacketSize, IN CCHAR StackSize)
Definition: irp.c:1854
NTSTATUS USBHUB_FdoStartDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fdo.c:1576
USB_HUB_DESCRIPTOR HubDescriptor
Definition: usbioctl.h:224
#define USB_STRING_DESCRIPTOR_TYPE
Definition: usb100.h:51
VOID NTAPI DeviceStatusChangeThread(IN PVOID Context)
Definition: fdo.c:205
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
#define UsbBuildVendorRequest(urb, cmd, length, transferFlags, reservedbits, request, value, index, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:68
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
IO_REMOVE_LOCK RemoveLock
Definition: usbhub.h:78
#define URB_FUNCTION_CLASS_DEVICE
Definition: usb.h:112
PUSB_CONFIGURATION_DESCRIPTOR FullConfigDesc
Definition: usbhub.h:94
Definition: usbdlib.h:7
while(1)
Definition: macro.lex.yy.c:740
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
KEVENT ResetComplete
Definition: usbhub.h:112
UNICODE_STRING usTextDescription
Definition: usbhub.h:91
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FILE_DEVICE_CONTROLLER
Definition: winioctl.h:109
#define USB_DEVICE_DESCRIPTOR_TYPE
Definition: usb100.h:49
#define UNICODE_NULL
PUSB_BUSIFFN_REMOVE_USB_DEVICE RemoveUsbDevice
Definition: hubbusif.h:544
#define IRP_MN_QUERY_REMOVE_DEVICE
struct _USB_NODE_CONNECTION_DRIVERKEY_NAME * PUSB_NODE_CONNECTION_DRIVERKEY_NAME
PUSB_BUSIFFN_IS_DEVICE_HIGH_SPEED IsDeviceHighSpeed
Definition: usbbusif.h:116
long LONG
Definition: pedump.c:60
#define USB_BUSIF_USBDI_VERSION_2
Definition: usbbusif.h:75
#define USB_CONFIGURATION_DESCRIPTOR_TYPE
Definition: usb100.h:50
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:434
#define USBD_TRANSFER_DIRECTION_OUT
Definition: usb.h:159
KGUARDED_MUTEX HubMutexLock
Definition: usbhub.h:109
#define USB_PORT_STATUS_RESET
Definition: usb200.h:155
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define USB_INTERFACE_DESCRIPTOR_TYPE
Definition: usb100.h:52
smooth NULL
Definition: ftsmooth.c:416
#define DO_BUS_ENUMERATED_DEVICE
NTSTATUS DestroyUsbChildDeviceObject(IN PDEVICE_OBJECT UsbHubDeviceObject, IN LONG PortId)
Definition: fdo.c:1088
_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
BOOLEAN USBHUB_IsRootHubFDO(IN PDEVICE_OBJECT DeviceObject)
Definition: fdo.c:1551
#define IoCompleteRequest
Definition: irp.c:1240
USB_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: usbioctl.h:291
#define IOCTL_USB_GET_NODE_CONNECTION_NAME
Definition: usbioctl.h:178
NTSTATUS NTAPI StatusChangeEndpointCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: fdo.c:396
NTSTATUS NTAPI IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength)
Definition: pnpmgr.c:4210
void DPRINT(...)
Definition: polytest.cpp:61
PORT_STATUS_CHANGE * PortStatusChange
Definition: usbhub.h:114
Definition: bufpool.h:45
USB_BUS_INTERFACE_USBDI_V2 UsbDInterface
Definition: usbhub.h:119
#define USB_HUB_TAG
Definition: usbhub.h:9
void * PVOID
Definition: retypes.h:9
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
WORK_QUEUE_ITEM WorkItem
Definition: usbhub.h:38
struct _WORK_ITEM_DATA * PWORK_ITEM_DATA
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
#define IRP_MN_QUERY_STOP_DEVICE
USB_BUS_INTERFACE_HUB_V5 HubInterface
Definition: usbhub.h:118
WCHAR NodeName[ANYSIZE_ARRAY]
Definition: usbioctl.h:310
struct _URB_HEADER UrbHeader
Definition: usb.h:531
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
NTSTATUS GetPortStatusAndChange(IN PDEVICE_OBJECT RootHubDeviceObject, IN ULONG PortId, OUT PPORT_STATUS_CHANGE StatusChange)
Definition: fdo.c:36
NTSTATUS USBHUB_FdoHandlePnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fdo.c:2029
const KSDEVICE_DESCRIPTOR DeviceDescriptor
Definition: splitter.c:257
PDEVICE_OBJECT RootHubFunctionalDeviceObject
Definition: usbhub.h:107
UCHAR bNumConfigurations
Definition: usb100.h:124
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
PUSB_INTERFACE_DESCRIPTOR NTAPI USBD_ParseConfigurationDescriptorEx(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PVOID StartPosition, LONG InterfaceNumber, LONG AlternateSetting, LONG InterfaceClass, LONG InterfaceSubClass, LONG InterfaceProtocol)
Definition: usbd.c:496
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define USB_MAXCHILDREN
Definition: usbhub.h:10
UCHAR bNumberOfPorts
Definition: usb100.h:173
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 RESTORE_PREVIOUS_PNP_STATE(_Data_)
Definition: fbtusb.h:115
PDEVICE_OBJECT ChildDeviceObject[USB_MAXCHILDREN]
Definition: usbhub.h:105
UNICODE_STRING usCompatibleIds
Definition: usbhub.h:90
PDEVICE_OBJECT RootHubPhysicalDeviceObject
Definition: usbhub.h:106
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define IRP_MN_START_DEVICE
struct _USB_NODE_CONNECTION_NAME * PUSB_NODE_CONNECTION_NAME
static const UCHAR Index[8]
Definition: usbohci.c:18
#define IOCTL_INTERNAL_USB_GET_HUB_COUNT
Definition: usbioctl.h:50
COMMON_DEVICE_EXTENSION Common
Definition: usbhub.h:83
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2866
NTSTATUS GetUsbDeviceDescriptor(IN PDEVICE_OBJECT ChildDeviceObject, IN UCHAR DescriptorType, IN UCHAR Index, IN USHORT LangId, OUT PVOID TransferBuffer, IN ULONG TransferBufferLength)
Definition: fdo.c:590
PUSB_DEVICE_HANDLE UsbDeviceHandle
Definition: usbhub.h:85
#define IRP_MN_QUERY_INTERFACE
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
USB_DEVICE_SPEED DeviceSpeed
Definition: hubbusif.h:698
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define USB_PORT_STATUS_CONNECT
Definition: usb200.h:151
PDEVICE_OBJECT ParentDeviceObject
Definition: usbhub.h:84
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define PORT_POWER
Definition: usbhub.h:20
NTSTATUS CreateUsbChildDeviceObject(IN PDEVICE_OBJECT UsbHubDeviceObject, IN LONG PortId, OUT PDEVICE_OBJECT *UsbChildDeviceObject, IN ULONG PortStatus)
Definition: fdo.c:1137
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define USB_REQUEST_GET_DESCRIPTOR
Definition: usb100.h:82
_In_opt_ PVPB _In_ PDEVICE_OBJECT RealDeviceObject
Definition: iofuncs.h:1499
#define IRP_MN_QUERY_BUS_INFORMATION
unsigned char UCHAR
Definition: xmlstorage.h:181
#define C_PORT_ENABLE
Definition: usbhub.h:23
#define IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO
Definition: usbioctl.h:38
static const WCHAR L[]
Definition: oid.c:1250
NTSTATUS QueryStatusChangeEndpoint(IN PDEVICE_OBJECT DeviceObject)
Definition: fdo.c:440
PUSB_BUSIFFN_GET_DEVICE_INFORMATION QueryDeviceInformation
Definition: hubbusif.h:547
NTSTATUS NTAPI ForwardIrpAndForget(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fdo.c:66
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define USB_ENDPOINT_DESCRIPTOR_TYPE
Definition: usb100.h:53
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
static const WCHAR Cleanup[]
Definition: register.c:80
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
_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
Status
Definition: gdiplustypes.h:24
USB_DEVICE_INFORMATION_0 DeviceInformation
Definition: usbhub.h:128
USBD_PIPE_HANDLE PipeHandle
Definition: usbhub.h:131
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
PUSB_BUSIFFN_ROOTHUB_INIT_NOTIFY RootHubInitNotification
Definition: hubbusif.h:554
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
USB_CONFIGURATION_DESCRIPTOR HubConfigDescriptor
Definition: usbhub.h:123
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1250
#define USBD_SHORT_TRANSFER_OK
Definition: usb.h:154
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:5090
struct _DEVICE_RELATIONS DEVICE_RELATIONS
struct _URB_SELECT_CONFIGURATION UrbSelectConfiguration
Definition: usb.h:533
ULONG IsCompositeDevice(IN PUSB_DEVICE_DESCRIPTOR DeviceDescriptor, IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
Definition: fdo.c:769
#define USB_REQUEST_GET_STATUS
Definition: usb100.h:78
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
COMMON_DEVICE_EXTENSION Common
Definition: usbhub.h:102
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
Definition: usbdlib.h:8
Definition: usb.h:529
PUSB_BUSIFFN_INITIALIZE_20HUB Initialize20Hub
Definition: hubbusif.h:553
USB_INTERFACE_DESCRIPTOR HubInterfaceDescriptor
Definition: usbhub.h:124
unsigned short USHORT
Definition: pedump.c:61
#define IoSizeOfIrp(_StackSize)
NTSTATUS USBHUB_FdoHandleDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fdo.c:2280
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
PUSB_BUSIFFN_CREATE_USB_DEVICE CreateUsbDevice
Definition: hubbusif.h:541
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define URB_FUNCTION_GET_STATUS_FROM_DEVICE
Definition: usb.h:105
#define IRP_MN_QUERY_DEVICE_RELATIONS
PUSB_BUSIFFN_INITIALIZE_USB_DEVICE InitializeUsbDevice
Definition: hubbusif.h:542
USB_DEVICE_INFORMATION_0 DeviceInformation
Definition: usbhub.h:97
PVOID Context
Definition: usbhub.h:39
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
USB_HUB_INFORMATION HubInformation
Definition: usbioctl.h:235
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
#define INITIALIZE_PNP_STATE(_Data_)
Definition: fbtusb.h:107
#define SET_NEW_PNP_STATE(_Data_, _state_)
Definition: fbtusb.h:111
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI RootHubInitCallbackFunction(PVOID Context)
Definition: fdo.c:1494
#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
USBD_CONFIGURATION_HANDLE ConfigurationHandle
Definition: usbhub.h:130
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
NTSTATUS ClearPortFeature(IN PDEVICE_OBJECT RootHubDeviceObject, IN ULONG PortId, IN ULONG Feature)
Definition: fdo.c:149
#define ULONG_PTR
Definition: config.h:101
char * cleanup(char *str)
Definition: wpickclick.c:99
#define USB_BUSIF_HUB_VERSION_5
Definition: hubbusif.h:426
#define IoReleaseRemoveLockAndWait(_RemoveLock, _Tag)
Definition: iofuncs.h:2726
struct _USB_NODE_INFORMATION USB_NODE_INFORMATION
DEVICE_PNP_STATE PnPState
Definition: usbhub.h:75
struct _URB_CONTROL_DESCRIPTOR_REQUEST UrbControlDescriptorRequest
Definition: usb.h:545
PUSB_BUSIFFN_GET_USB_DESCRIPTORS GetUsbDescriptors
Definition: hubbusif.h:543
WCHAR * LPWSTR
Definition: xmlstorage.h:184
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
#define UsbBuildInterruptOrBulkTransferRequest(urb, length, pipeHandle, transferBuffer, transferBufferMDL, transferBufferLength, transferFlags, link)
Definition: usbdlib.h:12
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
PURB NTAPI USBD_CreateConfigurationRequestEx(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PUSBD_INTERFACE_LIST_ENTRY InterfaceList)
Definition: usbd.c:329
return STATUS_SUCCESS
Definition: btrfs.c:2777
_In_ ULONG _In_ PVOID _In_ LONG DescriptorType
Definition: usbdlib.h:145
USB_EXTHUB_INFORMATION_0 UsbExtHubInfo
Definition: usbhub.h:127
#define URB_FUNCTION_CLASS_OTHER
Definition: usb.h:117
#define IoAcquireRemoveLock(RemoveLock, Tag)
USB_CONNECTION_STATUS ConnectionStatus
Definition: usbioctl.h:297
#define CONST
Definition: pedump.c:81
UNICODE_STRING usInstanceId
Definition: usbhub.h:88
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
USB_HUB_NODE NodeType
Definition: usbioctl.h:233
PUSB_BUSIFFN_GET_EXTENDED_HUB_INFO GetExtendedHubInformation
Definition: hubbusif.h:550
#define IOCTL_USB_GET_NODE_INFORMATION
Definition: usbioctl.h:169
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
#define IRP_MN_QUERY_CAPABILITIES
NTSTATUS SetPortFeature(IN PDEVICE_OBJECT RootHubDeviceObject, IN ULONG PortId, IN ULONG Feature)
Definition: fdo.c:93
UNICODE_STRING usDeviceId
Definition: usbhub.h:87
UCHAR bDescriptorType
Definition: usb100.h:172
NTSTATUS SubmitRequestToRootHub(IN PDEVICE_OBJECT RootHubDeviceObject, IN ULONG IoControlCode, OUT PVOID OutParameter1, OUT PVOID OutParameter2)
Definition: misc.c:150
#define USB_ENDPOINT_TYPE_INTERRUPT
Definition: usb100.h:65