Zebediah Figura : rpcrt4: Improve struct type detection.
Alexandre Julliard
julliard at winehq.org
Mon Apr 1 16:32:03 CDT 2019
Module: wine
Branch: master
Commit: 583dca9d7231479774be92aca8a30da1d660246a
URL: https://source.winehq.org/git/wine.git/?a=commit;h=583dca9d7231479774be92aca8a30da1d660246a
Author: Zebediah Figura <z.figura12 at gmail.com>
Date: Sun Mar 31 23:31:17 2019 -0500
rpcrt4: Improve struct type detection.
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/rpcrt4/ndr_typelib.c | 92 ++++++++++++++++++++++++++++++++++++++---------
1 file changed, 75 insertions(+), 17 deletions(-)
diff --git a/dlls/rpcrt4/ndr_typelib.c b/dlls/rpcrt4/ndr_typelib.c
index c756682..8f87693 100644
--- a/dlls/rpcrt4/ndr_typelib.c
+++ b/dlls/rpcrt4/ndr_typelib.c
@@ -231,34 +231,92 @@ static BOOL type_pointer_is_iface(ITypeInfo *typeinfo, TYPEDESC *tdesc)
}
static unsigned char get_array_fc(ITypeInfo *typeinfo, TYPEDESC *desc);
+static unsigned char get_struct_fc(ITypeInfo *typeinfo, TYPEATTR *attr);
-static unsigned char get_struct_fc(ITypeInfo *typeinfo, TYPEATTR *attr)
+static unsigned char get_struct_member_fc(ITypeInfo *typeinfo, TYPEDESC *tdesc)
{
- unsigned char fc = FC_STRUCT;
- VARDESC *desc;
- VARTYPE vt;
- WORD i;
+ unsigned char fc;
+ ITypeInfo *refinfo;
+ TYPEATTR *attr;
- for (i = 0; i < attr->cVars; i++)
+ switch (tdesc->vt)
{
- ITypeInfo_GetVarDesc(typeinfo, i, &desc);
- vt = desc->elemdescVar.tdesc.vt;
+ case VT_BSTR:
+ case VT_SAFEARRAY:
+ return (sizeof(void *) == 4) ? FC_PSTRUCT : FC_BOGUS_STRUCT;
+ case VT_CY:
+ return FC_STRUCT;
+ case VT_UNKNOWN:
+ case VT_DISPATCH:
+ return FC_BOGUS_STRUCT;
+ case VT_CARRAY:
+ if (get_array_fc(typeinfo, &tdesc->lpadesc->tdescElem) == FC_BOGUS_ARRAY)
+ return FC_BOGUS_STRUCT;
+ return FC_STRUCT;
+ case VT_PTR:
+ if (type_pointer_is_iface(typeinfo, tdesc))
+ fc = FC_BOGUS_STRUCT;
+ else
+ fc = (sizeof(void *) == 4) ? FC_PSTRUCT : FC_BOGUS_STRUCT;
+ break;
+ case VT_USERDEFINED:
+ ITypeInfo_GetRefTypeInfo(typeinfo, tdesc->hreftype, &refinfo);
+ ITypeInfo_GetTypeAttr(refinfo, &attr);
- switch (vt)
+ switch (attr->typekind)
{
- case VT_CARRAY:
- if (get_array_fc(typeinfo, &desc->elemdescVar.tdesc.lpadesc->tdescElem) == FC_BOGUS_ARRAY)
- fc = FC_BOGUS_STRUCT;
+ case TKIND_ENUM:
+ fc = FC_STRUCT;
+ break;
+ case TKIND_RECORD:
+ fc = get_struct_fc(refinfo, attr);
+ break;
+ case TKIND_INTERFACE:
+ case TKIND_DISPATCH:
+ case TKIND_COCLASS:
+ fc = FC_BOGUS_STRUCT;
+ break;
+ case TKIND_ALIAS:
+ fc = get_struct_member_fc(refinfo, &attr->tdescAlias);
break;
default:
- if (!get_basetype(typeinfo, &desc->elemdescVar.tdesc))
- {
- FIXME("unhandled type %u\n", vt);
- fc = FC_BOGUS_STRUCT;
- }
+ FIXME("Unhandled kind %#x.\n", attr->typekind);
+ fc = FC_BOGUS_STRUCT;
break;
}
+ ITypeInfo_ReleaseTypeAttr(refinfo, attr);
+ ITypeInfo_Release(refinfo);
+ break;
+ default:
+ if (get_basetype(typeinfo, tdesc))
+ return FC_STRUCT;
+ else
+ {
+ FIXME("Unhandled type %u.\n", tdesc->vt);
+ return FC_BOGUS_STRUCT;
+ }
+ }
+
+ return fc;
+}
+
+static unsigned char get_struct_fc(ITypeInfo *typeinfo, TYPEATTR *attr)
+{
+ unsigned char fc = FC_STRUCT, member_fc;
+ VARDESC *desc;
+ WORD i;
+
+ for (i = 0; i < attr->cVars; i++)
+ {
+ ITypeInfo_GetVarDesc(typeinfo, i, &desc);
+
+ member_fc = get_struct_member_fc(typeinfo, &desc->elemdescVar.tdesc);
+ if (member_fc == FC_BOGUS_STRUCT)
+ fc = FC_BOGUS_STRUCT;
+ else if (member_fc == FC_PSTRUCT && fc != FC_BOGUS_STRUCT)
+ fc = FC_PSTRUCT;
+
ITypeInfo_ReleaseVarDesc(typeinfo, desc);
}
More information about the wine-cvs
mailing list