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