Robert Shearman : rpcrt4:
Store the return value on the stack for interpreted stubs.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Apr 20 08:45:53 CDT 2006
Module: wine
Branch: refs/heads/master
Commit: 312df9bf7f7f34cea9f89a5bfebf4bbadbf503e0
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=312df9bf7f7f34cea9f89a5bfebf4bbadbf503e0
Author: Robert Shearman <rob at codeweavers.com>
Date: Thu Apr 20 11:43:22 2006 +0100
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.
---
dlls/rpcrt4/ndr_stubless.c | 90 +++++++++++++++++++++-----------------------
1 files changed, 43 insertions(+), 47 deletions(-)
diff --git a/dlls/rpcrt4/ndr_stubless.c b/dlls/rpcrt4/ndr_stubless.c
index a7f0b93..b9d379e 100644
--- a/dlls/rpcrt4/ndr_stubless.c
+++ b/dlls/rpcrt4/ndr_stubless.c
@@ -1010,9 +1010,8 @@ long WINAPI NdrStubCall2(
int current_offset;
/* -Oif or -Oicf generated format */
BOOL bV2Format = FALSE;
- /* the return value (not from this function, but to be put back onto
- * the wire */
- LONG_PTR RetVal = 0;
+ /* location to put retval into */
+ LONG_PTR *retval_ptr = NULL;
TRACE("pThis %p, pChannel %p, pRpcMsg %p, pdwStubPhase %p\n", pThis, pChannel, pRpcMsg, pdwStubPhase);
@@ -1173,16 +1172,30 @@ #endif
/* call the server function */
if (pServerInfo->ThunkTable && pServerInfo->ThunkTable[pRpcMsg->ProcNum])
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
- RetVal = call_server_func(pServerInfo->DispatchTable[pRpcMsg->ProcNum], args, stack_size);
+ {
+ SERVER_ROUTINE func;
+ LONG_PTR 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];
- TRACE("stub implementation returned %p\n", (void *)RetVal);
+ /* 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.BufferLength = 0;
@@ -1245,9 +1258,7 @@ #endif
switch (phase)
{
case STUBLESS_MARSHAL:
- if (pParam->param_attributes.IsReturn)
- call_marshaller(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
- else if (pParam->param_attributes.IsOut)
+ if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn)
{
if (pParam->param_attributes.IsSimpleRef)
call_marshaller(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
@@ -1264,11 +1275,14 @@ #endif
else
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;
case STUBLESS_CALCSIZE:
- if (pParam->param_attributes.IsReturn)
- call_buffer_sizer(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
- else if (pParam->param_attributes.IsOut)
+ if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn)
{
if (pParam->param_attributes.IsSimpleRef)
call_buffer_sizer(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
@@ -1295,9 +1309,7 @@ #endif
switch (phase)
{
case STUBLESS_MARSHAL:
- if (pParam->param_attributes.IsReturn)
- call_marshaller(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
- else if (pParam->param_attributes.IsOut)
+ if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn)
{
if (pParam->param_attributes.IsByValue)
call_marshaller(&stubMsg, pArg, pTypeFormat);
@@ -1317,17 +1329,15 @@ #endif
else
call_unmarshaller(&stubMsg, (unsigned char **)pArg, pTypeFormat, 0);
}
- else if ((pParam->param_attributes.IsOut) &&
- !(pParam->param_attributes.IsByValue))
+ else if (pParam->param_attributes.IsOut &&
+ !pParam->param_attributes.IsByValue)
{
*(void **)pArg = NdrAllocate(&stubMsg, sizeof(void *));
**(void ***)pArg = 0;
}
break;
case STUBLESS_CALCSIZE:
- if (pParam->param_attributes.IsReturn)
- call_buffer_sizer(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
- else if (pParam->param_attributes.IsOut)
+ if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn)
{
if (pParam->param_attributes.IsByValue)
call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
@@ -1367,10 +1377,7 @@ #endif
{
case STUBLESS_MARSHAL:
if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
- {
- unsigned char *pRetVal = (unsigned char *)&RetVal;
- call_marshaller(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat);
- }
+ call_marshaller(&stubMsg, pArg, pTypeFormat);
break;
case STUBLESS_UNMARSHAL:
if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE)
@@ -1378,10 +1385,7 @@ #endif
break;
case STUBLESS_CALCSIZE:
if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
- {
- unsigned char * pRetVal = (unsigned char *)&RetVal;
- call_buffer_sizer(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat);
- }
+ call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
break;
default:
RpcRaiseException(RPC_S_INTERNAL_ERROR);
@@ -1403,13 +1407,9 @@ #endif
switch (phase)
{
case STUBLESS_MARSHAL:
- if (pParam->param_direction == RPC_FC_RETURN_PARAM)
- {
- unsigned char *pRetVal = (unsigned char *)&RetVal;
- call_marshaller(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat);
- }
- else if (pParam->param_direction == RPC_FC_OUT_PARAM ||
- pParam->param_direction == RPC_FC_IN_OUT_PARAM)
+ if (pParam->param_direction == RPC_FC_OUT_PARAM ||
+ pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
+ pParam->param_direction == RPC_FC_RETURN_PARAM)
call_marshaller(&stubMsg, pArg, pTypeFormat);
break;
case STUBLESS_UNMARSHAL:
@@ -1418,13 +1418,9 @@ #endif
call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
break;
case STUBLESS_CALCSIZE:
- if (pParam->param_direction == RPC_FC_RETURN_PARAM)
- {
- unsigned char * pRetVal = (unsigned char *)&RetVal;
- 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)
+ if (pParam->param_direction == RPC_FC_OUT_PARAM ||
+ pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
+ pParam->param_direction == RPC_FC_RETURN_PARAM)
call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
break;
default:
More information about the wine-cvs
mailing list