source: trunk/DirectShowSpy/FilterGraphSpy.h @ 188

Last change on this file since 188 was 155, checked in by roman, 11 years ago

Additional evrprop.dll registration, fix for failed put onto ROT

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