2011-07-25 20:12:44 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS kernel-mode tests
|
|
|
|
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
|
|
|
* PURPOSE: Kernel-Mode Test Suite Singly-linked list test
|
|
|
|
* PROGRAMMER: Thomas Faber <thfabba@gmx.de>
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct _SINGLE_LIST_ENTRY;
|
2011-09-11 11:22:00 +00:00
|
|
|
#ifdef _X86_
|
2011-07-25 20:12:44 +00:00
|
|
|
struct _SINGLE_LIST_ENTRY *__stdcall ExInterlockedPushEntryList(struct _SINGLE_LIST_ENTRY *, struct _SINGLE_LIST_ENTRY *, unsigned long *);
|
|
|
|
struct _SINGLE_LIST_ENTRY *__stdcall ExInterlockedPopEntryList(struct _SINGLE_LIST_ENTRY *, unsigned long *);
|
2011-09-11 11:22:00 +00:00
|
|
|
#endif
|
2011-07-25 20:12:44 +00:00
|
|
|
|
|
|
|
#include <kmt_test.h>
|
|
|
|
|
|
|
|
#define ok_eq_free2(Value, Expected) do \
|
|
|
|
{ \
|
|
|
|
if (KmtIsCheckedBuild) \
|
|
|
|
ok_eq_pointer(Value, (PVOID)0xBADDD0FF); \
|
|
|
|
else \
|
|
|
|
ok_eq_pointer(Value, Expected); \
|
|
|
|
} while (0)
|
|
|
|
|
2011-08-21 16:08:27 +00:00
|
|
|
PSINGLE_LIST_ENTRY FlushList(PSINGLE_LIST_ENTRY ListHead)
|
2011-07-25 20:12:44 +00:00
|
|
|
{
|
2011-08-21 16:08:27 +00:00
|
|
|
PSINGLE_LIST_ENTRY Ret = ListHead->Next;
|
|
|
|
ListHead->Next = NULL;
|
|
|
|
return Ret;
|
|
|
|
}
|
2011-07-25 20:12:44 +00:00
|
|
|
|
2011-08-21 16:08:27 +00:00
|
|
|
USHORT QueryDepthList(PSINGLE_LIST_ENTRY ListHead)
|
|
|
|
{
|
|
|
|
USHORT Depth = 0;
|
|
|
|
while (ListHead->Next)
|
|
|
|
{
|
|
|
|
++Depth;
|
|
|
|
ListHead = ListHead->Next;
|
|
|
|
}
|
|
|
|
return Depth;
|
|
|
|
}
|
2011-07-25 20:12:44 +00:00
|
|
|
|
2011-08-21 16:08:27 +00:00
|
|
|
PSINGLE_LIST_ENTRY PushEntryListWrapper(PSINGLE_LIST_ENTRY ListHead, PSINGLE_LIST_ENTRY Entry, PKSPIN_LOCK Lock)
|
|
|
|
{
|
|
|
|
PSINGLE_LIST_ENTRY Ret;
|
|
|
|
UNREFERENCED_PARAMETER(Lock);
|
|
|
|
Ret = ListHead->Next;
|
|
|
|
PushEntryList(ListHead, Entry);
|
|
|
|
return Ret;
|
|
|
|
}
|
2011-07-25 20:12:44 +00:00
|
|
|
|
2011-08-21 16:08:27 +00:00
|
|
|
#define CheckListHeader(ListHead, ExpectedPointer, ExpectedDepth) do \
|
|
|
|
{ \
|
|
|
|
ok_eq_pointer((ListHead)->Next, ExpectedPointer); \
|
|
|
|
ok_eq_uint(QueryDepthList(ListHead), ExpectedDepth); \
|
|
|
|
ok_irql(HIGH_LEVEL); \
|
|
|
|
ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); \
|
|
|
|
} while (0)
|
2011-07-25 20:12:44 +00:00
|
|
|
|
2011-08-21 16:08:27 +00:00
|
|
|
#define PXLIST_HEADER PSINGLE_LIST_ENTRY
|
|
|
|
#define PXLIST_ENTRY PSINGLE_LIST_ENTRY
|
|
|
|
#define PushXList ExInterlockedPushEntryList
|
|
|
|
#define PopXList ExInterlockedPopEntryList
|
|
|
|
#define FlushXList FlushList
|
|
|
|
#define ok_free_xlist ok_eq_free2
|
|
|
|
#define CheckXListHeader CheckListHeader
|
|
|
|
#define TestXListFunctional TestListFunctional
|
|
|
|
#include "ExXList.h"
|
2011-07-25 20:12:44 +00:00
|
|
|
|
|
|
|
#undef ExInterlockedPushEntryList
|
|
|
|
#undef ExInterlockedPopEntryList
|
2011-08-21 16:08:27 +00:00
|
|
|
#define TestXListFunctional TestListFunctionalExports
|
|
|
|
#include "ExXList.h"
|
|
|
|
|
|
|
|
#undef PushXList
|
|
|
|
#define PushXList PushEntryListWrapper
|
|
|
|
#undef PopXList
|
|
|
|
#define PopXList(h, s) PopEntryList(h)
|
|
|
|
#undef ok_free_xlist
|
|
|
|
#define ok_free_xlist ok_eq_pointer
|
|
|
|
#define TestXListFunctional TestListFunctionalNoInterlocked
|
|
|
|
#include "ExXList.h"
|
2011-07-25 20:12:44 +00:00
|
|
|
|
2011-08-21 16:08:27 +00:00
|
|
|
START_TEST(ExSingleList)
|
|
|
|
{
|
|
|
|
KSPIN_LOCK SpinLock;
|
|
|
|
PSINGLE_LIST_ENTRY ListHead;
|
|
|
|
PSINGLE_LIST_ENTRY Entries;
|
|
|
|
SIZE_T EntriesSize = 5 * sizeof *Entries;
|
|
|
|
PCHAR Buffer;
|
|
|
|
KIRQL Irql;
|
2011-07-25 20:12:44 +00:00
|
|
|
|
2011-08-21 16:08:27 +00:00
|
|
|
KeInitializeSpinLock(&SpinLock);
|
2011-07-25 20:12:44 +00:00
|
|
|
|
2011-08-21 16:08:27 +00:00
|
|
|
/* make sure stuff is as un-aligned as possible ;) */
|
|
|
|
Buffer = ExAllocatePoolWithTag(NonPagedPool, sizeof *ListHead + EntriesSize + 1, 'TLiS');
|
|
|
|
ListHead = (PVOID)&Buffer[1];
|
|
|
|
Entries = (PVOID)&ListHead[1];
|
|
|
|
KeRaiseIrql(HIGH_LEVEL, &Irql);
|
|
|
|
|
|
|
|
RtlFillMemory(Entries, sizeof Entries, 0x55);
|
|
|
|
ListHead->Next = NULL;
|
|
|
|
TestListFunctional(ListHead, Entries, &SpinLock);
|
|
|
|
|
|
|
|
RtlFillMemory(Entries, sizeof Entries, 0x55);
|
|
|
|
ListHead->Next = NULL;
|
|
|
|
TestListFunctionalExports(ListHead, Entries, &SpinLock);
|
|
|
|
|
|
|
|
RtlFillMemory(Entries, sizeof Entries, 0x55);
|
|
|
|
ListHead->Next = NULL;
|
|
|
|
TestListFunctionalNoInterlocked(ListHead, Entries, &SpinLock);
|
|
|
|
|
|
|
|
KeLowerIrql(Irql);
|
|
|
|
ExFreePoolWithTag(Buffer, 'TLiS');
|
2011-07-25 20:12:44 +00:00
|
|
|
}
|