Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
a557934c
Commit
a557934c
authored
Sep 26, 2017
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Keep track of mapped memory views.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
d8232100
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
225 additions
and
7 deletions
+225
-7
virtual.c
dlls/ntdll/virtual.c
+38
-6
server_protocol.h
include/wine/server_protocol.h
+37
-1
file.h
server/file.h
+1
-0
mapping.c
server/mapping.c
+97
-0
process.c
server/process.c
+2
-0
process.h
server/process.h
+1
-0
protocol.def
server/protocol.def
+16
-0
request.h
server/request.h
+12
-0
trace.c
server/trace.c
+21
-0
No files found.
dlls/ntdll/virtual.c
View file @
a557934c
...
...
@@ -1329,8 +1329,8 @@ static NTSTATUS stat_mapping_file( struct file_view *view, struct stat *st )
*
* Map an executable (PE format) image into memory.
*/
static
NTSTATUS
map_image
(
HANDLE
hmapping
,
int
fd
,
char
*
base
,
SIZE_T
total_size
,
SIZE_T
mask
,
SIZE_T
header_size
,
int
shared_fd
,
HANDLE
dup_mapping
,
PVOID
*
addr_ptr
)
static
NTSTATUS
map_image
(
HANDLE
hmapping
,
ACCESS_MASK
access
,
int
fd
,
char
*
base
,
SIZE_T
total_size
,
SIZE_T
mask
,
SIZE_T
header_size
,
int
shared_fd
,
HANDLE
dup_mapping
,
PVOID
*
addr_ptr
)
{
IMAGE_DOS_HEADER
*
dos
;
IMAGE_NT_HEADERS
*
nt
;
...
...
@@ -1537,6 +1537,19 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz
done:
view
->
mapping
=
dup_mapping
;
SERVER_START_REQ
(
map_view
)
{
req
->
mapping
=
wine_server_obj_handle
(
hmapping
);
req
->
access
=
access
;
req
->
base
=
wine_server_client_ptr
(
view
->
base
);
req
->
size
=
view
->
size
;
req
->
start
=
0
;
status
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
if
(
status
)
goto
error
;
VIRTUAL_DEBUG_DUMP_VIEW
(
view
);
server_leave_uninterrupted_section
(
&
csVirtual
,
&
sigset
);
...
...
@@ -2930,14 +2943,14 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
if
((
res
=
server_get_unix_fd
(
shared_file
,
FILE_READ_DATA
|
FILE_WRITE_DATA
,
&
shared_fd
,
&
shared_needs_close
,
NULL
,
NULL
)))
goto
done
;
res
=
map_image
(
handle
,
unix_handle
,
base
,
size
,
mask
,
image_info
.
header_size
,
res
=
map_image
(
handle
,
access
,
unix_handle
,
base
,
size
,
mask
,
image_info
.
header_size
,
shared_fd
,
dup_mapping
,
addr_ptr
);
if
(
shared_needs_close
)
close
(
shared_fd
);
close_handle
(
shared_file
);
}
else
{
res
=
map_image
(
handle
,
unix_handle
,
base
,
size
,
mask
,
image_info
.
header_size
,
res
=
map_image
(
handle
,
access
,
unix_handle
,
base
,
size
,
mask
,
image_info
.
header_size
,
-
1
,
dup_mapping
,
addr_ptr
);
}
if
(
needs_close
)
close
(
unix_handle
);
...
...
@@ -2990,6 +3003,20 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
res
=
map_file_into_view
(
view
,
unix_handle
,
0
,
size
,
offset
.
QuadPart
,
vprot
,
!
dup_mapping
);
if
(
res
==
STATUS_SUCCESS
)
{
SERVER_START_REQ
(
map_view
)
{
req
->
mapping
=
wine_server_obj_handle
(
handle
);
req
->
access
=
access
;
req
->
base
=
wine_server_client_ptr
(
view
->
base
);
req
->
size
=
size
;
req
->
start
=
offset
.
QuadPart
;
res
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
}
if
(
res
==
STATUS_SUCCESS
)
{
*
addr_ptr
=
view
->
base
;
*
size_ptr
=
size
;
view
->
mapping
=
dup_mapping
;
...
...
@@ -3039,8 +3066,13 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
server_enter_uninterrupted_section
(
&
csVirtual
,
&
sigset
);
if
((
view
=
VIRTUAL_FindView
(
addr
,
0
))
&&
!
is_view_valloc
(
view
))
{
delete_view
(
view
);
status
=
STATUS_SUCCESS
;
SERVER_START_REQ
(
unmap_view
)
{
req
->
base
=
wine_server_client_ptr
(
view
->
base
);
status
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
if
(
!
status
)
delete_view
(
view
);
}
server_leave_uninterrupted_section
(
&
csVirtual
,
&
sigset
);
return
status
;
...
...
include/wine/server_protocol.h
View file @
a557934c
...
...
@@ -2228,6 +2228,36 @@ struct get_mapping_info_reply
struct
map_view_request
{
struct
request_header
__header
;
obj_handle_t
mapping
;
unsigned
int
access
;
char
__pad_20
[
4
];
client_ptr_t
base
;
mem_size_t
size
;
file_pos_t
start
;
};
struct
map_view_reply
{
struct
reply_header
__header
;
};
struct
unmap_view_request
{
struct
request_header
__header
;
char
__pad_12
[
4
];
client_ptr_t
base
;
};
struct
unmap_view_reply
{
struct
reply_header
__header
;
};
struct
get_mapping_committed_range_request
{
struct
request_header
__header
;
...
...
@@ -5626,6 +5656,8 @@ enum request
REQ_create_mapping
,
REQ_open_mapping
,
REQ_get_mapping_info
,
REQ_map_view
,
REQ_unmap_view
,
REQ_get_mapping_committed_range
,
REQ_add_mapping_committed_range
,
REQ_create_snapshot
,
...
...
@@ -5917,6 +5949,8 @@ union generic_request
struct
create_mapping_request
create_mapping_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
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
;
struct
create_snapshot_request
create_snapshot_request
;
...
...
@@ -6206,6 +6240,8 @@ union generic_reply
struct
create_mapping_reply
create_mapping_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
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
;
struct
create_snapshot_reply
create_snapshot_reply
;
...
...
@@ -6408,6 +6444,6 @@ union generic_reply
struct
terminate_job_reply
terminate_job_reply
;
};
#define SERVER_PROTOCOL_VERSION 53
7
#define SERVER_PROTOCOL_VERSION 53
8
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/file.h
View file @
a557934c
...
...
@@ -150,6 +150,7 @@ extern struct mapping *get_mapping_obj( struct process *process, obj_handle_t ha
extern
obj_handle_t
open_mapping_file
(
struct
process
*
process
,
struct
mapping
*
mapping
,
unsigned
int
access
,
unsigned
int
sharing
);
extern
struct
mapping
*
grab_mapping_unless_removable
(
struct
mapping
*
mapping
);
extern
void
free_mapped_views
(
struct
process
*
process
);
extern
int
get_page_size
(
void
);
/* device functions */
...
...
server/mapping.c
View file @
a557934c
...
...
@@ -55,6 +55,16 @@ struct ranges
}
ranges
[
1
];
};
/* memory view mapped in client address space */
struct
memory_view
{
struct
list
entry
;
/* entry in per-process view list */
unsigned
int
flags
;
/* SEC_* flags */
client_ptr_t
base
;
/* view base address (in process addr space) */
mem_size_t
size
;
/* view size */
file_pos_t
start
;
/* start offset in mapping */
};
struct
mapping
{
struct
object
obj
;
/* object header */
...
...
@@ -196,6 +206,33 @@ static int create_temp_file( file_pos_t size )
return
fd
;
}
/* find a memory view from its base address */
static
struct
memory_view
*
find_mapped_view
(
struct
process
*
process
,
client_ptr_t
base
)
{
struct
memory_view
*
view
;
LIST_FOR_EACH_ENTRY
(
view
,
&
process
->
views
,
struct
memory_view
,
entry
)
if
(
view
->
base
==
base
)
return
view
;
set_error
(
STATUS_NOT_MAPPED_VIEW
);
return
NULL
;
}
static
void
free_memory_view
(
struct
memory_view
*
view
)
{
list_remove
(
&
view
->
entry
);
free
(
view
);
}
/* free all mapped views at process exit */
void
free_mapped_views
(
struct
process
*
process
)
{
struct
list
*
ptr
;
while
((
ptr
=
list_head
(
&
process
->
views
)))
free_memory_view
(
LIST_ENTRY
(
ptr
,
struct
memory_view
,
entry
));
}
/* find the shared PE mapping for a given mapping */
static
struct
file
*
get_shared_file
(
struct
mapping
*
mapping
)
{
...
...
@@ -776,6 +813,66 @@ DECL_HANDLER(get_mapping_info)
release_object
(
mapping
);
}
/* add a memory view in the current process */
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 */
{
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
(
!
(
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
))
{
set_error
(
STATUS_INVALID_PARAMETER
);
goto
done
;
}
if
((
view
=
mem_alloc
(
sizeof
(
*
view
)
)))
{
view
->
base
=
req
->
base
;
view
->
size
=
req
->
size
;
view
->
start
=
req
->
start
;
view
->
flags
=
mapping
->
flags
;
list_add_tail
(
&
current
->
process
->
views
,
&
view
->
entry
);
}
done
:
release_object
(
mapping
);
}
/* unmap a memory view from the current process */
DECL_HANDLER
(
unmap_view
)
{
struct
memory_view
*
view
=
find_mapped_view
(
current
->
process
,
req
->
base
);
if
(
view
)
free_memory_view
(
view
);
}
/* get a range of committed pages in a file mapping */
DECL_HANDLER
(
get_mapping_committed_range
)
{
...
...
server/process.c
View file @
a557934c
...
...
@@ -537,6 +537,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit
list_init
(
&
process
->
locks
);
list_init
(
&
process
->
asyncs
);
list_init
(
&
process
->
classes
);
list_init
(
&
process
->
views
);
list_init
(
&
process
->
dlls
);
list_init
(
&
process
->
rawinput_devices
);
...
...
@@ -871,6 +872,7 @@ static void process_killed( struct process *process )
free
(
dll
);
}
destroy_process_classes
(
process
);
free_mapped_views
(
process
);
free_process_user_handles
(
process
);
remove_process_locks
(
process
);
set_process_startup_state
(
process
,
STARTUP_ABORTED
);
...
...
server/process.h
View file @
a557934c
...
...
@@ -88,6 +88,7 @@ struct process
obj_handle_t
winstation
;
/* main handle to process window station */
obj_handle_t
desktop
;
/* handle to desktop to use for new threads */
struct
token
*
token
;
/* security token associated with this process */
struct
list
views
;
/* list of memory views */
struct
list
dlls
;
/* list of loaded dlls */
client_ptr_t
peb
;
/* PEB address in client address space */
client_ptr_t
ldt_copy
;
/* pointer to LDT copy in client addr space */
...
...
server/protocol.def
View file @
a557934c
...
...
@@ -1726,6 +1726,22 @@ enum char_info_mode
@END
/* Add a memory view in the current process */
@REQ(map_view)
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 */
@END
/* Unmap a memory view from the current process */
@REQ(unmap_view)
client_ptr_t base; /* view base address */
@END
/* Get a range of committed pages in a file mapping */
@REQ(get_mapping_committed_range)
obj_handle_t handle; /* handle to the mapping */
...
...
server/request.h
View file @
a557934c
...
...
@@ -196,6 +196,8 @@ DECL_HANDLER(read_change);
DECL_HANDLER
(
create_mapping
);
DECL_HANDLER
(
open_mapping
);
DECL_HANDLER
(
get_mapping_info
);
DECL_HANDLER
(
map_view
);
DECL_HANDLER
(
unmap_view
);
DECL_HANDLER
(
get_mapping_committed_range
);
DECL_HANDLER
(
add_mapping_committed_range
);
DECL_HANDLER
(
create_snapshot
);
...
...
@@ -486,6 +488,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(
req_handler
)
req_create_mapping
,
(
req_handler
)
req_open_mapping
,
(
req_handler
)
req_get_mapping_info
,
(
req_handler
)
req_map_view
,
(
req_handler
)
req_unmap_view
,
(
req_handler
)
req_get_mapping_committed_range
,
(
req_handler
)
req_add_mapping_committed_range
,
(
req_handler
)
req_create_snapshot
,
...
...
@@ -1266,6 +1270,14 @@ C_ASSERT( FIELD_OFFSET(struct get_mapping_info_reply, flags) == 16 );
C_ASSERT
(
FIELD_OFFSET
(
struct
get_mapping_info_reply
,
mapping
)
==
20
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_mapping_info_reply
,
shared_file
)
==
24
);
C_ASSERT
(
sizeof
(
struct
get_mapping_info_reply
)
==
32
);
C_ASSERT
(
FIELD_OFFSET
(
struct
map_view_request
,
mapping
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
map_view_request
,
access
)
==
16
);
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
unmap_view_request
,
base
)
==
16
);
C_ASSERT
(
sizeof
(
struct
unmap_view_request
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_mapping_committed_range_request
,
handle
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_mapping_committed_range_request
,
offset
)
==
16
);
C_ASSERT
(
sizeof
(
struct
get_mapping_committed_range_request
)
==
24
);
...
...
server/trace.c
View file @
a557934c
...
...
@@ -2243,6 +2243,20 @@ static void dump_get_mapping_info_reply( const struct get_mapping_info_reply *re
dump_varargs_pe_image_info
(
", image="
,
cur_size
);
}
static
void
dump_map_view_request
(
const
struct
map_view_request
*
req
)
{
fprintf
(
stderr
,
" mapping=%04x"
,
req
->
mapping
);
fprintf
(
stderr
,
", access=%08x"
,
req
->
access
);
dump_uint64
(
", base="
,
&
req
->
base
);
dump_uint64
(
", size="
,
&
req
->
size
);
dump_uint64
(
", start="
,
&
req
->
start
);
}
static
void
dump_unmap_view_request
(
const
struct
unmap_view_request
*
req
)
{
dump_uint64
(
" base="
,
&
req
->
base
);
}
static
void
dump_get_mapping_committed_range_request
(
const
struct
get_mapping_committed_range_request
*
req
)
{
fprintf
(
stderr
,
" handle=%04x"
,
req
->
handle
);
...
...
@@ -4553,6 +4567,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_create_mapping_request
,
(
dump_func
)
dump_open_mapping_request
,
(
dump_func
)
dump_get_mapping_info_request
,
(
dump_func
)
dump_map_view_request
,
(
dump_func
)
dump_unmap_view_request
,
(
dump_func
)
dump_get_mapping_committed_range_request
,
(
dump_func
)
dump_add_mapping_committed_range_request
,
(
dump_func
)
dump_create_snapshot_request
,
...
...
@@ -4840,6 +4856,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_create_mapping_reply
,
(
dump_func
)
dump_open_mapping_reply
,
(
dump_func
)
dump_get_mapping_info_reply
,
NULL
,
NULL
,
(
dump_func
)
dump_get_mapping_committed_range_reply
,
NULL
,
(
dump_func
)
dump_create_snapshot_reply
,
...
...
@@ -5127,6 +5145,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"create_mapping"
,
"open_mapping"
,
"get_mapping_info"
,
"map_view"
,
"unmap_view"
,
"get_mapping_committed_range"
,
"add_mapping_committed_range"
,
"create_snapshot"
,
...
...
@@ -5407,6 +5427,7 @@ static const struct
{
"NOT_A_DIRECTORY"
,
STATUS_NOT_A_DIRECTORY
},
{
"NOT_FOUND"
,
STATUS_NOT_FOUND
},
{
"NOT_IMPLEMENTED"
,
STATUS_NOT_IMPLEMENTED
},
{
"NOT_MAPPED_VIEW"
,
STATUS_NOT_MAPPED_VIEW
},
{
"NOT_REGISTRY_FILE"
,
STATUS_NOT_REGISTRY_FILE
},
{
"NOT_SUPPORTED"
,
STATUS_NOT_SUPPORTED
},
{
"NO_DATA_DETECTED"
,
STATUS_NO_DATA_DETECTED
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment