2 * PROJECT: ReactOS API tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for Rtl handle tables
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
10 #define WIN32_NO_STATUS
11 #include <ndk/rtlfuncs.h>
14 typedef struct _TEST_HANDLE_ENTRY
16 RTL_HANDLE_TABLE_ENTRY HandleEntry
;
18 } TEST_HANDLE_ENTRY
, *PTEST_HANDLE_ENTRY
;
22 const ULONG MaxHandles
= 2048;
23 RTL_HANDLE_TABLE HandleTable
;
25 PRTL_HANDLE_TABLE_ENTRY HandleEntry
;
26 PTEST_HANDLE_ENTRY TestEntry
;
27 PTEST_HANDLE_ENTRY TestEntry2
;
32 /* Initialize handle table */
33 RtlFillMemory(&HandleTable
, sizeof(HandleTable
), 0x55);
34 RtlInitializeHandleTable(MaxHandles
, sizeof(TEST_HANDLE_ENTRY
), &HandleTable
);
35 ok(HandleTable
.MaximumNumberOfHandles
== MaxHandles
, "MaximumNumberOfHandles = %lu\n", HandleTable
.MaximumNumberOfHandles
);
36 ok(HandleTable
.SizeOfHandleTableEntry
== sizeof(TEST_HANDLE_ENTRY
),
37 "SizeOfHandleTableEntry = %lu\n", HandleTable
.SizeOfHandleTableEntry
);
38 ok(HandleTable
.Reserved
[0] == 0, "Reserved[0] = 0x%lx\n", HandleTable
.Reserved
[0]);
39 ok(HandleTable
.Reserved
[1] == 0, "Reserved[1] = 0x%lx\n", HandleTable
.Reserved
[1]);
40 ok(HandleTable
.CommittedHandles
== NULL
, "CommittedHandles = %p\n", HandleTable
.CommittedHandles
);
41 ok(HandleTable
.UnCommittedHandles
== NULL
, "UnCommittedHandles = %p\n", HandleTable
.UnCommittedHandles
);
42 ok(HandleTable
.MaxReservedHandles
== NULL
, "MaxReservedHandles = %p\n", HandleTable
.MaxReservedHandles
);
43 ok(HandleTable
.FreeHandles
== NULL
, "FreeHandles = %p\n", HandleTable
.FreeHandles
);
45 /* Allocate a handle, now we have a committed page */
46 HandleEntry
= RtlAllocateHandle(&HandleTable
, &Index
);
48 ok(HandleTable
.CommittedHandles
!= NULL
, "CommittedHandles = %p\n", HandleTable
.CommittedHandles
);
49 HandleBase
= (PUCHAR
)HandleTable
.CommittedHandles
;
51 trace("CommittedHandles = %p\n", HandleBase
);
52 ok((PUCHAR
)HandleTable
.UnCommittedHandles
== HandleBase
+ PAGE_SIZE
, "UnCommittedHandles = %p\n", HandleTable
.UnCommittedHandles
);
53 ok((PUCHAR
)HandleTable
.MaxReservedHandles
== HandleBase
+ MaxHandles
* sizeof(TEST_HANDLE_ENTRY
), "MaxReservedHandles = %p\n", HandleTable
.MaxReservedHandles
);
54 ok((PUCHAR
)HandleTable
.FreeHandles
== HandleBase
+ sizeof(TEST_HANDLE_ENTRY
), "FreeHandles = %p\n", HandleTable
.FreeHandles
);
56 ok((PUCHAR
)HandleEntry
== HandleBase
, "HandleEntry = %p\n", HandleEntry
);
57 ok(Index
== 0, "Index = %lu\n", Index
);
59 ok(HandleEntry
->Flags
== 0, "Flags = 0x%lx\n", HandleEntry
->Flags
);
61 TestEntry
= (PTEST_HANDLE_ENTRY
)HandleEntry
;
62 ok(TestEntry
->Data
== 0, "Data = %lu\n", TestEntry
->Data
);
63 TestEntry
->Data
= 0x87654321;
65 /* Handle is not recognized as valid unless we set the valid flag */
66 Valid
= RtlIsValidHandle(&HandleTable
, &TestEntry
->HandleEntry
);
67 ok(Valid
== FALSE
, "Valid = %u\n", Valid
);
68 HandleEntry
= InvalidPointer
;
69 Valid
= RtlIsValidIndexHandle(&HandleTable
, 0, &HandleEntry
);
70 ok(Valid
== FALSE
, "Valid = %u\n", Valid
);
71 ok(HandleEntry
== InvalidPointer
, "HandleEntry = %p\n", HandleEntry
);
73 TestEntry
->HandleEntry
.Flags
= RTL_HANDLE_VALID
;
74 Valid
= RtlIsValidHandle(&HandleTable
, &TestEntry
->HandleEntry
);
75 ok(Valid
== TRUE
, "Valid = %u\n", Valid
);
76 HandleEntry
= InvalidPointer
;
77 Valid
= RtlIsValidIndexHandle(&HandleTable
, 0, &HandleEntry
);
78 ok(Valid
== TRUE
, "Valid = %u\n", Valid
);
79 ok(HandleEntry
== &TestEntry
->HandleEntry
, "HandleEntry = %p\n", HandleEntry
);
81 /* Allocate a second handle */
82 HandleEntry
= RtlAllocateHandle(&HandleTable
, &Index
);
84 ok((PUCHAR
)HandleTable
.CommittedHandles
== HandleBase
, "CommittedHandles = %p\n", HandleTable
.CommittedHandles
);
85 ok((PUCHAR
)HandleTable
.UnCommittedHandles
== HandleBase
+ PAGE_SIZE
, "UnCommittedHandles = %p\n", HandleTable
.UnCommittedHandles
);
86 ok((PUCHAR
)HandleTable
.MaxReservedHandles
== HandleBase
+ MaxHandles
* sizeof(TEST_HANDLE_ENTRY
), "MaxReservedHandles = %p\n", HandleTable
.MaxReservedHandles
);
87 ok((PUCHAR
)HandleTable
.FreeHandles
== HandleBase
+ 2 * sizeof(TEST_HANDLE_ENTRY
), "FreeHandles = %p\n", HandleTable
.FreeHandles
);
89 ok((PUCHAR
)HandleEntry
== HandleBase
+ sizeof(TEST_HANDLE_ENTRY
), "HandleEntry = %p\n", HandleEntry
);
90 ok(Index
== 1, "Index = %lu\n", Index
);
92 TestEntry2
= (PTEST_HANDLE_ENTRY
)HandleEntry
;
93 ok(TestEntry2
->Data
== 0, "Data = %lu\n", TestEntry2
->Data
);
94 TestEntry2
->Data
= 0x87604321;
96 TestEntry2
->HandleEntry
.Flags
= RTL_HANDLE_VALID
;
97 Valid
= RtlIsValidHandle(&HandleTable
, &TestEntry2
->HandleEntry
);
98 ok(Valid
== TRUE
, "Valid = %u\n", Valid
);
100 Valid
= RtlIsValidIndexHandle(&HandleTable
, 1, &HandleEntry
);
101 ok(Valid
== TRUE
, "Valid = %u\n", Valid
);
102 ok(HandleEntry
== &TestEntry2
->HandleEntry
, "HandleEntry = %p\n", HandleEntry
);
104 /* Free the first and allocate another */
105 Valid
= RtlFreeHandle(&HandleTable
, &TestEntry
->HandleEntry
);
106 ok(Valid
== TRUE
, "Valid = %u\n", Valid
);
108 HandleEntry
= RtlAllocateHandle(&HandleTable
, &Index
);
109 ok((PUCHAR
)HandleEntry
== HandleBase
, "HandleEntry = %p\n", HandleEntry
);
110 ok(Index
== 0, "Index = %lu\n", Index
);
111 ok(HandleEntry
->Flags
== 0, "Flags = 0x%lx\n", HandleEntry
->Flags
);
113 TestEntry
= (PTEST_HANDLE_ENTRY
)HandleEntry
;
114 ok(TestEntry
->Data
== 0, "Data = %lu\n", TestEntry
->Data
);
115 TestEntry
->Data
= 0x87650321;
117 Valid
= RtlFreeHandle(&HandleTable
, &TestEntry2
->HandleEntry
);
118 ok(Valid
== TRUE
, "Valid = %u\n", Valid
);
119 TestEntry
->HandleEntry
.Flags
= RTL_HANDLE_VALID
;
120 Valid
= RtlFreeHandle(&HandleTable
, &TestEntry
->HandleEntry
);
121 ok(Valid
== TRUE
, "Valid = %u\n", Valid
);
123 ok((PUCHAR
)HandleTable
.FreeHandles
== HandleBase
, "FreeHandles = %p\n", HandleTable
.FreeHandles
);
125 /* Allocate all possible handles */
126 for (i
= 0; i
< MaxHandles
; i
++)
128 const ULONG EntriesPerPage
= PAGE_SIZE
/ sizeof(TEST_HANDLE_ENTRY
);
130 HandleEntry
= RtlAllocateHandle(&HandleTable
, &Index
);
131 ok(Index
== i
, "[%lu] Index = %lu\n", i
, Index
);
132 ok((PUCHAR
)HandleEntry
== HandleBase
+ i
* sizeof(TEST_HANDLE_ENTRY
),
133 "[%lu] HandleEntry = %p\n", i
, HandleEntry
);
135 ok((PUCHAR
)HandleTable
.CommittedHandles
== HandleBase
, "[%lu] CommittedHandles = %p\n", i
, HandleTable
.CommittedHandles
);
136 ok((PUCHAR
)HandleTable
.UnCommittedHandles
== HandleBase
+ PAGE_SIZE
* (i
/ EntriesPerPage
+ 1) , "[%lu] UnCommittedHandles = %p\n", i
, HandleTable
.UnCommittedHandles
);
137 ok((PUCHAR
)HandleTable
.MaxReservedHandles
== HandleBase
+ MaxHandles
* sizeof(TEST_HANDLE_ENTRY
), "[%lu] MaxReservedHandles = %p\n", i
, HandleTable
.MaxReservedHandles
);
138 if ((i
+ 1) % EntriesPerPage
== 0)
140 ok(HandleTable
.FreeHandles
== NULL
, "[%lu] FreeHandles = %p\n", i
, HandleTable
.FreeHandles
);
144 ok((PUCHAR
)HandleTable
.FreeHandles
== HandleBase
+ (i
+ 1) * sizeof(TEST_HANDLE_ENTRY
), "[%lu] FreeHandles = %p\n", i
, HandleTable
.FreeHandles
);
147 TestEntry
= (PTEST_HANDLE_ENTRY
)HandleEntry
;
148 ok(TestEntry
->Data
== 0, "[%lu] Data = 0x%lx\n", i
, TestEntry
->Data
);
149 TestEntry
->Data
= (i
<< 16) + (i
+ 1);
151 Valid
= RtlIsValidHandle(&HandleTable
, &TestEntry
->HandleEntry
);
152 ok(Valid
== FALSE
, "[%lu] Valid = %u\n", i
, Valid
);
153 HandleEntry
= InvalidPointer
;
154 Valid
= RtlIsValidIndexHandle(&HandleTable
, i
, &HandleEntry
);
155 ok(Valid
== FALSE
, "[%lu] Valid = %u\n", i
, Valid
);
156 ok(HandleEntry
== InvalidPointer
, "[%lu] HandleEntry = %p\n", i
, HandleEntry
);
161 HandleEntry
= RtlAllocateHandle(&HandleTable
, &Index
);
162 ok(HandleEntry
== NULL
, "HandleEntry = %p\n", HandleEntry
);
163 ok(Index
== 0x55555555, "Index = 0x%lx\n", Index
);
166 for (i
= 0; i
< MaxHandles
; i
++)
168 TestEntry
= (PTEST_HANDLE_ENTRY
)HandleBase
+ i
;
170 ok(TestEntry
->Data
== (i
<< 16) + (i
+ 1), "[%lu] Data = %lu\n", i
, TestEntry
->Data
);
172 TestEntry
->HandleEntry
.Flags
= RTL_HANDLE_VALID
;
174 Valid
= RtlIsValidHandle(&HandleTable
, &TestEntry
->HandleEntry
);
175 ok(Valid
== TRUE
, "[%lu] Valid = %u\n", i
, Valid
);
176 HandleEntry
= InvalidPointer
;
177 Valid
= RtlIsValidIndexHandle(&HandleTable
, i
, &HandleEntry
);
178 ok(Valid
== TRUE
, "[%lu] Valid = %u\n", i
, Valid
);
179 ok(HandleEntry
== &TestEntry
->HandleEntry
, "[%lu] HandleEntry = %p\n", i
, HandleEntry
);
181 Valid
= RtlFreeHandle(&HandleTable
, &TestEntry
->HandleEntry
);
182 ok(Valid
== TRUE
, "[%lu] Valid = %u\n", i
, Valid
);
184 Valid
= RtlIsValidHandle(&HandleTable
, &TestEntry
->HandleEntry
);
185 ok(Valid
== FALSE
, "[%lu] Valid = %u\n", i
, Valid
);
186 HandleEntry
= InvalidPointer
;
187 Valid
= RtlIsValidIndexHandle(&HandleTable
, i
, &HandleEntry
);
188 ok(Valid
== FALSE
, "[%lu] Valid = %u\n", i
, Valid
);
189 ok(HandleEntry
== InvalidPointer
, "[%lu] HandleEntry = %p\n", i
, HandleEntry
);
192 /* Check the memory commit once again */
193 ok((PUCHAR
)HandleTable
.CommittedHandles
== HandleBase
, "[%lu] CommittedHandles = %p\n", i
, HandleTable
.CommittedHandles
);
194 ok((PUCHAR
)HandleTable
.UnCommittedHandles
== HandleBase
+ MaxHandles
* sizeof(TEST_HANDLE_ENTRY
), "[%lu] UnCommittedHandles = %p\n", i
, HandleTable
.UnCommittedHandles
);
195 ok((PUCHAR
)HandleTable
.MaxReservedHandles
== HandleBase
+ MaxHandles
* sizeof(TEST_HANDLE_ENTRY
), "[%lu] MaxReservedHandles = %p\n", i
, HandleTable
.MaxReservedHandles
);
196 ok((PUCHAR
)HandleTable
.FreeHandles
== HandleBase
+ (i
- 1) * sizeof(TEST_HANDLE_ENTRY
), "[%lu] FreeHandles = %p\n", i
, HandleTable
.FreeHandles
);
198 /* Finally, destroy the table */
199 RtlDestroyHandleTable(&HandleTable
);
200 ok((PUCHAR
)HandleTable
.CommittedHandles
== HandleBase
, "CommittedHandles = %p\n", HandleTable
.CommittedHandles
);