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:
parent
a4cf16db08
commit
95299607f9
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue