ntdll: Determine the mapping type automatically from the WRITECOPY flag.

This commit is contained in:
Alexandre Julliard 2014-05-13 12:28:58 +02:00
parent 5ceb22714e
commit 2cef8dbcc2
1 changed files with 10 additions and 12 deletions

View File

@ -854,10 +854,11 @@ done:
* The csVirtual section must be held by caller. * The csVirtual section must be held by caller.
*/ */
static NTSTATUS map_file_into_view( struct file_view *view, int fd, size_t start, size_t size, static NTSTATUS map_file_into_view( struct file_view *view, int fd, size_t start, size_t size,
off_t offset, unsigned int vprot, int flags, BOOL removable ) off_t offset, unsigned int vprot, BOOL removable )
{ {
void *ptr; void *ptr;
int prot = VIRTUAL_GetUnixProt( vprot | VPROT_COMMITTED /* make sure it is accessible */ ); int prot = VIRTUAL_GetUnixProt( vprot | VPROT_COMMITTED /* make sure it is accessible */ );
unsigned int flags = MAP_FIXED | ((vprot & VPROT_WRITECOPY) ? MAP_PRIVATE : MAP_SHARED);
assert( start < view->size ); assert( start < view->size );
assert( start + size <= view->size ); assert( start + size <= view->size );
@ -872,7 +873,7 @@ static NTSTATUS map_file_into_view( struct file_view *view, int fd, size_t start
/* only try mmap if media is not removable (or if we require write access) */ /* only try mmap if media is not removable (or if we require write access) */
if (!removable || (flags & MAP_SHARED)) if (!removable || (flags & MAP_SHARED))
{ {
if (mmap( (char *)view->base + start, size, prot, flags | MAP_FIXED, fd, offset ) != (void *)-1) if (mmap( (char *)view->base + start, size, prot, flags, fd, offset ) != (void *)-1)
goto done; goto done;
if ((errno == EPERM) && (prot & PROT_EXEC)) if ((errno == EPERM) && (prot & PROT_EXEC))
@ -1094,7 +1095,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz
if (!st.st_size) goto error; if (!st.st_size) goto error;
header_size = min( header_size, st.st_size ); header_size = min( header_size, st.st_size );
if (map_file_into_view( view, fd, 0, header_size, 0, VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY, if (map_file_into_view( view, fd, 0, header_size, 0, VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY,
MAP_PRIVATE, !dup_mapping ) != STATUS_SUCCESS) goto error; !dup_mapping ) != STATUS_SUCCESS) goto error;
dos = (IMAGE_DOS_HEADER *)ptr; dos = (IMAGE_DOS_HEADER *)ptr;
nt = (IMAGE_NT_HEADERS *)(ptr + dos->e_lfanew); nt = (IMAGE_NT_HEADERS *)(ptr + dos->e_lfanew);
header_end = ptr + ROUND_SIZE( 0, header_size ); header_end = ptr + ROUND_SIZE( 0, header_size );
@ -1118,8 +1119,8 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz
/* unaligned sections, this happens for native subsystem binaries */ /* unaligned sections, this happens for native subsystem binaries */
/* in that case Windows simply maps in the whole file */ /* in that case Windows simply maps in the whole file */
if (map_file_into_view( view, fd, 0, total_size, 0, VPROT_COMMITTED | VPROT_READ, if (map_file_into_view( view, fd, 0, total_size, 0, VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY,
MAP_PRIVATE, !dup_mapping ) != STATUS_SUCCESS) goto error; !dup_mapping ) != STATUS_SUCCESS) goto error;
/* check that all sections are loaded at the right offset */ /* check that all sections are loaded at the right offset */
if (nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment) goto error; if (nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment) goto error;
@ -1172,8 +1173,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz
sec->PointerToRawData, (int)pos, file_size, map_size, sec->PointerToRawData, (int)pos, file_size, map_size,
sec->Characteristics ); sec->Characteristics );
if (map_file_into_view( view, shared_fd, sec->VirtualAddress, map_size, pos, if (map_file_into_view( view, shared_fd, sec->VirtualAddress, map_size, pos,
VPROT_COMMITTED | VPROT_READ | VPROT_WRITE, VPROT_COMMITTED | VPROT_READ | VPROT_WRITE, FALSE ) != STATUS_SUCCESS)
MAP_SHARED, FALSE ) != STATUS_SUCCESS)
{ {
ERR_(module)( "Could not map shared section %.8s\n", sec->Name ); ERR_(module)( "Could not map shared section %.8s\n", sec->Name );
goto error; goto error;
@ -1189,8 +1189,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz
if (end > base) if (end > base)
map_file_into_view( view, shared_fd, base, end - base, map_file_into_view( view, shared_fd, base, end - base,
pos + (base - sec->VirtualAddress), pos + (base - sec->VirtualAddress),
VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY, VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY, FALSE );
MAP_PRIVATE, FALSE );
} }
pos += map_size; pos += map_size;
continue; continue;
@ -1212,7 +1211,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz
end < file_start || end < file_start ||
map_file_into_view( view, fd, sec->VirtualAddress, file_size, file_start, map_file_into_view( view, fd, sec->VirtualAddress, file_size, file_start,
VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY, VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY,
MAP_PRIVATE, !dup_mapping ) != STATUS_SUCCESS) !dup_mapping ) != STATUS_SUCCESS)
{ {
ERR_(module)( "Could not map section %.8s, file probably truncated\n", sec->Name ); ERR_(module)( "Could not map section %.8s, file probably truncated\n", sec->Name );
goto error; goto error;
@ -2627,8 +2626,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
TRACE("handle=%p size=%lx offset=%x%08x\n", TRACE("handle=%p size=%lx offset=%x%08x\n",
handle, size, offset.u.HighPart, offset.u.LowPart ); handle, size, offset.u.HighPart, offset.u.LowPart );
res = map_file_into_view( view, unix_handle, 0, size, offset.QuadPart, vprot, res = map_file_into_view( view, unix_handle, 0, size, offset.QuadPart, vprot, !dup_mapping );
(vprot & VPROT_WRITECOPY) ? MAP_PRIVATE : MAP_SHARED, !dup_mapping );
if (res == STATUS_SUCCESS) if (res == STATUS_SUCCESS)
{ {
*addr_ptr = view->base; *addr_ptr = view->base;