source: trunk/DirectShowSpy/RunEvent.h @ 431

Last change on this file since 431 was 431, checked in by roman, 6 years ago
File size: 8.0 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2015
3// Created by Roman Ryltsov roman@alax.info, http://alax.info
4//
5// This source code is published to complement DirectShowSpy developer powertoy
6// and demonstrate the internal use of APIs and tricks powering the tool. It is
7// allowed to freely re-use the portions of the code in other projects, commercial
8// or otherwise (provided that you don’t pretend that you wrote the original tool).
9//
10// Please keep in mind that DirectShowSpy is a developer tool, it is strongly recommended
11// that it is not shipped with release grade software. It is allowed to distribute
12// DirectShowSpy if only it is not registered with Windows by default and either
13// used privately, or registered on specific throubleshooting request. The advice applies
14// to hooking methods used by DirectShowSpy in general as well.
15
16#pragma once
17
18////////////////////////////////////////////////////////////
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                VOID InternalAddItem(ULONGLONG nTime, LPCSTR pszText)
87                {
88                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
89                        if(!m_bCapture)
90                                return;
91                        CItem& Item = m_pItems[m_nItemIndex];
92                        Item.m_nTime = nTime;
93                        strncpy_s(Item.m_pszText, pszText, _TRUNCATE);
94                        if(m_nItemCount < t_nItemCapacity)
95                                m_nItemCount++;
96                        ++m_nItemIndex %= t_nItemCapacity;
97                        if(m_bTrace && m_nTraceItemCount)
98                                m_nTraceItemCount--;
99                }
100                VOID InternalAddItemV(ULONGLONG nTime, LPCSTR pszFormat, va_list Arguments)
101                {
102                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
103                        if(!m_bCapture)
104                                return;
105                        CItem& Item = m_pItems[m_nItemIndex];
106                        Item.m_nTime = nTime;
107                        vsprintf_s(Item.m_pszText, pszFormat, Arguments);
108                        if(m_nItemCount < t_nItemCapacity)
109                                m_nItemCount++;
110                        ++m_nItemIndex %= t_nItemCapacity;
111                        if(m_bTrace && m_nTraceItemCount)
112                                m_nTraceItemCount--;
113                }
114
115        public:
116        // CEventsT
117                CEventsT() :
118                        m_bCapture(FALSE),
119                        m_bTrace(FALSE)
120                {
121                }
122                static SIZE_T GetCapacity()
123                {
124                        return t_nItemCapacity;
125                }
126                BOOL IsCapture() const
127                {
128                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
129                        return m_bCapture;
130                }
131                VOID SetCapture(BOOL bCapture)
132                {
133                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
134                        if(m_bCapture == bCapture)
135                                return;
136                        m_bCapture = bCapture;
137                        if(bCapture)
138                        {
139                                m_nItemIndex = 0;
140                                m_nItemCount = 0;
141                        }
142                }
143                VOID AddItemV(ULONGLONG nTime, LPCSTR pszFormat, va_list Arguments)
144                {
145                        InternalAddItemV(nTime, pszFormat, Arguments);
146                }
147                VOID AddItem(ULONGLONG nTime, LPCSTR pszFormat, ...)
148                {
149                        va_list Arguments;
150                        va_start(Arguments, pszFormat);
151                        AddItemV(pszFormat, Arguments);
152                        va_end(Arguments);
153                }
154                VOID AddItem(LPCSTR pszFormat, ...)
155                {
156                        va_list Arguments;
157                        va_start(Arguments, pszFormat);
158                        AddItemV(CMsAccurateFileTime::GetTime(), pszFormat, Arguments);
159                        va_end(Arguments);
160                }
161                VOID AddItem(const CRoArrayT<CStringA>& Array)
162                {
163                        InternalAddItem(CMsAccurateFileTime::GetTime(), _StringHelper::Join(Array, "\t"));
164                }
165                CComVariantArray GetAsVariant() const
166                {
167                        CComVariantArray vValue;
168                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
169                        if(m_bCapture && m_nItemCount)
170                        {
171                                const ULONGLONG nTime = CMsAccurateFileTime::GetTime();
172                                CRoArrayT<CComVariantArray> Array;
173                                Array.SetCount(0, (INT) m_nItemCount);
174                                for(SIZE_T nItemIndex = 0; nItemIndex < m_nItemCount; nItemIndex++)
175                                {
176                                        const CItem& Item = m_pItems[((m_nItemIndex - 1) - nItemIndex + t_nItemCapacity) % t_nItemCapacity];
177                                        Array.Add(Item.GetAsVariant(nTime));
178                                }
179                                vValue.FromElementArray(Array);
180                        }
181                        return vValue;
182                }
183                SIZE_T GetText(CRoArrayT<CString>& Array) const
184                {
185                        _A(Array.IsEmpty());
186                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
187                        if(m_bCapture && m_nItemCount)
188                        {
189                                const ULONGLONG nTime = CMsAccurateFileTime::GetTime();
190                                Array.SetCount(0, (INT) m_nItemCount);
191                                for(SIZE_T nItemIndex = 0; nItemIndex < m_nItemCount; nItemIndex++)
192                                {
193                                        const CItem& Item = m_pItems[((m_nItemIndex - 1) - nItemIndex + t_nItemCapacity) % t_nItemCapacity];
194                                        Array.Add(Item.GetText(nTime));
195                                }
196                        }
197                        return Array.GetCount();
198                }
199                BOOL IsTrace() const
200                {
201                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
202                        return m_bTrace && !m_nTraceItemCount;
203                }
204                VOID SetTrace(BOOL bTrace, SIZE_T nTraceItemCount = 0)
205                {
206                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
207                        if(bTrace)
208                        {
209                                if(m_bTrace)
210                                        return; // Stick to Existing Schedule
211                                m_bTrace = TRUE;
212                                m_nTraceItemCount = nTraceItemCount;
213                        } else
214                                m_bTrace = FALSE;
215                }
216        };
217
218        typedef CEventsT<> CEvents;
219
220public:
221// CRunEventHelper
222};
223
224#if !defined(DIRECTSHOWSPY)
225
226////////////////////////////////////////////////////////////
227// CRunEventAwareT
228
229template <typename T>
230class ATL_NO_VTABLE CRunEventAwareT :
231        public IDispatchImpl<DIRECTSHOWSPY_NAMESPACE_PREFIX IRunEventAware, &__uuidof(DIRECTSHOWSPY_NAMESPACE_PREFIX IRunEventAware), &__uuidof(DIRECTSHOWSPY_NAMESPACE_PREFIX __AlaxInfoDirectShowSpy)>
232{
233protected:
234        CRunEventHelper::CEvents m_Events;
235
236public:
237// CRunEventAwareT
238       
239// AlaxInfoDirectShowSpy::IRunEventAware
240        STDMETHOD(get_Value)(VARIANT* pvEvents)
241        {
242                _Z4(atlTraceCOM, 4, _T("...\n"));
243                _ATLTRY
244                {
245                        __D(pvEvents, E_POINTER);
246                        VariantInit(pvEvents);
247                        T* pT = static_cast<T*>(this);
248                        //CRoCriticalSectionLock DataLock(pT->GetDataCriticalSection());
249                        _V(m_Events.GetAsVariant().Detach(pvEvents));
250                }
251                _ATLCATCH(Exception)
252                {
253                        _C(Exception);
254                }
255                return S_OK;
256        }
257        STDMETHOD(get_Capture)(VARIANT_BOOL* pbCapture)
258        {
259                _Z4(atlTraceCOM, 4, _T("...\n"));
260                _ATLTRY
261                {
262                        __D(pbCapture, E_POINTER);
263                        T* pT = static_cast<T*>(this);
264                        //CRoCriticalSectionLock DataLock(pT->GetDataCriticalSection());
265                        *pbCapture = m_Events.IsCapture() ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
266                }
267                _ATLCATCH(Exception)
268                {
269                        _C(Exception);
270                }
271                return S_OK;
272        }
273        STDMETHOD(put_Capture)(VARIANT_BOOL bCapture)
274        {
275                _Z4(atlTraceCOM, 4, _T("bCapture %d\n"), bCapture);
276                _ATLTRY
277                {
278                        T* pT = static_cast<T*>(this);
279                        //CRoCriticalSectionLock DataLock(pT->GetDataCriticalSection());
280                        m_Events.SetCapture(bCapture != ATL_VARIANT_FALSE);
281                }
282                _ATLCATCH(Exception)
283                {
284                        _C(Exception);
285                }
286                return S_OK;
287        }
288};
289
290#endif // !defined(DIRECTSHOWSPY)
Note: See TracBrowser for help on using the repository browser.