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

📄 mavioctl.c

📁 基于EP7312的MP3播放器源代码,包括MCU和PC端代码.
💻 C
📖 第 1 页 / 共 5 页
字号:

                //
                // 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;
        }

        //
        // Return invalid parameter for all other IOCTLs.
        //
        default:
        {
            ntStatus = Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
        }
    }

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

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

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

//****************************************************************************
//
// Checks port status; if OK, return success and does nothing more; if bad,
// it attempt to reset the device.
//
// Arguments:
//
//     DeviceObject - pointer to the device object for this instance of the
//                    device.
//
// Return Value:
//
//     NT status code
//
//****************************************************************************
NTSTATUS
MavUsb_ResetDevice(IN PDEVICE_OBJECT DeviceObject)
{
    NTSTATUS ntStatus;
    ULONG portStatus;

    //
    // Check the port state, if it is disabled we will need to re-enable it.
    //
    ntStatus = MavUsb_GetPortStatus(DeviceObject, &portStatus);

    //
    // See if the port is not enabled and is connected, in which case we will
    // reset the parent port.
    //
    if(NT_SUCCESS(ntStatus) && !(portStatus & USBD_PORT_ENABLED) &&
       (portStatus & USBD_PORT_CONNECTED))
    {
        //
        // The port is disabled, attempt to reset the parent port.
        //
        ntStatus = MavUsb_ResetParentPort(DeviceObject);
    }

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

//****************************************************************************
//
// Returns the port status for our device.
//
// Arguments:
//
//     DeviceObject - pointer to the devic eobject for this instance of the
//                    device.
//
//     PortStatus - status of the port.
//
// Return Value:
//
//     STATUS_SUCCESS if successful,
//     STATUS_UNSUCCESSFUL otherwise
//
//****************************************************************************
NTSTATUS
MavUsb_GetPortStatus(IN PDEVICE_OBJECT DeviceObject, IN PULONG PortStatus)
{
    NTSTATUS ntStatus, status = STATUS_SUCCESS;
    PIRP irp;
    KEVENT event;
    IO_STATUS_BLOCK ioStatus;
    PIO_STACK_LOCATION nextStack;
    PDEVICE_EXTENSION deviceExtension;

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

    //
    // Initialize the port status to zero.
    //
    *PortStatus = 0;

    //
    // Initialize an IRP completion event.
    //
    KeInitializeEvent(&event, NotificationEvent, FALSE);

    //
    // IoBuildDeviceIoControlRequest allocates and sets up an IRP for a device
    // control request.
    //
    irp =
        IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_PORT_STATUS,
                                      deviceExtension->TopOfStackDeviceObject,
                                      NULL, 0, NULL, 0, TRUE, &event,
                                      &ioStatus);

    //
    // IoGetNextIrpStackLocation gives a higher level driver access to the
    // next-lower driver's I/O stack location in an IRP so the caller can set
    // it up for the lower driver.
    //
    nextStack = IoGetNextIrpStackLocation(irp);

    //
    // Setup the argument in the IRP stack.
    //
    nextStack->Parameters.Others.Argument1 = PortStatus;

    //
    // Send the IRP to the PDO.
    //
    ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);

    //
    // See if we should wait for the IRP to complete.
    //
    if(ntStatus == STATUS_PENDING)
    {
        //
        // Wait for the IRP to complete.
        //
        KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
    }
    else
    {
        //
        // Set the status in the IO status block.
        //
        ioStatus.Status = ntStatus;
    }

    //
    // USBD maps the error code for us.
    //
    ntStatus = ioStatus.Status;

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

//****************************************************************************
//
// Reset our parent port.
//
// Arguments:
//
//     DeviceObject - pointer to the device object for this instance of the
//                    device.
//
// Return Value:
//
//     STATUS_SUCCESS if successful,
//     STATUS_UNSUCCESSFUL otherwise
//
//****************************************************************************
NTSTATUS
MavUsb_ResetParentPort(IN PDEVICE_OBJECT DeviceObject)
{
    NTSTATUS ntStatus, status = STATUS_SUCCESS;
    PIRP irp;
    KEVENT event;
    IO_STATUS_BLOCK ioStatus;
    PIO_STACK_LOCATION nextStack;
    PDEVICE_EXTENSION deviceExtension;

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

    //
    // Initialize an IRP completion event.
    //
    KeInitializeEvent(&event, NotificationEvent, FALSE);

    //
    // Allocate and setup an IRP for a device control request.
    //
    irp =
        IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_RESET_PORT,
                                      deviceExtension->TopOfStackDeviceObject,
                                      NULL, 0, NULL, 0, TRUE, &event,
                                      &ioStatus);

    //
    // IoGetNextIrpStackLocation gives a higher level driver access to the
    // next-lower driver's I/O stack location in an IRP so the caller can set
    // it up for the lower driver.
    //
    nextStack = IoGetNextIrpStackLocation(irp);

    //
    // Send the IRP to the PDO.
    //
    ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);

    //
    // See if we should wait for the IRP to complete.
    //
    if(ntStatus == STATUS_PENDING)
    {
        //
        // Wait for the IRP to complete.
        //
        KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
    }
    else
    {
        //
        // Set the status in the IO status block.
        //
        ioStatus.Status = ntStatus;
    }

    //
    // USBD maps the error code for us.
    //
    ntStatus = ioStatus.Status;

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

//****************************************************************************
//
// Sends a vendor specific command to the device.
//
// Arguments:
//
//     DeviceObject - pointer to the FDO for this instance of the device.
//
//****************************************************************************
NTSTATUS
MavUsb_SendVendorCommand(IN PDEVICE_OBJECT DeviceObject, IN PURB urb,
                         IN ULONG drive, IN ULONG request, IN USHORT value,
                         IN USHORT index, IN PUCHAR buffer, IN ULONG length)
{
    NTSTATUS ntStatus;

    //
    // Build the vendor request.
    //
    UsbBuildVendorRequest(urb, URB_FUNCTION_VENDOR_DEVICE,
                          sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
                          USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
                          0, (UCHAR)((drive << 5) | request), value, index,
                          buffer, 0, length, 0);

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

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

//****************************************************************************
//
// Performs a bulk transfer to/from the device.
//
//****************************************************************************
NTSTATUS
MavUsb_BulkXfer(IN PDEVICE_OBJECT DeviceObject, IN PUCHAR buffer,
                IN ULONG length, IN BOOLEAN Read)
{
    NTSTATUS ntStatus;
    PDEVICE_EXTENSION deviceExtension;
    PUSBD_INTERFACE_INFORMATION interface;
    USBD_PIPE_HANDLE PipeHandle;
    ULONG siz, flags;
    PURB urb;

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

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

    //
    // Get the pipe info structure for the pipe to be used.
    //
    PipeHandle = interface->Pipes[Read ? 0 : 1].PipeHandle;

    //
    // Get the flags for the transfer.
    //
    if(Read)
    {
        flags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
    }
    else
    {
        flags = USBD_SHORT_TRANSFER_OK;
    }

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

    //
    // Build the bulk transfer URB.
    //
    UsbBuildInterruptOrBulkTransferRequest(urb, (USHORT)siz, PipeHandle,
                                           buffer, NULL, length, flags, NULL);

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

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

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

//****************************************************************************
//
// Sends a "connect" request to the device.
//
//****************************************************************************
NTSTATUS
MavUsb_VendorConnect(IN PDEVICE_OBJECT DeviceObject)
{
    NTSTATUS ntStatus;
    PURB urb;
    ULONG ulTemp;

    //
    // Allocate memory from the non-paged pool for the URB.
    //
    urb = ExAllocatePool(NonPagedPool,
                         sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
    if(!urb)
    {
        return(STATUS_INSUFFICIENT_RESOURCES);
    }

    //
    // Send the "connect" vendor request.
    //
    ntStatus = MavUsb_SendVendorCommand(DeviceObject, urb, 0,
                                        USB_Vendor_Connect, 0, 0,
                                        (PUCHAR)&ulTemp, 4);

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

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

//****************************************************************************
//
// Sends a "disconnect" request to the device.
//
//****************************************************************************
NTSTATUS
MavUsb_VendorDisconnect(IN PDEVICE_OBJECT DeviceObject)
{
    NTSTATUS ntStatus;
    PURB urb;
    ULONG ulTemp;

    //
    // Allocate memory from the non-paged pool for the URB.
    //
    urb = ExAllocatePool(NonPagedPool,
                         sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
    if(!urb)
    {
        return(STATUS_INSUFFICIENT_RESOURCES);
    }

    //
    // Send the "disconnect" vendor request.
    //
    ntStatus = MavUsb_SendVendorCommand(DeviceObject, urb, 0,
                                        USB_Vendor_Disconnect, 0, 0,
                                        (PUCHAR)&ulTemp, 4);

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

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

⌨️ 快捷键说明

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