1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxNonPagedObject.hpp
8 
9 Abstract:
10 
11     This module defines the abstract FxNonPagedObject class.
12 
13 Author:
14 
15 
16 
17 Environment:
18 
19     Both kernel and user mode
20 
21 Revision History:
22 
23 
24         Made mode agnostic
25 
26         IMPORTANT: Common code must call Initialize method of
27         FxNonPagedObject before using it
28 
29         Cannot put CreateAndInitialize method on this class as it
30         cannot be instantiated
31 
32 --*/
33 
34 #ifndef _FXNONPAGEDOBJECT_H_
35 #define _FXNONPAGEDOBJECT_H_
36 
37 extern "C" {
38 
39 #if defined(EVENT_TRACING)
40 #include "FxNonPagedObject.hpp.tmh"
41 #endif
42 
43 }
44 
45 class FxNonPagedObject : public FxObject
46 {
47 private:
48 
49     MxLock  m_NPLock;
50 
51 public:
FxNonPagedObject(__in WDFTYPE Type,__in USHORT Size,__in PFX_DRIVER_GLOBALS FxDriverGlobals)52     FxNonPagedObject(
53         __in WDFTYPE Type,
54         __in USHORT Size,
55         __in PFX_DRIVER_GLOBALS FxDriverGlobals
56         ) :
57         FxObject(Type, Size, FxDriverGlobals)
58     {
59         if (IsDebug()) {
60             if (GetDriverGlobals()->FxVerifierLock) {
61                 //
62                 // VerifierLock CreateAndInitialize failure is not fatal,
63                 // we just won't track anything
64                 //
65                 FxVerifierLock * verifierLock = NULL;
66                 (void) FxVerifierLock::CreateAndInitialize(&verifierLock,
67                                                     GetDriverGlobals(),
68                                                     this);
69                 GetDebugExtension()->VerifierLock = verifierLock;
70             }
71         }
72     }
73 
FxNonPagedObject(__in WDFTYPE Type,__in USHORT Size,__in PFX_DRIVER_GLOBALS FxDriverGlobals,__in FxObjectType ObjectType)74     FxNonPagedObject(
75         __in WDFTYPE Type,
76         __in USHORT Size,
77         __in PFX_DRIVER_GLOBALS FxDriverGlobals,
78         __in FxObjectType ObjectType
79         ) :
80         FxObject(Type, Size, FxDriverGlobals, ObjectType)
81     {
82         if (IsDebug()) {
83             if (GetDriverGlobals()->FxVerifierLock) {
84                 //
85                 // VerifierLock CreateAndInitialize failure is not fatal,
86                 // we just won't track anything
87                 //
88                 FxVerifierLock * verifierLock = NULL;
89                 (void) FxVerifierLock::CreateAndInitialize(&verifierLock,
90                                                     GetDriverGlobals(),
91                                                     this);
92                 GetDebugExtension()->VerifierLock = verifierLock;
93             }
94         }
95     }
96 
97     virtual
~FxNonPagedObject(VOID)98     ~FxNonPagedObject(
99         VOID
100         )
101     {
102         if (IsDebug()) {
103             FxObjectDebugExtension* pExtension;
104 
105             pExtension = GetDebugExtension();
106 
107             if (pExtension->VerifierLock != NULL) {
108                 delete pExtension->VerifierLock;
109                 pExtension->VerifierLock = NULL;
110             }
111         }
112     }
113 
114     _Acquires_lock_(this->m_NPLock.m_Lock)
__drv_maxIRQL(DISPATCH_LEVEL)115     __drv_maxIRQL(DISPATCH_LEVEL)
116     __drv_setsIRQL(DISPATCH_LEVEL)
117     VOID
118     Lock(
119         __out __drv_deref(__drv_savesIRQL) PKIRQL PreviousIrql
120         )
121     {
122         if (IsDebug()) {
123             FxObjectDebugExtension* pExtension;
124 
125             pExtension = GetDebugExtension();
126 
127             if (pExtension->VerifierLock != NULL) {
128                 pExtension->VerifierLock->Lock(PreviousIrql, FALSE);
129                 //
130                 // return here so that we don't acquire the non verified lock
131                 // below
132                 //
133                 return;
134             }
135         }
136 
137         m_NPLock.Acquire(PreviousIrql);
138     }
139 
140     _Releases_lock_(this->m_NPLock.m_Lock)
__drv_requiresIRQL(DISPATCH_LEVEL)141     __drv_requiresIRQL(DISPATCH_LEVEL)
142     __inline
143     VOID
144     Unlock(
145         __in __drv_restoresIRQL KIRQL PreviousIrql
146         )
147     {
148         if (IsDebug()) {
149             FxObjectDebugExtension* pExtension;
150 
151             pExtension = GetDebugExtension();
152 
153             if (pExtension->VerifierLock != NULL) {
154                 pExtension->VerifierLock->Unlock(PreviousIrql, FALSE);
155 
156                 //
157                 // return here so that we don't release the non verified lock
158                 // below
159                 //
160                 return;
161             }
162         }
163 
164         m_NPLock.Release(PreviousIrql);
165     }
166 
167 #if FX_CORE_MODE==FX_CORE_KERNEL_MODE
168 
169     _Acquires_lock_(this->m_NPLock.m_Lock)
__drv_requiresIRQL(DISPATCH_LEVEL)170     __drv_requiresIRQL(DISPATCH_LEVEL)
171     VOID
172     LockAtDispatch(
173         VOID
174         )
175     {
176         if (IsDebug()) {
177             FxObjectDebugExtension* pExtension;
178 
179             pExtension = GetDebugExtension();
180 
181             if (pExtension->VerifierLock != NULL) {
182                 KIRQL previousIrql;
183 
184                 pExtension->VerifierLock->Lock(&previousIrql, TRUE);
185 
186                 ASSERT(previousIrql == DISPATCH_LEVEL);
187                 //
188                 // return here so that we don't acquire the non verified lock
189                 // below
190                 //
191                 return;
192             }
193         }
194 
195         m_NPLock.AcquireAtDpcLevel();
196     }
197 
198     _Requires_lock_held_(this->m_NPLock.m_Lock)
199     _Releases_lock_(this->m_NPLock.m_Lock)
__drv_requiresIRQL(DISPATCH_LEVEL)200     __drv_requiresIRQL(DISPATCH_LEVEL)
201     __inline
202     VOID
203     UnlockFromDispatch(
204         VOID
205         )
206     {
207         if (IsDebug()) {
208             FxObjectDebugExtension* pExtension;
209 
210             pExtension = GetDebugExtension();
211 
212             if (pExtension->VerifierLock != NULL) {
213                 pExtension->VerifierLock->Unlock(DISPATCH_LEVEL, TRUE);
214 
215                 //
216                 // return here so that we don't acquire the non verified lock
217                 // below
218                 //
219                 return;
220             }
221         }
222 
223         m_NPLock.ReleaseFromDpcLevel();
224     }
225 
226 #endif   //FX_CORE_MODE==FX_CORE_KERNEL_MODE
227 };
228 
229 #endif // _FXNONPAGEDOBJECT_H_
230