kernelbase/tests: Add tests for MEM_PRESERVE_PLACEHOLDER with UnmapViewOfFile2().

This commit is contained in:
Paul Gofman 2023-05-25 21:08:45 -06:00 committed by Alexandre Julliard
parent cd8f0fbac8
commit 4806b1c226
2 changed files with 63 additions and 3 deletions

View file

@ -41,6 +41,7 @@ static PVOID (WINAPI *pVirtualAllocFromApp)(PVOID, SIZE_T, DWORD, DWORD);
static HANDLE (WINAPI *pOpenFileMappingFromApp)( ULONG, BOOL, LPCWSTR);
static HANDLE (WINAPI *pCreateFileMappingFromApp)(HANDLE, PSECURITY_ATTRIBUTES, ULONG, ULONG64, PCWSTR);
static LPVOID (WINAPI *pMapViewOfFileFromApp)(HANDLE, ULONG, ULONG64, SIZE_T);
static BOOL (WINAPI *pUnmapViewOfFile2)(HANDLE, void *, ULONG);
static void test_CompareObjectHandles(void)
{
@ -166,6 +167,13 @@ static void test_VirtualAlloc2(void)
ret = VirtualFree(addr, 0, MEM_RELEASE);
ok(ret, "Unexpected return value %d, error %lu.\n", ret, GetLastError());
placeholder1 = pVirtualAlloc2(NULL, NULL, 2 * size, MEM_RESERVE, PAGE_NOACCESS, NULL, 0);
ok(!!placeholder1, "Failed to create a placeholder range.\n");
ret = VirtualFree(placeholder1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got ret %d, error %lu.\n", ret, GetLastError());
ret = VirtualFree(placeholder1, 0, MEM_RELEASE);
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);
ok(!!placeholder1, "Failed to create a placeholder range.\n");
@ -198,11 +206,20 @@ static void test_VirtualAlloc2(void)
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);
view1 = pMapViewOfFile3(section, NULL, NULL, 0, size, 0, PAGE_READWRITE, NULL, 0);
ok(!!view1, "Failed to map a section.\n");
ret = VirtualFree( view1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER );
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "Got ret %d, error %lu.\n", ret, GetLastError());
ret = pUnmapViewOfFile2(GetCurrentProcess(), view1, MEM_PRESERVE_PLACEHOLDER);
todo_wine ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got ret %d, error %lu.\n", ret, GetLastError());
ret = pUnmapViewOfFile2(GetCurrentProcess(), view1, 0);
todo_wine ok(ret, "Got error %lu.\n", GetLastError());
view1 = pMapViewOfFile3(section, NULL, placeholder1, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0);
ok(view1 == placeholder1, "Address does not match.\n");
view2 = pMapViewOfFile3(section, NULL, placeholder2, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0);
ok(!!view2, "Failed to map a section.\n");
ok(view2 == placeholder2, "Address does not match.\n");
memset(&info, 0, sizeof(info));
VirtualQuery(placeholder1, &info, sizeof(info));
@ -218,8 +235,47 @@ static void test_VirtualAlloc2(void)
ok(info.Type == MEM_MAPPED, "Unexpected type %#lx.\n", info.Type);
ok(info.RegionSize == size, "Unexpected size.\n");
ret = pUnmapViewOfFile2(NULL, view1, MEM_PRESERVE_PLACEHOLDER);
ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "Got error %lu.\n", GetLastError());
ret = VirtualFree( placeholder1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER );
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "Got ret %d, error %lu.\n", ret, GetLastError());
ret = pUnmapViewOfFile2(GetCurrentProcess(), view1, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
todo_wine ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "Got ret %d, error %lu.\n", ret, GetLastError());
ret = pUnmapViewOfFile2(GetCurrentProcess(), view1, MEM_PRESERVE_PLACEHOLDER);
todo_wine ok(ret, "Got error %lu.\n", GetLastError());
memset(&info, 0, sizeof(info));
VirtualQuery(placeholder1, &info, sizeof(info));
todo_wine ok(info.AllocationProtect == PAGE_NOACCESS, "Unexpected protection %#lx.\n", info.AllocationProtect);
todo_wine ok(info.State == MEM_RESERVE, "Unexpected state %#lx.\n", info.State);
todo_wine ok(info.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", info.Type);
ok(info.RegionSize == size, "Unexpected size.\n");
ret = pUnmapViewOfFile2(GetCurrentProcess(), view1, MEM_PRESERVE_PLACEHOLDER);
ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got error %lu.\n", GetLastError());
ret = UnmapViewOfFile(view1);
ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got error %lu.\n", GetLastError());
view1 = pMapViewOfFile3(section, NULL, placeholder1, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0);
todo_wine ok(view1 == placeholder1, "Address does not match.\n");
CloseHandle(section);
UnmapViewOfFile(view1);
ret = VirtualFree( view1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER );
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "Got ret %d, error %lu.\n", ret, GetLastError());
ret = pUnmapViewOfFile2(GetCurrentProcess(), view1, MEM_UNMAP_WITH_TRANSIENT_BOOST | MEM_PRESERVE_PLACEHOLDER);
todo_wine ok(ret, "Got error %lu.\n", GetLastError());
ret = VirtualFree( placeholder1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER );
ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got ret %d, error %lu.\n", ret, GetLastError());
ret = VirtualFreeEx(GetCurrentProcess(), placeholder1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER );
ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got ret %d, error %lu.\n", ret, GetLastError());
ret = VirtualFree(placeholder1, 0, MEM_RELEASE);
todo_wine ok(ret, "Got error %lu.\n", GetLastError());
UnmapViewOfFile(view2);
VirtualFree(placeholder1, 0, MEM_RELEASE);
@ -249,6 +305,8 @@ static void test_VirtualAlloc2(void)
p1 = p;
p2 = p + size / 2;
ret = VirtualFree(p1, 0, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "Got ret %d, error %lu.\n", ret, GetLastError());
ret = VirtualFree(p1, size / 2, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
ok(ret, "Failed to split a placeholder.\n");
check_region_size(p1, size / 2);
@ -461,6 +519,7 @@ static void init_funcs(void)
X(VirtualAlloc2);
X(VirtualAlloc2FromApp);
X(VirtualAllocFromApp);
X(UnmapViewOfFile2);
hmod = GetModuleHandleA("ntdll.dll");

View file

@ -837,6 +837,7 @@ typedef struct DECLSPEC_ALIGN(8) MEM_EXTENDED_PARAMETER {
#define MEM_PRESERVE_PLACEHOLDER 0x00000002
#define MEM_DECOMMIT 0x00004000
#define MEM_RELEASE 0x00008000
#define MEM_UNMAP_WITH_TRANSIENT_BOOST 0x00000001
#define MEM_FREE 0x00010000
#define MEM_PRIVATE 0x00020000