ntdll: Add support for the MEM_RESET flag in VirtualAlloc, with tests.

This commit is contained in:
Alexandre Julliard 2009-07-09 19:17:49 +02:00
parent b9be3bd766
commit df6c65623a
2 changed files with 45 additions and 2 deletions

View File

@ -284,6 +284,40 @@ static void test_VirtualAlloc(void)
ok(old_prot == PAGE_READONLY, ok(old_prot == PAGE_READONLY,
"wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot); "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 */ /* invalid protection values */
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
addr2 = VirtualAlloc(NULL, 0x1000, MEM_RESERVE, 0); addr2 = VirtualAlloc(NULL, 0x1000, MEM_RESERVE, 0);
@ -329,7 +363,7 @@ static void test_MapViewOfFile(void)
static const char testfile[] = "testfile.xxx"; static const char testfile[] = "testfile.xxx";
const char *name; const char *name;
HANDLE file, mapping, map2; HANDLE file, mapping, map2;
void *ptr, *ptr2; void *ptr, *ptr2, *addr;
MEMORY_BASIC_INFORMATION info; MEMORY_BASIC_INFORMATION info;
BOOL ret; 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); 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 ); ret = VirtualFree( ptr, 0x10000, MEM_DECOMMIT );
ok( !ret || broken(ret) /* win9x */, "VirtualFree succeeded\n" ); ok( !ret || broken(ret) /* win9x */, "VirtualFree succeeded\n" );
if (!ret) if (!ret)

View File

@ -1787,7 +1787,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_
/* Compute the alloc type flags */ /* 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))) (type & ~(MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN | MEM_WRITE_WATCH | MEM_RESET)))
{ {
WARN("called with wrong alloc type flags (%08x) !\n", type); 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 ); status = map_view( &view, base, size, mask, type & MEM_TOP_DOWN, vprot );
if (status == STATUS_SUCCESS) base = view->base; 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 */ else /* commit the pages */
{ {
if (!(view = VIRTUAL_FindView( base, size ))) status = STATUS_NOT_MAPPED_VIEW; if (!(view = VIRTUAL_FindView( base, size ))) status = STATUS_NOT_MAPPED_VIEW;