[NTDLL_APITEST] Add tests for RtlpEnsureBufferSize. CORE-11990
authorMark Jansen <mark.jansen@reactos.org>
Thu, 2 Mar 2017 20:38:58 +0000 (20:38 +0000)
committerMark Jansen <mark.jansen@reactos.org>
Thu, 2 Mar 2017 20:38:58 +0000 (20:38 +0000)
svn path=/trunk/; revision=74028

rostests/apitests/ntdll/CMakeLists.txt
rostests/apitests/ntdll/RtlpEnsureBufferSize.c [new file with mode: 0644]
rostests/apitests/ntdll/testlist.c

index dc80b5c..538261f 100644 (file)
@@ -43,6 +43,7 @@ list(APPEND SOURCE
     RtlInitializeBitMap.c
     RtlIsNameLegalDOS8Dot3.c
     RtlMemoryStream.c
     RtlInitializeBitMap.c
     RtlIsNameLegalDOS8Dot3.c
     RtlMemoryStream.c
+    RtlpEnsureBufferSize.c
     RtlReAllocateHeap.c
     RtlUpcaseUnicodeStringToCountedOemString.c
     StackOverflow.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 (file)
index 0000000..69bc5cf
--- /dev/null
@@ -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 <apitest.h>
+
+#define WIN32_NO_STATUS
+#include <ndk/rtlfuncs.h>
+#include <tlhelp32.h>
+
+#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);
+}
index 290e9ed..a830028 100644 (file)
@@ -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_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);
 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 },
     { "RtlInitializeBitMap",            func_RtlInitializeBitMap },
     { "RtlIsNameLegalDOS8Dot3",         func_RtlIsNameLegalDOS8Dot3 },
     { "RtlMemoryStream",                func_RtlMemoryStream },
+    { "RtlpEnsureBufferSize",           func_RtlpEnsureBufferSize },
     { "RtlReAllocateHeap",              func_RtlReAllocateHeap },
     { "RtlUpcaseUnicodeStringToCountedOemString", func_RtlUpcaseUnicodeStringToCountedOemString },
     { "StackOverflow",                  func_StackOverflow },
     { "RtlReAllocateHeap",              func_RtlReAllocateHeap },
     { "RtlUpcaseUnicodeStringToCountedOemString", func_RtlUpcaseUnicodeStringToCountedOemString },
     { "StackOverflow",                  func_StackOverflow },