source: trunk/DirectShowSpy/FilterMapperSpy.h @ 196

Last change on this file since 196 was 196, checked in by roman, 9 years ago

Cosmetic fixes, new .BAT names, UnregisterTreatAsClasses? export to force removal of TreatAs? keys

  • Property svn:keywords set to Id
File size: 13.6 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2011
3// Created by Roman Ryltsov roman@alax.info
4
5#pragma once
6
7#include "rodshow.h"
8#include <..\Samples\multimedia\directshow\misc\mapper\fil_data.h>
9#include "DirectShowSpy_i.h"
10#include "Common.h"
11
12////////////////////////////////////////////////////////////
13// CFilterMapperSpyT
14
15template <typename T, const CLSID* t_pFilterMapperClassIdentifier>
16class ATL_NO_VTABLE CFilterMapperSpyT :
17        public CComObjectRootEx<CComMultiThreadModel>,
18        //public CComCoClass<CFilterMapperSpyT, &CLSID_FilterMapperSpy>,
19        public CTransparentCoClassT<T, t_pFilterMapperClassIdentifier>,
20        public IDispatchImpl<IFilterMapperSpy>,
21        public IAMFilterData,
22        public IFilterMapper2
23{
24        typedef CFilterMapperSpyT<T, t_pFilterMapperClassIdentifier> CFilterMapperSpy;
25
26public:
27        //enum { IDR = IDR_FILTERMAPPERSPY };
28
29//DECLARE_REGISTRY_RESOURCEID(IDR)
30
31DECLARE_PROTECT_FINAL_CONSTRUCT()
32
33DECLARE_GET_CONTROLLING_UNKNOWN()
34
35DECLARE_QI_TRACE(CFilterMapperSpy)
36
37BEGIN_COM_MAP(CFilterMapperSpy)
38        COM_INTERFACE_ENTRY(IFilterMapperSpy)
39        COM_INTERFACE_ENTRY(IAMFilterData)
40        COM_INTERFACE_ENTRY(IFilterMapper2)
41        COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_pInnerUnknown)
42        //COM_INTERFACE_ENTRY(IDispatch)
43END_COM_MAP()
44
45private:
46        BOOL m_bIsAggregated;
47        HINSTANCE m_hQuartzModule;
48        CComPtr<IUnknown> m_pInnerUnknown;
49        CComPtr<IFilterMapper2> m_pFilterMapper2;
50        CComPtr<IAMFilterData> m_pAmFilterData;
51
52        static VOID Trace(const REGFILTER2* pFilterInformation)
53        {
54                _A(pFilterInformation);
55                _Z4(atlTraceCOM, 4, _T("pFilterInformation { dwVersion %d, dwMerit 0x%08x, cPins2 %d }\n"), pFilterInformation->dwVersion, pFilterInformation->dwMerit, pFilterInformation->cPins2);
56                if(pFilterInformation->dwVersion == 2)
57                        for(ULONG nPinIndex = 0; nPinIndex < pFilterInformation->cPins2; nPinIndex++)
58                        {
59                                const REGFILTERPINS2& Pin = pFilterInformation->rgPins2[nPinIndex];
60                                _Z4(atlTraceCOM, 4, _T("pFilterInformation->rgPins2[%d] { dwFlags 0x%x, cInstances %d, nMediaTypes %d, nMediums %d }\n"), nPinIndex, Pin.dwFlags, Pin.cInstances, Pin.nMediaTypes, Pin.nMediums, Pin.clsPinCategory ? (LPCWSTR) _PersistHelper::StringFromIdentifier(*Pin.clsPinCategory) : L"NULL");
61                                for(UINT nIndex = 0; nIndex < Pin.nMediaTypes; nIndex++)
62                                {
63                                        const REGPINTYPES& Type = Pin.lpMediaType[nIndex];
64                                        _Z4(atlTraceCOM, 4, _T("pFilterInformation->rgPins2[...].lpMediaType[%d] { clsMajorType %ls, clsMinorType %ls }\n"), nIndex, Type.clsMajorType ? (LPCWSTR) _PersistHelper::StringFromIdentifier(*Type.clsMajorType) : L"NULL", Type.clsMinorType ? (LPCWSTR) _PersistHelper::StringFromIdentifier(*Type.clsMinorType) : L"NULL");
65                                }
66                                for(UINT nIndex = 0; nIndex < Pin.nMediums; nIndex++)
67                                {
68                                        const REGPINMEDIUM& Medium = Pin.lpMedium[nIndex];
69                                        _Z4(atlTraceCOM, 4, _T("pFilterInformation->rgPins2[...].lpMedium[%d] { clsMedium %ls, dw1 0x%x, dw2 0x%x }\n"), nIndex, _PersistHelper::StringFromIdentifier(Medium.clsMedium), Medium.dw1, Medium.dw2);
70                                }
71                        }
72        }
73        BOOL IsAggregated() const throw()
74        {
75                return (ULONG) m_dwRef >= 0x00001000;
76        }
77
78public:
79// CFilterMapperSpyT
80        static LPCTSTR GetOriginalLibraryName() throw()
81        {
82                return _T("quartz.dll");
83        }
84        static CString GetObjectFriendlyName()
85        {
86                return _StringHelper::GetLine(T::IDR, 2);
87        }
88        static HRESULT WINAPI UpdateRegistry(BOOL bRegister) throw()
89        {
90                _Z2(atlTraceRegistrar, 2, _T("bRegister %d\n"), bRegister);
91                _ATLTRY
92                {
93                        TreatAsUpdateRegistryFromResource<T>(*t_pFilterMapperClassIdentifier, bRegister);
94                }
95                _ATLCATCH(Exception)
96                {
97                        _C(Exception);
98                }
99                return S_OK;
100        }
101        CFilterMapperSpyT() throw() :
102                m_hQuartzModule(NULL)
103        {
104                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
105        }
106        ~CFilterMapperSpyT() throw()
107        {
108                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
109        }
110        HRESULT FinalConstruct() throw()
111        {
112                _ATLTRY
113                {
114                        m_bIsAggregated = IsAggregated();
115                        TCHAR pszPath[MAX_PATH] = { 0 };
116                        _W(GetModuleFileName(NULL, pszPath, DIM(pszPath)));
117                        _Z4(atlTraceRefcount, 4, _T("pszPath \"%s\", this 0x%08x, m_dwRef %d, m_bIsAggregated %d\n"), pszPath, this, m_dwRef, m_bIsAggregated);
118                        const HINSTANCE hModule = CoLoadLibrary(const_cast<LPOLESTR>((LPCOLESTR) CT2COLE(GetOriginalLibraryName())), TRUE);
119                        _ATLTRY
120                        {
121                                typedef HRESULT (WINAPI *DLLGETCLASSOBJECT)(REFCLSID, REFIID, VOID**);
122                                DLLGETCLASSOBJECT DllGetClassObject = (DLLGETCLASSOBJECT) GetProcAddress(hModule, "DllGetClassObject");
123                                __E(DllGetClassObject);
124                                CComPtr<IClassFactory> pClassFactory;
125                                __C(DllGetClassObject(*t_pFilterMapperClassIdentifier, __uuidof(IClassFactory), (VOID**) &pClassFactory));
126                                _A(pClassFactory);
127                                const CComPtr<IUnknown> pControllingUnknown = GetControllingUnknown();
128                                {
129                                        CComPtr<IUnknown> pUnknown;
130                                        __C(pClassFactory->CreateInstance(pControllingUnknown, __uuidof(IUnknown), (VOID**) &pUnknown));
131                                        const CComQIPtr<IFilterMapper2> pFilterMapper2 = pUnknown;
132                                        __D(pFilterMapper2, E_NOINTERFACE);
133                                        pFilterMapper2.p->Release();
134                                        const CComQIPtr<IAMFilterData> pAmFilterData = pUnknown;
135                                        __D(pAmFilterData, E_NOINTERFACE);
136                                        pAmFilterData.p->Release();
137                                        m_pInnerUnknown = pUnknown;
138                                        m_pFilterMapper2 = pFilterMapper2;
139                                        m_pAmFilterData = pAmFilterData;
140                                }
141                        }
142                        _ATLCATCHALL()
143                        {
144                                CoFreeLibrary(hModule);
145                                _ATLRETHROW;
146                        }
147                        _A(!m_hQuartzModule);
148                        m_hQuartzModule = hModule;
149                }
150                _ATLCATCH(Exception)
151                {
152                        _C(Exception);
153                }
154                return S_OK;
155        }
156        VOID FinalRelease() throw()
157        {
158                _Z5(atlTraceRefcount, 5, _T("m_dwRef 0x%x\n"), m_dwRef);
159                CComPtr<IUnknown> pControllingUnknown = GetControllingUnknown();
160                if(m_pFilterMapper2)
161                {
162                        pControllingUnknown.p->AddRef();
163                        m_pFilterMapper2 = NULL;
164                }
165                if(m_pAmFilterData)
166                {
167                        pControllingUnknown.p->AddRef();
168                        m_pAmFilterData = NULL;
169                }
170                _ATLTRY
171                {
172                        m_pInnerUnknown = NULL;
173                }
174                _ATLCATCHALL()
175                {
176                        _Z_EXCEPTION();
177                        // NOTE: For some unidentified reason Quartz's FilterGraph may crash during final release, to smooth the effect the exception is silently caught
178                        m_pInnerUnknown.p = NULL;
179                }
180                if(m_hQuartzModule)
181                {
182                        CoFreeLibrary(m_hQuartzModule);
183                        m_hQuartzModule = NULL;
184                }
185        }
186
187// IFilterMapperSpy
188
189// IAMFilterData
190        STDMETHOD(ParseFilterData)(BYTE* pnFilterData, ULONG nFilterDataSize, BYTE** ppFilterInformation) throw()
191        {
192                _Z4(atlTraceCOM, 4, _T("nFilterDataSize %d\n"), nFilterDataSize);
193                const HRESULT nResult = m_pAmFilterData->ParseFilterData(pnFilterData, nFilterDataSize, ppFilterInformation);
194                if(SUCCEEDED(nResult) && ppFilterInformation && *ppFilterInformation && *((BYTE**) *ppFilterInformation))
195                        _ATLTRY
196                        {
197                                Trace((REGFILTER2*) *((BYTE**) *ppFilterInformation));
198                        }
199                        _ATLCATCHALL()
200                        {
201                                _Z_EXCEPTION();
202                        }
203                return nResult;
204        }
205        STDMETHOD(CreateFilterData)(REGFILTER2* pFilterInformation, BYTE** ppnFilterData, ULONG* pnFilterDataSize) throw()
206        {
207                _Z4(atlTraceCOM, 4, _T("...\n"));
208                if(pFilterInformation)
209                        _ATLTRY
210                        {
211                                Trace(pFilterInformation);
212                        }
213                        _ATLCATCHALL()
214                        {
215                                _Z_EXCEPTION();
216                        }
217                return m_pAmFilterData->CreateFilterData(pFilterInformation, ppnFilterData, pnFilterDataSize);
218        }
219
220// IFilterMapper2
221        STDMETHOD(CreateCategory)(REFCLSID CategoryIdentifier, DWORD nMerit, LPCWSTR pszDescription) throw()
222        {
223                _Z4(atlTraceCOM, 4, _T("CategoryIdentifier %ls, nMerit 0x%08x, pszDescription \"%s\"\n"), _PersistHelper::StringFromIdentifier(CategoryIdentifier), nMerit, CString(pszDescription));
224                return m_pFilterMapper2->CreateCategory(CategoryIdentifier, nMerit, pszDescription);
225        }
226        STDMETHOD(UnregisterFilter)(const CLSID* pCategoryIdentifier, LPCOLESTR pszInstance, REFCLSID FilterClassIdentifier) throw()
227        {
228                _Z4(atlTraceCOM, 4, _T("pCategoryIdentifier %ls, pszInstance %s, FilterClassIdentifier %ls\n"), pCategoryIdentifier ? (LPCWSTR) _PersistHelper::StringFromIdentifier(*pCategoryIdentifier) : L"NULL", pszInstance ? (LPCTSTR) AtlFormatString(_T("\"%s\""), CString(pszInstance)) : _T("NULL"), _PersistHelper::StringFromIdentifier(FilterClassIdentifier));
229                return m_pFilterMapper2->UnregisterFilter(pCategoryIdentifier, pszInstance, FilterClassIdentifier);
230        }
231        STDMETHOD(RegisterFilter)(REFCLSID FilterClassIdentifier, LPCWSTR pszName, IMoniker** ppMoniker, const CLSID* pCategoryIdentifier, LPCOLESTR pszInstance, const REGFILTER2* pFilterInformation) throw()
232        {
233                _Z4(atlTraceCOM, 4, _T("FilterClassIdentifier %ls, pszName \"%s\", pCategoryIdentifier %ls, pszInstance %s\n"), _PersistHelper::StringFromIdentifier(FilterClassIdentifier), CString(pszName), pCategoryIdentifier ? (LPCWSTR) _PersistHelper::StringFromIdentifier(*pCategoryIdentifier) : L"NULL", pszInstance ? (LPCTSTR) AtlFormatString(_T("\"%s\""), CString(pszInstance)) : _T("NULL"));
234                if(pFilterInformation)
235                        _ATLTRY
236                        {
237                                Trace(pFilterInformation);
238                        }
239                        _ATLCATCHALL()
240                        {
241                                _Z_EXCEPTION();
242                        }
243                return m_pFilterMapper2->RegisterFilter(FilterClassIdentifier, pszName, ppMoniker, pCategoryIdentifier, pszInstance, pFilterInformation);
244        }
245        STDMETHOD(EnumMatchingFilters)(IEnumMoniker** ppEnumMoniker, DWORD nFlags, BOOL bExactMatch, DWORD nMinimalMerit, BOOL bInputNeeded, DWORD nInputTypeCount, const GUID* pInputTypes, const REGPINMEDIUM* pInputMedium, const CLSID* pInputPinCategory, BOOL bRender, BOOL bOutputNeeded, DWORD nOutputTypeCount, const GUID* pOutputTypes, const REGPINMEDIUM* pOutputMedium, const CLSID* pOutputPinCategory) throw()
246        {
247                _Z4(atlTraceCOM, 4, _T("nFlags 0x%x, bExactMatch %d, nMinimalMerit 0x%08x, bInputNeeded %d, nInputTypeCount %d, pInputPinCategory %ls, bRender %d, bOutputNeeded %d, nOutputTypeCount %d, pOutputPinCategory %ls\n"), nFlags, bExactMatch, nMinimalMerit, bInputNeeded, nInputTypeCount, pInputPinCategory ? (LPCWSTR) _PersistHelper::StringFromIdentifier(*pInputPinCategory) : L"NULL", bRender, bOutputNeeded, nOutputTypeCount, pOutputPinCategory ? (LPCWSTR) _PersistHelper::StringFromIdentifier(*pOutputPinCategory) : L"NULL");
248                for(DWORD nInputTypeIndex = 0; nInputTypeIndex < nInputTypeCount; nInputTypeIndex++)
249                {
250                        const GUID& MajorType = pInputTypes[2 * nInputTypeIndex + 0];
251                        const GUID& Subtype = pInputTypes[2 * nInputTypeIndex + 1];
252                        _Z4(atlTraceCOM, 4, _T("nInputTypeIndex %d, MajorType %ls, Subtype %ls\n"), nInputTypeIndex, _PersistHelper::StringFromIdentifier(MajorType), _PersistHelper::StringFromIdentifier(Subtype));
253                }
254                if(pInputMedium)
255                        _Z4(atlTraceCOM, 4, _T("pInputMedium { clsMedium %ls, dw1 0x%x, dw2 0x%x }\n"), _PersistHelper::StringFromIdentifier(pInputMedium->clsMedium), pInputMedium->dw1, pInputMedium->dw2);
256                for(DWORD nOutputTypeIndex = 0; nOutputTypeIndex < nOutputTypeCount; nOutputTypeIndex++)
257                {
258                        const GUID& MajorType = pOutputTypes[2 * nOutputTypeIndex + 0];
259                        const GUID& Subtype = pOutputTypes[2 * nOutputTypeIndex + 1];
260                        _Z4(atlTraceCOM, 4, _T("nOutputTypeIndex %d, MajorType %ls, Subtype %ls\n"), nOutputTypeIndex, _PersistHelper::StringFromIdentifier(MajorType), _PersistHelper::StringFromIdentifier(Subtype));
261                }
262                if(pOutputMedium)
263                        _Z4(atlTraceCOM, 4, _T("pOutputMedium { clsMedium %ls, dw1 0x%x, dw2 0x%x }\n"), _PersistHelper::StringFromIdentifier(pOutputMedium->clsMedium), pOutputMedium->dw1, pOutputMedium->dw2);
264                const HRESULT nResult = m_pFilterMapper2->EnumMatchingFilters(ppEnumMoniker, nFlags, bExactMatch, nMinimalMerit, bInputNeeded, nInputTypeCount, pInputTypes, pInputMedium, pInputPinCategory, bRender, bOutputNeeded, nOutputTypeCount, pOutputTypes, pOutputMedium, pOutputPinCategory);
265                if(SUCCEEDED(nResult))
266                        _ATLTRY
267                        {
268                                const CComPtr<IEnumMoniker>& pEnumMoniker = reinterpret_cast<const CComPtr<IEnumMoniker>&>(*ppEnumMoniker);
269                                __C(pEnumMoniker->Reset());
270                                CComPtr<IMoniker> pMoniker;
271                                while(pEnumMoniker->Next(1, &pMoniker, NULL) == S_OK)
272                                {
273                                        _Z4(atlTraceCOM, 4, _T("pMoniker %ls\n"), _FilterGraphHelper::GetMonikerDisplayName(pMoniker));
274                                        CComPtr<IBindCtx> pBindCtx;
275                                        __C(CreateBindCtx(0, &pBindCtx));
276                                        CComPtr<IPropertyBag> pPropertyBag;
277                                        __C(pMoniker->BindToStorage(pBindCtx, NULL, __uuidof(IPropertyBag), (VOID**) &pPropertyBag));
278                                        const CStringW sFriendlyName = _FilterGraphHelper::ReadPropertyBagString(pPropertyBag, OLESTR("FriendlyName"));
279                                        const CStringW sDescription = _FilterGraphHelper::ReadPropertyBagString(pPropertyBag, OLESTR("Description"));
280                                        const CStringW sDevicePath = _FilterGraphHelper::ReadPropertyBagString(pPropertyBag, OLESTR("DevicePath"));
281                                        _Z4(atlTraceCOM, 4, _T("sFriendlyName \"%ls\", sDescription \"%ls\", sDevicePath \"%ls\"\n"), sFriendlyName, sDescription, sDevicePath);
282                                        pMoniker.Release();
283                                }
284                                __C(pEnumMoniker->Reset());
285                        }
286                        _ATLCATCHALL()
287                        {
288                                _Z_EXCEPTION();
289                        }
290                return nResult;
291        }
292};
293
294////////////////////////////////////////////////////////////
295// CFilterMapperSpy
296
297class ATL_NO_VTABLE CFilterMapperSpy :
298        public CFilterMapperSpyT<CFilterMapperSpy, &CLSID_FilterMapper2>,
299        public CComCoClass<CFilterMapperSpy, &CLSID_FilterMapperSpy>
300{
301public:
302        enum { IDR = IDR_FILTERMAPPERSPY };
303
304private:
305        static LPCTSTR g_pszClassName;
306
307public:
308        //typedef CBlackListAwareComCreatorT<CComObjectCached<CFilterMapperSpy>, CFilterMapperSpy, &g_pszClassName> _ClassFactoryCreatorClass; // DECLARE_CLASSFACTORY override
309        typedef CComCreator2<CBlackListAwareComCreatorT<CComObject<CFilterMapperSpy>, CFilterMapperSpy, &g_pszClassName>, CBlackListAwareComCreatorT<CComAggObject<CFilterMapperSpy>, CFilterMapperSpy, &g_pszClassName> > _CreatorClass; // DECLARE_AGGREGATABLE override
310
311public:
312// CFilterMapperSpy
313};
314
315__declspec(selectany) LPCTSTR CFilterMapperSpy::g_pszClassName = _T("CFilterMapperSpy");
316
317OBJECT_ENTRY_AUTO(__uuidof(FilterMapperSpy), CFilterMapperSpy)
318
Note: See TracBrowser for help on using the repository browser.