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
);