From: Felix Münchhalfenjan.felix.muenchhalfen@rwth-aachen.de
--- dlls/kernelbase/tests/process.c | 71 +++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+)
diff --git a/dlls/kernelbase/tests/process.c b/dlls/kernelbase/tests/process.c index 88a527c45d5..fcfe250c895 100644 --- a/dlls/kernelbase/tests/process.c +++ b/dlls/kernelbase/tests/process.c @@ -38,6 +38,7 @@ static LPVOID (WINAPI *pMapViewOfFile3)(HANDLE, HANDLE, PVOID, ULONG64 offset, S static LPVOID (WINAPI *pVirtualAlloc2)(HANDLE, void *, SIZE_T, DWORD, DWORD, MEM_EXTENDED_PARAMETER *, ULONG); static LPVOID (WINAPI *pVirtualAlloc2FromApp)(HANDLE, void *, SIZE_T, DWORD, DWORD, MEM_EXTENDED_PARAMETER *, ULONG); static PVOID (WINAPI *pVirtualAllocFromApp)(PVOID, SIZE_T, DWORD, DWORD); +static BOOL (WINAPI *pVirtualFree)(LPVOID,SIZE_T,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); @@ -106,6 +107,16 @@ static void test_MapViewOfFile3(void) HANDLE file, mapping; void *ptr; BOOL ret; + SYSTEM_INFO si; + DWORD dError; + size_t szFile = 1024UL*1024; // 1M + HANDLE hFileMapping; + PVOID pAllocation; + PVOID pMapStart; + PVOID pMapStartOff; + PVOID pMapEnd; + BOOL bVirtualFree; + PVOID pMappedFileView;
if (!pMapViewOfFile3) { @@ -132,6 +143,65 @@ static void test_MapViewOfFile3(void) CloseHandle( file ); ret = DeleteFileA( testfile ); ok(ret, "Failed to delete a test file.\n"); + + // Tests for using MapViewOfFile3 together with MEM_RESERVE_PLACEHOLDER/MEM_REPLACE_PLACEHOLDER + // like self pe-loading programs do (e.g. .net pe-loader). + // With MEM_REPLACE_PLACEHOLDER, MapViewOfFile3/NtMapViewOfSection(Ex) shall relax alignment from 64k to pagesize + GetSystemInfo(&si); + hFileMapping = CreateFileMappingA(NULL, NULL, PAGE_READWRITE, 0, (DWORD)szFile, NULL); + ok(hFileMapping != NULL, "CreateFileMapping did not return a handle %lu\n", GetLastError()); + + pAllocation = pVirtualAlloc2(GetCurrentProcess(), NULL, szFile, MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, PAGE_NOACCESS, NULL, 0); + ok(pAllocation != NULL, "VirtualAlloc2 returned NULL %lu\n", GetLastError()); + + pMapStart = (void*)(((ULONG_PTR)pAllocation + si.dwPageSize) & ~(si.dwPageSize-1)); // advance forward one pagesize + align to pagesize + pMapEnd = (void*)((ULONG_PTR)pMapStart + si.dwPageSize); + bVirtualFree = pVirtualFree(pMapStart, si.dwPageSize, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER); // split the region, keep placeholders + ok(bVirtualFree, "VirtualFree failed to split the placeholder %lu\n", GetLastError()); + pMappedFileView = pMapViewOfFile3(hFileMapping, GetCurrentProcess(), pMapStart, si.dwPageSize, si.dwPageSize, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0); + // this should succeed, because pMapStart is pagesize aligned + ok(pMappedFileView != NULL, "MapViewOfFile3 did not map the FileMapping %lu\n", GetLastError()); + ok(pMappedFileView == pMapStart, "MapViewOfFile did not map to the requested addr\n"); + ok(UnmapViewOfFile( pMappedFileView ), "UnmapViewOfFile failed %lu\n", GetLastError()); + // this should fail, because pMapStart-1 is not pagesize aligned + pMapStartOff = (void*)((ULONG_PTR)pMapStart - 1); + pMappedFileView = pMapViewOfFile3(hFileMapping, GetCurrentProcess(), pMapStartOff, si.dwPageSize, si.dwPageSize, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0); + ok(pMappedFileView == NULL, "MapViewOfFile3 did map the FileMapping, though baseaddr was not pagesize aligned\n"); + dError = GetLastError(); + ok(dError == ERROR_MAPPED_ALIGNMENT, "MapViewOfFile3 did not return ERROR_MAPPED_ALIGNMENT(%u), instead it returned %lu\n", ERROR_MAPPED_ALIGNMENT, dError); + // this should fail, because offset=si.dwPageSize-1 is not pagesize aligned + pMappedFileView = pMapViewOfFile3(hFileMapping, GetCurrentProcess(), pMapStart, si.dwPageSize-1, si.dwPageSize, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0); + ok(pMappedFileView == NULL, "MapViewOfFile3 did map the FileMapping, though offset was not pagesize aligned\n"); + dError = GetLastError(); + ok(dError == ERROR_MAPPED_ALIGNMENT, "MapViewOfFile3 did not return ERROR_MAPPED_ALIGNMENT(%u), instead it returned %lu\n", ERROR_MAPPED_ALIGNMENT, dError); + // Free the space and then test mapping into the now-free space normally (without MEM_REPLACE_PLACEHOLDER) + bVirtualFree = pVirtualFree(pAllocation, 0, MEM_RELEASE); + ok(bVirtualFree, "VirtualFree of first remaining region failed\n"); + bVirtualFree = pVirtualFree(pMapEnd, 0, MEM_RELEASE); + ok(bVirtualFree, "VirtualFree of remaining region failed\n"); + // this should fail because we require 64k alignment for baseaddr, if MEM_REPLACE_PLACEHOLDER is not used + pMappedFileView = pMapViewOfFile3(hFileMapping, GetCurrentProcess(), pMapEnd, si.dwPageSize, 0, 0, PAGE_READWRITE, NULL, 0); + ok(pMappedFileView == NULL, "MapViewOfFile3 did map the FileMapping, though baseaddr was not 64k aligned\n"); + dError = GetLastError(); + ok(dError == ERROR_MAPPED_ALIGNMENT, "MapViewOfFile3 did not return ERROR_MAPPED_ALIGNMENT(%u), instead it returned %lu\n", ERROR_MAPPED_ALIGNMENT, dError); + // this should fail because we require 64k alignment for offset, if MEM_REPLACE_PLACEHOLDER is not used + pMapStart = (void*)(((ULONG_PTR)pAllocation + si.dwAllocationGranularity)&~(si.dwAllocationGranularity-1)); // align pMapStart to 64k + pMappedFileView = pMapViewOfFile3(hFileMapping, GetCurrentProcess(), pMapEnd, si.dwPageSize, si.dwPageSize, 0, PAGE_READWRITE, NULL, 0); + ok(pMappedFileView == NULL, "MapViewOfFile3 did map the FileMapping, though offset was not 64k aligned\n"); + dError = GetLastError(); + ok(dError == ERROR_MAPPED_ALIGNMENT, "MapViewOfFile3 did not return ERROR_MAPPED_ALIGNMENT(%u), instead it returned %lu\n", ERROR_MAPPED_ALIGNMENT, dError); + // this should succeed if MEM_REPLACE_PLACEHOLDER is not used, because both baseaddr and offset are 64k aligned + pMappedFileView = pMapViewOfFile3(hFileMapping, GetCurrentProcess(), pMapStart, 0, si.dwPageSize, 0, PAGE_READWRITE, NULL, 0); + ok(pMappedFileView != NULL, "MapViewOfFile3 failed though both baseaddr and offset were 64k aligned %lu\n", GetLastError()); + ok(pMappedFileView == pMapStart, "MapViewOfFile did not map to the requested addr\n"); + ok(UnmapViewOfFile( pMappedFileView ), "UnmapViewOfFile failed %lu\n", GetLastError()); + // this should succeed too if MEM_REPLACE_PLACEHOLDER is not used, if offset is aligned to 64k and != 0 + pMappedFileView = pMapViewOfFile3(hFileMapping, GetCurrentProcess(), pMapStart, 4*si.dwAllocationGranularity, si.dwPageSize, 0, PAGE_READWRITE, NULL, 0); + ok(pMappedFileView != NULL, "MapViewOfFile3 failed though both baseaddr and offset were 64k aligned %lu\n", GetLastError()); + ok(pMappedFileView == pMapStart, "MapViewOfFile did not map to the requested addr\n"); + ok(UnmapViewOfFile( pMappedFileView ), "UnmapViewOfFile failed %lu\n", GetLastError()); + // cleanup file mapping + ok(CloseHandle(hFileMapping), "CloseHandle failed on hFileMapping\n"); }
#define check_region_size(p, s) check_region_size_(p, s, __LINE__) @@ -519,6 +589,7 @@ static void init_funcs(void) X(VirtualAlloc2); X(VirtualAlloc2FromApp); X(VirtualAllocFromApp); + X(VirtualFree); X(UnmapViewOfFile2);
hmod = GetModuleHandleA("ntdll.dll");