From 95299607f9cdde10af7623fea9eb337b33753161 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Mon, 9 Apr 2018 21:15:52 -0500 Subject: [PATCH] ole32: Allow marshalling objects from an implicit MTA. Signed-off-by: Zebediah Figura Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/ole32/compobj_private.h | 2 +- dlls/ole32/marshal.c | 5 ++-- dlls/ole32/rpc.c | 2 +- dlls/ole32/stubmanager.c | 3 +-- dlls/ole32/tests/marshal.c | 50 ++++++++++++++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 6 deletions(-) diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h index dc09d206a4a..212d3283171 100644 --- a/dlls/ole32/compobj_private.h +++ b/dlls/ole32/compobj_private.h @@ -200,7 +200,7 @@ void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const void stub_manager_disconnect(struct stub_manager *m) DECLSPEC_HIDDEN; HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **manager, IRpcStubBuffer **stub, IRpcChannelBuffer **chan, IID *iid, IUnknown **iface) DECLSPEC_HIDDEN; -HRESULT start_apartment_remote_unknown(void) DECLSPEC_HIDDEN; +HRESULT start_apartment_remote_unknown(APARTMENT *apt) DECLSPEC_HIDDEN; HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, DWORD dest_context, void *dest_context_data, MSHLFLAGS mshlflags) DECLSPEC_HIDDEN; diff --git a/dlls/ole32/marshal.c b/dlls/ole32/marshal.c index 822d06e9613..7c0f5413591 100644 --- a/dlls/ole32/marshal.c +++ b/dlls/ole32/marshal.c @@ -1225,11 +1225,11 @@ StdMarshalImpl_MarshalInterface( STDOBJREF stdobjref; ULONG res; HRESULT hres; - APARTMENT *apt = COM_CurrentApt(); + APARTMENT *apt; TRACE("(...,%s,...)\n", debugstr_guid(riid)); - if (!apt) + if (!(apt = apartment_get_current_or_mta())) { ERR("Apartment not initialized\n"); return CO_E_NOTINITIALIZED; @@ -1239,6 +1239,7 @@ StdMarshalImpl_MarshalInterface( RPC_StartRemoting(apt); hres = marshal_object(apt, &stdobjref, riid, pv, dest_context, dest_context_data, mshlflags); + apartment_release(apt); if (hres != S_OK) { ERR("Failed to create ifstub, hres=0x%x\n", hres); diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c index 5a7626b7b93..a73d23ce683 100644 --- a/dlls/ole32/rpc.c +++ b/dlls/ole32/rpc.c @@ -1648,7 +1648,7 @@ void RPC_StartRemoting(struct apartment *apt) /* FIXME: move remote unknown exporting into this function */ } - start_apartment_remote_unknown(); + start_apartment_remote_unknown(apt); } diff --git a/dlls/ole32/stubmanager.c b/dlls/ole32/stubmanager.c index 57048c63062..75c4b0416ec 100644 --- a/dlls/ole32/stubmanager.c +++ b/dlls/ole32/stubmanager.c @@ -812,11 +812,10 @@ static const IRemUnknownVtbl RemUnknown_Vtbl = }; /* starts the IRemUnknown listener for the current apartment */ -HRESULT start_apartment_remote_unknown(void) +HRESULT start_apartment_remote_unknown(APARTMENT *apt) { IRemUnknown *pRemUnknown; HRESULT hr = S_OK; - APARTMENT *apt = COM_CurrentApt(); EnterCriticalSection(&apt->cs); if (!apt->remunk_exported) diff --git a/dlls/ole32/tests/marshal.c b/dlls/ole32/tests/marshal.c index c5c69f096f8..e8558dd7a38 100644 --- a/dlls/ole32/tests/marshal.c +++ b/dlls/ole32/tests/marshal.c @@ -3475,10 +3475,34 @@ static DWORD CALLBACK implicit_mta_use_proc(void *param) return 0; } +struct implicit_mta_marshal_data +{ + IStream *stream; + HANDLE start; + HANDLE stop; +}; + +static DWORD CALLBACK implicit_mta_marshal_proc(void *param) +{ + struct implicit_mta_marshal_data *data = param; + HRESULT hr; + + hr = CoMarshalInterface(data->stream, &IID_IClassFactory, + (IUnknown *)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL); + ok_ole_success(hr, CoMarshalInterface); + + SetEvent(data->start); + + ok(!WaitForSingleObject(data->stop, 1000), "wait failed\n"); + return 0; +} + static void test_implicit_mta(void) { + struct implicit_mta_marshal_data data; HANDLE host_thread, thread; IClassFactory *cf; + IUnknown *proxy; IStream *stream; HRESULT hr; DWORD tid; @@ -3529,6 +3553,32 @@ static void test_implicit_mta(void) end_host_object(tid, host_thread); + /* Thirdly: we can marshal an object from the implicit MTA and then + * unmarshal it into the real one. */ + data.start = CreateEventA(NULL, FALSE, FALSE, NULL); + data.stop = CreateEventA(NULL, FALSE, FALSE, NULL); + + hr = CreateStreamOnHGlobal(NULL, TRUE, &data.stream); + ok_ole_success(hr, CreateStreamOnHGlobal); + + thread = CreateThread(NULL, 0, implicit_mta_marshal_proc, &data, 0, NULL); + ok(!WaitForSingleObject(data.start, 1000), "wait failed\n"); + + IStream_Seek(data.stream, ullZero, STREAM_SEEK_SET, NULL); + hr = CoUnmarshalInterface(data.stream, &IID_IClassFactory, (void **)&cf); + ok_ole_success(hr, CoUnmarshalInterface); + + hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void **)&proxy); + ok_ole_success(hr, IClassFactory_CreateInstance); + + IUnknown_Release(proxy); + + SetEvent(data.stop); + ok(!WaitForSingleObject(thread, 1000), "wait failed\n"); + CloseHandle(thread); + + IStream_Release(data.stream); + CoUninitialize(); }