[PATCH 2/2] rpcrt4: Handle bare coclasses as top-level parameters.

Zebediah Figura z.figura12 at gmail.com
Wed Mar 18 23:52:30 CDT 2020


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/oleaut32/tests/tmarshal.c   | 32 ++++++++++++++++++++++++++++++++
 dlls/oleaut32/tests/tmarshal.idl |  8 ++++++++
 dlls/rpcrt4/ndr_typelib.c        |  6 +++++-
 3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/dlls/oleaut32/tests/tmarshal.c b/dlls/oleaut32/tests/tmarshal.c
index 18e4b1b180..4e9a8baeca 100644
--- a/dlls/oleaut32/tests/tmarshal.c
+++ b/dlls/oleaut32/tests/tmarshal.c
@@ -1577,6 +1577,22 @@ static HRESULT WINAPI Widget_Coclass_ptr(IWidget *iface, Coclass1 **in, Coclass1
     return S_OK;
 }
 
+static HRESULT WINAPI Widget_Coclass_noptr(IWidget *iface, Coclass1 class1, Coclass2 class2, Coclass3 class3)
+{
+    HRESULT hr;
+
+    hr = ICoclass1_test(class1.iface);
+    ok(hr == 1, "Got hr %#x.\n", hr);
+
+    hr = ICoclass2_test(class2.iface);
+    ok(hr == 2, "Got hr %#x.\n", hr);
+
+    hr = ICoclass1_test(class3.iface);
+    ok(hr == 1, "Got hr %#x.\n", hr);
+
+    return S_OK;
+}
+
 static HRESULT WINAPI Widget_no_in_out(IWidget *iface, BSTR str, int i)
 {
     ok(SysStringLen(str) == 4, "unexpected len\n");
@@ -1644,6 +1660,7 @@ static const struct IWidgetVtbl Widget_VTable =
     Widget_myint,
     Widget_Coclass,
     Widget_Coclass_ptr,
+    Widget_Coclass_noptr,
     Widget_no_in_out,
 };
 
@@ -2671,6 +2688,9 @@ static void test_marshal_coclass(IWidget *widget, IDispatch *disp)
     struct coclass_obj *class1, *class2, *class3;
     IUnknown *unk_in, *unk_out, *unk_in_out;
     ICoclass1 *in, *out, *in_out;
+    Coclass1 class1_noptr;
+    Coclass2 class2_noptr;
+    Coclass3 class3_noptr;
     HRESULT hr;
 
     class1 = create_coclass_obj();
@@ -2742,6 +2762,18 @@ static void test_marshal_coclass(IWidget *widget, IDispatch *disp)
     ok(hr == S_OK, "Got hr %#x.\n", hr);
     ok(!in_out, "Got [in, out] %p.\n", in_out);
 
+    class1 = create_coclass_obj();
+    class2 = create_coclass_obj();
+    class3 = create_coclass_obj();
+    class1_noptr.iface = &class1->ICoclass1_iface;
+    class2_noptr.iface = &class2->ICoclass2_iface;
+    class3_noptr.iface = &class3->ICoclass1_iface;
+    hr = IWidget_Coclass_noptr(widget, class1_noptr, class2_noptr, class3_noptr);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    release_iface(&class1->ICoclass1_iface);
+    release_iface(&class2->ICoclass1_iface);
+    release_iface(&class3->ICoclass1_iface);
+
     /* 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 1344aa4912..9182def313 100644
--- a/dlls/oleaut32/tests/tmarshal.idl
+++ b/dlls/oleaut32/tests/tmarshal.idl
@@ -73,6 +73,7 @@ enum IWidget_dispids
     DISPID_TM_TYPEDEF,
     DISPID_TM_COCLASS,
     DISPID_TM_COCLASS_PTR,
+    DISPID_TM_COCLASS_NOPTR,
     DISPID_TM_NOINOUT
 };
 
@@ -171,6 +172,10 @@ library TestTypelib
         HRESULT test();
     }
 
+cpp_quote("struct Coclass1 { ICoclass1 *iface; };")
+cpp_quote("struct Coclass2 { ICoclass2 *iface; };")
+cpp_quote("struct Coclass3 { ICoclass1 *iface; };")
+
     [
         uuid(3f7e06fe-0bce-46f0-8b7d-3a68393c796c)
     ]
@@ -379,6 +384,9 @@ library TestTypelib
         [id(DISPID_TM_COCLASS_PTR)]
         HRESULT Coclass_ptr([in] Coclass1 **in, [out] Coclass1 **out, [in, out] Coclass1 **in_out);
 
+        [id(DISPID_TM_COCLASS_NOPTR)]
+        HRESULT Coclass_noptr([in] Coclass1 class1, [in] Coclass2 class2, [in] Coclass3 class3);
+
         [id(DISPID_TM_NOINOUT)]
         HRESULT no_in_out(BSTR str, int i);
     }
diff --git a/dlls/rpcrt4/ndr_typelib.c b/dlls/rpcrt4/ndr_typelib.c
index 462b235d33..91c4a07464 100644
--- a/dlls/rpcrt4/ndr_typelib.c
+++ b/dlls/rpcrt4/ndr_typelib.c
@@ -787,6 +787,7 @@ static size_t write_type_tfs(ITypeInfo *typeinfo, unsigned char *str,
     ITypeInfo *refinfo;
     TYPEATTR *attr;
     size_t off;
+    GUID guid;
 
     TRACE("vt %d%s\n", desc->vt, toplevel ? " (toplevel)" : "");
 
@@ -815,7 +816,9 @@ static size_t write_type_tfs(ITypeInfo *typeinfo, unsigned char *str,
             write_ip_tfs(str, len, &attr->guid);
             break;
         case TKIND_COCLASS:
-            assert(0);
+            off = *len;
+            get_default_iface(refinfo, attr->cImplTypes, &guid);
+            write_ip_tfs(str, len, &guid);
             break;
         case TKIND_ALIAS:
             off = write_type_tfs(refinfo, str, len, &attr->tdescAlias, toplevel, onstack);
@@ -1007,6 +1010,7 @@ static HRESULT get_param_info(ITypeInfo *typeinfo, TYPEDESC *tdesc, int is_in,
 
         case TKIND_INTERFACE:
         case TKIND_DISPATCH:
+        case TKIND_COCLASS:
             /* These are treated as if they were interface pointers. */
             *flags |= MustFree;
             break;
-- 
2.25.1




More information about the wine-devel mailing list