1*c2c66affSColin Finck /*
2*c2c66affSColin Finck * PROJECT: ReactOS kernel-mode tests
3*c2c66affSColin Finck * LICENSE: LGPLv2+ - See COPYING.LIB in the top level directory
4*c2c66affSColin Finck * PURPOSE: Kernel-Mode Test Suite RtlGenericTable
5*c2c66affSColin Finck * PROGRAMMER: arty
6*c2c66affSColin Finck */
7*c2c66affSColin Finck
8*c2c66affSColin Finck #define KMT_EMULATE_KERNEL
9*c2c66affSColin Finck #include <kmt_test.h>
10*c2c66affSColin Finck
11*c2c66affSColin Finck #define NDEBUG
12*c2c66affSColin Finck #include <debug.h>
13*c2c66affSColin Finck
14*c2c66affSColin Finck static LIST_ENTRY Allocations;
15*c2c66affSColin Finck
16*c2c66affSColin Finck static RTL_GENERIC_COMPARE_RESULTS NTAPI
CompareCharTable(PRTL_GENERIC_TABLE Table,PVOID A,PVOID B)17*c2c66affSColin Finck CompareCharTable(PRTL_GENERIC_TABLE Table, PVOID A, PVOID B)
18*c2c66affSColin Finck {
19*c2c66affSColin Finck RTL_GENERIC_COMPARE_RESULTS Result = (*((PCHAR)A) < *((PCHAR)B)) ? GenericLessThan :
20*c2c66affSColin Finck (*((PCHAR)A) > *((PCHAR)B)) ? GenericGreaterThan :
21*c2c66affSColin Finck GenericEqual;
22*c2c66affSColin Finck return Result;
23*c2c66affSColin Finck }
24*c2c66affSColin Finck
25*c2c66affSColin Finck static PVOID NTAPI
AllocRoutine(PRTL_GENERIC_TABLE Table,CLONG ByteSize)26*c2c66affSColin Finck AllocRoutine(PRTL_GENERIC_TABLE Table, CLONG ByteSize)
27*c2c66affSColin Finck {
28*c2c66affSColin Finck PLIST_ENTRY Entry = ExAllocatePool
29*c2c66affSColin Finck (NonPagedPool, sizeof(LIST_ENTRY) + ByteSize);
30*c2c66affSColin Finck InsertTailList(&Allocations, Entry);
31*c2c66affSColin Finck return &Entry[1];
32*c2c66affSColin Finck }
33*c2c66affSColin Finck
34*c2c66affSColin Finck static VOID NTAPI
FreeRoutine(PRTL_GENERIC_TABLE Table,PVOID Buffer)35*c2c66affSColin Finck FreeRoutine(PRTL_GENERIC_TABLE Table, PVOID Buffer)
36*c2c66affSColin Finck {
37*c2c66affSColin Finck PLIST_ENTRY Entry = (PLIST_ENTRY)(((PCHAR)Buffer) - sizeof(LIST_ENTRY));
38*c2c66affSColin Finck RemoveEntryList(Entry);
39*c2c66affSColin Finck ExFreePool(Entry);
40*c2c66affSColin Finck }
41*c2c66affSColin Finck
RtlSplayTreeTest()42*c2c66affSColin Finck static void RtlSplayTreeTest()
43*c2c66affSColin Finck {
44*c2c66affSColin Finck ULONG i, del;
45*c2c66affSColin Finck PCHAR Ch;
46*c2c66affSColin Finck CHAR Text[] = "the quick_brown!fOx-jUmp3d/0vER+THe^lazy.D@g";
47*c2c66affSColin Finck CHAR NewE[] = "11111111111111111111111111111111110111111111";
48*c2c66affSColin Finck RTL_GENERIC_TABLE Table;
49*c2c66affSColin Finck RtlInitializeGenericTable
50*c2c66affSColin Finck (&Table,
51*c2c66affSColin Finck CompareCharTable,
52*c2c66affSColin Finck AllocRoutine,
53*c2c66affSColin Finck FreeRoutine,
54*c2c66affSColin Finck NULL);
55*c2c66affSColin Finck for (i = 0; Text[i]; i++) {
56*c2c66affSColin Finck BOOLEAN WasNew;
57*c2c66affSColin Finck Ch = (PCHAR)RtlInsertElementGenericTable
58*c2c66affSColin Finck (&Table,
59*c2c66affSColin Finck &Text[i],
60*c2c66affSColin Finck sizeof(Text[i]),
61*c2c66affSColin Finck &WasNew);
62*c2c66affSColin Finck ok(Ch && *Ch == Text[i], "Copy character into node\n");
63*c2c66affSColin Finck ok(WasNew == (NewE[i] == '1'),
64*c2c66affSColin Finck "Character newness didn't match for char %u: '%c'\n",
65*c2c66affSColin Finck i, Text[i]);
66*c2c66affSColin Finck }
67*c2c66affSColin Finck for (Ch = (PCHAR)RtlEnumerateGenericTable(&Table, TRUE), i = 0;
68*c2c66affSColin Finck Ch;
69*c2c66affSColin Finck Ch = (PCHAR)RtlEnumerateGenericTable(&Table, FALSE), i++) {
70*c2c66affSColin Finck ok(strchr(Text, *Ch) != NULL, "Nonexistent character\n");
71*c2c66affSColin Finck }
72*c2c66affSColin Finck ok(RtlNumberGenericTableElements(&Table) == strlen(Text) - 1, "Not the right number of elements\n");
73*c2c66affSColin Finck ok(RtlLookupElementGenericTable(&Table, "q") != NULL, "Could not lookup q\n");
74*c2c66affSColin Finck ok(!RtlLookupElementGenericTable(&Table, "#"), "Found a character that shouldn't appear\n");
75*c2c66affSColin Finck ok(strlen(Text) == i + 1, "Didn't enumerate enough characters\n");
76*c2c66affSColin Finck del = 0;
77*c2c66affSColin Finck for (i = 0; Text[i]; i++) {
78*c2c66affSColin Finck if (NewE[i] == '1') {
79*c2c66affSColin Finck BOOLEAN WasDeleted;
80*c2c66affSColin Finck WasDeleted = RtlDeleteElementGenericTable(&Table, &Text[i]);
81*c2c66affSColin Finck del += WasDeleted;
82*c2c66affSColin Finck }
83*c2c66affSColin Finck }
84*c2c66affSColin Finck ok(!RtlNumberGenericTableElements(&Table), "Not zero elements\n");
85*c2c66affSColin Finck ok(!RtlGetElementGenericTable(&Table, 0), "Elements left when we removed them all\n");
86*c2c66affSColin Finck ok(strlen(Text) == del + 1, "Deleted too many times\n");
87*c2c66affSColin Finck ok(IsListEmpty(&Allocations), "Didn't free all memory\n");
88*c2c66affSColin Finck }
89*c2c66affSColin Finck
START_TEST(RtlSplayTree)90*c2c66affSColin Finck START_TEST(RtlSplayTree)
91*c2c66affSColin Finck {
92*c2c66affSColin Finck InitializeListHead(&Allocations);
93*c2c66affSColin Finck RtlSplayTreeTest();
94*c2c66affSColin Finck }
95