From 881c40e13359e82af61b799db327ae1986637c36 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sat, 8 Jun 2013 10:19:26 +0000 Subject: [PATCH] [KMTEST] - Implement simple KeDeviceQueue test by Moscow State Technical University students. Improvements are welcome. svn path=/trunk/; revision=59188 --- rostests/kmtests/CMakeLists.txt | 1 + rostests/kmtests/kmtest_drv/testlist.c | 2 + rostests/kmtests/ntos_ke/KeDevQueue.c | 200 +++++++++++++++++++++++++ 3 files changed, 203 insertions(+) create mode 100644 rostests/kmtests/ntos_ke/KeDevQueue.c diff --git a/rostests/kmtests/CMakeLists.txt b/rostests/kmtests/CMakeLists.txt index 2595562fc53..9c93fe780db 100644 --- a/rostests/kmtests/CMakeLists.txt +++ b/rostests/kmtests/CMakeLists.txt @@ -44,6 +44,7 @@ list(APPEND KMTEST_DRV_SOURCE ntos_io/IoIrp.c ntos_io/IoMdl.c ntos_ke/KeApc.c + ntos_ke/KeDevQueue.c ntos_ke/KeDpc.c ntos_ke/KeEvent.c ntos_ke/KeGuardedMutex.c diff --git a/rostests/kmtests/kmtest_drv/testlist.c b/rostests/kmtests/kmtest_drv/testlist.c index 735cb585405..e12ed6cabe6 100644 --- a/rostests/kmtests/kmtest_drv/testlist.c +++ b/rostests/kmtests/kmtest_drv/testlist.c @@ -28,6 +28,7 @@ KMT_TESTFUNC Test_IoInterrupt; KMT_TESTFUNC Test_IoIrp; KMT_TESTFUNC Test_IoMdl; KMT_TESTFUNC Test_KeApc; +KMT_TESTFUNC Test_KeDeviceQueue; KMT_TESTFUNC Test_KeDpc; KMT_TESTFUNC Test_KeEvent; KMT_TESTFUNC Test_KeGuardedMutex; @@ -76,6 +77,7 @@ const KMT_TEST TestList[] = { "IoIrp", Test_IoIrp }, { "IoMdl", Test_IoMdl }, { "KeApc", Test_KeApc }, + { "KeDeviceQueue", Test_KeDeviceQueue }, { "KeDpc", Test_KeDpc }, { "KeEvent", Test_KeEvent }, { "KeGuardedMutex", Test_KeGuardedMutex }, diff --git a/rostests/kmtests/ntos_ke/KeDevQueue.c b/rostests/kmtests/ntos_ke/KeDevQueue.c new file mode 100644 index 00000000000..59a6407c582 --- /dev/null +++ b/rostests/kmtests/ntos_ke/KeDevQueue.c @@ -0,0 +1,200 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Kernel-Mode Test Suite for Device Queues + * PROGRAMMERS: Pavel Batusov, Moscow State Technical University + * Denis Volhonsky, Moscow State Technical University + * Alexandra Safonova, Moscow State Technical University + */ + +#include + +#define NDEBUG +#include + +#define NUMBER 255 +#define INSERT_COUNT 5 + +int Check_mem(void* a, int n, int size) +{ + int i; + for (i = 0; i < size; i++) { + if (*((unsigned char*)a + i) != n) { + return 0; + } + } + return 1; +} + +void Test_Initialize() +{ + PKDEVICE_QUEUE testing_queue; + void* double_queue; + + trace("******* Testing KeInitializeDeviceQueue ************\n"); + DPRINT1("\nStart test for KeInitializeDeviceQueue function\n"); + + testing_queue = ExAllocatePool(NonPagedPool, sizeof(KDEVICE_QUEUE)); + + testing_queue->Busy = TRUE; + testing_queue->Size = 0; + + KeInitializeDeviceQueue(testing_queue); + + /* Check for properly setting up fields */ + ok(!testing_queue->Busy, "(Initialize testing) Test 1:\tExpected 'not busy' status\n"); + DPRINT1("1 test complete\n"); + + ok(testing_queue->Size == sizeof(KDEVICE_QUEUE), "(Initialize testing) Test 2:\tExpected another size for KDEVICE_QUEUE\n"); + DPRINT1("2 test complete\n"); + + ok(testing_queue->Type == DeviceQueueObject, "(Initialize testing) Test 3:\tExpected type == DeviceQueueObject\n"); + DPRINT1("3 test complete\n"); + + /* Make sure it does not write outside allocated buffer */ + double_queue = ExAllocatePool(NonPagedPool, sizeof(KDEVICE_QUEUE) * 2); + + memset(double_queue, NUMBER, sizeof(KDEVICE_QUEUE) * 2); + KeInitializeDeviceQueue(double_queue); + + ok(Check_mem((void*)((char*)double_queue + sizeof(KDEVICE_QUEUE)), NUMBER, sizeof(KDEVICE_QUEUE)), "(Initialize testing) Test 4:\tFunction uses someone else's memory \n"); + DPRINT1("4 test complete\n"); + +//==================================================================== + + ExFreePool(testing_queue); + ExFreePool(double_queue); + + DPRINT1("KeInitializeDeviceQueue test finished\n"); +} + +void Tests_Insert_And_Delete() +{ + ULONG i, j; + PKDEVICE_QUEUE testing_queue; + PKDEVICE_QUEUE_ENTRY element; + KIRQL OldIrql; + PKDEVICE_QUEUE_ENTRY* elem_array; + PLIST_ENTRY next; + ULONG key; + + trace("******* Testing KeInsertDeviceQueue **************** \n"); + DPRINT1("\nStart KeInsertDeviceQueue test\n"); + + testing_queue = ExAllocatePool(NonPagedPool, sizeof(KDEVICE_QUEUE)); + KeInitializeDeviceQueue(testing_queue); + + element = ExAllocatePool(NonPagedPool, sizeof(KDEVICE_QUEUE_ENTRY)); + + /* Raise to dispatch level */ + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + + KeInsertDeviceQueue(testing_queue, element); + ok(!element->Inserted, "Wrong 'Inserted' status\n"); + DPRINT1("1 test complete\n"); + + /* Fill the queue*/ + elem_array = ExAllocatePool(NonPagedPool, sizeof(PKDEVICE_QUEUE_ENTRY) * INSERT_COUNT); + + DPRINT1("Arrow of tests starting\n"); + for (i = 0; i < INSERT_COUNT; i++) { + elem_array[i] = ExAllocatePool(NonPagedPool, sizeof(KDEVICE_QUEUE_ENTRY)); + elem_array[i]->Inserted = FALSE; + elem_array[i]->SortKey = i; + KeInsertDeviceQueue(testing_queue, elem_array[i]); + ok(elem_array[i]->Inserted, "Element was not inserted\n"); + } + DPRINT1("Arrow of tests complete\n"); + + ok(testing_queue->Size == sizeof(KDEVICE_QUEUE), "Wrong size of queue\n"); + + /* Check how the queue was filled */ + next = &testing_queue->DeviceListHead; + + DPRINT1("Arrow of tests starting\n"); + for (i = 0; i < INSERT_COUNT; i++) { + next = next->Flink; + key = CONTAINING_RECORD(next, KDEVICE_QUEUE_ENTRY, DeviceListEntry)->SortKey; + ok(key == i, "Sort key was changed\n"); + } + DPRINT1("Arrow of tests complete\n"); + + trace("****************************************************\n\n"); + DPRINT1("KeInsertDeviceQueue test finish\n"); + + /* Test deletion */ + trace("******* Testing KeRemoveDeviceQueue **************** \n"); + DPRINT1("\nStart KeRemoveDeviceQueue test\n"); + + PKDEVICE_QUEUE_ENTRY return_value; + + DPRINT1("Start deleting elements from queue\n"); + for (i = 0; i < INSERT_COUNT; i++) { + return_value = KeRemoveDeviceQueue(testing_queue); + ok(return_value == elem_array[i], "Returning element != head element\n"); + ok(return_value->Inserted == FALSE, "Returning element is still in queue\n"); + next = &testing_queue->DeviceListHead; + for (j = i + 1; j < INSERT_COUNT; j++) { + next = next->Flink; + ok(CONTAINING_RECORD(next, KDEVICE_QUEUE_ENTRY, DeviceListEntry)->SortKey == j, "Queue was damaged\n"); + } + } + DPRINT1("Deleting finish. Queue must be empty\n"); + + ok(KeRemoveDeviceQueue(testing_queue) == NULL, "Queue is not empty\n"); + ok(testing_queue->Busy == FALSE, "Queue is busy\n"); + + trace("****************************************************\n\n"); + DPRINT1("Finish KeRemoveDeviceQueue test\n"); + +//==================================================================== + trace("******* Testing KeRemoveEntryDeviceQueue *********** \n"); + DPRINT1("\nStart KeRemoveEntryDeviceQueue test\n"); + + DPRINT1("Filling queue\n"); + for (i = 0; i < INSERT_COUNT; i++) { + elem_array[i]->SortKey = i; + elem_array[i]->Inserted = FALSE; + KeInsertDeviceQueue(testing_queue, elem_array[i]); + } + + //Delete half elements + DPRINT1("Deleting elements\n"); + for (i = 0; i < INSERT_COUNT / 2; i++) { + ok(KeRemoveEntryDeviceQueue(testing_queue, elem_array[i * 2 + 1]), "Element is not deleted\n"); + } + + //Checking queue + DPRINT1("Checking\n"); + next = &testing_queue->DeviceListHead; + for (i = 0; i < INSERT_COUNT / 2 + 1; i++) { + ok(CONTAINING_RECORD(next, KDEVICE_QUEUE_ENTRY, DeviceListEntry)->SortKey == i * 2, "Queue was damaged\n"); + next = next->Flink; + } + + //Trying delete elements, which are not in this queue + DPRINT1("Trying delete nonexistent elements\n"); + for (i = 0; i < INSERT_COUNT / 2; i++) { + ok(!KeRemoveEntryDeviceQueue(testing_queue, elem_array[i * 2 + 1]), "Wrong remove operation\n"); + } + + trace("****************************************************\n\n"); +//Îñâîáîæäåíåè ïàìÿòè +//==================================================================== + for (i = 0; i < INSERT_COUNT; i++) { + ExFreePool(elem_array[i]); + } + + /* Return back to previous IRQL */ + KeLowerIrql(OldIrql); + + ExFreePool(testing_queue); + ExFreePool(element); +} + +START_TEST(KeDeviceQueue) +{ + Test_Initialize(); + Tests_Insert_And_Delete(); +} + -- 2.17.1