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
);
51 if (FAILED(hr
) || !pPropBagCat
)
54 IMoniker_Release(pMoniker
);
58 hr
= IPropertyBag_Read(pPropBagCat
, wszFriendlyName
, &var
, NULL
);
59 ok(SUCCEEDED(hr
), "IPropertyBag_Read failed with %x\n", hr
);
63 CHAR val1
[512], val2
[512];
65 WideCharToMultiByte(CP_ACP
, 0, V_BSTR(&var
), -1, val1
, sizeof(val1
), 0, 0);
66 WideCharToMultiByte(CP_ACP
, 0, wszFilterName
, -1, val2
, sizeof(val2
), 0, 0);
67 if (!lstrcmpA(val1
, val2
)) found
= TRUE
;
70 IPropertyBag_Release(pPropBagCat
);
71 IMoniker_Release(pMoniker
);
78 static void test_fm2_enummatchingfilters(void)
80 IFilterMapper2
*pMapper
= NULL
;
83 REGFILTERPINS2 rgPins2
[2];
84 REGPINTYPES rgPinType
;
85 static const WCHAR wszFilterName1
[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', '1', 0 };
86 static const WCHAR wszFilterName2
[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', '2', 0 };
89 IEnumMoniker
*pEnum
= NULL
;
90 BOOL found
, registered
= TRUE
;
92 ZeroMemory(&rgf2
, sizeof(rgf2
));
94 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
,
95 &IID_IFilterMapper2
, (LPVOID
*)&pMapper
);
96 ok(hr
== S_OK
, "CoCreateInstance failed with %x\n", hr
);
97 if (FAILED(hr
)) goto out
;
99 hr
= CoCreateGuid(&clsidFilter1
);
100 ok(hr
== S_OK
, "CoCreateGuid failed with %x\n", hr
);
101 hr
= CoCreateGuid(&clsidFilter2
);
102 ok(hr
== S_OK
, "CoCreateGuid failed with %x\n", hr
);
104 /* Test that a test renderer filter is returned when enumerating filters with bRender=FALSE */
106 rgf2
.dwMerit
= MERIT_UNLIKELY
;
107 S2(U(rgf2
)).cPins2
= 1;
108 S2(U(rgf2
)).rgPins2
= rgPins2
;
110 rgPins2
[0].dwFlags
= REG_PINFLAG_B_RENDERER
;
111 rgPins2
[0].cInstances
= 1;
112 rgPins2
[0].nMediaTypes
= 1;
113 rgPins2
[0].lpMediaType
= &rgPinType
;
114 rgPins2
[0].nMediums
= 0;
115 rgPins2
[0].lpMedium
= NULL
;
116 rgPins2
[0].clsPinCategory
= NULL
;
118 rgPinType
.clsMajorType
= &GUID_NULL
;
119 rgPinType
.clsMinorType
= &GUID_NULL
;
121 hr
= IFilterMapper2_RegisterFilter(pMapper
, &clsidFilter1
, wszFilterName1
, NULL
,
122 &CLSID_LegacyAmFilterCategory
, NULL
, &rgf2
);
123 if (hr
== E_ACCESSDENIED
)
126 skip("Not authorized to register filters\n");
130 ok(hr
== S_OK
, "IFilterMapper2_RegisterFilter failed with %x\n", hr
);
132 rgPins2
[0].dwFlags
= 0;
134 rgPins2
[1].dwFlags
= REG_PINFLAG_B_OUTPUT
;
135 rgPins2
[1].cInstances
= 1;
136 rgPins2
[1].nMediaTypes
= 1;
137 rgPins2
[1].lpMediaType
= &rgPinType
;
138 rgPins2
[1].nMediums
= 0;
139 rgPins2
[1].lpMedium
= NULL
;
140 rgPins2
[1].clsPinCategory
= NULL
;
142 S2(U(rgf2
)).cPins2
= 2;
144 hr
= IFilterMapper2_RegisterFilter(pMapper
, &clsidFilter2
, wszFilterName2
, NULL
,
145 &CLSID_LegacyAmFilterCategory
, NULL
, &rgf2
);
146 ok(hr
== S_OK
, "IFilterMapper2_RegisterFilter failed with %x\n", hr
);
148 hr
= IFilterMapper2_EnumMatchingFilters(pMapper
, &pEnum
, 0, TRUE
, MERIT_UNLIKELY
, TRUE
,
149 0, NULL
, NULL
, &GUID_NULL
, FALSE
, FALSE
, 0, NULL
, NULL
, &GUID_NULL
);
150 ok(hr
== S_OK
, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr
);
151 if (SUCCEEDED(hr
) && pEnum
)
153 found
= enum_find_filter(wszFilterName1
, pEnum
);
154 ok(found
, "EnumMatchingFilters failed to return the test filter 1\n");
157 if (pEnum
) IEnumMoniker_Release(pEnum
);
160 hr
= IFilterMapper2_EnumMatchingFilters(pMapper
, &pEnum
, 0, TRUE
, MERIT_UNLIKELY
, TRUE
,
161 0, NULL
, NULL
, &GUID_NULL
, FALSE
, FALSE
, 0, NULL
, NULL
, &GUID_NULL
);
162 ok(hr
== S_OK
, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr
);
163 if (SUCCEEDED(hr
) && pEnum
)
165 found
= enum_find_filter(wszFilterName2
, pEnum
);
166 ok(found
, "EnumMatchingFilters failed to return the test filter 2\n");
169 if (pEnum
) IEnumMoniker_Release(pEnum
);
172 /* Non renderer must not be returned with bRender=TRUE */
174 hr
= IFilterMapper2_EnumMatchingFilters(pMapper
, &pEnum
, 0, TRUE
, MERIT_UNLIKELY
, TRUE
,
175 0, NULL
, NULL
, &GUID_NULL
, TRUE
, FALSE
, 0, NULL
, NULL
, &GUID_NULL
);
176 ok(hr
== S_OK
, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr
);
178 if (SUCCEEDED(hr
) && pEnum
)
180 found
= enum_find_filter(wszFilterName1
, pEnum
);
181 ok(found
, "EnumMatchingFilters failed to return the test filter 1\n");
185 if (pEnum
) IEnumMoniker_Release(pEnum
);
188 hr
= IFilterMapper2_EnumMatchingFilters(pMapper
, &pEnum
, 0, TRUE
, MERIT_UNLIKELY
, TRUE
,
189 0, NULL
, NULL
, &GUID_NULL
, TRUE
, FALSE
, 0, NULL
, NULL
, &GUID_NULL
);
190 ok(hr
== S_OK
, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr
);
192 if (SUCCEEDED(hr
) && pEnum
)
194 found
= enum_find_filter(wszFilterName2
, pEnum
);
195 ok(!found
, "EnumMatchingFilters should not return the test filter 2\n");
200 hr
= IFilterMapper2_UnregisterFilter(pMapper
, &CLSID_LegacyAmFilterCategory
, NULL
,
202 ok(SUCCEEDED(hr
), "IFilterMapper2_UnregisterFilter failed with %x\n", hr
);
204 hr
= IFilterMapper2_UnregisterFilter(pMapper
, &CLSID_LegacyAmFilterCategory
, NULL
,
206 ok(SUCCEEDED(hr
), "IFilterMapper2_UnregisterFilter failed with %x\n", hr
);
211 if (pEnum
) IEnumMoniker_Release(pEnum
);
212 if (pMapper
) IFilterMapper2_Release(pMapper
);
215 static void test_legacy_filter_registration(void)
217 IFilterMapper2
*pMapper2
= NULL
;
218 IFilterMapper
*pMapper
= NULL
;
220 static const WCHAR wszFilterName
[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', 0 };
221 static const CHAR szFilterName
[] = "Testfilter";
222 static const WCHAR wszPinName
[] = {'P', 'i', 'n', '1', 0 };
224 CHAR szRegKey
[MAX_PATH
];
225 static const CHAR szClsid
[] = "CLSID";
226 WCHAR wszGuidstring
[MAX_PATH
];
227 CHAR szGuidstring
[MAX_PATH
];
230 IEnumMoniker
*pEnum
= NULL
;
232 IEnumRegFilters
*pRegEnum
= NULL
;
234 /* Test if legacy filter registration scheme works (filter is added to HKCR\Filter). IFilterMapper_RegisterFilter
235 * registers in this way. Filters so registered must then be accessible through both IFilterMapper_EnumMatchingFilters
236 * and IFilterMapper2_EnumMatchingFilters. */
237 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
,
238 &IID_IFilterMapper2
, (LPVOID
*)&pMapper2
);
239 ok(hr
== S_OK
, "CoCreateInstance failed with %x\n", hr
);
240 if (FAILED(hr
)) goto out
;
242 hr
= IFilterMapper2_QueryInterface(pMapper2
, &IID_IFilterMapper
, (void **)&pMapper
);
243 ok(hr
== S_OK
, "IFilterMapper2_QueryInterface failed with %x\n", hr
);
244 if (FAILED(hr
)) goto out
;
246 /* Register a test filter. */
247 hr
= CoCreateGuid(&clsidFilter
);
248 ok(hr
== S_OK
, "CoCreateGuid failed with %x\n", hr
);
250 lRet
= StringFromGUID2(&clsidFilter
, wszGuidstring
, MAX_PATH
);
251 ok(lRet
> 0, "StringFromGUID2 failed\n");
253 WideCharToMultiByte(CP_ACP
, 0, wszGuidstring
, -1, szGuidstring
, MAX_PATH
, 0, 0);
255 lstrcpyA(szRegKey
, szClsid
);
256 lstrcatA(szRegKey
, "\\");
257 lstrcatA(szRegKey
, szGuidstring
);
259 /* Register---- functions need a filter class key to write pin and pin media type data to. Create a bogus
260 * class key for it. */
261 lRet
= RegCreateKeyExA(HKEY_CLASSES_ROOT
, szRegKey
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &hKey
, NULL
);
262 if (lRet
== ERROR_ACCESS_DENIED
)
263 skip("Not authorized to register filters\n");
266 ok(lRet
== ERROR_SUCCESS
, "RegCreateKeyExA failed with %x\n", HRESULT_FROM_WIN32(lRet
));
268 /* Set default value - this is interpreted as "friendly name" later. */
269 lRet
= RegSetValueExA(hKey
, NULL
, 0, REG_SZ
, (LPBYTE
)szFilterName
, lstrlenA(szFilterName
) + 1);
270 ok(lRet
== ERROR_SUCCESS
, "RegSetValueExA failed with %x\n", HRESULT_FROM_WIN32(lRet
));
272 if (hKey
) RegCloseKey(hKey
);
275 hr
= IFilterMapper_RegisterFilter(pMapper
, clsidFilter
, wszFilterName
, MERIT_UNLIKELY
);
276 ok(hr
== S_OK
, "IFilterMapper_RegisterFilter failed with %x\n", hr
);
278 hr
= IFilterMapper_RegisterPin(pMapper
, clsidFilter
, wszPinName
, TRUE
, FALSE
, FALSE
, FALSE
, GUID_NULL
, NULL
);
279 ok(hr
== S_OK
, "IFilterMapper_RegisterPin failed with %x\n", hr
);
281 hr
= IFilterMapper_RegisterPinType(pMapper
, clsidFilter
, wszPinName
, GUID_NULL
, GUID_NULL
);
282 ok(hr
== S_OK
, "IFilterMapper_RegisterPinType failed with %x\n", hr
);
284 hr
= IFilterMapper2_EnumMatchingFilters(pMapper2
, &pEnum
, 0, TRUE
, MERIT_UNLIKELY
, TRUE
,
285 0, NULL
, NULL
, &GUID_NULL
, FALSE
, FALSE
, 0, NULL
, NULL
, &GUID_NULL
);
286 ok(hr
== S_OK
, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr
);
287 if (SUCCEEDED(hr
) && pEnum
)
289 found
= enum_find_filter(wszFilterName
, pEnum
);
290 ok(found
, "IFilterMapper2_EnumMatchingFilters failed to return the test filter\n");
293 if (pEnum
) IEnumMoniker_Release(pEnum
);
297 hr
= IFilterMapper_EnumMatchingFilters(pMapper
, &pRegEnum
, MERIT_UNLIKELY
, TRUE
, GUID_NULL
, GUID_NULL
,
298 FALSE
, FALSE
, GUID_NULL
, GUID_NULL
);
299 ok(hr
== S_OK
, "IFilterMapper_EnumMatchingFilters failed with %x\n", hr
);
300 if (SUCCEEDED(hr
) && pRegEnum
)
305 while(!found
&& IEnumRegFilters_Next(pRegEnum
, 1, &prgf
, &cFetched
) == S_OK
)
309 WideCharToMultiByte(CP_ACP
, 0, prgf
->Name
, -1, val
, sizeof(val
), 0, 0);
310 if (!lstrcmpA(val
, szFilterName
)) found
= TRUE
;
315 IEnumRegFilters_Release(pRegEnum
);
317 ok(found
, "IFilterMapper_EnumMatchingFilters failed to return the test filter\n");
319 hr
= IFilterMapper_UnregisterFilter(pMapper
, clsidFilter
);
320 ok(hr
== S_OK
, "FilterMapper_UnregisterFilter failed with %x\n", hr
);
322 lRet
= RegOpenKeyExA(HKEY_CLASSES_ROOT
, szClsid
, 0, KEY_WRITE
| DELETE
, &hKey
);
323 ok(lRet
== ERROR_SUCCESS
, "RegOpenKeyExA failed with %x\n", HRESULT_FROM_WIN32(lRet
));
325 lRet
= RegDeleteKeyA(hKey
, szGuidstring
);
326 ok(lRet
== ERROR_SUCCESS
, "RegDeleteKeyA failed with %x\n", HRESULT_FROM_WIN32(lRet
));
329 if (hKey
) RegCloseKey(hKey
);
334 if (pMapper
) IFilterMapper_Release(pMapper
);
335 if (pMapper2
) IFilterMapper2_Release(pMapper2
);
338 static ULONG
getRefcount(IUnknown
*iface
)
340 IUnknown_AddRef(iface
);
341 return IUnknown_Release(iface
);
344 static void test_ifiltermapper_from_filtergraph(void)
346 IFilterGraph2
* pgraph2
= NULL
;
347 IFilterMapper2
*pMapper2
= NULL
;
348 IFilterGraph
*filtergraph
= NULL
;
352 hr
= CoCreateInstance(&CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterGraph2
, (LPVOID
*)&pgraph2
);
353 ok(hr
== S_OK
, "CoCreateInstance failed with %08x\n", hr
);
354 if (!pgraph2
) goto out
;
356 hr
= IFilterGraph2_QueryInterface(pgraph2
, &IID_IFilterMapper2
, (LPVOID
*)&pMapper2
);
357 ok(hr
== S_OK
, "IFilterGraph2_QueryInterface failed with %08x\n", hr
);
358 if (!pMapper2
) goto out
;
360 refcount
= getRefcount((IUnknown
*)pgraph2
);
361 ok(refcount
== 2, "unexpected reference count: %u\n", refcount
);
362 refcount
= getRefcount((IUnknown
*)pMapper2
);
363 ok(refcount
== 2, "unexpected reference count: %u\n", refcount
);
365 IFilterMapper2_AddRef(pMapper2
);
366 refcount
= getRefcount((IUnknown
*)pgraph2
);
367 ok(refcount
== 3, "unexpected reference count: %u\n", refcount
);
368 refcount
= getRefcount((IUnknown
*)pMapper2
);
369 ok(refcount
== 3, "unexpected reference count: %u\n", refcount
);
370 IFilterMapper2_Release(pMapper2
);
372 hr
= IFilterMapper2_QueryInterface(pMapper2
, &IID_IFilterGraph
, (LPVOID
*)&filtergraph
);
373 ok(hr
== S_OK
, "IFilterMapper2_QueryInterface failed with %08x\n", hr
);
374 if (!filtergraph
) goto out
;
376 IFilterMapper2_Release(pMapper2
);
378 IFilterGraph_Release(filtergraph
);
381 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterMapper2
, (LPVOID
*)&pMapper2
);
382 ok(hr
== S_OK
, "CoCreateInstance failed with %08x\n", hr
);
383 if (!pMapper2
) goto out
;
385 hr
= IFilterMapper2_QueryInterface(pMapper2
, &IID_IFilterGraph
, (LPVOID
*)&filtergraph
);
386 ok(hr
== E_NOINTERFACE
, "IFilterMapper2_QueryInterface unexpected result: %08x\n", hr
);
390 if (pMapper2
) IFilterMapper2_Release(pMapper2
);
391 if (filtergraph
) IFilterGraph_Release(filtergraph
);
392 if (pgraph2
) IFilterGraph2_Release(pgraph2
);
395 static void test_register_filter_with_null_clsMinorType(void)
397 IFilterMapper2
*pMapper
= NULL
;
400 REGFILTERPINS rgPins
;
401 REGFILTERPINS2 rgPins2
;
402 REGPINTYPES rgPinType
;
403 static WCHAR wszPinName
[] = {'P', 'i', 'n', 0 };
404 static const WCHAR wszFilterName1
[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', '1', 0 };
405 static const WCHAR wszFilterName2
[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', '2', 0 };
409 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
,
410 &IID_IFilterMapper2
, (LPVOID
*)&pMapper
);
411 ok(hr
== S_OK
, "CoCreateInstance failed with %x\n", hr
);
412 if (FAILED(hr
)) goto out
;
414 hr
= CoCreateGuid(&clsidFilter1
);
415 ok(hr
== S_OK
, "CoCreateGuid failed with %x\n", hr
);
416 hr
= CoCreateGuid(&clsidFilter2
);
417 ok(hr
== S_OK
, "CoCreateGuid failed with %x\n", hr
);
419 rgPinType
.clsMajorType
= &GUID_NULL
;
420 /* Make sure quartz accepts it without crashing */
421 rgPinType
.clsMinorType
= NULL
;
423 /* Test with pin descript version 1 */
424 ZeroMemory(&rgf2
, sizeof(rgf2
));
426 rgf2
.dwMerit
= MERIT_UNLIKELY
;
427 S1(U(rgf2
)).cPins
= 1;
428 S1(U(rgf2
)).rgPins
= &rgPins
;
430 rgPins
.strName
= wszPinName
;
431 rgPins
.bRendered
= 1;
435 rgPins
.clsConnectsToFilter
= NULL
;
436 rgPins
.strConnectsToPin
= NULL
;
437 rgPins
.nMediaTypes
= 1;
438 rgPins
.lpMediaType
= &rgPinType
;
440 hr
= IFilterMapper2_RegisterFilter(pMapper
, &clsidFilter1
, wszFilterName1
, NULL
,
441 &CLSID_LegacyAmFilterCategory
, NULL
, &rgf2
);
442 if (hr
== E_ACCESSDENIED
)
444 skip("Not authorized to register filters\n");
447 ok(hr
== S_OK
, "IFilterMapper2_RegisterFilter failed with %x\n", hr
);
449 hr
= IFilterMapper2_UnregisterFilter(pMapper
, &CLSID_LegacyAmFilterCategory
, NULL
, &clsidFilter1
);
450 ok(hr
== S_OK
, "FilterMapper_UnregisterFilter failed with %x\n", hr
);
452 /* Test with pin descript version 2 */
453 ZeroMemory(&rgf2
, sizeof(rgf2
));
455 rgf2
.dwMerit
= MERIT_UNLIKELY
;
456 S2(U(rgf2
)).cPins2
= 1;
457 S2(U(rgf2
)).rgPins2
= &rgPins2
;
459 rgPins2
.dwFlags
= REG_PINFLAG_B_RENDERER
;
460 rgPins2
.cInstances
= 1;
461 rgPins2
.nMediaTypes
= 1;
462 rgPins2
.lpMediaType
= &rgPinType
;
463 rgPins2
.nMediums
= 0;
464 rgPins2
.lpMedium
= NULL
;
465 rgPins2
.clsPinCategory
= NULL
;
467 hr
= IFilterMapper2_RegisterFilter(pMapper
, &clsidFilter2
, wszFilterName2
, NULL
,
468 &CLSID_LegacyAmFilterCategory
, NULL
, &rgf2
);
469 ok(hr
== S_OK
, "IFilterMapper2_RegisterFilter failed with %x\n", hr
);
471 hr
= IFilterMapper2_UnregisterFilter(pMapper
, &CLSID_LegacyAmFilterCategory
, NULL
, &clsidFilter2
);
472 ok(hr
== S_OK
, "FilterMapper_UnregisterFilter failed with %x\n", hr
);
476 if (pMapper
) IFilterMapper2_Release(pMapper
);
479 static void test_parse_filter_data(void)
481 static const BYTE data_block
[] = {
482 0x02,0x00,0x00,0x00,0xff,0xff,0x5f,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x70,0x69,0x33,
483 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
484 0x30,0x74,0x79,0x33,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x31,0x70,0x69,0x33,
485 0x08,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
486 0x30,0x74,0x79,0x33,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x76,0x69,0x64,0x73,
487 0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
488 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
490 BYTE
*prgbRegFilter2
= NULL
;
491 REGFILTER2
*pRegFilter
= NULL
;
492 IFilterMapper2
*pMapper
= NULL
;
493 SAFEARRAYBOUND saBound
;
494 SAFEARRAY
*psa
= NULL
;
495 LPBYTE pbSAData
= NULL
;
498 IAMFilterData
*pData
= NULL
;
500 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
,
501 &IID_IFilterMapper2
, (LPVOID
*)&pMapper
);
502 ok((hr
== S_OK
|| broken(hr
!= S_OK
)), "CoCreateInstance failed with %x\n", hr
);
503 if (FAILED(hr
)) goto out
;
505 hr
= IFilterMapper2_QueryInterface(pMapper
, &IID_IAMFilterData
, (LPVOID
*)&pData
);
506 ok((hr
== S_OK
|| broken(hr
!= S_OK
)), "Unable to find IID_IAMFilterData interface\n");
507 if (FAILED(hr
)) goto out
;
510 saBound
.cElements
= sizeof(data_block
);
511 psa
= SafeArrayCreate(VT_UI1
, 1, &saBound
);
512 ok(psa
!= NULL
, "Unable to create safe array\n");
514 hr
= SafeArrayAccessData(psa
, (LPVOID
*)&pbSAData
);
515 ok(hr
== S_OK
, "Unable to access array data\n");
516 if (FAILED(hr
)) goto out
;
517 memcpy(pbSAData
, data_block
, sizeof(data_block
));
519 hr
= IAMFilterData_ParseFilterData(pData
, pbSAData
, sizeof(data_block
), &prgbRegFilter2
);
520 /* We cannot do anything here. prgbRegFilter2 is very unstable */
521 /* Pre Vista, this is a stack pointer so anything that changes the stack invalidats it */
522 /* Post Vista, it is a static pointer in the data section of the module */
523 pRegFilter
=((REGFILTER2
**)prgbRegFilter2
)[0];
524 ok (hr
==S_OK
,"Failed to Parse filter Data\n");
526 ok(IsBadReadPtr(prgbRegFilter2
,sizeof(REGFILTER2
*))==0,"Bad read pointer returned\n");
527 ok(IsBadReadPtr(pRegFilter
,sizeof(REGFILTER2
))==0,"Bad read pointer for FilterData\n");
528 ok(pRegFilter
->dwMerit
== 0x5fffff,"Incorrect merit returned\n");
532 CoTaskMemFree(pRegFilter
);
535 SafeArrayUnaccessData(psa
);
536 SafeArrayDestroy(psa
);
539 IAMFilterData_Release(pData
);
541 IFilterMapper2_Release(pMapper
);
544 typedef struct IUnknownImpl
546 IUnknown IUnknown_iface
;
551 static IUnknownImpl
*IUnknownImpl_from_iface(IUnknown
* iface
)
553 return CONTAINING_RECORD(iface
, IUnknownImpl
, IUnknown_iface
);
556 static HRESULT WINAPI
IUnknownImpl_QueryInterface(IUnknown
* iface
, REFIID riid
, LPVOID
* ppv
)
558 ok(0, "QueryInterface should not be called for %s\n", wine_dbgstr_guid(riid
));
559 return E_NOINTERFACE
;
562 static ULONG WINAPI
IUnknownImpl_AddRef(IUnknown
* iface
)
564 IUnknownImpl
*This
= IUnknownImpl_from_iface(iface
);
565 This
->AddRef_called
++;
569 static ULONG WINAPI
IUnknownImpl_Release(IUnknown
* iface
)
571 IUnknownImpl
*This
= IUnknownImpl_from_iface(iface
);
572 This
->Release_called
++;
576 static CONST_VTBL IUnknownVtbl IUnknownImpl_Vtbl
=
578 IUnknownImpl_QueryInterface
,
583 static void test_aggregate_filter_mapper(void)
588 IUnknownImpl unk_outer
= { { &IUnknownImpl_Vtbl
}, 0, 0 };
590 hr
= CoCreateInstance(&CLSID_FilterMapper2
, &unk_outer
.IUnknown_iface
, CLSCTX_INPROC_SERVER
,
591 &IID_IUnknown
, (void **)&pmapper
);
592 ok(hr
== S_OK
, "CoCreateInstance returned %x\n", hr
);
593 ok(pmapper
!= &unk_outer
.IUnknown_iface
, "pmapper = %p, expected not %p\n", pmapper
, &unk_outer
.IUnknown_iface
);
595 hr
= IUnknown_QueryInterface(pmapper
, &IID_IUnknown
, (void **)&punk
);
596 ok(hr
== S_OK
, "CoCreateInstance returned %x\n", hr
);
597 ok(punk
!= &unk_outer
.IUnknown_iface
, "punk = %p, expected not %p\n", punk
, &unk_outer
.IUnknown_iface
);
598 IUnknown_Release(punk
);
600 ok(unk_outer
.AddRef_called
== 0, "IUnknownImpl_AddRef called %d times\n", unk_outer
.AddRef_called
);
601 ok(unk_outer
.Release_called
== 0, "IUnknownImpl_Release called %d times\n", unk_outer
.Release_called
);
602 unk_outer
.AddRef_called
= 0;
603 unk_outer
.Release_called
= 0;
605 hr
= IUnknown_QueryInterface(pmapper
, &IID_IFilterMapper
, (void **)&punk
);
606 ok(hr
== S_OK
, "CoCreateInstance returned %x\n", hr
);
607 ok(punk
!= &unk_outer
.IUnknown_iface
, "punk = %p, expected not %p\n", punk
, &unk_outer
.IUnknown_iface
);
608 IUnknown_Release(punk
);
610 ok(unk_outer
.AddRef_called
== 1, "IUnknownImpl_AddRef called %d times\n", unk_outer
.AddRef_called
);
611 ok(unk_outer
.Release_called
== 1, "IUnknownImpl_Release called %d times\n", unk_outer
.Release_called
);
612 unk_outer
.AddRef_called
= 0;
613 unk_outer
.Release_called
= 0;
615 hr
= IUnknown_QueryInterface(pmapper
, &IID_IFilterMapper2
, (void **)&punk
);
616 ok(hr
== S_OK
, "CoCreateInstance returned %x\n", hr
);
617 ok(punk
!= &unk_outer
.IUnknown_iface
, "punk = %p, expected not %p\n", punk
, &unk_outer
.IUnknown_iface
);
618 IUnknown_Release(punk
);
620 ok(unk_outer
.AddRef_called
== 1, "IUnknownImpl_AddRef called %d times\n", unk_outer
.AddRef_called
);
621 ok(unk_outer
.Release_called
== 1, "IUnknownImpl_Release called %d times\n", unk_outer
.Release_called
);
622 unk_outer
.AddRef_called
= 0;
623 unk_outer
.Release_called
= 0;
625 hr
= IUnknown_QueryInterface(pmapper
, &IID_IFilterMapper3
, (void **)&punk
);
626 ok(hr
== S_OK
, "CoCreateInstance returned %x\n", hr
);
627 ok(punk
!= &unk_outer
.IUnknown_iface
, "punk = %p, expected not %p\n", punk
, &unk_outer
.IUnknown_iface
);
628 IUnknown_Release(punk
);
630 ok(unk_outer
.AddRef_called
== 1, "IUnknownImpl_AddRef called %d times\n", unk_outer
.AddRef_called
);
631 ok(unk_outer
.Release_called
== 1, "IUnknownImpl_Release called %d times\n", unk_outer
.Release_called
);
633 IUnknown_Release(pmapper
);
636 START_TEST(filtermapper
)
640 test_fm2_enummatchingfilters();
641 test_legacy_filter_registration();
642 test_ifiltermapper_from_filtergraph();
643 test_register_filter_with_null_clsMinorType();
644 test_parse_filter_data();
645 test_aggregate_filter_mapper();