1 /*
2  * PROJECT:         ReactOS kernel-mode tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         Kernel-Mode Test Suite sequenced singly-linked list test
5  * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 struct _SINGLE_LIST_ENTRY;
9 union _SLIST_HEADER;
10 struct _SINGLE_LIST_ENTRY *__fastcall ExInterlockedPushEntrySList(union _SLIST_HEADER *, struct _SINGLE_LIST_ENTRY *, unsigned long *);
11 struct _SINGLE_LIST_ENTRY *__fastcall ExInterlockedPopEntrySList(union _SLIST_HEADER *, unsigned long *);
12 
13 #include <kmt_test.h>
14 
15 /* TODO: SLIST_HEADER is a lot different for x64 */
16 #ifndef _M_AMD64
17 #define CheckSListHeader(ListHead, ExpectedPointer, ExpectedDepth) do   \
18 {                                                                       \
19     ok_eq_pointer((ListHead)->Next.Next, ExpectedPointer);              \
20     /*ok_eq_pointer(FirstEntrySList(ListHead), ExpectedPointer);*/      \
21     ok_eq_uint((ListHead)->Depth, ExpectedDepth);                       \
22     ok_eq_uint((ListHead)->Sequence, ExpectedSequence);                 \
23     ok_eq_uint(ExQueryDepthSList(ListHead), ExpectedDepth);             \
24     ok_irql(HIGH_LEVEL);                                                \
25     ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");     \
26 } while (0)
27 
28 #define PXLIST_HEADER       PSLIST_HEADER
29 #define PXLIST_ENTRY        PSLIST_ENTRY
30 #define PushXList           ExInterlockedPushEntrySList
31 #define PopXList            ExInterlockedPopEntrySList
32 #define FlushXList          ExInterlockedFlushSList
33 #define ok_free_xlist       ok_eq_pointer
34 #define CheckXListHeader    CheckSListHeader
35 #define TestXListFunctional TestSListFunctional
36 #include "ExXList.h"
37 
38 #undef ExInterlockedPushEntrySList
39 #undef ExInterlockedPopEntrySList
40 #define TestXListFunctional TestSListFunctionalExports
41 #include "ExXList.h"
42 #endif
43 
START_TEST(ExSequencedList)44 START_TEST(ExSequencedList)
45 {
46 #ifndef _M_AMD64
47     PSLIST_HEADER ListHead;
48     KSPIN_LOCK SpinLock;
49     USHORT ExpectedSequence = 0;
50     PKSPIN_LOCK pSpinLock = &SpinLock;
51     PCHAR Buffer;
52     PSLIST_ENTRY Entries;
53     SIZE_T EntriesSize = 5 * sizeof *Entries;
54     KIRQL Irql;
55 
56     KeInitializeSpinLock(&SpinLock);
57 #ifdef _M_IX86
58     pSpinLock = NULL;
59 #endif
60 
61     /* make sure stuff is as un-aligned as possible ;) */
62     Buffer = ExAllocatePoolWithTag(NonPagedPool, sizeof *ListHead + EntriesSize + 1, 'TLqS');
63     ListHead = (PVOID)&Buffer[1];
64     Entries = (PVOID)&ListHead[1];
65     KeRaiseIrql(HIGH_LEVEL, &Irql);
66 
67     RtlFillMemory(Entries, EntriesSize, 0x55);
68     RtlFillMemory(ListHead, sizeof *ListHead, 0x55);
69     InitializeSListHead(ListHead);
70     CheckSListHeader(ListHead, NULL, 0);
71     TestSListFunctional(ListHead, Entries, pSpinLock);
72 
73     RtlFillMemory(Entries, EntriesSize, 0x55);
74     RtlFillMemory(ListHead, sizeof *ListHead, 0x55);
75     ExInitializeSListHead(ListHead);
76     CheckSListHeader(ListHead, NULL, 0);
77     TestSListFunctionalExports(ListHead, Entries, pSpinLock);
78 
79     KeLowerIrql(Irql);
80     ExFreePoolWithTag(Buffer, 'TLqS');
81 #endif
82 }
83