ReactOS  0.4.12-dev-375-g61fed54
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 
49 typedef struct FilterMapper3Impl
50 {
52  IFilterMapper3 IFilterMapper3_iface;
53  IFilterMapper IFilterMapper_iface;
58 
59 static inline FilterMapper3Impl *impl_from_IFilterMapper3( IFilterMapper3 *iface )
60 {
61  return CONTAINING_RECORD(iface, FilterMapper3Impl, IFilterMapper3_iface);
62 }
63 
64 static 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 
79 static const WCHAR wszClsidSlash[] = {'C','L','S','I','D','\\',0};
80 static const WCHAR wszSlashInstance[] = {'\\','I','n','s','t','a','n','c','e','\\',0};
81 static const WCHAR wszSlash[] = {'\\',0};
82 
83 /* CLSID property in media category Moniker */
84 static const WCHAR wszClsidName[] = {'C','L','S','I','D',0};
85 /* FriendlyName property in media category Moniker */
86 static 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) */
88 static const WCHAR wszMeritName[] = {'M','e','r','i','t',0};
89 /* FilterData property in media category Moniker (not CLSID_ActiveMovieCategories) */
90 static const WCHAR wszFilterDataName[] = {'F','i','l','t','e','r','D','a','t','a',0};
91 /* For filters registered with IFilterMapper */
92 static const WCHAR wszFilterSlash[] = {'F','i','l','t','e','r','\\',0};
93 static const WCHAR wszFilter[] = {'F','i','l','t','e','r',0};
94 /* For pins registered with IFilterMapper */
95 static const WCHAR wszPins[] = {'P','i','n','s',0};
96 static const WCHAR wszAllowedMany[] = {'A','l','l','o','w','e','d','M','a','n','y',0};
97 static const WCHAR wszAllowedZero[] = {'A','l','l','o','w','e','d','Z','e','r','o',0};
98 static const WCHAR wszDirection[] = {'D','i','r','e','c','t','i','o','n',0};
99 static const WCHAR wszIsRendered[] = {'I','s','R','e','n','d','e','r','e','d',0};
100 /* For types registered with IFilterMapper */
101 static const WCHAR wszTypes[] = {'T','y','p','e','s',0};
102 
103 
104 /* registry format for REGFILTER2 */
105 struct REG_RF
106 {
111 };
112 
113 struct REG_RFP
114 {
115  BYTE signature[4]; /* e.g. "0pi3" */
120  DWORD bCategory; /* is there a category clsid? */
121  /* optional: dwOffsetCategoryClsid */
122 };
123 
124 struct REG_TYPE
125 {
126  BYTE signature[4]; /* e.g. "0ty3" */
130 };
131 
133 {
136 };
137 
138 struct 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 */
146 static 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 
162 static 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 
172 static 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 
230 static const IUnknownVtbl IInner_VTable =
231 {
233  Inner_AddRef,
235 };
236 
238 {
240 
241  return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
242 }
243 
244 static ULONG WINAPI FilterMapper3_AddRef(IFilterMapper3 * iface)
245 {
247 
248  return IUnknown_AddRef(This->outer_unk);
249 }
250 
251 static 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 
311  RegCloseKey(hKey);
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;
370  V_BSTR(&var) = value = SysAllocString(szName);
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)
487  hr = E_OUTOFMEMORY;
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 
607 static void FM2_DeleteRegFilter(REGFILTER2 * prf2)
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  }
620  CoTaskMemFree((LPVOID)prf2->u.s2.rgPins2[i].lpMediaType);
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,
629  LPCWSTR szName,
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 */
859 static 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,
881  DWORD dwFlags,
882  BOOL bExactMatch,
883  DWORD dwMerit,
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 
942  VariantInit(&var);
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 
955  VariantClear(&var);
956 
957  if (TRACE_ON(quartz))
958  {
959  VARIANT temp;
960  V_VT(&temp) = VT_EMPTY;
961  IPropertyBag_Read(pPropBagCat, wszFriendlyName, &temp, NULL);
962  TRACE("Considering category %s\n", debugstr_w(V_BSTR(&temp)));
963  VariantClear(&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));
987  VariantInit(&var);
988 
989  hrSub = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBag);
990 
991  if (TRACE_ON(quartz))
992  {
993  VARIANT temp;
994  V_VT(&temp) = VT_EMPTY;
995  IPropertyBag_Read(pPropBag, wszFriendlyName, &temp, NULL);
996  TRACE("Considering filter %s\n", debugstr_w(V_BSTR(&temp)));
997  VariantClear(&temp);
998  }
999 
1000  if (SUCCEEDED(hrSub))
1001  {
1002  hrSub = IPropertyBag_Read(pPropBag, wszFilterDataName, &var, NULL);
1003  }
1004 
1005  if (SUCCEEDED(hrSub))
1006  hrSub = SafeArrayAccessData(V_ARRAY(&var), (LPVOID*)&pData);
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 
1090 static 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 
1098 static 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 
1123 static ULONG WINAPI FilterMapper_AddRef(IFilterMapper * iface)
1124 {
1126 
1127  return IUnknown_AddRef(This->outer_unk);
1128 }
1129 
1130 static 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);
1291  RegCloseKey(hKey);
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  {
1305  lRet = RegSetValueExW(hKey, wszMeritName, 0, REG_DWORD, (LPBYTE)&dwMerit, sizeof(dwMerit));
1306  hr = HRESULT_FROM_WIN32(lRet);
1307  RegCloseKey(hKey);
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,
1327  LPCWSTR szName,
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)
1411  RegCloseKey(hKey);
1412  if (hPinsKey)
1413  RegCloseKey(hPinsKey);
1414 
1415  return hr;
1416 }
1417 
1418 
1420  IFilterMapper * iface,
1421  CLSID clsFilter,
1422  LPCWSTR szName,
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);
1484  RegCloseKey(hKey);
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  {
1510  lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszFilter, 0, KEY_WRITE, &hKey);
1511  hr = HRESULT_FROM_WIN32(lRet);
1512  }
1513 
1514  if (SUCCEEDED(hr))
1515  {
1516  lRet = RegDeleteKeyW(hKey, wszClsid);
1517  hr = HRESULT_FROM_WIN32(lRet);
1518  RegCloseKey(hKey);
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  {
1534  lRet = RegDeleteValueW(hKey, wszMeritName);
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 
1542  RegCloseKey(hKey);
1543  }
1544 
1545 done:
1546  CoTaskMemFree(wszClsid);
1547 
1548  return hr;
1549 }
1550 
1551 static HRESULT WINAPI FilterMapper_UnregisterFilterInstance(IFilterMapper * iface, CLSID MRId)
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)
1605  RegCloseKey(hKey);
1606 
1607  return hr;
1608 }
1609 
1610 static 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 
1688 static 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 }
DWORD dwUnused
Definition: filtermapper.c:110
WCHAR OLECHAR
Definition: compat.h:1926
BYTE signature[4]
Definition: filtermapper.c:126
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
Definition: get.c:139
#define REFIID
Definition: guiddef.h:113
#define TRUE
Definition: types.h:120
static ULONG WINAPI FilterMapper_Release(IFilterMapper *iface)
#define E_NOINTERFACE
Definition: winerror.h:2364
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define ERROR_SUCCESS
Definition: deptool.c:10
static HRESULT WINAPI FilterMapper_RegisterFilterInstance(IFilterMapper *iface, CLSID clsid, LPCWSTR szName, CLSID *MRId)
DWORD dwUnused
Definition: filtermapper.c:127
static HRESULT WINAPI FilterMapper3_CreateCategory(IFilterMapper3 *iface, REFCLSID clsidCategory, DWORD dwCategoryMerit, LPCWSTR szDescription)
Definition: filtermapper.c:260
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 FM2_WriteFilterData(const REGFILTER2 *prf2, BYTE **ppData, ULONG *pcbData)
Definition: filtermapper.c:396
static const WCHAR wszDirection[]
Definition: filtermapper.c:98
__wchar_t WCHAR
Definition: xmlstorage.h:180
static const WCHAR wszSlashInstance[]
Definition: filtermapper.c:80
REFIID riid
Definition: precomp.h:44
#define DWORD
Definition: msvc.h:34
static const IFilterMapperVtbl fmvtbl
#define REFCLSID
Definition: guiddef.h:112
static FilterMapper3Impl * impl_from_IUnknown(IUnknown *iface)
Definition: filtermapper.c:74
#define V_ARRAY(A)
Definition: oleauto.h:222
static HRESULT WINAPI AMFilterData_QueryInterface(IAMFilterData *iface, REFIID riid, LPVOID *ppv)
#define CHARS_IN_GUID
const REGFILTERPINS2 * rgPins2
Definition: axextend.idl:246
const REGPINTYPES * lpMediaType
Definition: axextend.idl:199
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
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1240
REFIID LPVOID * ppv
Definition: atlbase.h:39
static int mm_compare(const void *left, const void *right)
Definition: filtermapper.c:859
void WINAPI SysFreeString(BSTR str)
Definition: oleaut.c:275
static FilterMapper3Impl * impl_from_IFilterMapper3(IFilterMapper3 *iface)
Definition: filtermapper.c:59
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define ZeroMemory
Definition: winbase.h:1635
HRESULT IEnumRegFiltersImpl_Construct(REGFILTER *pInRegFilters, const ULONG size, IEnumRegFilters **ppEnum)
static ULONG WINAPI Inner_AddRef(IUnknown *iface)
Definition: filtermapper.c:207
int capacity
Definition: filtermapper.c:141
CLSID Clsid
Definition: axextend.idl:76
static const WCHAR wszAllowedZero[]
Definition: filtermapper.c:97
OLECHAR * BSTR
Definition: compat.h:1927
static HRESULT WINAPI FilterMapper3_QueryInterface(IFilterMapper3 *iface, REFIID riid, LPVOID *ppv)
Definition: filtermapper.c:237
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:571
#define E_FAIL
Definition: ddrawi.h:102
static HRESULT WINAPI FilterMapper_RegisterFilter(IFilterMapper *iface, CLSID clsid, LPCWSTR szName, DWORD dwMerit)
Definition: send.c:47
HRESULT WINAPI VariantClear(VARIANTARG *pVarg)
Definition: variant.c:651
DWORD dwPins
Definition: filtermapper.c:109
static int find_data(const struct Vector *v, const BYTE *pData, int size)
Definition: filtermapper.c:162
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:1094
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2032
static const WCHAR wszPins[]
Definition: filtermapper.c:95
DWORD dwMediums
Definition: filtermapper.c:119
REGPINTYPES
Definition: axextend.idl:187
DWORD dwMerit
Definition: axextend.idl:232
static const WCHAR wszSlash[]
Definition: filtermapper.c:81
GLenum GLclampf GLint i
Definition: glfuncs.h:14
static const IAMFilterDataVtbl AMFilterDataVtbl
IAMFilterData IAMFilterData_iface
Definition: filtermapper.c:54
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1139
long LONG
Definition: pedump.c:60
const CLSID * clsMinorType
Definition: axextend.idl:186
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1802
#define debugstr_w
Definition: kernel32.h:32
static ULONG WINAPI Inner_Release(IUnknown *iface)
Definition: filtermapper.c:217
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 *))
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
unsigned int idx
Definition: utils.c:41
static HRESULT FM2_WriteFriendlyName(IPropertyBag *pPropBag, LPCWSTR szName)
Definition: filtermapper.c:363
#define E_INVALIDARG
Definition: ddrawi.h:101
static const IUnknownVtbl IInner_VTable
Definition: filtermapper.c:230
DWORD bCategory
Definition: filtermapper.c:120
DWORD dwMerit
Definition: filtermapper.c:108
smooth NULL
Definition: ftsmooth.c:416
const GUID IID_IPropertyBag
static HRESULT WINAPI FilterMapper_UnregisterFilter(IFilterMapper *iface, CLSID Filter)
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:242
IFilterMapper3 IFilterMapper3_iface
Definition: filtermapper.c:52
const CLSID * clsPinCategory
Definition: axextend.idl:226
int current
Definition: filtermapper.c:142
const REGFILTERPINS * rgPins
Definition: axextend.idl:239
const GUID IID_IParseDisplayName
GLuint index
Definition: glext.h:6031
static HRESULT WINAPI FilterMapper_UnregisterFilterInstance(IFilterMapper *iface, CLSID MRId)
#define debugstr_guid
Definition: kernel32.h:35
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
DWORD dwMediaTypes
Definition: filtermapper.c:118
HRESULT FilterMapper_create(IUnknown *pUnkOuter, LPVOID *ppObj)
static HRESULT WINAPI FilterMapper3_GetICreateDevEnum(IFilterMapper3 *iface, ICreateDevEnum **ppEnum)
IFilterMapper IFilterMapper_iface
Definition: filtermapper.c:53
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
static HRESULT WINAPI FilterMapper_RegisterPin(IFilterMapper *iface, CLSID Filter, LPCWSTR szName, BOOL bRendered, BOOL bOutput, BOOL bZero, BOOL bMany, CLSID ConnectsToFilter, LPCWSTR ConnectsToPin)
#define KEY_WRITE
Definition: nt_native.h:1031
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:4917
ULONG cPins2
Definition: axextend.idl:245
HRESULT FilterMapper2_create(IUnknown *pUnkOuter, LPVOID *ppObj)
DWORD dwVersion
Definition: filtermapper.c:107
#define TRACE(s)
Definition: solgame.cpp:4
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizeiptr size
Definition: glext.h:5919
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC *ppbc)
Definition: bindctx.c:556
static FilterMapper3Impl * impl_from_IAMFilterData(IAMFilterData *iface)
Definition: filtermapper.c:69
static const WCHAR wszClsidName[]
Definition: filtermapper.c:84
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
HRESULT EnumMonikerImpl_Create(IMoniker **ppMoniker, ULONG nMonikerCount, IEnumMoniker **ppEnum)
Definition: enummoniker.c:47
static HRESULT WINAPI FilterMapper_RegisterPinType(IFilterMapper *iface, CLSID clsFilter, LPCWSTR szName, CLSID clsMajorType, CLSID clsSubType)
#define MAX_PATH
Definition: compat.h:26
LPBYTE pData
Definition: filtermapper.c:140
struct FilterMapper3Impl FilterMapper3Impl
unsigned int UINT
Definition: ndis.h:50
static HRESULT WINAPI Inner_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: filtermapper.c:181
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint left
Definition: glext.h:7726
DWORD dwOffsetMajor
Definition: filtermapper.c:128
#define MEDIASUBTYPE_NULL
Definition: uuids.h:25
GLdouble GLdouble right
Definition: glext.h:10859
static DWORD cb
Definition: integrity.c:41
GLbitfield flags
Definition: glext.h:7161
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1349
PSDBQUERYRESULT_VISTA PVOID * ppData
Definition: env.c:54
IMoniker * pMoniker
Definition: filtermapper.c:134
#define V_UI4(A)
Definition: oleauto.h:270
int ret
REFCLSID clsid
Definition: msctf.c:84
static const WCHAR wszMeritName[]
Definition: filtermapper.c:88
#define index(s, c)
Definition: various.h:29
static const WCHAR wszFriendlyName[]
Definition: filtermapper.c:86
static HRESULT WINAPI AMFilterData_ParseFilterData(IAMFilterData *iface, BYTE *pData, ULONG cb, BYTE **ppRegFilter2)
#define InterlockedDecrement
Definition: armddk.h:52
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:47
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define V_VT(A)
Definition: oleauto.h:211
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
#define GUID_NULL
Definition: ks.h:106
BYTE signature[4]
Definition: filtermapper.c:115
ULONG cPins
Definition: axextend.idl:238
static stack_node_t temp
Definition: rpn.c:18
UINT nMediaTypes
Definition: axextend.idl:198
GLsizei const GLfloat * value
Definition: glext.h:6069
#define WINAPI
Definition: msvc.h:20
#define V_BSTR(A)
Definition: oleauto.h:226
IUnknown IUnknown_inner
Definition: filtermapper.c:51
DWORD dwFlags
Definition: filtermapper.c:116
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3237
LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1755
static void FM2_DeleteRegFilter(REGFILTER2 *prf2)
Definition: filtermapper.c:607
#define ERR(fmt,...)
Definition: debug.h:109
static const WCHAR wszTypes[]
Definition: filtermapper.c:101
SAFEARRAY *WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
Definition: safearray.c:602
static ULONG WINAPI AMFilterData_AddRef(IAMFilterData *iface)
#define S_OK
Definition: intsafe.h:59
static HRESULT WINAPI FilterMapper3_UnregisterFilter(IFilterMapper3 *iface, const CLSID *pclsidCategory, const OLECHAR *szInstance, REFCLSID Filter)
Definition: filtermapper.c:318
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
static HRESULT WINAPI FilterMapper_UnregisterPin(IFilterMapper *iface, CLSID Filter, LPCWSTR Name)
static const IFilterMapper3Vtbl fm3vtbl
#define InterlockedIncrement
Definition: armddk.h:53
const GLdouble * v
Definition: gl.h:2040
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2368
static const WCHAR wszIsRendered[]
Definition: filtermapper.c:99
LPWSTR Name
Definition: axextend.idl:77
static HRESULT WINAPI FilterMapper_QueryInterface(IFilterMapper *iface, REFIID riid, LPVOID *ppv)
static const WCHAR wszFilterDataName[]
Definition: filtermapper.c:90
DWORD dwVersion
Definition: axextend.idl:231
static const WCHAR wszAllowedMany[]
Definition: filtermapper.c:96
#define E_NOTIMPL
Definition: ddrawi.h:99
DWORD dwInstances
Definition: filtermapper.c:117
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
static const WCHAR wszClsidSlash[]
Definition: filtermapper.c:79
const REGPINTYPES * lpMediaType
Definition: axextend.idl:223
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4024
const REGPINMEDIUM * lpMedium
Definition: axextend.idl:225
DWORD dwOffsetMinor
Definition: filtermapper.c:129
static SCRIPT_CACHE SCRIPT_ANALYSIS * psa
Definition: usp10.c:64
static HRESULT FM2_ReadFilterData(BYTE *pData, REGFILTER2 *prf2)
Definition: filtermapper.c:501
static const WCHAR wszFilter[]
Definition: filtermapper.c:93
static FilterMapper3Impl * impl_from_IFilterMapper(IFilterMapper *iface)
Definition: filtermapper.c:64
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)
static const WCHAR szName[]
Definition: msipriv.h:1194
static ULONG WINAPI FilterMapper3_Release(IFilterMapper3 *iface)
Definition: filtermapper.c:251
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2250
unsigned int ULONG
Definition: retypes.h:1
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3381
IUnknown * outer_unk
Definition: filtermapper.c:55
static const WCHAR wszFilterSlash[]
Definition: filtermapper.c:92
static ULONG WINAPI FilterMapper3_AddRef(IFilterMapper3 *iface)
Definition: filtermapper.c:244
static int add_data(struct Vector *v, const BYTE *pData, int size)
Definition: filtermapper.c:146
static BOOL MatchTypes(BOOL bExactMatch, DWORD nPinTypes, const REGPINTYPES *pPinTypes, DWORD nMatchTypes, const GUID *pMatchTypes)
Definition: filtermapper.c:829
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
WCHAR * LPWSTR
Definition: xmlstorage.h:184
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1827
static HRESULT WINAPI AMFilterData_CreateFilterData(IAMFilterData *iface, REGFILTER2 *prf2, BYTE **pRegFilterData, ULONG *pcb)
static ULONG WINAPI AMFilterData_Release(IAMFilterData *iface)
#define E_POINTER
Definition: winerror.h:2365
#define REG_DWORD
Definition: sdbapi.c:539
#define TRACE_ON(x)
Definition: compat.h:65
static ULONG WINAPI FilterMapper_AddRef(IFilterMapper *iface)
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
static HRESULT FM2_WriteClsid(IPropertyBag *pPropBag, REFCLSID clsid)
Definition: filtermapper.c:378
static void delete_vector(struct Vector *v)
Definition: filtermapper.c:172
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:90
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1170
static const WCHAR szDescription[]
Definition: provider.c:52
#define SUCCEEDED(hr)
Definition: intsafe.h:57
_In_ DWORD _Out_writes_bytes_to_opt_ pcbData void _Inout_ DWORD * pcbData
Definition: wincrypt.h:4951
WINE_DEFAULT_DEBUG_CHANNEL(quartz)
HRESULT WINAPI StringFromCLSID(REFCLSID id, LPOLESTR *idstr)
Definition: compobj.c:2324
#define REG_SZ
Definition: layer.c:22