source: trunk/DirectShowSpy/FilterGraphSpy.h @ 196

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

Cosmetic fixes, new .BAT names, UnregisterTreatAsClasses? export to force removal of TreatAs? keys

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