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
34 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
37 #include "quartz_private.h"
44 /***************************************************************************/
46 typedef struct QUARTZ_REGFILTERDATA
48 DWORD dwVersion; /* =2 */
50 DWORD cPins; /* count of pins */
51 DWORD dwZero; /* padding??? */
52 } QUARTZ_REGFILTERDATA;
54 typedef struct QUARTZ_REGPINDATA
56 CHAR id[4]; /* '0pi3', '1pi3', ... */
57 DWORD dwFlags; /* flags */
58 UINT cInstances; /* FIXME - is this correct? */
59 UINT nMediaTypes; /* count of media types('0ty3') */
60 UINT nMediums; /* FIXME - is this correct? */
61 UINT nOfsClsPinCategory; /* FIXME - is this correct? */
64 typedef struct QUARTZ_REGMEDIATYPE
66 CHAR id[4]; /* '0ty3', '1ty3', ... */
67 DWORD nZero; /* padding??? */
70 } QUARTZ_REGMEDIATYPE;
74 /***************************************************************************/
77 REGFILTER2* QUARTZ_RegFilterV2FromFilterData(
78 const BYTE* pData, DWORD cbData )
84 const QUARTZ_REGFILTERDATA* pRegFilter;
85 const QUARTZ_REGPINDATA* pRegPin;
86 const QUARTZ_REGMEDIATYPE* pRegMediaType;
91 TRACE("(%p,%lu)\n",pData,cbData);
93 if ( cbData < sizeof(QUARTZ_REGFILTERDATA) )
96 pRegFilter = (QUARTZ_REGFILTERDATA*)pData;
98 if ( pRegFilter->dwVersion != 2 ) return NULL; /* FIXME */
100 if ( cbData < (sizeof(QUARTZ_REGFILTERDATA)+sizeof(QUARTZ_REGPINDATA)*pRegFilter->cPins) )
103 cbBufSize = sizeof(REGFILTER2);
104 cPins = pRegFilter->cPins;
105 pRegPin = (const QUARTZ_REGPINDATA*)(pRegFilter+1);
106 while ( cPins-- > 0 )
108 if ( pRegPin->nMediums != 0 ||
109 pRegPin->nOfsClsPinCategory != 0 )
110 return NULL; /* FIXME */
112 cbBufSize += sizeof(REGFILTERPINS2) +
113 pRegPin->nMediaTypes * (sizeof(REGPINTYPES) + sizeof(GUID)*2) +
114 pRegPin->nMediums * sizeof(REGPINMEDIUM) +
116 pRegPin = (const QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
117 sizeof(QUARTZ_REGPINDATA) +
118 sizeof(QUARTZ_REGMEDIATYPE) * pRegPin->nMediaTypes );
121 pFilter = (REGFILTER2*)QUARTZ_AllocMem( cbBufSize );
122 if ( pFilter == NULL ) return NULL;
123 ZeroMemory( pFilter, cbBufSize );
124 pPin = (REGFILTERPINS2*)(pFilter+1);
125 pDst = (BYTE*)(pPin + pRegFilter->cPins);
127 pFilter->dwVersion = 2;
128 pFilter->dwMerit = pRegFilter->dwMerit;
129 pFilter->u.s2.cPins2 = pRegFilter->cPins;
130 pFilter->u.s2.rgPins2 = pPin;
132 cPins = pRegFilter->cPins;
133 TRACE("cPins = %lu\n",cPins);
135 pRegPin = (const QUARTZ_REGPINDATA*)(pRegFilter+1);
136 while ( cPins-- > 0 )
138 pPin->dwFlags = pRegPin->dwFlags;
139 pPin->cInstances = pRegPin->cInstances;
140 pPin->nMediaTypes = pRegPin->nMediaTypes;
141 pPin->lpMediaType = NULL;
142 pPin->nMediums = pRegPin->nMediums;
143 pPin->lpMedium = NULL;
144 pPin->clsPinCategory = NULL;
146 pTypes = (REGPINTYPES*)pDst;
147 pPin->lpMediaType = pTypes;
148 pDst += sizeof(REGPINTYPES) * pRegPin->nMediaTypes;
150 pRegPin = (const QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
151 sizeof(QUARTZ_REGPINDATA) );
153 for ( n = 0; n < pPin->nMediaTypes; n++ )
155 pRegMediaType = ((const QUARTZ_REGMEDIATYPE*)pRegPin);
156 TRACE("ofsMajor = %u, ofsMinor = %u\n", pRegMediaType->nOfsMajorType, pRegMediaType->nOfsMinorType);
157 memcpy( pDst, pData+pRegMediaType->nOfsMajorType, sizeof(GUID) );
158 pTypes->clsMajorType = (const GUID*)pDst; pDst += sizeof(GUID);
159 memcpy( pDst, pData+pRegMediaType->nOfsMinorType, sizeof(GUID) );
160 pTypes->clsMinorType = (const GUID*)pDst; pDst += sizeof(GUID);
162 pRegPin = (const QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
163 sizeof(QUARTZ_REGMEDIATYPE) );
167 /* FIXME - pPin->lpMedium */
168 /* FIXME - pPin->clsPinCategory */
177 BYTE* QUARTZ_RegFilterV2ToFilterData(
178 const REGFILTER2* pFilter, DWORD* pcbData )
183 const REGFILTERPINS2* pPin;
184 const REGPINTYPES* pTypes;
187 QUARTZ_REGFILTERDATA* pRegFilter;
188 QUARTZ_REGPINDATA* pRegPin;
189 QUARTZ_REGMEDIATYPE* pRegMediaType;
192 if ( pFilter->dwVersion != 2 ) return NULL; /* FIXME */
194 cbData = sizeof(QUARTZ_REGFILTERDATA);
195 cPins = pFilter->u.s2.cPins2;
196 pPin = pFilter->u.s2.rgPins2;
197 if ( cPins > 10 ) return NULL; /* FIXME */
200 while ( cPins-- > 0 )
202 if ( pPin->cInstances != 0 ||
203 pPin->nMediaTypes > 10 ||
204 pPin->nMediums != 0 ||
205 pPin->clsPinCategory != 0 )
207 FIXME( "not implemented.\n" );
208 return NULL; /* FIXME */
211 cbPinData += sizeof(QUARTZ_REGPINDATA) +
212 pPin->nMediaTypes * sizeof(QUARTZ_REGMEDIATYPE);
213 cbData += pPin->nMediaTypes * (sizeof(GUID)*2);
217 TRACE("cbData %lu, cbPinData %lu\n",cbData,cbPinData);
219 pRet = (BYTE*)QUARTZ_AllocMem( cbData );
220 if ( pRet == NULL ) return NULL;
221 ZeroMemory( pRet, cbData );
224 pRegFilter = (QUARTZ_REGFILTERDATA*)pDst;
225 pDst += sizeof(QUARTZ_REGFILTERDATA);
227 pRegFilter->dwVersion = 2;
228 pRegFilter->dwMerit = pFilter->dwMerit;
229 pRegFilter->cPins = pFilter->u.s2.cPins2;
231 pRegPin = (QUARTZ_REGPINDATA*)pDst;
234 pPin = pFilter->u.s2.rgPins2;
235 for ( cPins = 0; cPins < pFilter->u.s2.cPins2; cPins++ )
237 pRegPin->id[0] = '0'+cPins;
238 pRegPin->id[1] = 'p';
239 pRegPin->id[2] = 'i';
240 pRegPin->id[3] = '3';
241 pRegPin->dwFlags = pPin->dwFlags; /* flags */
242 pRegPin->cInstances = pPin->cInstances;
243 pRegPin->nMediaTypes = pPin->nMediaTypes;
244 pRegPin->nMediums = pPin->nMediums;
245 pRegPin->nOfsClsPinCategory = 0; /* FIXME */
247 pTypes = pPin->lpMediaType;
248 pRegPin = (QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
249 sizeof(QUARTZ_REGPINDATA) );
250 for ( n = 0; n < pPin->nMediaTypes; n++ )
252 pRegMediaType = ((QUARTZ_REGMEDIATYPE*)pRegPin);
254 pRegMediaType->id[0] = '0'+n;
255 pRegMediaType->id[1] = 't';
256 pRegMediaType->id[2] = 'y';
257 pRegMediaType->id[3] = '3';
259 /* FIXME - CLSID should be shared. */
260 pRegMediaType->nOfsMajorType = pDst - pRet;
261 memcpy( pDst, pTypes->clsMajorType, sizeof(GUID) );
262 pDst += sizeof(GUID);
263 pRegMediaType->nOfsMinorType = pDst - pRet;
264 memcpy( pDst, pTypes->clsMinorType, sizeof(GUID) );
265 pDst += sizeof(GUID);
267 pRegPin = (QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) +
268 sizeof(QUARTZ_REGMEDIATYPE) );
274 *pcbData = pDst - pRet;
275 TRACE("cbData %lu/%lu\n",*pcbData,cbData);
281 REGFILTER2* QUARTZ_RegFilterV1ToV2( const REGFILTER2* prfV1 )
284 const REGFILTERPINS* pPinV1;
285 REGFILTERPINS2* pPinV2;
288 if ( prfV1->dwVersion != 1 ) return NULL;
290 prfV2 = (REGFILTER2*)QUARTZ_AllocMem(
291 sizeof(REGFILTER2) + sizeof(REGFILTERPINS2) * prfV1->u.s1.cPins );
292 if ( prfV2 == NULL ) return NULL;
293 ZeroMemory( prfV2, sizeof(REGFILTER2) + sizeof(REGFILTERPINS2) * prfV1->u.s1.cPins );
294 pPinV1 = prfV1->u.s1.rgPins;
295 pPinV2 = (REGFILTERPINS2*)(prfV2+1);
296 prfV2->dwVersion = 2;
297 prfV2->dwMerit = prfV1->dwMerit;
298 prfV2->u.s2.cPins2 = prfV1->u.s1.cPins;
299 prfV2->u.s2.rgPins2 = pPinV2;
301 cPins = prfV1->u.s1.cPins;
302 while ( cPins-- > 0 )
305 pPinV2->cInstances = 0;
306 pPinV2->nMediaTypes = pPinV1->nMediaTypes;
307 pPinV2->lpMediaType = pPinV1->lpMediaType;
308 pPinV2->nMediums = 0;
309 pPinV2->lpMedium = NULL;
310 pPinV2->clsPinCategory = NULL;
312 if ( pPinV1->bRendered )
313 pPinV2->dwFlags |= REG_PINFLAG_B_RENDERER;
314 if ( pPinV1->bOutput )
315 pPinV2->dwFlags |= REG_PINFLAG_B_OUTPUT;
317 pPinV2->dwFlags |= REG_PINFLAG_B_ZERO;
319 pPinV2->dwFlags |= REG_PINFLAG_B_MANY;
329 BYTE* QUARTZ_RegFilterToFilterData(
330 const REGFILTER2* pFilter, DWORD* pcbData )
336 switch ( pFilter->dwVersion )
339 prfV2 = QUARTZ_RegFilterV1ToV2( pFilter );
342 pRet = QUARTZ_RegFilterV2ToFilterData( prfV2, pcbData );
343 QUARTZ_FreeMem( prfV2 );
347 pRet = QUARTZ_RegFilterV2ToFilterData( pFilter, pcbData );
350 FIXME( "unknown REGFILTER2 version - %08lu\n", pFilter->dwVersion );
357 /***************************************************************************/
360 BOOL QUARTZ_CheckPinType( BOOL bExactMatch, const REGFILTERPINS2* pPin, DWORD cTypes, const GUID* pTypes, const REGPINMEDIUM* pMedium, const CLSID* pCategory, BOOL bRender )
365 if ( cTypes > 0 && pTypes != NULL )
368 for ( n1 = 0; n1 < pPin->nMediaTypes; n1++ )
370 for ( n2 = 0; n2 < cTypes; n2++ )
372 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)) )
374 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)) )
386 if ( pMedium != NULL )
389 for ( n1 = 0; n1 < pPin->nMediums; n1++ )
391 if ( IsEqualGUID( &pPin->lpMedium[n1].clsMedium, &pMedium->clsMedium ) && pPin->lpMedium[n1].dw1 == pMedium->dw1 && pPin->lpMedium[n1].dw2 == pMedium->dw2 )
401 if ( pCategory != NULL )
403 if ( pPin->clsPinCategory == NULL )
405 if ( (!bExactMatch && IsEqualGUID(pCategory,&GUID_NULL)) || IsEqualGUID(pCategory,pPin->clsPinCategory) )
410 if ( bRender && (!(pPin->dwFlags & REG_PINFLAG_B_RENDERER)) )
419 /***************************************************************************
421 * new/delete for CLSID_FilterMapper
425 /* can I use offsetof safely? - FIXME? */
426 static QUARTZ_IFEntry FMapIFEntries[] =
428 { &IID_IFilterMapper, offsetof(CFilterMapper,fmap)-offsetof(CFilterMapper,unk) },
432 static void QUARTZ_DestroyFilterMapper(IUnknown* punk)
434 CFilterMapper_THIS(punk,unk);
436 CFilterMapper_UninitIFilterMapper( This );
439 HRESULT QUARTZ_CreateFilterMapper(IUnknown* punkOuter,void** ppobj)
444 TRACE("(%p,%p)\n",punkOuter,ppobj);
446 pfm = (CFilterMapper*)QUARTZ_AllocObj( sizeof(CFilterMapper) );
448 return E_OUTOFMEMORY;
450 QUARTZ_IUnkInit( &pfm->unk, punkOuter );
451 hr = CFilterMapper_InitIFilterMapper( pfm );
454 QUARTZ_FreeObj( pfm );
458 pfm->unk.pEntries = FMapIFEntries;
459 pfm->unk.dwEntries = sizeof(FMapIFEntries)/sizeof(FMapIFEntries[0]);
460 pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper;
462 *ppobj = (void*)(&pfm->unk);
467 /***************************************************************************
469 * CLSID_FilterMapper::IFilterMapper
473 static HRESULT WINAPI
474 IFilterMapper_fnQueryInterface(IFilterMapper* iface,REFIID riid,void** ppobj)
476 CFilterMapper_THIS(iface,fmap);
478 TRACE("(%p)->()\n",This);
480 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
484 IFilterMapper_fnAddRef(IFilterMapper* iface)
486 CFilterMapper_THIS(iface,fmap);
488 TRACE("(%p)->()\n",This);
490 return IUnknown_AddRef(This->unk.punkControl);
494 IFilterMapper_fnRelease(IFilterMapper* iface)
496 CFilterMapper_THIS(iface,fmap);
498 TRACE("(%p)->()\n",This);
500 return IUnknown_Release(This->unk.punkControl);
504 static HRESULT WINAPI
505 IFilterMapper_fnRegisterFilter(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,DWORD dwMerit)
507 CFilterMapper_THIS(iface,fmap);
509 FIXME("(%p)->(%s,%s,%08lx)\n",This,
510 debugstr_guid(&clsid),debugstr_w(lpwszName),dwMerit);
513 /* FIXME - handle dwMerit! */
514 return QUARTZ_RegisterAMovieFilter(
515 &CLSID_LegacyAmFilterCategory,
518 lpwszName, NULL, TRUE );
521 static HRESULT WINAPI
522 IFilterMapper_fnRegisterFilterInstance(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,CLSID* pclsidMedia)
524 CFilterMapper_THIS(iface,fmap);
527 FIXME("(%p)->()\n",This);
529 if ( pclsidMedia == NULL )
531 hr = CoCreateGuid(pclsidMedia);
536 /* this doesn't work. */
537 /* return IFilterMapper_RegisterFilter(iface,
538 *pclsidMedia,lpwszName,0x60000000); */
543 static HRESULT WINAPI
544 IFilterMapper_fnRegisterPin(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR lpwszName,BOOL bRendered,BOOL bOutput,BOOL bZero,BOOL bMany,CLSID clsidReserved,LPCWSTR lpwszReserved)
546 CFilterMapper_THIS(iface,fmap);
548 FIXME("(%p)->() stub!\n",This);
553 static HRESULT WINAPI
554 IFilterMapper_fnRegisterPinType(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR lpwszName,CLSID clsidMajorType,CLSID clsidSubType)
556 CFilterMapper_THIS(iface,fmap);
558 FIXME("(%p)->() stub!\n",This);
563 static HRESULT WINAPI
564 IFilterMapper_fnUnregisterFilter(IFilterMapper* iface,CLSID clsidFilter)
566 CFilterMapper_THIS(iface,fmap);
568 FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidFilter));
571 return QUARTZ_RegisterAMovieFilter(
572 &CLSID_LegacyAmFilterCategory,
574 NULL, 0, NULL, NULL, FALSE );
577 static HRESULT WINAPI
578 IFilterMapper_fnUnregisterFilterInstance(IFilterMapper* iface,CLSID clsidMedia)
580 CFilterMapper_THIS(iface,fmap);
582 FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidMedia));
585 /* this doesn't work. */
586 /* return IFilterMapper_UnregisterFilter(iface,clsidMedia); */
591 static HRESULT WINAPI
592 IFilterMapper_fnUnregisterPin(IFilterMapper* iface,CLSID clsidPin,LPCWSTR lpwszName)
594 CFilterMapper_THIS(iface,fmap);
596 FIXME("(%p)->(%s,%s) stub!\n",This,
597 debugstr_guid(&clsidPin),debugstr_w(lpwszName));
602 static HRESULT WINAPI
603 IFilterMapper_fnEnumMatchingFilters(IFilterMapper* iface,IEnumRegFilters** ppobj,DWORD dwMerit,BOOL bInputNeeded,CLSID clsInMajorType,CLSID clsidSubType,BOOL bRender,BOOL bOutputNeeded,CLSID clsOutMajorType,CLSID clsOutSubType)
605 CFilterMapper_THIS(iface,fmap);
607 FIXME("(%p)->() stub!\n",This);
614 static ICOM_VTABLE(IFilterMapper) ifmap =
616 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
617 /* IUnknown fields */
618 IFilterMapper_fnQueryInterface,
619 IFilterMapper_fnAddRef,
620 IFilterMapper_fnRelease,
621 /* IFilterMapper fields */
622 IFilterMapper_fnRegisterFilter,
623 IFilterMapper_fnRegisterFilterInstance,
624 IFilterMapper_fnRegisterPin,
625 IFilterMapper_fnRegisterPinType,
626 IFilterMapper_fnUnregisterFilter,
627 IFilterMapper_fnUnregisterFilterInstance,
628 IFilterMapper_fnUnregisterPin,
629 IFilterMapper_fnEnumMatchingFilters,
633 HRESULT CFilterMapper_InitIFilterMapper( CFilterMapper* pfm )
636 ICOM_VTBL(&pfm->fmap) = &ifmap;
641 void CFilterMapper_UninitIFilterMapper( CFilterMapper* pfm )
647 /***************************************************************************
649 * new/delete for CLSID_FilterMapper2
653 /* can I use offsetof safely? - FIXME? */
654 static QUARTZ_IFEntry FMap2IFEntries[] =
656 { &IID_IFilterMapper2, offsetof(CFilterMapper2,fmap3)-offsetof(CFilterMapper2,unk) },
657 { &IID_IFilterMapper3, offsetof(CFilterMapper2,fmap3)-offsetof(CFilterMapper2,unk) },
661 static void QUARTZ_DestroyFilterMapper2(IUnknown* punk)
663 CFilterMapper2_THIS(punk,unk);
665 CFilterMapper2_UninitIFilterMapper3( This );
668 HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj)
673 TRACE("(%p,%p)\n",punkOuter,ppobj);
675 pfm = (CFilterMapper2*)QUARTZ_AllocObj( sizeof(CFilterMapper2) );
677 return E_OUTOFMEMORY;
679 QUARTZ_IUnkInit( &pfm->unk, punkOuter );
680 hr = CFilterMapper2_InitIFilterMapper3( pfm );
683 QUARTZ_FreeObj( pfm );
687 pfm->unk.pEntries = FMap2IFEntries;
688 pfm->unk.dwEntries = sizeof(FMap2IFEntries)/sizeof(FMap2IFEntries[0]);
689 pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper2;
691 *ppobj = (void*)(&pfm->unk);
696 /***************************************************************************
698 * CLSID_FilterMapper2::IFilterMapper3
703 static HRESULT WINAPI
704 IFilterMapper3_fnQueryInterface(IFilterMapper3* iface,REFIID riid,void** ppobj)
706 CFilterMapper2_THIS(iface,fmap3);
708 TRACE("(%p)->()\n",This);
710 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
714 IFilterMapper3_fnAddRef(IFilterMapper3* iface)
716 CFilterMapper2_THIS(iface,fmap3);
718 TRACE("(%p)->()\n",This);
720 return IUnknown_AddRef(This->unk.punkControl);
724 IFilterMapper3_fnRelease(IFilterMapper3* iface)
726 CFilterMapper2_THIS(iface,fmap3);
728 TRACE("(%p)->()\n",This);
730 return IUnknown_Release(This->unk.punkControl);
733 static HRESULT WINAPI
734 IFilterMapper3_fnCreateCategory(IFilterMapper3* iface,REFCLSID rclsidCategory,DWORD dwMerit,LPCWSTR lpwszDesc)
736 CFilterMapper2_THIS(iface,fmap3);
738 FIXME("(%p)->(%s,%lu,%s) stub!\n",This,
739 debugstr_guid(rclsidCategory),
740 (unsigned long)dwMerit,debugstr_w(lpwszDesc));
746 static HRESULT WINAPI
747 IFilterMapper3_fnUnregisterFilter(IFilterMapper3* iface,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,REFCLSID rclsidFilter)
749 CFilterMapper2_THIS(iface,fmap3);
750 WCHAR* pwszPath = NULL;
753 TRACE("(%p)->(%s,%s,%s)\n",This,
754 debugstr_guid(pclsidCategory),
755 debugstr_w(lpwszInst),
756 debugstr_guid(rclsidFilter));
758 if ( pclsidCategory == NULL )
759 pclsidCategory = &CLSID_LegacyAmFilterCategory;
761 hr = QUARTZ_GetFilterRegPath(
762 &pwszPath, pclsidCategory, rclsidFilter, lpwszInst );
766 hr = QUARTZ_RegDeleteKey(HKEY_CLASSES_ROOT,pwszPath);
767 QUARTZ_FreeMem(pwszPath);
773 static HRESULT WINAPI
774 IFilterMapper3_fnRegisterFilter(IFilterMapper3* iface,REFCLSID rclsidFilter,LPCWSTR lpName,IMoniker** ppMoniker,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,const REGFILTER2* pRF2)
776 CFilterMapper2_THIS(iface,fmap3);
777 WCHAR* pwszPath = NULL;
778 IMoniker* pMoniker = NULL;
779 BYTE* pFilterData = NULL;
780 DWORD cbFilterData = 0;
783 TRACE( "(%p)->(%s,%s,%p,%s,%s,%p) stub!\n",This,
784 debugstr_guid(rclsidFilter),debugstr_w(lpName),
785 ppMoniker,debugstr_guid(pclsidCategory),
786 debugstr_w(lpwszInst),pRF2 );
788 if ( lpName == NULL || pRF2 == NULL )
791 if ( ppMoniker != NULL && *ppMoniker != NULL )
793 FIXME( "ppMoniker != NULL - not implemented! *ppMoniker = %p\n",*ppMoniker );
797 if ( pclsidCategory == NULL )
798 pclsidCategory = &CLSID_LegacyAmFilterCategory;
800 if ( pMoniker == NULL )
802 hr = QUARTZ_GetFilterRegPath(
803 &pwszPath, pclsidCategory, rclsidFilter, lpwszInst );
806 hr = QUARTZ_CreateDeviceMoniker(
807 HKEY_CLASSES_ROOT,pwszPath,&pMoniker);
808 QUARTZ_FreeMem(pwszPath);
813 pFilterData = QUARTZ_RegFilterToFilterData( pRF2, &cbFilterData );
814 if ( pFilterData == NULL || cbFilterData == 0 )
820 hr = QUARTZ_RegisterFilterToMoniker(
821 pMoniker, rclsidFilter, lpName, pFilterData, cbFilterData );
825 if ( ppMoniker != NULL )
827 *ppMoniker = pMoniker;
831 if ( pFilterData != NULL )
832 QUARTZ_FreeMem(pFilterData);
833 if ( pMoniker != NULL )
834 IMoniker_Release(pMoniker);
840 static HRESULT WINAPI
841 IFilterMapper3_fnEnumMatchingFilters(IFilterMapper3* iface,
842 IEnumMoniker** ppEnumMoniker,DWORD dwFlags,BOOL bExactMatch,DWORD dwMerit,
843 BOOL bInputNeeded,DWORD cInputTypes,const GUID* pguidInputTypes,const REGPINMEDIUM* pPinMediumIn,const CLSID* pPinCategoryIn,BOOL bRender,
844 BOOL bOutputNeeded,DWORD cOutputTypes,const GUID* pguidOutputTypes,const REGPINMEDIUM* pPinMediumOut,const CLSID* pPinCategoryOut)
846 CFilterMapper2_THIS(iface,fmap3);
847 ICreateDevEnum* pEnum = NULL;
848 IEnumMoniker* pCategories = NULL;
849 IMoniker* pCat = NULL;
851 IEnumMoniker* pCatFilters = NULL;
852 IMoniker* pFilter = NULL;
855 BYTE* pbFilterData = NULL;
856 DWORD cbFilterData = 0;
857 REGFILTER2* prf2 = NULL;
858 QUARTZ_CompList* pList = NULL;
859 const REGFILTERPINS2* pRegFilterPin;
864 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);
866 if ( ppEnumMoniker == NULL )
868 *ppEnumMoniker = NULL;
872 hr = CoCreateInstance(
873 &CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
874 &IID_ICreateDevEnum, (void**)&pEnum );
878 hr = ICreateDevEnum_CreateClassEnumerator(pEnum,&CLSID_ActiveMovieCategories,&pCategories,0);
886 IMoniker_Release(pCat);
889 hr = IEnumMoniker_Next(pCategories,1,&pCat,&cReturned);
894 hr = QUARTZ_GetMeritFromMoniker(pCat,&dwCatMerit);
895 if ( hr != S_OK || dwMerit > dwCatMerit )
897 hr = QUARTZ_GetCLSIDFromMoniker(pCat,&clsid);
901 if ( pCatFilters != NULL )
903 IEnumMoniker_Release(pCatFilters);
906 hr = ICreateDevEnum_CreateClassEnumerator(pEnum,&clsid,&pCatFilters,0);
914 if ( pFilter != NULL )
916 IMoniker_Release(pFilter);
919 hr = IEnumMoniker_Next(pCatFilters,1,&pFilter,&cReturned);
924 if ( pbFilterData != NULL )
926 QUARTZ_FreeMem(pbFilterData);
929 hr = QUARTZ_GetFilterDataFromMoniker(pFilter,&pbFilterData,&cbFilterData);
935 QUARTZ_FreeMem(prf2);
938 prf2 = QUARTZ_RegFilterV2FromFilterData(pbFilterData,cbFilterData);
941 TRACE("prf2 %p, Merit %lu\n",prf2,prf2->dwMerit);
942 if ( prf2->dwMerit < dwMerit || prf2->dwVersion != 2 )
945 /* check input pins. */
949 for ( n = 0; n < prf2->u.s2.cPins2; n++ )
951 pRegFilterPin = &prf2->u.s2.rgPins2[n];
952 if ( pRegFilterPin->dwFlags & REG_PINFLAG_B_OUTPUT )
954 bMatch = QUARTZ_CheckPinType( bExactMatch, pRegFilterPin, cInputTypes, pguidInputTypes, pPinMediumIn, pPinCategoryIn, bRender );
962 /* check output pins. */
966 for ( n = 0; n < prf2->u.s2.cPins2; n++ )
968 pRegFilterPin = &prf2->u.s2.rgPins2[n];
969 if ( !(pRegFilterPin->dwFlags & REG_PINFLAG_B_OUTPUT) )
971 bMatch = QUARTZ_CheckPinType( bExactMatch, pRegFilterPin, cOutputTypes, pguidOutputTypes, pPinMediumOut, pPinCategoryOut, FALSE );
979 /* matched - add pFilter to the list. */
982 pList = QUARTZ_CompList_Alloc();
989 hr = QUARTZ_CompList_AddComp(
990 pList, (IUnknown*)pFilter, NULL, 0 );
1002 FIXME("create IEnumMoniker - not sorted\n");
1003 /* FIXME - should be sorted?(in Merit order) */
1004 hr = QUARTZ_CreateEnumUnknown( &IID_IEnumMoniker, (void**)ppEnumMoniker, pList );
1010 if ( pEnum != NULL )
1011 ICreateDevEnum_Release(pEnum);
1012 if ( pCategories != NULL )
1013 IEnumMoniker_Release(pCategories);
1015 IMoniker_Release(pCat);
1016 if ( pCatFilters != NULL )
1017 IEnumMoniker_Release(pCatFilters);
1018 if ( pFilter != NULL )
1019 IMoniker_Release(pFilter);
1020 if ( pbFilterData != NULL )
1021 QUARTZ_FreeMem(pbFilterData);
1023 QUARTZ_FreeMem(prf2);
1024 if ( pList != NULL )
1025 QUARTZ_CompList_Free( pList );
1027 TRACE("returns %08lx\n",hr);
1032 static HRESULT WINAPI
1033 IFilterMapper3_fnGetICreateDevEnum(IFilterMapper3* iface,ICreateDevEnum** ppDevEnum)
1035 CFilterMapper2_THIS(iface,fmap3);
1038 FIXME("(%p)->() stub!\n",This);
1046 static ICOM_VTABLE(IFilterMapper3) ifmap3 =
1048 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1049 /* IUnknown fields */
1050 IFilterMapper3_fnQueryInterface,
1051 IFilterMapper3_fnAddRef,
1052 IFilterMapper3_fnRelease,
1053 /* IFilterMapper2 fields */
1054 IFilterMapper3_fnCreateCategory,
1055 IFilterMapper3_fnUnregisterFilter,
1056 IFilterMapper3_fnRegisterFilter,
1057 IFilterMapper3_fnEnumMatchingFilters,
1058 /* IFilterMapper3 fields */
1059 IFilterMapper3_fnGetICreateDevEnum,
1063 HRESULT CFilterMapper2_InitIFilterMapper3( CFilterMapper2* pfm )
1065 TRACE("(%p)\n",pfm);
1066 ICOM_VTBL(&pfm->fmap3) = &ifmap3;
1071 void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* pfm )
1073 TRACE("(%p)\n",pfm);