source: trunk/DirectShowSpy/FilterGraphSpy.h @ 792

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

Exported function signatures replaced to accurately rundll32 compatible; added IModuleVersionInformation implementation to FilterGraphHelper?; added debug Host01 project; IFilterGraphHelper interface is extended with MediaSampleTrace? related automation methods; MediaSampleTrace? UI is extended to support data load from external file

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