[WIDL] Implement support for unique strings

Robert Shearman rob at codeweavers.com
Fri Mar 31 04:47:55 CST 2006


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




More information about the wine-devel mailing list