Zebediah Figura : rpcrt4: Retrieve the underlying interface for dual interfaces.

Alexandre Julliard julliard at winehq.org
Mon Nov 12 16:26:55 CST 2018


Module: wine
Branch: master
Commit: f6b1341aa2b505f1a1c516ec675f6667381db7c2
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=f6b1341aa2b505f1a1c516ec675f6667381db7c2

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Fri Nov  9 18:01:57 2018 -0600

rpcrt4: Retrieve the underlying interface for dual interfaces.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/rpcrt4/ndr_typelib.c | 37 +++++++++++++++++++++++++++++++------
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/dlls/rpcrt4/ndr_typelib.c b/dlls/rpcrt4/ndr_typelib.c
index f819026..31d9d40 100644
--- a/dlls/rpcrt4/ndr_typelib.c
+++ b/dlls/rpcrt4/ndr_typelib.c
@@ -792,15 +792,40 @@ err:
 }
 
 /* Common helper for Create{Proxy,Stub}FromTypeInfo(). */
-static HRESULT get_iface_info(ITypeInfo *typeinfo, WORD *funcs, WORD *parentfuncs)
+static HRESULT get_iface_info(ITypeInfo **typeinfo, WORD *funcs, WORD *parentfuncs)
 {
+    ITypeInfo *real_typeinfo;
     TYPEATTR *typeattr;
     ITypeLib *typelib;
     TLIBATTR *libattr;
+    TYPEKIND typekind;
+    HREFTYPE reftype;
     SYSKIND syskind;
     HRESULT hr;
 
-    hr = ITypeInfo_GetContainingTypeLib(typeinfo, &typelib, NULL);
+    /* 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);
+    if (FAILED(hr))
+        return hr;
+    typekind = typeattr->typekind;
+    ITypeInfo_ReleaseTypeAttr(*typeinfo, typeattr);
+    if (typekind == TKIND_DISPATCH)
+    {
+        hr = ITypeInfo_GetRefTypeOfImplType(*typeinfo, -1, &reftype);
+        if (FAILED(hr))
+            return hr;
+
+        hr = ITypeInfo_GetRefTypeInfo(*typeinfo, reftype, &real_typeinfo);
+        if (FAILED(hr))
+            return hr;
+
+        ITypeInfo_Release(*typeinfo);
+        *typeinfo = real_typeinfo;
+    }
+
+    hr = ITypeInfo_GetContainingTypeLib(*typeinfo, &typelib, NULL);
     if (FAILED(hr))
         return hr;
 
@@ -814,12 +839,12 @@ static HRESULT get_iface_info(ITypeInfo *typeinfo, WORD *funcs, WORD *parentfunc
     ITypeLib_ReleaseTLibAttr(typelib, libattr);
     ITypeLib_Release(typelib);
 
-    hr = ITypeInfo_GetTypeAttr(typeinfo, &typeattr);
+    hr = ITypeInfo_GetTypeAttr(*typeinfo, &typeattr);
     if (FAILED(hr))
         return hr;
     *funcs = typeattr->cFuncs;
     *parentfuncs = typeattr->cbSizeVft / (syskind == SYS_WIN64 ? 8 : 4) - *funcs;
-    ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
+    ITypeInfo_ReleaseTypeAttr(*typeinfo, typeattr);
 
     return S_OK;
 }
@@ -903,7 +928,7 @@ HRESULT WINAPI CreateProxyFromTypeInfo(ITypeInfo *typeinfo, IUnknown *outer,
     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);
+    hr = get_iface_info(&typeinfo, &funcs, &parentfuncs);
     if (FAILED(hr))
         return hr;
 
@@ -1016,7 +1041,7 @@ HRESULT WINAPI CreateStubFromTypeInfo(ITypeInfo *typeinfo, REFIID iid,
     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);
+    hr = get_iface_info(&typeinfo, &funcs, &parentfuncs);
     if (FAILED(hr))
         return hr;
 




More information about the wine-cvs mailing list