rpcrt4: The initialisation of [out] variables in the stubless code must be after the unmarshaling of [in] and [in, out] variables has been completed.

This is because the size of an [out] variable could depend on a
conformance value stored in an unmarshalled [in] or [in,out] variable.
This commit is contained in:
Rob Shearman 2008-01-14 11:56:13 +00:00 committed by Alexandre Julliard
parent 4f6142b8d9
commit ed5b296289
1 changed files with 36 additions and 27 deletions

View File

@ -114,11 +114,12 @@ static inline unsigned long call_memory_sizer(PMIDL_STUB_MESSAGE pStubMsg, PFORM
} }
#define STUBLESS_UNMARSHAL 1 #define STUBLESS_UNMARSHAL 1
#define STUBLESS_CALLSERVER 2 #define STUBLESS_INITOUT 2
#define STUBLESS_CALCSIZE 3 #define STUBLESS_CALLSERVER 3
#define STUBLESS_GETBUFFER 4 #define STUBLESS_CALCSIZE 4
#define STUBLESS_MARSHAL 5 #define STUBLESS_GETBUFFER 5
#define STUBLESS_FREE 6 #define STUBLESS_MARSHAL 6
#define STUBLESS_FREE 7
void WINAPI NdrRpcSmSetClientToOsf(PMIDL_STUB_MESSAGE pMessage) void WINAPI NdrRpcSmSetClientToOsf(PMIDL_STUB_MESSAGE pMessage)
{ {
@ -855,6 +856,7 @@ static DWORD calc_arg_size(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
pFormat = ComputeVariance(pStubMsg, NULL, pFormat, pStubMsg->MaxCount); pFormat = ComputeVariance(pStubMsg, NULL, pFormat, pStubMsg->MaxCount);
size = ComplexStructSize(pStubMsg, pFormat); size = ComplexStructSize(pStubMsg, pFormat);
size *= pStubMsg->MaxCount; size *= pStubMsg->MaxCount;
break;
default: default:
FIXME("Unhandled type %02x\n", *pFormat); FIXME("Unhandled type %02x\n", *pFormat);
/* fallthrough */ /* fallthrough */
@ -915,6 +917,8 @@ static LONG_PTR *stub_do_args(MIDL_STUB_MESSAGE *pStubMsg,
if (pParam->param_attributes.ServerAllocSize) if (pParam->param_attributes.ServerAllocSize)
HeapFree(GetProcessHeap(), 0, *(void **)pArg); HeapFree(GetProcessHeap(), 0, *(void **)pArg);
break; break;
case STUBLESS_INITOUT:
break;
case STUBLESS_UNMARSHAL: case STUBLESS_UNMARSHAL:
if (pParam->param_attributes.ServerAllocSize) if (pParam->param_attributes.ServerAllocSize)
*(void **)pArg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *(void **)pArg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
@ -988,7 +992,21 @@ static LONG_PTR *stub_do_args(MIDL_STUB_MESSAGE *pStubMsg,
if (pParam->param_attributes.ServerAllocSize) if (pParam->param_attributes.ServerAllocSize)
HeapFree(GetProcessHeap(), 0, *(void **)pArg); HeapFree(GetProcessHeap(), 0, *(void **)pArg);
/* FIXME: call call_freer here for IN types with MustFree set */ break;
case STUBLESS_INITOUT:
if (!pParam->param_attributes.IsIn &&
pParam->param_attributes.IsOut &&
!pParam->param_attributes.ServerAllocSize &&
!pParam->param_attributes.IsByValue)
{
DWORD size = calc_arg_size(pStubMsg, pTypeFormat);
if(size)
{
*(void **)pArg = NdrAllocate(pStubMsg, size);
memset(*(void **)pArg, 0, size);
}
}
break; break;
case STUBLESS_UNMARSHAL: case STUBLESS_UNMARSHAL:
if (pParam->param_attributes.ServerAllocSize) if (pParam->param_attributes.ServerAllocSize)
@ -1002,18 +1020,6 @@ static LONG_PTR *stub_do_args(MIDL_STUB_MESSAGE *pStubMsg,
else else
call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0); call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0);
} }
else if (pParam->param_attributes.IsOut &&
!pParam->param_attributes.ServerAllocSize &&
!pParam->param_attributes.IsByValue)
{
DWORD size = calc_arg_size(pStubMsg, pTypeFormat);
if(size)
{
*(void **)pArg = NdrAllocate(pStubMsg, size);
memset(*(void **)pArg, 0, size);
}
}
break; break;
case STUBLESS_CALCSIZE: case STUBLESS_CALCSIZE:
if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn) if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn)
@ -1127,14 +1133,9 @@ static LONG_PTR *stub_do_old_args(MIDL_STUB_MESSAGE *pStubMsg,
call_freer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); call_freer(pStubMsg, *(unsigned char **)pArg, pTypeFormat);
else if (pParam->param_direction == RPC_FC_OUT_PARAM) else if (pParam->param_direction == RPC_FC_OUT_PARAM)
pStubMsg->pfnFree(*(void **)pArg); pStubMsg->pfnFree(*(void **)pArg);
break; break;
case STUBLESS_UNMARSHAL: case STUBLESS_INITOUT:
if (pParam->param_direction == RPC_FC_IN_OUT_PARAM || if (pParam->param_direction == RPC_FC_OUT_PARAM)
pParam->param_direction == RPC_FC_IN_PARAM)
call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0);
else if (pParam->param_direction == RPC_FC_RETURN_PARAM)
retval_ptr = (LONG_PTR *)pArg;
else if (pParam->param_direction == RPC_FC_OUT_PARAM)
{ {
DWORD size = calc_arg_size(pStubMsg, pTypeFormat); DWORD size = calc_arg_size(pStubMsg, pTypeFormat);
@ -1145,6 +1146,13 @@ static LONG_PTR *stub_do_old_args(MIDL_STUB_MESSAGE *pStubMsg,
} }
} }
break; break;
case STUBLESS_UNMARSHAL:
if (pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
pParam->param_direction == RPC_FC_IN_PARAM)
call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0);
else if (pParam->param_direction == RPC_FC_RETURN_PARAM)
retval_ptr = (LONG_PTR *)pArg;
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 ||
@ -1406,9 +1414,10 @@ LONG WINAPI NdrStubCall2(
stubMsg.Buffer = stubMsg.BufferStart; stubMsg.Buffer = stubMsg.BufferStart;
} }
break; break;
case STUBLESS_MARSHAL:
case STUBLESS_UNMARSHAL: case STUBLESS_UNMARSHAL:
case STUBLESS_INITOUT:
case STUBLESS_CALCSIZE: case STUBLESS_CALCSIZE:
case STUBLESS_MARSHAL:
case STUBLESS_FREE: case STUBLESS_FREE:
if (bV2Format) if (bV2Format)
retval_ptr = stub_do_args(&stubMsg, &pFormat[parameter_start_offset], retval_ptr = stub_do_args(&stubMsg, &pFormat[parameter_start_offset],