source: trunk/DirectShowSpy/FilterGraphSpy.h @ 97

Last change on this file since 97 was 97, checked in by roman, 12 years ago

Rebuilt with fixes on underlying library (primarily call stacks in Windows libraries)

  • Property svn:keywords set to Id
File size: 32.6 KB
RevLine 
[95]1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2011
3// Created by Roman Ryltsov roman@alax.info
4//
5// $Id: FilterGraphSpy.h 97 2012-08-20 14:56:08Z roman $
6
7#pragma once
8
9#include "rodshow.h"
10#include "DirectShowSpy_i.h"
11#include "Common.h"
12
13////////////////////////////////////////////////////////////
14// CSpyT
15
16LPCTSTR g_pszAddRemoveHookName = _T("Add/Remove Hooks");
17LPCTSTR g_pszConnectHookName = _T("Connect Hooks");
18LPCTSTR g_pszStateControlHookName = _T("State Control Hooks");
19
20template <typename T, const CLSID* t_pFilterGraphClassIdentifier>
21class ATL_NO_VTABLE CSpyT :
22        public CComObjectRootEx<CComMultiThreadModel>,
23        //public CComCoClass<CSpyT, &CLSID_Spy>,
24        public CTransparentCoClassT<T, t_pFilterGraphClassIdentifier>,
25        public IDispatchImpl<ISpy>,
26        public IFilterGraph2,
27        public IDispatchImpl<IMediaControl, &__uuidof(IMediaControl), &__uuidof(Quartz::__QuartzTypeLib)>,
28        public IMediaEventSink,
29        public IDispatchImpl<IMediaEventEx, &__uuidof(IMediaEventEx), &__uuidof(Quartz::__QuartzTypeLib)>,
30        public IObjectWithSite,
31        public CHookHostT<T, IFilterGraphAddRemoveHook, &g_pszAddRemoveHookName>,
32        public CHookHostT<T, IFilterGraphConnectHook, &g_pszConnectHookName>,
33        public CHookHostT<T, IFilterGraphStateControlHook, &g_pszStateControlHookName>
34{
35        typedef CSpyT<T, t_pFilterGraphClassIdentifier> CSpy;
36        typedef CHookHostT<T, IFilterGraphAddRemoveHook, &g_pszAddRemoveHookName> CFilterGraphAddRemoveHookHost;
37        typedef CHookHostT<T, IFilterGraphConnectHook, &g_pszConnectHookName> CFilterGraphConnectHookHost;
38        typedef CHookHostT<T, IFilterGraphStateControlHook, &g_pszStateControlHookName> CFilterGraphStateControlHookHost;
39
40public:
41        //enum { IDR = IDR_FILTERGRAPHSPY };
42
43//DECLARE_CLASSFACTORY(...
44
45//DECLARE_AGGREGATABLE(...
46
47//DECLARE_REGISTRY_RESOURCEID(IDR)
48
49DECLARE_PROTECT_FINAL_CONSTRUCT()
50
51DECLARE_GET_CONTROLLING_UNKNOWN()
52
53DECLARE_QI_TRACE(CSpy)
54
55BEGIN_COM_MAP(CSpy)
56        COM_INTERFACE_ENTRY(ISpy)
57        COM_INTERFACE_ENTRY_FUNC(__uuidof(IFilterGraph3), 0, QueryFilterGraph3Interface)
58        COM_INTERFACE_ENTRY(IFilterGraph2)
59        COM_INTERFACE_ENTRY(IGraphBuilder)
60        COM_INTERFACE_ENTRY(IFilterGraph)
61        COM_INTERFACE_ENTRY(IMediaControl)
62        COM_INTERFACE_ENTRY(IMediaEventSink)
63        COM_INTERFACE_ENTRY(IMediaEventEx)
64        COM_INTERFACE_ENTRY(IMediaEvent)
65        COM_INTERFACE_ENTRY_FUNC(__uuidof(IObjectWithSite), 0, QueryObjectWithSiteInterface)
66        COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_pInnerUnknown)
67        //COM_INTERFACE_ENTRY(IDispatch)
68END_COM_MAP()
69
70public:
71
72        ////////////////////////////////////////////////////////
73        // CAmGraphBuilderCallback
74
75        class ATL_NO_VTABLE CAmGraphBuilderCallback :
76                public CComObjectRootEx<CComMultiThreadModelNoCS>,
77                public IAMGraphBuilderCallback
78        {
79        public:
80
81        BEGIN_COM_MAP(CAmGraphBuilderCallback)
82                COM_INTERFACE_ENTRY(IAMGraphBuilderCallback)
83        END_COM_MAP()
84
85        private:
86                mutable CRoCriticalSection m_DataCriticalSection;
87                T* m_pSpy;
88
89                CObjectPtr<T> GetSpy() const throw()
90                {
91                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
92                        return m_pSpy;
93                }
94
95        public:
96        // CAmGraphBuilderCallback
97                CAmGraphBuilderCallback() throw() :
98                        m_pSpy(NULL)
99                {
100                        _Z5(atlTraceRefcount, 5, _T("this 0x%p\n"), this);
101                }
102                ~CAmGraphBuilderCallback() throw()
103                {
104                        _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
105                }
106                VOID Initialize(T* pSpy) throw()
107                {
108                        _A(pSpy);
109                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
110                        _Z4(atlTraceRefcount, 4, _T("this 0x%p, pSpy 0x%p\n"), this, pSpy);
111                        _A(!m_pSpy);
112                        m_pSpy = pSpy;
113                }
114                VOID Terminate() throw()
115                {
116                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
117                        m_pSpy = NULL;
118                }
119                BOOL SetGraphBuilder(const CComQIPtr<IObjectWithSite> pObjectWithSite) throw()
120                {
121                        if(!pObjectWithSite)
122                                return FALSE;
123                        const HRESULT nSetSiteResult = pObjectWithSite->SetSite(this);
124                        if(SUCCEEDED(nSetSiteResult))
125                                return TRUE;
126                        _Z4(atlTraceRefcount, 4, _T("nSetSiteResult 0x%08x\n"), nSetSiteResult);
127                        return FALSE;
128                }
129                BOOL SetGraphBuilder(IUnknown* pObjectWithSiteUnknown) throw()
130                {
131                        return SetGraphBuilder(CComQIPtr<IObjectWithSite>(pObjectWithSiteUnknown));
132                }
133
134        // IAMGraphBuilderCallback
135        STDMETHOD(SelectedFilter)(IMoniker* pMoniker) throw()
136                {
137                        _Z4(atlTraceCOM, 4, _T("this 0x%p, pMoniker %ls\n"), this, _FilterGraphHelper::GetMonikerDisplayName(pMoniker));
138                        _ATLTRY
139                        {
140                                _A(pMoniker);
141                                const CObjectPtr<T> pSpy = GetSpy();
142                                HRESULT nSelectedFilterResult;
143                                if(pSpy)
144                                        if(pSpy->SelectedFilter(pMoniker, nSelectedFilterResult))
145                                        {
146                                                _Z4(atlTraceGeneral, 4, _T("this 0x%p, nSelectedFilterResult 0x%08x\n"), this, nSelectedFilterResult);
147                                                return nSelectedFilterResult;
148                                        }
149                        }
150                        _ATLCATCH(Exception)
151                        {
152                                _C(Exception);
153                        }
154                        return S_OK;
155                }
156                STDMETHOD(CreatedFilter)(IBaseFilter* pBaseFilter) throw()
157                {
158                        _Z4(atlTraceCOM, 4, _T("this 0x%p, pBaseFilter 0x%p %ls \"%ls\"\n"), this, pBaseFilter, _FilterGraphHelper::GetFilterClassIdentifierString(pBaseFilter), _FilterGraphHelper::GetFilterName(pBaseFilter));
159                        _ATLTRY
160                        {
161                                _A(pBaseFilter);
162                                const CObjectPtr<T> pSpy = GetSpy();
163                                HRESULT nCreatedFilterResult;
164                                if(pSpy)
165                                        if(pSpy->CreatedFilter(pBaseFilter, nCreatedFilterResult))
166                                        {
167                                                _Z4(atlTraceGeneral, 4, _T("this 0x%p, nCreatedFilterResult 0x%08x\n"), this, nCreatedFilterResult);
168                                                return nCreatedFilterResult;
169                                        }
170                        }
171                        _ATLCATCH(Exception)
172                        {
173                                _C(Exception);
174                        }
175                        return S_OK;
176                }
177        };
178
179private:
180        BOOL m_bIsAggregated;
181        HINSTANCE m_hQuartzModule;
182        CComPtr<IUnknown> m_pInnerUnknown;
183        CComPtr<IFilterGraph2> m_pInnerFilterGraph2;
184        CComPtr<IFilterGraph3> m_pInnerFilterGraph3;
185        CComPtr<IMediaControl> m_pInnerMediaControl;
186        CComPtr<IMediaEventSink> m_pInnerMediaEventSink;
187        CComPtr<IMediaEventEx> m_pInnerMediaEventEx;
188        _FilterGraphHelper::CRotRunningFilterGraph m_RunningFilterGraph;
189        CComPtr<IUnknown> m_pTemporaryUnknown;
190        CObjectPtr<CAmGraphBuilderCallback> m_pPrivateAmGraphBuilderCallback;
191        mutable CRoCriticalSection m_DataCriticalSection;
192        CComPtr<IUnknown> m_pSite;
193
194        BOOL IsAggregated() const throw()
195        {
196                return (ULONG) m_dwRef >= 0x00001000;
197        }
198        VOID ReleaseTemporaryUnknown() throw()
199        {
200                CComPtr<IUnknown> pUnknown;
201                Lock();
202                SwapMemory(&m_pTemporaryUnknown.p, &pUnknown.p);
203                Unlock();
204        }
205        VOID SetRunningFilterGraph()
206        {
207                if(m_RunningFilterGraph.GetCookie())
208                        return;
209                _Z4(atlTraceRefcount, 4, _T("this 0x%p, m_dwRef %d\n"), this, m_dwRef);
210                static CConstIntegerRegistryValue g_nEnableRotMonikerItemNameSuffix(_T("Enable ROT Moniker Item Name Suffix")); // 0 Default (Enabled), 1 Disabled, 2 Enabled
211                if(g_nEnableRotMonikerItemNameSuffix != 1)
212                {
213                        TCHAR pszPath[MAX_PATH] = { 0 };
214                        _W(GetModuleFileName(NULL, pszPath, DIM(pszPath)));
215                        LPCTSTR pszName = FindFileName(pszPath);
216                        SYSTEMTIME Time;
217                        GetLocalTime(&Time);
218                        CString sItemName = AtlFormatString(_T("%s; process: %s, time: %02d-%02d-%02d"), m_RunningFilterGraph.GetDefaultMonikerItemName(GetControllingUnknown()), pszName, Time.wHour, Time.wMinute, Time.wSecond);
219                        m_RunningFilterGraph.SetFilterGraph(GetControllingUnknown(), CStringW(sItemName));
220                } else
221                        m_RunningFilterGraph.SetFilterGraph(GetControllingUnknown());
222                _Z4(atlTraceRefcount, 4, _T("this 0x%p, m_dwRef %d\n"), this, m_dwRef);
223                Release();
224        }
225        VOID ResetRunningFilterGraph() throw()
226        {
227                if(!m_RunningFilterGraph.GetCookie())
228                        return;
229                AddRef();
230                _Z4(atlTraceRefcount, 4, _T("this 0x%p, m_dwRef 0x%x\n"), this, m_dwRef);
231                m_RunningFilterGraph.SetFilterGraph(NULL);
232                _Z4(atlTraceRefcount, 4, _T("this 0x%p, m_dwRef 0x%x\n"), this, m_dwRef);
233        }
234        HRESULT InternalQueryFilterGraph3Interface(REFIID InterfaceIdentifier, VOID** ppvObject) throw()
235        {
236                _A(InterfaceIdentifier == __uuidof(IFilterGraph3));
237                _A(ppvObject);
238                if(!m_pInnerFilterGraph3)
239                {
240                        *ppvObject = NULL;
241                        return E_NOINTERFACE;
242                }
243                T* pT = static_cast<T*>(this);
244                *ppvObject = (IFilterGraph3*) pT;
245                pT->InternalAddRef();
246                return S_OK;
247        }
248        static HRESULT WINAPI QueryFilterGraph3Interface(VOID* pvThis, REFIID InterfaceIdentifier, VOID** ppvObject, DWORD_PTR) throw()
249        {
250                return ((CSpy*) pvThis)->InternalQueryFilterGraph3Interface(InterfaceIdentifier, ppvObject);
251        }
252        HRESULT HookMediaControlAddSourceFilter(BSTR sFileName, IBaseFilter** ppBaseFilter, BOOL* pbDefault) throw()
253        {
254                _A(pbDefault);
255                HOOK_PROLOG(CFilterGraphAddRemoveHookHost)
256                        OnAddSourceFilter(pT, sFileName, NULL, reinterpret_cast<IUnknown**>(ppBaseFilter), &bDefault);
257                        *pbDefault = bDefault;
258                HOOK_EPILOG()
259                return S_OK;
260        }
261
262public:
263// CSpyT
264        static LPCTSTR GetOriginalLibraryName() throw()
265        {
266                return _T("quartz.dll");
267        }
268        static CString GetObjectFriendlyName()
269        {
270                return _StringHelper::GetLine(T::IDR, 2);
271        }
272        static HRESULT WINAPI UpdateRegistry(BOOL bRegister) throw()
273        {
274                _Z2(atlTraceRegistrar, 2, _T("bRegister %d\n"), bRegister);
275                _ATLTRY
276                {
277                        TreatAsUpdateRegistryFromResource<T>(*t_pFilterGraphClassIdentifier, bRegister);
278                }
279                _ATLCATCH(Exception)
280                {
281                        _C(Exception);
282                }
283                return S_OK;
284        }
285        CSpyT() throw() :
286                m_hQuartzModule(NULL)
287        {
288                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
289        }
290        ~CSpyT() throw()
291        {
292                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
293        }
294        HRESULT FinalConstruct() throw()
295        {
296                m_bIsAggregated = IsAggregated();
297                if(!m_bIsAggregated)
298                        InternalAddRef();
299                _ATLTRY
300                {
301                        TCHAR pszPath[MAX_PATH] = { 0 };
302                        _W(GetModuleFileName(NULL, pszPath, DIM(pszPath)));
303                        _Z4(atlTraceRefcount, 4, _T("pszPath \"%s\", this 0x%p, m_dwRef %d, m_bIsAggregated %d\n"), pszPath, this, m_dwRef, m_bIsAggregated);
304                        const HINSTANCE hModule = CoLoadOriginalLibrary();
305                        _ATLTRY
306                        {
307                                _A(hModule);
308                                const CComPtr<IUnknown> pControllingUnknown = GetControllingUnknown();
309                                #pragma region Instantiation
310                                {
311                                        { const ULONG nAddRefCount = pControllingUnknown.p->AddRef(); const ULONG nReleaseCount = pControllingUnknown.p->Release(); _Z5(atlTraceRefcount, 5, _T("m_dwRef 0x%x, AddRef %d, Release %d\n"), m_dwRef, nAddRefCount, nReleaseCount); }
312                                        const CComPtr<IUnknown> pUnknown = CoCreateOriginalInstance(hModule, pControllingUnknown);
313                                        // NOTE: DirectShow FilterGraph is incorrectly implementing COM aggregation adding outer reference to interfaces queried from private IUnknown
314                                        const CComQIPtr<IFilterGraph2> pFilterGraph2 = pUnknown;
315                                        __D(pFilterGraph2, E_NOINTERFACE);
316                                        pFilterGraph2.p->Release();
317                                        const CComQIPtr<IFilterGraph3> pFilterGraph3 = pUnknown;
318                                        if(pFilterGraph3)
319                                                pFilterGraph3.p->Release();
320                                        const CComQIPtr<IMediaControl> pMediaControl = pUnknown;
321                                        __D(pMediaControl, E_NOINTERFACE);
322                                        pMediaControl.p->Release();
323                                        const CComQIPtr<IMediaEventSink> pMediaEventSink = pUnknown;
324                                        __D(pMediaEventSink, E_NOINTERFACE);
325                                        pMediaEventSink.p->Release();
326                                        const CComQIPtr<IMediaEventEx> pMediaEventEx = pUnknown;
327                                        __D(pMediaEventEx, E_NOINTERFACE);
328                                        pMediaEventEx.p->Release();
329                                        #pragma region ROT Registration
330                                        { const ULONG nAddRefCount = pControllingUnknown.p->AddRef(); const ULONG nReleaseCount = pControllingUnknown.p->Release(); _Z5(atlTraceRefcount, 5, _T("m_dwRef 0x%x, AddRef %d, Release %d\n"), m_dwRef, nAddRefCount, nReleaseCount); }
331                                        SetRunningFilterGraph();
332                                        { const ULONG nAddRefCount = pControllingUnknown.p->AddRef(); const ULONG nReleaseCount = pControllingUnknown.p->Release(); _Z5(atlTraceRefcount, 5, _T("m_dwRef 0x%x, AddRef %d, Release %d\n"), m_dwRef, nAddRefCount, nReleaseCount); }
333                                        #pragma endregion
334                                        m_pInnerUnknown = pUnknown;
335                                        m_pInnerFilterGraph2 = pFilterGraph2;
336                                        m_pInnerFilterGraph3 = pFilterGraph3;
337                                        m_pInnerMediaControl = pMediaControl;
338                                        m_pInnerMediaEventSink = pMediaEventSink;
339                                        m_pInnerMediaEventEx = pMediaEventEx;
340                                }
341                                #pragma endregion
342                                #pragma region Set Private IAMGraphBuilderCallback
343                                static CConstIntegerRegistryValue g_nSetPrivateCallback(_T("Set Private CSpyT IAMGraphBuilderCallback")); // 0 Default (Enabled), 1 Disabled, 2 Enabled
344                                const DWORD nSetPrivateCallback = g_nSetPrivateCallback;
345                                if(nSetPrivateCallback != 1)
346                                {
347                                        CObjectPtr<CAmGraphBuilderCallback> pAmGraphBuilderCallback;
348                                        pAmGraphBuilderCallback.Construct();
349                                        pAmGraphBuilderCallback->Initialize(static_cast<T*>(this));
350                                        // WARN: Private site only forwards IAMGraphBuilderCallback interface and indicates other as not implemented
351                                        //       even if the external site does provide such implementation
352                                        if(pAmGraphBuilderCallback->SetGraphBuilder(pControllingUnknown))
353                                                m_pPrivateAmGraphBuilderCallback = pAmGraphBuilderCallback;
354                                        else
355                                                pAmGraphBuilderCallback->Terminate();
356                                }
357                                #pragma endregion
358                                #pragma region Temporary Reference for Aggregated Instantiation
359                                if(m_bIsAggregated)
360                                {
361                                        pControllingUnknown.p->AddRef();
362                                        const ULONG nReferenceCount = pControllingUnknown.p->Release();
363                                        if(nReferenceCount == 1)
364                                                m_pTemporaryUnknown = pControllingUnknown;
365                                }
366                                #pragma endregion
367                        }
368                        _ATLCATCHALL()
369                        {
370                                CoFreeLibrary(hModule);
371                                _ATLRETHROW;
372                        }
373#if defined(_DEBUG) && FALSE
374                        typedef HRESULT (WINAPI *DLLCANUNLOADNOW)();
375                        DLLCANUNLOADNOW DllCanUnloadNow = (DLLCANUNLOADNOW) GetProcAddress(hModule, "DllCanUnloadNow");
376                        __E(DllCanUnloadNow);
377                        const HRESULT nDllCanUnloadNowResult = DllCanUnloadNow();
378                        _Z4(atlTraceRefcount, 4, _T("nDllCanUnloadNowResult 0x%08x\n"), nDllCanUnloadNowResult); 
379#endif // defined(_DEBUG)
380                        _A(!m_hQuartzModule);
381                        m_hQuartzModule = hModule;
382                        #pragma region Extra Reference
383                        // NOTE: This feature allows to leave an extra COM reference on the object to extend its lifetime and work around early destruction issues
384                        static CConstIntegerRegistryValue g_nAddExtraReference(_T("Add Extra CSpyT Reference")); // 0 Default (Disabled), 1 Not Aggregated Only, 2 Aggregated Only, 3 Both
385                        const DWORD nAddExtraReference = g_nAddExtraReference;
386                        if(!m_bIsAggregated)
387                        {
388                                if(nAddExtraReference & 1)
389                                        InternalAddRef();
390                        } else
391                                if(nAddExtraReference & 2)
392                                        GetControllingUnknown()->AddRef();
393                        #pragma endregion
394                }
395                _ATLCATCH(Exception)
396                {
397                        if(!m_bIsAggregated)
398                                _W(InternalRelease() > 0);
399                        _C(Exception);
400                }
401                // NOTE: x64 build experiences a problem under COM Surrogate process that we're already being released to zero while still in this method
402                if(!m_bIsAggregated)
403                        if(InternalRelease() <= 0)
404                                return E_UNEXPECTED;
405                return S_OK;
406        }
407        VOID FinalRelease() throw()
408        {
409                _Z5(atlTraceRefcount, 5, _T("m_dwRef 0x%x\n"), m_dwRef);
410                _A(!m_pTemporaryUnknown);
411                const CComPtr<IUnknown> pControllingUnknown = GetControllingUnknown();
412                #pragma region Reset Private IAMGraphBuilderCallback
413                if(m_pPrivateAmGraphBuilderCallback)
414                {
415                        m_pPrivateAmGraphBuilderCallback->Terminate();
416                        m_pPrivateAmGraphBuilderCallback = NULL;
417                }
418                #pragma endregion
419                ResetRunningFilterGraph();
420                #pragma region Release Secondary Inner Interfaces
421                if(m_pInnerMediaEventEx)
422                {
423                        pControllingUnknown.p->AddRef();
424                        m_pInnerMediaEventEx = NULL;
425                }
426                if(m_pInnerMediaEventSink)
427                {
428                        pControllingUnknown.p->AddRef();
429                        m_pInnerMediaEventSink = NULL;
430                }
431                if(m_pInnerMediaControl)
432                {
433                        pControllingUnknown.p->AddRef();
434                        m_pInnerMediaControl = NULL;
435                }
436                if(m_pInnerFilterGraph3)
437                {
438                        pControllingUnknown.p->AddRef();
439                        m_pInnerFilterGraph3 = NULL;
440                }
441                if(m_pInnerFilterGraph2)
442                {
443                        pControllingUnknown.p->AddRef();
444                        m_pInnerFilterGraph2 = NULL;
445                }
446                #pragma endregion
447                #pragma region Release Primary Inner IUnknown
448                _ATLTRY
449                {
450                        m_pInnerUnknown = NULL;
451                }
452                _ATLCATCHALL()
453                {
454                        _Z_EXCEPTION();
455                        // NOTE: For some unidentified reason Quartz's FilterGraph may crash during final release, to smooth the effect the exception is silently caught
456                        m_pInnerUnknown.p = NULL;
457                }
458                #pragma endregion
459                #pragma region Release Quartz Library
460                if(m_hQuartzModule)
461                {
462                        CoFreeLibrary(m_hQuartzModule);
463                        m_hQuartzModule = NULL;
464                }
465                #pragma endregion
466        }
467        HRESULT QueryObjectWithSiteInterface(REFIID InterfaceIdentifier, LPVOID* ppvObject) throw()
468        {
469                _A(InterfaceIdentifier == __uuidof(IObjectWithSite));
470                _A(ppvObject);
471                if(m_pPrivateAmGraphBuilderCallback)
472                {
473                        reinterpret_cast<CComPtr<IObjectWithSite>&>(*ppvObject) = static_cast<T*>(this);
474                        return S_OK;
475                }
476                _A(m_pInnerUnknown);
477                return m_pInnerUnknown->QueryInterface(InterfaceIdentifier, ppvObject);
478        }
479        static HRESULT WINAPI QueryObjectWithSiteInterface(VOID* pvInstance, REFIID InterfaceIdentifier, LPVOID* ppvObject, DWORD_PTR) throw()
480        {
481                return ((CSpy*) pvInstance)->QueryObjectWithSiteInterface(InterfaceIdentifier, ppvObject);
482        }
483        CComPtr<IUnknown> GetSite() const throw()
484        {
485                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
486                return m_pSite;
487        }
488        BOOL SelectedFilter(IMoniker* pMoniker, HRESULT& nSelectedFilterResult)
489        {
490                const CComQIPtr<IAMGraphBuilderCallback> pAmGraphBuilderCallback = GetSite();
491                if(pAmGraphBuilderCallback)
492                {
493                        nSelectedFilterResult = pAmGraphBuilderCallback->SelectedFilter(pMoniker);
494                        return TRUE;
495                }
496                return FALSE;
497        }
498        BOOL CreatedFilter(IBaseFilter* pBaseFilter, HRESULT& nCreatedFilterResult)
499        {
500                const CComQIPtr<IAMGraphBuilderCallback> pAmGraphBuilderCallback = GetSite();
501                if(pAmGraphBuilderCallback)
502                {
503                        nCreatedFilterResult = pAmGraphBuilderCallback->CreatedFilter(pBaseFilter);
504                        return TRUE;
505                }
506                return FALSE;
507        }
508
509// ISpy
510
511// IFilterGraph
512        STDMETHOD(AddFilter)(IBaseFilter* pBaseFilter, LPCWSTR pszName) throw()
513        {
514                _Z4(atlTraceCOM, 4, _T("this 0x%p, pBaseFilter 0x%p %ls, pszName \"%s\"\n"), this, pBaseFilter, _FilterGraphHelper::GetFilterClassIdentifierString(pBaseFilter), CString(pszName));
515                ReleaseTemporaryUnknown();
516                HOOK_PROLOG(CFilterGraphAddRemoveHookHost)
517                        OnAddFilter(pT, pBaseFilter, pszName, &bDefault);
518                HOOK_EPILOG()
519                const HRESULT nResult = m_pInnerFilterGraph2->AddFilter(pBaseFilter, pszName);
520                if(SUCCEEDED(nResult))
521                        _ATLTRY
522                        {
523                                const CStringW sName = _FilterGraphHelper::GetFilterName(pBaseFilter);
524                                _Z4(atlTraceGeneral, 4, _T("this 0x%p, sName \"%ls\"\n"), this, sName);
525                        }
526                        _ATLCATCHALL()
527                        {
528                                _Z_EXCEPTION();
529                        }
530                return nResult;
531        }
532    STDMETHOD(RemoveFilter)(IBaseFilter* pBaseFilter) throw()
533        {
534                _Z4(atlTraceCOM, 4, _T("this 0x%p, pBaseFilter 0x%p\n"), this, pBaseFilter);
535                if(pBaseFilter)
536                        _ATLTRY
537                        {
538                                const CStringW sName = _FilterGraphHelper::GetFilterName(pBaseFilter);
539                                _Z4(atlTraceGeneral, 4, _T("this 0x%p, sName \"%ls\"\n"), this, sName);
540                        }
541                        _ATLCATCHALL()
542                        {
543                                _Z_EXCEPTION();
544                        }
545                HOOK_PROLOG(CFilterGraphAddRemoveHookHost)
546                        OnRemoveFilter(pT, pBaseFilter, &bDefault);
547                HOOK_EPILOG()
548                return m_pInnerFilterGraph2->RemoveFilter(pBaseFilter);
549        }
550    STDMETHOD(EnumFilters)(IEnumFilters** ppEnumFilters) throw()
551        {
552                _Z4(atlTraceCOM, 4, _T("...\n"));
553                return m_pInnerFilterGraph2->EnumFilters(ppEnumFilters);
554        }
555    STDMETHOD(FindFilterByName)(LPCWSTR pszName, IBaseFilter** ppFilter) throw()
556        {
557                _Z4(atlTraceCOM, 4, _T("pszName \"%s\"\n"), CString(pszName));
558                return m_pInnerFilterGraph2->FindFilterByName(pszName, ppFilter);
559        }
560    STDMETHOD(ConnectDirect)(IPin* pOutputPin, IPin* pInputPin, const AM_MEDIA_TYPE* pMediaType) throw()
561        {
562                _Z4(atlTraceCOM, 4, _T("...\n"));
563                if(pOutputPin && pInputPin)
564                        _ATLTRY
565                        {
566                                _Z4(atlTraceGeneral, 4, _T("pOutputPin \"%ls\", pInputPin \"%ls\"\n"), _FilterGraphHelper::GetPinFullName(pOutputPin), _FilterGraphHelper::GetPinFullName(pInputPin));
567                                if(pMediaType)
568                                        _FilterGraphHelper::TraceMediaType(pMediaType);
569                        }
570                        _ATLCATCHALL()
571                        {
572                                _Z_EXCEPTION();
573                        }
574                HOOK_PROLOG(CFilterGraphConnectHookHost)
575                        OnConnectDirect(pT, pOutputPin, pInputPin, (const BYTE*) pMediaType, &bDefault);
576                HOOK_EPILOG()
577                return m_pInnerFilterGraph2->ConnectDirect(pOutputPin, pInputPin, pMediaType);
578        }
579    STDMETHOD(Reconnect)(IPin* pPin) throw()
580        {
581                _Z4(atlTraceCOM, 4, _T("...\n"));
582                HOOK_PROLOG(CFilterGraphConnectHookHost)
583                        OnReconnect(pT, pPin, &bDefault);
584                HOOK_EPILOG()
585                return m_pInnerFilterGraph2->Reconnect(pPin);
586        }
587    STDMETHOD(Disconnect)(IPin* pPin) throw()
588        {
589                _Z4(atlTraceCOM, 4, _T("...\n"));
590                HOOK_PROLOG(CFilterGraphConnectHookHost)
591                        OnDisconnect(pT, pPin, &bDefault);
592                HOOK_EPILOG()
593                return m_pInnerFilterGraph2->Disconnect(pPin);
594        }
595    STDMETHOD(SetDefaultSyncSource)() throw()
596        {
597                _Z4(atlTraceCOM, 4, _T("...\n"));
598                return m_pInnerFilterGraph2->SetDefaultSyncSource();
599        }
600
601// IGraphBuilder
602    STDMETHOD(Connect)(IPin* pOutputPin, IPin* pInputPin) throw()
603        {
604                _Z4(atlTraceCOM, 4, _T("pOutputPin 0x%p, pInputPin 0x%p\n"), pOutputPin, pInputPin);
605                if(pOutputPin && pInputPin)
606                        _ATLTRY
607                        {
608                                _Z4(atlTraceGeneral, 4, _T("this 0x%p, pOutputPin 0x%p \"%ls\" (filter 0x%p), pInputPin 0x%p \"%ls\" (filter 0x%p)\n"), this, 
609                                        pOutputPin, _FilterGraphHelper::GetPinFullName(pOutputPin), _FilterGraphHelper::GetPinFilter(pOutputPin),
610                                        pInputPin, _FilterGraphHelper::GetPinFullName(pInputPin), _FilterGraphHelper::GetPinFilter(pInputPin),
611                                        0);
612                        }
613                        _ATLCATCHALL()
614                        {
615                                _Z_EXCEPTION();
616                        }
617                HOOK_PROLOG(CFilterGraphConnectHookHost)
618                        OnConnect(pT, pOutputPin, pInputPin, &bDefault);
619                HOOK_EPILOG()
620                return m_pInnerFilterGraph2->Connect(pOutputPin, pInputPin);
621        }
622    STDMETHOD(Render)(IPin* pOutputPin) throw()
623        {
624                _Z4(atlTraceCOM, 4, _T("...\n"));
625                return m_pInnerFilterGraph2->Render(pOutputPin);
626        }
627    STDMETHOD(RenderFile)(LPCWSTR pszFileName, LPCWSTR pszPlayListFileName) throw()
628        {
629                _Z4(atlTraceCOM, 4, _T("pszFileName \"%s\", pszPlayListFileName \"%s\"\n"), CString(pszFileName), CString(pszPlayListFileName));
630                return m_pInnerFilterGraph2->RenderFile(pszFileName, pszPlayListFileName);
631        }
632    STDMETHOD(AddSourceFilter)(LPCWSTR pszFileName, LPCWSTR pszFilterName, IBaseFilter** ppBaseFilter) throw()
633        {
634                _Z4(atlTraceCOM, 4, _T("pszFileName \"%s\", pszFilterName \"%s\"\n"), CString(pszFileName), CString(pszFilterName));
635                ReleaseTemporaryUnknown();
636                HOOK_PROLOG(CFilterGraphAddRemoveHookHost)
637                        OnAddSourceFilter(pT, pszFileName, pszFilterName, reinterpret_cast<IUnknown**>(ppBaseFilter), &bDefault);
638                HOOK_EPILOG()
639                return m_pInnerFilterGraph2->AddSourceFilter(pszFileName, pszFilterName, ppBaseFilter);
640        }
641        STDMETHOD(SetLogFile)(DWORD_PTR hFile) throw()
642        {
643                _Z4(atlTraceCOM, 4, _T("...\n"));
644                return m_pInnerFilterGraph2->SetLogFile(hFile);
645        }
646        STDMETHOD(Abort)() throw()
647        {
648                _Z4(atlTraceCOM, 4, _T("...\n"));
649                return m_pInnerFilterGraph2->Abort();
650        }
651        STDMETHOD(ShouldOperationContinue)() throw()
652        {
653                _Z4(atlTraceCOM, 4, _T("...\n"));
654                return m_pInnerFilterGraph2->ShouldOperationContinue();
655        }
656
657// IFilterGraph2
658        STDMETHOD(AddSourceFilterForMoniker)(IMoniker* pMoniker, IBindCtx* pBindCtx, LPCWSTR pszFilterName, IBaseFilter** ppBaseFilter) throw()
659        {
660                _Z4(atlTraceCOM, 4, _T("pszFilterName \"%s\"\n"), CString(pszFilterName));
661                ReleaseTemporaryUnknown();
662                HOOK_PROLOG(CFilterGraphAddRemoveHookHost)
663                        OnAddSourceFilterForMoniker(pT, pMoniker, pBindCtx, pszFilterName, reinterpret_cast<IUnknown**>(ppBaseFilter), &bDefault);
664                HOOK_EPILOG()
665                return m_pInnerFilterGraph2->AddSourceFilterForMoniker(pMoniker, pBindCtx, pszFilterName, ppBaseFilter);
666        }
667        STDMETHOD(ReconnectEx)(IPin* pPin, const AM_MEDIA_TYPE* pMediaType) throw()
668        {
669                _Z4(atlTraceCOM, 4, _T("...\n"));
670                HOOK_PROLOG(CFilterGraphConnectHookHost)
671                        OnReconnectEx(pT, pPin, (const BYTE*) pMediaType, &bDefault);
672                HOOK_EPILOG()
673                return m_pInnerFilterGraph2->ReconnectEx(pPin, pMediaType);
674        }
675        STDMETHOD(RenderEx)(IPin* pOutputPin, DWORD nFlags, DWORD* pnContext) throw()
676        {
677                _Z4(atlTraceCOM, 4, _T("nFlags 0x%x\n"), nFlags);
678                return m_pInnerFilterGraph2->RenderEx(pOutputPin, nFlags, pnContext);
679        }
680
681// IFilterGraph3
682    STDMETHOD(SetSyncSourceEx)(IReferenceClock* pFilterGraphReferenceClock, IReferenceClock* pFilterReferenceClock, IBaseFilter* pBaseFilter) throw()
683        {
684                _Z4(atlTraceCOM, 4, _T("...\n"));
685                _A(m_pInnerFilterGraph3);
686                return m_pInnerFilterGraph3->SetSyncSourceEx(pFilterGraphReferenceClock, pFilterReferenceClock, pBaseFilter);
687        }
688
689// IMediaControl
690        STDMETHOD(Run)() throw()
691        {
692                _Z4(atlTraceCOM, 4, _T("...\n"));
693                _ATLTRY
694                {
695                        OAFilterState State = (OAFilterState) -1;
696                        if(SUCCEEDED(m_pInnerMediaControl->GetState(0, &State)) && State == State_Stopped)
697                                _FilterGraphHelper::TraceGraphBuilder(this);
698                }
699                _ATLCATCHALL()
700                {
701                        _Z_EXCEPTION();
702                }
703                HOOK_PROLOG(CFilterGraphStateControlHookHost)
704                        OnRun(pT, &bDefault);
705                HOOK_EPILOG()
706                const HRESULT nRunResult = m_pInnerMediaControl->Run();
707                _Z4(atlTraceGeneral, 4, _T("nRunResult 0x%08x\n"), nRunResult);
708                return nRunResult;
709        }
710        STDMETHOD(Pause)() throw()
711        {
712                _Z4(atlTraceCOM, 4, _T("...\n"));
713                _ATLTRY
714                {
715                        OAFilterState State = (OAFilterState) -1;
716                        if(SUCCEEDED(m_pInnerMediaControl->GetState(0, &State)) && State == State_Stopped)
717                                _FilterGraphHelper::TraceGraphBuilder(this);
718                }
719                _ATLCATCHALL()
720                {
721                        _Z_EXCEPTION();
722                }
723                HOOK_PROLOG(CFilterGraphStateControlHookHost)
724                        OnPause(pT, &bDefault);
725                HOOK_EPILOG()
726                return m_pInnerMediaControl->Pause();
727        }
728        STDMETHOD(Stop)() throw()
729        {
730                _Z4(atlTraceCOM, 4, _T("...\n"));
731                HOOK_PROLOG(CFilterGraphStateControlHookHost)
732                        OnStop(pT, &bDefault);
733                HOOK_EPILOG()
734                return m_pInnerMediaControl->Stop();
735        }
736        STDMETHOD(GetState)(LONG nTimeout, OAFilterState* pState) throw()
737        {
738                _Z4(atlTraceCOM, 4, _T("nTimeout %d\n"), nTimeout);
739                return m_pInnerMediaControl->GetState(nTimeout, pState);
740        }
741        STDMETHOD(RenderFile)(BSTR sFileName) throw()
742        {
743                _Z4(atlTraceCOM, 4, _T("sFileName \"%s\"\n"), CString(sFileName));
744                return m_pInnerMediaControl->RenderFile(sFileName);
745        }
746    STDMETHOD(AddSourceFilter)(BSTR sFileName, IDispatch** ppDispatch) throw()
747        {
748                _Z4(atlTraceCOM, 4, _T("sFileName \"%s\"\n"), CString(sFileName));
749                ReleaseTemporaryUnknown();
750                _ATLTRY
751                {
752                        CComPtr<IBaseFilter> pBaseFilter;
753                        BOOL bDefault = TRUE;
754                        const HRESULT nResult = HookMediaControlAddSourceFilter(sFileName, &pBaseFilter, &bDefault);
755                        if(!bDefault)
756                        {
757                                __D(ppDispatch, E_POINTER);
758                                *ppDispatch = NULL;
759                                if(SUCCEEDED(nResult))
760                                {
761                                        CComQIPtr<IDispatch> pDispatch = pBaseFilter;
762                                        __D(pDispatch, E_NOINTERFACE);
763                                        *ppDispatch = pDispatch.Detach();
764                                }
765                                return nResult;
766                        }
767                }
768                _ATLCATCH(Exception)
769                {
770                        _C(Exception);
771                }
772                return m_pInnerMediaControl->AddSourceFilter(sFileName, ppDispatch);
773        }
774        STDMETHOD(get_FilterCollection)(IDispatch** ppDispatch) throw()
775        {
776                _Z4(atlTraceCOM, 4, _T("...\n"));
777                ReleaseTemporaryUnknown();
778                return m_pInnerMediaControl->get_FilterCollection(ppDispatch);
779        }
780        STDMETHOD(get_RegFilterCollection)(IDispatch** ppDispatch) throw()
781        {
782                _Z4(atlTraceCOM, 4, _T("...\n"));
783                ReleaseTemporaryUnknown();
784                return m_pInnerMediaControl->get_RegFilterCollection(ppDispatch);
785        }
786        STDMETHOD(StopWhenReady)() throw()
787        {
788                _Z4(atlTraceCOM, 4, _T("...\n"));
789                return m_pInnerMediaControl->StopWhenReady();
790        }
791
792// IMediaEventSink
793    STDMETHOD(Notify)(LONG nEventCode, LONG_PTR nParameter1, LONG_PTR nParameter2) throw()
794        {
795                _Z4(atlTraceCOM, 4, _T("nEventCode 0x%02X, nParameter1 0x%p, nParameter2 0x%p\n"), nEventCode, nParameter1, nParameter2);
796                #if defined(_M_IX86)
797                        // WARN: Guarding section around might be preventing from walknig frame up the stack
798                        if(nEventCode == EC_ERRORABORT)
799                        {
800                                CONTEXT ThreadContext = { CONTEXT_FULL };
801                                GetCurrentThreadContext(&ThreadContext);
802                                CDebugTraceCallStack::TraceCallStack(ThreadContext, (nEventCode == EC_ERRORABORT) ? 32 : 8);
803                        }
804                #endif // defined(_M_IX86)
805                return m_pInnerMediaEventSink->Notify(nEventCode, nParameter1, nParameter2);
806        }
807
808// IMediaEvent
809        STDMETHOD(GetEventHandle)(OAEVENT* pnEventHandle) throw()
810        {
811                _Z4(atlTraceCOM, 4, _T("...\n"));
812                return m_pInnerMediaEventEx->GetEventHandle(pnEventHandle);
813        }
814        STDMETHOD(GetEvent)(LONG* pnEventCode, LONG_PTR* pnParameter1, LONG_PTR* pnParameter2, LONG nTimeout) throw()
815        {
816                _Z4(atlTraceCOM, nTimeout ? 4 : 5, _T("nTimeout %d\n"), nTimeout);
817                const HRESULT nGetEventResult = m_pInnerMediaEventEx->GetEvent(pnEventCode, pnParameter1, pnParameter2, nTimeout);
818                if(pnEventCode && pnParameter1 && pnParameter2)
819                        _Z4(atlTraceCOM, (nGetEventResult != E_ABORT) ? 4 : 5, _T("nGetEventResult 0x%x, *pnEventCode 0x%02X, *pnParameter1 0x%p, *pnParameter2 0x%p\n"), nGetEventResult, *pnEventCode, *pnParameter1, *pnParameter2);
820                return nGetEventResult;
821        }
822        STDMETHOD(WaitForCompletion)(LONG nTimeout, LONG* pnEventCode) throw()
823        {
824                _Z4(atlTraceCOM, 4, _T("nTimeout %d\n"), nTimeout);
825                const HRESULT nWaitForCompletionResult = m_pInnerMediaEventEx->WaitForCompletion(nTimeout, pnEventCode);
826                if(pnEventCode)
827                        _Z4(atlTraceCOM, 4, _T("nWaitForCompletionResult 0x%x, *pnEventCode 0x%02X\n"), nWaitForCompletionResult, *pnEventCode);
828                return nWaitForCompletionResult;
829        }
830        STDMETHOD(CancelDefaultHandling)(LONG nEventCode) throw()
831        {
832                _Z4(atlTraceCOM, 4, _T("nEventCode 0x%02X\n"), nEventCode);
833                return m_pInnerMediaEventEx->CancelDefaultHandling(nEventCode);
834        }
835        STDMETHOD(RestoreDefaultHandling)(LONG nEventCode) throw()
836        {
837                _Z4(atlTraceCOM, 4, _T("nEventCode 0x%02X\n"), nEventCode);
838                return m_pInnerMediaEventEx->RestoreDefaultHandling(nEventCode);
839        }
840        STDMETHOD(FreeEventParams)(LONG nEventCode, LONG_PTR nParameter1, LONG_PTR nParameter2) throw()
841        {
842                _Z4(atlTraceCOM, 4, _T("nEventCode 0x%02X, nParameter1 0x%p, nParameter2 0x%p\n"), nEventCode, nParameter1, nParameter2);
843                return m_pInnerMediaEventEx->FreeEventParams(nEventCode, nParameter1, nParameter2);
844        }
845       
846// IMediaEventEx
847        STDMETHOD(SetNotifyWindow)(OAHWND nWindowHandle, LONG nMessage, LONG_PTR nParameter) throw()
848        {
849                _Z4(atlTraceCOM, 4, _T("nWindowHandle 0x%08x, nMessage 0x%04x, nParameter %p\n"), nWindowHandle, nMessage, nParameter);
850                return m_pInnerMediaEventEx->SetNotifyWindow(nWindowHandle, nMessage, nParameter);
851        }
852        STDMETHOD(SetNotifyFlags)(LONG nNotifyFlags) throw()
853        {
854                _Z4(atlTraceCOM, 4, _T("nNotifyFlags 0x%x\n"), nNotifyFlags);
855                return m_pInnerMediaEventEx->SetNotifyFlags(nNotifyFlags);
856        }
857        STDMETHOD(GetNotifyFlags)(LONG* pnNotifyFlags) throw()
858        {
859                _Z4(atlTraceCOM, 4, _T("...\n"));
860                return m_pInnerMediaEventEx->GetNotifyFlags(pnNotifyFlags);
861        }
862
863// IObjectWithSite
864        STDMETHOD(SetSite)(IUnknown* pSite) throw()
865        {
866                _Z4(atlTraceCOM, 4, _T("pSite 0x%p\n"), pSite);
867                _ATLTRY
868                {
869                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
870                        m_pSite = pSite;
871                }
872                _ATLCATCH(Exception)
873                {
874                        _C(Exception);
875                }
876                return S_OK;
877        }
878    STDMETHOD(GetSite)(REFIID InterfaceIdentifier, VOID** ppvSite) throw()
879        {
880                _Z4(atlTraceCOM, 4, _T("InterfaceIdentifier %ls\n"), _PersistHelper::StringFromInterfaceIdentifier(InterfaceIdentifier));
881                _ATLTRY
882                {
883                        __D(ppvSite, E_POINTER);
884                        *ppvSite = NULL;
885                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
886                        _D(m_pSite, E_FAIL);
887                        return m_pSite->QueryInterface(InterfaceIdentifier, ppvSite);
888                }
889                _ATLCATCH(Exception)
890                {
891                        _C(Exception);
892                }
893                return S_OK;
894        }
895};
896
897////////////////////////////////////////////////////////////
898// CSpy
899
900class ATL_NO_VTABLE CSpy :
901        public CSpyT<CSpy, &CLSID_FilterGraph>,
902        public CComCoClass<CSpy, &CLSID_Spy>
903{
904public:
905        enum { IDR = IDR_FILTERGRAPHSPY };
906
907private:
908        static LPCTSTR g_pszClassName;
909
910public:
911        //typedef CBlackListAwareComCreatorT<CComObjectCached<CSpy>, CSpy, &g_pszClassName> _ClassFactoryCreatorClass; // DECLARE_CLASSFACTORY override
912        typedef CComCreator2<CBlackListAwareComCreatorT<CComObject<CSpy>, CSpy, &g_pszClassName>, CBlackListAwareComCreatorT<CComAggObject<CSpy>, CSpy, &g_pszClassName> > _CreatorClass; // DECLARE_AGGREGATABLE override
913
914public:
915// CSpy
916};
917
918__declspec(selectany) LPCTSTR CSpy::g_pszClassName = _T("CSpy");
919
920OBJECT_ENTRY_AUTO(__uuidof(Spy), CSpy)
921
922////////////////////////////////////////////////////////////
923// CNoThreadSpy
924
925class ATL_NO_VTABLE CNoThreadSpy :
926        public CSpyT<CNoThreadSpy, &CLSID_FilterGraphNoThread>,
927        public CComCoClass<CNoThreadSpy, &CLSID_NoThreadSpy>
928{
929public:
930        enum { IDR = IDR_NOTHREADFILTERGRAPHSPY };
931
932private:
933        static LPCTSTR g_pszClassName;
934
935public:
936        //typedef CBlackListAwareComCreatorT<CComObjectCached<CNoThreadSpy>, CNoThreadSpy, &g_pszClassName> _ClassFactoryCreatorClass; // DECLARE_CLASSFACTORY override
937        typedef CComCreator2<CBlackListAwareComCreatorT<CComObject<CNoThreadSpy>, CNoThreadSpy, &g_pszClassName>, CBlackListAwareComCreatorT<CComAggObject<CNoThreadSpy>, CNoThreadSpy, &g_pszClassName> > _CreatorClass; // DECLARE_AGGREGATABLE override
938
939public:
940// CNoThreadSpy
941};
942
943__declspec(selectany) LPCTSTR CNoThreadSpy::g_pszClassName = _T("CNoThreadSpy");
944
945OBJECT_ENTRY_AUTO(__uuidof(NoThreadSpy), CNoThreadSpy)
Note: See TracBrowser for help on using the repository browser.