Jacek Caban : oleaut32: Ensure that the right interface is passed to the callee in ITypeInfo:: Invoke.

Alexandre Julliard julliard at winehq.org
Mon Aug 20 14:16:19 CDT 2012


Module: wine
Branch: master
Commit: 44936abd8444f676a7d0e8fe415749146da73125
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=44936abd8444f676a7d0e8fe415749146da73125

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Aug 20 17:42:40 2012 +0200

oleaut32: Ensure that the right interface is passed to the callee in ITypeInfo::Invoke.

---

 dlls/oleaut32/tests/tmarshal.c |    1 -
 dlls/oleaut32/typelib.c        |   33 +++++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletions(-)

diff --git a/dlls/oleaut32/tests/tmarshal.c b/dlls/oleaut32/tests/tmarshal.c
index cb626d3..337e911 100644
--- a/dlls/oleaut32/tests/tmarshal.c
+++ b/dlls/oleaut32/tests/tmarshal.c
@@ -782,7 +782,6 @@ static HRESULT WINAPI StaticWidget_Invoke(IStaticWidget *iface, DISPID dispIdMem
 static HRESULT WINAPI StaticWidget_TestDual(IStaticWidget *iface, ItestDual *p)
 {
     trace("TestDual()\n");
-    todo_wine
     ok(p == &TestDual, "wrong ItestDual\n");
     return S_OK;
 }
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 3339c49..0fc7a6e 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -6357,6 +6357,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
             for (i = 0; i < func_desc->cParams; i++)
             {
                 USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
+                TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
                 VARIANTARG *src_arg;
 
                 if (wParamFlags & PARAMFLAG_FLCID)
@@ -6509,6 +6510,38 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                     {
                         prgpvarg[i] = src_arg;
                     }
+
+                    if((tdesc->vt == VT_USERDEFINED || (tdesc->vt == VT_PTR && tdesc->u.lptdesc->vt == VT_USERDEFINED))
+                       && (V_VT(prgpvarg[i]) == VT_DISPATCH || V_VT(prgpvarg[i]) == VT_UNKNOWN)) {
+                        const TYPEDESC *userdefined_tdesc = tdesc;
+                        IUnknown *userdefined_iface;
+                        ITypeInfo *tinfo2;
+                        TYPEATTR *tattr;
+
+                        if(tdesc->vt == VT_PTR)
+                            userdefined_tdesc = tdesc->u.lptdesc;
+
+                        hres = ITypeInfo2_GetRefTypeInfo(iface, userdefined_tdesc->u.hreftype, &tinfo2);
+                        if(FAILED(hres))
+                            break;
+
+                        hres = ITypeInfo_GetTypeAttr(tinfo2, &tattr);
+                        if(FAILED(hres)) {
+                            ITypeInfo_Release(tinfo2);
+                            return hres;
+                        }
+
+                        hres = IUnknown_QueryInterface(V_UNKNOWN(prgpvarg[i]), &tattr->guid, (void**)&userdefined_iface);
+                        ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
+                        ITypeInfo_Release(tinfo2);
+                        if(FAILED(hres)) {
+                            ERR("argument does not support %s interface\n", debugstr_guid(&tattr->guid));
+                            break;
+                        }
+
+                        IUnknown_Release(V_UNKNOWN(prgpvarg[i]));
+                        V_UNKNOWN(prgpvarg[i]) = userdefined_iface;
+                    }
                 }
                 else if (wParamFlags & PARAMFLAG_FOPT)
                 {




More information about the wine-cvs mailing list