⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ios.c

📁 usb海量存储的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:

VOID
UMSS_ClassSpecificRequest(
    IN PDEVICE_EXTENSION DeviceExtension,
    IN UCHAR Request,
    IN UCHAR TransferDirection,
    IN PVOID Buffer,
    IN ULONG BufferLength,
    IN PIO_COMPLETION_ROUTINE CompletionRoutine
    )
/*++
Routine Description:

    Sends a class-specific request to the device

    NOTE: Assumes device extension has valid IRP and URB.

 Arguments:

    DeviceExtension - Our device extension.
    Request - Class specific request value.
    TransferDirection - Direction of data transfer.
    Buffer - Address of data buffer to use for data transfer.
    BufferLength - Number of bytes to transfer.
    CompletionRoutine - Function to call when request completes.

Return Value:

    NONE.

--*/

{
    PIRP Irp;
    PURB Urb;
    PIO_STACK_LOCATION NextStack;

    ENTER(UMSS_ClassSpecificRequest);

    Irp = DeviceExtension->Irp;
    Urb = DeviceExtension->Urb;

    // Build URB for the ADSC command
    UsbBuildVendorRequest(
        Urb,
        URB_FUNCTION_CLASS_INTERFACE,
        (USHORT) sizeof (struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
        (DATA_IN == TransferDirection) ? USBD_TRANSFER_DIRECTION_IN : 0,
        0,
        Request,
        0,
        0,
        Buffer,
        NULL,
        BufferLength,
        NULL
        );

    NextStack = IoGetNextIrpStackLocation(Irp);
    UMSS_ASSERT(NextStack != NULL);
    UMSS_ASSERT(DeviceExtension->Fdo->StackSize>1);

    // Initialize our Irp
    NextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
    NextStack->Parameters.Others.Argument1 = Urb;
    NextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;

    // Register our Irp completion handler
    IoSetCompletionRoutine(
        Irp,
        CompletionRoutine,
        DeviceExtension, 
        TRUE,    // invoke on success
        TRUE,    // invoke on error
        TRUE     // invoke on cancellation of the Irp
        );

    // Pass Irp to the USB driver stack
    IoCallDriver(DeviceExtension->TopOfStackDeviceObject, Irp);

    EXIT(UMSS_ClassSpecificRequest);
}


VOID
UMSS_BulkTransfer(
    IN PDEVICE_EXTENSION DeviceExtension,
    IN UCHAR TransferDirection,
    IN PVOID Buffer,
    IN ULONG BufferLength,
    IN PIO_COMPLETION_ROUTINE CompletionRoutine
    )
/*++
Routine Description:

    Initiates a bulk transfer with the USB device.

 Arguments:

    DeviceExtension - Our device extension.
    TransferDirection - Direction of data transfer.
    Buffer - Address of data buffer to use for data transfer.
    BufferLength - Number of bytes to transfer.
    CompletionRoutine - Function to call when request completes.

Return Value:

    NONE

--*/

{
    PIO_STACK_LOCATION NextStack;
    USBD_PIPE_HANDLE PipeHandle;
    PIRP Irp;
    PURB Urb;

    ENTER(UMSS_DoBulkTransfer);

    if (DATA_IN == TransferDirection)
        PipeHandle = DeviceExtension->UsbInterface->Pipes[DeviceExtension->DataInPipe].PipeHandle;
    else
        PipeHandle = DeviceExtension->UsbInterface->Pipes[DeviceExtension->DataOutPipe].PipeHandle;

    Urb = DeviceExtension->Urb;
    Irp = DeviceExtension->Irp;

    // Build a URB for our bulk transfer
    UsbBuildInterruptOrBulkTransferRequest(
        Urb,
        sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER),
        PipeHandle,
        Buffer,
        NULL,
        BufferLength,
        (DATA_OUT == TransferDirection) ? USBD_TRANSFER_DIRECTION_OUT :
                    USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
        NULL
        );

    NextStack = IoGetNextIrpStackLocation(Irp);

    UMSS_ASSERT(NextStack != NULL);
    UMSS_ASSERT(DeviceExtension->Fdo->StackSize>1);

    // Initialize our Irp
    NextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
    NextStack->Parameters.Others.Argument1 = Urb;
    NextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;

    // Register our Irp completion handler
    IoSetCompletionRoutine(
        Irp,
        CompletionRoutine,
        DeviceExtension, 
        TRUE,    // invoke on success
        TRUE,    // invoke on error
        TRUE     // invoke on cancellation of the Irp
        );

    // Pass Irp to the USB driver stack
    IoCallDriver(DeviceExtension->TopOfStackDeviceObject, Irp);

    EXIT(UMSS_DoBulkTransfer);
}

VOID
UMSS_BulkTransfer2(
    IN PDEVICE_EXTENSION DeviceExtension,
    IN UCHAR TransferDirection,
    IN PVOID Buffer,
    IN ULONG BufferLength,
    IN PIO_COMPLETION_ROUTINE CompletionRoutine
    )
/*++
Routine Description:

    Initiates a bulk transfer with the USB device.

 Arguments:

    DeviceExtension - Our device extension.
    TransferDirection - Direction of data transfer.
    Buffer - Address of data buffer to use for data transfer.
    BufferLength - Number of bytes to transfer.
    CompletionRoutine - Function to call when request completes.

Return Value:

    NONE

--*/

{
    PIO_STACK_LOCATION NextStack;
    USBD_PIPE_HANDLE PipeHandle;
    PIRP Irp;
    PURB Urb;

    ENTER(UMSS_DoBulkTransfer);

    if (DATA_IN == TransferDirection)
        PipeHandle = DeviceExtension->UsbInterface->Pipes[DeviceExtension->DataInPipe].PipeHandle;
    else
        PipeHandle = DeviceExtension->UsbInterface->Pipes[DeviceExtension->DataOutPipe].PipeHandle;

    Urb = DeviceExtension->Urb2;
    Irp = DeviceExtension->Irp2;

    // Build a URB for our bulk transfer
    UsbBuildInterruptOrBulkTransferRequest(
        Urb,
        sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER),
        PipeHandle,
        Buffer,
        NULL,
        BufferLength,
        (DATA_OUT == TransferDirection) ? USBD_TRANSFER_DIRECTION_OUT :
                    USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
        NULL
        );

    NextStack = IoGetNextIrpStackLocation(Irp);

    UMSS_ASSERT(NextStack != NULL);
    UMSS_ASSERT(DeviceExtension->Fdo->StackSize>1);

    // Initialize our Irp
    NextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
    NextStack->Parameters.Others.Argument1 = Urb;
    NextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;

    // Register our Irp completion handler
    IoSetCompletionRoutine(
        Irp,
        CompletionRoutine,
        DeviceExtension, 
        TRUE,    // invoke on success
        TRUE,    // invoke on error
        TRUE     // invoke on cancellation of the Irp
        );

    // Pass Irp to the USB driver stack
    IoCallDriver(DeviceExtension->TopOfStackDeviceObject, Irp);

    EXIT(UMSS_DoBulkTransfer);
}

VOID
UMSS_BulkTransfer3(
    IN PDEVICE_EXTENSION DeviceExtension,
    IN UCHAR TransferDirection,
    IN PVOID Buffer,
    IN ULONG BufferLength,
    IN PIO_COMPLETION_ROUTINE CompletionRoutine
    )
/*++
Routine Description:

    Initiates a bulk transfer with the USB device.

 Arguments:

    DeviceExtension - Our device extension.
    TransferDirection - Direction of data transfer.
    Buffer - Address of data buffer to use for data transfer.
    BufferLength - Number of bytes to transfer.
    CompletionRoutine - Function to call when request completes.

Return Value:

    NONE

--*/

{
    PIO_STACK_LOCATION NextStack;
    USBD_PIPE_HANDLE PipeHandle;
    PIRP Irp;
    PURB Urb;

    ENTER(UMSS_DoBulkTransfer);

    if (DATA_IN == TransferDirection)
        PipeHandle = DeviceExtension->UsbInterface->Pipes[DeviceExtension->DataInPipe].PipeHandle;
    else
        PipeHandle = DeviceExtension->UsbInterface->Pipes[DeviceExtension->DataOutPipe].PipeHandle;

    Urb = DeviceExtension->Urb3;
    Irp = DeviceExtension->Irp3;

    // Build a URB for our bulk transfer
    UsbBuildInterruptOrBulkTransferRequest(
        Urb,
        sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER),
        PipeHandle,
        Buffer,
        NULL,
        BufferLength,
        (DATA_OUT == TransferDirection) ? USBD_TRANSFER_DIRECTION_OUT :
                    USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
        NULL
        );

    NextStack = IoGetNextIrpStackLocation(Irp);

    UMSS_ASSERT(NextStack != NULL);
    UMSS_ASSERT(DeviceExtension->Fdo->StackSize>1);

    // Initialize our Irp
    NextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
    NextStack->Parameters.Others.Argument1 = Urb;
    NextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;

    // Register our Irp completion handler
    IoSetCompletionRoutine(
        Irp,
        CompletionRoutine,
        DeviceExtension, 
        TRUE,    // invoke on success
        TRUE,    // invoke on error
        TRUE     // invoke on cancellation of the Irp
        );

    // Pass Irp to the USB driver stack
    IoCallDriver(DeviceExtension->TopOfStackDeviceObject, Irp);

    EXIT(UMSS_DoBulkTransfer);
}


BOOLEAN
UMSS_ScheduleWorkItem(
    PVOID Context,
    UMSS_WORKER_ROUTINE Routine
    )
/*++
Routine Description:

    Wrapper for handling worker thread callbacks

 Arguments:

    Routine - Routine to be called when this work-item is processed
    Context - Value to be passed to worker routine

Return Value:
    TRUE if work item queued
    FALSE if work item not queued

--*/

{
    BOOLEAN RetVal = TRUE;
    PWORK_QUEUE_ITEM WorkItem;
    PUMSS_WORKER_PACKET WorkerPacket;

    ENTER(UMSS_ScheduleWorkItem);

    WorkItem = UMSS_ExAllocatePool(NonPagedPool, sizeof(WORK_QUEUE_ITEM));
    WorkerPacket = UMSS_ExAllocatePool(NonPagedPool, sizeof(UMSS_WORKER_PACKET));     

    if ((WorkItem) && (WorkerPacket))
    {
        WorkerPacket->Routine = Routine;
        WorkerPacket->Context = Context;
        WorkerPacket->WorkItem = WorkItem;

        // Initialize the work-item
        ExInitializeWorkItem(
            WorkItem,
            UMSS_Worker,
            WorkerPacket
            );

        // Schedule the work-item
        ExQueueWorkItem(
            WorkItem,
            DelayedWorkQueue
            );

        UMSS_KdPrint( DBGLVL_MINIMUM,("Work-item queued\n"));
    }
    else
    {
        UMSS_KdPrint( DBGLVL_MINIMUM,("Failed to allocate work-item\n"));

        if (WorkItem)
            UMSS_ExFreePool(WorkItem);

        if (WorkerPacket)
            UMSS_ExFreePool(WorkerPacket);

        RetVal = FALSE;
    }

    RETURN(RetVal, UMSS_ScheduleWorkItem);
}


VOID 
UMSS_Worker(
    IN PVOID Reference
    )
/*++
Routine Description:

    Wrapper for worker thread function.  Handles cleaning up work-item, etc.,
    before calling real worker function.

 Arguments:

    Reference - Context value to be passed to worker function.

Return Value:

    NONE

--*/

{
    PUMSS_WORKER_PACKET WorkerPacket;

    ENTER(UMSS_Worker);

    WorkerPacket = (PUMSS_WORKER_PACKET)Reference;

    WorkerPacket->Routine(WorkerPacket->Context);

    UMSS_ExFreePool(WorkerPacket->WorkItem);
    UMSS_ExFreePool(WorkerPacket);

    EXIT(UMSS_Worker);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -