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