Module: wine Branch: master Commit: 26c59d845e8dd1111c976c54e1667504f2888652 URL: http://source.winehq.org/git/wine.git/?a=commit;h=26c59d845e8dd1111c976c54e1...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Sep 8 15:47:28 2017 +0200
ntdll: Ignore attempts to commit pages in an already committed anonymous mapping.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernel32/tests/virtual.c | 96 ++++++++++++++++++++++++++++++++++++++++++- dlls/ntdll/virtual.c | 2 +- 2 files changed, 96 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c index 76953d5..9b99464 100644 --- a/dlls/kernel32/tests/virtual.c +++ b/dlls/kernel32/tests/virtual.c @@ -775,7 +775,7 @@ static void test_MapViewOfFile(void)
/* read/write mapping with SEC_RESERVE */ mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_RESERVE, 0, MAPPING_SIZE, NULL); - ok(mapping != INVALID_HANDLE_VALUE, "CreateFileMappingA failed with error %d\n", GetLastError()); + ok(mapping != 0, "CreateFileMappingA failed with error %d\n", GetLastError()); status = pNtQuerySection( mapping, SectionBasicInformation, §ion_info, sizeof(section_info), NULL ); ok( !status, "NtQuerySection failed err %x\n", status ); @@ -863,6 +863,100 @@ static void test_MapViewOfFile(void) ok(ret, "UnmapViewOfFile failed with error %d\n", GetLastError()); CloseHandle(mapping);
+ /* same thing with SEC_COMMIT */ + mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, MAPPING_SIZE, NULL); + ok(mapping != 0, "CreateFileMappingA failed with error %d\n", GetLastError()); + status = pNtQuerySection( mapping, SectionBasicInformation, §ion_info, + sizeof(section_info), NULL ); + ok( !status, "NtQuerySection failed err %x\n", status ); + ok( section_info.Attributes == SEC_COMMIT, "NtQuerySection wrong attr %08x\n", + section_info.Attributes ); + ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress ); + ok( section_info.Size.QuadPart == MAPPING_SIZE, "NtQuerySection wrong size %x%08x / %08x\n", + section_info.Size.u.HighPart, section_info.Size.u.LowPart, MAPPING_SIZE ); + + ptr = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0); + ok(ptr != NULL, "MapViewOfFile failed with error %d\n", GetLastError()); + + ret = VirtualQuery(ptr, &info, sizeof(info)); + ok(ret, "VirtualQuery failed with error %d\n", GetLastError()); + ok(info.BaseAddress == ptr, "wrong BaseAddress %p/%p\n", ptr, info.BaseAddress); + ok(info.AllocationBase == ptr, "wrong AllocationBase %p/%p\n", ptr, info.AllocationBase); + ok(info.RegionSize == MAPPING_SIZE, "wrong RegionSize 0x%lx\n", info.RegionSize); + ok(info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State); + ok(info.AllocationProtect == PAGE_READWRITE, "wrong AllocationProtect 0x%x\n", info.AllocationProtect); + ok(info.Protect == PAGE_READWRITE, "wrong Protect 0x%x\n", info.Protect); + ok(info.Type == MEM_MAPPED, "wrong Type 0x%x\n", info.Type); + + ptr = VirtualAlloc(ptr, 0x10000, MEM_COMMIT, PAGE_READONLY); + ok(ptr != NULL, "VirtualAlloc failed with error %d\n", GetLastError()); + + ret = VirtualQuery(ptr, &info, sizeof(info)); + ok(ret, "VirtualQuery failed with error %d\n", GetLastError()); + ok(info.BaseAddress == ptr, "wrong BaseAddress %p/%p\n", ptr, info.BaseAddress); + ok(info.AllocationBase == ptr, "wrong AllocationBase %p/%p\n", ptr, info.AllocationBase); + ok(info.RegionSize == 0x10000, "wrong RegionSize 0x%lx\n", info.RegionSize); + ok(info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State); + ok(info.AllocationProtect == PAGE_READWRITE, "wrong AllocationProtect 0x%x\n", info.AllocationProtect); + ok(info.Protect == PAGE_READONLY, "wrong Protect 0x%x\n", info.Protect); + ok(info.Type == MEM_MAPPED, "wrong Type 0x%x\n", info.Type); + + addr = VirtualAlloc( ptr, MAPPING_SIZE, MEM_RESET, PAGE_READONLY ); + ok( addr == ptr, "VirtualAlloc failed with error %u\n", GetLastError() ); + + ret = VirtualFree( ptr, 0x10000, MEM_DECOMMIT ); + ok( !ret, "VirtualFree succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "VirtualFree failed with %u\n", GetLastError() ); + + ret = UnmapViewOfFile(ptr); + ok(ret, "UnmapViewOfFile failed with error %d\n", GetLastError()); + CloseHandle(mapping); + + /* same thing with SEC_NOCACHE (only supported on recent Windows versions) */ + mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT | SEC_NOCACHE, + 0, MAPPING_SIZE, NULL); + ok(mapping != 0, "CreateFileMappingA failed with error %d\n", GetLastError()); + status = pNtQuerySection( mapping, SectionBasicInformation, §ion_info, + sizeof(section_info), NULL ); + ok( !status, "NtQuerySection failed err %x\n", status ); + ok( section_info.Attributes == (SEC_COMMIT | SEC_NOCACHE) || + broken(section_info.Attributes == SEC_COMMIT), + "NtQuerySection wrong attr %08x\n", section_info.Attributes ); + if (section_info.Attributes & SEC_NOCACHE) + { + ptr = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0); + ok(ptr != NULL, "MapViewOfFile failed with error %d\n", GetLastError()); + + ret = VirtualQuery(ptr, &info, sizeof(info)); + ok(ret, "VirtualQuery failed with error %d\n", GetLastError()); + ok(info.BaseAddress == ptr, "wrong BaseAddress %p/%p\n", ptr, info.BaseAddress); + ok(info.AllocationBase == ptr, "wrong AllocationBase %p/%p\n", ptr, info.AllocationBase); + ok(info.RegionSize == MAPPING_SIZE, "wrong RegionSize 0x%lx\n", info.RegionSize); + ok(info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State); + ok(info.AllocationProtect == (PAGE_READWRITE | PAGE_NOCACHE), + "wrong AllocationProtect 0x%x\n", info.AllocationProtect); + ok(info.Protect == (PAGE_READWRITE | PAGE_NOCACHE), "wrong Protect 0x%x\n", info.Protect); + ok(info.Type == MEM_MAPPED, "wrong Type 0x%x\n", info.Type); + + ptr = VirtualAlloc(ptr, 0x10000, MEM_COMMIT, PAGE_READONLY); + ok(ptr != NULL, "VirtualAlloc failed with error %d\n", GetLastError()); + + ret = VirtualQuery(ptr, &info, sizeof(info)); + ok(ret, "VirtualQuery failed with error %d\n", GetLastError()); + ok(info.BaseAddress == ptr, "wrong BaseAddress %p/%p\n", ptr, info.BaseAddress); + ok(info.AllocationBase == ptr, "wrong AllocationBase %p/%p\n", ptr, info.AllocationBase); + ok(info.RegionSize == 0x10000, "wrong RegionSize 0x%lx\n", info.RegionSize); + ok(info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State); + ok(info.AllocationProtect == (PAGE_READWRITE | PAGE_NOCACHE), + "wrong AllocationProtect 0x%x\n", info.AllocationProtect); + ok(info.Protect == (PAGE_READONLY | PAGE_NOCACHE), "wrong Protect 0x%x\n", info.Protect); + ok(info.Type == MEM_MAPPED, "wrong Type 0x%x\n", info.Type); + + ret = UnmapViewOfFile(ptr); + ok(ret, "UnmapViewOfFile failed with error %d\n", GetLastError()); + } + CloseHandle(mapping); + addr = VirtualAlloc(NULL, 0x10000, MEM_COMMIT, PAGE_READONLY ); ok( addr != NULL, "VirtualAlloc failed with error %u\n", GetLastError() );
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 8cf09bd..0505617 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -2165,7 +2165,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_ else /* commit the pages */ { if (!(view = VIRTUAL_FindView( base, size ))) status = STATUS_NOT_MAPPED_VIEW; - else if (view->mapping && !(view->protect & SEC_RESERVE)) status = STATUS_ALREADY_COMMITTED; + else if (view->protect & SEC_FILE) status = STATUS_ALREADY_COMMITTED; else if (!VIRTUAL_SetProt( view, base, size, vprot )) status = STATUS_ACCESS_DENIED; else if (view->protect & SEC_RESERVE) {