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

📄 power.c

📁 基于DDK的驱动间同步调用测试示例程序,DriverA是目标驱动,DriverB是主驱动,test是MFC测试示例
💻 C
📖 第 1 页 / 共 3 页
字号:
// power.c
//
// Generated by C DriverWizard 3.2.0 (Build 2485)
// Requires DDK Only
// File created on 3/11/2009
//

#include "pch.h"
#ifdef DRIVERA_WMI_TRACE
#include "power.tmh"
#endif

///////////////////////////////////////////////////////////////////////////////////////////////////
//  DriverAPowerDispatch 
//      Dispatch routine for IRPs of IRP_MJ_POWER type
//
//  Arguments:
//      IN  DeviceObject
//              Device object for our driver
//
//      IN  Irp
//              The power IRP to handle
//
//  Return Value:
//      Status
//
NTSTATUS DriverAPowerDispatch(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
{
    PDRIVERA_DEVICE_EXTENSION    deviceExtension;
    NTSTATUS                        status;
    PIO_STACK_LOCATION              irpStack;

    DriverADebugPrint(DBG_POWER, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);

    DriverADumpIrp(Irp);

    // Get our current IRP stack location
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    // Get our device extension
    deviceExtension = (PDRIVERA_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    // check if device has been removed
    if (!DriverAAcquireRemoveLock(deviceExtension))
    {
        status = STATUS_NO_SUCH_DEVICE;

        PoStartNextPowerIrp(Irp);
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        DriverADebugPrint(DBG_POWER, DBG_WARN, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

        return status;
    }

    // If our device has not been started, we just pass the 
    // power requests down the stack
    if (deviceExtension->PnpState == PnpStateNotStarted) 
    {
        PoStartNextPowerIrp(Irp);
        IoSkipCurrentIrpStackLocation(Irp);

        status = PoCallDriver(deviceExtension->LowerDeviceObject, Irp);

        // Release Remove Lock
        DriverAReleaseRemoveLock(deviceExtension);

        DriverADebugPrint(DBG_POWER, DBG_WARN, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

        return status;
    }

    // Determine the power IRP type
    switch(irpStack->MinorFunction)
    {
    case IRP_MN_QUERY_POWER:

        if (irpStack->Parameters.Power.Type == SystemPowerState)
        {
            // Handle the system power IRP case
            status = DriverASystemPowerDispatch(deviceExtension, Irp);
        }
        else
        {
            // Handle the device power IRP case here

            // we should only get a query when going to a less or same powered state
            ASSERT(irpStack->Parameters.Power.State.DeviceState >= deviceExtension->DevicePowerState);

            // If the query is for our current state, just return SUCCESS
            if (irpStack->Parameters.Power.State.DeviceState == deviceExtension->DevicePowerState)
            {
                // Let the power manager know we can handle new device power IRPs
                PoStartNextPowerIrp(Irp);

                // forward the IRP down the stack
                IoSkipCurrentIrpStackLocation(Irp);
                Irp->IoStatus.Status = STATUS_SUCCESS;
                
                status = PoCallDriver(deviceExtension->LowerDeviceObject, Irp);

                // Adjust our power IRP count
                DriverAReleaseRemoveLock(deviceExtension);
            }
            else
            {
                // Save off our device power IRP
                deviceExtension->DevicePowerIrp = Irp;

                // Mark the IRP pending
                IoMarkIrpPending(Irp);
                status = STATUS_PENDING;

                // handle device power IRP at PASSIVE_LEVEL
                if (KeGetCurrentIrql() < DISPATCH_LEVEL)
                {
                    DriverAPowerDownPrepCallback(DeviceObject, deviceExtension);
                }
                else
                {
                    IoQueueWorkItem(
                        deviceExtension->PowerWorkItem,
                        DriverAPowerDownPrepCallback,
                        DelayedWorkQueue,
                        deviceExtension
                        );
                }
            }
        }
        break;
    case IRP_MN_SET_POWER:

        if (irpStack->Parameters.Power.Type == SystemPowerState)
        {
            // Handle the system power IRP case
            status = DriverASystemPowerDispatch(deviceExtension, Irp);
        }
        else
        {
            // Handle the device power IRP case here

            // determine if we are powering up, powering down, or staying the same
            if (irpStack->Parameters.Power.State.DeviceState < deviceExtension->DevicePowerState)
            {
                // Powering up

                // Powering up needs to happen bottom to top for the device stack
                // so we send the IRP down with a completion routine, and handle
                // our power up tasks in the completion routine

                // Mark the IRP pending, as our completion 
                // routine won't complete it
                IoMarkIrpPending(Irp);
                status = STATUS_PENDING;

                // Prepare the next stack location
                IoCopyCurrentIrpStackLocationToNext(Irp);

                // Insert our completion routine
                IoSetCompletionRoutine(
                    Irp,
                    DriverADeviceSetPowerCompletionRoutine,
                    deviceExtension,
                    TRUE,
                    TRUE,
                    TRUE
                    );

                // send the IRP down the stack
                PoCallDriver(deviceExtension->LowerDeviceObject, Irp);
            }
            else if (irpStack->Parameters.Power.State.DeviceState > deviceExtension->DevicePowerState)
            {
                // Powering down

                // Powering down needs to occur top to bottom for the device stack, so
                // we can handle power down functionality right here

                //*****************************************************************
                //*****************************************************************
                // TODO:  Add device specific power down code here
                //*****************************************************************
                //*****************************************************************

                // Save off our device power IRP
                deviceExtension->DevicePowerIrp = Irp;

                // Mark the IRP pending
                IoMarkIrpPending(Irp);
                status = STATUS_PENDING;

                if (KeGetCurrentIrql() < DISPATCH_LEVEL)
                {
                    DriverAPowerDownPrepCallback(DeviceObject, deviceExtension);
                }
                else
                {
                    IoQueueWorkItem(
                        deviceExtension->PowerWorkItem,
                        DriverAPowerDownPrepCallback,
                        DelayedWorkQueue,
                        deviceExtension
                        );
                }
            }
            else
            {
                // Power stays the same

                // If our current device power state is PowerDeviceD0, then restart
                // our queues
                if (deviceExtension->DevicePowerState == PowerDeviceD0)
                {
                    // Save off our device power IRP
                    deviceExtension->DevicePowerIrp = Irp;

                    // Mark the IRP pending
                    IoMarkIrpPending(Irp);
                    status = STATUS_PENDING;

                    if (KeGetCurrentIrql() < DISPATCH_LEVEL)
                    {
                        DriverAPowerD0PrepCallback(DeviceObject, deviceExtension);
                    }
                    else
                    {
                        IoQueueWorkItem(
                            deviceExtension->PowerWorkItem,
                            DriverAPowerD0PrepCallback,
                            DelayedWorkQueue,
                            deviceExtension
                            );
                    }
                }
                else
                {
                    // Let the power manager know we can handle new
                    // device power IRPs
                    PoStartNextPowerIrp(Irp);

                    // forward the IRP down the stack
                    IoSkipCurrentIrpStackLocation(Irp);
                    Irp->IoStatus.Status = STATUS_SUCCESS;
                    
                    status = PoCallDriver(deviceExtension->LowerDeviceObject, Irp);

                    // Adjust our IRP count
                    DriverAReleaseRemoveLock(deviceExtension);
                }
            }
        }

        break;
    case IRP_MN_WAIT_WAKE:
    case IRP_MN_POWER_SEQUENCE:
    default:
        // default case, just send the IRP down and let other drivers
        // in the stack handle it

        // Let the power manager know we can handle another
        // power IRP of this type
        PoStartNextPowerIrp(Irp);

        // send the IRP down the stack
        IoSkipCurrentIrpStackLocation(Irp);

        // Drivers must use PoCallDriver, rather than IoCallDriver,
        // to pass power IRPs. PoCallDriver allows the Power Manager
        // to ensure that power IRPs are properly synchronized throughout
        // the system.
        status = PoCallDriver(deviceExtension->LowerDeviceObject, Irp);

        // Adjust our IRP count
        DriverAReleaseRemoveLock(deviceExtension);

        break;
    }

    DriverADebugPrint(DBG_POWER, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  DriverASystemPowerDispatch 
//      Dispatch routine for system IRP_MJ_POWER IRPs
//
//  Arguments:
//      IN  DeviceExtension
//              Our device extension
//
//      IN  Irp
//              The power IRP to handle
//
//  Return Value:
//      NT status code
//
NTSTATUS DriverASystemPowerDispatch(
    PDRIVERA_DEVICE_EXTENSION    DeviceExtension,
    IN  PIRP                        Irp
    )
{
    // In this case we have to request a device power IRP
    // before completing the system power IRP.  So, we send
    // the system power IRP down the stack with a completion
    // routine and request the device power IRP from that
    // completion routine.  We specify a power complete callback
    // when requesting the device power IRP, and we complete
    // the system power IRP in that power complete callback.

    DriverADebugPrint(DBG_POWER, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);

    // Mark the IRP pending
    IoMarkIrpPending(Irp);

    // Prepare the next stack location
    IoCopyCurrentIrpStackLocationToNext(Irp);

    // Insert our completion routine
    IoSetCompletionRoutine(
        Irp,
        DriverASystemPowerCompletionRoutine,
        DeviceExtension,

⌨️ 快捷键说明

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