rpcrt4: Hide the details of the rpc transport mechanism.
This commit is contained in:
parent
83109e4937
commit
87ddd7b53a
|
@ -33,8 +33,6 @@ typedef struct _RpcConnection
|
||||||
LPSTR NetworkAddr;
|
LPSTR NetworkAddr;
|
||||||
LPSTR Endpoint;
|
LPSTR Endpoint;
|
||||||
struct protseq_ops *ops;
|
struct protseq_ops *ops;
|
||||||
HANDLE conn, thread;
|
|
||||||
OVERLAPPED ovl;
|
|
||||||
USHORT MaxTransmissionSize;
|
USHORT MaxTransmissionSize;
|
||||||
/* The active interface bound to server. */
|
/* The active interface bound to server. */
|
||||||
RPC_SYNTAX_IDENTIFIER ActiveInterface;
|
RPC_SYNTAX_IDENTIFIER ActiveInterface;
|
||||||
|
@ -42,6 +40,7 @@ typedef struct _RpcConnection
|
||||||
|
|
||||||
struct protseq_ops {
|
struct protseq_ops {
|
||||||
char *name;
|
char *name;
|
||||||
|
RpcConnection *(*alloc)(void);
|
||||||
RPC_STATUS (*open_connection)(RpcConnection *conn);
|
RPC_STATUS (*open_connection)(RpcConnection *conn);
|
||||||
HANDLE (*get_connect_wait_handle)(RpcConnection *conn);
|
HANDLE (*get_connect_wait_handle)(RpcConnection *conn);
|
||||||
RPC_STATUS (*handoff)(RpcConnection *old_conn, RpcConnection *new_conn);
|
RPC_STATUS (*handoff)(RpcConnection *old_conn, RpcConnection *new_conn);
|
||||||
|
|
|
@ -47,22 +47,35 @@ WINE_DEFAULT_DEBUG_CHANNEL(rpc);
|
||||||
|
|
||||||
static struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq);
|
static struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq);
|
||||||
|
|
||||||
|
typedef struct _RpcConnection_np
|
||||||
|
{
|
||||||
|
RpcConnection common;
|
||||||
|
HANDLE pipe, thread;
|
||||||
|
OVERLAPPED ovl;
|
||||||
|
} RpcConnection_np;
|
||||||
|
|
||||||
|
static RpcConnection *rpcrt4_conn_np_alloc(void)
|
||||||
|
{
|
||||||
|
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcConnection_np));
|
||||||
|
}
|
||||||
|
|
||||||
static RPC_STATUS rpcrt4_connect_pipe(RpcConnection *Connection, LPCSTR pname)
|
static RPC_STATUS rpcrt4_connect_pipe(RpcConnection *Connection, LPCSTR pname)
|
||||||
{
|
{
|
||||||
|
RpcConnection_np *npc = (RpcConnection_np *) Connection;
|
||||||
TRACE("listening on %s\n", pname);
|
TRACE("listening on %s\n", pname);
|
||||||
|
|
||||||
Connection->conn = CreateNamedPipeA(pname, PIPE_ACCESS_DUPLEX,
|
npc->pipe = CreateNamedPipeA(pname, PIPE_ACCESS_DUPLEX,
|
||||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
|
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
|
||||||
PIPE_UNLIMITED_INSTANCES,
|
PIPE_UNLIMITED_INSTANCES,
|
||||||
RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, 5000, NULL);
|
RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, 5000, NULL);
|
||||||
memset(&Connection->ovl, 0, sizeof(Connection->ovl));
|
memset(&npc->ovl, 0, sizeof(npc->ovl));
|
||||||
Connection->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
npc->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||||
if (ConnectNamedPipe(Connection->conn, &Connection->ovl))
|
if (ConnectNamedPipe(npc->pipe, &npc->ovl))
|
||||||
return RPC_S_OK;
|
return RPC_S_OK;
|
||||||
|
|
||||||
WARN("Couldn't ConnectNamedPipe (error was %ld)\n", GetLastError());
|
WARN("Couldn't ConnectNamedPipe (error was %ld)\n", GetLastError());
|
||||||
if (GetLastError() == ERROR_PIPE_CONNECTED) {
|
if (GetLastError() == ERROR_PIPE_CONNECTED) {
|
||||||
SetEvent(Connection->ovl.hEvent);
|
SetEvent(npc->ovl.hEvent);
|
||||||
return RPC_S_OK;
|
return RPC_S_OK;
|
||||||
}
|
}
|
||||||
if (GetLastError() == ERROR_IO_PENDING) {
|
if (GetLastError() == ERROR_IO_PENDING) {
|
||||||
|
@ -74,15 +87,16 @@ static RPC_STATUS rpcrt4_connect_pipe(RpcConnection *Connection, LPCSTR pname)
|
||||||
|
|
||||||
static RPC_STATUS rpcrt4_open_pipe(RpcConnection *Connection, LPCSTR pname, BOOL wait)
|
static RPC_STATUS rpcrt4_open_pipe(RpcConnection *Connection, LPCSTR pname, BOOL wait)
|
||||||
{
|
{
|
||||||
HANDLE conn;
|
RpcConnection_np *npc = (RpcConnection_np *) Connection;
|
||||||
|
HANDLE pipe;
|
||||||
DWORD err, dwMode;
|
DWORD err, dwMode;
|
||||||
|
|
||||||
TRACE("connecting to %s\n", pname);
|
TRACE("connecting to %s\n", pname);
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
conn = CreateFileA(pname, GENERIC_READ|GENERIC_WRITE, 0, NULL,
|
pipe = CreateFileA(pname, GENERIC_READ|GENERIC_WRITE, 0, NULL,
|
||||||
OPEN_EXISTING, 0, 0);
|
OPEN_EXISTING, 0, 0);
|
||||||
if (conn != INVALID_HANDLE_VALUE) break;
|
if (pipe != INVALID_HANDLE_VALUE) break;
|
||||||
err = GetLastError();
|
err = GetLastError();
|
||||||
if (err == ERROR_PIPE_BUSY) {
|
if (err == ERROR_PIPE_BUSY) {
|
||||||
TRACE("connection failed, error=%lx\n", err);
|
TRACE("connection failed, error=%lx\n", err);
|
||||||
|
@ -98,24 +112,25 @@ static RPC_STATUS rpcrt4_open_pipe(RpcConnection *Connection, LPCSTR pname, BOOL
|
||||||
}
|
}
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
memset(&Connection->ovl, 0, sizeof(Connection->ovl));
|
memset(&npc->ovl, 0, sizeof(npc->ovl));
|
||||||
/* pipe is connected; change to message-read mode. */
|
/* pipe is connected; change to message-read mode. */
|
||||||
dwMode = PIPE_READMODE_MESSAGE;
|
dwMode = PIPE_READMODE_MESSAGE;
|
||||||
SetNamedPipeHandleState(conn, &dwMode, NULL, NULL);
|
SetNamedPipeHandleState(pipe, &dwMode, NULL, NULL);
|
||||||
Connection->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
npc->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||||
Connection->conn = conn;
|
npc->pipe = pipe;
|
||||||
|
|
||||||
return RPC_S_OK;
|
return RPC_S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RPC_STATUS rpcrt4_ncalrpc_open(RpcConnection* Connection)
|
static RPC_STATUS rpcrt4_ncalrpc_open(RpcConnection* Connection)
|
||||||
{
|
{
|
||||||
|
RpcConnection_np *npc = (RpcConnection_np *) Connection;
|
||||||
static LPCSTR prefix = "\\\\.\\pipe\\lrpc\\";
|
static LPCSTR prefix = "\\\\.\\pipe\\lrpc\\";
|
||||||
RPC_STATUS r;
|
RPC_STATUS r;
|
||||||
LPSTR pname;
|
LPSTR pname;
|
||||||
|
|
||||||
/* already connected? */
|
/* already connected? */
|
||||||
if (Connection->conn)
|
if (npc->pipe)
|
||||||
return RPC_S_OK;
|
return RPC_S_OK;
|
||||||
|
|
||||||
/* protseq=ncalrpc: supposed to use NT LPC ports,
|
/* protseq=ncalrpc: supposed to use NT LPC ports,
|
||||||
|
@ -134,12 +149,13 @@ static RPC_STATUS rpcrt4_ncalrpc_open(RpcConnection* Connection)
|
||||||
|
|
||||||
static RPC_STATUS rpcrt4_ncacn_np_open(RpcConnection* Connection)
|
static RPC_STATUS rpcrt4_ncacn_np_open(RpcConnection* Connection)
|
||||||
{
|
{
|
||||||
|
RpcConnection_np *npc = (RpcConnection_np *) Connection;
|
||||||
static LPCSTR prefix = "\\\\.";
|
static LPCSTR prefix = "\\\\.";
|
||||||
RPC_STATUS r;
|
RPC_STATUS r;
|
||||||
LPSTR pname;
|
LPSTR pname;
|
||||||
|
|
||||||
/* already connected? */
|
/* already connected? */
|
||||||
if (Connection->conn)
|
if (npc->pipe)
|
||||||
return RPC_S_OK;
|
return RPC_S_OK;
|
||||||
|
|
||||||
/* protseq=ncacn_np: named pipes */
|
/* protseq=ncacn_np: named pipes */
|
||||||
|
@ -154,28 +170,32 @@ static RPC_STATUS rpcrt4_ncacn_np_open(RpcConnection* Connection)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HANDLE rpcrt4_conn_np_get_connect_event(RpcConnection *conn)
|
static HANDLE rpcrt4_conn_np_get_connect_event(RpcConnection *Connection)
|
||||||
{
|
{
|
||||||
return conn->ovl.hEvent;
|
RpcConnection_np *npc = (RpcConnection_np *) Connection;
|
||||||
|
return npc->ovl.hEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RPC_STATUS rpcrt4_conn_np_handoff(RpcConnection *old_conn, RpcConnection *new_conn)
|
static RPC_STATUS rpcrt4_conn_np_handoff(RpcConnection *old_conn, RpcConnection *new_conn)
|
||||||
{
|
{
|
||||||
|
RpcConnection_np *old_npc = (RpcConnection_np *) old_conn;
|
||||||
|
RpcConnection_np *new_npc = (RpcConnection_np *) new_conn;
|
||||||
/* because of the way named pipes work, we'll transfer the connected pipe
|
/* because of the way named pipes work, we'll transfer the connected pipe
|
||||||
* to the child, then reopen the server binding to continue listening */
|
* to the child, then reopen the server binding to continue listening */
|
||||||
|
|
||||||
new_conn->conn = old_conn->conn;
|
new_npc->pipe = old_npc->pipe;
|
||||||
new_conn->ovl = old_conn->ovl;
|
new_npc->ovl = old_npc->ovl;
|
||||||
old_conn->conn = 0;
|
old_npc->pipe = 0;
|
||||||
memset(&old_conn->ovl, 0, sizeof(old_conn->ovl));
|
memset(&old_npc->ovl, 0, sizeof(old_npc->ovl));
|
||||||
return RPCRT4_OpenConnection(old_conn);
|
return RPCRT4_OpenConnection(old_conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rpcrt4_conn_np_read(RpcConnection *Connection,
|
static int rpcrt4_conn_np_read(RpcConnection *Connection,
|
||||||
void *buffer, unsigned int count)
|
void *buffer, unsigned int count)
|
||||||
{
|
{
|
||||||
|
RpcConnection_np *npc = (RpcConnection_np *) Connection;
|
||||||
DWORD dwRead = 0;
|
DWORD dwRead = 0;
|
||||||
if (!ReadFile(Connection->conn, buffer, count, &dwRead, NULL) &&
|
if (!ReadFile(npc->pipe, buffer, count, &dwRead, NULL) &&
|
||||||
(GetLastError() != ERROR_MORE_DATA))
|
(GetLastError() != ERROR_MORE_DATA))
|
||||||
return -1;
|
return -1;
|
||||||
return dwRead;
|
return dwRead;
|
||||||
|
@ -184,28 +204,31 @@ static int rpcrt4_conn_np_read(RpcConnection *Connection,
|
||||||
static int rpcrt4_conn_np_write(RpcConnection *Connection,
|
static int rpcrt4_conn_np_write(RpcConnection *Connection,
|
||||||
const void *buffer, unsigned int count)
|
const void *buffer, unsigned int count)
|
||||||
{
|
{
|
||||||
|
RpcConnection_np *npc = (RpcConnection_np *) Connection;
|
||||||
DWORD dwWritten = 0;
|
DWORD dwWritten = 0;
|
||||||
if (!WriteFile(Connection->conn, buffer, count, &dwWritten, NULL))
|
if (!WriteFile(npc->pipe, buffer, count, &dwWritten, NULL))
|
||||||
return -1;
|
return -1;
|
||||||
return dwWritten;
|
return dwWritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rpcrt4_conn_np_close(RpcConnection *Connection)
|
static int rpcrt4_conn_np_close(RpcConnection *Connection)
|
||||||
{
|
{
|
||||||
if (Connection->conn) {
|
RpcConnection_np *npc = (RpcConnection_np *) Connection;
|
||||||
FlushFileBuffers(Connection->conn);
|
if (npc->pipe) {
|
||||||
CloseHandle(Connection->conn);
|
FlushFileBuffers(npc->pipe);
|
||||||
Connection->conn = 0;
|
CloseHandle(npc->pipe);
|
||||||
|
npc->pipe = 0;
|
||||||
}
|
}
|
||||||
if (Connection->ovl.hEvent) {
|
if (npc->ovl.hEvent) {
|
||||||
CloseHandle(Connection->ovl.hEvent);
|
CloseHandle(npc->ovl.hEvent);
|
||||||
Connection->ovl.hEvent = 0;
|
npc->ovl.hEvent = 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct protseq_ops protseq_list[] = {
|
struct protseq_ops protseq_list[] = {
|
||||||
{ "ncacn_np",
|
{ "ncacn_np",
|
||||||
|
rpcrt4_conn_np_alloc,
|
||||||
rpcrt4_ncalrpc_open,
|
rpcrt4_ncalrpc_open,
|
||||||
rpcrt4_conn_np_get_connect_event,
|
rpcrt4_conn_np_get_connect_event,
|
||||||
rpcrt4_conn_np_handoff,
|
rpcrt4_conn_np_handoff,
|
||||||
|
@ -214,6 +237,7 @@ struct protseq_ops protseq_list[] = {
|
||||||
rpcrt4_conn_np_close,
|
rpcrt4_conn_np_close,
|
||||||
},
|
},
|
||||||
{ "ncalrpc",
|
{ "ncalrpc",
|
||||||
|
rpcrt4_conn_np_alloc,
|
||||||
rpcrt4_ncacn_np_open,
|
rpcrt4_ncacn_np_open,
|
||||||
rpcrt4_conn_np_get_connect_event,
|
rpcrt4_conn_np_get_connect_event,
|
||||||
rpcrt4_conn_np_handoff,
|
rpcrt4_conn_np_handoff,
|
||||||
|
@ -257,7 +281,7 @@ RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPCS
|
||||||
if (!ops)
|
if (!ops)
|
||||||
return RPC_S_PROTSEQ_NOT_SUPPORTED;
|
return RPC_S_PROTSEQ_NOT_SUPPORTED;
|
||||||
|
|
||||||
NewConnection = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcConnection));
|
NewConnection = ops->alloc();
|
||||||
NewConnection->server = server;
|
NewConnection->server = server;
|
||||||
NewConnection->ops = ops;
|
NewConnection->ops = ops;
|
||||||
NewConnection->NetworkAddr = RPCRT4_strdupA(NetworkAddr);
|
NewConnection->NetworkAddr = RPCRT4_strdupA(NetworkAddr);
|
||||||
|
|
Loading…
Reference in New Issue