ntdll: Disallow changing PAGE_NOCACHE flag for individual pages.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2017-09-08 12:41:01 +02:00
parent e5c39a565a
commit 08acac0864
2 changed files with 71 additions and 0 deletions

View File

@ -362,6 +362,75 @@ static void test_VirtualAlloc(void)
ok(VirtualFree(addr1, 0, MEM_RELEASE), "VirtualFree failed\n");
/* PAGE_NOCACHE cannot be set per page in recent Windows */
addr1 = VirtualAlloc( NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE | PAGE_NOCACHE );
ok( addr1 != NULL, "VirtualAlloc failed\n");
ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info), "VirtualQuery failed\n");
ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
ok(info.AllocationProtect == (PAGE_READWRITE | PAGE_NOCACHE),
"wrong protect %x\n", info.AllocationProtect);
ok(info.RegionSize == 0x2000, "wrong size %lx\n", info.RegionSize);
ok(info.State == MEM_COMMIT, "wrong state %x\n", info.State);
ok(info.Protect == (PAGE_READWRITE | PAGE_NOCACHE), "wrong protect %x\n", info.Protect);
ok(info.Type == MEM_PRIVATE, "wrong type %x\n", info.Type);
ok(VirtualProtect(addr1, 0x1000, PAGE_READWRITE, &old_prot), "VirtualProtect failed\n");
ok( old_prot == (PAGE_READWRITE | PAGE_NOCACHE), "wrong protect %x\n", old_prot );
ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info), "VirtualQuery failed\n");
ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
ok(info.AllocationProtect == (PAGE_READWRITE | PAGE_NOCACHE),
"wrong protect %x\n", info.AllocationProtect);
ok(info.RegionSize == 0x2000 || broken(info.RegionSize == 0x1000),
"wrong size %lx\n", info.RegionSize);
ok(info.State == MEM_COMMIT, "wrong state %x\n", info.State);
ok(info.Protect == (PAGE_READWRITE | PAGE_NOCACHE) || broken(info.Protect == PAGE_READWRITE),
"wrong protect %x\n", info.Protect);
ok(info.Type == MEM_PRIVATE, "wrong type %x\n", info.Type);
ok(VirtualProtect(addr1, 0x1000, PAGE_READONLY, &old_prot), "VirtualProtect failed\n");
ok( old_prot == (PAGE_READWRITE | PAGE_NOCACHE) || broken(old_prot == PAGE_READWRITE),
"wrong protect %x\n", old_prot );
ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info), "VirtualQuery failed\n");
ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
ok(info.AllocationProtect == (PAGE_READWRITE | PAGE_NOCACHE),
"wrong protect %x\n", info.AllocationProtect);
ok(info.RegionSize == 0x1000, "wrong size %lx\n", info.RegionSize);
ok(info.State == MEM_COMMIT, "wrong state %x\n", info.State);
ok(info.Protect == (PAGE_READONLY | PAGE_NOCACHE) || broken(info.Protect == PAGE_READONLY),
"wrong protect %x\n", info.Protect);
ok(info.Type == MEM_PRIVATE, "wrong type %x\n", info.Type);
ok(VirtualFree(addr1, 0, MEM_RELEASE), "VirtualFree failed\n");
addr1 = VirtualAlloc( NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE );
ok( addr1 != NULL, "VirtualAlloc failed\n");
ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info), "VirtualQuery failed\n");
ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
ok(info.AllocationProtect == PAGE_READWRITE,
"wrong protect %x\n", info.AllocationProtect);
ok(info.RegionSize == 0x2000, "wrong size %lx\n", info.RegionSize);
ok(info.State == MEM_COMMIT, "wrong state %x\n", info.State);
ok(info.Protect == PAGE_READWRITE, "wrong protect %x\n", info.Protect);
ok(info.Type == MEM_PRIVATE, "wrong type %x\n", info.Type);
ok(VirtualProtect(addr1, 0x1000, PAGE_READONLY | PAGE_NOCACHE, &old_prot), "VirtualProtect failed\n");
ok( old_prot == PAGE_READWRITE, "wrong protect %x\n", old_prot );
ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info), "VirtualQuery failed\n");
ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
ok(info.AllocationProtect == PAGE_READWRITE, "wrong protect %x\n", info.AllocationProtect);
ok(info.RegionSize == 0x1000, "wrong size %lx\n", info.RegionSize);
ok(info.State == MEM_COMMIT, "wrong state %x\n", info.State);
ok(info.Protect == PAGE_READONLY || broken(info.Protect == (PAGE_READONLY | PAGE_NOCACHE)),
"wrong protect %x\n", info.Protect);
ok(info.Type == MEM_PRIVATE, "wrong type %x\n", info.Type);
ok(VirtualFree(addr1, 0, MEM_RELEASE), "VirtualFree failed\n");
/* memory returned by VirtualAlloc should be aligned to 64k */
addr1 = VirtualAlloc(0, 0x2000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
ok(addr1 != NULL, "VirtualAlloc failed\n");

View File

@ -2369,6 +2369,8 @@ NTSTATUS WINAPI NtProtectVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T
if (!view->mapping || is_compatible_protection( view, new_vprot ))
{
new_vprot |= VPROT_COMMITTED;
if (view->protect & VPROT_NOCACHE) new_vprot |= VPROT_NOCACHE;
else new_vprot &= ~VPROT_NOCACHE;
if (old_prot) *old_prot = VIRTUAL_GetWin32Prot( vprot );
if (!VIRTUAL_SetProt( view, base, size, new_vprot )) status = STATUS_ACCESS_DENIED;
}