2 * Filtermapper unit tests for Quartz
4 * Copyright (C) 2008 Alexander Dorofeyev
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.
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.
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
23 #include "wine/test.h"
27 #include "wine/winternl.h"
31 DEFINE_GUID(GUID_NULL
,0,0,0,0,0,0,0,0,0,0,0);
33 /* Helper function, checks if filter with given name was enumerated. */
34 static BOOL
enum_find_filter(const WCHAR
*wszFilterName
, IEnumMoniker
*pEnum
)
36 IMoniker
*pMoniker
= NULL
;
40 static const WCHAR wszFriendlyName
[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
42 while(!found
&& IEnumMoniker_Next(pEnum
, 1, &pMoniker
, &nb
) == S_OK
)
44 IPropertyBag
* pPropBagCat
= NULL
;
49 hr
= IMoniker_BindToStorage(pMoniker
, NULL
, NULL
, &IID_IPropertyBag
, (LPVOID
*)&pPropBagCat
);
50 ok(SUCCEEDED(hr
), "IMoniker_BindToStorage failed with %x\n", hr
);
52 hr
= IPropertyBag_Read(pPropBagCat
, wszFriendlyName
, &var
, NULL
);
53 ok(SUCCEEDED(hr
), "IPropertyBag_Read failed with %x\n", hr
);
55 if (!lstrcmpW(V_BSTR(&var
), wszFilterName
))
58 IPropertyBag_Release(pPropBagCat
);
59 IMoniker_Release(pMoniker
);
66 static void test_fm2_enummatchingfilters(void)
68 IEnumRegFilters
*enum_reg
;
69 IFilterMapper2
*pMapper
= NULL
;
70 IFilterMapper
*mapper
;
73 REGFILTERPINS2 rgPins2
[2];
74 REGPINTYPES rgPinType
;
75 static const WCHAR wszFilterName1
[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', '1', 0 };
76 static const WCHAR wszFilterName2
[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', '2', 0 };
79 IEnumMoniker
*pEnum
= NULL
;
80 BOOL found
, registered
= TRUE
;
84 ZeroMemory(&rgf2
, sizeof(rgf2
));
86 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
,
87 &IID_IFilterMapper2
, (LPVOID
*)&pMapper
);
88 ok(hr
== S_OK
, "CoCreateInstance failed with %x\n", hr
);
89 if (FAILED(hr
)) goto out
;
91 hr
= CoCreateGuid(&clsidFilter1
);
92 ok(hr
== S_OK
, "CoCreateGuid failed with %x\n", hr
);
93 hr
= CoCreateGuid(&clsidFilter2
);
94 ok(hr
== S_OK
, "CoCreateGuid failed with %x\n", hr
);
96 /* Test that a test renderer filter is returned when enumerating filters with bRender=FALSE */
98 rgf2
.dwMerit
= MERIT_UNLIKELY
;
99 S2(U(rgf2
)).cPins2
= 1;
100 S2(U(rgf2
)).rgPins2
= rgPins2
;
102 rgPins2
[0].dwFlags
= REG_PINFLAG_B_RENDERER
;
103 rgPins2
[0].cInstances
= 1;
104 rgPins2
[0].nMediaTypes
= 1;
105 rgPins2
[0].lpMediaType
= &rgPinType
;
106 rgPins2
[0].nMediums
= 0;
107 rgPins2
[0].lpMedium
= NULL
;
108 rgPins2
[0].clsPinCategory
= NULL
;
110 rgPinType
.clsMajorType
= &GUID_NULL
;
111 rgPinType
.clsMinorType
= &GUID_NULL
;
113 hr
= IFilterMapper2_RegisterFilter(pMapper
, &clsidFilter1
, wszFilterName1
, NULL
,
114 &CLSID_LegacyAmFilterCategory
, NULL
, &rgf2
);
115 if (hr
== E_ACCESSDENIED
)
118 skip("Not authorized to register filters\n");
122 ok(hr
== S_OK
, "IFilterMapper2_RegisterFilter failed with %x\n", hr
);
124 rgPins2
[0].dwFlags
= 0;
126 rgPins2
[1].dwFlags
= REG_PINFLAG_B_OUTPUT
;
127 rgPins2
[1].cInstances
= 1;
128 rgPins2
[1].nMediaTypes
= 1;
129 rgPins2
[1].lpMediaType
= &rgPinType
;
130 rgPins2
[1].nMediums
= 0;
131 rgPins2
[1].lpMedium
= NULL
;
132 rgPins2
[1].clsPinCategory
= NULL
;
134 S2(U(rgf2
)).cPins2
= 2;
136 hr
= IFilterMapper2_RegisterFilter(pMapper
, &clsidFilter2
, wszFilterName2
, NULL
,
137 &CLSID_LegacyAmFilterCategory
, NULL
, &rgf2
);
138 ok(hr
== S_OK
, "IFilterMapper2_RegisterFilter failed with %x\n", hr
);
140 hr
= IFilterMapper2_EnumMatchingFilters(pMapper
, &pEnum
, 0, TRUE
, MERIT_UNLIKELY
, TRUE
,
141 0, NULL
, NULL
, &GUID_NULL
, FALSE
, FALSE
, 0, NULL
, NULL
, &GUID_NULL
);
142 ok(hr
== S_OK
, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr
);
143 if (SUCCEEDED(hr
) && pEnum
)
145 found
= enum_find_filter(wszFilterName1
, pEnum
);
146 ok(found
, "EnumMatchingFilters failed to return the test filter 1\n");
149 if (pEnum
) IEnumMoniker_Release(pEnum
);
152 hr
= IFilterMapper2_EnumMatchingFilters(pMapper
, &pEnum
, 0, TRUE
, MERIT_UNLIKELY
, TRUE
,
153 0, NULL
, NULL
, &GUID_NULL
, FALSE
, FALSE
, 0, NULL
, NULL
, &GUID_NULL
);
154 ok(hr
== S_OK
, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr
);
155 if (SUCCEEDED(hr
) && pEnum
)
157 found
= enum_find_filter(wszFilterName2
, pEnum
);
158 ok(found
, "EnumMatchingFilters failed to return the test filter 2\n");
161 if (pEnum
) IEnumMoniker_Release(pEnum
);
164 /* Non renderer must not be returned with bRender=TRUE */
166 hr
= IFilterMapper2_EnumMatchingFilters(pMapper
, &pEnum
, 0, TRUE
, MERIT_UNLIKELY
, TRUE
,
167 0, NULL
, NULL
, &GUID_NULL
, TRUE
, FALSE
, 0, NULL
, NULL
, &GUID_NULL
);
168 ok(hr
== S_OK
, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr
);
170 if (SUCCEEDED(hr
) && pEnum
)
172 found
= enum_find_filter(wszFilterName1
, pEnum
);
173 ok(found
, "EnumMatchingFilters failed to return the test filter 1\n");
176 hr
= IFilterMapper2_QueryInterface(pMapper
, &IID_IFilterMapper
, (void **)&mapper
);
177 ok(hr
== S_OK
, "QueryInterface(IFilterMapper) failed: %#x\n", hr
);
180 hr
= IFilterMapper_EnumMatchingFilters(mapper
, &enum_reg
, MERIT_UNLIKELY
,
181 FALSE
, GUID_NULL
, GUID_NULL
, FALSE
, FALSE
, GUID_NULL
, GUID_NULL
);
182 ok(hr
== S_OK
, "IFilterMapper_EnumMatchingFilters failed: %#x\n", hr
);
183 while (!found
&& IEnumRegFilters_Next(enum_reg
, 1, ®filter
, &count
) == S_OK
)
185 if (!lstrcmpW(regfilter
->Name
, wszFilterName1
) && IsEqualGUID(&clsidFilter1
, ®filter
->Clsid
))
188 IEnumRegFilters_Release(enum_reg
);
189 ok(found
, "IFilterMapper didn't find filter\n");
192 if (pEnum
) IEnumMoniker_Release(pEnum
);
195 hr
= IFilterMapper2_EnumMatchingFilters(pMapper
, &pEnum
, 0, TRUE
, MERIT_UNLIKELY
, TRUE
,
196 0, NULL
, NULL
, &GUID_NULL
, TRUE
, FALSE
, 0, NULL
, NULL
, &GUID_NULL
);
197 ok(hr
== S_OK
, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr
);
199 if (SUCCEEDED(hr
) && pEnum
)
201 found
= enum_find_filter(wszFilterName2
, pEnum
);
202 ok(!found
, "EnumMatchingFilters should not return the test filter 2\n");
207 hr
= IFilterMapper2_UnregisterFilter(pMapper
, &CLSID_LegacyAmFilterCategory
, NULL
,
209 ok(SUCCEEDED(hr
), "IFilterMapper2_UnregisterFilter failed with %x\n", hr
);
211 hr
= IFilterMapper2_UnregisterFilter(pMapper
, &CLSID_LegacyAmFilterCategory
, NULL
,
213 ok(SUCCEEDED(hr
), "IFilterMapper2_UnregisterFilter failed with %x\n", hr
);
218 if (pEnum
) IEnumMoniker_Release(pEnum
);
219 if (pMapper
) IFilterMapper2_Release(pMapper
);
222 static void test_legacy_filter_registration(void)
224 static const WCHAR testfilterW
[] = {'T','e','s','t','f','i','l','t','e','r',0};
225 static const WCHAR clsidW
[] = {'C','L','S','I','D','\\',0};
226 static const WCHAR pinW
[] = {'P','i','n','1',0};
227 IEnumRegFilters
*enum_reg
;
228 IEnumMoniker
*enum_mon
;
229 IFilterMapper2
*mapper2
;
230 IFilterMapper
*mapper
;
231 REGFILTER
*regfilter
;
232 WCHAR clsidstring
[40];
241 /* Register* functions need a filter class key to write pin and pin media
242 * type data to. Create a bogus class key for it. */
243 CoCreateGuid(&clsid
);
244 StringFromGUID2(&clsid
, clsidstring
, sizeof(clsidstring
));
245 lstrcpyW(key_name
, clsidW
);
246 lstrcatW(key_name
, clsidstring
);
247 ret
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, key_name
, 0, NULL
, 0, KEY_WRITE
, NULL
, &hkey
, NULL
);
248 if (ret
== ERROR_ACCESS_DENIED
)
250 skip("Not authorized to register filters\n");
254 /* Test if legacy filter registration scheme works (filter is added to HKCR\Filter). IFilterMapper_RegisterFilter
255 * registers in this way. Filters so registered must then be accessible through both IFilterMapper_EnumMatchingFilters
256 * and IFilterMapper2_EnumMatchingFilters. */
257 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterMapper2
, (void **)&mapper2
);
258 ok(hr
== S_OK
, "CoCreateInstance failed with %x\n", hr
);
260 hr
= IFilterMapper2_QueryInterface(mapper2
, &IID_IFilterMapper
, (void **)&mapper
);
261 ok(hr
== S_OK
, "IFilterMapper2_QueryInterface failed with %x\n", hr
);
263 /* Set default value - this is interpreted as "friendly name" later. */
264 RegSetValueExW(hkey
, NULL
, 0, REG_SZ
, (BYTE
*)testfilterW
, sizeof(testfilterW
));
267 hr
= IFilterMapper_RegisterFilter(mapper
, clsid
, testfilterW
, MERIT_UNLIKELY
);
268 ok(hr
== S_OK
, "RegisterFilter failed: %#x\n", hr
);
270 hr
= IFilterMapper_RegisterPin(mapper
, clsid
, pinW
, TRUE
, FALSE
, FALSE
, FALSE
, GUID_NULL
, NULL
);
271 ok(hr
== S_OK
, "RegisterPin failed: %#x\n", hr
);
273 hr
= IFilterMapper_RegisterPinType(mapper
, clsid
, pinW
, GUID_NULL
, GUID_NULL
);
274 ok(hr
== S_OK
, "RegisterPinType failed: %#x\n", hr
);
276 hr
= IFilterMapper2_EnumMatchingFilters(mapper2
, &enum_mon
, 0, TRUE
, MERIT_UNLIKELY
, TRUE
,
277 0, NULL
, NULL
, &GUID_NULL
, FALSE
, FALSE
, 0, NULL
, NULL
, &GUID_NULL
);
278 ok(hr
== S_OK
, "IFilterMapper2_EnumMatchingFilters failed: %x\n", hr
);
279 ok(enum_find_filter(testfilterW
, enum_mon
), "IFilterMapper2 didn't find filter\n");
280 IEnumMoniker_Release(enum_mon
);
283 hr
= IFilterMapper_EnumMatchingFilters(mapper
, &enum_reg
, MERIT_UNLIKELY
, TRUE
, GUID_NULL
, GUID_NULL
,
284 FALSE
, FALSE
, GUID_NULL
, GUID_NULL
);
285 ok(hr
== S_OK
, "IFilterMapper_EnumMatchingFilters failed with %x\n", hr
);
286 while(!found
&& IEnumRegFilters_Next(enum_reg
, 1, ®filter
, &count
) == S_OK
)
288 if (!lstrcmpW(regfilter
->Name
, testfilterW
) && IsEqualGUID(&clsid
, ®filter
->Clsid
))
291 IEnumRegFilters_Release(enum_reg
);
292 ok(found
, "IFilterMapper didn't find filter\n");
294 hr
= IFilterMapper_UnregisterFilter(mapper
, clsid
);
295 ok(hr
== S_OK
, "FilterMapper_UnregisterFilter failed with %x\n", hr
);
297 hr
= IFilterMapper2_EnumMatchingFilters(mapper2
, &enum_mon
, 0, TRUE
, MERIT_UNLIKELY
, TRUE
,
298 0, NULL
, NULL
, &GUID_NULL
, FALSE
, FALSE
, 0, NULL
, NULL
, &GUID_NULL
);
299 ok(hr
== S_OK
, "IFilterMapper2_EnumMatchingFilters failed: %x\n", hr
);
300 ok(!enum_find_filter(testfilterW
, enum_mon
), "IFilterMapper2 shouldn't find filter\n");
301 IEnumMoniker_Release(enum_mon
);
304 hr
= IFilterMapper_EnumMatchingFilters(mapper
, &enum_reg
, MERIT_UNLIKELY
, TRUE
, GUID_NULL
, GUID_NULL
,
305 FALSE
, FALSE
, GUID_NULL
, GUID_NULL
);
306 ok(hr
== S_OK
, "IFilterMapper_EnumMatchingFilters failed with %x\n", hr
);
307 while(!found
&& IEnumRegFilters_Next(enum_reg
, 1, ®filter
, &count
) == S_OK
)
309 if (!lstrcmpW(regfilter
->Name
, testfilterW
) && IsEqualGUID(&clsid
, ®filter
->Clsid
))
312 IEnumRegFilters_Release(enum_reg
);
313 ok(!found
, "IFilterMapper shouldn't find filter\n");
315 ret
= RegDeleteKeyW(HKEY_CLASSES_ROOT
, key_name
);
316 ok(!ret
, "RegDeleteKeyA failed: %lu\n", ret
);
318 hr
= IFilterMapper_RegisterFilter(mapper
, clsid
, testfilterW
, MERIT_UNLIKELY
);
319 ok(hr
== S_OK
, "RegisterFilter failed: %#x\n", hr
);
321 hr
= IFilterMapper_UnregisterFilter(mapper
, clsid
);
322 ok(hr
== S_OK
, "FilterMapper_UnregisterFilter failed with %x\n", hr
);
324 IFilterMapper_Release(mapper
);
325 IFilterMapper2_Release(mapper2
);
328 static ULONG
getRefcount(IUnknown
*iface
)
330 IUnknown_AddRef(iface
);
331 return IUnknown_Release(iface
);
334 static void test_ifiltermapper_from_filtergraph(void)
336 IFilterGraph2
* pgraph2
= NULL
;
337 IFilterMapper2
*pMapper2
= NULL
;
338 IFilterGraph
*filtergraph
= NULL
;
342 hr
= CoCreateInstance(&CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterGraph2
, (LPVOID
*)&pgraph2
);
343 ok(hr
== S_OK
, "CoCreateInstance failed with %08x\n", hr
);
344 if (!pgraph2
) goto out
;
346 hr
= IFilterGraph2_QueryInterface(pgraph2
, &IID_IFilterMapper2
, (LPVOID
*)&pMapper2
);
347 ok(hr
== S_OK
, "IFilterGraph2_QueryInterface failed with %08x\n", hr
);
348 if (!pMapper2
) goto out
;
350 refcount
= getRefcount((IUnknown
*)pgraph2
);
351 ok(refcount
== 2, "unexpected reference count: %u\n", refcount
);
352 refcount
= getRefcount((IUnknown
*)pMapper2
);
353 ok(refcount
== 2, "unexpected reference count: %u\n", refcount
);
355 IFilterMapper2_AddRef(pMapper2
);
356 refcount
= getRefcount((IUnknown
*)pgraph2
);
357 ok(refcount
== 3, "unexpected reference count: %u\n", refcount
);
358 refcount
= getRefcount((IUnknown
*)pMapper2
);
359 ok(refcount
== 3, "unexpected reference count: %u\n", refcount
);
360 IFilterMapper2_Release(pMapper2
);
362 hr
= IFilterMapper2_QueryInterface(pMapper2
, &IID_IFilterGraph
, (LPVOID
*)&filtergraph
);
363 ok(hr
== S_OK
, "IFilterMapper2_QueryInterface failed with %08x\n", hr
);
364 if (!filtergraph
) goto out
;
366 IFilterMapper2_Release(pMapper2
);
368 IFilterGraph_Release(filtergraph
);
371 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterMapper2
, (LPVOID
*)&pMapper2
);
372 ok(hr
== S_OK
, "CoCreateInstance failed with %08x\n", hr
);
373 if (!pMapper2
) goto out
;
375 hr
= IFilterMapper2_QueryInterface(pMapper2
, &IID_IFilterGraph
, (LPVOID
*)&filtergraph
);
376 ok(hr
== E_NOINTERFACE
, "IFilterMapper2_QueryInterface unexpected result: %08x\n", hr
);
380 if (pMapper2
) IFilterMapper2_Release(pMapper2
);
381 if (filtergraph
) IFilterGraph_Release(filtergraph
);
382 if (pgraph2
) IFilterGraph2_Release(pgraph2
);
385 static void test_register_filter_with_null_clsMinorType(void)
387 IFilterMapper2
*pMapper
= NULL
;
390 REGFILTERPINS rgPins
;
391 REGFILTERPINS2 rgPins2
;
392 REGPINTYPES rgPinType
;
393 static WCHAR wszPinName
[] = {'P', 'i', 'n', 0 };
394 static const WCHAR wszFilterName1
[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', '1', 0 };
395 static const WCHAR wszFilterName2
[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', '2', 0 };
399 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
,
400 &IID_IFilterMapper2
, (LPVOID
*)&pMapper
);
401 ok(hr
== S_OK
, "CoCreateInstance failed with %x\n", hr
);
402 if (FAILED(hr
)) goto out
;
404 hr
= CoCreateGuid(&clsidFilter1
);
405 ok(hr
== S_OK
, "CoCreateGuid failed with %x\n", hr
);
406 hr
= CoCreateGuid(&clsidFilter2
);
407 ok(hr
== S_OK
, "CoCreateGuid failed with %x\n", hr
);
409 rgPinType
.clsMajorType
= &GUID_NULL
;
410 /* Make sure quartz accepts it without crashing */
411 rgPinType
.clsMinorType
= NULL
;
413 /* Test with pin descript version 1 */
414 ZeroMemory(&rgf2
, sizeof(rgf2
));
416 rgf2
.dwMerit
= MERIT_UNLIKELY
;
417 S1(U(rgf2
)).cPins
= 1;
418 S1(U(rgf2
)).rgPins
= &rgPins
;
420 rgPins
.strName
= wszPinName
;
421 rgPins
.bRendered
= 1;
425 rgPins
.clsConnectsToFilter
= NULL
;
426 rgPins
.strConnectsToPin
= NULL
;
427 rgPins
.nMediaTypes
= 1;
428 rgPins
.lpMediaType
= &rgPinType
;
430 hr
= IFilterMapper2_RegisterFilter(pMapper
, &clsidFilter1
, wszFilterName1
, NULL
,
431 &CLSID_LegacyAmFilterCategory
, NULL
, &rgf2
);
432 if (hr
== E_ACCESSDENIED
)
434 skip("Not authorized to register filters\n");
437 ok(hr
== S_OK
, "IFilterMapper2_RegisterFilter failed with %x\n", hr
);
439 hr
= IFilterMapper2_UnregisterFilter(pMapper
, &CLSID_LegacyAmFilterCategory
, NULL
, &clsidFilter1
);
440 ok(hr
== S_OK
, "FilterMapper_UnregisterFilter failed with %x\n", hr
);
442 /* Test with pin descript version 2 */
443 ZeroMemory(&rgf2
, sizeof(rgf2
));
445 rgf2
.dwMerit
= MERIT_UNLIKELY
;
446 S2(U(rgf2
)).cPins2
= 1;
447 S2(U(rgf2
)).rgPins2
= &rgPins2
;
449 rgPins2
.dwFlags
= REG_PINFLAG_B_RENDERER
;
450 rgPins2
.cInstances
= 1;
451 rgPins2
.nMediaTypes
= 1;
452 rgPins2
.lpMediaType
= &rgPinType
;
453 rgPins2
.nMediums
= 0;
454 rgPins2
.lpMedium
= NULL
;
455 rgPins2
.clsPinCategory
= NULL
;
457 hr
= IFilterMapper2_RegisterFilter(pMapper
, &clsidFilter2
, wszFilterName2
, NULL
,
458 &CLSID_LegacyAmFilterCategory
, NULL
, &rgf2
);
459 ok(hr
== S_OK
, "IFilterMapper2_RegisterFilter failed with %x\n", hr
);
461 hr
= IFilterMapper2_UnregisterFilter(pMapper
, &CLSID_LegacyAmFilterCategory
, NULL
, &clsidFilter2
);
462 ok(hr
== S_OK
, "FilterMapper_UnregisterFilter failed with %x\n", hr
);
466 if (pMapper
) IFilterMapper2_Release(pMapper
);
469 static void test_parse_filter_data(void)
471 static const BYTE data_block
[] = {
472 0x02,0x00,0x00,0x00,0xff,0xff,0x5f,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x70,0x69,0x33,
473 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
474 0x30,0x74,0x79,0x33,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x31,0x70,0x69,0x33,
475 0x08,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
476 0x30,0x74,0x79,0x33,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x76,0x69,0x64,0x73,
477 0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
478 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
480 BYTE
*prgbRegFilter2
= NULL
;
481 REGFILTER2
*pRegFilter
= NULL
;
482 IFilterMapper2
*pMapper
= NULL
;
483 SAFEARRAYBOUND saBound
;
484 SAFEARRAY
*psa
= NULL
;
485 LPBYTE pbSAData
= NULL
;
488 IAMFilterData
*pData
= NULL
;
490 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
,
491 &IID_IFilterMapper2
, (LPVOID
*)&pMapper
);
492 ok((hr
== S_OK
|| broken(hr
!= S_OK
)), "CoCreateInstance failed with %x\n", hr
);
493 if (FAILED(hr
)) goto out
;
495 hr
= IFilterMapper2_QueryInterface(pMapper
, &IID_IAMFilterData
, (LPVOID
*)&pData
);
496 ok((hr
== S_OK
|| broken(hr
!= S_OK
)), "Unable to find IID_IAMFilterData interface\n");
497 if (FAILED(hr
)) goto out
;
500 saBound
.cElements
= sizeof(data_block
);
501 psa
= SafeArrayCreate(VT_UI1
, 1, &saBound
);
502 ok(psa
!= NULL
, "Unable to create safe array\n");
504 hr
= SafeArrayAccessData(psa
, (LPVOID
*)&pbSAData
);
505 ok(hr
== S_OK
, "Unable to access array data\n");
506 if (FAILED(hr
)) goto out
;
507 memcpy(pbSAData
, data_block
, sizeof(data_block
));
509 hr
= IAMFilterData_ParseFilterData(pData
, pbSAData
, sizeof(data_block
), &prgbRegFilter2
);
510 /* We cannot do anything here. prgbRegFilter2 is very unstable */
511 /* Pre Vista, this is a stack pointer so anything that changes the stack invalidats it */
512 /* Post Vista, it is a static pointer in the data section of the module */
513 pRegFilter
=((REGFILTER2
**)prgbRegFilter2
)[0];
514 ok (hr
==S_OK
,"Failed to Parse filter Data\n");
516 ok(IsBadReadPtr(prgbRegFilter2
,sizeof(REGFILTER2
*))==0,"Bad read pointer returned\n");
517 ok(IsBadReadPtr(pRegFilter
,sizeof(REGFILTER2
))==0,"Bad read pointer for FilterData\n");
518 ok(pRegFilter
->dwMerit
== 0x5fffff,"Incorrect merit returned\n");
521 CoTaskMemFree(pRegFilter
);
524 SafeArrayUnaccessData(psa
);
525 SafeArrayDestroy(psa
);
528 IAMFilterData_Release(pData
);
530 IFilterMapper2_Release(pMapper
);
533 typedef struct IUnknownImpl
535 IUnknown IUnknown_iface
;
540 static IUnknownImpl
*IUnknownImpl_from_iface(IUnknown
* iface
)
542 return CONTAINING_RECORD(iface
, IUnknownImpl
, IUnknown_iface
);
545 static HRESULT WINAPI
IUnknownImpl_QueryInterface(IUnknown
* iface
, REFIID riid
, LPVOID
* ppv
)
547 ok(0, "QueryInterface should not be called for %s\n", wine_dbgstr_guid(riid
));
548 return E_NOINTERFACE
;
551 static ULONG WINAPI
IUnknownImpl_AddRef(IUnknown
* iface
)
553 IUnknownImpl
*This
= IUnknownImpl_from_iface(iface
);
554 This
->AddRef_called
++;
558 static ULONG WINAPI
IUnknownImpl_Release(IUnknown
* iface
)
560 IUnknownImpl
*This
= IUnknownImpl_from_iface(iface
);
561 This
->Release_called
++;
565 static CONST_VTBL IUnknownVtbl IUnknownImpl_Vtbl
=
567 IUnknownImpl_QueryInterface
,
572 static void test_aggregate_filter_mapper(void)
577 IUnknownImpl unk_outer
= { { &IUnknownImpl_Vtbl
}, 0, 0 };
579 hr
= CoCreateInstance(&CLSID_FilterMapper2
, &unk_outer
.IUnknown_iface
, CLSCTX_INPROC_SERVER
,
580 &IID_IUnknown
, (void **)&pmapper
);
581 ok(hr
== S_OK
, "CoCreateInstance returned %x\n", hr
);
582 ok(pmapper
!= &unk_outer
.IUnknown_iface
, "pmapper = %p, expected not %p\n", pmapper
, &unk_outer
.IUnknown_iface
);
584 hr
= IUnknown_QueryInterface(pmapper
, &IID_IUnknown
, (void **)&punk
);
585 ok(hr
== S_OK
, "IUnknown_QueryInterface returned %x\n", hr
);
586 ok(punk
!= &unk_outer
.IUnknown_iface
, "punk = %p, expected not %p\n", punk
, &unk_outer
.IUnknown_iface
);
587 IUnknown_Release(punk
);
589 ok(unk_outer
.AddRef_called
== 0, "IUnknownImpl_AddRef called %d times\n", unk_outer
.AddRef_called
);
590 ok(unk_outer
.Release_called
== 0, "IUnknownImpl_Release called %d times\n", unk_outer
.Release_called
);
591 unk_outer
.AddRef_called
= 0;
592 unk_outer
.Release_called
= 0;
594 hr
= IUnknown_QueryInterface(pmapper
, &IID_IFilterMapper
, (void **)&punk
);
595 ok(hr
== S_OK
, "IUnknown_QueryInterface returned %x\n", hr
);
596 ok(punk
!= &unk_outer
.IUnknown_iface
, "punk = %p, expected not %p\n", punk
, &unk_outer
.IUnknown_iface
);
597 IUnknown_Release(punk
);
599 ok(unk_outer
.AddRef_called
== 1, "IUnknownImpl_AddRef called %d times\n", unk_outer
.AddRef_called
);
600 ok(unk_outer
.Release_called
== 1, "IUnknownImpl_Release called %d times\n", unk_outer
.Release_called
);
601 unk_outer
.AddRef_called
= 0;
602 unk_outer
.Release_called
= 0;
604 hr
= IUnknown_QueryInterface(pmapper
, &IID_IFilterMapper2
, (void **)&punk
);
605 ok(hr
== S_OK
, "IUnknown_QueryInterface returned %x\n", hr
);
606 ok(punk
!= &unk_outer
.IUnknown_iface
, "punk = %p, expected not %p\n", punk
, &unk_outer
.IUnknown_iface
);
607 IUnknown_Release(punk
);
609 ok(unk_outer
.AddRef_called
== 1, "IUnknownImpl_AddRef called %d times\n", unk_outer
.AddRef_called
);
610 ok(unk_outer
.Release_called
== 1, "IUnknownImpl_Release called %d times\n", unk_outer
.Release_called
);
611 unk_outer
.AddRef_called
= 0;
612 unk_outer
.Release_called
= 0;
614 hr
= IUnknown_QueryInterface(pmapper
, &IID_IFilterMapper3
, (void **)&punk
);
615 ok(hr
== S_OK
, "IUnknown_QueryInterface returned %x\n", hr
);
616 ok(punk
!= &unk_outer
.IUnknown_iface
, "punk = %p, expected not %p\n", punk
, &unk_outer
.IUnknown_iface
);
617 IUnknown_Release(punk
);
619 ok(unk_outer
.AddRef_called
== 1, "IUnknownImpl_AddRef called %d times\n", unk_outer
.AddRef_called
);
620 ok(unk_outer
.Release_called
== 1, "IUnknownImpl_Release called %d times\n", unk_outer
.Release_called
);
622 IUnknown_Release(pmapper
);
625 START_TEST(filtermapper
)
629 test_fm2_enummatchingfilters();
630 test_legacy_filter_registration();
631 test_ifiltermapper_from_filtergraph();
632 test_register_filter_with_null_clsMinorType();
633 test_parse_filter_data();
634 test_aggregate_filter_mapper();