source: trunk/DirectShowSpy/FilterGraphSpy.h @ 117

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