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
16 #define INSERT_COUNT 5
18 int Check_mem(void* a
, int n
, int size
)
21 for (i
= 0; i
< size
; i
++) {
22 if (*((unsigned char*)a
+ i
) != n
) {
29 void Test_Initialize()
31 PKDEVICE_QUEUE testing_queue
;
34 trace("******* Testing KeInitializeDeviceQueue ************\n");
35 DPRINT1("\nStart test for KeInitializeDeviceQueue function\n");
37 testing_queue
= ExAllocatePool(NonPagedPool
, sizeof(KDEVICE_QUEUE
));
39 testing_queue
->Busy
= TRUE
;
40 testing_queue
->Size
= 0;
42 KeInitializeDeviceQueue(testing_queue
);
44 /* Check for properly setting up fields */
45 ok(!testing_queue
->Busy
, "(Initialize testing) Test 1:\tExpected 'not busy' status\n");
46 DPRINT1("Test 1 completed\n");
48 ok(testing_queue
->Size
== sizeof(KDEVICE_QUEUE
), "(Initialize testing) Test 2:\tExpected another size for KDEVICE_QUEUE\n");
49 DPRINT1("Test 2 completed\n");
51 ok(testing_queue
->Type
== DeviceQueueObject
, "(Initialize testing) Test 3:\tExpected type == DeviceQueueObject\n");
52 DPRINT1("Test 3 completed\n");
54 /* Make sure it does not write outside allocated buffer */
55 double_queue
= ExAllocatePool(NonPagedPool
, sizeof(KDEVICE_QUEUE
) * 2);
57 memset(double_queue
, NUMBER
, sizeof(KDEVICE_QUEUE
) * 2);
58 KeInitializeDeviceQueue(double_queue
);
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("Test 4 completed\n");
63 //====================================================================
65 ExFreePool(testing_queue
);
66 ExFreePool(double_queue
);
68 DPRINT1("KeInitializeDeviceQueue test finished\n");
71 void Tests_Insert_And_Delete()
74 PKDEVICE_QUEUE testing_queue
;
75 PKDEVICE_QUEUE_ENTRY element
;
77 PKDEVICE_QUEUE_ENTRY
* elem_array
;
78 PKDEVICE_QUEUE_ENTRY return_value
;
82 trace("******* Testing KeInsertDeviceQueue **************** \n");
83 DPRINT1("\nStart KeInsertDeviceQueue test\n");
85 testing_queue
= ExAllocatePool(NonPagedPool
, sizeof(KDEVICE_QUEUE
));
86 KeInitializeDeviceQueue(testing_queue
);
88 element
= ExAllocatePool(NonPagedPool
, sizeof(KDEVICE_QUEUE_ENTRY
));
90 /* Raise to dispatch level */
91 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
93 KeInsertDeviceQueue(testing_queue
, element
);
94 ok(!element
->Inserted
, "Wrong 'Inserted' status\n");
95 DPRINT1("Test 1 completed\n");
98 elem_array
= ExAllocatePool(NonPagedPool
, sizeof(PKDEVICE_QUEUE_ENTRY
) * INSERT_COUNT
);
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");
108 DPRINT1("Arrow of tests complete\n");
110 ok(testing_queue
->Size
== sizeof(KDEVICE_QUEUE
), "Wrong size of queue\n");
112 /* Check how the queue was filled */
113 next
= &testing_queue
->DeviceListHead
;
115 DPRINT1("Bunch of tests starting\n");
116 for (i
= 0; i
< INSERT_COUNT
; i
++) {
118 key
= CONTAINING_RECORD(next
, KDEVICE_QUEUE_ENTRY
, DeviceListEntry
)->SortKey
;
119 ok(key
== i
, "Sort key was changed\n");
121 DPRINT1("Bunch of tests completed\n");
123 trace("****************************************************\n\n");
124 DPRINT1("KeInsertDeviceQueue test finish\n");
127 trace("******* Testing KeRemoveDeviceQueue **************** \n");
128 DPRINT1("\nStart KeRemoveDeviceQueue test\n");
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
++) {
138 ok(CONTAINING_RECORD(next
, KDEVICE_QUEUE_ENTRY
, DeviceListEntry
)->SortKey
== j
, "Queue was damaged\n");
141 DPRINT1("Deleting finish. Queue must be empty\n");
143 ok(KeRemoveDeviceQueue(testing_queue
) == NULL
, "Queue is not empty\n");
144 ok(testing_queue
->Busy
== FALSE
, "Queue is busy\n");
146 trace("****************************************************\n\n");
147 DPRINT1("Finish KeRemoveDeviceQueue test\n");
149 trace("******* Testing KeRemoveEntryDeviceQueue *********** \n");
150 DPRINT1("\nStart KeRemoveEntryDeviceQueue test\n");
152 DPRINT1("Filling queue\n");
153 for (i
= 0; i
< INSERT_COUNT
; i
++) {
154 elem_array
[i
]->SortKey
= i
;
155 elem_array
[i
]->Inserted
= FALSE
;
156 KeInsertDeviceQueue(testing_queue
, elem_array
[i
]);
159 /* Delete half of all elements in the queue */
160 DPRINT1("Deleting elements\n");
161 for (i
= 0; i
< INSERT_COUNT
/ 2; i
++) {
162 ok(KeRemoveEntryDeviceQueue(testing_queue
, elem_array
[i
* 2 + 1]), "Element is not deleted\n");
166 DPRINT1("Checking\n");
167 next
= &testing_queue
->DeviceListHead
;
168 for (i
= 0; i
< INSERT_COUNT
/ 2 + 1; i
++) {
169 ok(CONTAINING_RECORD(next
, KDEVICE_QUEUE_ENTRY
, DeviceListEntry
)->SortKey
== i
* 2, "Queue was damaged\n");
173 /* Trying delete elements, which are not in this queue */
174 DPRINT1("Trying delete nonexistent elements\n");
175 for (i
= 0; i
< INSERT_COUNT
/ 2; i
++) {
176 ok(!KeRemoveEntryDeviceQueue(testing_queue
, elem_array
[i
* 2 + 1]), "Wrong remove operation\n");
179 trace("****************************************************\n\n");
181 for (i
= 0; i
< INSERT_COUNT
; i
++) {
182 ExFreePool(elem_array
[i
]);
185 /* Return back to previous IRQL */
186 KeLowerIrql(OldIrql
);
188 ExFreePool(testing_queue
);
192 START_TEST(KeDeviceQueue
)
195 Tests_Insert_And_Delete();