Signed-off-by: Zebediah Figura z.figura12@gmail.com --- 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;
Signed-off-by: Zebediah Figura z.figura12@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;