mirror of
https://github.com/reactos/wine.git
synced 2024-11-26 05:00:30 +00:00
oleaut32: Fix the typelib marshaler when the vtbl has holes.
This commit is contained in:
parent
060c8daf7f
commit
ac5e9812fd
@ -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)
|
||||
{
|
||||
if(attr->wTypeFlags & TYPEFLAG_FDUAL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
else /* non-dual dispinterface */
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < attr->cImplTypes; i++)
|
||||
{
|
||||
HREFTYPE href;
|
||||
hres = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href);
|
||||
if(FAILED(hres))
|
||||
{
|
||||
ERR("Unable to get interface href from dual dispinterface\n");
|
||||
goto end;
|
||||
}
|
||||
hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2);
|
||||
if(FAILED(hres))
|
||||
{
|
||||
ERR("Unable to get interface from dual dispinterface\n");
|
||||
goto end;
|
||||
}
|
||||
hres = num_of_funcs(tinfo2, num);
|
||||
ITypeInfo_Release(tinfo2);
|
||||
}
|
||||
else
|
||||
{
|
||||
*num = attr->cbSizeVft / 4;
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user