Commit d0f914be authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

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.
parent bb78c3f8
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment