2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: USB hub driver
4 * FILE: drivers/usb/cromwell/hub/fdo.c
5 * PURPOSE: IRP_MJ_PNP operations for FDOs
7 * PROGRAMMERS: Herv� Poussineau (hpoussin@reactos.com)
8 * Michael Martin (michael.martin@reactos.org)
17 #define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
19 typedef struct _PORTSTATUSANDCHANGE
23 } PORTSTATUSANDCHANGE
, *PPORTSTATUSANDCHANGE
;
26 QueryRootHub(IN PDEVICE_OBJECT Pdo
, IN ULONG IoControlCode
, OUT PVOID OutParameter1
, OUT PVOID OutParameter2
);
28 WaitForUsbDeviceArrivalNotification(PDEVICE_OBJECT DeviceObject
);
30 SubmitUrbToRootHub(IN PDEVICE_OBJECT Pdo
, IN ULONG IoControlCode
, IN PURB Urb
);
32 VOID
DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor
)
34 DPRINT1("Dumping Device Descriptor %x\n", DeviceDescriptor
);
35 DPRINT1("bLength %x\n", DeviceDescriptor
->bLength
);
36 DPRINT1("bDescriptorType %x\n", DeviceDescriptor
->bDescriptorType
);
37 DPRINT1("bcdUSB %x\n", DeviceDescriptor
->bcdUSB
);
38 DPRINT1("bDeviceClass %x\n", DeviceDescriptor
->bDeviceClass
);
39 DPRINT1("bDeviceSubClass %x\n", DeviceDescriptor
->bDeviceSubClass
);
40 DPRINT1("bDeviceProtocol %x\n", DeviceDescriptor
->bDeviceProtocol
);
41 DPRINT1("bMaxPacketSize0 %x\n", DeviceDescriptor
->bMaxPacketSize0
);
42 DPRINT1("idVendor %x\n", DeviceDescriptor
->idVendor
);
43 DPRINT1("idProduct %x\n", DeviceDescriptor
->idProduct
);
44 DPRINT1("bcdDevice %x\n", DeviceDescriptor
->bcdDevice
);
45 DPRINT1("iManufacturer %x\n", DeviceDescriptor
->iManufacturer
);
46 DPRINT1("iProduct %x\n", DeviceDescriptor
->iProduct
);
47 DPRINT1("iSerialNumber %x\n", DeviceDescriptor
->iSerialNumber
);
48 DPRINT1("bNumConfigurations %x\n", DeviceDescriptor
->bNumConfigurations
);
51 VOID
DumpFullConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
)
53 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
54 PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
57 DPRINT1("Duming ConfigurationDescriptor %x\n", ConfigurationDescriptor
);
58 DPRINT1("bLength %x\n", ConfigurationDescriptor
->bLength
);
59 DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor
->bDescriptorType
);
60 DPRINT1("wTotalLength %x\n", ConfigurationDescriptor
->wTotalLength
);
61 DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor
->bNumInterfaces
);
62 DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor
->bConfigurationValue
);
63 DPRINT1("iConfiguration %x\n", ConfigurationDescriptor
->iConfiguration
);
64 DPRINT1("bmAttributes %x\n", ConfigurationDescriptor
->bmAttributes
);
65 DPRINT1("MaxPower %x\n", ConfigurationDescriptor
->MaxPower
);
67 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
) ((ULONG_PTR
)ConfigurationDescriptor
+ sizeof(USB_CONFIGURATION_DESCRIPTOR
));
69 for (i
=0; i
< ConfigurationDescriptor
->bNumInterfaces
; i
++)
71 DPRINT1("- Dumping InterfaceDescriptor %x\n", InterfaceDescriptor
);
72 DPRINT1(" bLength %x\n", InterfaceDescriptor
->bLength
);
73 DPRINT1(" bDescriptorType %x\n", InterfaceDescriptor
->bDescriptorType
);
74 DPRINT1(" bInterfaceNumber %x\n", InterfaceDescriptor
->bInterfaceNumber
);
75 DPRINT1(" bAlternateSetting %x\n", InterfaceDescriptor
->bAlternateSetting
);
76 DPRINT1(" bNumEndpoints %x\n", InterfaceDescriptor
->bNumEndpoints
);
77 DPRINT1(" bInterfaceClass %x\n", InterfaceDescriptor
->bInterfaceClass
);
78 DPRINT1(" bInterfaceSubClass %x\n", InterfaceDescriptor
->bInterfaceSubClass
);
79 DPRINT1(" bInterfaceProtocol %x\n", InterfaceDescriptor
->bInterfaceProtocol
);
80 DPRINT1(" iInterface %x\n", InterfaceDescriptor
->iInterface
);
82 EndpointDescriptor
= (PUSB_ENDPOINT_DESCRIPTOR
) ((ULONG_PTR
)InterfaceDescriptor
+ sizeof(USB_INTERFACE_DESCRIPTOR
));
84 for (j
=0; j
< InterfaceDescriptor
->bNumEndpoints
; j
++)
86 DPRINT1(" bLength %x\n", EndpointDescriptor
->bLength
);
87 DPRINT1(" bDescriptorType %x\n", EndpointDescriptor
->bDescriptorType
);
88 DPRINT1(" bEndpointAddress %x\n", EndpointDescriptor
->bEndpointAddress
);
89 DPRINT1(" bmAttributes %x\n", EndpointDescriptor
->bmAttributes
);
90 DPRINT1(" wMaxPacketSize %x\n", EndpointDescriptor
->wMaxPacketSize
);
91 DPRINT1(" bInterval %x\n", EndpointDescriptor
->bInterval
);
92 EndpointDescriptor
= (PUSB_ENDPOINT_DESCRIPTOR
) ((ULONG_PTR
)EndpointDescriptor
+ sizeof(USB_ENDPOINT_DESCRIPTOR
));
94 InterfaceDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)(ULONG_PTR
)EndpointDescriptor
;
99 VOID
DumpInterfaceInfo(PUSBD_INTERFACE_INFORMATION InterfaceInformation
)
101 PUSBD_PIPE_INFORMATION PipeInformation
;
104 DPRINT1("IntefaceLenth %x\n",InterfaceInformation
->Length
);
105 DPRINT1("InterfaceNumber %x\n",InterfaceInformation
->InterfaceNumber
);
106 DPRINT1("AlternateSetting %x\n",InterfaceInformation
->AlternateSetting
);
107 DPRINT1("Class %x\n",InterfaceInformation
->Class
);
108 DPRINT1("SubClass %x\n",InterfaceInformation
->SubClass
);
109 DPRINT1("Protocol %x\n",InterfaceInformation
->Protocol
);
110 DPRINT1("Reserved %x\n",InterfaceInformation
->Reserved
);
111 DPRINT1("InterfaceHandle %x\n",InterfaceInformation
->InterfaceHandle
);
112 DPRINT1("NumberOfPipes %x\n", InterfaceInformation
->NumberOfPipes
);
114 PipeInformation
= &InterfaceInformation
->Pipes
[0];
116 for (i
= 0; i
< InterfaceInformation
->NumberOfPipes
; i
++)
119 DPRINT1("MaximumPacketSize %x\n", PipeInformation
->MaximumPacketSize
);
120 DPRINT1("EndpointAddress %x\n", PipeInformation
->EndpointAddress
);
121 DPRINT1("Interval %x\n", PipeInformation
->Interval
);
122 DPRINT1("PipeType %x\n", PipeInformation
->PipeType
);
123 DPRINT1("PipeHandle %x\n", PipeInformation
->PipeHandle
);
124 DPRINT1("PipeFlags %x\n", PipeInformation
->PipeFlags
);
125 DPRINT1("MaximumTransferSize %x\n", PipeInformation
->MaximumTransferSize
);
126 PipeInformation
= (PUSBD_PIPE_INFORMATION
)((ULONG_PTR
)PipeInformation
+ sizeof(USBD_PIPE_INFORMATION
));
132 WorkerThread(IN PVOID Context
)
134 PHUB_DEVICE_EXTENSION DeviceExtension
;
135 PDEVICE_OBJECT DeviceObject
, Pdo
;
136 PHUB_CHILDDEVICE_EXTENSION PdoExtension
;
138 PORTSTATUSANDCHANGE PortStatusAndChange
;
139 int PortLoop
, DeviceCount
;
141 USB_DEVICE_DESCRIPTOR DevDesc
;
142 USB_CONFIGURATION_DESCRIPTOR ConfigDesc
;
143 ULONG DevDescSize
, ConfigDescSize
;
144 PUSB_STRING_DESCRIPTOR StringDesc
;
145 USB_STRING_DESCRIPTOR LanguageIdDescriptor
;
146 PWORKITEMDATA WorkItemData
= (PWORKITEMDATA
)Context
;
148 DeviceObject
= (PDEVICE_OBJECT
)WorkItemData
->Context
;
150 DeviceExtension
= (PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
152 /* Determine where in the children array to store this device info */
153 for (DeviceCount
= 0; DeviceCount
< USB_MAXCHILDREN
; DeviceCount
++)
155 if (DeviceExtension
->UsbChildren
[DeviceCount
] == NULL
)
161 Urb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(URB
), USB_HUB_TAG
);
164 DPRINT1("Failed to allocate memory for URB!\n");
168 RtlZeroMemory(Urb
, sizeof(URB
));
170 for (PortLoop
= 0; PortLoop
< DeviceExtension
->UsbExtHubInfo
.NumberOfPorts
; PortLoop
++)
172 /* Get the port status */
173 UsbBuildVendorRequest(Urb
,
174 URB_FUNCTION_CLASS_OTHER
,
175 sizeof(Urb
->UrbControlVendorClassRequest
),
176 USBD_TRANSFER_DIRECTION_OUT
,
178 USB_REQUEST_GET_STATUS
,
181 &PortStatusAndChange
,
183 sizeof(PORTSTATUSANDCHANGE
),
186 Status
= QueryRootHub(DeviceExtension
->RootHubPdo
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
187 if (!NT_SUCCESS(Status
))
189 DPRINT1("Failed to get PortStatus!\n");
193 DPRINT("Notification Port %x:\n", PortLoop
+ 1);
194 DPRINT("Status %x\n", PortStatusAndChange
.Status
);
195 DPRINT("Change %x\n", PortStatusAndChange
.Change
);
197 if (PortStatusAndChange
.Change
== USB_PORT_STATUS_RESET
)
199 /* Clear the Reset */
200 UsbBuildVendorRequest(Urb
,
201 URB_FUNCTION_CLASS_OTHER
,
202 sizeof(Urb
->UrbControlVendorClassRequest
),
203 USBD_TRANSFER_DIRECTION_IN
,
205 USB_REQUEST_CLEAR_FEATURE
,
208 &PortStatusAndChange
,
210 sizeof(PORTSTATUSANDCHANGE
),
213 Status
= QueryRootHub(DeviceExtension
->RootHubPdo
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
214 if (!NT_SUCCESS(Status
))
216 DPRINT1("Failed to Clear the Port Reset with Status %x!\n", Status
);
220 UsbBuildVendorRequest(Urb
, URB_FUNCTION_CLASS_OTHER
,
221 sizeof(Urb
->UrbControlVendorClassRequest
),
222 USBD_TRANSFER_DIRECTION_OUT
,
224 USB_REQUEST_GET_STATUS
,
227 &PortStatusAndChange
,
229 sizeof(PORTSTATUSANDCHANGE
),
232 Status
= QueryRootHub(DeviceExtension
->RootHubPdo
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
234 DPRINT("Status %x\n", PortStatusAndChange
.Status
);
235 DPRINT("Change %x\n", PortStatusAndChange
.Change
);
237 /* Create the UsbDevice */
238 Status
= DeviceExtension
->HubInterface
.CreateUsbDevice(DeviceExtension
->RootHubPdo
,
239 (PVOID
)&DeviceExtension
->UsbChildren
[DeviceCount
],
240 DeviceExtension
->RootHubUsbDevice
,
241 PortStatusAndChange
.Status
,
243 DPRINT1("CreateUsbDevice Status %x\n", Status
);
245 Status
= DeviceExtension
->HubInterface
.InitializeUsbDevice(DeviceExtension
->RootHubPdo
, DeviceExtension
->UsbChildren
[DeviceCount
]);
246 DPRINT1("InitializeUsbDevice Status %x\n", Status
);
248 DevDescSize
= sizeof(USB_DEVICE_DESCRIPTOR
);
249 ConfigDescSize
= sizeof(USB_CONFIGURATION_DESCRIPTOR
);
250 Status
= DeviceExtension
->HubInterface
.GetUsbDescriptors(DeviceExtension
->RootHubPdo
,
251 DeviceExtension
->UsbChildren
[DeviceCount
],
256 if (!NT_SUCCESS(Status
))
258 DPRINT1("Failed to Get Usb Deccriptors %x!\n", Status
);
261 DumpDeviceDescriptor(&DevDesc
);
263 Status
= IoCreateDevice(DeviceObject
->DriverObject
,
264 sizeof(HUB_CHILDDEVICE_EXTENSION
),
266 FILE_DEVICE_CONTROLLER
,
267 FILE_AUTOGENERATED_DEVICE_NAME
,
269 &DeviceExtension
->Children
[DeviceCount
]);
271 if (!NT_SUCCESS(Status
))
273 DPRINT1("UsbHub; IoCreateDevice failed with status %x\n",Status
);
277 Pdo
= DeviceExtension
->Children
[DeviceCount
];
278 DPRINT1("Created New Device with %x\n", Pdo
);
279 Pdo
->Flags
|= DO_BUS_ENUMERATED_DEVICE
;
281 PdoExtension
= Pdo
->DeviceExtension
;
283 RtlZeroMemory(PdoExtension
, sizeof(HUB_CHILDDEVICE_EXTENSION
));
285 PdoExtension
->DeviceId
= ExAllocatePoolWithTag(NonPagedPool
, 32 * sizeof(WCHAR
), USB_HUB_TAG
);
286 RtlZeroMemory(PdoExtension
->DeviceId
, 32 * sizeof(WCHAR
));
287 swprintf(PdoExtension
->DeviceId
, L
"USB\\Vid_%04x&Pid_%04x", DevDesc
.idVendor
, DevDesc
.idProduct
);
290 /* Get the LANGids */
291 RtlZeroMemory(&LanguageIdDescriptor
, sizeof(USB_STRING_DESCRIPTOR
));
292 UsbBuildGetDescriptorRequest(Urb
,
293 sizeof(Urb
->UrbControlDescriptorRequest
),
294 USB_STRING_DESCRIPTOR_TYPE
,
297 &LanguageIdDescriptor
,
299 sizeof(USB_STRING_DESCRIPTOR
),
302 Urb
->UrbHeader
.UsbdDeviceHandle
= DeviceExtension
->UsbChildren
[DeviceCount
];
303 Status
= QueryRootHub(DeviceExtension
->RootHubPdo
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
305 /* Get the length of the SerialNumber */
306 StringDesc
= ExAllocatePoolWithTag(PagedPool
, 64, USB_HUB_TAG
);
307 RtlZeroMemory(StringDesc
, 64);
308 StringDesc
->bLength
= 0;
309 StringDesc
->bDescriptorType
= 0;
311 UsbBuildGetDescriptorRequest(Urb
,
312 sizeof(Urb
->UrbControlDescriptorRequest
),
313 USB_STRING_DESCRIPTOR_TYPE
,
314 DevDesc
.iSerialNumber
,
315 LanguageIdDescriptor
.bString
[0],
321 Urb
->UrbHeader
.UsbdDeviceHandle
= DeviceExtension
->UsbChildren
[DeviceCount
];
323 Status
= QueryRootHub(DeviceExtension
->RootHubPdo
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
325 PdoExtension
->InstanceId
= ExAllocatePoolWithTag(NonPagedPool
, (StringDesc
->bLength
+ 1) * sizeof(WCHAR
), USB_HUB_TAG
);
326 DPRINT1("PdoExtension->InstanceId %x\n",PdoExtension
->InstanceId
);
328 RtlZeroMemory(PdoExtension
->InstanceId
, (StringDesc
->bLength
+ 1) * sizeof(WCHAR
));
329 RtlCopyMemory(PdoExtension
->InstanceId
, &StringDesc
->bString
[0], StringDesc
->bLength
);
330 DPRINT1("------>SerialNumber %S\n", PdoExtension
->InstanceId
);
334 RtlZeroMemory(StringDesc
, 64);
335 StringDesc
->bLength
= 0;
336 StringDesc
->bDescriptorType
= 0;
338 UsbBuildGetDescriptorRequest(Urb
,
339 sizeof(Urb
->UrbControlDescriptorRequest
),
340 USB_STRING_DESCRIPTOR_TYPE
,
342 LanguageIdDescriptor
.bString
[0],
348 Urb
->UrbHeader
.UsbdDeviceHandle
= DeviceExtension
->UsbChildren
[DeviceCount
];
350 Status
= QueryRootHub(DeviceExtension
->RootHubPdo
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
352 PdoExtension
->TextDescription
= ExAllocatePoolWithTag(NonPagedPool
, (StringDesc
->bLength
+ 1) * sizeof(WCHAR
), USB_HUB_TAG
);
354 RtlZeroMemory(PdoExtension
->TextDescription
, (StringDesc
->bLength
+ 1) * sizeof(WCHAR
));
355 RtlCopyMemory(PdoExtension
->TextDescription
, &StringDesc
->bString
[0], StringDesc
->bLength
);
356 ExFreePool(StringDesc
);
357 DPRINT1("------>TextDescription %S\n", PdoExtension
->TextDescription
);
359 PdoExtension
->IsFDO
= FALSE
;
360 PdoExtension
->Parent
= DeviceObject
;
361 Pdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
363 ExFreePool(WorkItemData
);
366 IoInvalidateDeviceRelations(DeviceExtension
->RootHubPdo
, BusRelations
);
370 /* Is a device connected to this port */
371 if (PortStatusAndChange
.Change
== USB_PORT_STATUS_CONNECT
)
373 /* Clear the Connect from ProtChange */
374 UsbBuildVendorRequest(Urb
,
375 URB_FUNCTION_CLASS_OTHER
,
376 sizeof(Urb
->UrbControlVendorClassRequest
),
377 USBD_TRANSFER_DIRECTION_IN
,
379 USB_REQUEST_CLEAR_FEATURE
,
382 &PortStatusAndChange
,
384 sizeof(PORTSTATUSANDCHANGE
),
387 Status
= QueryRootHub(DeviceExtension
->RootHubPdo
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
388 if (!NT_SUCCESS(Status
))
390 DPRINT1("Failed to Clear the Port Connect!\n");
394 /* Send the miniport controller a SCE request so when the port resets we can be informed */
395 WaitForUsbDeviceArrivalNotification(DeviceObject
);
397 UsbBuildVendorRequest(Urb
,
398 URB_FUNCTION_CLASS_OTHER
,
399 sizeof(Urb
->UrbControlVendorClassRequest
),
400 USBD_TRANSFER_DIRECTION_IN
,
402 USB_REQUEST_SET_FEATURE
,
405 &PortStatusAndChange
,
407 sizeof(PORTSTATUSANDCHANGE
),
410 Status
= QueryRootHub(DeviceExtension
->RootHubPdo
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
412 if (!NT_SUCCESS(Status
))
414 DPRINT1("Failed to Reset the port!\n");
417 /* At this point the miniport will complete another SCE to inform of Reset completed */
422 ExFreePool(WorkItemData
);
427 DeviceArrivalCompletion(PDEVICE_OBJECT DeviceObject
, PIRP Irp
, PVOID Context
)
429 PHUB_DEVICE_EXTENSION DeviceExtension
;
431 PWORKITEMDATA WorkItemData
;
433 DeviceExtension
= (PHUB_DEVICE_EXTENSION
)((PDEVICE_OBJECT
)Context
)->DeviceExtension
;
435 for (i
=0; i
< DeviceExtension
->UsbExtHubInfo
.NumberOfPorts
; i
++)
436 DPRINT1("Port %x DeviceExtension->PortStatus %x\n",i
+1, DeviceExtension
->PortStatus
[i
]);
440 WorkItemData
= ExAllocatePool(NonPagedPool
, sizeof(WORKITEMDATA
));
443 DPRINT1("Failed to allocate memory\n");
444 return STATUS_NO_MEMORY
;
448 RtlZeroMemory(WorkItemData
, sizeof(WORKITEMDATA
));
449 WorkItemData
->Context
= Context
;
451 ExInitializeWorkItem(&WorkItemData
->WorkItem
, (PWORKER_THREAD_ROUTINE
)WorkerThread
, (PVOID
)WorkItemData
);
452 ExQueueWorkItem(&WorkItemData
->WorkItem
, DelayedWorkQueue
);
453 return STATUS_MORE_PROCESSING_REQUIRED
;
458 WaitForUsbDeviceArrivalNotification(PDEVICE_OBJECT DeviceObject
)
463 PIO_STACK_LOCATION Stack
= NULL
;
464 PHUB_DEVICE_EXTENSION DeviceExtension
;
466 DeviceExtension
= (PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
468 Urb
= &DeviceExtension
->Urb
;
470 RtlZeroMemory(Urb
, sizeof(URB
));
472 /* Send URB to the miniports Status Change Endpoint SCE */
473 UsbBuildInterruptOrBulkTransferRequest(Urb
,
474 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
),
475 DeviceExtension
->PipeHandle
,
476 &DeviceExtension
->PortStatus
,
479 USBD_TRANSFER_DIRECTION_IN
| USBD_SHORT_TRANSFER_OK
,
482 Urb
->UrbHeader
.UsbdDeviceHandle
= DeviceExtension
->RootHubUsbDevice
;
484 Irp
= IoAllocateIrp(DeviceExtension
->RootHubPdo
->StackSize
, FALSE
);
488 DPRINT("Usbhub: IoBuildDeviceIoControlRequest() failed\n");
489 return STATUS_INSUFFICIENT_RESOURCES
;
493 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
494 Irp
->IoStatus
.Information
= 0;
496 Irp
->UserBuffer
= NULL
;
498 Stack
= IoGetCurrentIrpStackLocation(Irp
);
499 Stack
->DeviceObject
= DeviceExtension
->RootHubPdo
;
501 Stack
= IoGetNextIrpStackLocation(Irp
);
502 Stack
->DeviceObject
= DeviceExtension
->RootHubPdo
;
503 Stack
->Parameters
.Others
.Argument1
= Urb
;
504 Stack
->Parameters
.Others
.Argument2
= NULL
;
505 Stack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
506 Stack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_URB
;
508 //IoSetCompletionRoutineEx(DeviceExtension->RootHubPdo, Irp, (PIO_COMPLETION_ROUTINE)DeviceArrivalCompletion, DeviceObject, TRUE, TRUE, TRUE);
509 IoSetCompletionRoutine(Irp
, (PIO_COMPLETION_ROUTINE
)DeviceArrivalCompletion
, DeviceObject
, TRUE
, TRUE
, TRUE
);
511 Status
= IoCallDriver(DeviceExtension
->RootHubPdo
, Irp
);
512 DPRINT1("SCE request status %x\n", Status
);
514 return STATUS_PENDING
;
518 SubmitUrbToRootHub(IN PDEVICE_OBJECT Pdo
, IN ULONG IoControlCode
, IN PURB Urb
)
521 IO_STATUS_BLOCK IoStatus
;
523 PIO_STACK_LOCATION Stack
= NULL
;
525 Irp
= IoBuildDeviceIoControlRequest(IoControlCode
,
535 DPRINT("Usbhub: IoBuildDeviceIoControlRequest() failed\n");
536 return STATUS_INSUFFICIENT_RESOURCES
;
539 /* Initialize the status block before sending the IRP */
540 IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
541 IoStatus
.Information
= 0;
543 Stack
= IoGetNextIrpStackLocation(Irp
);
545 Stack
->Parameters
.Others
.Argument1
= Urb
;
546 Stack
->Parameters
.Others
.Argument2
= NULL
;
548 Status
= IoCallDriver(Pdo
, Irp
);
554 QueryRootHub(IN PDEVICE_OBJECT Pdo
, IN ULONG IoControlCode
, OUT PVOID OutParameter1
, OUT PVOID OutParameter2
)
558 IO_STATUS_BLOCK IoStatus
;
560 PIO_STACK_LOCATION Stack
= NULL
;
562 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
564 Irp
= IoBuildDeviceIoControlRequest(IoControlCode
,
574 DPRINT("Usbhub: IoBuildDeviceIoControlRequest() failed\n");
575 return STATUS_INSUFFICIENT_RESOURCES
;
578 /* Initialize the status block before sending the IRP */
579 IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
580 IoStatus
.Information
= 0;
582 Stack
= IoGetNextIrpStackLocation(Irp
);
584 Stack
->Parameters
.Others
.Argument1
= OutParameter1
;
585 Stack
->Parameters
.Others
.Argument2
= OutParameter2
;
587 Status
= IoCallDriver(Pdo
, Irp
);
589 if (Status
== STATUS_PENDING
)
591 DPRINT1("Usbhub: Operation pending\n");
592 KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
593 Status
= IoStatus
.Status
;
599 NTSTATUS
QueryInterface(IN PDEVICE_OBJECT Pdo
, IN CONST GUID InterfaceType
, IN LONG Size
, IN LONG Version
, OUT PVOID Interface
)
603 IO_STATUS_BLOCK IoStatus
;
605 PIO_STACK_LOCATION Stack
= NULL
;
607 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
609 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_PNP
,
617 Stack
= IoGetNextIrpStackLocation(Irp
);
618 Stack
->MinorFunction
= IRP_MN_QUERY_INTERFACE
;
619 Stack
->Parameters
.QueryInterface
.InterfaceType
= &InterfaceType
;//USB_BUS_INTERFACE_HUB_GUID;
620 Stack
->Parameters
.QueryInterface
.Size
= Size
;
621 Stack
->Parameters
.QueryInterface
.Version
= Version
;
622 Stack
->Parameters
.QueryInterface
.Interface
= Interface
;
623 Stack
->Parameters
.QueryInterface
.InterfaceSpecificData
= NULL
;
625 Status
= IoCallDriver(Pdo
, Irp
);
627 if (Status
== STATUS_PENDING
)
629 DPRINT("Usbhub: Operation pending\n");
630 KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
631 Status
= IoStatus
.Status
;
638 UsbhubGetUserBuffers(IN PIRP Irp
, IN ULONG IoControlCode
, OUT PVOID
* BufferIn
, OUT PVOID
* BufferOut
)
644 switch (IO_METHOD_FROM_CTL_CODE(IoControlCode
))
646 case METHOD_BUFFERED
:
647 *BufferIn
= *BufferOut
= Irp
->AssociatedIrp
.SystemBuffer
;
649 case METHOD_IN_DIRECT
:
650 case METHOD_OUT_DIRECT
:
651 *BufferIn
= Irp
->AssociatedIrp
.SystemBuffer
;
652 *BufferOut
= MmGetSystemAddressForMdl(Irp
->MdlAddress
);
655 *BufferIn
= IoGetCurrentIrpStackLocation(Irp
)->Parameters
.DeviceIoControl
.Type3InputBuffer
;
656 *BufferOut
= Irp
->UserBuffer
;
659 /* Should never happen */
667 UsbhubFdoQueryBusRelations(IN PDEVICE_OBJECT DeviceObject
, OUT PDEVICE_RELATIONS
* pDeviceRelations
)
669 PHUB_DEVICE_EXTENSION DeviceExtension
;
670 PDEVICE_RELATIONS DeviceRelations
;
675 DeviceExtension
= (PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
676 DPRINT1("USBHUB: Query Bus Relations\n");
678 /* Create PDOs that are missing */
679 for (i
= 0; i
< USB_MAXCHILDREN
; i
++)
682 if (DeviceExtension
->UsbChildren
[i
] == NULL
)
689 /* Fill returned structure */
690 NeededSize
= sizeof(DEVICE_RELATIONS
);
692 NeededSize
+= (Children
- 1) * sizeof(PDEVICE_OBJECT
);
694 DeviceRelations
= (PDEVICE_RELATIONS
)ExAllocatePool(PagedPool
,
697 if (!DeviceRelations
)
698 return STATUS_INSUFFICIENT_RESOURCES
;
699 DeviceRelations
->Count
= Children
;
702 for (i
= 0; i
< USB_MAXCHILDREN
; i
++)
704 if (DeviceExtension
->Children
[i
])
706 ObReferenceObject(DeviceExtension
->Children
[i
]);
707 DeviceRelations
->Objects
[Children
++] = DeviceExtension
->Children
[i
];
711 ASSERT(Children
== DeviceRelations
->Count
);
712 *pDeviceRelations
= DeviceRelations
;
714 WaitForUsbDeviceArrivalNotification(DeviceObject
);
716 return STATUS_SUCCESS
;
719 VOID
CallBackRoutine(IN PVOID Argument1
)
721 DPRINT1("RH_INIT_CALLBACK %x\n", Argument1
);
726 UsbhubPnpFdo(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
)
728 PIO_STACK_LOCATION IrpSp
;
729 NTSTATUS Status
= STATUS_SUCCESS
;
731 ULONG_PTR Information
= 0;
732 PHUB_DEVICE_EXTENSION DeviceExtension
;
734 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
735 MinorFunction
= IrpSp
->MinorFunction
;
737 DeviceExtension
= (PHUB_DEVICE_EXTENSION
) DeviceObject
->DeviceExtension
;
739 switch (MinorFunction
)
741 case IRP_MN_START_DEVICE
: /* 0x0 */
745 PUSB_INTERFACE_DESCRIPTOR Pid
;
746 /* Theres only one descriptor on hub */
747 USBD_INTERFACE_LIST_ENTRY InterfaceList
[2] = {{NULL
, NULL
}, {NULL
, NULL
}};
748 PURB ConfigUrb
= NULL
;
750 /* We differ from windows on hubpdo because we dont have usbport.sys which manages all usb device objects */
751 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
753 /* Allocating size including the sizeof USBD_INTERFACE_LIST_ENTRY */
754 Urb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(URB
) + sizeof(USBD_INTERFACE_LIST_ENTRY
), USB_HUB_TAG
);
755 RtlZeroMemory(Urb
, sizeof(URB
) + sizeof(USBD_INTERFACE_LIST_ENTRY
));
757 /* Get the hubs PDO */
758 QueryRootHub(DeviceExtension
->LowerDevice
, IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO
, &DeviceExtension
->RootHubPdo
, &DeviceExtension
->RootHubFdo
);
759 ASSERT(DeviceExtension
->RootHubPdo
);
760 ASSERT(DeviceExtension
->RootHubFdo
);
761 DPRINT1("RootPdo %x, RootFdo %x\n", DeviceExtension
->RootHubPdo
, DeviceExtension
->RootHubFdo
);
763 /* Send the START_DEVICE irp down to the PDO of RootHub */
764 Status
= ForwardIrpAndWait(DeviceExtension
->RootHubPdo
, Irp
);
766 if (!NT_SUCCESS(Status
))
768 DPRINT1("Failed to start the RootHub PDO\n");
772 /* Get the current number of hubs */
773 QueryRootHub(DeviceExtension
->RootHubPdo
,IOCTL_INTERNAL_USB_GET_HUB_COUNT
, &DeviceExtension
->HubCount
, NULL
);
775 /* Get the Direct Call Interfaces */
776 Status
= QueryInterface(DeviceExtension
->RootHubPdo
,
777 USB_BUS_INTERFACE_HUB_GUID
,
778 sizeof(USB_BUS_INTERFACE_HUB_V5
),
780 (PVOID
)&DeviceExtension
->HubInterface
);
781 if (!NT_SUCCESS(Status
))
783 DPRINT1("UsbhubM Failed to get HUB_GUID interface with status 0x%08lx\n", Status
);
784 return STATUS_UNSUCCESSFUL
;
787 Status
= QueryInterface(DeviceExtension
->RootHubPdo
,
788 USB_BUS_INTERFACE_USBDI_GUID
,
789 sizeof(USB_BUS_INTERFACE_USBDI_V2
),
791 (PVOID
)&DeviceExtension
->UsbDInterface
);
792 if (!NT_SUCCESS(Status
))
794 DPRINT1("UsbhubM Failed to get USBDI_GUID interface with status 0x%08lx\n", Status
);
795 return STATUS_UNSUCCESSFUL
;
798 /* Get roothub device handle */
799 Status
= QueryRootHub(DeviceExtension
->RootHubPdo
, IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE
, &DeviceExtension
->RootHubUsbDevice
, NULL
);
800 if (!NT_SUCCESS(Status
))
802 DPRINT1("Usbhub: GetRootHubDeviceHandle failed with status 0x%08lx\n", Status
);
806 Status
= DeviceExtension
->HubInterface
.QueryDeviceInformation(DeviceExtension
->RootHubPdo
,
807 DeviceExtension
->RootHubUsbDevice
,
808 &DeviceExtension
->DeviceInformation
,
809 sizeof(USB_DEVICE_INFORMATION_0
),
813 DPRINT("Status %x, Result %x\n", Status
, Result
);
814 DPRINT("InformationLevel %x\n", DeviceExtension
->DeviceInformation
.InformationLevel
);
815 DPRINT("ActualLength %x\n", DeviceExtension
->DeviceInformation
.ActualLength
);
816 DPRINT("PortNumber %x\n", DeviceExtension
->DeviceInformation
.PortNumber
);
817 DPRINT("DeviceDescriptor %x\n", DeviceExtension
->DeviceInformation
.DeviceDescriptor
);
818 DPRINT("HubAddress %x\n", DeviceExtension
->DeviceInformation
.HubAddress
);
819 DPRINT("NumberofPipes %x\n", DeviceExtension
->DeviceInformation
.NumberOfOpenPipes
);
821 /* Get roothubs device descriptor */
822 UsbBuildGetDescriptorRequest(Urb
,
823 sizeof(Urb
->UrbControlDescriptorRequest
),
824 USB_DEVICE_DESCRIPTOR_TYPE
,
827 &DeviceExtension
->HubDeviceDescriptor
,
829 sizeof(USB_DEVICE_DESCRIPTOR
),
832 Urb
->UrbHeader
.UsbdDeviceHandle
= DeviceExtension
->RootHubUsbDevice
;
834 Status
= QueryRootHub(DeviceExtension
->RootHubPdo
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
835 if (!NT_SUCCESS(Status
))
837 DPRINT1("Usbhub: Failed to get HubDeviceDescriptor!\n");
840 DumpDeviceDescriptor(&DeviceExtension
->HubDeviceDescriptor
);
842 /* Get roothubs configuration descriptor */
843 UsbBuildGetDescriptorRequest(Urb
,
844 sizeof(Urb
->UrbControlDescriptorRequest
),
845 USB_CONFIGURATION_DESCRIPTOR_TYPE
,
848 &DeviceExtension
->HubConfigDescriptor
,
850 sizeof(USB_CONFIGURATION_DESCRIPTOR
) + sizeof(USB_INTERFACE_DESCRIPTOR
) + sizeof(USB_ENDPOINT_DESCRIPTOR
),
852 Urb
->UrbHeader
.UsbdDeviceHandle
= DeviceExtension
->RootHubUsbDevice
;
854 Status
= QueryRootHub(DeviceExtension
->RootHubPdo
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
856 if (!NT_SUCCESS(Status
))
858 DPRINT1("Usbhub: Failed to get RootHub Configuration with status %x\n", Status
);
861 ASSERT(DeviceExtension
->HubConfigDescriptor
.wTotalLength
);
863 DumpFullConfigurationDescriptor(&DeviceExtension
->HubConfigDescriptor
);
864 //DPRINT1("DeviceExtension->HubConfigDescriptor.wTotalLength %x\n", DeviceExtension->HubConfigDescriptor.wTotalLength);
866 Status
= DeviceExtension
->HubInterface
.GetExtendedHubInformation(DeviceExtension
->RootHubPdo
,
867 DeviceExtension
->RootHubPdo
,
868 &DeviceExtension
->UsbExtHubInfo
,
869 sizeof(USB_EXTHUB_INFORMATION_0
),
871 if (!NT_SUCCESS(Status
))
873 DPRINT1("Usbhub: Failed to extended hub information. Unable to determine the number of ports!\n");
877 DPRINT1("DeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", DeviceExtension
->UsbExtHubInfo
.NumberOfPorts
);
879 UsbBuildVendorRequest(Urb
,
880 URB_FUNCTION_CLASS_DEVICE
,
881 sizeof(Urb
->UrbControlVendorClassRequest
),
882 USBD_TRANSFER_DIRECTION_IN
,
884 USB_DEVICE_CLASS_RESERVED
,
887 &DeviceExtension
->HubDescriptor
,
889 sizeof(USB_HUB_DESCRIPTOR
),
892 Urb
->UrbHeader
.UsbdDeviceHandle
= DeviceExtension
->RootHubUsbDevice
;
894 Status
= QueryRootHub(DeviceExtension
->RootHubPdo
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
896 DPRINT1("bDescriptorType %x\n", DeviceExtension
->HubDescriptor
.bDescriptorType
);
898 /* Select the configuration */
900 /* Get the first one */
901 Pid
= USBD_ParseConfigurationDescriptorEx(&DeviceExtension
->HubConfigDescriptor
,
902 &DeviceExtension
->HubConfigDescriptor
,
905 InterfaceList
[0].InterfaceDescriptor
= Pid
;
906 ConfigUrb
= USBD_CreateConfigurationRequestEx(&DeviceExtension
->HubConfigDescriptor
, (PUSBD_INTERFACE_LIST_ENTRY
)&InterfaceList
);
907 ASSERT(ConfigUrb
!= NULL
);
908 Status
= QueryRootHub(DeviceExtension
->RootHubPdo
, IOCTL_INTERNAL_USB_SUBMIT_URB
, ConfigUrb
, NULL
);
910 DeviceExtension
->ConfigurationHandle
= ConfigUrb
->UrbSelectConfiguration
.ConfigurationHandle
;
911 DeviceExtension
->PipeHandle
= ConfigUrb
->UrbSelectConfiguration
.Interface
.Pipes
[0].PipeHandle
;
912 DPRINT1("Configuration Handle %x\n", DeviceExtension
->ConfigurationHandle
);
914 ExFreePool(ConfigUrb
);
916 Status
= DeviceExtension
->HubInterface
.Initialize20Hub(DeviceExtension
->RootHubPdo
, DeviceExtension
->RootHubUsbDevice
, 1);
917 DPRINT1("Status %x\n", Status
);
921 USHORT PortStatusAndChange
[2];
923 for (PortLoop
=0; PortLoop
< DeviceExtension
->UsbExtHubInfo
.NumberOfPorts
; PortLoop
++)
925 DPRINT1("Port %x\n", PortLoop
);
926 UsbBuildVendorRequest(Urb
,
927 URB_FUNCTION_CLASS_OTHER
,
928 sizeof(Urb
->UrbControlVendorClassRequest
),
929 USBD_TRANSFER_DIRECTION_IN
,
931 USB_REQUEST_SET_FEATURE
,
939 Urb
->UrbOSFeatureDescriptorRequest
.MS_FeatureDescriptorIndex
= PortLoop
+ 1;
940 Status
= QueryRootHub(DeviceExtension
->RootHubPdo
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
942 DPRINT1("Status %x\n", Status
);
944 UsbBuildVendorRequest(Urb
,
945 URB_FUNCTION_CLASS_OTHER
,
946 sizeof(Urb
->UrbControlVendorClassRequest
),
947 USBD_TRANSFER_DIRECTION_OUT
,
949 USB_REQUEST_GET_STATUS
,
952 &PortStatusAndChange
,
954 sizeof(PortStatusAndChange
),
956 Status
= QueryRootHub(DeviceExtension
->RootHubPdo
, IOCTL_INTERNAL_USB_SUBMIT_URB
, Urb
, NULL
);
958 DPRINT1("Status %x\n", Status
);
959 DPRINT1("PortStatus = %x\n", PortStatusAndChange
[0]);
960 DPRINT1("PortChange = %x\n", PortStatusAndChange
[1]);
968 case IRP_MN_QUERY_DEVICE_RELATIONS
: /* (optional) 0x7 */
970 switch (IrpSp
->Parameters
.QueryDeviceRelations
.Type
)
974 PDEVICE_RELATIONS DeviceRelations
= NULL
;
975 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
977 Status
= UsbhubFdoQueryBusRelations(DeviceObject
, &DeviceRelations
);
979 Information
= (ULONG_PTR
)DeviceRelations
;
982 case RemovalRelations
:
984 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
985 return ForwardIrpAndForget(DeviceObject
, Irp
);
988 DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
989 IrpSp
->Parameters
.QueryDeviceRelations
.Type
);
990 return ForwardIrpAndForget(DeviceObject
, Irp
);
994 case IRP_MN_QUERY_BUS_INFORMATION
:
996 DPRINT1("IRP_MN_QUERY_BUS_INFORMATION\n");
999 case IRP_MN_QUERY_ID
:
1001 DPRINT1("IRP_MN_QUERY_ID\n");
1004 case IRP_MN_QUERY_CAPABILITIES
:
1006 DPRINT1("IRP_MN_QUERY_CAPABILITIES\n");
1011 DPRINT1("Usbhub: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction
);
1012 return ForwardIrpAndForget(DeviceObject
, Irp
);
1015 Irp
->IoStatus
.Information
= Information
;
1016 Irp
->IoStatus
.Status
= Status
;
1017 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1022 UsbhubDeviceControlFdo(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
)
1024 PIO_STACK_LOCATION Stack
;
1025 ULONG IoControlCode
;
1026 PHUB_DEVICE_EXTENSION DeviceExtension
;
1027 ULONG LengthIn
, LengthOut
;
1028 ULONG_PTR Information
= 0;
1029 PVOID BufferIn
, BufferOut
;
1030 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1032 Stack
= IoGetCurrentIrpStackLocation(Irp
);
1033 LengthIn
= Stack
->Parameters
.DeviceIoControl
.InputBufferLength
;
1034 LengthOut
= Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1035 DeviceExtension
= (PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1036 IoControlCode
= Stack
->Parameters
.DeviceIoControl
.IoControlCode
;
1037 UsbhubGetUserBuffers(Irp
, IoControlCode
, &BufferIn
, &BufferOut
);
1039 switch (IoControlCode
)
1041 case IOCTL_USB_GET_NODE_INFORMATION
:
1043 //PUSB_NODE_INFORMATION NodeInformation;
1045 DPRINT1("Usbhub: IOCTL_USB_GET_NODE_INFORMATION\n");
1046 if (LengthOut
< sizeof(USB_NODE_INFORMATION
))
1047 Status
= STATUS_BUFFER_TOO_SMALL
;
1048 else if (BufferOut
== NULL
)
1049 Status
= STATUS_INVALID_PARAMETER
;
1052 /*NodeInformation = (PUSB_NODE_INFORMATION)BufferOut;
1053 dev = ((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->dev;
1054 NodeInformation->NodeType = UsbHub;
1056 &NodeInformation->u.HubInformation.HubDescriptor,
1057 ((struct usb_hub *)usb_get_intfdata(to_usb_interface(&dev->actconfig->interface[0].dev)))->descriptor,
1058 sizeof(USB_HUB_DESCRIPTOR));
1059 NodeInformation->u.HubInformation.HubIsBusPowered = dev->actconfig->desc.bmAttributes & 0x80;
1060 Information = sizeof(USB_NODE_INFORMATION);*/
1061 Status
= STATUS_SUCCESS
;
1065 case IOCTL_USB_GET_NODE_CONNECTION_NAME
:
1067 PHUB_DEVICE_EXTENSION DeviceExtension
;
1068 PUSB_NODE_CONNECTION_NAME ConnectionName
;
1069 DeviceExtension
= (PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1070 ConnectionName
= (PUSB_NODE_CONNECTION_NAME
)BufferOut
;
1072 DPRINT1("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_NAME\n");
1073 if (LengthOut
< sizeof(USB_NODE_CONNECTION_NAME
))
1074 Status
= STATUS_BUFFER_TOO_SMALL
;
1075 else if (BufferOut
== NULL
)
1076 Status
= STATUS_INVALID_PARAMETER
;
1077 else if (ConnectionName
->ConnectionIndex
< 1
1078 || ConnectionName
->ConnectionIndex
> USB_MAXCHILDREN
)
1079 Status
= STATUS_INVALID_PARAMETER
;
1080 else if (DeviceExtension
->Children
[ConnectionName
->ConnectionIndex
- 1] == NULL
)
1081 Status
= STATUS_INVALID_PARAMETER
;
1084 ULONG NeededStructureSize
;
1085 DeviceExtension
= (PHUB_DEVICE_EXTENSION
)DeviceExtension
->Children
[ConnectionName
->ConnectionIndex
- 1]->DeviceExtension
;
1086 NeededStructureSize
= DeviceExtension
->SymbolicLinkName
.Length
+ sizeof(UNICODE_NULL
) + FIELD_OFFSET(USB_NODE_CONNECTION_NAME
, NodeName
);
1087 if (ConnectionName
->ActualLength
< NeededStructureSize
/ sizeof(WCHAR
)
1088 || LengthOut
< NeededStructureSize
)
1090 /* Buffer too small */
1091 ConnectionName
->ActualLength
= NeededStructureSize
/ sizeof(WCHAR
);
1092 Information
= sizeof(USB_NODE_CONNECTION_NAME
);
1093 Status
= STATUS_BUFFER_TOO_SMALL
;
1098 ConnectionName
->NodeName
,
1099 DeviceExtension
->SymbolicLinkName
.Buffer
,
1100 DeviceExtension
->SymbolicLinkName
.Length
);
1101 ConnectionName
->NodeName
[DeviceExtension
->SymbolicLinkName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1102 DPRINT1("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_NAME returns '%S'\n", ConnectionName
->NodeName
);
1103 ConnectionName
->ActualLength
= NeededStructureSize
/ sizeof(WCHAR
);
1104 Information
= NeededStructureSize
;
1105 Status
= STATUS_SUCCESS
;
1107 Information
= LengthOut
;
1111 case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION
:
1113 PUSB_NODE_CONNECTION_INFORMATION ConnectionInformation
;
1116 struct usb_device* dev;
1117 ULONG NumberOfOpenPipes = 0;
1118 ULONG SizeOfOpenPipesArray;
1120 ConnectionInformation
= (PUSB_NODE_CONNECTION_INFORMATION
)BufferOut
;
1122 DPRINT1("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_INFORMATION\n");
1123 if (LengthOut
< sizeof(USB_NODE_CONNECTION_INFORMATION
))
1124 Status
= STATUS_BUFFER_TOO_SMALL
;
1125 else if (BufferOut
== NULL
)
1126 Status
= STATUS_INVALID_PARAMETER
;
1127 else if (ConnectionInformation
->ConnectionIndex
< 1
1128 || ConnectionInformation
->ConnectionIndex
> USB_MAXCHILDREN
)
1129 Status
= STATUS_INVALID_PARAMETER
;
1132 DPRINT1("Usbhub: We should succeed\n");
1136 case IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION
:
1138 //PUSB_DESCRIPTOR_REQUEST Descriptor;
1139 DPRINT1("Usbhub: IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION\n");
1141 Status
= STATUS_NOT_IMPLEMENTED
;
1144 case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME
:
1146 PHUB_DEVICE_EXTENSION DeviceExtension
;
1147 PUSB_NODE_CONNECTION_DRIVERKEY_NAME StringDescriptor
;
1148 DPRINT1("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME\n");
1149 DeviceExtension
= (PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1150 StringDescriptor
= (PUSB_NODE_CONNECTION_DRIVERKEY_NAME
)BufferOut
;
1151 if (LengthOut
< sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME
))
1152 Status
= STATUS_BUFFER_TOO_SMALL
;
1153 else if (StringDescriptor
== NULL
)
1154 Status
= STATUS_INVALID_PARAMETER
;
1155 else if (StringDescriptor
->ConnectionIndex
< 1
1156 || StringDescriptor
->ConnectionIndex
> USB_MAXCHILDREN
)
1157 Status
= STATUS_INVALID_PARAMETER
;
1158 else if (DeviceExtension
->Children
[StringDescriptor
->ConnectionIndex
- 1] == NULL
)
1159 Status
= STATUS_INVALID_PARAMETER
;
1163 Status
= IoGetDeviceProperty(
1164 DeviceExtension
->Children
[StringDescriptor
->ConnectionIndex
- 1],
1165 DevicePropertyDriverKeyName
,
1166 LengthOut
- FIELD_OFFSET(USB_NODE_CONNECTION_DRIVERKEY_NAME
, DriverKeyName
),
1167 StringDescriptor
->DriverKeyName
,
1169 if (NT_SUCCESS(Status
) || Status
== STATUS_BUFFER_TOO_SMALL
)
1171 StringDescriptor
->ActualLength
= StringSize
+ FIELD_OFFSET(USB_NODE_CONNECTION_DRIVERKEY_NAME
, DriverKeyName
);
1172 Information
= LengthOut
;
1173 Status
= STATUS_SUCCESS
;
1180 /* Pass Irp to lower driver */
1181 DPRINT1("Usbhub: Unknown IOCTL code 0x%lx\n", Stack
->Parameters
.DeviceIoControl
.IoControlCode
);
1182 return ForwardIrpAndForget(DeviceObject
, Irp
);
1186 Irp
->IoStatus
.Information
= Information
;
1187 Irp
->IoStatus
.Status
= Status
;
1188 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);