[KMTESTS:PO]
authorThomas Faber <thomas.faber@reactos.org>
Sun, 11 Oct 2015 17:06:14 +0000 (17:06 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Sun, 11 Oct 2015 17:06:14 +0000 (17:06 +0000)
- Add a test for PoRequestPowerIrp

svn path=/trunk/; revision=69499

rostests/kmtests/CMakeLists.txt
rostests/kmtests/kmtest/testlist.c
rostests/kmtests/kmtest_drv/kmtest_standalone.c
rostests/kmtests/ntos_po/CMakeLists.txt [new file with mode: 0644]
rostests/kmtests/ntos_po/PoIrp.h [new file with mode: 0644]
rostests/kmtests/ntos_po/PoIrp_drv.c [new file with mode: 0644]
rostests/kmtests/ntos_po/PoIrp_user.c [new file with mode: 0644]

index 30dcade..730f7f3 100644 (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)
index 2823a07..360e120 100644 (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 },
index a2e397a..c6ad096 100644 (file)
@@ -310,8 +310,6 @@ DriverDispatch(
     PIO_STACK_LOCATION IoStackLocation;
     int i;
 
-    PAGED_CODE();
-
     IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
 
     DPRINT("DriverDispatch: Function=%s, Device=%p\n",
diff --git a/rostests/kmtests/ntos_po/CMakeLists.txt b/rostests/kmtests/ntos_po/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e6f0745
--- /dev/null
@@ -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)
diff --git a/rostests/kmtests/ntos_po/PoIrp.h b/rostests/kmtests/ntos_po/PoIrp.h
new file mode 100644 (file)
index 0000000..055f711
--- /dev/null
@@ -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_ */
diff --git a/rostests/kmtests/ntos_po/PoIrp_drv.c b/rostests/kmtests/ntos_po/PoIrp_drv.c
new file mode 100644 (file)
index 0000000..7147dd1
--- /dev/null
@@ -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;
+}
diff --git a/rostests/kmtests/ntos_po/PoIrp_user.c b/rostests/kmtests/ntos_po/PoIrp_user.c
new file mode 100644 (file)
index 0000000..ed945ea
--- /dev/null
@@ -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();
+}