на главную | войти | регистрация | DMCA | контакты | справка | donate |      

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Э Ю Я


моя полка | жанры | рекомендуем | рейтинг книг | рейтинг авторов | впечатления | новое | форум | сборники | читалки | авторам | добавить



Handling Set Power IRPs

The parameters on the stack of a Set Power IRP indicate which system or device power state is being set.

If Parameters.Power.Type is SystemPowerState, Parameters.Power.State.SystemState is the desired system state. If Parameters.Power.Type is DevicePowerState, Parameters.Power.State.DeviceState is the desired device state. The Parameters.Power.ShutdownType field gives more information about system Shutdown messages. A final parameter, Parameters.Power.SystemContext, is not currently used.

Listing 10.2 shows the main Wdm2 handler for all Power IRPs, Wdm2Power. If this is a Set Power IRP, PowerSetPower is called. Other Power IRPs are passed to DefaultPowerHandler, which simply hands them down to the lower drivers in the same way as Wdm1. All Power IRPs are completed with an error status if the device is not in the started PnP state.


Listing 10.2 Basic Wdm2 power handling

NTSTATUS Wdm2Power(IN PDEVICE_OBJECT fdo, IN PIRP Irp) {

 PWDM2_DEVICE_EXTENSION dx = (PWDM2_DEVICE_EXTENSI0N)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;

 DebugPrint("Power %I",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;

}


NTSTATUS DefaultPowerHandler(IN PWDM2_DEVICE_EXTENSION dx, IN PIRP Irp) {

 DebugPrintMsg("DefaultPowerHandler");

 // Just pass to lower driver

 PoStartNextPowerIrp(Irp);

 IoSkipCurrentlrpStackLocation(Irp);

 return PoCallDriver(dx->NextStackDevice, Irp);

}

Listing 10.3 shows the PowerSetPower routine. As can be seen, there are two main sections to this code. The first handles setting system power states and the second sets a device power state.


Listing 10.3 PowerSetPower routine

NTSTATUS PowerSetPower(IN PWDM2_DEVICE_EXTENSION dx, IN PIRP Irp) {

 NTSTATUS status = STATUS_SUCCESS;

 PIO_STACK_IOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);

 POWER_STATE_TYPE PowerType = IrpStack->Parameters.Power.Type;

 POWER_STATE PowerState = IrpStack->Parameters.Power.State;


 ////////////////////////////////////////////////////////////////////

 // Set System Power

 if (PowerType==SystemPowerState) {

  DEVICE_POWER_STATE DesiredDevicePowerState = (PowerState.SystemState<=PowerSystemWorking ? PowerDeviceD0 : PowerDeviceD3);

  if (DesiredDevicePowerStatePowerState) {

   // This system state means we have to increase device power

   DebugPrint("System state %d. Increase device power to %d", PowerState.SystemState, DesiredDevicePowerState);

   // Process on way up stack…

   PoStartNextPowerIrp(Irp);

   IoCopyCurrentIrpStackLocationToNext(Irp);

   IoSetCompletionRoutine(Irp, OnCompleteIncreaseSystemPower, NULL, TRUE, TRUE, TRUE);

   return PoCallDriver(dx->NextStackDevice, Irp);

  } else if(DesiredDevicePowerState>dx->PowerState) {

   // This system state means we have to decrease device power

   DebugPrint("System state %d. Decrease device power to %d",

    PowerState.SystemState, DesiredDevicePowerState);

   // Send power down request to device

   status = SendDeviceSetPower(dx, DesiredDevicePowerState);

   if (!NT_SUCCESS(status)) {

    PoStartNextPowerIrp(Irp);

    return CompleteIrp(Irp, status, 0);

   }

  }

 }


 ////////////////////////////////////////////////////////////////////

 // Set Device Power

 else if (PowerType==DevicePowerState) {

  DEVICE_POWER_STATE DesiredDevicePowerState = PowerState.DeviceState;

  if (DesiredDevicePowerStatePowerState) {

   // Increase device power state

   DebugPrint("Increase device power to %d", DesiredDevicePowerState);

   // Process on way up stack…

   PoStartNextPowerIrp(Irp);

   IoCopyCurrentIrpStackLocationToNext(Irp);

   IoSetCompletionRoutine(Irp, OnCompleteIncreaseDevicePower, NULL,TRUE, TRUE, TRUE);

   return PoCallDriver(dx->NextStackDevice, Irp);

  } else if (DesiredDevicePowerState>dx->PowerState) {

   // Decrease device power state

   DebugPrint("Decrease device power to %d", DesiredDevicePowerState);

   // Set power state

   SetPowerState(dx,PawerState.DeviceState);

  }

 }


 ////////////////////////////////////////////////////////////////////

 // Unrecognised Set Power

#if DBG

 else DebugPrint("Power: unrecognised power type %d",PowerType);

#endif

 // Finally pass to lower drivers return DefaultPowerHandler(dx, Irp);

}


Device Power Policy Owner | Writing Windows WDM Device Drivers | Setting System Power States