diff --git a/dlls/ntdll/cdrom.c b/dlls/ntdll/cdrom.c index 9a400d0d106..2046e11edbb 100644 --- a/dlls/ntdll/cdrom.c +++ b/dlls/ntdll/cdrom.c @@ -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; diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c index 0ab16d267a8..d2c0d16adce 100644 --- a/dlls/ntdll/directory.c +++ b/dlls/ntdll/directory.c @@ -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 ); diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index eecce673594..514a8a75769 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -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; } diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 7ce4b02aac7..d18728fe708 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -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 ); diff --git a/dlls/ntdll/serial.c b/dlls/ntdll/serial.c index dde864a4405..7321e6ea390 100644 --- a/dlls/ntdll/serial.c +++ b/dlls/ntdll/serial.c @@ -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; diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index a41fb69f4dd..2d6235c8126 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -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; } diff --git a/dlls/ntdll/tape.c b/dlls/ntdll/tape.c index ecb1cc50909..8ce68f37b3f 100644 --- a/dlls/ntdll/tape.c +++ b/dlls/ntdll/tape.c @@ -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; diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 60708d10fb1..cce7ddd2a5e 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -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; }