1 /* 2 * PROJECT: ReactOS kernel-mode tests 3 * LICENSE: GPLv2+ - See COPYING in the top level directory 4 * PURPOSE: Kernel-Mode Test Suite Doubly-linked list test 5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org> 6 */ 7 8 struct _LIST_ENTRY; 9 #ifdef _X86_ 10 struct _LIST_ENTRY *__stdcall ExInterlockedInsertHeadList(struct _LIST_ENTRY *, struct _LIST_ENTRY *, unsigned long *); 11 struct _LIST_ENTRY *__stdcall ExInterlockedInsertTailList(struct _LIST_ENTRY *, struct _LIST_ENTRY *, unsigned long *); 12 struct _LIST_ENTRY *__stdcall ExInterlockedRemoveHeadList(struct _LIST_ENTRY *, unsigned long *); 13 #endif 14 15 #include <kmt_test.h> 16 17 LIST_ENTRY Entries[5]; 18 19 #define ok_eq_free(Value, Expected) do \ 20 { \ 21 if (KmtIsCheckedBuild) \ 22 ok_eq_pointer(Value, (PVOID)0x0BADD0FF); \ 23 else \ 24 ok_eq_pointer(Value, Expected); \ 25 } while (0) 26 27 #define ok_eq_free2(Value, Expected) do \ 28 { \ 29 if (KmtIsCheckedBuild) \ 30 ok_eq_pointer(Value, (PVOID)(ULONG_PTR)0xBADDD0FFBADDD0FFULL); \ 31 else \ 32 ok_eq_pointer(Value, Expected); \ 33 } while (0) 34 35 START_TEST(ExDoubleList) 36 { 37 KSPIN_LOCK SpinLock; 38 LIST_ENTRY ListHead; 39 PLIST_ENTRY Ret; 40 41 KeInitializeSpinLock(&SpinLock); 42 43 memset(&ListHead, 0x55, sizeof ListHead); 44 InitializeListHead(&ListHead); 45 ok_eq_pointer(ListHead.Flink, &ListHead); 46 ok_eq_pointer(ListHead.Blink, &ListHead); 47 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 48 ok_irql(PASSIVE_LEVEL); 49 50 Ret = ExInterlockedInsertHeadList(&ListHead, &Entries[0], &SpinLock); 51 ok_eq_pointer(Ret, NULL); 52 ok_eq_pointer(ListHead.Flink, &Entries[0]); 53 ok_eq_pointer(ListHead.Blink, &Entries[0]); 54 ok_eq_pointer(Entries[0].Flink, &ListHead); 55 ok_eq_pointer(Entries[0].Blink, &ListHead); 56 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 57 ok_irql(PASSIVE_LEVEL); 58 59 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock); 60 ok_eq_pointer(Ret, &Entries[0]); 61 ok_eq_pointer(ListHead.Flink, &ListHead); 62 ok_eq_pointer(ListHead.Blink, &ListHead); 63 ok_eq_free(Entries[0].Flink, &ListHead); 64 ok_eq_free(Entries[0].Blink, &ListHead); 65 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 66 ok_irql(PASSIVE_LEVEL); 67 68 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock); 69 ok_eq_pointer(Ret, NULL); 70 ok_eq_pointer(ListHead.Flink, &ListHead); 71 ok_eq_pointer(ListHead.Blink, &ListHead); 72 ok_eq_free(Entries[0].Flink, &ListHead); 73 ok_eq_free(Entries[0].Blink, &ListHead); 74 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 75 ok_irql(PASSIVE_LEVEL); 76 77 Ret = ExInterlockedInsertTailList(&ListHead, &Entries[0], &SpinLock); 78 ok_eq_pointer(Ret, NULL); 79 ok_eq_pointer(ListHead.Flink, &Entries[0]); 80 ok_eq_pointer(ListHead.Blink, &Entries[0]); 81 ok_eq_pointer(Entries[0].Flink, &ListHead); 82 ok_eq_pointer(Entries[0].Blink, &ListHead); 83 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 84 ok_irql(PASSIVE_LEVEL); 85 86 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock); 87 ok_eq_pointer(Ret, &Entries[0]); 88 ok_eq_pointer(ListHead.Flink, &ListHead); 89 ok_eq_pointer(ListHead.Blink, &ListHead); 90 ok_eq_free(Entries[0].Flink, &ListHead); 91 ok_eq_free(Entries[0].Blink, &ListHead); 92 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 93 ok_irql(PASSIVE_LEVEL); 94 95 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock); 96 ok_eq_pointer(Ret, NULL); 97 ok_eq_pointer(ListHead.Flink, &ListHead); 98 ok_eq_pointer(ListHead.Blink, &ListHead); 99 ok_eq_free(Entries[0].Flink, &ListHead); 100 ok_eq_free(Entries[0].Blink, &ListHead); 101 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 102 ok_irql(PASSIVE_LEVEL); 103 104 Ret = ExInterlockedInsertTailList(&ListHead, &Entries[0], &SpinLock); 105 ok_eq_pointer(Ret, NULL); 106 ok_eq_pointer(ListHead.Flink, &Entries[0]); 107 ok_eq_pointer(ListHead.Blink, &Entries[0]); 108 ok_eq_pointer(Entries[0].Flink, &ListHead); 109 ok_eq_pointer(Entries[0].Blink, &ListHead); 110 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 111 ok_irql(PASSIVE_LEVEL); 112 113 Ret = ExInterlockedInsertHeadList(&ListHead, &Entries[1], &SpinLock); 114 ok_eq_pointer(Ret, &Entries[0]); 115 ok_eq_pointer(ListHead.Flink, &Entries[1]); 116 ok_eq_pointer(ListHead.Blink, &Entries[0]); 117 ok_eq_pointer(Entries[0].Flink, &ListHead); 118 ok_eq_pointer(Entries[0].Blink, &Entries[1]); 119 ok_eq_pointer(Entries[1].Flink, &Entries[0]); 120 ok_eq_pointer(Entries[1].Blink, &ListHead); 121 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 122 ok_irql(PASSIVE_LEVEL); 123 124 Ret = ExInterlockedInsertTailList(&ListHead, &Entries[2], &SpinLock); 125 ok_eq_pointer(Ret, &Entries[0]); 126 ok_eq_pointer(ListHead.Flink, &Entries[1]); 127 ok_eq_pointer(ListHead.Blink, &Entries[2]); 128 ok_eq_pointer(Entries[0].Flink, &Entries[2]); 129 ok_eq_pointer(Entries[0].Blink, &Entries[1]); 130 ok_eq_pointer(Entries[1].Flink, &Entries[0]); 131 ok_eq_pointer(Entries[1].Blink, &ListHead); 132 ok_eq_pointer(Entries[2].Flink, &ListHead); 133 ok_eq_pointer(Entries[2].Blink, &Entries[0]); 134 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 135 ok_irql(PASSIVE_LEVEL); 136 137 memset(Entries, 0x55, sizeof Entries); 138 #undef ExInterlockedInsertHeadList 139 #undef ExInterlockedInsertTailList 140 #undef ExInterlockedRemoveHeadList 141 142 memset(&ListHead, 0x55, sizeof ListHead); 143 InitializeListHead(&ListHead); 144 ok_eq_pointer(ListHead.Flink, &ListHead); 145 ok_eq_pointer(ListHead.Blink, &ListHead); 146 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 147 ok_irql(PASSIVE_LEVEL); 148 149 Ret = ExInterlockedInsertHeadList(&ListHead, &Entries[0], &SpinLock); 150 ok_eq_pointer(Ret, NULL); 151 ok_eq_pointer(ListHead.Flink, &Entries[0]); 152 ok_eq_pointer(ListHead.Blink, &Entries[0]); 153 ok_eq_pointer(Entries[0].Flink, &ListHead); 154 ok_eq_pointer(Entries[0].Blink, &ListHead); 155 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 156 ok_irql(PASSIVE_LEVEL); 157 158 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock); 159 ok_eq_pointer(Ret, &Entries[0]); 160 ok_eq_pointer(ListHead.Flink, &ListHead); 161 ok_eq_pointer(ListHead.Blink, &ListHead); 162 ok_eq_free2(Entries[0].Flink, &ListHead); 163 ok_eq_free2(Entries[0].Blink, &ListHead); 164 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 165 ok_irql(PASSIVE_LEVEL); 166 167 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock); 168 ok_eq_pointer(Ret, NULL); 169 ok_eq_pointer(ListHead.Flink, &ListHead); 170 ok_eq_pointer(ListHead.Blink, &ListHead); 171 ok_eq_free2(Entries[0].Flink, &ListHead); 172 ok_eq_free2(Entries[0].Blink, &ListHead); 173 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 174 ok_irql(PASSIVE_LEVEL); 175 176 Ret = ExInterlockedInsertTailList(&ListHead, &Entries[0], &SpinLock); 177 ok_eq_pointer(Ret, NULL); 178 ok_eq_pointer(ListHead.Flink, &Entries[0]); 179 ok_eq_pointer(ListHead.Blink, &Entries[0]); 180 ok_eq_pointer(Entries[0].Flink, &ListHead); 181 ok_eq_pointer(Entries[0].Blink, &ListHead); 182 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 183 ok_irql(PASSIVE_LEVEL); 184 185 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock); 186 ok_eq_pointer(Ret, &Entries[0]); 187 ok_eq_pointer(ListHead.Flink, &ListHead); 188 ok_eq_pointer(ListHead.Blink, &ListHead); 189 ok_eq_free2(Entries[0].Flink, &ListHead); 190 ok_eq_free2(Entries[0].Blink, &ListHead); 191 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 192 ok_irql(PASSIVE_LEVEL); 193 194 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock); 195 ok_eq_pointer(Ret, NULL); 196 ok_eq_pointer(ListHead.Flink, &ListHead); 197 ok_eq_pointer(ListHead.Blink, &ListHead); 198 ok_eq_free2(Entries[0].Flink, &ListHead); 199 ok_eq_free2(Entries[0].Blink, &ListHead); 200 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 201 ok_irql(PASSIVE_LEVEL); 202 203 Ret = ExInterlockedInsertTailList(&ListHead, &Entries[0], &SpinLock); 204 ok_eq_pointer(Ret, NULL); 205 ok_eq_pointer(ListHead.Flink, &Entries[0]); 206 ok_eq_pointer(ListHead.Blink, &Entries[0]); 207 ok_eq_pointer(Entries[0].Flink, &ListHead); 208 ok_eq_pointer(Entries[0].Blink, &ListHead); 209 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 210 ok_irql(PASSIVE_LEVEL); 211 212 Ret = ExInterlockedInsertHeadList(&ListHead, &Entries[1], &SpinLock); 213 ok_eq_pointer(Ret, &Entries[0]); 214 ok_eq_pointer(ListHead.Flink, &Entries[1]); 215 ok_eq_pointer(ListHead.Blink, &Entries[0]); 216 ok_eq_pointer(Entries[0].Flink, &ListHead); 217 ok_eq_pointer(Entries[0].Blink, &Entries[1]); 218 ok_eq_pointer(Entries[1].Flink, &Entries[0]); 219 ok_eq_pointer(Entries[1].Blink, &ListHead); 220 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 221 ok_irql(PASSIVE_LEVEL); 222 223 Ret = ExInterlockedInsertTailList(&ListHead, &Entries[2], &SpinLock); 224 ok_eq_pointer(Ret, &Entries[0]); 225 ok_eq_pointer(ListHead.Flink, &Entries[1]); 226 ok_eq_pointer(ListHead.Blink, &Entries[2]); 227 ok_eq_pointer(Entries[0].Flink, &Entries[2]); 228 ok_eq_pointer(Entries[0].Blink, &Entries[1]); 229 ok_eq_pointer(Entries[1].Flink, &Entries[0]); 230 ok_eq_pointer(Entries[1].Blink, &ListHead); 231 ok_eq_pointer(Entries[2].Flink, &ListHead); 232 ok_eq_pointer(Entries[2].Blink, &Entries[0]); 233 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); 234 ok_irql(PASSIVE_LEVEL); 235 236 KmtSetIrql(PASSIVE_LEVEL); 237 } 238