[PATCH 06/14] rpcrt4: Write parameter signatures into the procedure format string.

Huw Davies huw at codeweavers.com
Tue Nov 6 02:50:30 CST 2018


On Sat, Nov 03, 2018 at 06:07:18PM -0500, Zebediah Figura wrote:
> Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
> ---
>  dlls/rpcrt4/ndr_typelib.c | 256 +++++++++++++++++++++++++++++++++++++-
>  1 file changed, 255 insertions(+), 1 deletion(-)
> 
> diff --git a/dlls/rpcrt4/ndr_typelib.c b/dlls/rpcrt4/ndr_typelib.c
> index 51e198d711..ee4e551fcb 100644
> --- a/dlls/rpcrt4/ndr_typelib.c
> +++ b/dlls/rpcrt4/ndr_typelib.c
> @@ -35,6 +35,30 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);

> +static HRESULT get_param_pointer_info(ITypeInfo *typeinfo, TYPEDESC *tdesc, int is_in,
> +        int is_out, unsigned short *server_size, unsigned short *flags,
> +        unsigned char *basetype, TYPEDESC **tfs_tdesc)
> +{
> +    ITypeInfo *refinfo;
> +    TYPEATTR *attr;
> +    HRESULT hr;
> +
> +    switch (tdesc->vt)
> +    {
> +    case VT_UNKNOWN:
> +    case VT_DISPATCH:
> +        *flags |= MustFree;
> +        if (is_in && is_out)
> +            *server_size = sizeof(void *);
> +        break;
> +    case VT_PTR:
> +        *flags |= MustFree;
> +
> +        if (tdesc->lptdesc->vt == VT_USERDEFINED)
> +        {
> +            ITypeInfo_GetRefTypeInfo(typeinfo, tdesc->lptdesc->hreftype, &refinfo);
> +            ITypeInfo_GetTypeAttr(refinfo, &attr);
> +
> +            switch (attr->typekind)
> +            {
> +            case TKIND_INTERFACE:
> +            case TKIND_DISPATCH:
> +            case TKIND_COCLASS:
> +                if (is_in && is_out)
> +                    *server_size = sizeof(void *);
> +                break;
> +            default:
> +                *server_size = sizeof(void *);
> +            }
> +
> +            ITypeInfo_ReleaseTypeAttr(refinfo, attr);
> +            ITypeInfo_Release(refinfo);
> +        }
> +        else
> +            *server_size = sizeof(void *);
> +        break;
> +    case VT_CARRAY:
> +        *flags |= IsSimpleRef | MustFree;
> +        *server_size = type_memsize(typeinfo, tdesc);
> +        *tfs_tdesc = tdesc;
> +        break;
> +    case VT_USERDEFINED:
> +        ITypeInfo_GetRefTypeInfo(typeinfo, tdesc->hreftype, &refinfo);
> +        ITypeInfo_GetTypeAttr(refinfo, &attr);
> +
> +        switch (attr->typekind)
> +        {
> +        case TKIND_ENUM:
> +            *flags |= IsSimpleRef | IsBasetype;
> +            if (!is_in && is_out)
> +                *server_size = sizeof(void *);
> +            *basetype = FC_ENUM32;
> +            break;
> +        case TKIND_RECORD:
> +            *flags |= IsSimpleRef | MustFree;
> +            if (!is_in && is_out)
> +                *server_size = attr->cbSizeInstance;
> +            *tfs_tdesc = tdesc;
> +            break;
> +        case TKIND_INTERFACE:
> +        case TKIND_DISPATCH:
> +        case TKIND_COCLASS:
> +            *flags |= MustFree;
> +            break;
> +        case TKIND_ALIAS:
> +            hr = get_param_pointer_info(refinfo, &attr->tdescAlias, is_in,
> +                    is_out, server_size, flags, basetype, tfs_tdesc);
> +            if (FAILED(hr))
> +                return hr;

Leaking refinfo and attr.

> +            break;
> +        default:
> +            FIXME("unhandled kind %#x\n", attr->typekind);
> +            return E_NOTIMPL;

And here.

> +        }
> +
> +        ITypeInfo_ReleaseTypeAttr(refinfo, attr);
> +        ITypeInfo_Release(refinfo);
> +        break;
> +    default:
> +        *flags |= IsSimpleRef;
> +        *tfs_tdesc = tdesc;
> +        if (!is_in && is_out)
> +            *server_size = type_memsize(typeinfo, tdesc);
> +        if ((*basetype = get_base_type(tdesc->vt)))
> +            *flags |= IsBasetype;
> +        break;
> +    }
> +
> +    return S_OK;
> +}
> +
> +static HRESULT get_param_info(ITypeInfo *typeinfo, TYPEDESC *tdesc, int is_in,
> +        int is_out, unsigned short *server_size, unsigned short *flags,
> +        unsigned char *basetype, TYPEDESC **tfs_tdesc)
> +{
> +    ITypeInfo *refinfo;
> +    TYPEATTR *attr;
> +    HRESULT hr;
> +
> +    *server_size = 0;
> +    *flags = MustSize;
> +    *basetype = 0;
> +    *tfs_tdesc = tdesc;
> +
> +    TRACE("vt %u\n", tdesc->vt);
> +
> +    switch (tdesc->vt)
> +    {
> +    case VT_VARIANT:
> +#ifndef __i386__
> +        *flags |= IsSimpleRef | MustFree;
> +        break;
> +#endif
> +        /* otherwise fall through */
> +    case VT_BSTR:
> +    case VT_SAFEARRAY:
> +    case VT_CY:
> +        *flags |= IsByValue | MustFree;
> +        break;
> +    case VT_UNKNOWN:
> +    case VT_DISPATCH:
> +    case VT_CARRAY:
> +        *flags |= MustFree;
> +        break;
> +    case VT_PTR:
> +        return get_param_pointer_info(typeinfo, tdesc->lptdesc, is_in, is_out,
> +                server_size, flags, basetype, tfs_tdesc);
> +    case VT_USERDEFINED:
> +        ITypeInfo_GetRefTypeInfo(typeinfo, tdesc->hreftype, &refinfo);
> +        ITypeInfo_GetTypeAttr(refinfo, &attr);
> +
> +        switch (attr->typekind)
> +        {
> +        case TKIND_ENUM:
> +            *flags |= IsBasetype;
> +            *basetype = FC_ENUM32;
> +            break;
> +        case TKIND_RECORD:
> +#ifdef __i386__
> +            *flags |= IsByValue | MustFree;
> +#elif defined(__x86_64__)
> +            if (attr->cbSizeInstance <= 8)
> +                *flags |= IsByValue | MustFree;
> +            else
> +                *flags |= IsSimpleRef | MustFree;
> +#endif
> +            break;
> +        case TKIND_ALIAS:
> +            hr = get_param_info(refinfo, &attr->tdescAlias, is_in, is_out,
> +                    server_size, flags, basetype, tfs_tdesc);
> +            if (FAILED(hr))
> +                return hr;

And here.

> +            break;
> +        default:
> +            FIXME("unhandled kind %#x\n", attr->typekind);
> +            return E_NOTIMPL;

And here.

> +        }
> +
> +        ITypeInfo_ReleaseTypeAttr(refinfo, attr);
> +        ITypeInfo_Release(refinfo);
> +        break;
> +    default:
> +        if ((*basetype = get_base_type(tdesc->vt)))
> +            *flags |= IsBasetype;
> +        else
> +        {
> +            FIXME("unhandled type %u\n", tdesc->vt);
> +            return E_NOTIMPL;
> +        }
> +        break;
> +    }
> +
> +    return S_OK;
> +}
> +



More information about the wine-devel mailing list