📄 power.cpp
字号:
#include "WdmUsb.h"
//-----------------------------------Defines------------------------------------------
NTSTATUS PowerSetPower(IN PWDMUSB_DEVICE_EXTENSION dx,IN PIRP Irp);
NTSTATUS DefaultPowerHandler(IN PWDMUSB_DEVICE_EXTENSION dx,IN PIRP Irp);
NTSTATUS OnCompleteIncreaseSystemPower(IN PDEVICE_OBJECT fdo,IN PIRP Irp,
IN PVOID context);
NTSTATUS OnCompleteIncreaseDevicePower(IN PDEVICE_OBJECT fdo,IN PIRP Irp,
IN PVOID context);
VOID OnCompleteDeviceSetPower(IN PDEVICE_OBJECT fdo,IN UCHAR MinorFunction,
IN POWER_STATE PowerState,IN PVOID Context,
IN PIO_STATUS_BLOCK IoStatus);
//--------------------------------Routines-----------------------------------------------
NTSTATUS WdmUsbPower(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
PWDMUSB_DEVICE_EXTENSION dx=(PWDMUSB_DEVICE_EXTENSION)fdo->DeviceExtension;
if(dx->IODisabled)
return CompleteIrp(Irp,STATUS_DEVICE_NOT_CONNECTED,0);
if(!LockDevice(dx))
return CompleteIrp(Irp,STATUS_DELETE_PENDING,0);
NTSTATUS status=STATUS_SUCCESS;
KdPrint(("Power %x",Irp));
PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);
ULONG MinorFunction=IrpStack->MinorFunction;
if(MinorFunction==IRP_MN_SET_POWER)
status=PowerSetPower(dx,Irp);
else
status=DefaultPowerHandler(dx,Irp);
UnlockDevice(dx);
return status;
}
typedef struct _SDSP
{
KEVENT event;
NTSTATUS Status;
} SDSP, *PSDSP;
NTSTATUS SendDeviceSetPower( IN PWDMUSB_DEVICE_EXTENSION dx, IN DEVICE_POWER_STATE NewDevicePowerState)
{
KdPrint(("SendDeviceSetPower to %d",NewDevicePowerState));
POWER_STATE NewState;
NewState.DeviceState=NewDevicePowerState;
SDSP sdsp;
KeInitializeEvent(&sdsp.event,NotificationEvent,FALSE);
sdsp.Status=STATUS_SUCCESS;
NTSTATUS status=PoRequestPowerIrp(dx->pdo,
IRP_MN_SET_POWER,
NewState,
OnCompleteDeviceSetPower,
&sdsp,
NULL);
if(status==STATUS_PENDING)
{
KeWaitForSingleObject(&sdsp.event,Executive,KernelMode,FALSE,NULL);
status=sdsp.Status;
}
if(NT_SUCCESS(status)&&dx->PowerState!=NewDevicePowerState)
{
KdPrint(("SendDeviceSetPower: Device state not set properly by us. Setting again"));
SetPowerState(dx,NewDevicePowerState);
}
return status;
}
//---------------------------------Define Routines---------------------------------------
NTSTATUS PowerSetPower(IN PWDMUSB_DEVICE_EXTENSION dx,IN PIRP Irp)
{
NTSTATUS status=STATUS_SUCCESS;
PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);
POWER_STATE_TYPE PowerType=IrpStack->Parameters.Power.Type;
POWER_STATE PowerState=IrpStack->Parameters.Power.State;
if(PowerType==SystemPowerState)
{
DEVICE_POWER_STATE DesiredDevicePowerState=
(PowerState.SystemState<=PowerSystemWorking?PowerDeviceD0:PowerDeviceD3);
if(DesiredDevicePowerState<dx->PowerState)
{
KdPrint(("System state %d. Increase device power to %d",
PowerState.SystemState, DesiredDevicePowerState));
PoStartNextPowerIrp(Irp);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,OnCompleteIncreaseSystemPower,
NULL,TRUE,TRUE,TRUE);
return PoCallDriver(dx->NextStackDevice,Irp);
}
else if(DesiredDevicePowerState>dx->PowerState)
{
KdPrint(("System state %d. Decrease device power to %d",
PowerState.SystemState, DesiredDevicePowerState));
status=SendDeviceSetPower(dx,DesiredDevicePowerState);
if(!NT_SUCCESS(status))
{
PoStartNextPowerIrp(Irp);
return CompleteIrp(Irp,status,0);
}
}
}
else if(PowerType==DevicePowerState)
{
DEVICE_POWER_STATE DesiredDevicePowerState=PowerState.DeviceState;
if(DesiredDevicePowerState<dx->PowerState)
{
KdPrint(("Increase device power to %d", DesiredDevicePowerState));
PoStartNextPowerIrp(Irp);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,OnCompleteIncreaseDevicePower,NULL,TRUE,TRUE,TRUE);
return PoCallDriver(dx->NextStackDevice,Irp);
}
else if(DesiredDevicePowerState>dx->PowerState)
{
KdPrint(("Decrease device power to %d", DesiredDevicePowerState));
SetPowerState(dx,PowerState.DeviceState);
}
}
KdPrint(("Power: unrecognised power type %d",PowerType));
return DefaultPowerHandler(dx,Irp);
}
NTSTATUS DefaultPowerHandler(IN PWDMUSB_DEVICE_EXTENSION dx,IN PIRP Irp)
{
KdPrint(("DefaultPowerHandler"));
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver(dx->NextStackDevice,Irp);
}
NTSTATUS OnCompleteIncreaseSystemPower(IN PDEVICE_OBJECT fdo,IN PIRP Irp,
IN PVOID context)
{
PWDMUSB_DEVICE_EXTENSION dx=(PWDMUSB_DEVICE_EXTENSION)fdo->DeviceExtension;
if(Irp->PendingReturned)
IoMarkIrpPending(Irp);
NTSTATUS status=Irp->IoStatus.Status;
KdPrint(("OnCompleteIncreaseSystemPower %x",status));
if(!NT_SUCCESS(status))
return status;
PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);
POWER_STATE PowerState=IrpStack->Parameters.Power.State;
DEVICE_POWER_STATE DesirdDevicePowerState=
(PowerState.SystemState<=PowerSystemWorking?PowerDeviceD0:PowerDeviceD3);
if(DesirdDevicePowerState<dx->PowerState)
status=SendDeviceSetPower(dx,DesirdDevicePowerState);
PoStartNextPowerIrp(Irp);
return status;
}
NTSTATUS OnCompleteIncreaseDevicePower(IN PDEVICE_OBJECT fdo,IN PIRP Irp,
IN PVOID context)
{
PWDMUSB_DEVICE_EXTENSION dx=(PWDMUSB_DEVICE_EXTENSION)fdo->DeviceExtension;
if(Irp->PendingReturned)
IoMarkIrpPending(Irp);
NTSTATUS status=Irp->IoStatus.Status;
KdPrint(("OnCompleteIncreaseDevicePower %x",status));
if(!NT_SUCCESS(status))
return status;
PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);
POWER_STATE PowerState=IrpStack->Parameters.Power.State;
SetPowerState(dx,PowerState.DeviceState);
PoStartNextPowerIrp(Irp);
return status;
}
VOID OnCompleteDeviceSetPower(IN PDEVICE_OBJECT fdo,IN UCHAR MinorFunction,
IN POWER_STATE PowerState,IN PVOID Context,
IN PIO_STATUS_BLOCK IoStatus)
{
KdPrint(("OnCompleteDeviceSetPower"));
PSDSP psdsp=(PSDSP)Context;
psdsp->Status=IoStatus->Status;
KeSetEvent(&psdsp->event,0,FALSE);
}
//--------------------------------Define Routines end-------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -