ntdll: Fix handling of zero size with MEM_DECOMMIT.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52023 Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
32fb017d4a
commit
7d2a7b94aa
|
@ -219,6 +219,49 @@ static void test_NtAllocateVirtualMemory(void)
|
|||
status = NtFreeVirtualMemory(NtCurrentProcess(), &addr1, &size, MEM_RELEASE);
|
||||
ok(status == STATUS_SUCCESS, "NtFreeVirtualMemory failed\n");
|
||||
|
||||
/* NtFreeVirtualMemory tests */
|
||||
|
||||
size = 0x10000;
|
||||
addr1 = NULL;
|
||||
status = NtAllocateVirtualMemory(NtCurrentProcess(), &addr1, 0, &size,
|
||||
MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
ok(status == STATUS_SUCCESS, "NtAllocateVirtualMemory returned %08x\n", status);
|
||||
|
||||
size = 2;
|
||||
addr2 = (char *)addr1 + 0x1fff;
|
||||
status = NtFreeVirtualMemory(NtCurrentProcess(), &addr2, &size, MEM_DECOMMIT);
|
||||
ok(status == STATUS_SUCCESS, "NtFreeVirtualMemory failed %x\n", status);
|
||||
ok( size == 0x2000, "wrong size %lx\n", size );
|
||||
ok( addr2 == (char *)addr1 + 0x1000, "wrong addr %p\n", addr2 );
|
||||
|
||||
size = 0;
|
||||
addr2 = (char *)addr1 + 0x1001;
|
||||
status = NtFreeVirtualMemory(NtCurrentProcess(), &addr2, &size, MEM_DECOMMIT);
|
||||
ok(status == STATUS_FREE_VM_NOT_AT_BASE, "NtFreeVirtualMemory failed %x\n", status);
|
||||
ok( size == 0, "wrong size %lx\n", size );
|
||||
ok( addr2 == (char *)addr1 + 0x1001, "wrong addr %p\n", addr2 );
|
||||
|
||||
size = 0;
|
||||
addr2 = (char *)addr1 + 0xffe;
|
||||
status = NtFreeVirtualMemory(NtCurrentProcess(), &addr2, &size, MEM_DECOMMIT);
|
||||
ok(status == STATUS_SUCCESS, "NtFreeVirtualMemory failed %x\n", status);
|
||||
ok( size == 0, "wrong size %lx\n", size );
|
||||
ok( addr2 == addr1, "wrong addr %p\n", addr2 );
|
||||
|
||||
size = 0;
|
||||
addr2 = (char *)addr1 + 0x1001;
|
||||
status = NtFreeVirtualMemory(NtCurrentProcess(), &addr2, &size, MEM_RELEASE);
|
||||
ok(status == STATUS_FREE_VM_NOT_AT_BASE, "NtFreeVirtualMemory failed %x\n", status);
|
||||
ok( size == 0, "wrong size %lx\n", size );
|
||||
ok( addr2 == (char *)addr1 + 0x1001, "wrong addr %p\n", addr2 );
|
||||
|
||||
size = 0;
|
||||
addr2 = (char *)addr1 + 0xfff;
|
||||
status = NtFreeVirtualMemory(NtCurrentProcess(), &addr2, &size, MEM_RELEASE);
|
||||
ok(status == STATUS_SUCCESS, "NtFreeVirtualMemory failed %x\n", status);
|
||||
ok( size == 0x10000, "wrong size %lx\n", size );
|
||||
ok( addr2 == addr1, "wrong addr %p\n", addr2 );
|
||||
|
||||
if (!pNtAllocateVirtualMemoryEx)
|
||||
{
|
||||
win_skip("NtAllocateVirtualMemoryEx() is missing\n");
|
||||
|
|
|
@ -2121,13 +2121,14 @@ static SIZE_T get_committed_size( struct file_view *view, void *base, BYTE *vpro
|
|||
|
||||
|
||||
/***********************************************************************
|
||||
* decommit_view
|
||||
* decommit_pages
|
||||
*
|
||||
* Decommit some pages of a given view.
|
||||
* virtual_mutex must be held by caller.
|
||||
*/
|
||||
static NTSTATUS decommit_pages( struct file_view *view, size_t start, size_t size )
|
||||
{
|
||||
if (!size) size = view->size;
|
||||
if (anon_mmap_fixed( (char *)view->base + start, size, PROT_NONE, 0 ) != MAP_FAILED)
|
||||
{
|
||||
set_page_vprot_bits( (char *)view->base + start, size, 0, VPROT_COMMITTED );
|
||||
|
@ -3966,7 +3967,7 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
|
|||
|
||||
/* Fix the parameters */
|
||||
|
||||
size = ROUND_SIZE( addr, size );
|
||||
if (size) size = ROUND_SIZE( addr, size );
|
||||
base = ROUND_ADDR( addr, page_mask );
|
||||
|
||||
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
|
@ -3975,7 +3976,7 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
|
|||
if (!base)
|
||||
{
|
||||
/* address 1 is magic to mean release reserved space */
|
||||
if (addr == (void *)1 && !*size_ptr && type == MEM_RELEASE) virtual_release_address_space();
|
||||
if (addr == (void *)1 && !size && type == MEM_RELEASE) virtual_release_address_space();
|
||||
else status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
else if (!(view = find_view( base, size )) || !is_view_valloc( view ))
|
||||
|
@ -3986,17 +3987,19 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
|
|||
{
|
||||
/* Free the pages */
|
||||
|
||||
if (size || (base != view->base)) status = STATUS_INVALID_PARAMETER;
|
||||
if (size) status = STATUS_INVALID_PARAMETER;
|
||||
else if (base != view->base) status = STATUS_FREE_VM_NOT_AT_BASE;
|
||||
else
|
||||
{
|
||||
delete_view( view );
|
||||
*addr_ptr = base;
|
||||
*size_ptr = size;
|
||||
*size_ptr = view->size;
|
||||
delete_view( view );
|
||||
}
|
||||
}
|
||||
else if (type == MEM_DECOMMIT)
|
||||
{
|
||||
status = decommit_pages( view, base - (char *)view->base, size );
|
||||
if (!size && base != view->base) status = STATUS_FREE_VM_NOT_AT_BASE;
|
||||
else status = decommit_pages( view, base - (char *)view->base, size );
|
||||
if (status == STATUS_SUCCESS)
|
||||
{
|
||||
*addr_ptr = base;
|
||||
|
|
Loading…
Reference in New Issue