source: trunk/DirectShowSpy/FilterMapperSpy.h @ 144

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