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/C…
==============================================================================
--- 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/k…
==============================================================================
--- 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/k…
==============================================================================
--- 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/n…
==============================================================================
--- 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 <thfabba(a)gmx.de>
+ */
+
+#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/n…
==============================================================================
--- 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 <thfabba(a)gmx.de>
+ */
+
+#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