Commit 4cbe867a authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Duplicate the mapping handle on the server side for NtMapViewOfSection.

parent 5bd51364
...@@ -934,7 +934,7 @@ static int do_relocations( char *base, const IMAGE_DATA_DIRECTORY *dir, ...@@ -934,7 +934,7 @@ static int do_relocations( char *base, const IMAGE_DATA_DIRECTORY *dir,
* Map an executable (PE format) image into memory. * 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, static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_size, SIZE_T mask,
SIZE_T header_size, int shared_fd, BOOL removable, PVOID *addr_ptr ) SIZE_T header_size, int shared_fd, HANDLE dup_mapping, PVOID *addr_ptr )
{ {
IMAGE_DOS_HEADER *dos; IMAGE_DOS_HEADER *dos;
IMAGE_NT_HEADERS *nt; IMAGE_NT_HEADERS *nt;
...@@ -975,7 +975,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz ...@@ -975,7 +975,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,
removable ) != 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 );
...@@ -1019,7 +1019,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz ...@@ -1019,7 +1019,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz
/* 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,
removable ) != 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;
...@@ -1121,7 +1121,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz ...@@ -1121,7 +1121,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,
removable ) != 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;
...@@ -1195,11 +1195,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz ...@@ -1195,11 +1195,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz
} }
done: done:
if (!removable) /* don't keep handle open on removable media */ view->mapping = dup_mapping;
NtDuplicateObject( NtCurrentProcess(), hmapping,
NtCurrentProcess(), &view->mapping,
0, 0, DUPLICATE_SAME_ACCESS );
RtlLeaveCriticalSection( &csVirtual ); RtlLeaveCriticalSection( &csVirtual );
*addr_ptr = ptr; *addr_ptr = ptr;
...@@ -1208,6 +1204,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz ...@@ -1208,6 +1204,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz
error: error:
if (view) delete_view( view ); if (view) delete_view( view );
RtlLeaveCriticalSection( &csVirtual ); RtlLeaveCriticalSection( &csVirtual );
if (dup_mapping) NtClose( dup_mapping );
return status; return status;
} }
...@@ -1837,13 +1834,12 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p ...@@ -1837,13 +1834,12 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
NTSTATUS res; NTSTATUS res;
SIZE_T size = 0; SIZE_T size = 0;
SIZE_T mask = get_mask( zero_bits ); SIZE_T mask = get_mask( zero_bits );
int unix_handle = -1, flags, needs_close; int unix_handle = -1, needs_close;
int prot; int prot;
void *base; void *base;
struct file_view *view; struct file_view *view;
DWORD size_low, size_high, header_size, shared_size; DWORD size_low, size_high, header_size, shared_size;
HANDLE shared_file; HANDLE dup_mapping, shared_file;
BOOL removable = FALSE;
LARGE_INTEGER offset; LARGE_INTEGER offset;
offset.QuadPart = offset_ptr ? offset_ptr->QuadPart : 0; offset.QuadPart = offset_ptr ? offset_ptr->QuadPart : 0;
...@@ -1871,14 +1867,14 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p ...@@ -1871,14 +1867,14 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
size_low = reply->size_low; size_low = reply->size_low;
size_high = reply->size_high; size_high = reply->size_high;
header_size = reply->header_size; header_size = reply->header_size;
dup_mapping = reply->mapping;
shared_file = reply->shared_file; shared_file = reply->shared_file;
shared_size = reply->shared_size; shared_size = reply->shared_size;
} }
SERVER_END_REQ; SERVER_END_REQ;
if (res) return res; if (res) return res;
if ((res = server_get_unix_fd( handle, 0, &unix_handle, &needs_close, NULL, &flags ))) return res; if ((res = server_get_unix_fd( handle, 0, &unix_handle, &needs_close, NULL, NULL ))) goto done;
removable = (flags & FD_FLAG_REMOVABLE) != 0;
if (prot & VPROT_IMAGE) if (prot & VPROT_IMAGE)
{ {
...@@ -1889,14 +1885,14 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p ...@@ -1889,14 +1885,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, if ((res = server_get_unix_fd( shared_file, FILE_READ_DATA|FILE_WRITE_DATA,
&shared_fd, &shared_needs_close, NULL, NULL ))) goto done; &shared_fd, &shared_needs_close, NULL, NULL ))) goto done;
res = map_image( handle, unix_handle, base, size_low, mask, header_size, res = map_image( handle, unix_handle, base, size_low, mask, header_size,
shared_fd, removable, addr_ptr ); shared_fd, dup_mapping, addr_ptr );
if (shared_needs_close) close( shared_fd ); if (shared_needs_close) close( shared_fd );
NtClose( shared_file ); NtClose( shared_file );
} }
else else
{ {
res = map_image( handle, unix_handle, base, size_low, mask, header_size, res = map_image( handle, unix_handle, base, size_low, mask, header_size,
-1, removable, addr_ptr ); -1, dup_mapping, addr_ptr );
} }
if (needs_close) close( unix_handle ); if (needs_close) close( unix_handle );
if (!res) *size_ptr = size_low; if (!res) *size_ptr = size_low;
...@@ -1926,7 +1922,6 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p ...@@ -1926,7 +1922,6 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
res = STATUS_INVALID_PARAMETER; res = STATUS_INVALID_PARAMETER;
goto done; goto done;
} }
removable = FALSE;
/* fall through */ /* fall through */
case PAGE_READONLY: case PAGE_READONLY:
case PAGE_WRITECOPY: case PAGE_WRITECOPY:
...@@ -1964,16 +1959,13 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p ...@@ -1964,16 +1959,13 @@ 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, prot, removable ); res = map_file_into_view( view, unix_handle, 0, size, offset.QuadPart, prot, !dup_mapping );
if (res == STATUS_SUCCESS) if (res == STATUS_SUCCESS)
{ {
if (!removable) /* don't keep handle open on removable media */
NtDuplicateObject( NtCurrentProcess(), handle,
NtCurrentProcess(), &view->mapping,
0, 0, DUPLICATE_SAME_ACCESS );
*addr_ptr = view->base; *addr_ptr = view->base;
*size_ptr = size; *size_ptr = size;
view->mapping = dup_mapping;
dup_mapping = 0; /* don't close it */
} }
else else
{ {
...@@ -1985,6 +1977,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p ...@@ -1985,6 +1977,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
RtlLeaveCriticalSection( &csVirtual ); RtlLeaveCriticalSection( &csVirtual );
done: done:
if (dup_mapping) NtClose( dup_mapping );
if (needs_close) close( unix_handle ); if (needs_close) close( unix_handle );
return res; return res;
} }
......
...@@ -1535,6 +1535,7 @@ struct get_mapping_info_reply ...@@ -1535,6 +1535,7 @@ struct get_mapping_info_reply
int protect; int protect;
int header_size; int header_size;
void* base; void* base;
obj_handle_t mapping;
obj_handle_t shared_file; obj_handle_t shared_file;
int shared_size; int shared_size;
}; };
...@@ -4436,6 +4437,6 @@ union generic_reply ...@@ -4436,6 +4437,6 @@ union generic_reply
struct query_symlink_reply query_symlink_reply; struct query_symlink_reply query_symlink_reply;
}; };
#define SERVER_PROTOCOL_VERSION 263 #define SERVER_PROTOCOL_VERSION 264
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -432,6 +432,7 @@ DECL_HANDLER(open_mapping) ...@@ -432,6 +432,7 @@ DECL_HANDLER(open_mapping)
DECL_HANDLER(get_mapping_info) DECL_HANDLER(get_mapping_info)
{ {
struct mapping *mapping; struct mapping *mapping;
struct fd *fd;
if ((mapping = (struct mapping *)get_handle_obj( current->process, req->handle, if ((mapping = (struct mapping *)get_handle_obj( current->process, req->handle,
0, &mapping_ops ))) 0, &mapping_ops )))
...@@ -443,9 +444,20 @@ DECL_HANDLER(get_mapping_info) ...@@ -443,9 +444,20 @@ DECL_HANDLER(get_mapping_info)
reply->base = mapping->base; reply->base = mapping->base;
reply->shared_file = 0; reply->shared_file = 0;
reply->shared_size = mapping->shared_size; reply->shared_size = mapping->shared_size;
if ((fd = get_obj_fd( &mapping->obj )))
{
if (!is_fd_removable(fd))
reply->mapping = alloc_handle( current->process, mapping, 0, 0 );
release_object( fd );
}
if (mapping->shared_file) if (mapping->shared_file)
reply->shared_file = alloc_handle( current->process, mapping->shared_file, {
GENERIC_READ|GENERIC_WRITE, 0 ); if (!(reply->shared_file = alloc_handle( current->process, mapping->shared_file,
GENERIC_READ|GENERIC_WRITE, 0 )))
{
if (reply->mapping) close_handle( current->process, reply->mapping );
}
}
release_object( mapping ); release_object( mapping );
} }
} }
...@@ -1159,6 +1159,7 @@ enum char_info_mode ...@@ -1159,6 +1159,7 @@ enum char_info_mode
int protect; /* protection flags */ int protect; /* protection flags */
int header_size; /* header size (for VPROT_IMAGE mapping) */ int header_size; /* header size (for VPROT_IMAGE mapping) */
void* base; /* default base addr (for VPROT_IMAGE mapping) */ void* base; /* default base addr (for VPROT_IMAGE mapping) */
obj_handle_t mapping; /* duplicate mapping handle unless removable */
obj_handle_t shared_file; /* shared mapping file handle */ obj_handle_t shared_file; /* shared mapping file handle */
int shared_size; /* shared mapping size */ int shared_size; /* shared mapping size */
@END @END
......
...@@ -1570,6 +1570,7 @@ static void dump_get_mapping_info_reply( const struct get_mapping_info_reply *re ...@@ -1570,6 +1570,7 @@ static void dump_get_mapping_info_reply( const struct get_mapping_info_reply *re
fprintf( stderr, " protect=%d,", req->protect ); fprintf( stderr, " protect=%d,", req->protect );
fprintf( stderr, " header_size=%d,", req->header_size ); fprintf( stderr, " header_size=%d,", req->header_size );
fprintf( stderr, " base=%p,", req->base ); fprintf( stderr, " base=%p,", req->base );
fprintf( stderr, " mapping=%p,", req->mapping );
fprintf( stderr, " shared_file=%p,", req->shared_file ); fprintf( stderr, " shared_file=%p,", req->shared_file );
fprintf( stderr, " shared_size=%d", req->shared_size ); fprintf( stderr, " shared_size=%d", req->shared_size );
} }
...@@ -3966,6 +3967,7 @@ static const struct ...@@ -3966,6 +3967,7 @@ static const struct
{ "FILE_LOCK_CONFLICT", STATUS_FILE_LOCK_CONFLICT }, { "FILE_LOCK_CONFLICT", STATUS_FILE_LOCK_CONFLICT },
{ "HANDLES_CLOSED", STATUS_HANDLES_CLOSED }, { "HANDLES_CLOSED", STATUS_HANDLES_CLOSED },
{ "HANDLE_NOT_CLOSABLE", STATUS_HANDLE_NOT_CLOSABLE }, { "HANDLE_NOT_CLOSABLE", STATUS_HANDLE_NOT_CLOSABLE },
{ "ILLEGAL_FUNCTION", STATUS_ILLEGAL_FUNCTION },
{ "INSTANCE_NOT_AVAILABLE", STATUS_INSTANCE_NOT_AVAILABLE }, { "INSTANCE_NOT_AVAILABLE", STATUS_INSTANCE_NOT_AVAILABLE },
{ "INVALID_CID", STATUS_INVALID_CID }, { "INVALID_CID", STATUS_INVALID_CID },
{ "INVALID_FILE_FOR_SECTION", STATUS_INVALID_FILE_FOR_SECTION }, { "INVALID_FILE_FOR_SECTION", STATUS_INVALID_FILE_FOR_SECTION },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment