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 * ...@@ -332,7 +332,7 @@ static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection *
break; break;
} }
I_RpcFreeBuffer(&msg); I_RpcFree(msg.Buffer);
RPCRT4_FreeHeader(response_hdr); RPCRT4_FreeHeader(response_hdr);
return status; return status;
} }
......
...@@ -754,8 +754,12 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, ...@@ -754,8 +754,12 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
TRACE("buffer length = %u\n", pMsg->BufferLength); TRACE("buffer length = %u\n", pMsg->BufferLength);
status = I_RpcGetBuffer(pMsg); pMsg->Buffer = I_RpcAllocate(pMsg->BufferLength);
if (status != RPC_S_OK) goto fail; if (!pMsg->Buffer)
{
status = ERROR_OUTOFMEMORY;
goto fail;
}
first_flag = RPC_FLG_FIRST; first_flag = RPC_FLG_FIRST;
auth_length = common_hdr.auth_len; auth_length = common_hdr.auth_len;
...@@ -891,6 +895,54 @@ fail: ...@@ -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.@] * I_RpcGetBuffer [RPCRT4.@]
* *
* Allocates a buffer for use by I_RpcSend or I_RpcSendReceive and binds to the * Allocates a buffer for use by I_RpcSend or I_RpcSendReceive and binds to the
...@@ -916,11 +968,30 @@ fail: ...@@ -916,11 +968,30 @@ fail:
*/ */
RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg) RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg)
{ {
RPC_STATUS status;
RpcBinding* bind = (RpcBinding*)pMsg->Handle;
TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength); 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); 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) ...@@ -952,8 +1023,19 @@ static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg)
*/ */
RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg) RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg)
{ {
RpcBinding* bind = (RpcBinding*)pMsg->Handle;
TRACE("(%p) Buffer=%p\n", pMsg, pMsg->Buffer); 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; return RPC_S_OK;
} }
...@@ -978,44 +1060,26 @@ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg) ...@@ -978,44 +1060,26 @@ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg)
{ {
RpcBinding* bind = (RpcBinding*)pMsg->Handle; RpcBinding* bind = (RpcBinding*)pMsg->Handle;
RpcConnection* conn; RpcConnection* conn;
RPC_CLIENT_INTERFACE* cif = NULL;
RPC_STATUS status; RPC_STATUS status;
RpcPktHdr *hdr; RpcPktHdr *hdr;
TRACE("(%p)\n", pMsg); TRACE("(%p)\n", pMsg);
if (!bind || bind->server) return RPC_S_INVALID_BINDING; if (!bind || bind->server || !pMsg->ReservedForRuntime) 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;
}
status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax, conn = pMsg->ReservedForRuntime;
&cif->InterfaceId);
if (status != RPC_S_OK) return status;
hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation, hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation,
pMsg->BufferLength, pMsg->BufferLength,
pMsg->ProcNum & ~RPC_FLAGS_VALID_BIT, pMsg->ProcNum & ~RPC_FLAGS_VALID_BIT,
&bind->ObjectUuid); &bind->ObjectUuid);
if (!hdr) if (!hdr)
{
RPCRT4_CloseBinding(bind, conn);
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
}
hdr->common.call_id = conn->NextCallId++; hdr->common.call_id = conn->NextCallId++;
status = RPCRT4_Send(conn, hdr, pMsg->Buffer, pMsg->BufferLength); status = RPCRT4_Send(conn, hdr, pMsg->Buffer, pMsg->BufferLength);
RPCRT4_FreeHeader(hdr); RPCRT4_FreeHeader(hdr);
/* save the connection, so the response can be read from it */
pMsg->ReservedForRuntime = conn;
return status; return status;
} }
...@@ -1043,41 +1107,14 @@ static inline BOOL is_hard_error(RPC_STATUS status) ...@@ -1043,41 +1107,14 @@ static inline BOOL is_hard_error(RPC_STATUS status)
RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
{ {
RpcBinding* bind = (RpcBinding*)pMsg->Handle; RpcBinding* bind = (RpcBinding*)pMsg->Handle;
RpcConnection* conn;
RPC_CLIENT_INTERFACE* cif = NULL;
RPC_SERVER_INTERFACE* sif = NULL;
RPC_STATUS status; RPC_STATUS status;
RpcPktHdr *hdr = NULL; RpcPktHdr *hdr = NULL;
RpcConnection *conn;
TRACE("(%p)\n", pMsg); TRACE("(%p)\n", pMsg);
if (!bind) return RPC_S_INVALID_BINDING; if (!bind || bind->server || !pMsg->ReservedForRuntime) 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;
}
conn = pMsg->ReservedForRuntime;
status = RPCRT4_Receive(conn, &hdr, pMsg); status = RPCRT4_Receive(conn, &hdr, pMsg);
if (status != RPC_S_OK) { if (status != RPC_S_OK) {
WARN("receive failed with error %lx\n", status); WARN("receive failed with error %lx\n", status);
...@@ -1086,16 +1123,6 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) ...@@ -1086,16 +1123,6 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
switch (hdr->common.ptype) { switch (hdr->common.ptype) {
case PKT_RESPONSE: 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; break;
case PKT_FAULT: case PKT_FAULT:
ERR ("we got fault packet with status 0x%lx\n", hdr->fault.status); 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) ...@@ -1110,13 +1137,13 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
} }
/* success */ /* success */
RPCRT4_CloseBinding(bind, conn);
RPCRT4_FreeHeader(hdr); RPCRT4_FreeHeader(hdr);
return status; return status;
fail: fail:
RPCRT4_FreeHeader(hdr); RPCRT4_FreeHeader(hdr);
RPCRT4_DestroyConnection(conn); RPCRT4_DestroyConnection(conn);
pMsg->ReservedForRuntime = NULL;
return status; return status;
} }
...@@ -1141,17 +1168,17 @@ fail: ...@@ -1141,17 +1168,17 @@ fail:
RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg) RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg)
{ {
RPC_STATUS status; RPC_STATUS status;
RPC_MESSAGE original_message; void *original_buffer;
TRACE("(%p)\n", pMsg); TRACE("(%p)\n", pMsg);
original_message = *pMsg; original_buffer = pMsg->Buffer;
status = I_RpcSend(pMsg); status = I_RpcSend(pMsg);
if (status == RPC_S_OK) if (status == RPC_S_OK)
status = I_RpcReceive(pMsg); status = I_RpcReceive(pMsg);
/* free the buffer replaced by a new buffer in I_RpcReceive */ /* free the buffer replaced by a new buffer in I_RpcReceive */
if (status == RPC_S_OK) if (status == RPC_S_OK)
I_RpcFreeBuffer(&original_message); I_RpcFree(original_buffer);
return status; return status;
} }
......
...@@ -335,10 +335,8 @@ fail: ...@@ -335,10 +335,8 @@ fail:
/* clean up */ /* clean up */
if (msg->Buffer == buf) msg->Buffer = NULL; if (msg->Buffer == buf) msg->Buffer = NULL;
TRACE("freeing Buffer=%p\n", buf); TRACE("freeing Buffer=%p\n", buf);
HeapFree(GetProcessHeap(), 0, buf); I_RpcFree(buf);
msg->Handle = 0;
I_RpcFreeBuffer(msg); I_RpcFreeBuffer(msg);
msg->Buffer = NULL;
RPCRT4_FreeHeader(hdr); RPCRT4_FreeHeader(hdr);
HeapFree(GetProcessHeap(), 0, msg); 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