2 * Implementation of CLSID_FilterMapper and CLSID_FilterMapper2.
6 * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
38 #include "quartz_private.h"
45 /***************************************************************************/
47 typedef struct QUARTZ_REGFILTERDATA
49 DWORD dwVersion; /* =2 */
51 DWORD cPins; /* count of pins */
52 DWORD dwZero; /* padding??? */
53 } QUARTZ_REGFILTERDATA;
55 typedef struct QUARTZ_REGPINDATA
57 CHAR id[4]; /* '0pi3', '1pi3', ... */
58 DWORD dwFlags; /* flags */
59 UINT cInstances; /* FIXME - is this correct? */
60 UINT nMediaTypes; /* count of media types('0ty3') */
61 UINT nMediums; /* FIXME - is this correct? */
62 UINT nOfsClsPinCategory; /* FIXME - is this correct? */
65 typedef struct QUARTZ_REGMEDIATYPE
67 CHAR id[4]; /* '0ty3', '1ty3', ... */
68 DWORD nZero; /* padding??? */
71 } QUARTZ_REGMEDIATYPE;
75 /***************************************************************************/
78 REGFILTER2* QUARTZ_RegFilterV2FromFilterData(
79 const BYTE* pData, DWORD cbData )
85 const QUARTZ_REGFILTERDATA* pRegFilter;
86 const QUARTZ_REGPINDATA* pRegPin;
87 const QUARTZ_REGMEDIATYPE* pRegMediaType;
92 TRACE("(%p,%lu)\n",pData,cbData);
94 if ( cbData < sizeof(QUARTZ_REGFILTERDATA) )
97 pRegFilter = (QUARTZ_REGFILTERDATA*)pData;
99 if ( pRegFilter->dwVersion != 2 ) return NULL; /* FIXME */
101 if ( cbData < (sizeof(QUARTZ_REGFILTERDATA)+sizeof(QUARTZ_REGPINDATA)*pRegFilter->cPins) )
104 cbBufSize = sizeof(REGFILTER2);
105 cPins = pRegFilter->cPins;
106 pRegPin = (const QUARTZ_REGPINDATA*)(pRegFilter+1);
107 while ( cPins-- > 0 )
109 if ( pRegPin->nMediums != 0 ||
110 pRegPin->nOfsClsPinCategory != 0 )
111 return NULL; /* FIXME */
113 cbBufSize += sizeof(REGFILTERPINS2) +
114 pRegPin->nMediaTypes * (sizeof(REGPINTYPES) + sizeof(GUID)*2) +
115 pRegPin->nMediums * sizeof(REGPINMEDIUM) +
117 pRegPin = (const QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
118 sizeof(QUARTZ_REGPINDATA) +
119 sizeof(QUARTZ_REGMEDIATYPE) * pRegPin->nMediaTypes );
122 pFilter = (REGFILTER2*)QUARTZ_AllocMem( cbBufSize );
123 if ( pFilter == NULL ) return NULL;
124 ZeroMemory( pFilter, cbBufSize );
125 pPin = (REGFILTERPINS2*)(pFilter+1);
126 pDst = (BYTE*)(pPin + pRegFilter->cPins);
128 pFilter->dwVersion = 2;
129 pFilter->dwMerit = pRegFilter->dwMerit;
130 pFilter->u.s2.cPins2 = pRegFilter->cPins;
131 pFilter->u.s2.rgPins2 = pPin;
133 cPins = pRegFilter->cPins;
134 TRACE("cPins = %lu\n",cPins);
136 pRegPin = (const QUARTZ_REGPINDATA*)(pRegFilter+1);
137 while ( cPins-- > 0 )
139 pPin->dwFlags = pRegPin->dwFlags;
140 pPin->cInstances = pRegPin->cInstances;
141 pPin->nMediaTypes = pRegPin->nMediaTypes;
142 pPin->lpMediaType = NULL;
143 pPin->nMediums = pRegPin->nMediums;
144 pPin->lpMedium = NULL;
145 pPin->clsPinCategory = NULL;
147 pTypes = (REGPINTYPES*)pDst;
148 pPin->lpMediaType = pTypes;
149 pDst += sizeof(REGPINTYPES) * pRegPin->nMediaTypes;
151 pRegPin = (const QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
152 sizeof(QUARTZ_REGPINDATA) );
154 for ( n = 0; n < pPin->nMediaTypes; n++ )
156 pRegMediaType = ((const QUARTZ_REGMEDIATYPE*)pRegPin);
157 TRACE("ofsMajor = %u, ofsMinor = %u\n", pRegMediaType->nOfsMajorType, pRegMediaType->nOfsMinorType);
158 memcpy( pDst, pData+pRegMediaType->nOfsMajorType, sizeof(GUID) );
159 pTypes->clsMajorType = (const GUID*)pDst; pDst += sizeof(GUID);
160 memcpy( pDst, pData+pRegMediaType->nOfsMinorType, sizeof(GUID) );
161 pTypes->clsMinorType = (const GUID*)pDst; pDst += sizeof(GUID);
163 pRegPin = (const QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
164 sizeof(QUARTZ_REGMEDIATYPE) );
168 /* FIXME - pPin->lpMedium */
169 /* FIXME - pPin->clsPinCategory */
178 BYTE* QUARTZ_RegFilterV2ToFilterData(
179 const REGFILTER2* pFilter, DWORD* pcbData )
184 const REGFILTERPINS2* pPin;
185 const REGPINTYPES* pTypes;
188 QUARTZ_REGFILTERDATA* pRegFilter;
189 QUARTZ_REGPINDATA* pRegPin;
190 QUARTZ_REGMEDIATYPE* pRegMediaType;
193 if ( pFilter->dwVersion != 2 ) return NULL; /* FIXME */
195 cbData = sizeof(QUARTZ_REGFILTERDATA);
196 cPins = pFilter->u.s2.cPins2;
197 pPin = pFilter->u.s2.rgPins2;
198 if ( cPins > 10 ) return NULL; /* FIXME */
201 while ( cPins-- > 0 )
203 if ( pPin->cInstances != 0 ||
204 pPin->nMediaTypes > 10 ||
205 pPin->nMediums != 0 ||
206 pPin->clsPinCategory != 0 )
208 FIXME( "not implemented.\n" );
209 return NULL; /* FIXME */
212 cbPinData += sizeof(QUARTZ_REGPINDATA) +
213 pPin->nMediaTypes * sizeof(QUARTZ_REGMEDIATYPE);
214 cbData += pPin->nMediaTypes * (sizeof(GUID)*2);
218 TRACE("cbData %lu, cbPinData %lu\n",cbData,cbPinData);
220 pRet = (BYTE*)QUARTZ_AllocMem( cbData );
221 if ( pRet == NULL ) return NULL;
222 ZeroMemory( pRet, cbData );
225 pRegFilter = (QUARTZ_REGFILTERDATA*)pDst;
226 pDst += sizeof(QUARTZ_REGFILTERDATA);
228 pRegFilter->dwVersion = 2;
229 pRegFilter->dwMerit = pFilter->dwMerit;
230 pRegFilter->cPins = pFilter->u.s2.cPins2;
232 pRegPin = (QUARTZ_REGPINDATA*)pDst;
235 pPin = pFilter->u.s2.rgPins2;
236 for ( cPins = 0; cPins < pFilter->u.s2.cPins2; cPins++ )
238 pRegPin->id[0] = '0'+cPins;
239 pRegPin->id[1] = 'p';
240 pRegPin->id[2] = 'i';
241 pRegPin->id[3] = '3';
242 pRegPin->dwFlags = pPin->dwFlags; /* flags */
243 pRegPin->cInstances = pPin->cInstances;
244 pRegPin->nMediaTypes = pPin->nMediaTypes;
245 pRegPin->nMediums = pPin->nMediums;
246 pRegPin->nOfsClsPinCategory = 0; /* FIXME */
248 pTypes = pPin->lpMediaType;
249 pRegPin = (QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
250 sizeof(QUARTZ_REGPINDATA) );
251 for ( n = 0; n < pPin->nMediaTypes; n++ )
253 pRegMediaType = ((QUARTZ_REGMEDIATYPE*)pRegPin);
255 pRegMediaType->id[0] = '0'+n;
256 pRegMediaType->id[1] = 't';
257 pRegMediaType->id[2] = 'y';
258 pRegMediaType->id[3] = '3';
260 /* FIXME - CLSID should be shared. */
261 pRegMediaType->nOfsMajorType = pDst - pRet;
262 memcpy( pDst, pTypes->clsMajorType, sizeof(GUID) );
263 pDst += sizeof(GUID);
264 pRegMediaType->nOfsMinorType = pDst - pRet;
265 memcpy( pDst, pTypes->clsMinorType, sizeof(GUID) );
266 pDst += sizeof(GUID);
268 pRegPin = (QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
269 sizeof(QUARTZ_REGMEDIATYPE) );
275 *pcbData = pDst - pRet;
276 TRACE("cbData %lu/%lu\n",*pcbData,cbData);
282 REGFILTER2* QUARTZ_RegFilterV1ToV2( const REGFILTER2* prfV1 )
285 const REGFILTERPINS* pPinV1;
286 REGFILTERPINS2* pPinV2;
289 if ( prfV1->dwVersion != 1 ) return NULL;
291 prfV2 = (REGFILTER2*)QUARTZ_AllocMem(
292 sizeof(REGFILTER2) + sizeof(REGFILTERPINS2) * prfV1->u.s1.cPins );
293 if ( prfV2 == NULL ) return NULL;
294 ZeroMemory( prfV2, sizeof(REGFILTER2) + sizeof(REGFILTERPINS2) * prfV1->u.s1.cPins );
295 pPinV1 = prfV1->u.s1.rgPins;
296 pPinV2 = (REGFILTERPINS2*)(prfV2+1);
297 prfV2->dwVersion = 2;
298 prfV2->dwMerit = prfV1->dwMerit;
299 prfV2->u.s2.cPins2 = prfV1->u.s1.cPins;
300 prfV2->u.s2.rgPins2 = pPinV2;
302 cPins = prfV1->u.s1.cPins;
303 while ( cPins-- > 0 )
306 pPinV2->cInstances = 0;
307 pPinV2->nMediaTypes = pPinV1->nMediaTypes;
308 pPinV2->lpMediaType = pPinV1->lpMediaType;
309 pPinV2->nMediums = 0;
310 pPinV2->lpMedium = NULL;
311 pPinV2->clsPinCategory = NULL;
313 if ( pPinV1->bRendered )
314 pPinV2->dwFlags |= REG_PINFLAG_B_RENDERER;
315 if ( pPinV1->bOutput )
316 pPinV2->dwFlags |= REG_PINFLAG_B_OUTPUT;
318 pPinV2->dwFlags |= REG_PINFLAG_B_ZERO;
320 pPinV2->dwFlags |= REG_PINFLAG_B_MANY;
330 BYTE* QUARTZ_RegFilterToFilterData(
331 const REGFILTER2* pFilter, DWORD* pcbData )
337 switch ( pFilter->dwVersion )
340 prfV2 = QUARTZ_RegFilterV1ToV2( pFilter );
343 pRet = QUARTZ_RegFilterV2ToFilterData( prfV2, pcbData );
344 QUARTZ_FreeMem( prfV2 );
348 pRet = QUARTZ_RegFilterV2ToFilterData( pFilter, pcbData );
351 FIXME( "unknown REGFILTER2 version - %08lu\n", pFilter->dwVersion );
358 /***************************************************************************/
361 BOOL QUARTZ_CheckPinType( BOOL bExactMatch, const REGFILTERPINS2* pPin, DWORD cTypes, const GUID* pTypes, const REGPINMEDIUM* pMedium, const CLSID* pCategory, BOOL bRender )
366 if ( cTypes > 0 && pTypes != NULL )
369 for ( n1 = 0; n1 < pPin->nMediaTypes; n1++ )
371 for ( n2 = 0; n2 < cTypes; n2++ )
373 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)) )
375 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)) )
383 TRACE("Check media type %d\n",(int)bMatch);
388 if ( pMedium != NULL )
391 for ( n1 = 0; n1 < pPin->nMediums; n1++ )
393 if ( IsEqualGUID( &pPin->lpMedium[n1].clsMedium, &pMedium->clsMedium ) && pPin->lpMedium[n1].dw1 == pMedium->dw1 && pPin->lpMedium[n1].dw2 == pMedium->dw2 )
399 TRACE("Check medium %d\n",(int)bMatch);
404 if ( pCategory != NULL )
406 if ( pPin->clsPinCategory == NULL )
408 if ( (!bExactMatch && IsEqualGUID(pCategory,&GUID_NULL)) || IsEqualGUID(pCategory,pPin->clsPinCategory) )
413 if ( bRender && (!(pPin->dwFlags & REG_PINFLAG_B_RENDERER)) )
415 TRACE("not a renderer\n");
425 /***************************************************************************
427 * new/delete for CLSID_FilterMapper
431 /* can I use offsetof safely? - FIXME? */
432 static QUARTZ_IFEntry FMapIFEntries[] =
434 { &IID_IFilterMapper, offsetof(CFilterMapper,fmap)-offsetof(CFilterMapper,unk) },
438 static void QUARTZ_DestroyFilterMapper(IUnknown* punk)
440 CFilterMapper_THIS(punk,unk);
442 CFilterMapper_UninitIFilterMapper( This );
445 HRESULT QUARTZ_CreateFilterMapper(IUnknown* punkOuter,void** ppobj)
450 TRACE("(%p,%p)\n",punkOuter,ppobj);
452 pfm = (CFilterMapper*)QUARTZ_AllocObj( sizeof(CFilterMapper) );
454 return E_OUTOFMEMORY;
456 QUARTZ_IUnkInit( &pfm->unk, punkOuter );
457 hr = CFilterMapper_InitIFilterMapper( pfm );
460 QUARTZ_FreeObj( pfm );
464 pfm->unk.pEntries = FMapIFEntries;
465 pfm->unk.dwEntries = sizeof(FMapIFEntries)/sizeof(FMapIFEntries[0]);
466 pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper;
468 *ppobj = (void*)(&pfm->unk);
473 /***************************************************************************
475 * CLSID_FilterMapper::IFilterMapper
479 static HRESULT WINAPI
480 IFilterMapper_fnQueryInterface(IFilterMapper* iface,REFIID riid,void** ppobj)
482 CFilterMapper_THIS(iface,fmap);
484 TRACE("(%p)->()\n",This);
486 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
490 IFilterMapper_fnAddRef(IFilterMapper* iface)
492 CFilterMapper_THIS(iface,fmap);
494 TRACE("(%p)->()\n",This);
496 return IUnknown_AddRef(This->unk.punkControl);
500 IFilterMapper_fnRelease(IFilterMapper* iface)
502 CFilterMapper_THIS(iface,fmap);
504 TRACE("(%p)->()\n",This);
506 return IUnknown_Release(This->unk.punkControl);
510 static HRESULT WINAPI
511 IFilterMapper_fnRegisterFilter(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,DWORD dwMerit)
513 CFilterMapper_THIS(iface,fmap);
515 FIXME("(%p)->(%s,%s,%08lx)\n",This,
516 debugstr_guid(&clsid),debugstr_w(lpwszName),dwMerit);
519 /* FIXME - handle dwMerit! */
520 return QUARTZ_RegisterAMovieFilter(
521 &CLSID_LegacyAmFilterCategory,
524 lpwszName, NULL, TRUE );
527 static HRESULT WINAPI
528 IFilterMapper_fnRegisterFilterInstance(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,CLSID* pclsidMedia)
530 CFilterMapper_THIS(iface,fmap);
533 FIXME("(%p)->()\n",This);
535 if ( pclsidMedia == NULL )
537 hr = CoCreateGuid(pclsidMedia);
542 /* this doesn't work. */
543 /* return IFilterMapper_RegisterFilter(iface,
544 *pclsidMedia,lpwszName,0x60000000); */
549 static HRESULT WINAPI
550 IFilterMapper_fnRegisterPin(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR lpwszName,BOOL bRendered,BOOL bOutput,BOOL bZero,BOOL bMany,CLSID clsidReserved,LPCWSTR lpwszReserved)
552 CFilterMapper_THIS(iface,fmap);
554 FIXME("(%p)->() stub!\n",This);
559 static HRESULT WINAPI
560 IFilterMapper_fnRegisterPinType(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR lpwszName,CLSID clsidMajorType,CLSID clsidSubType)
562 CFilterMapper_THIS(iface,fmap);
564 FIXME("(%p)->() stub!\n",This);
569 static HRESULT WINAPI
570 IFilterMapper_fnUnregisterFilter(IFilterMapper* iface,CLSID clsidFilter)
572 CFilterMapper_THIS(iface,fmap);
574 FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidFilter));
577 return QUARTZ_RegisterAMovieFilter(
578 &CLSID_LegacyAmFilterCategory,
580 NULL, 0, NULL, NULL, FALSE );
583 static HRESULT WINAPI
584 IFilterMapper_fnUnregisterFilterInstance(IFilterMapper* iface,CLSID clsidMedia)
586 CFilterMapper_THIS(iface,fmap);
588 FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidMedia));
591 /* this doesn't work. */
592 /* return IFilterMapper_UnregisterFilter(iface,clsidMedia); */
597 static HRESULT WINAPI
598 IFilterMapper_fnUnregisterPin(IFilterMapper* iface,CLSID clsidPin,LPCWSTR lpwszName)
600 CFilterMapper_THIS(iface,fmap);
602 FIXME("(%p)->(%s,%s) stub!\n",This,
603 debugstr_guid(&clsidPin),debugstr_w(lpwszName));
608 static HRESULT WINAPI
609 IFilterMapper_fnEnumMatchingFilters(IFilterMapper* iface,IEnumRegFilters** ppobj,DWORD dwMerit,BOOL bInputNeeded,CLSID clsInMajorType,CLSID clsidSubType,BOOL bRender,BOOL bOutputNeeded,CLSID clsOutMajorType,CLSID clsOutSubType)
611 CFilterMapper_THIS(iface,fmap);
613 FIXME("(%p)->() stub!\n",This);
620 static ICOM_VTABLE(IFilterMapper) ifmap =
622 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
623 /* IUnknown fields */
624 IFilterMapper_fnQueryInterface,
625 IFilterMapper_fnAddRef,
626 IFilterMapper_fnRelease,
627 /* IFilterMapper fields */
628 IFilterMapper_fnRegisterFilter,
629 IFilterMapper_fnRegisterFilterInstance,
630 IFilterMapper_fnRegisterPin,
631 IFilterMapper_fnRegisterPinType,
632 IFilterMapper_fnUnregisterFilter,
633 IFilterMapper_fnUnregisterFilterInstance,
634 IFilterMapper_fnUnregisterPin,
635 IFilterMapper_fnEnumMatchingFilters,
639 HRESULT CFilterMapper_InitIFilterMapper( CFilterMapper* pfm )
642 ICOM_VTBL(&pfm->fmap) = &ifmap;
647 void CFilterMapper_UninitIFilterMapper( CFilterMapper* pfm )
653 /***************************************************************************
655 * new/delete for CLSID_FilterMapper2
659 /* can I use offsetof safely? - FIXME? */
660 static QUARTZ_IFEntry FMap2IFEntries[] =
662 { &IID_IFilterMapper2, offsetof(CFilterMapper2,fmap2)-offsetof(CFilterMapper2,unk) },
666 static void QUARTZ_DestroyFilterMapper2(IUnknown* punk)
668 CFilterMapper2_THIS(punk,unk);
670 CFilterMapper2_UninitIFilterMapper2( This );
673 HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj)
678 TRACE("(%p,%p)\n",punkOuter,ppobj);
680 pfm = (CFilterMapper2*)QUARTZ_AllocObj( sizeof(CFilterMapper2) );
682 return E_OUTOFMEMORY;
684 QUARTZ_IUnkInit( &pfm->unk, punkOuter );
685 hr = CFilterMapper2_InitIFilterMapper2( pfm );
688 QUARTZ_FreeObj( pfm );
692 pfm->unk.pEntries = FMap2IFEntries;
693 pfm->unk.dwEntries = sizeof(FMap2IFEntries)/sizeof(FMap2IFEntries[0]);
694 pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper2;
696 *ppobj = (void*)(&pfm->unk);
701 /***************************************************************************
703 * CLSID_FilterMapper2::IFilterMapper2
708 static HRESULT WINAPI
709 IFilterMapper2_fnQueryInterface(IFilterMapper2* iface,REFIID riid,void** ppobj)
711 CFilterMapper2_THIS(iface,fmap2);
713 TRACE("(%p)->()\n",This);
715 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
719 IFilterMapper2_fnAddRef(IFilterMapper2* iface)
721 CFilterMapper2_THIS(iface,fmap2);
723 TRACE("(%p)->()\n",This);
725 return IUnknown_AddRef(This->unk.punkControl);
729 IFilterMapper2_fnRelease(IFilterMapper2* iface)
731 CFilterMapper2_THIS(iface,fmap2);
733 TRACE("(%p)->()\n",This);
735 return IUnknown_Release(This->unk.punkControl);
738 static HRESULT WINAPI
739 IFilterMapper2_fnCreateCategory(IFilterMapper2* iface,REFCLSID rclsidCategory,DWORD dwMerit,LPCWSTR lpwszDesc)
741 CFilterMapper2_THIS(iface,fmap2);
743 FIXME("(%p)->(%s,%lu,%s) stub!\n",This,
744 debugstr_guid(rclsidCategory),
745 (unsigned long)dwMerit,debugstr_w(lpwszDesc));
751 static HRESULT WINAPI
752 IFilterMapper2_fnUnregisterFilter(IFilterMapper2* iface,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,REFCLSID rclsidFilter)
754 CFilterMapper2_THIS(iface,fmap2);
755 WCHAR* pwszPath = NULL;
758 TRACE("(%p)->(%s,%s,%s)\n",This,
759 debugstr_guid(pclsidCategory),
760 debugstr_w(lpwszInst),
761 debugstr_guid(rclsidFilter));
763 if ( pclsidCategory == NULL )
764 pclsidCategory = &CLSID_LegacyAmFilterCategory;
766 hr = QUARTZ_GetFilterRegPath(
767 &pwszPath, pclsidCategory, rclsidFilter, lpwszInst );
771 hr = QUARTZ_RegDeleteKey(HKEY_CLASSES_ROOT,pwszPath);
772 QUARTZ_FreeMem(pwszPath);
778 static HRESULT WINAPI
779 IFilterMapper2_fnRegisterFilter(IFilterMapper2* iface,REFCLSID rclsidFilter,LPCWSTR lpName,IMoniker** ppMoniker,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,const REGFILTER2* pRF2)
781 CFilterMapper2_THIS(iface,fmap2);
782 WCHAR* pwszPath = NULL;
783 IMoniker* pMoniker = NULL;
784 BYTE* pFilterData = NULL;
785 DWORD cbFilterData = 0;
788 TRACE( "(%p)->(%s,%s,%p,%s,%s,%p) stub!\n",This,
789 debugstr_guid(rclsidFilter),debugstr_w(lpName),
790 ppMoniker,debugstr_guid(pclsidCategory),
791 debugstr_w(lpwszInst),pRF2 );
793 if ( lpName == NULL || pRF2 == NULL )
796 if ( ppMoniker != NULL && *ppMoniker != NULL )
798 FIXME( "ppMoniker != NULL - not implemented! *ppMoniker = %p\n",*ppMoniker );
802 if ( pclsidCategory == NULL )
803 pclsidCategory = &CLSID_LegacyAmFilterCategory;
805 if ( pMoniker == NULL )
807 hr = QUARTZ_GetFilterRegPath(
808 &pwszPath, pclsidCategory, rclsidFilter, lpwszInst );
811 hr = QUARTZ_CreateDeviceMoniker(
812 HKEY_CLASSES_ROOT,pwszPath,&pMoniker);
813 QUARTZ_FreeMem(pwszPath);
818 pFilterData = QUARTZ_RegFilterToFilterData( pRF2, &cbFilterData );
819 if ( pFilterData == NULL || cbFilterData == 0 )
825 hr = QUARTZ_RegisterFilterToMoniker(
826 pMoniker, rclsidFilter, lpName, pFilterData, cbFilterData );
830 if ( ppMoniker != NULL )
832 *ppMoniker = pMoniker;
836 if ( pFilterData != NULL )
837 QUARTZ_FreeMem(pFilterData);
838 if ( pMoniker != NULL )
839 IMoniker_Release(pMoniker);
846 IMoniker* pMonFilter;
850 static int sort_comp_merit(const void* p1,const void* p2)
852 const struct MATCHED_ITEM* pItem1 = (const struct MATCHED_ITEM*)p1;
853 const struct MATCHED_ITEM* pItem2 = (const struct MATCHED_ITEM*)p2;
855 return (int)pItem2->dwMerit - (int)pItem1->dwMerit;
858 static HRESULT WINAPI
859 IFilterMapper2_fnEnumMatchingFilters(IFilterMapper2* iface,
860 IEnumMoniker** ppEnumMoniker,DWORD dwFlags,BOOL bExactMatch,DWORD dwMerit,
861 BOOL bInputNeeded,DWORD cInputTypes,const GUID* pguidInputTypes,const REGPINMEDIUM* pPinMediumIn,const CLSID* pPinCategoryIn,BOOL bRender,
862 BOOL bOutputNeeded,DWORD cOutputTypes,const GUID* pguidOutputTypes,const REGPINMEDIUM* pPinMediumOut,const CLSID* pPinCategoryOut)
864 CFilterMapper2_THIS(iface,fmap2);
865 ICreateDevEnum* pEnum = NULL;
866 IEnumMoniker* pCategories = NULL;
867 IMoniker* pCat = NULL;
869 IEnumMoniker* pCatFilters = NULL;
870 IMoniker* pFilter = NULL;
873 BYTE* pbFilterData = NULL;
874 DWORD cbFilterData = 0;
875 REGFILTER2* prf2 = NULL;
876 QUARTZ_CompList* pListFilters = NULL;
877 struct MATCHED_ITEM* pItems = NULL;
878 struct MATCHED_ITEM* pItemsTmp;
880 const REGFILTERPINS2* pRegFilterPin;
885 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);
887 if ( ppEnumMoniker == NULL )
889 *ppEnumMoniker = NULL;
893 hr = CoCreateInstance(
894 &CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
895 &IID_ICreateDevEnum, (void**)&pEnum );
899 hr = ICreateDevEnum_CreateClassEnumerator(pEnum,&CLSID_ActiveMovieCategories,&pCategories,0);
907 IMoniker_Release(pCat);
910 hr = IEnumMoniker_Next(pCategories,1,&pCat,&cReturned);
915 hr = QUARTZ_GetMeritFromMoniker(pCat,&dwCatMerit);
916 if ( hr != S_OK || dwMerit > dwCatMerit )
918 hr = QUARTZ_GetCLSIDFromMoniker(pCat,&clsid);
922 if ( pCatFilters != NULL )
924 IEnumMoniker_Release(pCatFilters);
927 hr = ICreateDevEnum_CreateClassEnumerator(pEnum,&clsid,&pCatFilters,0);
935 if ( pFilter != NULL )
937 IMoniker_Release(pFilter);
940 hr = IEnumMoniker_Next(pCatFilters,1,&pFilter,&cReturned);
945 if ( pbFilterData != NULL )
947 QUARTZ_FreeMem(pbFilterData);
953 if (SUCCEEDED(QUARTZ_GetCLSIDFromMoniker(pFilter,&clsidTrace)))
955 TRACE("moniker clsid %s\n",debugstr_guid(&clsidTrace));
958 hr = QUARTZ_GetFilterDataFromMoniker(pFilter,&pbFilterData,&cbFilterData);
964 QUARTZ_FreeMem(prf2);
967 prf2 = QUARTZ_RegFilterV2FromFilterData(pbFilterData,cbFilterData);
970 TRACE("prf2 %p, Merit %08lx\n",prf2,prf2->dwMerit);
971 if ( prf2->dwMerit < dwMerit || prf2->dwVersion != 2 )
974 /* check input pins. */
978 for ( n = 0; n < prf2->u.s2.cPins2; n++ )
980 pRegFilterPin = &prf2->u.s2.rgPins2[n];
981 if ( pRegFilterPin->dwFlags & REG_PINFLAG_B_OUTPUT )
983 bMatch = QUARTZ_CheckPinType( bExactMatch, pRegFilterPin, cInputTypes, pguidInputTypes, pPinMediumIn, pPinCategoryIn, bRender );
989 TRACE("no matching input pin\n");
994 /* check output pins. */
998 for ( n = 0; n < prf2->u.s2.cPins2; n++ )
1000 pRegFilterPin = &prf2->u.s2.rgPins2[n];
1001 if ( !(pRegFilterPin->dwFlags & REG_PINFLAG_B_OUTPUT) )
1003 bMatch = QUARTZ_CheckPinType( bExactMatch, pRegFilterPin, cOutputTypes, pguidOutputTypes, pPinMediumOut, pPinCategoryOut, FALSE );
1009 TRACE("no matching output pin\n");
1014 /* matched - add pFilter to the list. */
1015 pItemsTmp = QUARTZ_ReallocMem( pItems, sizeof(struct MATCHED_ITEM) * (cItems+1) );
1016 if ( pItemsTmp == NULL )
1022 pItemsTmp = pItems + cItems; cItems ++;
1023 pItemsTmp->pMonFilter = pFilter; pFilter = NULL;
1024 pItemsTmp->dwMerit = prf2->dwMerit;
1028 if ( pItems == NULL || cItems == 0 )
1034 /* FIXME - sort in Merit order */
1035 TRACE("sort in Merit order\n");
1036 qsort( pItems, cItems, sizeof(struct MATCHED_ITEM), sort_comp_merit );
1038 pListFilters = QUARTZ_CompList_Alloc();
1039 if ( pListFilters == NULL )
1044 for ( n = 0; n < cItems; n++ )
1046 TRACE("merit %08lx\n",pItems[n].dwMerit);
1047 hr = QUARTZ_CompList_AddComp( pListFilters, (IUnknown*)pItems[n].pMonFilter, NULL, 0 );
1052 hr = QUARTZ_CreateEnumUnknown( &IID_IEnumMoniker, (void**)ppEnumMoniker, pListFilters );
1058 if ( pEnum != NULL )
1059 ICreateDevEnum_Release(pEnum);
1060 if ( pCategories != NULL )
1061 IEnumMoniker_Release(pCategories);
1063 IMoniker_Release(pCat);
1064 if ( pCatFilters != NULL )
1065 IEnumMoniker_Release(pCatFilters);
1066 if ( pFilter != NULL )
1067 IMoniker_Release(pFilter);
1068 if ( pbFilterData != NULL )
1069 QUARTZ_FreeMem(pbFilterData);
1071 QUARTZ_FreeMem(prf2);
1072 if ( pItems != NULL && cItems > 0 )
1074 for ( n = 0; n < cItems; n++ )
1076 if ( pItems[n].pMonFilter != NULL )
1077 IMoniker_Release(pItems[n].pMonFilter);
1079 QUARTZ_FreeMem(pItems);
1081 if ( pListFilters != NULL )
1082 QUARTZ_CompList_Free( pListFilters );
1084 TRACE("returns %08lx\n",hr);
1092 static ICOM_VTABLE(IFilterMapper2) ifmap2 =
1094 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1095 /* IUnknown fields */
1096 IFilterMapper2_fnQueryInterface,
1097 IFilterMapper2_fnAddRef,
1098 IFilterMapper2_fnRelease,
1099 /* IFilterMapper2 fields */
1100 IFilterMapper2_fnCreateCategory,
1101 IFilterMapper2_fnUnregisterFilter,
1102 IFilterMapper2_fnRegisterFilter,
1103 IFilterMapper2_fnEnumMatchingFilters,
1107 HRESULT CFilterMapper2_InitIFilterMapper2( CFilterMapper2* pfm )
1109 TRACE("(%p)\n",pfm);
1110 ICOM_VTBL(&pfm->fmap2) = &ifmap2;
1115 void CFilterMapper2_UninitIFilterMapper2( CFilterMapper2* pfm )
1117 TRACE("(%p)\n",pfm);