rpcrt4: Fix handling of arguments passed by value in the old-style stubless marshaller.

This commit is contained in:
Alexandre Julliard 2011-06-07 20:41:17 +02:00
parent 0941644db7
commit 5d7e4da81a
1 changed files with 55 additions and 14 deletions

View File

@ -438,6 +438,23 @@ static unsigned int type_stack_size(unsigned char fc)
} }
} }
static BOOL is_by_value( PFORMAT_STRING format )
{
switch (*format)
{
case RPC_FC_USER_MARSHAL:
case RPC_FC_STRUCT:
case RPC_FC_PSTRUCT:
case RPC_FC_CSTRUCT:
case RPC_FC_CPSTRUCT:
case RPC_FC_CVSTRUCT:
case RPC_FC_BOGUS_STRUCT:
return TRUE;
default:
return FALSE;
}
}
void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg,
PFORMAT_STRING pFormat, int phase, unsigned char *args, PFORMAT_STRING pFormat, int phase, unsigned char *args,
unsigned short stack_size, unsigned short stack_size,
@ -510,11 +527,9 @@ void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg,
} }
else else
{ {
const NDR_PARAM_OI_OTHER *pParamOther = const NDR_PARAM_OI_OTHER *pParamOther = (const NDR_PARAM_OI_OTHER *)&pFormat[current_offset];
(const NDR_PARAM_OI_OTHER *)&pFormat[current_offset]; const unsigned char *pTypeFormat = &pStubMsg->StubDesc->pFormatTypes[pParamOther->type_offset];
const BOOL by_value = is_by_value( pTypeFormat );
const unsigned char *pTypeFormat =
&pStubMsg->StubDesc->pFormatTypes[pParamOther->type_offset];
TRACE("\tcomplex type 0x%02x\n", *pTypeFormat); TRACE("\tcomplex type 0x%02x\n", *pTypeFormat);
@ -523,17 +538,28 @@ void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg,
case PROXY_CALCSIZE: case PROXY_CALCSIZE:
if (pParam->param_direction == RPC_FC_IN_PARAM || if (pParam->param_direction == RPC_FC_IN_PARAM ||
pParam->param_direction == RPC_FC_IN_OUT_PARAM) pParam->param_direction == RPC_FC_IN_OUT_PARAM)
call_buffer_sizer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); {
if (!by_value) pArg = *(unsigned char **)pArg;
call_buffer_sizer(pStubMsg, pArg, pTypeFormat);
}
break; break;
case PROXY_MARSHAL: case PROXY_MARSHAL:
if (pParam->param_direction == RPC_FC_IN_PARAM || if (pParam->param_direction == RPC_FC_IN_PARAM ||
pParam->param_direction == RPC_FC_IN_OUT_PARAM) pParam->param_direction == RPC_FC_IN_OUT_PARAM)
call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat); {
if (!by_value) pArg = *(unsigned char **)pArg;
call_marshaller(pStubMsg, pArg, pTypeFormat);
}
break; break;
case PROXY_UNMARSHAL: case PROXY_UNMARSHAL:
if (pParam->param_direction == RPC_FC_IN_OUT_PARAM || if (pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
pParam->param_direction == RPC_FC_OUT_PARAM) pParam->param_direction == RPC_FC_OUT_PARAM)
call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0); {
if (by_value)
call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0);
else
call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0);
}
else if (pParam->param_direction == RPC_FC_RETURN_PARAM) else if (pParam->param_direction == RPC_FC_RETURN_PARAM)
call_unmarshaller(pStubMsg, (unsigned char **)pRetVal, pTypeFormat, 0); call_unmarshaller(pStubMsg, (unsigned char **)pRetVal, pTypeFormat, 0);
break; break;
@ -1283,6 +1309,7 @@ static LONG_PTR *stub_do_old_args(MIDL_STUB_MESSAGE *pStubMsg,
const unsigned char * pTypeFormat = const unsigned char * pTypeFormat =
&pStubMsg->StubDesc->pFormatTypes[pParamOther->type_offset]; &pStubMsg->StubDesc->pFormatTypes[pParamOther->type_offset];
const BOOL by_value = is_by_value( pTypeFormat );
TRACE("\tcomplex type 0x%02x\n", *pTypeFormat); TRACE("\tcomplex type 0x%02x\n", *pTypeFormat);
@ -1295,17 +1322,23 @@ static LONG_PTR *stub_do_old_args(MIDL_STUB_MESSAGE *pStubMsg,
if (pParam->param_direction == RPC_FC_OUT_PARAM || if (pParam->param_direction == RPC_FC_OUT_PARAM ||
pParam->param_direction == RPC_FC_IN_OUT_PARAM || pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
pParam->param_direction == RPC_FC_RETURN_PARAM) pParam->param_direction == RPC_FC_RETURN_PARAM)
call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat); {
if (!by_value) pArg = *(unsigned char **)pArg;
call_marshaller(pStubMsg, pArg, pTypeFormat);
}
break; break;
case STUBLESS_FREE: case STUBLESS_FREE:
if (pParam->param_direction == RPC_FC_IN_OUT_PARAM || if (pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
pParam->param_direction == RPC_FC_IN_PARAM) pParam->param_direction == RPC_FC_IN_PARAM)
call_freer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); {
else if (pParam->param_direction == RPC_FC_OUT_PARAM) if (!by_value) pArg = *(unsigned char **)pArg;
call_freer(pStubMsg, pArg, pTypeFormat);
}
else if (pParam->param_direction == RPC_FC_OUT_PARAM && !by_value)
pStubMsg->pfnFree(*(void **)pArg); pStubMsg->pfnFree(*(void **)pArg);
break; break;
case STUBLESS_INITOUT: case STUBLESS_INITOUT:
if (pParam->param_direction == RPC_FC_OUT_PARAM) if (pParam->param_direction == RPC_FC_OUT_PARAM && !by_value)
{ {
DWORD size = calc_arg_size(pStubMsg, pTypeFormat); DWORD size = calc_arg_size(pStubMsg, pTypeFormat);
@ -1319,13 +1352,21 @@ static LONG_PTR *stub_do_old_args(MIDL_STUB_MESSAGE *pStubMsg,
case STUBLESS_UNMARSHAL: case STUBLESS_UNMARSHAL:
if (pParam->param_direction == RPC_FC_IN_OUT_PARAM || if (pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
pParam->param_direction == RPC_FC_IN_PARAM) pParam->param_direction == RPC_FC_IN_PARAM)
call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0); {
if (by_value)
call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0);
else
call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0);
}
break; break;
case STUBLESS_CALCSIZE: case STUBLESS_CALCSIZE:
if (pParam->param_direction == RPC_FC_OUT_PARAM || if (pParam->param_direction == RPC_FC_OUT_PARAM ||
pParam->param_direction == RPC_FC_IN_OUT_PARAM || pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
pParam->param_direction == RPC_FC_RETURN_PARAM) pParam->param_direction == RPC_FC_RETURN_PARAM)
call_buffer_sizer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); {
if (!by_value) pArg = *(unsigned char **)pArg;
call_buffer_sizer(pStubMsg, pArg, pTypeFormat);
}
break; break;
default: default:
RpcRaiseException(RPC_S_INTERNAL_ERROR); RpcRaiseException(RPC_S_INTERNAL_ERROR);