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

📄 mavpnp.c

📁 基于EP7312的MP3播放器源代码,包括MCU和PC端代码.
💻 C
📖 第 1 页 / 共 3 页
字号:
            // quickly failed.
            //
            deviceExtension->RemoveDeviceRequested = TRUE;

            //
            // Wait for any io request pending in our driver to complete before
            // returning success.  This event is set when
            // deviceExtension->PendingIoCount goes to 1.
            //
            KeWaitForSingleObject(&deviceExtension->NoPendingIoEvent,
                                  Suspended, KernelMode, FALSE, NULL);

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

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

        //
        // The PnP Manager uses this IRP to inform the drivers for a device
        // that the device will not be removed.
        //
        case IRP_MN_CANCEL_REMOVE_DEVICE:
        {
            //
            // It is sent only after a successful IRP_MN_QUERY_REMOVE_DEVICE.
            //
            if(!deviceExtension->DeviceStarted)
            {
                //
                // If we've never been started, just pass it on.
                //
                IoSkipCurrentIrpStackLocation(Irp);
                ntStatus =
                    IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);

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

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

            //
            // Reset this flag so new IOCTL and IO IRP processing will be
            // re-enabled.
            //
            deviceExtension->RemoveDeviceRequested = FALSE;

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

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

        //
        // For a surprise-style device removal (i.e. sudden cord yank), the
        // physical device has already been removed so the PnP Manager sends
        // the remove IRP without a prior query-remove.  A device can be in any
        // state when it receives a remove IRP as a result of a surprise-style
        // removal.
        //
        case IRP_MN_SURPRISE_REMOVAL:
        {
            //
            // Match the increment at the begining of the dispatch routine.
            //
            MavUsb_DecrementIoCount(DeviceObject);

            //
            // Once DeviceRemoved is set no new IOCTL or read/write IRPs will
            // be passed down the stack to lower drivers; all will be quickly
            // failed.
            //
            deviceExtension->DeviceRemoved = TRUE;

            //
            // If any pipes are still open, call USBD with
            // URB_FUNCTION_ABORT_PIPE.  This call will also close the pipes;
            // if any user close calls get through, they will be noops.
            //
            MavUsb_AbortPipes(DeviceObject);

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

            //
            // We don't explicitly wait for the below driver to complete, but
            // just make the call and go on, finishing cleanup.
            //
            IoCopyCurrentIrpStackLocationToNext(Irp);
            ntStatus = IoCallDriver(stackDeviceObject, Irp);

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

        //
        // The PnP Manager uses this IRP to direct drivers to remove a device.
        // For a "polite" device removal, the PnP Manager sends an
        // IRP_MN_QUERY_REMOVE_DEVICE prior to the remove IRP.  In this case,
        // the device is in the remove-pending state when the remove IRP
        // arrives.  For a surprise-style device removal (i.e. sudden cord
        // yank), the physical device has already been removed and the PnP
        // Manager may not have sent IRP_MN_SURPRISE_REMOVAL.  A device can be
        // in any state when it receives a remove IRP as a result of a
        // surprise-style removal.
        //
        case IRP_MN_REMOVE_DEVICE:
        {
            //
            // Match the increment at the begining of the dispatch routine.
            //
            MavUsb_DecrementIoCount(DeviceObject);

            //
            // Once DeviceRemoved is set no new IOCTL or read/write IRPs will
            // be passed down the stack to lower drivers; all will be quickly
            // failed.
            //
            deviceExtension->DeviceRemoved = TRUE;

            //
            // If any pipes are still open, call USBD with
            // URB_FUNCTION_ABORT_PIPE.  This call will also close the pipes;
            // if any user close calls get through, they will be noops.
            //
            MavUsb_AbortPipes(DeviceObject);

            //
            // We don't explicitly wait for the below driver to complete, but
            // just make the call and go on, finishing cleanup.
            //
            IoCopyCurrentIrpStackLocationToNext(Irp);
            ntStatus = IoCallDriver(stackDeviceObject, Irp);

            //
            // The final decrement to device extension PendingIoCount == 0
            // will set deviceExtension->RemoveEvent, enabling device removal.
            // If there is no pending IO at this point, the below decrement
            // will be it.
            //
            MavUsb_DecrementIoCount(DeviceObject);

            //
            // Wait for any io request pending in our driver to complete before
            // finishing the remove.
            //
            KeWaitForSingleObject(&deviceExtension->RemoveEvent, Suspended,
                                  KernelMode, FALSE, NULL);

            //
            // Delete the link and FDO we created.
            //
            MavUsb_RemoveDevice(DeviceObject);

            //
            // Detach from the PDO.
            //
            IoDetachDevice(deviceExtension->TopOfStackDeviceObject);

            //
            // Delete our FDO.
            //
            IoDeleteDevice(DeviceObject);

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

        //
        // Handle all other IRPs.
        //
        default:
        {
            //
            // In this case we must not touch the status. As ntstatus is
            // STATUS_SUCCESS, we will skip the failure case and pass down the
            // IRP untouched.
            //
        }
    }

    //
    // Handle any error conditions.
    //
    if(!NT_SUCCESS(ntStatus))
    {
        //
        // Set the status in the IRP.
        //
        Irp->IoStatus.Status = ntStatus;

        //
        // Complete the IRP without passing it down.
        //
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

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

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

    //
    // Prepare to send the IRP down by copying it to the next location on the
    // IRP stack.
    //
    IoCopyCurrentIrpStackLocationToNext(Irp);

    //
    // All PNP_POWER messages get passed to the TopOfStackDeviceObject we were
    // given in PnPAddDevice
    //
    ntStatus = IoCallDriver(stackDeviceObject, Irp);

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

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

//****************************************************************************
//
// This routine is called to create and initialize our Functional Device
// Object (FDO).  For monolithic drivers, this is done in DriverEntry(), but
// Plug and Play devices wait for a PnP event.
//
// Arguments:
//
//     DriverObject - pointer to the driver object for this instance
//
//     PhysicalDeviceObject - pointer to a device object created by the bus
//
// Return Value:
//
//     STATUS_SUCCESS if successful,
//     STATUS_UNSUCCESSFUL otherwise
//
//****************************************************************************
NTSTATUS
MavUsb_PnPAddDevice(IN PDRIVER_OBJECT DriverObject,
             IN PDEVICE_OBJECT PhysicalDeviceObject)
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PDEVICE_OBJECT deviceObject = NULL;
    PDEVICE_EXTENSION deviceExtension;
    USBD_VERSION_INFORMATION versionInformation;
    ULONG i;

    //
    // Create our funtional device object (FDO).
    //
    ntStatus = MavUsb_CreateDeviceObject(DriverObject, PhysicalDeviceObject,
                                         &deviceObject);
    if(NT_SUCCESS(ntStatus))
    {
        //
        // Get the pointer to the device extension.
        //
        deviceExtension = deviceObject->DeviceExtension;

        //
        // We support direct io for read/write.
        //
        deviceObject->Flags |= DO_DIRECT_IO;

        //
        // Set this flag causes the driver to not receive a IRP_MN_STOP_DEVICE
        // during suspend and also not get an IRP_MN_START_DEVICE during
        // resume.  This is neccesary because during the start device call,
        // the GetDescriptors() call will be failed by the USB stack.
        //
        deviceObject->Flags |= DO_POWER_PAGABLE;

        //
        // Initialize our device extension.  Remember the physical device
        // object.
        //
        deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;

        //
        // Attach to the PDO.
        //
        deviceExtension->TopOfStackDeviceObject =
            IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject);

        //
        // Get a copy of the physical device's capabilities into a
        // DEVICE_CAPABILITIES struct in our device extension;
        // We are most interested in learning which system power states
        // are to be mapped to which device power states for handling
        // IRP_MJ_SET_POWER IRPs.
        //
        MavUsb_QueryCapabilities(deviceExtension->TopOfStackDeviceObject,
                                 &deviceExtension->DeviceCapabilities);

        //
        // We want to determine what level to auto-powerdown to; this is the
        // lowest sleeping level that is LESS than D3; if all are set to D3,
        // auto powerdown/powerup will be disabled.
        //
        deviceExtension->PowerDownLevel = PowerDeviceUnspecified;
        for(i = PowerSystemSleeping1; i <= PowerSystemSleeping3; i++)
        {
            if(deviceExtension->DeviceCapabilities.DeviceState[i] <
               PowerDeviceD3)
            {
                deviceExtension->PowerDownLevel =
                    deviceExtension->DeviceCapabilities.DeviceState[i];
            }
        }

        //
        // We keep a pending IO count (extension->PendingIoCount) in the
        // device extension.  The first increment of this count is done on
        // adding the device.  Subsequently, the count is incremented for each
        // new IRP received and decremented when each IRP is completed or
        // passed on.
        //
        // Transition to 'one' therefore indicates no IO is pending and signals
        // deviceExtension->NoPendingIoEvent. This is needed for processing
        // IRP_MN_QUERY_REMOVE_DEVICE
        //
        // Transition to 'zero' signals an event

⌨️ 快捷键说明

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