2 * Implementation of CLSID_FilterMapper and CLSID_FilterMapper2.
6 * hidenori@a2.ctktv.ne.jp
20 #include "debugtools.h"
21 DEFAULT_DEBUG_CHANNEL(quartz);
23 #include "quartz_private.h"
30 /***************************************************************************/
32 typedef struct QUARTZ_REGFILTERDATA
34 DWORD dwVersion; /* =2 */
36 DWORD cPins; /* count of pins */
37 DWORD dwZero; /* padding??? */
38 } QUARTZ_REGFILTERDATA;
40 typedef struct QUARTZ_REGPINDATA
42 CHAR id[4]; /* '0pi3', '1pi3', ... */
43 DWORD dwFlags; /* flags */
44 UINT cInstances; /* FIXME - is this correct? */
45 UINT nMediaTypes; /* count of media types('0ty3') */
46 UINT nMediums; /* FIXME - is this correct? */
47 UINT nOfsClsPinCategory; /* FIXME - is this correct? */
50 typedef struct QUARTZ_REGMEDIATYPE
52 CHAR id[4]; /* '0ty3', '1ty3', ... */
53 DWORD nZero; /* padding??? */
56 } QUARTZ_REGMEDIATYPE;
60 /***************************************************************************/
63 REGFILTER2* QUARTZ_RegFilterV2FromFilterData(
64 const BYTE* pData, DWORD cbData )
70 const QUARTZ_REGFILTERDATA* pRegFilter;
71 const QUARTZ_REGPINDATA* pRegPin;
72 const QUARTZ_REGMEDIATYPE* pRegMediaType;
77 TRACE("(%p,%lu)\n",pData,cbData);
79 if ( cbData < sizeof(QUARTZ_REGFILTERDATA) )
82 pRegFilter = (QUARTZ_REGFILTERDATA*)pData;
84 if ( pRegFilter->dwVersion != 2 ) return NULL; /* FIXME */
86 if ( cbData < (sizeof(QUARTZ_REGFILTERDATA)+sizeof(QUARTZ_REGPINDATA)*pRegFilter->cPins) )
89 cbBufSize = sizeof(REGFILTER2);
90 cPins = pRegFilter->cPins;
91 pRegPin = (const QUARTZ_REGPINDATA*)(pRegFilter+1);
94 if ( pRegPin->nMediums != 0 ||
95 pRegPin->nOfsClsPinCategory != 0 )
96 return NULL; /* FIXME */
98 cbBufSize += sizeof(REGFILTERPINS2) +
99 pRegPin->nMediaTypes * (sizeof(REGPINTYPES) + sizeof(GUID)*2) +
100 pRegPin->nMediums * sizeof(REGPINMEDIUM) +
102 pRegPin = (const QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
103 sizeof(QUARTZ_REGPINDATA) +
104 sizeof(QUARTZ_REGMEDIATYPE) * pRegPin->nMediaTypes );
107 pFilter = (REGFILTER2*)QUARTZ_AllocMem( cbBufSize );
108 if ( pFilter == NULL ) return NULL;
109 ZeroMemory( pFilter, cbBufSize );
110 pPin = (REGFILTERPINS2*)(pFilter+1);
111 pDst = (BYTE*)(pPin + pRegFilter->cPins);
113 pFilter->dwVersion = 2;
114 pFilter->dwMerit = pRegFilter->dwMerit;
115 pFilter->u.s2.cPins2 = pRegFilter->cPins;
116 pFilter->u.s2.rgPins2 = pPin;
118 cPins = pRegFilter->cPins;
119 TRACE("cPins = %lu\n",cPins);
121 pRegPin = (const QUARTZ_REGPINDATA*)(pRegFilter+1);
122 while ( cPins-- > 0 )
124 pPin->dwFlags = pRegPin->dwFlags;
125 pPin->cInstances = pRegPin->cInstances;
126 pPin->nMediaTypes = pRegPin->nMediaTypes;
127 pPin->lpMediaType = NULL;
128 pPin->nMediums = pRegPin->nMediums;
129 pPin->lpMedium = NULL;
130 pPin->clsPinCategory = NULL;
132 pTypes = (REGPINTYPES*)pDst;
133 pPin->lpMediaType = pTypes;
134 pDst += sizeof(REGPINTYPES) * pRegPin->nMediaTypes;
136 pRegPin = (const QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
137 sizeof(QUARTZ_REGPINDATA) );
139 for ( n = 0; n < pPin->nMediaTypes; n++ )
141 pRegMediaType = ((const QUARTZ_REGMEDIATYPE*)pRegPin);
142 TRACE("ofsMajor = %u, ofsMinor = %u\n", pRegMediaType->nOfsMajorType, pRegMediaType->nOfsMinorType);
143 memcpy( pDst, pData+pRegMediaType->nOfsMajorType, sizeof(GUID) );
144 pTypes->clsMajorType = (const GUID*)pDst; pDst += sizeof(GUID);
145 memcpy( pDst, pData+pRegMediaType->nOfsMinorType, sizeof(GUID) );
146 pTypes->clsMinorType = (const GUID*)pDst; pDst += sizeof(GUID);
148 pRegPin = (const QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
149 sizeof(QUARTZ_REGMEDIATYPE) );
153 /* FIXME - pPin->lpMedium */
154 /* FIXME - pPin->clsPinCategory */
163 BYTE* QUARTZ_RegFilterV2ToFilterData(
164 const REGFILTER2* pFilter, DWORD* pcbData )
169 const REGFILTERPINS2* pPin;
170 const REGPINTYPES* pTypes;
173 QUARTZ_REGFILTERDATA* pRegFilter;
174 QUARTZ_REGPINDATA* pRegPin;
175 QUARTZ_REGMEDIATYPE* pRegMediaType;
178 if ( pFilter->dwVersion != 2 ) return NULL; /* FIXME */
180 cbData = sizeof(QUARTZ_REGFILTERDATA);
181 cPins = pFilter->u.s2.cPins2;
182 pPin = pFilter->u.s2.rgPins2;
183 if ( cPins > 10 ) return NULL; /* FIXME */
186 while ( cPins-- > 0 )
188 if ( pPin->cInstances != 0 ||
189 pPin->nMediaTypes > 10 ||
190 pPin->nMediums != 0 ||
191 pPin->clsPinCategory != 0 )
193 FIXME( "not implemented.\n" );
194 return NULL; /* FIXME */
197 cbPinData += sizeof(QUARTZ_REGPINDATA) +
198 pPin->nMediaTypes * sizeof(QUARTZ_REGMEDIATYPE);
199 cbData += pPin->nMediaTypes * (sizeof(GUID)*2);
203 TRACE("cbData %lu, cbPinData %lu\n",cbData,cbPinData);
205 pRet = (BYTE*)QUARTZ_AllocMem( cbData );
206 if ( pRet == NULL ) return NULL;
207 ZeroMemory( pRet, cbData );
210 pRegFilter = (QUARTZ_REGFILTERDATA*)pDst;
211 pDst += sizeof(QUARTZ_REGFILTERDATA);
213 pRegFilter->dwVersion = 2;
214 pRegFilter->dwMerit = pFilter->dwMerit;
215 pRegFilter->cPins = pFilter->u.s2.cPins2;
217 pRegPin = (QUARTZ_REGPINDATA*)pDst;
220 pPin = pFilter->u.s2.rgPins2;
221 for ( cPins = 0; cPins < pFilter->u.s2.cPins2; cPins++ )
223 pRegPin->id[0] = '0'+cPins;
224 pRegPin->id[1] = 'p';
225 pRegPin->id[2] = 'i';
226 pRegPin->id[3] = '3';
227 pRegPin->dwFlags = pPin->dwFlags; /* flags */
228 pRegPin->cInstances = pPin->cInstances;
229 pRegPin->nMediaTypes = pPin->nMediaTypes;
230 pRegPin->nMediums = pPin->nMediums;
231 pRegPin->nOfsClsPinCategory = 0; /* FIXME */
233 pTypes = pPin->lpMediaType;
234 pRegPin = (QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
235 sizeof(QUARTZ_REGPINDATA) );
236 for ( n = 0; n < pPin->nMediaTypes; n++ )
238 pRegMediaType = ((QUARTZ_REGMEDIATYPE*)pRegPin);
240 pRegMediaType->id[0] = '0'+n;
241 pRegMediaType->id[1] = 't';
242 pRegMediaType->id[2] = 'y';
243 pRegMediaType->id[3] = '3';
245 /* FIXME - CLSID should be shared. */
246 pRegMediaType->nOfsMajorType = pDst - pRet;
247 memcpy( pDst, pTypes->clsMajorType, sizeof(GUID) );
248 pDst += sizeof(GUID);
249 pRegMediaType->nOfsMinorType = pDst - pRet;
250 memcpy( pDst, pTypes->clsMinorType, sizeof(GUID) );
251 pDst += sizeof(GUID);
253 pRegPin = (QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
254 sizeof(QUARTZ_REGMEDIATYPE) );
260 *pcbData = pDst - pRet;
261 TRACE("cbData %lu/%lu\n",*pcbData,cbData);
267 REGFILTER2* QUARTZ_RegFilterV1ToV2( const REGFILTER2* prfV1 )
270 const REGFILTERPINS* pPinV1;
271 REGFILTERPINS2* pPinV2;
274 if ( prfV1->dwVersion != 1 ) return NULL;
276 prfV2 = (REGFILTER2*)QUARTZ_AllocMem(
277 sizeof(REGFILTER2) + sizeof(REGFILTERPINS2) * prfV1->u.s1.cPins );
278 if ( prfV2 == NULL ) return NULL;
279 ZeroMemory( prfV2, sizeof(REGFILTER2) + sizeof(REGFILTERPINS2) * prfV1->u.s1.cPins );
280 pPinV1 = prfV1->u.s1.rgPins;
281 pPinV2 = (REGFILTERPINS2*)(prfV2+1);
282 prfV2->dwVersion = 2;
283 prfV2->dwMerit = prfV1->dwMerit;
284 prfV2->u.s2.cPins2 = prfV1->u.s1.cPins;
285 prfV2->u.s2.rgPins2 = pPinV2;
287 cPins = prfV1->u.s1.cPins;
288 while ( cPins-- > 0 )
291 pPinV2->cInstances = 0;
292 pPinV2->nMediaTypes = pPinV1->nMediaTypes;
293 pPinV2->lpMediaType = pPinV1->lpMediaType;
294 pPinV2->nMediums = 0;
295 pPinV2->lpMedium = NULL;
296 pPinV2->clsPinCategory = NULL;
298 if ( pPinV1->bRendered )
299 pPinV2->dwFlags |= REG_PINFLAG_B_RENDERER;
300 if ( pPinV1->bOutput )
301 pPinV2->dwFlags |= REG_PINFLAG_B_OUTPUT;
303 pPinV2->dwFlags |= REG_PINFLAG_B_ZERO;
305 pPinV2->dwFlags |= REG_PINFLAG_B_MANY;
315 BYTE* QUARTZ_RegFilterToFilterData(
316 const REGFILTER2* pFilter, DWORD* pcbData )
322 switch ( pFilter->dwVersion )
325 prfV2 = QUARTZ_RegFilterV1ToV2( pFilter );
328 pRet = QUARTZ_RegFilterV2ToFilterData( prfV2, pcbData );
329 QUARTZ_FreeMem( prfV2 );
333 pRet = QUARTZ_RegFilterV2ToFilterData( pFilter, pcbData );
336 FIXME( "unknown REGFILTER2 version - %08lu\n", pFilter->dwVersion );
343 /***************************************************************************/
346 BOOL QUARTZ_CheckPinType( BOOL bExactMatch, const REGFILTERPINS2* pPin, DWORD cTypes, const GUID* pTypes, const REGPINMEDIUM* pMedium, const CLSID* pCategory, BOOL bRender )
351 if ( cTypes > 0 && pTypes != NULL )
354 for ( n1 = 0; n1 < pPin->nMediaTypes; n1++ )
356 for ( n2 = 0; n2 < cTypes; n2++ )
358 if ( IsEqualGUID(pPin->lpMediaType[n1].clsMajorType,&GUID_NULL) || IsEqualGUID(pPin->lpMediaType[n1].clsMajorType, &pTypes[n2*2+0]) || (!bExactMatch && IsEqualGUID(pPin->lpMediaType[n1].clsMajorType,&GUID_NULL)) )
360 if ( IsEqualGUID(pPin->lpMediaType[n1].clsMinorType,&GUID_NULL) || IsEqualGUID(pPin->lpMediaType[n1].clsMinorType, &pTypes[n2*2+1]) || (!bExactMatch && IsEqualGUID(pPin->lpMediaType[n1].clsMinorType,&GUID_NULL)) )
372 if ( pMedium != NULL )
375 for ( n1 = 0; n1 < pPin->nMediums; n1++ )
377 if ( IsEqualGUID( &pPin->lpMedium[n1].clsMedium, &pMedium->clsMedium ) && pPin->lpMedium[n1].dw1 == pMedium->dw1 && pPin->lpMedium[n1].dw2 == pMedium->dw2 )
387 if ( pCategory != NULL )
389 if ( pPin->clsPinCategory == NULL )
391 if ( (!bExactMatch && IsEqualGUID(pCategory,&GUID_NULL)) || IsEqualGUID(pCategory,pPin->clsPinCategory) )
396 if ( bRender && (!(pPin->dwFlags & REG_PINFLAG_B_RENDERER)) )
405 /***************************************************************************
407 * new/delete for CLSID_FilterMapper
411 /* can I use offsetof safely? - FIXME? */
412 static QUARTZ_IFEntry FMapIFEntries[] =
414 { &IID_IFilterMapper, offsetof(CFilterMapper,fmap)-offsetof(CFilterMapper,unk) },
418 static void QUARTZ_DestroyFilterMapper(IUnknown* punk)
420 CFilterMapper_THIS(punk,unk);
422 CFilterMapper_UninitIFilterMapper( This );
425 HRESULT QUARTZ_CreateFilterMapper(IUnknown* punkOuter,void** ppobj)
430 TRACE("(%p,%p)\n",punkOuter,ppobj);
432 pfm = (CFilterMapper*)QUARTZ_AllocObj( sizeof(CFilterMapper) );
434 return E_OUTOFMEMORY;
436 QUARTZ_IUnkInit( &pfm->unk, punkOuter );
437 hr = CFilterMapper_InitIFilterMapper( pfm );
440 QUARTZ_FreeObj( pfm );
444 pfm->unk.pEntries = FMapIFEntries;
445 pfm->unk.dwEntries = sizeof(FMapIFEntries)/sizeof(FMapIFEntries[0]);
446 pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper;
448 *ppobj = (void*)(&pfm->unk);
453 /***************************************************************************
455 * CLSID_FilterMapper::IFilterMapper
459 static HRESULT WINAPI
460 IFilterMapper_fnQueryInterface(IFilterMapper* iface,REFIID riid,void** ppobj)
462 CFilterMapper_THIS(iface,fmap);
464 TRACE("(%p)->()\n",This);
466 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
470 IFilterMapper_fnAddRef(IFilterMapper* iface)
472 CFilterMapper_THIS(iface,fmap);
474 TRACE("(%p)->()\n",This);
476 return IUnknown_AddRef(This->unk.punkControl);
480 IFilterMapper_fnRelease(IFilterMapper* iface)
482 CFilterMapper_THIS(iface,fmap);
484 TRACE("(%p)->()\n",This);
486 return IUnknown_Release(This->unk.punkControl);
490 static HRESULT WINAPI
491 IFilterMapper_fnRegisterFilter(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,DWORD dwMerit)
493 CFilterMapper_THIS(iface,fmap);
495 FIXME("(%p)->(%s,%s,%08lx)\n",This,
496 debugstr_guid(&clsid),debugstr_w(lpwszName),dwMerit);
499 /* FIXME - handle dwMerit! */
500 return QUARTZ_RegisterAMovieFilter(
501 &CLSID_LegacyAmFilterCategory,
504 lpwszName, NULL, TRUE );
507 static HRESULT WINAPI
508 IFilterMapper_fnRegisterFilterInstance(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,CLSID* pclsidMedia)
510 CFilterMapper_THIS(iface,fmap);
513 FIXME("(%p)->()\n",This);
515 if ( pclsidMedia == NULL )
517 hr = CoCreateGuid(pclsidMedia);
522 /* this doesn't work. */
523 /* return IFilterMapper_RegisterFilter(iface,
524 *pclsidMedia,lpwszName,0x60000000); */
529 static HRESULT WINAPI
530 IFilterMapper_fnRegisterPin(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR lpwszName,BOOL bRendered,BOOL bOutput,BOOL bZero,BOOL bMany,CLSID clsidReserved,LPCWSTR lpwszReserved)
532 CFilterMapper_THIS(iface,fmap);
534 FIXME("(%p)->() stub!\n",This);
539 static HRESULT WINAPI
540 IFilterMapper_fnRegisterPinType(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR lpwszName,CLSID clsidMajorType,CLSID clsidSubType)
542 CFilterMapper_THIS(iface,fmap);
544 FIXME("(%p)->() stub!\n",This);
549 static HRESULT WINAPI
550 IFilterMapper_fnUnregisterFilter(IFilterMapper* iface,CLSID clsidFilter)
552 CFilterMapper_THIS(iface,fmap);
554 FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidFilter));
557 return QUARTZ_RegisterAMovieFilter(
558 &CLSID_LegacyAmFilterCategory,
560 NULL, 0, NULL, NULL, FALSE );
563 static HRESULT WINAPI
564 IFilterMapper_fnUnregisterFilterInstance(IFilterMapper* iface,CLSID clsidMedia)
566 CFilterMapper_THIS(iface,fmap);
568 FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidMedia));
571 /* this doesn't work. */
572 /* return IFilterMapper_UnregisterFilter(iface,clsidMedia); */
577 static HRESULT WINAPI
578 IFilterMapper_fnUnregisterPin(IFilterMapper* iface,CLSID clsidPin,LPCWSTR lpwszName)
580 CFilterMapper_THIS(iface,fmap);
582 FIXME("(%p)->(%s,%s) stub!\n",This,
583 debugstr_guid(&clsidPin),debugstr_w(lpwszName));
588 static HRESULT WINAPI
589 IFilterMapper_fnEnumMatchingFilters(IFilterMapper* iface,IEnumRegFilters** ppobj,DWORD dwMerit,BOOL bInputNeeded,CLSID clsInMajorType,CLSID clsidSubType,BOOL bRender,BOOL bOutputNeeded,CLSID clsOutMajorType,CLSID clsOutSubType)
591 CFilterMapper_THIS(iface,fmap);
593 FIXME("(%p)->() stub!\n",This);
600 static ICOM_VTABLE(IFilterMapper) ifmap =
602 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
603 /* IUnknown fields */
604 IFilterMapper_fnQueryInterface,
605 IFilterMapper_fnAddRef,
606 IFilterMapper_fnRelease,
607 /* IFilterMapper fields */
608 IFilterMapper_fnRegisterFilter,
609 IFilterMapper_fnRegisterFilterInstance,
610 IFilterMapper_fnRegisterPin,
611 IFilterMapper_fnRegisterPinType,
612 IFilterMapper_fnUnregisterFilter,
613 IFilterMapper_fnUnregisterFilterInstance,
614 IFilterMapper_fnUnregisterPin,
615 IFilterMapper_fnEnumMatchingFilters,
619 HRESULT CFilterMapper_InitIFilterMapper( CFilterMapper* pfm )
622 ICOM_VTBL(&pfm->fmap) = &ifmap;
627 void CFilterMapper_UninitIFilterMapper( CFilterMapper* pfm )
633 /***************************************************************************
635 * new/delete for CLSID_FilterMapper2
639 /* can I use offsetof safely? - FIXME? */
640 static QUARTZ_IFEntry FMap2IFEntries[] =
642 { &IID_IFilterMapper2, offsetof(CFilterMapper2,fmap3)-offsetof(CFilterMapper2,unk) },
643 { &IID_IFilterMapper3, offsetof(CFilterMapper2,fmap3)-offsetof(CFilterMapper2,unk) },
647 static void QUARTZ_DestroyFilterMapper2(IUnknown* punk)
649 CFilterMapper2_THIS(punk,unk);
651 CFilterMapper2_UninitIFilterMapper3( This );
654 HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj)
659 TRACE("(%p,%p)\n",punkOuter,ppobj);
661 pfm = (CFilterMapper2*)QUARTZ_AllocObj( sizeof(CFilterMapper2) );
663 return E_OUTOFMEMORY;
665 QUARTZ_IUnkInit( &pfm->unk, punkOuter );
666 hr = CFilterMapper2_InitIFilterMapper3( pfm );
669 QUARTZ_FreeObj( pfm );
673 pfm->unk.pEntries = FMap2IFEntries;
674 pfm->unk.dwEntries = sizeof(FMap2IFEntries)/sizeof(FMap2IFEntries[0]);
675 pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper2;
677 *ppobj = (void*)(&pfm->unk);
682 /***************************************************************************
684 * CLSID_FilterMapper2::IFilterMapper3
689 static HRESULT WINAPI
690 IFilterMapper3_fnQueryInterface(IFilterMapper3* iface,REFIID riid,void** ppobj)
692 CFilterMapper2_THIS(iface,fmap3);
694 TRACE("(%p)->()\n",This);
696 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
700 IFilterMapper3_fnAddRef(IFilterMapper3* iface)
702 CFilterMapper2_THIS(iface,fmap3);
704 TRACE("(%p)->()\n",This);
706 return IUnknown_AddRef(This->unk.punkControl);
710 IFilterMapper3_fnRelease(IFilterMapper3* iface)
712 CFilterMapper2_THIS(iface,fmap3);
714 TRACE("(%p)->()\n",This);
716 return IUnknown_Release(This->unk.punkControl);
719 static HRESULT WINAPI
720 IFilterMapper3_fnCreateCategory(IFilterMapper3* iface,REFCLSID rclsidCategory,DWORD dwMerit,LPCWSTR lpwszDesc)
722 CFilterMapper2_THIS(iface,fmap3);
724 FIXME("(%p)->(%s,%lu,%s) stub!\n",This,
725 debugstr_guid(rclsidCategory),
726 (unsigned long)dwMerit,debugstr_w(lpwszDesc));
732 static HRESULT WINAPI
733 IFilterMapper3_fnUnregisterFilter(IFilterMapper3* iface,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,REFCLSID rclsidFilter)
735 CFilterMapper2_THIS(iface,fmap3);
736 WCHAR* pwszPath = NULL;
739 TRACE("(%p)->(%s,%s,%s)\n",This,
740 debugstr_guid(pclsidCategory),
741 debugstr_w(lpwszInst),
742 debugstr_guid(rclsidFilter));
744 if ( pclsidCategory == NULL )
745 pclsidCategory = &CLSID_LegacyAmFilterCategory;
747 hr = QUARTZ_GetFilterRegPath(
748 &pwszPath, pclsidCategory, rclsidFilter, lpwszInst );
752 hr = QUARTZ_RegDeleteKey(HKEY_CLASSES_ROOT,pwszPath);
753 QUARTZ_FreeMem(pwszPath);
759 static HRESULT WINAPI
760 IFilterMapper3_fnRegisterFilter(IFilterMapper3* iface,REFCLSID rclsidFilter,LPCWSTR lpName,IMoniker** ppMoniker,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,const REGFILTER2* pRF2)
762 CFilterMapper2_THIS(iface,fmap3);
763 WCHAR* pwszPath = NULL;
764 IMoniker* pMoniker = NULL;
765 BYTE* pFilterData = NULL;
766 DWORD cbFilterData = 0;
769 TRACE( "(%p)->(%s,%s,%p,%s,%s,%p) stub!\n",This,
770 debugstr_guid(rclsidFilter),debugstr_w(lpName),
771 ppMoniker,debugstr_guid(pclsidCategory),
772 debugstr_w(lpwszInst),pRF2 );
774 if ( lpName == NULL || pRF2 == NULL )
777 if ( ppMoniker != NULL && *ppMoniker != NULL )
779 FIXME( "ppMoniker != NULL - not implemented! *ppMoniker = %p\n",*ppMoniker );
783 if ( pclsidCategory == NULL )
784 pclsidCategory = &CLSID_LegacyAmFilterCategory;
786 if ( pMoniker == NULL )
788 hr = QUARTZ_GetFilterRegPath(
789 &pwszPath, pclsidCategory, rclsidFilter, lpwszInst );
792 hr = QUARTZ_CreateDeviceMoniker(
793 HKEY_CLASSES_ROOT,pwszPath,&pMoniker);
794 QUARTZ_FreeMem(pwszPath);
799 pFilterData = QUARTZ_RegFilterToFilterData( pRF2, &cbFilterData );
800 if ( pFilterData == NULL || cbFilterData == 0 )
806 hr = QUARTZ_RegisterFilterToMoniker(
807 pMoniker, rclsidFilter, lpName, pFilterData, cbFilterData );
811 if ( ppMoniker != NULL )
813 *ppMoniker = pMoniker;
817 if ( pFilterData != NULL )
818 QUARTZ_FreeMem(pFilterData);
819 if ( pMoniker != NULL )
820 IMoniker_Release(pMoniker);
826 static HRESULT WINAPI
827 IFilterMapper3_fnEnumMatchingFilters(IFilterMapper3* iface,
828 IEnumMoniker** ppEnumMoniker,DWORD dwFlags,BOOL bExactMatch,DWORD dwMerit,
829 BOOL bInputNeeded,DWORD cInputTypes,const GUID* pguidInputTypes,const REGPINMEDIUM* pPinMediumIn,const CLSID* pPinCategoryIn,BOOL bRender,
830 BOOL bOutputNeeded,DWORD cOutputTypes,const GUID* pguidOutputTypes,const REGPINMEDIUM* pPinMediumOut,const CLSID* pPinCategoryOut)
832 CFilterMapper2_THIS(iface,fmap3);
833 ICreateDevEnum* pEnum = NULL;
834 IEnumMoniker* pCategories = NULL;
835 IMoniker* pCat = NULL;
837 IEnumMoniker* pCatFilters = NULL;
838 IMoniker* pFilter = NULL;
841 BYTE* pbFilterData = NULL;
842 DWORD cbFilterData = 0;
843 REGFILTER2* prf2 = NULL;
844 QUARTZ_CompList* pList = NULL;
845 const REGFILTERPINS2* pRegFilterPin;
850 FIXME("(%p)->(%p,%08lx,%d,%08lx,%d,%lu,%p,%p,%p,%d,%d,%lu,%p,%p,%p)\n",This,ppEnumMoniker,dwFlags,bExactMatch,dwMerit,bInputNeeded,cInputTypes,pguidInputTypes,pPinMediumIn,pPinCategoryIn,bRender,bOutputNeeded,cOutputTypes,pguidOutputTypes,pPinMediumOut,pPinCategoryOut);
852 if ( ppEnumMoniker == NULL )
854 *ppEnumMoniker = NULL;
858 hr = CoCreateInstance(
859 &CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
860 &IID_ICreateDevEnum, (void**)&pEnum );
864 hr = ICreateDevEnum_CreateClassEnumerator(pEnum,&CLSID_ActiveMovieCategories,&pCategories,0);
872 IMoniker_Release(pCat);
875 hr = IEnumMoniker_Next(pCategories,1,&pCat,&cReturned);
880 hr = QUARTZ_GetMeritFromMoniker(pCat,&dwCatMerit);
881 if ( hr != S_OK || dwMerit > dwCatMerit )
883 hr = QUARTZ_GetCLSIDFromMoniker(pCat,&clsid);
887 if ( pCatFilters != NULL )
889 IEnumMoniker_Release(pCatFilters);
892 hr = ICreateDevEnum_CreateClassEnumerator(pEnum,&clsid,&pCatFilters,0);
900 if ( pFilter != NULL )
902 IMoniker_Release(pFilter);
905 hr = IEnumMoniker_Next(pCatFilters,1,&pFilter,&cReturned);
910 if ( pbFilterData != NULL )
912 QUARTZ_FreeMem(pbFilterData);
915 hr = QUARTZ_GetFilterDataFromMoniker(pFilter,&pbFilterData,&cbFilterData);
921 QUARTZ_FreeMem(prf2);
924 prf2 = QUARTZ_RegFilterV2FromFilterData(pbFilterData,cbFilterData);
927 TRACE("prf2 %p, Merit %lu\n",prf2,prf2->dwMerit);
928 if ( prf2->dwMerit < dwMerit || prf2->dwVersion != 2 )
931 /* check input pins. */
935 for ( n = 0; n < prf2->u.s2.cPins2; n++ )
937 pRegFilterPin = &prf2->u.s2.rgPins2[n];
938 if ( pRegFilterPin->dwFlags & REG_PINFLAG_B_OUTPUT )
940 bMatch = QUARTZ_CheckPinType( bExactMatch, pRegFilterPin, cInputTypes, pguidInputTypes, pPinMediumIn, pPinCategoryIn, bRender );
948 /* check output pins. */
952 for ( n = 0; n < prf2->u.s2.cPins2; n++ )
954 pRegFilterPin = &prf2->u.s2.rgPins2[n];
955 if ( !(pRegFilterPin->dwFlags & REG_PINFLAG_B_OUTPUT) )
957 bMatch = QUARTZ_CheckPinType( bExactMatch, pRegFilterPin, cOutputTypes, pguidOutputTypes, pPinMediumOut, pPinCategoryOut, FALSE );
965 /* matched - add pFilter to the list. */
968 pList = QUARTZ_CompList_Alloc();
975 hr = QUARTZ_CompList_AddComp(
976 pList, (IUnknown*)pFilter, NULL, 0 );
988 FIXME("create IEnumMoniker - not sorted\n");
989 /* FIXME - should be sorted?(in Merit order) */
990 hr = QUARTZ_CreateEnumUnknown( &IID_IEnumMoniker, (void**)ppEnumMoniker, pList );
997 ICreateDevEnum_Release(pEnum);
998 if ( pCategories != NULL )
999 IEnumMoniker_Release(pCategories);
1001 IMoniker_Release(pCat);
1002 if ( pCatFilters != NULL )
1003 IEnumMoniker_Release(pCatFilters);
1004 if ( pFilter != NULL )
1005 IMoniker_Release(pFilter);
1006 if ( pbFilterData != NULL )
1007 QUARTZ_FreeMem(pbFilterData);
1009 QUARTZ_FreeMem(prf2);
1010 if ( pList != NULL )
1011 QUARTZ_CompList_Free( pList );
1013 TRACE("returns %08lx\n",hr);
1018 static HRESULT WINAPI
1019 IFilterMapper3_fnGetICreateDevEnum(IFilterMapper3* iface,ICreateDevEnum** ppDevEnum)
1021 CFilterMapper2_THIS(iface,fmap3);
1024 FIXME("(%p)->() stub!\n",This);
1032 static ICOM_VTABLE(IFilterMapper3) ifmap3 =
1034 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1035 /* IUnknown fields */
1036 IFilterMapper3_fnQueryInterface,
1037 IFilterMapper3_fnAddRef,
1038 IFilterMapper3_fnRelease,
1039 /* IFilterMapper2 fields */
1040 IFilterMapper3_fnCreateCategory,
1041 IFilterMapper3_fnUnregisterFilter,
1042 IFilterMapper3_fnRegisterFilter,
1043 IFilterMapper3_fnEnumMatchingFilters,
1044 /* IFilterMapper3 fields */
1045 IFilterMapper3_fnGetICreateDevEnum,
1049 HRESULT CFilterMapper2_InitIFilterMapper3( CFilterMapper2* pfm )
1051 TRACE("(%p)\n",pfm);
1052 ICOM_VTBL(&pfm->fmap3) = &ifmap3;
1057 void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* pfm )
1059 TRACE("(%p)\n",pfm);