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)(ULONG_PTR)0xBADDD0FFBADDD0FFULL); \ 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 } 115