mavpnp.c

来自「基于EP7312的MP3播放器源代码,包括MCU和PC端代码.」· C语言 代码 · 共 1,065 行 · 第 1/3 页

C
1,065
字号
        // (deviceExtension->RemoveEvent) to enable device removal. This is
        // used in processing for IRP_MN_REMOVE_DEVICE
        //
        MavUsb_IncrementIoCount(deviceObject);
    }

    //
    // Get the version of the USB driver.
    //
    USBD_GetUSBDIVersion(&versionInformation);
    if(NT_SUCCESS(ntStatus))
    {
        NTSTATUS actStat;

        //
        // Try to power down device until IO actually requested.
        //
        actStat = MavUsb_SelfSuspendOrActivate(deviceObject, TRUE);

        //
        // Inidicte that we are done initializing the device.
        //
        deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    }

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

//****************************************************************************
//
// Called from MavUsb_ProcessPnPIrp(), the dispatch routine for IRP_MJ_PNP.
// Initializes a given instance of the device on the USB.  USB client drivers
// such as us set up URBs (USB Request Packets) to send requests to the host
// controller driver (HCD). The URB structure defines a format for all
// possible commands that can be sent to a USB device.  Here, we request the
// device descriptor and store it, and configure the device.
//
// Arguments:
//
//     DeviceObject - pointer to the FDO (Functional Device Object)
//
// Return Value:
//
//     NT status code
//
//****************************************************************************
NTSTATUS
MavUsb_StartDevice(IN PDEVICE_OBJECT DeviceObject)
{
    PDEVICE_EXTENSION deviceExtension;
    NTSTATUS ntStatus;
    PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
    PURB urb;
    ULONG siz1, siz2;

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

    //
    // Allocate memory from the non-paged pool for a URB.
    //
    siz1 = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);
    urb = ExAllocatePool(NonPagedPool, siz1);

    //
    // Make sure we were able to allocate memory.
    //
    if(urb)
    {
        //
        // Allocate memory from the non-paged pool for the device descriptor.
        //
        siz2 = sizeof(USB_DEVICE_DESCRIPTOR);
        deviceDescriptor = ExAllocatePool(NonPagedPool, siz2);

        //
        // Make sure we were able to allocate memory.
        //
        if(deviceDescriptor)
        {
            //
            // Build the get descriptor request in the URB.
            //
            UsbBuildGetDescriptorRequest(urb, (USHORT)siz1,
                                         USB_DEVICE_DESCRIPTOR_TYPE, 0, 0,
                                         deviceDescriptor, NULL, siz2, NULL);

            //
            // Send the URB to the USB driver.
            //
            ntStatus = MavUsb_CallUSBD(DeviceObject, urb);
        }
        else
        {
            //
            // If we got here we failed to allocate deviceDescriptor
            //
            ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        }

        //
        // If the get descriptor was successful, then store the pointer to the
        // device descriptor in the device extension.
        //
        if(NT_SUCCESS(ntStatus))
        {
            deviceExtension->UsbDeviceDescriptor = deviceDescriptor;
        }

        //
        // Otherwise, free the descriptor memory if it was allocated.
        //
        else if(deviceDescriptor)
        {
            ExFreePool(deviceDescriptor);
        }

        //
        // Free the memory for the URB.
        //
        ExFreePool(urb);
    }
    else
    {
        //
        // If we got here we failed to allocate the URB.
        //
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // If we successfully got the device descriptor, then configure the device.
    //
    if(NT_SUCCESS(ntStatus))
    {
        ntStatus = MavUsb_ConfigureDevice(DeviceObject);
    }

    //
    // If the device was configured successfully, then indicate that the device
    // has been started.
    //
    if(NT_SUCCESS(ntStatus))
    {
        deviceExtension->DeviceStarted = TRUE;
    }

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

//****************************************************************************
//
// Called from MavUsb_ProcessPnPIrp() to clean up our device instance's
// allocated buffers and free symbolic links.
//
// Arguments:
//
//     DeviceObject - pointer to the FDO
//
// Return Value:
//
//     NT status code from free symbolic link operation
//
//****************************************************************************
NTSTATUS
MavUsb_RemoveDevice(IN PDEVICE_OBJECT DeviceObject)
{
    PDEVICE_EXTENSION deviceExtension;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    UNICODE_STRING deviceLinkUnicodeString;

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

    //
    // Get the name of the symbolic link.
    //
    RtlInitUnicodeString(&deviceLinkUnicodeString,
                         deviceExtension->DeviceLinkNameBuffer);

    //
    // Remove the GUID-based symbolic link.
    //
    ntStatus = IoSetDeviceInterfaceState(&deviceLinkUnicodeString, FALSE);

    //
    // Free device descriptor structure.
    //
    if(deviceExtension->UsbDeviceDescriptor)
    {
        ExFreePool(deviceExtension->UsbDeviceDescriptor);
        deviceExtension->UsbDeviceDescriptor = NULL;
    }

    //
    // Free up the UsbInterface structure.
    //
    if(deviceExtension->UsbInterface)
    {
        ExFreePool(deviceExtension->UsbInterface);
        deviceExtension->UsbInterface = NULL;
    }

    //
    // Free up the USB config discriptor.
    //
    if(deviceExtension->UsbConfigurationDescriptor)
    {
        ExFreePool(deviceExtension->UsbConfigurationDescriptor);
        deviceExtension->UsbConfigurationDescriptor = NULL;
    }

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

//****************************************************************************
//
// Stops a given instance of the device on the USB.  We basically just tell
// USB this device is now 'unconfigured'
//
// Arguments:
//
//     DeviceObject - pointer to the device object for this instance of the
//                    device
//
// Return Value:
//
//     NT status code
//
//****************************************************************************
NTSTATUS
MavUsb_StopDevice(IN PDEVICE_OBJECT DeviceObject)
{
    PDEVICE_EXTENSION deviceExtension;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PURB urb;
    ULONG siz;

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

    //
    // Send the select configuration urb with a NULL pointer for the
    // configuration handle.  This closes the configuration and puts the device
    // in the 'unconfigured' state.
    //
    siz = sizeof(struct _URB_SELECT_CONFIGURATION);
    urb = ExAllocatePool(NonPagedPool, siz);

    //
    // Make sure we were able to allocate memory.
    //
    if(urb)
    {
        //
        // Build the set configuration request in the URB.
        //
        UsbBuildSelectConfigurationRequest(urb, (USHORT)siz, NULL);

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

        //
        // Free the memory for the URB.
        //
        ExFreePool(urb);
    }
    else
    {
        //
        // If we got here we failed to allocate the URB.
        //
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // If the set configuration was successful, then indicate that the device
    // is not started.
    //
    if(NT_SUCCESS(ntStatus))
    {
        deviceExtension->DeviceStarted = FALSE;
    }

    //
    // The stop request has been handled.
    //
    deviceExtension->StopDeviceRequested = FALSE;

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

//****************************************************************************
//
// Used as a general purpose completion routine so it can signal an event,
// passed as the Context, when the next lower driver is done with the input
// IRP.
//
// This routine is used by both PnP and Power Management logic.
//
// Even though this routine does nothing but set an event, it must be defined
// and prototyped as a completetion routine for use as such.
//
// Arguments:
//
//     DeviceObject - Pointer to the device object for the class device.
//
//     Irp - IRP completed.
//
//     Context - Driver defined context, in this case a pointer to an event.
//
// Return Value:
//
//     The function value is the final status from the operation.
//
//****************************************************************************
NTSTATUS
MavUsb_IrpCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp,
                            IN PVOID Context)
{
    PKEVENT event = Context;

    //
    // Set the input event, with priority increment for the waiting thread and
    // no wait immediately following the set event.
    //
    KeSetEvent(event, 1, FALSE);

    //
    // This routine must return STATUS_MORE_PROCESSING_REQUIRED because we have
    // not yet called IoFreeIrp() on this IRP.
    //
    return(STATUS_MORE_PROCESSING_REQUIRED);
}

⌨️ 快捷键说明

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