Huw Davies : oleaut32: Rewrite get_funcdesc to avoid using the funcdesc' s oVft member so that it works correctly for non-dual dispinterfaces.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Apr 26 10:23:59 CDT 2007


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

Author: Huw Davies <huw at codeweavers.com>
Date:   Thu Apr 26 11:56:44 2007 +0100

oleaut32: Rewrite get_funcdesc to avoid using the funcdesc's oVft member so that it works correctly for non-dual dispinterfaces.

---

 dlls/oleaut32/tmarshal.c |  109 ++++++++++++++++++++++++----------------------
 1 files changed, 57 insertions(+), 52 deletions(-)

diff --git a/dlls/oleaut32/tmarshal.c b/dlls/oleaut32/tmarshal.c
index 46faf62..7d0637e 100644
--- a/dlls/oleaut32/tmarshal.c
+++ b/dlls/oleaut32/tmarshal.c
@@ -1198,63 +1198,68 @@ deserialize_param(
     }
 }
 
-/* Searches function, also in inherited interfaces */
-static HRESULT
-_get_funcdesc(
-    ITypeInfo *tinfo, int iMethod, ITypeInfo **tactual, const FUNCDESC **fdesc, BSTR *iname, BSTR *fname)
+/* Retrieves a function's funcdesc, searching back into inherited interfaces. */
+static HRESULT get_funcdesc(ITypeInfo *tinfo, int iMethod, ITypeInfo **tactual, const FUNCDESC **fdesc,
+                            BSTR *iname, BSTR *fname, UINT *num)
 {
-    int i = 0, j = 0;
-    HRESULT hres;
+    HRESULT hr;
+    UINT i, impl_types;
+    UINT inherited_funcs = 0;
+    TYPEATTR *attr;
 
     if (fname) *fname = NULL;
     if (iname) *iname = NULL;
+    if (num) *num = 0;
+    *tactual = NULL;
 
-    while (1) {
-	hres = ITypeInfoImpl_GetInternalFuncDesc(tinfo, i, fdesc);
+    hr = ITypeInfo_GetTypeAttr(tinfo, &attr);
+    if (FAILED(hr))
+    {
+        ERR("GetTypeAttr failed with %x\n",hr);
+        return hr;
+    }
+    impl_types = attr->cImplTypes;
+    ITypeInfo_ReleaseTypeAttr(tinfo, attr);
 
-	if (hres) {
-	    ITypeInfo	*tinfo2;
-	    HREFTYPE	href;
-	    TYPEATTR	*attr;
+    for (i = 0; i < impl_types; i++)
+    {
+        HREFTYPE href;
+        ITypeInfo *pSubTypeInfo;
+        UINT sub_funcs;
 
-	    hres = ITypeInfo_GetTypeAttr(tinfo, &attr);
-	    if (hres) {
-		ERR("GetTypeAttr failed with %x\n",hres);
-		return hres;
-	    }
-	    /* Not found, so look in inherited ifaces. */
-	    for (j=0;j<attr->cImplTypes;j++) {
-		hres = ITypeInfo_GetRefTypeOfImplType(tinfo, j, &href);
-		if (hres) {
-		    ERR("Did not find a reftype for interface offset %d?\n",j);
-		    break;
-		}
-		hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
-		if (hres) {
-		    ERR("Did not find a typeinfo for reftype %d?\n",href);
-		    continue;
-		}
-		hres = _get_funcdesc(tinfo2,iMethod,tactual,fdesc,iname,fname);
-		ITypeInfo_Release(tinfo2);
-		if (!hres) {
-		    ITypeInfo_ReleaseTypeAttr(tinfo, attr);
-		    return S_OK;
-                }
-	    }
-	    ITypeInfo_ReleaseTypeAttr(tinfo, attr);
-	    return hres;
-	}
-	if (((*fdesc)->oVft/4) == iMethod) {
-	    if (fname)
-		ITypeInfo_GetDocumentation(tinfo,(*fdesc)->memid,fname,NULL,NULL,NULL);
-	    if (iname)
-		ITypeInfo_GetDocumentation(tinfo,-1,iname,NULL,NULL,NULL);
-	    *tactual = tinfo;
-	    ITypeInfo_AddRef(*tactual);
-	    return S_OK;
-	}
-	i++;
+        hr = ITypeInfo_GetRefTypeOfImplType(tinfo, i, &href);
+        if (FAILED(hr)) return hr;
+        hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &pSubTypeInfo);
+        if (FAILED(hr)) return hr;
+
+        hr = get_funcdesc(pSubTypeInfo, iMethod, tactual, fdesc, iname, fname, &sub_funcs);
+        inherited_funcs += sub_funcs;
+        ITypeInfo_Release(pSubTypeInfo);
+        if(SUCCEEDED(hr)) return hr;
     }
+    if(iMethod < inherited_funcs)
+    {
+        ERR("shouldn't be here\n");
+        return E_INVALIDARG;
+    }
+
+    for(i = inherited_funcs; i <= iMethod; i++)
+    {
+        hr = ITypeInfoImpl_GetInternalFuncDesc(tinfo, i - inherited_funcs, fdesc);
+        if(FAILED(hr))
+        {
+            if(num) *num = i;
+            return hr;
+        }
+    }
+
+    /* found it. We don't care about num so zero it */
+    if(num) *num = 0;
+    *tactual = tinfo;
+    ITypeInfo_AddRef(*tactual);
+    if (fname) ITypeInfo_GetDocumentation(tinfo,(*fdesc)->memid,fname,NULL,NULL,NULL);
+    if (iname) ITypeInfo_GetDocumentation(tinfo,-1,iname,NULL,NULL,NULL);
+    return S_OK;
 }
 
 static inline BOOL is_in_elem(const ELEMDESC *elem)
@@ -1286,7 +1291,7 @@ xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
 
     EnterCriticalSection(&tpinfo->crit);
 
-    hres = _get_funcdesc(tpinfo->tinfo,method,&tinfo,&fdesc,&iname,&fname);
+    hres = get_funcdesc(tpinfo->tinfo,method,&tinfo,&fdesc,&iname,&fname,NULL);
     if (hres) {
         ERR("Did not find typeinfo/funcdesc entry for method %d!\n",method);
         LeaveCriticalSection(&tpinfo->crit);
@@ -1700,7 +1705,7 @@ PSFacBuf_CreateProxy(
 		/* nrofargs without This */
 		int nrofargs;
                 ITypeInfo *tinfo2;
-		hres = _get_funcdesc(tinfo,i,&tinfo2,&fdesc,NULL,NULL);
+		hres = get_funcdesc(tinfo,i,&tinfo2,&fdesc,NULL,NULL,NULL);
 		if (hres) {
 		    ERR("GetFuncDesc %x should not fail here.\n",hres);
 		    return hres;
@@ -1916,7 +1921,7 @@ TMStubImpl_Invoke(
     memcpy(buf.base, xmsg->Buffer, xmsg->cbBuffer);
     buf.curoff	= 0;
 
-    hres = _get_funcdesc(This->tinfo,xmsg->iMethod,&tinfo,&fdesc,&iname,NULL);
+    hres = get_funcdesc(This->tinfo,xmsg->iMethod,&tinfo,&fdesc,&iname,NULL,NULL);
     if (hres) {
 	ERR("GetFuncDesc on method %d failed with %x\n",xmsg->iMethod,hres);
 	return hres;




More information about the wine-cvs mailing list