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_bindi…
==============================================================================
--- 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_serve…
==============================================================================
--- 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_serve…
==============================================================================
--- 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_trans…
==============================================================================
--- 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=…
==============================================================================
--- 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