kernel32: Fix access flags to page protection mapping in MapViewOfFileEx.
Dmitry Timoshkov
dmitry at baikal.ru
Mon Jan 16 23:43:36 CST 2012
---
dlls/kernel32/tests/virtual.c | 34 +++-------------------------------
dlls/kernel32/virtual.c | 14 ++++++++++----
dlls/ntdll/virtual.c | 2 +-
3 files changed, 14 insertions(+), 36 deletions(-)
diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c
index 6a135c8..eb213a6 100644
--- a/dlls/kernel32/tests/virtual.c
+++ b/dlls/kernel32/tests/virtual.c
@@ -419,6 +419,7 @@ static void test_MapViewOfFile(void)
ret = DuplicateHandle( GetCurrentProcess(), mapping, GetCurrentProcess(), &map2,
FILE_MAP_READ, FALSE, 0 );
ok( ret, "DuplicateHandle failed error %u\n", GetLastError());
+ SetLastError(0xdeadbeef);
ptr = MapViewOfFile( map2, FILE_MAP_WRITE, 0, 0, 4096 );
if (!ptr)
{
@@ -426,6 +427,7 @@ static void test_MapViewOfFile(void)
CloseHandle( map2 );
ret = DuplicateHandle( GetCurrentProcess(), mapping, GetCurrentProcess(), &map2, 0, FALSE, 0 );
ok( ret, "DuplicateHandle failed error %u\n", GetLastError());
+ SetLastError(0xdeadbeef);
ptr = MapViewOfFile( map2, 0, 0, 0, 4096 );
ok( !ptr, "MapViewOfFile succeeded\n" );
ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
@@ -1933,7 +1935,7 @@ static DWORD map_prot_to_access(DWORD prot)
static BOOL is_compatible_access(DWORD map_prot, DWORD view_prot)
{
DWORD access = map_prot_to_access(map_prot);
- if (!access) return FALSE;
+ if (!view_prot) view_prot = SECTION_MAP_READ;
return (view_prot & access) == view_prot;
}
@@ -2112,17 +2114,10 @@ static void test_mapping(void)
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))
{
@@ -2145,15 +2140,6 @@ static void test_mapping(void)
ok(ret, "%d: VirtualQuery failed %d\n", j, GetLastError());
ok(info.BaseAddress == base, "%d: (%04x) got %p, expected %p\n", j, view[j].access, info.BaseAddress, base);
ok(info.RegionSize == si.dwPageSize, "%d: (%04x) got %#lx != expected %#x\n", j, view[j].access, info.RegionSize, si.dwPageSize);
- /* FIXME: completely remove the condition below once Wine is fixed */
- if (info.Protect != view[j].prot)
- todo_wine
- ok(info.Protect == view[j].prot ||
- broken(view[j].prot == PAGE_EXECUTE_READ && info.Protect == PAGE_READONLY) || /* win2k */
- broken(view[j].prot == PAGE_EXECUTE_READWRITE && info.Protect == PAGE_READWRITE) || /* win2k */
- broken(view[j].prot == PAGE_EXECUTE_WRITECOPY && info.Protect == PAGE_NOACCESS), /* XP */
- "%d: (%04x) got %#x, expected %#x\n", j, view[j].access, info.Protect, view[j].prot);
- else
ok(info.Protect == view[j].prot ||
broken(view[j].prot == PAGE_EXECUTE_READ && info.Protect == PAGE_READONLY) || /* win2k */
broken(view[j].prot == PAGE_EXECUTE_READWRITE && info.Protect == PAGE_READWRITE) || /* win2k */
@@ -2167,23 +2153,9 @@ static void test_mapping(void)
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);
diff --git a/dlls/kernel32/virtual.c b/dlls/kernel32/virtual.c
index 949ceb5..bddd638 100644
--- a/dlls/kernel32/virtual.c
+++ b/dlls/kernel32/virtual.c
@@ -533,15 +533,21 @@ LPVOID WINAPI MapViewOfFileEx( HANDLE handle, DWORD access,
NTSTATUS status;
LARGE_INTEGER offset;
ULONG protect;
+ BOOL exec;
offset.u.LowPart = offset_low;
offset.u.HighPart = offset_high;
- if (access & FILE_MAP_WRITE) protect = PAGE_READWRITE;
- else if (access & FILE_MAP_COPY) protect = PAGE_WRITECOPY;
- else protect = PAGE_READONLY;
+ exec = access & FILE_MAP_EXECUTE;
+ access &= ~FILE_MAP_EXECUTE;
- if (access & FILE_MAP_EXECUTE) protect <<= 4;
+ if (access == FILE_MAP_COPY)
+ protect = exec ? PAGE_EXECUTE_WRITECOPY : PAGE_WRITECOPY;
+ else if (access & FILE_MAP_WRITE)
+ protect = exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
+ else if (access & FILE_MAP_READ)
+ protect = exec ? PAGE_EXECUTE_READ : PAGE_READONLY;
+ else protect = PAGE_NOACCESS;
if ((status = NtMapViewOfSection( handle, GetCurrentProcess(), &addr, 0, 0, &offset,
&count, ViewShare, 0, protect )) < 0)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 6ee3444..344a81a 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -2494,7 +2494,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
switch(protect)
{
case PAGE_NOACCESS:
- access = 0;
+ access = SECTION_MAP_READ;
break;
case PAGE_READWRITE:
case PAGE_EXECUTE_READWRITE:
--
1.7.7.4
More information about the wine-patches
mailing list