ntdll: Setting WRITECOPY protection on a memory-mapped file is allowed.

This commit is contained in:
Dmitry Timoshkov 2011-12-16 14:44:35 +08:00 committed by Alexandre Julliard
parent 47fa932ac0
commit eed406e028
2 changed files with 19 additions and 26 deletions

View File

@ -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);

View File

@ -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)