mirror of
https://github.com/reactos/reactos.git
synced 2024-10-01 06:57:08 +00:00
[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
This commit is contained in:
parent
a7c1b9e740
commit
c0cd33da02
|
@ -15,14 +15,6 @@
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* 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
|
typedef struct _POWER_STATE_TRAVERSE_CONTEXT
|
||||||
{
|
{
|
||||||
SYSTEM_POWER_STATE SystemPowerState;
|
SYSTEM_POWER_STATE SystemPowerState;
|
||||||
|
@ -45,21 +37,22 @@ PopRequestPowerIrpCompletion(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PVOID Context)
|
IN PVOID Context)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION Stack;
|
PIO_STACK_LOCATION Stack;
|
||||||
PREQUEST_POWER_ITEM RequestPowerItem;
|
PREQUEST_POWER_COMPLETE CompletionRoutine;
|
||||||
|
POWER_STATE PowerState;
|
||||||
|
|
||||||
Stack = IoGetNextIrpStackLocation(Irp);
|
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
RequestPowerItem = (PREQUEST_POWER_ITEM)Context;
|
CompletionRoutine = Context;
|
||||||
|
|
||||||
RequestPowerItem->CompletionRoutine(DeviceObject,
|
PowerState.DeviceState = (ULONG_PTR)Stack->Parameters.Others.Argument3;
|
||||||
Stack->MinorFunction,
|
CompletionRoutine(Stack->Parameters.Others.Argument1,
|
||||||
RequestPowerItem->PowerState,
|
(UCHAR)(ULONG_PTR)Stack->Parameters.Others.Argument2,
|
||||||
RequestPowerItem->Context,
|
PowerState,
|
||||||
|
Stack->Parameters.Others.Argument4,
|
||||||
&Irp->IoStatus);
|
&Irp->IoStatus);
|
||||||
|
|
||||||
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
IoFreeIrp(Irp);
|
IoFreeIrp(Irp);
|
||||||
|
ObDereferenceObject(DeviceObject);
|
||||||
ObDereferenceObject(RequestPowerItem->TopDeviceObject);
|
|
||||||
ExFreePoolWithTag(Context, 'IRoP');
|
|
||||||
|
|
||||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
}
|
}
|
||||||
|
@ -521,59 +514,52 @@ PoRequestPowerIrp(IN PDEVICE_OBJECT DeviceObject,
|
||||||
PDEVICE_OBJECT TopDeviceObject;
|
PDEVICE_OBJECT TopDeviceObject;
|
||||||
PIO_STACK_LOCATION Stack;
|
PIO_STACK_LOCATION Stack;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
PREQUEST_POWER_ITEM RequestPowerItem;
|
|
||||||
|
|
||||||
if (MinorFunction != IRP_MN_QUERY_POWER
|
if (MinorFunction != IRP_MN_QUERY_POWER
|
||||||
&& MinorFunction != IRP_MN_SET_POWER
|
&& MinorFunction != IRP_MN_SET_POWER
|
||||||
&& MinorFunction != IRP_MN_WAIT_WAKE)
|
&& MinorFunction != IRP_MN_WAIT_WAKE)
|
||||||
return STATUS_INVALID_PARAMETER_2;
|
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 */
|
/* Always call the top of the device stack */
|
||||||
TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
|
TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
|
||||||
|
|
||||||
Irp = IoBuildAsynchronousFsdRequest(IRP_MJ_POWER,
|
Irp = IoAllocateIrp(TopDeviceObject->StackSize + 2, FALSE);
|
||||||
TopDeviceObject,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
if (!Irp)
|
if (!Irp)
|
||||||
{
|
{
|
||||||
ObDereferenceObject(TopDeviceObject);
|
ObDereferenceObject(TopDeviceObject);
|
||||||
ExFreePoolWithTag(RequestPowerItem, 'IRoP');
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* POWER IRPs are always initialized with a status code of
|
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||||
STATUS_NOT_IMPLEMENTED */
|
|
||||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
|
IoSetNextIrpStackLocation(Irp);
|
||||||
|
|
||||||
Stack = IoGetNextIrpStackLocation(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;
|
Stack->MinorFunction = MinorFunction;
|
||||||
if (MinorFunction == IRP_MN_WAIT_WAKE)
|
if (MinorFunction == IRP_MN_WAIT_WAKE)
|
||||||
|
{
|
||||||
Stack->Parameters.WaitWake.PowerState = PowerState.SystemState;
|
Stack->Parameters.WaitWake.PowerState = PowerState.SystemState;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Stack->Parameters.Power.Type = DevicePowerState;
|
Stack->Parameters.Power.Type = DevicePowerState;
|
||||||
Stack->Parameters.Power.State = PowerState;
|
Stack->Parameters.Power.State = PowerState;
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestPowerItem->CompletionRoutine = CompletionFunction;
|
|
||||||
RequestPowerItem->PowerState = PowerState;
|
|
||||||
RequestPowerItem->Context = Context;
|
|
||||||
RequestPowerItem->TopDeviceObject = TopDeviceObject;
|
|
||||||
|
|
||||||
if (pIrp != NULL)
|
if (pIrp != NULL)
|
||||||
*pIrp = Irp;
|
*pIrp = Irp;
|
||||||
|
|
||||||
IoSetCompletionRoutine(Irp, PopRequestPowerIrpCompletion, RequestPowerItem, TRUE, TRUE, TRUE);
|
IoSetCompletionRoutine(Irp, PopRequestPowerIrpCompletion, CompletionFunction, TRUE, TRUE, TRUE);
|
||||||
PoCallDriver(TopDeviceObject, Irp);
|
PoCallDriver(TopDeviceObject, Irp);
|
||||||
|
|
||||||
/* Always return STATUS_PENDING. The completion routine
|
/* Always return STATUS_PENDING. The completion routine
|
||||||
|
|
|
@ -136,10 +136,15 @@ RequestedPowerCompletion(
|
||||||
|
|
||||||
ok_eq_uint(Irp->StackCount, 5);
|
ok_eq_uint(Irp->StackCount, 5);
|
||||||
ok_eq_uint(Irp->CurrentLocation, 4);
|
ok_eq_uint(Irp->CurrentLocation, 4);
|
||||||
|
ok_eq_pointer(Irp->Tail.Overlay.Thread, NULL);
|
||||||
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
|
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.Argument1, DeviceObject);
|
||||||
ok_eq_pointer(IoStackLocation->Parameters.Others.Argument2, (PVOID)(ULONG_PTR)MinorFunction);
|
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);
|
ok_eq_pointer(IoStackLocation->Parameters.Others.Argument4, Context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,8 +163,10 @@ RequestedPowerIrpHandler(
|
||||||
ok_eq_uint(Irp->StackCount, 5);
|
ok_eq_uint(Irp->StackCount, 5);
|
||||||
ok_eq_ulongptr(Irp->IoStatus.Information, 0);
|
ok_eq_ulongptr(Irp->IoStatus.Information, 0);
|
||||||
ok_eq_hex(Irp->IoStatus.Status, STATUS_NOT_SUPPORTED);
|
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->MajorFunction, IRP_MJ_POWER);
|
||||||
ok_eq_uint(IoStackLocation->MinorFunction, IRP_MN_SET_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.Type, DevicePowerState);
|
||||||
ok_eq_uint(IoStackLocation->Parameters.Power.State.DeviceState, PowerDeviceD0);
|
ok_eq_uint(IoStackLocation->Parameters.Power.State.DeviceState, PowerDeviceD0);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue