kernel32: Test MapViewOfFile and NtMapViewOfSection side by side.
Dmitry Timoshkov
dmitry at baikal.ru
Mon Jan 16 07:50:35 CST 2012
---
dlls/kernel32/tests/virtual.c | 118 +++++++++++++++++++++++++++++++++++++----
1 files changed, 108 insertions(+), 10 deletions(-)
diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c
index 203a400..6a135c8 100644
--- a/dlls/kernel32/tests/virtual.c
+++ b/dlls/kernel32/tests/virtual.c
@@ -38,6 +38,8 @@ static BOOL (WINAPI *pVirtualFreeEx)(HANDLE, LPVOID, SIZE_T, DWORD);
static UINT (WINAPI *pGetWriteWatch)(DWORD,LPVOID,SIZE_T,LPVOID*,ULONG_PTR*,ULONG*);
static UINT (WINAPI *pResetWriteWatch)(LPVOID,SIZE_T);
static NTSTATUS (WINAPI *pNtAreMappedFilesTheSame)(PVOID,PVOID);
+static NTSTATUS (WINAPI *pNtMapViewOfSection)(HANDLE, HANDLE, PVOID *, ULONG, SIZE_T, const LARGE_INTEGER *, SIZE_T *, ULONG, ULONG, ULONG);
+static DWORD (WINAPI *pNtUnmapViewOfSection)(HANDLE, PVOID);
/* ############################### */
@@ -778,12 +780,6 @@ static void test_MapViewOfFile(void)
ok( VirtualFree(addr, 0, MEM_RELEASE), "VirtualFree failed\n" );
}
-static DWORD (WINAPI *pNtMapViewOfSection)( HANDLE handle, HANDLE process, PVOID *addr_ptr,
- ULONG zero_bits, SIZE_T commit_size,
- const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr,
- ULONG inherit, ULONG alloc_type, ULONG protect );
-static DWORD (WINAPI *pNtUnmapViewOfSection)( HANDLE process, PVOID addr );
-
static void test_NtMapViewOfSection(void)
{
HANDLE hProcess;
@@ -798,8 +794,6 @@ static void test_NtMapViewOfSection(void)
SIZE_T size, result;
LARGE_INTEGER offset;
- pNtMapViewOfSection = (void *)GetProcAddress( GetModuleHandle("ntdll.dll"), "NtMapViewOfSection" );
- pNtUnmapViewOfSection = (void *)GetProcAddress( GetModuleHandle("ntdll.dll"), "NtUnmapViewOfSection" );
if (!pNtMapViewOfSection || !pNtUnmapViewOfSection)
{
win_skip( "NtMapViewOfSection not available\n" );
@@ -1943,6 +1937,59 @@ static BOOL is_compatible_access(DWORD map_prot, DWORD view_prot)
return (view_prot & access) == view_prot;
}
+static void *map_view_of_file(HANDLE handle, DWORD access)
+{
+ NTSTATUS status;
+ LARGE_INTEGER offset;
+ SIZE_T count;
+ ULONG protect;
+ BOOL exec;
+ void *addr;
+
+ if (!pNtMapViewOfSection) return NULL;
+
+ count = 0;
+ offset.u.LowPart = 0;
+ offset.u.HighPart = 0;
+
+ exec = access & FILE_MAP_EXECUTE;
+ access &= ~FILE_MAP_EXECUTE;
+
+ if (access == FILE_MAP_COPY)
+ {
+ if (exec)
+ protect = PAGE_EXECUTE_WRITECOPY;
+ else
+ protect = PAGE_WRITECOPY;
+ }
+ else if (access & FILE_MAP_WRITE)
+ {
+ if (exec)
+ protect = PAGE_EXECUTE_READWRITE;
+ else
+ protect = PAGE_READWRITE;
+ }
+ else if (access & FILE_MAP_READ)
+ {
+ if (exec)
+ protect = PAGE_EXECUTE_READ;
+ else
+ protect = PAGE_READONLY;
+ }
+ else protect = PAGE_NOACCESS;
+
+ addr = NULL;
+ status = pNtMapViewOfSection(handle, GetCurrentProcess(), &addr, 0, 0, &offset,
+ &count, 1 /* ViewShare */, 0, protect);
+ if (status)
+ {
+ /* for simplicity */
+ SetLastError(ERROR_ACCESS_DENIED);
+ addr = NULL;
+ }
+ return addr;
+}
+
static void test_mapping(void)
{
static const DWORD page_prot[] =
@@ -1988,13 +2035,13 @@ static void test_mapping(void)
{ FILE_MAP_EXECUTE | SECTION_MAP_EXECUTE | FILE_MAP_READ | FILE_MAP_WRITE, PAGE_EXECUTE_READWRITE }, /* 0x2e */
{ FILE_MAP_EXECUTE | SECTION_MAP_EXECUTE | FILE_MAP_READ | FILE_MAP_WRITE | FILE_MAP_COPY, PAGE_EXECUTE_READWRITE } /* 0x2f */
};
- void *base;
+ void *base, *nt_base;
DWORD i, j, k, ret, old_prot, prev_prot;
SYSTEM_INFO si;
char temp_path[MAX_PATH];
char file_name[MAX_PATH];
HANDLE hfile, hmap;
- MEMORY_BASIC_INFORMATION info;
+ MEMORY_BASIC_INFORMATION info, nt_info;
GetSystemInfo(&si);
trace("system page size %#x\n", si.dwPageSize);
@@ -2053,9 +2100,30 @@ static void test_mapping(void)
for (j = 0; j < sizeof(view)/sizeof(view[0]); j++)
{
+ nt_base = map_view_of_file(hmap, view[j].access);
+ if (nt_base)
+ {
+ SetLastError(0xdeadbeef);
+ ret = VirtualQuery(nt_base, &nt_info, sizeof(nt_info));
+ ok(ret, "%d: VirtualQuery failed %d\n", j, GetLastError());
+ UnmapViewOfFile(nt_base);
+ }
+
SetLastError(0xdeadbeef);
base = MapViewOfFile(hmap, view[j].access, 0, 0, 0);
+ /* FIXME: completely remove the condition below once Wine is fixed */
+ if (!nt_base != !base)
+ todo_wine
+ /* Vista+ supports FILE_MAP_EXECUTE properly, earlier versions don't */
+ ok(!nt_base == !base ||
+ broken((view[j].access & FILE_MAP_EXECUTE) && !nt_base != !base),
+ "%d: (%04x/%04x) NT %p kernel %p\n", j, page_prot[i], view[j].access, nt_base, base);
+ else
+ ok(!nt_base == !base ||
+ broken((view[j].access & FILE_MAP_EXECUTE) && !nt_base != !base),
+ "%d: (%04x/%04x) NT %p kernel %p\n", j, page_prot[i], view[j].access, nt_base, base);
+
if (!is_compatible_access(page_prot[i], view[j].access))
{
ok(!base, "%d: MapViewOfFile(%04x/%04x) should fail\n", j, page_prot[i], view[j].access);
@@ -2096,6 +2164,33 @@ static void test_mapping(void)
ok(info.State == MEM_COMMIT, "%d: (%04x) got %#x, expected MEM_COMMIT\n", j, view[j].access, info.State);
ok(info.Type == MEM_MAPPED, "%d: (%04x) got %#x, expected MEM_MAPPED\n", j, view[j].access, info.Type);
+ if (nt_base && base)
+ {
+ ok(nt_info.RegionSize == info.RegionSize, "%d: (%04x) got %#lx != expected %#lx\n", j, view[j].access, nt_info.RegionSize, info.RegionSize);
+ /* FIXME: completely remove the condition below once Wine is fixed */
+ if (nt_info.Protect != info.Protect)
+ todo_wine
+ ok(nt_info.Protect == info.Protect /* Vista+ */ ||
+ broken(nt_info.AllocationProtect == PAGE_EXECUTE_WRITECOPY && info.Protect == PAGE_NOACCESS), /* XP */
+ "%d: (%04x) got %#x, expected %#x\n", j, view[j].access, nt_info.Protect, info.Protect);
+ else
+ ok(nt_info.Protect == info.Protect /* Vista+ */ ||
+ broken(nt_info.AllocationProtect == PAGE_EXECUTE_WRITECOPY && info.Protect == PAGE_NOACCESS), /* XP */
+ "%d: (%04x) got %#x, expected %#x\n", j, view[j].access, nt_info.Protect, info.Protect);
+ /* FIXME: completely remove the condition below once Wine is fixed */
+ if (nt_info.AllocationProtect != info.AllocationProtect)
+ todo_wine
+ ok(nt_info.AllocationProtect == info.AllocationProtect /* Vista+ */ ||
+ broken(nt_info.AllocationProtect == PAGE_EXECUTE_WRITECOPY && info.Protect == PAGE_NOACCESS), /* XP */
+ "%d: (%04x) got %#x, expected %#x\n", j, view[j].access, nt_info.AllocationProtect, info.AllocationProtect);
+ else
+ ok(nt_info.AllocationProtect == info.AllocationProtect /* Vista+ */ ||
+ broken(nt_info.AllocationProtect == PAGE_EXECUTE_WRITECOPY && info.Protect == PAGE_NOACCESS), /* XP */
+ "%d: (%04x) got %#x, expected %#x\n", j, view[j].access, nt_info.AllocationProtect, info.AllocationProtect);
+ ok(nt_info.State == info.State, "%d: (%04x) got %#x, expected %#x\n", j, view[j].access, nt_info.State, info.State);
+ ok(nt_info.Type == info.Type, "%d: (%04x) got %#x, expected %#x\n", j, view[j].access, nt_info.Type, info.Type);
+ }
+
prev_prot = info.Protect;
for (k = 0; k < sizeof(page_prot)/sizeof(page_prot[0]); k++)
@@ -2197,6 +2292,9 @@ START_TEST(virtual)
pResetWriteWatch = (void *) GetProcAddress(hkernel32, "ResetWriteWatch");
pNtAreMappedFilesTheSame = (void *)GetProcAddress( GetModuleHandle("ntdll.dll"),
"NtAreMappedFilesTheSame" );
+ pNtMapViewOfSection = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtMapViewOfSection");
+ pNtUnmapViewOfSection = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtUnmapViewOfSection");
+
test_mapping();
test_CreateFileMapping_protection();
test_VirtualAlloc_protection();
--
1.7.7.4
More information about the wine-patches
mailing list