Alexandre Julliard : ntdll:
Duplicate the mapping handle on the server side for NtMapViewOfSection.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Jan 12 13:55:13 CST 2007
Module: wine
Branch: master
Commit: 4cbe867a8504a4aedd1ddc4f8a5429c1cc1aea3b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4cbe867a8504a4aedd1ddc4f8a5429c1cc1aea3b
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Jan 12 14:55:31 2007 +0100
ntdll: Duplicate the mapping handle on the server side for NtMapViewOfSection.
---
dlls/ntdll/virtual.c | 39 ++++++++++++++++-----------------------
include/wine/server_protocol.h | 3 ++-
server/mapping.c | 16 ++++++++++++++--
server/protocol.def | 1 +
server/trace.c | 2 ++
5 files changed, 35 insertions(+), 26 deletions(-)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 2ad3cfb..64a8b8e 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -934,7 +934,7 @@ static int do_relocations( char *base, c
* 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 hmappi
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 hmappi
/* 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 hmappi
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 hmappi
}
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 hmappi
error:
if (view) delete_view( view );
RtlLeaveCriticalSection( &csVirtual );
+ if (dup_mapping) NtClose( dup_mapping );
return status;
}
@@ -1837,13 +1834,12 @@ NTSTATUS WINAPI NtMapViewOfSection( HAND
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( HAND
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( HAND
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( HAND
res = STATUS_INVALID_PARAMETER;
goto done;
}
- removable = FALSE;
/* fall through */
case PAGE_READONLY:
case PAGE_WRITECOPY:
@@ -1964,16 +1959,13 @@ NTSTATUS WINAPI NtMapViewOfSection( HAND
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( HAND
RtlLeaveCriticalSection( &csVirtual );
done:
+ if (dup_mapping) NtClose( dup_mapping );
if (needs_close) close( unix_handle );
return res;
}
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index ce55bf0..03969ff 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -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 */
diff --git a/server/mapping.c b/server/mapping.c
index fe99879..9b123e2 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -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 );
}
}
diff --git a/server/protocol.def b/server/protocol.def
index a71bcee..3f7fbd5 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -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
diff --git a/server/trace.c b/server/trace.c
index 1770a6d..5defbda 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1570,6 +1570,7 @@ static void dump_get_mapping_info_reply(
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 },
More information about the wine-cvs
mailing list