Commit fe99f330 authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

rpcrt4: Abstract the transport layer functionality.

parent 924d91ca
......@@ -99,13 +99,20 @@ void RPCRT4_strfree(LPSTR src)
HeapFree(GetProcessHeap(), 0, src);
}
RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPSTR Protseq, LPSTR NetworkAddr, LPSTR Endpoint, LPSTR NetworkOptions, RpcBinding* Binding)
static struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq);
RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCSTR NetworkOptions, RpcBinding* Binding)
{
struct protseq_ops *ops;
RpcConnection* NewConnection;
ops = rpcrt4_get_protseq_ops(Protseq);
if (!ops)
return RPC_S_PROTSEQ_NOT_SUPPORTED;
NewConnection = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcConnection));
NewConnection->server = server;
NewConnection->Protseq = RPCRT4_strdupA(Protseq);
NewConnection->ops = ops;
NewConnection->NetworkAddr = RPCRT4_strdupA(NetworkAddr);
NewConnection->Endpoint = RPCRT4_strdupA(Endpoint);
NewConnection->Used = Binding;
......@@ -124,7 +131,6 @@ RPC_STATUS RPCRT4_DestroyConnection(RpcConnection* Connection)
RPCRT4_CloseConnection(Connection);
RPCRT4_strfree(Connection->Endpoint);
RPCRT4_strfree(Connection->NetworkAddr);
RPCRT4_strfree(Connection->Protseq);
HeapFree(GetProcessHeap(), 0, Connection);
return RPC_S_OK;
}
......@@ -228,27 +234,32 @@ static RPC_STATUS rpcrt4_ncacn_np_open(RpcConnection* Connection)
return r;
}
RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection)
static HANDLE rpcrt4_conn_np_get_connect_event(RpcConnection *conn)
{
TRACE("(Connection == ^%p)\n", Connection);
/* already connected? */
if (Connection->conn)
return RPC_S_OK;
if (strcmp(Connection->Protseq, "ncalrpc") == 0)
return rpcrt4_ncalrpc_open(Connection);
return conn->ovl.hEvent;
}
if (strcmp(Connection->Protseq, "ncacn_np") == 0)
return rpcrt4_ncacn_np_open(Connection);
static int rpcrt4_conn_np_read(RpcConnection *Connection,
void *buffer, unsigned int count)
{
DWORD dwRead = 0;
if (!ReadFile(Connection->conn, buffer, count, &dwRead, NULL) &&
(GetLastError() != ERROR_MORE_DATA))
return -1;
return dwRead;
}
ERR("protseq %s not supported\n", Connection->Protseq);
return RPC_S_PROTSEQ_NOT_SUPPORTED;
static int rpcrt4_conn_np_write(RpcConnection *Connection,
const void *buffer, unsigned int count)
{
DWORD dwWritten = 0;
if (!WriteFile(Connection->conn, buffer, count, &dwWritten, NULL))
return -1;
return dwWritten;
}
RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection)
static int rpcrt4_conn_np_close(RpcConnection *Connection)
{
TRACE("(Connection == ^%p)\n", Connection);
if (Connection->conn) {
FlushFileBuffers(Connection->conn);
CloseHandle(Connection->conn);
......@@ -258,14 +269,64 @@ RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection)
CloseHandle(Connection->ovl.hEvent);
Connection->ovl.hEvent = 0;
}
return 0;
}
struct protseq_ops protseq_list[] = {
{ "ncacn_np",
rpcrt4_ncalrpc_open,
rpcrt4_conn_np_get_connect_event,
rpcrt4_conn_np_read,
rpcrt4_conn_np_write,
rpcrt4_conn_np_close,
},
{ "ncalrpc",
rpcrt4_ncacn_np_open,
rpcrt4_conn_np_get_connect_event,
rpcrt4_conn_np_read,
rpcrt4_conn_np_write,
rpcrt4_conn_np_close,
},
};
#define MAX_PROTSEQ (sizeof protseq_list / sizeof protseq_list[0])
static struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq)
{
int i;
for(i=0; i<MAX_PROTSEQ; i++)
if (!strcmp(protseq_list[i].name, protseq))
return &protseq_list[i];
return NULL;
}
RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection)
{
TRACE("(Connection == ^%p)\n", Connection);
/* already connected? */
if (Connection->conn)
return RPC_S_OK;
return Connection->ops->open_connection(Connection);
}
RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection)
{
TRACE("(Connection == ^%p)\n", Connection);
rpcrt4_conn_close(Connection);
return RPC_S_OK;
}
RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, RpcConnection* OldConnection)
{
RpcConnection* NewConnection;
RPC_STATUS err = RPCRT4_CreateConnection(&NewConnection, OldConnection->server, OldConnection->Protseq,
OldConnection->NetworkAddr, OldConnection->Endpoint, NULL, NULL);
RPC_STATUS err;
err = RPCRT4_CreateConnection(&NewConnection, OldConnection->server,
rpcrt4_conn_get_name(OldConnection),
OldConnection->NetworkAddr,
OldConnection->Endpoint, NULL, NULL);
if (err == RPC_S_OK) {
/* because of the way named pipes work, we'll transfer the connected pipe
* to the child, then reopen the server binding to continue listening */
......@@ -378,7 +439,7 @@ RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection)
TRACE("(RpcBinding == ^%p, Connection == ^%p)\n", Binding, Connection);
RPCRT4_AllocBinding(&NewBinding, Connection->server);
NewBinding->Protseq = RPCRT4_strdupA(Connection->Protseq);
NewBinding->Protseq = RPCRT4_strdupA(rpcrt4_conn_get_name(Connection));
NewBinding->NetworkAddr = RPCRT4_strdupA(Connection->NetworkAddr);
NewBinding->Endpoint = RPCRT4_strdupA(Connection->Endpoint);
NewBinding->FromConn = Connection;
......
......@@ -23,14 +23,16 @@
#include "wine/rpcss_shared.h"
struct protseq_ops;
typedef struct _RpcConnection
{
struct _RpcConnection* Next;
struct _RpcBinding* Used;
BOOL server;
LPSTR Protseq;
LPSTR NetworkAddr;
LPSTR Endpoint;
struct protseq_ops *ops;
HANDLE conn, thread;
OVERLAPPED ovl;
USHORT MaxTransmissionSize;
......@@ -38,6 +40,15 @@ typedef struct _RpcConnection
RPC_SYNTAX_IDENTIFIER ActiveInterface;
} RpcConnection;
struct protseq_ops {
char *name;
RPC_STATUS (*open_connection)(RpcConnection *conn);
HANDLE (*get_connect_wait_handle)(RpcConnection *conn);
int (*read)(RpcConnection *conn, void *buffer, unsigned int len);
int (*write)(RpcConnection *conn, const void *buffer, unsigned int len);
int (*close)(RpcConnection *conn);
};
/* don't know what MS's structure looks like */
typedef struct _RpcBinding
{
......@@ -62,7 +73,7 @@ void RPCRT4_strfree(LPSTR src);
#define RPCRT4_strdupA(x) RPCRT4_strndupA((x),-1)
#define RPCRT4_strdupW(x) RPCRT4_strndupW((x),-1)
RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPSTR Protseq, LPSTR NetworkAddr, LPSTR Endpoint, LPSTR NetworkOptions, RpcBinding* Binding);
RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCSTR NetworkOptions, RpcBinding* Binding);
RPC_STATUS RPCRT4_DestroyConnection(RpcConnection* Connection);
RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection);
RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection);
......@@ -83,7 +94,31 @@ BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPC
HANDLE RPCRT4_GetMasterMutex(void);
HANDLE RPCRT4_RpcssNPConnect(void);
int rpcrt4_conn_read(RpcConnection *Connection,
void *buffer, unsigned int count);
static inline const char *rpcrt4_conn_get_name(RpcConnection *Connection)
{
return Connection->ops->name;
}
static inline int rpcrt4_conn_read(RpcConnection *Connection,
void *buffer, unsigned int len)
{
return Connection->ops->read(Connection, buffer, len);
}
static inline int rpcrt4_conn_write(RpcConnection *Connection,
const void *buffer, unsigned int len)
{
return Connection->ops->write(Connection, buffer, len);
}
static inline int rpcrt4_conn_close(RpcConnection *Connection)
{
return Connection->ops->close(Connection);
}
static inline HANDLE rpcrt4_conn_get_wait_object(RpcConnection *Connection)
{
return Connection->ops->get_connect_wait_handle(Connection);
}
#endif
......@@ -238,15 +238,6 @@ VOID RPCRT4_FreeHeader(RpcPktHdr *Header)
HeapFree(GetProcessHeap(), 0, Header);
}
static int rpcrt4_conn_write(RpcConnection *Connection,
const void *buffer, unsigned int count)
{
DWORD dwWritten = 0;
if (!WriteFile(Connection->conn, buffer, count, &dwWritten, NULL))
return -1;
return dwWritten;
}
/***********************************************************************
* RPCRT4_Send (internal)
*
......@@ -302,21 +293,6 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header,
}
/***********************************************************************
* rpcrt4_conn_read (internal)
*
* Reads data from a connection
*/
int rpcrt4_conn_read(RpcConnection *Connection,
void *buffer, unsigned int count)
{
DWORD dwRead = 0;
if (!ReadFile(Connection->conn, buffer, count, &dwRead, NULL) &&
(GetLastError() != ERROR_MORE_DATA))
return -1;
return dwRead;
}
/***********************************************************************
* RPCRT4_Receive (internal)
*
* Receive a packet from connection and merge the fragments.
......
......@@ -455,11 +455,6 @@ static void RPCRT4_new_client(RpcConnection* conn)
CloseHandle( thread );
}
static HANDLE rpcrt4_conn_get_wait_object(RpcConnection *conn)
{
return conn->ovl.hEvent;
}
static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
{
HANDLE m_event = mgr_event, b_handle;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment