From 30f1777e87c2bbb27094048eab3805e39d5f9214 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Fri, 20 May 2022 09:36:52 +0300 Subject: [PATCH] kernelbase/tests: Add some VirtualAlloc2() tests. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/kernelbase/tests/process.c | 73 +++++++++++++++++++++++++++++++++ include/winnt.h | 23 +++++++---- 2 files changed, 88 insertions(+), 8 deletions(-) diff --git a/dlls/kernelbase/tests/process.c b/dlls/kernelbase/tests/process.c index bacf9057836..52c481a59e8 100644 --- a/dlls/kernelbase/tests/process.c +++ b/dlls/kernelbase/tests/process.c @@ -33,6 +33,7 @@ static BOOL (WINAPI *pCompareObjectHandles)(HANDLE, HANDLE); static LPVOID (WINAPI *pMapViewOfFile3)(HANDLE, HANDLE, PVOID, ULONG64 offset, SIZE_T size, ULONG, ULONG, MEM_EXTENDED_PARAMETER *, ULONG); +static LPVOID (WINAPI *pVirtualAlloc2)(HANDLE, void *, SIZE_T, DWORD, DWORD, MEM_EXTENDED_PARAMETER *, ULONG); static void test_CompareObjectHandles(void) { @@ -125,6 +126,76 @@ static void test_MapViewOfFile3(void) ok(ret, "Failed to delete a test file.\n"); } +static void test_VirtualAlloc2(void) +{ + void *placeholder1, *placeholder2, *view1, *view2, *addr; + MEMORY_BASIC_INFORMATION info; + HANDLE section; + SIZE_T size; + BOOL ret; + + if (!pVirtualAlloc2) + { + win_skip("VirtualAlloc2() is not supported.\n"); + return; + } + + size = 0x80000; + addr = pVirtualAlloc2(NULL, NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE, NULL, 0); + todo_wine + ok(!!addr, "Failed to allocate, error %lu.\n", GetLastError()); + ret = VirtualFree(addr, 0, MEM_RELEASE); + todo_wine + ok(ret, "Unexpected return value %d, error %lu.\n", ret, GetLastError()); + + /* Placeholder splitting functionality */ + placeholder1 = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE_PLACEHOLDER | MEM_RESERVE, PAGE_NOACCESS, NULL, 0); + todo_wine + ok(!!placeholder1, "Failed to create a placeholder range.\n"); + if (!placeholder1) return; + + memset(&info, 0, sizeof(info)); + VirtualQuery(placeholder1, &info, sizeof(info)); + ok(info.AllocationProtect == PAGE_NOACCESS, "Unexpected protection %#lx.\n", info.AllocationProtect); + ok(info.State == MEM_RESERVE, "Unexpected state %#lx.\n", info.State); + ok(info.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", info.Type); + ok(info.RegionSize == 2 * size, "Unexpected size.\n"); + + ret = VirtualFree(placeholder1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); + ok(ret, "Failed to split placeholder.\n"); + + memset(&info, 0, sizeof(info)); + VirtualQuery(placeholder1, &info, sizeof(info)); + ok(info.AllocationProtect == PAGE_NOACCESS, "Unexpected protection %#lx.\n", info.AllocationProtect); + ok(info.State == MEM_RESERVE, "Unexpected state %#lx.\n", info.State); + ok(info.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", info.Type); + ok(info.RegionSize == size, "Unexpected size.\n"); + + placeholder2 = (void *)((BYTE *)placeholder1 + size); + memset(&info, 0, sizeof(info)); + VirtualQuery(placeholder2, &info, sizeof(info)); + ok(info.AllocationProtect == PAGE_NOACCESS, "Unexpected protection %#lx.\n", info.AllocationProtect); + ok(info.State == MEM_RESERVE, "Unexpected state %#lx.\n", info.State); + ok(info.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", info.Type); + ok(info.RegionSize == size, "Unexpected size.\n"); + + section = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, NULL); + ok(!!section, "Failed to create a section.\n"); + + view1 = pMapViewOfFile3(section, NULL, placeholder1, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0); + ok(!!view1, "Failed to map a section.\n"); + + view2 = pMapViewOfFile3(section, NULL, placeholder2, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0); + ok(!!view2, "Failed to map a section.\n"); + + CloseHandle(section); + UnmapViewOfFile(view1); + UnmapViewOfFile(view2); + + VirtualFree(placeholder1, 0, MEM_RELEASE); + VirtualFree(placeholder2, 0, MEM_RELEASE); +} + START_TEST(process) { HMODULE hmod; @@ -136,7 +207,9 @@ START_TEST(process) hmod = GetModuleHandleA("kernelbase.dll"); pCompareObjectHandles = (void *)GetProcAddress(hmod, "CompareObjectHandles"); pMapViewOfFile3 = (void *)GetProcAddress(hmod, "MapViewOfFile3"); + pVirtualAlloc2 = (void *)GetProcAddress(hmod, "VirtualAlloc2"); test_CompareObjectHandles(); test_MapViewOfFile3(); + test_VirtualAlloc2(); } diff --git a/include/winnt.h b/include/winnt.h index 5ca106d1031..7aafbcf0cfe 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -806,18 +806,25 @@ typedef struct _WIN32_MEMORY_RANGE_ENTRY #define PAGE_NOCACHE 0x200 #define PAGE_WRITECOMBINE 0x400 -#define MEM_COMMIT 0x00001000 -#define MEM_RESERVE 0x00002000 -#define MEM_DECOMMIT 0x00004000 -#define MEM_RELEASE 0x00008000 +#define MEM_COMMIT 0x00001000 +#define MEM_RESERVE 0x00002000 +#define MEM_REPLACE_PLACEHOLDER 0x00004000 +#define MEM_RESERVE_PLACEHOLDER 0x00040000 +#define MEM_RESET 0x00080000 +#define MEM_TOP_DOWN 0x00100000 +#define MEM_PHYSICAL 0x00400000 +#define MEM_RESET_UNDO 0x10000000 +#define MEM_LARGE_PAGES 0x20000000 + +#define MEM_COALESCE_PLACEHOLDERS 0x00000001 +#define MEM_PRESERVE_PLACEHOLDER 0x00000002 +#define MEM_DECOMMIT 0x00004000 +#define MEM_RELEASE 0x00008000 + #define MEM_FREE 0x00010000 #define MEM_PRIVATE 0x00020000 #define MEM_MAPPED 0x00040000 -#define MEM_RESET 0x00080000 -#define MEM_TOP_DOWN 0x00100000 #define MEM_WRITE_WATCH 0x00200000 -#define MEM_PHYSICAL 0x00400000 -#define MEM_LARGE_PAGES 0x20000000 #define MEM_4MB_PAGES 0x80000000 #define SEC_FILE 0x00800000