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

📄 power.c

📁 基于DDK的驱动间同步调用测试示例程序,DriverA是目标驱动,DriverB是主驱动,test是MFC测试示例
💻 C
📖 第 1 页 / 共 3 页
字号:
//
VOID DriverAPowerDownPrepCallback(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PVOID           Context
    )
{
    PDRIVERA_DEVICE_EXTENSION    deviceExtension;
    PIRP                            irp;
    PIO_STACK_LOCATION              irpStack;

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

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

    // get our device IRP
    irp = deviceExtension->DevicePowerIrp;

    // NULL our pointer
    deviceExtension->DevicePowerIrp = NULL;

    ASSERT(irp != NULL);

    irpStack = IoGetCurrentIrpStackLocation(irp);

    if (!deviceExtension->bPowerStop)
    {
        // stall all io processing
        deviceExtension->bPowerStop = TRUE;
        DriverAStallQueues(deviceExtension);
    }

    if (irpStack->MinorFunction == IRP_MN_SET_POWER)
    {
        //*****************************************************************
        //*****************************************************************
        // TODO: power down your device
        //*****************************************************************
        //*****************************************************************

        // Let the power manager know our new device power state
        PoSetPowerState(
            deviceExtension->DeviceObject,
            irpStack->Parameters.Power.Type,
            irpStack->Parameters.Power.State
            );

        // Save our new power state
        deviceExtension->DevicePowerState = irpStack->Parameters.Power.State.DeviceState;
    }

    // Let the power manager know we can handle a new device power IRP
    PoStartNextPowerIrp(irp);

    // send the device power IRP down the stack
    IoSkipCurrentIrpStackLocation(irp);
    irp->IoStatus.Status = STATUS_SUCCESS;

    PoCallDriver(deviceExtension->LowerDeviceObject, irp);

    // Adjust our IRP count
    DriverAReleaseRemoveLock(deviceExtension);

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

    return;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  DriverAPowerD0PrepCallback
//      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
//
VOID DriverAPowerD0PrepCallback(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PVOID           Context
    )
{
    PDRIVERA_DEVICE_EXTENSION    deviceExtension;
    PIRP                    irp;
    PIO_STACK_LOCATION      irpStack;

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

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

    //*****************************************************************
    //*****************************************************************
    // TODO:  Handle any unwinding of a previous query to power down here
    //*****************************************************************
    //*****************************************************************

    if (deviceExtension->bPowerStop)
    {
        // restart our queues
        deviceExtension->bPowerStop = FALSE;
        DriverARestartQueues(deviceExtension);
    }

    // get our device IRP
    irp = deviceExtension->DevicePowerIrp;

    // NULL our pointer
    deviceExtension->DevicePowerIrp = NULL;

    ASSERT(irp != NULL);

    // 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;
    
    PoCallDriver(deviceExtension->LowerDeviceObject, irp);

    // Adjust our IRP count
    DriverAReleaseRemoveLock(deviceExtension);

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

    return;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  DriverAPowerUpCallback
//      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
//
VOID DriverAPowerUpCallback(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PVOID           Context
    )
{
    PDRIVERA_DEVICE_EXTENSION    deviceExtension;
    PIRP                            irp;
    PIO_STACK_LOCATION              irpStack;

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

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

    // Get our device power IRP
    irp = deviceExtension->DevicePowerIrp;

    ASSERT(irp != NULL);

    // NULL our IRP pointer
    deviceExtension->DevicePowerIrp = NULL;

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

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

    // Let the power manager know our new device power state
    PoSetPowerState(
        deviceExtension->DeviceObject,
        irpStack->Parameters.Power.Type,
        irpStack->Parameters.Power.State
        );

    // Save our new power state
    deviceExtension->DevicePowerState = irpStack->Parameters.Power.State.DeviceState;

    if (deviceExtension->bPowerStop)
    {
        // restart our queues
        deviceExtension->bPowerStop = FALSE;
        DriverARestartQueues(deviceExtension);
    }

    // Let the power manager know we can handle new
    // device power IRPs
    PoStartNextPowerIrp(irp);

    // Complete the IRP
    IoCompleteRequest(irp, IO_NO_INCREMENT);

    // Adjust our IRP count
    DriverAReleaseRemoveLock(deviceExtension);

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

    return;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  DriverARequestDevicePowerIrpCallback
//      Callback used to signal completion of power handling
//
//  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 DriverARequestDevicePowerIrpCallback(
    IN  PDEVICE_OBJECT      DeviceObject,
    IN  UCHAR               MinorFunction,
    IN  POWER_STATE         PowerState,
    IN  PVOID               Context,
    IN  PIO_STATUS_BLOCK    IoStatus
    )
{
    PDRIVERA_POWER_IRP_CONTEXT context;

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

    context = (PDRIVERA_POWER_IRP_CONTEXT)Context;

    // copy status in our context block
    context->Status = IoStatus->Status;

    // signal completion event
    KeSetEvent(context->Event, IO_NO_INCREMENT, FALSE);

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

    return;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  DriverARequestDevicePowerIrp
//      This routine requests IRP_MN_SET_POWER and wait for its
//      completion
//
//  Arguments:
//      IN  DeviceExtension
//              our device extension
//
//      IN  DeviceState
//              New device power state
//
//  Return Value:
//      NT Status code
//
NTSTATUS DriverARequestDevicePowerIrp(
    IN  PDRIVERA_DEVICE_EXTENSION        DeviceExtension,
    IN  DEVICE_POWER_STATE             DeviceState
    )
{
    NTSTATUS                    status;
    POWER_STATE                 powerState;
    DRIVERA_POWER_IRP_CONTEXT   powerContext;
    KEVENT                      event;

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

    // We must be at IRQL less than DISPATCH_LEVEL
    // in order to block on KeWaitForSingleObject
    ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);

    KeInitializeEvent(&event, NotificationEvent, FALSE);
    powerContext.Event = &event;
    powerState.DeviceState = DeviceState;

    status = PoRequestPowerIrp(
                DeviceExtension->PhysicalDeviceObject,
                IRP_MN_SET_POWER,
                powerState,
                DriverARequestDevicePowerIrpCallback,
                &powerContext,
                NULL
                );

    if (status == STATUS_PENDING)
    {
        KeWaitForSingleObject(
            &event, 
            Executive,
            KernelMode,
            FALSE,
            NULL
            );

        status = powerContext.Status;
    }

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

    return status;
}

⌨️ 快捷键说明

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