Re: [WIDL] Implement support for unique strings
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
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
participants (2)
-
Eric Kohl -
Robert Shearman