From 4617ea0c823000ae6ec82a21a70ca29427714c14 Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Thu, 2 Mar 2017 20:38:58 +0000 Subject: [PATCH] [NTDLL_APITEST] Add tests for RtlpEnsureBufferSize. CORE-11990 svn path=/trunk/; revision=74028 --- rostests/apitests/ntdll/CMakeLists.txt | 1 + .../apitests/ntdll/RtlpEnsureBufferSize.c | 196 ++++++++++++++++++ rostests/apitests/ntdll/testlist.c | 2 + 3 files changed, 199 insertions(+) create mode 100644 rostests/apitests/ntdll/RtlpEnsureBufferSize.c diff --git a/rostests/apitests/ntdll/CMakeLists.txt b/rostests/apitests/ntdll/CMakeLists.txt index dc80b5c436e..538261f0240 100644 --- a/rostests/apitests/ntdll/CMakeLists.txt +++ b/rostests/apitests/ntdll/CMakeLists.txt @@ -43,6 +43,7 @@ list(APPEND SOURCE RtlInitializeBitMap.c RtlIsNameLegalDOS8Dot3.c RtlMemoryStream.c + RtlpEnsureBufferSize.c RtlReAllocateHeap.c RtlUpcaseUnicodeStringToCountedOemString.c StackOverflow.c diff --git a/rostests/apitests/ntdll/RtlpEnsureBufferSize.c b/rostests/apitests/ntdll/RtlpEnsureBufferSize.c new file mode 100644 index 00000000000..69bc5cfe3e8 --- /dev/null +++ b/rostests/apitests/ntdll/RtlpEnsureBufferSize.c @@ -0,0 +1,196 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Test for RtlpEnsureBufferSize + * PROGRAMMER: Mark Jansen + */ + +#include + +#define WIN32_NO_STATUS +#include +#include + +#ifndef RtlInitBuffer +#define RtlInitBuffer(RtlBuf, StaticData, StaticDataSize) \ + do { \ + (RtlBuf)->Buffer = (RtlBuf)->StaticBuffer = (PUCHAR)StaticData; \ + (RtlBuf)->Size = (RtlBuf)->StaticSize = StaticDataSize; \ + (RtlBuf)->ReservedForAllocatedSize = 0; \ + (RtlBuf)->ReservedForIMalloc = NULL; \ + } while (0) +#endif + +#ifndef RtlFreeBuffer +#define RtlFreeBuffer(RtlBuf) \ + do { \ + if ((RtlBuf)->Buffer != (RtlBuf)->StaticBuffer && (RtlBuf)->Buffer) \ + RtlFreeHeap(RtlGetProcessHeap(), 0, (RtlBuf)->Buffer); \ + (RtlBuf)->Buffer = (RtlBuf)->StaticBuffer; \ + (RtlBuf)->Size = (RtlBuf)->StaticSize; \ + } while (0) +#endif + +#ifndef RTL_SKIP_BUFFER_COPY +#define RTL_SKIP_BUFFER_COPY 0x00000001 +#endif + +NTSTATUS (NTAPI *pRtlpEnsureBufferSize)(_In_ ULONG Flags, _Inout_ PRTL_BUFFER Buffer, _In_ SIZE_T RequiredSize); + + +static BOOL IsBlockFromHeap(HANDLE hHeap, PVOID ptr) +{ + /* Use when this is implemented */ +#if 0 + PROCESS_HEAP_ENTRY Entry; + BOOL ret = FALSE; + if (!HeapLock(hHeap)) + { + skip("Unable to lock heap\n"); + return FALSE; + } + + Entry.lpData = NULL; + while (!ret && HeapWalk(hHeap, &Entry)) + { + if ((Entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) && + (Entry.lpData == ptr)) + { + ret = TRUE; + } + } + + HeapUnlock(hHeap); + return ret; +#else + HEAPENTRY32 he; + BOOL ret = FALSE; + HANDLE hHeapSnap = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, GetCurrentProcessId()); + + if (hHeapSnap == INVALID_HANDLE_VALUE) + return FALSE; + + he.dwSize = sizeof(he); + + if (Heap32First(&he, GetCurrentProcessId(), (DWORD)hHeap)) + { + do { + if ((DWORD)ptr >= he.dwAddress && (DWORD)ptr <= (he.dwAddress + he.dwBlockSize)) + ret = TRUE; + } while (!ret && Heap32Next(&he)); + } + + CloseHandle(hHeapSnap); + + return ret; +#endif +} + + +START_TEST(RtlpEnsureBufferSize) +{ + RTL_BUFFER Buffer = { 0 }; + ULONG Flag; + UCHAR StaticBuf[4]; + PVOID tmp; + BOOL SkipHeapCheck; + + HMODULE mod = GetModuleHandleW(L"ntdll.dll"); + pRtlpEnsureBufferSize = (void *)GetProcAddress(mod, "RtlpEnsureBufferSize"); + + if (!pRtlpEnsureBufferSize) + { + skip("No RtlpEnsureBufferSize\n"); + return; + } + + memset(StaticBuf, 0xba, sizeof(StaticBuf)); + RtlInitBuffer(&Buffer, StaticBuf, sizeof(StaticBuf)); + + /* NULL buffer yields a failure */ + ok_ntstatus(pRtlpEnsureBufferSize(0, NULL, 0), STATUS_INVALID_PARAMETER); + + /* All flags other than '1' yield a failure */ + for (Flag = 2; Flag; Flag <<= 1) + { + ok_ntstatus(pRtlpEnsureBufferSize(Flag, &Buffer, 0), STATUS_INVALID_PARAMETER); + ok_ptr(Buffer.Buffer, Buffer.StaticBuffer); + ok_int(Buffer.Size, Buffer.StaticSize); + ok_ptr(Buffer.StaticBuffer, StaticBuf); + ok_int(Buffer.StaticSize, sizeof(StaticBuf)); + RtlFreeBuffer(&Buffer); + } + + ok_ntstatus(pRtlpEnsureBufferSize(0, &Buffer, 0), STATUS_SUCCESS); + ok_ptr(Buffer.Buffer, Buffer.StaticBuffer); + ok_int(Buffer.Size, Buffer.StaticSize); + ok_ptr(Buffer.StaticBuffer, StaticBuf); + ok_int(Buffer.StaticSize, sizeof(StaticBuf)); + RtlFreeBuffer(&Buffer); + + ok_ntstatus(pRtlpEnsureBufferSize(0, &Buffer, 1), STATUS_SUCCESS); + ok_ptr(Buffer.Buffer, Buffer.StaticBuffer); + ok_int(Buffer.Size, Buffer.StaticSize); + ok_ptr(Buffer.StaticBuffer, StaticBuf); + ok_int(Buffer.StaticSize, sizeof(StaticBuf)); + RtlFreeBuffer(&Buffer); + + ok_ntstatus(pRtlpEnsureBufferSize(0, &Buffer, 2), STATUS_SUCCESS); + ok_ptr(Buffer.Buffer, Buffer.StaticBuffer); + ok_int(Buffer.Size, Buffer.StaticSize); + ok_ptr(Buffer.StaticBuffer, StaticBuf); + ok_int(Buffer.StaticSize, sizeof(StaticBuf)); + RtlFreeBuffer(&Buffer); + + ok_ntstatus(pRtlpEnsureBufferSize(0, &Buffer, 3), STATUS_SUCCESS); + ok_ptr(Buffer.Buffer, Buffer.StaticBuffer); + ok_int(Buffer.Size, Buffer.StaticSize); + ok_ptr(Buffer.StaticBuffer, StaticBuf); + ok_int(Buffer.StaticSize, sizeof(StaticBuf)); + RtlFreeBuffer(&Buffer); + + ok_ntstatus(pRtlpEnsureBufferSize(0, &Buffer, 4), STATUS_SUCCESS); + ok_ptr(Buffer.Buffer, Buffer.StaticBuffer); + ok_int(Buffer.Size, Buffer.StaticSize); + ok_ptr(Buffer.StaticBuffer, StaticBuf); + ok_int(Buffer.StaticSize, sizeof(StaticBuf)); + RtlFreeBuffer(&Buffer); + + /* Check that IsBlockFromHeap works! */ + tmp = RtlAllocateHeap(RtlGetProcessHeap(), 0, 5); + SkipHeapCheck = (IsBlockFromHeap(RtlGetProcessHeap(), StaticBuf) != FALSE) || + (IsBlockFromHeap(RtlGetProcessHeap(), tmp) != TRUE); + RtlFreeHeap(RtlGetProcessHeap(), 0, tmp); + + if (SkipHeapCheck) + skip("Unable to verify the heap used\n"); + + /* Allocated is exactly what is asked for, not rounded to nearest whatever */ + ok_ntstatus(pRtlpEnsureBufferSize(0, &Buffer, 5), STATUS_SUCCESS); + if (!SkipHeapCheck) + ok_int(IsBlockFromHeap(RtlGetProcessHeap(), Buffer.Buffer), TRUE); + ok(!memcmp(Buffer.Buffer, StaticBuf, sizeof(StaticBuf)), "Expected First 4 bytes to be the same!\n"); + ok_int(Buffer.Size, 5); + ok_ptr(Buffer.StaticBuffer, StaticBuf); + ok_int(Buffer.StaticSize, sizeof(StaticBuf)); + RtlFreeBuffer(&Buffer); + + ok_ntstatus(pRtlpEnsureBufferSize(RTL_SKIP_BUFFER_COPY, &Buffer, 5), STATUS_SUCCESS); + if (!SkipHeapCheck) + ok_int(IsBlockFromHeap(RtlGetProcessHeap(), Buffer.Buffer), TRUE); + ok(memcmp(Buffer.Buffer, StaticBuf, sizeof(StaticBuf)), "Expected First 4 bytes to be different!\n"); + ok_int(Buffer.Size, 5); + ok_ptr(Buffer.StaticBuffer, StaticBuf); + ok_int(Buffer.StaticSize, sizeof(StaticBuf)); + RtlFreeBuffer(&Buffer); + + /* Size is not limited to UNICODE_STRING sizes */ + ok_ntstatus(pRtlpEnsureBufferSize(RTL_SKIP_BUFFER_COPY, &Buffer, UNICODE_STRING_MAX_BYTES + 1), STATUS_SUCCESS); + if (!SkipHeapCheck) + ok_int(IsBlockFromHeap(RtlGetProcessHeap(), Buffer.Buffer), TRUE); + ok(memcmp(Buffer.Buffer, StaticBuf, sizeof(StaticBuf)), "Expected First 4 bytes to be different!\n"); + ok_int(Buffer.Size, UNICODE_STRING_MAX_BYTES + 1); + ok_ptr(Buffer.StaticBuffer, StaticBuf); + ok_int(Buffer.StaticSize, sizeof(StaticBuf)); + RtlFreeBuffer(&Buffer); +} diff --git a/rostests/apitests/ntdll/testlist.c b/rostests/apitests/ntdll/testlist.c index 290e9ed9f77..a8300288e35 100644 --- a/rostests/apitests/ntdll/testlist.c +++ b/rostests/apitests/ntdll/testlist.c @@ -47,6 +47,7 @@ extern void func_RtlImageRvaToVa(void); extern void func_RtlInitializeBitMap(void); extern void func_RtlIsNameLegalDOS8Dot3(void); extern void func_RtlMemoryStream(void); +extern void func_RtlpEnsureBufferSize(void); extern void func_RtlReAllocateHeap(void); extern void func_RtlUpcaseUnicodeStringToCountedOemString(void); extern void func_StackOverflow(void); @@ -98,6 +99,7 @@ const struct test winetest_testlist[] = { "RtlInitializeBitMap", func_RtlInitializeBitMap }, { "RtlIsNameLegalDOS8Dot3", func_RtlIsNameLegalDOS8Dot3 }, { "RtlMemoryStream", func_RtlMemoryStream }, + { "RtlpEnsureBufferSize", func_RtlpEnsureBufferSize }, { "RtlReAllocateHeap", func_RtlReAllocateHeap }, { "RtlUpcaseUnicodeStringToCountedOemString", func_RtlUpcaseUnicodeStringToCountedOemString }, { "StackOverflow", func_StackOverflow }, -- 2.17.1