Exemplo n.º 1
0
NTSTATUS NTAPI
UsbhubPnpFdo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    PIO_STACK_LOCATION IrpSp;
    NTSTATUS Status = STATUS_SUCCESS;
    ULONG MinorFunction;
    ULONG_PTR Information = 0;
    PHUB_DEVICE_EXTENSION DeviceExtension;

    IrpSp = IoGetCurrentIrpStackLocation(Irp);
    MinorFunction = IrpSp->MinorFunction;

    DeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;

    switch (MinorFunction)
    {
        case IRP_MN_START_DEVICE: /* 0x0 */
        {
            PURB Urb;
            ULONG Result = 0;
            PUSB_INTERFACE_DESCRIPTOR Pid;
            /* Theres only one descriptor on hub */
            USBD_INTERFACE_LIST_ENTRY InterfaceList[2] = {{NULL, NULL}, {NULL, NULL}};
            PURB ConfigUrb = NULL;

            /* We differ from windows on hubpdo because we dont have usbport.sys which manages all usb device objects */
            DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");

            /* Allocating 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 hubs PDO */
            QueryRootHub(DeviceExtension->LowerDevice, IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO, &DeviceExtension->RootHubPdo, &DeviceExtension->RootHubFdo);
            ASSERT(DeviceExtension->RootHubPdo);
            ASSERT(DeviceExtension->RootHubFdo);
            DPRINT1("RootPdo %x, RootFdo %x\n", DeviceExtension->RootHubPdo, DeviceExtension->RootHubFdo);

            /* Send the START_DEVICE irp down to the PDO of RootHub */
            Status = ForwardIrpAndWait(DeviceExtension->RootHubPdo, Irp);

            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Failed to start the RootHub PDO\n");
                ASSERT(FALSE);
            }

            /* Get the current number of hubs */
            QueryRootHub(DeviceExtension->RootHubPdo,IOCTL_INTERNAL_USB_GET_HUB_COUNT, &DeviceExtension->HubCount, NULL);

            /* Get the Direct Call Interfaces */
            Status = QueryInterface(DeviceExtension->RootHubPdo, 
                                    USB_BUS_INTERFACE_HUB_GUID,
                                    sizeof(USB_BUS_INTERFACE_HUB_V5),
                                    5,
                                    (PVOID)&DeviceExtension->HubInterface);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("UsbhubM Failed to get HUB_GUID interface with status 0x%08lx\n", Status);
                return STATUS_UNSUCCESSFUL;
            }

            Status = QueryInterface(DeviceExtension->RootHubPdo,
                                    USB_BUS_INTERFACE_USBDI_GUID,
                                    sizeof(USB_BUS_INTERFACE_USBDI_V2),
                                    2,
                                    (PVOID)&DeviceExtension->UsbDInterface);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("UsbhubM Failed to get USBDI_GUID interface with status 0x%08lx\n", Status);
                return STATUS_UNSUCCESSFUL;
            }

            /* Get roothub device handle */
            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE, &DeviceExtension->RootHubUsbDevice, NULL);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Usbhub: GetRootHubDeviceHandle failed with status 0x%08lx\n", Status);
                return Status;
            }

            Status = DeviceExtension->HubInterface.QueryDeviceInformation(DeviceExtension->RootHubPdo,
                                                                 DeviceExtension->RootHubUsbDevice,
                                                                 &DeviceExtension->DeviceInformation,
                                                                 sizeof(USB_DEVICE_INFORMATION_0),
                                                                 &Result);


            DPRINT("Status %x, Result %x\n", Status, Result);
            DPRINT("InformationLevel %x\n", DeviceExtension->DeviceInformation.InformationLevel);
            DPRINT("ActualLength %x\n", DeviceExtension->DeviceInformation.ActualLength);
            DPRINT("PortNumber %x\n", DeviceExtension->DeviceInformation.PortNumber);
            DPRINT("DeviceDescriptor %x\n", DeviceExtension->DeviceInformation.DeviceDescriptor);
            DPRINT("HubAddress %x\n", DeviceExtension->DeviceInformation.HubAddress);
            DPRINT("NumberofPipes %x\n", DeviceExtension->DeviceInformation.NumberOfOpenPipes);

            /* Get roothubs device descriptor */
            UsbBuildGetDescriptorRequest(Urb,
                                         sizeof(Urb->UrbControlDescriptorRequest),
                                         USB_DEVICE_DESCRIPTOR_TYPE,
                                         0,
                                         0,
                                         &DeviceExtension->HubDeviceDescriptor,
                                         NULL,
                                         sizeof(USB_DEVICE_DESCRIPTOR),
                                         NULL);

            Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->RootHubUsbDevice;

            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Usbhub: Failed to get HubDeviceDescriptor!\n");
            }

            DumpDeviceDescriptor(&DeviceExtension->HubDeviceDescriptor);

            /* Get roothubs configuration descriptor */
            UsbBuildGetDescriptorRequest(Urb,
                                         sizeof(Urb->UrbControlDescriptorRequest),
                                         USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                         0,
                                         0,
                                         &DeviceExtension->HubConfigDescriptor,
                                         NULL,
                                         sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR),
                                         NULL);
            Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->RootHubUsbDevice;

            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);

            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Usbhub: Failed to get RootHub Configuration with status %x\n", Status);
                ASSERT(FALSE);
            }
            ASSERT(DeviceExtension->HubConfigDescriptor.wTotalLength);

            DumpFullConfigurationDescriptor(&DeviceExtension->HubConfigDescriptor);
            //DPRINT1("DeviceExtension->HubConfigDescriptor.wTotalLength %x\n", DeviceExtension->HubConfigDescriptor.wTotalLength);

            Status = DeviceExtension->HubInterface.GetExtendedHubInformation(DeviceExtension->RootHubPdo,
                                                                    DeviceExtension->RootHubPdo,
                                                                    &DeviceExtension->UsbExtHubInfo,
                                                                    sizeof(USB_EXTHUB_INFORMATION_0),
                                                                    &Result);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Usbhub: Failed to extended hub information. Unable to determine the number of ports!\n");
                ASSERT(FALSE);
            }

            DPRINT1("DeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", DeviceExtension->UsbExtHubInfo.NumberOfPorts);

            UsbBuildVendorRequest(Urb,
                                  URB_FUNCTION_CLASS_DEVICE,
                                  sizeof(Urb->UrbControlVendorClassRequest),
                                  USBD_TRANSFER_DIRECTION_IN,
                                  0,
                                  USB_DEVICE_CLASS_RESERVED,
                                  0,
                                  0,
                                  &DeviceExtension->HubDescriptor,
                                  NULL,
                                  sizeof(USB_HUB_DESCRIPTOR),
                                  NULL);

            Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->RootHubUsbDevice;

            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);

            DPRINT1("bDescriptorType %x\n", DeviceExtension->HubDescriptor.bDescriptorType);

            /* Select the configuration */

            /* Get the first one */
            Pid = USBD_ParseConfigurationDescriptorEx(&DeviceExtension->HubConfigDescriptor,
                                                      &DeviceExtension->HubConfigDescriptor,
                                                      -1, -1, -1, -1, -1);
            ASSERT(Pid != NULL);
            InterfaceList[0].InterfaceDescriptor = Pid;
            ConfigUrb = USBD_CreateConfigurationRequestEx(&DeviceExtension->HubConfigDescriptor, (PUSBD_INTERFACE_LIST_ENTRY)&InterfaceList);
            ASSERT(ConfigUrb != NULL);
            Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, ConfigUrb, NULL);

            DeviceExtension->ConfigurationHandle = ConfigUrb->UrbSelectConfiguration.ConfigurationHandle;
            DeviceExtension->PipeHandle = ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
            DPRINT1("Configuration Handle %x\n", DeviceExtension->ConfigurationHandle);

            ExFreePool(ConfigUrb);

            Status = DeviceExtension->HubInterface.Initialize20Hub(DeviceExtension->RootHubPdo, DeviceExtension->RootHubUsbDevice, 1);
            DPRINT1("Status %x\n", Status);

            {
                int PortLoop;
                USHORT PortStatusAndChange[2];

                for (PortLoop=0; PortLoop< DeviceExtension->UsbExtHubInfo.NumberOfPorts; PortLoop++)
                {
                    DPRINT1("Port %x\n", PortLoop);
                    UsbBuildVendorRequest(Urb,
                                          URB_FUNCTION_CLASS_OTHER,
                                          sizeof(Urb->UrbControlVendorClassRequest),
                                          USBD_TRANSFER_DIRECTION_IN,
                                          0,
                                          USB_REQUEST_SET_FEATURE,
                                          PORT_POWER,
                                          1,
                                          0,
                                          0,
                                          0,
                                          0);

                    Urb->UrbOSFeatureDescriptorRequest.MS_FeatureDescriptorIndex = PortLoop + 1;
                    Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);

                    DPRINT1("Status %x\n", Status);

                    UsbBuildVendorRequest(Urb,
                                          URB_FUNCTION_CLASS_OTHER,
                                          sizeof(Urb->UrbControlVendorClassRequest),
                                          USBD_TRANSFER_DIRECTION_OUT,
                                          0,
                                          USB_REQUEST_GET_STATUS,
                                          0,
                                          PortLoop + 1,
                                          &PortStatusAndChange,
                                          0,
                                        sizeof(PortStatusAndChange),
                                        0);
                    Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);

                    DPRINT1("Status %x\n", Status);
                    DPRINT1("PortStatus = %x\n", PortStatusAndChange[0]);
                    DPRINT1("PortChange = %x\n", PortStatusAndChange[1]);
                }
            }

            ExFreePool(Urb);
            break;
        }

        case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */
        {
            switch (IrpSp->Parameters.QueryDeviceRelations.Type)
            {
                case BusRelations:
                {
                    PDEVICE_RELATIONS DeviceRelations = NULL;
                    DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");

                    Status = UsbhubFdoQueryBusRelations(DeviceObject, &DeviceRelations);

                    Information = (ULONG_PTR)DeviceRelations;
                    break;
                }
                case RemovalRelations:
                {
                    DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
                    return ForwardIrpAndForget(DeviceObject, Irp);
                }
                default:
                    DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
                        IrpSp->Parameters.QueryDeviceRelations.Type);
                    return ForwardIrpAndForget(DeviceObject, Irp);
            }
            break;
        }
        case IRP_MN_QUERY_BUS_INFORMATION:
        {
            DPRINT1("IRP_MN_QUERY_BUS_INFORMATION\n");
            break;
        }
        case IRP_MN_QUERY_ID:
        {
            DPRINT1("IRP_MN_QUERY_ID\n");
            break;
        }
        case IRP_MN_QUERY_CAPABILITIES:
        {
            DPRINT1("IRP_MN_QUERY_CAPABILITIES\n");
            break;
        }
        default:
        {
            DPRINT1("Usbhub: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
            return ForwardIrpAndForget(DeviceObject, Irp);
        }
    }
    Irp->IoStatus.Information = Information;
    Irp->IoStatus.Status = Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return Status;
}
Exemplo n.º 2
0
NTSTATUS
NTAPI
USBCCGP_ScanConfigurationDescriptor(
    IN OUT PFDO_DEVICE_EXTENSION FDODeviceExtension,
    IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
{
    PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
    ULONG InterfaceIndex = 0;
    ULONG DescriptorCount;

    //
    // sanity checks
    //
    ASSERT(ConfigurationDescriptor);
    ASSERT(ConfigurationDescriptor->bNumInterfaces);

    //
    // count all interface descriptors
    //
    DescriptorCount = ConfigurationDescriptor->bNumInterfaces;

    //
    // allocate array holding the interface descriptors
    //
    FDODeviceExtension->InterfaceList = AllocateItem(NonPagedPool, sizeof(USBD_INTERFACE_LIST_ENTRY) * (DescriptorCount + 1));
    if (!FDODeviceExtension->InterfaceList)
    {
        //
        // no memory
        //
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    do
    {
        //
        // parse configuration descriptor
        //
        InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, InterfaceIndex, -1, -1, -1, -1);
        if (InterfaceDescriptor)
        {
            //
            // store in interface list
            //
            FDODeviceExtension->InterfaceList[FDODeviceExtension->InterfaceListCount].InterfaceDescriptor = InterfaceDescriptor;
            FDODeviceExtension->InterfaceListCount++;
        }
        else
        {
            DumpConfigurationDescriptor(ConfigurationDescriptor);
            DumpFullConfigurationDescriptor(FDODeviceExtension, ConfigurationDescriptor);

            //
            // see issue
            // CORE-6574 Test 3 (USB Web Cam)
            //
            if (FDODeviceExtension->DeviceDescriptor && FDODeviceExtension->DeviceDescriptor->idVendor == 0x0458 && FDODeviceExtension->DeviceDescriptor->idProduct == 0x705f)
                ASSERT(FALSE);
        }

        //
        // move to next interface
        //
        InterfaceIndex++;

    }while(InterfaceIndex < DescriptorCount);

    //
    // sanity check
    //
    ASSERT(FDODeviceExtension->InterfaceListCount);

    //
    // done
    //
    return STATUS_SUCCESS;
}