Export the FILE_GetUnixHandle functionality from ntdll.
This commit is contained in:
parent
ead221211f
commit
8d1550d1c6
|
@ -1041,6 +1041,7 @@ debug_channels (atom cdrom console debug delayhlp dll dosfs dosmem file fixup
|
||||||
|
|
||||||
# Server interface
|
# Server interface
|
||||||
@ cdecl -norelay wine_server_call(ptr) wine_server_call
|
@ cdecl -norelay wine_server_call(ptr) wine_server_call
|
||||||
|
@ cdecl wine_server_handle_to_fd(long long ptr ptr ptr) wine_server_handle_to_fd
|
||||||
|
|
||||||
# Codepages
|
# Codepages
|
||||||
@ cdecl __wine_init_codepages(ptr ptr) __wine_init_codepages
|
@ cdecl __wine_init_codepages(ptr ptr) __wine_init_codepages
|
||||||
|
|
36
files/file.c
36
files/file.c
|
@ -227,36 +227,12 @@ HANDLE FILE_DupUnixHandle( int fd, DWORD access, BOOL inherit )
|
||||||
* Retrieve the Unix handle corresponding to a file handle.
|
* Retrieve the Unix handle corresponding to a file handle.
|
||||||
* Returns -1 on failure.
|
* Returns -1 on failure.
|
||||||
*/
|
*/
|
||||||
static int FILE_GetUnixHandleType( HANDLE handle, DWORD access, enum fd_type *type, DWORD *flags )
|
static int FILE_GetUnixHandleType( HANDLE handle, DWORD access, enum fd_type *type, int *flags )
|
||||||
{
|
{
|
||||||
int ret, fd = -1;
|
int ret, fd = -1;
|
||||||
|
|
||||||
do
|
ret = wine_server_handle_to_fd( handle, access, &fd, type, flags );
|
||||||
{
|
if (ret) SetLastError( RtlNtStatusToDosError(ret) );
|
||||||
SERVER_START_REQ( get_handle_fd )
|
|
||||||
{
|
|
||||||
req->handle = handle;
|
|
||||||
req->access = access;
|
|
||||||
if (!(ret = wine_server_call_err( req )))
|
|
||||||
{
|
|
||||||
fd = reply->fd;
|
|
||||||
}
|
|
||||||
if (type) *type = reply->type;
|
|
||||||
if (flags) *flags = reply->flags;
|
|
||||||
}
|
|
||||||
SERVER_END_REQ;
|
|
||||||
if (ret) return -1;
|
|
||||||
|
|
||||||
if (fd == -1) /* it wasn't in the cache, get it from the server */
|
|
||||||
fd = wine_server_recv_fd( handle );
|
|
||||||
|
|
||||||
} while (fd == -2); /* -2 means race condition, so restart from scratch */
|
|
||||||
|
|
||||||
if (fd != -1)
|
|
||||||
{
|
|
||||||
if ((fd = dup(fd)) == -1)
|
|
||||||
SetLastError( ERROR_TOO_MANY_OPEN_FILES );
|
|
||||||
}
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1467,9 +1443,8 @@ static BOOL FILE_TimeoutRead(HANDLE hFile, LPVOID buffer, DWORD bytesToRead, LPD
|
||||||
BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
|
BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
|
||||||
LPDWORD bytesRead, LPOVERLAPPED overlapped )
|
LPDWORD bytesRead, LPOVERLAPPED overlapped )
|
||||||
{
|
{
|
||||||
int unix_handle, result;
|
int unix_handle, result, flags;
|
||||||
enum fd_type type;
|
enum fd_type type;
|
||||||
DWORD flags;
|
|
||||||
|
|
||||||
TRACE("%d %p %ld %p %p\n", hFile, buffer, bytesToRead,
|
TRACE("%d %p %ld %p %p\n", hFile, buffer, bytesToRead,
|
||||||
bytesRead, overlapped );
|
bytesRead, overlapped );
|
||||||
|
@ -1693,9 +1668,8 @@ BOOL WINAPI WriteFileEx(HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
|
||||||
BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
|
BOOL WINAPI WriteFile( HANDLE hFile, LPCVOID buffer, DWORD bytesToWrite,
|
||||||
LPDWORD bytesWritten, LPOVERLAPPED overlapped )
|
LPDWORD bytesWritten, LPOVERLAPPED overlapped )
|
||||||
{
|
{
|
||||||
int unix_handle, result;
|
int unix_handle, result, flags;
|
||||||
enum fd_type type;
|
enum fd_type type;
|
||||||
DWORD flags;
|
|
||||||
|
|
||||||
TRACE("%d %p %ld %p %p\n", hFile, buffer, bytesToWrite,
|
TRACE("%d %p %ld %p %p\n", hFile, buffer, bytesToWrite,
|
||||||
bytesWritten, overlapped );
|
bytesWritten, overlapped );
|
||||||
|
|
|
@ -51,7 +51,8 @@ struct __server_request_info
|
||||||
|
|
||||||
extern unsigned int wine_server_call( void *req_ptr );
|
extern unsigned int wine_server_call( void *req_ptr );
|
||||||
extern void wine_server_send_fd( int fd );
|
extern void wine_server_send_fd( int fd );
|
||||||
extern int wine_server_recv_fd( handle_t handle );
|
extern int wine_server_handle_to_fd( handle_t handle, unsigned int access, int *unix_fd,
|
||||||
|
enum fd_type *type, int *flags );
|
||||||
|
|
||||||
/* do a server call and set the last error code */
|
/* do a server call and set the last error code */
|
||||||
inline static unsigned int wine_server_call_err( void *req_ptr )
|
inline static unsigned int wine_server_call_err( void *req_ptr )
|
||||||
|
|
|
@ -330,23 +330,17 @@ static int receive_fd( handle_t *handle )
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* wine_server_recv_fd
|
* store_cached_fd
|
||||||
*
|
*
|
||||||
* Receive a file descriptor passed from the server.
|
* Store the cached fd value for a given handle back into the server.
|
||||||
* The file descriptor must not be closed.
|
* Returns the new fd, which can be different if there was already an
|
||||||
* Return -2 if a race condition stole our file descriptor.
|
* fd in the cache for that handle.
|
||||||
*/
|
*/
|
||||||
int wine_server_recv_fd( handle_t handle )
|
inline static int store_cached_fd( int fd, handle_t handle )
|
||||||
{
|
{
|
||||||
handle_t fd_handle;
|
|
||||||
|
|
||||||
int fd = receive_fd( &fd_handle );
|
|
||||||
|
|
||||||
/* now store it in the server fd cache for this handle */
|
|
||||||
|
|
||||||
SERVER_START_REQ( set_handle_info )
|
SERVER_START_REQ( set_handle_info )
|
||||||
{
|
{
|
||||||
req->handle = fd_handle;
|
req->handle = handle;
|
||||||
req->flags = 0;
|
req->flags = 0;
|
||||||
req->mask = 0;
|
req->mask = 0;
|
||||||
req->fd = fd;
|
req->fd = fd;
|
||||||
|
@ -366,12 +360,55 @@ int wine_server_recv_fd( handle_t handle )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
if (handle != fd_handle) fd = -2; /* not the one we expected */
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* wine_server_handle_to_fd (NTDLL.@)
|
||||||
|
*
|
||||||
|
* Retrieve the Unix fd corresponding to a file handle.
|
||||||
|
*/
|
||||||
|
int wine_server_handle_to_fd( handle_t handle, unsigned int access, int *unix_fd,
|
||||||
|
enum fd_type *type, int *flags )
|
||||||
|
{
|
||||||
|
handle_t fd_handle;
|
||||||
|
int ret, fd = -1;
|
||||||
|
|
||||||
|
*unix_fd = -1;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
SERVER_START_REQ( get_handle_fd )
|
||||||
|
{
|
||||||
|
req->handle = handle;
|
||||||
|
req->access = access;
|
||||||
|
if (!(ret = wine_server_call( req ))) fd = reply->fd;
|
||||||
|
if (type) *type = reply->type;
|
||||||
|
if (flags) *flags = reply->flags;
|
||||||
|
}
|
||||||
|
SERVER_END_REQ;
|
||||||
|
if (ret) return ret;
|
||||||
|
|
||||||
|
if (fd != -1) break;
|
||||||
|
|
||||||
|
/* it wasn't in the cache, get it from the server */
|
||||||
|
fd = receive_fd( &fd_handle );
|
||||||
|
/* and store it back into the cache */
|
||||||
|
fd = store_cached_fd( fd, fd_handle );
|
||||||
|
|
||||||
|
if (fd_handle == handle) break;
|
||||||
|
/* if we received a different handle this means there was
|
||||||
|
* a race with another thread; we restart everything from
|
||||||
|
* scratch in this case.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fd != -1) && ((fd = dup(fd)) == -1)) return STATUS_TOO_MANY_OPENED_FILES;
|
||||||
|
*unix_fd = fd;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* get_config_dir
|
* get_config_dir
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue