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