Jacek Caban : oleaut32: Fix handling dual interfaces in ITypeInfo::GetRefTypeInfo.

Alexandre Julliard julliard at winehq.org
Thu Mar 26 16:27:26 CDT 2020


Module: wine
Branch: master
Commit: 8fac69ba50d957599869d6a62355efaf0f68f182
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=8fac69ba50d957599869d6a62355efaf0f68f182

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Mar 26 20:54:17 2020 +0100

oleaut32: Fix handling dual interfaces in ITypeInfo::GetRefTypeInfo.

Based on patch by Puetz Kevin.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/oleaut32/tests/tmarshal.idl | 23 ++++++++++++++++
 dlls/oleaut32/tests/typelib.c    | 58 +++++++++++++++++++++++++++++++++++++--
 dlls/oleaut32/typelib.c          | 59 ++++++++++++++++++++++++----------------
 3 files changed, 114 insertions(+), 26 deletions(-)

diff --git a/dlls/oleaut32/tests/tmarshal.idl b/dlls/oleaut32/tests/tmarshal.idl
index 9182def313..a594f9137d 100644
--- a/dlls/oleaut32/tests/tmarshal.idl
+++ b/dlls/oleaut32/tests/tmarshal.idl
@@ -582,4 +582,27 @@ cpp_quote("struct Coclass3 { ICoclass1 *iface; };")
         interface ItestIF7;
     }
 
+    [
+        object,
+        uuid(ec236d8e-2cc7-44f2-b394-46c86ff3da74),
+        dual,
+        oleautomation
+    ]
+    interface ItestIF12 : IDispatch
+    {
+        [id(0x1234)] HRESULT fn4([in] int a);
+        [id(0x1235)] HRESULT fn5([in] int a);
+    }
+
+    [
+        object,
+        uuid(f711b105-554d-4751-818c-56fcc5d7c0d5),
+        dual,
+        oleautomation
+    ]
+    interface ItestIF13 : ItestIF12
+    {
+        [id(0x1236)] HRESULT fn6([in] GUID a);
+    }
+
 };
diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c
index 75f8d78f07..5e5b44a034 100644
--- a/dlls/oleaut32/tests/typelib.c
+++ b/dlls/oleaut32/tests/typelib.c
@@ -1577,7 +1577,7 @@ static void test_inheritance(void)
 {
     HRESULT hr;
     ITypeLib *pTL;
-    ITypeInfo *pTI, *pTI_p;
+    ITypeInfo *pTI, *pTI_p, *dual_ti;
     TYPEATTR *pTA;
     HREFTYPE href;
     FUNCDESC *pFD;
@@ -1720,7 +1720,7 @@ static void test_inheritance(void)
     hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
     ok(hr == S_OK, "hr %08x\n", hr);
     ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
-    ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
+    ok(pTA->cbSizeVft == sizeof(IDispatchVtbl), "sizevft %d\n", pTA->cbSizeVft);
     ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags);
     ok(pTA->cFuncs == 3, "cfuncs %d\n", pTA->cFuncs);
     ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
@@ -1815,6 +1815,60 @@ static void test_inheritance(void)
     ITypeInfo_ReleaseFuncDesc(pTI, pFD);
     ITypeInfo_Release(pTI);
 
+    /* ItestIF13 is dual with inherited dual ifaces */
+    hr = ITypeLib_GetTypeInfoOfGuid(pTL, &IID_ItestIF13, &pTI);
+    ok(hr == S_OK, "hr %08x\n", hr);
+
+    hr = ITypeInfo_GetTypeAttr(pTI, &pTA);
+    ok(hr == S_OK, "hr %08x\n", hr);
+    ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind);
+    ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft);
+    ok(pTA->wTypeFlags == (TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL), "typeflags %x\n", pTA->wTypeFlags);
+    ok(pTA->cFuncs == 10, "cfuncs %d\n", pTA->cFuncs);
+    ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
+    ITypeInfo_ReleaseTypeAttr(pTI, pTA);
+
+    hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href);
+    ok(hr == S_OK, "hr %08x\n", hr);
+    hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p);
+    ok(hr == S_OK, "hr %08x\n", hr);
+    hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid %s\n", wine_dbgstr_guid(&pTA->guid));
+    ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
+
+    hr = ITypeInfo_GetFuncDesc(pTI, 9, &pFD);
+    ok(hr == S_OK, "hr %08x\n", hr);
+    ok(pFD->memid == 0x1236, "memid %08x\n", pFD->memid);
+    ITypeInfo_ReleaseFuncDesc(pTI, pFD);
+
+    hr = ITypeInfo_GetRefTypeInfo(pTI, -2, &dual_ti);
+    ok(hr == S_OK, "hr %08x\n", hr);
+
+    hr = ITypeInfo_GetTypeAttr(dual_ti, &pTA);
+    ok(hr == S_OK, "hr %08x\n", hr);
+    ok(pTA->typekind == TKIND_INTERFACE, "kind %04x\n", pTA->typekind);
+    ok(pTA->cbSizeVft == sizeof(ItestIF13Vtbl), "sizevft %d\n", pTA->cbSizeVft);
+    ok(pTA->wTypeFlags == (TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FOLEAUTOMATION|TYPEFLAG_FDUAL), "typeflags %x\n", pTA->wTypeFlags);
+    ok(pTA->cFuncs == 1, "cfuncs %d\n", pTA->cFuncs);
+    ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes);
+    ITypeInfo_ReleaseTypeAttr(dual_ti, pTA);
+
+    hr = ITypeInfo_GetRefTypeOfImplType(dual_ti, 0, &href);
+    ok(hr == S_OK, "hr %08x\n", hr);
+    hr = ITypeInfo_GetRefTypeInfo(dual_ti, href, &pTI_p);
+    ok(hr == S_OK, "hr %08x\n", hr);
+    hr = ITypeInfo_GetTypeAttr(pTI_p, &pTA);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(pTA->typekind == TKIND_INTERFACE, "kind %04x\n", pTA->typekind);
+    ok(pTA->cbSizeVft == sizeof(ItestIF12Vtbl), "sizevft %d\n", pTA->cbSizeVft);
+    ok(IsEqualGUID(&pTA->guid, &IID_ItestIF12), "guid %s\n", wine_dbgstr_guid(&pTA->guid));
+    ITypeInfo_ReleaseTypeAttr(pTI_p, pTA);
+    ITypeInfo_Release(pTI_p);
+
+    ITypeInfo_Release(dual_ti);
+    ITypeInfo_Release(pTI);
+
     ITypeLib_Release(pTL);
 
     return;
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 68c31e1d88..f8d7136834 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -7911,7 +7911,10 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
 	ITypeInfo  **ppTInfo)
 {
     ITypeInfoImpl *This = impl_from_ITypeInfo2(iface);
+    ITypeInfo *type_info = NULL;
     HRESULT result = E_FAIL;
+    TLBRefType *ref_type;
+    UINT i;
 
     if(!ppTInfo)
         return E_INVALIDARG;
@@ -7944,32 +7947,32 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
          * refcount goes to zero, but we need to signal to the new instance to
          * not free its data structures when it is destroyed */
         pTypeInfoImpl->not_attached_to_typelib = TRUE;
-
         ITypeInfo_AddRef(*ppTInfo);
 
-        result = S_OK;
-    } else if ((hRefType & DISPATCH_HREF_MASK) &&
-        (This->typeattr.typekind == TKIND_DISPATCH))
-    {
-        HREFTYPE href_dispatch = hRefType;
-        result = ITypeInfoImpl_GetDispatchRefTypeInfo((ITypeInfo *)iface, &href_dispatch, ppTInfo);
-    } else {
-        TLBRefType *ref_type;
-        ITypeLib *pTLib = NULL;
-        UINT i;
+        TRACE("got dual interface %p\n", *ppTInfo);
+        return S_OK;
+    }
 
-        if(!(hRefType & 0x1)){
-            for(i = 0; i < This->pTypeLib->TypeInfoCount; ++i)
+    if ((hRefType & DISPATCH_HREF_MASK) && (This->typeattr.typekind == TKIND_DISPATCH))
+        return ITypeInfoImpl_GetDispatchRefTypeInfo((ITypeInfo *)iface, &hRefType, ppTInfo);
+
+    if(!(hRefType & 0x1))
+    {
+        for(i = 0; i < This->pTypeLib->TypeInfoCount; ++i)
+        {
+            if (This->pTypeLib->typeinfos[i]->hreftype == (hRefType&(~0x3)))
             {
-                if (This->pTypeLib->typeinfos[i]->hreftype == (hRefType&(~0x3)))
-                {
-                    result = S_OK;
-                    *ppTInfo = (ITypeInfo*)&This->pTypeLib->typeinfos[i]->ITypeInfo2_iface;
-                    ITypeInfo_AddRef(*ppTInfo);
-                    goto end;
-                }
+                result = S_OK;
+                type_info = (ITypeInfo*)&This->pTypeLib->typeinfos[i]->ITypeInfo2_iface;
+                ITypeInfo_AddRef(type_info);
+                break;
             }
         }
+    }
+
+    if (!type_info)
+    {
+        ITypeLib *pTLib = NULL;
 
         LIST_FOR_EACH_ENTRY(ref_type, &This->pTypeLib->ref_list, TLBRefType, entry)
         {
@@ -7979,7 +7982,7 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
         if(&ref_type->entry == &This->pTypeLib->ref_list)
         {
             FIXME("Can't find pRefType for ref %x\n", hRefType);
-            goto end;
+            return E_FAIL;
         }
 
         if(ref_type->pImpTLInfo == TLB_REF_INTERNAL) {
@@ -8057,15 +8060,23 @@ static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
         }
         if(SUCCEEDED(result)) {
             if(ref_type->index == TLB_REF_USE_GUID)
-                result = ITypeLib_GetTypeInfoOfGuid(pTLib, TLB_get_guid_null(ref_type->guid), ppTInfo);
+                result = ITypeLib_GetTypeInfoOfGuid(pTLib, TLB_get_guid_null(ref_type->guid), &type_info);
             else
-                result = ITypeLib_GetTypeInfo(pTLib, ref_type->index, ppTInfo);
+                result = ITypeLib_GetTypeInfo(pTLib, ref_type->index, &type_info);
         }
         if (pTLib != NULL)
             ITypeLib_Release(pTLib);
+        if (FAILED(result))
+        {
+            WARN("(%p) failed hreftype 0x%04x\n", This, hRefType);
+            return result;
+        }
     }
 
-end:
+    if ((hRefType & 0x2) && SUCCEEDED(ITypeInfo_GetRefTypeInfo(type_info, -2, ppTInfo)))
+        ITypeInfo_Release(type_info);
+    else *ppTInfo = type_info;
+
     TRACE("(%p) hreftype 0x%04x loaded %s (%p)\n", This, hRefType,
           SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
     return result;




More information about the wine-cvs mailing list