server: Add a separate request to create a memory view for an image mapping.

This commit is contained in:
Alexandre Julliard 2023-05-25 11:22:18 +02:00
parent d84704192e
commit c306e76645
6 changed files with 95 additions and 26 deletions

View file

@ -2766,7 +2766,7 @@ static unsigned int get_mapping_info( HANDLE handle, ACCESS_MASK access, unsigne
*
* Map a PE image section into memory.
*/
static NTSTATUS virtual_map_image( HANDLE mapping, ACCESS_MASK access, void **addr_ptr, SIZE_T *size_ptr, HANDLE shared_file,
static NTSTATUS virtual_map_image( HANDLE mapping, void **addr_ptr, SIZE_T *size_ptr, HANDLE shared_file,
ULONG_PTR limit, ULONG alloc_type, USHORT machine,
pe_image_info_t *image_info, WCHAR *filename, BOOL is_builtin )
{
@ -2805,10 +2805,9 @@ static NTSTATUS virtual_map_image( HANDLE mapping, ACCESS_MASK access, void **ad
machine, shared_fd, needs_close );
if (status == STATUS_SUCCESS)
{
SERVER_START_REQ( map_view )
SERVER_START_REQ( map_image_view )
{
req->mapping = wine_server_obj_handle( mapping );
req->access = access;
req->base = wine_server_client_ptr( view->base );
req->size = size;
status = wine_server_call( req );
@ -2887,7 +2886,7 @@ static unsigned int virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_P
/* check if we can replace that mapping with the builtin */
res = load_builtin( image_info, filename, machine, addr_ptr, size_ptr, limit );
if (res == STATUS_IMAGE_ALREADY_LOADED)
res = virtual_map_image( handle, access, addr_ptr, size_ptr, shared_file, limit,
res = virtual_map_image( handle, addr_ptr, size_ptr, shared_file, limit,
alloc_type, machine, image_info, filename, FALSE );
if (shared_file) NtClose( shared_file );
free( image_info );
@ -3109,11 +3108,11 @@ NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module, SIZE_T *size
unsigned int sec_flags;
HANDLE shared_file;
pe_image_info_t *image_info = NULL;
ACCESS_MASK access = SECTION_MAP_READ | SECTION_MAP_EXECUTE;
NTSTATUS status;
WCHAR *filename;
if ((status = get_mapping_info( mapping, access, &sec_flags, &full_size, &shared_file, &image_info )))
if ((status = get_mapping_info( mapping, SECTION_MAP_READ,
&sec_flags, &full_size, &shared_file, &image_info )))
return status;
if (!image_info) return STATUS_INVALID_PARAMETER;
@ -3134,7 +3133,7 @@ NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module, SIZE_T *size
}
else
{
status = virtual_map_image( mapping, access, module, size, shared_file, limit, 0,
status = virtual_map_image( mapping, module, size, shared_file, limit, 0,
machine, image_info, filename, TRUE );
virtual_fill_image_information( image_info, info );
}
@ -3156,10 +3155,10 @@ NTSTATUS virtual_map_module( HANDLE mapping, void **module, SIZE_T *size, SECTIO
unsigned int sec_flags;
HANDLE shared_file;
pe_image_info_t *image_info = NULL;
ACCESS_MASK access = SECTION_MAP_READ | SECTION_MAP_EXECUTE;
WCHAR *filename;
if ((status = get_mapping_info( mapping, access, &sec_flags, &full_size, &shared_file, &image_info )))
if ((status = get_mapping_info( mapping, SECTION_MAP_READ,
&sec_flags, &full_size, &shared_file, &image_info )))
return status;
if (!image_info) return STATUS_INVALID_PARAMETER;
@ -3171,7 +3170,7 @@ NTSTATUS virtual_map_module( HANDLE mapping, void **module, SIZE_T *size, SECTIO
/* check if we can replace that mapping with the builtin */
status = load_builtin( image_info, filename, machine, module, size, limit );
if (status == STATUS_IMAGE_ALREADY_LOADED)
status = virtual_map_image( mapping, access, module, size, shared_file, limit, 0,
status = virtual_map_image( mapping, module, size, shared_file, limit, 0,
machine, image_info, filename, FALSE );
virtual_fill_image_information( image_info, info );

View file

@ -1992,6 +1992,20 @@ struct map_view_reply
struct map_image_view_request
{
struct request_header __header;
obj_handle_t mapping;
client_ptr_t base;
mem_size_t size;
};
struct map_image_view_reply
{
struct reply_header __header;
};
struct map_builtin_view_request
{
struct request_header __header;
@ -5607,6 +5621,7 @@ enum request
REQ_open_mapping,
REQ_get_mapping_info,
REQ_map_view,
REQ_map_image_view,
REQ_map_builtin_view,
REQ_unmap_view,
REQ_get_mapping_committed_range,
@ -5893,6 +5908,7 @@ union generic_request
struct open_mapping_request open_mapping_request;
struct get_mapping_info_request get_mapping_info_request;
struct map_view_request map_view_request;
struct map_image_view_request map_image_view_request;
struct map_builtin_view_request map_builtin_view_request;
struct unmap_view_request unmap_view_request;
struct get_mapping_committed_range_request get_mapping_committed_range_request;
@ -6177,6 +6193,7 @@ union generic_reply
struct open_mapping_reply open_mapping_reply;
struct get_mapping_info_reply get_mapping_info_reply;
struct map_view_reply map_view_reply;
struct map_image_view_reply map_image_view_reply;
struct map_builtin_view_reply map_builtin_view_reply;
struct unmap_view_reply unmap_view_reply;
struct get_mapping_committed_range_reply get_mapping_committed_range_reply;

View file

@ -1206,7 +1206,7 @@ DECL_HANDLER(get_mapping_info)
/* add a memory view in the current process */
DECL_HANDLER(map_view)
{
struct mapping *mapping = NULL;
struct mapping *mapping;
struct memory_view *view;
if (!is_valid_view_addr( current->process, req->base, req->size ))
@ -1217,17 +1217,10 @@ DECL_HANDLER(map_view)
if (!(mapping = get_mapping_obj( current->process, req->mapping, req->access ))) return;
if (mapping->flags & SEC_IMAGE)
{
if (req->start || req->size > mapping->image.map_size)
{
set_error( STATUS_INVALID_PARAMETER );
goto done;
}
}
else if (req->start >= mapping->size ||
req->start + req->size < req->start ||
req->start + req->size > ((mapping->size + page_mask) & ~(mem_size_t)page_mask))
if ((mapping->flags & SEC_IMAGE) ||
req->start >= mapping->size ||
req->start + req->size < req->start ||
req->start + req->size > ((mapping->size + page_mask) & ~(mem_size_t)page_mask))
{
set_error( STATUS_INVALID_PARAMETER );
goto done;
@ -1242,11 +1235,47 @@ DECL_HANDLER(map_view)
view->namelen = 0;
view->fd = !is_fd_removable( mapping->fd ) ? (struct fd *)grab_object( mapping->fd ) : NULL;
view->committed = mapping->committed ? (struct ranges *)grab_object( mapping->committed ) : NULL;
view->shared = mapping->shared ? (struct shared_map *)grab_object( mapping->shared ) : NULL;
if (view->flags & SEC_IMAGE) view->image = mapping->image;
view->shared = NULL;
add_process_view( current, view );
if (view->flags & SEC_IMAGE && view->base != mapping->image.base)
set_error( STATUS_IMAGE_NOT_AT_BASE );
}
done:
release_object( mapping );
}
/* add a memory view for an image mapping in the current process */
DECL_HANDLER(map_image_view)
{
struct mapping *mapping;
struct memory_view *view;
if (!is_valid_view_addr( current->process, req->base, req->size ))
{
set_error( STATUS_INVALID_PARAMETER );
return;
}
if (!(mapping = get_mapping_obj( current->process, req->mapping, SECTION_MAP_READ ))) return;
if (!(mapping->flags & SEC_IMAGE) || req->size > mapping->image.map_size)
{
set_error( STATUS_INVALID_PARAMETER );
goto done;
}
if ((view = mem_alloc( sizeof(*view) )))
{
view->base = req->base;
view->size = req->size;
view->flags = mapping->flags;
view->start = 0;
view->namelen = 0;
view->fd = !is_fd_removable( mapping->fd ) ? (struct fd *)grab_object( mapping->fd ) : NULL;
view->committed = NULL;
view->shared = mapping->shared ? (struct shared_map *)grab_object( mapping->shared ) : NULL;
view->image = mapping->image;
add_process_view( current, view );
if (view->base != mapping->image.base) set_error( STATUS_IMAGE_NOT_AT_BASE );
}
done:

View file

@ -1607,6 +1607,14 @@ enum server_fd_type
@END
/* Add a memory view for an image mapping in the current process */
@REQ(map_image_view)
obj_handle_t mapping; /* file mapping handle */
client_ptr_t base; /* view base address (page-aligned) */
mem_size_t size; /* view size */
@END
/* Add a memory view for a builtin dll in the current process */
@REQ(map_builtin_view)
VARARG(image,pe_image_info);/* image info */

View file

@ -184,6 +184,7 @@ DECL_HANDLER(create_mapping);
DECL_HANDLER(open_mapping);
DECL_HANDLER(get_mapping_info);
DECL_HANDLER(map_view);
DECL_HANDLER(map_image_view);
DECL_HANDLER(map_builtin_view);
DECL_HANDLER(unmap_view);
DECL_HANDLER(get_mapping_committed_range);
@ -469,6 +470,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_open_mapping,
(req_handler)req_get_mapping_info,
(req_handler)req_map_view,
(req_handler)req_map_image_view,
(req_handler)req_map_builtin_view,
(req_handler)req_unmap_view,
(req_handler)req_get_mapping_committed_range,
@ -1121,6 +1123,10 @@ C_ASSERT( FIELD_OFFSET(struct map_view_request, base) == 24 );
C_ASSERT( FIELD_OFFSET(struct map_view_request, size) == 32 );
C_ASSERT( FIELD_OFFSET(struct map_view_request, start) == 40 );
C_ASSERT( sizeof(struct map_view_request) == 48 );
C_ASSERT( FIELD_OFFSET(struct map_image_view_request, mapping) == 12 );
C_ASSERT( FIELD_OFFSET(struct map_image_view_request, base) == 16 );
C_ASSERT( FIELD_OFFSET(struct map_image_view_request, size) == 24 );
C_ASSERT( sizeof(struct map_image_view_request) == 32 );
C_ASSERT( sizeof(struct map_builtin_view_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct unmap_view_request, base) == 16 );
C_ASSERT( sizeof(struct unmap_view_request) == 24 );

View file

@ -2180,6 +2180,13 @@ static void dump_map_view_request( const struct map_view_request *req )
dump_uint64( ", start=", &req->start );
}
static void dump_map_image_view_request( const struct map_image_view_request *req )
{
fprintf( stderr, " mapping=%04x", req->mapping );
dump_uint64( ", base=", &req->base );
dump_uint64( ", size=", &req->size );
}
static void dump_map_builtin_view_request( const struct map_builtin_view_request *req )
{
dump_varargs_pe_image_info( " image=", cur_size );
@ -4597,6 +4604,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_open_mapping_request,
(dump_func)dump_get_mapping_info_request,
(dump_func)dump_map_view_request,
(dump_func)dump_map_image_view_request,
(dump_func)dump_map_builtin_view_request,
(dump_func)dump_unmap_view_request,
(dump_func)dump_get_mapping_committed_range_request,
@ -4881,6 +4889,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
NULL,
NULL,
NULL,
NULL,
(dump_func)dump_get_mapping_committed_range_reply,
NULL,
NULL,
@ -5161,6 +5170,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"open_mapping",
"get_mapping_info",
"map_view",
"map_image_view",
"map_builtin_view",
"unmap_view",
"get_mapping_committed_range",