Author: tfaber Date: Fri May 19 18:05:12 2017 New Revision: 74598 URL: http://svn.reactos.org/svn/reactos?rev=74598&view=rev Log: [NTDLL_APITEST] - Add a test for RTL handle tables CORE-13271
Added: trunk/rostests/apitests/ntdll/RtlHandle.c (with props) Modified: trunk/rostests/apitests/ntdll/CMakeLists.txt trunk/rostests/apitests/ntdll/testlist.c Modified: trunk/rostests/apitests/ntdll/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/ntdll/CMakeLists.txt?rev=74598&r1=74597&r2=74598&view=diff ============================================================================== --- trunk/rostests/apitests/ntdll/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/apitests/ntdll/CMakeLists.txt [iso-8859-1] Fri May 19 18:05:12 2017 @@ -40,6 +40,7 @@ RtlGetFullPathName_UstrEx.c RtlGetLengthWithoutTrailingPathSeperators.c RtlGetLongestNtPathLength.c + RtlHandle.c RtlImageRvaToVa.c RtlInitializeBitMap.c RtlIsNameLegalDOS8Dot3.c Added: trunk/rostests/apitests/ntdll/RtlHandle.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/ntdll/RtlHandle.c?rev=74598 ============================================================================== --- trunk/rostests/apitests/ntdll/RtlHandle.c (added) +++ trunk/rostests/apitests/ntdll/RtlHandle.c [iso-8859-1] Fri May 19 18:05:12 2017 @@ -0,0 +1,201 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Test for Rtl handle tables + * PROGRAMMER: Thomas Faber <thomas.fa...@reactos.org> + */ + +#include <apitest.h> + +#define WIN32_NO_STATUS +#include <ndk/rtlfuncs.h> +#include <stdio.h> + +typedef struct _TEST_HANDLE_ENTRY +{ + RTL_HANDLE_TABLE_ENTRY HandleEntry; + ULONG Data; +} TEST_HANDLE_ENTRY, *PTEST_HANDLE_ENTRY; + +START_TEST(RtlHandle) +{ + const ULONG MaxHandles = 2048; + RTL_HANDLE_TABLE HandleTable; + PUCHAR HandleBase; + PRTL_HANDLE_TABLE_ENTRY HandleEntry; + PTEST_HANDLE_ENTRY TestEntry; + PTEST_HANDLE_ENTRY TestEntry2; + ULONG Index; + BOOLEAN Valid; + ULONG i; + + /* Initialize handle table */ + RtlFillMemory(&HandleTable, sizeof(HandleTable), 0x55); + RtlInitializeHandleTable(MaxHandles, sizeof(TEST_HANDLE_ENTRY), &HandleTable); + ok(HandleTable.MaximumNumberOfHandles == MaxHandles, "MaximumNumberOfHandles = %lu\n", HandleTable.MaximumNumberOfHandles); + ok(HandleTable.SizeOfHandleTableEntry == sizeof(TEST_HANDLE_ENTRY), + "SizeOfHandleTableEntry = %lu\n", HandleTable.SizeOfHandleTableEntry); + ok(HandleTable.Reserved[0] == 0, "Reserved[0] = 0x%lx\n", HandleTable.Reserved[0]); + ok(HandleTable.Reserved[1] == 0, "Reserved[1] = 0x%lx\n", HandleTable.Reserved[1]); + ok(HandleTable.CommittedHandles == NULL, "CommittedHandles = %p\n", HandleTable.CommittedHandles); + ok(HandleTable.UnCommittedHandles == NULL, "UnCommittedHandles = %p\n", HandleTable.UnCommittedHandles); + ok(HandleTable.MaxReservedHandles == NULL, "MaxReservedHandles = %p\n", HandleTable.MaxReservedHandles); + ok(HandleTable.FreeHandles == NULL, "FreeHandles = %p\n", HandleTable.FreeHandles); + + /* Allocate a handle, now we have a committed page */ + HandleEntry = RtlAllocateHandle(&HandleTable, &Index); + + ok(HandleTable.CommittedHandles != NULL, "CommittedHandles = %p\n", HandleTable.CommittedHandles); + HandleBase = (PUCHAR)HandleTable.CommittedHandles; + + trace("CommittedHandles = %p\n", HandleBase); + ok((PUCHAR)HandleTable.UnCommittedHandles == HandleBase + PAGE_SIZE, "UnCommittedHandles = %p\n", HandleTable.UnCommittedHandles); + ok((PUCHAR)HandleTable.MaxReservedHandles == HandleBase + MaxHandles * sizeof(TEST_HANDLE_ENTRY), "MaxReservedHandles = %p\n", HandleTable.MaxReservedHandles); + ok((PUCHAR)HandleTable.FreeHandles == HandleBase + sizeof(TEST_HANDLE_ENTRY), "FreeHandles = %p\n", HandleTable.FreeHandles); + + ok((PUCHAR)HandleEntry == HandleBase, "HandleEntry = %p\n", HandleEntry); + ok(Index == 0, "Index = %lu\n", Index); + + ok(HandleEntry->Flags == 0, "Flags = 0x%lx\n", HandleEntry->Flags); + + TestEntry = (PTEST_HANDLE_ENTRY)HandleEntry; + ok(TestEntry->Data == 0, "Data = %lu\n", TestEntry->Data); + TestEntry->Data = 0x87654321; + + /* Handle is not recognized as valid unless we set the valid flag */ + Valid = RtlIsValidHandle(&HandleTable, &TestEntry->HandleEntry); + ok(Valid == FALSE, "Valid = %u\n", Valid); + HandleEntry = InvalidPointer; + Valid = RtlIsValidIndexHandle(&HandleTable, 0, &HandleEntry); + ok(Valid == FALSE, "Valid = %u\n", Valid); + ok(HandleEntry == InvalidPointer, "HandleEntry = %p\n", HandleEntry); + + TestEntry->HandleEntry.Flags = RTL_HANDLE_VALID; + Valid = RtlIsValidHandle(&HandleTable, &TestEntry->HandleEntry); + ok(Valid == TRUE, "Valid = %u\n", Valid); + HandleEntry = InvalidPointer; + Valid = RtlIsValidIndexHandle(&HandleTable, 0, &HandleEntry); + ok(Valid == TRUE, "Valid = %u\n", Valid); + ok(HandleEntry == &TestEntry->HandleEntry, "HandleEntry = %p\n", HandleEntry); + + /* Allocate a second handle */ + HandleEntry = RtlAllocateHandle(&HandleTable, &Index); + + ok((PUCHAR)HandleTable.CommittedHandles == HandleBase, "CommittedHandles = %p\n", HandleTable.CommittedHandles); + ok((PUCHAR)HandleTable.UnCommittedHandles == HandleBase + PAGE_SIZE, "UnCommittedHandles = %p\n", HandleTable.UnCommittedHandles); + ok((PUCHAR)HandleTable.MaxReservedHandles == HandleBase + MaxHandles * sizeof(TEST_HANDLE_ENTRY), "MaxReservedHandles = %p\n", HandleTable.MaxReservedHandles); + ok((PUCHAR)HandleTable.FreeHandles == HandleBase + 2 * sizeof(TEST_HANDLE_ENTRY), "FreeHandles = %p\n", HandleTable.FreeHandles); + + ok((PUCHAR)HandleEntry == HandleBase + sizeof(TEST_HANDLE_ENTRY), "HandleEntry = %p\n", HandleEntry); + ok(Index == 1, "Index = %lu\n", Index); + + TestEntry2 = (PTEST_HANDLE_ENTRY)HandleEntry; + ok(TestEntry2->Data == 0, "Data = %lu\n", TestEntry2->Data); + TestEntry2->Data = 0x87604321; + + TestEntry2->HandleEntry.Flags = RTL_HANDLE_VALID; + Valid = RtlIsValidHandle(&HandleTable, &TestEntry2->HandleEntry); + ok(Valid == TRUE, "Valid = %u\n", Valid); + HandleEntry = NULL; + Valid = RtlIsValidIndexHandle(&HandleTable, 1, &HandleEntry); + ok(Valid == TRUE, "Valid = %u\n", Valid); + ok(HandleEntry == &TestEntry2->HandleEntry, "HandleEntry = %p\n", HandleEntry); + + /* Free the first and allocate another */ + Valid = RtlFreeHandle(&HandleTable, &TestEntry->HandleEntry); + ok(Valid == TRUE, "Valid = %u\n", Valid); + + HandleEntry = RtlAllocateHandle(&HandleTable, &Index); + ok((PUCHAR)HandleEntry == HandleBase, "HandleEntry = %p\n", HandleEntry); + ok(Index == 0, "Index = %lu\n", Index); + ok(HandleEntry->Flags == 0, "Flags = 0x%lx\n", HandleEntry->Flags); + + TestEntry = (PTEST_HANDLE_ENTRY)HandleEntry; + ok(TestEntry->Data == 0, "Data = %lu\n", TestEntry->Data); + TestEntry->Data = 0x87650321; + + Valid = RtlFreeHandle(&HandleTable, &TestEntry2->HandleEntry); + ok(Valid == TRUE, "Valid = %u\n", Valid); + TestEntry->HandleEntry.Flags = RTL_HANDLE_VALID; + Valid = RtlFreeHandle(&HandleTable, &TestEntry->HandleEntry); + ok(Valid == TRUE, "Valid = %u\n", Valid); + + ok((PUCHAR)HandleTable.FreeHandles == HandleBase, "FreeHandles = %p\n", HandleTable.FreeHandles); + + /* Allocate all possible handles */ + for (i = 0; i < MaxHandles; i++) + { + const ULONG EntriesPerPage = PAGE_SIZE / sizeof(TEST_HANDLE_ENTRY); + + HandleEntry = RtlAllocateHandle(&HandleTable, &Index); + ok(Index == i, "[%lu] Index = %lu\n", i, Index); + ok((PUCHAR)HandleEntry == HandleBase + i * sizeof(TEST_HANDLE_ENTRY), + "[%lu] HandleEntry = %p\n", i, HandleEntry); + + ok((PUCHAR)HandleTable.CommittedHandles == HandleBase, "[%lu] CommittedHandles = %p\n", i, HandleTable.CommittedHandles); + ok((PUCHAR)HandleTable.UnCommittedHandles == HandleBase + PAGE_SIZE * (i / EntriesPerPage + 1) , "[%lu] UnCommittedHandles = %p\n", i, HandleTable.UnCommittedHandles); + ok((PUCHAR)HandleTable.MaxReservedHandles == HandleBase + MaxHandles * sizeof(TEST_HANDLE_ENTRY), "[%lu] MaxReservedHandles = %p\n", i, HandleTable.MaxReservedHandles); + if ((i + 1) % EntriesPerPage == 0) + { + ok(HandleTable.FreeHandles == NULL, "[%lu] FreeHandles = %p\n", i, HandleTable.FreeHandles); + } + else + { + ok((PUCHAR)HandleTable.FreeHandles == HandleBase + (i + 1) * sizeof(TEST_HANDLE_ENTRY), "[%lu] FreeHandles = %p\n", i, HandleTable.FreeHandles); + } + + TestEntry = (PTEST_HANDLE_ENTRY)HandleEntry; + ok(TestEntry->Data == 0, "[%lu] Data = 0x%lx\n", i, TestEntry->Data); + TestEntry->Data = (i << 16) + (i + 1); + + Valid = RtlIsValidHandle(&HandleTable, &TestEntry->HandleEntry); + ok(Valid == FALSE, "[%lu] Valid = %u\n", i, Valid); + HandleEntry = InvalidPointer; + Valid = RtlIsValidIndexHandle(&HandleTable, i, &HandleEntry); + ok(Valid == FALSE, "[%lu] Valid = %u\n", i, Valid); + ok(HandleEntry == InvalidPointer, "[%lu] HandleEntry = %p\n", i, HandleEntry); + } + + /* Try one more */ + Index = 0x55555555; + HandleEntry = RtlAllocateHandle(&HandleTable, &Index); + ok(HandleEntry == NULL, "HandleEntry = %p\n", HandleEntry); + ok(Index == 0x55555555, "Index = 0x%lx\n", Index); + + /* Free them all */ + for (i = 0; i < MaxHandles; i++) + { + TestEntry = (PTEST_HANDLE_ENTRY)HandleBase + i; + + ok(TestEntry->Data == (i << 16) + (i + 1), "[%lu] Data = %lu\n", i, TestEntry->Data); + + TestEntry->HandleEntry.Flags = RTL_HANDLE_VALID; + + Valid = RtlIsValidHandle(&HandleTable, &TestEntry->HandleEntry); + ok(Valid == TRUE, "[%lu] Valid = %u\n", i, Valid); + HandleEntry = InvalidPointer; + Valid = RtlIsValidIndexHandle(&HandleTable, i, &HandleEntry); + ok(Valid == TRUE, "[%lu] Valid = %u\n", i, Valid); + ok(HandleEntry == &TestEntry->HandleEntry, "[%lu] HandleEntry = %p\n", i, HandleEntry); + + Valid = RtlFreeHandle(&HandleTable, &TestEntry->HandleEntry); + ok(Valid == TRUE, "[%lu] Valid = %u\n", i, Valid); + + Valid = RtlIsValidHandle(&HandleTable, &TestEntry->HandleEntry); + ok(Valid == FALSE, "[%lu] Valid = %u\n", i, Valid); + HandleEntry = InvalidPointer; + Valid = RtlIsValidIndexHandle(&HandleTable, i, &HandleEntry); + ok(Valid == FALSE, "[%lu] Valid = %u\n", i, Valid); + ok(HandleEntry == InvalidPointer, "[%lu] HandleEntry = %p\n", i, HandleEntry); + } + + /* Check the memory commit once again */ + ok((PUCHAR)HandleTable.CommittedHandles == HandleBase, "[%lu] CommittedHandles = %p\n", i, HandleTable.CommittedHandles); + ok((PUCHAR)HandleTable.UnCommittedHandles == HandleBase + MaxHandles * sizeof(TEST_HANDLE_ENTRY), "[%lu] UnCommittedHandles = %p\n", i, HandleTable.UnCommittedHandles); + ok((PUCHAR)HandleTable.MaxReservedHandles == HandleBase + MaxHandles * sizeof(TEST_HANDLE_ENTRY), "[%lu] MaxReservedHandles = %p\n", i, HandleTable.MaxReservedHandles); + ok((PUCHAR)HandleTable.FreeHandles == HandleBase + (i - 1) * sizeof(TEST_HANDLE_ENTRY), "[%lu] FreeHandles = %p\n", i, HandleTable.FreeHandles); + + /* Finally, destroy the table */ + RtlDestroyHandleTable(&HandleTable); + ok((PUCHAR)HandleTable.CommittedHandles == HandleBase, "CommittedHandles = %p\n", HandleTable.CommittedHandles); +} Propchange: trunk/rostests/apitests/ntdll/RtlHandle.c ------------------------------------------------------------------------------ svn:eol-style = native Modified: trunk/rostests/apitests/ntdll/testlist.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/ntdll/testlist.c?rev=74598&r1=74597&r2=74598&view=diff ============================================================================== --- trunk/rostests/apitests/ntdll/testlist.c [iso-8859-1] (original) +++ trunk/rostests/apitests/ntdll/testlist.c [iso-8859-1] Fri May 19 18:05:12 2017 @@ -44,6 +44,7 @@ extern void func_RtlGetFullPathName_UstrEx(void); extern void func_RtlGetLengthWithoutTrailingPathSeperators(void); extern void func_RtlGetLongestNtPathLength(void); +extern void func_RtlHandle(void); extern void func_RtlImageRvaToVa(void); extern void func_RtlInitializeBitMap(void); extern void func_RtlIsNameLegalDOS8Dot3(void); @@ -98,6 +99,7 @@ { "RtlGetFullPathName_UstrEx", func_RtlGetFullPathName_UstrEx }, { "RtlGetLengthWithoutTrailingPathSeperators", func_RtlGetLengthWithoutTrailingPathSeperators }, { "RtlGetLongestNtPathLength", func_RtlGetLongestNtPathLength }, + { "RtlHandle", func_RtlHandle }, { "RtlImageRvaToVa", func_RtlImageRvaToVa }, { "RtlInitializeBitMap", func_RtlInitializeBitMap }, { "RtlIsNameLegalDOS8Dot3", func_RtlIsNameLegalDOS8Dot3 },