ntdll: Support MEM_PRESERVE_PLACEHOLDER in NtUnmapViewOfSectionEx().

This commit is contained in:
Paul Gofman 2022-11-11 12:54:19 -06:00 committed by Alexandre Julliard
parent 3e3ca7dd28
commit fce615a2c3
5 changed files with 24 additions and 17 deletions

View file

@ -211,9 +211,9 @@ static void test_VirtualAlloc2(void)
ret = VirtualFree( view1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER );
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "Got ret %d, error %lu.\n", ret, GetLastError());
ret = pUnmapViewOfFile2(GetCurrentProcess(), view1, MEM_PRESERVE_PLACEHOLDER);
todo_wine ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got ret %d, error %lu.\n", ret, GetLastError());
ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got ret %d, error %lu.\n", ret, GetLastError());
ret = pUnmapViewOfFile2(GetCurrentProcess(), view1, 0);
todo_wine ok(ret, "Got error %lu.\n", GetLastError());
ok(ret, "Got error %lu.\n", GetLastError());
view1 = pMapViewOfFile3(section, NULL, placeholder1, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0);
ok(view1 == placeholder1, "Address does not match.\n");
@ -248,9 +248,9 @@ static void test_VirtualAlloc2(void)
memset(&info, 0, sizeof(info));
VirtualQuery(placeholder1, &info, sizeof(info));
todo_wine ok(info.AllocationProtect == PAGE_NOACCESS, "Unexpected protection %#lx.\n", info.AllocationProtect);
todo_wine ok(info.State == MEM_RESERVE, "Unexpected state %#lx.\n", info.State);
todo_wine ok(info.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", info.Type);
ok(info.AllocationProtect == PAGE_NOACCESS, "Unexpected protection %#lx.\n", info.AllocationProtect);
ok(info.State == MEM_RESERVE, "Unexpected state %#lx.\n", info.State);
ok(info.Type == MEM_PRIVATE, "Unexpected type %#lx.\n", info.Type);
ok(info.RegionSize == size, "Unexpected size.\n");
ret = pUnmapViewOfFile2(GetCurrentProcess(), view1, MEM_PRESERVE_PLACEHOLDER);
@ -260,21 +260,21 @@ static void test_VirtualAlloc2(void)
ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got error %lu.\n", GetLastError());
view1 = pMapViewOfFile3(section, NULL, placeholder1, 0, size, MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, NULL, 0);
todo_wine ok(view1 == placeholder1, "Address does not match.\n");
ok(view1 == placeholder1, "Address does not match.\n");
CloseHandle(section);
ret = VirtualFree( view1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER );
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "Got ret %d, error %lu.\n", ret, GetLastError());
ret = pUnmapViewOfFile2(GetCurrentProcess(), view1, MEM_UNMAP_WITH_TRANSIENT_BOOST | MEM_PRESERVE_PLACEHOLDER);
todo_wine ok(ret, "Got error %lu.\n", GetLastError());
ok(ret, "Got error %lu.\n", GetLastError());
ret = VirtualFree( placeholder1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER );
ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got ret %d, error %lu.\n", ret, GetLastError());
ret = VirtualFreeEx(GetCurrentProcess(), placeholder1, size, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER );
ok(!ret && GetLastError() == ERROR_INVALID_ADDRESS, "Got ret %d, error %lu.\n", ret, GetLastError());
ret = VirtualFree(placeholder1, 0, MEM_RELEASE);
todo_wine ok(ret, "Got error %lu.\n", GetLastError());
ok(ret, "Got error %lu.\n", GetLastError());
UnmapViewOfFile(view2);

View file

@ -615,7 +615,7 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result, BOO
result->type = call->type;
addr = wine_server_get_ptr( call->unmap_view.addr );
if ((ULONG_PTR)addr == call->unmap_view.addr)
result->unmap_view.status = NtUnmapViewOfSection( NtCurrentProcess(), addr );
result->unmap_view.status = NtUnmapViewOfSectionEx( NtCurrentProcess(), addr, call->unmap_view.flags );
else
result->unmap_view.status = STATUS_INVALID_PARAMETER;
break;

View file

@ -5225,7 +5225,7 @@ NTSTATUS WINAPI NtMapViewOfSectionEx( HANDLE handle, HANDLE process, PVOID *addr
*
* NtUnmapViewOfSection[Ex] implementation.
*/
static NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr )
static NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr, ULONG flags )
{
struct file_view *view;
unsigned int status = STATUS_NOT_MAPPED_VIEW;
@ -5240,6 +5240,7 @@ static NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr )
call.unmap_view.type = APC_UNMAP_VIEW;
call.unmap_view.addr = wine_server_client_ptr( addr );
call.unmap_view.flags = flags;
status = server_queue_process_apc( process, &call, &result );
if (status == STATUS_SUCCESS) status = result.unmap_view.status;
return status;
@ -5248,6 +5249,11 @@ static NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr )
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
if (!(view = find_view( addr, 0 )) || is_view_valloc( view )) goto done;
if (flags & MEM_PRESERVE_PLACEHOLDER && !(view->protect & VPROT_PLACEHOLDER))
{
status = STATUS_CONFLICTING_ADDRESSES;
goto done;
}
if (view->protect & VPROT_SYSTEM)
{
struct builtin_module *builtin;
@ -5274,7 +5280,8 @@ static NTSTATUS unmap_view_of_section( HANDLE process, PVOID addr )
if (!status)
{
if (view->protect & SEC_IMAGE) release_builtin_module( view->base );
delete_view( view );
if (flags & MEM_PRESERVE_PLACEHOLDER) free_pages_preserve_placeholder( view, view->base, view->size );
else delete_view( view );
}
else FIXME( "failed to unmap %p %x\n", view->base, status );
done:
@ -5289,7 +5296,7 @@ done:
*/
NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
{
return unmap_view_of_section( process, addr );
return unmap_view_of_section( process, addr, 0 );
}
/***********************************************************************
@ -5305,8 +5312,8 @@ NTSTATUS WINAPI NtUnmapViewOfSectionEx( HANDLE process, PVOID addr, ULONG flags
WARN( "Unsupported flags %#x.\n", (int)flags );
return STATUS_INVALID_PARAMETER;
}
if (flags) FIXME( "Ignoring flags %#x.\n", (int)flags );
return unmap_view_of_section( process, addr );
if (flags & MEM_UNMAP_WITH_TRANSIENT_BOOST) FIXME( "Ignoring MEM_UNMAP_WITH_TRANSIENT_BOOST.\n" );
return unmap_view_of_section( process, addr, flags );
}
/******************************************************************************

View file

@ -598,7 +598,7 @@ typedef union
struct
{
enum apc_type type;
int __pad;
unsigned int flags;
client_ptr_t addr;
} unmap_view;
struct
@ -6415,7 +6415,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 770
#define SERVER_PROTOCOL_VERSION 771
/* ### protocol_version end ### */

View file

@ -614,7 +614,7 @@ typedef union
struct
{
enum apc_type type; /* APC_UNMAP_VIEW */
int __pad;
unsigned int flags; /* unmap flags */
client_ptr_t addr; /* view address */
} unmap_view;
struct