Exemple #1
0
NTSTATUS
USBSTOR_FdoHandleStartDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN PFDO_DEVICE_EXTENSION DeviceExtension,
    IN OUT PIRP Irp)
{
    PUSB_INTERFACE_DESCRIPTOR InterfaceDesc;
    NTSTATUS Status;
    UCHAR Index = 0;

    //
    // forward irp to lower device
    //
    Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
    if (!NT_SUCCESS(Status))
    {
        //
        // failed to start
        //
        DPRINT1("USBSTOR_FdoHandleStartDevice Lower device failed to start %x\n", Status);
        return Status;
    }

    //
    // initialize irp queue
    //
    USBSTOR_QueueInitialize(DeviceExtension);

    //
    // first get device & configuration & string descriptor
    //
    Status = USBSTOR_GetDescriptors(DeviceObject);
    if (!NT_SUCCESS(Status))
    {
        //
        // failed to get device descriptor
        //
        DPRINT1("USBSTOR_FdoHandleStartDevice failed to get device descriptor with %x\n", Status);
        return Status;
    }

    //
    // dump device descriptor
    //
    USBSTOR_DumpDeviceDescriptor(DeviceExtension->DeviceDescriptor);

    //
    // Check that this device uses bulk transfers and is SCSI
    //
    InterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)DeviceExtension->ConfigurationDescriptor + sizeof(USB_CONFIGURATION_DESCRIPTOR));

    //
    // sanity check
    //
    ASSERT(InterfaceDesc->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);
    ASSERT(InterfaceDesc->bLength == sizeof(USB_INTERFACE_DESCRIPTOR));

    DPRINT("bInterfaceSubClass %x\n", InterfaceDesc->bInterfaceSubClass);
    if (InterfaceDesc->bInterfaceProtocol != 0x50)
    {
        DPRINT1("USB Device is not a bulk only device and is not currently supported\n");
        return STATUS_NOT_SUPPORTED;
    }

    if (InterfaceDesc->bInterfaceSubClass != 0x06)
    {
        //
        // FIXME: need to pad CDBs to 12 byte
        // mode select commands must be translated from 1AH / 15h to 5AH / 55h
        //
        DPRINT1("[USBSTOR] Error: need to pad CDBs\n");
        return STATUS_NOT_IMPLEMENTED;
    }

    //
    // now select an interface
    //
    Status = USBSTOR_SelectConfigurationAndInterface(DeviceObject, DeviceExtension);
    if (!NT_SUCCESS(Status))
    {
        //
        // failed to get device descriptor
        //
        DPRINT1("USBSTOR_FdoHandleStartDevice failed to select configuration / interface with %x\n", Status);
        return Status;
    }

    //
    // check if we got a bulk in + bulk out endpoint
    //
    Status = USBSTOR_GetPipeHandles(DeviceExtension);
    if (!NT_SUCCESS(Status))
    {
        //
        // failed to get pipe handles descriptor
        //
        DPRINT1("USBSTOR_FdoHandleStartDevice no pipe handles %x\n", Status);
        return Status;
    }

    //
    // get num of lun which are supported
    //
    Status = USBSTOR_GetMaxLUN(DeviceExtension->LowerDeviceObject, DeviceExtension);
    if (!NT_SUCCESS(Status))
    {
        //
        // failed to get max LUN
        //
        DPRINT1("USBSTOR_FdoHandleStartDevice failed to get max lun %x\n", Status);
        return Status;
    }

    //
    // now create for each LUN a device object, 1 minimum
    //
    do
    {
        //
        // create pdo
        //
        Status = USBSTOR_CreatePDO(DeviceObject, Index);

        //
        // check for failure
        //
        if (!NT_SUCCESS(Status))
        {
            //
            // failed to create child pdo
            //
            DPRINT1("USBSTOR_FdoHandleStartDevice USBSTOR_CreatePDO failed for Index %lu with Status %x\n", Index, Status);
            return Status;
        }

        //
        // increment pdo index
        //
        Index++;
        DeviceExtension->InstanceCount++;

    }while(Index < DeviceExtension->MaxLUN);

#if 0
    //
    // finally get usb device interface
    //
    Status = USBSTOR_GetBusInterface(DeviceExtension->LowerDeviceObject, &DeviceExtension->BusInterface);
    if (!NT_SUCCESS(Status))
    {
        //
        // failed to device interface
        //
        DPRINT1("USBSTOR_FdoHandleStartDevice failed to get device interface %x\n", Status);
        return Status;
    }
#endif


    //
    // start the timer
    //
    //IoStartTimer(DeviceObject);


    //
    // fdo is now initialized
    //
    DPRINT("USBSTOR_FdoHandleStartDevice FDO is initialized\n");
    return STATUS_SUCCESS;
}
Exemple #2
0
NTSTATUS
USBSTOR_FdoHandleDeviceRelations(
    IN PFDO_DEVICE_EXTENSION DeviceExtension,
    IN OUT PIRP Irp)
{
    ULONG DeviceCount = 0;
    LONG Index;
    PDEVICE_RELATIONS DeviceRelations;
    PIO_STACK_LOCATION IoStack;

    //
    // get current irp stack location
    //
    IoStack = IoGetCurrentIrpStackLocation(Irp);

    //
    // check if relation type is BusRelations
    //
    if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations)
    {
        //
        // FDO always only handles bus relations
        //
        return USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
    }

    //
    // go through array and count device objects
    //
    for (Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++)
    {
        if (DeviceExtension->ChildPDO[Index])
        {
            //
            // child pdo
            //
            DeviceCount++;
        }
    }

    //
    // allocate device relations
    //
    DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS) + (DeviceCount > 1 ? (DeviceCount-1) * sizeof(PDEVICE_OBJECT) : 0));
    if (!DeviceRelations)
    {
        //
        // no memory
        //
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // add device objects
    //
    for(Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++)
    {
        if (DeviceExtension->ChildPDO[Index])
        {
            //
            // store child pdo
            //
            DeviceRelations->Objects[DeviceRelations->Count] = DeviceExtension->ChildPDO[Index];

            //
            // add reference
            //
            ObReferenceObject(DeviceExtension->ChildPDO[Index]);

            //
            // increment count
            //
            DeviceRelations->Count++;
        }
    }

    //
    // store result
    //
    Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;

    //
    // request completed successfully
    //
    return STATUS_SUCCESS;
}
Exemple #3
0
NTSTATUS
USBSTOR_PdoHandlePnp(
    IN PDEVICE_OBJECT DeviceObject,
    IN OUT PIRP Irp)
{
    PIO_STACK_LOCATION IoStack;
    PPDO_DEVICE_EXTENSION DeviceExtension;
    NTSTATUS Status;
    PDEVICE_CAPABILITIES Caps;
    ULONG bDelete;

    //
    // get current stack location
    //
    IoStack = IoGetCurrentIrpStackLocation(Irp);

    //
    // get device extension
    //
    DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    //
    // sanity check
    //
    ASSERT(DeviceExtension->Common.IsFDO == FALSE);

    switch(IoStack->MinorFunction)
    {
    case IRP_MN_QUERY_DEVICE_RELATIONS:
    {
        Status = USBSTOR_PdoHandleDeviceRelations(DeviceObject, Irp);
        break;
    }
    case IRP_MN_QUERY_DEVICE_TEXT:
    {
        Status = USBSTOR_PdoHandleQueryDeviceText(DeviceObject, Irp);
        break;
    }
    case IRP_MN_QUERY_ID:
    {
        if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
        {
            //
            // handle query device id
            //
            Status = USBSTOR_PdoHandleQueryDeviceId(DeviceObject, Irp);
            break;
        }
        else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
        {
            //
            // handle instance id
            //
            Status = USBSTOR_PdoHandleQueryHardwareId(DeviceObject, Irp);
            break;
        }
        else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
        {
            //
            // handle instance id
            //
            Status = USBSTOR_PdoHandleQueryInstanceId(DeviceObject, Irp);
            break;
        }
        else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
        {
            //
            // handle instance id
            //
            Status = USBSTOR_PdoHandleQueryCompatibleId(DeviceObject, Irp);
            break;
        }

        DPRINT1("USBSTOR_PdoHandlePnp: IRP_MN_QUERY_ID IdType %x unimplemented\n", IoStack->Parameters.QueryId.IdType);
        Status = STATUS_NOT_SUPPORTED;
        Irp->IoStatus.Information = 0;
        break;
    }
    case IRP_MN_REMOVE_DEVICE:
    {
        DPRINT("IRP_MN_REMOVE_DEVICE\n");

        if(*DeviceExtension->PDODeviceObject != NULL)
        {
            //
            // clear entry in FDO pdo list
            //
            *DeviceExtension->PDODeviceObject = NULL;
            bDelete = TRUE;
        }
        else
        {
            //
            // device object already marked for deletion
            //
            bDelete = FALSE;
        }

        /* Complete the IRP */
        Irp->IoStatus.Status = STATUS_SUCCESS;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        if (bDelete)
        {
            /* Delete the device object */
            IoDeleteDevice(DeviceObject);
        }
        return STATUS_SUCCESS;
    }
    case IRP_MN_QUERY_CAPABILITIES:
    {
        //
        // just forward irp to lower device
        //
        Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp);
        ASSERT(Status == STATUS_SUCCESS);

        if (NT_SUCCESS(Status))
        {
            //
            // check if no unique id
            //
            Caps = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities;
            Caps->UniqueID = FALSE; // no unique id is supported
            Caps->Removable = TRUE; //FIXME
        }
        break;
    }
    case IRP_MN_QUERY_REMOVE_DEVICE:
    case IRP_MN_QUERY_STOP_DEVICE:
    {
#if 0
        //
        // if we're not claimed it's ok
        //
        if (DeviceExtension->Claimed)
#else
        if (TRUE)
#endif
        {
            Status = STATUS_UNSUCCESSFUL;
            DPRINT1("[USBSTOR] Request %x fails because device is still claimed\n", IoStack->MinorFunction);
        }
        else
            Status = STATUS_SUCCESS;
        break;
    }
    case IRP_MN_START_DEVICE:
    {
        //
        // no-op for PDO
        //
        Status = STATUS_SUCCESS;
        break;
    }
    case IRP_MN_SURPRISE_REMOVAL:
    {
        Status = STATUS_SUCCESS;
        break;
    }
    default:
    {
        //
        // do nothing
        //
        Status = Irp->IoStatus.Status;
    }
    }

    //
    // complete request
    //
    if (Status != STATUS_PENDING)
    {
        //
        // store result
        //
        Irp->IoStatus.Status = Status;

        //
        // complete request
        //
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }

    //
    // done processing
    //
    return Status;
}