ReactOS 0.4.15-dev-7958-gcd0bb1a
filtermapper.c
Go to the documentation of this file.
1/*
2 * IFilterMapper & IFilterMapper3 Implementations
3 *
4 * Copyright 2003 Robert Shearman
5 * Copyright 2004 Christian Costa
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#define NONAMELESSUNION
23#define NONAMELESSSTRUCT
24#include <stdarg.h>
25
26#include "windef.h"
27#include "winbase.h"
28#include "winuser.h"
29#include "winreg.h"
30#include "winerror.h"
31
32#include "quartz_private.h"
33
34#include "ole2.h"
35#include "olectl.h"
36#include "strmif.h"
37#include "wine/unicode.h"
38#include "uuids.h"
39#include "initguid.h"
40#include "fil_data.h"
41
42#include "wine/debug.h"
43
45
46#undef ARRAYSIZE
47#define ARRAYSIZE(array) (sizeof(array)/sizeof((array)[0]))
48
49typedef struct FilterMapper3Impl
50{
52 IFilterMapper3 IFilterMapper3_iface;
53 IFilterMapper IFilterMapper_iface;
58
59static inline FilterMapper3Impl *impl_from_IFilterMapper3( IFilterMapper3 *iface )
60{
61 return CONTAINING_RECORD(iface, FilterMapper3Impl, IFilterMapper3_iface);
62}
63
64static inline FilterMapper3Impl *impl_from_IFilterMapper( IFilterMapper *iface )
65{
66 return CONTAINING_RECORD(iface, FilterMapper3Impl, IFilterMapper_iface);
67}
68
70{
71 return CONTAINING_RECORD(iface, FilterMapper3Impl, IAMFilterData_iface);
72}
73
75{
76 return CONTAINING_RECORD(iface, FilterMapper3Impl, IUnknown_inner);
77}
78
79static const WCHAR wszClsidSlash[] = {'C','L','S','I','D','\\',0};
80static const WCHAR wszSlashInstance[] = {'\\','I','n','s','t','a','n','c','e','\\',0};
81static const WCHAR wszSlash[] = {'\\',0};
82
83/* CLSID property in media category Moniker */
84static const WCHAR wszClsidName[] = {'C','L','S','I','D',0};
85/* FriendlyName property in media category Moniker */
86static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
87/* Merit property in media category Moniker (CLSID_ActiveMovieCategories only) */
88static const WCHAR wszMeritName[] = {'M','e','r','i','t',0};
89/* FilterData property in media category Moniker (not CLSID_ActiveMovieCategories) */
90static const WCHAR wszFilterDataName[] = {'F','i','l','t','e','r','D','a','t','a',0};
91/* For filters registered with IFilterMapper */
92static const WCHAR wszFilterSlash[] = {'F','i','l','t','e','r','\\',0};
93static const WCHAR wszFilter[] = {'F','i','l','t','e','r',0};
94/* For pins registered with IFilterMapper */
95static const WCHAR wszPins[] = {'P','i','n','s',0};
96static const WCHAR wszAllowedMany[] = {'A','l','l','o','w','e','d','M','a','n','y',0};
97static const WCHAR wszAllowedZero[] = {'A','l','l','o','w','e','d','Z','e','r','o',0};
98static const WCHAR wszDirection[] = {'D','i','r','e','c','t','i','o','n',0};
99static const WCHAR wszIsRendered[] = {'I','s','R','e','n','d','e','r','e','d',0};
100/* For types registered with IFilterMapper */
101static const WCHAR wszTypes[] = {'T','y','p','e','s',0};
102
103
104/* registry format for REGFILTER2 */
105struct REG_RF
106{
111};
112
114{
115 BYTE signature[4]; /* e.g. "0pi3" */
120 DWORD bCategory; /* is there a category clsid? */
121 /* optional: dwOffsetCategoryClsid */
122};
123
125{
126 BYTE signature[4]; /* e.g. "0ty3" */
130};
131
133{
136};
137
138struct Vector
139{
141 int capacity; /* in bytes */
142 int current; /* pointer to next free byte */
143};
144
145/* returns the position it was added at */
146static int add_data(struct Vector * v, const BYTE * pData, int size)
147{
148 int index = v->current;
149 if (v->current + size > v->capacity)
150 {
151 LPBYTE pOldData = v->pData;
152 v->capacity = (v->capacity + size) * 2;
153 v->pData = CoTaskMemAlloc(v->capacity);
154 memcpy(v->pData, pOldData, v->current);
155 CoTaskMemFree(pOldData);
156 }
157 memcpy(v->pData + v->current, pData, size);
158 v->current += size;
159 return index;
160}
161
162static int find_data(const struct Vector * v, const BYTE * pData, int size)
163{
164 int index;
165 for (index = 0; index < v->current; index++)
166 if (!memcmp(v->pData + index, pData, size))
167 return index;
168 /* not found */
169 return -1;
170}
171
172static void delete_vector(struct Vector * v)
173{
174 CoTaskMemFree(v->pData);
175 v->current = 0;
176 v->capacity = 0;
177}
178
179/*** IUnknown (inner) methods ***/
180
182{
184
185 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
186
187 *ppv = NULL;
189 *ppv = &This->IUnknown_inner;
190 else if (IsEqualIID(riid, &IID_IFilterMapper2) || IsEqualIID(riid, &IID_IFilterMapper3))
191 *ppv = &This->IFilterMapper3_iface;
192 else if (IsEqualIID(riid, &IID_IFilterMapper))
193 *ppv = &This->IFilterMapper_iface;
194 else if (IsEqualIID(riid, &IID_IAMFilterData))
195 *ppv = &This->IAMFilterData_iface;
196
197 if (*ppv != NULL)
198 {
199 IUnknown_AddRef((IUnknown *)*ppv);
200 return S_OK;
201 }
202
203 FIXME("No interface for %s\n", debugstr_guid(riid));
204 return E_NOINTERFACE;
205}
206
208{
211
212 TRACE("(%p)->(): new ref = %d\n", This, ref);
213
214 return ref;
215}
216
218{
221
222 TRACE("(%p)->(): new ref = %d\n", This, ref);
223
224 if (ref == 0)
226
227 return ref;
228}
229
230static const IUnknownVtbl IInner_VTable =
231{
235};
236
238{
240
241 return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
242}
243
244static ULONG WINAPI FilterMapper3_AddRef(IFilterMapper3 * iface)
245{
247
248 return IUnknown_AddRef(This->outer_unk);
249}
250
251static ULONG WINAPI FilterMapper3_Release(IFilterMapper3 * iface)
252{
254
255 return IUnknown_Release(This->outer_unk);
256}
257
258/*** IFilterMapper3 methods ***/
259
261 IFilterMapper3 * iface,
262 REFCLSID clsidCategory,
263 DWORD dwCategoryMerit,
265{
266 LPWSTR wClsidAMCat = NULL;
267 LPWSTR wClsidCategory = NULL;
268 WCHAR wszKeyName[ARRAYSIZE(wszClsidSlash)-1 + ARRAYSIZE(wszSlashInstance)-1 + (CHARS_IN_GUID-1) * 2 + 1];
269 HKEY hKey = NULL;
270 LONG lRet;
271 HRESULT hr;
272
273 TRACE("(%s, %x, %s)\n", debugstr_guid(clsidCategory), dwCategoryMerit, debugstr_w(szDescription));
274
275 hr = StringFromCLSID(&CLSID_ActiveMovieCategories, &wClsidAMCat);
276
277 if (SUCCEEDED(hr))
278 {
279 hr = StringFromCLSID(clsidCategory, &wClsidCategory);
280 }
281
282 if (SUCCEEDED(hr))
283 {
284 strcpyW(wszKeyName, wszClsidSlash);
285 strcatW(wszKeyName, wClsidAMCat);
286 strcatW(wszKeyName, wszSlashInstance);
287 strcatW(wszKeyName, wClsidCategory);
288
290 hr = HRESULT_FROM_WIN32(lRet);
291 }
292
293 if (SUCCEEDED(hr))
294 {
295 lRet = RegSetValueExW(hKey, wszFriendlyName, 0, REG_SZ, (const BYTE*)szDescription, (strlenW(szDescription) + 1) * sizeof(WCHAR));
296 hr = HRESULT_FROM_WIN32(lRet);
297 }
298
299 if (SUCCEEDED(hr))
300 {
301 lRet = RegSetValueExW(hKey, wszClsidName, 0, REG_SZ, (LPBYTE)wClsidCategory, (strlenW(wClsidCategory) + 1) * sizeof(WCHAR));
302 hr = HRESULT_FROM_WIN32(lRet);
303 }
304
305 if (SUCCEEDED(hr))
306 {
307 lRet = RegSetValueExW(hKey, wszMeritName, 0, REG_DWORD, (LPBYTE)&dwCategoryMerit, sizeof(dwCategoryMerit));
308 hr = HRESULT_FROM_WIN32(lRet);
309 }
310
312 CoTaskMemFree(wClsidCategory);
313 CoTaskMemFree(wClsidAMCat);
314
315 return hr;
316}
317
319 IFilterMapper3 * iface,
320 const CLSID *pclsidCategory,
321 const OLECHAR *szInstance,
323{
324 WCHAR wszKeyName[MAX_PATH];
325 LPWSTR wClsidCategory = NULL;
326 LPWSTR wFilter = NULL;
327 HRESULT hr;
328
329 TRACE("(%p, %s, %s)\n", pclsidCategory, debugstr_w(szInstance), debugstr_guid(Filter));
330
331 if (!pclsidCategory)
332 pclsidCategory = &CLSID_LegacyAmFilterCategory;
333
334 hr = StringFromCLSID(pclsidCategory, &wClsidCategory);
335
336 if (SUCCEEDED(hr))
337 {
338 strcpyW(wszKeyName, wszClsidSlash);
339 strcatW(wszKeyName, wClsidCategory);
340 strcatW(wszKeyName, wszSlashInstance);
341 if (szInstance)
342 strcatW(wszKeyName, szInstance);
343 else
344 {
345 hr = StringFromCLSID(Filter, &wFilter);
346 if (SUCCEEDED(hr))
347 strcatW(wszKeyName, wFilter);
348 }
349 }
350
351 if (SUCCEEDED(hr))
352 {
353 LONG lRet = RegDeleteKeyW(HKEY_CLASSES_ROOT, wszKeyName);
354 hr = HRESULT_FROM_WIN32(lRet);
355 }
356
357 CoTaskMemFree(wClsidCategory);
358 CoTaskMemFree(wFilter);
359
360 return hr;
361}
362
364{
365 VARIANT var;
366 HRESULT ret;
367 BSTR value;
368
369 V_VT(&var) = VT_BSTR;
371
372 ret = IPropertyBag_Write(pPropBag, wszFriendlyName, &var);
374
375 return ret;
376}
377
379{
380 LPWSTR wszClsid = NULL;
381 VARIANT var;
382 HRESULT hr;
383
384 hr = StringFromCLSID(clsid, &wszClsid);
385
386 if (SUCCEEDED(hr))
387 {
388 V_VT(&var) = VT_BSTR;
389 V_BSTR(&var) = wszClsid;
390 hr = IPropertyBag_Write(pPropBag, wszClsidName, &var);
391 }
392 CoTaskMemFree(wszClsid);
393 return hr;
394}
395
397{
398 int size = sizeof(struct REG_RF);
399 unsigned int i;
400 struct Vector mainStore = {NULL, 0, 0};
401 struct Vector clsidStore = {NULL, 0, 0};
402 struct REG_RF rrf;
403 HRESULT hr = S_OK;
404
405 rrf.dwVersion = prf2->dwVersion;
406 rrf.dwMerit = prf2->dwMerit;
407 rrf.dwPins = prf2->u.s2.cPins2;
408 rrf.dwUnused = 0;
409
410 add_data(&mainStore, (LPBYTE)&rrf, sizeof(rrf));
411
412 for (i = 0; i < prf2->u.s2.cPins2; i++)
413 {
414 size += sizeof(struct REG_RFP);
415 if (prf2->u.s2.rgPins2[i].clsPinCategory)
416 size += sizeof(DWORD);
417 size += prf2->u.s2.rgPins2[i].nMediaTypes * sizeof(struct REG_TYPE);
418 size += prf2->u.s2.rgPins2[i].nMediums * sizeof(DWORD);
419 }
420
421 for (i = 0; i < prf2->u.s2.cPins2; i++)
422 {
423 struct REG_RFP rrfp;
424 REGFILTERPINS2 rgPin2 = prf2->u.s2.rgPins2[i];
425 unsigned int j;
426
427 rrfp.signature[0] = '0';
428 rrfp.signature[1] = 'p';
429 rrfp.signature[2] = 'i';
430 rrfp.signature[3] = '3';
431 rrfp.signature[0] += i;
432 rrfp.dwFlags = rgPin2.dwFlags;
433 rrfp.dwInstances = rgPin2.cInstances;
434 rrfp.dwMediaTypes = rgPin2.nMediaTypes;
435 rrfp.dwMediums = rgPin2.nMediums;
436 rrfp.bCategory = rgPin2.clsPinCategory ? 1 : 0;
437
438 add_data(&mainStore, (LPBYTE)&rrfp, sizeof(rrfp));
439 if (rrfp.bCategory)
440 {
441 DWORD index = find_data(&clsidStore, (const BYTE*)rgPin2.clsPinCategory, sizeof(CLSID));
442 if (index == -1)
443 index = add_data(&clsidStore, (const BYTE*)rgPin2.clsPinCategory, sizeof(CLSID));
444 index += size;
445
446 add_data(&mainStore, (LPBYTE)&index, sizeof(index));
447 }
448
449 for (j = 0; j < rgPin2.nMediaTypes; j++)
450 {
451 struct REG_TYPE rt;
452 const CLSID * clsMinorType = rgPin2.lpMediaType[j].clsMinorType ? rgPin2.lpMediaType[j].clsMinorType : &MEDIASUBTYPE_NULL;
453 rt.signature[0] = '0';
454 rt.signature[1] = 't';
455 rt.signature[2] = 'y';
456 rt.signature[3] = '3';
457 rt.signature[0] += j;
458 rt.dwUnused = 0;
459 rt.dwOffsetMajor = find_data(&clsidStore, (const BYTE*)rgPin2.lpMediaType[j].clsMajorType, sizeof(CLSID));
460 if (rt.dwOffsetMajor == -1)
461 rt.dwOffsetMajor = add_data(&clsidStore, (const BYTE*)rgPin2.lpMediaType[j].clsMajorType, sizeof(CLSID));
462 rt.dwOffsetMajor += size;
463 rt.dwOffsetMinor = find_data(&clsidStore, (const BYTE*)clsMinorType, sizeof(CLSID));
464 if (rt.dwOffsetMinor == -1)
465 rt.dwOffsetMinor = add_data(&clsidStore, (const BYTE*)clsMinorType, sizeof(CLSID));
466 rt.dwOffsetMinor += size;
467
468 add_data(&mainStore, (LPBYTE)&rt, sizeof(rt));
469 }
470
471 for (j = 0; j < rgPin2.nMediums; j++)
472 {
473 DWORD index = find_data(&clsidStore, (const BYTE*)(rgPin2.lpMedium + j), sizeof(REGPINMEDIUM));
474 if (index == -1)
475 index = add_data(&clsidStore, (const BYTE*)(rgPin2.lpMedium + j), sizeof(REGPINMEDIUM));
476 index += size;
477
478 add_data(&mainStore, (LPBYTE)&index, sizeof(index));
479 }
480 }
481
482 if (SUCCEEDED(hr))
483 {
484 *pcbData = mainStore.current + clsidStore.current;
486 if (!*ppData)
488 }
489
490 if (SUCCEEDED(hr))
491 {
492 memcpy(*ppData, mainStore.pData, mainStore.current);
493 memcpy((*ppData) + mainStore.current, clsidStore.pData, clsidStore.current);
494 }
495
496 delete_vector(&mainStore);
497 delete_vector(&clsidStore);
498 return hr;
499}
500
502{
503 HRESULT hr = S_OK;
504 struct REG_RF * prrf;
505 LPBYTE pCurrent;
506 DWORD i;
507 REGFILTERPINS2 * rgPins2;
508
509 prrf = (struct REG_RF *)pData;
510 pCurrent = pData;
511
512 if (prrf->dwVersion != 2)
513 {
514 FIXME("Filter registry version %d not supported\n", prrf->dwVersion);
515 ZeroMemory(prf2, sizeof(*prf2));
516 hr = E_FAIL;
517 }
518
519 if (SUCCEEDED(hr))
520 {
521 TRACE("version = %d, merit = %x, #pins = %d, unused = %x\n",
522 prrf->dwVersion, prrf->dwMerit, prrf->dwPins, prrf->dwUnused);
523
524 prf2->dwVersion = prrf->dwVersion;
525 prf2->dwMerit = prrf->dwMerit;
526 prf2->u.s2.cPins2 = prrf->dwPins;
527 rgPins2 = CoTaskMemAlloc(prrf->dwPins * sizeof(*rgPins2));
528 prf2->u.s2.rgPins2 = rgPins2;
529 pCurrent += sizeof(struct REG_RF);
530
531 for (i = 0; i < prrf->dwPins; i++)
532 {
533 struct REG_RFP * prrfp = (struct REG_RFP *)pCurrent;
534 REGPINTYPES * lpMediaType;
535 REGPINMEDIUM * lpMedium;
536 UINT j;
537
538 /* FIXME: check signature */
539
540 TRACE("\tsignature = %s\n", debugstr_an((const char*)prrfp->signature, 4));
541
542 TRACE("\tpin[%d]: flags = %x, instances = %d, media types = %d, mediums = %d\n",
543 i, prrfp->dwFlags, prrfp->dwInstances, prrfp->dwMediaTypes, prrfp->dwMediums);
544
545 rgPins2[i].dwFlags = prrfp->dwFlags;
546 rgPins2[i].cInstances = prrfp->dwInstances;
547 rgPins2[i].nMediaTypes = prrfp->dwMediaTypes;
548 rgPins2[i].nMediums = prrfp->dwMediums;
549 pCurrent += sizeof(struct REG_RFP);
550 if (prrfp->bCategory)
551 {
552 CLSID * clsCat = CoTaskMemAlloc(sizeof(CLSID));
553 memcpy(clsCat, pData + *(DWORD*)(pCurrent), sizeof(CLSID));
554 pCurrent += sizeof(DWORD);
555 rgPins2[i].clsPinCategory = clsCat;
556 }
557 else
558 rgPins2[i].clsPinCategory = NULL;
559
560 if (rgPins2[i].nMediaTypes > 0)
561 lpMediaType = CoTaskMemAlloc(rgPins2[i].nMediaTypes * sizeof(*lpMediaType));
562 else
563 lpMediaType = NULL;
564
565 rgPins2[i].lpMediaType = lpMediaType;
566
567 for (j = 0; j < rgPins2[i].nMediaTypes; j++)
568 {
569 struct REG_TYPE * prt = (struct REG_TYPE *)pCurrent;
570 CLSID * clsMajor = CoTaskMemAlloc(sizeof(CLSID));
571 CLSID * clsMinor = CoTaskMemAlloc(sizeof(CLSID));
572
573 /* FIXME: check signature */
574 TRACE("\t\tsignature = %s\n", debugstr_an((const char*)prt->signature, 4));
575
576 memcpy(clsMajor, pData + prt->dwOffsetMajor, sizeof(CLSID));
577 memcpy(clsMinor, pData + prt->dwOffsetMinor, sizeof(CLSID));
578
579 lpMediaType[j].clsMajorType = clsMajor;
580 lpMediaType[j].clsMinorType = clsMinor;
581
582 pCurrent += sizeof(*prt);
583 }
584
585 if (rgPins2[i].nMediums > 0)
586 lpMedium = CoTaskMemAlloc(rgPins2[i].nMediums * sizeof(*lpMedium));
587 else
588 lpMedium = NULL;
589
590 rgPins2[i].lpMedium = lpMedium;
591
592 for (j = 0; j < rgPins2[i].nMediums; j++)
593 {
594 DWORD dwOffset = *(DWORD *)pCurrent;
595
596 memcpy(lpMedium + j, pData + dwOffset, sizeof(REGPINMEDIUM));
597
598 pCurrent += sizeof(dwOffset);
599 }
600 }
601
602 }
603
604 return hr;
605}
606
608{
609 UINT i;
610 for (i = 0; i < prf2->u.s2.cPins2; i++)
611 {
612 UINT j;
613 CoTaskMemFree((void*)prf2->u.s2.rgPins2[i].clsPinCategory);
614
615 for (j = 0; j < prf2->u.s2.rgPins2[i].nMediaTypes; j++)
616 {
617 CoTaskMemFree((LPVOID)prf2->u.s2.rgPins2[i].lpMediaType[j].clsMajorType);
618 CoTaskMemFree((LPVOID)prf2->u.s2.rgPins2[i].lpMediaType[j].clsMinorType);
619 }
621 CoTaskMemFree((LPVOID)prf2->u.s2.rgPins2[i].lpMedium);
622 }
623 CoTaskMemFree((LPVOID)prf2->u.s2.rgPins2);
624}
625
627 IFilterMapper3 * iface,
628 REFCLSID clsidFilter,
630 IMoniker **ppMoniker,
631 const CLSID *pclsidCategory,
632 const OLECHAR *szInstance,
633 const REGFILTER2 *prf2)
634{
635 IParseDisplayName * pParser = NULL;
636 IBindCtx * pBindCtx = NULL;
637 IMoniker * pMoniker = NULL;
638 IPropertyBag * pPropBag = NULL;
639 HRESULT hr;
640 LPWSTR pwszParseName = NULL;
641 LPWSTR pCurrent;
642 static const WCHAR wszDevice[] = {'@','d','e','v','i','c','e',':','s','w',':',0};
643 int nameLen;
644 ULONG ulEaten;
645 LPWSTR szClsidTemp = NULL;
646 REGFILTER2 regfilter2;
647 REGFILTERPINS2* pregfp2 = NULL;
648
649 TRACE("(%s, %s, %p, %s, %s, %p)\n",
650 debugstr_guid(clsidFilter),
652 ppMoniker,
653 debugstr_guid(pclsidCategory),
654 debugstr_w(szInstance),
655 prf2);
656
657 if (prf2->dwVersion == 2)
658 {
659 regfilter2 = *prf2;
660 }
661 else if (prf2->dwVersion == 1)
662 {
663 ULONG i;
664 DWORD flags;
665 /* REGFILTER2 structure is converted from version 1 to 2. Tested on Win2k. */
666 regfilter2.dwVersion = 2;
667 regfilter2.dwMerit = prf2->dwMerit;
668 regfilter2.u.s2.cPins2 = prf2->u.s1.cPins;
669 pregfp2 = CoTaskMemAlloc(prf2->u.s1.cPins * sizeof(REGFILTERPINS2));
670 regfilter2.u.s2.rgPins2 = pregfp2;
671 for (i = 0; i < prf2->u.s1.cPins; i++)
672 {
673 flags = 0;
674 if (prf2->u.s1.rgPins[i].bRendered)
676 if (prf2->u.s1.rgPins[i].bOutput)
678 if (prf2->u.s1.rgPins[i].bZero)
680 if (prf2->u.s1.rgPins[i].bMany)
682 pregfp2[i].dwFlags = flags;
683 pregfp2[i].cInstances = 1;
684 pregfp2[i].nMediaTypes = prf2->u.s1.rgPins[i].nMediaTypes;
685 pregfp2[i].lpMediaType = prf2->u.s1.rgPins[i].lpMediaType;
686 pregfp2[i].nMediums = 0;
687 pregfp2[i].lpMedium = NULL;
688 pregfp2[i].clsPinCategory = NULL;
689 }
690 }
691 else
692 {
693 FIXME("dwVersion other that 1 or 2 not supported at the moment\n");
694 return E_NOTIMPL;
695 }
696
697 if (ppMoniker)
698 *ppMoniker = NULL;
699
700 if (!pclsidCategory)
701 /* MSDN mentions the inexistent CLSID_ActiveMovieFilters GUID.
702 * In fact this is the CLSID_LegacyAmFilterCategory one */
703 pclsidCategory = &CLSID_LegacyAmFilterCategory;
704
705 /* sizeof... will include the null terminator and
706 * the + 1 is for the separator ('\\'). The -1 is
707 * because CHARS_IN_GUID includes the null terminator
708 */
709 nameLen = sizeof(wszDevice)/sizeof(wszDevice[0]) + CHARS_IN_GUID - 1 + 1;
710
711 if (szInstance)
712 nameLen += strlenW(szInstance);
713 else
714 nameLen += CHARS_IN_GUID - 1; /* CHARS_IN_GUID includes null terminator */
715
716 pCurrent = pwszParseName = CoTaskMemAlloc(nameLen*sizeof(WCHAR));
717 if (!pwszParseName)
718 return E_OUTOFMEMORY;
719
720 strcpyW(pwszParseName, wszDevice);
721 pCurrent += strlenW(wszDevice);
722
723 hr = StringFromCLSID(pclsidCategory, &szClsidTemp);
724
725 if (SUCCEEDED(hr))
726 {
727 memcpy(pCurrent, szClsidTemp, CHARS_IN_GUID * sizeof(WCHAR));
728 pCurrent += CHARS_IN_GUID - 1;
729 pCurrent[0] = '\\';
730
731 if (szInstance)
732 strcpyW(pCurrent+1, szInstance);
733 else
734 {
735 CoTaskMemFree(szClsidTemp);
736 szClsidTemp = NULL;
737
738 hr = StringFromCLSID(clsidFilter, &szClsidTemp);
739 if (SUCCEEDED(hr))
740 strcpyW(pCurrent+1, szClsidTemp);
741 }
742 }
743
744 if (SUCCEEDED(hr))
745 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (LPVOID *)&pParser);
746
747 if (SUCCEEDED(hr))
748 hr = CreateBindCtx(0, &pBindCtx);
749
750 if (SUCCEEDED(hr))
751 hr = IParseDisplayName_ParseDisplayName(pParser, pBindCtx, pwszParseName, &ulEaten, &pMoniker);
752
753 if (pBindCtx)
754 IBindCtx_Release(pBindCtx);
755 if (pParser)
756 IParseDisplayName_Release(pParser);
757
758 if (SUCCEEDED(hr))
759 hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID)&pPropBag);
760
761 if (SUCCEEDED(hr))
762 hr = FM2_WriteFriendlyName(pPropBag, szName);
763
764 if (SUCCEEDED(hr))
765 hr = FM2_WriteClsid(pPropBag, clsidFilter);
766
767 if (SUCCEEDED(hr))
768 {
769 BYTE *pData;
770 ULONG cbData;
771
772 hr = FM2_WriteFilterData(&regfilter2, &pData, &cbData);
773 if (SUCCEEDED(hr))
774 {
775 VARIANT var;
776 SAFEARRAY *psa;
777 SAFEARRAYBOUND saBound;
778
779 saBound.lLbound = 0;
780 saBound.cElements = cbData;
781 psa = SafeArrayCreate(VT_UI1, 1, &saBound);
782 if (!psa)
783 {
784 ERR("Couldn't create SAFEARRAY\n");
785 hr = E_FAIL;
786 }
787
788 if (SUCCEEDED(hr))
789 {
790 LPBYTE pbSAData;
791 hr = SafeArrayAccessData(psa, (LPVOID *)&pbSAData);
792 if (SUCCEEDED(hr))
793 {
794 memcpy(pbSAData, pData, cbData);
796 }
797 }
798
799 V_VT(&var) = VT_ARRAY | VT_UI1;
800 V_ARRAY(&var) = psa;
801
802 if (SUCCEEDED(hr))
803 hr = IPropertyBag_Write(pPropBag, wszFilterDataName, &var);
804
805 if (psa)
808 }
809 }
810
811 if (pPropBag)
812 IPropertyBag_Release(pPropBag);
813 CoTaskMemFree(szClsidTemp);
814 CoTaskMemFree(pwszParseName);
815
816 if (SUCCEEDED(hr) && ppMoniker)
817 *ppMoniker = pMoniker;
818 else if (pMoniker)
819 IMoniker_Release(pMoniker);
820
821 CoTaskMemFree(pregfp2);
822
823 TRACE("-- returning %x\n", hr);
824
825 return hr;
826}
827
828/* internal helper function */
830 BOOL bExactMatch,
831 DWORD nPinTypes,
832 const REGPINTYPES * pPinTypes,
833 DWORD nMatchTypes,
834 const GUID * pMatchTypes)
835{
836 BOOL bMatch = FALSE;
837 DWORD j;
838
839 if ((nMatchTypes == 0) && (nPinTypes > 0))
840 bMatch = TRUE;
841
842 for (j = 0; j < nPinTypes; j++)
843 {
844 DWORD i;
845 for (i = 0; i < nMatchTypes*2; i+=2)
846 {
847 if (((!bExactMatch && IsEqualGUID(pPinTypes[j].clsMajorType, &GUID_NULL)) || IsEqualGUID(&pMatchTypes[i], &GUID_NULL) || IsEqualGUID(pPinTypes[j].clsMajorType, &pMatchTypes[i])) &&
848 ((!bExactMatch && IsEqualGUID(pPinTypes[j].clsMinorType, &GUID_NULL)) || IsEqualGUID(&pMatchTypes[i+1], &GUID_NULL) || IsEqualGUID(pPinTypes[j].clsMinorType, &pMatchTypes[i+1])))
849 {
850 bMatch = TRUE;
851 break;
852 }
853 }
854 }
855 return bMatch;
856}
857
858/* internal helper function for qsort of MONIKER_MERIT array */
859static int mm_compare(const void * left, const void * right)
860{
861 const struct MONIKER_MERIT * mmLeft = left;
862 const struct MONIKER_MERIT * mmRight = right;
863
864 if (mmLeft->dwMerit == mmRight->dwMerit)
865 return 0;
866 if (mmLeft->dwMerit > mmRight->dwMerit)
867 return -1;
868 return 1;
869}
870
871/* NOTES:
872 * Exact match means whether or not to treat GUID_NULL's in filter data as wild cards
873 * (GUID_NULL's in input to function automatically treated as wild cards)
874 * Input/Output needed means match only on criteria if TRUE (with zero input types
875 * meaning match any input/output pin as long as one exists), otherwise match any
876 * filter that meets the rest of the requirements.
877 */
879 IFilterMapper3 * iface,
880 IEnumMoniker **ppEnum,
882 BOOL bExactMatch,
884 BOOL bInputNeeded,
885 DWORD cInputTypes,
886 const GUID *pInputTypes,
887 const REGPINMEDIUM *pMedIn,
888 const CLSID *pPinCategoryIn,
889 BOOL bRender,
890 BOOL bOutputNeeded,
891 DWORD cOutputTypes,
892 const GUID *pOutputTypes,
893 const REGPINMEDIUM *pMedOut,
894 const CLSID *pPinCategoryOut)
895{
896 ICreateDevEnum * pCreateDevEnum;
897 IMoniker * pMonikerCat;
898 IEnumMoniker * pEnumCat;
899 HRESULT hr;
900 struct Vector monikers = {NULL, 0, 0};
901
902 TRACE("(%p, %x, %s, %x, %s, %d, %p, %p, %p, %s, %s, %p, %p, %p)\n",
903 ppEnum,
904 dwFlags,
905 bExactMatch ? "true" : "false",
906 dwMerit,
907 bInputNeeded ? "true" : "false",
908 cInputTypes,
909 pInputTypes,
910 pMedIn,
911 pPinCategoryIn,
912 bRender ? "true" : "false",
913 bOutputNeeded ? "true" : "false",
914 pOutputTypes,
915 pMedOut,
916 pPinCategoryOut);
917
918 if (dwFlags != 0)
919 {
920 FIXME("dwFlags = %x not implemented\n", dwFlags);
921 }
922
923 *ppEnum = NULL;
924
925 hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, &IID_ICreateDevEnum, (LPVOID*)&pCreateDevEnum);
926 if (FAILED(hr))
927 return hr;
928
929 hr = ICreateDevEnum_CreateClassEnumerator(pCreateDevEnum, &CLSID_ActiveMovieCategories, &pEnumCat, 0);
930 if (FAILED(hr)) {
931 ICreateDevEnum_Release(pCreateDevEnum);
932 return hr;
933 }
934
935 while (IEnumMoniker_Next(pEnumCat, 1, &pMonikerCat, NULL) == S_OK)
936 {
937 IPropertyBag * pPropBagCat = NULL;
938 VARIANT var;
939 HRESULT hrSub; /* this is so that one buggy filter
940 doesn't make the whole lot fail */
941
943
944 hrSub = IMoniker_BindToStorage(pMonikerCat, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBagCat);
945
946 if (SUCCEEDED(hrSub))
947 hrSub = IPropertyBag_Read(pPropBagCat, wszMeritName, &var, NULL);
948
949 if (SUCCEEDED(hrSub) && (V_UI4(&var) >= dwMerit))
950 {
951 CLSID clsidCat;
952 IEnumMoniker * pEnum;
953 IMoniker * pMoniker;
954
956
957 if (TRACE_ON(quartz))
958 {
960 V_VT(&temp) = VT_EMPTY;
961 IPropertyBag_Read(pPropBagCat, wszFriendlyName, &temp, NULL);
962 TRACE("Considering category %s\n", debugstr_w(V_BSTR(&temp)));
964 }
965
966 hrSub = IPropertyBag_Read(pPropBagCat, wszClsidName, &var, NULL);
967
968 if (SUCCEEDED(hrSub))
969 hrSub = CLSIDFromString(V_BSTR(&var), &clsidCat);
970
971 if (SUCCEEDED(hrSub))
972 hrSub = ICreateDevEnum_CreateClassEnumerator(pCreateDevEnum, &clsidCat, &pEnum, 0);
973
974 if (hrSub == S_OK)
975 {
976 while (IEnumMoniker_Next(pEnum, 1, &pMoniker, NULL) == S_OK)
977 {
978 IPropertyBag * pPropBag = NULL;
979 VARIANT var;
980 BYTE *pData = NULL;
981 REGFILTER2 rf2;
982 DWORD i;
983 BOOL bInputMatch = !bInputNeeded;
984 BOOL bOutputMatch = !bOutputNeeded;
985
986 ZeroMemory(&rf2, sizeof(rf2));
988
989 hrSub = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBag);
990
991 if (TRACE_ON(quartz))
992 {
994 V_VT(&temp) = VT_EMPTY;
995 IPropertyBag_Read(pPropBag, wszFriendlyName, &temp, NULL);
996 TRACE("Considering filter %s\n", debugstr_w(V_BSTR(&temp)));
998 }
999
1000 if (SUCCEEDED(hrSub))
1001 {
1002 hrSub = IPropertyBag_Read(pPropBag, wszFilterDataName, &var, NULL);
1003 }
1004
1005 if (SUCCEEDED(hrSub))
1007
1008 if (SUCCEEDED(hrSub))
1009 hrSub = FM2_ReadFilterData(pData, &rf2);
1010
1011 if (pData)
1013
1014 VariantClear(&var);
1015
1016 /* Logic used for bInputMatch expression:
1017 * There exists some pin such that bInputNeeded implies (pin is an input and
1018 * (bRender implies pin has render flag) and major/minor types members of
1019 * pInputTypes )
1020 * bOutputMatch is similar, but without the "bRender implies ..." part
1021 * and substituting variables names containing input for output
1022 */
1023
1024 /* determine whether filter meets requirements */
1025 if (SUCCEEDED(hrSub) && (rf2.dwMerit >= dwMerit))
1026 {
1027 for (i = 0; (i < rf2.u.s2.cPins2) && (!bInputMatch || !bOutputMatch); i++)
1028 {
1029 const REGFILTERPINS2 * rfp2 = rf2.u.s2.rgPins2 + i;
1030
1031 bInputMatch = bInputMatch || (!(rfp2->dwFlags & REG_PINFLAG_B_OUTPUT) &&
1032 (!bRender || (rfp2->dwFlags & REG_PINFLAG_B_RENDERER)) &&
1033 MatchTypes(bExactMatch, rfp2->nMediaTypes, rfp2->lpMediaType, cInputTypes, pInputTypes));
1034 bOutputMatch = bOutputMatch || ((rfp2->dwFlags & REG_PINFLAG_B_OUTPUT) &&
1035 MatchTypes(bExactMatch, rfp2->nMediaTypes, rfp2->lpMediaType, cOutputTypes, pOutputTypes));
1036 }
1037
1038 if (bInputMatch && bOutputMatch)
1039 {
1040 struct MONIKER_MERIT mm = {pMoniker, rf2.dwMerit};
1041 IMoniker_AddRef(pMoniker);
1042 add_data(&monikers, (LPBYTE)&mm, sizeof(mm));
1043 }
1044 }
1045
1046 FM2_DeleteRegFilter(&rf2);
1047 if (pPropBag)
1048 IPropertyBag_Release(pPropBag);
1049 IMoniker_Release(pMoniker);
1050 }
1051 IEnumMoniker_Release(pEnum);
1052 }
1053 }
1054
1055 VariantClear(&var);
1056 if (pPropBagCat)
1057 IPropertyBag_Release(pPropBagCat);
1058 IMoniker_Release(pMonikerCat);
1059 }
1060
1061 if (SUCCEEDED(hr))
1062 {
1063 IMoniker ** ppMoniker;
1064 unsigned int i;
1065 ULONG nMonikerCount = monikers.current / sizeof(struct MONIKER_MERIT);
1066
1067 /* sort the monikers in descending merit order */
1068 qsort(monikers.pData, nMonikerCount,
1069 sizeof(struct MONIKER_MERIT),
1070 mm_compare);
1071
1072 /* construct an IEnumMoniker interface */
1073 ppMoniker = CoTaskMemAlloc(nMonikerCount * sizeof(IMoniker *));
1074 for (i = 0; i < nMonikerCount; i++)
1075 {
1076 /* no need to AddRef here as already AddRef'd above */
1077 ppMoniker[i] = ((struct MONIKER_MERIT *)monikers.pData)[i].pMoniker;
1078 }
1079 hr = EnumMonikerImpl_Create(ppMoniker, nMonikerCount, ppEnum);
1080 CoTaskMemFree(ppMoniker);
1081 }
1082
1083 delete_vector(&monikers);
1084 IEnumMoniker_Release(pEnumCat);
1085 ICreateDevEnum_Release(pCreateDevEnum);
1086
1087 return hr;
1088}
1089
1090static HRESULT WINAPI FilterMapper3_GetICreateDevEnum(IFilterMapper3 *iface, ICreateDevEnum **ppEnum)
1091{
1092 TRACE("(%p, %p)\n", iface, ppEnum);
1093 if (!ppEnum)
1094 return E_POINTER;
1095 return CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, &IID_ICreateDevEnum, (void**)ppEnum);
1096}
1097
1098static const IFilterMapper3Vtbl fm3vtbl =
1099{
1100
1104
1110};
1111
1112/*** IUnknown methods ***/
1113
1115{
1117
1118 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
1119
1120 return FilterMapper3_QueryInterface(&This->IFilterMapper3_iface, riid, ppv);
1121}
1122
1123static ULONG WINAPI FilterMapper_AddRef(IFilterMapper * iface)
1124{
1126
1127 return IUnknown_AddRef(This->outer_unk);
1128}
1129
1130static ULONG WINAPI FilterMapper_Release(IFilterMapper * iface)
1131{
1133
1134 return IUnknown_Release(This->outer_unk);
1135}
1136
1137/*** IFilterMapper methods ***/
1138
1140 IFilterMapper * iface,
1141 IEnumRegFilters **ppEnum,
1142 DWORD dwMerit,
1143 BOOL bInputNeeded,
1144 CLSID clsInMaj,
1145 CLSID clsInSub,
1146 BOOL bRender,
1147 BOOL bOutputNeeded,
1148 CLSID clsOutMaj,
1149 CLSID clsOutSub)
1150{
1152 GUID InputType[2];
1153 GUID OutputType[2];
1154 IEnumMoniker* ppEnumMoniker;
1155 IMoniker* IMon;
1156 ULONG nb;
1157 ULONG idx = 0, nb_mon = 0;
1158 REGFILTER* regfilters;
1159 HRESULT hr;
1160
1161 TRACE("(%p/%p)->(%p, %x, %s, %s, %s, %s, %s, %s, %s)\n",
1162 This,
1163 iface,
1164 ppEnum,
1165 dwMerit,
1166 bInputNeeded ? "true" : "false",
1167 debugstr_guid(&clsInMaj),
1168 debugstr_guid(&clsInSub),
1169 bRender ? "true" : "false",
1170 bOutputNeeded ? "true" : "false",
1171 debugstr_guid(&clsOutMaj),
1172 debugstr_guid(&clsOutSub));
1173
1174 InputType[0] = clsInMaj;
1175 InputType[1] = clsInSub;
1176 OutputType[0] = clsOutMaj;
1177 OutputType[1] = clsOutSub;
1178
1179 *ppEnum = NULL;
1180
1181 hr = IFilterMapper3_EnumMatchingFilters(&This->IFilterMapper3_iface, &ppEnumMoniker, 0, TRUE,
1182 dwMerit, bInputNeeded, 1, InputType, NULL, &GUID_NULL, bRender, bOutputNeeded, 1,
1183 OutputType, NULL, &GUID_NULL);
1184
1185 if (FAILED(hr))
1186 return hr;
1187
1188 while(IEnumMoniker_Next(ppEnumMoniker, 1, &IMon, &nb) == S_OK)
1189 {
1190 IMoniker_Release(IMon);
1191 nb_mon++;
1192 }
1193
1194 if (!nb_mon)
1195 {
1196 IEnumMoniker_Release(ppEnumMoniker);
1197 return IEnumRegFiltersImpl_Construct(NULL, 0, ppEnum);
1198 }
1199
1200 regfilters = CoTaskMemAlloc(nb_mon * sizeof(REGFILTER));
1201 if (!regfilters)
1202 {
1203 IEnumMoniker_Release(ppEnumMoniker);
1204 return E_OUTOFMEMORY;
1205 }
1206 ZeroMemory(regfilters, nb_mon * sizeof(REGFILTER)); /* will prevent bad free of Name in case of error. */
1207
1208 IEnumMoniker_Reset(ppEnumMoniker);
1209 while(IEnumMoniker_Next(ppEnumMoniker, 1, &IMon, &nb) == S_OK)
1210 {
1211 IPropertyBag * pPropBagCat = NULL;
1212 VARIANT var;
1213 HRESULT hrSub;
1214 GUID clsid;
1215 int len;
1216
1217 VariantInit(&var);
1218
1219 hrSub = IMoniker_BindToStorage(IMon, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBagCat);
1220
1221 if (SUCCEEDED(hrSub))
1222 hrSub = IPropertyBag_Read(pPropBagCat, wszClsidName, &var, NULL);
1223
1224 if (SUCCEEDED(hrSub))
1225 hrSub = CLSIDFromString(V_BSTR(&var), &clsid);
1226
1227 VariantClear(&var);
1228
1229 if (SUCCEEDED(hrSub))
1230 hrSub = IPropertyBag_Read(pPropBagCat, wszFriendlyName, &var, NULL);
1231
1232 if (SUCCEEDED(hrSub))
1233 {
1234 len = (strlenW(V_BSTR(&var))+1) * sizeof(WCHAR);
1235 if (!(regfilters[idx].Name = CoTaskMemAlloc(len*2)))
1236 hr = E_OUTOFMEMORY;
1237 }
1238
1239 if (SUCCEEDED(hrSub) && regfilters[idx].Name)
1240 {
1241 memcpy(regfilters[idx].Name, V_BSTR(&var), len);
1242 regfilters[idx].Clsid = clsid;
1243 idx++;
1244 }
1245
1246 if (pPropBagCat)
1247 IPropertyBag_Release(pPropBagCat);
1248 IMoniker_Release(IMon);
1249 VariantClear(&var);
1250 }
1251
1252 if (SUCCEEDED(hr))
1253 {
1254 hr = IEnumRegFiltersImpl_Construct(regfilters, nb_mon, ppEnum);
1255 }
1256
1257 for (idx = 0; idx < nb_mon; idx++)
1258 CoTaskMemFree(regfilters[idx].Name);
1259 CoTaskMemFree(regfilters);
1260 IEnumMoniker_Release(ppEnumMoniker);
1261
1262 return hr;
1263}
1264
1265
1267{
1268 HRESULT hr;
1269 LPWSTR wszClsid = NULL;
1270 HKEY hKey;
1271 LONG lRet;
1272 WCHAR wszKeyName[ARRAYSIZE(wszFilterSlash)-1 + (CHARS_IN_GUID-1) + 1];
1273
1274 TRACE("(%p)->(%s, %s, %x)\n", iface, debugstr_guid(&clsid), debugstr_w(szName), dwMerit);
1275
1276 hr = StringFromCLSID(&clsid, &wszClsid);
1277
1278 if (SUCCEEDED(hr))
1279 {
1280 strcpyW(wszKeyName, wszFilterSlash);
1281 strcatW(wszKeyName, wszClsid);
1282
1284 hr = HRESULT_FROM_WIN32(lRet);
1285 }
1286
1287 if (SUCCEEDED(hr))
1288 {
1289 lRet = RegSetValueExW(hKey, NULL, 0, REG_SZ, (const BYTE*)szName, (strlenW(szName) + 1) * sizeof(WCHAR));
1290 hr = HRESULT_FROM_WIN32(lRet);
1292 }
1293
1294 if (SUCCEEDED(hr))
1295 {
1296 strcpyW(wszKeyName, wszClsidSlash);
1297 strcatW(wszKeyName, wszClsid);
1298
1300 hr = HRESULT_FROM_WIN32(lRet);
1301 }
1302
1303 if (SUCCEEDED(hr))
1304 {
1306 hr = HRESULT_FROM_WIN32(lRet);
1308 }
1309
1310 CoTaskMemFree(wszClsid);
1311
1312 return hr;
1313}
1314
1316{
1317 TRACE("(%p)->(%s, %s, %p)\n", iface, debugstr_guid(&clsid), debugstr_w(szName), MRId);
1318
1319 /* Not implemented in Windows (tested on Win2k) */
1320
1321 return E_NOTIMPL;
1322}
1323
1325 IFilterMapper * iface,
1326 CLSID Filter,
1328 BOOL bRendered,
1329 BOOL bOutput,
1330 BOOL bZero,
1331 BOOL bMany,
1332 CLSID ConnectsToFilter,
1333 LPCWSTR ConnectsToPin)
1334{
1335 HRESULT hr;
1336 LONG lRet;
1337 LPWSTR wszClsid = NULL;
1338 HKEY hKey = NULL;
1339 HKEY hPinsKey = NULL;
1340 WCHAR * wszPinsKeyName;
1341 WCHAR wszKeyName[ARRAYSIZE(wszClsidSlash)-1 + (CHARS_IN_GUID-1) + 1];
1342
1343 TRACE("(%p)->(%s, %s, %d, %d, %d, %d, %s, %s)\n", iface, debugstr_guid(&Filter), debugstr_w(szName), bRendered,
1344 bOutput, bZero, bMany, debugstr_guid(&ConnectsToFilter), debugstr_w(ConnectsToPin));
1345
1346 hr = StringFromCLSID(&Filter, &wszClsid);
1347
1348 if (SUCCEEDED(hr))
1349 {
1350 strcpyW(wszKeyName, wszClsidSlash);
1351 strcatW(wszKeyName, wszClsid);
1352
1353 lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszKeyName, 0, KEY_WRITE, &hKey);
1354 hr = HRESULT_FROM_WIN32(lRet);
1355 }
1356
1357 if (SUCCEEDED(hr))
1358 {
1359 wszPinsKeyName = CoTaskMemAlloc((strlenW(wszPins) + 1 + strlenW(szName) + 1) * 2);
1360 if (!wszPinsKeyName)
1361 hr = E_OUTOFMEMORY;
1362 }
1363
1364 if (SUCCEEDED(hr))
1365 {
1366 strcpyW(wszPinsKeyName, wszPins);
1367 strcatW(wszPinsKeyName, wszSlash);
1368 strcatW(wszPinsKeyName, szName);
1369
1370 lRet = RegCreateKeyExW(hKey, wszPinsKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hPinsKey, NULL);
1371 hr = HRESULT_FROM_WIN32(lRet);
1372 CoTaskMemFree(wszPinsKeyName);
1373 }
1374
1375 if (SUCCEEDED(hr))
1376 {
1377 lRet = RegSetValueExW(hPinsKey, wszAllowedMany, 0, REG_DWORD, (LPBYTE)&bMany, sizeof(bMany));
1378 hr = HRESULT_FROM_WIN32(lRet);
1379 }
1380
1381 if (SUCCEEDED(hr))
1382 {
1383 lRet = RegSetValueExW(hPinsKey, wszAllowedZero, 0, REG_DWORD, (LPBYTE)&bZero, sizeof(bZero));
1384 hr = HRESULT_FROM_WIN32(lRet);
1385 }
1386
1387 if (SUCCEEDED(hr))
1388 {
1389 lRet = RegSetValueExW(hPinsKey, wszDirection, 0, REG_DWORD, (LPBYTE)&bOutput, sizeof(bOutput));
1390 hr = HRESULT_FROM_WIN32(lRet);
1391 }
1392
1393 if (SUCCEEDED(hr))
1394 {
1395 lRet = RegSetValueExW(hPinsKey, wszIsRendered, 0, REG_DWORD, (LPBYTE)&bRendered, sizeof(bRendered));
1396 hr = HRESULT_FROM_WIN32(lRet);
1397 }
1398
1399 if (SUCCEEDED(hr))
1400 {
1401 HKEY hkeyDummy = NULL;
1402
1403 lRet = RegCreateKeyExW(hPinsKey, wszTypes, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkeyDummy, NULL);
1404 hr = HRESULT_FROM_WIN32(lRet);
1405
1406 if (hkeyDummy) RegCloseKey(hkeyDummy);
1407 }
1408
1409 CoTaskMemFree(wszClsid);
1410 if (hKey)
1412 if (hPinsKey)
1413 RegCloseKey(hPinsKey);
1414
1415 return hr;
1416}
1417
1418
1420 IFilterMapper * iface,
1421 CLSID clsFilter,
1423 CLSID clsMajorType,
1424 CLSID clsSubType)
1425{
1426 HRESULT hr;
1427 LONG lRet;
1428 LPWSTR wszClsid = NULL;
1429 LPWSTR wszClsidMajorType = NULL;
1430 LPWSTR wszClsidSubType = NULL;
1431 HKEY hKey = NULL;
1432 WCHAR * wszTypesKey;
1433 WCHAR wszKeyName[MAX_PATH];
1434
1435 TRACE("(%p)->(%s, %s, %s, %s)\n", iface, debugstr_guid(&clsFilter), debugstr_w(szName),
1436 debugstr_guid(&clsMajorType), debugstr_guid(&clsSubType));
1437
1438 hr = StringFromCLSID(&clsFilter, &wszClsid);
1439
1440 if (SUCCEEDED(hr))
1441 {
1442 hr = StringFromCLSID(&clsMajorType, &wszClsidMajorType);
1443 }
1444
1445 if (SUCCEEDED(hr))
1446 {
1447 hr = StringFromCLSID(&clsSubType, &wszClsidSubType);
1448 }
1449
1450 if (SUCCEEDED(hr))
1451 {
1452 wszTypesKey = CoTaskMemAlloc((strlenW(wszClsidSlash) + strlenW(wszClsid) + strlenW(wszPins) +
1453 strlenW(szName) + strlenW(wszTypes) + 3 + 1) * 2);
1454 if (!wszTypesKey)
1455 hr = E_OUTOFMEMORY;
1456 }
1457
1458 if (SUCCEEDED(hr))
1459 {
1460 strcpyW(wszTypesKey, wszClsidSlash);
1461 strcatW(wszTypesKey, wszClsid);
1462 strcatW(wszTypesKey, wszSlash);
1463 strcatW(wszTypesKey, wszPins);
1464 strcatW(wszTypesKey, wszSlash);
1465 strcatW(wszTypesKey, szName);
1466 strcatW(wszTypesKey, wszSlash);
1467 strcatW(wszTypesKey, wszTypes);
1468
1469 lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszTypesKey, 0, KEY_WRITE, &hKey);
1470 hr = HRESULT_FROM_WIN32(lRet);
1471 CoTaskMemFree(wszTypesKey);
1472 }
1473
1474 if (SUCCEEDED(hr))
1475 {
1476 HKEY hkeyDummy = NULL;
1477
1478 strcpyW(wszKeyName, wszClsidMajorType);
1479 strcatW(wszKeyName, wszSlash);
1480 strcatW(wszKeyName, wszClsidSubType);
1481
1482 lRet = RegCreateKeyExW(hKey, wszKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkeyDummy, NULL);
1483 hr = HRESULT_FROM_WIN32(lRet);
1485
1486 if (hkeyDummy) RegCloseKey(hkeyDummy);
1487 }
1488
1489 CoTaskMemFree(wszClsid);
1490 CoTaskMemFree(wszClsidMajorType);
1491 CoTaskMemFree(wszClsidSubType);
1492
1493 return hr;
1494}
1495
1497{
1498 HRESULT hr;
1499 LONG lRet;
1500 LPWSTR wszClsid = NULL;
1501 HKEY hKey;
1502 WCHAR wszKeyName[ARRAYSIZE(wszClsidSlash)-1 + (CHARS_IN_GUID-1) + 1];
1503
1504 TRACE("(%p)->(%s)\n", iface, debugstr_guid(&Filter));
1505
1506 hr = StringFromCLSID(&Filter, &wszClsid);
1507
1508 if (SUCCEEDED(hr))
1509 {
1511 hr = HRESULT_FROM_WIN32(lRet);
1512 }
1513
1514 if (SUCCEEDED(hr))
1515 {
1516 lRet = RegDeleteKeyW(hKey, wszClsid);
1517 hr = HRESULT_FROM_WIN32(lRet);
1519 }
1520
1521 if (SUCCEEDED(hr))
1522 {
1523 strcpyW(wszKeyName, wszClsidSlash);
1524 strcatW(wszKeyName, wszClsid);
1525
1526 lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszKeyName, 0, KEY_WRITE, &hKey);
1527 if (lRet == ERROR_FILE_NOT_FOUND)
1528 goto done;
1529 hr = HRESULT_FROM_WIN32(lRet);
1530 }
1531
1532 if (SUCCEEDED(hr))
1533 {
1535 if (lRet != ERROR_SUCCESS && lRet != ERROR_FILE_NOT_FOUND)
1536 hr = HRESULT_FROM_WIN32(lRet);
1537
1538 lRet = RegDeleteTreeW(hKey, wszPins);
1539 if (lRet != ERROR_SUCCESS && lRet != ERROR_FILE_NOT_FOUND)
1540 hr = HRESULT_FROM_WIN32(lRet);
1541
1543 }
1544
1545done:
1546 CoTaskMemFree(wszClsid);
1547
1548 return hr;
1549}
1550
1552{
1553 TRACE("(%p)->(%s)\n", iface, debugstr_guid(&MRId));
1554
1555 /* Not implemented in Windows (tested on Win2k) */
1556
1557 return E_NOTIMPL;
1558}
1559
1561{
1562 HRESULT hr;
1563 LONG lRet;
1564 LPWSTR wszClsid = NULL;
1565 HKEY hKey = NULL;
1566 WCHAR * wszPinNameKey;
1567 WCHAR wszKeyName[ARRAYSIZE(wszClsidSlash)-1 + (CHARS_IN_GUID-1) + 1];
1568
1569 TRACE("(%p)->(%s, %s)\n", iface, debugstr_guid(&Filter), debugstr_w(Name));
1570
1571 if (!Name)
1572 return E_INVALIDARG;
1573
1574 hr = StringFromCLSID(&Filter, &wszClsid);
1575
1576 if (SUCCEEDED(hr))
1577 {
1578 strcpyW(wszKeyName, wszClsidSlash);
1579 strcatW(wszKeyName, wszClsid);
1580
1581 lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszKeyName, 0, KEY_WRITE, &hKey);
1582 hr = HRESULT_FROM_WIN32(lRet);
1583 }
1584
1585 if (SUCCEEDED(hr))
1586 {
1587 wszPinNameKey = CoTaskMemAlloc((strlenW(wszPins) + 1 + strlenW(Name) + 1) * 2);
1588 if (!wszPinNameKey)
1589 hr = E_OUTOFMEMORY;
1590 }
1591
1592 if (SUCCEEDED(hr))
1593 {
1594 strcpyW(wszPinNameKey, wszPins);
1595 strcatW(wszPinNameKey, wszSlash);
1596 strcatW(wszPinNameKey, Name);
1597
1598 lRet = RegDeleteTreeW(hKey, wszPinNameKey);
1599 hr = HRESULT_FROM_WIN32(lRet);
1600 CoTaskMemFree(wszPinNameKey);
1601 }
1602
1603 CoTaskMemFree(wszClsid);
1604 if (hKey)
1606
1607 return hr;
1608}
1609
1610static const IFilterMapperVtbl fmvtbl =
1611{
1612
1616
1625};
1626
1627
1628/*** IUnknown methods ***/
1630{
1632
1633 return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
1634}
1635
1637{
1639
1640 return IUnknown_AddRef(This->outer_unk);
1641}
1642
1644{
1646
1647 return IUnknown_Release(This->outer_unk);
1648}
1649
1650/*** IAMFilterData methods ***/
1652 BYTE *pData, ULONG cb,
1653 BYTE **ppRegFilter2)
1654{
1656 HRESULT hr = S_OK;
1657 static REGFILTER2 *prf2;
1658
1659 TRACE("(%p/%p)->(%p, %d, %p)\n", This, iface, pData, cb, ppRegFilter2);
1660
1661 prf2 = CoTaskMemAlloc(sizeof(*prf2));
1662 if (!prf2)
1663 return E_OUTOFMEMORY;
1664 *ppRegFilter2 = (BYTE *)&prf2;
1665
1666 hr = FM2_ReadFilterData(pData, prf2);
1667 if (FAILED(hr))
1668 {
1669 CoTaskMemFree(prf2);
1670 *ppRegFilter2 = NULL;
1671 }
1672
1673 return hr;
1674}
1675
1677 REGFILTER2 *prf2,
1678 BYTE **pRegFilterData,
1679 ULONG *pcb)
1680{
1682
1683 TRACE("(%p/%p)->(%p, %p, %p)\n", This, iface, prf2, pRegFilterData, pcb);
1684
1685 return FM2_WriteFilterData(prf2, pRegFilterData, pcb);
1686}
1687
1688static const IAMFilterDataVtbl AMFilterDataVtbl = {
1694};
1695
1697{
1698 FilterMapper3Impl * pFM2impl;
1699
1700 TRACE("(%p, %p)\n", pUnkOuter, ppObj);
1701
1702 pFM2impl = CoTaskMemAlloc(sizeof(*pFM2impl));
1703 if (!pFM2impl)
1704 return E_OUTOFMEMORY;
1705
1706 pFM2impl->IUnknown_inner.lpVtbl = &IInner_VTable;
1707 pFM2impl->IFilterMapper3_iface.lpVtbl = &fm3vtbl;
1708 pFM2impl->IFilterMapper_iface.lpVtbl = &fmvtbl;
1709 pFM2impl->IAMFilterData_iface.lpVtbl = &AMFilterDataVtbl;
1710 pFM2impl->ref = 1;
1711
1712 if (pUnkOuter)
1713 pFM2impl->outer_unk = pUnkOuter;
1714 else
1715 pFM2impl->outer_unk = &pFM2impl->IUnknown_inner;
1716
1717 *ppObj = &pFM2impl->IUnknown_inner;
1718
1719 TRACE("-- created at %p\n", pFM2impl);
1720
1721 return S_OK;
1722}
1723
1725{
1726 FilterMapper3Impl *pFM2impl;
1727 HRESULT hr;
1728
1729 TRACE("(%p, %p)\n", pUnkOuter, ppObj);
1730
1731 hr = FilterMapper2_create(pUnkOuter, (LPVOID*)&pFM2impl);
1732 if (FAILED(hr))
1733 return hr;
1734
1735 *ppObj = &pFM2impl->IFilterMapper_iface;
1736
1737 return hr;
1738}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
@ REG_PINFLAG_B_RENDERER
Definition: axextend.idl:217
@ REG_PINFLAG_B_OUTPUT
Definition: axextend.idl:219
@ REG_PINFLAG_B_ZERO
Definition: axextend.idl:216
REGPINTYPES
Definition: axextend.idl:192
const CLSID * clsMinorType
Definition: axextend.idl:191
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define RegCloseKey(hKey)
Definition: registry.h:49
LSTATUS WINAPI RegDeleteTreeW(_In_ HKEY, _In_opt_ LPCWSTR)
#define CHARS_IN_GUID
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR szDescription[]
Definition: provider.c:55
static const WCHAR wszDirection[]
Definition: filtermapper.c:98
static HRESULT WINAPI FilterMapper_UnregisterPin(IFilterMapper *iface, CLSID Filter, LPCWSTR Name)
static const WCHAR wszClsidName[]
Definition: filtermapper.c:84
static FilterMapper3Impl * impl_from_IFilterMapper(IFilterMapper *iface)
Definition: filtermapper.c:64
static ULONG WINAPI AMFilterData_Release(IAMFilterData *iface)
static const WCHAR wszFilterSlash[]
Definition: filtermapper.c:92
static const WCHAR wszSlashInstance[]
Definition: filtermapper.c:80
static int mm_compare(const void *left, const void *right)
Definition: filtermapper.c:859
static const IAMFilterDataVtbl AMFilterDataVtbl
static const WCHAR wszTypes[]
Definition: filtermapper.c:101
static HRESULT FM2_ReadFilterData(BYTE *pData, REGFILTER2 *prf2)
Definition: filtermapper.c:501
static HRESULT WINAPI FilterMapper3_QueryInterface(IFilterMapper3 *iface, REFIID riid, LPVOID *ppv)
Definition: filtermapper.c:237
static void delete_vector(struct Vector *v)
Definition: filtermapper.c:172
static BOOL MatchTypes(BOOL bExactMatch, DWORD nPinTypes, const REGPINTYPES *pPinTypes, DWORD nMatchTypes, const GUID *pMatchTypes)
Definition: filtermapper.c:829
static HRESULT FM2_WriteFriendlyName(IPropertyBag *pPropBag, LPCWSTR szName)
Definition: filtermapper.c:363
static ULONG WINAPI FilterMapper3_Release(IFilterMapper3 *iface)
Definition: filtermapper.c:251
static const WCHAR wszSlash[]
Definition: filtermapper.c:81
static const WCHAR wszFilter[]
Definition: filtermapper.c:93
static HRESULT WINAPI Inner_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: filtermapper.c:181
static HRESULT WINAPI FilterMapper_UnregisterFilter(IFilterMapper *iface, CLSID Filter)
static const WCHAR wszAllowedMany[]
Definition: filtermapper.c:96
static HRESULT WINAPI FilterMapper_RegisterPinType(IFilterMapper *iface, CLSID clsFilter, LPCWSTR szName, CLSID clsMajorType, CLSID clsSubType)
static HRESULT WINAPI FilterMapper3_EnumMatchingFilters(IFilterMapper3 *iface, IEnumMoniker **ppEnum, DWORD dwFlags, BOOL bExactMatch, DWORD dwMerit, BOOL bInputNeeded, DWORD cInputTypes, const GUID *pInputTypes, const REGPINMEDIUM *pMedIn, const CLSID *pPinCategoryIn, BOOL bRender, BOOL bOutputNeeded, DWORD cOutputTypes, const GUID *pOutputTypes, const REGPINMEDIUM *pMedOut, const CLSID *pPinCategoryOut)
Definition: filtermapper.c:878
static HRESULT WINAPI FilterMapper_RegisterFilter(IFilterMapper *iface, CLSID clsid, LPCWSTR szName, DWORD dwMerit)
static ULONG WINAPI FilterMapper_Release(IFilterMapper *iface)
static HRESULT WINAPI FilterMapper3_GetICreateDevEnum(IFilterMapper3 *iface, ICreateDevEnum **ppEnum)
static const IFilterMapperVtbl fmvtbl
static ULONG WINAPI AMFilterData_AddRef(IAMFilterData *iface)
static ULONG WINAPI Inner_Release(IUnknown *iface)
Definition: filtermapper.c:217
static int add_data(struct Vector *v, const BYTE *pData, int size)
Definition: filtermapper.c:146
static HRESULT WINAPI FilterMapper_RegisterFilterInstance(IFilterMapper *iface, CLSID clsid, LPCWSTR szName, CLSID *MRId)
static HRESULT WINAPI FilterMapper_RegisterPin(IFilterMapper *iface, CLSID Filter, LPCWSTR szName, BOOL bRendered, BOOL bOutput, BOOL bZero, BOOL bMany, CLSID ConnectsToFilter, LPCWSTR ConnectsToPin)
static int find_data(const struct Vector *v, const BYTE *pData, int size)
Definition: filtermapper.c:162
static HRESULT WINAPI FilterMapper_QueryInterface(IFilterMapper *iface, REFIID riid, LPVOID *ppv)
static HRESULT WINAPI FilterMapper3_RegisterFilter(IFilterMapper3 *iface, REFCLSID clsidFilter, LPCWSTR szName, IMoniker **ppMoniker, const CLSID *pclsidCategory, const OLECHAR *szInstance, const REGFILTER2 *prf2)
Definition: filtermapper.c:626
static const WCHAR wszMeritName[]
Definition: filtermapper.c:88
static const IFilterMapper3Vtbl fm3vtbl
static HRESULT WINAPI AMFilterData_QueryInterface(IAMFilterData *iface, REFIID riid, LPVOID *ppv)
static FilterMapper3Impl * impl_from_IFilterMapper3(IFilterMapper3 *iface)
Definition: filtermapper.c:59
static HRESULT FM2_WriteFilterData(const REGFILTER2 *prf2, BYTE **ppData, ULONG *pcbData)
Definition: filtermapper.c:396
static HRESULT WINAPI AMFilterData_ParseFilterData(IAMFilterData *iface, BYTE *pData, ULONG cb, BYTE **ppRegFilter2)
static void FM2_DeleteRegFilter(REGFILTER2 *prf2)
Definition: filtermapper.c:607
static const WCHAR wszPins[]
Definition: filtermapper.c:95
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
static HRESULT WINAPI AMFilterData_CreateFilterData(IAMFilterData *iface, REGFILTER2 *prf2, BYTE **pRegFilterData, ULONG *pcb)
HRESULT FilterMapper2_create(IUnknown *pUnkOuter, LPVOID *ppObj)
static const WCHAR wszAllowedZero[]
Definition: filtermapper.c:97
static HRESULT FM2_WriteClsid(IPropertyBag *pPropBag, REFCLSID clsid)
Definition: filtermapper.c:378
static const WCHAR wszClsidSlash[]
Definition: filtermapper.c:79
static ULONG WINAPI Inner_AddRef(IUnknown *iface)
Definition: filtermapper.c:207
static HRESULT WINAPI FilterMapper3_CreateCategory(IFilterMapper3 *iface, REFCLSID clsidCategory, DWORD dwCategoryMerit, LPCWSTR szDescription)
Definition: filtermapper.c:260
static HRESULT WINAPI FilterMapper_UnregisterFilterInstance(IFilterMapper *iface, CLSID MRId)
static HRESULT WINAPI FilterMapper3_UnregisterFilter(IFilterMapper3 *iface, const CLSID *pclsidCategory, const OLECHAR *szInstance, REFCLSID Filter)
Definition: filtermapper.c:318
static ULONG WINAPI FilterMapper3_AddRef(IFilterMapper3 *iface)
Definition: filtermapper.c:244
static const WCHAR wszFilterDataName[]
Definition: filtermapper.c:90
static HRESULT WINAPI FilterMapper_EnumMatchingFilters(IFilterMapper *iface, IEnumRegFilters **ppEnum, DWORD dwMerit, BOOL bInputNeeded, CLSID clsInMaj, CLSID clsInSub, BOOL bRender, BOOL bOutputNeeded, CLSID clsOutMaj, CLSID clsOutSub)
HRESULT FilterMapper_create(IUnknown *pUnkOuter, LPVOID *ppObj)
static FilterMapper3Impl * impl_from_IUnknown(IUnknown *iface)
Definition: filtermapper.c:74
static const IUnknownVtbl IInner_VTable
Definition: filtermapper.c:230
static const WCHAR wszFriendlyName[]
Definition: filtermapper.c:86
static ULONG WINAPI FilterMapper_AddRef(IFilterMapper *iface)
static const WCHAR wszIsRendered[]
Definition: filtermapper.c:99
static FilterMapper3Impl * impl_from_IAMFilterData(IAMFilterData *iface)
Definition: filtermapper.c:69
unsigned int idx
Definition: utils.c:41
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
WCHAR OLECHAR
Definition: compat.h:2292
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
OLECHAR * BSTR
Definition: compat.h:2293
#define TRACE_ON(x)
Definition: compat.h:75
#define MAX_PATH
Definition: compat.h:34
@ VT_BSTR
Definition: compat.h:2303
@ VT_ARRAY
Definition: compat.h:2341
@ VT_EMPTY
Definition: compat.h:2295
@ VT_UI1
Definition: compat.h:2311
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
HRESULT WINAPI StringFromCLSID(REFCLSID id, LPOLESTR *idstr)
Definition: compobj.c:2412
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1137
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1168
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1347
SAFEARRAY *WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
Definition: safearray.c:600
#define REG_PINFLAG_B_MANY
Definition: precomp.h:17
HRESULT EnumMonikerImpl_Create(IMoniker **ppMoniker, ULONG nMonikerCount, IEnumMoniker **ppEnum)
Definition: enummoniker.c:47
HRESULT IEnumRegFiltersImpl_Construct(REGFILTER *pInRegFilters, const ULONG size, IEnumRegFilters **ppEnum)
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1801
FxAutoRegKey hKey
const GLdouble * v
Definition: gl.h:2040
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
GLdouble GLdouble right
Definition: glext.h:10859
GLint left
Definition: glext.h:7726
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
#define GUID_NULL
Definition: ks.h:106
#define REG_SZ
Definition: layer.c:22
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
PSDBQUERYRESULT_VISTA PVOID * ppData
Definition: env.c:56
const char * var
Definition: shader.c:5666
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static SCRIPT_CACHE SCRIPT_ANALYSIS * psa
Definition: usp10.c:64
REFCLSID clsid
Definition: msctf.c:82
unsigned int UINT
Definition: ndis.h:50
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
#define DWORD
Definition: nt_native.h:44
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2033
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC *ppbc)
Definition: bindctx.c:556
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
#define V_ARRAY(A)
Definition: oleauto.h:222
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_UI4(A)
Definition: oleauto.h:270
const GUID IID_IParseDisplayName
const GUID IID_IPropertyBag
long LONG
Definition: pedump.c:60
static const WCHAR szName[]
Definition: powrprof.c:45
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define strlenW(s)
Definition: unicode.h:28
#define strcatW(d, s)
Definition: unicode.h:30
#define strcpyW(d, s)
Definition: unicode.h:29
static calc_node_t temp
Definition: rpn_ieee.c:38
#define REG_DWORD
Definition: sdbapi.c:596
void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements *_SizeOfElements) void *_Base, _In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, _In_ int(__cdecl *_PtFuncCompare)(const void *, const void *))
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
IFilterMapper3 IFilterMapper3_iface
Definition: filtermapper.c:52
IUnknown * outer_unk
Definition: filtermapper.c:55
IUnknown IUnknown_inner
Definition: filtermapper.c:51
IFilterMapper IFilterMapper_iface
Definition: filtermapper.c:53
IAMFilterData IAMFilterData_iface
Definition: filtermapper.c:54
IMoniker * pMoniker
Definition: filtermapper.c:134
DWORD dwVersion
Definition: axextend.idl:236
const REGFILTERPINS * rgPins
Definition: axextend.idl:244
ULONG cPins
Definition: axextend.idl:243
DWORD dwMerit
Definition: axextend.idl:237
const REGFILTERPINS2 * rgPins2
Definition: axextend.idl:251
ULONG cPins2
Definition: axextend.idl:250
const CLSID * clsPinCategory
Definition: axextend.idl:231
const REGPINMEDIUM * lpMedium
Definition: axextend.idl:230
const REGPINTYPES * lpMediaType
Definition: axextend.idl:228
const REGPINTYPES * lpMediaType
Definition: axextend.idl:204
UINT nMediaTypes
Definition: axextend.idl:203
CLSID Clsid
Definition: axextend.idl:81
LPWSTR Name
Definition: axextend.idl:82
BYTE signature[4]
Definition: filtermapper.c:115
DWORD dwMediaTypes
Definition: filtermapper.c:118
DWORD bCategory
Definition: filtermapper.c:120
DWORD dwInstances
Definition: filtermapper.c:117
DWORD dwFlags
Definition: filtermapper.c:116
DWORD dwMediums
Definition: filtermapper.c:119
DWORD dwVersion
Definition: filtermapper.c:107
DWORD dwUnused
Definition: filtermapper.c:110
DWORD dwMerit
Definition: filtermapper.c:108
DWORD dwPins
Definition: filtermapper.c:109
BYTE signature[4]
Definition: filtermapper.c:126
DWORD dwOffsetMajor
Definition: filtermapper.c:128
DWORD dwUnused
Definition: filtermapper.c:127
DWORD dwOffsetMinor
Definition: filtermapper.c:129
LPBYTE pData
Definition: filtermapper.c:140
int capacity
Definition: filtermapper.c:141
int current
Definition: filtermapper.c:142
Definition: send.c:48
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
unsigned char * LPBYTE
Definition: typedefs.h:53
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: pdh_main.c:94
#define MEDIASUBTYPE_NULL
Definition: uuids.h:25
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
int ret
#define ZeroMemory
Definition: winbase.h:1712
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
_In_ DWORD _Out_writes_bytes_to_opt_ pcbData void _Inout_ DWORD * pcbData
Definition: wincrypt.h:4950
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define E_POINTER
Definition: winerror.h:2365
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193