Reactos
at master 233 lines 7.5 kB view raw
1/* 2 * Misc unit tests for Quartz 3 * 4 * Copyright (C) 2007 Google (Lei Zhang) 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21#define COBJMACROS 22 23#include "wine/test.h" 24#include "dshow.h" 25 26#define QI_SUCCEED(iface, riid, ppv) hr = IUnknown_QueryInterface(iface, &riid, (LPVOID*)&ppv); \ 27 ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr); \ 28 ok(ppv != NULL, "Pointer is NULL\n"); 29 30#define QI_FAIL(iface, riid, ppv) hr = IUnknown_QueryInterface(iface, &riid, (LPVOID*)&ppv); \ 31 ok(hr == E_NOINTERFACE, "IUnknown_QueryInterface returned %x\n", hr); \ 32 ok(ppv == NULL, "Pointer is %p\n", ppv); 33 34#define ADDREF_EXPECT(iface, num) if (iface) { \ 35 refCount = IUnknown_AddRef(iface); \ 36 ok(refCount == num, "IUnknown_AddRef should return %d, got %d\n", num, refCount); \ 37} 38 39#define RELEASE_EXPECT(iface, num) if (iface) { \ 40 refCount = IUnknown_Release(iface); \ 41 ok(refCount == num, "IUnknown_Release should return %d, got %d\n", num, refCount); \ 42} 43 44static void test_aggregation(const CLSID clsidOuter, const CLSID clsidInner, 45 const IID iidOuter, const IID iidInner) 46{ 47 HRESULT hr; 48 ULONG refCount; 49 IUnknown *pUnkOuter = NULL; 50 IUnknown *pUnkInner = NULL; 51 IUnknown *pUnkInnerFail = NULL; 52 IUnknown *pUnkOuterTest = NULL; 53 IUnknown *pUnkInnerTest = NULL; 54 IUnknown *pUnkAggregatee = NULL; 55 IUnknown *pUnkAggregator = NULL; 56 IUnknown *pUnkTest = NULL; 57 58 hr = CoCreateInstance(&clsidOuter, NULL, CLSCTX_INPROC_SERVER, 59 &IID_IUnknown, (LPVOID*)&pUnkOuter); 60 ok(hr == S_OK, "CoCreateInstance failed with %x\n", hr); 61 ok(pUnkOuter != NULL, "pUnkOuter is NULL\n"); 62 63 if (!pUnkOuter) 64 { 65 skip("pUnkOuter is NULL\n"); 66 return; 67 } 68 69 /* for aggregation, we should only be able to request IUnknown */ 70 hr = CoCreateInstance(&clsidInner, pUnkOuter, CLSCTX_INPROC_SERVER, 71 &iidInner, (LPVOID*)&pUnkInnerFail); 72 if (hr == REGDB_E_CLASSNOTREG) 73 { 74 skip("Class not registered\n"); 75 return; 76 } 77 ok(hr == E_NOINTERFACE, "CoCreateInstance returned %x\n", hr); 78 ok(pUnkInnerFail == NULL, "pUnkInnerFail is not NULL\n"); 79 80 /* aggregation, request IUnknown */ 81 hr = CoCreateInstance(&clsidInner, pUnkOuter, CLSCTX_INPROC_SERVER, 82 &IID_IUnknown, (LPVOID*)&pUnkInner); 83 ok(hr == S_OK, "CoCreateInstance returned %x\n", hr); 84 ok(pUnkInner != NULL, "pUnkInner is NULL\n"); 85 86 if (!pUnkInner) 87 { 88 skip("pUnkInner is NULL\n"); 89 return; 90 } 91 92 ADDREF_EXPECT(pUnkOuter, 2); 93 ADDREF_EXPECT(pUnkInner, 2); 94 RELEASE_EXPECT(pUnkOuter, 1); 95 RELEASE_EXPECT(pUnkInner, 1); 96 97 QI_FAIL(pUnkOuter, iidInner, pUnkAggregatee); 98 QI_FAIL(pUnkInner, iidOuter, pUnkAggregator); 99 100 /* these QueryInterface calls should work */ 101 QI_SUCCEED(pUnkOuter, iidOuter, pUnkAggregator); 102 QI_SUCCEED(pUnkOuter, IID_IUnknown, pUnkOuterTest); 103 /* IGraphConfig interface comes with DirectShow 9 */ 104 if(IsEqualGUID(&IID_IGraphConfig, &iidInner)) 105 { 106 hr = IUnknown_QueryInterface(pUnkInner, &iidInner, (LPVOID*)&pUnkAggregatee); 107 ok(hr == S_OK || broken(hr == E_NOINTERFACE), "IUnknown_QueryInterface returned %x\n", hr); 108 ok(pUnkAggregatee != NULL || broken(!pUnkAggregatee), "Pointer is NULL\n"); 109 } 110 else 111 { 112 QI_SUCCEED(pUnkInner, iidInner, pUnkAggregatee); 113 } 114 QI_SUCCEED(pUnkInner, IID_IUnknown, pUnkInnerTest); 115 116 if (!pUnkAggregator || !pUnkOuterTest || !pUnkAggregatee 117 || !pUnkInnerTest) 118 { 119 skip("One of the required interfaces is NULL\n"); 120 return; 121 } 122 123 ADDREF_EXPECT(pUnkAggregator, 5); 124 ADDREF_EXPECT(pUnkOuterTest, 6); 125 ADDREF_EXPECT(pUnkAggregatee, 7); 126 ADDREF_EXPECT(pUnkInnerTest, 3); 127 RELEASE_EXPECT(pUnkAggregator, 6); 128 RELEASE_EXPECT(pUnkOuterTest, 5); 129 RELEASE_EXPECT(pUnkAggregatee, 4); 130 RELEASE_EXPECT(pUnkInnerTest, 2); 131 132 QI_SUCCEED(pUnkAggregator, IID_IUnknown, pUnkTest); 133 QI_SUCCEED(pUnkOuterTest, IID_IUnknown, pUnkTest); 134 QI_SUCCEED(pUnkAggregatee, IID_IUnknown, pUnkTest); 135 QI_SUCCEED(pUnkInnerTest, IID_IUnknown, pUnkTest); 136 137 QI_FAIL(pUnkAggregator, iidInner, pUnkTest); 138 QI_FAIL(pUnkOuterTest, iidInner, pUnkTest); 139 QI_FAIL(pUnkAggregatee, iidInner, pUnkTest); 140 QI_SUCCEED(pUnkInnerTest, iidInner, pUnkTest); 141 142 QI_SUCCEED(pUnkAggregator, iidOuter, pUnkTest); 143 QI_SUCCEED(pUnkOuterTest, iidOuter, pUnkTest); 144 QI_SUCCEED(pUnkAggregatee, iidOuter, pUnkTest); 145 QI_FAIL(pUnkInnerTest, iidOuter, pUnkTest); 146 147 RELEASE_EXPECT(pUnkAggregator, 10); 148 RELEASE_EXPECT(pUnkOuterTest, 9); 149 RELEASE_EXPECT(pUnkAggregatee, 8); 150 RELEASE_EXPECT(pUnkInnerTest, 2); 151 RELEASE_EXPECT(pUnkOuter, 7); 152 RELEASE_EXPECT(pUnkInner, 1); 153 154 do 155 { 156 refCount = IUnknown_Release(pUnkInner); 157 } while (refCount); 158 159 do 160 { 161 refCount = IUnknown_Release(pUnkOuter); 162 } while (refCount); 163} 164 165static void test_null_renderer_aggregations(void) 166{ 167 const IID * iids[] = { 168 &IID_IMediaFilter, &IID_IBaseFilter 169 }; 170 int i; 171 172 for (i = 0; i < sizeof(iids) / sizeof(iids[0]); i++) 173 { 174 test_aggregation(CLSID_SystemClock, CLSID_NullRenderer, IID_IReferenceClock, *iids[i]); 175 } 176} 177 178static void test_video_renderer_aggregations(void) 179{ 180 const IID * iids[] = { 181 &IID_IMediaFilter, &IID_IBaseFilter, &IID_IBasicVideo, &IID_IVideoWindow 182 }; 183 int i; 184 185 for (i = 0; i < sizeof(iids) / sizeof(iids[0]); i++) 186 { 187 test_aggregation(CLSID_SystemClock, CLSID_VideoRenderer, 188 IID_IReferenceClock, *iids[i]); 189 } 190} 191 192static void test_filter_graph_aggregations(void) 193{ 194 const IID * iids[] = { 195 &IID_IFilterGraph2, &IID_IMediaControl, &IID_IGraphBuilder, 196 &IID_IFilterGraph, &IID_IMediaSeeking, &IID_IBasicAudio, &IID_IBasicVideo, 197 &IID_IVideoWindow, &IID_IMediaEventEx, &IID_IMediaFilter, 198 &IID_IMediaEventSink, &IID_IGraphConfig, &IID_IMediaPosition 199 }; 200 int i; 201 202 for (i = 0; i < sizeof(iids) / sizeof(iids[0]); i++) 203 { 204 test_aggregation(CLSID_SystemClock, CLSID_FilterGraph, 205 IID_IReferenceClock, *iids[i]); 206 } 207} 208 209static void test_filter_mapper_aggregations(void) 210{ 211 const IID * iids[] = { 212 &IID_IFilterMapper2, &IID_IFilterMapper 213 }; 214 int i; 215 216 for (i = 0; i < sizeof(iids) / sizeof(iids[0]); i++) 217 { 218 test_aggregation(CLSID_SystemClock, CLSID_FilterMapper2, 219 IID_IReferenceClock, *iids[i]); 220 } 221} 222 223START_TEST(misc) 224{ 225 CoInitialize(NULL); 226 227 test_null_renderer_aggregations(); 228 test_video_renderer_aggregations(); 229 test_filter_graph_aggregations(); 230 test_filter_mapper_aggregations(); 231 232 CoUninitialize(); 233}