1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxLock.hpp
8 
9 Abstract:
10 
11     This is the C++ header for the FxLock
12 
13     This represents a container for handling locking
14 
15 Author:
16 
17 
18 
19 
20 Revision History:
21 
22 
23 --*/
24 
25 #ifndef _FXLOCK_H_
26 #define _FXLOCK_H_
27 
28 /**
29  * This is the base lock object implementation
30  *
31  * This is intended to be embedded in an FxNonPagedObject
32  * rather than forcing a separate allocation for
33  * non-verifier mode.
34  *
35  * In order to reduce the runtime memory cost of
36  * building in verifier support for a retail version,
37  * a single pointer it stored to FxVerifierLock
38  * if verifier is on. If this pointer is != NULL,
39  * lock calls are proxied to this lock function,
40  * leaving our internal spinlock redundent.
41  *
42  * The decision is to minimize the non-verifier
43  * memory footprint so we do not have to compile
44  * it out for retail builds, but always have it
45  * available through a driver debug setting.
46  */
47 
48 class FxLock {
49 
50 private:
51     MxLock m_lock;
52 
53     // For Verifier
54     FxVerifierLock* m_Verifier;
55 
56 public:
57     FxLock(
58         VOID
59         )
60     {
61 
62 
63 
64 
65         m_lock.Initialize();
66         m_Verifier = NULL;
67     }
68 
69     VOID
70     Initialize(
71         __in FxObject * ParentObject
72         );
73 
74     ~FxLock()
75     {
76         if (m_Verifier != NULL) {
77             delete m_Verifier;
78         }
79     }
80 
81     _When_(this->m_Verifier == NULL, _Acquires_lock_(this->m_lock))
82     inline
83     VOID
84     Lock(
85         __out PKIRQL PreviousIrql
86         )
87     {
88         if (m_Verifier != NULL) {
89             m_Verifier->Lock(PreviousIrql, FALSE);
90         }
91         //  else if (PreviousIrql == NULL) {
92          //     KeAcquireSpinLockAtDpcLevel(&m_lock);
93         //  }
94         else {
95             m_lock.Acquire(PreviousIrql);
96         }
97     }
98 
99     _When_(this->m_Verifier == NULL, _Releases_lock_(this->m_lock))
100     inline
101     void
102     Unlock(
103         __in KIRQL PreviousIrql
104         )
105     {
106         if (m_Verifier != NULL) {
107             m_Verifier->Unlock(PreviousIrql, FALSE);
108         }
109         // else if (AtDpc) {
110         //     KeReleaseSpinLockFromDpcLevel(&m_lock);
111         // }
112         else {
113             m_lock.Release(PreviousIrql);
114         }
115     }
116 
117     _When_(this->m_Verifier == NULL, _Acquires_lock_(this->m_lock))
118     inline
119     VOID
120     LockAtDispatch(
121         VOID
122         )
123     {
124         if (m_Verifier != NULL) {
125             KIRQL previousIrql;
126 
127             m_Verifier->Lock(&previousIrql, TRUE);
128         }
129         else {
130             m_lock.AcquireAtDpcLevel();
131         }
132     }
133 
134    _When_(this->m_Verifier == NULL, _Releases_lock_(this->m_lock))
135    inline
136     void
137     UnlockFromDispatch(
138         VOID
139         )
140     {
141         if (m_Verifier != NULL) {
142             m_Verifier->Unlock(DISPATCH_LEVEL, TRUE);
143         }
144         else {
145             m_lock.ReleaseFromDpcLevel();
146         }
147     }
148 };
149 
150 #endif // _FXLOCK_H_
151