Huw Davies : oleaut32: Fix the typelib marshaler when the vtbl has holes.
Alexandre Julliard
julliard at winehq.org
Thu Feb 24 11:43:25 CST 2011
Module: wine
Branch: master
Commit: ac5e9812fdb6929e0fc3c9f3805223dd6062da62
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ac5e9812fdb6929e0fc3c9f3805223dd6062da62
Author: Huw Davies <huw at codeweavers.com>
Date: Thu Feb 24 10:09:36 2011 +0000
oleaut32: Fix the typelib marshaler when the vtbl has holes.
---
dlls/oleaut32/tmarshal.c | 91 +++++++++++++++++++++++++++++++++-------------
1 files changed, 65 insertions(+), 26 deletions(-)
diff --git a/dlls/oleaut32/tmarshal.c b/dlls/oleaut32/tmarshal.c
index 6536bb4..42eaadd 100644
--- a/dlls/oleaut32/tmarshal.c
+++ b/dlls/oleaut32/tmarshal.c
@@ -323,48 +323,85 @@ _get_typeinfo_for_iid(REFIID riid, ITypeInfo**ti) {
}
/*
- * Determine the number of functions including all inherited functions.
+ * Determine the number of functions including all inherited functions
+ * and well as the size of the vtbl.
* Note for non-dual dispinterfaces we simply return the size of IDispatch.
*/
-static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int *num)
+static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int *num,
+ unsigned int *vtbl_size)
{
- HRESULT hres;
+ HRESULT hr;
TYPEATTR *attr;
ITypeInfo *tinfo2;
+ UINT inherited_funcs = 0, i;
*num = 0;
- hres = ITypeInfo_GetTypeAttr(tinfo, &attr);
- if (hres) {
- ERR("GetTypeAttr failed with %x\n",hres);
- return hres;
+ if(vtbl_size) *vtbl_size = 0;
+
+ hr = ITypeInfo_GetTypeAttr(tinfo, &attr);
+ if (hr)
+ {
+ ERR("GetTypeAttr failed with %x\n", hr);
+ return hr;
}
- if(attr->typekind == TKIND_DISPATCH && (attr->wTypeFlags & TYPEFLAG_FDUAL))
+ if(attr->typekind == TKIND_DISPATCH)
{
- HREFTYPE href;
- hres = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href);
- if(FAILED(hres))
+ if(attr->wTypeFlags & TYPEFLAG_FDUAL)
{
- ERR("Unable to get interface href from dual dispinterface\n");
- goto end;
+ HREFTYPE href;
+
+ ITypeInfo_ReleaseTypeAttr(tinfo, attr);
+ hr = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href);
+ if(FAILED(hr))
+ {
+ ERR("Unable to get interface href from dual dispinterface\n");
+ return hr;
+ }
+ hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
+ if(FAILED(hr))
+ {
+ ERR("Unable to get interface from dual dispinterface\n");
+ return hr;
+ }
+ hr = num_of_funcs(tinfo2, num, vtbl_size);
+ ITypeInfo_Release(tinfo2);
+ return hr;
}
- hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
- if(FAILED(hres))
+ else /* non-dual dispinterface */
{
- ERR("Unable to get interface from dual dispinterface\n");
- goto end;
+ /* These will be the size of IDispatchVtbl */
+ *num = attr->cbSizeVft / sizeof(void *);
+ if(vtbl_size) *vtbl_size = attr->cbSizeVft;
+ ITypeInfo_ReleaseTypeAttr(tinfo, attr);
+ return hr;
}
- hres = num_of_funcs(tinfo2, num);
- ITypeInfo_Release(tinfo2);
}
- else
+
+ for (i = 0; i < attr->cImplTypes; i++)
{
- *num = attr->cbSizeVft / 4;
+ HREFTYPE href;
+ ITypeInfo *pSubTypeInfo;
+ UINT sub_funcs;
+
+ hr = ITypeInfo_GetRefTypeOfImplType(tinfo, i, &href);
+ if (FAILED(hr)) goto end;
+ hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &pSubTypeInfo);
+ if (FAILED(hr)) goto end;
+
+ hr = num_of_funcs(pSubTypeInfo, &sub_funcs, NULL);
+ ITypeInfo_Release(pSubTypeInfo);
+
+ if(FAILED(hr)) goto end;
+ inherited_funcs += sub_funcs;
}
+ *num = inherited_funcs + attr->cFuncs;
+ if(vtbl_size) *vtbl_size = attr->cbSizeVft;
+
end:
ITypeInfo_ReleaseTypeAttr(tinfo, attr);
- return hres;
+ return hr;
}
#ifdef __i386__
@@ -1698,7 +1735,7 @@ static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num)
xasm->lret = 0xc2;
xasm->bytestopop = (nrofargs+2)*4; /* pop args, This, iMethod */
xasm->nop = 0x90;
- proxy->lpvtbl[num] = xasm;
+ proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm;
#else
FIXME("not implemented on non i386\n");
return E_FAIL;
@@ -1713,7 +1750,7 @@ PSFacBuf_CreateProxy(
{
HRESULT hres;
ITypeInfo *tinfo;
- unsigned int i, nroffuncs;
+ unsigned int i, nroffuncs, vtbl_size;
TMProxyImpl *proxy;
TYPEATTR *typeattr;
BOOL defer_to_dispatch = FALSE;
@@ -1725,7 +1762,9 @@ PSFacBuf_CreateProxy(
return hres;
}
- hres = num_of_funcs(tinfo, &nroffuncs);
+ hres = num_of_funcs(tinfo, &nroffuncs, &vtbl_size);
+ TRACE("Got %d funcs, vtbl size %d\n", nroffuncs, vtbl_size);
+
if (FAILED(hres)) {
ERR("Cannot get number of functions for typeinfo %s\n",debugstr_guid(riid));
ITypeInfo_Release(tinfo);
@@ -1756,7 +1795,7 @@ PSFacBuf_CreateProxy(
InitializeCriticalSection(&proxy->crit);
proxy->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TMProxyImpl.crit");
- proxy->lpvtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPBYTE)*nroffuncs);
+ proxy->lpvtbl = HeapAlloc(GetProcessHeap(), 0, vtbl_size);
/* if we derive from IDispatch then defer to its proxy for its methods */
hres = ITypeInfo_GetTypeAttr(tinfo, &typeattr);
More information about the wine-cvs
mailing list