Jacek Caban : rpcrt4: Add close_read implementation for named pipe connections.
Module: wine Branch: master Commit: 29f0b2824068496eca4a0e19ce3e464d965cf010 URL: http://source.winehq.org/git/wine.git/?a=commit;h=29f0b2824068496eca4a0e19ce... Author: Jacek Caban <jacek(a)codeweavers.com> Date: Wed May 24 13:52:14 2017 +0200 rpcrt4: Add close_read implementation for named pipe connections. Signed-off-by: Jacek Caban <jacek(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/rpcrt4/rpc_transport.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c index 6f83a24..293d09f 100644 --- a/dlls/rpcrt4/rpc_transport.c +++ b/dlls/rpcrt4/rpc_transport.c @@ -69,6 +69,7 @@ typedef struct _RpcConnection_np HANDLE listen_event; IO_STATUS_BLOCK io_status; HANDLE event_cache; + BOOL read_closed; } RpcConnection_np; static RpcConnection *rpcrt4_conn_np_alloc(void) @@ -384,7 +385,6 @@ static RPC_STATUS rpcrt4_ncalrpc_handoff(RpcConnection *old_conn, RpcConnection static int rpcrt4_conn_np_read(RpcConnection *conn, void *buffer, unsigned int count) { RpcConnection_np *connection = (RpcConnection_np *) conn; - IO_STATUS_BLOCK io_status; HANDLE event; NTSTATUS status; @@ -392,14 +392,23 @@ static int rpcrt4_conn_np_read(RpcConnection *conn, void *buffer, unsigned int c if (!event) return -1; - status = NtReadFile(connection->pipe, event, NULL, NULL, &io_status, buffer, count, NULL, NULL); + if (connection->read_closed) + status = STATUS_CANCELLED; + else + status = NtReadFile(connection->pipe, event, NULL, NULL, &connection->io_status, buffer, count, NULL, NULL); if (status == STATUS_PENDING) { + /* check read_closed again before waiting to avoid a race */ + if (connection->read_closed) + { + IO_STATUS_BLOCK io_status; + NtCancelIoFileEx(connection->pipe, &connection->io_status, &io_status); + } WaitForSingleObject(event, INFINITE); - status = io_status.Status; + status = connection->io_status.Status; } release_np_event(connection, event); - return status && status != STATUS_BUFFER_OVERFLOW ? -1 : io_status.Information; + return status && status != STATUS_BUFFER_OVERFLOW ? -1 : connection->io_status.Information; } static int rpcrt4_conn_np_write(RpcConnection *conn, const void *buffer, unsigned int count) @@ -451,7 +460,11 @@ static int rpcrt4_conn_np_close(RpcConnection *conn) static void rpcrt4_conn_np_close_read(RpcConnection *conn) { - /* FIXME */ + RpcConnection_np *connection = (RpcConnection_np*)conn; + IO_STATUS_BLOCK io_status; + + connection->read_closed = TRUE; + NtCancelIoFileEx(connection->pipe, &connection->io_status, &io_status); } static void rpcrt4_conn_np_cancel_call(RpcConnection *conn)
participants (1)
-
Alexandre Julliard