2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Power IRP management test
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
11 static PDRIVER_OBJECT TestDriverObject
;
12 static KMT_MESSAGE_HANDLER TestMessageHandler
;
14 static PDEVICE_OBJECT DeviceObject1
;
15 static PDEVICE_OBJECT DeviceObject2
;
16 static PDEVICE_OBJECT DeviceObject3
;
21 _In_ PDRIVER_OBJECT DriverObject
)
24 PDEVICE_OBJECT AttachedDevice
;
26 Status
= IoCreateDevice(DriverObject
, 0, NULL
, FILE_DEVICE_UNKNOWN
, 0, FALSE
, &DeviceObject1
);
27 if (!NT_SUCCESS(Status
))
30 DeviceObject1
->Flags
&= ~DO_DEVICE_INITIALIZING
;
32 Status
= IoCreateDevice(DriverObject
, 0, NULL
, FILE_DEVICE_UNKNOWN
, 0, FALSE
, &DeviceObject2
);
33 if (!NT_SUCCESS(Status
))
35 IoDeleteDevice(DeviceObject1
);
39 AttachedDevice
= IoAttachDeviceToDeviceStack(DeviceObject2
, DeviceObject1
);
40 ok(AttachedDevice
== DeviceObject1
, "Device attached to %p is %p, expected %p\n", DeviceObject2
, AttachedDevice
, DeviceObject1
);
41 if (AttachedDevice
== NULL
)
43 IoDeleteDevice(DeviceObject2
);
44 IoDeleteDevice(DeviceObject1
);
45 return STATUS_UNSUCCESSFUL
;
48 DeviceObject2
->Flags
&= ~DO_DEVICE_INITIALIZING
;
50 Status
= IoCreateDevice(DriverObject
, 0, NULL
, FILE_DEVICE_UNKNOWN
, 0, FALSE
, &DeviceObject3
);
51 if (!NT_SUCCESS(Status
))
53 IoDetachDevice(DeviceObject1
);
54 IoDeleteDevice(DeviceObject2
);
55 IoDeleteDevice(DeviceObject1
);
59 AttachedDevice
= IoAttachDeviceToDeviceStack(DeviceObject3
, DeviceObject1
);
60 ok(AttachedDevice
== DeviceObject2
, "Device attached to %p is %p, expected %p\n", DeviceObject2
, AttachedDevice
, DeviceObject2
);
61 if (AttachedDevice
== NULL
)
63 IoDeleteDevice(DeviceObject3
);
64 IoDetachDevice(DeviceObject1
);
65 IoDeleteDevice(DeviceObject2
);
66 IoDeleteDevice(DeviceObject1
);
67 return STATUS_UNSUCCESSFUL
;
70 DeviceObject3
->Flags
&= ~DO_DEVICE_INITIALIZING
;
77 _In_ PDRIVER_OBJECT DriverObject
,
78 _In_ PCUNICODE_STRING RegistryPath
,
79 _Out_ PCWSTR
*DeviceName
,
82 NTSTATUS Status
= STATUS_SUCCESS
;
86 UNREFERENCED_PARAMETER(RegistryPath
);
88 TestDriverObject
= DriverObject
;
90 *DeviceName
= L
"PoIrp";
91 *Flags
= TESTENTRY_NO_EXCLUSIVE_DEVICE
;
93 KmtRegisterMessageHandler(0, NULL
, TestMessageHandler
);
100 IN PDRIVER_OBJECT DriverObject
)
102 UNREFERENCED_PARAMETER(DriverObject
);
108 // PoRequestPowerIrp test
110 static KEVENT TestDoneEvent
;
111 static PIRP RequestedPowerIrp
;
112 static PIRP RequestedPowerIrpReturned
;
117 RequestedPowerCompletion(
118 _In_ PDEVICE_OBJECT DeviceObject
,
119 _In_ UCHAR MinorFunction
,
120 _In_ POWER_STATE PowerState
,
121 _In_opt_ PVOID Context
,
122 _In_ PIO_STATUS_BLOCK IoStatus
)
125 PIO_STACK_LOCATION IoStackLocation
;
127 ok_eq_pointer(DeviceObject
, DeviceObject2
);
128 ok_eq_uint(MinorFunction
, IRP_MN_SET_POWER
);
129 ok_eq_uint(PowerState
.DeviceState
, PowerDeviceD0
);
130 ok_eq_pointer(Context
, &RequestedPowerIrp
);
131 Irp
= CONTAINING_RECORD(IoStatus
, IRP
, IoStatus
);
132 ok_eq_pointer(Irp
, RequestedPowerIrp
);
133 ok_eq_ulongptr(IoStatus
->Information
, 7);
134 ok_eq_hex(IoStatus
->Status
, STATUS_WAIT_3
);
135 KeSetEvent(&TestDoneEvent
, IO_NO_INCREMENT
, FALSE
);
137 ok_eq_uint(Irp
->StackCount
, 5);
138 ok_eq_uint(Irp
->CurrentLocation
, 4);
139 ok_eq_pointer(Irp
->Tail
.Overlay
.Thread
, NULL
);
140 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
141 ok_eq_uint(IoStackLocation
->MajorFunction
, 0);
142 ok_eq_uint(IoStackLocation
->MinorFunction
, 0);
143 ok_eq_pointer(IoStackLocation
->CompletionRoutine
, NULL
);
144 ok_eq_pointer(IoStackLocation
->Context
, NULL
);
145 ok_eq_pointer(IoStackLocation
->Parameters
.Others
.Argument1
, DeviceObject
);
146 ok_eq_pointer(IoStackLocation
->Parameters
.Others
.Argument2
, (PVOID
)(ULONG_PTR
)MinorFunction
);
147 ok_eq_pointer(IoStackLocation
->Parameters
.Others
.Argument3
, (PVOID
)(ULONG_PTR
)PowerState
.SystemState
);
148 ok_eq_pointer(IoStackLocation
->Parameters
.Others
.Argument4
, Context
);
153 RequestedPowerIrpHandler(
154 _In_ PDEVICE_OBJECT DeviceObject
,
156 _In_ PIO_STACK_LOCATION IoStackLocation
)
158 if (RequestedPowerIrp
== NULL
)
159 RequestedPowerIrp
= Irp
;
161 ok_eq_pointer(Irp
, RequestedPowerIrp
);
163 ok_eq_uint(Irp
->StackCount
, 5);
164 ok_eq_ulongptr(Irp
->IoStatus
.Information
, 0);
165 ok_eq_hex(Irp
->IoStatus
.Status
, STATUS_NOT_SUPPORTED
);
166 ok_eq_pointer(Irp
->Tail
.Overlay
.Thread
, NULL
);
167 ok_eq_uint(IoStackLocation
->MajorFunction
, IRP_MJ_POWER
);
168 ok_eq_uint(IoStackLocation
->MinorFunction
, IRP_MN_SET_POWER
);
169 ok_eq_pointer(IoStackLocation
->Context
, RequestedPowerCompletion
);
170 ok_eq_uint(IoStackLocation
->Parameters
.Power
.Type
, DevicePowerState
);
171 ok_eq_uint(IoStackLocation
->Parameters
.Power
.State
.DeviceState
, PowerDeviceD0
);
173 if (DeviceObject
== DeviceObject1
)
175 ok_eq_uint(Irp
->CurrentLocation
, 3);
176 Irp
->IoStatus
.Information
= 7;
177 Irp
->IoStatus
.Status
= STATUS_WAIT_3
;
178 PoStartNextPowerIrp(Irp
);
179 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
180 return STATUS_SUCCESS
;
182 else if (DeviceObject
== DeviceObject2
)
184 ok_eq_uint(Irp
->CurrentLocation
, 3);
185 PoStartNextPowerIrp(Irp
);
186 IoSkipCurrentIrpStackLocation(Irp
);
187 return PoCallDriver(DeviceObject1
, Irp
);
189 else if (DeviceObject
== DeviceObject3
)
191 ok_eq_uint(Irp
->CurrentLocation
, 3);
192 PoStartNextPowerIrp(Irp
);
193 IoSkipCurrentIrpStackLocation(Irp
);
194 return PoCallDriver(DeviceObject2
, Irp
);
199 PoStartNextPowerIrp(Irp
);
200 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
201 return STATUS_NOT_SUPPORTED
;
207 TestPoRequestPowerIrp(VOID
)
210 POWER_STATE PowerState
;
212 KmtRegisterIrpHandler(IRP_MJ_POWER
, NULL
, RequestedPowerIrpHandler
);
214 KeInitializeEvent(&TestDoneEvent
, NotificationEvent
, FALSE
);
216 PowerState
.DeviceState
= PowerDeviceD0
;
217 Status
= PoRequestPowerIrp(DeviceObject2
,
220 RequestedPowerCompletion
,
222 &RequestedPowerIrpReturned
);
223 ok(Status
== STATUS_PENDING
, "PoRequestPowerIrp returned %lx\n", Status
);
224 ok_eq_pointer(RequestedPowerIrpReturned
, RequestedPowerIrp
);
226 Status
= KeWaitForSingleObject(&TestDoneEvent
, Executive
, KernelMode
, FALSE
, NULL
);
227 ok(Status
== STATUS_SUCCESS
, "Status = %lx\n", Status
);
228 KmtUnregisterIrpHandler(IRP_MJ_POWER
, NULL
, RequestedPowerIrpHandler
);
238 _In_ PDEVICE_OBJECT DeviceObject
,
239 _In_ ULONG ControlCode
,
240 _In_ PVOID Buffer OPTIONAL
,
241 _In_ SIZE_T InLength
,
242 _Inout_ PSIZE_T OutLength
)
244 NTSTATUS Status
= STATUS_SUCCESS
;
252 Status
= CreateTestDevices(TestDriverObject
);
253 ok_eq_hex(Status
, STATUS_SUCCESS
);
254 if (!NT_SUCCESS(Status
))
257 TestPoRequestPowerIrp();
259 IoDetachDevice(DeviceObject2
);
260 IoDeleteDevice(DeviceObject3
);
261 IoDetachDevice(DeviceObject1
);
262 IoDeleteDevice(DeviceObject2
);
263 IoDeleteDevice(DeviceObject1
);
268 return STATUS_NOT_SUPPORTED
;