source: trunk/DirectShowSpy/RunEvent.h @ 310

Last change on this file since 310 was 310, checked in by roman, 10 years ago

Uniform source code file naming; VS 2012 build (v110_xp toolset); Binaries

File size: 8.1 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2014
3// Created by Roman Ryltsov roman@alax.info, http://alax.info
4//
5// This source code is published to complement DirectShowSpy developer powertoy
6// and demonstrate the internal use of APIs and tricks powering the tool. It is
7// allowed to freely re-use the portions of the code in other projects, commercial
8// or otherwise (provided that you don’t pretend that you wrote the original tool).
9//
10// Please keep in mind that DirectShowSpy is a developer tool, it is strongly recommended
11// that it is not shipped with release grade software. It is allowed to distribute
12// DirectShowSpy if only it is not registered with Windows by default and either
13// used privately, or registered on specific throubleshooting request. The advice applies
14// to hooking methods used by DirectShowSpy in general as well.
15
16#pragma once
17
18////////////////////////////////////////////////////////////
19// CRunEventHelper
20
21class CRunEventHelper
22{
23public:
24
25        ////////////////////////////////////////////////////////
26        // CEventsT, CEvents
27
28        template <SIZE_T t_nItemCapacity = 256, SIZE_T t_nItemTextLength = 256>
29        class CEventsT
30        {
31        public:
32
33                ////////////////////////////////////////////////////
34                // CItem
35
36                class CItem
37                {
38                public:
39                        ULONGLONG m_nTime;
40                        CHAR m_pszText[t_nItemTextLength];
41
42                public:
43                // CItem
44                        CComVariantArray GetAsVariant(ULONGLONG nTime) const
45                        {
46                                CComVariantArray vValue;
47                                vValue.FromElements(2, CComVariant((LONG) (nTime - m_nTime) / 10000), CComVariant(m_pszText));
48                                return vValue;
49                        }
50                        BOOL SetAsVariant(CComVariantArray& vValue)
51                        {
52                                if(vValue.vt != (VT_ARRAY | VT_VARIANT))
53                                        return FALSE;
54                                _A(vValue.GetDimensionCount() == 1);
55                                CRoArrayT<CComVariantArray> Array;
56                                vValue.ToElementArray(Array);
57                                if(Array.GetCount() < 2)
58                                        return FALSE;
59                                m_nTime = Array[0].GetAsType(VT_I4).lVal * 10000;
60                                strncpy_s(m_pszText, CW2A(Array[1].GetAsType(VT_BSTR).bstrVal), _TRUNCATE);
61                                return TRUE;
62                        }
63                        BOOL SetAsVariant(VARIANT vValue)
64                        {
65                                return SetAsVariant(reinterpret_cast<CComVariantArray&>(vValue));
66                        }
67                        CString GetText(ULONGLONG nTime) const
68                        {
69                                CString sText;
70                                sText.AppendFormat(_T("%Id"), (LONG) (nTime - m_nTime));
71                                sText.AppendChar(_T('\t'));
72                                sText.Append(CA2CT(m_pszText));
73                                return sText;
74                        }
75                };
76
77        private:
78                mutable CRoLightCriticalSection m_DataCriticalSection;
79                BOOL m_bCapture;
80                CItem m_pItems[t_nItemCapacity];
81                SIZE_T m_nItemIndex;
82                SIZE_T m_nItemCount;
83                BOOL m_bTrace;
84                SIZE_T m_nTraceItemCount;
85
86        public:
87        // CEventsT
88                CEventsT() :
89                        m_bCapture(FALSE),
90                        m_bTrace(FALSE)
91                {
92                }
93                static SIZE_T GetCapacity()
94                {
95                        return t_nItemCapacity;
96                }
97                BOOL IsCapture() const
98                {
99                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
100                        return m_bCapture;
101                }
102                VOID SetCapture(BOOL bCapture)
103                {
104                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
105                        if(m_bCapture == bCapture)
106                                return;
107                        m_bCapture = bCapture;
108                        if(bCapture)
109                        {
110                                m_nItemIndex = 0;
111                                m_nItemCount = 0;
112                        }
113                }
114                VOID AddItemV(ULONGLONG nTime, LPCSTR pszFormat, va_list Arguments)
115                {
116                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
117                        if(!m_bCapture)
118                                return;
119                        CItem& Item = m_pItems[m_nItemIndex];
120                        Item.m_nTime = nTime;
121                        vsprintf_s(Item.m_pszText, pszFormat, Arguments);
122                        if(m_nItemCount < t_nItemCapacity)
123                                m_nItemCount++;
124                        ++m_nItemIndex %= t_nItemCapacity;
125                        if(m_bTrace && m_nTraceItemCount)
126                                m_nTraceItemCount--;
127                }
128                VOID AddItem(ULONGLONG nTime, LPCSTR pszFormat, ...)
129                {
130                        va_list Arguments;
131                        va_start(Arguments, pszFormat);
132                        AddItemV(pszFormat, Arguments);
133                        va_end(Arguments);
134                }
135                VOID AddItem(LPCSTR pszFormat, ...)
136                {
137                        va_list Arguments;
138                        va_start(Arguments, pszFormat);
139                        AddItemV(CMsAccurateFileTime::GetTime(), pszFormat, Arguments);
140                        va_end(Arguments);
141                }
142                CComVariantArray GetAsVariant() const
143                {
144                        CComVariantArray vValue;
145                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
146                        if(m_bCapture && m_nItemCount)
147                        {
148                                const ULONGLONG nTime = CMsAccurateFileTime::GetTime();
149                                CRoArrayT<CComVariantArray> Array;
150                                Array.SetCount(0, (INT) m_nItemCount);
151                                for(SIZE_T nItemIndex = 0; nItemIndex < m_nItemCount; nItemIndex++)
152                                {
153                                        const CItem& Item = m_pItems[((m_nItemIndex - 1) - nItemIndex + t_nItemCapacity) % t_nItemCapacity];
154                                        Array.Add(Item.GetAsVariant(nTime));
155                                }
156                                vValue.FromElementArray(Array);
157                        }
158                        return vValue;
159                }
160                SIZE_T GetText(CRoArrayT<CString>& Array) const
161                {
162                        _A(Array.IsEmpty());
163                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
164                        if(m_bCapture && m_nItemCount)
165                        {
166                                const ULONGLONG nTime = CMsAccurateFileTime::GetTime();
167                                Array.SetCount(0, (INT) m_nItemCount);
168                                for(SIZE_T nItemIndex = 0; nItemIndex < m_nItemCount; nItemIndex++)
169                                {
170                                        const CItem& Item = m_pItems[((m_nItemIndex - 1) - nItemIndex + t_nItemCapacity) % t_nItemCapacity];
171                                        Array.Add(Item.GetText(nTime));
172                                }
173                        }
174                        return Array.GetCount();
175                }
176                BOOL IsTrace() const
177                {
178                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
179                        return m_bTrace && !m_nTraceItemCount;
180                }
181                VOID SetTrace(BOOL bTrace, SIZE_T nTraceItemCount = 0)
182                {
183                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
184                        if(bTrace)
185                        {
186                                if(m_bTrace)
187                                        return; // Stick to Existing Schedule
188                                m_bTrace = TRUE;
189                                m_nTraceItemCount = nTraceItemCount;
190                        } else
191                                m_bTrace = FALSE;
192                }
193        };
194
195        typedef CEventsT<> CEvents;
196
197public:
198// CRunEventHelper
199};
200
201#if defined(DIRECTSHOWSPY_IRUNXXX_TEMPLATE)
202
203////////////////////////////////////////////////////////////
204// CRunPropertyBagAwareT
205
206template <typename T>
207class ATL_NO_VTABLE CRunPropertyBagAwareT :
208        public IDispatchImpl<AlaxInfoDirectShowSpy::IRunPropertyBagAware, &__uuidof(AlaxInfoDirectShowSpy::IRunPropertyBagAware), &__uuidof(AlaxInfoDirectShowSpy::__AlaxInfoDirectShowSpy)>
209{
210public:
211// CRunPropertyBagAwareT
212
213// AlaxInfoDirectShowSpy::IRunPropertyBagAware
214        STDMETHOD(get_Value)(IUnknown** ppPropertyBagUnknown)
215        {
216                _Z4(atlTraceCOM, 4, _T("...\n"));
217                _ATLTRY
218                {
219                        __D(ppPropertyBagUnknown, E_POINTER);
220                        T* pT = static_cast<T*>(this);
221                        *ppPropertyBagUnknown = (IPropertyBag*) pT->CreatePerformancePropertyBag().Detach();
222                }
223                _ATLCATCH(Exception)
224                {
225                        _C(Exception);
226                }
227                return S_OK;
228        }
229};
230
231////////////////////////////////////////////////////////////
232// CRunEventAwareT
233
234template <typename T>
235class ATL_NO_VTABLE CRunEventAwareT :
236        public IDispatchImpl<AlaxInfoDirectShowSpy::IRunEventAware, &__uuidof(AlaxInfoDirectShowSpy::IRunEventAware), &__uuidof(AlaxInfoDirectShowSpy::__AlaxInfoDirectShowSpy)>
237{
238protected:
239        CRunEventHelper::CEvents m_Events;
240
241public:
242// CRunEventAwareT
243       
244// AlaxInfoDirectShowSpy::IRunEventAware
245        STDMETHOD(get_Value)(VARIANT* pvEvents)
246        {
247                _Z4(atlTraceCOM, 4, _T("...\n"));
248                _ATLTRY
249                {
250                        __D(pvEvents, E_POINTER);
251                        VariantInit(pvEvents);
252                        T* pT = static_cast<T*>(this);
253                        //CRoCriticalSectionLock DataLock(pT->GetDataCriticalSection());
254                        _V(m_Events.GetAsVariant().Detach(pvEvents));
255                }
256                _ATLCATCH(Exception)
257                {
258                        _C(Exception);
259                }
260                return S_OK;
261        }
262        STDMETHOD(get_Capture)(VARIANT_BOOL* pbCapture)
263        {
264                _Z4(atlTraceCOM, 4, _T("...\n"));
265                _ATLTRY
266                {
267                        __D(pbCapture, E_POINTER);
268                        T* pT = static_cast<T*>(this);
269                        //CRoCriticalSectionLock DataLock(pT->GetDataCriticalSection());
270                        *pbCapture = m_Events.IsCapture() ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
271                }
272                _ATLCATCH(Exception)
273                {
274                        _C(Exception);
275                }
276                return S_OK;
277        }
278        STDMETHOD(put_Capture)(VARIANT_BOOL bCapture)
279        {
280                _Z4(atlTraceCOM, 4, _T("bCapture %d\n"), bCapture);
281                _ATLTRY
282                {
283                        T* pT = static_cast<T*>(this);
284                        //CRoCriticalSectionLock DataLock(pT->GetDataCriticalSection());
285                        m_Events.SetCapture(bCapture != ATL_VARIANT_FALSE);
286                }
287                _ATLCATCH(Exception)
288                {
289                        _C(Exception);
290                }
291                return S_OK;
292        }
293};
294
295#endif // defined(DIRECTSHOWSPY_IRUNXXX_TEMPLATE)
Note: See TracBrowser for help on using the repository browser.