ole32/tests: Extend the lifecycle tests to objects which expose IExternalConnection.

oldstable
Huw Davies 2013-10-24 16:16:47 +01:00 committed by Alexandre Julliard
parent e47edf47fe
commit 14a879085e
1 changed files with 201 additions and 35 deletions

View File

@ -46,6 +46,9 @@ static HRESULT (WINAPI *pDllGetClassObject)(REFCLSID,REFIID,LPVOID);
#define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
#define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
#define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
#define ok_non_zero_external_conn() do {if (with_external_conn) ok(external_connections, "got no external connections\n");} while(0);
#define ok_zero_external_conn() do {if (with_external_conn) ok(!external_connections, "got %d external connections\n", external_connections);} while(0);
#define ok_last_release_closes(b) do {if (with_external_conn) ok(last_release_closes == b, "got %d expected %d\n", last_release_closes, b);} while(0);
static const IID IID_IWineTest =
{
@ -382,6 +385,7 @@ static void test_normal_marshal_and_release(void)
IStream *pStream = NULL;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
@ -389,6 +393,7 @@ static void test_normal_marshal_and_release(void)
ok_ole_success(hr, CoMarshalInterface);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoReleaseMarshalData(pStream);
@ -396,6 +401,8 @@ static void test_normal_marshal_and_release(void)
IStream_Release(pStream);
ok_no_locks();
ok_zero_external_conn();
ok_last_release_closes(TRUE);
}
/* tests success case of a same-thread marshal and unmarshal */
@ -406,6 +413,7 @@ static void test_normal_marshal_and_unmarshal(void)
IUnknown *pProxy = NULL;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
@ -413,6 +421,7 @@ static void test_normal_marshal_and_unmarshal(void)
ok_ole_success(hr, CoMarshalInterface);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
@ -420,6 +429,9 @@ static void test_normal_marshal_and_unmarshal(void)
IStream_Release(pStream);
ok_more_than_one_lock();
ok_zero_external_conn();
todo_wine
ok_last_release_closes(FALSE);
IUnknown_Release(pProxy);
@ -437,18 +449,22 @@ static void test_marshal_and_unmarshal_invalid(void)
HANDLE thread;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoReleaseMarshalData(pStream);
ok_ole_success(hr, CoReleaseMarshalData);
ok_no_locks();
ok_zero_external_conn();
ok_last_release_closes(TRUE);
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
@ -477,6 +493,7 @@ static void test_same_apartment_unmarshal_failure(void)
static const LARGE_INTEGER llZero;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
@ -485,6 +502,7 @@ static void test_same_apartment_unmarshal_failure(void)
ok_ole_success(hr, CoMarshalInterface);
ok_more_than_one_lock();
ok_non_zero_external_conn();
hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
ok_ole_success(hr, IStream_Seek);
@ -493,6 +511,9 @@ static void test_same_apartment_unmarshal_failure(void)
ok(hr == E_NOINTERFACE, "CoUnmarshalInterface should have returned E_NOINTERFACE instead of 0x%08x\n", hr);
ok_no_locks();
ok_zero_external_conn();
todo_wine
ok_last_release_closes(FALSE);
IStream_Release(pStream);
}
@ -507,12 +528,14 @@ static void test_interthread_marshal_and_unmarshal(void)
HANDLE thread;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
@ -520,10 +543,13 @@ static void test_interthread_marshal_and_unmarshal(void)
IStream_Release(pStream);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IUnknown_Release(pProxy);
ok_no_locks();
ok_zero_external_conn();
ok_last_release_closes(TRUE);
end_host_object(tid, thread);
}
@ -544,12 +570,14 @@ static void test_proxy_marshal_and_unmarshal(void)
int i;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
@ -582,6 +610,7 @@ static void test_proxy_marshal_and_unmarshal(void)
ok_ole_success(hr, CoUnmarshalInterface);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IUnknown_Release(pProxy2);
@ -595,6 +624,8 @@ static void test_proxy_marshal_and_unmarshal(void)
}
ok_no_locks();
ok_zero_external_conn();
ok_last_release_closes(TRUE);
IStream_Release(pStream);
@ -613,12 +644,14 @@ static void test_proxy_marshal_and_unmarshal2(void)
HANDLE thread;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
tid = start_host_object(pStream, &IID_IUnknown, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)&pProxy);
@ -653,10 +686,13 @@ static void test_proxy_marshal_and_unmarshal2(void)
IUnknown_Release(pProxy);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IUnknown_Release(pProxy2);
ok_no_locks();
ok_zero_external_conn();
ok_last_release_closes(TRUE);
end_host_object(tid, thread);
}
@ -672,18 +708,21 @@ static void test_proxy_marshal_and_unmarshal_weak(void)
HANDLE thread;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
ok_ole_success(hr, CoUnmarshalInterface);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
/* marshal the proxy */
@ -691,6 +730,7 @@ static void test_proxy_marshal_and_unmarshal_weak(void)
ok_ole_success(hr, CoMarshalInterface);
ok_more_than_one_lock();
ok_non_zero_external_conn();
/* release the original proxy to test that we successfully keep the
* original object alive */
@ -702,6 +742,8 @@ static void test_proxy_marshal_and_unmarshal_weak(void)
ok(hr == CO_E_OBJNOTREG, "CoUnmarshalInterface should return CO_E_OBJNOTREG instead of 0x%08x\n", hr);
ok_no_locks();
ok_zero_external_conn();
ok_last_release_closes(TRUE);
IStream_Release(pStream);
@ -719,18 +761,21 @@ static void test_proxy_marshal_and_unmarshal_strong(void)
HANDLE thread;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
ok_ole_success(hr, CoUnmarshalInterface);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
/* marshal the proxy */
@ -744,6 +789,7 @@ static void test_proxy_marshal_and_unmarshal_strong(void)
}
ok_more_than_one_lock();
ok_non_zero_external_conn();
/* release the original proxy to test that we successfully keep the
* original object alive */
@ -754,10 +800,12 @@ static void test_proxy_marshal_and_unmarshal_strong(void)
ok_ole_success(hr, CoUnmarshalInterface);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IUnknown_Release(pProxy2);
ok_more_than_one_lock();
ok_non_zero_external_conn();
end:
IStream_Release(pStream);
@ -765,6 +813,10 @@ end:
end_host_object(tid, thread);
ok_no_locks();
todo_wine {
ok_zero_external_conn();
ok_last_release_closes(FALSE);
}
}
/* tests that stubs are released when the containing apartment is destroyed */
@ -777,12 +829,14 @@ static void test_marshal_stub_apartment_shutdown(void)
HANDLE thread;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
@ -790,10 +844,15 @@ static void test_marshal_stub_apartment_shutdown(void)
IStream_Release(pStream);
ok_more_than_one_lock();
ok_non_zero_external_conn();
end_host_object(tid, thread);
ok_no_locks();
todo_wine {
ok_zero_external_conn();
ok_last_release_closes(FALSE);
}
IUnknown_Release(pProxy);
@ -810,12 +869,14 @@ static void test_marshal_proxy_apartment_shutdown(void)
HANDLE thread;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
@ -823,10 +884,13 @@ static void test_marshal_proxy_apartment_shutdown(void)
IStream_Release(pStream);
ok_more_than_one_lock();
ok_non_zero_external_conn();
CoUninitialize();
ok_no_locks();
ok_zero_external_conn();
ok_last_release_closes(TRUE);
IUnknown_Release(pProxy);
@ -850,12 +914,14 @@ static void test_marshal_proxy_mta_apartment_shutdown(void)
pCoInitializeEx(NULL, COINIT_MULTITHREADED);
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
@ -863,10 +929,13 @@ static void test_marshal_proxy_mta_apartment_shutdown(void)
IStream_Release(pStream);
ok_more_than_one_lock();
ok_non_zero_external_conn();
CoUninitialize();
ok_no_locks();
ok_zero_external_conn();
ok_last_release_closes(TRUE);
IUnknown_Release(pProxy);
@ -916,6 +985,7 @@ static void test_no_couninitialize_server(void)
struct ncu_params ncu_params;
cLocks = 0;
external_connections = 0;
ncu_params.marshal_event = CreateEventA(NULL, TRUE, FALSE, NULL);
ncu_params.unmarshal_event = CreateEventA(NULL, TRUE, FALSE, NULL);
@ -928,6 +998,7 @@ static void test_no_couninitialize_server(void)
ok( !WaitForSingleObject(ncu_params.marshal_event, 10000), "wait timed out\n" );
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
@ -935,11 +1006,16 @@ static void test_no_couninitialize_server(void)
IStream_Release(pStream);
ok_more_than_one_lock();
ok_non_zero_external_conn();
SetEvent(ncu_params.unmarshal_event);
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
ok_no_locks();
todo_wine {
ok_zero_external_conn();
ok_last_release_closes(FALSE);
}
CloseHandle(thread);
CloseHandle(ncu_params.marshal_event);
@ -982,6 +1058,7 @@ static void test_no_couninitialize_client(void)
struct ncu_params ncu_params;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
@ -993,6 +1070,7 @@ static void test_no_couninitialize_client(void)
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
ok_more_than_one_lock();
ok_non_zero_external_conn();
thread = CreateThread(NULL, 0, no_couninitialize_client_proc, &ncu_params, 0, &tid);
@ -1000,6 +1078,8 @@ static void test_no_couninitialize_client(void)
CloseHandle(thread);
ok_no_locks();
ok_zero_external_conn();
ok_last_release_closes(TRUE);
end_host_object(host_tid, host_thread);
}
@ -1015,34 +1095,49 @@ static void test_tableweak_marshal_and_unmarshal_twice(void)
HANDLE thread;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLEWEAK, &thread);
ok_more_than_one_lock();
ok_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
ok_ole_success(hr, CoUnmarshalInterface);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
IStream_Release(pStream);
ok_ole_success(hr, CoUnmarshalInterface);
ok_more_than_one_lock();
IUnknown_Release(pProxy1);
ok_non_zero_external_conn();
IUnknown_Release(pProxy2);
ok_zero_external_conn();
ok_last_release_closes(TRUE);
/* this line is shows the difference between weak and strong table marshaling:
* weak has cLocks == 0
* strong has cLocks > 0 */
/* When IExternalConnection is present COM's lifetime management
* behaviour is altered; the remaining weak ref prevents stub shutdown. */
if (with_external_conn)
{
todo_wine
ok_more_than_one_lock();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
release_host_object(tid);
}
/* Without IExternalConnection this line is shows the difference between weak and strong table marshaling
* weak has cLocks == 0, strong has cLocks > 0. */
ok_no_locks();
IStream_Release(pStream);
end_host_object(tid, thread);
}
@ -1057,18 +1152,21 @@ static void test_tableweak_marshal_releasedata1(void)
HANDLE thread;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLEWEAK, &thread);
ok_more_than_one_lock();
ok_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
ok_ole_success(hr, CoUnmarshalInterface);
ok_more_than_one_lock();
ok_non_zero_external_conn();
/* release the remaining reference on the object by calling
* CoReleaseMarshalData in the hosting thread */
@ -1076,6 +1174,7 @@ static void test_tableweak_marshal_releasedata1(void)
release_host_object(tid);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
@ -1083,15 +1182,22 @@ static void test_tableweak_marshal_releasedata1(void)
IStream_Release(pStream);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IUnknown_Release(pProxy1);
if (pProxy2)
{
ok_non_zero_external_conn();
IUnknown_Release(pProxy2);
}
/* this line is shows the difference between weak and strong table marshaling:
* weak has cLocks == 0
* strong has cLocks > 0 */
ok_no_locks();
ok_zero_external_conn();
ok_last_release_closes(TRUE);
end_host_object(tid, thread);
}
@ -1106,12 +1212,14 @@ static void test_tableweak_marshal_releasedata2(void)
HANDLE thread;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLEWEAK, &thread);
ok_more_than_one_lock();
ok_zero_external_conn();
/* release the remaining reference on the object by calling
* CoReleaseMarshalData in the hosting thread */
@ -1131,6 +1239,7 @@ static void test_tableweak_marshal_releasedata2(void)
IStream_Release(pStream);
ok_no_locks();
ok_zero_external_conn();
end_host_object(tid, thread);
}
@ -1166,7 +1275,15 @@ static DWORD CALLBACK weak_and_normal_marshal_thread_proc(void *p)
while (WAIT_OBJECT_0 + 1 == MsgWaitForMultipleObjects(1, &hQuitEvent, FALSE, 10000, QS_ALLINPUT))
{
while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
DispatchMessageA(&msg);
{
if (msg.hwnd == NULL && msg.message == RELEASEMARSHALDATA)
{
CoReleaseMarshalData(data->pStreamWeak);
SetEvent((HANDLE)msg.lParam);
}
else
DispatchMessageA(&msg);
}
}
CloseHandle(hQuitEvent);
@ -1186,6 +1303,7 @@ static void test_tableweak_and_normal_marshal_and_unmarshal(void)
struct weak_and_normal_marshal_data data;
cLocks = 0;
external_connections = 0;
data.hReadyEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
data.hQuitEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
@ -1199,6 +1317,7 @@ static void test_tableweak_and_normal_marshal_and_unmarshal(void)
CloseHandle(data.hReadyEvent);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(data.pStreamWeak, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(data.pStreamWeak, &IID_IClassFactory, (void **)&pProxyWeak);
@ -1215,9 +1334,22 @@ static void test_tableweak_and_normal_marshal_and_unmarshal(void)
IUnknown_Release(pProxyNormal);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IUnknown_Release(pProxyWeak);
ok_zero_external_conn();
ok_last_release_closes(TRUE);
/* When IExternalConnection is present COM's lifetime management
* behaviour is altered; the remaining weak ref prevents stub shutdown. */
if (with_external_conn)
{
todo_wine
ok_more_than_one_lock();
IStream_Seek(data.pStreamWeak, ullZero, STREAM_SEEK_SET, NULL);
release_host_object(tid);
}
ok_no_locks();
IStream_Release(data.pStreamWeak);
@ -1239,12 +1371,14 @@ static void test_tablestrong_marshal_and_unmarshal_twice(void)
HANDLE thread;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLESTRONG, &thread);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
@ -1273,6 +1407,8 @@ static void test_tablestrong_marshal_and_unmarshal_twice(void)
IStream_Release(pStream);
ok_no_locks();
ok_zero_external_conn();
ok_last_release_closes(TRUE);
end_host_object(tid, thread);
}
@ -1284,17 +1420,20 @@ static void test_lock_object_external(void)
IStream *pStream = NULL;
cLocks = 0;
with_external_conn = TRUE;
external_connections = 0;
/* test the stub manager creation aspect of CoLockObjectExternal when the
* object hasn't been marshaled yet */
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, TRUE, TRUE);
ok_more_than_one_lock();
ok_non_zero_external_conn();
CoDisconnectObject((IUnknown*)&Test_ClassFactory, 0);
ok_no_locks();
ok_non_zero_external_conn();
external_connections = 0;
/* test our empty stub manager being handled correctly in
* CoMarshalInterface */
@ -1308,6 +1447,7 @@ static void test_lock_object_external(void)
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, TRUE, TRUE);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoReleaseMarshalData(pStream);
@ -1315,15 +1455,20 @@ static void test_lock_object_external(void)
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
ok_more_than_one_lock();
ok_non_zero_external_conn();
ok_last_release_closes(TRUE);
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, FALSE, TRUE);
ok_more_than_one_lock();
ok_non_zero_external_conn();
ok_last_release_closes(TRUE);
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, FALSE, TRUE);
ok_no_locks();
ok(last_release_closes, "last_release_closes FALSE\n");
ok_zero_external_conn();
ok_last_release_closes(TRUE);
/* test CoLockObjectExternal releases reference to object with
* fLastUnlockReleases as TRUE and there are only strong references on
@ -1331,12 +1476,14 @@ static void test_lock_object_external(void)
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, TRUE, FALSE);
ok_more_than_one_lock();
ok_non_zero_external_conn();
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, FALSE, FALSE);
ok_no_locks();
ok_zero_external_conn();
todo_wine
ok(!last_release_closes, "last_release_closes TRUE\n");
ok_last_release_closes(FALSE);
/* test CoLockObjectExternal doesn't release the last reference to an
* object with fLastUnlockReleases as TRUE and there is a weak reference
@ -1345,23 +1492,25 @@ todo_wine
ok_ole_success(hr, CoMarshalInterface);
ok_more_than_one_lock();
ok_zero_external_conn();
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, TRUE, FALSE);
ok_more_than_one_lock();
ok_non_zero_external_conn();
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, FALSE, FALSE);
ok_more_than_one_lock();
ok_zero_external_conn();
todo_wine
ok_last_release_closes(FALSE);
CoDisconnectObject((IUnknown*)&Test_ClassFactory, 0);
ok_no_locks();
todo_wine
ok(!last_release_closes, "last_release_closes TRUE\n");
IStream_Release(pStream);
with_external_conn = FALSE;
}
/* tests disconnecting stubs */
@ -1371,15 +1520,19 @@ static void test_disconnect_stub(void)
IStream *pStream = NULL;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
ok_ole_success(hr, CoMarshalInterface);
ok_non_zero_external_conn();
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, TRUE, TRUE);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoReleaseMarshalData(pStream);
@ -1387,10 +1540,12 @@ static void test_disconnect_stub(void)
IStream_Release(pStream);
ok_more_than_one_lock();
ok_non_zero_external_conn();
CoDisconnectObject((IUnknown*)&Test_ClassFactory, 0);
ok_no_locks();
ok_non_zero_external_conn();
hr = CoDisconnectObject(NULL, 0);
ok( hr == E_INVALIDARG, "wrong status %x\n", hr );
@ -1405,6 +1560,7 @@ static void test_normal_marshal_and_unmarshal_twice(void)
IUnknown *pProxy2 = NULL;
cLocks = 0;
external_connections = 0;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
ok_ole_success(hr, CreateStreamOnHGlobal);
@ -1412,12 +1568,16 @@ static void test_normal_marshal_and_unmarshal_twice(void)
ok_ole_success(hr, CoMarshalInterface);
ok_more_than_one_lock();
ok_non_zero_external_conn();
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
ok_ole_success(hr, CoUnmarshalInterface);
ok_more_than_one_lock();
ok_zero_external_conn();
todo_wine
ok_last_release_closes(FALSE);
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
@ -3250,29 +3410,35 @@ START_TEST(marshal)
/* FIXME: test CoCreateInstanceEx */
/* lifecycle management and marshaling tests */
test_no_marshaler();
test_normal_marshal_and_release();
test_normal_marshal_and_unmarshal();
test_marshal_and_unmarshal_invalid();
test_same_apartment_unmarshal_failure();
test_interthread_marshal_and_unmarshal();
test_proxy_marshal_and_unmarshal();
test_proxy_marshal_and_unmarshal2();
test_proxy_marshal_and_unmarshal_weak();
test_proxy_marshal_and_unmarshal_strong();
test_marshal_stub_apartment_shutdown();
test_marshal_proxy_apartment_shutdown();
test_marshal_proxy_mta_apartment_shutdown();
test_no_couninitialize_server();
test_no_couninitialize_client();
test_tableweak_marshal_and_unmarshal_twice();
test_tableweak_marshal_releasedata1();
test_tableweak_marshal_releasedata2();
test_tableweak_and_normal_marshal_and_unmarshal();
test_tablestrong_marshal_and_unmarshal_twice();
test_lock_object_external();
test_disconnect_stub();
test_normal_marshal_and_unmarshal_twice();
do
{
test_no_marshaler();
test_normal_marshal_and_release();
test_normal_marshal_and_unmarshal();
test_marshal_and_unmarshal_invalid();
test_same_apartment_unmarshal_failure();
test_interthread_marshal_and_unmarshal();
test_proxy_marshal_and_unmarshal();
test_proxy_marshal_and_unmarshal2();
test_proxy_marshal_and_unmarshal_weak();
test_proxy_marshal_and_unmarshal_strong();
test_marshal_stub_apartment_shutdown();
test_marshal_proxy_apartment_shutdown();
test_marshal_proxy_mta_apartment_shutdown();
test_no_couninitialize_server();
test_no_couninitialize_client();
test_tableweak_marshal_and_unmarshal_twice();
test_tableweak_marshal_releasedata1();
test_tableweak_marshal_releasedata2();
test_tableweak_and_normal_marshal_and_unmarshal();
test_tablestrong_marshal_and_unmarshal_twice();
test_lock_object_external();
test_disconnect_stub();
test_normal_marshal_and_unmarshal_twice();
with_external_conn = !with_external_conn;
} while (with_external_conn);
test_hresult_marshaling();
test_proxy_used_in_wrong_thread();
test_message_filter();