Eric Kohl wrote:
> Robert Shearman wrote:
>
>>> case PASS_OUT:
>>> + if (in_attr && has_size && pointer_type == RPC_FC_UP &&
>>> phase == PHASE_FREE)
>>> + break;
>>> if (!out_attr)
>>> continue;
>>> break;
>>>
>>>
>>
>> I don't think this is correct. Firstly, it should continue, not
>> break. Secondly, I think it only doesn't need to free the string if
>> it has a size. I'm pretty sure it shouldn't depend on being a unique
>> string.
>>
>
> Robert,
> this is exactly what I want! WIDL must generate a call to
> NdrPointerFree for 'in', 'unique', sized pointers to strings. Other
> 'in' pointers don't need to be freed.
>
> Why? Because three different versions of MIDL do it this way.
>
Counter-example with the following IDL:
void ConformantString2Out([in] long size, [in, out, string,
size_is(size)] char **pszString);
void Test([in] long size, [in, out, size_is(size)] char **pszArray);
Both generate NdrPointerFree calls and I believe both are satisfied by
the test you introduced:
void __RPC_STUB
Tests_ConformantString2Out(
PRPC_MESSAGE _pRpcMessage )
{
MIDL_STUB_MESSAGE _StubMsg;
unsigned char **pszString;
long size;
RPC_STATUS _Status;
((void)(_Status));
NdrServerInitializeNew(
_pRpcMessage,
&_StubMsg,
&Tests_StubDesc);
size = 0;
( unsigned char ** )pszString = 0;
RpcTryFinally
{
RpcTryExcept
{
if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) !=
NDR_LOCAL_DATA_REPRESENTATION )
NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg,
(PFORMAT_STRING) &__MIDL_ProcFormatString.Format[44] );
_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer +
3) & ~ 0x3);
if(_StubMsg.Buffer + 4 > _StubMsg.BufferEnd)
{
RpcRaiseException(RPC_X_BAD_STUB_DATA);
}
size = *(( long * )_StubMsg.Buffer)++;
NdrConformantArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg,
(unsigned char * *)&pszString,
(PFORMAT_STRING)
&__MIDL_TypeFormatString.Format[44],
(unsigned char)0 );
if(_StubMsg.Buffer > _StubMsg.BufferEnd)
{
RpcRaiseException(RPC_X_BAD_STUB_DATA);
}
}
RpcExcept( RPC_BAD_STUB_DATA_EXCEPTION_FILTER )
{
RpcRaiseException(RPC_X_BAD_STUB_DATA);
}
RpcEndExcept
ConformantString2Out(size,pszString);
_StubMsg.BufferLength = 0;
_StubMsg.MaxCount = ( unsigned long )size;
NdrConformantArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg,
(unsigned char *)pszString,
(PFORMAT_STRING)
&__MIDL_TypeFormatString.Format[44] );
_pRpcMessage->BufferLength = _StubMsg.BufferLength;
_Status = I_RpcGetBuffer( _pRpcMessage );
if ( _Status )
RpcRaiseException( _Status );
_StubMsg.Buffer = (unsigned char *) _pRpcMessage->Buffer;
_StubMsg.MaxCount = ( unsigned long )size;
NdrConformantArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg,
(unsigned char *)pszString,
(PFORMAT_STRING)
&__MIDL_TypeFormatString.Format[44] );
}
RpcFinally
{
_StubMsg.MaxCount = ( unsigned long )size;
NdrPointerFree( &_StubMsg,
(unsigned char *)pszString,
&__MIDL_TypeFormatString.Format[40] );
}
RpcEndFinally
_pRpcMessage->BufferLength =
(unsigned int)(_StubMsg.Buffer - (unsigned char
*)_pRpcMessage->Buffer);
}
void __RPC_STUB
Tests_Test(
PRPC_MESSAGE _pRpcMessage )
{
MIDL_STUB_MESSAGE _StubMsg;
unsigned char **pszArray;
long size;
RPC_STATUS _Status;
((void)(_Status));
NdrServerInitializeNew(
_pRpcMessage,
&_StubMsg,
&Tests_StubDesc);
size = 0;
( unsigned char ** )pszArray = 0;
RpcTryFinally
{
RpcTryExcept
{
if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) !=
NDR_LOCAL_DATA_REPRESENTATION )
NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg,
(PFORMAT_STRING) &__MIDL_ProcFormatString.Format[52] );
_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer +
3) & ~ 0x3);
if(_StubMsg.Buffer + 4 > _StubMsg.BufferEnd)
{
RpcRaiseException(RPC_X_BAD_STUB_DATA);
}
size = *(( long * )_StubMsg.Buffer)++;
NdrConformantArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg,
(unsigned char * *)&pszArray,
(PFORMAT_STRING)
&__MIDL_TypeFormatString.Format[78],
(unsigned char)0 );
if(_StubMsg.Buffer > _StubMsg.BufferEnd)
{
RpcRaiseException(RPC_X_BAD_STUB_DATA);
}
}
RpcExcept( RPC_BAD_STUB_DATA_EXCEPTION_FILTER )
{
RpcRaiseException(RPC_X_BAD_STUB_DATA);
}
RpcEndExcept
Test(size,pszArray);
_StubMsg.BufferLength = 0;
_StubMsg.MaxCount = ( unsigned long )size;
NdrConformantArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg,
(unsigned char *)pszArray,
(PFORMAT_STRING)
&__MIDL_TypeFormatString.Format[78] );
_pRpcMessage->BufferLength = _StubMsg.BufferLength;
_Status = I_RpcGetBuffer( _pRpcMessage );
if ( _Status )
RpcRaiseException( _Status );
_StubMsg.Buffer = (unsigned char *) _pRpcMessage->Buffer;
_StubMsg.MaxCount = ( unsigned long )size;
NdrConformantArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg,
(unsigned char *)pszArray,
(PFORMAT_STRING)
&__MIDL_TypeFormatString.Format[78] );
}
RpcFinally
{
_StubMsg.MaxCount = ( unsigned long )size;
NdrPointerFree( &_StubMsg,
(unsigned char *)pszArray,
&__MIDL_TypeFormatString.Format[74] );
}
RpcEndFinally
_pRpcMessage->BufferLength =
(unsigned int)(_StubMsg.Buffer - (unsigned char
*)_pRpcMessage->Buffer);
}
--
Rob Shearman