source: trunk/DirectShowSpy/RunEvent.h @ 937

Last change on this file since 937 was 851, checked in by roman, 4 years ago

Added filter states and intermediate states; earlier minor fixes

File size: 8.1 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#include "Common.h"
19
20////////////////////////////////////////////////////////////
21// CRunEventHelper
22
23class CRunEventHelper
24{
25public:
26
27        ////////////////////////////////////////////////////////
28        // CEventsT, CEvents
29
30        template <SIZE_T t_nItemCapacity = 256, SIZE_T t_nItemTextLength = 256>
31        class CEventsT
32        {
33        public:
34
35                ////////////////////////////////////////////////////
36                // CItem
37
38                class CItem
39                {
40                public:
41                        ULONGLONG m_nTime;
42                        CHAR m_pszText[t_nItemTextLength];
43
44                public:
45                // CItem
46                        CComVariantArray GetAsVariant(ULONGLONG nTime) const
47                        {
48                                CComVariantArray vValue;
49                                vValue.FromElements(2, CComVariant((LONG) ((nTime - m_nTime) / 10000)), CComVariant(m_pszText));
50                                return vValue;
51                        }
52                        BOOL SetAsVariant(CComVariantArray& vValue)
53                        {
54                                if(vValue.vt != (VT_ARRAY | VT_VARIANT))
55                                        return FALSE;
56                                _A(vValue.GetDimensionCount() == 1);
57                                CRoArrayT<CComVariantArray> Array;
58                                vValue.ToElementArray(Array);
59                                if(Array.GetCount() < 2)
60                                        return FALSE;
61                                m_nTime = Array[0].GetAsType(VT_I4).lVal * 10000;
62                                strncpy_s(m_pszText, CW2A(Array[1].GetAsType(VT_BSTR).bstrVal), _TRUNCATE);
63                                return TRUE;
64                        }
65                        BOOL SetAsVariant(VARIANT vValue)
66                        {
67                                return SetAsVariant(reinterpret_cast<CComVariantArray&>(vValue));
68                        }
69                        CString GetText(ULONGLONG nTime) const
70                        {
71                                CString sText;
72                                sText.AppendFormat(_T("%Id"), (LONG) (nTime - m_nTime));
73                                sText.AppendChar(_T('\t'));
74                                sText.Append(CA2CT(m_pszText));
75                                return sText;
76                        }
77                };
78
79        private:
80                mutable CRoLightCriticalSection m_DataCriticalSection;
81                BOOL m_bCapture;
82                CItem m_pItems[t_nItemCapacity];
83                SIZE_T m_nItemIndex;
84                SIZE_T m_nItemCount;
85                BOOL m_bTrace;
86                SIZE_T m_nTraceItemCount;
87
88                VOID InternalAddItem(ULONGLONG nTime, LPCSTR pszText)
89                {
90                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
91                        if(!m_bCapture)
92                                return;
93                        CItem& Item = m_pItems[m_nItemIndex];
94                        Item.m_nTime = nTime;
95                        strncpy_s(Item.m_pszText, pszText, _TRUNCATE);
96                        if(m_nItemCount < t_nItemCapacity)
97                                m_nItemCount++;
98                        ++m_nItemIndex %= t_nItemCapacity;
99                        if(m_bTrace && m_nTraceItemCount)
100                                m_nTraceItemCount--;
101                }
102                VOID InternalAddItemV(ULONGLONG nTime, LPCSTR pszFormat, va_list Arguments)
103                {
104                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
105                        if(!m_bCapture)
106                                return;
107                        CItem& Item = m_pItems[m_nItemIndex];
108                        Item.m_nTime = nTime;
109                        vsprintf_s(Item.m_pszText, pszFormat, Arguments);
110                        if(m_nItemCount < t_nItemCapacity)
111                                m_nItemCount++;
112                        ++m_nItemIndex %= t_nItemCapacity;
113                        if(m_bTrace && m_nTraceItemCount)
114                                m_nTraceItemCount--;
115                }
116
117        public:
118        // CEventsT
119                CEventsT() :
120                        m_bCapture(FALSE),
121                        m_bTrace(FALSE)
122                {
123                }
124                static SIZE_T GetCapacity()
125                {
126                        return t_nItemCapacity;
127                }
128                BOOL IsCapture() const
129                {
130                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
131                        return m_bCapture;
132                }
133                VOID SetCapture(BOOL bCapture)
134                {
135                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
136                        if(m_bCapture == bCapture)
137                                return;
138                        m_bCapture = bCapture;
139                        if(bCapture)
140                        {
141                                m_nItemIndex = 0;
142                                m_nItemCount = 0;
143                        }
144                }
145                VOID AddItemV(ULONGLONG nTime, LPCSTR pszFormat, va_list Arguments)
146                {
147                        InternalAddItemV(nTime, pszFormat, Arguments);
148                }
149                VOID AddItem(ULONGLONG nTime, LPCSTR pszFormat, ...)
150                {
151                        va_list Arguments;
152                        va_start(Arguments, pszFormat);
153                        AddItemV(pszFormat, Arguments);
154                        va_end(Arguments);
155                }
156                VOID AddItem(LPCSTR pszFormat, ...)
157                {
158                        va_list Arguments;
159                        va_start(Arguments, pszFormat);
160                        AddItemV(CMsAccurateFileTime::GetTime(), pszFormat, Arguments);
161                        va_end(Arguments);
162                }
163                VOID AddItem(const CRoArrayT<CStringA>& Array)
164                {
165                        InternalAddItem(CMsAccurateFileTime::GetTime(), _StringHelper::Join(Array, "\t"));
166                }
167                CComVariantArray GetAsVariant() const
168                {
169                        CComVariantArray vValue;
170                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
171                        if(m_bCapture && m_nItemCount)
172                        {
173                                const ULONGLONG nTime = CMsAccurateFileTime::GetTime();
174                                CRoArrayT<CComVariantArray> Array;
175                                Array.SetCount(0, (INT) m_nItemCount);
176                                for(SIZE_T nItemIndex = 0; nItemIndex < m_nItemCount; nItemIndex++)
177                                {
178                                        const CItem& Item = m_pItems[((m_nItemIndex - 1) - nItemIndex + t_nItemCapacity) % t_nItemCapacity];
179                                        Array.Add(Item.GetAsVariant(nTime));
180                                }
181                                vValue.FromElementArray(Array);
182                        }
183                        return vValue;
184                }
185                SIZE_T GetText(CRoArrayT<CString>& Array) const
186                {
187                        _A(Array.IsEmpty());
188                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
189                        if(m_bCapture && m_nItemCount)
190                        {
191                                const ULONGLONG nTime = CMsAccurateFileTime::GetTime();
192                                Array.SetCount(0, (INT) m_nItemCount);
193                                for(SIZE_T nItemIndex = 0; nItemIndex < m_nItemCount; nItemIndex++)
194                                {
195                                        const CItem& Item = m_pItems[((m_nItemIndex - 1) - nItemIndex + t_nItemCapacity) % t_nItemCapacity];
196                                        Array.Add(Item.GetText(nTime));
197                                }
198                        }
199                        return Array.GetCount();
200                }
201                BOOL IsTrace() const
202                {
203                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
204                        return m_bTrace && !m_nTraceItemCount;
205                }
206                VOID SetTrace(BOOL bTrace, SIZE_T nTraceItemCount = 0)
207                {
208                        CRoLightCriticalSectionLock DataLock(m_DataCriticalSection);
209                        if(bTrace)
210                        {
211                                if(m_bTrace)
212                                        return; // Stick to Existing Schedule
213                                m_bTrace = TRUE;
214                                m_nTraceItemCount = nTraceItemCount;
215                        } else
216                                m_bTrace = FALSE;
217                }
218        };
219
220        typedef CEventsT<> CEvents;
221
222public:
223// CRunEventHelper
224};
225
226#if !defined(DIRECTSHOWSPY)
227
228////////////////////////////////////////////////////////////
229// CRunEventAwareT
230
231template <typename T>
232class ATL_NO_VTABLE CRunEventAwareT :
233        public IDispatchImpl<DIRECTSHOWSPY_NAMESPACE_PREFIX IRunEventAware, &__uuidof(DIRECTSHOWSPY_NAMESPACE_PREFIX IRunEventAware), &__uuidof(DIRECTSHOWSPY_NAMESPACE_PREFIX __AlaxInfoDirectShowSpy)>
234{
235protected:
236        CRunEventHelper::CEvents m_Events;
237
238public:
239// CRunEventAwareT
240       
241// AlaxInfoDirectShowSpy::IRunEventAware
242        STDMETHOD(get_Value)(VARIANT* pvEvents)
243        {
244                _Z4(atlTraceCOM, 4, _T("...\n"));
245                _ATLTRY
246                {
247                        __D(pvEvents, E_POINTER);
248                        VariantInit(pvEvents);
249                        T* pT = static_cast<T*>(this);
250                        //CRoCriticalSectionLock DataLock(pT->GetDataCriticalSection());
251                        _V(m_Events.GetAsVariant().Detach(pvEvents));
252                }
253                _ATLCATCH(Exception)
254                {
255                        _C(Exception);
256                }
257                return S_OK;
258        }
259        STDMETHOD(get_Capture)(VARIANT_BOOL* pbCapture)
260        {
261                _Z4(atlTraceCOM, 4, _T("...\n"));
262                _ATLTRY
263                {
264                        __D(pbCapture, E_POINTER);
265                        T* pT = static_cast<T*>(this);
266                        //CRoCriticalSectionLock DataLock(pT->GetDataCriticalSection());
267                        *pbCapture = m_Events.IsCapture() ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
268                }
269                _ATLCATCH(Exception)
270                {
271                        _C(Exception);
272                }
273                return S_OK;
274        }
275        STDMETHOD(put_Capture)(VARIANT_BOOL bCapture)
276        {
277                _Z4(atlTraceCOM, 4, _T("bCapture %d\n"), bCapture);
278                _ATLTRY
279                {
280                        T* pT = static_cast<T*>(this);
281                        //CRoCriticalSectionLock DataLock(pT->GetDataCriticalSection());
282                        m_Events.SetCapture(bCapture != ATL_VARIANT_FALSE);
283                }
284                _ATLCATCH(Exception)
285                {
286                        _C(Exception);
287                }
288                return S_OK;
289        }
290};
291
292#endif // !defined(DIRECTSHOWSPY)
Note: See TracBrowser for help on using the repository browser.