Author: akhaldi
Date: Sun Jun  4 14:01:54 2017
New Revision: 74904

URL: http://svn.reactos.org/svn/reactos?rev=74904&view=rev
Log:
[RPCRT4] Sync with Wine Staging 2.9. CORE-13362

6b53b79 rpcrt4: Use HEAP_ZERO_MEMORY to alloc RpcServerProtseq objects.
28f865b rpcrt4: Add close_read implementation for TCP connections.
29f0b28 rpcrt4: Add close_read implementation for named pipe connections.
42ba4d7 rpcrt4: Introduce op for closing connection read end and use it when 
shutting down server.
ef267f1 rpcrt4: Store all active connections in RpcServerProtseq.
dae3065 rpcrt4: Remove connection from list in RPCRT4_ReleaseConnection.
812897c rpcrt4: Use HEAP_ZERO_MEMORY to alloc RpcConnection objects.
13d529a rpcrt4: Renamed connections list to listeners.
c953763 rpcrt4: Remove no longer needed helpers.
b548338 rpcrt4: Implement cancel_call for named pipes.
372c9e0 rpcrt4: Cache event handle in RpcConnection_np object.
6e7a297 rpcrt4: Use non-blocking listening on named pipes.
4f4ac8c rpcrt4: Use named pipe in overlapped mode.
bd6f807 rpcrt4: Simplify rpcrt4_conn_np_read implementation.
f62b9d6 rpcrt4: Simplify rpcrt4_conn_np_write implementation.
2035294 rpcrt4: Use standard Wine list to store connections in RpcServerProtseq.
e621593 rpcrt4: Always use winsock for networking.
d0ed6d1 rpcrt4: Get rid of manual_listen_count and use binary state instead.

Modified:
    trunk/reactos/dll/win32/rpcrt4/rpc_binding.h
    trunk/reactos/dll/win32/rpcrt4/rpc_server.c
    trunk/reactos/dll/win32/rpcrt4/rpc_server.h
    trunk/reactos/dll/win32/rpcrt4/rpc_transport.c
    trunk/reactos/media/doc/README.WINE

Modified: trunk/reactos/dll/win32/rpcrt4/rpc_binding.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/rpcrt4/rpc_binding.h?rev=74904&r1=74903&r2=74904&view=diff
==============================================================================
--- trunk/reactos/dll/win32/rpcrt4/rpc_binding.h        [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/rpcrt4/rpc_binding.h        [iso-8859-1] Sun Jun  4 
14:01:54 2017
@@ -86,7 +86,8 @@
   /* The active interface bound to server. */
   RPC_SYNTAX_IDENTIFIER ActiveInterface;
   USHORT NextCallId;
-  struct _RpcConnection* Next;
+  struct list protseq_entry;
+  struct _RpcServerProtseq *protseq;
   struct _RpcBinding *server_binding;
 } RpcConnection;
 
@@ -99,6 +100,7 @@
   int (*read)(RpcConnection *conn, void *buffer, unsigned int len);
   int (*write)(RpcConnection *conn, const void *buffer, unsigned int len);
   int (*close)(RpcConnection *conn);
+  void (*close_read)(RpcConnection *conn);
   void (*cancel_call)(RpcConnection *conn);
   RPC_STATUS (*is_server_listening)(const char *endpoint);
   int (*wait_for_incoming_data)(RpcConnection *conn);
@@ -192,6 +194,11 @@
   return Connection->ops->close(Connection);
 }
 
+static inline void rpcrt4_conn_close_read(RpcConnection *connection)
+{
+  connection->ops->close_read(connection);
+}
+
 static inline void rpcrt4_conn_cancel_call(RpcConnection *Connection)
 {
   Connection->ops->cancel_call(Connection);

Modified: trunk/reactos/dll/win32/rpcrt4/rpc_server.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/rpcrt4/rpc_server.c?rev=74904&r1=74903&r2=74904&view=diff
==============================================================================
--- trunk/reactos/dll/win32/rpcrt4/rpc_server.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/rpcrt4/rpc_server.c [iso-8859-1] Sun Jun  4 
14:01:54 2017
@@ -79,11 +79,9 @@
 
 /* whether the server is currently listening */
 static BOOL std_listen;
-/* number of manual listeners (calls to RpcServerListen) */
-static LONG manual_listen_count;
 /* total listeners including auto listeners */
 static LONG listen_count;
-/* event set once all listening is finished */
+/* event set once all manual listening is finished */
 static HANDLE listen_done_event;
 
 static UUID uuid_nil;
@@ -649,9 +647,12 @@
     {
       /* cleanup */
       cps->ops->free_wait_array(cps, objs);
+
       EnterCriticalSection(&cps->cs);
-      for (conn = cps->conn; conn; conn = conn->Next)
+      LIST_FOR_EACH_ENTRY(conn, &cps->listeners, RpcConnection, protseq_entry)
         RPCRT4_CloseConnection(conn);
+      LIST_FOR_EACH_ENTRY(conn, &cps->connections, RpcConnection, 
protseq_entry)
+        rpcrt4_conn_close_read(conn);
       LeaveCriticalSection(&cps->cs);
 
       if (res == 0 && !std_listen)
@@ -713,13 +714,16 @@
   TRACE("\n");
 
   EnterCriticalSection(&listen_cs);
-  if (auto_listen || (manual_listen_count++ == 0))
+  if (auto_listen || !listen_done_event)
   {
     status = RPC_S_OK;
+    if(!auto_listen)
+      listen_done_event = CreateEventW(NULL, TRUE, FALSE, NULL);
     if (++listen_count == 1)
       std_listen = TRUE;
   }
   LeaveCriticalSection(&listen_cs);
+  if (status) return status;
 
   if (std_listen)
   {
@@ -742,51 +746,53 @@
 
 static RPC_STATUS RPCRT4_stop_listen(BOOL auto_listen)
 {
+  BOOL stop_listen = FALSE;
   RPC_STATUS status = RPC_S_OK;
 
   EnterCriticalSection(&listen_cs);
-
-  if (!std_listen)
+  if (!std_listen && (auto_listen || !listen_done_event))
   {
     status = RPC_S_NOT_LISTENING;
-    goto done;
-  }
-
-  if (auto_listen || (--manual_listen_count == 0))
+  }
+  else
   {
-    if (listen_count != 0 && --listen_count == 0) {
-      RpcServerProtseq *cps;
-
+    stop_listen = listen_count != 0 && --listen_count == 0;
+    assert(listen_count >= 0);
+    if (stop_listen)
       std_listen = FALSE;
+  }
+  LeaveCriticalSection(&listen_cs);
+
+  if (status) return status;
+
+  if (stop_listen) {
+    RpcServerProtseq *cps;
+    LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry)
+      RPCRT4_sync_with_server_thread(cps);
+  }
+
+  if (!auto_listen)
+  {
+      EnterCriticalSection(&listen_cs);
+      SetEvent( listen_done_event );
       LeaveCriticalSection(&listen_cs);
-
-      LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry)
-        RPCRT4_sync_with_server_thread(cps);
-
-      EnterCriticalSection(&listen_cs);
-      if (listen_done_event) SetEvent( listen_done_event );
-      listen_done_event = 0;
-      goto done;
-    }
-    assert(listen_count >= 0);
-  }
-
-done:
-  LeaveCriticalSection(&listen_cs);
-  return status;
+  }
+  return RPC_S_OK;
 }
 
 static BOOL RPCRT4_protseq_is_endpoint_registered(RpcServerProtseq *protseq, 
const char *endpoint)
 {
   RpcConnection *conn;
+  BOOL registered = FALSE;
   EnterCriticalSection(&protseq->cs);
-  for (conn = protseq->conn; conn; conn = conn->Next)
-  {
-    if (!endpoint || !strcmp(endpoint, conn->Endpoint))
+  LIST_FOR_EACH_ENTRY(conn, &protseq->listeners, RpcConnection, protseq_entry) 
{
+    if (!endpoint || !strcmp(endpoint, conn->Endpoint)) {
+      registered = TRUE;
       break;
+    }
   }
   LeaveCriticalSection(&protseq->cs);
-  return (conn != NULL);
+  return registered;
 }
 
 static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, const char 
*endpoint)
@@ -835,7 +841,7 @@
   count = 0;
   LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) {
     EnterCriticalSection(&ps->cs);
-    for (conn = ps->conn; conn; conn = conn->Next)
+    LIST_FOR_EACH_ENTRY(conn, &ps->listeners, RpcConnection, protseq_entry)
       count++;
     LeaveCriticalSection(&ps->cs);
   }
@@ -848,7 +854,7 @@
     count = 0;
     LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) {
       EnterCriticalSection(&ps->cs);
-      for (conn = ps->conn; conn; conn = conn->Next) {
+      LIST_FOR_EACH_ENTRY(conn, &ps->listeners, RpcConnection, protseq_entry) {
        RPCRT4_MakeBinding((RpcBinding**)&(*BindingVector)->BindingH[count],
                           conn);
        count++;
@@ -919,13 +925,10 @@
   (*ps)->MaxCalls = MaxCalls;
   (*ps)->Protseq = RPCRT4_strdupA(Protseq);
   (*ps)->ops = ops;
-  (*ps)->MaxCalls = 0;
-  (*ps)->conn = NULL;
+  list_init(&(*ps)->listeners);
+  list_init(&(*ps)->connections);
   InitializeCriticalSection(&(*ps)->cs);
   (*ps)->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": 
RpcServerProtseq.cs");
-  (*ps)->is_listening = FALSE;
-  (*ps)->mgr_mutex = NULL;
-  (*ps)->server_ready_event = NULL;
 
   list_add_head(&protseqs, &(*ps)->entry);
 
@@ -1505,25 +1508,23 @@
   TRACE("()\n");
 
   EnterCriticalSection(&listen_cs);
-
-  if (!std_listen) {
-    LeaveCriticalSection(&listen_cs);
-    return RPC_S_NOT_LISTENING;
-  }
-  if (listen_done_event) {
-    LeaveCriticalSection(&listen_cs);
-    return RPC_S_ALREADY_LISTENING;
-  }
-  event = CreateEventW( NULL, TRUE, FALSE, NULL );
-  listen_done_event = event;
-
+  event = listen_done_event;
   LeaveCriticalSection(&listen_cs);
+
+  if (!event)
+      return RPC_S_NOT_LISTENING;
 
   TRACE( "waiting for server calls to finish\n" );
   WaitForSingleObject( event, INFINITE );
   TRACE( "done waiting\n" );
 
-  CloseHandle( event );
+  EnterCriticalSection(&listen_cs);
+  if (listen_done_event == event)
+  {
+      listen_done_event = NULL;
+      CloseHandle( event );
+  }
+  LeaveCriticalSection(&listen_cs);
   return RPC_S_OK;
 }
 
@@ -1649,7 +1650,7 @@
     status = RPCRT4_IsServerListening(rpc_binding->Protseq, 
rpc_binding->Endpoint);
   }else {
     EnterCriticalSection(&listen_cs);
-    if (manual_listen_count > 0) status = RPC_S_OK;
+    if (listen_done_event && std_listen) status = RPC_S_OK;
     LeaveCriticalSection(&listen_cs);
   }
 

Modified: trunk/reactos/dll/win32/rpcrt4/rpc_server.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/rpcrt4/rpc_server.h?rev=74904&r1=74903&r2=74904&view=diff
==============================================================================
--- trunk/reactos/dll/win32/rpcrt4/rpc_server.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/rpcrt4/rpc_server.h [iso-8859-1] Sun Jun  4 
14:01:54 2017
@@ -32,7 +32,8 @@
   LPSTR Protseq; /* RO */
   UINT MaxCalls; /* RO */
   /* list of listening connections */
-  RpcConnection* conn; /* CS cs */
+  struct list listeners; /* CS cs */
+  struct list connections; /* CS cs */
   CRITICAL_SECTION cs;
 
   /* is the server currently listening? */

Modified: trunk/reactos/dll/win32/rpcrt4/rpc_transport.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/rpcrt4/rpc_transport.c?rev=74904&r1=74903&r2=74904&view=diff
==============================================================================
--- trunk/reactos/dll/win32/rpcrt4/rpc_transport.c      [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/rpcrt4/rpc_transport.c      [iso-8859-1] Sun Jun  4 
14:01:54 2017
@@ -25,57 +25,14 @@
 
 #include "precomp.h"
 
-#if defined(__MINGW32__) || defined (_MSC_VER)
-# include <ws2tcpip.h>
-# ifndef EADDRINUSE
-#  define EADDRINUSE WSAEADDRINUSE
-# endif
-# ifndef EAGAIN
-#  define EAGAIN WSAEWOULDBLOCK
-# endif
-# undef errno
-# define errno WSAGetLastError()
-#else
-# include <errno.h>
-# ifdef HAVE_UNISTD_H
-#  include <unistd.h>
-# endif
-# include <fcntl.h>
-# ifdef HAVE_SYS_SOCKET_H
-#  include <sys/socket.h>
-# endif
-# ifdef HAVE_NETINET_IN_H
-#  include <netinet/in.h>
-# endif
-# ifdef HAVE_NETINET_TCP_H
-#  include <netinet/tcp.h>
-# endif
-# ifdef HAVE_ARPA_INET_H
-#  include <arpa/inet.h>
-# endif
-# ifdef HAVE_NETDB_H
-#  include <netdb.h>
-# endif
-# ifdef HAVE_SYS_POLL_H
-#  include <sys/poll.h>
-# endif
-# ifdef HAVE_SYS_FILIO_H
-#  include <sys/filio.h>
-# endif
-# ifdef HAVE_SYS_IOCTL_H
-#  include <sys/ioctl.h>
-# endif
-# define closesocket close
-# define ioctlsocket ioctl
-#endif /* defined(__MINGW32__) || defined (_MSC_VER) */
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include <ws2tcpip.h>
 
 #include <wininet.h>
+#include <winioctl.h>
 
 #include "epm_towers.h"
-
-#ifndef SOL_TCP
-# define SOL_TCP IPPROTO_TCP
-#endif
 
 #define DEFAULT_NCACN_HTTP_TIMEOUT (60 * 1000)
 
@@ -84,78 +41,53 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(rpc);
 
-static RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, 
RpcConnection* OldConnection);
+#ifdef __REACTOS__ /* FIXME: Inspect */
+BOOL WINAPI CancelIoEx(HANDLE handle, LPOVERLAPPED lpOverlapped)
+{
+     IO_STATUS_BLOCK    io_status;
+
+    NtCancelIoFile(handle, &io_status);
+    if (io_status.u.Status)
+    {
+        SetLastError( RtlNtStatusToDosError( io_status.u.Status ) );
+        return FALSE;
+    }
+    return TRUE;
+}
+#endif
+
+static RpcConnection *rpcrt4_spawn_connection(RpcConnection *old_connection);
 
 /**** ncacn_np support ****/
 
 typedef struct _RpcConnection_np
 {
-  RpcConnection common;
-  HANDLE pipe;
-  OVERLAPPED ovl;
-  BOOL listening;
+    RpcConnection common;
+    HANDLE pipe;
+    HANDLE listen_event;
+    IO_STATUS_BLOCK io_status;
+    HANDLE event_cache;
+    BOOL read_closed;
 } RpcConnection_np;
 
 static RpcConnection *rpcrt4_conn_np_alloc(void)
 {
   RpcConnection_np *npc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
sizeof(RpcConnection_np));
-  if (npc)
-  {
-    npc->pipe = NULL;
-    memset(&npc->ovl, 0, sizeof(npc->ovl));
-    npc->listening = FALSE;
-  }
   return &npc->common;
 }
 
-static RPC_STATUS rpcrt4_conn_listen_pipe(RpcConnection_np *npc)
-{
-  if (npc->listening)
-    return RPC_S_OK;
-
-  npc->listening = TRUE;
-  for (;;)
-  {
-      if (ConnectNamedPipe(npc->pipe, &npc->ovl))
-          return RPC_S_OK;
-
-      switch(GetLastError())
-      {
-      case ERROR_PIPE_CONNECTED:
-          SetEvent(npc->ovl.hEvent);
-          return RPC_S_OK;
-      case ERROR_IO_PENDING:
-          /* will be completed in rpcrt4_protseq_np_wait_for_new_connection */
-          return RPC_S_OK;
-      case ERROR_NO_DATA_DETECTED:
-          /* client has disconnected, retry */
-          DisconnectNamedPipe( npc->pipe );
-          break;
-      default:
-          npc->listening = FALSE;
-          WARN("Couldn't ConnectNamedPipe (error was %d)\n", GetLastError());
-          return RPC_S_OUT_OF_RESOURCES;
-      }
-  }
-}
-
-#ifndef __REACTOS__
-static RPC_STATUS rpcrt4_conn_listen_pipe(RpcConnection_np *npc)
-{
-  if (npc->listening)
-    return RPC_S_OK;
-
-  npc->listening = TRUE;
-  npc->listen_thread = CreateThread(NULL, 0, listen_thread, npc, 0, NULL);
-  if (!npc->listen_thread)
-  {
-      npc->listening = FALSE;
-      ERR("Couldn't create listen thread (error was %d)\n", GetLastError());
-      return RPC_S_OUT_OF_RESOURCES;
-  }
-  return RPC_S_OK;
-}
-#endif
+static HANDLE get_np_event(RpcConnection_np *connection)
+{
+    HANDLE event = InterlockedExchangePointer(&connection->event_cache, NULL);
+    return event ? event : CreateEventW(NULL, TRUE, FALSE, NULL);
+}
+
+static void release_np_event(RpcConnection_np *connection, HANDLE event)
+{
+    event = InterlockedExchangePointer(&connection->event_cache, event);
+    if (event)
+        CloseHandle(event);
+}
 
 static RPC_STATUS rpcrt4_conn_create_pipe(RpcConnection *Connection, LPCSTR 
pname)
 {
@@ -173,9 +105,6 @@
     else
       return RPC_S_CANT_CREATE_ENDPOINT;
   }
-
-  memset(&npc->ovl, 0, sizeof(npc->ovl));
-  npc->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
 
   /* Note: we don't call ConnectNamedPipe here because it must be done in the
    * server thread as the thread must be alertable */
@@ -217,15 +146,12 @@
             dwFlags |= SECURITY_CONTEXT_TRACKING;
     }
     pipe = CreateFileA(pname, GENERIC_READ|GENERIC_WRITE, 0, NULL,
-                       OPEN_EXISTING, dwFlags, 0);
+                       OPEN_EXISTING, dwFlags | FILE_FLAG_OVERLAPPED, 0);
     if (pipe != INVALID_HANDLE_VALUE) break;
     err = GetLastError();
     if (err == ERROR_PIPE_BUSY) {
       TRACE("connection failed, error=%x\n", err);
       return RPC_S_SERVER_TOO_BUSY;
-    } else if (err == ERROR_BAD_NETPATH) {
-      TRACE("connection failed, error=%x\n", err);
-      return RPC_S_SERVER_UNAVAILABLE;
     }
     if (!wait || !WaitNamedPipeA(pname, NMPWAIT_WAIT_FOREVER)) {
       err = GetLastError();
@@ -235,11 +161,9 @@
   }
 
   /* success */
-  memset(&npc->ovl, 0, sizeof(npc->ovl));
   /* pipe is connected; change to message-read mode. */
   dwMode = PIPE_READMODE_MESSAGE;
   SetNamedPipeHandleState(pipe, &dwMode, NULL, NULL);
-  npc->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
   npc->pipe = pipe;
 
   return RPC_S_OK;
@@ -301,8 +225,8 @@
   I_RpcFree(pname);
 
   EnterCriticalSection(&protseq->cs);
-  Connection->Next = protseq->conn;
-  protseq->conn = Connection;
+  list_add_head(&protseq->listeners, &Connection->protseq_entry);
+  Connection->protseq = protseq;
   LeaveCriticalSection(&protseq->cs);
 
   return r;
@@ -322,64 +246,15 @@
 static RPC_STATUS rpcrt4_ncacn_np_open(RpcConnection* Connection)
 {
   RpcConnection_np *npc = (RpcConnection_np *) Connection;
-  static const char prefix[] = "\\\\";
-  static const char local[] = ".";
-  BOOL bUseLocalName = TRUE;
-  CHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
-  DWORD bufLen = sizeof(ComputerName)/sizeof(ComputerName[0]);
   RPC_STATUS r;
   LPSTR pname;
-  LPSTR NetworkAddr;
-  INT size;
 
   /* already connected? */
   if (npc->pipe)
     return RPC_S_OK;
 
-  /* protseq=ncacn_np: named pipes */
-  size = strlen(prefix);
-
-  if (Connection->NetworkAddr == NULL || strlen(Connection->NetworkAddr) == 0)
-  {
-    bUseLocalName = TRUE;
-    size += strlen(local);
-  }
-  else
-  {
-    NetworkAddr = Connection->NetworkAddr;
-    if (NetworkAddr[0] == '\\' && NetworkAddr[1] == '\\')
-        NetworkAddr += 2;
-
-    if (GetComputerNameA(ComputerName, &bufLen))
-    {
-      if (stricmp(ComputerName, NetworkAddr) == 0)
-      {
-        bUseLocalName = TRUE;
-        size += strlen(local);
-      }
-      else
-      {
-        bUseLocalName = FALSE;
-        size += strlen(NetworkAddr);
-      }
-    }
-    else
-    {
-      bUseLocalName = FALSE;
-      size += strlen(NetworkAddr);
-    }
-  }
-
-  size += strlen(Connection->Endpoint) + 1;
-
-  pname = I_RpcAllocate(size);
-  strcpy(pname, prefix);
-  if (bUseLocalName)
-    strcat(pname, local);
-  else
-    strcat(pname, NetworkAddr);
-  strcat(pname, Connection->Endpoint);
-  r = rpcrt4_conn_open_pipe(Connection, pname, TRUE);
+  pname = ncacn_pipe_name(Connection->Endpoint);
+  r = rpcrt4_conn_open_pipe(Connection, pname, FALSE);
   I_RpcFree(pname);
 
   return r;
@@ -412,8 +287,8 @@
   I_RpcFree(pname);
 
   EnterCriticalSection(&protseq->cs);
-  Connection->Next = protseq->conn;
-  protseq->conn = Connection;
+  list_add_head(&protseq->listeners, &Connection->protseq_entry);
+  Connection->protseq = protseq;
   LeaveCriticalSection(&protseq->cs);
 
   return r;
@@ -421,14 +296,12 @@
 
 static void rpcrt4_conn_np_handoff(RpcConnection_np *old_npc, RpcConnection_np 
*new_npc)
 {    
-  /* because of the way named pipes work, we'll transfer the connected pipe
-   * to the child, then reopen the server binding to continue listening */
-
-  new_npc->pipe = old_npc->pipe;
-  new_npc->ovl = old_npc->ovl;
-  old_npc->pipe = 0;
-  memset(&old_npc->ovl, 0, sizeof(old_npc->ovl));
-  old_npc->listening = FALSE;
+    /* because of the way named pipes work, we'll transfer the connected pipe
+     * to the child, then reopen the server binding to continue listening */
+
+    new_npc->pipe = old_npc->pipe;
+    old_npc->pipe = 0;
+    assert(!old_npc->listen_event);
 }
 
 static RPC_STATUS rpcrt4_ncacn_np_handoff(RpcConnection *old_conn, 
RpcConnection *new_conn)
@@ -507,80 +380,103 @@
   return status;
 }
 
-static int rpcrt4_conn_np_read(RpcConnection *Connection,
-                        void *buffer, unsigned int count)
-{
-  RpcConnection_np *npc = (RpcConnection_np *) Connection;
-  char *buf = buffer;
-  BOOL ret = TRUE;
-  unsigned int bytes_left = count;
-  OVERLAPPED ovl;
-
-  ZeroMemory(&ovl, sizeof(ovl));
-  ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
-
-  while (bytes_left)
-  {
-    DWORD bytes_read;
-    ret = ReadFile(npc->pipe, buf, bytes_left, &bytes_read, &ovl);
-    if (!ret && GetLastError() == ERROR_IO_PENDING)
-        ret = GetOverlappedResult(npc->pipe, &ovl, &bytes_read, TRUE);
-    if (!ret && GetLastError() == ERROR_MORE_DATA)
-        ret = TRUE;
-    if (!ret || !bytes_read)
-        break;
-    bytes_left -= bytes_read;
-    buf += bytes_read;
-  }
-  CloseHandle(ovl.hEvent);
-  return ret ? count : -1;
-}
-
-static int rpcrt4_conn_np_write(RpcConnection *Connection,
-                             const void *buffer, unsigned int count)
-{
-  RpcConnection_np *npc = (RpcConnection_np *) Connection;
-  const char *buf = buffer;
-  BOOL ret = TRUE;
-  unsigned int bytes_left = count;
-  OVERLAPPED ovl;
-
-  ZeroMemory(&ovl, sizeof(ovl));
-  ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
-
-  while (bytes_left)
-  {
-    DWORD bytes_written;
-    ret = WriteFile(npc->pipe, buf, bytes_left, &bytes_written, &ovl);
-    if (!ret && GetLastError() == ERROR_IO_PENDING)
-        ret = GetOverlappedResult(npc->pipe, &ovl, &bytes_written, TRUE);
-    if (!ret || !bytes_written)
-        break;
-    bytes_left -= bytes_written;
-    buf += bytes_written;
-  }
-  CloseHandle(ovl.hEvent);
-  return ret ? count : -1;
-}
-
-static int rpcrt4_conn_np_close(RpcConnection *Connection)
-{
-  RpcConnection_np *npc = (RpcConnection_np *) Connection;
-  if (npc->pipe) {
-    FlushFileBuffers(npc->pipe);
-    CloseHandle(npc->pipe);
-    npc->pipe = 0;
-  }
-  if (npc->ovl.hEvent) {
-    CloseHandle(npc->ovl.hEvent);
-    npc->ovl.hEvent = 0;
-  }
-  return 0;
-}
-
-static void rpcrt4_conn_np_cancel_call(RpcConnection *Connection)
-{
-    /* FIXME: implement when named pipe writes use overlapped I/O */
+static int rpcrt4_conn_np_read(RpcConnection *conn, void *buffer, unsigned int 
count)
+{
+    RpcConnection_np *connection = (RpcConnection_np *) conn;
+    HANDLE event;
+    NTSTATUS status;
+
+    event = get_np_event(connection);
+    if (!event)
+        return -1;
+
+    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;
+#ifdef __REACTOS__ /* FIXME: We should also cancel I/O for other threads */
+            NtCancelIoFile(connection->pipe, &io_status);
+#else
+            NtCancelIoFileEx(connection->pipe, &connection->io_status, 
&io_status);
+#endif
+        }
+        WaitForSingleObject(event, INFINITE);
+        status = connection->io_status.u.Status;
+    }
+    release_np_event(connection, event);
+    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)
+{
+    RpcConnection_np *connection = (RpcConnection_np *) conn;
+    IO_STATUS_BLOCK io_status;
+    HANDLE event;
+    NTSTATUS status;
+
+    event = get_np_event(connection);
+    if (!event)
+        return -1;
+
+    status = NtWriteFile(connection->pipe, event, NULL, NULL, &io_status, 
buffer, count, NULL, NULL);
+    if (status == STATUS_PENDING)
+    {
+        WaitForSingleObject(event, INFINITE);
+        status = io_status.u.Status;
+    }
+    release_np_event(connection, event);
+    if (status)
+        return -1;
+
+    assert(io_status.Information == count);
+    return count;
+}
+
+static int rpcrt4_conn_np_close(RpcConnection *conn)
+{
+    RpcConnection_np *connection = (RpcConnection_np *) conn;
+    if (connection->pipe)
+    {
+        FlushFileBuffers(connection->pipe);
+        CloseHandle(connection->pipe);
+        connection->pipe = 0;
+    }
+    if (connection->listen_event)
+    {
+        CloseHandle(connection->listen_event);
+        connection->listen_event = 0;
+    }
+    if (connection->event_cache)
+    {
+        CloseHandle(connection->event_cache);
+        connection->event_cache = 0;
+    }
+    return 0;
+}
+
+static void rpcrt4_conn_np_close_read(RpcConnection *conn)
+{
+    RpcConnection_np *connection = (RpcConnection_np*)conn;
+    IO_STATUS_BLOCK io_status;
+
+    connection->read_closed = TRUE;
+#ifdef __REACTOS__ /* FIXME: We should also cancel I/O for other threads */
+    NtCancelIoFile(connection->pipe, &io_status);
+#else
+    NtCancelIoFileEx(connection->pipe, &connection->io_status, &io_status);
+#endif
+}
+
+static void rpcrt4_conn_np_cancel_call(RpcConnection *conn)
+{
+    RpcConnection_np *connection = (RpcConnection_np *)conn;
+    CancelIoEx(connection->pipe, NULL);
 }
 
 static int rpcrt4_conn_np_wait_for_incoming_data(RpcConnection *Connection)
@@ -752,7 +648,7 @@
 
 static RpcServerProtseq *rpcrt4_protseq_np_alloc(void)
 {
-    RpcServerProtseq_np *ps = HeapAlloc(GetProcessHeap(), 0, sizeof(*ps));
+    RpcServerProtseq_np *ps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
sizeof(*ps));
     if (ps)
         ps->mgr_event = CreateEventW(NULL, FALSE, FALSE, NULL);
     return &ps->common;
@@ -774,12 +670,35 @@
     
     /* open and count connections */
     *count = 1;
-    conn = CONTAINING_RECORD(protseq->conn, RpcConnection_np, common);
-    while (conn) {
-        rpcrt4_conn_listen_pipe(conn);
-        if (conn->ovl.hEvent)
-            (*count)++;
-        conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_np, common);
+    LIST_FOR_EACH_ENTRY(conn, &protseq->listeners, RpcConnection_np, 
common.protseq_entry)
+    {
+        if (!conn->listen_event)
+        {
+            NTSTATUS status;
+            HANDLE event;
+
+            event = get_np_event(conn);
+            if (!event)
+                continue;
+
+            status = NtFsControlFile(conn->pipe, event, NULL, NULL, 
&conn->io_status, FSCTL_PIPE_LISTEN, NULL, 0, NULL, 0);
+            switch (status)
+            {
+            case STATUS_SUCCESS:
+            case STATUS_PIPE_CONNECTED:
+                conn->io_status.u.Status = status;
+                SetEvent(event);
+                break;
+            case STATUS_PENDING:
+                break;
+            default:
+                ERR("pipe listen error %x\n", status);
+                continue;
+            }
+
+            conn->listen_event = event;
+        }
+        (*count)++;
     }
     
     /* make array of connections */
@@ -796,11 +715,10 @@
     
     objs[0] = npps->mgr_event;
     *count = 1;
-    conn = CONTAINING_RECORD(protseq->conn, RpcConnection_np, common);
-    while (conn) {
-        if ((objs[*count] = conn->ovl.hEvent))
-            (*count)++;
-        conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_np, common);
+    LIST_FOR_EACH_ENTRY(conn, &protseq->listeners, RpcConnection_np, 
common.protseq_entry)
+    {
+        if (conn->listen_event)
+            objs[(*count)++] = conn->listen_event;
     }
     LeaveCriticalSection(&protseq->cs);
     return objs;
@@ -816,7 +734,7 @@
     HANDLE b_handle;
     HANDLE *objs = wait_array;
     DWORD res;
-    RpcConnection *cconn;
+    RpcConnection *cconn = NULL;
     RpcConnection_np *conn;
     
     if (!objs)
@@ -843,23 +761,27 @@
         b_handle = objs[res - WAIT_OBJECT_0];
         /* find which connection got a RPC */
         EnterCriticalSection(&protseq->cs);
-        conn = CONTAINING_RECORD(protseq->conn, RpcConnection_np, common);
-        while (conn) {
-            if (b_handle == conn->ovl.hEvent) break;
-            conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_np, 
common);
-        }
-        cconn = NULL;
-        if (conn)
-            RPCRT4_SpawnConnection(&cconn, &conn->common);
-        else
+        LIST_FOR_EACH_ENTRY(conn, &protseq->listeners, RpcConnection_np, 
common.protseq_entry)
+        {
+            if (b_handle == conn->listen_event)
+            {
+                release_np_event(conn, conn->listen_event);
+                conn->listen_event = NULL;
+                if (conn->io_status.u.Status == STATUS_SUCCESS || 
conn->io_status.u.Status == STATUS_PIPE_CONNECTED)
+                    cconn = rpcrt4_spawn_connection(&conn->common);
+                else
+                    ERR("listen failed %x\n", conn->io_status.u.Status);
+                break;
+            }
+        }
+        LeaveCriticalSection(&protseq->cs);
+        if (!cconn)
+        {
             ERR("failed to locate connection for handle %p\n", b_handle);
-        LeaveCriticalSection(&protseq->cs);
-        if (cconn)
-        {
-            RPCRT4_new_client(cconn);
-            return 1;
-        }
-        else return -1;
+            return -1;
+        }
+        RPCRT4_new_client(cconn);
+        return 1;
     }
 }
 
@@ -1111,7 +1033,7 @@
         in_addr.s_addr = ipv4_floor->ipv4addr;
         if (!inet_ntop(AF_INET, &in_addr, *networkaddr, INET_ADDRSTRLEN))
         {
-            ERR("inet_ntop: %s\n", strerror(errno));
+            ERR("inet_ntop: %u\n", WSAGetLastError());
             I_RpcFree(*networkaddr);
             *networkaddr = NULL;
             if (endpoint)
@@ -1130,74 +1052,9 @@
 {
   RpcConnection common;
   int sock;
-#ifdef HAVE_SOCKETPAIR
-  int cancel_fds[2];
-#else
   HANDLE sock_event;
   HANDLE cancel_event;
-#endif
 } RpcConnection_tcp;
-
-#ifdef HAVE_SOCKETPAIR
-
-static BOOL rpcrt4_sock_wait_init(RpcConnection_tcp *tcpc)
-{
-  if (socketpair(PF_UNIX, SOCK_STREAM, 0, tcpc->cancel_fds) < 0)
-  {
-    ERR("socketpair() failed: %s\n", strerror(errno));
-    return FALSE;
-  }
-  return TRUE;
-}
-
-static BOOL rpcrt4_sock_wait_for_recv(RpcConnection_tcp *tcpc)
-{
-  struct pollfd pfds[2];
-  pfds[0].fd = tcpc->sock;
-  pfds[0].events = POLLIN;
-  pfds[1].fd = tcpc->cancel_fds[0];
-  pfds[1].events = POLLIN;
-  if (poll(pfds, 2, -1 /* infinite */) == -1 && errno != EINTR)
-  {
-    ERR("poll() failed: %s\n", strerror(errno));
-    return FALSE;
-  }
-  if (pfds[1].revents & POLLIN) /* canceled */
-  {
-    char dummy;
-    read(pfds[1].fd, &dummy, sizeof(dummy));
-    return FALSE;
-  }
-  return TRUE;
-}
-
-static BOOL rpcrt4_sock_wait_for_send(RpcConnection_tcp *tcpc)
-{
-  struct pollfd pfd;
-  pfd.fd = tcpc->sock;
-  pfd.events = POLLOUT;
-  if (poll(&pfd, 1, -1 /* infinite */) == -1 && errno != EINTR)
-  {
-    ERR("poll() failed: %s\n", strerror(errno));
-    return FALSE;
-  }
-  return TRUE;
-}
-
-static void rpcrt4_sock_wait_cancel(RpcConnection_tcp *tcpc)
-{
-  char dummy = 1;
-
-  write(tcpc->cancel_fds[1], &dummy, 1);
-}
-
-static void rpcrt4_sock_wait_destroy(RpcConnection_tcp *tcpc)
-{
-  close(tcpc->cancel_fds[0]);
-  close(tcpc->cancel_fds[1]);
-}
-
-#else /* HAVE_SOCKETPAIR */
 
 static BOOL rpcrt4_sock_wait_init(RpcConnection_tcp *tcpc)
 {
@@ -1264,23 +1121,10 @@
   }
 }
 
-static void rpcrt4_sock_wait_cancel(RpcConnection_tcp *tcpc)
-{
-  SetEvent(tcpc->cancel_event);
-}
-
-static void rpcrt4_sock_wait_destroy(RpcConnection_tcp *tcpc)
-{
-  CloseHandle(tcpc->sock_event);
-  CloseHandle(tcpc->cancel_event);
-}
-
-#endif
-
 static RpcConnection *rpcrt4_conn_tcp_alloc(void)
 {
   RpcConnection_tcp *tcpc;
-  tcpc = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcConnection_tcp));
+  tcpc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
sizeof(RpcConnection_tcp));
   if (tcpc == NULL)
     return NULL;
   tcpc->sock = -1;
@@ -1347,20 +1191,20 @@
     sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol);
     if (sock == -1)
     {
-      WARN("socket() failed: %s\n", strerror(errno));
+      WARN("socket() failed: %u\n", WSAGetLastError());
       continue;
     }
 
     if (0>connect(sock, ai_cur->ai_addr, ai_cur->ai_addrlen))
     {
-      WARN("connect() failed: %s\n", strerror(errno));
+      WARN("connect() failed: %u\n", WSAGetLastError());
       closesocket(sock);
       continue;
     }
 
     /* RPC depends on having minimal latency so disable the Nagle algorithm */
     val = 1;
-    setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
+    setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
     nonblocking = 1;
     ioctlsocket(sock, FIONBIO, &nonblocking);
 
@@ -1384,7 +1228,6 @@
     struct addrinfo *ai;
     struct addrinfo *ai_cur;
     struct addrinfo hints;
-    RpcConnection *first_connection = NULL;
 
     TRACE("(%p, %s)\n", protseq, endpoint);
 
@@ -1434,7 +1277,7 @@
         sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, 
ai_cur->ai_protocol);
         if (sock == -1)
         {
-            WARN("socket() failed: %s\n", strerror(errno));
+            WARN("socket() failed: %u\n", WSAGetLastError());
             status = RPC_S_CANT_CREATE_ENDPOINT;
             continue;
         }
@@ -1442,9 +1285,9 @@
         ret = bind(sock, ai_cur->ai_addr, ai_cur->ai_addrlen);
         if (ret < 0)
         {
-            WARN("bind failed: %s\n", strerror(errno));
+            WARN("bind failed: %u\n", WSAGetLastError());
             closesocket(sock);
-            if (errno == EADDRINUSE)
+            if (WSAGetLastError() == WSAEADDRINUSE)
               status = RPC_S_DUPLICATE_ENDPOINT;
             else
               status = RPC_S_CANT_CREATE_ENDPOINT;
@@ -1454,7 +1297,7 @@
         sa_len = sizeof(sa);
         if (getsockname(sock, (struct sockaddr *)&sa, &sa_len))
         {
-            WARN("getsockname() failed: %s\n", strerror(errno));
+            WARN("getsockname() failed: %u\n", WSAGetLastError());
             closesocket(sock);
             status = RPC_S_CANT_CREATE_ENDPOINT;
             continue;
@@ -1485,7 +1328,7 @@
         ret = listen(sock, protseq->MaxCalls);
         if (ret < 0)
         {
-            WARN("listen failed: %s\n", strerror(errno));
+            WARN("listen failed: %u\n", WSAGetLastError());
             RPCRT4_ReleaseConnection(&tcpc->common);
             status = RPC_S_OUT_OF_RESOURCES;
             continue;
@@ -1504,35 +1347,20 @@
             continue;
         }
 
-        tcpc->common.Next = first_connection;
-        first_connection = &tcpc->common;
+        EnterCriticalSection(&protseq->cs);
+        list_add_tail(&protseq->listeners, &tcpc->common.protseq_entry);
+        tcpc->common.protseq = protseq;
+        LeaveCriticalSection(&protseq->cs);
+
+        freeaddrinfo(ai);
 
         /* since IPv4 and IPv6 share the same port space, we only need one
          * successful bind to listen for both */
-        break;
-    }
-
-    freeaddrinfo(ai);
-
-    /* if at least one connection was created for an endpoint then
-     * return success */
-    if (first_connection)
-    {
-        RpcConnection *conn;
-
-        /* find last element in list */
-        for (conn = first_connection; conn->Next; conn = conn->Next)
-            ;
-
-        EnterCriticalSection(&protseq->cs);
-        conn->Next = protseq->conn;
-        protseq->conn = first_connection;
-        LeaveCriticalSection(&protseq->cs);
-        
         TRACE("listening on %s\n", endpoint);
         return RPC_S_OK;
     }
 
+    freeaddrinfo(ai);
     ERR("couldn't listen on port %s\n", endpoint);
     return status;
 }
@@ -1582,11 +1410,11 @@
       return -1;
     else if (r > 0)
       bytes_read += r;
-    else if (errno == EINTR)
+    else if (WSAGetLastError() == WSAEINTR)
       continue;
-    else if (errno != EAGAIN)
-    {
-      WARN("recv() failed: %s\n", strerror(errno));
+    else if (WSAGetLastError() != WSAEWOULDBLOCK)
+    {
+      WARN("recv() failed: %u\n", WSAGetLastError());
       return -1;
     }
     else
@@ -1609,9 +1437,9 @@
     int r = send(tcpc->sock, (const char *)buffer + bytes_written, count - 
bytes_written, 0);
     if (r >= 0)
       bytes_written += r;
-    else if (errno == EINTR)
+    else if (WSAGetLastError() == WSAEINTR)
       continue;
-    else if (errno != EAGAIN)
+    else if (WSAGetLastError() != WSAEWOULDBLOCK)
       return -1;
     else
     {
@@ -1623,24 +1451,33 @@
   return bytes_written;
 }
 
-static int rpcrt4_conn_tcp_close(RpcConnection *Connection)
-{
-  RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection;
-
-  TRACE("%d\n", tcpc->sock);
-
-  if (tcpc->sock != -1)
-    closesocket(tcpc->sock);
-  tcpc->sock = -1;
-  rpcrt4_sock_wait_destroy(tcpc);
-  return 0;
-}
-
-static void rpcrt4_conn_tcp_cancel_call(RpcConnection *Connection)
-{
-    RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection;
-    TRACE("%p\n", Connection);
-    rpcrt4_sock_wait_cancel(tcpc);
+static int rpcrt4_conn_tcp_close(RpcConnection *conn)
+{
+    RpcConnection_tcp *connection = (RpcConnection_tcp *) conn;
+
+    TRACE("%d\n", connection->sock);
+
+    if (connection->sock != -1)
+        closesocket(connection->sock);
+    connection->sock = -1;
+    CloseHandle(connection->sock_event);
+    CloseHandle(connection->cancel_event);
+    return 0;
+}
+
+static void rpcrt4_conn_tcp_close_read(RpcConnection *conn)
+{
+    RpcConnection_tcp *connection = (RpcConnection_tcp *) conn;
+    shutdown(connection->sock, SD_RECEIVE);
+}
+
+static void rpcrt4_conn_tcp_cancel_call(RpcConnection *conn)
+{
+    RpcConnection_tcp *connection = (RpcConnection_tcp *) conn;
+
+    TRACE("%p\n", connection);
+
+    SetEvent(connection->cancel_event);
 }
 
 static RPC_STATUS rpcrt4_conn_tcp_is_server_listening(const char *endpoint)
@@ -1668,149 +1505,6 @@
                                           EPM_PROTOCOL_TCP, endpoint);
 }
 
-#ifdef HAVE_SOCKETPAIR
-
-typedef struct _RpcServerProtseq_sock
-{
-    RpcServerProtseq common;
-    int mgr_event_rcv;
-    int mgr_event_snd;
-} RpcServerProtseq_sock;
-
-static RpcServerProtseq *rpcrt4_protseq_sock_alloc(void)
-{
-    RpcServerProtseq_sock *ps = HeapAlloc(GetProcessHeap(), 0, sizeof(*ps));
-    if (ps)
-    {
-        int fds[2];
-        if (!socketpair(PF_UNIX, SOCK_DGRAM, 0, fds))
-        {
-            fcntl(fds[0], F_SETFL, O_NONBLOCK);
-            fcntl(fds[1], F_SETFL, O_NONBLOCK);
-            ps->mgr_event_rcv = fds[0];
-            ps->mgr_event_snd = fds[1];
-        }
-        else
-        {
-            ERR("socketpair failed with error %s\n", strerror(errno));
-            HeapFree(GetProcessHeap(), 0, ps);
-            return NULL;
-        }
-    }
-    return &ps->common;
-}
-
-static void rpcrt4_protseq_sock_signal_state_changed(RpcServerProtseq *protseq)
-{
-    RpcServerProtseq_sock *sockps = CONTAINING_RECORD(protseq, 
RpcServerProtseq_sock, common);
-    char dummy = 1;
-    write(sockps->mgr_event_snd, &dummy, sizeof(dummy));
-}
-
-static void *rpcrt4_protseq_sock_get_wait_array(RpcServerProtseq *protseq, 
void *prev_array, unsigned int *count)
-{
-    struct pollfd *poll_info = prev_array;
-    RpcConnection_tcp *conn;
-    RpcServerProtseq_sock *sockps = CONTAINING_RECORD(protseq, 
RpcServerProtseq_sock, common);
-
-    EnterCriticalSection(&protseq->cs);
-    
-    /* open and count connections */
-    *count = 1;
-    conn = (RpcConnection_tcp *)protseq->conn;
-    while (conn) {
-        if (conn->sock != -1)
-            (*count)++;
-        conn = (RpcConnection_tcp *)conn->common.Next;
-    }
-    
-    /* make array of connections */
-    if (poll_info)
-        poll_info = HeapReAlloc(GetProcessHeap(), 0, poll_info, 
*count*sizeof(*poll_info));
-    else
-        poll_info = HeapAlloc(GetProcessHeap(), 0, *count*sizeof(*poll_info));
-    if (!poll_info)
-    {
-        ERR("couldn't allocate poll_info\n");
-        LeaveCriticalSection(&protseq->cs);
-        return NULL;
-    }
-
-    poll_info[0].fd = sockps->mgr_event_rcv;
-    poll_info[0].events = POLLIN;
-    *count = 1;
-    conn =  CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common);
-    while (conn) {
-        if (conn->sock != -1)
-        {
-            poll_info[*count].fd = conn->sock;
-            poll_info[*count].events = POLLIN;
-            (*count)++;
-        }
-        conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common);
-    }
-    LeaveCriticalSection(&protseq->cs);
-    return poll_info;
-}
-
-static void rpcrt4_protseq_sock_free_wait_array(RpcServerProtseq *protseq, 
void *array)
-{
-    HeapFree(GetProcessHeap(), 0, array);
-}
-
-static int rpcrt4_protseq_sock_wait_for_new_connection(RpcServerProtseq 
*protseq, unsigned int count, void *wait_array)
-{
-    struct pollfd *poll_info = wait_array;
-    int ret;
-    unsigned int i;
-    RpcConnection *cconn;
-    RpcConnection_tcp *conn;
-    
-    if (!poll_info)
-        return -1;
-    
-    ret = poll(poll_info, count, -1);
-    if (ret < 0)
-    {
-        ERR("poll failed with error %d\n", ret);
-        return -1;
-    }
-
-    for (i = 0; i < count; i++)
-        if (poll_info[i].revents & POLLIN)
-        {
-            /* RPC server event */
-            if (i == 0)
-            {
-                char dummy;
-                read(poll_info[0].fd, &dummy, sizeof(dummy));
-                return 0;
-            }
-
-            /* find which connection got a RPC */
-            EnterCriticalSection(&protseq->cs);
-            conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common);
-            while (conn) {
-                if (poll_info[i].fd == conn->sock) break;
-                conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, 
common);
-            }
-            cconn = NULL;
-            if (conn)
-                RPCRT4_SpawnConnection(&cconn, &conn->common);
-            else
-                ERR("failed to locate connection for fd %d\n", 
poll_info[i].fd);
-            LeaveCriticalSection(&protseq->cs);
-            if (cconn)
-                RPCRT4_new_client(cconn);
-            else
-                return -1;
-        }
-
-    return 1;
-}
-
-#else /* HAVE_SOCKETPAIR */
-
 typedef struct _RpcServerProtseq_sock
 {
     RpcServerProtseq common;
@@ -1819,7 +1513,7 @@
 
 static RpcServerProtseq *rpcrt4_protseq_sock_alloc(void)
 {
-    RpcServerProtseq_sock *ps = HeapAlloc(GetProcessHeap(), 0, sizeof(*ps));
+    RpcServerProtseq_sock *ps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
sizeof(*ps));
     if (ps)
     {
         static BOOL wsa_inited;
@@ -1852,12 +1546,10 @@
 
     /* open and count connections */
     *count = 1;
-    conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common);
-    while (conn)
+    LIST_FOR_EACH_ENTRY(conn, &protseq->listeners, RpcConnection_tcp, 
common.protseq_entry)
     {
         if (conn->sock != -1)
             (*count)++;
-        conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common);
     }
 
     /* make array of connections */
@@ -1874,8 +1566,7 @@
 
     objs[0] = sockps->mgr_event;
     *count = 1;
-    conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common);
-    while (conn)
+    LIST_FOR_EACH_ENTRY(conn, &protseq->listeners, RpcConnection_tcp, 
common.protseq_entry)
     {
         if (conn->sock != -1)
         {
@@ -1888,7 +1579,6 @@
                 (*count)++;
             }
         }
-        conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common);
     }
     LeaveCriticalSection(&protseq->cs);
     return objs;
@@ -1904,7 +1594,7 @@
     HANDLE b_handle;
     HANDLE *objs = wait_array;
     DWORD res;
-    RpcConnection *cconn;
+    RpcConnection *cconn = NULL;
     RpcConnection_tcp *conn;
 
     if (!objs)
@@ -1921,38 +1611,34 @@
 
     if (res == WAIT_OBJECT_0)
         return 0;
-    else if (res == WAIT_FAILED)
+    if (res == WAIT_FAILED)
     {
         ERR("wait failed with error %d\n", GetLastError());
         return -1;
     }
-    else
-    {
-        b_handle = objs[res - WAIT_OBJECT_0];
-        /* find which connection got a RPC */
-        EnterCriticalSection(&protseq->cs);
-        conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common);
-        while (conn)
-        {
-            if (b_handle == conn->sock_event) break;
-            conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, 
common);
-        }
-        cconn = NULL;
-        if (conn)
-            RPCRT4_SpawnConnection(&cconn, &conn->common);
-        else
-            ERR("failed to locate connection for handle %p\n", b_handle);
-        LeaveCriticalSection(&protseq->cs);
-        if (cconn)
-        {
-            RPCRT4_new_client(cconn);
-            return 1;
-        }
-        else return -1;
-    }
-}
-
-#endif  /* HAVE_SOCKETPAIR */
+
+    b_handle = objs[res - WAIT_OBJECT_0];
+
+    /* find which connection got a RPC */
+    EnterCriticalSection(&protseq->cs);
+    LIST_FOR_EACH_ENTRY(conn, &protseq->listeners, RpcConnection_tcp, 
common.protseq_entry)
+    {
+        if (b_handle == conn->sock_event)
+        {
+            cconn = rpcrt4_spawn_connection(&conn->common);
+            break;
+        }
+    }
+    LeaveCriticalSection(&protseq->cs);
+    if (!cconn)
+    {
+        ERR("failed to locate connection for handle %p\n", b_handle);
+        return -1;
+    }
+
+    RPCRT4_new_client(cconn);
+    return 1;
+}
 
 static RPC_STATUS rpcrt4_ncacn_ip_tcp_parse_top_of_tower(const unsigned char 
*tower_data,
                                                          size_t tower_size,
@@ -2085,7 +1771,6 @@
     httpc->cancel_event = CreateEventW(NULL, FALSE, FALSE, NULL);
     httpc->async_data->refs = 1;
     httpc->async_data->inet_buffers.dwStructSize = sizeof(INTERNET_BUFFERSW);
-    httpc->async_data->inet_buffers.lpvBuffer = NULL;
     InitializeCriticalSection(&httpc->async_data->cs);
     httpc->async_data->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": 
RpcHttpAsyncData.cs");
     return &httpc->common;
@@ -3411,6 +3096,11 @@
   return 0;
 }
 
+static void rpcrt4_ncacn_http_close_read(RpcConnection *conn)
+{
+    rpcrt4_ncacn_http_close(conn); /* FIXME */
+}
+
 static void rpcrt4_ncacn_http_cancel_call(RpcConnection *Connection)
 {
   RpcConnection_http *httpc = (RpcConnection_http *) Connection;
@@ -3464,6 +3154,7 @@
     rpcrt4_conn_np_read,
     rpcrt4_conn_np_write,
     rpcrt4_conn_np_close,
+    rpcrt4_conn_np_close_read,
     rpcrt4_conn_np_cancel_call,
     rpcrt4_ncacn_np_is_server_listening,
     rpcrt4_conn_np_wait_for_incoming_data,
@@ -3485,6 +3176,7 @@
     rpcrt4_conn_np_read,
     rpcrt4_conn_np_write,
     rpcrt4_conn_np_close,
+    rpcrt4_conn_np_close_read,
     rpcrt4_conn_np_cancel_call,
     rpcrt4_ncalrpc_np_is_server_listening,
     rpcrt4_conn_np_wait_for_incoming_data,
@@ -3506,6 +3198,7 @@
     rpcrt4_conn_tcp_read,
     rpcrt4_conn_tcp_write,
     rpcrt4_conn_tcp_close,
+    rpcrt4_conn_tcp_close_read,
     rpcrt4_conn_tcp_cancel_call,
     rpcrt4_conn_tcp_is_server_listening,
     rpcrt4_conn_tcp_wait_for_incoming_data,
@@ -3527,6 +3220,7 @@
     rpcrt4_ncacn_http_read,
     rpcrt4_ncacn_http_write,
     rpcrt4_ncacn_http_close,
+    rpcrt4_ncacn_http_close_read,
     rpcrt4_ncacn_http_cancel_call,
     rpcrt4_ncacn_http_is_server_listening,
     rpcrt4_ncacn_http_wait_for_incoming_data,
@@ -3631,8 +3325,6 @@
 
   NewConnection = ops->alloc();
   NewConnection->ref = 1;
-  NewConnection->Next = NULL;
-  NewConnection->server_binding = NULL;
   NewConnection->server = server;
   NewConnection->ops = ops;
   NewConnection->NetworkAddr = RPCRT4_strdupA(NetworkAddr);
@@ -3640,22 +3332,17 @@
   NewConnection->NetworkOptions = RPCRT4_strdupW(NetworkOptions);
   NewConnection->CookieAuth = RPCRT4_strdupW(CookieAuth);
   NewConnection->MaxTransmissionSize = RPC_MAX_PACKET_SIZE;
-  memset(&NewConnection->ActiveInterface, 0, 
sizeof(NewConnection->ActiveInterface));
   NewConnection->NextCallId = 1;
 
   SecInvalidateHandle(&NewConnection->ctx);
-  memset(&NewConnection->exp, 0, sizeof(NewConnection->exp));
-  NewConnection->attr = 0;
   if (AuthInfo) RpcAuthInfo_AddRef(AuthInfo);
   NewConnection->AuthInfo = AuthInfo;
   NewConnection->auth_context_id = InterlockedIncrement( &next_id );
-  NewConnection->encryption_auth_len = 0;
-  NewConnection->signature_auth_len = 0;
   if (QOS) RpcQualityOfService_AddRef(QOS);
   NewConnection->QOS = QOS;
 
   list_init(&NewConnection->conn_pool_entry);
-  NewConnection->async_state = NULL;
+  list_init(&NewConnection->protseq_entry);
 
   TRACE("connection: %p\n", NewConnection);
   *Connection = NewConnection;
@@ -3663,16 +3350,26 @@
   return RPC_S_OK;
 }
 
-static RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, 
RpcConnection* OldConnection)
-{
-  RPC_STATUS err;
-
-  err = RPCRT4_CreateConnection(Connection, OldConnection->server, 
rpcrt4_conn_get_name(OldConnection),
-                                OldConnection->NetworkAddr, 
OldConnection->Endpoint, NULL,
-                                OldConnection->AuthInfo, OldConnection->QOS, 
OldConnection->CookieAuth);
-  if (err == RPC_S_OK)
-    rpcrt4_conn_handoff(OldConnection, *Connection);
-  return err;
+static RpcConnection *rpcrt4_spawn_connection(RpcConnection *old_connection)
+{
+    RpcConnection *connection;
+    RPC_STATUS err;
+
+    err = RPCRT4_CreateConnection(&connection, old_connection->server, 
rpcrt4_conn_get_name(old_connection),
+                                  old_connection->NetworkAddr, 
old_connection->Endpoint, NULL,
+                                  old_connection->AuthInfo, 
old_connection->QOS, old_connection->CookieAuth);
+    if (err != RPC_S_OK)
+        return NULL;
+
+    rpcrt4_conn_handoff(old_connection, connection);
+    if (old_connection->protseq)
+    {
+        EnterCriticalSection(&old_connection->protseq->cs);
+        connection->protseq = old_connection->protseq;
+        list_add_tail(&old_connection->protseq->connections, 
&connection->protseq_entry);
+        LeaveCriticalSection(&old_connection->protseq->cs);
+    }
+    return connection;
 }
 
 RpcConnection *RPCRT4_GrabConnection( RpcConnection *conn )
@@ -3697,6 +3394,13 @@
 
   /* server-only */
   if (Connection->server_binding) 
RPCRT4_ReleaseBinding(Connection->server_binding);
+
+  if (Connection->protseq)
+  {
+    EnterCriticalSection(&Connection->protseq->cs);
+    list_remove(&Connection->protseq_entry);
+    LeaveCriticalSection(&Connection->protseq->cs);
+  }
 
   HeapFree(GetProcessHeap(), 0, Connection);
   return RPC_S_OK;

Modified: trunk/reactos/media/doc/README.WINE
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=74904&r1=74903&r2=74904&view=diff
==============================================================================
--- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original)
+++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Sun Jun  4 14:01:54 2017
@@ -160,7 +160,7 @@
 reactos/dll/win32/resutils            # Synced to WineStaging-1.9.11
 reactos/dll/win32/riched20            # Synced to WineStaging-2.9
 reactos/dll/win32/riched32            # Synced to WineStaging-1.9.11
-reactos/dll/win32/rpcrt4              # Synced to WineStaging-2.2
+reactos/dll/win32/rpcrt4              # Synced to WineStaging-2.9
 reactos/dll/win32/rsabase             # Synced to WineStaging-1.9.11
 reactos/dll/win32/rsaenh              # Synced to WineStaging-2.9
 reactos/dll/win32/sccbase             # Synced to WineStaging-1.9.11


Reply via email to