IN PDEVICE_OBJECT UsbHubDeviceObject,
IN LONG PortId);
-NTSTATUS
-SubmitRequestToRootHub(
- IN PDEVICE_OBJECT RootHubDeviceObject,
- IN ULONG IoControlCode,
- OUT PVOID OutParameter1,
- OUT PVOID OutParameter2)
-{
- KEVENT Event;
- PIRP Irp;
- IO_STATUS_BLOCK IoStatus;
- NTSTATUS Status;
- PIO_STACK_LOCATION Stack = NULL;
-
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
- //
- // Build Control Request
- //
- Irp = IoBuildDeviceIoControlRequest(IoControlCode,
- RootHubDeviceObject,
- NULL, 0,
- NULL, 0,
- TRUE,
- &Event,
- &IoStatus);
-
- if (Irp == NULL)
- {
- DPRINT("Usbhub: IoBuildDeviceIoControlRequest() failed\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- //
- // Initialize the status block before sending the IRP
- //
- IoStatus.Status = STATUS_NOT_SUPPORTED;
- IoStatus.Information = 0;
-
- //
- // Get Next Stack Location and Initialize it
- //
- Stack = IoGetNextIrpStackLocation(Irp);
- Stack->Parameters.Others.Argument1 = OutParameter1;
- Stack->Parameters.Others.Argument2 = OutParameter2;
-
- //
- // Call RootHub
- //
- Status = IoCallDriver(RootHubDeviceObject, Irp);
-
- //
- // Its ok to block here as this function is called in an nonarbitrary thread
- //
- if (Status == STATUS_PENDING)
- {
- KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
- Status = IoStatus.Status;
- }
-
- //
- // The IO Manager will free the IRP
- //
-
- return Status;
-}
NTSTATUS
GetPortStatusAndChange(
sizeof(PORT_STATUS_CHANGE),
0);
+ // FIXME: support usb hubs
+ Urb->UrbHeader.UsbdDeviceHandle = NULL;
+
+
//
// Query the Root Hub
//
0,
0,
0);
+
+ // FIXME support usbhubs
+ Urb->UrbHeader.UsbdDeviceHandle = NULL;
+
//
// Query the Root Hub
//
0,
0,
0);
+
+ // FIXME: support usb hubs
+ Urb->UrbHeader.UsbdDeviceHandle = NULL;
+
//
// Query the Root Hub
//
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to clear connection change for port %d\n", PortId);
+ continue;
}
//
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to delete child device object after disconnect\n");
+ continue;
}
}
else
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reset port %d\n", PortId);
+ SignalResetComplete = TRUE;
+ continue;
}
}
}
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to clear enable change on port %d\n", PortId);
+ continue;
}
}
else if (PortStatus.Change & USB_PORT_STATUS_RESET)
{
+ //
+ // Request event signalling later
+ //
+ SignalResetComplete = TRUE;
+
//
// Clear Reset
//
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to clear reset change on port %d\n", PortId);
+ continue;
}
//
if(PortStatus.Change & USB_PORT_STATUS_RESET)
{
DPRINT1("Port did not clear reset! Possible Hardware problem!\n");
+ continue;
}
//
// This is a new device
//
Status = CreateUsbChildDeviceObject(DeviceObject, PortId, NULL, PortStatus.Status);
-
- //
- // Request event signalling later
- //
- SignalResetComplete = TRUE;
}
}
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
NULL);
- //
- // Set the device handle to null for roothub
- //
- PendingSCEUrb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
+ // Set the device handle
+ PendingSCEUrb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
//
// Allocate an Irp
//
-
HubDeviceExtension->PendingSCEIrp = ExAllocatePoolWithTag(NonPagedPool,
IoSizeOfIrp(RootHubDeviceObject->StackSize),
USB_HUB_TAG);
ExFreePool(StringDesc);
return STATUS_INSUFFICIENT_RESOURCES;
}
- DPRINT("Buffer %p\n", Buffer);
- RtlZeroMemory(Buffer, SizeNeeded);
- DPRINT("SizeNeeded %lu\n", SizeNeeded);
- DPRINT("Offset %lu\n", FIELD_OFFSET(USB_STRING_DESCRIPTOR, bLength));
- DPRINT("Length %lu\n", SizeNeeded - FIELD_OFFSET(USB_STRING_DESCRIPTOR, bLength));
+ RtlZeroMemory(Buffer, SizeNeeded);
//
// Copy the string to destination
LPWSTR DeviceString;
WCHAR Buffer[200];
PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
+ PHUB_DEVICE_EXTENSION HubDeviceExtension;
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
//
UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)UsbChildDeviceObject->DeviceExtension;
+ // get hub device extension
+ HubDeviceExtension = (PHUB_DEVICE_EXTENSION) UsbChildExtension->ParentDeviceObject->DeviceExtension;
+
//
// get device descriptor
//
}
else
{
- //
- // sanity checks for simple usb device
- //
- ASSERT(ConfigurationDescriptor->bNumInterfaces == 1);
-
//
// FIXME: support multiple configurations
//
if (!NT_SUCCESS(Status))
{
DPRINT1("USBHUB: GetUsbStringDescriptor failed with status %x\n", Status);
- RtlInitUnicodeString(&UsbChildExtension->usTextDescription, L"");
+ RtlInitUnicodeString(&UsbChildExtension->usTextDescription, L"USB Device"); // FIXME NON-NLS
}
else
{
//
if (UsbChildExtension->DeviceDesc.iSerialNumber)
{
+ LPWSTR SerialBuffer = NULL;
+
Status = GetUsbStringDescriptor(UsbChildDeviceObject,
UsbChildExtension->DeviceDesc.iSerialNumber,
0,
- (PVOID*)&UsbChildExtension->usInstanceId.Buffer,
+ (PVOID*)&SerialBuffer,
&UsbChildExtension->usInstanceId.Length);
if (!NT_SUCCESS(Status))
{
return Status;
}
- UsbChildExtension->usInstanceId.MaximumLength = UsbChildExtension->usInstanceId.Length;
- DPRINT("Usb InstanceId %wZ\n", &UsbChildExtension->usInstanceId);
+ // construct instance id buffer
+ Index = swprintf(Buffer, L"%04d&%s", HubDeviceExtension->InstanceCount, SerialBuffer) + 1;
+ UsbChildExtension->usInstanceId.Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR));
+ if (UsbChildExtension->usInstanceId.Buffer == NULL)
+ {
+ DPRINT1("Error: failed to allocate %lu bytes\n", Index * sizeof(WCHAR));
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ return Status;
+ }
+
+ //
+ // copy instance id
+ //
+ RtlCopyMemory(UsbChildExtension->usInstanceId.Buffer, Buffer, Index * sizeof(WCHAR));
+ UsbChildExtension->usInstanceId.Length = UsbChildExtension->usInstanceId.MaximumLength = Index * sizeof(WCHAR);
+ ExFreePool(SerialBuffer);
+
+ DPRINT("Usb InstanceId %wZ InstanceCount %x\n", &UsbChildExtension->usInstanceId, HubDeviceExtension->InstanceCount);
}
else
{
//
// the device did not provide a serial number, lets create a pseudo instance id
//
- Index = swprintf(Buffer, L"0&%04d", UsbChildExtension->PortNumber) + 1;
+ Index = swprintf(Buffer, L"%04d&%04d", HubDeviceExtension->InstanceCount, UsbChildExtension->PortNumber) + 1;
UsbChildExtension->usInstanceId.Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR));
if (UsbChildExtension->usInstanceId.Buffer == NULL)
{
DPRINT("usDeviceId %wZ\n", &UsbChildExtension->usInstanceId);
}
- return Status;
+ return STATUS_SUCCESS;
}
NTSTATUS
ULONG ChildDeviceCount, UsbDeviceNumber = 0;
WCHAR CharDeviceName[64];
UNICODE_STRING DeviceName;
- ULONG ConfigDescSize, DeviceDescSize;
+ ULONG ConfigDescSize, DeviceDescSize, DeviceInfoSize;
PVOID HubInterfaceBusContext;
USB_CONFIGURATION_DESCRIPTOR ConfigDesc;
UsbChildExtension->ParentDeviceObject = UsbHubDeviceObject;
UsbChildExtension->PortNumber = PortId;
+ // copy device interface
+ RtlCopyMemory(&UsbChildExtension->DeviceInterface, &HubDeviceExtension->DeviceInterface, sizeof(USB_BUS_INTERFACE_USBDI_V2));
+
+
//
// Create the UsbDeviceObject
//
goto Cleanup;
}
+ // copy device interface
+ RtlCopyMemory(&UsbChildExtension->DeviceInterface, &HubDeviceExtension->DeviceInterface, sizeof(USB_BUS_INTERFACE_USBDI_V2));
+
+ // FIXME replace buscontext
+ UsbChildExtension->DeviceInterface.BusContext = UsbChildExtension->UsbDeviceHandle;
+
//
// Initialize UsbDevice
//
goto Cleanup;
}
+ // query device details
+ Status = HubInterface->QueryDeviceInformation(HubInterfaceBusContext,
+ UsbChildExtension->UsbDeviceHandle,
+ &UsbChildExtension->DeviceInformation,
+ sizeof(USB_DEVICE_INFORMATION_0),
+ &DeviceInfoSize);
+
+
//DumpFullConfigurationDescriptor(UsbChildExtension->FullConfigDesc);
//
}
HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] = NewChildDeviceObject;
+ HubDeviceExtension->InstanceCount++;
IoInvalidateDeviceRelations(RootHubDeviceObject, BusRelations);
return STATUS_SUCCESS;
}
}
+BOOLEAN
+USBHUB_IsRootHubFDO(
+ IN PDEVICE_OBJECT DeviceObject)
+{
+ NTSTATUS Status;
+ PDEVICE_OBJECT RootHubPhysicalDeviceObject = NULL;
+ PHUB_DEVICE_EXTENSION HubDeviceExtension;
+
+ // get hub device extension
+ HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
+
+ // Get the Root Hub Pdo
+ Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
+ IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO,
+ &RootHubPhysicalDeviceObject,
+ NULL);
+
+ // FIXME handle error
+ ASSERT(NT_SUCCESS(Status));
+
+ // physical device object is only obtained for root hubs
+ return (RootHubPhysicalDeviceObject != NULL);
+}
+
+
NTSTATUS
-USBHUB_FdoHandlePnp(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
+USBHUB_FdoStartDevice(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
+ PURB Urb;
+ PUSB_INTERFACE_DESCRIPTOR Pid;
+ ULONG Result = 0, PortId;
+ USBD_INTERFACE_LIST_ENTRY InterfaceList[2] = {{NULL, NULL}, {NULL, NULL}};
+ PURB ConfigUrb = NULL;
+ ULONG HubStatus;
PIO_STACK_LOCATION Stack;
NTSTATUS Status = STATUS_SUCCESS;
- ULONG_PTR Information = 0;
PHUB_DEVICE_EXTENSION HubDeviceExtension;
PDEVICE_OBJECT RootHubDeviceObject;
PVOID HubInterfaceBusContext , UsbDInterfaceBusContext;
PORT_STATUS_CHANGE StatusChange;
+ // get current stack location
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+
+ // get hub device extension
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
- Stack = IoGetCurrentIrpStackLocation(Irp);
+ DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
- switch (Stack->MinorFunction)
+ // Allocated size including the sizeof USBD_INTERFACE_LIST_ENTRY
+ Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY), USB_HUB_TAG);
+ if (!Urb)
{
- case IRP_MN_START_DEVICE:
- {
- PURB Urb;
- PUSB_INTERFACE_DESCRIPTOR Pid;
- ULONG Result = 0, PortId;
- USBD_INTERFACE_LIST_ENTRY InterfaceList[2] = {{NULL, NULL}, {NULL, NULL}};
- PURB ConfigUrb = NULL;
- ULONG HubStatus;
+ // no memory
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
- DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
+ // zero urb
+ RtlZeroMemory(Urb, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY));
- //
- // Allocated size including the sizeof USBD_INTERFACE_LIST_ENTRY
- //
- Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY), USB_HUB_TAG);
- RtlZeroMemory(Urb, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY));
+ // Get the Root Hub Pdo
+ Status = SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
+ IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO,
+ &HubDeviceExtension->RootHubPhysicalDeviceObject,
+ &HubDeviceExtension->RootHubFunctionalDeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ // failed to obtain hub pdo
+ DPRINT1("IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO failed with %x\n", Status);
+ ExFreePool(Urb);
+ return Status;
+ }
- //
- // Get the Root Hub Pdo
- //
- SubmitRequestToRootHub(HubDeviceExtension->LowerDeviceObject,
- IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO,
- &HubDeviceExtension->RootHubPhysicalDeviceObject,
- &HubDeviceExtension->RootHubFunctionalDeviceObject);
-
- RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
- ASSERT(HubDeviceExtension->RootHubPhysicalDeviceObject);
- ASSERT(HubDeviceExtension->RootHubFunctionalDeviceObject);
- DPRINT("RootPdo %x, RootFdo %x\n",
- HubDeviceExtension->RootHubPhysicalDeviceObject,
- HubDeviceExtension->RootHubFunctionalDeviceObject);
+ // sanity checks
+ ASSERT(HubDeviceExtension->RootHubPhysicalDeviceObject);
+ ASSERT(HubDeviceExtension->RootHubFunctionalDeviceObject);
- //
- // Send the StartDevice to RootHub
- //
- Status = ForwardIrpAndWait(RootHubDeviceObject, Irp);
+ // get roothub
+ RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to start the RootHub PDO\n");
- ASSERT(FALSE);
- }
+ // Send the StartDevice to RootHub
+ Status = ForwardIrpAndWait(RootHubDeviceObject, Irp);
- //
- // Get the current number of hubs
- //
- Status = SubmitRequestToRootHub(RootHubDeviceObject,
- IOCTL_INTERNAL_USB_GET_HUB_COUNT,
- &HubDeviceExtension->NumberOfHubs, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ // failed to start pdo
+ DPRINT1("Failed to start the RootHub PDO\n");
+ ExFreePool(Urb);
+ return Status;
+ }
- //
- // Get the Hub Interface
- //
- Status = QueryInterface(RootHubDeviceObject,
- USB_BUS_INTERFACE_HUB_GUID,
- sizeof(USB_BUS_INTERFACE_HUB_V5),
- 5,
- (PVOID)&HubDeviceExtension->HubInterface);
+ // Get the current number of hubs
+ Status = SubmitRequestToRootHub(RootHubDeviceObject,
+ IOCTL_INTERNAL_USB_GET_HUB_COUNT,
+ &HubDeviceExtension->NumberOfHubs, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ // failed to get number of hubs
+ DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT failed with %x\n", Status);
+ ExFreePool(Urb);
+ return Status;
+ }
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to get HUB_GUID interface with status 0x%08lx\n", Status);
- return STATUS_UNSUCCESSFUL;
- }
+ // Get the Hub Interface
+ Status = QueryInterface(RootHubDeviceObject,
+ USB_BUS_INTERFACE_HUB_GUID,
+ sizeof(USB_BUS_INTERFACE_HUB_V5),
+ USB_BUSIF_HUB_VERSION_5,
+ (PVOID)&HubDeviceExtension->HubInterface);
- HubInterfaceBusContext = HubDeviceExtension->HubInterface.BusContext;
+ if (!NT_SUCCESS(Status))
+ {
+ // failed to get root hub interface
+ DPRINT1("Failed to get HUB_GUID interface with status 0x%08lx\n", Status);
+ ExFreePool(Urb);
+ return Status;
+ }
- //
- // Get the USBDI Interface
- //
- Status = QueryInterface(RootHubDeviceObject,
- USB_BUS_INTERFACE_USBDI_GUID,
- sizeof(USB_BUS_INTERFACE_USBDI_V2),
- 2,
- (PVOID)&HubDeviceExtension->UsbDInterface);
+ HubInterfaceBusContext = HubDeviceExtension->HubInterface.BusContext;
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to get USBDI_GUID interface with status 0x%08lx\n", Status);
- return Status;
- }
+ // Get the USBDI Interface
+ Status = QueryInterface(RootHubDeviceObject,
+ USB_BUS_INTERFACE_USBDI_GUID,
+ sizeof(USB_BUS_INTERFACE_USBDI_V2),
+ USB_BUSIF_USBDI_VERSION_2,
+ (PVOID)&HubDeviceExtension->UsbDInterface);
- UsbDInterfaceBusContext = HubDeviceExtension->UsbDInterface.BusContext;
+ if (!NT_SUCCESS(Status))
+ {
+ // failed to get usbdi interface
+ DPRINT1("Failed to get USBDI_GUID interface with status 0x%08lx\n", Status);
+ ExFreePool(Urb);
+ return Status;
+ }
- //
- // Get Root Hub Device Handle
- //
- Status = SubmitRequestToRootHub(RootHubDeviceObject,
- IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE,
- &HubDeviceExtension->RootHubHandle,
- NULL);
+ UsbDInterfaceBusContext = HubDeviceExtension->UsbDInterface.BusContext;
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("GetRootHubDeviceHandle failed with status 0x%08lx\n", Status);
- return Status;
- }
+ // Get Root Hub Device Handle
+ Status = SubmitRequestToRootHub(RootHubDeviceObject,
+ IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE,
+ &HubDeviceExtension->RootHubHandle,
+ NULL);
- //
- // Get Hub Device Information
- //
- Status = HubDeviceExtension->HubInterface.QueryDeviceInformation(HubInterfaceBusContext,
- HubDeviceExtension->RootHubHandle,
- &HubDeviceExtension->DeviceInformation,
- sizeof(USB_DEVICE_INFORMATION_0),
- &Result);
-
- DPRINT1("Status %x, Result 0x%08lx\n", Status, Result);
- DPRINT1("InformationLevel %x\n", HubDeviceExtension->DeviceInformation.InformationLevel);
- DPRINT1("ActualLength %x\n", HubDeviceExtension->DeviceInformation.ActualLength);
- DPRINT1("PortNumber %x\n", HubDeviceExtension->DeviceInformation.PortNumber);
- DPRINT1("DeviceDescriptor %x\n", HubDeviceExtension->DeviceInformation.DeviceDescriptor);
- DPRINT1("HubAddress %x\n", HubDeviceExtension->DeviceInformation.HubAddress);
- DPRINT1("NumberofPipes %x\n", HubDeviceExtension->DeviceInformation.NumberOfOpenPipes);
+ if (!NT_SUCCESS(Status))
+ {
+ // failed
+ DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE failed with status 0x%08lx\n", Status);
+ ExFreePool(Urb);
+ return Status;
+ }
- //
- // Get Root Hubs Device Descriptor
- //
- UsbBuildGetDescriptorRequest(Urb,
- sizeof(Urb->UrbControlDescriptorRequest),
- USB_DEVICE_DESCRIPTOR_TYPE,
- 0,
- 0,
- &HubDeviceExtension->HubDeviceDescriptor,
- NULL,
- sizeof(USB_DEVICE_DESCRIPTOR),
- NULL);
-
- Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
-
- Status = SubmitRequestToRootHub(RootHubDeviceObject,
- IOCTL_INTERNAL_USB_SUBMIT_URB,
- Urb,
- NULL);
+ //
+ // Get Hub Device Information
+ //
+ Status = HubDeviceExtension->HubInterface.QueryDeviceInformation(HubInterfaceBusContext,
+ HubDeviceExtension->RootHubHandle,
+ &HubDeviceExtension->DeviceInformation,
+ sizeof(USB_DEVICE_INFORMATION_0),
+ &Result);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to get HubDeviceDescriptor!\n");
- }
+ DPRINT1("Status %x, Result 0x%08lx\n", Status, Result);
+ DPRINT1("InformationLevel %x\n", HubDeviceExtension->DeviceInformation.InformationLevel);
+ DPRINT1("ActualLength %x\n", HubDeviceExtension->DeviceInformation.ActualLength);
+ DPRINT1("PortNumber %x\n", HubDeviceExtension->DeviceInformation.PortNumber);
+ DPRINT1("DeviceDescriptor %x\n", HubDeviceExtension->DeviceInformation.DeviceDescriptor);
+ DPRINT1("HubAddress %x\n", HubDeviceExtension->DeviceInformation.HubAddress);
+ DPRINT1("NumberofPipes %x\n", HubDeviceExtension->DeviceInformation.NumberOfOpenPipes);
- DumpDeviceDescriptor(&HubDeviceExtension->HubDeviceDescriptor);
+ // Get Root Hubs Device Descriptor
+ UsbBuildGetDescriptorRequest(Urb,
+ sizeof(Urb->UrbControlDescriptorRequest),
+ USB_DEVICE_DESCRIPTOR_TYPE,
+ 0,
+ 0,
+ &HubDeviceExtension->HubDeviceDescriptor,
+ NULL,
+ sizeof(USB_DEVICE_DESCRIPTOR),
+ NULL);
- //
- // Get Root Hubs Configuration Descriptor
- //
- UsbBuildGetDescriptorRequest(Urb,
- sizeof(Urb->UrbControlDescriptorRequest),
- USB_CONFIGURATION_DESCRIPTOR_TYPE,
- 0,
- 0,
- &HubDeviceExtension->HubConfigDescriptor,
- NULL,
- sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR),
- NULL);
-
- DPRINT("RootHub Handle %x\n", HubDeviceExtension->RootHubHandle);
- Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
-
- Status = SubmitRequestToRootHub(RootHubDeviceObject,
- IOCTL_INTERNAL_USB_SUBMIT_URB,
- Urb,
- NULL);
+ // set device handle
+ Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to get RootHub Configuration with status %x\n", Status);
- ASSERT(FALSE);
- }
- ASSERT(HubDeviceExtension->HubConfigDescriptor.wTotalLength);
+ // get hub device descriptor
+ Status = SubmitRequestToRootHub(RootHubDeviceObject,
+ IOCTL_INTERNAL_USB_SUBMIT_URB,
+ Urb,
+ NULL);
- DumpConfigurationDescriptor(&HubDeviceExtension->HubConfigDescriptor);
+ if (!NT_SUCCESS(Status))
+ {
+ // failed to get device descriptor of hub
+ DPRINT1("Failed to get HubDeviceDescriptor!\n");
+ ExFreePool(Urb);
+ return Status;
+ }
- Status = HubDeviceExtension->HubInterface.GetExtendedHubInformation(HubInterfaceBusContext,
- RootHubDeviceObject,
- &HubDeviceExtension->UsbExtHubInfo,
- sizeof(USB_EXTHUB_INFORMATION_0),
- &Result);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to extended hub information. Unable to determine the number of ports!\n");
- ASSERT(FALSE);
- }
+ // build configuration request
+ UsbBuildGetDescriptorRequest(Urb,
+ sizeof(Urb->UrbControlDescriptorRequest),
+ USB_CONFIGURATION_DESCRIPTOR_TYPE,
+ 0,
+ 0,
+ &HubDeviceExtension->HubConfigDescriptor,
+ NULL,
+ sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR),
+ NULL);
- DPRINT1("HubDeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", HubDeviceExtension->UsbExtHubInfo.NumberOfPorts);
+ // set device handle
+ Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
- //
- // Get the Hub Descriptor
- //
- UsbBuildVendorRequest(Urb,
- URB_FUNCTION_CLASS_DEVICE,
- sizeof(Urb->UrbControlVendorClassRequest),
- USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
- 0,
- USB_REQUEST_GET_DESCRIPTOR,
- USB_DEVICE_CLASS_RESERVED,
- 0,
- &HubDeviceExtension->HubDescriptor,
- NULL,
- sizeof(USB_HUB_DESCRIPTOR),
- NULL);
-
- Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
-
- Status = SubmitRequestToRootHub(RootHubDeviceObject,
- IOCTL_INTERNAL_USB_SUBMIT_URB,
- Urb,
- NULL);
-
- DPRINT1("bDescriptorType %x\n", HubDeviceExtension->HubDescriptor.bDescriptorType);
+ // request configuration descriptor
+ Status = SubmitRequestToRootHub(RootHubDeviceObject,
+ IOCTL_INTERNAL_USB_SUBMIT_URB,
+ Urb,
+ NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to get Hub Descriptor!\n");
- ExFreePool(Urb);
- return STATUS_UNSUCCESSFUL;
- }
+ if (!NT_SUCCESS(Status))
+ {
+ // failed to get configuration descriptor
+ DPRINT1("Failed to get RootHub Configuration with status %x\n", Status);
+ ExFreePool(Urb);
+ return Status;
+ }
- HubStatus = 0;
- UsbBuildGetStatusRequest(Urb,
- URB_FUNCTION_GET_STATUS_FROM_DEVICE,
- 0,
- &HubStatus,
- 0,
- NULL);
- Urb->UrbHeader.UsbdDeviceHandle = NULL;//HubDeviceExtension->RootHubHandle;
-
- Status = SubmitRequestToRootHub(RootHubDeviceObject,
- IOCTL_INTERNAL_USB_SUBMIT_URB,
- Urb,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to get Hub Status!\n");
- ExFreePool(Urb);
- return STATUS_UNSUCCESSFUL;
- }
+ // sanity checks
+ ASSERT(HubDeviceExtension->HubConfigDescriptor.wTotalLength == sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR));
+ ASSERT(HubDeviceExtension->HubConfigDescriptor.bDescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE);
+ ASSERT(HubDeviceExtension->HubConfigDescriptor.bLength == sizeof(USB_CONFIGURATION_DESCRIPTOR));
+ ASSERT(HubDeviceExtension->HubConfigDescriptor.bNumInterfaces == 1);
+ ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bLength == sizeof(USB_INTERFACE_DESCRIPTOR));
+ ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);
+ ASSERT(HubDeviceExtension->HubInterfaceDescriptor.bNumEndpoints == 1);
+ ASSERT(HubDeviceExtension->HubEndPointDescriptor.bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE);
+ ASSERT(HubDeviceExtension->HubEndPointDescriptor.bLength == sizeof(USB_ENDPOINT_DESCRIPTOR));
+ ASSERT(HubDeviceExtension->HubEndPointDescriptor.bmAttributes == USB_ENDPOINT_TYPE_INTERRUPT);
+ ASSERT(HubDeviceExtension->HubEndPointDescriptor.bEndpointAddress == 0x81); // interrupt in
+
+ // get hub information
+ Status = HubDeviceExtension->HubInterface.GetExtendedHubInformation(HubInterfaceBusContext,
+ RootHubDeviceObject,
+ &HubDeviceExtension->UsbExtHubInfo,
+ sizeof(USB_EXTHUB_INFORMATION_0),
+ &Result);
+ if (!NT_SUCCESS(Status))
+ {
+ // failed to get hub information
+ DPRINT1("Failed to extended hub information. Unable to determine the number of ports!\n");
+ ExFreePool(Urb);
+ return Status;
+ }
- DPRINT1("HubStatus %x\n", HubStatus);
+ if (!HubDeviceExtension->UsbExtHubInfo.NumberOfPorts)
+ {
+ // bogus port driver
+ DPRINT1("Failed to retrieve the number of ports\n");
+ ExFreePool(Urb);
+ return STATUS_UNSUCCESSFUL;
+ }
- //
- // Allocate memory for PortStatusChange to hold 2 USHORTs for each port on hub
- //
- HubDeviceExtension->PortStatusChange = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(ULONG) * HubDeviceExtension->UsbExtHubInfo.NumberOfPorts,
- USB_HUB_TAG);
+ DPRINT1("HubDeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", HubDeviceExtension->UsbExtHubInfo.NumberOfPorts);
- //
- // Get the first Configuration Descriptor
- //
- Pid = USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor,
- &HubDeviceExtension->HubConfigDescriptor,
- -1, -1, -1, -1, -1);
+ // Build hub descriptor request
+ UsbBuildVendorRequest(Urb,
+ URB_FUNCTION_CLASS_DEVICE,
+ sizeof(Urb->UrbControlVendorClassRequest),
+ USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
+ 0,
+ USB_REQUEST_GET_DESCRIPTOR,
+ USB_DEVICE_CLASS_RESERVED,
+ 0,
+ &HubDeviceExtension->HubDescriptor,
+ NULL,
+ sizeof(USB_HUB_DESCRIPTOR),
+ NULL);
+
+ // set device handle
+ Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
+
+ // send request
+ Status = SubmitRequestToRootHub(RootHubDeviceObject,
+ IOCTL_INTERNAL_USB_SUBMIT_URB,
+ Urb,
+ NULL);
- ASSERT(Pid != NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to get Hub Descriptor!\n");
+ ExFreePool(Urb);
+ return STATUS_UNSUCCESSFUL;
+ }
- InterfaceList[0].InterfaceDescriptor = Pid;
- ConfigUrb = USBD_CreateConfigurationRequestEx(&HubDeviceExtension->HubConfigDescriptor,
- (PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList);
- ASSERT(ConfigUrb != NULL);
+ // sanity checks
+ ASSERT(HubDeviceExtension->HubDescriptor.bDescriptorLength == sizeof(USB_HUB_DESCRIPTOR));
+ ASSERT(HubDeviceExtension->HubDescriptor.bNumberOfPorts == HubDeviceExtension->UsbExtHubInfo.NumberOfPorts);
+ ASSERT(HubDeviceExtension->HubDescriptor.bDescriptorType == 0x29);
+
+ // build get status request
+ HubStatus = 0;
+ UsbBuildGetStatusRequest(Urb,
+ URB_FUNCTION_GET_STATUS_FROM_DEVICE,
+ 0,
+ &HubStatus,
+ 0,
+ NULL);
+ // set device handle
+ Urb->UrbHeader.UsbdDeviceHandle = HubDeviceExtension->RootHubHandle;
+
+ // send request
+ Status = SubmitRequestToRootHub(RootHubDeviceObject,
+ IOCTL_INTERNAL_USB_SUBMIT_URB,
+ Urb,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ // failed to get hub status
+ DPRINT1("Failed to get Hub Status!\n");
+ ExFreePool(Urb);
+ return STATUS_UNSUCCESSFUL;
+ }
- Status = SubmitRequestToRootHub(RootHubDeviceObject,
- IOCTL_INTERNAL_USB_SUBMIT_URB,
- ConfigUrb,
- NULL);
+ // Allocate memory for PortStatusChange to hold 2 USHORTs for each port on hub
+ HubDeviceExtension->PortStatusChange = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(ULONG) * HubDeviceExtension->UsbExtHubInfo.NumberOfPorts,
+ USB_HUB_TAG);
- HubDeviceExtension->ConfigurationHandle = ConfigUrb->UrbSelectConfiguration.ConfigurationHandle;
- HubDeviceExtension->PipeHandle = ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
- DPRINT("Configuration Handle %x\n", HubDeviceExtension->ConfigurationHandle);
+ // Get the first Configuration Descriptor
+ Pid = USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor,
+ &HubDeviceExtension->HubConfigDescriptor,
+ -1, -1, -1, -1, -1);
+ if (Pid == NULL)
+ {
+ // failed parse hub descriptor
+ DPRINT1("Failed to parse configuration descriptor\n");
+ ExFreePool(Urb);
+ return STATUS_UNSUCCESSFUL;
+ }
- //
- // check if function is available
- //
- if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed)
- {
- //
- // is it high speed bus
- //
- if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed(HubInterfaceBusContext))
- {
- //
- // initialize usb 2.0 hub
- //
- Status = HubDeviceExtension->HubInterface.Initialize20Hub(HubInterfaceBusContext,
- HubDeviceExtension->RootHubHandle, 1);
- DPRINT("Status %x\n", Status);
+ // create configuration request
+ InterfaceList[0].InterfaceDescriptor = Pid;
+ ConfigUrb = USBD_CreateConfigurationRequestEx(&HubDeviceExtension->HubConfigDescriptor,
+ (PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList);
+ if (ConfigUrb == NULL)
+ {
+ // failed to build urb
+ DPRINT1("Failed to allocate urb\n");
+ ExFreePool(Urb);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
- //
- // FIXME handle error
- //
- ASSERT(Status == STATUS_SUCCESS);
- }
- }
+ // send request
+ Status = SubmitRequestToRootHub(RootHubDeviceObject,
+ IOCTL_INTERNAL_USB_SUBMIT_URB,
+ ConfigUrb,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ // failed to select configuration
+ DPRINT1("Failed to select configuration with %x\n", Status);
+ ExFreePool(Urb);
+ ExFreePool(ConfigUrb);
+ return Status;
+ }
- ExFreePool(ConfigUrb);
+ // store configuration & pipe handle
+ HubDeviceExtension->ConfigurationHandle = ConfigUrb->UrbSelectConfiguration.ConfigurationHandle;
+ HubDeviceExtension->PipeHandle = ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
+ DPRINT("Configuration Handle %x\n", HubDeviceExtension->ConfigurationHandle);
- //
- // Enable power on all ports
- //
+ FDO_QueryInterface(DeviceObject, &HubDeviceExtension->DeviceInterface);
- DPRINT("Enabling PortPower on all ports!\n");
- for (PortId = 1; PortId <= HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++)
- {
- Status = SetPortFeature(RootHubDeviceObject, PortId, PORT_POWER);
- if (!NT_SUCCESS(Status))
- DPRINT1("Failed to power on port %d\n", PortId);
+ // free urb
+ ExFreePool(ConfigUrb);
- Status = ClearPortFeature(RootHubDeviceObject, PortId, C_PORT_CONNECTION);
- if (!NT_SUCCESS(Status))
- DPRINT1("Failed to power on port %d\n", PortId);
- }
+ // check if function is available
+ if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed)
+ {
+ // is it high speed bus
+ if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed(HubInterfaceBusContext))
+ {
+ // initialize usb 2.0 hub
+ Status = HubDeviceExtension->HubInterface.Initialize20Hub(HubInterfaceBusContext,
+ HubDeviceExtension->RootHubHandle, 1);
+ DPRINT("Status %x\n", Status);
+
+ // FIXME handle error
+ ASSERT(Status == STATUS_SUCCESS);
+ }
+ }
+
+
+ // Enable power on all ports
+ DPRINT("Enabling PortPower on all ports!\n");
+ for (PortId = 1; PortId <= HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++)
+ {
+ Status = SetPortFeature(RootHubDeviceObject, PortId, PORT_POWER);
+ if (!NT_SUCCESS(Status))
+ DPRINT1("Failed to power on port %d\n", PortId);
+
+ Status = ClearPortFeature(RootHubDeviceObject, PortId, C_PORT_CONNECTION);
+ if (!NT_SUCCESS(Status))
+ DPRINT1("Failed to power on port %d\n", PortId);
+ }
- DPRINT("RootHubInitNotification %x\n", HubDeviceExtension->HubInterface.RootHubInitNotification);
+ // init root hub notification
+ if (HubDeviceExtension->HubInterface.RootHubInitNotification)
+ {
+ Status = HubDeviceExtension->HubInterface.RootHubInitNotification(HubInterfaceBusContext,
+ DeviceObject,
+ RootHubInitCallbackFunction);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to set callback\n");
+ ExFreePool(Urb);
+ return Status;
+ }
+ }
+ else
+ {
+ // Send the first SCE Request
+ QueryStatusChangeEndpoint(DeviceObject);
+ //
+ // reset ports
+ //
+ for (PortId = 1; PortId <= HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++)
+ {
//
- // init root hub notification
+ // get port status
//
- if (HubDeviceExtension->HubInterface.RootHubInitNotification)
+ Status = GetPortStatusAndChange(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, &StatusChange);
+ if (NT_SUCCESS(Status))
{
- Status = HubDeviceExtension->HubInterface.RootHubInitNotification(HubInterfaceBusContext,
- DeviceObject,
- RootHubInitCallbackFunction);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to set callback\n");
- }
- }
- else
- {
- //
- // Send the first SCE Request
//
- QueryStatusChangeEndpoint(DeviceObject);
-
- //
- // reset ports
+ // is there a device connected
//
- for (PortId = 1; PortId <= HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++)
+ if (StatusChange.Status & USB_PORT_STATUS_CONNECT)
{
//
- // get port status
+ // reset port
//
- Status = GetPortStatusAndChange(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, &StatusChange);
- if (NT_SUCCESS(Status))
+ Status = SetPortFeature(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, PORT_RESET);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to reset on port %d\n", PortId);
+ }
+ else
{
//
- // is there a device connected
+ // wait for the reset to be handled since we want to enumerate synchronously
//
- if (StatusChange.Status & USB_PORT_STATUS_CONNECT)
- {
- //
- // reset port
- //
- Status = SetPortFeature(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, PORT_RESET);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to reset on port %d\n", PortId);
- }
- else
- {
- //
- // wait for the reset to be handled since we want to enumerate synchronously
- //
- KeWaitForSingleObject(&HubDeviceExtension->ResetComplete,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- KeClearEvent(&HubDeviceExtension->ResetComplete);
- }
- }
+ KeWaitForSingleObject(&HubDeviceExtension->ResetComplete,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ KeClearEvent(&HubDeviceExtension->ResetComplete);
}
}
}
+ }
+ }
- ExFreePool(Urb);
+ // free urb
+ ExFreePool(Urb);
+
+ // done
+ return Status;
+}
+
+NTSTATUS
+USBHUB_FdoHandlePnp(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION Stack;
+ NTSTATUS Status = STATUS_SUCCESS;
+ ULONG_PTR Information = 0;
+ PHUB_DEVICE_EXTENSION HubDeviceExtension;
+
+ HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+
+ switch (Stack->MinorFunction)
+ {
+ case IRP_MN_START_DEVICE:
+ {
+ if (USBHUB_IsRootHubFDO(DeviceObject))
+ {
+ // start root hub fdo
+ Status = USBHUB_FdoStartDevice(DeviceObject, Irp);
+ }
+ else
+ {
+ Status = USBHUB_ParentFDOStartDevice(DeviceObject, Irp);
+ }
break;
}
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- DPRINT1("FdoHandleDeviceControl\n");
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
+ PIO_STACK_LOCATION IoStack;
+ NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
+ PUSB_NODE_INFORMATION NodeInformation;
+ PHUB_DEVICE_EXTENSION HubDeviceExtension;
+ PUSB_NODE_CONNECTION_INFORMATION NodeConnectionInfo;
+ PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
+ PUSB_NODE_CONNECTION_DRIVERKEY_NAME NodeKey;
+ ULONG Index, Length;
+
+ // get stack location
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ // get device extension
+ HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
+
+ if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_NODE_INFORMATION)
+ {
+ // is the buffer big enough
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(USB_NODE_INFORMATION))
+ {
+ // buffer too small
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ // get buffer
+ NodeInformation = (PUSB_NODE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+
+ // sanity check
+ ASSERT(NodeInformation);
+
+ // init buffer
+ NodeInformation->NodeType = UsbHub;
+ RtlCopyMemory(&NodeInformation->u.HubInformation.HubDescriptor, &HubDeviceExtension->HubDescriptor, sizeof(USB_HUB_DESCRIPTOR));
+
+ // FIXME is hub powered
+ NodeInformation->u.HubInformation.HubIsBusPowered = TRUE;
+
+ // done
+ Irp->IoStatus.Information = sizeof(USB_NODE_INFORMATION);
+ Status = STATUS_SUCCESS;
+ }
+
+
+ }
+ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_NODE_CONNECTION_INFORMATION)
+ {
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(USB_NODE_CONNECTION_INFORMATION))
+ {
+ // buffer too small
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ // get node connection info
+ NodeConnectionInfo = (PUSB_NODE_CONNECTION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+
+ // sanity checks
+ ASSERT(NodeConnectionInfo);
+
+ for(Index = 0; Index < USB_MAXCHILDREN; Index++)
+ {
+ if (HubDeviceExtension->ChildDeviceObject[Index] == NULL)
+ continue;
+
+ // get child device extension
+ ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)HubDeviceExtension->ChildDeviceObject[Index]->DeviceExtension;
+
+ if (ChildDeviceExtension->PortNumber != NodeConnectionInfo->ConnectionIndex)
+ continue;
+
+ // init node connection info
+ RtlCopyMemory(&NodeConnectionInfo->DeviceDescriptor, &ChildDeviceExtension->DeviceDesc, sizeof(USB_DEVICE_DESCRIPTOR));
+ NodeConnectionInfo->CurrentConfigurationValue = ChildDeviceExtension->FullConfigDesc->bConfigurationValue;
+ NodeConnectionInfo->DeviceIsHub = FALSE; //FIXME support hubs
+ NodeConnectionInfo->LowSpeed = ChildDeviceExtension->DeviceInformation.DeviceSpeed == UsbLowSpeed;
+ NodeConnectionInfo->DeviceAddress = ChildDeviceExtension->DeviceInformation.DeviceAddress;
+ NodeConnectionInfo->NumberOfOpenPipes = ChildDeviceExtension->DeviceInformation.NumberOfOpenPipes;
+ NodeConnectionInfo->ConnectionStatus = DeviceConnected; //FIXME
+
+ if (NodeConnectionInfo->NumberOfOpenPipes)
+ {
+ DPRINT1("Need to copy pipe information\n");
+ }
+ break;
+ }
+
+ // done
+ Irp->IoStatus.Information = sizeof(USB_NODE_INFORMATION);
+ Status = STATUS_SUCCESS;
+ }
+ }
+ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME)
+ {
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(USB_NODE_CONNECTION_INFORMATION))
+ {
+ // buffer too small
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ // get node connection info
+ NodeKey = (PUSB_NODE_CONNECTION_DRIVERKEY_NAME)Irp->AssociatedIrp.SystemBuffer;
+
+ // sanity checks
+ ASSERT(NodeKey);
+
+ for(Index = 0; Index < USB_MAXCHILDREN; Index++)
+ {
+ if (HubDeviceExtension->ChildDeviceObject[Index] == NULL)
+ continue;
+
+ // get child device extension
+ ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)HubDeviceExtension->ChildDeviceObject[Index]->DeviceExtension;
+
+ if (ChildDeviceExtension->PortNumber != NodeKey->ConnectionIndex)
+ continue;
+
+ // get driver key
+ Status = IoGetDeviceProperty(HubDeviceExtension->ChildDeviceObject[Index], DevicePropertyDriverKeyName,
+ IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME),
+ NodeKey->DriverKeyName,
+ &Length);
+
+ if (Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ // normalize status
+ Status = STATUS_SUCCESS;
+ }
+
+ if (Length + sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME) > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
+ {
+ // terminate node key name
+ NodeKey->DriverKeyName[0] = 0;
+ Irp->IoStatus.Information = sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME);
+ }
+ else
+ {
+ // result size
+ Irp->IoStatus.Information = Length + sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME);
+ }
+
+ // length of driver name
+ NodeKey->ActualLength = Length + sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME);
+ break;
+ }
+ }
+ }
+ else
+ {
+ DPRINT1("UNIMPLEMENTED FdoHandleDeviceControl IoCtl %x InputBufferLength %x OutputBufferLength %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode,
+ IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength);
+ }
+
+ // finish irp
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return Status;
}