Jacek Caban : rpcrt4: Add close_read implementation for named pipe connections.

Alexandre Julliard julliard at winehq.org
Wed May 24 17:17:33 CDT 2017


Module: wine
Branch: master
Commit: 29f0b2824068496eca4a0e19ce3e464d965cf010
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=29f0b2824068496eca4a0e19ce3e464d965cf010

Author: Jacek Caban <jacek at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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)




More information about the wine-cvs mailing list