Signed-off-by: Jactry Zeng <jzeng(a)codeweavers.com>
---
dlls/qcap/tests/qcap.c | 145 ---------------------------------
dlls/qcap/tests/videocapture.c | 132 ++++++++++++++++++++++++++++++
2 files changed, 132 insertions(+), 145 deletions(-)
diff --git a/dlls/qcap/tests/qcap.c b/dlls/qcap/tests/qcap.c
index 56eaf77513..d1b2cb810f 100644
--- a/dlls/qcap/tests/qcap.c
+++ b/dlls/qcap/tests/qcap.c
@@ -1643,150 +1643,6 @@ static void test_AviMux(char *arg)
ok(ref == 0, "IStream was not destroyed (%d)\n", ref);
}
-/* Outer IUnknown for COM aggregation tests */
-struct unk_impl {
- IUnknown IUnknown_iface;
- LONG ref;
- IUnknown *inner_unk;
-};
-
-static inline struct unk_impl *impl_from_IUnknown(IUnknown *iface)
-{
- return CONTAINING_RECORD(iface, struct unk_impl, IUnknown_iface);
-}
-
-static HRESULT WINAPI unk_QueryInterface(IUnknown *iface, REFIID riid, void **ret_iface)
-{
- struct unk_impl *This = impl_from_IUnknown(iface);
-
- return IUnknown_QueryInterface(This->inner_unk, riid, ret_iface);
-}
-
-static ULONG WINAPI unk_AddRef(IUnknown *iface)
-{
- struct unk_impl *This = impl_from_IUnknown(iface);
-
- return InterlockedIncrement(&This->ref);
-}
-
-static ULONG WINAPI unk_Release(IUnknown *iface)
-{
- struct unk_impl *This = impl_from_IUnknown(iface);
-
- return InterlockedDecrement(&This->ref);
-}
-
-static const IUnknownVtbl unk_vtbl =
-{
- unk_QueryInterface,
- unk_AddRef,
- unk_Release
-};
-
-static void test_COM_vfwcapture(void)
-{
- struct unk_impl unk_obj = {{&unk_vtbl}, 19, NULL};
- IBaseFilter *bf;
- IMediaFilter *mf;
- IPersist *p;
- IPersistPropertyBag *ppb;
- IAMVfwCaptureDialogs *amvcd;
- IAMFilterMiscFlags *amfmf;
- ISpecifyPropertyPages *spp;
- IUnknown *unk;
- ULONG refcount;
- HRESULT hr;
-
- /* COM aggregation */
- hr = CoCreateInstance(&CLSID_VfwCapture, &unk_obj.IUnknown_iface, CLSCTX_INPROC_SERVER,
- &IID_IUnknown, (void**)&unk_obj.inner_unk);
- if ((hr == REGDB_E_CLASSNOTREG) || (hr == CLASS_E_CLASSNOTAVAILABLE))
- {
- win_skip("CLSID_VfwCapture not supported (0x%x)\n", hr);
- return;
- }
- ok(hr == S_OK, "VfwCapture create failed: %08x\n", hr);
- hr = IUnknown_QueryInterface(unk_obj.inner_unk, &IID_IBaseFilter, (void**)&bf);
- ok(hr == S_OK, "QueryInterface for IID_IBaseFilter failed: %08x\n", hr);
- refcount = IBaseFilter_AddRef(bf);
- ok(refcount == unk_obj.ref, "VfwCapture just pretends to support COM aggregation\n");
- refcount = IBaseFilter_Release(bf);
- ok(refcount == unk_obj.ref, "VfwCapture just pretends to support COM aggregation\n");
- refcount = IBaseFilter_Release(bf);
- ok(refcount == 19, "Refcount should be back at 19 but is %u\n", refcount);
- IUnknown_Release(unk_obj.inner_unk);
-
- /* Invalid RIID */
- hr = CoCreateInstance(&CLSID_VfwCapture, NULL, CLSCTX_INPROC_SERVER, &IID_IClassFactory,
- (void**)&bf);
- ok(hr == E_NOINTERFACE, "VfwCapture create failed: %08x, expected E_NOINTERFACE\n", hr);
-
- /* Same refcount for all VfwCapture interfaces */
- hr = CoCreateInstance(&CLSID_VfwCapture, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter,
- (void**)&bf);
- ok(hr == S_OK, "VfwCapture create failed: %08x, expected S_OK\n", hr);
- refcount = IBaseFilter_AddRef(bf);
- ok(refcount == 2, "refcount == %u, expected 2\n", refcount);
-
- hr = IBaseFilter_QueryInterface(bf, &IID_IMediaFilter, (void**)&mf);
- ok(hr == S_OK, "QueryInterface for IID_IMediaFilter failed: %08x\n", hr);
- refcount = IMediaFilter_AddRef(mf);
- ok(refcount == 4, "refcount == %u, expected 4\n", refcount);
- refcount = IMediaFilter_Release(mf);
-
- hr = IBaseFilter_QueryInterface(bf, &IID_IPersist, (void**)&p);
- ok(hr == S_OK, "QueryInterface for IID_IPersist failed: %08x\n", hr);
- refcount = IPersist_AddRef(p);
- ok(refcount == 5, "refcount == %u, expected 5\n", refcount);
- refcount = IPersist_Release(p);
-
- hr = IBaseFilter_QueryInterface(bf, &IID_IPersistPropertyBag, (void**)&ppb);
- ok(hr == S_OK, "QueryInterface for IID_IPersistPropertyBag failed: %08x\n", hr);
- refcount = IPersistPropertyBag_AddRef(ppb);
- ok(refcount == 6, "refcount == %u, expected 6\n", refcount);
- refcount = IPersistPropertyBag_Release(ppb);
-
- hr = IBaseFilter_QueryInterface(bf, &IID_IAMVfwCaptureDialogs, (void**)&amvcd);
- todo_wine ok(hr == S_OK, "QueryInterface for IID_IAMVfwCaptureDialogs failed: %08x\n", hr);
- if (hr == S_OK) {
- refcount = IAMVfwCaptureDialogs_AddRef(amvcd);
- ok(refcount == 7, "refcount == %u, expected 7\n", refcount);
- refcount = IAMVfwCaptureDialogs_Release(amvcd);
- }
-
- hr = IBaseFilter_QueryInterface(bf, &IID_IAMFilterMiscFlags, (void**)&amfmf);
- todo_wine ok(hr == S_OK, "QueryInterface for IID_IAMFilterMiscFlags failed: %08x\n", hr);
- if (hr == S_OK) {
- refcount = IAMFilterMiscFlags_AddRef(amfmf);
- ok(refcount == 8, "refcount == %u, expected 8\n", refcount);
- refcount = IAMFilterMiscFlags_Release(amfmf);
- }
-
- hr = IBaseFilter_QueryInterface(bf, &IID_ISpecifyPropertyPages, (void**)&spp);
- todo_wine ok(hr == S_OK, "QueryInterface for IID_ISpecifyPropertyPages failed: %08x\n", hr);
- if (hr == S_OK) {
- refcount = ISpecifyPropertyPages_AddRef(spp);
- ok(refcount == 9, "refcount == %u, expected 9\n", refcount);
- refcount = ISpecifyPropertyPages_Release(spp);
- }
-
- hr = IBaseFilter_QueryInterface(bf, &IID_IUnknown, (void**)&unk);
- ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr);
- refcount = IUnknown_AddRef(unk);
- todo_wine ok(refcount == 10, "refcount == %u, expected 10\n", refcount);
- refcount = IUnknown_Release(unk);
-
- /* Unsupported interfaces */
- hr = IBaseFilter_QueryInterface(bf, &IID_IAMStreamConfig, (void**)&unk);
- ok(hr == E_NOINTERFACE, "QueryInterface for IID_IAMStreamConfig failed: %08x\n", hr);
- hr = IBaseFilter_QueryInterface(bf, &IID_IAMVideoProcAmp, (void**)&unk);
- todo_wine ok(hr == E_NOINTERFACE, "QueryInterface for IID_IAMVideoProcAmp failed: %08x\n", hr);
- hr = IBaseFilter_QueryInterface(bf, &IID_IOverlayNotify, (void**)&unk);
- ok(hr == E_NOINTERFACE, "QueryInterface for IID_IOverlayNotify failed: %08x\n", hr);
-
- while (IBaseFilter_Release(bf));
-}
-
START_TEST(qcap)
{
if (SUCCEEDED(CoInitialize(NULL)))
@@ -1797,7 +1653,6 @@ START_TEST(qcap)
arg_c = winetest_get_mainargs(&arg_v);
test_AviMux(arg_c>2 ? arg_v[2] : NULL);
- test_COM_vfwcapture();
CoUninitialize();
}
diff --git a/dlls/qcap/tests/videocapture.c b/dlls/qcap/tests/videocapture.c
index cd613b00e7..a6ce6c565f 100644
--- a/dlls/qcap/tests/videocapture.c
+++ b/dlls/qcap/tests/videocapture.c
@@ -38,6 +38,13 @@ static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOO
IUnknown_Release(unk);
}
+static ULONG get_refcount(void *iface)
+{
+ IUnknown *unknown = iface;
+ IUnknown_AddRef(unknown);
+ return IUnknown_Release(unknown);
+}
+
static void test_media_types(IPin *pin)
{
IEnumMediaTypes *enum_media_types;
@@ -235,6 +242,127 @@ static void test_capture(IBaseFilter *filter)
check_interface(filter, &IID_IOverlayNotify, FALSE);
}
+static const GUID test_iid = {0x33333333};
+static LONG outer_ref = 1;
+
+static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID riid, void **ret_iface)
+{
+ if (IsEqualGUID(riid, &IID_IUnknown)
+ || IsEqualGUID(riid, &IID_IBaseFilter)
+ || IsEqualGUID(riid, &test_iid))
+ {
+ *ret_iface = (IUnknown *)0xdeadbeef;
+ return S_OK;
+ }
+ ok(0, "Unexpected call %s.\n", wine_dbgstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI outer_AddRef(IUnknown *iface)
+{
+ return InterlockedIncrement(&outer_ref);
+}
+
+static ULONG WINAPI outer_Release(IUnknown *iface)
+{
+ return InterlockedDecrement(&outer_ref);
+}
+
+static const IUnknownVtbl outer_vtbl =
+{
+ outer_QueryInterface,
+ outer_AddRef,
+ outer_Release,
+};
+
+static IUnknown test_outer = {&outer_vtbl};
+
+static void test_aggregation(void)
+{
+ IBaseFilter *filter, *filter2;
+ IUnknown *unk, *unk2;
+ HRESULT hr;
+ ULONG ref;
+
+ filter = (IBaseFilter *)0xdeadbeef;
+ hr = CoCreateInstance(&CLSID_VfwCapture, &test_outer, CLSCTX_INPROC_SERVER,
+ &IID_IBaseFilter, (void **)&filter);
+ ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
+ ok(!filter, "Got interface %p.\n", filter);
+
+ hr = CoCreateInstance(&CLSID_VfwCapture, &test_outer, CLSCTX_INPROC_SERVER,
+ &IID_IUnknown, (void **)&unk);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
+ ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
+ ref = get_refcount(unk);
+ ok(ref == 1, "Got unexpected refcount %d.\n", ref);
+
+ ref = IUnknown_AddRef(unk);
+ ok(ref == 2, "Got unexpected refcount %d.\n", ref);
+ ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
+
+ ref = IUnknown_Release(unk);
+ ok(ref == 1, "Got unexpected refcount %d.\n", ref);
+ ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
+
+ hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2);
+ IUnknown_Release(unk2);
+
+ hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
+
+ hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2);
+
+ hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2);
+ ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
+ ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
+
+ hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
+
+ IBaseFilter_Release(filter);
+ ref = IUnknown_Release(unk);
+ ok(!ref, "Got unexpected refcount %d.\n", ref);
+ ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
+}
+
+static void test_interfaces(void)
+{
+ IBaseFilter *filter = NULL;
+ HRESULT hr;
+ ULONG ref;
+
+ hr = CoCreateInstance(&CLSID_VfwCapture, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IBaseFilter, (void **)&filter);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ todo_wine check_interface(filter, &IID_IAMFilterMiscFlags, TRUE);
+ todo_wine check_interface(filter, &IID_IAMVfwCaptureDialogs, TRUE);
+ check_interface(filter, &IID_IBaseFilter, TRUE);
+ check_interface(filter, &IID_IMediaFilter, TRUE);
+ check_interface(filter, &IID_IPersist, TRUE);
+ check_interface(filter, &IID_IPersistPropertyBag, TRUE);
+ todo_wine check_interface(filter, &IID_ISpecifyPropertyPages, TRUE);
+ check_interface(filter, &IID_IUnknown, TRUE);
+
+ check_interface(filter, &IID_IAMStreamConfig, FALSE);
+ todo_wine check_interface(filter, &IID_IAMVideoProcAmp, FALSE);
+ check_interface(filter, &IID_IOverlayNotify, FALSE);
+
+ ref = IBaseFilter_Release(filter);
+ ok(!ref, "Got unexpected refcount %d.\n", ref);
+}
+
START_TEST(videocapture)
{
ICreateDevEnum *dev_enum;
@@ -283,5 +411,9 @@ START_TEST(videocapture)
ICreateDevEnum_Release(dev_enum);
IEnumMoniker_Release(class_enum);
+
+ test_aggregation();
+ test_interfaces();
+
CoUninitialize();
}
--
2.26.2