[PATCH 6/6] ole32: Allow marshalling objects from an implicit MTA.
Zebediah Figura
z.figura12 at gmail.com
Sun Mar 25 12:34:02 CDT 2018
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
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 dc09d20..212d328 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 822d06e..7c0f541 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 5a7626b..a73d23c 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 57048c6..75c4b04 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 c5c69f0..e8558dd 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();
}
--
2.7.4
More information about the wine-devel
mailing list