[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