ntdll: Added a server_get_unix_fd function that avoids doing a dup() of the fd when not required.
This commit is contained in:
parent
7c38ff6adf
commit
9ddb9294da
|
@ -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;
|
||||
|
|
|
@ -524,6 +524,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.@)
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue