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

📄 mavioctl.c

📁 基于EP7312的MP3播放器源代码,包括MCU和PC端代码.
💻 C
📖 第 1 页 / 共 5 页
字号:
//****************************************************************************
//
// MAVIOCTL.C - IOCTL handler for the Maverick(tm) USB driver.
//
// Copyright (c) 2000 Cirrus Logic, Inc.
// Copyright (c) 1997-1998 Microsoft Corporation.  All Rights Reserved.
//   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//   KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//   IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
//   PURPOSE.
//
//****************************************************************************
#include "wdm.h"
#include "usbdi.h"
#include "usbdlib.h"
#include "mavusb.h"
#include "mavproto.h"
#include "../../player/usbven.h"

//****************************************************************************
//
// Dispatch table handler for IRP_MJ_DEVICE_CONTROL; handles DeviceIoControl()
// calls from User mode.
//
// Arguments:
//
//     DeviceObject - pointer to the FDO for this instance of the device.
//
//     Irp - pointer to the IRP
//
// Return Value:
//
//     NT status code
//
//****************************************************************************
NTSTATUS
MavUsb_ProcessIOCTL(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    PIO_STACK_LOCATION irpStack;
    PVOID ioBuffer;
    ULONG inputBufferLength;
    ULONG outputBufferLength;
    PDEVICE_EXTENSION deviceExtension;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    ULONG length;
    PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor;

    //
    // Increment the pending IRP count.
    //
    MavUsb_IncrementIoCount(DeviceObject);

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

    //
    // 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 to delete pending.
        //
        ntStatus = STATUS_DELETE_PENDING;

        //
        // Set the status in the IRP.
        //
        Irp->IoStatus.Status = ntStatus;
        Irp->IoStatus.Information = 0;

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

        //
        // Decrement the pending IRP count.
        //
        MavUsb_DecrementIoCount(DeviceObject);

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

    //
    // Get a pointer to the current location on the IRP stack.
    //
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    //
    // Set the default status to success.
    //
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    //
    // Get pointers and lengths of the caller's (user's) IO buffer.
    //
    ioBuffer = Irp->AssociatedIrp.SystemBuffer;
    inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outputBufferLength =
        irpStack->Parameters.DeviceIoControl.OutputBufferLength;

    //
    // Determine which IOCTL we were sent.
    //
    switch(irpStack->Parameters.DeviceIoControl.IoControlCode)
    {
        //
        // Reset the given pipe.
        //
        case IOCTL_MAVUSB_RESET_PIPE:
        {
            PUSBD_PIPE_INFORMATION pipe;
            PFILE_OBJECT fileObject;

            //
            // Get our context and see if it is a pipe.
            //
            fileObject = irpStack->FileObject;
            pipe = (PUSBD_PIPE_INFORMATION)fileObject->FsContext;

            //
            // See if this is a pipe.
            //
            if(pipe == NULL)
            {
                //
                // Error, this is not a pipe.
                //
                ntStatus = Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
            }
            else
            {
                //
                // Reset the pipe.
                //
                MavUsb_ResetPipe(DeviceObject, pipe);
            }

            //
            // We're done handling this IOCTL.
            //
            break;
        }

        //
        // Get a copy of the configuration descriptor and all endpoint and
        // interface descriptors.
        //
        case IOCTL_MAVUSB_GET_CONFIG_DESCRIPTOR:
        {
            //
            // Get a copy of the configuration descriptor pointer.
            //
            configurationDescriptor =
                deviceExtension->UsbConfigurationDescriptor;

            //
            // See if there is a configuration descriptor.
            //
            if(configurationDescriptor)
            {
                //
                // Get the length of the configuration descriptor.
                //
                length = configurationDescriptor->wTotalLength;

                //
                // See if there is enough space in the output buffer for the
                // entire configuration descriptor.
                //
                if(outputBufferLength >= length)
                {
                    //
                    // Copy the configuration descriptor into the output
                    // buffer.
                    //
                    RtlCopyMemory(ioBuffer, configurationDescriptor, length);

                    //
                    // Return the actual length in the IRP.
                    //
                    Irp->IoStatus.Information = length;
                }
                else
                {
                    //
                    // There is not enough space in the output buffer, so
                    // return an invalid parameter status.
                    //
                    ntStatus = Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
                    Irp->IoStatus.Information = 0;
                }
            }
            else
            {
                //
                // There is no configuration descriptor, so return a device
                // data error.
                //
                ntStatus = Irp->IoStatus.Status = STATUS_DEVICE_DATA_ERROR;
                Irp->IoStatus.Information = 0;
            }

            //
            // We're done with the IOCTL.
            //
            break;
        }

        //
        // Reset the device.
        //
        case IOCTL_MAVUSB_RESET_DEVICE:
        {
            //
            // Reset the device.
            //
            ntStatus = Irp->IoStatus.Status = MavUsb_ResetDevice(DeviceObject);

            //
            // We're done with this IOCTL.
            //
            break;
        }

        //
        // Send a vendor command to the device.
        //
        case IOCTL_MAVUSB_DEVICE_REQUEST:
        {
            //
            // Process the IRP.
            //
            ntStatus = Irp->IoStatus.Status =
                MavUsb_VendorCommand(DeviceObject, Irp, irpStack);

            //
            // We're done with this IOCTL.
            //
            break;
        }

        //
        // Reset the count of bytes transferred.
        //
        case IOCTL_MAVUSB_RESET_TRANSFER_COUNT:
        {
            //
            // Reset the transfer count.
            //
            deviceExtension->StagedBytesTransferred = 0;

            //
            // The status is success.
            //
            ntStatus = Irp->IoStatus.Status = STATUS_SUCCESS;

            //
            // We're done with this IOCTL.
            //
            break;
        }

        //
        // Get the current count of bytes transferred.
        //
        case IOCTL_MAVUSB_GET_TRANSFER_COUNT:
        {
            //
            // Get the transfer count.
            //
            *((PULONG)ioBuffer) = deviceExtension->StagedBytesTransferred;

            //
            // The length of the return is 4.
            //
            Irp->IoStatus.Information = 4;

            //
            // The status is success.
            //
            ntStatus = Irp->IoStatus.Status = STATUS_SUCCESS;

            //
            // We're done with this IOCTL.
            //
            break;
        }

        //
        // Get the name of the device.
        //
        case IOCTL_MAVUSB_GET_NAME:
        {
            unsigned char *pucBuffer = ioBuffer;
            int size, index;
            PURB urb;

            //
            // Allocate memory for a URB.
            //
            size = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
            urb = ExAllocatePool(NonPagedPool, size);
            if(!urb)
            {
                ntStatus = Irp->IoStatus.Status =
                    STATUS_INSUFFICIENT_RESOURCES;
                break;
            }

            //
            // Get the index of the product description string.
            //
            index = deviceExtension->UsbDeviceDescriptor->iProduct;

            //
            // Make sure that there is a product description string.
            //
            if(index == 0)
            {
                ntStatus = Irp->IoStatus.Status =
                    STATUS_INVALID_PARAMETER;
                break;
            }

            //
            // Build the get descriptor request URB.
            //
            UsbBuildGetDescriptorRequest(urb, (USHORT)size,
                                         USB_STRING_DESCRIPTOR_TYPE,
                                         (UCHAR)index, 0x0409, pucBuffer, NULL,
                                         outputBufferLength, NULL);

            //
            // Send the URB to the USB driver.
            //
            ntStatus = Irp->IoStatus.Status =
                MavUsb_CallUSBD(DeviceObject, urb);

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

            //
            // See if the request succeeded.
            //
            if(NT_SUCCESS(ntStatus))
            {
                //
                // Determine the length of the string.
                //
                if(pucBuffer[0] > outputBufferLength)
                {
                    size = outputBufferLength - 2;
                }
                else
                {
                    size = pucBuffer[0] - 2;
                }

                //
                // Copy the string to the beginning of the buffer, blasting the
                // two byte USB string descriptor header.
                //
                RtlCopyMemory(pucBuffer, pucBuffer + 2, size);

                //
                // Place an end-of-string character at the end of the string
                // in the buffer.
                //
                pucBuffer[size] = 0;
                pucBuffer[size + 1] = 0;

                //
                // Return the length of the string.
                //
                Irp->IoStatus.Information = size + 2;
            }

            //
            // We're done with this IOCTL.
            //
            break;
        }

        //
        // Get the name of the device manufacturer.
        //
        case IOCTL_MAVUSB_GET_MANUFACTURER_NAME:
        {
            unsigned char *pucBuffer = ioBuffer;
            int size, index;
            PURB urb;

            //
            // Allocate memory for a URB.
            //
            size = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
            urb = ExAllocatePool(NonPagedPool, size);
            if(!urb)
            {
                ntStatus = Irp->IoStatus.Status =
                    STATUS_INSUFFICIENT_RESOURCES;
                break;
            }

            //
            // Get the index of the product description string.
            //
            index = deviceExtension->UsbDeviceDescriptor->iManufacturer;

            //
            // Make sure that there is a product description string.
            //
            if(index == 0)
            {
                ntStatus = Irp->IoStatus.Status =
                    STATUS_INVALID_PARAMETER;
                break;
            }

            //
            // Build the get descriptor request URB.
            //
            UsbBuildGetDescriptorRequest(urb, (USHORT)size,
                                         USB_STRING_DESCRIPTOR_TYPE,
                                         (UCHAR)index, 0x0409, pucBuffer, NULL,
                                         outputBufferLength, NULL);

            //
            // Send the URB to the USB driver.
            //
            ntStatus = Irp->IoStatus.Status =
                MavUsb_CallUSBD(DeviceObject, urb);

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

            //
            // See if the request succeeded.
            //
            if(NT_SUCCESS(ntStatus))
            {
                //
                // Determine the length of the string.
                //
                if(pucBuffer[0] > outputBufferLength)
                {
                    size = outputBufferLength - 2;
                }
                else
                {
                    size = pucBuffer[0] - 2;
                }

⌨️ 快捷键说明

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