Rob Shearman : rpcrt4:
Make binding to an interface a function of RpcAssoc instead of
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Jul 13 08:30:10 CDT 2007
Module: wine
Branch: master
Commit: c6dc14d81b7cb7c1d81868382122eca56009c673
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c6dc14d81b7cb7c1d81868382122eca56009c673
Author: Rob Shearman <rob at codeweavers.com>
Date: Thu Jul 12 15:32:43 2007 +0100
rpcrt4: Make binding to an interface a function of RpcAssoc instead of
binding handles, since binding requires information from the
association and not from the binding handle.
---
dlls/rpcrt4/rpc_binding.c | 82 ++------------------------------------
dlls/rpcrt4/rpc_binding.h | 2 +-
dlls/rpcrt4/rpc_transport.c | 92 ++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 96 insertions(+), 80 deletions(-)
diff --git a/dlls/rpcrt4/rpc_binding.c b/dlls/rpcrt4/rpc_binding.c
index 79eceda..db30be6 100644
--- a/dlls/rpcrt4/rpc_binding.c
+++ b/dlls/rpcrt4/rpc_binding.c
@@ -277,93 +277,21 @@ RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection,
PRPC_SYNTAX_IDENTIFIER TransferSyntax,
PRPC_SYNTAX_IDENTIFIER InterfaceId)
{
- RpcConnection* NewConnection;
- RPC_STATUS status;
-
TRACE("(Binding == ^%p)\n", Binding);
if (!Binding->server) {
- /* try to find a compatible connection from the connection pool */
- NewConnection = RpcAssoc_GetIdleConnection(Binding->Assoc, InterfaceId,
- TransferSyntax, Binding->AuthInfo, Binding->QOS);
- if (NewConnection) {
- *Connection = NewConnection;
- return RPC_S_OK;
- }
+ return RpcAssoc_GetClientConnection(Binding->Assoc, InterfaceId,
+ TransferSyntax, Binding->AuthInfo, Binding->QOS, Connection);
} else {
/* we already have a connection with acceptable binding, so use it */
if (Binding->FromConn) {
*Connection = Binding->FromConn;
return RPC_S_OK;
+ } else {
+ ERR("no connection in binding\n");
+ return RPC_S_INTERNAL_ERROR;
}
}
-
- /* create a new connection */
- status = RPCRT4_CreateConnection(&NewConnection, Binding->server,
- Binding->Protseq, Binding->NetworkAddr,
- Binding->Endpoint, Binding->NetworkOptions,
- Binding->AuthInfo, Binding->QOS);
- if (status != RPC_S_OK)
- return status;
-
- status = RPCRT4_OpenClientConnection(NewConnection);
- if (status != RPC_S_OK)
- {
- RPCRT4_DestroyConnection(NewConnection);
- return status;
- }
-
- /* we need to send a binding packet if we are client. */
- if (!NewConnection->server) {
- RpcPktHdr *hdr;
- RpcPktHdr *response_hdr;
- RPC_MESSAGE msg;
-
- TRACE("sending bind request to server\n");
-
- hdr = RPCRT4_BuildBindHeader(NDR_LOCAL_DATA_REPRESENTATION,
- RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE,
- Binding->Assoc->assoc_group_id,
- InterfaceId, TransferSyntax);
-
- status = RPCRT4_Send(NewConnection, hdr, NULL, 0);
- RPCRT4_FreeHeader(hdr);
- if (status != RPC_S_OK) {
- RPCRT4_DestroyConnection(NewConnection);
- return status;
- }
-
- status = RPCRT4_Receive(NewConnection, &response_hdr, &msg);
- if (status != RPC_S_OK) {
- ERR("receive failed\n");
- RPCRT4_DestroyConnection(NewConnection);
- return status;
- }
-
- if (response_hdr->common.ptype != PKT_BIND_ACK ||
- response_hdr->bind_ack.max_tsize < RPC_MIN_PACKET_SIZE) {
- ERR("failed to bind for interface %s, %d.%d\n",
- debugstr_guid(&InterfaceId->SyntaxGUID),
- InterfaceId->SyntaxVersion.MajorVersion,
- InterfaceId->SyntaxVersion.MinorVersion);
- RPCRT4_FreeHeader(response_hdr);
- RPCRT4_DestroyConnection(NewConnection);
- return RPC_S_PROTOCOL_ERROR;
- }
-
- /* FIXME: do more checks? */
-
- NewConnection->MaxTransmissionSize = response_hdr->bind_ack.max_tsize;
- NewConnection->assoc_group_id = response_hdr->bind_ack.assoc_gid;
- NewConnection->ActiveInterface = *InterfaceId;
- RPCRT4_FreeHeader(response_hdr);
- }
-
- if (Binding->server)
- Binding->FromConn = NewConnection;
- *Connection = NewConnection;
-
- return RPC_S_OK;
}
RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection)
diff --git a/dlls/rpcrt4/rpc_binding.h b/dlls/rpcrt4/rpc_binding.h
index 58f2d06..5113b27 100644
--- a/dlls/rpcrt4/rpc_binding.h
+++ b/dlls/rpcrt4/rpc_binding.h
@@ -146,7 +146,7 @@ ULONG RpcQualityOfService_Release(RpcQualityOfService *qos);
BOOL RpcQualityOfService_IsEqual(const RpcQualityOfService *qos1, const RpcQualityOfService *qos2);
RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAssoc **assoc);
-RpcConnection *RpcAssoc_GetIdleConnection(RpcAssoc *assoc, const RPC_SYNTAX_IDENTIFIER *InterfaceId, const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RpcAuthInfo *AuthInfo, const RpcQualityOfService *QOS);
+RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, const RPC_SYNTAX_IDENTIFIER *InterfaceId, const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo, RpcQualityOfService *QOS, RpcConnection **Connection);
void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection);
ULONG RpcAssoc_Release(RpcAssoc *assoc);
diff --git a/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c
index 2bb891d..413bcbb 100644
--- a/dlls/rpcrt4/rpc_transport.c
+++ b/dlls/rpcrt4/rpc_transport.c
@@ -1473,15 +1473,63 @@ ULONG RpcAssoc_Release(RpcAssoc *assoc)
return refs;
}
-RpcConnection *RpcAssoc_GetIdleConnection(RpcAssoc *assoc,
+static RPC_STATUS RpcAssoc_BindConnection(RpcAssoc *assoc, RpcConnection *conn,
+ const RPC_SYNTAX_IDENTIFIER *InterfaceId,
+ const RPC_SYNTAX_IDENTIFIER *TransferSyntax)
+{
+ RpcPktHdr *hdr;
+ RpcPktHdr *response_hdr;
+ RPC_MESSAGE msg;
+ RPC_STATUS status;
+
+ TRACE("sending bind request to server\n");
+
+ hdr = RPCRT4_BuildBindHeader(NDR_LOCAL_DATA_REPRESENTATION,
+ RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE,
+ assoc->assoc_group_id,
+ InterfaceId, TransferSyntax);
+
+ status = RPCRT4_Send(conn, hdr, NULL, 0);
+ RPCRT4_FreeHeader(hdr);
+ if (status != RPC_S_OK)
+ return status;
+
+ status = RPCRT4_Receive(conn, &response_hdr, &msg);
+ if (status != RPC_S_OK)
+ {
+ ERR("receive failed\n");
+ return status;
+ }
+
+ if (response_hdr->common.ptype != PKT_BIND_ACK)
+ {
+ ERR("failed to bind for interface %s, %d.%d\n",
+ debugstr_guid(&InterfaceId->SyntaxGUID),
+ InterfaceId->SyntaxVersion.MajorVersion,
+ InterfaceId->SyntaxVersion.MinorVersion);
+ RPCRT4_FreeHeader(response_hdr);
+ return RPC_S_PROTOCOL_ERROR;
+ }
+
+ /* FIXME: do more checks? */
+
+ conn->assoc_group_id = response_hdr->bind_ack.assoc_gid;
+ conn->MaxTransmissionSize = response_hdr->bind_ack.max_tsize;
+ conn->ActiveInterface = *InterfaceId;
+ RPCRT4_FreeHeader(response_hdr);
+ return RPC_S_OK;
+}
+
+static RpcConnection *RpcAssoc_GetIdleConnection(RpcAssoc *assoc,
const RPC_SYNTAX_IDENTIFIER *InterfaceId,
const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RpcAuthInfo *AuthInfo,
const RpcQualityOfService *QOS)
{
RpcConnection *Connection;
- /* try to find a compatible connection from the connection pool */
EnterCriticalSection(&assoc->cs);
+ /* try to find a compatible connection from the connection pool */
LIST_FOR_EACH_ENTRY(Connection, &assoc->connection_pool, RpcConnection, conn_pool_entry)
+ {
if (!memcmp(&Connection->ActiveInterface, InterfaceId,
sizeof(RPC_SYNTAX_IDENTIFIER)) &&
RpcAuthInfo_IsEqual(Connection->AuthInfo, AuthInfo) &&
@@ -1492,11 +1540,51 @@ RpcConnection *RpcAssoc_GetIdleConnection(RpcAssoc *assoc,
TRACE("got connection from pool %p\n", Connection);
return Connection;
}
+ }
LeaveCriticalSection(&assoc->cs);
return NULL;
}
+RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc,
+ const RPC_SYNTAX_IDENTIFIER *InterfaceId,
+ const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo,
+ RpcQualityOfService *QOS, RpcConnection **Connection)
+{
+ RpcConnection *NewConnection;
+ RPC_STATUS status;
+
+ *Connection = RpcAssoc_GetIdleConnection(assoc, InterfaceId, TransferSyntax, AuthInfo, QOS);
+ if (*Connection)
+ return RPC_S_OK;
+
+ /* create a new connection */
+ status = RPCRT4_CreateConnection(&NewConnection, FALSE /* is this a server connection? */,
+ assoc->Protseq, assoc->NetworkAddr,
+ assoc->Endpoint, assoc->NetworkOptions,
+ AuthInfo, QOS);
+ if (status != RPC_S_OK)
+ return status;
+
+ status = RPCRT4_OpenClientConnection(NewConnection);
+ if (status != RPC_S_OK)
+ {
+ RPCRT4_DestroyConnection(NewConnection);
+ return status;
+ }
+
+ status = RpcAssoc_BindConnection(assoc, NewConnection, InterfaceId, TransferSyntax);
+ if (status != RPC_S_OK)
+ {
+ RPCRT4_DestroyConnection(NewConnection);
+ return status;
+ }
+
+ *Connection = NewConnection;
+
+ return RPC_S_OK;
+}
+
void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection)
{
assert(!Connection->server);
More information about the wine-cvs
mailing list