📄 power.c
字号:
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 + -