source: trunk/DirectShowSpy/FilterGraphSpy.h @ 322

Last change on this file since 322 was 322, checked in by roman, 8 years ago

Added memory allocator buffer inspection capability

  • Property svn:keywords set to Id
File size: 45.3 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2014
3// Created by Roman Ryltsov roman@alax.info, http://alax.info
4//
5// This source code is published to complement DirectShowSpy developer powertoy
6// and demonstrate the internal use of APIs and tricks powering the tool. It is
7// allowed to freely re-use the portions of the code in other projects, commercial
8// or otherwise (provided that you don’t pretend that you wrote the original tool).
9//
10// Please keep in mind that DirectShowSpy is a developer tool, it is strongly recommended
11// that it is not shipped with release grade software. It is allowed to distribute
12// DirectShowSpy if only it is not registered with Windows by default and either
13// used privately, or registered on specific throubleshooting request. The advice applies
14// to hooking methods used by DirectShowSpy in general as well.
15
16#pragma once
17
18#include "rodshow.h"
19#include "Module_i.h"
20#include "Common.h"
21#include "RunPropertyBag.h"
22
23HRESULT FilterGraphHelper_OpenGraphStudioNext(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult);
24HRESULT FilterGraphHelper_OpenGraphEdit(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult);
25
26////////////////////////////////////////////////////////////
27// CModuleVersionInformationT
28
29template <typename T>
30class ATL_NO_VTABLE CModuleVersionInformationT :
31        public IDispatchImpl<IModuleVersionInformation>
32{
33public:
34// CModuleVersionInformationT
35
36// IModuleVersionInformation
37        STDMETHOD(get_Path)(BSTR* psPath)
38        {
39                _Z4(atlTraceCOM, 4, _T("...\n"));
40                _ATLTRY
41                {
42                        __D(psPath, E_POINTER);
43                        *psPath = CComBSTR(_VersionInfoHelper::GetModulePath()).Detach();
44                }
45                _ATLCATCH(Exception)
46                {
47                        _C(Exception);
48                }
49                return S_OK;
50        }
51        STDMETHOD(get_FileVersion)(LONGLONG* pnFileVersion)
52        {
53                _Z4(atlTraceCOM, 4, _T("...\n"));
54                _ATLTRY
55                {
56                        __D(pnFileVersion, E_POINTER);
57                        *pnFileVersion = (LONGLONG) _VersionInfoHelper::GetFileVersion(_VersionInfoHelper::GetModulePath());
58                }
59                _ATLCATCH(Exception)
60                {
61                        _C(Exception);
62                }
63                return S_OK;
64        }
65        STDMETHOD(get_FileVersionString)(BSTR* psFileVersionString)
66        {
67                _Z4(atlTraceCOM, 4, _T("...\n"));
68                _ATLTRY
69                {
70                        __D(psFileVersionString, E_POINTER);
71                        *psFileVersionString = CComBSTR(_VersionInfoHelper::GetVersionString(_VersionInfoHelper::GetFileVersion(_VersionInfoHelper::GetModulePath()))).Detach();
72                }
73                _ATLCATCH(Exception)
74                {
75                        _C(Exception);
76                }
77                return S_OK;
78        }
79};
80
81////////////////////////////////////////////////////////////
82// CFilterGraphMemoryAllocatorData
83
84template <typename T>
85class ATL_NO_VTABLE CFilterGraphMemoryAllocatorDataT :
86        public IDispatchImpl<IFilterGraphMemoryAllocatorData>
87{
88public:
89
90        ////////////////////////////////////////////////////////
91        // CMemoryAllocatorData
92
93        class CMemoryAllocatorData
94        {
95        public:
96                CComPtr<IMemAllocator> m_pMemAllocator;
97                CRoArrayT<CString> m_NameArray;
98
99        public:
100        // CMemoryAllocatorData
101                CComVariantArray GetAsVariant() const
102                {
103                        CRoArrayT<CComVariantArray> Array;
104                        Array.Add(CComVariant((LONG) (LONG_PTR) (IMemAllocator*) m_pMemAllocator));
105                        Array.Add(CComVariant(_StringHelper::Join(m_NameArray, _T(", "))));
106                        #pragma region IMemAllocator, ALLOCATOR_PROPERTIES
107                        _ATLTRY
108                        {
109                                ALLOCATOR_PROPERTIES Properties;
110                                const HRESULT nGetPropertiesResult = m_pMemAllocator->GetProperties(&Properties);
111                                __C(nGetPropertiesResult);
112                                Array.Add(CComVariant());
113                                Array.Add(CComVariant(Properties.cBuffers));
114                                Array.Add(CComVariant(Properties.cbBuffer));
115                                Array.Add(CComVariant(Properties.cbAlign));
116                                Array.Add(CComVariant(Properties.cbPrefix));
117                        }
118                        _ATLCATCH(Exception)
119                        {
120                                _Z_ATLEXCEPTION(Exception);
121                                Array.Add(CComVariant((LONG) (HRESULT) Exception));
122                        }
123                        #pragma endregion
124                        #pragma region IMemAllocatorCallbackTemp
125                        const CComQIPtr<IMemAllocatorCallbackTemp> pMemAllocatorCallbackTemp = m_pMemAllocator;
126                        if(pMemAllocatorCallbackTemp)
127                        {
128                                _ATLTRY
129                                {
130                                        LONG nFreeCount = 0;
131                                        __C(pMemAllocatorCallbackTemp->GetFreeCount(&nFreeCount));
132                                        Array.Add(CComVariant());
133                                        Array.Add(CComVariant(nFreeCount));
134                                }
135                                _ATLCATCH(Exception)
136                                {
137                                        _Z_ATLEXCEPTION(Exception);
138                                        Array.Add(CComVariant((LONG) (HRESULT) Exception));
139                                }
140                        } else
141                                Array.Add(CComVariant((LONG) (HRESULT) E_NOINTERFACE));
142                        #pragma endregion
143                        CComVariantArray vResult;
144                        return vResult.FromElementArray(Array);
145                }
146        };
147
148public:
149// CFilterGraphMemoryAllocatorDataT
150        static BOOL CompareMemAllocator(const CMemoryAllocatorData& Data, IMemAllocator* pMemAllocator)
151        {
152                return Data.m_pMemAllocator == pMemAllocator;
153        }
154        CComVariantArray GetValue()
155        {
156                #pragma region Enumerate
157                CRoArrayT<CMemoryAllocatorData> DataArray;
158                {
159                        _FilterGraphHelper::CFilterArray FilterArray;
160                        _FilterGraphHelper::GetGraphFilters((IFilterGraph2*) static_cast<T*>(this), FilterArray);
161                        for(auto&& pBaseFilter: FilterArray)
162                        {
163                                _ATLTRY
164                                {
165                                        _FilterGraphHelper::CPinArray PinArray;
166                                        _FilterGraphHelper::GetFilterPins(pBaseFilter, PINDIR_INPUT, PinArray);
167                                        for(auto&& pInputPin: PinArray)
168                                        {
169                                                _ATLTRY
170                                                {
171                                                        const CComPtr<IPin> pOutputPin = _FilterGraphHelper::GetPeerPin(pInputPin);
172                                                        if(!pOutputPin)
173                                                                continue;
174                                                        const CComQIPtr<IMemInputPin> pMemInputPin = pInputPin;
175                                                        if(!pMemInputPin)
176                                                                continue;
177                                                        CComPtr<IMemAllocator> pMemAllocator;
178                                                        pMemInputPin->GetAllocator(&pMemAllocator);
179                                                        if(!pMemAllocator)
180                                                                continue;
181                                                        SIZE_T nIndex;
182                                                        if(!DataArray.FindFirstThatT<IMemAllocator*>(&CFilterGraphMemoryAllocatorDataT<T>::CompareMemAllocator, pMemAllocator, &nIndex))
183                                                        {
184                                                                nIndex = DataArray.Add();
185                                                                DataArray[nIndex].m_pMemAllocator = pMemAllocator;
186                                                        }
187                                                        CMemoryAllocatorData& Data = DataArray[nIndex];
188                                                        Data.m_NameArray.Add(AtlFormatString(_T("%ls - %ls"), _FilterGraphHelper::GetPinFullName(pOutputPin), _FilterGraphHelper::GetPinFullName(pInputPin)));
189                                                }
190                                                _ATLCATCHALL()
191                                                {
192                                                        _Z_EXCEPTION();
193                                                }
194                                        }
195                                }
196                                _ATLCATCHALL()
197                                {
198                                        _Z_EXCEPTION();
199                                }
200                        }
201                }
202                #pragma endregion
203                CRoArrayT<CComVariantArray> Array;
204                for(auto&& Data: DataArray)
205                        Array.Add(Data.GetAsVariant());
206                CComVariantArray vResult;
207                return vResult.FromElementArray(Array);
208        }
209
210// IFilterGraphMemoryAllocatorData
211        STDMETHOD(get_Value)(VARIANT* pvValue)
212        {
213                _Z4(atlTraceCOM, 4, _T("this 0x%p\n"), this);
214                _ATLTRY
215                {
216                        __D(pvValue, E_POINTER);
217                        VariantInit(pvValue);
218                        _V(GetValue().Detach(pvValue));
219                }
220                _ATLCATCH(Exception)
221                {
222                        _C(Exception);
223                }
224                return S_OK;
225        }
226};
227
228////////////////////////////////////////////////////////////
229// CSpyT
230
231LPCTSTR g_pszAddRemoveHookName = _T("Add/Remove Hooks");
232LPCTSTR g_pszConnectHookName = _T("Connect Hooks");
233LPCTSTR g_pszStateControlHookName = _T("State Control Hooks");
234
235template <typename T, const CLSID* t_pFilterGraphClassIdentifier>
236class ATL_NO_VTABLE CSpyT :
237        public CComObjectRootEx<CComMultiThreadModel>,
238        //public CComCoClass<CSpyT, &CLSID_Spy>,
239        public CTransparentCoClassT<T, t_pFilterGraphClassIdentifier>,
240        public IDispatchImpl<ISpy>,
241        public ISpyEx,
242        public IFilterGraph2,
243        public IDispatchImpl<IMediaControl, &__uuidof(IMediaControl), &__uuidof(Quartz::__QuartzTypeLib)>,
244        public IMediaEventSink,
245        public IDispatchImpl<IMediaEventEx, &__uuidof(IMediaEventEx), &__uuidof(Quartz::__QuartzTypeLib)>,
246        public IObjectWithSite,
247        public CModuleVersionInformationT<T>,
248        public CFilterGraphMemoryAllocatorDataT<T>,
249        public CHookHostT<T, IFilterGraphAddRemoveHook, &g_pszAddRemoveHookName>,
250        public CHookHostT<T, IFilterGraphConnectHook, &g_pszConnectHookName>,
251        public CHookHostT<T, IFilterGraphStateControlHook, &g_pszStateControlHookName>
252{
253        typedef CSpyT<T, t_pFilterGraphClassIdentifier> CSpy;
254        typedef CHookHostT<T, IFilterGraphAddRemoveHook, &g_pszAddRemoveHookName> CFilterGraphAddRemoveHookHost;
255        typedef CHookHostT<T, IFilterGraphConnectHook, &g_pszConnectHookName> CFilterGraphConnectHookHost;
256        typedef CHookHostT<T, IFilterGraphStateControlHook, &g_pszStateControlHookName> CFilterGraphStateControlHookHost;
257
258public:
259        //enum { IDR = IDR_FILTERGRAPHSPY };
260
261//DECLARE_CLASSFACTORY(...
262
263//DECLARE_AGGREGATABLE(...
264
265//DECLARE_REGISTRY_RESOURCEID(IDR)
266
267DECLARE_PROTECT_FINAL_CONSTRUCT()
268
269DECLARE_GET_CONTROLLING_UNKNOWN()
270
271DECLARE_QI_TRACE(CSpy)
272
273BEGIN_COM_MAP(CSpy)
274        COM_INTERFACE_ENTRY(ISpy)
275        COM_INTERFACE_ENTRY_FUNC(__uuidof(IFilterGraph3), 0, QueryFilterGraph3Interface)
276        COM_INTERFACE_ENTRY(ISpyEx)
277        COM_INTERFACE_ENTRY(IFilterGraph2)
278        COM_INTERFACE_ENTRY(IGraphBuilder)
279        COM_INTERFACE_ENTRY(IFilterGraph)
280        COM_INTERFACE_ENTRY(IMediaControl)
281        COM_INTERFACE_ENTRY(IMediaEventSink)
282        COM_INTERFACE_ENTRY(IMediaEventEx)
283        COM_INTERFACE_ENTRY(IMediaEvent)
284        COM_INTERFACE_ENTRY_FUNC(__uuidof(IObjectWithSite), 0, QueryObjectWithSiteInterface)
285        COM_INTERFACE_ENTRY(IModuleVersionInformation)
286        COM_INTERFACE_ENTRY(IFilterGraphMemoryAllocatorData)
287        COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_pInnerUnknown)
288        //COM_INTERFACE_ENTRY(IDispatch)
289END_COM_MAP()
290
291public:
292
293        ////////////////////////////////////////////////////////
294        // CAmGraphBuilderCallback
295
296        class ATL_NO_VTABLE CAmGraphBuilderCallback :
297                public CComObjectRootEx<CComMultiThreadModelNoCS>,
298                public IAMGraphBuilderCallback
299        {
300        public:
301
302        BEGIN_COM_MAP(CAmGraphBuilderCallback)
303                COM_INTERFACE_ENTRY(IAMGraphBuilderCallback)
304        END_COM_MAP()
305
306        private:
307                mutable CRoCriticalSection m_DataCriticalSection;
308                T* m_pSpy;
309
310                CObjectPtr<T> GetSpy() const
311                {
312                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
313                        return m_pSpy;
314                }
315
316        public:
317        // CAmGraphBuilderCallback
318                CAmGraphBuilderCallback() :
319                        m_pSpy(NULL)
320                {
321                        _Z5_THIS();
322                }
323                ~CAmGraphBuilderCallback()
324                {
325                        _Z5_THIS();
326                }
327                VOID Initialize(T* pSpy)
328                {
329                        _A(pSpy);
330                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
331                        _Z4(atlTraceRefcount, 4, _T("this 0x%p, pSpy 0x%p\n"), this, pSpy);
332                        _A(!m_pSpy);
333                        m_pSpy = pSpy;
334                }
335                VOID Terminate()
336                {
337                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
338                        m_pSpy = NULL;
339                }
340                BOOL SetGraphBuilder(const CComQIPtr<IObjectWithSite> pObjectWithSite)
341                {
342                        if(!pObjectWithSite)
343                                return FALSE;
344                        const HRESULT nSetSiteResult = pObjectWithSite->SetSite(this);
345                        if(SUCCEEDED(nSetSiteResult))
346                                return TRUE;
347                        _Z4_HRESULT(nSetSiteResult);
348                        return FALSE;
349                }
350                BOOL SetGraphBuilder(IUnknown* pObjectWithSiteUnknown)
351                {
352                        return SetGraphBuilder(CComQIPtr<IObjectWithSite>(pObjectWithSiteUnknown));
353                }
354
355        // IAMGraphBuilderCallback
356        STDMETHOD(SelectedFilter)(IMoniker* pMoniker)
357                {
358                        _Z4(atlTraceCOM, 4, _T("this 0x%p, pMoniker %ls\n"), this, _FilterGraphHelper::GetMonikerDisplayName(pMoniker));
359                        _ATLTRY
360                        {
361                                _A(pMoniker);
362                                const CObjectPtr<T> pSpy = GetSpy();
363                                HRESULT nSelectedFilterResult;
364                                if(pSpy)
365                                        if(pSpy->SelectedFilter(pMoniker, nSelectedFilterResult))
366                                        {
367                                                _Z4(atlTraceGeneral, 4, _T("this 0x%p, nSelectedFilterResult 0x%08X\n"), this, nSelectedFilterResult);
368                                                return nSelectedFilterResult;
369                                        }
370                        }
371                        _ATLCATCH(Exception)
372                        {
373                                _C(Exception);
374                        }
375                        return S_OK;
376                }
377                STDMETHOD(CreatedFilter)(IBaseFilter* pBaseFilter)
378                {
379                        _Z4(atlTraceCOM, 4, _T("this 0x%p, pBaseFilter 0x%p %ls \"%ls\"\n"), this, pBaseFilter, _FilterGraphHelper::GetFilterClassIdentifierString(pBaseFilter), _FilterGraphHelper::GetFilterName(pBaseFilter));
380                        _ATLTRY
381                        {
382                                _A(pBaseFilter);
383                                const CObjectPtr<T> pSpy = GetSpy();
384                                HRESULT nCreatedFilterResult;
385                                if(pSpy)
386                                        if(pSpy->CreatedFilter(pBaseFilter, nCreatedFilterResult))
387                                        {
388                                                _Z4(atlTraceGeneral, 4, _T("this 0x%p, nCreatedFilterResult 0x%08X\n"), this, nCreatedFilterResult);
389                                                return nCreatedFilterResult;
390                                        }
391                        }
392                        _ATLCATCH(Exception)
393                        {
394                                _C(Exception);
395                        }
396                        return S_OK;
397                }
398        };
399
400private:
401        BOOL m_bIsAggregated;
402        HINSTANCE m_hQuartzModule;
403        CComPtr<IUnknown> m_pInnerUnknown;
404        CComPtr<IFilterGraph2> m_pInnerFilterGraph2;
405        CComPtr<IFilterGraph3> m_pInnerFilterGraph3;
406        CComPtr<IMediaControl> m_pInnerMediaControl;
407        CComPtr<IMediaEventSink> m_pInnerMediaEventSink;
408        CComPtr<IMediaEventEx> m_pInnerMediaEventEx;
409        _FilterGraphHelper::CRotRunningFilterGraph m_RunningFilterGraph;
410        INT m_nRunningFilterGraphReference;
411        SYSTEMTIME m_Time;
412        CStringW m_sMonikerDisplayName;
413        CComPtr<IUnknown> m_pTemporaryUnknown;
414        CObjectPtr<CAmGraphBuilderCallback> m_pPrivateAmGraphBuilderCallback;
415        mutable CRoCriticalSection m_DataCriticalSection;
416        CComPtr<IUnknown> m_pSite;
417        CStringW m_sFriendlyName;
418
419        BOOL IsAggregated() const
420        {
421                return (ULONG) m_dwRef >= 0x00001000;
422        }
423        VOID ReleaseTemporaryUnknown()
424        {
425                CComPtr<IUnknown> pUnknown;
426                Lock();
427                SwapMemory(&m_pTemporaryUnknown.p, &pUnknown.p);
428                Unlock();
429        }
430        VOID SetRunningFilterGraph()
431        {
432                if(m_RunningFilterGraph.GetCookie())
433                        return;
434                _Z4(atlTraceRefcount, 4, _T("this 0x%p, m_dwRef %d\n"), this, m_dwRef);
435                m_nRunningFilterGraphReference = 0;
436                CInterlockedLong& nReferenceCount = reinterpret_cast<CInterlockedLong&>(m_dwRef);
437                const LONG nBeforeReferenceCount = m_dwRef;
438                SYSTEMTIME Time;
439                GetLocalTime(&Time);
440                CStringW sMonikerDisplayName;
441                static CConstIntegerRegistryValue g_nEnableRotMonikerItemNameSuffix(_T("Enable ROT Moniker Item Name Suffix")); // 0 Default (Enabled), 1 Disabled, 2 Enabled
442                if(g_nEnableRotMonikerItemNameSuffix != 1)
443                {
444                        TCHAR pszPath[MAX_PATH] = { 0 };
445                        _W(GetModuleFileName(NULL, pszPath, DIM(pszPath)));
446                        LPCTSTR pszName = FindFileName(pszPath);
447                        CString sItemName = AtlFormatString(_T("%s; process: %s, time: %02d-%02d-%02d"), m_RunningFilterGraph.GetDefaultMonikerItemName(GetControllingUnknown()), pszName, Time.wHour, Time.wMinute, Time.wSecond);
448                        m_RunningFilterGraph.SetFilterGraph(GetControllingUnknown(), CStringW(sItemName), &sMonikerDisplayName);
449                } else
450                        m_RunningFilterGraph.SetFilterGraph(GetControllingUnknown(), &sMonikerDisplayName);
451                _Z4(atlTraceRefcount, 4, _T("this 0x%p, m_bIsAggregated %d, m_dwRef %d, sMonikerDisplayName \"%ls\"\n"), this, m_bIsAggregated, m_dwRef, sMonikerDisplayName);
452                {
453                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
454                        m_Time = Time;
455                        m_sMonikerDisplayName = sMonikerDisplayName;
456                }
457                if(!m_bIsAggregated)
458                {
459                        m_nRunningFilterGraphReference++;
460                        const LONG nAfterReferenceCount = m_dwRef;
461                        if(nBeforeReferenceCount == nAfterReferenceCount)
462                        {
463                                // NOTE: Putting onto Running Object Table succeeded, however no external reference detected which we need to compensate by self-releasing
464                                m_nRunningFilterGraphReference++;
465                                return;
466                        }
467                }
468                Release();
469        }
470        VOID ResetRunningFilterGraph()
471        {
472                if(!m_RunningFilterGraph.GetCookie())
473                        return;
474                if(m_nRunningFilterGraphReference != 2)
475                        AddRef();
476                _Z4(atlTraceRefcount, 4, _T("this 0x%p, m_dwRef 0x%x\n"), this, m_dwRef);
477                m_RunningFilterGraph.SetFilterGraph(NULL);
478                {
479                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
480                        m_sMonikerDisplayName.Empty();
481                }
482                _Z4(atlTraceRefcount, 4, _T("this 0x%p, m_dwRef 0x%x\n"), this, m_dwRef);
483        }
484        HRESULT InternalQueryFilterGraph3Interface(REFIID InterfaceIdentifier, VOID** ppvObject)
485        {
486                _A(InterfaceIdentifier == __uuidof(IFilterGraph3));
487                _A(ppvObject);
488                if(!m_pInnerFilterGraph3)
489                {
490                        *ppvObject = NULL;
491                        return E_NOINTERFACE;
492                }
493                T* pT = static_cast<T*>(this);
494                *ppvObject = (IFilterGraph3*) pT;
495                pT->InternalAddRef();
496                return S_OK;
497        }
498        static HRESULT WINAPI QueryFilterGraph3Interface(VOID* pvThis, REFIID InterfaceIdentifier, VOID** ppvObject, DWORD_PTR)
499        {
500                return ((CSpy*) pvThis)->InternalQueryFilterGraph3Interface(InterfaceIdentifier, ppvObject);
501        }
502        HRESULT HookMediaControlAddSourceFilter(BSTR sFileName, IBaseFilter** ppBaseFilter, BOOL* pbDefault)
503        {
504                _A(pbDefault);
505                HOOK_PROLOG(CFilterGraphAddRemoveHookHost)
506                        OnAddSourceFilter(pT, sFileName, NULL, reinterpret_cast<IUnknown**>(ppBaseFilter), &bDefault);
507                        *pbDefault = bDefault;
508                HOOK_EPILOG()
509                return S_OK;
510        }
511
512public:
513// CSpyT
514        static LPCTSTR GetOriginalLibraryName()
515        {
516                return _T("quartz.dll");
517        }
518        static CString GetObjectFriendlyName()
519        {
520                return _StringHelper::GetLine(T::IDR, 2);
521        }
522        static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
523        {
524                _Z2(atlTraceRegistrar, 2, _T("bRegister %d\n"), bRegister);
525                _ATLTRY
526                {
527                        TreatAsUpdateRegistryFromResource<T>(*t_pFilterGraphClassIdentifier, bRegister);
528                }
529                _ATLCATCH(Exception)
530                {
531                        _C(Exception);
532                }
533                return S_OK;
534        }
535        CSpyT() :
536                m_hQuartzModule(NULL)
537        {
538                _Z4_THIS();
539                ZeroMemory(&m_Time, sizeof m_Time);
540        }
541        ~CSpyT()
542        {
543                _Z4_THIS();
544        }
545        HRESULT FinalConstruct()
546        {
547                m_bIsAggregated = IsAggregated();
548                if(!m_bIsAggregated)
549                        InternalAddRef();
550                _ATLTRY
551                {
552                        TCHAR pszPath[MAX_PATH] = { 0 };
553                        _W(GetModuleFileName(NULL, pszPath, DIM(pszPath)));
554                        _Z4(atlTraceRefcount, 4, _T("pszPath \"%s\", this 0x%p, m_dwRef %d, m_bIsAggregated %d\n"), pszPath, this, m_dwRef, m_bIsAggregated);
555                        const HINSTANCE hModule = CoLoadOriginalLibrary();
556                        _ATLTRY
557                        {
558                                _A(hModule);
559                                const CComPtr<IUnknown> pControllingUnknown = GetControllingUnknown();
560                                #pragma region Instantiation
561                                {
562                                        { 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); }
563                                        const CComPtr<IUnknown> pUnknown = CoCreateOriginalInstance(hModule, pControllingUnknown);
564                                        // NOTE: DirectShow FilterGraph is incorrectly implementing COM aggregation adding outer reference to interfaces queried from private IUnknown
565                                        const CComQIPtr<IFilterGraph2> pFilterGraph2 = pUnknown;
566                                        __D(pFilterGraph2, E_NOINTERFACE);
567                                        pFilterGraph2.p->Release();
568                                        const CComQIPtr<IFilterGraph3> pFilterGraph3 = pUnknown;
569                                        if(pFilterGraph3)
570                                                pFilterGraph3.p->Release();
571                                        const CComQIPtr<IMediaControl> pMediaControl = pUnknown;
572                                        __D(pMediaControl, E_NOINTERFACE);
573                                        pMediaControl.p->Release();
574                                        const CComQIPtr<IMediaEventSink> pMediaEventSink = pUnknown;
575                                        __D(pMediaEventSink, E_NOINTERFACE);
576                                        pMediaEventSink.p->Release();
577                                        const CComQIPtr<IMediaEventEx> pMediaEventEx = pUnknown;
578                                        __D(pMediaEventEx, E_NOINTERFACE);
579                                        pMediaEventEx.p->Release();
580                                        #pragma region ROT Registration
581                                        { 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); }
582                                        SetRunningFilterGraph();
583                                        { 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); }
584                                        #pragma endregion
585                                        m_pInnerUnknown = pUnknown;
586                                        m_pInnerFilterGraph2 = pFilterGraph2;
587                                        m_pInnerFilterGraph3 = pFilterGraph3;
588                                        m_pInnerMediaControl = pMediaControl;
589                                        m_pInnerMediaEventSink = pMediaEventSink;
590                                        m_pInnerMediaEventEx = pMediaEventEx;
591                                }
592                                #pragma endregion
593                                #pragma region Set Private IAMGraphBuilderCallback
594                                static CConstIntegerRegistryValue g_nSetPrivateCallback(_T("Set Private CSpyT IAMGraphBuilderCallback")); // 0 Default (Enabled), 1 Disabled, 2 Enabled
595                                const DWORD nSetPrivateCallback = g_nSetPrivateCallback;
596                                if(nSetPrivateCallback != 1)
597                                {
598                                        CObjectPtr<CAmGraphBuilderCallback> pAmGraphBuilderCallback;
599                                        pAmGraphBuilderCallback.Construct();
600                                        pAmGraphBuilderCallback->Initialize(static_cast<T*>(this));
601                                        // WARN: Private site only forwards IAMGraphBuilderCallback interface and indicates other as not implemented
602                                        //       even if the external site does provide such implementation
603                                        if(pAmGraphBuilderCallback->SetGraphBuilder(pControllingUnknown))
604                                                m_pPrivateAmGraphBuilderCallback = pAmGraphBuilderCallback;
605                                        else
606                                                pAmGraphBuilderCallback->Terminate();
607                                }
608                                #pragma endregion
609                                #pragma region Temporary Reference for Aggregated Instantiation
610                                if(m_bIsAggregated)
611                                {
612                                        pControllingUnknown.p->AddRef();
613                                        const ULONG nReferenceCount = pControllingUnknown.p->Release();
614                                        if(nReferenceCount == 1)
615                                                m_pTemporaryUnknown = pControllingUnknown;
616                                }
617                                #pragma endregion
618                        }
619                        _ATLCATCHALL()
620                        {
621                                CoFreeLibrary(hModule);
622                                _ATLRETHROW;
623                        }
624                        #if defined(_DEBUG) && FALSE
625                                typedef HRESULT (WINAPI *DLLCANUNLOADNOW)();
626                                DLLCANUNLOADNOW DllCanUnloadNow = (DLLCANUNLOADNOW) GetProcAddress(hModule, "DllCanUnloadNow");
627                                __E(DllCanUnloadNow);
628                                const HRESULT nDllCanUnloadNowResult = DllCanUnloadNow();
629                                _Z4_HRESULT(nDllCanUnloadNowResult); 
630                        #endif // defined(_DEBUG)
631                        _A(!m_hQuartzModule);
632                        m_hQuartzModule = hModule;
633                        #pragma region Extra Reference
634                        // NOTE: This feature allows to leave an extra COM reference on the object to extend its lifetime and work around early destruction issues
635                        static CConstIntegerRegistryValue g_nAddExtraReference(_T("Add Extra CSpyT Reference")); // 0 Default (Disabled), 1 Not Aggregated Only, 2 Aggregated Only, 3 Both
636                        const DWORD nAddExtraReference = g_nAddExtraReference;
637                        if(!m_bIsAggregated)
638                        {
639                                if(nAddExtraReference & 1)
640                                        InternalAddRef();
641                        } else
642                                if(nAddExtraReference & 2)
643                                        GetControllingUnknown()->AddRef();
644                        #pragma endregion
645                }
646                _ATLCATCH(Exception)
647                {
648                        if(!m_bIsAggregated)
649                                _W(InternalRelease() > 0);
650                        _C(Exception);
651                }
652                // NOTE: x64 build experiences a problem under COM Surrogate process that we're already being released to zero while still in this method
653                if(!m_bIsAggregated)
654                        if(InternalRelease() <= 0)
655                                return E_UNEXPECTED;
656                return S_OK;
657        }
658        VOID FinalRelease()
659        {
660                _Z5(atlTraceRefcount, 5, _T("m_dwRef 0x%x\n"), m_dwRef);
661                _A(!m_pTemporaryUnknown);
662                const CComPtr<IUnknown> pControllingUnknown = GetControllingUnknown();
663                #pragma region Reset Private IAMGraphBuilderCallback
664                if(m_pPrivateAmGraphBuilderCallback)
665                {
666                        m_pPrivateAmGraphBuilderCallback->Terminate();
667                        m_pPrivateAmGraphBuilderCallback = NULL;
668                }
669                #pragma endregion
670                ResetRunningFilterGraph();
671                #pragma region Release Secondary Inner Interfaces
672                if(m_pInnerMediaEventEx)
673                {
674                        pControllingUnknown.p->AddRef();
675                        m_pInnerMediaEventEx = NULL;
676                }
677                if(m_pInnerMediaEventSink)
678                {
679                        pControllingUnknown.p->AddRef();
680                        m_pInnerMediaEventSink = NULL;
681                }
682                if(m_pInnerMediaControl)
683                {
684                        pControllingUnknown.p->AddRef();
685                        m_pInnerMediaControl = NULL;
686                }
687                if(m_pInnerFilterGraph3)
688                {
689                        pControllingUnknown.p->AddRef();
690                        m_pInnerFilterGraph3 = NULL;
691                }
692                if(m_pInnerFilterGraph2)
693                {
694                        pControllingUnknown.p->AddRef();
695                        m_pInnerFilterGraph2 = NULL;
696                }
697                #pragma endregion
698                #pragma region Release Primary Inner IUnknown
699                _ATLTRY
700                {
701                        m_pInnerUnknown = NULL;
702                }
703                _ATLCATCHALL()
704                {
705                        _Z_EXCEPTION();
706                        // NOTE: For some unidentified reason Quartz's FilterGraph may crash during final release, to smooth the effect the exception is silently caught
707                        m_pInnerUnknown.p = NULL;
708                }
709                #pragma endregion
710                #pragma region Release Quartz Library
711                if(m_hQuartzModule)
712                {
713                        CoFreeLibrary(m_hQuartzModule);
714                        m_hQuartzModule = NULL;
715                }
716                #pragma endregion
717        }
718        HRESULT QueryObjectWithSiteInterface(REFIID InterfaceIdentifier, LPVOID* ppvObject)
719        {
720                _A(InterfaceIdentifier == __uuidof(IObjectWithSite));
721                _A(ppvObject);
722                if(m_pPrivateAmGraphBuilderCallback)
723                {
724                        *ppvObject = CComPtr<IObjectWithSite>(static_cast<T*>(this)).Detach();
725                        return S_OK;
726                }
727                _A(m_pInnerUnknown);
728                return m_pInnerUnknown->QueryInterface(InterfaceIdentifier, ppvObject);
729        }
730        static HRESULT WINAPI QueryObjectWithSiteInterface(VOID* pvInstance, REFIID InterfaceIdentifier, LPVOID* ppvObject, DWORD_PTR)
731        {
732                return ((CSpy*) pvInstance)->QueryObjectWithSiteInterface(InterfaceIdentifier, ppvObject);
733        }
734        CComPtr<IUnknown> GetSite() const
735        {
736                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
737                return m_pSite;
738        }
739        BOOL SelectedFilter(IMoniker* pMoniker, HRESULT& nSelectedFilterResult)
740        {
741                const CComQIPtr<IAMGraphBuilderCallback> pAmGraphBuilderCallback = GetSite();
742                if(pAmGraphBuilderCallback)
743                {
744                        nSelectedFilterResult = pAmGraphBuilderCallback->SelectedFilter(pMoniker);
745                        return TRUE;
746                }
747                return FALSE;
748        }
749        BOOL CreatedFilter(IBaseFilter* pBaseFilter, HRESULT& nCreatedFilterResult)
750        {
751                const CComQIPtr<IAMGraphBuilderCallback> pAmGraphBuilderCallback = GetSite();
752                if(pAmGraphBuilderCallback)
753                {
754                        nCreatedFilterResult = pAmGraphBuilderCallback->CreatedFilter(pBaseFilter);
755                        return TRUE;
756                }
757                return FALSE;
758        }
759        static BOOL LookupEventCodeName(LONG nEventCode, LPCSTR& pszName)
760        {
761                // NOTE: See Windows SDK evcode.h
762                static const struct { LONG nEventCode; LPCSTR pszName; } g_pMap[] = 
763                {
764                        #define A(x) { x, #x },
765                        A(EC_COMPLETE)
766                        A(EC_USERABORT)
767                        A(EC_ERRORABORT)
768                        A(EC_TIME)
769                        A(EC_REPAINT)
770                        A(EC_STREAM_ERROR_STOPPED)
771                        A(EC_STREAM_ERROR_STILLPLAYING)
772                        A(EC_ERROR_STILLPLAYING)
773                        A(EC_PALETTE_CHANGED)
774                        A(EC_VIDEO_SIZE_CHANGED)
775                        A(EC_QUALITY_CHANGE)
776                        A(EC_SHUTTING_DOWN)
777                        A(EC_CLOCK_CHANGED)
778                        A(EC_PAUSED)
779                        A(EC_OPENING_FILE)
780                        A(EC_BUFFERING_DATA)
781                        A(EC_FULLSCREEN_LOST)
782                        A(EC_ACTIVATE)
783                        A(EC_NEED_RESTART)
784                        A(EC_WINDOW_DESTROYED)
785                        A(EC_DISPLAY_CHANGED)
786                        A(EC_STARVATION)
787                        A(EC_OLE_EVENT)
788                        A(EC_NOTIFY_WINDOW)
789                        A(EC_STREAM_CONTROL_STOPPED)
790                        A(EC_STREAM_CONTROL_STARTED)
791                        A(EC_END_OF_SEGMENT)
792                        A(EC_SEGMENT_STARTED)
793                        A(EC_LENGTH_CHANGED)
794                        A(EC_DEVICE_LOST)
795                        A(EC_SAMPLE_NEEDED)
796                        A(EC_PROCESSING_LATENCY)
797                        A(EC_SAMPLE_LATENCY)
798                        A(EC_SCRUB_TIME)
799                        A(EC_STEP_COMPLETE)
800                        #undef A
801                };
802                for(SIZE_T nIndex = 0; nIndex < DIM(g_pMap); nIndex++)
803                        if(g_pMap[nIndex].nEventCode == nEventCode)
804                        {
805                                pszName = g_pMap[nIndex].pszName;
806                                return TRUE;
807                        }
808                return FALSE;
809        }
810        CStringW GetMonikerDisplayName() const
811        {
812                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
813                return m_sMonikerDisplayName;
814        }
815
816// ISpy
817    STDMETHOD(get_MonikerDisplayName)(BSTR* psMonikerDisplayName)
818        {
819                _Z4(atlTraceCOM, 4, _T("this 0x%p\n"), this);
820                _ATLTRY
821                {
822                        __D(psMonikerDisplayName, E_POINTER);
823                        *psMonikerDisplayName = CComBSTR(GetMonikerDisplayName()).Detach();
824                }
825                _ATLCATCHALL()
826                {
827                        _Z_EXCEPTION();
828                }
829                return S_OK;
830        }
831        STDMETHOD(get_CreationTime)(DATE* pfTime)
832        {
833                _Z4(atlTraceCOM, 4, _T("this 0x%p\n"), this);
834                _ATLTRY
835                {
836                        __D(pfTime, E_POINTER);
837                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
838                        FILETIME LocalFileTime, FileTime;
839                        _W(SystemTimeToFileTime(&m_Time, &LocalFileTime));
840                        _W(LocalFileTimeToFileTime(&LocalFileTime, &FileTime));
841                        SYSTEMTIME Time;
842                        _W(FileTimeToSystemTime(&FileTime, &Time));
843                        _W(SystemTimeToVariantTime(&Time, pfTime));
844                }
845                _ATLCATCHALL()
846                {
847                        _Z_EXCEPTION();
848                }
849                return S_OK;
850        }
851        STDMETHOD(get_FriendlyName)(BSTR* psFriendlyName)
852        {
853                _Z4(atlTraceCOM, 4, _T("this 0x%p\n"), this);
854                _ATLTRY
855                {
856                        __D(psFriendlyName, E_POINTER);
857                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
858                        *psFriendlyName = CComBSTR(m_sFriendlyName).Detach();
859                }
860                _ATLCATCHALL()
861                {
862                        _Z_EXCEPTION();
863                }
864                return S_OK;
865        }
866        STDMETHOD(put_FriendlyName)(BSTR sFriendlyName)
867        {
868                _Z4(atlTraceCOM, 4, _T("this 0x%p, sFriendlyName \"%s\"\n"), this, CString(sFriendlyName));
869                _ATLTRY
870                {
871                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
872                        m_sFriendlyName = sFriendlyName;
873                }
874                _ATLCATCHALL()
875                {
876                        _Z_EXCEPTION();
877                }
878                return S_OK;
879        }
880        STDMETHOD(DoPropertyFrameModal)(LONG nParentWindowHandle)
881        {
882                _Z4(atlTraceCOM, 4, _T("this 0x%p, nParentWindowHandle 0x%08X\n"), this, nParentWindowHandle);
883                _ATLTRY
884                {
885                        T* pT = static_cast<T*>(this);
886                        return FilterGraphHelper_DoPropertyFrameModal(nParentWindowHandle, (IFilterGraph*) CComQIPtr<IFilterGraph>(pT));
887                }
888                _ATLCATCHALL()
889                {
890                        _Z_EXCEPTION();
891                }
892                return S_OK;
893        }
894        STDMETHOD(DoFilterGraphListModal)(LONG nParentWindowHandle)
895        {
896                _Z4(atlTraceCOM, 4, _T("this 0x%p, nParentWindowHandle 0x%08X\n"), this, nParentWindowHandle);
897                _ATLTRY
898                {
899                        return FilterGraphHelper_DoFilterGraphListModal(nParentWindowHandle);
900                }
901                _ATLCATCHALL()
902                {
903                        _Z_EXCEPTION();
904                }
905                return S_OK;
906        }
907        STDMETHOD(OpenGraphStudioNext)(LONG nParentWindowHandle, VARIANT_BOOL* pbResult)
908        {
909                _Z4(atlTraceCOM, 4, _T("this 0x%p, nParentWindowHandle 0x%08X\n"), this, nParentWindowHandle);
910                _ATLTRY
911                {
912                        return FilterGraphHelper_OpenGraphStudioNext(nParentWindowHandle, GetMonikerDisplayName(), pbResult);
913                }
914                _ATLCATCHALL()
915                {
916                        _Z_EXCEPTION();
917                }
918                return S_OK;
919        }
920        STDMETHOD(OpenGraphEdit)(LONG nParentWindowHandle, VARIANT_BOOL* pbResult)
921        {
922                _Z4(atlTraceCOM, 4, _T("this 0x%p, nParentWindowHandle 0x%08X\n"), this, nParentWindowHandle);
923                _ATLTRY
924                {
925                        return FilterGraphHelper_OpenGraphEdit(nParentWindowHandle, GetMonikerDisplayName(), pbResult);
926                }
927                _ATLCATCHALL()
928                {
929                        _Z_EXCEPTION();
930                }
931                return S_OK;
932        }
933        STDMETHOD(ReadRunPropertyBag)(IUnknown* pBaseFilterUnknown, VARIANT_BOOL bAllowExtension, VARIANT* pvValue)
934        {
935                _Z4(atlTraceCOM, 4, _T("this 0x%p, pBaseFilterUnknown 0x%p, bAllowExtension %d\n"), this, pBaseFilterUnknown, bAllowExtension);
936                _ATLTRY
937                {
938                        __D(pBaseFilterUnknown, E_INVALIDARG);
939                        __D(pvValue, E_POINTER);
940                        VariantInit(pvValue);
941                        _V(CRunPropertyBagHelper::ReadRunPropertyBag(pBaseFilterUnknown, bAllowExtension != ATL_VARIANT_FALSE).Detach(pvValue));
942                }
943                _ATLCATCHALL()
944                {
945                        _Z_EXCEPTION();
946                }
947                return S_OK;
948        }
949
950// ISpyEx
951
952// IFilterGraph
953        STDMETHOD(AddFilter)(IBaseFilter* pBaseFilter, LPCWSTR pszName)
954        {
955                _Z4(atlTraceCOM, 4, _T("this 0x%p, pBaseFilter 0x%p %ls, pszName \"%s\"\n"), this, pBaseFilter, _FilterGraphHelper::GetFilterClassIdentifierString(pBaseFilter), CString(pszName));
956                ReleaseTemporaryUnknown();
957                HOOK_PROLOG(CFilterGraphAddRemoveHookHost)
958                        OnAddFilter(pT, pBaseFilter, pszName, &bDefault);
959                HOOK_EPILOG()
960                const HRESULT nResult = m_pInnerFilterGraph2->AddFilter(pBaseFilter, pszName);
961                if(SUCCEEDED(nResult))
962                        _ATLTRY
963                        {
964                                const CStringW sName = _FilterGraphHelper::GetFilterName(pBaseFilter);
965                                _Z4(atlTraceGeneral, 4, _T("this 0x%p, sName \"%ls\"\n"), this, sName);
966                        }
967                        _ATLCATCHALL()
968                        {
969                                _Z_EXCEPTION();
970                        }
971                return nResult;
972        }
973    STDMETHOD(RemoveFilter)(IBaseFilter* pBaseFilter)
974        {
975                _Z4(atlTraceCOM, 4, _T("this 0x%p, pBaseFilter 0x%p\n"), this, pBaseFilter);
976                if(pBaseFilter)
977                        _ATLTRY
978                        {
979                                const CStringW sName = _FilterGraphHelper::GetFilterName(pBaseFilter);
980                                _Z4(atlTraceGeneral, 4, _T("this 0x%p, sName \"%ls\"\n"), this, sName);
981                        }
982                        _ATLCATCHALL()
983                        {
984                                _Z_EXCEPTION();
985                        }
986                HOOK_PROLOG(CFilterGraphAddRemoveHookHost)
987                        OnRemoveFilter(pT, pBaseFilter, &bDefault);
988                HOOK_EPILOG()
989                return m_pInnerFilterGraph2->RemoveFilter(pBaseFilter);
990        }
991    STDMETHOD(EnumFilters)(IEnumFilters** ppEnumFilters)
992        {
993                _Z4(atlTraceCOM, 4, _T("...\n"));
994                return m_pInnerFilterGraph2->EnumFilters(ppEnumFilters);
995        }
996    STDMETHOD(FindFilterByName)(LPCWSTR pszName, IBaseFilter** ppFilter)
997        {
998                _Z4(atlTraceCOM, 4, _T("pszName \"%s\"\n"), CString(pszName));
999                return m_pInnerFilterGraph2->FindFilterByName(pszName, ppFilter);
1000        }
1001    STDMETHOD(ConnectDirect)(IPin* pOutputPin, IPin* pInputPin, const AM_MEDIA_TYPE* pMediaType)
1002        {
1003                _Z4(atlTraceCOM, 4, _T("...\n"));
1004                if(pOutputPin && pInputPin)
1005                        _ATLTRY
1006                        {
1007                                _Z4(atlTraceGeneral, 4, _T("pOutputPin \"%ls\", pInputPin \"%ls\"\n"), _FilterGraphHelper::GetPinFullName(pOutputPin), _FilterGraphHelper::GetPinFullName(pInputPin));
1008                                if(pMediaType)
1009                                        _FilterGraphHelper::TraceMediaType(pMediaType);
1010                        }
1011                        _ATLCATCHALL()
1012                        {
1013                                _Z_EXCEPTION();
1014                        }
1015                HOOK_PROLOG(CFilterGraphConnectHookHost)
1016                        OnConnectDirect(pT, pOutputPin, pInputPin, (const BYTE*) pMediaType, &bDefault);
1017                HOOK_EPILOG()
1018                return m_pInnerFilterGraph2->ConnectDirect(pOutputPin, pInputPin, pMediaType);
1019        }
1020    STDMETHOD(Reconnect)(IPin* pPin)
1021        {
1022                _Z4(atlTraceCOM, 4, _T("...\n"));
1023                HOOK_PROLOG(CFilterGraphConnectHookHost)
1024                        OnReconnect(pT, pPin, &bDefault);
1025                HOOK_EPILOG()
1026                return m_pInnerFilterGraph2->Reconnect(pPin);
1027        }
1028    STDMETHOD(Disconnect)(IPin* pPin)
1029        {
1030                _Z4(atlTraceCOM, 4, _T("...\n"));
1031                HOOK_PROLOG(CFilterGraphConnectHookHost)
1032                        OnDisconnect(pT, pPin, &bDefault);
1033                HOOK_EPILOG()
1034                return m_pInnerFilterGraph2->Disconnect(pPin);
1035        }
1036    STDMETHOD(SetDefaultSyncSource)()
1037        {
1038                _Z4(atlTraceCOM, 4, _T("...\n"));
1039                return m_pInnerFilterGraph2->SetDefaultSyncSource();
1040        }
1041
1042// IGraphBuilder
1043    STDMETHOD(Connect)(IPin* pOutputPin, IPin* pInputPin)
1044        {
1045                _Z4(atlTraceCOM, 4, _T("pOutputPin 0x%p, pInputPin 0x%p\n"), pOutputPin, pInputPin);
1046                if(pOutputPin && pInputPin)
1047                        _ATLTRY
1048                        {
1049                                _Z4(atlTraceGeneral, 4, _T("this 0x%p, pOutputPin 0x%p \"%ls\" (filter 0x%p), pInputPin 0x%p \"%ls\" (filter 0x%p)\n"), this, 
1050                                        pOutputPin, _FilterGraphHelper::GetPinFullName(pOutputPin), _FilterGraphHelper::GetPinFilter(pOutputPin),
1051                                        pInputPin, _FilterGraphHelper::GetPinFullName(pInputPin), _FilterGraphHelper::GetPinFilter(pInputPin),
1052                                        0);
1053                        }
1054                        _ATLCATCHALL()
1055                        {
1056                                _Z_EXCEPTION();
1057                        }
1058                HOOK_PROLOG(CFilterGraphConnectHookHost)
1059                        OnConnect(pT, pOutputPin, pInputPin, &bDefault);
1060                HOOK_EPILOG()
1061                return m_pInnerFilterGraph2->Connect(pOutputPin, pInputPin);
1062        }
1063    STDMETHOD(Render)(IPin* pOutputPin)
1064        {
1065                _Z4(atlTraceCOM, 4, _T("...\n"));
1066                return m_pInnerFilterGraph2->Render(pOutputPin);
1067        }
1068    STDMETHOD(RenderFile)(LPCWSTR pszFileName, LPCWSTR pszPlayListFileName)
1069        {
1070                _Z4(atlTraceCOM, 4, _T("pszFileName \"%s\", pszPlayListFileName \"%s\"\n"), CString(pszFileName), CString(pszPlayListFileName));
1071                return m_pInnerFilterGraph2->RenderFile(pszFileName, pszPlayListFileName);
1072        }
1073    STDMETHOD(AddSourceFilter)(LPCWSTR pszFileName, LPCWSTR pszFilterName, IBaseFilter** ppBaseFilter)
1074        {
1075                _Z4(atlTraceCOM, 4, _T("pszFileName \"%s\", pszFilterName \"%s\"\n"), CString(pszFileName), CString(pszFilterName));
1076                ReleaseTemporaryUnknown();
1077                HOOK_PROLOG(CFilterGraphAddRemoveHookHost)
1078                        OnAddSourceFilter(pT, pszFileName, pszFilterName, reinterpret_cast<IUnknown**>(ppBaseFilter), &bDefault);
1079                HOOK_EPILOG()
1080                return m_pInnerFilterGraph2->AddSourceFilter(pszFileName, pszFilterName, ppBaseFilter);
1081        }
1082        STDMETHOD(SetLogFile)(DWORD_PTR hFile)
1083        {
1084                _Z4(atlTraceCOM, 4, _T("...\n"));
1085                return m_pInnerFilterGraph2->SetLogFile(hFile);
1086        }
1087        STDMETHOD(Abort)()
1088        {
1089                _Z4(atlTraceCOM, 4, _T("...\n"));
1090                return m_pInnerFilterGraph2->Abort();
1091        }
1092        STDMETHOD(ShouldOperationContinue)()
1093        {
1094                _Z4(atlTraceCOM, 4, _T("...\n"));
1095                return m_pInnerFilterGraph2->ShouldOperationContinue();
1096        }
1097
1098// IFilterGraph2
1099        STDMETHOD(AddSourceFilterForMoniker)(IMoniker* pMoniker, IBindCtx* pBindCtx, LPCWSTR pszFilterName, IBaseFilter** ppBaseFilter)
1100        {
1101                _Z4(atlTraceCOM, 4, _T("pszFilterName \"%s\"\n"), CString(pszFilterName));
1102                ReleaseTemporaryUnknown();
1103                HOOK_PROLOG(CFilterGraphAddRemoveHookHost)
1104                        OnAddSourceFilterForMoniker(pT, pMoniker, pBindCtx, pszFilterName, reinterpret_cast<IUnknown**>(ppBaseFilter), &bDefault);
1105                HOOK_EPILOG()
1106                return m_pInnerFilterGraph2->AddSourceFilterForMoniker(pMoniker, pBindCtx, pszFilterName, ppBaseFilter);
1107        }
1108        STDMETHOD(ReconnectEx)(IPin* pPin, const AM_MEDIA_TYPE* pMediaType)
1109        {
1110                _Z4(atlTraceCOM, 4, _T("...\n"));
1111                HOOK_PROLOG(CFilterGraphConnectHookHost)
1112                        OnReconnectEx(pT, pPin, (const BYTE*) pMediaType, &bDefault);
1113                HOOK_EPILOG()
1114                return m_pInnerFilterGraph2->ReconnectEx(pPin, pMediaType);
1115        }
1116        STDMETHOD(RenderEx)(IPin* pOutputPin, DWORD nFlags, DWORD* pnContext)
1117        {
1118                _Z4(atlTraceCOM, 4, _T("nFlags 0x%x\n"), nFlags);
1119                return m_pInnerFilterGraph2->RenderEx(pOutputPin, nFlags, pnContext);
1120        }
1121
1122// IFilterGraph3
1123    STDMETHOD(SetSyncSourceEx)(IReferenceClock* pFilterGraphReferenceClock, IReferenceClock* pFilterReferenceClock, IBaseFilter* pBaseFilter)
1124        {
1125                _Z4(atlTraceCOM, 4, _T("...\n"));
1126                _A(m_pInnerFilterGraph3);
1127                return m_pInnerFilterGraph3->SetSyncSourceEx(pFilterGraphReferenceClock, pFilterReferenceClock, pBaseFilter);
1128        }
1129
1130// IMediaControl
1131        STDMETHOD(Run)()
1132        {
1133                _Z4(atlTraceCOM, 4, _T("...\n"));
1134                _ATLTRY
1135                {
1136                        OAFilterState State = (OAFilterState) -1;
1137                        if(SUCCEEDED(m_pInnerMediaControl->GetState(0, &State)) && State == State_Stopped)
1138                                _FilterGraphHelper::TraceGraphBuilder(this);
1139                }
1140                _ATLCATCHALL()
1141                {
1142                        _Z_EXCEPTION();
1143                }
1144                HOOK_PROLOG(CFilterGraphStateControlHookHost)
1145                        OnRun(pT, &bDefault);
1146                HOOK_EPILOG()
1147                const HRESULT nRunResult = m_pInnerMediaControl->Run();
1148                _Z4_DSHRESULT(nRunResult);
1149                return nRunResult;
1150        }
1151        STDMETHOD(Pause)()
1152        {
1153                _Z4(atlTraceCOM, 4, _T("...\n"));
1154                _ATLTRY
1155                {
1156                        OAFilterState State = (OAFilterState) -1;
1157                        if(SUCCEEDED(m_pInnerMediaControl->GetState(0, &State)) && State == State_Stopped)
1158                                _FilterGraphHelper::TraceGraphBuilder(this);
1159                }
1160                _ATLCATCHALL()
1161                {
1162                        _Z_EXCEPTION();
1163                }
1164                HOOK_PROLOG(CFilterGraphStateControlHookHost)
1165                        OnPause(pT, &bDefault);
1166                HOOK_EPILOG()
1167                return m_pInnerMediaControl->Pause();
1168        }
1169        STDMETHOD(Stop)()
1170        {
1171                _Z4(atlTraceCOM, 4, _T("...\n"));
1172                HOOK_PROLOG(CFilterGraphStateControlHookHost)
1173                        OnStop(pT, &bDefault);
1174                HOOK_EPILOG()
1175                return m_pInnerMediaControl->Stop();
1176        }
1177        STDMETHOD(GetState)(LONG nTimeout, OAFilterState* pState)
1178        {
1179                _Z5(atlTraceCOM, 5, _T("nTimeout %d\n"), nTimeout);
1180                return m_pInnerMediaControl->GetState(nTimeout, pState);
1181        }
1182        STDMETHOD(RenderFile)(BSTR sFileName)
1183        {
1184                _Z4(atlTraceCOM, 4, _T("sFileName \"%s\"\n"), CString(sFileName));
1185                return m_pInnerMediaControl->RenderFile(sFileName);
1186        }
1187    STDMETHOD(AddSourceFilter)(BSTR sFileName, IDispatch** ppDispatch)
1188        {
1189                _Z4(atlTraceCOM, 4, _T("sFileName \"%s\"\n"), CString(sFileName));
1190                ReleaseTemporaryUnknown();
1191                _ATLTRY
1192                {
1193                        CComPtr<IBaseFilter> pBaseFilter;
1194                        BOOL bDefault = TRUE;
1195                        const HRESULT nResult = HookMediaControlAddSourceFilter(sFileName, &pBaseFilter, &bDefault);
1196                        if(!bDefault)
1197                        {
1198                                __D(ppDispatch, E_POINTER);
1199                                *ppDispatch = NULL;
1200                                if(SUCCEEDED(nResult))
1201                                {
1202                                        CComQIPtr<IDispatch> pDispatch = pBaseFilter;
1203                                        __D(pDispatch, E_NOINTERFACE);
1204                                        *ppDispatch = pDispatch.Detach();
1205                                }
1206                                return nResult;
1207                        }
1208                }
1209                _ATLCATCH(Exception)
1210                {
1211                        _C(Exception);
1212                }
1213                return m_pInnerMediaControl->AddSourceFilter(sFileName, ppDispatch);
1214        }
1215        STDMETHOD(get_FilterCollection)(IDispatch** ppDispatch)
1216        {
1217                _Z4(atlTraceCOM, 4, _T("...\n"));
1218                ReleaseTemporaryUnknown();
1219                return m_pInnerMediaControl->get_FilterCollection(ppDispatch);
1220        }
1221        STDMETHOD(get_RegFilterCollection)(IDispatch** ppDispatch)
1222        {
1223                _Z4(atlTraceCOM, 4, _T("...\n"));
1224                ReleaseTemporaryUnknown();
1225                return m_pInnerMediaControl->get_RegFilterCollection(ppDispatch);
1226        }
1227        STDMETHOD(StopWhenReady)()
1228        {
1229                _Z4(atlTraceCOM, 4, _T("...\n"));
1230                return m_pInnerMediaControl->StopWhenReady();
1231        }
1232
1233// IMediaEventSink
1234    STDMETHOD(Notify)(LONG nEventCode, LONG_PTR nParameter1, LONG_PTR nParameter2)
1235        {
1236                #if TRUE
1237                        LPCSTR pszEventName = NULL;
1238                        if(LookupEventCodeName(nEventCode, pszEventName))
1239                        {
1240                                _Z4(atlTraceCOM, 4, _T("nEventCode %hs (0x%02X), nParameter1 0x%p, nParameter2 0x%p\n"), pszEventName, nEventCode, nParameter1, nParameter2);
1241                        } else
1242                #endif
1243                _Z4(atlTraceCOM, 4, _T("nEventCode 0x%02X, nParameter1 0x%p, nParameter2 0x%p\n"), nEventCode, nParameter1, nParameter2);
1244                #if defined(_M_IX86)
1245                        // WARN: Guarding section around might be preventing from walknig frame up the stack
1246                        if(nEventCode == EC_ERRORABORT) // || nEventCode == EC_VIDEO_SIZE_CHANGED)
1247                        {
1248                                CONTEXT ThreadContext = { CONTEXT_FULL };
1249                                GetCurrentThreadContext(&ThreadContext);
1250                                CDebugTraceCallStack::TraceCallStack(ThreadContext, 32); //(nEventCode == EC_ERRORABORT) ? 32 : 8);
1251                        }
1252                #endif // defined(_M_IX86)
1253                if(!m_pInnerMediaEventSink)
1254                        return S_FALSE;
1255                return m_pInnerMediaEventSink->Notify(nEventCode, nParameter1, nParameter2);
1256        }
1257
1258// IMediaEvent
1259        STDMETHOD(GetEventHandle)(OAEVENT* pnEventHandle)
1260        {
1261                _Z4(atlTraceCOM, 4, _T("...\n"));
1262                return m_pInnerMediaEventEx->GetEventHandle(pnEventHandle);
1263        }
1264        STDMETHOD(GetEvent)(LONG* pnEventCode, LONG_PTR* pnParameter1, LONG_PTR* pnParameter2, LONG nTimeout)
1265        {
1266                _Z4(atlTraceCOM, nTimeout ? 4 : 5, _T("nTimeout %d\n"), nTimeout);
1267                const HRESULT nGetEventResult = m_pInnerMediaEventEx->GetEvent(pnEventCode, pnParameter1, pnParameter2, nTimeout);
1268                if(pnEventCode && pnParameter1 && pnParameter2)
1269                        _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);
1270                return nGetEventResult;
1271        }
1272        STDMETHOD(WaitForCompletion)(LONG nTimeout, LONG* pnEventCode)
1273        {
1274                _Z4(atlTraceCOM, 4, _T("nTimeout %d\n"), nTimeout);
1275                const HRESULT nWaitForCompletionResult = m_pInnerMediaEventEx->WaitForCompletion(nTimeout, pnEventCode);
1276                if(pnEventCode)
1277                        _Z4(atlTraceCOM, 4, _T("nWaitForCompletionResult 0x%x, *pnEventCode 0x%02X\n"), nWaitForCompletionResult, *pnEventCode);
1278                return nWaitForCompletionResult;
1279        }
1280        STDMETHOD(CancelDefaultHandling)(LONG nEventCode)
1281        {
1282                #if TRUE
1283                        LPCSTR pszEventName = NULL;
1284                        if(LookupEventCodeName(nEventCode, pszEventName))
1285                        {
1286                                _Z4(atlTraceCOM, 4, _T("nEventCode %hs (0x%02X)\n"), pszEventName, nEventCode);
1287                        } else
1288                #endif
1289                _Z4(atlTraceCOM, 4, _T("nEventCode 0x%02X\n"), nEventCode);
1290                return m_pInnerMediaEventEx->CancelDefaultHandling(nEventCode);
1291        }
1292        STDMETHOD(RestoreDefaultHandling)(LONG nEventCode)
1293        {
1294                #if TRUE
1295                        LPCSTR pszEventName = NULL;
1296                        if(LookupEventCodeName(nEventCode, pszEventName))
1297                        {
1298                                _Z4(atlTraceCOM, 4, _T("nEventCode %hs (0x%02X)\n"), pszEventName, nEventCode);
1299                        } else
1300                #endif
1301                _Z4(atlTraceCOM, 4, _T("nEventCode 0x%02X\n"), nEventCode);
1302                return m_pInnerMediaEventEx->RestoreDefaultHandling(nEventCode);
1303        }
1304        STDMETHOD(FreeEventParams)(LONG nEventCode, LONG_PTR nParameter1, LONG_PTR nParameter2)
1305        {
1306                _Z4(atlTraceCOM, 4, _T("nEventCode 0x%02X, nParameter1 0x%p, nParameter2 0x%p\n"), nEventCode, nParameter1, nParameter2);
1307                return m_pInnerMediaEventEx->FreeEventParams(nEventCode, nParameter1, nParameter2);
1308        }
1309       
1310// IMediaEventEx
1311        STDMETHOD(SetNotifyWindow)(OAHWND nWindowHandle, LONG nMessage, LONG_PTR nParameter)
1312        {
1313                _Z4(atlTraceCOM, 4, _T("nWindowHandle 0x%08X, nMessage 0x%04x, nParameter %p\n"), nWindowHandle, nMessage, nParameter);
1314                return m_pInnerMediaEventEx->SetNotifyWindow(nWindowHandle, nMessage, nParameter);
1315        }
1316        STDMETHOD(SetNotifyFlags)(LONG nNotifyFlags)
1317        {
1318                _Z4(atlTraceCOM, 4, _T("nNotifyFlags 0x%x\n"), nNotifyFlags);
1319                return m_pInnerMediaEventEx->SetNotifyFlags(nNotifyFlags);
1320        }
1321        STDMETHOD(GetNotifyFlags)(LONG* pnNotifyFlags)
1322        {
1323                _Z4(atlTraceCOM, 4, _T("...\n"));
1324                return m_pInnerMediaEventEx->GetNotifyFlags(pnNotifyFlags);
1325        }
1326
1327// IObjectWithSite
1328        STDMETHOD(SetSite)(IUnknown* pSite)
1329        {
1330                _Z4(atlTraceCOM, 4, _T("pSite 0x%p\n"), pSite);
1331                _ATLTRY
1332                {
1333                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
1334                        m_pSite = pSite;
1335                }
1336                _ATLCATCH(Exception)
1337                {
1338                        _C(Exception);
1339                }
1340                return S_OK;
1341        }
1342    STDMETHOD(GetSite)(REFIID InterfaceIdentifier, VOID** ppvSite)
1343        {
1344                _Z4(atlTraceCOM, 4, _T("InterfaceIdentifier %ls\n"), _PersistHelper::StringFromInterfaceIdentifier(InterfaceIdentifier));
1345                _ATLTRY
1346                {
1347                        __D(ppvSite, E_POINTER);
1348                        *ppvSite = NULL;
1349                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
1350                        _D(m_pSite, E_FAIL);
1351                        return m_pSite->QueryInterface(InterfaceIdentifier, ppvSite);
1352                }
1353                _ATLCATCH(Exception)
1354                {
1355                        _C(Exception);
1356                }
1357                return S_OK;
1358        }
1359};
1360
1361////////////////////////////////////////////////////////////
1362// CSpy
1363
1364class ATL_NO_VTABLE CSpy :
1365        public CSpyT<CSpy, &CLSID_FilterGraph>,
1366        public CComCoClass<CSpy, &CLSID_Spy>
1367{
1368public:
1369        enum { IDR = IDR_FILTERGRAPHSPY };
1370
1371private:
1372        static LPCTSTR g_pszClassName;
1373
1374public:
1375        //typedef CBlackListAwareComCreatorT<CComObjectCached<CSpy>, CSpy, &g_pszClassName> _ClassFactoryCreatorClass; // DECLARE_CLASSFACTORY override
1376        typedef CComCreator2<CBlackListAwareComCreatorT<CComObject<CSpy>, CSpy, &g_pszClassName>, CBlackListAwareComCreatorT<CComAggObject<CSpy>, CSpy, &g_pszClassName> > _CreatorClass; // DECLARE_AGGREGATABLE override
1377
1378public:
1379// CSpy
1380};
1381
1382__declspec(selectany) LPCTSTR CSpy::g_pszClassName = _T("CSpy");
1383
1384OBJECT_ENTRY_AUTO(__uuidof(Spy), CSpy)
1385
1386////////////////////////////////////////////////////////////
1387// CNoThreadSpy
1388
1389class ATL_NO_VTABLE CNoThreadSpy :
1390        public CSpyT<CNoThreadSpy, &CLSID_FilterGraphNoThread>,
1391        public CComCoClass<CNoThreadSpy, &CLSID_NoThreadSpy>
1392{
1393public:
1394        enum { IDR = IDR_NOTHREADFILTERGRAPHSPY };
1395
1396private:
1397        static LPCTSTR g_pszClassName;
1398
1399public:
1400        //typedef CBlackListAwareComCreatorT<CComObjectCached<CNoThreadSpy>, CNoThreadSpy, &g_pszClassName> _ClassFactoryCreatorClass; // DECLARE_CLASSFACTORY override
1401        typedef CComCreator2<CBlackListAwareComCreatorT<CComObject<CNoThreadSpy>, CNoThreadSpy, &g_pszClassName>, CBlackListAwareComCreatorT<CComAggObject<CNoThreadSpy>, CNoThreadSpy, &g_pszClassName> > _CreatorClass; // DECLARE_AGGREGATABLE override
1402
1403public:
1404// CNoThreadSpy
1405};
1406
1407__declspec(selectany) LPCTSTR CNoThreadSpy::g_pszClassName = _T("CNoThreadSpy");
1408
1409OBJECT_ENTRY_AUTO(__uuidof(NoThreadSpy), CNoThreadSpy)
Note: See TracBrowser for help on using the repository browser.