[PATCH 8/8] quartz/tests: Clean up and expand tests for aggregation.

Zebediah Figura z.figura12 at gmail.com
Thu Apr 18 23:01:29 CDT 2019


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/quartz/tests/Makefile.in     |   1 -
 dlls/quartz/tests/filtergraph.c   | 139 +++++++++---------
 dlls/quartz/tests/filtermapper.c  | 159 ++++++++++----------
 dlls/quartz/tests/misc.c          | 233 ------------------------------
 dlls/quartz/tests/videorenderer.c |  94 ++++++++++++
 dlls/quartz/tests/vmr7.c          |  95 ++++++++++++
 dlls/quartz/tests/vmr9.c          |  95 ++++++++++++
 7 files changed, 442 insertions(+), 374 deletions(-)
 delete mode 100644 dlls/quartz/tests/misc.c

diff --git a/dlls/quartz/tests/Makefile.in b/dlls/quartz/tests/Makefile.in
index 59124c32af..2ba32921e1 100644
--- a/dlls/quartz/tests/Makefile.in
+++ b/dlls/quartz/tests/Makefile.in
@@ -10,7 +10,6 @@ C_SRCS = \
 	filtergraph.c \
 	filtermapper.c \
 	memallocator.c \
-	misc.c \
 	mpegsplit.c \
 	systemclock.c \
 	videorenderer.c \
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c
index f0e4b58cb3..6b6d8aeb20 100644
--- a/dlls/quartz/tests/filtergraph.c
+++ b/dlls/quartz/tests/filtergraph.c
@@ -78,6 +78,13 @@ static IFilterGraph2 *create_graph(void)
     return ret;
 }
 
+static ULONG get_refcount(void *iface)
+{
+    IUnknown *unknown = iface;
+    IUnknown_AddRef(unknown);
+    return IUnknown_Release(unknown);
+}
+
 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
 {
@@ -2291,96 +2298,98 @@ out:
     ok(parser3_pins[1].ref == 1, "Got outstanding refcount %d.\n", parser3_pins[1].ref);
 }
 
-typedef struct IUnknownImpl
-{
-    IUnknown IUnknown_iface;
-    int AddRef_called;
-    int Release_called;
-} IUnknownImpl;
-
-static IUnknownImpl *IUnknownImpl_from_iface(IUnknown * iface)
-{
-    return CONTAINING_RECORD(iface, IUnknownImpl, IUnknown_iface);
-}
+static const GUID test_iid = {0x33333333};
+static LONG outer_ref = 1;
 
-static HRESULT WINAPI IUnknownImpl_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv)
+static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out)
 {
-    ok(0, "QueryInterface should not be called for %s\n", wine_dbgstr_guid(riid));
+    if (IsEqualGUID(iid, &IID_IUnknown)
+            || IsEqualGUID(iid, &IID_IFilterGraph2)
+            || 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 IUnknownImpl_AddRef(IUnknown * iface)
+static ULONG WINAPI outer_AddRef(IUnknown *iface)
 {
-    IUnknownImpl *This = IUnknownImpl_from_iface(iface);
-    This->AddRef_called++;
-    return 2;
+    return InterlockedIncrement(&outer_ref);
 }
 
-static ULONG WINAPI IUnknownImpl_Release(IUnknown * iface)
+static ULONG WINAPI outer_Release(IUnknown *iface)
 {
-    IUnknownImpl *This = IUnknownImpl_from_iface(iface);
-    This->Release_called++;
-    return 1;
+    return InterlockedDecrement(&outer_ref);
 }
 
-static CONST_VTBL IUnknownVtbl IUnknownImpl_Vtbl =
+static const IUnknownVtbl outer_vtbl =
 {
-    IUnknownImpl_QueryInterface,
-    IUnknownImpl_AddRef,
-    IUnknownImpl_Release
+    outer_QueryInterface,
+    outer_AddRef,
+    outer_Release,
 };
 
-static void test_aggregate_filter_graph(void)
+static IUnknown test_outer = {&outer_vtbl};
+
+static void test_aggregation(void)
 {
+    IFilterGraph2 *graph, *graph2;
+    IUnknown *unk, *unk2;
     HRESULT hr;
-    IUnknown *pgraph;
-    IUnknown *punk;
-    IUnknownImpl unk_outer = { { &IUnknownImpl_Vtbl }, 0, 0 };
+    ULONG ref;
 
-    hr = CoCreateInstance(&CLSID_FilterGraph, &unk_outer.IUnknown_iface, CLSCTX_INPROC_SERVER,
-                          &IID_IUnknown, (void **)&pgraph);
-    ok(hr == S_OK, "CoCreateInstance returned %x\n", hr);
-    ok(pgraph != &unk_outer.IUnknown_iface, "pgraph = %p, expected not %p\n", pgraph, &unk_outer.IUnknown_iface);
+    graph = (IFilterGraph2 *)0xdeadbeef;
+    hr = CoCreateInstance(&CLSID_FilterGraph, &test_outer, CLSCTX_INPROC_SERVER,
+            &IID_IFilterGraph2, (void **)&graph);
+    ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
+    ok(!graph, "Got interface %p.\n", graph);
 
-    hr = IUnknown_QueryInterface(pgraph, &IID_IUnknown, (void **)&punk);
-    ok(hr == S_OK, "CoCreateInstance returned %x\n", hr);
-    ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface);
-    IUnknown_Release(punk);
+    hr = CoCreateInstance(&CLSID_FilterGraph, &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);
 
-    ok(unk_outer.AddRef_called == 0, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called);
-    ok(unk_outer.Release_called == 0, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called);
-    unk_outer.AddRef_called = 0;
-    unk_outer.Release_called = 0;
+    ref = IUnknown_AddRef(unk);
+    ok(ref == 2, "Got unexpected refcount %d.\n", ref);
+    ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
 
-    hr = IUnknown_QueryInterface(pgraph, &IID_IFilterMapper, (void **)&punk);
-    ok(hr == S_OK, "CoCreateInstance returned %x\n", hr);
-    ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface);
-    IUnknown_Release(punk);
+    ref = IUnknown_Release(unk);
+    ok(ref == 1, "Got unexpected refcount %d.\n", ref);
+    ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
 
-    ok(unk_outer.AddRef_called == 1, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called);
-    ok(unk_outer.Release_called == 1, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called);
-    unk_outer.AddRef_called = 0;
-    unk_outer.Release_called = 0;
+    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(pgraph, &IID_IFilterMapper2, (void **)&punk);
-    ok(hr == S_OK, "CoCreateInstance returned %x\n", hr);
-    ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface);
-    IUnknown_Release(punk);
+    hr = IUnknown_QueryInterface(unk, &IID_IFilterGraph2, (void **)&graph);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
 
-    ok(unk_outer.AddRef_called == 1, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called);
-    ok(unk_outer.Release_called == 1, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called);
-    unk_outer.AddRef_called = 0;
-    unk_outer.Release_called = 0;
+    hr = IFilterGraph2_QueryInterface(graph, &IID_IUnknown, (void **)&unk2);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
 
-    hr = IUnknown_QueryInterface(pgraph, &IID_IFilterMapper3, (void **)&punk);
-    ok(hr == S_OK, "CoCreateInstance returned %x\n", hr);
-    ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface);
-    IUnknown_Release(punk);
+    hr = IFilterGraph2_QueryInterface(graph, &IID_IFilterGraph2, (void **)&graph2);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(graph2 == (IFilterGraph2 *)0xdeadbeef, "Got unexpected IFilterGraph2 %p.\n", graph2);
 
-    ok(unk_outer.AddRef_called == 1, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called);
-    ok(unk_outer.Release_called == 1, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called);
+    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);
 
-    IUnknown_Release(pgraph);
+    hr = IFilterGraph2_QueryInterface(graph, &test_iid, (void **)&unk2);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
+
+    IFilterGraph2_Release(graph);
+    ref = IUnknown_Release(unk);
+    ok(!ref, "Got unexpected refcount %d.\n", ref);
+    ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
 }
 
 /* Test how methods from "control" interfaces (IBasicAudio, IBasicVideo,
@@ -3220,7 +3229,7 @@ START_TEST(filtergraph)
     test_enum_filters();
     test_graph_builder_render();
     test_graph_builder_connect();
-    test_aggregate_filter_graph();
+    test_aggregation();
     test_control_delegation();
     test_add_remove_filter();
     test_connect_direct();
diff --git a/dlls/quartz/tests/filtermapper.c b/dlls/quartz/tests/filtermapper.c
index fc4fa95fa4..1f7080965f 100644
--- a/dlls/quartz/tests/filtermapper.c
+++ b/dlls/quartz/tests/filtermapper.c
@@ -27,6 +27,13 @@
 #include "initguid.h"
 #include "wine/fil_data.h"
 
+static ULONG get_refcount(void *iface)
+{
+    IUnknown *unknown = iface;
+    IUnknown_AddRef(unknown);
+    return IUnknown_Release(unknown);
+}
+
 /* Helper function, checks if filter with given name was enumerated. */
 static BOOL enum_find_filter(const WCHAR *wszFilterName, IEnumMoniker *pEnum)
 {
@@ -527,96 +534,98 @@ out:
         IFilterMapper2_Release(pMapper);
 }
 
-typedef struct IUnknownImpl
-{
-    IUnknown IUnknown_iface;
-    int AddRef_called;
-    int Release_called;
-} IUnknownImpl;
-
-static IUnknownImpl *IUnknownImpl_from_iface(IUnknown * iface)
-{
-    return CONTAINING_RECORD(iface, IUnknownImpl, IUnknown_iface);
-}
+static const GUID test_iid = {0x33333333};
+static LONG outer_ref = 1;
 
-static HRESULT WINAPI IUnknownImpl_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv)
+static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out)
 {
-    ok(0, "QueryInterface should not be called for %s\n", wine_dbgstr_guid(riid));
+    if (IsEqualGUID(iid, &IID_IUnknown)
+            || IsEqualGUID(iid, &IID_IFilterMapper3)
+            || 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 IUnknownImpl_AddRef(IUnknown * iface)
+static ULONG WINAPI outer_AddRef(IUnknown *iface)
 {
-    IUnknownImpl *This = IUnknownImpl_from_iface(iface);
-    This->AddRef_called++;
-    return 2;
+    return InterlockedIncrement(&outer_ref);
 }
 
-static ULONG WINAPI IUnknownImpl_Release(IUnknown * iface)
+static ULONG WINAPI outer_Release(IUnknown *iface)
 {
-    IUnknownImpl *This = IUnknownImpl_from_iface(iface);
-    This->Release_called++;
-    return 1;
+    return InterlockedDecrement(&outer_ref);
 }
 
-static CONST_VTBL IUnknownVtbl IUnknownImpl_Vtbl =
+static const IUnknownVtbl outer_vtbl =
 {
-    IUnknownImpl_QueryInterface,
-    IUnknownImpl_AddRef,
-    IUnknownImpl_Release
+    outer_QueryInterface,
+    outer_AddRef,
+    outer_Release,
 };
 
-static void test_aggregate_filter_mapper(void)
+static IUnknown test_outer = {&outer_vtbl};
+
+static void test_aggregation(void)
 {
+    IFilterMapper3 *mapper, *mapper2;
+    IUnknown *unk, *unk2;
     HRESULT hr;
-    IUnknown *pmapper;
-    IUnknown *punk;
-    IUnknownImpl unk_outer = { { &IUnknownImpl_Vtbl }, 0, 0 };
-
-    hr = CoCreateInstance(&CLSID_FilterMapper2, &unk_outer.IUnknown_iface, CLSCTX_INPROC_SERVER,
-                          &IID_IUnknown, (void **)&pmapper);
-    ok(hr == S_OK, "CoCreateInstance returned %x\n", hr);
-    ok(pmapper != &unk_outer.IUnknown_iface, "pmapper = %p, expected not %p\n", pmapper, &unk_outer.IUnknown_iface);
-
-    hr = IUnknown_QueryInterface(pmapper, &IID_IUnknown, (void **)&punk);
-    ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr);
-    ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface);
-    IUnknown_Release(punk);
-
-    ok(unk_outer.AddRef_called == 0, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called);
-    ok(unk_outer.Release_called == 0, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called);
-    unk_outer.AddRef_called = 0;
-    unk_outer.Release_called = 0;
-
-    hr = IUnknown_QueryInterface(pmapper, &IID_IFilterMapper, (void **)&punk);
-    ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr);
-    ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface);
-    IUnknown_Release(punk);
-
-    ok(unk_outer.AddRef_called == 1, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called);
-    ok(unk_outer.Release_called == 1, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called);
-    unk_outer.AddRef_called = 0;
-    unk_outer.Release_called = 0;
-
-    hr = IUnknown_QueryInterface(pmapper, &IID_IFilterMapper2, (void **)&punk);
-    ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr);
-    ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface);
-    IUnknown_Release(punk);
-
-    ok(unk_outer.AddRef_called == 1, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called);
-    ok(unk_outer.Release_called == 1, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called);
-    unk_outer.AddRef_called = 0;
-    unk_outer.Release_called = 0;
-
-    hr = IUnknown_QueryInterface(pmapper, &IID_IFilterMapper3, (void **)&punk);
-    ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr);
-    ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface);
-    IUnknown_Release(punk);
-
-    ok(unk_outer.AddRef_called == 1, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called);
-    ok(unk_outer.Release_called == 1, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called);
-
-    IUnknown_Release(pmapper);
+    ULONG ref;
+
+    mapper = (IFilterMapper3 *)0xdeadbeef;
+    hr = CoCreateInstance(&CLSID_FilterMapper2, &test_outer, CLSCTX_INPROC_SERVER,
+            &IID_IFilterMapper3, (void **)&mapper);
+    ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
+    ok(!mapper, "Got interface %p.\n", mapper);
+
+    hr = CoCreateInstance(&CLSID_FilterMapper2, &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_IFilterMapper3, (void **)&mapper);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+    hr = IFilterMapper3_QueryInterface(mapper, &IID_IUnknown, (void **)&unk2);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
+
+    hr = IFilterMapper3_QueryInterface(mapper, &IID_IFilterMapper3, (void **)&mapper2);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(mapper2 == (IFilterMapper3 *)0xdeadbeef, "Got unexpected IFilterMapper3 %p.\n", mapper2);
+
+    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 = IFilterMapper3_QueryInterface(mapper, &test_iid, (void **)&unk2);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
+
+    IFilterMapper3_Release(mapper);
+    ref = IUnknown_Release(unk);
+    ok(!ref, "Got unexpected refcount %d.\n", ref);
+    ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
 }
 
 START_TEST(filtermapper)
@@ -628,7 +637,7 @@ START_TEST(filtermapper)
     test_ifiltermapper_from_filtergraph();
     test_register_filter_with_null_clsMinorType();
     test_parse_filter_data();
-    test_aggregate_filter_mapper();
+    test_aggregation();
 
     CoUninitialize();
 }
diff --git a/dlls/quartz/tests/misc.c b/dlls/quartz/tests/misc.c
deleted file mode 100644
index 16b6d40ce4..0000000000
--- a/dlls/quartz/tests/misc.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Misc unit tests for Quartz
- *
- * Copyright (C) 2007 Google (Lei Zhang)
- *
- * 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 "wine/test.h"
-#include "dshow.h"
-
-#define QI_SUCCEED(iface, riid, ppv) hr = IUnknown_QueryInterface(iface, &riid, (LPVOID*)&ppv); \
-    ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr); \
-    ok(ppv != NULL, "Pointer is NULL\n");
-
-#define QI_FAIL(iface, riid, ppv) hr = IUnknown_QueryInterface(iface, &riid, (LPVOID*)&ppv); \
-    ok(hr == E_NOINTERFACE, "IUnknown_QueryInterface returned %x\n", hr); \
-    ok(ppv == NULL, "Pointer is %p\n", ppv);
-
-#define ADDREF_EXPECT(iface, num) if (iface) { \
-    refCount = IUnknown_AddRef(iface); \
-    ok(refCount == num, "IUnknown_AddRef should return %d, got %d\n", num, refCount); \
-}
-
-#define RELEASE_EXPECT(iface, num) if (iface) { \
-    refCount = IUnknown_Release(iface); \
-    ok(refCount == num, "IUnknown_Release should return %d, got %d\n", num, refCount); \
-}
-
-static void test_aggregation(const CLSID clsidOuter, const CLSID clsidInner,
-                             const IID iidOuter, const IID iidInner)
-{
-    HRESULT hr;
-    ULONG refCount;
-    IUnknown *pUnkOuter = NULL;
-    IUnknown *pUnkInner = NULL;
-    IUnknown *pUnkInnerFail = NULL;
-    IUnknown *pUnkOuterTest = NULL;
-    IUnknown *pUnkInnerTest = NULL;
-    IUnknown *pUnkAggregatee = NULL;
-    IUnknown *pUnkAggregator = NULL;
-    IUnknown *pUnkTest = NULL;
-
-    hr = CoCreateInstance(&clsidOuter, NULL, CLSCTX_INPROC_SERVER,
-                          &IID_IUnknown, (LPVOID*)&pUnkOuter);
-    ok(hr == S_OK, "CoCreateInstance failed with %x\n", hr);
-    ok(pUnkOuter != NULL, "pUnkOuter is NULL\n");
-
-    if (!pUnkOuter)
-    {
-        skip("pUnkOuter is NULL\n");
-        return;
-    }
-
-    /* for aggregation, we should only be able to request IUnknown */
-    hr = CoCreateInstance(&clsidInner, pUnkOuter, CLSCTX_INPROC_SERVER,
-                          &iidInner, (LPVOID*)&pUnkInnerFail);
-    if (hr == REGDB_E_CLASSNOTREG)
-    {
-        skip("Class not registered\n");
-        return;
-    }
-    ok(hr == E_NOINTERFACE, "CoCreateInstance returned %x\n", hr);
-    ok(pUnkInnerFail == NULL, "pUnkInnerFail is not NULL\n");
-
-    /* aggregation, request IUnknown */
-    hr = CoCreateInstance(&clsidInner, pUnkOuter, CLSCTX_INPROC_SERVER,
-                          &IID_IUnknown, (LPVOID*)&pUnkInner);
-    ok(hr == S_OK, "CoCreateInstance returned %x\n", hr);
-    ok(pUnkInner != NULL, "pUnkInner is NULL\n");
-
-    if (!pUnkInner)
-    {
-        skip("pUnkInner is NULL\n");
-        return;
-    }
-
-    ADDREF_EXPECT(pUnkOuter, 2);
-    ADDREF_EXPECT(pUnkInner, 2);
-    RELEASE_EXPECT(pUnkOuter, 1);
-    RELEASE_EXPECT(pUnkInner, 1);
-
-    QI_FAIL(pUnkOuter, iidInner, pUnkAggregatee);
-    QI_FAIL(pUnkInner, iidOuter, pUnkAggregator);
-
-    /* these QueryInterface calls should work */
-    QI_SUCCEED(pUnkOuter, iidOuter, pUnkAggregator);
-    QI_SUCCEED(pUnkOuter, IID_IUnknown, pUnkOuterTest);
-    /* IGraphConfig interface comes with DirectShow 9 */
-    if(IsEqualGUID(&IID_IGraphConfig, &iidInner))
-    {
-        hr = IUnknown_QueryInterface(pUnkInner, &iidInner, (LPVOID*)&pUnkAggregatee);
-        ok(hr == S_OK || broken(hr == E_NOINTERFACE), "IUnknown_QueryInterface returned %x\n", hr);
-        ok(pUnkAggregatee != NULL || broken(!pUnkAggregatee), "Pointer is NULL\n");
-    }
-    else
-    {
-        QI_SUCCEED(pUnkInner, iidInner, pUnkAggregatee);
-    }
-    QI_SUCCEED(pUnkInner, IID_IUnknown, pUnkInnerTest);
-
-    if (!pUnkAggregator || !pUnkOuterTest || !pUnkAggregatee
-                    || !pUnkInnerTest)
-    {
-        skip("One of the required interfaces is NULL\n");
-        return;
-    }
-
-    ADDREF_EXPECT(pUnkAggregator, 5);
-    ADDREF_EXPECT(pUnkOuterTest, 6);
-    ADDREF_EXPECT(pUnkAggregatee, 7);
-    ADDREF_EXPECT(pUnkInnerTest, 3);
-    RELEASE_EXPECT(pUnkAggregator, 6);
-    RELEASE_EXPECT(pUnkOuterTest, 5);
-    RELEASE_EXPECT(pUnkAggregatee, 4);
-    RELEASE_EXPECT(pUnkInnerTest, 2);
-
-    QI_SUCCEED(pUnkAggregator, IID_IUnknown, pUnkTest);
-    QI_SUCCEED(pUnkOuterTest, IID_IUnknown, pUnkTest);
-    QI_SUCCEED(pUnkAggregatee, IID_IUnknown, pUnkTest);
-    QI_SUCCEED(pUnkInnerTest, IID_IUnknown, pUnkTest);
-
-    QI_FAIL(pUnkAggregator, iidInner, pUnkTest);
-    QI_FAIL(pUnkOuterTest, iidInner, pUnkTest);
-    QI_FAIL(pUnkAggregatee, iidInner, pUnkTest);
-    QI_SUCCEED(pUnkInnerTest, iidInner, pUnkTest);
-
-    QI_SUCCEED(pUnkAggregator, iidOuter, pUnkTest);
-    QI_SUCCEED(pUnkOuterTest, iidOuter, pUnkTest);
-    QI_SUCCEED(pUnkAggregatee, iidOuter, pUnkTest);
-    QI_FAIL(pUnkInnerTest, iidOuter, pUnkTest);
-
-    RELEASE_EXPECT(pUnkAggregator, 10);
-    RELEASE_EXPECT(pUnkOuterTest, 9);
-    RELEASE_EXPECT(pUnkAggregatee, 8);
-    RELEASE_EXPECT(pUnkInnerTest, 2);
-    RELEASE_EXPECT(pUnkOuter, 7);
-    RELEASE_EXPECT(pUnkInner, 1);
-
-    do
-    {
-        refCount = IUnknown_Release(pUnkInner);
-    } while (refCount);
-
-    do
-    {
-        refCount = IUnknown_Release(pUnkOuter);
-    } while (refCount);
-}
-
-static void test_null_renderer_aggregations(void)
-{
-    const IID * iids[] = {
-        &IID_IMediaFilter, &IID_IBaseFilter
-    };
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(iids); i++)
-    {
-        test_aggregation(CLSID_SystemClock, CLSID_NullRenderer, IID_IReferenceClock, *iids[i]);
-    }
-}
-
-static void test_video_renderer_aggregations(void)
-{
-    const IID * iids[] = {
-        &IID_IMediaFilter, &IID_IBaseFilter, &IID_IBasicVideo, &IID_IVideoWindow
-    };
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(iids); i++)
-    {
-        test_aggregation(CLSID_SystemClock, CLSID_VideoRenderer,
-                         IID_IReferenceClock, *iids[i]);
-    }
-}
-
-static void test_filter_graph_aggregations(void)
-{
-    const IID * iids[] = {
-        &IID_IFilterGraph2, &IID_IMediaControl, &IID_IGraphBuilder,
-        &IID_IFilterGraph, &IID_IMediaSeeking, &IID_IBasicAudio, &IID_IBasicVideo,
-        &IID_IVideoWindow, &IID_IMediaEventEx, &IID_IMediaFilter,
-        &IID_IMediaEventSink, &IID_IGraphConfig, &IID_IMediaPosition
-    };
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(iids); i++)
-    {
-        test_aggregation(CLSID_SystemClock, CLSID_FilterGraph,
-                         IID_IReferenceClock, *iids[i]);
-    }
-}
-
-static void test_filter_mapper_aggregations(void)
-{
-    const IID * iids[] = {
-        &IID_IFilterMapper2, &IID_IFilterMapper
-    };
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(iids); i++)
-    {
-        test_aggregation(CLSID_SystemClock, CLSID_FilterMapper2,
-                         IID_IReferenceClock, *iids[i]);
-    }
-}
-
-START_TEST(misc)
-{
-    CoInitialize(NULL);
-
-    test_null_renderer_aggregations();
-    test_video_renderer_aggregations();
-    test_filter_graph_aggregations();
-    test_filter_mapper_aggregations();
-
-    CoUninitialize();
-}
diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c
index 48e21fc427..ec31303480 100644
--- a/dlls/quartz/tests/videorenderer.c
+++ b/dlls/quartz/tests/videorenderer.c
@@ -99,6 +99,99 @@ static void test_interfaces(void)
     IBaseFilter_Release(filter);
 }
 
+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_IBaseFilter)
+            || 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)
+{
+    IBaseFilter *filter, *filter2;
+    IUnknown *unk, *unk2;
+    HRESULT hr;
+    ULONG ref;
+
+    filter = (IBaseFilter *)0xdeadbeef;
+    hr = CoCreateInstance(&CLSID_VideoRenderer, &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_VideoRenderer, &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_enum_pins(void)
 {
@@ -422,6 +515,7 @@ START_TEST(videorenderer)
     CoInitialize(NULL);
 
     test_interfaces();
+    test_aggregation();
     test_enum_pins();
     test_find_pin();
     test_pin_info();
diff --git a/dlls/quartz/tests/vmr7.c b/dlls/quartz/tests/vmr7.c
index 8a16039673..5defcc5245 100644
--- a/dlls/quartz/tests/vmr7.c
+++ b/dlls/quartz/tests/vmr7.c
@@ -307,6 +307,100 @@ static void test_interfaces(void)
     ok(!ref, "Got outstanding refcount %d.\n", ref);
 }
 
+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_IBaseFilter)
+            || 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)
+{
+    IBaseFilter *filter, *filter2;
+    IUnknown *unk, *unk2;
+    HRESULT hr;
+    ULONG ref;
+
+    filter = (IBaseFilter *)0xdeadbeef;
+    hr = CoCreateInstance(&CLSID_VideoMixingRenderer, &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_VideoMixingRenderer, &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_enum_pins(void)
 {
     IBaseFilter *filter = create_vmr7(0);
@@ -697,6 +791,7 @@ START_TEST(vmr7)
 
     test_filter_config();
     test_interfaces();
+    test_aggregation();
     test_enum_pins();
     test_find_pin();
     test_pin_info();
diff --git a/dlls/quartz/tests/vmr9.c b/dlls/quartz/tests/vmr9.c
index 6c1c314502..0f3e470d6e 100644
--- a/dlls/quartz/tests/vmr9.c
+++ b/dlls/quartz/tests/vmr9.c
@@ -300,6 +300,100 @@ static void test_interfaces(void)
     ok(!ref, "Got outstanding refcount %d.\n", ref);
 }
 
+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_IBaseFilter)
+            || 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)
+{
+    IBaseFilter *filter, *filter2;
+    IUnknown *unk, *unk2;
+    HRESULT hr;
+    ULONG ref;
+
+    filter = (IBaseFilter *)0xdeadbeef;
+    hr = CoCreateInstance(&CLSID_VideoMixingRenderer, &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_VideoMixingRenderer, &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 HRESULT set_mixing_mode(IBaseFilter *filter)
 {
     IVMRFilterConfig9 *config;
@@ -687,6 +781,7 @@ START_TEST(vmr9)
 
     test_filter_config();
     test_interfaces();
+    test_aggregation();
     test_enum_pins();
     test_find_pin();
     test_pin_info();
-- 
2.21.0




More information about the wine-devel mailing list