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.
This commit is contained in:
parent
bb78c3f86d
commit
d0f914befc
|
@ -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;
|
||||
|
@ -890,6 +894,54 @@ fail:
|
|||
return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* 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.@]
|
||||
*
|
||||
|
@ -916,11 +968,30 @@ fail:
|
|||
*/
|
||||
RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg)
|
||||
{
|
||||
TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength);
|
||||
pMsg->Buffer = HeapAlloc(GetProcessHeap(), 0, pMsg->BufferLength);
|
||||
RPC_STATUS status;
|
||||
RpcBinding* bind = (RpcBinding*)pMsg->Handle;
|
||||
|
||||
TRACE("(%p): BufferLength=%d\n", pMsg, 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;
|
||||
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,
|
||||
&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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue