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

📄 power.c

📁 基于DDK的驱动间同步调用测试示例程序,DriverA是目标驱动,DriverB是主驱动,test是MFC测试示例
💻 C
📖 第 1 页 / 共 3 页
字号:
        TRUE,
        TRUE,
        TRUE
        );

    // send the IRP down the stack
    PoCallDriver(DeviceExtension->LowerDeviceObject, Irp);

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

    return STATUS_PENDING;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  DriverASystemPowerCompletionRoutine
//      I/O completion routine for system power IRP requests.
//
//  Arguments:
//      IN  DeviceObject
//              Device object for our device
//
//      IN  Irp
//              The system power IRP
//
//      IN  Context
//              Our device extension
//
//  Return Value:
//      returns STATUS_MORE_PROCESSING_REQUIRED if all goes well, 
//          indicating that we aren't done with the system power IRP
//      returns STATUS_SUCCESS if there is an error in order to let 
//          the system IRP go
//
NTSTATUS DriverASystemPowerCompletionRoutine(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp,
    IN  PVOID           Context
    )
{
    PDRIVERA_DEVICE_EXTENSION    deviceExtension;
    PIO_STACK_LOCATION              irpStack;
    POWER_STATE                     powerState;
    NTSTATUS                        status;

    // Get our device extension
    deviceExtension = (PDRIVERA_DEVICE_EXTENSION)Context;

    status = Irp->IoStatus.Status;

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

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

    if (NT_SUCCESS(status))
    {
        // Save off the system power IRP
        deviceExtension->SystemPowerIrp = Irp;

        // Get our device power state for the given system power state
        status = DriverAGetDevicePowerState(
                    deviceExtension, 
                    irpStack->Parameters.Power.State.SystemState,
                    &powerState.DeviceState
                    );

        if (NT_SUCCESS(status))
        {
            // Request the device power IRP
            status = PoRequestPowerIrp(
                        deviceExtension->PhysicalDeviceObject,
                        irpStack->MinorFunction,  
                        powerState,
                        DriverADevicePowerCompleteCallback,
                        deviceExtension,
                        NULL
                        );
        }
    }

    if (!NT_SUCCESS(status))
    {
        ASSERT(irpStack->MinorFunction != IRP_MN_SET_POWER);

        // NULL our system IRP storage
        deviceExtension->SystemPowerIrp = NULL;

        // Let the power manager know we can handle new 
        // system power IRPs
        PoStartNextPowerIrp(Irp);

        // save error status
        Irp->IoStatus.Status = status;

        // Adjust our IRP count
        DriverAReleaseRemoveLock(deviceExtension);

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

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

        // We aren't done with the system power IRP yet,
        // so we return more processing required here
        return STATUS_MORE_PROCESSING_REQUIRED;
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  DriverADevicePowerCompleteCallback
//      Power complete callback routine called by the power manager when our 
//      device power IRP has been completely processed by the entire
//      device stack.  **This is not an I/O completion routine**
//
//  Arguments:
//      IN  DeviceObject
//              Device object for our device
//
//      IN  MinorFunction
//              The minor function of the power IRP
//
//      IN  PowerState
//              The power state of the power IRP
//
//      IN  Context
//              Our device extension
//
//      IN  IoStatus
//              Status block of the power IRP
//
//  Return Value:
//      none
//
VOID DriverADevicePowerCompleteCallback(
    IN  PDEVICE_OBJECT      DeviceObject,
    IN  UCHAR               MinorFunction,
    IN  POWER_STATE         PowerState,
    IN  PVOID               Context,
    IN  PIO_STATUS_BLOCK    IoStatus
    )
{
    PDRIVERA_DEVICE_EXTENSION    deviceExtension;
    PIO_STACK_LOCATION              irpStack;

    // Get our device extension
    deviceExtension = (PDRIVERA_DEVICE_EXTENSION)Context;

    DriverADebugPrint(DBG_POWER, DBG_TRACE, __FUNCTION__"++. IRP %p", deviceExtension->SystemPowerIrp);

    // Get the current stack location for our system power IRP
    irpStack = IoGetCurrentIrpStackLocation(deviceExtension->SystemPowerIrp);

    // If this is a QUERY power IRP, use the device power IRP's status
    // as the system power IRPs status
    if (MinorFunction == IRP_MN_QUERY_POWER)
    {
        deviceExtension->SystemPowerIrp->IoStatus.Status = IoStatus->Status;
    }
    else
    {
        ASSERT(MinorFunction == IRP_MN_SET_POWER);

        // do not fail set power irp
        deviceExtension->SystemPowerIrp->IoStatus.Status = STATUS_SUCCESS;

        // save the new system power state
        deviceExtension->SystemPowerState = irpStack->Parameters.Power.State.SystemState;
    }

    // Let the power manager know we can accept new system power IRPs
    PoStartNextPowerIrp(deviceExtension->SystemPowerIrp);

    // complete the system power IRP
    IoCompleteRequest(deviceExtension->SystemPowerIrp, IO_NO_INCREMENT);

    // set our pointer to NULL
    deviceExtension->SystemPowerIrp = NULL;

    // Adjust our IRP count
    DriverAReleaseRemoveLock(deviceExtension);

    DriverADebugPrint(DBG_POWER, DBG_TRACE, __FUNCTION__"--");

    return;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  DriverADeviceSetPowerCompletionRoutine
//      I/O completion routine for device power IRP requests to power up
//
//  Arguments:
//      IN  DeviceObject
//              Device object for our device
//
//      IN  Irp
//              The system power IRP
//
//      IN  Context
//              Our device extension
//
//  Return Value:
//      returns STATUS_MORE_PROCESSING_REQUIRED
//
NTSTATUS DriverADeviceSetPowerCompletionRoutine(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp,
    IN  PVOID           Context
    )
{
    PDRIVERA_DEVICE_EXTENSION    deviceExtension;
    PIO_STACK_LOCATION              irpStack;
    NTSTATUS                        status;

    status = Irp->IoStatus.Status;

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

    // Get our device extension
    deviceExtension = (PDRIVERA_DEVICE_EXTENSION)Context;

    if (NT_SUCCESS(status))
    {
        // Get our IRP stack location
        irpStack = IoGetCurrentIrpStackLocation(Irp);

        // Store off the device power IRP
        deviceExtension->DevicePowerIrp = Irp;

        // do the real work at PASSIVE_LEVEL
        if (KeGetCurrentIrql() < DISPATCH_LEVEL)
        {
            DriverAPowerUpCallback(DeviceObject, deviceExtension);
        }
        else
        {
            // Queue the work item
            IoQueueWorkItem(
                deviceExtension->PowerWorkItem,
                DriverAPowerUpCallback,
                DelayedWorkQueue,
                deviceExtension
                );
        }

        DriverADebugPrint(DBG_POWER, DBG_TRACE, __FUNCTION__"--");

        // We aren't done with the device power IRP
        // so return more processing required
        return STATUS_MORE_PROCESSING_REQUIRED;
    }
    else
    {
        PoStartNextPowerIrp(Irp);

        // Adjust our IRP count
        DriverAReleaseRemoveLock(deviceExtension);

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

        return STATUS_SUCCESS;
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  DriverAGetDevicePowerState
//      Uses the device capabilities structure, received in the IRP_MJ_PNP, 
//      IRP_MN_QUERY_CAPABILITIES IRP handler, to determine the System
//      to Device (S to D) power state mappings for a given system
//      power state
//
//  Arguments:
//      IN  DeviceExtension
//              Our device extension
//
//      IN  SystemState
//              System power state to provide device power state mapping for
//
//
//  Return Value:
//      returns the device power state corresponding to the system 
//      power state
//
NTSTATUS DriverAGetDevicePowerState(
    IN  PDRIVERA_DEVICE_EXTENSION    DeviceExtension,
    IN  SYSTEM_POWER_STATE              SystemState,
    OUT PDEVICE_POWER_STATE             DeviceState
    )
{
    NTSTATUS            status;
    DEVICE_POWER_STATE  deviceState;

    DriverADebugPrint(DBG_POWER, DBG_TRACE, __FUNCTION__"++. %s", SystemPowerStateString(SystemState));

    status = STATUS_SUCCESS;

    if (SystemState == PowerSystemWorking)
    {
        *DeviceState = PowerDeviceD0;
    }
    else
    {
        *DeviceState = PowerDeviceD3;
    }

    DriverADebugPrint(DBG_POWER, DBG_TRACE, __FUNCTION__"++. %s STATUS %x", DevicePowerStateString(*DeviceState), status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  DriverAPowerDownPrepCallback
//      Callback used to handle power down tasks that need to either block
//      run at PASSIVE_LEVEL for some other reason
//
//  Arguments:
//      IN  DeviceObject
//              Device object for our device
//
//      IN  Context
//              Our device extension
//
//  Return Value:
//      none

⌨️ 快捷键说明

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