server: Add a separate request to create a memory view for an image mapping.
This commit is contained in:
parent
d84704192e
commit
c306e76645
6 changed files with 95 additions and 26 deletions
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Add table
Reference in a new issue