rpcrt4: Store the return value on the stack for interpreted stubs.

Store the return value on the stack for stubs, as MIDL reserves space
for it and gives us a stack offset. This fixes calling methods with
thunks that assume that the return value will be stored on the stack.
This commit is contained in:
Robert Shearman 2006-04-20 11:43:22 +01:00 committed by Alexandre Julliard
parent f4de78babe
commit 312df9bf7f
1 changed files with 43 additions and 47 deletions

View File

@ -1010,9 +1010,8 @@ long WINAPI NdrStubCall2(
int current_offset; int current_offset;
/* -Oif or -Oicf generated format */ /* -Oif or -Oicf generated format */
BOOL bV2Format = FALSE; BOOL bV2Format = FALSE;
/* the return value (not from this function, but to be put back onto /* location to put retval into */
* the wire */ LONG_PTR *retval_ptr = NULL;
LONG_PTR RetVal = 0;
TRACE("pThis %p, pChannel %p, pRpcMsg %p, pdwStubPhase %p\n", pThis, pChannel, pRpcMsg, pdwStubPhase); TRACE("pThis %p, pChannel %p, pRpcMsg %p, pdwStubPhase %p\n", pThis, pChannel, pRpcMsg, pdwStubPhase);
@ -1173,16 +1172,30 @@ long WINAPI NdrStubCall2(
/* call the server function */ /* call the server function */
if (pServerInfo->ThunkTable && pServerInfo->ThunkTable[pRpcMsg->ProcNum]) if (pServerInfo->ThunkTable && pServerInfo->ThunkTable[pRpcMsg->ProcNum])
pServerInfo->ThunkTable[pRpcMsg->ProcNum](&stubMsg); pServerInfo->ThunkTable[pRpcMsg->ProcNum](&stubMsg);
/* FIXME: RetVal is stored as the last argument - retrieve it */
else if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
{
SERVER_ROUTINE *vtbl = *(SERVER_ROUTINE **)((CStdStubBuffer *)pThis)->pvServerObject;
RetVal = call_server_func(vtbl[pRpcMsg->ProcNum], args, stack_size);
}
else else
RetVal = call_server_func(pServerInfo->DispatchTable[pRpcMsg->ProcNum], args, stack_size); {
SERVER_ROUTINE func;
LONG_PTR retval;
TRACE("stub implementation returned %p\n", (void *)RetVal); if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
{
SERVER_ROUTINE *vtbl = *(SERVER_ROUTINE **)((CStdStubBuffer *)pThis)->pvServerObject;
func = vtbl[pRpcMsg->ProcNum];
}
else
func = pServerInfo->DispatchTable[pRpcMsg->ProcNum];
/* FIXME: what happens with return values that don't fit into a single register on x86? */
retval = call_server_func(func, args, stack_size);
if (retval_ptr)
{
TRACE("stub implementation returned 0x%lx\n", retval);
*retval_ptr = retval;
}
else
TRACE("void stub implementation\n");
}
stubMsg.Buffer = NULL; stubMsg.Buffer = NULL;
stubMsg.BufferLength = 0; stubMsg.BufferLength = 0;
@ -1245,9 +1258,7 @@ long WINAPI NdrStubCall2(
switch (phase) switch (phase)
{ {
case STUBLESS_MARSHAL: case STUBLESS_MARSHAL:
if (pParam->param_attributes.IsReturn) if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn)
call_marshaller(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
else if (pParam->param_attributes.IsOut)
{ {
if (pParam->param_attributes.IsSimpleRef) if (pParam->param_attributes.IsSimpleRef)
call_marshaller(&stubMsg, *(unsigned char **)pArg, pTypeFormat); call_marshaller(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
@ -1264,11 +1275,14 @@ long WINAPI NdrStubCall2(
else else
call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
} }
/* make a note of the address of the return value parameter for later */
if (pParam->param_attributes.IsReturn)
retval_ptr = (LONG_PTR *)pArg;
break; break;
case STUBLESS_CALCSIZE: case STUBLESS_CALCSIZE:
if (pParam->param_attributes.IsReturn) if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn)
call_buffer_sizer(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
else if (pParam->param_attributes.IsOut)
{ {
if (pParam->param_attributes.IsSimpleRef) if (pParam->param_attributes.IsSimpleRef)
call_buffer_sizer(&stubMsg, *(unsigned char **)pArg, pTypeFormat); call_buffer_sizer(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
@ -1295,9 +1309,7 @@ long WINAPI NdrStubCall2(
switch (phase) switch (phase)
{ {
case STUBLESS_MARSHAL: case STUBLESS_MARSHAL:
if (pParam->param_attributes.IsReturn) if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn)
call_marshaller(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
else if (pParam->param_attributes.IsOut)
{ {
if (pParam->param_attributes.IsByValue) if (pParam->param_attributes.IsByValue)
call_marshaller(&stubMsg, pArg, pTypeFormat); call_marshaller(&stubMsg, pArg, pTypeFormat);
@ -1317,17 +1329,15 @@ long WINAPI NdrStubCall2(
else else
call_unmarshaller(&stubMsg, (unsigned char **)pArg, pTypeFormat, 0); call_unmarshaller(&stubMsg, (unsigned char **)pArg, pTypeFormat, 0);
} }
else if ((pParam->param_attributes.IsOut) && else if (pParam->param_attributes.IsOut &&
!(pParam->param_attributes.IsByValue)) !pParam->param_attributes.IsByValue)
{ {
*(void **)pArg = NdrAllocate(&stubMsg, sizeof(void *)); *(void **)pArg = NdrAllocate(&stubMsg, sizeof(void *));
**(void ***)pArg = 0; **(void ***)pArg = 0;
} }
break; break;
case STUBLESS_CALCSIZE: case STUBLESS_CALCSIZE:
if (pParam->param_attributes.IsReturn) if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn)
call_buffer_sizer(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
else if (pParam->param_attributes.IsOut)
{ {
if (pParam->param_attributes.IsByValue) if (pParam->param_attributes.IsByValue)
call_buffer_sizer(&stubMsg, pArg, pTypeFormat); call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
@ -1367,10 +1377,7 @@ long WINAPI NdrStubCall2(
{ {
case STUBLESS_MARSHAL: case STUBLESS_MARSHAL:
if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
{ call_marshaller(&stubMsg, pArg, pTypeFormat);
unsigned char *pRetVal = (unsigned char *)&RetVal;
call_marshaller(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat);
}
break; break;
case STUBLESS_UNMARSHAL: case STUBLESS_UNMARSHAL:
if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE)
@ -1378,10 +1385,7 @@ long WINAPI NdrStubCall2(
break; break;
case STUBLESS_CALCSIZE: case STUBLESS_CALCSIZE:
if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
{ call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
unsigned char * pRetVal = (unsigned char *)&RetVal;
call_buffer_sizer(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat);
}
break; break;
default: default:
RpcRaiseException(RPC_S_INTERNAL_ERROR); RpcRaiseException(RPC_S_INTERNAL_ERROR);
@ -1403,13 +1407,9 @@ long WINAPI NdrStubCall2(
switch (phase) switch (phase)
{ {
case STUBLESS_MARSHAL: case STUBLESS_MARSHAL:
if (pParam->param_direction == RPC_FC_RETURN_PARAM) if (pParam->param_direction == RPC_FC_OUT_PARAM ||
{ pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
unsigned char *pRetVal = (unsigned char *)&RetVal; pParam->param_direction == RPC_FC_RETURN_PARAM)
call_marshaller(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat);
}
else if (pParam->param_direction == RPC_FC_OUT_PARAM ||
pParam->param_direction == RPC_FC_IN_OUT_PARAM)
call_marshaller(&stubMsg, pArg, pTypeFormat); call_marshaller(&stubMsg, pArg, pTypeFormat);
break; break;
case STUBLESS_UNMARSHAL: case STUBLESS_UNMARSHAL:
@ -1418,13 +1418,9 @@ long WINAPI NdrStubCall2(
call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
break; break;
case STUBLESS_CALCSIZE: case STUBLESS_CALCSIZE:
if (pParam->param_direction == RPC_FC_RETURN_PARAM) if (pParam->param_direction == RPC_FC_OUT_PARAM ||
{ pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
unsigned char * pRetVal = (unsigned char *)&RetVal; pParam->param_direction == RPC_FC_RETURN_PARAM)
call_buffer_sizer(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat);
}
else if (pParam->param_direction == RPC_FC_OUT_PARAM ||
pParam->param_direction == RPC_FC_IN_OUT_PARAM)
call_buffer_sizer(&stubMsg, pArg, pTypeFormat); call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
break; break;
default: default: