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