[KMTESTS]
[reactos.git] / kmtests / ntos_ex / ExSingleList.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Singly-linked list test
5 * PROGRAMMER: Thomas Faber <thfabba@gmx.de>
6 */
7
8 struct _SINGLE_LIST_ENTRY;
9 struct _SINGLE_LIST_ENTRY *__stdcall ExInterlockedPushEntryList(struct _SINGLE_LIST_ENTRY *, struct _SINGLE_LIST_ENTRY *, unsigned long *);
10 struct _SINGLE_LIST_ENTRY *__stdcall ExInterlockedPopEntryList(struct _SINGLE_LIST_ENTRY *, unsigned long *);
11
12 #include <kmt_test.h>
13
14 #define ok_eq_free2(Value, Expected) do \
15 { \
16 if (KmtIsCheckedBuild) \
17 ok_eq_pointer(Value, (PVOID)0xBADDD0FF); \
18 else \
19 ok_eq_pointer(Value, Expected); \
20 } while (0)
21
22 PSINGLE_LIST_ENTRY FlushList(PSINGLE_LIST_ENTRY ListHead)
23 {
24 PSINGLE_LIST_ENTRY Ret = ListHead->Next;
25 ListHead->Next = NULL;
26 return Ret;
27 }
28
29 USHORT QueryDepthList(PSINGLE_LIST_ENTRY ListHead)
30 {
31 USHORT Depth = 0;
32 while (ListHead->Next)
33 {
34 ++Depth;
35 ListHead = ListHead->Next;
36 }
37 return Depth;
38 }
39
40 PSINGLE_LIST_ENTRY PushEntryListWrapper(PSINGLE_LIST_ENTRY ListHead, PSINGLE_LIST_ENTRY Entry, PKSPIN_LOCK Lock)
41 {
42 PSINGLE_LIST_ENTRY Ret;
43 UNREFERENCED_PARAMETER(Lock);
44 Ret = ListHead->Next;
45 PushEntryList(ListHead, Entry);
46 return Ret;
47 }
48
49 #define CheckListHeader(ListHead, ExpectedPointer, ExpectedDepth) do \
50 { \
51 ok_eq_pointer((ListHead)->Next, ExpectedPointer); \
52 ok_eq_uint(QueryDepthList(ListHead), ExpectedDepth); \
53 ok_irql(HIGH_LEVEL); \
54 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); \
55 } while (0)
56
57 #define PXLIST_HEADER PSINGLE_LIST_ENTRY
58 #define PXLIST_ENTRY PSINGLE_LIST_ENTRY
59 #define PushXList ExInterlockedPushEntryList
60 #define PopXList ExInterlockedPopEntryList
61 #define FlushXList FlushList
62 #define ok_free_xlist ok_eq_free2
63 #define CheckXListHeader CheckListHeader
64 #define TestXListFunctional TestListFunctional
65 #include "ExXList.h"
66
67 #undef ExInterlockedPushEntryList
68 #undef ExInterlockedPopEntryList
69 #define TestXListFunctional TestListFunctionalExports
70 #include "ExXList.h"
71
72 #undef PushXList
73 #define PushXList PushEntryListWrapper
74 #undef PopXList
75 #define PopXList(h, s) PopEntryList(h)
76 #undef ok_free_xlist
77 #define ok_free_xlist ok_eq_pointer
78 #define TestXListFunctional TestListFunctionalNoInterlocked
79 #include "ExXList.h"
80
81 START_TEST(ExSingleList)
82 {
83 KSPIN_LOCK SpinLock;
84 PSINGLE_LIST_ENTRY ListHead;
85 PSINGLE_LIST_ENTRY Entries;
86 SIZE_T EntriesSize = 5 * sizeof *Entries;
87 PCHAR Buffer;
88 KIRQL Irql;
89
90 KeInitializeSpinLock(&SpinLock);
91
92 /* make sure stuff is as un-aligned as possible ;) */
93 Buffer = ExAllocatePoolWithTag(NonPagedPool, sizeof *ListHead + EntriesSize + 1, 'TLiS');
94 ListHead = (PVOID)&Buffer[1];
95 Entries = (PVOID)&ListHead[1];
96 KeRaiseIrql(HIGH_LEVEL, &Irql);
97
98 RtlFillMemory(Entries, sizeof Entries, 0x55);
99 ListHead->Next = NULL;
100 TestListFunctional(ListHead, Entries, &SpinLock);
101
102 RtlFillMemory(Entries, sizeof Entries, 0x55);
103 ListHead->Next = NULL;
104 TestListFunctionalExports(ListHead, Entries, &SpinLock);
105
106 RtlFillMemory(Entries, sizeof Entries, 0x55);
107 ListHead->Next = NULL;
108 TestListFunctionalNoInterlocked(ListHead, Entries, &SpinLock);
109
110 KeLowerIrql(Irql);
111 ExFreePoolWithTag(Buffer, 'TLiS');
112 }