1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxTimer.hpp
8 
9 Abstract:
10 
11     This module implements a frameworks managed TIMER that
12     can synchrononize with driver frameworks object locks.
13 
14 Author:
15 
16 
17 
18 
19 Environment:
20 
21     Both kernel and user mode
22 
23 Revision History:
24 
25 
26 --*/
27 
28 #ifndef _FXTIMER_H_
29 #define _FXTIMER_H_
30 
31 //
32 // Driver Frameworks TIMER Design:
33 //
34 // The driver frameworks provides an optional TIMER wrapper object that allows
35 // a reference counted TIMER object to be created that can synchronize
36 // automatically with certain frameworks objects.
37 //
38 // This provides automatic synchronization between the TIMER's execution, and the
39 // frameworks objects event callbacks into the device driver.
40 //
41 
42 class FxTimer : public FxNonPagedObject {
43 
44 private:
45 
46     //
47     // Kernel Timer Object
48     //
49     MxTimer             m_Timer;
50 
51     //
52     // This is the Framework object who is associated with the TIMER
53     // if supplied
54     //
55     FxObject*           m_Object;
56 
57     //
58     // This is the supplied Period to WdfTimerCreate
59     //
60     ULONG               m_Period;
61 
62     //
63     // Optional tolerance for the timer in milliseconds
64     //
65     ULONG               m_TolerableDelay;
66 
67     //
68     // This indicates whether a high resolution attribute is set
69     // for the timer
70     //
71     BOOLEAN             m_UseHighResolutionTimer;
72 
73     //
74     // This is the callback lock for the object this TIMER will
75     // synchronize with
76     //
77     FxCallbackLock*     m_CallbackLock;
78 
79     //
80     // This is the object whose reference count actually controls
81     // the lifetime of the m_CallbackLock
82     //
83     FxObject*           m_CallbackLockObject;
84 
85     //
86     // This is the user supplied callback function
87     //
88     PFN_WDF_TIMER       m_Callback;
89 
90     //
91     // This workitem object will be used to queue workitem from the timer
92     // dpc callback if the caller requests passive callback.
93     //
94     FxSystemWorkItem*   m_SystemWorkItem;
95 
96     //
97     // This is a pointer to thread object that invoked our dpc callback
98     // callback. This value will be used to avoid deadlock when we try
99     // to stop or delete the timer.
100     //
101     volatile POINTER_ALIGNMENT MxThread   m_CallbackThread;
102 
103     //
104     // This is a pointer to the Stop thread object when driver invokes the
105     // timer's WdfTimerStop function.
106     //
107     MxThread            m_StopThread;
108 
109     //
110     // TRUE if the timer was restarted while stopping.
111     //
112     BOOLEAN             m_StopAgain;
113 
114     //
115     // TRUE if a start operation was aborted b/c stop was in progress.
116     //
117     BOOLEAN             m_StartAborted;
118 
119     //
120     // Ensures only one of either Delete or Cleanup runsdown the object
121     //
122     BOOLEAN             m_RunningDown;
123 
124 public:
125     static
126     _Must_inspect_result_
127     NTSTATUS
128     _Create(
129         __in PFX_DRIVER_GLOBALS FxDriverGlobals,
130         __in PWDF_TIMER_CONFIG Config,
131         __in PWDF_OBJECT_ATTRIBUTES Attributes,
132         __in FxObject* ParentObject,
133         __out WDFTIMER* Timer
134         );
135 
136     FxTimer(
137         __in PFX_DRIVER_GLOBALS FxDriverGlobals
138         );
139 
140     virtual
141     ~FxTimer(
142         VOID
143         );
144 
145     _Must_inspect_result_
146     NTSTATUS
147     Initialize(
148         __in PWDF_OBJECT_ATTRIBUTES Attributes,
149         __in PWDF_TIMER_CONFIG Config,
150         __in FxObject* ParentObject,
151         __out WDFTIMER* Timer
152         );
153 
154     virtual
155     BOOLEAN
156     Dispose(
157         VOID
158         );
159 
160     BOOLEAN
161     Start(
162         __in LARGE_INTEGER DueTime
163         );
164 
165     BOOLEAN
166     Stop(
167         __in BOOLEAN  Wait
168         );
169 
170     VOID
171     TimerHandler(
172         VOID
173         );
174 
175     WDFOBJECT
176     GetObject(
177         VOID
178         )
179     {
180         if( m_Object != NULL ) {
181             return m_Object->GetObjectHandle();
182         }
183         else {
184             return NULL;
185         }
186     }
187 
188     WDFTIMER
189     GetHandle(
190         VOID
191         )
192     {
193         return (WDFTIMER) GetObjectHandle();
194     }
195 
196 private:
197 
198     //
199     // Called from Dispose, or cleanup list to perform final flushing of any
200     // outstanding DPC's and dereferencing of objects.
201     //
202     VOID
203     FlushAndRundown(
204         VOID
205         );
206 
207     static
208     FN_WDF_SYSTEMWORKITEM
209     _FxTimerWorkItemCallback;
210 
211     static
212     MdDeferredRoutineType
213     _FxTimerDpcThunk;
214 
215     static
216     MdExtCallbackType
217     _FxTimerExtCallbackThunk;
218 };
219 
220 #endif // _FXTIMER_H
221 
222