1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
 * PROJECT:         ReactOS kernel-mode tests
 * LICENSE:         GPLv2+ - See COPYING in the top level directory
 * PURPOSE:         Kernel-Mode Test Suite sequenced singly-linked list test
 * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
 */

struct _SINGLE_LIST_ENTRY;
union _SLIST_HEADER;
struct _SINGLE_LIST_ENTRY *__fastcall ExInterlockedPushEntrySList(union _SLIST_HEADER *, struct _SINGLE_LIST_ENTRY *, unsigned long *);
struct _SINGLE_LIST_ENTRY *__fastcall ExInterlockedPopEntrySList(union _SLIST_HEADER *, unsigned long *);

#include <kmt_test.h>

/* TODO: SLIST_HEADER is a lot different for x64 */
#ifndef _M_AMD64
#define CheckSListHeader(ListHead, ExpectedPointer, ExpectedDepth) do   \
{                                                                       \
    ok_eq_pointer((ListHead)->Next.Next, ExpectedPointer);              \
    /*ok_eq_pointer(FirstEntrySList(ListHead), ExpectedPointer);*/      \
    ok_eq_uint((ListHead)->Depth, ExpectedDepth);                       \
    ok_eq_uint((ListHead)->Sequence, ExpectedSequence);                 \
    ok_eq_uint(ExQueryDepthSList(ListHead), ExpectedDepth);             \
    ok_irql(HIGH_LEVEL);                                                \
    ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");     \
} while (0)

#define PXLIST_HEADER       PSLIST_HEADER
#define PXLIST_ENTRY        PSLIST_ENTRY
#define PushXList           ExInterlockedPushEntrySList
#define PopXList            ExInterlockedPopEntrySList
#define FlushXList          ExInterlockedFlushSList
#define ok_free_xlist       ok_eq_pointer
#define CheckXListHeader    CheckSListHeader
#define TestXListFunctional TestSListFunctional
#include "ExXList.h"

#undef ExInterlockedPushEntrySList
#undef ExInterlockedPopEntrySList
#define TestXListFunctional TestSListFunctionalExports
#include "ExXList.h"
#endif

START_TEST(ExSequencedList)
{
#ifndef _M_AMD64
    PSLIST_HEADER ListHead;
    KSPIN_LOCK SpinLock;
    USHORT ExpectedSequence = 0;
    PKSPIN_LOCK pSpinLock = &SpinLock;<--- pSpinLock is initialized
    PCHAR Buffer;
    PSLIST_ENTRY Entries;
    SIZE_T EntriesSize = 5 * sizeof *Entries;
    KIRQL Irql;

    KeInitializeSpinLock(&SpinLock);
#ifdef _M_IX86
    pSpinLock = NULL;<--- pSpinLock is overwritten
#endif

    /* make sure stuff is as un-aligned as possible ;) */
    Buffer = ExAllocatePoolWithTag(NonPagedPool, sizeof *ListHead + EntriesSize + 1, 'TLqS');
    ListHead = (PVOID)&Buffer[1];
    Entries = (PVOID)&ListHead[1];
    KeRaiseIrql(HIGH_LEVEL, &Irql);

    RtlFillMemory(Entries, EntriesSize, 0x55);
    RtlFillMemory(ListHead, sizeof *ListHead, 0x55);
    InitializeSListHead(ListHead);
    CheckSListHeader(ListHead, NULL, 0);
    TestSListFunctional(ListHead, Entries, pSpinLock);

    RtlFillMemory(Entries, EntriesSize, 0x55);
    RtlFillMemory(ListHead, sizeof *ListHead, 0x55);
    ExInitializeSListHead(ListHead);
    CheckSListHeader(ListHead, NULL, 0);
    TestSListFunctionalExports(ListHead, Entries, pSpinLock);
    
    KeLowerIrql(Irql);
    ExFreePoolWithTag(Buffer, 'TLqS');
#endif
}