Added wine_server_release_fd function to release the fd returned by
wine_server_handle_to_fd. Fixed a couple of potential fd leaks.
This commit is contained in:
parent
854e59d9ec
commit
f3f435ffa1
|
@ -200,28 +200,6 @@ static void fileio_async_cleanup( struct async_private *ovp )
|
|||
RtlFreeHeap( ntdll_get_process_heap(), 0, ovp );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FILE_GetUnixHandleType
|
||||
*
|
||||
* Retrieve the Unix handle corresponding to a file handle.
|
||||
* Returns -1 on failure.
|
||||
*/
|
||||
static int FILE_GetUnixHandleType( HANDLE handle, DWORD access, enum fd_type *type, int *flags_ptr, int *fd )
|
||||
{
|
||||
int ret, flags;
|
||||
|
||||
*fd = -1;
|
||||
ret = wine_server_handle_to_fd( handle, access, fd, type, &flags );
|
||||
if (flags_ptr) *flags_ptr = flags;
|
||||
if (!ret && (((access & GENERIC_READ) && (flags & FD_FLAG_RECV_SHUTDOWN)) ||
|
||||
((access & GENERIC_WRITE) && (flags & FD_FLAG_SEND_SHUTDOWN))))
|
||||
{
|
||||
close(*fd);
|
||||
ret = STATUS_PIPE_DISCONNECTED;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* FILE_GetNtStatus(void)
|
||||
*
|
||||
|
@ -351,19 +329,30 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
|
|||
hFile,hEvent,apc,apc_user,io_status,buffer,length,offset,key);
|
||||
|
||||
io_status->Information = 0;
|
||||
io_status->u.Status = FILE_GetUnixHandleType( hFile, GENERIC_READ, &type, &flags, &unix_handle );
|
||||
io_status->u.Status = wine_server_handle_to_fd( hFile, GENERIC_READ, &unix_handle, &type, &flags );
|
||||
if (io_status->u.Status) return io_status->u.Status;
|
||||
|
||||
if (flags & FD_FLAG_RECV_SHUTDOWN)
|
||||
{
|
||||
wine_server_release_fd( hFile, unix_handle );
|
||||
return STATUS_PIPE_DISCONNECTED;
|
||||
}
|
||||
|
||||
if (flags & FD_FLAG_TIMEOUT)
|
||||
{
|
||||
if (hEvent)
|
||||
{
|
||||
/* this shouldn't happen, but check it */
|
||||
FIXME("NIY-hEvent\n");
|
||||
wine_server_release_fd( hFile, unix_handle );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
io_status->u.Status = NtCreateEvent(&hEvent, SYNCHRONIZE, NULL, 0, 0);
|
||||
if (io_status->u.Status) return io_status->u.Status;
|
||||
if (io_status->u.Status)
|
||||
{
|
||||
wine_server_release_fd( hFile, unix_handle );
|
||||
return io_status->u.Status;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & (FD_FLAG_OVERLAPPED|FD_FLAG_TIMEOUT))
|
||||
|
@ -371,14 +360,14 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
|
|||
async_fileio* ovp;
|
||||
NTSTATUS ret;
|
||||
|
||||
if (unix_handle < 0) return STATUS_INVALID_HANDLE;
|
||||
|
||||
ovp = RtlAllocateHeap(ntdll_get_process_heap(), 0, sizeof(async_fileio));
|
||||
if (!ovp) return STATUS_NO_MEMORY;
|
||||
|
||||
if (!(ovp = RtlAllocateHeap(ntdll_get_process_heap(), 0, sizeof(async_fileio))))
|
||||
{
|
||||
wine_server_release_fd( hFile, unix_handle );
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
ovp->async.ops = (apc ? &fileio_async_ops : &fileio_nocomp_async_ops );
|
||||
ovp->async.handle = hFile;
|
||||
ovp->async.fd = unix_handle;
|
||||
ovp->async.fd = unix_handle; /* FIXME */
|
||||
ovp->async.type = ASYNC_TYPE_READ;
|
||||
ovp->async.func = FILE_AsyncReadService;
|
||||
ovp->async.event = hEvent;
|
||||
|
@ -419,19 +408,18 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
|
|||
{
|
||||
case FD_TYPE_SMB:
|
||||
FIXME("NIY-SMB\n");
|
||||
close(unix_handle);
|
||||
/* FIXME */
|
||||
/* return SMB_ReadFile(hFile, buffer, length, io_status); */
|
||||
/* return SMB_ReadFile(hFile, unix_handle, buffer, length, io_status); */
|
||||
wine_server_release_fd( hFile, unix_handle );
|
||||
return STATUS_INVALID_HANDLE;
|
||||
|
||||
case FD_TYPE_DEFAULT:
|
||||
/* normal unix files */
|
||||
if (unix_handle == -1) return STATUS_INVALID_HANDLE;
|
||||
/* normal unix file */
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unsupported type of fd %d\n", type);
|
||||
if (unix_handle == -1) close(unix_handle);
|
||||
wine_server_release_fd( hFile, unix_handle );
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
|
@ -444,7 +432,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
|
|||
FilePositionInformation);
|
||||
if (io_status->u.Status)
|
||||
{
|
||||
close(unix_handle);
|
||||
wine_server_release_fd( hFile, unix_handle );
|
||||
return io_status->u.Status;
|
||||
}
|
||||
}
|
||||
|
@ -456,7 +444,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
|
|||
io_status->u.Status = FILE_GetNtStatus();
|
||||
break;
|
||||
}
|
||||
close( unix_handle );
|
||||
wine_server_release_fd( hFile, unix_handle );
|
||||
return io_status->u.Status;
|
||||
}
|
||||
|
||||
|
@ -543,23 +531,28 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
|
|||
hFile,hEvent,apc,apc_user,io_status,buffer,length,offset,key);
|
||||
|
||||
io_status->Information = 0;
|
||||
|
||||
io_status->u.Status = FILE_GetUnixHandleType( hFile, GENERIC_WRITE, &type, &flags, &unix_handle );
|
||||
io_status->u.Status = wine_server_handle_to_fd( hFile, GENERIC_WRITE, &unix_handle, &type, &flags );
|
||||
if (io_status->u.Status) return io_status->u.Status;
|
||||
|
||||
if (flags & FD_FLAG_SEND_SHUTDOWN)
|
||||
{
|
||||
wine_server_release_fd( hFile, unix_handle );
|
||||
return STATUS_PIPE_DISCONNECTED;
|
||||
}
|
||||
|
||||
if (flags & (FD_FLAG_OVERLAPPED|FD_FLAG_TIMEOUT))
|
||||
{
|
||||
async_fileio* ovp;
|
||||
NTSTATUS ret;
|
||||
|
||||
if (unix_handle < 0) return STATUS_INVALID_HANDLE;
|
||||
|
||||
ovp = RtlAllocateHeap(ntdll_get_process_heap(), 0, sizeof(async_fileio));
|
||||
if (!ovp) return STATUS_NO_MEMORY;
|
||||
|
||||
if (!(ovp = RtlAllocateHeap(ntdll_get_process_heap(), 0, sizeof(async_fileio))))
|
||||
{
|
||||
wine_server_release_fd( hFile, unix_handle );
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
ovp->async.ops = (apc ? &fileio_async_ops : &fileio_nocomp_async_ops );
|
||||
ovp->async.handle = hFile;
|
||||
ovp->async.fd = unix_handle;
|
||||
ovp->async.fd = unix_handle; /* FIXME */
|
||||
ovp->async.type = ASYNC_TYPE_WRITE;
|
||||
ovp->async.func = FILE_AsyncWriteService;
|
||||
ovp->async.event = hEvent;
|
||||
|
@ -595,7 +588,7 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
|
|||
{
|
||||
case FD_TYPE_SMB:
|
||||
FIXME("NIY-SMB\n");
|
||||
close(unix_handle);
|
||||
wine_server_release_fd( hFile, unix_handle );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
case FD_TYPE_DEFAULT:
|
||||
|
@ -605,7 +598,7 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
|
|||
|
||||
default:
|
||||
FIXME("Unsupported type of fd %d\n", type);
|
||||
if (unix_handle == -1) close(unix_handle);
|
||||
wine_server_release_fd( hFile, unix_handle );
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
|
@ -618,7 +611,7 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
|
|||
FilePositionInformation);
|
||||
if (io_status->u.Status)
|
||||
{
|
||||
close(unix_handle);
|
||||
wine_server_release_fd( hFile, unix_handle );
|
||||
return io_status->u.Status;
|
||||
}
|
||||
}
|
||||
|
@ -632,7 +625,7 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
|
|||
else io_status->u.Status = FILE_GetNtStatus();
|
||||
break;
|
||||
}
|
||||
close( unix_handle );
|
||||
wine_server_release_fd( hFile, unix_handle );
|
||||
return io_status->u.Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -1067,6 +1067,7 @@
|
|||
@ cdecl -norelay wine_server_call(ptr)
|
||||
@ cdecl wine_server_fd_to_handle(long long long ptr)
|
||||
@ cdecl wine_server_handle_to_fd(long long ptr ptr ptr)
|
||||
@ cdecl wine_server_release_fd(long long)
|
||||
@ cdecl wine_server_send_fd(long)
|
||||
|
||||
# Codepages
|
||||
|
|
|
@ -360,31 +360,33 @@ static int receive_fd( obj_handle_t *handle )
|
|||
* Returns the new fd, which can be different if there was already an
|
||||
* fd in the cache for that handle.
|
||||
*/
|
||||
inline static int store_cached_fd( int fd, obj_handle_t handle )
|
||||
inline static int store_cached_fd( int *fd, obj_handle_t handle )
|
||||
{
|
||||
int ret;
|
||||
|
||||
SERVER_START_REQ( set_handle_info )
|
||||
{
|
||||
req->handle = handle;
|
||||
req->flags = 0;
|
||||
req->mask = 0;
|
||||
req->fd = fd;
|
||||
if (!wine_server_call( req ))
|
||||
req->fd = *fd;
|
||||
if (!(ret = wine_server_call( req )))
|
||||
{
|
||||
if (reply->cur_fd != fd)
|
||||
if (reply->cur_fd != *fd)
|
||||
{
|
||||
/* someone was here before us */
|
||||
close( fd );
|
||||
fd = reply->cur_fd;
|
||||
close( *fd );
|
||||
*fd = reply->cur_fd;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
close( fd );
|
||||
fd = -1;
|
||||
close( *fd );
|
||||
*fd = -1;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return fd;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -442,7 +444,8 @@ int wine_server_handle_to_fd( obj_handle_t handle, unsigned int access, int *uni
|
|||
/* it wasn't in the cache, get it from the server */
|
||||
fd = receive_fd( &fd_handle );
|
||||
/* and store it back into the cache */
|
||||
fd = store_cached_fd( fd, fd_handle );
|
||||
ret = store_cached_fd( &fd, fd_handle );
|
||||
if (ret) return ret;
|
||||
|
||||
if (fd_handle == handle) break;
|
||||
/* if we received a different handle this means there was
|
||||
|
@ -457,6 +460,17 @@ int wine_server_handle_to_fd( obj_handle_t handle, unsigned int access, int *uni
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* wine_server_release_fd (NTDLL.@)
|
||||
*
|
||||
* Release the Unix fd returned by wine_server_handle_to_fd.
|
||||
*/
|
||||
void wine_server_release_fd( obj_handle_t handle, int unix_fd )
|
||||
{
|
||||
close( unix_fd );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* start_server
|
||||
*
|
||||
|
|
|
@ -555,8 +555,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, DWORD total_size,
|
||||
DWORD header_size, int shared_fd, DWORD shared_size,
|
||||
BOOL removable, PVOID *addr_ptr )
|
||||
DWORD header_size, int shared_fd, BOOL removable, PVOID *addr_ptr )
|
||||
{
|
||||
IMAGE_DOS_HEADER *dos;
|
||||
IMAGE_NT_HEADERS *nt;
|
||||
|
@ -756,13 +755,11 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, DWORD total_size
|
|||
VIRTUAL_SetProt( view, ptr + sec->VirtualAddress, size, vprot );
|
||||
}
|
||||
|
||||
close( fd );
|
||||
*addr_ptr = ptr;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
error:
|
||||
if (ptr != (char *)-1) munmap( ptr, total_size );
|
||||
close( fd );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1415,28 +1412,33 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
|||
removable = reply->removable;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (res) goto error;
|
||||
if (res) return res;
|
||||
|
||||
if ((res = wine_server_handle_to_fd( handle, 0, &unix_handle, NULL, NULL ))) goto error;
|
||||
if ((res = wine_server_handle_to_fd( handle, 0, &unix_handle, NULL, NULL ))) return res;
|
||||
|
||||
if (prot & VPROT_IMAGE)
|
||||
{
|
||||
int shared_fd = -1;
|
||||
|
||||
if (shared_file)
|
||||
{
|
||||
int shared_fd;
|
||||
|
||||
if ((res = wine_server_handle_to_fd( shared_file, GENERIC_READ, &shared_fd,
|
||||
NULL, NULL ))) goto error;
|
||||
NtClose( shared_file ); /* we no longer need it */
|
||||
res = map_image( handle, unix_handle, base, size_low, header_size,
|
||||
shared_fd, removable, addr_ptr );
|
||||
wine_server_release_fd( shared_file, shared_fd );
|
||||
NtClose( shared_file );
|
||||
}
|
||||
res = map_image( handle, unix_handle, base, size_low, header_size,
|
||||
shared_fd, shared_size, removable, addr_ptr );
|
||||
if (shared_fd != -1) close( shared_fd );
|
||||
else
|
||||
{
|
||||
res = map_image( handle, unix_handle, base, size_low, header_size,
|
||||
-1, removable, addr_ptr );
|
||||
}
|
||||
wine_server_release_fd( handle, unix_handle );
|
||||
if (!res) *size_ptr = size_low;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
if (size_high)
|
||||
ERR("Sizes larger than 4Gb not supported\n");
|
||||
|
||||
|
@ -1507,12 +1509,12 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
|||
res = STATUS_NO_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
if (unix_handle != -1) close( unix_handle );
|
||||
wine_server_release_fd( handle, unix_handle );
|
||||
*size_ptr = size;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
error:
|
||||
if (unix_handle != -1) close( unix_handle );
|
||||
wine_server_release_fd( handle, unix_handle );
|
||||
if (ptr != (void *)-1) munmap( ptr, size );
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -1580,10 +1580,9 @@ static NTSTATUS SMB_SetOffset(HANDLE hFile, DWORD offset)
|
|||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI SMB_ReadFile(HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
|
||||
NTSTATUS WINAPI SMB_ReadFile(HANDLE hFile, int fd, LPVOID buffer, DWORD bytesToRead,
|
||||
PIO_STATUS_BLOCK io_status)
|
||||
{
|
||||
int fd;
|
||||
DWORD count, offset;
|
||||
USHORT user_id, tree_id, dialect, file_id, read;
|
||||
|
||||
|
@ -1594,9 +1593,6 @@ NTSTATUS WINAPI SMB_ReadFile(HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
|
|||
io_status->u.Status = SMB_GetSmbInfo(hFile, &tree_id, &user_id, &dialect, &file_id, &offset);
|
||||
if (io_status->u.Status) return io_status->u.Status;
|
||||
|
||||
fd = FILE_GetUnixHandle(hFile, GENERIC_READ);
|
||||
if (fd<0) return io_status->u.Status = STATUS_INVALID_HANDLE;
|
||||
|
||||
while(1)
|
||||
{
|
||||
count = bytesToRead - io_status->Information;
|
||||
|
@ -1615,8 +1611,6 @@ NTSTATUS WINAPI SMB_ReadFile(HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
|
|||
if(io_status->Information >= bytesToRead)
|
||||
break;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
return io_status->u.Status = SMB_SetOffset(hFile, offset);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
static inline int SMB_isSepW (WCHAR c) {return (c == '\\' || c == '/');}
|
||||
static inline int SMB_isUNCW (LPCWSTR filename) {return (filename && SMB_isSepW (filename[0]) && SMB_isSepW (filename[1]));}
|
||||
|
||||
NTSTATUS WINAPI SMB_ReadFile(HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
|
||||
NTSTATUS WINAPI SMB_ReadFile(HANDLE hFile, int fd, LPVOID buffer, DWORD bytesToRead,
|
||||
PIO_STATUS_BLOCK io_status);
|
||||
extern HANDLE WINAPI SMB_CreateFileW( LPCWSTR filename, DWORD access, DWORD sharing,
|
||||
LPSECURITY_ATTRIBUTES sa, DWORD creation,
|
||||
|
|
|
@ -77,7 +77,7 @@ inline static void finish_async( async_private *ovp )
|
|||
|
||||
ovp->next = ovp->prev = NULL;
|
||||
|
||||
close(ovp->fd);
|
||||
wine_server_release_fd( ovp->handle, ovp->fd );
|
||||
if ( ovp->event != INVALID_HANDLE_VALUE )
|
||||
NtSetEvent( ovp->event, NULL );
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ extern void wine_server_send_fd( int fd );
|
|||
extern int wine_server_fd_to_handle( int fd, unsigned int access, int inherit, obj_handle_t *handle );
|
||||
extern int wine_server_handle_to_fd( obj_handle_t handle, unsigned int access, int *unix_fd,
|
||||
enum fd_type *type, int *flags );
|
||||
extern void wine_server_release_fd( obj_handle_t handle, int unix_fd );
|
||||
|
||||
/* do a server call and set the last error code */
|
||||
inline static unsigned int wine_server_call_err( void *req_ptr )
|
||||
|
|
|
@ -1040,8 +1040,8 @@ DECL_HANDLER(get_handle_fd)
|
|||
if (unix_fd != -1) reply->fd = unix_fd;
|
||||
else if (!get_error())
|
||||
{
|
||||
unix_fd = fd->unix_fd;
|
||||
if (unix_fd != -1) send_client_fd( current->process, unix_fd, req->handle );
|
||||
assert( fd->unix_fd != -1 );
|
||||
send_client_fd( current->process, fd->unix_fd, req->handle );
|
||||
}
|
||||
reply->type = fd->fd_ops->get_file_info( fd, NULL, &reply->flags );
|
||||
release_object( fd );
|
||||
|
|
Loading…
Reference in New Issue