Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/quartz/tests/Makefile.in | 1 + dlls/quartz/tests/passthrough.c | 133 ++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 dlls/quartz/tests/passthrough.c
diff --git a/dlls/quartz/tests/Makefile.in b/dlls/quartz/tests/Makefile.in index fe1a45e8ec5..46b3728ab82 100644 --- a/dlls/quartz/tests/Makefile.in +++ b/dlls/quartz/tests/Makefile.in @@ -11,6 +11,7 @@ C_SRCS = \ filtermapper.c \ memallocator.c \ mpegsplit.c \ + passthrough.c \ systemclock.c \ videorenderer.c \ vmr7.c \ diff --git a/dlls/quartz/tests/passthrough.c b/dlls/quartz/tests/passthrough.c new file mode 100644 index 00000000000..6042bc7f5ab --- /dev/null +++ b/dlls/quartz/tests/passthrough.c @@ -0,0 +1,133 @@ +/* + * Seeking passthrough unit tests + * + * Copyright 2020 Zebediah Figura for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS +#include "dshow.h" +#include "wine/test.h" + +static ULONG get_refcount(void *iface) +{ + IUnknown *unknown = iface; + IUnknown_AddRef(unknown); + return IUnknown_Release(unknown); +} + +static const GUID test_iid = {0x33333333}; +static LONG outer_ref = 1; + +static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out) +{ + if (IsEqualGUID(iid, &IID_IUnknown) + || IsEqualGUID(iid, &IID_ISeekingPassThru) + || IsEqualGUID(iid, &test_iid)) + { + *out = (IUnknown *)0xdeadbeef; + return S_OK; + } + ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid)); + 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) +{ + ISeekingPassThru *passthrough, *passthrough2; + IUnknown *unk, *unk2; + HRESULT hr; + ULONG ref; + + passthrough = (ISeekingPassThru *)0xdeadbeef; + hr = CoCreateInstance(&CLSID_SeekingPassThru, &test_outer, CLSCTX_INPROC_SERVER, + &IID_ISeekingPassThru, (void **)&passthrough); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!passthrough, "Got interface %p.\n", passthrough); + + hr = CoCreateInstance(&CLSID_SeekingPassThru, &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_ISeekingPassThru, (void **)&passthrough); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = ISeekingPassThru_QueryInterface(passthrough, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + + hr = ISeekingPassThru_QueryInterface(passthrough, &IID_ISeekingPassThru, (void **)&passthrough2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(passthrough2 == (ISeekingPassThru *)0xdeadbeef, "Got unexpected ISeekingPassThru %p.\n", passthrough2); + + 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 = ISeekingPassThru_QueryInterface(passthrough, &test_iid, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + + ISeekingPassThru_Release(passthrough); + ref = IUnknown_Release(unk); + todo_wine ok(!ref, "Got unexpected refcount %d.\n", ref); + todo_wine ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); +} + +START_TEST(passthrough) +{ + CoInitialize(NULL); + + test_aggregation(); + + CoUninitialize(); +}