1 /* 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> 6 */ 7 8 #include "precomp.h" 9 10 typedef struct _TEST_HANDLE_ENTRY 11 { 12 RTL_HANDLE_TABLE_ENTRY HandleEntry; 13 ULONG Data; 14 } TEST_HANDLE_ENTRY, *PTEST_HANDLE_ENTRY; 15 16 START_TEST(RtlHandle) 17 { 18 const ULONG MaxHandles = 2048; 19 RTL_HANDLE_TABLE HandleTable; 20 PUCHAR HandleBase; 21 PRTL_HANDLE_TABLE_ENTRY HandleEntry; 22 PTEST_HANDLE_ENTRY TestEntry; 23 PTEST_HANDLE_ENTRY TestEntry2; 24 ULONG Index; 25 BOOLEAN Valid; 26 ULONG i; 27 28 /* Initialize handle table */ 29 RtlFillMemory(&HandleTable, sizeof(HandleTable), 0x55); 30 RtlInitializeHandleTable(MaxHandles, sizeof(TEST_HANDLE_ENTRY), &HandleTable); 31 ok(HandleTable.MaximumNumberOfHandles == MaxHandles, "MaximumNumberOfHandles = %lu\n", HandleTable.MaximumNumberOfHandles); 32 ok(HandleTable.SizeOfHandleTableEntry == sizeof(TEST_HANDLE_ENTRY), 33 "SizeOfHandleTableEntry = %lu\n", HandleTable.SizeOfHandleTableEntry); 34 ok(HandleTable.Reserved[0] == 0, "Reserved[0] = 0x%lx\n", HandleTable.Reserved[0]); 35 ok(HandleTable.Reserved[1] == 0, "Reserved[1] = 0x%lx\n", HandleTable.Reserved[1]); 36 ok(HandleTable.CommittedHandles == NULL, "CommittedHandles = %p\n", HandleTable.CommittedHandles); 37 ok(HandleTable.UnCommittedHandles == NULL, "UnCommittedHandles = %p\n", HandleTable.UnCommittedHandles); 38 ok(HandleTable.MaxReservedHandles == NULL, "MaxReservedHandles = %p\n", HandleTable.MaxReservedHandles); 39 ok(HandleTable.FreeHandles == NULL, "FreeHandles = %p\n", HandleTable.FreeHandles); 40 41 /* Allocate a handle, now we have a committed page */ 42 HandleEntry = RtlAllocateHandle(&HandleTable, &Index); 43 44 ok(HandleTable.CommittedHandles != NULL, "CommittedHandles = %p\n", HandleTable.CommittedHandles); 45 HandleBase = (PUCHAR)HandleTable.CommittedHandles; 46 47 trace("CommittedHandles = %p\n", HandleBase); 48 ok((PUCHAR)HandleTable.UnCommittedHandles == HandleBase + PAGE_SIZE, "UnCommittedHandles = %p\n", HandleTable.UnCommittedHandles); 49 ok((PUCHAR)HandleTable.MaxReservedHandles == HandleBase + MaxHandles * sizeof(TEST_HANDLE_ENTRY), "MaxReservedHandles = %p\n", HandleTable.MaxReservedHandles); 50 ok((PUCHAR)HandleTable.FreeHandles == HandleBase + sizeof(TEST_HANDLE_ENTRY), "FreeHandles = %p\n", HandleTable.FreeHandles); 51 52 ok((PUCHAR)HandleEntry == HandleBase, "HandleEntry = %p\n", HandleEntry); 53 ok(Index == 0, "Index = %lu\n", Index); 54 55 ok(HandleEntry->Flags == 0, "Flags = 0x%lx\n", HandleEntry->Flags); 56 57 TestEntry = (PTEST_HANDLE_ENTRY)HandleEntry; 58 ok(TestEntry->Data == 0, "Data = %lu\n", TestEntry->Data); 59 TestEntry->Data = 0x87654321; 60 61 /* Handle is not recognized as valid unless we set the valid flag */ 62 Valid = RtlIsValidHandle(&HandleTable, &TestEntry->HandleEntry); 63 ok(Valid == FALSE, "Valid = %u\n", Valid); 64 HandleEntry = InvalidPointer; 65 Valid = RtlIsValidIndexHandle(&HandleTable, 0, &HandleEntry); 66 ok(Valid == FALSE, "Valid = %u\n", Valid); 67 ok(HandleEntry == InvalidPointer, "HandleEntry = %p\n", HandleEntry); 68 69 TestEntry->HandleEntry.Flags = RTL_HANDLE_VALID; 70 Valid = RtlIsValidHandle(&HandleTable, &TestEntry->HandleEntry); 71 ok(Valid == TRUE, "Valid = %u\n", Valid); 72 HandleEntry = InvalidPointer; 73 Valid = RtlIsValidIndexHandle(&HandleTable, 0, &HandleEntry); 74 ok(Valid == TRUE, "Valid = %u\n", Valid); 75 ok(HandleEntry == &TestEntry->HandleEntry, "HandleEntry = %p\n", HandleEntry); 76 77 /* Allocate a second handle */ 78 HandleEntry = RtlAllocateHandle(&HandleTable, &Index); 79 80 ok((PUCHAR)HandleTable.CommittedHandles == HandleBase, "CommittedHandles = %p\n", HandleTable.CommittedHandles); 81 ok((PUCHAR)HandleTable.UnCommittedHandles == HandleBase + PAGE_SIZE, "UnCommittedHandles = %p\n", HandleTable.UnCommittedHandles); 82 ok((PUCHAR)HandleTable.MaxReservedHandles == HandleBase + MaxHandles * sizeof(TEST_HANDLE_ENTRY), "MaxReservedHandles = %p\n", HandleTable.MaxReservedHandles); 83 ok((PUCHAR)HandleTable.FreeHandles == HandleBase + 2 * sizeof(TEST_HANDLE_ENTRY), "FreeHandles = %p\n", HandleTable.FreeHandles); 84 85 ok((PUCHAR)HandleEntry == HandleBase + sizeof(TEST_HANDLE_ENTRY), "HandleEntry = %p\n", HandleEntry); 86 ok(Index == 1, "Index = %lu\n", Index); 87 88 TestEntry2 = (PTEST_HANDLE_ENTRY)HandleEntry; 89 ok(TestEntry2->Data == 0, "Data = %lu\n", TestEntry2->Data); 90 TestEntry2->Data = 0x87604321; 91 92 TestEntry2->HandleEntry.Flags = RTL_HANDLE_VALID; 93 Valid = RtlIsValidHandle(&HandleTable, &TestEntry2->HandleEntry); 94 ok(Valid == TRUE, "Valid = %u\n", Valid); 95 HandleEntry = NULL; 96 Valid = RtlIsValidIndexHandle(&HandleTable, 1, &HandleEntry); 97 ok(Valid == TRUE, "Valid = %u\n", Valid); 98 ok(HandleEntry == &TestEntry2->HandleEntry, "HandleEntry = %p\n", HandleEntry); 99 100 /* Free the first and allocate another */ 101 Valid = RtlFreeHandle(&HandleTable, &TestEntry->HandleEntry); 102 ok(Valid == TRUE, "Valid = %u\n", Valid); 103 104 HandleEntry = RtlAllocateHandle(&HandleTable, &Index); 105 ok((PUCHAR)HandleEntry == HandleBase, "HandleEntry = %p\n", HandleEntry); 106 ok(Index == 0, "Index = %lu\n", Index); 107 ok(HandleEntry->Flags == 0, "Flags = 0x%lx\n", HandleEntry->Flags); 108 109 TestEntry = (PTEST_HANDLE_ENTRY)HandleEntry; 110 ok(TestEntry->Data == 0, "Data = %lu\n", TestEntry->Data); 111 TestEntry->Data = 0x87650321; 112 113 Valid = RtlFreeHandle(&HandleTable, &TestEntry2->HandleEntry); 114 ok(Valid == TRUE, "Valid = %u\n", Valid); 115 TestEntry->HandleEntry.Flags = RTL_HANDLE_VALID; 116 Valid = RtlFreeHandle(&HandleTable, &TestEntry->HandleEntry); 117 ok(Valid == TRUE, "Valid = %u\n", Valid); 118 119 ok((PUCHAR)HandleTable.FreeHandles == HandleBase, "FreeHandles = %p\n", HandleTable.FreeHandles); 120 121 /* Allocate all possible handles */ 122 for (i = 0; i < MaxHandles; i++) 123 { 124 const ULONG EntriesPerPage = PAGE_SIZE / sizeof(TEST_HANDLE_ENTRY); 125 126 HandleEntry = RtlAllocateHandle(&HandleTable, &Index); 127 ok(Index == i, "[%lu] Index = %lu\n", i, Index); 128 ok((PUCHAR)HandleEntry == HandleBase + i * sizeof(TEST_HANDLE_ENTRY), 129 "[%lu] HandleEntry = %p\n", i, HandleEntry); 130 131 ok((PUCHAR)HandleTable.CommittedHandles == HandleBase, "[%lu] CommittedHandles = %p\n", i, HandleTable.CommittedHandles); 132 ok((PUCHAR)HandleTable.UnCommittedHandles == HandleBase + PAGE_SIZE * (i / EntriesPerPage + 1) , "[%lu] UnCommittedHandles = %p\n", i, HandleTable.UnCommittedHandles); 133 ok((PUCHAR)HandleTable.MaxReservedHandles == HandleBase + MaxHandles * sizeof(TEST_HANDLE_ENTRY), "[%lu] MaxReservedHandles = %p\n", i, HandleTable.MaxReservedHandles); 134 if ((i + 1) % EntriesPerPage == 0) 135 { 136 ok(HandleTable.FreeHandles == NULL, "[%lu] FreeHandles = %p\n", i, HandleTable.FreeHandles); 137 } 138 else 139 { 140 ok((PUCHAR)HandleTable.FreeHandles == HandleBase + (i + 1) * sizeof(TEST_HANDLE_ENTRY), "[%lu] FreeHandles = %p\n", i, HandleTable.FreeHandles); 141 } 142 143 TestEntry = (PTEST_HANDLE_ENTRY)HandleEntry; 144 ok(TestEntry->Data == 0, "[%lu] Data = 0x%lx\n", i, TestEntry->Data); 145 TestEntry->Data = (i << 16) + (i + 1); 146 147 Valid = RtlIsValidHandle(&HandleTable, &TestEntry->HandleEntry); 148 ok(Valid == FALSE, "[%lu] Valid = %u\n", i, Valid); 149 HandleEntry = InvalidPointer; 150 Valid = RtlIsValidIndexHandle(&HandleTable, i, &HandleEntry); 151 ok(Valid == FALSE, "[%lu] Valid = %u\n", i, Valid); 152 ok(HandleEntry == InvalidPointer, "[%lu] HandleEntry = %p\n", i, HandleEntry); 153 } 154 155 /* Try one more */ 156 Index = 0x55555555; 157 HandleEntry = RtlAllocateHandle(&HandleTable, &Index); 158 ok(HandleEntry == NULL, "HandleEntry = %p\n", HandleEntry); 159 ok(Index == 0x55555555, "Index = 0x%lx\n", Index); 160 161 /* Free them all */ 162 for (i = 0; i < MaxHandles; i++) 163 { 164 TestEntry = (PTEST_HANDLE_ENTRY)HandleBase + i; 165 166 ok(TestEntry->Data == (i << 16) + (i + 1), "[%lu] Data = %lu\n", i, TestEntry->Data); 167 168 TestEntry->HandleEntry.Flags = RTL_HANDLE_VALID; 169 170 Valid = RtlIsValidHandle(&HandleTable, &TestEntry->HandleEntry); 171 ok(Valid == TRUE, "[%lu] Valid = %u\n", i, Valid); 172 HandleEntry = InvalidPointer; 173 Valid = RtlIsValidIndexHandle(&HandleTable, i, &HandleEntry); 174 ok(Valid == TRUE, "[%lu] Valid = %u\n", i, Valid); 175 ok(HandleEntry == &TestEntry->HandleEntry, "[%lu] HandleEntry = %p\n", i, HandleEntry); 176 177 Valid = RtlFreeHandle(&HandleTable, &TestEntry->HandleEntry); 178 ok(Valid == TRUE, "[%lu] Valid = %u\n", i, Valid); 179 180 Valid = RtlIsValidHandle(&HandleTable, &TestEntry->HandleEntry); 181 ok(Valid == FALSE, "[%lu] Valid = %u\n", i, Valid); 182 HandleEntry = InvalidPointer; 183 Valid = RtlIsValidIndexHandle(&HandleTable, i, &HandleEntry); 184 ok(Valid == FALSE, "[%lu] Valid = %u\n", i, Valid); 185 ok(HandleEntry == InvalidPointer, "[%lu] HandleEntry = %p\n", i, HandleEntry); 186 } 187 188 /* Check the memory commit once again */ 189 ok((PUCHAR)HandleTable.CommittedHandles == HandleBase, "[%lu] CommittedHandles = %p\n", i, HandleTable.CommittedHandles); 190 ok((PUCHAR)HandleTable.UnCommittedHandles == HandleBase + MaxHandles * sizeof(TEST_HANDLE_ENTRY), "[%lu] UnCommittedHandles = %p\n", i, HandleTable.UnCommittedHandles); 191 ok((PUCHAR)HandleTable.MaxReservedHandles == HandleBase + MaxHandles * sizeof(TEST_HANDLE_ENTRY), "[%lu] MaxReservedHandles = %p\n", i, HandleTable.MaxReservedHandles); 192 ok((PUCHAR)HandleTable.FreeHandles == HandleBase + (i - 1) * sizeof(TEST_HANDLE_ENTRY), "[%lu] FreeHandles = %p\n", i, HandleTable.FreeHandles); 193 194 /* Finally, destroy the table */ 195 RtlDestroyHandleTable(&HandleTable); 196 ok((PUCHAR)HandleTable.CommittedHandles == HandleBase, "CommittedHandles = %p\n", HandleTable.CommittedHandles); 197 } 198