Commit 9ddb9294 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Added a server_get_unix_fd function that avoids doing a dup() of the fd when not required.

parent 7c38ff6a
......@@ -2014,7 +2014,7 @@ NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
{
DWORD sz = 0;
NTSTATUS status = STATUS_SUCCESS;
int fd, dev;
int fd, needs_close, dev;
TRACE("%p %s %p %d %p %d %p\n",
hDevice, iocodex(dwIoControlCode), lpInBuffer, nInBufferSize,
......@@ -2022,10 +2022,10 @@ NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
piosb->Information = 0;
if ((status = wine_server_handle_to_fd( hDevice, 0, &fd, NULL ))) goto error;
if ((status = server_get_unix_fd( hDevice, 0, &fd, &needs_close, NULL ))) goto error;
if ((status = CDROM_Open(fd, &dev)))
{
wine_server_release_fd( hDevice, fd );
if (needs_close) close( fd );
goto error;
}
......@@ -2281,7 +2281,7 @@ NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
status = STATUS_INVALID_PARAMETER;
break;
}
wine_server_release_fd( hDevice, fd );
if (needs_close) close( fd );
error:
piosb->u.Status = status;
piosb->Information = sz;
......
......@@ -1284,7 +1284,7 @@ NTSTATUS WINAPI NtQueryDirectoryFile( HANDLE handle, HANDLE event,
PUNICODE_STRING mask,
BOOLEAN restart_scan )
{
int cwd, fd;
int cwd, fd, needs_close;
static const WCHAR wszWildcards[] = { '*','?',0 };
TRACE("(%p %p %p %p %p %p 0x%08x 0x%08x 0x%08x %s 0x%08x\n",
......@@ -1305,7 +1305,7 @@ NTSTATUS WINAPI NtQueryDirectoryFile( HANDLE handle, HANDLE event,
return io->u.Status = STATUS_NOT_IMPLEMENTED;
}
if ((io->u.Status = wine_server_handle_to_fd( handle, FILE_LIST_DIRECTORY, &fd, NULL )) != STATUS_SUCCESS)
if ((io->u.Status = server_get_unix_fd( handle, FILE_LIST_DIRECTORY, &fd, &needs_close, NULL )) != STATUS_SUCCESS)
return io->u.Status;
io->Information = 0;
......@@ -1336,7 +1336,7 @@ NTSTATUS WINAPI NtQueryDirectoryFile( HANDLE handle, HANDLE event,
RtlLeaveCriticalSection( &dir_section );
wine_server_release_fd( handle, fd );
if (needs_close) close( fd );
if (cwd != -1) close( cwd );
TRACE( "=> %x (%ld)\n", io->u.Status, io->Information );
return io->u.Status;
......@@ -1819,7 +1819,7 @@ BOOLEAN WINAPI RtlDoesFileExists_U(LPCWSTR file_name)
NTSTATUS DIR_unmount_device( HANDLE handle )
{
NTSTATUS status;
int unix_fd;
int unix_fd, needs_close;
SERVER_START_REQ( unmount_device )
{
......@@ -1829,7 +1829,7 @@ NTSTATUS DIR_unmount_device( HANDLE handle )
SERVER_END_REQ;
if (status) return status;
if (!(status = wine_server_handle_to_fd( handle, 0, &unix_fd, NULL )))
if (!(status = server_get_unix_fd( handle, 0, &unix_fd, &needs_close, NULL )))
{
struct stat st;
char *mount_point = NULL;
......@@ -1861,7 +1861,7 @@ NTSTATUS DIR_unmount_device( HANDLE handle )
RtlFreeHeap( GetProcessHeap(), 0, mount_point );
}
}
wine_server_release_fd( handle, unix_fd );
if (needs_close) close( unix_fd );
}
return status;
}
......@@ -1875,7 +1875,7 @@ NTSTATUS DIR_unmount_device( HANDLE handle )
*/
NTSTATUS DIR_get_unix_cwd( char **cwd )
{
int old_cwd, unix_fd;
int old_cwd, unix_fd, needs_close;
CURDIR *curdir;
HANDLE handle;
NTSTATUS status;
......@@ -1911,7 +1911,7 @@ NTSTATUS DIR_get_unix_cwd( char **cwd )
if (status != STATUS_SUCCESS) goto done;
}
if ((status = wine_server_handle_to_fd( handle, 0, &unix_fd, NULL )) == STATUS_SUCCESS)
if ((status = server_get_unix_fd( handle, 0, &unix_fd, &needs_close, NULL )) == STATUS_SUCCESS)
{
RtlEnterCriticalSection( &dir_section );
......@@ -1940,7 +1940,7 @@ NTSTATUS DIR_get_unix_cwd( char **cwd )
else status = FILE_GetNtStatus();
RtlLeaveCriticalSection( &dir_section );
wine_server_release_fd( handle, unix_fd );
if (needs_close) close( unix_fd );
}
if (!curdir->Handle) NtClose( handle );
......
......@@ -287,6 +287,7 @@ typedef struct async_fileio
int queue_apc_on_error;
BOOL avail_mode;
int fd;
int needs_close;
HANDLE event;
} async_fileio;
......@@ -294,9 +295,8 @@ static void fileio_terminate(async_fileio *fileio, IO_STATUS_BLOCK* iosb)
{
TRACE("data: %p\n", fileio);
wine_server_release_fd( fileio->handle, fileio->fd );
if ( fileio->event != INVALID_HANDLE_VALUE )
NtSetEvent( fileio->event, NULL );
if (fileio->needs_close) close( fileio->fd );
if (fileio->event) NtSetEvent( fileio->event, NULL );
if (fileio->apc &&
(iosb->u.Status == STATUS_SUCCESS || fileio->queue_apc_on_error))
......@@ -485,7 +485,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
PIO_STATUS_BLOCK io_status, void* buffer, ULONG length,
PLARGE_INTEGER offset, PULONG key)
{
int unix_handle, flags;
int unix_handle, needs_close, flags;
TRACE("(%p,%p,%p,%p,%p,%p,0x%08x,%p,%p),partial stub!\n",
hFile,hEvent,apc,apc_user,io_status,buffer,length,offset,key);
......@@ -493,12 +493,12 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
if (!io_status) return STATUS_ACCESS_VIOLATION;
io_status->Information = 0;
io_status->u.Status = wine_server_handle_to_fd( hFile, FILE_READ_DATA, &unix_handle, &flags );
io_status->u.Status = server_get_unix_fd( hFile, FILE_READ_DATA, &unix_handle, &needs_close, &flags );
if (io_status->u.Status) return io_status->u.Status;
if (flags & FD_FLAG_RECV_SHUTDOWN)
{
wine_server_release_fd( hFile, unix_handle );
if (needs_close) close( unix_handle );
return STATUS_PIPE_DISCONNECTED;
}
......@@ -508,13 +508,13 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
{
/* this shouldn't happen, but check it */
FIXME("NIY-hEvent\n");
wine_server_release_fd( hFile, unix_handle );
if (needs_close) close( unix_handle );
return STATUS_NOT_IMPLEMENTED;
}
io_status->u.Status = NtCreateEvent(&hEvent, EVENT_ALL_ACCESS, NULL, 0, 0);
if (io_status->u.Status)
{
wine_server_release_fd( hFile, unix_handle );
if (needs_close) close( unix_handle );
return io_status->u.Status;
}
}
......@@ -526,7 +526,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
if (!(fileio = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(async_fileio))))
{
wine_server_release_fd( hFile, unix_handle );
if (needs_close) close( unix_handle );
if (flags & FD_FLAG_TIMEOUT) NtClose(hEvent);
return STATUS_NO_MEMORY;
}
......@@ -546,6 +546,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
fileio->queue_apc_on_error = 0;
fileio->avail_mode = (flags & FD_FLAG_AVAILABLE);
fileio->fd = unix_handle; /* FIXME */
fileio->needs_close = needs_close;
fileio->event = hEvent;
NtResetEvent(hEvent, NULL);
......@@ -553,7 +554,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
ret = fileio_queue_async(fileio, io_status, TRUE);
if (ret != STATUS_SUCCESS)
{
wine_server_release_fd( hFile, unix_handle );
if (needs_close) close( unix_handle );
if (flags & FD_FLAG_TIMEOUT) NtClose(hEvent);
return ret;
}
......@@ -594,11 +595,7 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
fpi.CurrentByteOffset = *offset;
io_status->u.Status = NtSetInformationFile(hFile, io_status, &fpi, sizeof(fpi),
FilePositionInformation);
if (io_status->u.Status)
{
wine_server_release_fd( hFile, unix_handle );
return io_status->u.Status;
}
if (io_status->u.Status) goto done;
}
/* code for synchronous reads */
while ((io_status->Information = read( unix_handle, buffer, length )) == -1)
......@@ -620,7 +617,8 @@ NTSTATUS WINAPI NtReadFile(HANDLE hFile, HANDLE hEvent,
else
io_status->u.Status = STATUS_END_OF_FILE;
}
wine_server_release_fd( hFile, unix_handle );
done:
if (needs_close) close( unix_handle );
TRACE("= 0x%08x (%lu)\n", io_status->u.Status, io_status->Information);
return io_status->u.Status;
}
......@@ -707,7 +705,7 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
const void* buffer, ULONG length,
PLARGE_INTEGER offset, PULONG key)
{
int unix_handle, flags;
int unix_handle, needs_close, flags;
TRACE("(%p,%p,%p,%p,%p,%p,0x%08x,%p,%p)!\n",
hFile,hEvent,apc,apc_user,io_status,buffer,length,offset,key);
......@@ -715,12 +713,12 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
if (!io_status) return STATUS_ACCESS_VIOLATION;
io_status->Information = 0;
io_status->u.Status = wine_server_handle_to_fd( hFile, FILE_WRITE_DATA, &unix_handle, &flags );
io_status->u.Status = server_get_unix_fd( hFile, FILE_WRITE_DATA, &unix_handle, &needs_close, &flags );
if (io_status->u.Status) return io_status->u.Status;
if (flags & FD_FLAG_SEND_SHUTDOWN)
{
wine_server_release_fd( hFile, unix_handle );
if (needs_close) close( unix_handle );
return STATUS_PIPE_DISCONNECTED;
}
......@@ -730,13 +728,13 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
{
/* this shouldn't happen, but check it */
FIXME("NIY-hEvent\n");
wine_server_release_fd( hFile, unix_handle );
if (needs_close) close( unix_handle );
return STATUS_NOT_IMPLEMENTED;
}
io_status->u.Status = NtCreateEvent(&hEvent, EVENT_ALL_ACCESS, NULL, 0, 0);
if (io_status->u.Status)
{
wine_server_release_fd( hFile, unix_handle );
if (needs_close) close( unix_handle );
return io_status->u.Status;
}
}
......@@ -748,7 +746,7 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
if (!(fileio = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(async_fileio))))
{
wine_server_release_fd( hFile, unix_handle );
if (needs_close) close( unix_handle );
if (flags & FD_FLAG_TIMEOUT) NtClose(hEvent);
return STATUS_NO_MEMORY;
}
......@@ -770,6 +768,7 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
fileio->queue_apc_on_error = 0;
fileio->avail_mode = (flags & FD_FLAG_AVAILABLE);
fileio->fd = unix_handle; /* FIXME */
fileio->needs_close = needs_close;
fileio->event = hEvent;
NtResetEvent(hEvent, NULL);
......@@ -778,7 +777,7 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
ret = fileio_queue_async(fileio, io_status, FALSE);
if (ret != STATUS_SUCCESS)
{
wine_server_release_fd( hFile, unix_handle );
if (needs_close) close( unix_handle );
if (flags & FD_FLAG_TIMEOUT) NtClose(hEvent);
return ret;
}
......@@ -818,11 +817,7 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
fpi.CurrentByteOffset = *offset;
io_status->u.Status = NtSetInformationFile(hFile, io_status, &fpi, sizeof(fpi),
FilePositionInformation);
if (io_status->u.Status)
{
wine_server_release_fd( hFile, unix_handle );
return io_status->u.Status;
}
if (io_status->u.Status) goto done;
}
/* synchronous file write */
......@@ -838,7 +833,8 @@ NTSTATUS WINAPI NtWriteFile(HANDLE hFile, HANDLE hEvent,
else io_status->u.Status = FILE_GetNtStatus();
break;
}
wine_server_release_fd( hFile, unix_handle );
done:
if (needs_close) close( unix_handle );
return io_status->u.Status;
}
......@@ -1026,7 +1022,7 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
case FSCTL_PIPE_PEEK:
{
FILE_PIPE_PEEK_BUFFER *buffer = out_buffer;
int avail = 0, fd, flags;
int avail = 0, fd, needs_close, flags;
if (out_size < FIELD_OFFSET( FILE_PIPE_PEEK_BUFFER, Data ))
{
......@@ -1034,12 +1030,12 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
break;
}
if ((io->u.Status = wine_server_handle_to_fd( handle, FILE_READ_DATA, &fd, &flags )))
if ((io->u.Status = server_get_unix_fd( handle, FILE_READ_DATA, &fd, &needs_close, &flags )))
break;
if (flags & FD_FLAG_RECV_SHUTDOWN)
{
wine_server_release_fd( handle, fd );
if (needs_close) close( fd );
io->u.Status = STATUS_PIPE_DISCONNECTED;
break;
}
......@@ -1048,7 +1044,7 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
if (ioctl( fd, FIONREAD, &avail ) != 0)
{
TRACE("FIONREAD failed reason: %s\n",strerror(errno));
wine_server_release_fd( handle, fd );
if (needs_close) close( fd );
io->u.Status = FILE_GetNtStatus();
break;
}
......@@ -1064,7 +1060,7 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
ret = poll( &pollfd, 1, 0 );
if (ret == -1 || (ret == 1 && (pollfd.revents & (POLLHUP|POLLERR))))
{
wine_server_release_fd( handle, fd );
if (needs_close) close( fd );
io->u.Status = STATUS_PIPE_BROKEN;
break;
}
......@@ -1084,7 +1080,7 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
if (res >= 0) io->Information += res;
}
}
wine_server_release_fd( handle, fd );
if (needs_close) close( fd );
}
break;
......@@ -1205,7 +1201,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
};
struct stat st;
int fd;
int fd, needs_close;
TRACE("(%p,%p,%p,0x%08x,0x%08x)\n", hFile, io, ptr, len, class);
......@@ -1223,9 +1219,9 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
if (class != FilePipeLocalInformation)
{
if ((io->u.Status = wine_server_handle_to_fd( hFile, 0, &fd, NULL )))
if ((io->u.Status = server_get_unix_fd( hFile, 0, &fd, &needs_close, NULL )))
return io->u.Status;
} else fd = -1;
}
switch (class)
{
......@@ -1398,7 +1394,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
io->u.Status = STATUS_NOT_IMPLEMENTED;
break;
}
if (fd != -1) wine_server_release_fd( hFile, fd );
if (needs_close) close( fd );
if (io->u.Status == STATUS_SUCCESS && !io->Information) io->Information = info_sizes[class];
return io->u.Status;
}
......@@ -1423,11 +1419,11 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
PVOID ptr, ULONG len, FILE_INFORMATION_CLASS class)
{
int fd;
int fd, needs_close;
TRACE("(%p,%p,%p,0x%08x,0x%08x)\n", handle, io, ptr, len, class);
if ((io->u.Status = wine_server_handle_to_fd( handle, 0, &fd, NULL )))
if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL )))
return io->u.Status;
io->u.Status = STATUS_SUCCESS;
......@@ -1549,7 +1545,7 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
io->u.Status = STATUS_NOT_IMPLEMENTED;
break;
}
wine_server_release_fd( handle, fd );
if (needs_close) close( fd );
io->Information = 0;
return io->u.Status;
}
......@@ -1813,10 +1809,10 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io
PVOID buffer, ULONG length,
FS_INFORMATION_CLASS info_class )
{
int fd;
int fd, needs_close;
struct stat st;
if ((io->u.Status = wine_server_handle_to_fd( handle, 0, &fd, NULL )) != STATUS_SUCCESS)
if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL )) != STATUS_SUCCESS)
return io->u.Status;
io->u.Status = STATUS_NOT_IMPLEMENTED;
......@@ -1905,7 +1901,7 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io
io->u.Status = STATUS_INVALID_PARAMETER;
break;
}
wine_server_release_fd( handle, fd );
if (needs_close) close( fd );
return io->u.Status;
}
......
......@@ -62,6 +62,8 @@ extern void DECLSPEC_NORETURN server_protocol_perror( const char *err );
extern void DECLSPEC_NORETURN server_exit_thread( int status );
extern void DECLSPEC_NORETURN server_abort_thread( int status );
extern int server_remove_fd_from_cache( obj_handle_t handle );
extern int server_get_unix_fd( obj_handle_t handle, unsigned int access, int *unix_fd,
int *flags, int *needs_close );
/* module handling */
extern NTSTATUS MODULE_DllThreadAttach( LPVOID lpReserved );
......
......@@ -980,13 +980,9 @@ static DWORD WINAPI check_events(int fd, DWORD mask,
static DWORD CALLBACK wait_for_event(LPVOID arg)
{
async_commio *commio = (async_commio*) arg;
int fd;
int fd, needs_close;
if (wine_server_handle_to_fd( commio->hDevice, FILE_READ_DATA | FILE_WRITE_DATA, &fd, NULL ))
{
fd = -1;
}
else
if (!server_get_unix_fd( commio->hDevice, FILE_READ_DATA | FILE_WRITE_DATA, &fd, &needs_close, NULL ))
{
serial_irq_info new_irq_info;
DWORD new_mstat, new_evtmask;
......@@ -1020,10 +1016,9 @@ static DWORD CALLBACK wait_for_event(LPVOID arg)
break;
}
}
if (needs_close) close( fd );
}
if (commio->hEvent != INVALID_HANDLE_VALUE)
NtSetEvent(commio->hEvent, NULL);
if (fd != -1) wine_server_release_fd( commio->hDevice, fd );
if (commio->hEvent) NtSetEvent(commio->hEvent, NULL);
RtlFreeHeap(GetProcessHeap(), 0, commio);
return 0;
}
......@@ -1126,7 +1121,7 @@ static inline NTSTATUS io_control(HANDLE hDevice,
{
DWORD sz = 0, access = FILE_READ_DATA;
NTSTATUS status = STATUS_SUCCESS;
int fd = -1;
int fd = -1, needs_close = 0;
TRACE("%p %s %p %d %p %d %p\n",
hDevice, iocode2str(dwIoControlCode), lpInBuffer, nInBufferSize,
......@@ -1135,7 +1130,7 @@ static inline NTSTATUS io_control(HANDLE hDevice,
piosb->Information = 0;
if (dwIoControlCode != IOCTL_SERIAL_GET_TIMEOUTS)
if ((status = wine_server_handle_to_fd( hDevice, access, &fd, NULL )))
if ((status = server_get_unix_fd( hDevice, access, &fd, &needs_close, NULL )))
goto error;
switch (dwIoControlCode)
......@@ -1343,7 +1338,7 @@ static inline NTSTATUS io_control(HANDLE hDevice,
status = STATUS_INVALID_PARAMETER;
break;
}
if (fd != -1) wine_server_release_fd( hDevice, fd );
if (needs_close) close( fd );
error:
piosb->u.Status = status;
piosb->Information = sz;
......
......@@ -525,6 +525,58 @@ int server_remove_fd_from_cache( obj_handle_t handle )
/***********************************************************************
* server_get_unix_fd
*
* The returned unix_fd should be closed iff needs_close is non-zero.
*/
int server_get_unix_fd( obj_handle_t handle, unsigned int access, int *unix_fd,
int *needs_close, int *flags )
{
obj_handle_t fd_handle;
int ret = 0, removable = 0, fd;
*unix_fd = -1;
*needs_close = 0;
RtlEnterCriticalSection( &fd_cache_section );
fd = get_cached_fd( handle );
if (fd != -1 && !flags) goto done;
SERVER_START_REQ( get_handle_fd )
{
req->handle = handle;
req->access = access;
req->cached = (fd != -1);
if (!(ret = wine_server_call( req )))
{
removable = reply->flags & FD_FLAG_REMOVABLE;
if (flags) *flags = reply->flags;
}
}
SERVER_END_REQ;
if (!ret && fd == -1)
{
/* it wasn't in the cache, get it from the server */
fd = receive_fd( &fd_handle );
if (fd == -1)
{
ret = STATUS_TOO_MANY_OPENED_FILES;
goto done;
}
assert( fd_handle == handle );
*needs_close = removable || !add_fd_to_cache( handle, fd );
}
done:
RtlLeaveCriticalSection( &fd_cache_section );
if (!ret) *unix_fd = fd;
return ret;
}
/***********************************************************************
* wine_server_fd_to_handle (NTDLL.@)
*
* Allocate a file handle for a Unix file descriptor.
......@@ -573,59 +625,12 @@ int wine_server_fd_to_handle( int fd, unsigned int access, unsigned int attribut
*/
int wine_server_handle_to_fd( obj_handle_t handle, unsigned int access, int *unix_fd, int *flags )
{
obj_handle_t fd_handle;
int ret = 0, removable = 0, fd = -1;
int needs_close, ret = server_get_unix_fd( handle, access, unix_fd, &needs_close, flags );
RtlEnterCriticalSection( &fd_cache_section );
*unix_fd = -1;
fd = get_cached_fd( handle );
if (fd != -1 && !flags)
if (!ret && !needs_close)
{
if ((fd = dup(fd)) == -1) ret = FILE_GetNtStatus();
goto done;
if ((*unix_fd = dup(*unix_fd)) == -1) ret = FILE_GetNtStatus();
}
SERVER_START_REQ( get_handle_fd )
{
req->handle = handle;
req->access = access;
req->cached = (fd != -1);
if (!(ret = wine_server_call( req )))
{
removable = reply->flags & FD_FLAG_REMOVABLE;
if (flags) *flags = reply->flags;
}
}
SERVER_END_REQ;
if (ret) goto done;
if (fd != -1)
{
if ((fd = dup(fd)) == -1) ret = FILE_GetNtStatus();
goto done;
}
/* it wasn't in the cache, get it from the server */
fd = receive_fd( &fd_handle );
if (fd == -1)
{
ret = STATUS_TOO_MANY_OPENED_FILES;
goto done;
}
assert( fd_handle == handle );
if (removable) goto done; /* don't cache it */
if (add_fd_to_cache( handle, fd ))
{
if ((fd = dup(fd)) == -1) ret = FILE_GetNtStatus();
}
done:
RtlLeaveCriticalSection( &fd_cache_section );
if (!ret) *unix_fd = fd;
return ret;
}
......
......@@ -512,14 +512,14 @@ NTSTATUS TAPE_DeviceIoControl( HANDLE device, HANDLE event,
{
DWORD sz = 0;
NTSTATUS status = STATUS_INVALID_PARAMETER;
int fd;
int fd, needs_close;
TRACE( "%p %s %p %d %p %d %p\n", device, io2str(io_control),
in_buffer, in_size, out_buffer, out_size, io_status );
io_status->Information = 0;
if ((status = wine_server_handle_to_fd( device, 0, &fd, NULL )))
if ((status = server_get_unix_fd( device, 0, &fd, &needs_close, NULL )))
goto error;
switch (io_control)
......@@ -569,7 +569,7 @@ NTSTATUS TAPE_DeviceIoControl( HANDLE device, HANDLE event,
break;
}
wine_server_release_fd( device, fd );
if (needs_close) close( fd );
error:
io_status->u.Status = status;
......
......@@ -1767,11 +1767,10 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
SIZE_T commit_size, const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr,
SECTION_INHERIT inherit, ULONG alloc_type, ULONG protect )
{
FILE_FS_DEVICE_INFORMATION device_info;
NTSTATUS res;
SIZE_T size = 0;
SIZE_T mask = get_mask( zero_bits );
int unix_handle = -1;
int unix_handle = -1, flags, needs_close;
int prot;
void *base;
struct file_view *view;
......@@ -1811,22 +1810,20 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
SERVER_END_REQ;
if (res) return res;
if ((res = wine_server_handle_to_fd( handle, 0, &unix_handle, NULL ))) return res;
if (FILE_GetDeviceInfo( unix_handle, &device_info ) == STATUS_SUCCESS)
removable = device_info.Characteristics & FILE_REMOVABLE_MEDIA;
if ((res = server_get_unix_fd( handle, 0, &unix_handle, &needs_close, &flags ))) return res;
removable = (flags & FD_FLAG_REMOVABLE) != 0;
if (prot & VPROT_IMAGE)
{
if (shared_file)
{
int shared_fd;
int shared_fd, shared_needs_close;
if ((res = wine_server_handle_to_fd( shared_file, FILE_READ_DATA|FILE_WRITE_DATA,
&shared_fd, NULL ))) goto done;
if ((res = server_get_unix_fd( shared_file, FILE_READ_DATA|FILE_WRITE_DATA,
&shared_fd, &shared_needs_close, NULL ))) goto done;
res = map_image( handle, unix_handle, base, size_low, mask, header_size,
shared_fd, removable, addr_ptr );
wine_server_release_fd( shared_file, shared_fd );
if (shared_needs_close) close( shared_fd );
NtClose( shared_file );
}
else
......@@ -1834,7 +1831,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
res = map_image( handle, unix_handle, base, size_low, mask, header_size,
-1, removable, addr_ptr );
}
wine_server_release_fd( handle, unix_handle );
if (needs_close) close( unix_handle );
if (!res) *size_ptr = size_low;
return res;
}
......@@ -1921,7 +1918,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
RtlLeaveCriticalSection( &csVirtual );
done:
wine_server_release_fd( handle, unix_handle );
if (needs_close) close( unix_handle );
return res;
}
......
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