[KMTESTS:PO]

- Add a test for PoRequestPowerIrp

svn path=/trunk/; revision=69499
This commit is contained in:
Thomas Faber 2015-10-11 17:06:14 +00:00
parent 400e093f7b
commit 073a2904ca
7 changed files with 319 additions and 2 deletions

View file

@ -7,6 +7,7 @@ include_directories(include)
add_subdirectory(example)
add_subdirectory(kernel32)
add_subdirectory(ntos_io)
add_subdirectory(ntos_po)
add_subdirectory(tcpip)
list(APPEND COMMON_SOURCE
@ -115,6 +116,7 @@ list(APPEND KMTEST_SOURCE
ntos_io/IoCreateFile_user.c
ntos_io/IoDeviceObject_user.c
ntos_io/IoReadWrite_user.c
ntos_po/PoIrp_user.c
tcpip/TcpIp_user.c
${COMMON_SOURCE}
@ -136,10 +138,12 @@ add_custom_target(kmtest_drivers)
add_dependencies(kmtest_drivers
kmtest_drv
example_drv
findfile_drv
iocreatefile_drv
iodeviceobject_drv
iohelper_drv
ioreadwrite_drv
poirp_drv
tcpip_drv)
add_custom_target(kmtest_all)

View file

@ -12,6 +12,7 @@ KMT_TESTFUNC Test_FindFile;
KMT_TESTFUNC Test_IoCreateFile;
KMT_TESTFUNC Test_IoDeviceObject;
KMT_TESTFUNC Test_IoReadWrite;
KMT_TESTFUNC Test_PoIrp;
KMT_TESTFUNC Test_RtlAvlTree;
KMT_TESTFUNC Test_RtlException;
KMT_TESTFUNC Test_RtlIntSafe;
@ -31,6 +32,7 @@ const KMT_TEST TestList[] =
{ "IoCreateFile", Test_IoCreateFile },
{ "IoDeviceObject", Test_IoDeviceObject },
{ "IoReadWrite", Test_IoReadWrite },
{ "PoIrp", Test_PoIrp },
{ "RtlAvlTree", Test_RtlAvlTree },
{ "RtlException", Test_RtlException },
{ "RtlIntSafe", Test_RtlIntSafe },

View file

@ -310,8 +310,6 @@ DriverDispatch(
PIO_STACK_LOCATION IoStackLocation;
int i;
PAGED_CODE();
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
DPRINT("DriverDispatch: Function=%s, Device=%p\n",

View file

@ -0,0 +1,17 @@
include_directories(../include)
#
# PoIrp
#
list(APPEND POIRP_DRV_SOURCE
../kmtest_drv/kmtest_standalone.c
PoIrp_drv.c)
add_library(poirp_drv SHARED ${POIRP_DRV_SOURCE})
set_module_type(poirp_drv kernelmodedriver)
target_link_libraries(poirp_drv kmtest_printf ${PSEH_LIB})
add_importlibs(poirp_drv ntoskrnl hal)
add_target_compile_definitions(poirp_drv KMT_STANDALONE_DRIVER)
#add_pch(poirp_drv ../include/kmt_test.h)
add_cd_file(TARGET poirp_drv DESTINATION reactos/bin FOR all)

View file

@ -0,0 +1,13 @@
/*
* PROJECT: ReactOS kernel-mode tests
* LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
* PURPOSE: Kernel-Mode Test Suite Power IRP management test declarations
* PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
*/
#ifndef _KMTEST_POIRP_H_
#define _KMTEST_POIRP_H_
#define IOCTL_RUN_TEST 1
#endif /* !defined _KMTEST_POIRP_H_ */

View file

@ -0,0 +1,265 @@
/*
* PROJECT: ReactOS kernel-mode tests
* LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
* PURPOSE: Kernel-Mode Test Suite Power IRP management test
* PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
*/
#include <kmt_test.h>
#include "PoIrp.h"
static PDRIVER_OBJECT TestDriverObject;
static KMT_MESSAGE_HANDLER TestMessageHandler;
static PDEVICE_OBJECT DeviceObject1;
static PDEVICE_OBJECT DeviceObject2;
static PDEVICE_OBJECT DeviceObject3;
static
NTSTATUS
CreateTestDevices(
_In_ PDRIVER_OBJECT DriverObject)
{
NTSTATUS Status;
PDEVICE_OBJECT AttachedDevice;
Status = IoCreateDevice(DriverObject, 0, NULL, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject1);
if (!NT_SUCCESS(Status))
return Status;
DeviceObject1->Flags &= ~DO_DEVICE_INITIALIZING;
Status = IoCreateDevice(DriverObject, 0, NULL, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject2);
if (!NT_SUCCESS(Status))
{
IoDeleteDevice(DeviceObject1);
return Status;
}
AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject2, DeviceObject1);
ok(AttachedDevice == DeviceObject1, "Device attached to %p is %p, expected %p\n", DeviceObject2, AttachedDevice, DeviceObject1);
if (AttachedDevice == NULL)
{
IoDeleteDevice(DeviceObject2);
IoDeleteDevice(DeviceObject1);
return STATUS_UNSUCCESSFUL;
}
DeviceObject2->Flags &= ~DO_DEVICE_INITIALIZING;
Status = IoCreateDevice(DriverObject, 0, NULL, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject3);
if (!NT_SUCCESS(Status))
{
IoDetachDevice(DeviceObject1);
IoDeleteDevice(DeviceObject2);
IoDeleteDevice(DeviceObject1);
return Status;
}
AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject3, DeviceObject1);
ok(AttachedDevice == DeviceObject2, "Device attached to %p is %p, expected %p\n", DeviceObject2, AttachedDevice, DeviceObject2);
if (AttachedDevice == NULL)
{
IoDeleteDevice(DeviceObject3);
IoDetachDevice(DeviceObject1);
IoDeleteDevice(DeviceObject2);
IoDeleteDevice(DeviceObject1);
return STATUS_UNSUCCESSFUL;
}
DeviceObject3->Flags &= ~DO_DEVICE_INITIALIZING;
return Status;
}
NTSTATUS
TestEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PCUNICODE_STRING RegistryPath,
_Out_ PCWSTR *DeviceName,
_Inout_ INT *Flags)
{
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
UNREFERENCED_PARAMETER(RegistryPath);
TestDriverObject = DriverObject;
*DeviceName = L"PoIrp";
*Flags = TESTENTRY_NO_EXCLUSIVE_DEVICE;
KmtRegisterMessageHandler(0, NULL, TestMessageHandler);
return Status;
}
VOID
TestUnload(
IN PDRIVER_OBJECT DriverObject)
{
UNREFERENCED_PARAMETER(DriverObject);
PAGED_CODE();
}
//
// PoRequestPowerIrp test
//
static KEVENT TestDoneEvent;
static PIRP RequestedPowerIrp;
static PIRP RequestedPowerIrpReturned;
static
VOID
NTAPI
RequestedPowerCompletion(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ UCHAR MinorFunction,
_In_ POWER_STATE PowerState,
_In_opt_ PVOID Context,
_In_ PIO_STATUS_BLOCK IoStatus)
{
PIRP Irp;
PIO_STACK_LOCATION IoStackLocation;
ok_eq_pointer(DeviceObject, DeviceObject2);
ok_eq_uint(MinorFunction, IRP_MN_SET_POWER);
ok_eq_uint(PowerState.DeviceState, PowerDeviceD0);
ok_eq_pointer(Context, &RequestedPowerIrp);
Irp = CONTAINING_RECORD(IoStatus, IRP, IoStatus);
ok_eq_pointer(Irp, RequestedPowerIrp);
ok_eq_ulongptr(IoStatus->Information, 7);
ok_eq_hex(IoStatus->Status, STATUS_WAIT_3);
KeSetEvent(&TestDoneEvent, IO_NO_INCREMENT, FALSE);
ok_eq_uint(Irp->StackCount, 5);
ok_eq_uint(Irp->CurrentLocation, 4);
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
ok_eq_pointer(IoStackLocation->Parameters.Others.Argument1, DeviceObject);
ok_eq_pointer(IoStackLocation->Parameters.Others.Argument2, (PVOID)MinorFunction);
ok_eq_pointer(IoStackLocation->Parameters.Others.Argument3, (PVOID)PowerState.SystemState);
ok_eq_pointer(IoStackLocation->Parameters.Others.Argument4, Context);
}
static
NTSTATUS
RequestedPowerIrpHandler(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp,
_In_ PIO_STACK_LOCATION IoStackLocation)
{
if (RequestedPowerIrp == NULL)
RequestedPowerIrp = Irp;
else
ok_eq_pointer(Irp, RequestedPowerIrp);
ok_eq_uint(Irp->StackCount, 5);
ok_eq_ulongptr(Irp->IoStatus.Information, 0);
ok_eq_hex(Irp->IoStatus.Status, STATUS_NOT_SUPPORTED);
ok_eq_uint(IoStackLocation->MajorFunction, IRP_MJ_POWER);
ok_eq_uint(IoStackLocation->MinorFunction, IRP_MN_SET_POWER);
ok_eq_uint(IoStackLocation->Parameters.Power.Type, DevicePowerState);
ok_eq_uint(IoStackLocation->Parameters.Power.State.DeviceState, PowerDeviceD0);
if (DeviceObject == DeviceObject1)
{
ok_eq_uint(Irp->CurrentLocation, 3);
Irp->IoStatus.Information = 7;
Irp->IoStatus.Status = STATUS_WAIT_3;
PoStartNextPowerIrp(Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
else if (DeviceObject == DeviceObject2)
{
ok_eq_uint(Irp->CurrentLocation, 3);
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver(DeviceObject1, Irp);
}
else if (DeviceObject == DeviceObject3)
{
ok_eq_uint(Irp->CurrentLocation, 3);
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver(DeviceObject2, Irp);
}
else
{
ok(0, "\n");
PoStartNextPowerIrp(Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_SUPPORTED;
}
}
static
VOID
TestPoRequestPowerIrp(VOID)
{
NTSTATUS Status;
POWER_STATE PowerState;
KmtRegisterIrpHandler(IRP_MJ_POWER, NULL, RequestedPowerIrpHandler);
KeInitializeEvent(&TestDoneEvent, NotificationEvent, FALSE);
PowerState.DeviceState = PowerDeviceD0;
Status = PoRequestPowerIrp(DeviceObject2,
IRP_MN_SET_POWER,
PowerState,
RequestedPowerCompletion,
&RequestedPowerIrp,
&RequestedPowerIrpReturned);
ok(Status == STATUS_PENDING, "PoRequestPowerIrp returned %lx\n", Status);
ok_eq_pointer(RequestedPowerIrpReturned, RequestedPowerIrp);
Status = KeWaitForSingleObject(&TestDoneEvent, Executive, KernelMode, FALSE, NULL);
ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
KmtUnregisterIrpHandler(IRP_MJ_POWER, NULL, RequestedPowerIrpHandler);
}
//
// Message handler
//
static
NTSTATUS
TestMessageHandler(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ ULONG ControlCode,
_In_ PVOID Buffer OPTIONAL,
_In_ SIZE_T InLength,
_Inout_ PSIZE_T OutLength)
{
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
switch (ControlCode)
{
case IOCTL_RUN_TEST:
{
Status = CreateTestDevices(TestDriverObject);
ok_eq_hex(Status, STATUS_SUCCESS);
if (!NT_SUCCESS(Status))
return Status;
TestPoRequestPowerIrp();
IoDetachDevice(DeviceObject2);
IoDeleteDevice(DeviceObject3);
IoDetachDevice(DeviceObject1);
IoDeleteDevice(DeviceObject2);
IoDeleteDevice(DeviceObject1);
break;
}
default:
return STATUS_NOT_SUPPORTED;
}
return Status;
}

View file

@ -0,0 +1,18 @@
/*
* PROJECT: ReactOS kernel-mode tests
* LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
* PURPOSE: Kernel-Mode Test Suite power IRP management test user-mode part
* PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
*/
#include <kmt_test.h>
#include "PoIrp.h"
START_TEST(PoIrp)
{
KmtLoadDriver(L"PoIrp", TRUE);
KmtOpenDriver();
KmtSendToDriver(IOCTL_RUN_TEST);
KmtCloseDriver();
KmtUnloadDriver();
}