diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c index e665f0f3b96..b7e97db667c 100644 --- a/dlls/kernel32/tests/virtual.c +++ b/dlls/kernel32/tests/virtual.c @@ -284,6 +284,40 @@ static void test_VirtualAlloc(void) ok(old_prot == PAGE_READONLY, "wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot); + ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info), + "VirtualQuery failed\n"); + ok(info.RegionSize == 0x1000, "%lx != 0x1000\n", info.RegionSize); + ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State); + ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect); + memset( addr1, 0x55, 20 ); + ok( *(DWORD *)addr1 == 0x55555555, "wrong data %x\n", *(DWORD *)addr1 ); + + addr2 = VirtualAlloc( addr1, 0x1000, MEM_RESET, PAGE_NOACCESS ); + ok( addr2 == addr1 || broken( !addr2 && GetLastError() == ERROR_INVALID_PARAMETER), /* win9x */ + "VirtualAlloc failed err %u\n", GetLastError() ); + ok( *(DWORD *)addr1 == 0x55555555 || *(DWORD *)addr1 == 0, "wrong data %x\n", *(DWORD *)addr1 ); + if (addr2) + { + ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info), + "VirtualQuery failed\n"); + ok(info.RegionSize == 0x1000, "%lx != 0x1000\n", info.RegionSize); + ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State); + ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect); + + addr2 = VirtualAlloc( (char *)addr1 + 0x1000, 0x1000, MEM_RESET, PAGE_NOACCESS ); + ok( (char *)addr2 == (char *)addr1 + 0x1000, "VirtualAlloc failed\n" ); + + ok(VirtualQuery(addr2, &info, sizeof(info)) == sizeof(info), + "VirtualQuery failed\n"); + ok(info.RegionSize == 0xf000, "%lx != 0xf000\n", info.RegionSize); + ok(info.State == MEM_RESERVE, "%x != MEM_RESERVE\n", info.State); + ok(info.Protect == 0, "%x != 0\n", info.Protect); + + addr2 = VirtualAlloc( (char *)addr1 + 0xf000, 0x2000, MEM_RESET, PAGE_NOACCESS ); + ok( !addr2, "VirtualAlloc failed\n" ); + ok( GetLastError() == ERROR_INVALID_ADDRESS, "wrong error %u\n", GetLastError() ); + } + /* invalid protection values */ SetLastError(0xdeadbeef); addr2 = VirtualAlloc(NULL, 0x1000, MEM_RESERVE, 0); @@ -329,7 +363,7 @@ static void test_MapViewOfFile(void) static const char testfile[] = "testfile.xxx"; const char *name; HANDLE file, mapping, map2; - void *ptr, *ptr2; + void *ptr, *ptr2, *addr; MEMORY_BASIC_INFORMATION info; BOOL ret; @@ -700,6 +734,10 @@ static void test_MapViewOfFile(void) ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type); } + addr = VirtualAlloc( ptr, MAPPING_SIZE, MEM_RESET, PAGE_READONLY ); + ok( addr == ptr || broken(!addr && GetLastError() == ERROR_INVALID_PARAMETER), /* win9x */ + "VirtualAlloc failed with error %u\n", GetLastError() ); + ret = VirtualFree( ptr, 0x10000, MEM_DECOMMIT ); ok( !ret || broken(ret) /* win9x */, "VirtualFree succeeded\n" ); if (!ret) diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 32e7d938b83..04c90f6f44a 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -1787,7 +1787,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_ /* Compute the alloc type flags */ - if (!(type & (MEM_COMMIT | MEM_RESERVE)) || + if (!(type & (MEM_COMMIT | MEM_RESERVE | MEM_RESET)) || (type & ~(MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN | MEM_WRITE_WATCH | MEM_RESET))) { WARN("called with wrong alloc type flags (%08x) !\n", type); @@ -1804,6 +1804,11 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_ status = map_view( &view, base, size, mask, type & MEM_TOP_DOWN, vprot ); if (status == STATUS_SUCCESS) base = view->base; } + else if (type & MEM_RESET) + { + if (!(view = VIRTUAL_FindView( base, size ))) status = STATUS_NOT_MAPPED_VIEW; + else madvise( base, size, MADV_DONTNEED ); + } else /* commit the pages */ { if (!(view = VIRTUAL_FindView( base, size ))) status = STATUS_NOT_MAPPED_VIEW;