[USP10_WINETEST] Sync with Wine Staging 2.9. CORE-13362
[reactos.git] / rostests / 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 <thomas.faber@reactos.org>
6 */
7
8 struct _SINGLE_LIST_ENTRY;
9 #ifdef _X86_
10 struct _SINGLE_LIST_ENTRY *__stdcall ExInterlockedPushEntryList(struct _SINGLE_LIST_ENTRY *, struct _SINGLE_LIST_ENTRY *, unsigned long *);
11 struct _SINGLE_LIST_ENTRY *__stdcall ExInterlockedPopEntryList(struct _SINGLE_LIST_ENTRY *, unsigned long *);
12 #endif
13
14 #include <kmt_test.h>
15
16 #define ok_eq_free2(Value, Expected) do \
17 { \
18 if (KmtIsCheckedBuild) \
19 ok_eq_pointer(Value, (PVOID)0xBADDD0FF); \
20 else \
21 ok_eq_pointer(Value, Expected); \
22 } while (0)
23
24 PSINGLE_LIST_ENTRY FlushList(PSINGLE_LIST_ENTRY ListHead)
25 {
26 PSINGLE_LIST_ENTRY Ret = ListHead->Next;
27 ListHead->Next = NULL;
28 return Ret;
29 }
30
31 USHORT QueryDepthList(PSINGLE_LIST_ENTRY ListHead)
32 {
33 USHORT Depth = 0;
34 while (ListHead->Next)
35 {
36 ++Depth;
37 ListHead = ListHead->Next;
38 }
39 return Depth;
40 }
41
42 PSINGLE_LIST_ENTRY PushEntryListWrapper(PSINGLE_LIST_ENTRY ListHead, PSINGLE_LIST_ENTRY Entry, PKSPIN_LOCK Lock)
43 {
44 PSINGLE_LIST_ENTRY Ret;
45 UNREFERENCED_PARAMETER(Lock);
46 Ret = ListHead->Next;
47 PushEntryList(ListHead, Entry);
48 return Ret;
49 }
50
51 #define CheckListHeader(ListHead, ExpectedPointer, ExpectedDepth) do \
52 { \
53 ok_eq_pointer((ListHead)->Next, ExpectedPointer); \
54 ok_eq_uint(QueryDepthList(ListHead), ExpectedDepth); \
55 ok_irql(HIGH_LEVEL); \
56 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); \
57 } while (0)
58
59 #define PXLIST_HEADER PSINGLE_LIST_ENTRY
60 #define PXLIST_ENTRY PSINGLE_LIST_ENTRY
61 #define PushXList ExInterlockedPushEntryList
62 #define PopXList ExInterlockedPopEntryList
63 #define FlushXList FlushList
64 #define ok_free_xlist ok_eq_free2
65 #define CheckXListHeader CheckListHeader
66 #define TestXListFunctional TestListFunctional
67 #include "ExXList.h"
68
69 #undef ExInterlockedPushEntryList
70 #undef ExInterlockedPopEntryList
71 #define TestXListFunctional TestListFunctionalExports
72 #include "ExXList.h"
73
74 #undef PushXList
75 #define PushXList PushEntryListWrapper
76 #undef PopXList
77 #define PopXList(h, s) PopEntryList(h)
78 #undef ok_free_xlist
79 #define ok_free_xlist ok_eq_pointer
80 #define TestXListFunctional TestListFunctionalNoInterlocked
81 #include "ExXList.h"
82
83 START_TEST(ExSingleList)
84 {
85 KSPIN_LOCK SpinLock;
86 PSINGLE_LIST_ENTRY ListHead;
87 PSINGLE_LIST_ENTRY Entries;
88 SIZE_T EntriesSize = 5 * sizeof *Entries;
89 PCHAR Buffer;
90 KIRQL Irql;
91
92 KeInitializeSpinLock(&SpinLock);
93
94 /* make sure stuff is as un-aligned as possible ;) */
95 Buffer = ExAllocatePoolWithTag(NonPagedPool, sizeof *ListHead + EntriesSize + 1, 'TLiS');
96 ListHead = (PVOID)&Buffer[1];
97 Entries = (PVOID)&ListHead[1];
98 KeRaiseIrql(HIGH_LEVEL, &Irql);
99
100 RtlFillMemory(Entries, sizeof(*Entries), 0x55);
101 ListHead->Next = NULL;
102 TestListFunctional(ListHead, Entries, &SpinLock);
103
104 RtlFillMemory(Entries, sizeof(*Entries), 0x55);
105 ListHead->Next = NULL;
106 TestListFunctionalExports(ListHead, Entries, &SpinLock);
107
108 RtlFillMemory(Entries, sizeof(*Entries), 0x55);
109 ListHead->Next = NULL;
110 TestListFunctionalNoInterlocked(ListHead, Entries, &SpinLock);
111
112 KeLowerIrql(Irql);
113 ExFreePoolWithTag(Buffer, 'TLiS');
114 }