66b9fe8e47311752fa2254f5981a65b33b8b288e
[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 PKDEVICE_QUEUE_ENTRY return_value;
79 PLIST_ENTRY next;
80 ULONG key;
81
82 trace("******* Testing KeInsertDeviceQueue **************** \n");
83 DPRINT1("\nStart KeInsertDeviceQueue test\n");
84
85 testing_queue = ExAllocatePool(NonPagedPool, sizeof(KDEVICE_QUEUE));
86 KeInitializeDeviceQueue(testing_queue);
87
88 element = ExAllocatePool(NonPagedPool, sizeof(KDEVICE_QUEUE_ENTRY));
89
90 /* Raise to dispatch level */
91 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
92
93 KeInsertDeviceQueue(testing_queue, element);
94 ok(!element->Inserted, "Wrong 'Inserted' status\n");
95 DPRINT1("1 test complete\n");
96
97 /* Fill the queue*/
98 elem_array = ExAllocatePool(NonPagedPool, sizeof(PKDEVICE_QUEUE_ENTRY) * INSERT_COUNT);
99
100 DPRINT1("Arrow of tests starting\n");
101 for (i = 0; i < INSERT_COUNT; i++) {
102 elem_array[i] = ExAllocatePool(NonPagedPool, sizeof(KDEVICE_QUEUE_ENTRY));
103 elem_array[i]->Inserted = FALSE;
104 elem_array[i]->SortKey = i;
105 KeInsertDeviceQueue(testing_queue, elem_array[i]);
106 ok(elem_array[i]->Inserted, "Element was not inserted\n");
107 }
108 DPRINT1("Arrow of tests complete\n");
109
110 ok(testing_queue->Size == sizeof(KDEVICE_QUEUE), "Wrong size of queue\n");
111
112 /* Check how the queue was filled */
113 next = &testing_queue->DeviceListHead;
114
115 DPRINT1("Arrow of tests starting\n");
116 for (i = 0; i < INSERT_COUNT; i++) {
117 next = next->Flink;
118 key = CONTAINING_RECORD(next, KDEVICE_QUEUE_ENTRY, DeviceListEntry)->SortKey;
119 ok(key == i, "Sort key was changed\n");
120 }
121 DPRINT1("Arrow of tests complete\n");
122
123 trace("****************************************************\n\n");
124 DPRINT1("KeInsertDeviceQueue test finish\n");
125
126 /* Test deletion */
127 trace("******* Testing KeRemoveDeviceQueue **************** \n");
128 DPRINT1("\nStart KeRemoveDeviceQueue test\n");
129
130 DPRINT1("Start deleting elements from queue\n");
131 for (i = 0; i < INSERT_COUNT; i++) {
132 return_value = KeRemoveDeviceQueue(testing_queue);
133 ok(return_value == elem_array[i], "Returning element != head element\n");
134 ok(return_value->Inserted == FALSE, "Returning element is still in queue\n");
135 next = &testing_queue->DeviceListHead;
136 for (j = i + 1; j < INSERT_COUNT; j++) {
137 next = next->Flink;
138 ok(CONTAINING_RECORD(next, KDEVICE_QUEUE_ENTRY, DeviceListEntry)->SortKey == j, "Queue was damaged\n");
139 }
140 }
141 DPRINT1("Deleting finish. Queue must be empty\n");
142
143 ok(KeRemoveDeviceQueue(testing_queue) == NULL, "Queue is not empty\n");
144 ok(testing_queue->Busy == FALSE, "Queue is busy\n");
145
146 trace("****************************************************\n\n");
147 DPRINT1("Finish KeRemoveDeviceQueue test\n");
148
149 //====================================================================
150 trace("******* Testing KeRemoveEntryDeviceQueue *********** \n");
151 DPRINT1("\nStart KeRemoveEntryDeviceQueue test\n");
152
153 DPRINT1("Filling queue\n");
154 for (i = 0; i < INSERT_COUNT; i++) {
155 elem_array[i]->SortKey = i;
156 elem_array[i]->Inserted = FALSE;
157 KeInsertDeviceQueue(testing_queue, elem_array[i]);
158 }
159
160 //Delete half elements
161 DPRINT1("Deleting elements\n");
162 for (i = 0; i < INSERT_COUNT / 2; i++) {
163 ok(KeRemoveEntryDeviceQueue(testing_queue, elem_array[i * 2 + 1]), "Element is not deleted\n");
164 }
165
166 //Checking queue
167 DPRINT1("Checking\n");
168 next = &testing_queue->DeviceListHead;
169 for (i = 0; i < INSERT_COUNT / 2 + 1; i++) {
170 ok(CONTAINING_RECORD(next, KDEVICE_QUEUE_ENTRY, DeviceListEntry)->SortKey == i * 2, "Queue was damaged\n");
171 next = next->Flink;
172 }
173
174 //Trying delete elements, which are not in this queue
175 DPRINT1("Trying delete nonexistent elements\n");
176 for (i = 0; i < INSERT_COUNT / 2; i++) {
177 ok(!KeRemoveEntryDeviceQueue(testing_queue, elem_array[i * 2 + 1]), "Wrong remove operation\n");
178 }
179
180 trace("****************************************************\n\n");
181 //Îñâîáîæäåíåè ïàìÿòè
182 //====================================================================
183 for (i = 0; i < INSERT_COUNT; i++) {
184 ExFreePool(elem_array[i]);
185 }
186
187 /* Return back to previous IRQL */
188 KeLowerIrql(OldIrql);
189
190 ExFreePool(testing_queue);
191 ExFreePool(element);
192 }
193
194 START_TEST(KeDeviceQueue)
195 {
196 Test_Initialize();
197 Tests_Insert_And_Delete();
198 }
199