Author: tfaber
Date: Fri Jul  8 06:38:01 2011
New Revision: 52567

URL: http://svn.reactos.org/svn/reactos?rev=52567&view=rev
Log:
[KMTESTS/KE]
- add a test for DPCs
- add a test for IRQ levels

Added:
    branches/GSoC_2011/KMTestSuite/kmtests/ntos_ke/KeDpc.c   (with props)
    branches/GSoC_2011/KMTestSuite/kmtests/ntos_ke/KeIrql.c   (with props)
Modified:
    branches/GSoC_2011/KMTestSuite/kmtests/CMakeLists.txt
    branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv.rbuild
    branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv/testlist.c

Modified: branches/GSoC_2011/KMTestSuite/kmtests/CMakeLists.txt
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/CMakeLists.txt?rev=52567&r1=52566&r2=52567&view=diff
==============================================================================
--- branches/GSoC_2011/KMTestSuite/kmtests/CMakeLists.txt [iso-8859-1] 
(original)
+++ branches/GSoC_2011/KMTestSuite/kmtests/CMakeLists.txt [iso-8859-1] Fri Jul  
8 06:38:01 2011
@@ -4,7 +4,7 @@
 #
 # subdirectories containing special-purpose drivers
 #
-add_subdirectory(Example)
+add_subdirectory(example)
 
 #
 # kmtest_drv.sys driver
@@ -20,6 +20,8 @@
     ntos_io/IoDeviceInterface.c
     ntos_io/IoIrp.c
     ntos_io/IoMdl.c
+    ntos_ke/KeDpc.c
+    ntos_ke/KeIrql.c
     ntos_ke/KeProcessor.c
     ntos_ob/ObCreate.c
 

Modified: branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv.rbuild
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv.rbuild?rev=52567&r1=52566&r2=52567&view=diff
==============================================================================
--- branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv.rbuild [iso-8859-1] 
(original)
+++ branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv.rbuild [iso-8859-1] Fri 
Jul  8 06:38:01 2011
@@ -25,6 +25,8 @@
                <file>IoMdl.c</file>
        </directory>
        <directory name="ntos_ke">
+               <file>KeDpc.c</file>
+               <file>KeIrql.c</file>
                <file>KeProcessor.c</file>
        </directory>
        <directory name="ntos_ob">

Modified: branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv/testlist.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv/testlist.c?rev=52567&r1=52566&r2=52567&view=diff
==============================================================================
--- branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv/testlist.c [iso-8859-1] 
(original)
+++ branches/GSoC_2011/KMTestSuite/kmtests/kmtest_drv/testlist.c [iso-8859-1] 
Fri Jul  8 06:38:01 2011
@@ -15,6 +15,8 @@
 KMT_TESTFUNC Test_IoDeviceInterface;
 KMT_TESTFUNC Test_IoIrp;
 KMT_TESTFUNC Test_IoMdl;
+KMT_TESTFUNC Test_KeDpc;
+KMT_TESTFUNC Test_KeIrql;
 KMT_TESTFUNC Test_KeProcessor;
 KMT_TESTFUNC Test_ObCreate;
 
@@ -27,6 +29,8 @@
     { "IoDeviceInterface",  Test_IoDeviceInterface },
     { "IoIrp",              Test_IoIrp },
     { "IoMdl",              Test_IoMdl },
+    { "KeDpc",              Test_KeDpc },
+    { "KeIrql",             Test_KeIrql },
     { "KeProcessor",        Test_KeProcessor },
     { "ObCreate",           Test_ObCreate },
     { NULL,                 NULL }

Added: branches/GSoC_2011/KMTestSuite/kmtests/ntos_ke/KeDpc.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/ntos_ke/KeDpc.c?rev=52567&view=auto
==============================================================================
--- branches/GSoC_2011/KMTestSuite/kmtests/ntos_ke/KeDpc.c (added)
+++ branches/GSoC_2011/KMTestSuite/kmtests/ntos_ke/KeDpc.c [iso-8859-1] Fri Jul 
 8 06:38:01 2011
@@ -1,0 +1,185 @@
+/*
+ * PROJECT:         ReactOS kernel-mode tests
+ * LICENSE:         GPLv2+ - See COPYING in the top level directory
+ * PURPOSE:         Kernel-Mode Test Suite Deferred Procedure Call test
+ * PROGRAMMER:      Thomas Faber <[email protected]>
+ */
+
+#include <ntddk.h>
+#include <ntifs.h>
+#include <ndk/ketypes.h>
+#include <kmt_test.h>
+#include <pseh/pseh2.h>
+
+//#define NDEBUG
+#include <debug.h>
+
+/* TODO: DPC importance */
+
+static volatile LONG DpcCount = 0;
+static volatile UCHAR DpcImportance = MediumImportance;
+
+static KDEFERRED_ROUTINE DpcHandler;
+
+static
+VOID
+NTAPI
+DpcHandler(
+    IN PRKDPC Dpc,
+    IN PVOID DeferredContext,
+    IN PVOID SystemArgument1,
+    IN PVOID SystemArgument2)
+{
+    PKPCR Pcr = KeGetPcr();
+    PKPRCB Prcb = Pcr->Prcb;
+
+    ok_irql(DISPATCH_LEVEL);
+    InterlockedIncrement(&DpcCount);
+    ok(DeferredContext == Dpc, "DeferredContext = %p, Dpc = %p, expected 
equal\n", DeferredContext, Dpc);
+    ok_eq_pointer(SystemArgument1, (PVOID)0xabc123);
+    ok_eq_pointer(SystemArgument2, (PVOID)0x5678);
+
+    /* KDPC object contents */
+    ok_eq_uint(Dpc->Type, DpcObject);
+    ok_eq_uint(Dpc->Importance, DpcImportance);
+    ok_eq_uint(Dpc->Number, 0);
+    ok(Dpc->DpcListEntry.Blink != NULL, "\n");
+    ok(Dpc->DpcListEntry.Blink != &Dpc->DpcListEntry, "\n");
+    if (!skip(Dpc->DpcListEntry.Blink != NULL, "DpcListEntry.Blink == NULL\n"))
+        ok_eq_pointer(Dpc->DpcListEntry.Flink, Dpc->DpcListEntry.Blink->Flink);
+
+    ok(Dpc->DpcListEntry.Flink != NULL, "\n");
+    ok(Dpc->DpcListEntry.Flink != &Dpc->DpcListEntry, "\n");
+    if (!skip(Dpc->DpcListEntry.Flink != NULL, "DpcListEntry.Flink == NULL\n"))
+        ok_eq_pointer(Dpc->DpcListEntry.Blink, Dpc->DpcListEntry.Flink->Blink);
+
+    ok_eq_pointer(Dpc->DeferredRoutine, DpcHandler);
+    ok_eq_pointer(Dpc->DeferredContext, DeferredContext);
+    ok_eq_pointer(Dpc->SystemArgument1, SystemArgument1);
+    ok_eq_pointer(Dpc->SystemArgument2, SystemArgument2);
+    ok_eq_pointer(Dpc->DpcData, NULL);
+    
+    ok_eq_uint(Prcb->DpcRoutineActive, 1);
+    /* this DPC is not in the list anymore, but it was at the head! */
+    ok_eq_pointer(Prcb->DpcData[DPC_NORMAL].DpcListHead.Flink, 
Dpc->DpcListEntry.Flink);
+    ok_eq_pointer(Prcb->DpcData[DPC_NORMAL].DpcListHead.Blink, 
Dpc->DpcListEntry.Blink);
+}
+
+START_TEST(KeDpc)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    KDPC Dpc;
+    KIRQL Irql, Irql2, Irql3;
+    LONG ExpectedDpcCount = 0;
+    BOOLEAN Ret;
+    int i;
+
+#define ok_dpccount() ok(DpcCount == ExpectedDpcCount, "DpcCount = %ld, 
expected %ld\n", DpcCount, ExpectedDpcCount);
+    trace("Dpc = %p\n", &Dpc);
+    memset(&Dpc, 0x55, sizeof Dpc);
+    KeInitializeDpc(&Dpc, DpcHandler, &Dpc);
+    /* check the Dpc object's fields */
+    ok_eq_uint(Dpc.Type, DpcObject);
+    ok_eq_uint(Dpc.Importance, DpcImportance);
+    ok_eq_uint(Dpc.Number, 0);
+    ok_eq_pointer(Dpc.DpcListEntry.Flink, (LIST_ENTRY *)0x5555555555555555);
+    ok_eq_pointer(Dpc.DpcListEntry.Blink, (LIST_ENTRY *)0x5555555555555555);
+    ok_eq_pointer(Dpc.DeferredRoutine, DpcHandler);
+    ok_eq_pointer(Dpc.DeferredContext, &Dpc);
+    ok_eq_pointer(Dpc.SystemArgument1, (PVOID)0x5555555555555555);
+    ok_eq_pointer(Dpc.SystemArgument2, (PVOID)0x5555555555555555);
+    ok_eq_pointer(Dpc.DpcData, NULL);
+
+    /* simply run the Dpc a few times */
+    for (i = 0; i < 5; ++i)
+    {
+        ok_dpccount();
+        Ret = KeInsertQueueDpc(&Dpc, (PVOID)0xabc123, (PVOID)0x5678);
+        ok_bool_true(Ret, "KeInsertQueueDpc returned");
+        ++ExpectedDpcCount;
+        ok_dpccount();
+    }
+
+    /* insert into queue at high irql
+     * -> should only run when lowered to APC_LEVEL,
+     *    inserting a second time should fail
+     */
+    KeRaiseIrql(APC_LEVEL, &Irql);
+    for (i = 0; i < 5; ++i)
+    {
+        KeRaiseIrql(DISPATCH_LEVEL, &Irql2);
+          ok_dpccount();
+          Ret = KeInsertQueueDpc(&Dpc, (PVOID)0xabc123, (PVOID)0x5678);
+          ok_bool_true(Ret, "KeInsertQueueDpc returned");
+          Ret = KeInsertQueueDpc(&Dpc, (PVOID)0xdef, (PVOID)0x123);
+          ok_bool_false(Ret, "KeInsertQueueDpc returned");
+          ok_dpccount();
+          KeRaiseIrql(HIGH_LEVEL, &Irql3);
+            ok_dpccount();
+          KeLowerIrql(Irql3);
+          ok_dpccount();
+          DPRINT1("This is a debug print\n");
+          ok_dpccount();
+        KeLowerIrql(Irql2);
+        ++ExpectedDpcCount;
+        ok_dpccount();
+    }
+    KeLowerIrql(Irql);
+
+    /* now test removing from the queue */
+    KeRaiseIrql(APC_LEVEL, &Irql);
+    for (i = 0; i < 5; ++i)
+    {
+        KeRaiseIrql(DISPATCH_LEVEL, &Irql2);
+          ok_dpccount();
+          Ret = KeRemoveQueueDpc(&Dpc);
+          ok_bool_false(Ret, "KeRemoveQueueDpc returned");
+          Ret = KeInsertQueueDpc(&Dpc, (PVOID)0xabc123, (PVOID)0x5678);
+          ok_bool_true(Ret, "KeInsertQueueDpc returned");
+          ok_dpccount();
+          KeRaiseIrql(HIGH_LEVEL, &Irql3);
+            ok_dpccount();
+          KeLowerIrql(Irql3);
+          ok_dpccount();
+          Ret = KeRemoveQueueDpc(&Dpc);
+          ok_bool_true(Ret, "KeRemoveQueueDpc returned");
+        KeLowerIrql(Irql2);
+        ok_dpccount();
+    }
+    KeLowerIrql(Irql);
+
+    /* parameter checks */
+    Status = STATUS_SUCCESS;
+    _SEH2_TRY {
+        KeInitializeDpc(&Dpc, NULL, NULL);
+    } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+        Status = _SEH2_GetExceptionCode();
+    } _SEH2_END;
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    if (!skip(Status == STATUS_SUCCESS, "KeInitializeDpc failed\n"))
+    {
+        KeRaiseIrql(HIGH_LEVEL, &Irql);
+          Ret = KeInsertQueueDpc(&Dpc, NULL, NULL);
+          ok_bool_true(Ret, "KeInsertQueueDpc returned");
+          Ret = KeRemoveQueueDpc(&Dpc);
+          ok_bool_true(Ret, "KeRemoveQueueDpc returned");
+        KeLowerIrql(Irql);
+    }
+
+    Status = STATUS_SUCCESS;
+    _SEH2_TRY {
+        KeInitializeDpc(NULL, NULL, NULL);
+    } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+        Status = _SEH2_GetExceptionCode();
+    } _SEH2_END;
+    ok_eq_hex(Status, STATUS_ACCESS_VIOLATION);
+
+    /* These result in IRQL_NOT_LESS_OR_EQUAL on 2k3 -- IRQLs 0x1f and 0xff (?)
+    Ret = KeInsertQueueDpc(NULL, NULL, NULL);
+    Ret = KeRemoveQueueDpc(NULL);*/
+
+    ok_dpccount();
+    ok_irql(PASSIVE_LEVEL);
+    trace("Final Dpc count: %ld, expected %ld\n", DpcCount, ExpectedDpcCount);
+}

Propchange: branches/GSoC_2011/KMTestSuite/kmtests/ntos_ke/KeDpc.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/GSoC_2011/KMTestSuite/kmtests/ntos_ke/KeIrql.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/KMTestSuite/kmtests/ntos_ke/KeIrql.c?rev=52567&view=auto
==============================================================================
--- branches/GSoC_2011/KMTestSuite/kmtests/ntos_ke/KeIrql.c (added)
+++ branches/GSoC_2011/KMTestSuite/kmtests/ntos_ke/KeIrql.c [iso-8859-1] Fri 
Jul  8 06:38:01 2011
@@ -1,0 +1,135 @@
+/*
+ * PROJECT:         ReactOS kernel-mode tests
+ * LICENSE:         GPLv2+ - See COPYING in the top level directory
+ * PURPOSE:         Kernel-Mode Test Suite Interrupt Request Level test
+ * PROGRAMMER:      Thomas Faber <[email protected]>
+ */
+
+#include <ntddk.h>
+#include <ntifs.h>
+#include <ndk/ntndk.h>
+#include <kmt_test.h>
+#include <pseh/pseh2.h>
+
+#define NDEBUG
+#include <debug.h>
+
+START_TEST(KeIrql)
+{
+    KIRQL Irql, Irql2, PrevIrql, SynchIrql;
+
+    /* we should be called at PASSIVE_LEVEL */
+    ok_irql(PASSIVE_LEVEL);
+
+    PrevIrql = KeGetCurrentIrql();
+
+    // SYNCH_LEVEL is different for UP/MP
+    if (KeGetCurrentPrcb()->BuildType & PRCB_BUILD_UNIPROCESSOR)
+    {
+        trace("This is a Uniprocessor kernel\n");
+        SynchIrql = DISPATCH_LEVEL;
+    }
+    else
+    {
+        trace("This is a Multiprocessor kernel\n");
+        SynchIrql = IPI_LEVEL - 2;
+    }
+    
+    /* some Irqls MUST work */
+    {
+    const KIRQL Irqls[] = { LOW_LEVEL, PASSIVE_LEVEL, APC_LEVEL, 
DISPATCH_LEVEL,
+                            CMCI_LEVEL, CLOCK1_LEVEL, CLOCK2_LEVEL, 
CLOCK_LEVEL,
+                            PROFILE_LEVEL, IPI_LEVEL, /*POWER_LEVEL,*/ 
SynchIrql, HIGH_LEVEL };
+    int i;
+    for (i = 0; i < sizeof Irqls / sizeof Irqls[0]; ++i)
+    {
+        KeRaiseIrql(Irqls[i], &Irql2);
+        ok_eq_uint(Irql2, PrevIrql);
+        ok_irql(Irqls[i]);
+        KeLowerIrql(Irql2);
+        ok_irql(PrevIrql);
+    }
+    }
+
+    /* raising/lowering to the current level should have no effect */
+    ok_irql(PASSIVE_LEVEL);
+    KeRaiseIrql(PASSIVE_LEVEL, &Irql);
+    ok_eq_uint(Irql, PASSIVE_LEVEL);
+    KeLowerIrql(PASSIVE_LEVEL);
+    ok_irql(PASSIVE_LEVEL);
+
+    /* try to raise to each Irql and back */
+    for (Irql = PASSIVE_LEVEL; Irql <= HIGH_LEVEL; ++Irql)
+    {
+        DPRINT("Raising to %u\n", Irql);
+        KeRaiseIrql(Irql, &Irql2);
+        ok_eq_uint(Irql2, PrevIrql);
+        KeLowerIrql(Irql2);
+        ok_irql(PrevIrql);
+    }
+
+    /* go through all Irqls in order, skip the ones that the system doesn't 
accept */
+    for (Irql = PASSIVE_LEVEL; Irql <= HIGH_LEVEL; ++Irql)
+    {
+        DPRINT("Raising to %u\n", Irql);
+        KeRaiseIrql(Irql, &Irql2);
+        ok_eq_uint(Irql2, PrevIrql);
+        Irql2 = KeGetCurrentIrql();
+        ok(Irql2 <= Irql, "New Irql is %u, expected <= requested value of 
%u\n", Irql2, Irql);
+        PrevIrql = Irql2;
+    }
+
+    ok_irql(HIGH_LEVEL);
+
+    /* now go back again, skipping the ones that don't work */
+    for (Irql = HIGH_LEVEL; Irql > PASSIVE_LEVEL;)
+    {
+        DPRINT("Lowering to %u\n", Irql - 1);
+        KeLowerIrql(Irql - 1);
+        Irql2 = KeGetCurrentIrql();
+        ok(Irql2 < Irql, "New Irql is %u, expected <= requested value of 
%u\n", Irql2, Irql - 1);
+        if (Irql2 < Irql)
+            Irql = Irql2;
+        else
+            --Irql;
+    }
+
+    DPRINT("Alive!\n");
+    /* on x86, you can raise to _any_ possible KIRQL value */
+    /* on x64, anything with more than the least significant 4 bits set 
bugchecked, last time I tried */
+    /* TODO: other platforms? */
+#if defined _M_X86
+    for (Irql = PASSIVE_LEVEL; Irql <= (KIRQL)-1; ++Irql)
+    {
+        DPRINT("Raising to %u\n", Irql);
+        KeRaiseIrql(Irql, &Irql2);
+        ok_eq_uint(Irql2, PrevIrql);
+        KeLowerIrql(Irql2);
+        ok_irql(PrevIrql);
+    }
+#endif /* defined _M_X86 */
+
+    /* test KeRaiseIrqlToDpcLevel */
+    ok_irql(PASSIVE_LEVEL);
+    Irql = KeRaiseIrqlToDpcLevel();
+    ok_irql(DISPATCH_LEVEL);
+    ok_eq_uint(Irql, PASSIVE_LEVEL);
+    Irql = KeRaiseIrqlToDpcLevel();
+    ok_irql(DISPATCH_LEVEL);
+    ok_eq_uint(Irql, DISPATCH_LEVEL);
+    KeLowerIrql(PASSIVE_LEVEL);
+
+    /* test KeRaiseIrqlToSynchLevel */
+    ok_irql(PASSIVE_LEVEL);
+    Irql = KeRaiseIrqlToSynchLevel();
+    ok_irql(SynchIrql);
+    ok_eq_uint(Irql, PASSIVE_LEVEL);
+    Irql = KeRaiseIrqlToSynchLevel();
+    ok_irql(SynchIrql);
+    ok_eq_uint(Irql, SynchIrql);
+    KeLowerIrql(PASSIVE_LEVEL);
+
+    /* make sure we exit gracefully */
+    ok_irql(PASSIVE_LEVEL);
+    KeLowerIrql(PASSIVE_LEVEL);
+}

Propchange: branches/GSoC_2011/KMTestSuite/kmtests/ntos_ke/KeIrql.c
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to