Signed-off-by: Jactry Zeng jzeng@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(); }
Sorry for not making a response to 185107; CLSID_VfwCapture is kind of an awkward situation and I wasn't sure how I wanted to proceed with it...
The problem is that we kind of roll into one filter what should really be two (and the bulk of neither of which should be implemented in qcap, but that's a problem for another day).
In practice I have yet to see a video camera exposed through the VFW capture filter on Windows. Accordingly I'm inclined to just get rid of any VFW-specific code or tests (at least, if it starts causing problems, like here—obviously we still need to keep the IPersistPropertyBag bits around, though...)
I've sent a patch effecting this.