Module: wine Branch: master Commit: d0f914befce1e3180f4f8712db3952248afad543 URL: http://source.winehq.org/git/wine.git/?a=commit;h=d0f914befce1e3180f4f8712db...
Author: Rob Shearman rob@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); }