On Sat, Nov 03, 2018 at 06:07:18PM -0500, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura z.figura12@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;
+}