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);
}
Robert Shearman wrote:
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:
These example include arrays of strings which I have not tested yet and are not officially supported yet. I'll fix these later.
My focus is making the Wine-WIDL compatible with ReactOS-WIDL as quickly as possible. Additional features will be added or fixed later.
Regards, Eric