b52d17e1221e7ed9fd40830c9a607d4092afe794
[reactos.git] / rostests / winetests / quartz / filtermapper.c
1 /*
2 * Filtermapper unit tests for Quartz
3 *
4 * Copyright (C) 2008 Alexander Dorofeyev
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 "winbase.h"
25 #include "initguid.h"
26 #include "dshow.h"
27 #include "winternl.h"
28
29 #include "fil_data.h"
30
31 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
32
33 /* Helper function, checks if filter with given name was enumerated. */
34 static BOOL enum_find_filter(const WCHAR *wszFilterName, IEnumMoniker *pEnum)
35 {
36 IMoniker *pMoniker = NULL;
37 BOOL found = FALSE;
38 ULONG nb;
39 HRESULT hr;
40 static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
41
42 while(!found && IEnumMoniker_Next(pEnum, 1, &pMoniker, &nb) == S_OK)
43 {
44 IPropertyBag * pPropBagCat = NULL;
45 VARIANT var;
46
47 VariantInit(&var);
48
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)
52 {
53 VariantClear(&var);
54 IMoniker_Release(pMoniker);
55 continue;
56 }
57
58 hr = IPropertyBag_Read(pPropBagCat, wszFriendlyName, &var, NULL);
59 ok(SUCCEEDED(hr), "IPropertyBag_Read failed with %x\n", hr);
60
61 if (SUCCEEDED(hr))
62 {
63 CHAR val1[512], val2[512];
64
65 WideCharToMultiByte(CP_ACP, 0, V_UNION(&var, bstrVal), -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;
68 }
69
70 IPropertyBag_Release(pPropBagCat);
71 IMoniker_Release(pMoniker);
72 VariantClear(&var);
73 }
74
75 return found;
76 }
77
78 static void test_fm2_enummatchingfilters(void)
79 {
80 IFilterMapper2 *pMapper = NULL;
81 HRESULT hr;
82 REGFILTER2 rgf2;
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 };
87 CLSID clsidFilter1;
88 CLSID clsidFilter2;
89 IEnumMoniker *pEnum = NULL;
90 BOOL found;
91
92 ZeroMemory(&rgf2, sizeof(rgf2));
93
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;
98
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);
103
104 /* Test that a test renderer filter is returned when enumerating filters with bRender=FALSE */
105 rgf2.dwVersion = 2;
106 rgf2.dwMerit = MERIT_UNLIKELY;
107 S2(U(rgf2)).cPins2 = 1;
108 S2(U(rgf2)).rgPins2 = rgPins2;
109
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;
117
118 rgPinType.clsMajorType = &GUID_NULL;
119 rgPinType.clsMinorType = &GUID_NULL;
120
121 hr = IFilterMapper2_RegisterFilter(pMapper, &clsidFilter1, wszFilterName1, NULL,
122 &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
123 if (hr == E_ACCESSDENIED)
124 skip("Not authorized to register filters\n");
125 else
126 {
127 ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
128
129 rgPins2[0].dwFlags = 0;
130
131 rgPins2[1].dwFlags = REG_PINFLAG_B_OUTPUT;
132 rgPins2[1].cInstances = 1;
133 rgPins2[1].nMediaTypes = 1;
134 rgPins2[1].lpMediaType = &rgPinType;
135 rgPins2[1].nMediums = 0;
136 rgPins2[1].lpMedium = NULL;
137 rgPins2[1].clsPinCategory = NULL;
138
139 S2(U(rgf2)).cPins2 = 2;
140
141 hr = IFilterMapper2_RegisterFilter(pMapper, &clsidFilter2, wszFilterName2, NULL,
142 &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
143 ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
144
145 hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
146 0, NULL, NULL, &GUID_NULL, FALSE, FALSE, 0, NULL, NULL, &GUID_NULL);
147 ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
148 if (SUCCEEDED(hr) && pEnum)
149 {
150 found = enum_find_filter(wszFilterName1, pEnum);
151 ok(found, "EnumMatchingFilters failed to return the test filter 1\n");
152 }
153
154 if (pEnum) IEnumMoniker_Release(pEnum);
155 pEnum = NULL;
156
157 hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
158 0, NULL, NULL, &GUID_NULL, FALSE, FALSE, 0, NULL, NULL, &GUID_NULL);
159 ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
160 if (SUCCEEDED(hr) && pEnum)
161 {
162 found = enum_find_filter(wszFilterName2, pEnum);
163 ok(found, "EnumMatchingFilters failed to return the test filter 2\n");
164 }
165
166 if (pEnum) IEnumMoniker_Release(pEnum);
167 pEnum = NULL;
168
169 /* Non renderer must not be returned with bRender=TRUE */
170
171 hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
172 0, NULL, NULL, &GUID_NULL, TRUE, FALSE, 0, NULL, NULL, &GUID_NULL);
173 ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
174
175 if (SUCCEEDED(hr) && pEnum)
176 {
177 found = enum_find_filter(wszFilterName1, pEnum);
178 ok(found, "EnumMatchingFilters failed to return the test filter 1\n");
179 }
180 }
181
182 if (pEnum) IEnumMoniker_Release(pEnum);
183 pEnum = NULL;
184
185 hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
186 0, NULL, NULL, &GUID_NULL, TRUE, FALSE, 0, NULL, NULL, &GUID_NULL);
187 ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
188
189 if (SUCCEEDED(hr) && pEnum)
190 {
191 found = enum_find_filter(wszFilterName2, pEnum);
192 ok(!found, "EnumMatchingFilters should not return the test filter 2\n");
193 }
194
195 hr = IFilterMapper2_UnregisterFilter(pMapper, &CLSID_LegacyAmFilterCategory, NULL,
196 &clsidFilter1);
197 ok(SUCCEEDED(hr), "IFilterMapper2_UnregisterFilter failed with %x\n", hr);
198
199 hr = IFilterMapper2_UnregisterFilter(pMapper, &CLSID_LegacyAmFilterCategory, NULL,
200 &clsidFilter2);
201 ok(SUCCEEDED(hr), "IFilterMapper2_UnregisterFilter failed with %x\n", hr);
202
203 out:
204
205 if (pEnum) IEnumMoniker_Release(pEnum);
206 if (pMapper) IFilterMapper2_Release(pMapper);
207 }
208
209 static void test_legacy_filter_registration(void)
210 {
211 IFilterMapper2 *pMapper2 = NULL;
212 IFilterMapper *pMapper = NULL;
213 HRESULT hr;
214 static const WCHAR wszFilterName[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', 0 };
215 static const CHAR szFilterName[] = "Testfilter";
216 static const WCHAR wszPinName[] = {'P', 'i', 'n', '1', 0 };
217 CLSID clsidFilter;
218 CHAR szRegKey[MAX_PATH];
219 static const CHAR szClsid[] = "CLSID";
220 WCHAR wszGuidstring[MAX_PATH];
221 CHAR szGuidstring[MAX_PATH];
222 LONG lRet;
223 HKEY hKey = NULL;
224 IEnumMoniker *pEnum = NULL;
225 BOOL found;
226 IEnumRegFilters *pRegEnum = NULL;
227
228 /* Test if legacy filter registration scheme works (filter is added to HKCR\Filter). IFilterMapper_RegisterFilter
229 * registers in this way. Filters so registered must then be accessible through both IFilterMapper_EnumMatchingFilters
230 * and IFilterMapper2_EnumMatchingFilters. */
231 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
232 &IID_IFilterMapper2, (LPVOID*)&pMapper2);
233 ok(hr == S_OK, "CoCreateInstance failed with %x\n", hr);
234 if (FAILED(hr)) goto out;
235
236 hr = IFilterMapper2_QueryInterface(pMapper2, &IID_IFilterMapper, (LPVOID)&pMapper);
237 ok(hr == S_OK, "IFilterMapper2_QueryInterface failed with %x\n", hr);
238 if (FAILED(hr)) goto out;
239
240 /* Register a test filter. */
241 hr = CoCreateGuid(&clsidFilter);
242 ok(hr == S_OK, "CoCreateGuid failed with %x\n", hr);
243
244 lRet = StringFromGUID2(&clsidFilter, wszGuidstring, MAX_PATH);
245 ok(lRet > 0, "StringFromGUID2 failed\n");
246 if (!lRet) goto out;
247 WideCharToMultiByte(CP_ACP, 0, wszGuidstring, -1, szGuidstring, MAX_PATH, 0, 0);
248
249 lstrcpyA(szRegKey, szClsid);
250 lstrcatA(szRegKey, "\\");
251 lstrcatA(szRegKey, szGuidstring);
252
253 /* Register---- functions need a filter class key to write pin and pin media type data to. Create a bogus
254 * class key for it. */
255 lRet = RegCreateKeyExA(HKEY_CLASSES_ROOT, szRegKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
256 if (lRet == ERROR_ACCESS_DENIED)
257 skip("Not authorized to register filters\n");
258 else
259 {
260 ok(lRet == ERROR_SUCCESS, "RegCreateKeyExA failed with %x\n", HRESULT_FROM_WIN32(lRet));
261
262 /* Set default value - this is interpreted as "friendly name" later. */
263 lRet = RegSetValueExA(hKey, NULL, 0, REG_SZ, (LPBYTE)szFilterName, lstrlenA(szFilterName) + 1);
264 ok(lRet == ERROR_SUCCESS, "RegSetValueExA failed with %x\n", HRESULT_FROM_WIN32(lRet));
265
266 if (hKey) RegCloseKey(hKey);
267 hKey = NULL;
268
269 hr = IFilterMapper_RegisterFilter(pMapper, clsidFilter, wszFilterName, MERIT_UNLIKELY);
270 ok(hr == S_OK, "IFilterMapper_RegisterFilter failed with %x\n", hr);
271
272 hr = IFilterMapper_RegisterPin(pMapper, clsidFilter, wszPinName, TRUE, FALSE, FALSE, FALSE, GUID_NULL, NULL);
273 ok(hr == S_OK, "IFilterMapper_RegisterPin failed with %x\n", hr);
274
275 hr = IFilterMapper_RegisterPinType(pMapper, clsidFilter, wszPinName, GUID_NULL, GUID_NULL);
276 ok(hr == S_OK, "IFilterMapper_RegisterPinType failed with %x\n", hr);
277
278 hr = IFilterMapper2_EnumMatchingFilters(pMapper2, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
279 0, NULL, NULL, &GUID_NULL, FALSE, FALSE, 0, NULL, NULL, &GUID_NULL);
280 ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
281 if (SUCCEEDED(hr) && pEnum)
282 {
283 found = enum_find_filter(wszFilterName, pEnum);
284 ok(found, "IFilterMapper2_EnumMatchingFilters failed to return the test filter\n");
285 }
286
287 if (pEnum) IEnumMoniker_Release(pEnum);
288 pEnum = NULL;
289
290 found = FALSE;
291 hr = IFilterMapper_EnumMatchingFilters(pMapper, &pRegEnum, MERIT_UNLIKELY, TRUE, GUID_NULL, GUID_NULL,
292 FALSE, FALSE, GUID_NULL, GUID_NULL);
293 ok(hr == S_OK, "IFilterMapper_EnumMatchingFilters failed with %x\n", hr);
294 if (SUCCEEDED(hr) && pRegEnum)
295 {
296 ULONG cFetched;
297 REGFILTER *prgf;
298
299 while(!found && IEnumRegFilters_Next(pRegEnum, 1, &prgf, &cFetched) == S_OK)
300 {
301 CHAR val[512];
302
303 WideCharToMultiByte(CP_ACP, 0, prgf->Name, -1, val, sizeof(val), 0, 0);
304 if (!lstrcmpA(val, szFilterName)) found = TRUE;
305
306 CoTaskMemFree(prgf);
307 }
308
309 IEnumRegFilters_Release(pRegEnum);
310 }
311 ok(found, "IFilterMapper_EnumMatchingFilters failed to return the test filter\n");
312
313 hr = IFilterMapper_UnregisterFilter(pMapper, clsidFilter);
314 ok(hr == S_OK, "FilterMapper_UnregisterFilter failed with %x\n", hr);
315
316 lRet = RegOpenKeyExA(HKEY_CLASSES_ROOT, szClsid, 0, KEY_WRITE | DELETE, &hKey);
317 ok(lRet == ERROR_SUCCESS, "RegOpenKeyExA failed with %x\n", HRESULT_FROM_WIN32(lRet));
318
319 lRet = RegDeleteKeyA(hKey, szGuidstring);
320 ok(lRet == ERROR_SUCCESS, "RegDeleteKeyA failed with %x\n", HRESULT_FROM_WIN32(lRet));
321 }
322
323 if (hKey) RegCloseKey(hKey);
324 hKey = NULL;
325
326 out:
327
328 if (pMapper) IFilterMapper_Release(pMapper);
329 if (pMapper2) IFilterMapper2_Release(pMapper2);
330 }
331
332 static ULONG getRefcount(IUnknown *iface)
333 {
334 IUnknown_AddRef(iface);
335 return IUnknown_Release(iface);
336 }
337
338 static void test_ifiltermapper_from_filtergraph(void)
339 {
340 IFilterGraph2* pgraph2 = NULL;
341 IFilterMapper2 *pMapper2 = NULL;
342 IFilterGraph *filtergraph = NULL;
343 HRESULT hr;
344 ULONG refcount;
345
346 hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterGraph2, (LPVOID*)&pgraph2);
347 ok(hr == S_OK, "CoCreateInstance failed with %08x\n", hr);
348 if (!pgraph2) goto out;
349
350 hr = IFilterGraph2_QueryInterface(pgraph2, &IID_IFilterMapper2, (LPVOID*)&pMapper2);
351 ok(hr == S_OK, "IFilterGraph2_QueryInterface failed with %08x\n", hr);
352 if (!pMapper2) goto out;
353
354 refcount = getRefcount((IUnknown*)pgraph2);
355 ok(refcount == 2, "unexpected reference count: %u\n", refcount);
356 refcount = getRefcount((IUnknown*)pMapper2);
357 ok(refcount == 2, "unexpected reference count: %u\n", refcount);
358
359 IFilterMapper2_AddRef(pMapper2);
360 refcount = getRefcount((IUnknown*)pgraph2);
361 ok(refcount == 3, "unexpected reference count: %u\n", refcount);
362 refcount = getRefcount((IUnknown*)pMapper2);
363 ok(refcount == 3, "unexpected reference count: %u\n", refcount);
364 IFilterMapper2_Release(pMapper2);
365
366 hr = IFilterMapper2_QueryInterface(pMapper2, &IID_IFilterGraph, (LPVOID*)&filtergraph);
367 ok(hr == S_OK, "IFilterMapper2_QueryInterface failed with %08x\n", hr);
368 if (!filtergraph) goto out;
369
370 IFilterMapper2_Release(pMapper2);
371 pMapper2 = NULL;
372 IFilterGraph_Release(filtergraph);
373 filtergraph = NULL;
374
375 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (LPVOID*)&pMapper2);
376 ok(hr == S_OK, "CoCreateInstance failed with %08x\n", hr);
377 if (!pMapper2) goto out;
378
379 hr = IFilterMapper2_QueryInterface(pMapper2, &IID_IFilterGraph, (LPVOID*)&filtergraph);
380 ok(hr == E_NOINTERFACE, "IFilterMapper2_QueryInterface unexpected result: %08x\n", hr);
381
382 out:
383
384 if (pMapper2) IFilterMapper2_Release(pMapper2);
385 if (filtergraph) IFilterGraph_Release(filtergraph);
386 if (pgraph2) IFilterGraph2_Release(pgraph2);
387 }
388
389 static void test_register_filter_with_null_clsMinorType(void)
390 {
391 IFilterMapper2 *pMapper = NULL;
392 HRESULT hr;
393 REGFILTER2 rgf2;
394 REGFILTERPINS rgPins;
395 REGFILTERPINS2 rgPins2;
396 REGPINTYPES rgPinType;
397 static WCHAR wszPinName[] = {'P', 'i', 'n', 0 };
398 static const WCHAR wszFilterName1[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', '1', 0 };
399 static const WCHAR wszFilterName2[] = {'T', 'e', 's', 't', 'f', 'i', 'l', 't', 'e', 'r', '2', 0 };
400 CLSID clsidFilter1;
401 CLSID clsidFilter2;
402
403 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
404 &IID_IFilterMapper2, (LPVOID*)&pMapper);
405 ok(hr == S_OK, "CoCreateInstance failed with %x\n", hr);
406 if (FAILED(hr)) goto out;
407
408 hr = CoCreateGuid(&clsidFilter1);
409 ok(hr == S_OK, "CoCreateGuid failed with %x\n", hr);
410 hr = CoCreateGuid(&clsidFilter2);
411 ok(hr == S_OK, "CoCreateGuid failed with %x\n", hr);
412
413 rgPinType.clsMajorType = &GUID_NULL;
414 /* Make sure quartz accepts it without crashing */
415 rgPinType.clsMinorType = NULL;
416
417 /* Test with pin descript version 1 */
418 ZeroMemory(&rgf2, sizeof(rgf2));
419 rgf2.dwVersion = 1;
420 rgf2.dwMerit = MERIT_UNLIKELY;
421 S1(U(rgf2)).cPins = 1;
422 S1(U(rgf2)).rgPins = &rgPins;
423
424 rgPins.strName = wszPinName;
425 rgPins.bRendered = 1;
426 rgPins.bOutput = 0;
427 rgPins.bZero = 0;
428 rgPins.bMany = 0;
429 rgPins.clsConnectsToFilter = NULL;
430 rgPins.strConnectsToPin = NULL;
431 rgPins.nMediaTypes = 1;
432 rgPins.lpMediaType = &rgPinType;
433
434 hr = IFilterMapper2_RegisterFilter(pMapper, &clsidFilter1, wszFilterName1, NULL,
435 &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
436 if (hr == E_ACCESSDENIED)
437 {
438 skip("Not authorized to register filters\n");
439 goto out;
440 }
441 ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
442
443 hr = IFilterMapper2_UnregisterFilter(pMapper, &CLSID_LegacyAmFilterCategory, NULL, &clsidFilter1);
444 ok(hr == S_OK, "FilterMapper_UnregisterFilter failed with %x\n", hr);
445
446 /* Test with pin descript version 2 */
447 ZeroMemory(&rgf2, sizeof(rgf2));
448 rgf2.dwVersion = 2;
449 rgf2.dwMerit = MERIT_UNLIKELY;
450 S2(U(rgf2)).cPins2 = 1;
451 S2(U(rgf2)).rgPins2 = &rgPins2;
452
453 rgPins2.dwFlags = REG_PINFLAG_B_RENDERER;
454 rgPins2.cInstances = 1;
455 rgPins2.nMediaTypes = 1;
456 rgPins2.lpMediaType = &rgPinType;
457 rgPins2.nMediums = 0;
458 rgPins2.lpMedium = NULL;
459 rgPins2.clsPinCategory = NULL;
460
461 hr = IFilterMapper2_RegisterFilter(pMapper, &clsidFilter2, wszFilterName2, NULL,
462 &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
463 ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
464
465 hr = IFilterMapper2_UnregisterFilter(pMapper, &CLSID_LegacyAmFilterCategory, NULL, &clsidFilter2);
466 ok(hr == S_OK, "FilterMapper_UnregisterFilter failed with %x\n", hr);
467
468 out:
469
470 if (pMapper) IFilterMapper2_Release(pMapper);
471 }
472
473 static void test_parse_filter_data(void)
474 {
475 static const BYTE data_block[] = {
476 0x02,0x00,0x00,0x00,0xff,0xff,0x5f,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x70,0x69,0x33,
477 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
478 0x30,0x74,0x79,0x33,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x31,0x70,0x69,0x33,
479 0x08,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
480 0x30,0x74,0x79,0x33,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x76,0x69,0x64,0x73,
481 0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
482 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
483
484 BYTE *prgbRegFilter2 = NULL;
485 REGFILTER2 *pRegFilter = NULL;
486 IFilterMapper2 *pMapper = NULL;
487 SAFEARRAYBOUND saBound;
488 SAFEARRAY *psa = NULL;
489 LPBYTE pbSAData = NULL;
490 HRESULT hr;
491
492 IAMFilterData *pData = NULL;
493
494 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
495 &IID_IFilterMapper2, (LPVOID*)&pMapper);
496 ok((hr == S_OK || broken(hr != S_OK)), "CoCreateInstance failed with %x\n", hr);
497 if (FAILED(hr)) goto out;
498
499 hr = IFilterMapper2_QueryInterface(pMapper, &IID_IAMFilterData, (LPVOID*)&pData);
500 ok((hr == S_OK || broken(hr != S_OK)), "Unable to find IID_IAMFilterData interface\n");
501 if (FAILED(hr)) goto out;
502
503 saBound.lLbound = 0;
504 saBound.cElements = sizeof(data_block);
505 psa = SafeArrayCreate(VT_UI1, 1, &saBound);
506 ok(psa != NULL, "Unable to crate safe array\n");
507 if (!psa) goto out;
508 hr = SafeArrayAccessData(psa, (LPVOID *)&pbSAData);
509 ok(hr == S_OK, "Unable to access array data\n");
510 if (FAILED(hr)) goto out;
511 memcpy(pbSAData, data_block, sizeof(data_block));
512
513 hr = IAMFilterData_ParseFilterData(pData, pbSAData, sizeof(data_block), &prgbRegFilter2);
514 /* We cannot do anything here. prgbRegFilter2 is very unstable */
515 /* Pre Vista, this is a stack pointer so anything that changes the stack invalidats it */
516 /* Post Vista, it is a static pointer in the data section of the module */
517 pRegFilter =((REGFILTER2**)prgbRegFilter2)[0];
518 ok (hr==S_OK,"Failed to Parse filter Data\n");
519
520 ok(IsBadReadPtr(prgbRegFilter2,sizeof(REGFILTER2*))==0,"Bad read pointer returned\n");
521 ok(IsBadReadPtr(pRegFilter,sizeof(REGFILTER2))==0,"Bad read pointer for FilterData\n");
522 ok(pRegFilter->dwMerit == 0x5fffff,"Incorrect merit returned\n");
523
524 out:
525 if (pRegFilter)
526 CoTaskMemFree(pRegFilter);
527 if (psa)
528 {
529 SafeArrayUnaccessData(psa);
530 SafeArrayDestroy(psa);
531 }
532 if (pData)
533 IAMFilterData_Release(pData);
534 if (pMapper)
535 IFilterMapper2_Release(pMapper);
536 }
537
538 START_TEST(filtermapper)
539 {
540 CoInitialize(NULL);
541
542 test_fm2_enummatchingfilters();
543 test_legacy_filter_registration();
544 test_ifiltermapper_from_filtergraph();
545 test_register_filter_with_null_clsMinorType();
546 test_parse_filter_data();
547
548 CoUninitialize();
549 }