PowerFilter sets the IoStatus.Status to a failed status and returns that
status but you can’t fail this IRP if the systen power state is being set.
“A driver must not fail a request to set the system power state.”
Read this page:
https://msdn.microsoft.com/fr-fr/library/windows/hardware/ff551744(v=vs.85).aspx
Remember that the remove lock is owned by your driver. If you can’t acquire
it than the game is over because your driver is processing an
IRP_MN_REMOVE_DEVICE IRP. This later IRP cannot be failed and the driver is
supposed to power down the device when the IRP is processed.
So, if you can’t acquire the remove lock, the device is being powered off.
If the power IRP is sent at PASSIVE_LEVEL, you could wait for the
IRP_MN_REMOVE_DEVICE to set an event when the device is powered off. This
IRQL depends on what device object’s flag the driver has set
(DO_POWER_PAGABLE for PASSIVE_LEVEL or DO_POWER_INRUSH for DISPATCH_LEVEL).
Le 5 avr. 2017 19:17, a écrit :
> According to the WDK, a driver must not fail an
> IRP_MJ_POWER/IRP_MN_SET_POWER. My question is this: Does this include
> failing on acquiring a remlock? For example, if my IoAcquireRemoveLock()
> fails indicating the device is being removed, should I still pass the IRP
> down? Here is a generic WDM power dispatcher and completion handler I have
> thrown together:
>
> static NTSTATUS PowerComplete(In PDEVICE_OBJECT Device, In PIRP Irp,
> Reserved PVOID Context) {
> if (Irp->PendingReturned) {
> IoMarkIrpPending(Irp);
> }
> register PFILTER_EXTENSION FilterExt = Device->DeviceExtension;
> IoReleaseRemoveLock(&FilterExt->RemoveLock, Irp);
> // Pre-VISTA power IRP is handled differently.
> PIO_STACK_LOCATION CurrSl = IoGetCurrentIrpStackLocation(Irp);
> if (CurrSl->Parameters.Power.Type == DevicePowerState) {
> if ((CurrSl->MinorFunction == IRP_MN_QUERY_POWER) ||
> (CurrSl->MinorFunction == IRP_MN_SET_POWER)) {
> // Post XP/2003 this is a NOP.
> PoStartNextPowerIrp(Irp);
> }
> }
> return STATUS_SUCCESS;
> UNREFERENCED_PARAMETER(Context);
> }
>
> static NTSTATUS PowerFilter(In PDEVICE_OBJECT Device, In PIRP Irp) {
> PFILTER_EXTENSION FilterExt = Device->DeviceExtension;
> PIO_STACK_LOCATION CurrSl = IoGetCurrentIrpStackLocation(Irp);
> NTSTATUS Status = IoAcquireRemoveLock(&FilterExt->RemoveLock,
> Irp);
> if (!NT_SUCCESS(Status)) {
> Irp->IoStatus.Status = Status;
> Irp->IoStatus.Information = 0;
> // Pre-VISTA power IRP is handled differently.
> if ((CurrSl->Parameters.Power.Type == SystemPowerState) &&
> (CurrSl->MinorFunction == IRP_MN_QUERY_POWER)) {
> // Post XP/2003 this is a NOP.
> PoStartNextPowerIrp(Irp);
> }
> IoCompleteRequest(Irp, IO_NO_INCREMENT);
> return Status;
> }
> // Pre-VISTA power IRP is handled differently.
> if ((CurrSl->Parameters.Power.Type == SystemPowerState) &&
> ((CurrSl->MinorFunction == IRP_MN_QUERY_POWER) ||
> (CurrSl->MinorFunction == IRP_MN_SET_POWER))) {
> // Post XP/2003 this is a NOP.
> PoStartNextPowerIrp(Irp);
> }
> IoCopyCurrentIrpStackLocationToNext(Irp);
> IoSetCompletionRoutine(Irp, PowerComplete, NULL, TRUE, TRUE, TRUE);
> // Post XP/2003 this calls IoCallDriver().
> return PoCallDriver(FilterExt->TargetDevice, Irp);
> }
>
> Can I get into trouble for not passing down the power IRP. I’ve not seen
> any issues, but I was reading the WDK documentation last night on power
> IRPS, and I began to question my code.
>
> – Jamey
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer>
></http:></http:>