ReactOS  0.4.15-dev-3303-g1ade494
FxTimer Class Reference

#include <fxtimer.hpp>

Inheritance diagram for FxTimer:
Collaboration diagram for FxTimer:

Public Member Functions

 FxTimer (__in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
virtual ~FxTimer (VOID)
 
_Must_inspect_result_ NTSTATUS Initialize (__in PWDF_OBJECT_ATTRIBUTES Attributes, __in PWDF_TIMER_CONFIG Config, __in FxObject *ParentObject, __out WDFTIMER *Timer)
 
virtual BOOLEAN Dispose (VOID)
 
BOOLEAN Start (__in LARGE_INTEGER DueTime)
 
BOOLEAN Stop (__in BOOLEAN Wait)
 
VOID TimerHandler (VOID)
 
WDFOBJECT GetObject (VOID)
 
WDFTIMER GetHandle (VOID)
 
- Public Member Functions inherited from FxNonPagedObject
 FxNonPagedObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
 FxNonPagedObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType ObjectType)
 
virtual ~FxNonPagedObject (VOID)
 
 _Acquires_lock_ (this->m_NPLock.m_Lock) __drv_maxIRQL(DISPATCH_LEVEL) __drv_setsIRQL(DISPATCH_LEVEL) VOID Lock(__out __drv_deref(__drv_savesIRQL) PKIRQL PreviousIrql)
 
 _Releases_lock_ (this->m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) __inline VOID Unlock(__in __drv_restoresIRQL KIRQL PreviousIrql)
 
 _Acquires_lock_ (this->m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) VOID LockAtDispatch(VOID)
 
 _Requires_lock_held_ (this->m_NPLock.m_Lock) _Releases_lock_(this -> m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) __inline VOID UnlockFromDispatch(VOID)
 
- Public Member Functions inherited from FxObject
PVOID GetCOMWrapper ()
 
void SetCOMWrapper (__drv_aliasesMem PVOID Wrapper)
 
 FxObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
virtual ~FxObject (VOID)
 
PVOID __inline operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType Type)
 
PVOID __inline operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __in USHORT ExtraSize=0)
 
VOID operator delete (__in PVOID Memory)
 
VOID SetNoContextHeader (VOID)
 
PVOID __inline GetObjectHandle (VOID)
 
__inline FxContextHeaderGetContextHeader (VOID)
 
__inline PFX_DRIVER_GLOBALS GetDriverGlobals (VOID)
 
WDFTYPE GetType (VOID)
 
USHORT GetObjectSize (VOID)
 
LONG GetRefCnt (VOID)
 
FxTagTrackerGetTagTracker (VOID)
 
CfxDeviceGetDevice (VOID)
 
CfxDeviceBaseGetDeviceBase (VOID)
 
VOID SetDeviceBase (__in CfxDeviceBase *DeviceBase)
 
__inline VOID CallCleanup (VOID)
 
ULONG __inline AddRef (__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG Release (__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG AddRefOverride (__in WDFOBJECT_OFFSET Offset, __in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG ReleaseOverride (__in WDFOBJECT_OFFSET Offset, __in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual _Must_inspect_result_ NTSTATUS QueryInterface (__in FxQueryInterfaceParams *Params)
 
VOID MarkTraceState (VOID)
 
BOOLEAN __inline IsTraceState (VOID)
 
VOID __inline TraceDroppedEvent (__in FxObjectDroppedEvent Event)
 
VOID MarkPassiveDispose (__in FxObjectLockState State=ObjectLock)
 
VOID MarkPassiveCallbacks (__in FxObjectLockState State=ObjectLock)
 
VOID MarkForceDisposeThread (__in FxObjectLockState State=ObjectLock)
 
BOOLEAN IsPassiveCallbacks (__in BOOLEAN AcquireLock=TRUE)
 
BOOLEAN IsPassiveDispose (__in BOOLEAN AcquireLock=TRUE)
 
BOOLEAN IsForceDisposeThread (__in BOOLEAN AcquireLock=TRUE)
 
VOID MarkCommitted (VOID)
 
BOOLEAN IsCommitted (VOID)
 
VOID MarkDisposeOverride (__in FxObjectLockState State=ObjectLock)
 
VOID MarkNoDeleteDDI (__in FxObjectLockState State=ObjectLock)
 
BOOLEAN IsNoDeleteDDI (VOID)
 
_Must_inspect_result_ NTSTATUS Commit (__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
 
VOID DeleteFromFailedCreate (VOID)
 
VOID ClearEvtCallbacks (VOID)
 
BOOLEAN EarlyDispose (VOID)
 
virtual VOID DeleteObject (VOID)
 
_Must_inspect_result_ NTSTATUS AssignParentObject (__in FxObject *ParentObject)
 
_Must_inspect_result_ NTSTATUS AddContext (__in FxContextHeader *Header, __in PVOID *Context, __in PWDF_OBJECT_ATTRIBUTES Attributes)
 
_Must_inspect_result_ NTSTATUS RemoveParentAssignment (VOID)
 
_Must_inspect_result_ FxObjectGetParentObjectReferenced (__in PVOID Tag)
 
BOOLEAN IsDisposed (VOID)
 

Static Public Member Functions

static _Must_inspect_result_ NTSTATUS _Create (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_TIMER_CONFIG Config, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in FxObject *ParentObject, __out WDFTIMER *Timer)
 
- Static Public Member Functions inherited from FxObject
static FxObject_FromDisposeEntry (__in PSINGLE_LIST_ENTRY Entry)
 
static FxObject_GetObjectFromHandle (__in WDFOBJECT Handle, __inout PWDFOBJECT_OFFSET ObjectOffset)
 
static PVOID __inline _ToHandle (__in FxObject *Object)
 
static VOID __inline _ReferenceActual (__in WDFOBJECT Object, __in_opt PVOID Tag, __in LONG Line, __in PSTR File)
 
static VOID __inline _DereferenceActual (__in WDFOBJECT Object, __in_opt PVOID Tag, __in LONG Line, __in PSTR File)
 
static PVOID _GetDebugBase (__in FxObject *Object)
 
static PFX_POOL_HEADER _CleanupPointer (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObject *Object)
 
static _Must_inspect_result_ NTSTATUS _GetEffectiveLock (__in FxObject *Object, __in_opt IFxHasCallbacks *Callbacks, __in BOOLEAN AutomaticLocking, __in BOOLEAN PassiveCallbacks, __out FxCallbackLock **CallbackLock, __out_opt FxObject **CallbackLockObject)
 
static _Must_inspect_result_ NTSTATUS _ObjectQuery (_In_ FxObject *Object, _In_ CONST GUID *Guid, _In_ ULONG QueryBufferLength, _Out_writes_bytes_(QueryBufferLength) PVOID QueryBuffer)
 

Private Member Functions

VOID FlushAndRundown (VOID)
 

Private Attributes

MxTimer m_Timer
 
FxObjectm_Object
 
ULONG m_Period
 
ULONG m_TolerableDelay
 
BOOLEAN m_UseHighResolutionTimer
 
FxCallbackLockm_CallbackLock
 
FxObjectm_CallbackLockObject
 
PFN_WDF_TIMER m_Callback
 
FxSystemWorkItemm_SystemWorkItem
 
volatile POINTER_ALIGNMENT MxThread m_CallbackThread
 
MxThread m_StopThread
 
BOOLEAN m_StopAgain
 
BOOLEAN m_StartAborted
 
BOOLEAN m_RunningDown
 

Static Private Attributes

static FN_WDF_SYSTEMWORKITEM _FxTimerWorkItemCallback
 
static MdDeferredRoutineType _FxTimerDpcThunk
 
static MdExtCallbackType _FxTimerExtCallbackThunk
 

Additional Inherited Members

- Protected Member Functions inherited from FxObject
 FxObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType ObjectType)
 
FxObjectDebugExtensionGetDebugExtension (VOID)
 
BOOLEAN IsDebug (VOID)
 
VOID AllocateTagTracker (__in WDFTYPE Type)
 
virtual VOID SelfDestruct (VOID)
 
PVOID __inline GetObjectHandleUnchecked (VOID)
 
VOID __inline DestroyChildren (VOID)
 
VOID DeleteEarlyDisposedObject (VOID)
 
- Static Protected Member Functions inherited from FxObject
static PVOID _GetBase (__in FxObject *Object)
 
- Protected Attributes inherited from FxObject
union {
   CfxDeviceBase *   m_DeviceBase
 
   CfxDevice *   m_Device
 
}; 
 

Detailed Description

Definition at line 42 of file fxtimer.hpp.

Constructor & Destructor Documentation

◆ FxTimer()

FxTimer::FxTimer ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals)

Definition at line 40 of file fxtimer.cpp.

42  :
43  FxNonPagedObject(FX_TYPE_TIMER, sizeof(FxTimer), FxDriverGlobals)
44 {
45  m_Object = NULL;
46  m_Period = 0;
47  m_TolerableDelay = 0;
50  m_Callback = NULL;
57 
58  //
59  // Mark the object has having passive level dispose so that KeFlushQueuedDpcs
60  // can be called in Dispose().
61  //
63 
65 }
ULONG m_Period
Definition: fxtimer.hpp:60
FxNonPagedObject(__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
FxSystemWorkItem * m_SystemWorkItem
Definition: fxtimer.hpp:94
FxCallbackLock * m_CallbackLock
Definition: fxtimer.hpp:77
PFN_WDF_TIMER m_Callback
Definition: fxtimer.hpp:88
VOID MarkPassiveDispose(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:944
#define FALSE
Definition: types.h:117
VOID MarkDisposeOverride(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1101
MxThread m_StopThread
Definition: fxtimer.hpp:107
BOOLEAN m_StartAborted
Definition: fxtimer.hpp:117
BOOLEAN m_RunningDown
Definition: fxtimer.hpp:122
#define NULL
Definition: types.h:112
volatile POINTER_ALIGNMENT MxThread m_CallbackThread
Definition: fxtimer.hpp:101
BOOLEAN m_StopAgain
Definition: fxtimer.hpp:112
FxObject * m_CallbackLockObject
Definition: fxtimer.hpp:83
ULONG m_TolerableDelay
Definition: fxtimer.hpp:65
FxObject * m_Object
Definition: fxtimer.hpp:55

Referenced by _Create().

◆ ~FxTimer()

FxTimer::~FxTimer ( VOID  )
virtual

Definition at line 67 of file fxtimer.cpp.

68 {
69  //
70  // If this hits, its because someone destroyed the TIMER by
71  // removing too many references by mistake without calling WdfObjectDelete
72  //
73  if (m_Object != NULL) {
76  "WDFTIMER %p destroyed without calling WdfObjectDelete, "
77  "or by Framework processing DeviceRemove. Possible reference count "
78  "problem?", GetObjectHandleUnchecked());
80  }
81 
83 }
FxSystemWorkItem * m_SystemWorkItem
Definition: fxtimer.hpp:94
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define ASSERT(a)
Definition: mode.c:44
PVOID __inline GetObjectHandleUnchecked(VOID)
Definition: fxobject.hpp:446
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
FxVerifierDbgBreakPoint(pFxDriverGlobals)
FxObject * m_Object
Definition: fxtimer.hpp:55

Member Function Documentation

◆ _Create()

return FxTimer::_Create ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in PWDF_TIMER_CONFIG  Config,
__in PWDF_OBJECT_ATTRIBUTES  Attributes,
__in FxObject ParentObject,
__out WDFTIMER *  Timer 
)
static

Definition at line 87 of file fxtimer.cpp.

94 {
97 
98  pFxTimer = new(FxDriverGlobals, Attributes) FxTimer(FxDriverGlobals);
99 
100  if (pFxTimer == NULL) {
102  }
103 
105  Attributes,
106  Config,
107  ParentObject,
108  Timer
109  );
110 
111  if (!NT_SUCCESS(status)) {
113  }
114 
115  return status;
116 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG NTSTATUS
Definition: precomp.h:26
FxTimer(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxtimer.cpp:40
_Must_inspect_result_ NTSTATUS Initialize(__in PWDF_OBJECT_ATTRIBUTES Attributes, __in PWDF_TIMER_CONFIG Config, __in FxObject *ParentObject, __out WDFTIMER *Timer)
Definition: fxtimer.cpp:120
FxTimer * pFxTimer
Definition: fxtimerapi.cpp:234
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:474
#define NULL
Definition: types.h:112
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
static SERVICE_STATUS status
Definition: service.c:31
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
Definition: ps.c:97

◆ Dispose()

BOOLEAN FxTimer::Dispose ( VOID  )
virtual

Reimplemented from FxObject.

Definition at line 458 of file fxtimer.cpp.

459 {
460  KIRQL irql;
461 
462  // MarkPassiveDispose() in Initialize ensures this
464 
465  //
466  // Signal that we are running down.
467  //
468  Lock(&irql);
470  Unlock(irql);
471 
472  //
473  // Cancel the timer, wait for its callback, then cleanup.
474  //
475  FlushAndRundown();
476 
477  return TRUE;
478 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
#define TRUE
Definition: types.h:120
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define ASSERT(a)
Definition: mode.c:44
static __inline KIRQL MxGetCurrentIrql()
Definition: mxgeneralkm.h:86
VOID FlushAndRundown(VOID)
Definition: fxtimer.cpp:481
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
BOOLEAN m_RunningDown
Definition: fxtimer.hpp:122
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124

◆ FlushAndRundown()

VOID FxTimer::FlushAndRundown ( VOID  )
private

Definition at line 481 of file fxtimer.cpp.

496 {
497  FxObject* pObject;
498 
501  "Deleting WDFTIMER %p from with in the callback will "
502  "lead to deadlock, PRKTHREAD %p",
505  }
506 
507  //
508  // Cancel the timer, wait for its callback.
509  //
510  Stop(TRUE);
511 
512  //
513  // Delete will also wait for the workitem to exit.
514  //
515  if (m_SystemWorkItem != NULL) {
518  }
519 
520  //
521  // Release our reference count to the associated parent object if present
522  //
523  if (m_Object != NULL) {
524  pObject = m_Object;
525  m_Object = NULL;
526 
527  pObject->RELEASE(this);
528  }
529 
530  //
531  // Perform our final release to ourselves, destroying the FxTimer
532  //
533  RELEASE(this);
534 }
virtual VOID DeleteObject(VOID)
FxObject * pObject
FxSystemWorkItem * m_SystemWorkItem
Definition: fxtimer.hpp:94
#define TRUE
Definition: types.h:120
BOOLEAN Stop(__in BOOLEAN Wait)
Definition: fxtimer.cpp:633
#define RELEASE(_tag)
Definition: fxobject.hpp:50
#define TRACINGDEVICE
Definition: dbgtrace.h:58
WDFTIMER GetHandle(VOID)
Definition: fxtimer.hpp:189
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
static __inline MxThread MxGetCurrentThread()
Definition: mxgeneralkm.h:61
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
volatile POINTER_ALIGNMENT MxThread m_CallbackThread
Definition: fxtimer.hpp:101
FxVerifierDbgBreakPoint(pFxDriverGlobals)
FxObject * m_Object
Definition: fxtimer.hpp:55

Referenced by Dispose().

◆ GetHandle()

WDFTIMER FxTimer::GetHandle ( VOID  )
inline

Definition at line 189 of file fxtimer.hpp.

192  {
193  return (WDFTIMER) GetObjectHandle();
194  }
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603

Referenced by FlushAndRundown(), Start(), Stop(), and TimerHandler().

◆ GetObject()

WDFOBJECT FxTimer::GetObject ( VOID  )
inline

Definition at line 176 of file fxtimer.hpp.

179  {
180  if( m_Object != NULL ) {
181  return m_Object->GetObjectHandle();
182  }
183  else {
184  return NULL;
185  }
186  }
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
#define NULL
Definition: types.h:112
FxObject * m_Object
Definition: fxtimer.hpp:55

◆ Initialize()

_Must_inspect_result_ NTSTATUS FxTimer::Initialize ( __in PWDF_OBJECT_ATTRIBUTES  Attributes,
__in PWDF_TIMER_CONFIG  Config,
__in FxObject ParentObject,
__out WDFTIMER *  Timer 
)

Definition at line 120 of file fxtimer.cpp.

126 {
128  IFxHasCallbacks* pCallbacks;
130  BOOLEAN isPassiveTimer;
131 
133  pCallbacks = NULL;
134  isPassiveTimer = FALSE;
135 
136  m_Period = Config->Period;
137 
138  // Set tolerable delay.
139  if (Config->Size > sizeof(WDF_TIMER_CONFIG_V1_7)) {
140  m_TolerableDelay = Config->TolerableDelay;
141  }
142 
143  if (Config->Size > sizeof(WDF_TIMER_CONFIG_V1_11)) {
144  m_UseHighResolutionTimer = Config->UseHighResolutionTimer;
145  }
146 
147  // Set users callback function
148  m_Callback = Config->EvtTimerFunc;
149 
150  //
151  // Decide whether to use the legacy KTimer or the new Ktimer2/ExTimer
152  // and call the appropriate initialization routine.
153  // The new ExTimers expose two kind of timers:no wake timers and the
154  // high resolution timers. For kernel mode, these timers are only exposed
155  // to new clients.
156  // For user mode,the underlying Threadpool APIs internally were upgraded
157  // to using the no wake timers and we don't expose the High
158  // resolution timers. Therefore the user mode code does not need to use
159  // the ex initialization.
160  //
161 
162 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
163  // __REACTOS__ Ex timers are not supported
164  // if (pFxDriverGlobals->IsVersionGreaterThanOrEqualTo(1,13)) {
165  // status = m_Timer.InitializeEx(this, FxTimer::_FxTimerExtCallbackThunk, m_Period,
166  // m_TolerableDelay, m_UseHighResolutionTimer);
167  // } else
168  {
170  }
171 #else
173 #endif
174 
175  if (!NT_SUCCESS(status)) {
178  "Failed to initialize timer %!STATUS!", status);
179  return status;
180  }
181 
182  //
183  // As long as we are associated, the parent object holds a reference
184  // count on the TIMER.
185  //
186  // We keep an extra reference count since on Dispose, we wait until
187  // all outstanding DPCs complete before allowing finalization.
188  //
189  // This reference must be taken early before we return any failure,
190  // since Dispose() expects this extra reference, and Dispose() will
191  // be called even if we return a failure status right now.
192  //
193  ADDREF(this);
194 
195  m_DeviceBase = FxDeviceBase::_SearchForDevice(ParentObject, &pCallbacks);
196  if (m_DeviceBase == NULL) {
198  }
199 
200  if (Attributes->ExecutionLevel == WdfExecutionLevelPassive) {
201  isPassiveTimer = TRUE;
202  }
203 
204  //
205  // Configure Serialization for the callbacks on the supplied object.
206  //
208  ParentObject,
209  pCallbacks,
210  Config->AutomaticSerialization,
211  isPassiveTimer,
214  );
215 
216  if (!NT_SUCCESS(status)) {
218 
219 
220 
221 
222 
223 
226  "ParentObject %p cannot automatically synchronize callbacks "
227  "with a Timer since it is configured for passive level callback "
228  "constraints. Set AutomaticSerialization to FALSE. %!STATUS!",
229  Attributes->ParentObject, status);
230  }
231 
232  return status;
233  }
234 
235  //
236  // If the caller wants passive callback then create a workitem.
237  //
238  if (isPassiveTimer) {
242  );
243  if (!NT_SUCCESS(status)) {
245  "Could not allocate workitem: %!STATUS!", status);
246  return status;
247  }
248  }
249 
250  //
251  // We automatically synchronize with and reference count
252  // the lifetime of the framework object to prevent any TIMER races
253  // that can access the object while it is going away.
254  //
255 
256  //
257  // The caller supplied object is the object the caller wants the
258  // TIMER to be associated with, and the framework must ensure this
259  // object remains live until the TIMER object is destroyed. Otherwise,
260  // it could access either object context memory, or an object API
261  // on a freed object.
262  //
263  // Due to the locking model of the framework, the lock may actually
264  // be owned by a higher level object as well. This is the lockObject
265  // returned. As long was we are a child of this object, the lockObject
266  // does not need to be dereferenced since it will notify us of Cleanup
267  // before it goes away.
268  //
269 
270  //
271  // Associate the FxTimer with the object. When this object Cleans up, it
272  // will notify our Dispose function as well.
273  //
274 
275  //
276  // Add a reference to the parent object we are associated with.
277  // We will be notified of Cleanup to release this reference.
278  //
279  ParentObject->ADDREF(this);
280 
281  //
282  // Save the ptr to the object the TIMER is associated with
283  //
284  m_Object = ParentObject;
285 
286  //
287  // Attributes->ParentObject is the same as ParentObject. Since we already
288  // converted it to an object, use that.
289  //
290  status = Commit(Attributes, (WDFOBJECT*)Timer, ParentObject);
291 
292  if (!NT_SUCCESS(status)) {
293  return status;
294  }
295 
296  return status;
297 }
CfxDevice * m_Device
Definition: fxobject.hpp:329
MxTimer m_Timer
Definition: fxtimer.hpp:49
ULONG m_Period
Definition: fxtimer.hpp:60
CHECK_RETURN_IF_USER_MODE __inline NTSTATUS Initialize(__in_opt PVOID TimerContext, __in MdDeferredRoutine TimerCallback, __in LONG Period)
Definition: mxtimerkm.h:119
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PVOID WdmObject, __out FxSystemWorkItem **pObject)
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
_Must_inspect_result_ NTSTATUS Commit(__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
Definition: fxobject.cpp:904
static _Must_inspect_result_ NTSTATUS _GetEffectiveLock(__in FxObject *Object, __in_opt IFxHasCallbacks *Callbacks, __in BOOLEAN AutomaticLocking, __in BOOLEAN PassiveCallbacks, __out FxCallbackLock **CallbackLock, __out_opt FxObject **CallbackLockObject)
Definition: fxobject.cpp:1044
FxSystemWorkItem * m_SystemWorkItem
Definition: fxtimer.hpp:94
FxCallbackLock * m_CallbackLock
Definition: fxtimer.hpp:77
#define TRUE
Definition: types.h:120
PFN_WDF_TIMER m_Callback
Definition: fxtimer.hpp:88
BOOLEAN m_UseHighResolutionTimer
Definition: fxtimer.hpp:71
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
static FxDeviceBase * _SearchForDevice(__in FxObject *Object, __out_opt IFxHasCallbacks **Callbacks)
#define FALSE
Definition: types.h:117
#define ADDREF(_tag)
Definition: fxobject.hpp:49
#define STATUS_WDF_INCOMPATIBLE_EXECUTION_LEVEL
Definition: wdfstatus.h:198
unsigned char BOOLEAN
#define TRACINGDEVICE
Definition: dbgtrace.h:58
PFX_DRIVER_GLOBALS pFxDriverGlobals
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CfxDeviceBase * m_DeviceBase
Definition: fxobject.hpp:328
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:474
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
static MdDeferredRoutineType _FxTimerDpcThunk
Definition: fxtimer.hpp:213
static SERVICE_STATUS status
Definition: service.c:31
FxObject * m_CallbackLockObject
Definition: fxtimer.hpp:83
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
ULONG m_TolerableDelay
Definition: fxtimer.hpp:65
Definition: ps.c:97
FxObject * m_Object
Definition: fxtimer.hpp:55

Referenced by _Create().

◆ Start()

BOOLEAN FxTimer::Start ( __in LARGE_INTEGER  DueTime)

Definition at line 537 of file fxtimer.cpp.

558 {
559  KIRQL irql;
560  BOOLEAN result = FALSE;
562 
563  Lock(&irql);
564 
565  //
566  // Basic check to make sure timer object is not deleted. Note that this
567  // logic is not foolproof b/c someone may dispose the timer just after this
568  // validation and before the start routine queues the timer; but at least it
569  // is better than nothing.
570  //
571  if (m_RunningDown) {
573  "Calling WdfTimerStart when the timer object %p is"
574  " running down will lead to a crash",
575  GetHandle());
577  }
578  else if (m_StopThread != NULL) {
581  "WDFTIMER 0x%p is been stopped by PRKTHREAD 0x%p. "
582  "Ignoring the request to start timer",
584 
585  //
586  // Let the stop thread know that we aborted this start operation.
587  //
589  }
590  else {
591  //
592  // Yes, the timer can be started.
593  //
594  startTimer = TRUE;
595  }
596 
597  Unlock(irql);
598 
599  if (startTimer) {
600  //
601  // It may be possible for the timer to fire before the call from
602  // KeSetTimerEx completes. If this happens and if the timer callback
603  // disposes the timer object, a dispose work-item is queued.
604  // This work-item in turn may also run before KeSetTimerEx completes,
605  // making the object invalid by the time we try to take its Lock()
606  // below. This ADDREF() prevents the object from going away and it is
607  // matched by a RELEASE() when we are done.
608  //
609  ADDREF(this);
610 
611  //
612  // Call the tolerable timer API only if OS supports it and driver
613  // requested it.
614  //
616 
617  Lock(&irql);
618  if (m_StopThread != NULL) {
619  m_StopAgain = TRUE;
620  }
621  Unlock(irql);
622 
623  //
624  // See ADDREF() comment above.
625  //
626  RELEASE(this);
627  }
628 
629  return result;
630 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
MxTimer m_Timer
Definition: fxtimer.hpp:49
GLuint64EXT * result
Definition: glext.h:11304
#define TRUE
Definition: types.h:120
KIRQL irql
Definition: wave.h:1
#define RELEASE(_tag)
Definition: fxobject.hpp:50
UCHAR KIRQL
Definition: env_spec_w32.h:591
static void startTimer(void)
Definition: xmllint.c:469
#define FALSE
Definition: types.h:117
#define ADDREF(_tag)
Definition: fxobject.hpp:49
unsigned char BOOLEAN
#define TRACINGDEVICE
Definition: dbgtrace.h:58
__inline BOOLEAN StartWithReturn(__in LARGE_INTEGER DueTime, __in ULONG TolerableDelay=0)
Definition: mxtimerkm.h:209
MxThread m_StopThread
Definition: fxtimer.hpp:107
WDFTIMER GetHandle(VOID)
Definition: fxtimer.hpp:189
BOOLEAN m_StartAborted
Definition: fxtimer.hpp:117
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
BOOLEAN m_RunningDown
Definition: fxtimer.hpp:122
#define NULL
Definition: types.h:112
_In_ WDFTIMER _In_ LONGLONG DueTime
Definition: wdftimer.h:187
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
BOOLEAN m_StopAgain
Definition: fxtimer.hpp:112
FxVerifierDbgBreakPoint(pFxDriverGlobals)
ULONG m_TolerableDelay
Definition: fxtimer.hpp:65

◆ Stop()

BOOLEAN FxTimer::Stop ( __in BOOLEAN  Wait)

Definition at line 633 of file fxtimer.cpp.

636 {
637  KIRQL irql;
638  BOOLEAN result;
639 #ifdef DBG
640  ULONG retryCount = 0;
641 #endif
642 
643  if (Wait) {
644  //
645  // If the caller specified wait, we will flush the queued DPC's
646  // to ensure any outstanding timer DPC has finished executing.
647  //
648  // The return value of timers is ambiguous in the case of periodic
649  // timers, so we flush whenever the caller desires to ensure all
650  // callbacks are complete.
651  //
652 
653  //
654  // Make sure the stop is not called from within the callback
655  // because it's semantically incorrect and can lead to deadlock
656  // if the wait parameter is set.
657  //
661  "Calling WdfTimerStop from within the WDFTIMER "
662  "%p callback will lead to deadlock, PRKTHREAD %p",
665  return FALSE;
666  }
667 
668  if (GetDriverGlobals()->FxVerifierOn) {
672  "WdfTimerStop(Wait==TRUE) called at IRQL > PASSIVE_LEVEL, "
673  "current IRQL = 0x%x", Mx::MxGetCurrentIrql());
675  return FALSE;
676  }
677  }
678 
679  //
680  // Prevent the callback from restarting the timer.
681  //
682  Lock(&irql);
683 
684  //
685  // Driver issue.
686  //
687  if (GetDriverGlobals()->IsVerificationEnabled(1, 9, OkForDownLevel) &&
688  m_StopThread != NULL) {
691  "Detected multiple calls to WdfTimerStop for "
692  "WDFTIMER 0x%p, stop in progress on PRKTHREAD 0x%p, "
693  "current PRKTHREAD 0x%p",
696  }
697 
698  //
699  // Reset the flag to find out if the timer's start logic aborts
700  // b/c of this stop operation.
701  //
703 
704  //
705  // This field is used for the following purposes:
706  // (a) Let the start thread know not to restart the timer while stop
707  // is running.
708  // (b) Detect concurrent calls to stop the timer.
709  // (c) To remember the thread id of the stopping thread.
710  //
712 
713  do {
714 #ifdef DBG
715  retryCount++;
716 #endif
717  //
718  // Reset flag to catch when timer callback is restarting the
719  // timer.
720  //
721  m_StopAgain = FALSE;
722  Unlock(irql);
723 
724  //
725  // Cancel the timer
726  //
727  result = m_Timer.Stop();
728 
729  //
730  // Wait for the timer's DPC.
731  //
733 
734  //
735  // Wait for the timer's passive work item.
736  //
737  if (m_SystemWorkItem != NULL) {
739  }
740 
741  Lock(&irql);
742 #ifdef DBG
743  //
744  // This loop is run for a max of 2 times.
745  //
746  ASSERT(retryCount < 3);
747 #endif
748  //
749  // Re-stop timer if timer was not in queue and
750  // it got restarted in callback.
751  //
752  }while (result == FALSE && m_StopAgain);
753 
754  //
755  // Stop completed.
756  //
757  m_StopThread = NULL;
758  m_StopAgain = FALSE;
759 
760  //
761  // Return TRUE (i.e., timer in queue) if
762  // (a) stop logic successfully cancelled the timer or
763  // (b) the start logic aborted b/c of this stop.
764  //
765  if (m_StartAborted) {
766  result = TRUE;
768  }
769 
770  Unlock(irql);
771  }
772  else {
773  //
774  // Caller doesn't want any synchronization.
775  // Cancel the timer.
776  //
777  result = m_Timer.Stop();
778  }
779 
780  return result;
781 }
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
MxTimer m_Timer
Definition: fxtimer.hpp:49
__inline VOID FlushQueuedDpcs(VOID)
Definition: mxtimerkm.h:291
GLuint64EXT * result
Definition: glext.h:11304
FxSystemWorkItem * m_SystemWorkItem
Definition: fxtimer.hpp:94
#define TRUE
Definition: types.h:120
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#define ASSERT(a)
Definition: mode.c:44
static __inline KIRQL MxGetCurrentIrql()
Definition: mxgeneralkm.h:86
MxThread m_StopThread
Definition: fxtimer.hpp:107
WDFTIMER GetHandle(VOID)
Definition: fxtimer.hpp:189
BOOLEAN m_StartAborted
Definition: fxtimer.hpp:117
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
static __inline MxThread MxGetCurrentThread()
Definition: mxgeneralkm.h:61
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
volatile POINTER_ALIGNMENT MxThread m_CallbackThread
Definition: fxtimer.hpp:101
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN m_StopAgain
Definition: fxtimer.hpp:112
FxVerifierDbgBreakPoint(pFxDriverGlobals)
_Must_inspect_result_ __inline BOOLEAN Stop(VOID)
Definition: mxtimerkm.h:273

Referenced by FlushAndRundown().

◆ TimerHandler()

VOID FxTimer::TimerHandler ( VOID  )

Definition at line 300 of file fxtimer.cpp.

303 {
305 
306  if (m_Callback != NULL) {
307 
308  //
309  // Save the current thread object pointer. We will use this avoid
310  // deadlock if the driver tries to delete or stop the timer from within
311  // the callback.
312  //
314 
315  if (m_CallbackLock != NULL) {
316  KIRQL irql = 0;
317 
321  }
322  else {
324  }
325 
327  }
328 }
FxCallbackLock * m_CallbackLock
Definition: fxtimer.hpp:77
PFN_WDF_TIMER m_Callback
Definition: fxtimer.hpp:88
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
virtual void Lock(__out PKIRQL PreviousIrql)=0
WDFTIMER GetHandle(VOID)
Definition: fxtimer.hpp:189
virtual void Unlock(__in KIRQL PreviousIrql)=0
static __inline MxThread MxGetCurrentThread()
Definition: mxgeneralkm.h:61
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
#define NULL
Definition: types.h:112
volatile POINTER_ALIGNMENT MxThread m_CallbackThread
Definition: fxtimer.hpp:101
FX_TRACK_DRIVER(fxDriverGlobals)

Member Data Documentation

◆ _FxTimerDpcThunk

VOID FxTimer::_FxTimerDpcThunk
staticprivate

Definition at line 213 of file fxtimer.hpp.

Referenced by Initialize().

◆ _FxTimerExtCallbackThunk

VOID FxTimer::_FxTimerExtCallbackThunk
staticprivate

Definition at line 217 of file fxtimer.hpp.

◆ _FxTimerWorkItemCallback

VOID FxTimer::_FxTimerWorkItemCallback
staticprivate

Definition at line 209 of file fxtimer.hpp.

◆ m_Callback

PFN_WDF_TIMER FxTimer::m_Callback
private

Definition at line 88 of file fxtimer.hpp.

Referenced by FxTimer(), Initialize(), and TimerHandler().

◆ m_CallbackLock

FxCallbackLock* FxTimer::m_CallbackLock
private

Definition at line 77 of file fxtimer.hpp.

Referenced by FxTimer(), Initialize(), and TimerHandler().

◆ m_CallbackLockObject

FxObject* FxTimer::m_CallbackLockObject
private

Definition at line 83 of file fxtimer.hpp.

Referenced by FxTimer(), and Initialize().

◆ m_CallbackThread

volatile POINTER_ALIGNMENT MxThread FxTimer::m_CallbackThread
private

Definition at line 101 of file fxtimer.hpp.

Referenced by FlushAndRundown(), FxTimer(), Stop(), and TimerHandler().

◆ m_Object

FxObject* FxTimer::m_Object
private

Definition at line 55 of file fxtimer.hpp.

Referenced by FlushAndRundown(), FxTimer(), GetObject(), Initialize(), and ~FxTimer().

◆ m_Period

ULONG FxTimer::m_Period
private

Definition at line 60 of file fxtimer.hpp.

Referenced by FxTimer(), and Initialize().

◆ m_RunningDown

BOOLEAN FxTimer::m_RunningDown
private

Definition at line 122 of file fxtimer.hpp.

Referenced by Dispose(), FxTimer(), and Start().

◆ m_StartAborted

BOOLEAN FxTimer::m_StartAborted
private

Definition at line 117 of file fxtimer.hpp.

Referenced by FxTimer(), Start(), and Stop().

◆ m_StopAgain

BOOLEAN FxTimer::m_StopAgain
private

Definition at line 112 of file fxtimer.hpp.

Referenced by FxTimer(), Start(), and Stop().

◆ m_StopThread

MxThread FxTimer::m_StopThread
private

Definition at line 107 of file fxtimer.hpp.

Referenced by FxTimer(), Start(), and Stop().

◆ m_SystemWorkItem

FxSystemWorkItem* FxTimer::m_SystemWorkItem
private

Definition at line 94 of file fxtimer.hpp.

Referenced by FlushAndRundown(), FxTimer(), Initialize(), Stop(), and ~FxTimer().

◆ m_Timer

MxTimer FxTimer::m_Timer
private

Definition at line 49 of file fxtimer.hpp.

Referenced by Initialize(), Start(), and Stop().

◆ m_TolerableDelay

ULONG FxTimer::m_TolerableDelay
private

Definition at line 65 of file fxtimer.hpp.

Referenced by FxTimer(), Initialize(), and Start().

◆ m_UseHighResolutionTimer

BOOLEAN FxTimer::m_UseHighResolutionTimer
private

Definition at line 71 of file fxtimer.hpp.

Referenced by Initialize().


The documentation for this class was generated from the following files: