Commit 14a87908 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

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

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