Dmitry Timoshkov : ntdll: Setting WRITECOPY protection on a memory-mapped file is allowed.
Alexandre Julliard
julliard at winehq.org
Fri Dec 16 11:22:53 CST 2011
Module: wine
Branch: master
Commit: eed406e028102e40a8d33cfd319884015c4496f1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=eed406e028102e40a8d33cfd319884015c4496f1
Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date: Fri Dec 16 14:44:35 2011 +0800
ntdll: Setting WRITECOPY protection on a memory-mapped file is allowed.
---
dlls/kernel32/tests/virtual.c | 21 +++++----------------
dlls/ntdll/virtual.c | 24 ++++++++++++++----------
2 files changed, 19 insertions(+), 26 deletions(-)
diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c
index 3812cb2..336fd87 100644
--- a/dlls/kernel32/tests/virtual.c
+++ b/dlls/kernel32/tests/virtual.c
@@ -1787,13 +1787,6 @@ static void test_CreateFileMapping_protection(void)
{
if (!ret)
{
- /* FIXME: completely remove the condition below once Wine is fixed */
- if (td[i].prot == PAGE_WRITECOPY)
- {
- todo_wine
- ok(ret, "%d: VirtualProtect error %d\n", i, GetLastError());
- continue;
- }
/* win2k and XP don't support EXEC on file mappings */
if (td[i].prot == PAGE_EXECUTE)
{
@@ -1809,7 +1802,6 @@ static void test_CreateFileMapping_protection(void)
/* Vista+ supports PAGE_EXECUTE_WRITECOPY, earlier versions don't */
if (td[i].prot == PAGE_EXECUTE_WRITECOPY)
{
- todo_wine
ok(broken(!ret), "%d: VirtualProtect doesn't support PAGE_EXECUTE_WRITECOPY\n", i);
continue;
}
@@ -1827,7 +1819,11 @@ static void test_CreateFileMapping_protection(void)
ok(ret, "VirtualQuery failed %d\n", GetLastError());
ok(info.BaseAddress == base, "%d: got %p != expected %p\n", i, info.BaseAddress, base);
ok(info.RegionSize == si.dwPageSize, "%d: got %#lx != expected %#x\n", i, info.RegionSize, si.dwPageSize);
- ok(info.Protect == prot, "%d: got %#x != expected %#x\n", i, info.Protect, prot);
+ /* FIXME: remove the condition below once Wine is fixed */
+ if (td[i].prot == PAGE_EXECUTE_WRITECOPY)
+ todo_wine ok(info.Protect == prot, "%d: got %#x != expected %#x\n", i, info.Protect, prot);
+ else
+ ok(info.Protect == prot, "%d: got %#x != expected %#x\n", i, info.Protect, prot);
ok(info.AllocationBase == base, "%d: %p != %p\n", i, info.AllocationBase, base);
ok(info.AllocationProtect == alloc_prot, "%d: %#x != %#x\n", i, info.AllocationProtect, alloc_prot);
ok(info.State == MEM_COMMIT, "%d: %#x != MEM_COMMIT\n", i, info.State);
@@ -2122,13 +2118,6 @@ static void test_mapping(void)
ok(broken(!ret), "VirtualProtect doesn't support PAGE_EXECUTE_WRITECOPY view properly\n");
continue;
}
- /* FIXME: completely remove the condition below once Wine is fixed */
- if (!ret && page_prot[k] == PAGE_WRITECOPY)
- {
- todo_wine
- ok(ret, "VirtualProtect error %d\n", GetLastError());
- continue;
- }
ok(ret, "VirtualProtect error %d, map %#x, view %#x, requested prot %#x\n", GetLastError(), page_prot[i], view[j].prot, page_prot[k]);
ok(old_prot == prev_prot, "got %#x, expected %#x\n", old_prot, prev_prot);
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index e6ca21a..ee56e71 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -2079,26 +2079,30 @@ NTSTATUS WINAPI NtProtectVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T
size = ROUND_SIZE( addr, size );
base = ROUND_ADDR( addr, page_mask );
- if ((status = get_vprot_flags( new_prot, &new_vprot ))) return status;
- if (new_vprot & VPROT_WRITECOPY) return STATUS_INVALID_PAGE_PROTECTION;
- new_vprot |= VPROT_COMMITTED;
server_enter_uninterrupted_section( &csVirtual, &sigset );
- if (!(view = VIRTUAL_FindView( base, size )))
- {
- status = STATUS_INVALID_PARAMETER;
- }
- else
+ if ((view = VIRTUAL_FindView( base, size )))
{
/* Make sure all the pages are committed */
if (get_committed_size( view, base, &vprot ) >= size && (vprot & VPROT_COMMITTED))
{
- if (old_prot) *old_prot = VIRTUAL_GetWin32Prot( vprot );
- if (!VIRTUAL_SetProt( view, base, size, new_vprot )) status = STATUS_ACCESS_DENIED;
+ if (!(status = get_vprot_flags( new_prot, &new_vprot )))
+ {
+ if ((new_vprot & VPROT_WRITECOPY) && (view->protect & VPROT_VALLOC))
+ status = STATUS_INVALID_PAGE_PROTECTION;
+ else
+ {
+ new_vprot |= VPROT_COMMITTED;
+ if (old_prot) *old_prot = VIRTUAL_GetWin32Prot( vprot );
+ if (!VIRTUAL_SetProt( view, base, size, new_vprot )) status = STATUS_ACCESS_DENIED;
+ }
+ }
}
else status = STATUS_NOT_COMMITTED;
}
+ else status = STATUS_INVALID_PARAMETER;
+
server_leave_uninterrupted_section( &csVirtual, &sigset );
if (status == STATUS_SUCCESS)
More information about the wine-cvs
mailing list