server: Add a separate request to create a memory view for a .so builtin.

This commit is contained in:
Alexandre Julliard 2023-05-12 15:07:30 +02:00
parent fddd7aab7c
commit 8f9c0c825d
6 changed files with 87 additions and 39 deletions

View file

@ -3107,17 +3107,15 @@ NTSTATUS virtual_create_builtin_view( void *module, const UNICODE_STRING *nt_nam
set_page_vprot( (char *)base + sec[i].VirtualAddress, sec[i].Misc.VirtualSize, flags );
}
SERVER_START_REQ( map_view )
SERVER_START_REQ( map_builtin_view )
{
req->base = wine_server_client_ptr( view->base );
req->size = size;
wine_server_add_data( req, info, sizeof(*info) );
wine_server_add_data( req, nt_name->Buffer, nt_name->Length );
status = wine_server_call( req );
}
SERVER_END_REQ;
if (status >= 0)
if (!status)
{
add_builtin_module( view->base, so_handle );
VIRTUAL_DEBUG_DUMP_VIEW( view );

View file

@ -1982,8 +1982,6 @@ struct map_view_request
client_ptr_t base;
mem_size_t size;
file_pos_t start;
/* VARARG(image,pe_image_info); */
/* VARARG(name,unicode_str); */
};
struct map_view_reply
{
@ -1992,6 +1990,20 @@ struct map_view_reply
struct map_builtin_view_request
{
struct request_header __header;
/* VARARG(image,pe_image_info); */
/* VARARG(name,unicode_str); */
char __pad_12[4];
};
struct map_builtin_view_reply
{
struct reply_header __header;
};
struct unmap_view_request
{
struct request_header __header;
@ -5593,6 +5605,7 @@ enum request
REQ_open_mapping,
REQ_get_mapping_info,
REQ_map_view,
REQ_map_builtin_view,
REQ_unmap_view,
REQ_get_mapping_committed_range,
REQ_add_mapping_committed_range,
@ -5878,6 +5891,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_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;
struct add_mapping_committed_range_request add_mapping_committed_range_request;
@ -6161,6 +6175,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_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;
struct add_mapping_committed_range_reply add_mapping_committed_range_reply;
@ -6378,7 +6393,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 764
#define SERVER_PROTOCOL_VERSION 765
/* ### protocol_version end ### */

View file

@ -358,6 +358,25 @@ static struct memory_view *find_mapped_addr( struct process *process, client_ptr
return NULL;
}
/* check if an address range is valid for creating a view */
static int is_valid_view_addr( struct process *process, client_ptr_t addr, mem_size_t size )
{
struct memory_view *view;
if (!size) return 0;
if (addr & page_mask) return 0;
if (addr + size < addr) return 0; /* overflow */
/* check for overlapping view */
LIST_FOR_EACH_ENTRY( view, &process->views, struct memory_view, entry )
{
if (view->base + view->size <= addr) continue;
if (view->base >= addr + size) continue;
return 0;
}
return 1;
}
/* get the main exe memory view */
struct memory_view *get_exe_view( struct process *process )
{
@ -1190,39 +1209,12 @@ DECL_HANDLER(map_view)
struct mapping *mapping = NULL;
struct memory_view *view;
if (!req->size || (req->base & page_mask) || req->base + req->size < req->base) /* overflow */
if (!is_valid_view_addr( current->process, req->base, req->size ))
{
set_error( STATUS_INVALID_PARAMETER );
return;
}
/* make sure we don't already have an overlapping view */
LIST_FOR_EACH_ENTRY( view, &current->process->views, struct memory_view, entry )
{
if (view->base + view->size <= req->base) continue;
if (view->base >= req->base + req->size) continue;
set_error( STATUS_INVALID_PARAMETER );
return;
}
if (!req->mapping) /* image mapping for a .so dll */
{
data_size_t namelen = 0;
if (get_req_data_size() > sizeof(view->image)) namelen = get_req_data_size() - sizeof(view->image);
if (!(view = mem_alloc( sizeof(struct memory_view) + namelen * sizeof(WCHAR) ))) return;
memset( view, 0, sizeof(*view) );
view->base = req->base;
view->size = req->size;
view->start = req->start;
view->flags = SEC_IMAGE;
view->namelen = namelen;
memcpy( &view->image, get_req_data(), min( sizeof(view->image), get_req_data_size() ));
memcpy( view->name, (pe_image_info_t *)get_req_data() + 1, namelen );
add_process_view( current, view );
return;
}
if (!(mapping = get_mapping_obj( current->process, req->mapping, req->access ))) return;
if (mapping->flags & SEC_IMAGE)
@ -1261,6 +1253,34 @@ done:
release_object( mapping );
}
/* add a memory view for a builtin dll in the current process */
DECL_HANDLER(map_builtin_view)
{
struct memory_view *view;
const pe_image_info_t *image = get_req_data();
data_size_t namelen = get_req_data_size() - sizeof(*image);
if (get_req_data_size() < sizeof(*image) ||
(namelen & (sizeof(WCHAR) - 1)) ||
!is_valid_view_addr( current->process, image->base, image->map_size ))
{
set_error( STATUS_INVALID_PARAMETER );
return;
}
if ((view = mem_alloc( sizeof(struct memory_view) + namelen )))
{
memset( view, 0, sizeof(*view) );
view->base = image->base;
view->size = image->map_size;
view->flags = SEC_IMAGE;
view->image = *image;
view->namelen = namelen;
memcpy( view->name, image + 1, namelen );
add_process_view( current, view );
}
}
/* unmap a memory view from the current process */
DECL_HANDLER(unmap_view)
{

View file

@ -1597,13 +1597,18 @@ enum server_fd_type
/* Add a memory view in the current process */
@REQ(map_view)
obj_handle_t mapping; /* file mapping handle, or 0 for .so builtin */
obj_handle_t mapping; /* file mapping handle */
unsigned int access; /* wanted access rights */
client_ptr_t base; /* view base address (page-aligned) */
mem_size_t size; /* view size */
file_pos_t start; /* start offset in mapping */
VARARG(image,pe_image_info);/* image info for .so builtins */
VARARG(name,unicode_str); /* image filename for .so builtins */
@END
/* Add a memory view for a builtin dll in the current process */
@REQ(map_builtin_view)
VARARG(image,pe_image_info);/* image info */
VARARG(name,unicode_str); /* image filename */
@END

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_builtin_view);
DECL_HANDLER(unmap_view);
DECL_HANDLER(get_mapping_committed_range);
DECL_HANDLER(add_mapping_committed_range);
@ -468,6 +469,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_builtin_view,
(req_handler)req_unmap_view,
(req_handler)req_get_mapping_committed_range,
(req_handler)req_add_mapping_committed_range,
@ -1118,6 +1120,7 @@ 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( 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 );
C_ASSERT( FIELD_OFFSET(struct get_mapping_committed_range_request, base) == 16 );

View file

@ -2176,7 +2176,11 @@ static void dump_map_view_request( const struct map_view_request *req )
dump_uint64( ", base=", &req->base );
dump_uint64( ", size=", &req->size );
dump_uint64( ", start=", &req->start );
dump_varargs_pe_image_info( ", image=", cur_size );
}
static void dump_map_builtin_view_request( const struct map_builtin_view_request *req )
{
dump_varargs_pe_image_info( " image=", cur_size );
dump_varargs_unicode_str( ", name=", cur_size );
}
@ -4591,6 +4595,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_builtin_view_request,
(dump_func)dump_unmap_view_request,
(dump_func)dump_get_mapping_committed_range_request,
(dump_func)dump_add_mapping_committed_range_request,
@ -4873,6 +4878,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_mapping_info_reply,
NULL,
NULL,
NULL,
(dump_func)dump_get_mapping_committed_range_reply,
NULL,
NULL,
@ -5153,6 +5159,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"open_mapping",
"get_mapping_info",
"map_view",
"map_builtin_view",
"unmap_view",
"get_mapping_committed_range",
"add_mapping_committed_range",