ntdll: Duplicate the mapping handle on the server side for NtMapViewOfSection.
This commit is contained in:
parent
5bd513640b
commit
4cbe867a85
|
@ -934,7 +934,7 @@ static int do_relocations( char *base, const IMAGE_DATA_DIRECTORY *dir,
|
|||
* 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, BOOL removable, PVOID *addr_ptr )
|
||||
SIZE_T header_size, int shared_fd, HANDLE dup_mapping, PVOID *addr_ptr )
|
||||
{
|
||||
IMAGE_DOS_HEADER *dos;
|
||||
IMAGE_NT_HEADERS *nt;
|
||||
|
@ -975,7 +975,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz
|
|||
if (!st.st_size) goto error;
|
||||
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,
|
||||
removable ) != STATUS_SUCCESS) goto error;
|
||||
!dup_mapping ) != STATUS_SUCCESS) goto error;
|
||||
dos = (IMAGE_DOS_HEADER *)ptr;
|
||||
nt = (IMAGE_NT_HEADERS *)(ptr + dos->e_lfanew);
|
||||
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
|
|||
/* 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,
|
||||
removable ) != STATUS_SUCCESS) goto error;
|
||||
!dup_mapping ) != STATUS_SUCCESS) goto error;
|
||||
|
||||
/* check that all sections are loaded at the right offset */
|
||||
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
|
|||
end < file_start ||
|
||||
map_file_into_view( view, fd, sec->VirtualAddress, file_size, file_start,
|
||||
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 );
|
||||
goto error;
|
||||
|
@ -1195,11 +1195,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz
|
|||
}
|
||||
|
||||
done:
|
||||
if (!removable) /* don't keep handle open on removable media */
|
||||
NtDuplicateObject( NtCurrentProcess(), hmapping,
|
||||
NtCurrentProcess(), &view->mapping,
|
||||
0, 0, DUPLICATE_SAME_ACCESS );
|
||||
|
||||
view->mapping = dup_mapping;
|
||||
RtlLeaveCriticalSection( &csVirtual );
|
||||
|
||||
*addr_ptr = ptr;
|
||||
|
@ -1208,6 +1204,7 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz
|
|||
error:
|
||||
if (view) delete_view( view );
|
||||
RtlLeaveCriticalSection( &csVirtual );
|
||||
if (dup_mapping) NtClose( dup_mapping );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1837,13 +1834,12 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
|||
NTSTATUS res;
|
||||
SIZE_T size = 0;
|
||||
SIZE_T mask = get_mask( zero_bits );
|
||||
int unix_handle = -1, flags, needs_close;
|
||||
int unix_handle = -1, needs_close;
|
||||
int prot;
|
||||
void *base;
|
||||
struct file_view *view;
|
||||
DWORD size_low, size_high, header_size, shared_size;
|
||||
HANDLE shared_file;
|
||||
BOOL removable = FALSE;
|
||||
HANDLE dup_mapping, shared_file;
|
||||
LARGE_INTEGER offset;
|
||||
|
||||
offset.QuadPart = offset_ptr ? offset_ptr->QuadPart : 0;
|
||||
|
@ -1871,14 +1867,14 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
|||
size_low = reply->size_low;
|
||||
size_high = reply->size_high;
|
||||
header_size = reply->header_size;
|
||||
dup_mapping = reply->mapping;
|
||||
shared_file = reply->shared_file;
|
||||
shared_size = reply->shared_size;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (res) return res;
|
||||
|
||||
if ((res = server_get_unix_fd( handle, 0, &unix_handle, &needs_close, NULL, &flags ))) return res;
|
||||
removable = (flags & FD_FLAG_REMOVABLE) != 0;
|
||||
if ((res = server_get_unix_fd( handle, 0, &unix_handle, &needs_close, NULL, NULL ))) goto done;
|
||||
|
||||
if (prot & VPROT_IMAGE)
|
||||
{
|
||||
|
@ -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,
|
||||
&shared_fd, &shared_needs_close, NULL, NULL ))) goto done;
|
||||
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 );
|
||||
NtClose( shared_file );
|
||||
}
|
||||
else
|
||||
{
|
||||
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 (!res) *size_ptr = size_low;
|
||||
|
@ -1926,7 +1922,6 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
|||
res = STATUS_INVALID_PARAMETER;
|
||||
goto done;
|
||||
}
|
||||
removable = FALSE;
|
||||
/* fall through */
|
||||
case PAGE_READONLY:
|
||||
case PAGE_WRITECOPY:
|
||||
|
@ -1964,16 +1959,13 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
|||
TRACE("handle=%p size=%lx offset=%x%08x\n",
|
||||
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 (!removable) /* don't keep handle open on removable media */
|
||||
NtDuplicateObject( NtCurrentProcess(), handle,
|
||||
NtCurrentProcess(), &view->mapping,
|
||||
0, 0, DUPLICATE_SAME_ACCESS );
|
||||
|
||||
*addr_ptr = view->base;
|
||||
*size_ptr = size;
|
||||
view->mapping = dup_mapping;
|
||||
dup_mapping = 0; /* don't close it */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1985,6 +1977,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
|||
RtlLeaveCriticalSection( &csVirtual );
|
||||
|
||||
done:
|
||||
if (dup_mapping) NtClose( dup_mapping );
|
||||
if (needs_close) close( unix_handle );
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -1535,6 +1535,7 @@ struct get_mapping_info_reply
|
|||
int protect;
|
||||
int header_size;
|
||||
void* base;
|
||||
obj_handle_t mapping;
|
||||
obj_handle_t shared_file;
|
||||
int shared_size;
|
||||
};
|
||||
|
@ -4436,6 +4437,6 @@ union generic_reply
|
|||
struct query_symlink_reply query_symlink_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 263
|
||||
#define SERVER_PROTOCOL_VERSION 264
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -432,6 +432,7 @@ DECL_HANDLER(open_mapping)
|
|||
DECL_HANDLER(get_mapping_info)
|
||||
{
|
||||
struct mapping *mapping;
|
||||
struct fd *fd;
|
||||
|
||||
if ((mapping = (struct mapping *)get_handle_obj( current->process, req->handle,
|
||||
0, &mapping_ops )))
|
||||
|
@ -443,9 +444,20 @@ DECL_HANDLER(get_mapping_info)
|
|||
reply->base = mapping->base;
|
||||
reply->shared_file = 0;
|
||||
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)
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1159,6 +1159,7 @@ enum char_info_mode
|
|||
int protect; /* protection flags */
|
||||
int header_size; /* header size (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 */
|
||||
int shared_size; /* shared mapping size */
|
||||
@END
|
||||
|
|
|
@ -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, " header_size=%d,", req->header_size );
|
||||
fprintf( stderr, " base=%p,", req->base );
|
||||
fprintf( stderr, " mapping=%p,", req->mapping );
|
||||
fprintf( stderr, " shared_file=%p,", req->shared_file );
|
||||
fprintf( stderr, " shared_size=%d", req->shared_size );
|
||||
}
|
||||
|
@ -3966,6 +3967,7 @@ static const struct
|
|||
{ "FILE_LOCK_CONFLICT", STATUS_FILE_LOCK_CONFLICT },
|
||||
{ "HANDLES_CLOSED", STATUS_HANDLES_CLOSED },
|
||||
{ "HANDLE_NOT_CLOSABLE", STATUS_HANDLE_NOT_CLOSABLE },
|
||||
{ "ILLEGAL_FUNCTION", STATUS_ILLEGAL_FUNCTION },
|
||||
{ "INSTANCE_NOT_AVAILABLE", STATUS_INSTANCE_NOT_AVAILABLE },
|
||||
{ "INVALID_CID", STATUS_INVALID_CID },
|
||||
{ "INVALID_FILE_FOR_SECTION", STATUS_INVALID_FILE_FOR_SECTION },
|
||||
|
|
Loading…
Reference in New Issue