From c0cd33da0284fe130751937d2e42620d2b0a0771 Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Sun, 11 Oct 2015 19:57:06 +0000 Subject: [PATCH] [NTOS:PO] - Pass the correct DeviceObject to PoRequestPowerIrp's callback - Use the IRP stack to store callback parameters instead of a pool allocation as shown by the test svn path=/trunk/; revision=69503 --- reactos/ntoskrnl/po/power.c | 70 +++++++++++----------------- rostests/kmtests/ntos_po/PoIrp_drv.c | 9 +++- 2 files changed, 36 insertions(+), 43 deletions(-) diff --git a/reactos/ntoskrnl/po/power.c b/reactos/ntoskrnl/po/power.c index 168cbf25df7..684a25ef9f4 100644 --- a/reactos/ntoskrnl/po/power.c +++ b/reactos/ntoskrnl/po/power.c @@ -15,14 +15,6 @@ /* GLOBALS *******************************************************************/ -typedef struct _REQUEST_POWER_ITEM -{ - PREQUEST_POWER_COMPLETE CompletionRoutine; - POWER_STATE PowerState; - PVOID Context; - PDEVICE_OBJECT TopDeviceObject; -} REQUEST_POWER_ITEM, *PREQUEST_POWER_ITEM; - typedef struct _POWER_STATE_TRAVERSE_CONTEXT { SYSTEM_POWER_STATE SystemPowerState; @@ -45,21 +37,22 @@ PopRequestPowerIrpCompletion(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context) { PIO_STACK_LOCATION Stack; - PREQUEST_POWER_ITEM RequestPowerItem; + PREQUEST_POWER_COMPLETE CompletionRoutine; + POWER_STATE PowerState; - Stack = IoGetNextIrpStackLocation(Irp); - RequestPowerItem = (PREQUEST_POWER_ITEM)Context; + Stack = IoGetCurrentIrpStackLocation(Irp); + CompletionRoutine = Context; - RequestPowerItem->CompletionRoutine(DeviceObject, - Stack->MinorFunction, - RequestPowerItem->PowerState, - RequestPowerItem->Context, - &Irp->IoStatus); + PowerState.DeviceState = (ULONG_PTR)Stack->Parameters.Others.Argument3; + CompletionRoutine(Stack->Parameters.Others.Argument1, + (UCHAR)(ULONG_PTR)Stack->Parameters.Others.Argument2, + PowerState, + Stack->Parameters.Others.Argument4, + &Irp->IoStatus); + IoSkipCurrentIrpStackLocation(Irp); IoFreeIrp(Irp); - - ObDereferenceObject(RequestPowerItem->TopDeviceObject); - ExFreePoolWithTag(Context, 'IRoP'); + ObDereferenceObject(DeviceObject); return STATUS_MORE_PROCESSING_REQUIRED; } @@ -521,59 +514,52 @@ PoRequestPowerIrp(IN PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT TopDeviceObject; PIO_STACK_LOCATION Stack; PIRP Irp; - PREQUEST_POWER_ITEM RequestPowerItem; if (MinorFunction != IRP_MN_QUERY_POWER && MinorFunction != IRP_MN_SET_POWER && MinorFunction != IRP_MN_WAIT_WAKE) return STATUS_INVALID_PARAMETER_2; - RequestPowerItem = ExAllocatePoolWithTag(NonPagedPool, - sizeof(REQUEST_POWER_ITEM), - 'IRoP'); - if (!RequestPowerItem) - return STATUS_INSUFFICIENT_RESOURCES; - /* Always call the top of the device stack */ TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject); - Irp = IoBuildAsynchronousFsdRequest(IRP_MJ_POWER, - TopDeviceObject, - NULL, - 0, - NULL, - NULL); + Irp = IoAllocateIrp(TopDeviceObject->StackSize + 2, FALSE); if (!Irp) { ObDereferenceObject(TopDeviceObject); - ExFreePoolWithTag(RequestPowerItem, 'IRoP'); return STATUS_INSUFFICIENT_RESOURCES; } - /* POWER IRPs are always initialized with a status code of - STATUS_NOT_IMPLEMENTED */ - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; Irp->IoStatus.Information = 0; + IoSetNextIrpStackLocation(Irp); + + Stack = IoGetNextIrpStackLocation(Irp); + Stack->Parameters.Others.Argument1 = DeviceObject; + Stack->Parameters.Others.Argument2 = (PVOID)(ULONG_PTR)MinorFunction; + Stack->Parameters.Others.Argument3 = (PVOID)(ULONG_PTR)PowerState.DeviceState; + Stack->Parameters.Others.Argument4 = Context; + Stack->DeviceObject = TopDeviceObject; + IoSetNextIrpStackLocation(Irp); + Stack = IoGetNextIrpStackLocation(Irp); + Stack->MajorFunction = IRP_MJ_POWER; Stack->MinorFunction = MinorFunction; if (MinorFunction == IRP_MN_WAIT_WAKE) + { Stack->Parameters.WaitWake.PowerState = PowerState.SystemState; + } else { Stack->Parameters.Power.Type = DevicePowerState; Stack->Parameters.Power.State = PowerState; } - RequestPowerItem->CompletionRoutine = CompletionFunction; - RequestPowerItem->PowerState = PowerState; - RequestPowerItem->Context = Context; - RequestPowerItem->TopDeviceObject = TopDeviceObject; - if (pIrp != NULL) *pIrp = Irp; - IoSetCompletionRoutine(Irp, PopRequestPowerIrpCompletion, RequestPowerItem, TRUE, TRUE, TRUE); + IoSetCompletionRoutine(Irp, PopRequestPowerIrpCompletion, CompletionFunction, TRUE, TRUE, TRUE); PoCallDriver(TopDeviceObject, Irp); /* Always return STATUS_PENDING. The completion routine diff --git a/rostests/kmtests/ntos_po/PoIrp_drv.c b/rostests/kmtests/ntos_po/PoIrp_drv.c index 3e063eaa523..a95d7871655 100644 --- a/rostests/kmtests/ntos_po/PoIrp_drv.c +++ b/rostests/kmtests/ntos_po/PoIrp_drv.c @@ -136,10 +136,15 @@ RequestedPowerCompletion( ok_eq_uint(Irp->StackCount, 5); ok_eq_uint(Irp->CurrentLocation, 4); + ok_eq_pointer(Irp->Tail.Overlay.Thread, NULL); IoStackLocation = IoGetCurrentIrpStackLocation(Irp); + ok_eq_uint(IoStackLocation->MajorFunction, 0); + ok_eq_uint(IoStackLocation->MinorFunction, 0); + ok_eq_pointer(IoStackLocation->CompletionRoutine, NULL); + ok_eq_pointer(IoStackLocation->Context, NULL); ok_eq_pointer(IoStackLocation->Parameters.Others.Argument1, DeviceObject); ok_eq_pointer(IoStackLocation->Parameters.Others.Argument2, (PVOID)(ULONG_PTR)MinorFunction); - ok_eq_pointer(IoStackLocation->Parameters.Others.Argument3, (PVOID)PowerState.SystemState); + ok_eq_pointer(IoStackLocation->Parameters.Others.Argument3, (PVOID)(ULONG_PTR)PowerState.SystemState); ok_eq_pointer(IoStackLocation->Parameters.Others.Argument4, Context); } @@ -158,8 +163,10 @@ RequestedPowerIrpHandler( ok_eq_uint(Irp->StackCount, 5); ok_eq_ulongptr(Irp->IoStatus.Information, 0); ok_eq_hex(Irp->IoStatus.Status, STATUS_NOT_SUPPORTED); + ok_eq_pointer(Irp->Tail.Overlay.Thread, NULL); ok_eq_uint(IoStackLocation->MajorFunction, IRP_MJ_POWER); ok_eq_uint(IoStackLocation->MinorFunction, IRP_MN_SET_POWER); + ok_eq_pointer(IoStackLocation->Context, RequestedPowerCompletion); ok_eq_uint(IoStackLocation->Parameters.Power.Type, DevicePowerState); ok_eq_uint(IoStackLocation->Parameters.Power.State.DeviceState, PowerDeviceD0); -- 2.17.1