Zebediah Figura : rpcrt4: Fix ITypeInfo ref count handling.
Alexandre Julliard
julliard at winehq.org
Tue Dec 17 15:58:19 CST 2019
Module: wine
Branch: master
Commit: 53efccdb6589b2fbe8370d2216d1652bf53b984b
URL: https://source.winehq.org/git/wine.git/?a=commit;h=53efccdb6589b2fbe8370d2216d1652bf53b984b
Author: Zebediah Figura <z.figura12 at gmail.com>
Date: Mon Dec 16 15:49:17 2019 -0600
rpcrt4: Fix ITypeInfo ref count handling.
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/rpcrt4/ndr_typelib.c | 60 +++++++++++++++++++++++++++--------------------
1 file changed, 35 insertions(+), 25 deletions(-)
diff --git a/dlls/rpcrt4/ndr_typelib.c b/dlls/rpcrt4/ndr_typelib.c
index 5c48010030..dd3043e78b 100644
--- a/dlls/rpcrt4/ndr_typelib.c
+++ b/dlls/rpcrt4/ndr_typelib.c
@@ -1199,10 +1199,10 @@ err:
}
/* Common helper for Create{Proxy,Stub}FromTypeInfo(). */
-static HRESULT get_iface_info(ITypeInfo **typeinfo, WORD *funcs, WORD *parentfuncs,
- GUID *parentiid)
+static HRESULT get_iface_info(ITypeInfo *typeinfo, WORD *funcs, WORD *parentfuncs,
+ GUID *parentiid, ITypeInfo **real_typeinfo)
{
- ITypeInfo *real_typeinfo, *parentinfo;
+ ITypeInfo *parentinfo;
TYPEATTR *typeattr;
ITypeLib *typelib;
TLIBATTR *libattr;
@@ -1214,59 +1214,62 @@ static HRESULT get_iface_info(ITypeInfo **typeinfo, WORD *funcs, WORD *parentfun
/* Dual interfaces report their size to be sizeof(IDispatchVtbl) and their
* implemented type to be IDispatch. We need to retrieve the underlying
* interface to get that information. */
- hr = ITypeInfo_GetTypeAttr(*typeinfo, &typeattr);
+ hr = ITypeInfo_GetTypeAttr(typeinfo, &typeattr);
if (FAILED(hr))
return hr;
typekind = typeattr->typekind;
- ITypeInfo_ReleaseTypeAttr(*typeinfo, typeattr);
+ ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
if (typekind == TKIND_DISPATCH)
{
- hr = ITypeInfo_GetRefTypeOfImplType(*typeinfo, -1, &reftype);
+ hr = ITypeInfo_GetRefTypeOfImplType(typeinfo, -1, &reftype);
if (FAILED(hr))
return hr;
- hr = ITypeInfo_GetRefTypeInfo(*typeinfo, reftype, &real_typeinfo);
+ hr = ITypeInfo_GetRefTypeInfo(typeinfo, reftype, real_typeinfo);
if (FAILED(hr))
return hr;
-
- ITypeInfo_Release(*typeinfo);
- *typeinfo = real_typeinfo;
}
+ else
+ ITypeInfo_AddRef(*real_typeinfo = typeinfo);
- hr = ITypeInfo_GetContainingTypeLib(*typeinfo, &typelib, NULL);
+ hr = ITypeInfo_GetContainingTypeLib(*real_typeinfo, &typelib, NULL);
if (FAILED(hr))
- return hr;
+ goto err;
hr = ITypeLib_GetLibAttr(typelib, &libattr);
if (FAILED(hr))
{
ITypeLib_Release(typelib);
- return hr;
+ goto err;
}
syskind = libattr->syskind;
ITypeLib_ReleaseTLibAttr(typelib, libattr);
ITypeLib_Release(typelib);
- hr = ITypeInfo_GetTypeAttr(*typeinfo, &typeattr);
+ hr = ITypeInfo_GetTypeAttr(*real_typeinfo, &typeattr);
if (FAILED(hr))
- return hr;
+ goto err;
*funcs = typeattr->cFuncs;
*parentfuncs = typeattr->cbSizeVft / (syskind == SYS_WIN64 ? 8 : 4) - *funcs;
- ITypeInfo_ReleaseTypeAttr(*typeinfo, typeattr);
+ ITypeInfo_ReleaseTypeAttr(*real_typeinfo, typeattr);
- hr = ITypeInfo_GetRefTypeOfImplType(*typeinfo, 0, &reftype);
+ hr = ITypeInfo_GetRefTypeOfImplType(*real_typeinfo, 0, &reftype);
if (FAILED(hr))
- return hr;
- hr = ITypeInfo_GetRefTypeInfo(*typeinfo, reftype, &parentinfo);
+ goto err;
+ hr = ITypeInfo_GetRefTypeInfo(*real_typeinfo, reftype, &parentinfo);
if (FAILED(hr))
- return hr;
+ goto err;
hr = ITypeInfo_GetTypeAttr(parentinfo, &typeattr);
if (FAILED(hr))
- return hr;
+ goto err;
*parentiid = typeattr->guid;
ITypeInfo_ReleaseTypeAttr(parentinfo, typeattr);
ITypeInfo_Release(parentinfo);
+ return S_OK;
+
+err:
+ ITypeInfo_Release(*real_typeinfo);
return hr;
}
@@ -1355,19 +1358,21 @@ HRESULT WINAPI CreateProxyFromTypeInfo(ITypeInfo *typeinfo, IUnknown *outer,
{
struct typelib_proxy *proxy;
WORD funcs, parentfuncs, i;
+ ITypeInfo *real_typeinfo;
GUID parentiid;
HRESULT hr;
TRACE("typeinfo %p, outer %p, iid %s, proxy_buffer %p, out %p.\n",
typeinfo, outer, debugstr_guid(iid), proxy_buffer, out);
- hr = get_iface_info(&typeinfo, &funcs, &parentfuncs, &parentiid);
+ hr = get_iface_info(typeinfo, &funcs, &parentfuncs, &parentiid, &real_typeinfo);
if (FAILED(hr))
return hr;
if (!(proxy = heap_alloc_zero(sizeof(*proxy))))
{
ERR("Failed to allocate proxy object.\n");
+ ITypeInfo_Release(real_typeinfo);
return E_OUTOFMEMORY;
}
@@ -1379,6 +1384,7 @@ HRESULT WINAPI CreateProxyFromTypeInfo(ITypeInfo *typeinfo, IUnknown *outer,
{
ERR("Failed to allocate proxy vtbl.\n");
heap_free(proxy);
+ ITypeInfo_Release(real_typeinfo);
return E_OUTOFMEMORY;
}
proxy->proxy_vtbl->header.pStublessProxyInfo = &proxy->proxy_info;
@@ -1388,8 +1394,9 @@ HRESULT WINAPI CreateProxyFromTypeInfo(ITypeInfo *typeinfo, IUnknown *outer,
for (i = 0; i < funcs; i++)
proxy->proxy_vtbl->Vtbl[parentfuncs + i] = (void *)-1;
- hr = build_format_strings(typeinfo, funcs, parentfuncs, &proxy->stub_desc.pFormatTypes,
+ hr = build_format_strings(real_typeinfo, funcs, parentfuncs, &proxy->stub_desc.pFormatTypes,
&proxy->proxy_info.ProcFormatString, &proxy->offset_table);
+ ITypeInfo_Release(real_typeinfo);
if (FAILED(hr))
{
heap_free(proxy->proxy_vtbl);
@@ -1490,27 +1497,30 @@ HRESULT WINAPI CreateStubFromTypeInfo(ITypeInfo *typeinfo, REFIID iid,
{
WORD funcs, parentfuncs, i;
struct typelib_stub *stub;
+ ITypeInfo *real_typeinfo;
GUID parentiid;
HRESULT hr;
TRACE("typeinfo %p, iid %s, server %p, stub_buffer %p.\n",
typeinfo, debugstr_guid(iid), server, stub_buffer);
- hr = get_iface_info(&typeinfo, &funcs, &parentfuncs, &parentiid);
+ hr = get_iface_info(typeinfo, &funcs, &parentfuncs, &parentiid, &real_typeinfo);
if (FAILED(hr))
return hr;
if (!(stub = heap_alloc_zero(sizeof(*stub))))
{
ERR("Failed to allocate stub object.\n");
+ ITypeInfo_Release(real_typeinfo);
return E_OUTOFMEMORY;
}
init_stub_desc(&stub->stub_desc);
stub->server_info.pStubDesc = &stub->stub_desc;
- hr = build_format_strings(typeinfo, funcs, parentfuncs, &stub->stub_desc.pFormatTypes,
+ hr = build_format_strings(real_typeinfo, funcs, parentfuncs, &stub->stub_desc.pFormatTypes,
&stub->server_info.ProcString, &stub->offset_table);
+ ITypeInfo_Release(real_typeinfo);
if (FAILED(hr))
{
heap_free(stub);
More information about the wine-cvs
mailing list