ole32: Allow marshalling objects from an implicit MTA.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2018-04-09 21:15:52 -05:00 committed by Alexandre Julliard
parent a4cf16db08
commit 95299607f9
5 changed files with 56 additions and 6 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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)

View File

@ -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();
}