On Thu, Nov 08, 2018 at 10:18:15PM -0600, Zebediah Figura wrote:
+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; + HRESULT hr = S_OK; + TYPEATTR *attr; + + 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); + break; + default: + FIXME("unhandled kind %#x\n", attr->typekind); + return E_NOTIMPL;
There's still a leak here and in a similar place later on. I've resent the set with a fix. Huw.