diff --git a/dlls/kernelbase/tests/process.c b/dlls/kernelbase/tests/process.c index e5185a2587d..7c6544f6dd9 100644 --- a/dlls/kernelbase/tests/process.c +++ b/dlls/kernelbase/tests/process.c @@ -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"); diff --git a/include/winnt.h b/include/winnt.h index 1a7f65776a7..0117100a921 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -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