Author: tfaber Date: Sun Oct 11 19:57:06 2015 New Revision: 69503
URL: http://svn.reactos.org/svn/reactos?rev=69503&view=rev Log: [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
Modified: trunk/reactos/ntoskrnl/po/power.c trunk/rostests/kmtests/ntos_po/PoIrp_drv.c
Modified: trunk/reactos/ntoskrnl/po/power.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/po/power.c?rev=695... ============================================================================== --- trunk/reactos/ntoskrnl/po/power.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/po/power.c [iso-8859-1] Sun Oct 11 19:57:06 2015 @@ -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 @@ IN PVOID Context) { PIO_STACK_LOCATION Stack; - PREQUEST_POWER_ITEM RequestPowerItem; - - Stack = IoGetNextIrpStackLocation(Irp); - RequestPowerItem = (PREQUEST_POWER_ITEM)Context; - - RequestPowerItem->CompletionRoutine(DeviceObject, - Stack->MinorFunction, - RequestPowerItem->PowerState, - RequestPowerItem->Context, - &Irp->IoStatus); - + PREQUEST_POWER_COMPLETE CompletionRoutine; + POWER_STATE PowerState; + + Stack = IoGetCurrentIrpStackLocation(Irp); + CompletionRoutine = Context; + + 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 @@ 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
Modified: trunk/rostests/kmtests/ntos_po/PoIrp_drv.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_po/PoIrp_drv.... ============================================================================== --- trunk/rostests/kmtests/ntos_po/PoIrp_drv.c [iso-8859-1] (original) +++ trunk/rostests/kmtests/ntos_po/PoIrp_drv.c [iso-8859-1] Sun Oct 11 19:57:06 2015 @@ -136,10 +136,15 @@
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 @@ 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);