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

📄 mavocrw.c

📁 基于EP7312的MP3播放器源代码,包括MCU和PC端代码.
💻 C
📖 第 1 页 / 共 2 页
字号:
        //
        // Increment the number of bytes transferred.
        //
        deviceExtension->StagedBytesTransferred += readsize;
    }

    //
    // Set the number of bytes read in the IRP status.
    //
    Irp->IoStatus.Information = offset;

    //
    // Set the status of the IRP to success.
    //
    Irp->IoStatus.Status = STATUS_SUCCESS;

    //
    // Complete the IRP.
    //
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    //
    // Free our staged URB.
    //
    ExFreePool(urb);

    //
    // Indicate that a staged IO operation is no longer pending.
    //
    deviceExtension->StagedIoPending = FALSE;

    //
    // Decrement the count of pending IRPs.
    //
    MavUsb_DecrementIoCount(DeviceObject);

    //
    // Return success.
    //
    return(STATUS_SUCCESS);
}

//****************************************************************************
//
// This is the IRP_MJ_WRITE routine set in our dispatch table; WriteFile()
// calls from user mode ultimately land here.
//
// Arguments:
//
//     DeviceObject - pointer to the device object for this instance of the
//                    device.
//
//     IRP - pointer to the IRP_MJ_WRITE
//
// Return Value:
//
//     NT status code
//
//****************************************************************************
NTSTATUS
MavUsb_Write(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    PDEVICE_EXTENSION deviceExtension;
    NTSTATUS ntStatus;
    USBD_PIPE_HANDLE pipeHandle;
    PURB urb;
    PMDL mdl;
    PVOID va;
    ULONG size, offset, length, writesize;

    //
    // Set the initial status in the IRP to pending.
    //
    Irp->IoStatus.Information = STATUS_PENDING;

    //
    // Set the initial count of bytes written to zero.
    //
    Irp->IoStatus.Information = 0;

    //
    // Can't accept a new IO request if:
    //  1) device is removed,
    //  2) has never been started,
    //  3) is stopped,
    //  4) has a remove request pending,
    //  5) has a stop device pending
    //
    if(!MavUsb_CanAcceptIoRequests(DeviceObject))
    {
        //
        // Set the status in the IRP to delete pending.
        //
        Irp->IoStatus.Status = STATUS_DELETE_PENDING;

        //
        // Complete the IRP.
        //
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        //
        // Return a delete pending status.
        //
        return(STATUS_DELETE_PENDING);
    }

    //
    // Increment the count of pending IRPs.
    //
    MavUsb_IncrementIoCount(DeviceObject);

    //
    // Get a pointer to the device extension.
    //
    deviceExtension = DeviceObject->DeviceExtension;

    //
    // Get the length of the requested transfer.  The MDL address could be NULL
    // for a zero length request.
    //
    if(Irp->MdlAddress)
    {
        length = MmGetMdlByteCount(Irp->MdlAddress);
    }
    else
    {
        length = 0;
    }

    //
    // If the length of the transfer is zero, then return success.
    //
    if(length == 0)
    {
        //
        // Set the status in the IRP to success.
        //
        Irp->IoStatus.Status = STATUS_SUCCESS;

        //
        // Complete the IRP.
        //
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        //
        // Decrement the count of pending IRPs.
        //
        MavUsb_DecrementIoCount(DeviceObject);

        //
        // Return a success status.
        //
        return(STATUS_SUCCESS);
    }

    //
    // Get the virtual address for the buffer described by the input IRP's MDL.
    //
    va = MmGetMdlVirtualAddress(Irp->MdlAddress);

    //
    // Allocate memory for the URB to be sent to the USB driver.
    //
    urb = ExAllocatePool(NonPagedPool, sizeof(struct _URB) + 4);
    if(!urb)
    {
        //
        // Set the status in the IRP to insufficient resources.
        //
        Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;

        //
        // Complete the IRP.
        //
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        //
        // Decrement the count of pending IRPs.
        //
        MavUsb_DecrementIoCount(DeviceObject);

        //
        // Return an insufficient resources status.
        //
        return(STATUS_INSUFFICIENT_RESOURCES);
    }

    //
    // Indicate that a staged IO operation is pending.
    //
    deviceExtension->StagedIoPending = TRUE;

    //
    // Send write requests to the device until we've sent the entire data
    // buffer.
    //
    offset = 0;
    while(offset != length)
    {
        //
        // Make sure that we can still send IO requests.
        //
        if(!MavUsb_CanAcceptIoRequests(DeviceObject))
        {
            break;
        }

        //
        // Determine the length of the next write.
        //
        if((offset + 16384) > length)
        {
            writesize = length - offset;
        }
        else
        {
            writesize = 16384;
        }

        //
        // Allocate an MDL to describe the portion of the buffer for this bulk
        // transfer.
        //
        mdl = IoAllocateMdl(va, length, FALSE, FALSE, NULL);
        if(!mdl)
        {
            break;
        }

        //
        // Map the next portion of the write buffer to send the data for
        // this write.
        //
        IoBuildPartialMdl(Irp->MdlAddress, mdl, (PUCHAR)va + offset,
                          writesize);

        //
        // Get the pipe handle for the bulk out pipe.
        //
        pipeHandle = deviceExtension->UsbInterface->Pipes[1].PipeHandle;

        //
        // Build the URB for the bulk out transfer request.
        //
        size = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
        UsbBuildInterruptOrBulkTransferRequest(urb, (USHORT)size, pipeHandle,
                                               NULL, mdl, writesize, 0, NULL);

        //
        // Send this bulk out transfer request to the USB driver.
        //
        ntStatus = MavUsb_CallUSBD(DeviceObject, urb);

        //
        // Free the MDL.
        //
        IoFreeMdl(mdl);

        //
        // Stop writing if the bulk out transfer request failed.
        //
        if(!NT_SUCCESS(ntStatus))
        {
            break;
        }

        //
        // Build the URB for the vendor write request.
        //
        size = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
        UsbBuildVendorRequest(urb, URB_FUNCTION_VENDOR_DEVICE, (USHORT)size,
                              USBD_TRANSFER_DIRECTION_IN |
                              USBD_SHORT_TRANSFER_OK, 0, USB_Vendor_Write,
                              (USHORT)writesize, 0, urb + 1, NULL, 4, NULL);

        //
        // Send the vendor write command to the USB driver.
        //
        ntStatus = MavUsb_CallUSBD(DeviceObject, urb);
        if(!NT_SUCCESS(ntStatus))
        {
            break;
        }

        //
        // Get the length of the write from the result of the vendor command.
        //
        writesize = *((ULONG *)(urb + 1));

        //
        // Stop writing if the size of the write is zero.
        //
        if(writesize == 0)
        {
            break;
        }

        //
        // Increment the buffer pointer.
        //
        offset += writesize;

        //
        // Increment the number of bytes transferred.
        //
        deviceExtension->StagedBytesTransferred += writesize;
    }

    //
    // Set the number of bytes read in the IRP status.
    //
    Irp->IoStatus.Information = offset;

    //
    // Set the status of the IRP to success.
    //
    Irp->IoStatus.Status = STATUS_SUCCESS;

    //
    // Complete the IRP.
    //
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    //
    // Free our staged URB.
    //
    ExFreePool(urb);

    //
    // Indicate that a staged IO operation is no longer pending.
    //
    deviceExtension->StagedIoPending = FALSE;

    //
    // Decrement the count of pending IRPs.
    //
    MavUsb_DecrementIoCount(DeviceObject);

    //
    // Return success.
    //
    return(STATUS_SUCCESS);
}

//****************************************************************************
//
// Called as part of sudden device removal handling.  Cancels any pending
// transfers for all open pipes.  If any pipes are still open, call USBD with
// URB_FUNCTION_ABORT_PIPE.  Also marks the pipe 'closed' in our saved
// configuration info.
//
// Arguments:
//
//     Ptrs to our FDO
//
// Return Value:
//
//     NT status code
//
//****************************************************************************
NTSTATUS
MavUsb_AbortPipes(IN PDEVICE_OBJECT DeviceObject)
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PURB urb;
    PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
    ULONG i;
    PUSBD_INTERFACE_INFORMATION interface;

    //
    // If the device is not opened, then we do not need to abort the pipes.
    //
    if(deviceExtension->OpenPipeCount == 0)
    {
        return(STATUS_SUCCESS);
    }

    //
    // Allocate memory for an URB.
    //
    urb = ExAllocatePool(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST));
    if(!urb)
    {
        return(STATUS_INSUFFICIENT_RESOURCES);
    }

    //
    // Get a pointer to the USB interface descriptor.
    //
    interface = deviceExtension->UsbInterface;

    //
    // Loop through all the pipes in the device.
    //
    for(i = 0; i < interface->NumberOfPipes; i++)
    {
        //
        // Build the abort pipe request for the USB driver.
        //
        urb->UrbHeader.Length = (USHORT)sizeof(struct _URB_PIPE_REQUEST);
        urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE;
        urb->UrbPipeRequest.PipeHandle = interface->Pipes[i].PipeHandle;

        //
        // Send the URB to the USB driver.
        //
        ntStatus = MavUsb_CallUSBD(DeviceObject, urb);

        //
        // If the request failed, then stop sending requests.
        //
        if(!NT_SUCCESS(ntStatus))
        {
            break;
        }
    }

    //
    // Free the URB.
    //
    ExFreePool(urb);

    //
    // Return the status.
    //
    return(ntStatus);
}

//****************************************************************************
//
// Check device extension status flags; can't accept a new IO request if
// device:
//     1) is removed,
//     2) has never been started,
//     3) is stopped,
//     4) has a remove request pending, or
//     5) has a stop device pending
//
// Arguments:
//
//     DeviceObject - pointer to the device object for this instance of the
//                    device.
//
// Return Value:
//
//     return TRUE if can accept new IO requests, else FALSE
//
//****************************************************************************
BOOLEAN
MavUsb_CanAcceptIoRequests(IN PDEVICE_OBJECT DeviceObject)
{
    PDEVICE_EXTENSION deviceExtension;
    BOOLEAN fCan = FALSE;

    //
    // Get a pointer to the device extension.
    //
    deviceExtension = DeviceObject->DeviceExtension;

    //
    // We can accept IO requests when:
    //   1) the device is not removed,
    //   2) the device is started,
    //   3) a device remove has not been requested, and
    //   4) a device stop has not been requested.
    //
    if(!deviceExtension->DeviceRemoved &&
       deviceExtension->DeviceStarted &&
       !deviceExtension->RemoveDeviceRequested &&
       !deviceExtension->StopDeviceRequested)
    {
        fCan = TRUE;
    }

    //
    // Return the result.
    //
    return(fCan);
}

⌨️ 快捷键说明

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