[KMTEST]
[reactos.git] / rostests / kmtests / ntos_ke / KeDevQueue.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite for Device Queues
5 * PROGRAMMERS: Pavel Batusov, Moscow State Technical University
6 * Denis Volhonsky, Moscow State Technical University
7 * Alexandra Safonova, Moscow State Technical University
8 */
9
10 #include <kmt_test.h>
11
12 #define NDEBUG
13 #include <debug.h>
14
15 #define NUMBER 255
16 #define INSERT_COUNT 5
17
18 int Check_mem(void* a, int n, int size)
19 {
20 int i;
21 for (i = 0; i < size; i++) {
22 if (*((unsigned char*)a + i) != n) {
23 return 0;
24 }
25 }
26 return 1;
27 }
28
29 void Test_Initialize()
30 {
31 PKDEVICE_QUEUE testing_queue;
32 void* double_queue;
33
34 trace("******* Testing KeInitializeDeviceQueue ************\n");
35 DPRINT1("\nStart test for KeInitializeDeviceQueue function\n");
36
37 testing_queue = ExAllocatePool(NonPagedPool, sizeof(KDEVICE_QUEUE));
38
39 testing_queue->Busy = TRUE;
40 testing_queue->Size = 0;
41
42 KeInitializeDeviceQueue(testing_queue);
43
44 /* Check for properly setting up fields */
45 ok(!testing_queue->Busy, "(Initialize testing) Test 1:\tExpected 'not busy' status\n");
46 DPRINT1("1 test complete\n");
47
48 ok(testing_queue->Size == sizeof(KDEVICE_QUEUE), "(Initialize testing) Test 2:\tExpected another size for KDEVICE_QUEUE\n");
49 DPRINT1("2 test complete\n");
50
51 ok(testing_queue->Type == DeviceQueueObject, "(Initialize testing) Test 3:\tExpected type == DeviceQueueObject\n");
52 DPRINT1("3 test complete\n");
53
54 /* Make sure it does not write outside allocated buffer */
55 double_queue = ExAllocatePool(NonPagedPool, sizeof(KDEVICE_QUEUE) * 2);
56
57 memset(double_queue, NUMBER, sizeof(KDEVICE_QUEUE) * 2);
58 KeInitializeDeviceQueue(double_queue);
59
60 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");
61 DPRINT1("4 test complete\n");
62
63 //====================================================================
64
65 ExFreePool(testing_queue);
66 ExFreePool(double_queue);
67
68 DPRINT1("KeInitializeDeviceQueue test finished\n");
69 }
70
71 void Tests_Insert_And_Delete()
72 {
73 ULONG i, j;
74 PKDEVICE_QUEUE testing_queue;
75 PKDEVICE_QUEUE_ENTRY element;
76 KIRQL OldIrql;
77 PKDEVICE_QUEUE_ENTRY* elem_array;
78 PLIST_ENTRY next;
79 ULONG key;
80
81 trace("******* Testing KeInsertDeviceQueue **************** \n");
82 DPRINT1("\nStart KeInsertDeviceQueue test\n");
83
84 testing_queue = ExAllocatePool(NonPagedPool, sizeof(KDEVICE_QUEUE));
85 KeInitializeDeviceQueue(testing_queue);
86
87 element = ExAllocatePool(NonPagedPool, sizeof(KDEVICE_QUEUE_ENTRY));
88
89 /* Raise to dispatch level */
90 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
91
92 KeInsertDeviceQueue(testing_queue, element);
93 ok(!element->Inserted, "Wrong 'Inserted' status\n");
94 DPRINT1("1 test complete\n");
95
96 /* Fill the queue*/
97 elem_array = ExAllocatePool(NonPagedPool, sizeof(PKDEVICE_QUEUE_ENTRY) * INSERT_COUNT);
98
99 DPRINT1("Arrow of tests starting\n");
100 for (i = 0; i < INSERT_COUNT; i++) {
101 elem_array[i] = ExAllocatePool(NonPagedPool, sizeof(KDEVICE_QUEUE_ENTRY));
102 elem_array[i]->Inserted = FALSE;
103 elem_array[i]->SortKey = i;
104 KeInsertDeviceQueue(testing_queue, elem_array[i]);
105 ok(elem_array[i]->Inserted, "Element was not inserted\n");
106 }
107 DPRINT1("Arrow of tests complete\n");
108
109 ok(testing_queue->Size == sizeof(KDEVICE_QUEUE), "Wrong size of queue\n");
110
111 /* Check how the queue was filled */
112 next = &testing_queue->DeviceListHead;
113
114 DPRINT1("Arrow of tests starting\n");
115 for (i = 0; i < INSERT_COUNT; i++) {
116 next = next->Flink;
117 key = CONTAINING_RECORD(next, KDEVICE_QUEUE_ENTRY, DeviceListEntry)->SortKey;
118 ok(key == i, "Sort key was changed\n");
119 }
120 DPRINT1("Arrow of tests complete\n");
121
122 trace("****************************************************\n\n");
123 DPRINT1("KeInsertDeviceQueue test finish\n");
124
125 /* Test deletion */
126 trace("******* Testing KeRemoveDeviceQueue **************** \n");
127 DPRINT1("\nStart KeRemoveDeviceQueue test\n");
128
129 PKDEVICE_QUEUE_ENTRY return_value;
130
131 DPRINT1("Start deleting elements from queue\n");
132 for (i = 0; i < INSERT_COUNT; i++) {
133 return_value = KeRemoveDeviceQueue(testing_queue);
134 ok(return_value == elem_array[i], "Returning element != head element\n");
135 ok(return_value->Inserted == FALSE, "Returning element is still in queue\n");
136 next = &testing_queue->DeviceListHead;
137 for (j = i + 1; j < INSERT_COUNT; j++) {
138 next = next->Flink;
139 ok(CONTAINING_RECORD(next, KDEVICE_QUEUE_ENTRY, DeviceListEntry)->SortKey == j, "Queue was damaged\n");
140 }
141 }
142 DPRINT1("Deleting finish. Queue must be empty\n");
143
144 ok(KeRemoveDeviceQueue(testing_queue) == NULL, "Queue is not empty\n");
145 ok(testing_queue->Busy == FALSE, "Queue is busy\n");
146
147 trace("****************************************************\n\n");
148 DPRINT1("Finish KeRemoveDeviceQueue test\n");
149
150 //====================================================================
151 trace("******* Testing KeRemoveEntryDeviceQueue *********** \n");
152 DPRINT1("\nStart KeRemoveEntryDeviceQueue test\n");
153
154 DPRINT1("Filling queue\n");
155 for (i = 0; i < INSERT_COUNT; i++) {
156 elem_array[i]->SortKey = i;
157 elem_array[i]->Inserted = FALSE;
158 KeInsertDeviceQueue(testing_queue, elem_array[i]);
159 }
160
161 //Delete half elements
162 DPRINT1("Deleting elements\n");
163 for (i = 0; i < INSERT_COUNT / 2; i++) {
164 ok(KeRemoveEntryDeviceQueue(testing_queue, elem_array[i * 2 + 1]), "Element is not deleted\n");
165 }
166
167 //Checking queue
168 DPRINT1("Checking\n");
169 next = &testing_queue->DeviceListHead;
170 for (i = 0; i < INSERT_COUNT / 2 + 1; i++) {
171 ok(CONTAINING_RECORD(next, KDEVICE_QUEUE_ENTRY, DeviceListEntry)->SortKey == i * 2, "Queue was damaged\n");
172 next = next->Flink;
173 }
174
175 //Trying delete elements, which are not in this queue
176 DPRINT1("Trying delete nonexistent elements\n");
177 for (i = 0; i < INSERT_COUNT / 2; i++) {
178 ok(!KeRemoveEntryDeviceQueue(testing_queue, elem_array[i * 2 + 1]), "Wrong remove operation\n");
179 }
180
181 trace("****************************************************\n\n");
182 //Îñâîáîæäåíåè ïàìÿòè
183 //====================================================================
184 for (i = 0; i < INSERT_COUNT; i++) {
185 ExFreePool(elem_array[i]);
186 }
187
188 /* Return back to previous IRQL */
189 KeLowerIrql(OldIrql);
190
191 ExFreePool(testing_queue);
192 ExFreePool(element);
193 }
194
195 START_TEST(KeDeviceQueue)
196 {
197 Test_Initialize();
198 Tests_Insert_And_Delete();
199 }
200