Zebediah Figura : rpcrt4: Handle bare interfaces as top-level parameters.

Alexandre Julliard julliard at winehq.org
Thu Mar 19 16:27:47 CDT 2020


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

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Wed Mar 18 23:52:29 2020 -0500

rpcrt4: Handle bare interfaces as top-level parameters.

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

---

 dlls/oleaut32/tests/tmarshal.c   | 22 ++++++++++++++++++++++
 dlls/oleaut32/tests/tmarshal.idl |  4 ++++
 dlls/rpcrt4/ndr_typelib.c        | 11 +++++++++++
 3 files changed, 37 insertions(+)

diff --git a/dlls/oleaut32/tests/tmarshal.c b/dlls/oleaut32/tests/tmarshal.c
index 8710645c61..18e4b1b180 100644
--- a/dlls/oleaut32/tests/tmarshal.c
+++ b/dlls/oleaut32/tests/tmarshal.c
@@ -1291,6 +1291,12 @@ static HRESULT WINAPI Widget_iface_ptr(IWidget *iface, ISomethingFromDispatch **
     return S_OK;
 }
 
+static HRESULT WINAPI Widget_iface_noptr(IWidget *iface, IUnknown unk, IDispatch disp, ISomethingFromDispatch sfd)
+{
+    check_iface_marshal((IUnknown *)unk.lpVtbl, (IDispatch *)disp.lpVtbl, (ISomethingFromDispatch *)sfd.lpVtbl);
+    return S_OK;
+}
+
 static HRESULT WINAPI Widget_bstr(IWidget *iface, BSTR in, BSTR *out, BSTR *in_ptr, BSTR *in_out)
 {
     UINT len;
@@ -1623,6 +1629,7 @@ static const struct IWidgetVtbl Widget_VTable =
     Widget_iface_in,
     Widget_iface_out,
     Widget_iface_ptr,
+    Widget_iface_noptr,
     Widget_bstr,
     Widget_variant,
     Widget_safearray,
@@ -2169,6 +2176,9 @@ static void test_marshal_iface(IWidget *widget, IDispatch *disp)
     ISomethingFromDispatch *sfd1, *sfd2, *sfd3, *proxy_sfd, *sfd_in, *sfd_out, *sfd_in_out;
     IUnknown *proxy_unk, *proxy_unk2, *unk_in, *unk_out, *unk_in_out;
     IDispatch *proxy_disp;
+    IUnknown unk_noptr;
+    IDispatch disp_noptr;
+    ISomethingFromDispatch sfd_noptr;
     HRESULT hr;
 
     testmode = 0;
@@ -2251,6 +2261,18 @@ static void test_marshal_iface(IWidget *widget, IDispatch *disp)
     ok(!sfd_in_out, "Got [in, out] %p.\n", sfd_in_out);
     release_iface(sfd3);
 
+    sfd1 = create_disp_obj();
+    sfd2 = create_disp_obj();
+    sfd3 = create_disp_obj();
+    unk_noptr.lpVtbl = (IUnknownVtbl *)sfd1;
+    disp_noptr.lpVtbl = (IDispatchVtbl *)sfd2;
+    sfd_noptr.lpVtbl = (ISomethingFromDispatchVtbl *)sfd3;
+    hr = IWidget_iface_noptr(widget, unk_noptr, disp_noptr, sfd_noptr);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    release_iface(sfd1);
+    release_iface(sfd2);
+    release_iface(sfd3);
+
     /* Test with Invoke(). Note that since we pass VT_UNKNOWN, we don't get our
      * interface back, but rather an IUnknown. */
 
diff --git a/dlls/oleaut32/tests/tmarshal.idl b/dlls/oleaut32/tests/tmarshal.idl
index f1e040ed4d..1344aa4912 100644
--- a/dlls/oleaut32/tests/tmarshal.idl
+++ b/dlls/oleaut32/tests/tmarshal.idl
@@ -58,6 +58,7 @@ enum IWidget_dispids
     DISPID_TM_IFACE_IN,
     DISPID_TM_IFACE_OUT,
     DISPID_TM_IFACE_PTR,
+    DISPID_TM_IFACE_NOPTR,
     DISPID_TM_BSTR,
     DISPID_TM_VARIANT,
     DISPID_TM_SAFEARRAY,
@@ -312,6 +313,9 @@ library TestTypelib
         [id(DISPID_TM_IFACE_PTR)]
         HRESULT iface_ptr([in] ISomethingFromDispatch **in, [out] ISomethingFromDispatch **out, [in, out] ISomethingFromDispatch **in_out);
 
+        [id(DISPID_TM_IFACE_NOPTR)]
+        HRESULT iface_noptr([in] IUnknown unk, [in] IDispatch disp, [in] ISomethingFromDispatch sfd);
+
         [id(DISPID_TM_BSTR)]
         HRESULT bstr([in] BSTR in, [out] BSTR *out, [in] BSTR *in_ptr, [in, out] BSTR *in_out);
 
diff --git a/dlls/rpcrt4/ndr_typelib.c b/dlls/rpcrt4/ndr_typelib.c
index c90c60c7b8..462b235d33 100644
--- a/dlls/rpcrt4/ndr_typelib.c
+++ b/dlls/rpcrt4/ndr_typelib.c
@@ -810,6 +810,10 @@ static size_t write_type_tfs(ITypeInfo *typeinfo, unsigned char *str,
             break;
         case TKIND_INTERFACE:
         case TKIND_DISPATCH:
+            /* These are treated as if they were interface pointers. */
+            off = *len;
+            write_ip_tfs(str, len, &attr->guid);
+            break;
         case TKIND_COCLASS:
             assert(0);
             break;
@@ -1000,6 +1004,13 @@ static HRESULT get_param_info(ITypeInfo *typeinfo, TYPEDESC *tdesc, int is_in,
             hr = get_param_info(refinfo, &attr->tdescAlias, is_in, is_out,
                     server_size, flags, basetype, tfs_tdesc);
             break;
+
+        case TKIND_INTERFACE:
+        case TKIND_DISPATCH:
+            /* These are treated as if they were interface pointers. */
+            *flags |= MustFree;
+            break;
+
         default:
             FIXME("unhandled kind %#x\n", attr->typekind);
             hr = E_NOTIMPL;




More information about the wine-cvs mailing list