source: trunk/DirectShowSpy/FilterGraphSpy.h @ 440

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

Added media sample trace API and UI

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