Rob Shearman : rpcrt4: Bind to the server interface in I_RpcGetBuffer, not I_RpcSendReceive.
Alexandre Julliard
julliard at winehq.org
Tue Jan 8 10:21:47 CST 2008
Module: wine
Branch: master
Commit: d0f914befce1e3180f4f8712db3952248afad543
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d0f914befce1e3180f4f8712db3952248afad543
Author: Rob Shearman <rob at codeweavers.com>
Date: Tue Jan 8 12:26:19 2008 +0000
rpcrt4: Bind to the server interface in I_RpcGetBuffer, not I_RpcSendReceive.
The actual sending of the request is still done in I_RpcSendReceive though.
Disallow the server from calling I_RpcSend and I_RpcReceive to allow
simplification of the code. The releasing of the connection is now done
in I_RpcFreeBuffer.
Implement I_RpcNegotiateTransferSyntax.
---
dlls/rpcrt4/rpc_assoc.c | 2 +-
dlls/rpcrt4/rpc_message.c | 165 ++++++++++++++++++++++++++-------------------
dlls/rpcrt4/rpc_server.c | 4 +-
3 files changed, 98 insertions(+), 73 deletions(-)
diff --git a/dlls/rpcrt4/rpc_assoc.c b/dlls/rpcrt4/rpc_assoc.c
index 1bffb85..6075278 100644
--- a/dlls/rpcrt4/rpc_assoc.c
+++ b/dlls/rpcrt4/rpc_assoc.c
@@ -332,7 +332,7 @@ static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection *
break;
}
- I_RpcFreeBuffer(&msg);
+ I_RpcFree(msg.Buffer);
RPCRT4_FreeHeader(response_hdr);
return status;
}
diff --git a/dlls/rpcrt4/rpc_message.c b/dlls/rpcrt4/rpc_message.c
index bbcc798..9246afd 100644
--- a/dlls/rpcrt4/rpc_message.c
+++ b/dlls/rpcrt4/rpc_message.c
@@ -754,8 +754,12 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
TRACE("buffer length = %u\n", pMsg->BufferLength);
- status = I_RpcGetBuffer(pMsg);
- if (status != RPC_S_OK) goto fail;
+ pMsg->Buffer = I_RpcAllocate(pMsg->BufferLength);
+ if (!pMsg->Buffer)
+ {
+ status = ERROR_OUTOFMEMORY;
+ goto fail;
+ }
first_flag = RPC_FLG_FIRST;
auth_length = common_hdr.auth_len;
@@ -891,6 +895,54 @@ fail:
}
/***********************************************************************
+ * I_RpcNegotiateTransferSyntax [RPCRT4.@]
+ *
+ * Negotiates the transfer syntax used by a client connection by connecting
+ * to the server.
+ *
+ * PARAMS
+ * pMsg [I] RPC Message structure.
+ * pAsync [I] Asynchronous state to set.
+ *
+ * RETURNS
+ * Success: RPC_S_OK.
+ * Failure: Any error code.
+ */
+RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg)
+{
+ RpcBinding* bind = (RpcBinding*)pMsg->Handle;
+ RpcConnection* conn;
+ RPC_STATUS status = RPC_S_OK;
+
+ TRACE("(%p)\n", pMsg);
+
+ if (!bind || bind->server)
+ return RPC_S_INVALID_BINDING;
+
+ /* if we already have a connection, we don't need to negotiate again */
+ if (!pMsg->ReservedForRuntime)
+ {
+ RPC_CLIENT_INTERFACE *cif = pMsg->RpcInterfaceInformation;
+ if (!cif) return RPC_S_INTERFACE_NOT_FOUND;
+
+ if (!bind->Endpoint || !bind->Endpoint[0])
+ {
+ TRACE("automatically resolving partially bound binding\n");
+ status = RpcEpResolveBinding(bind, cif);
+ if (status != RPC_S_OK) return status;
+ }
+
+ status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax,
+ &cif->InterfaceId);
+
+ if (status == RPC_S_OK)
+ pMsg->ReservedForRuntime = conn;
+ }
+
+ return status;
+}
+
+/***********************************************************************
* I_RpcGetBuffer [RPCRT4.@]
*
* Allocates a buffer for use by I_RpcSend or I_RpcSendReceive and binds to the
@@ -916,11 +968,30 @@ fail:
*/
RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg)
{
+ RPC_STATUS status;
+ RpcBinding* bind = (RpcBinding*)pMsg->Handle;
+
TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength);
- pMsg->Buffer = HeapAlloc(GetProcessHeap(), 0, pMsg->BufferLength);
+ if (!bind)
+ return RPC_S_INVALID_BINDING;
+
+ pMsg->Buffer = I_RpcAllocate(pMsg->BufferLength);
TRACE("Buffer=%p\n", pMsg->Buffer);
- return pMsg->Buffer ? RPC_S_OK : ERROR_OUTOFMEMORY;
+
+ if (!pMsg->Buffer)
+ return ERROR_OUTOFMEMORY;
+
+ if (!bind->server)
+ {
+ status = I_RpcNegotiateTransferSyntax(pMsg);
+ if (status != RPC_S_OK)
+ I_RpcFree(pMsg->Buffer);
+ }
+ else
+ status = RPC_S_OK;
+
+ return status;
}
/***********************************************************************
@@ -952,8 +1023,19 @@ static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg)
*/
RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg)
{
+ RpcBinding* bind = (RpcBinding*)pMsg->Handle;
+
TRACE("(%p) Buffer=%p\n", pMsg, pMsg->Buffer);
- HeapFree(GetProcessHeap(), 0, pMsg->Buffer);
+
+ if (!bind) return RPC_S_INVALID_BINDING;
+
+ if (pMsg->ReservedForRuntime)
+ {
+ RpcConnection *conn = pMsg->ReservedForRuntime;
+ RPCRT4_CloseBinding(bind, conn);
+ pMsg->ReservedForRuntime = NULL;
+ }
+ I_RpcFree(pMsg->Buffer);
return RPC_S_OK;
}
@@ -978,44 +1060,26 @@ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg)
{
RpcBinding* bind = (RpcBinding*)pMsg->Handle;
RpcConnection* conn;
- RPC_CLIENT_INTERFACE* cif = NULL;
RPC_STATUS status;
RpcPktHdr *hdr;
TRACE("(%p)\n", pMsg);
- if (!bind || bind->server) return RPC_S_INVALID_BINDING;
-
- cif = pMsg->RpcInterfaceInformation;
- if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */
-
- if (!bind->Endpoint || !bind->Endpoint[0])
- {
- TRACE("automatically resolving partially bound binding\n");
- status = RpcEpResolveBinding(bind, cif);
- if (status != RPC_S_OK) return status;
- }
+ if (!bind || bind->server || !pMsg->ReservedForRuntime) return RPC_S_INVALID_BINDING;
- status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax,
- &cif->InterfaceId);
- if (status != RPC_S_OK) return status;
+ conn = pMsg->ReservedForRuntime;
hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation,
pMsg->BufferLength,
pMsg->ProcNum & ~RPC_FLAGS_VALID_BIT,
&bind->ObjectUuid);
if (!hdr)
- {
- RPCRT4_CloseBinding(bind, conn);
return ERROR_OUTOFMEMORY;
- }
hdr->common.call_id = conn->NextCallId++;
status = RPCRT4_Send(conn, hdr, pMsg->Buffer, pMsg->BufferLength);
RPCRT4_FreeHeader(hdr);
- /* save the connection, so the response can be read from it */
- pMsg->ReservedForRuntime = conn;
return status;
}
@@ -1043,41 +1107,14 @@ static inline BOOL is_hard_error(RPC_STATUS status)
RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
{
RpcBinding* bind = (RpcBinding*)pMsg->Handle;
- RpcConnection* conn;
- RPC_CLIENT_INTERFACE* cif = NULL;
- RPC_SERVER_INTERFACE* sif = NULL;
RPC_STATUS status;
RpcPktHdr *hdr = NULL;
+ RpcConnection *conn;
TRACE("(%p)\n", pMsg);
- if (!bind) return RPC_S_INVALID_BINDING;
-
- if (pMsg->ReservedForRuntime) {
- conn = pMsg->ReservedForRuntime;
- pMsg->ReservedForRuntime = NULL;
- } else {
- if (bind->server) {
- sif = pMsg->RpcInterfaceInformation;
- if (!sif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */
- status = RPCRT4_OpenBinding(bind, &conn, &sif->TransferSyntax,
- &sif->InterfaceId);
- } else {
- cif = pMsg->RpcInterfaceInformation;
- if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */
-
- if (!bind->Endpoint || !bind->Endpoint[0])
- {
- TRACE("automatically resolving partially bound binding\n");
- status = RpcEpResolveBinding(bind, cif);
- if (status != RPC_S_OK) return status;
- }
-
- status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax,
- &cif->InterfaceId);
- }
- if (status != RPC_S_OK) return status;
- }
+ if (!bind || bind->server || !pMsg->ReservedForRuntime) return RPC_S_INVALID_BINDING;
+ conn = pMsg->ReservedForRuntime;
status = RPCRT4_Receive(conn, &hdr, pMsg);
if (status != RPC_S_OK) {
WARN("receive failed with error %lx\n", status);
@@ -1086,16 +1123,6 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
switch (hdr->common.ptype) {
case PKT_RESPONSE:
- if (bind->server) {
- status = RPC_S_PROTOCOL_ERROR;
- goto fail;
- }
- break;
- case PKT_REQUEST:
- if (!bind->server) {
- status = RPC_S_PROTOCOL_ERROR;
- goto fail;
- }
break;
case PKT_FAULT:
ERR ("we got fault packet with status 0x%lx\n", hdr->fault.status);
@@ -1110,13 +1137,13 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
}
/* success */
- RPCRT4_CloseBinding(bind, conn);
RPCRT4_FreeHeader(hdr);
return status;
fail:
RPCRT4_FreeHeader(hdr);
RPCRT4_DestroyConnection(conn);
+ pMsg->ReservedForRuntime = NULL;
return status;
}
@@ -1141,17 +1168,17 @@ fail:
RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg)
{
RPC_STATUS status;
- RPC_MESSAGE original_message;
+ void *original_buffer;
TRACE("(%p)\n", pMsg);
- original_message = *pMsg;
+ original_buffer = pMsg->Buffer;
status = I_RpcSend(pMsg);
if (status == RPC_S_OK)
status = I_RpcReceive(pMsg);
/* free the buffer replaced by a new buffer in I_RpcReceive */
if (status == RPC_S_OK)
- I_RpcFreeBuffer(&original_message);
+ I_RpcFree(original_buffer);
return status;
}
diff --git a/dlls/rpcrt4/rpc_server.c b/dlls/rpcrt4/rpc_server.c
index 3db7365..fcac3dd 100644
--- a/dlls/rpcrt4/rpc_server.c
+++ b/dlls/rpcrt4/rpc_server.c
@@ -335,10 +335,8 @@ fail:
/* clean up */
if (msg->Buffer == buf) msg->Buffer = NULL;
TRACE("freeing Buffer=%p\n", buf);
- HeapFree(GetProcessHeap(), 0, buf);
- msg->Handle = 0;
+ I_RpcFree(buf);
I_RpcFreeBuffer(msg);
- msg->Buffer = NULL;
RPCRT4_FreeHeader(hdr);
HeapFree(GetProcessHeap(), 0, msg);
}
More information about the wine-cvs
mailing list