1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxVerifier.cpp
8 
9 Abstract:
10 
11     This is the main driver framework verifier
12 
13 Environment:
14 
15     kernel/user mode
16 
17 Revision History:
18 
19 
20         Made it mode agnostic
21 
22 --*/
23 
24 #ifndef _FXVERIFIER_H_
25 #define _FXVERIFIER_H_
26 
27 extern "C" {
28 #if defined(EVENT_TRACING)
29 #include "FxVerifier.h.tmh"
30 #endif
31 }
32 
33 
34 enum FxEnhancedVerifierBitFlags {
35     //
36     // low 2 bytes are used for function table Hooking
37     //
38     FxEnhancedVerifierCallbackIrqlAndCRCheck      = 0x00000001,
39     //
40     // Lower nibble of 3rd byte  for forward progress
41     //
42     FxEnhancedVerifierForwardProgressFailAll      = 0x00010000,
43     FxEnhancedVerifierForwardProgressFailRandom   = 0x00020000,
44 
45     //
46     // bit masks
47     //
48     FxEnhancedVerifierFunctionTableHookMask       = 0x0000ffff,
49     FxEnhancedVerifierForwardProgressMask         = 0x000f0000,
50 
51     //
52     // higher nibble of 3rd byte for performance analysis
53     //
54     FxEnhancedVerifierPerformanceAnalysisMask      = 0x00f00000,
55 };
56 
57 #if (FX_CORE_MODE == FX_CORE_USER_MODE)
58 #define FxVerifierBugCheck(FxDriverGlobals, Error, ...)              \
59     FX_VERIFY_WITH_NAME(DRIVER(BadAction, Error),                    \
60                         TRAPMSG("WDF Violation: Please check"        \
61                         "tracelog for a description of this error"), \
62                         FxDriverGlobals->Public.DriverName)
63 #else
64 #define FxVerifierBugCheck(FxDriverGlobals, ...)              \
65         FxVerifierBugCheckWorker(FxDriverGlobals, __VA_ARGS__);
66 #endif
67 
68 //
69 // FxVerifierDbgBreakPoint and FxVerifierBreakOnDeviceStateError are mapped
70 // to FX_VERIFY in UMDF and break regardless of any flags
71 //
72 __inline
73 VOID
FxVerifierDbgBreakPoint(__in PFX_DRIVER_GLOBALS FxDriverGlobals)74 FxVerifierDbgBreakPoint(
75     __in PFX_DRIVER_GLOBALS FxDriverGlobals
76     )
77 {
78 #if FX_CORE_MODE == FX_CORE_KERNEL_MODE
79     CHAR ext[] = "sys";
80 #else
81     CHAR ext[] = "dll";
82 #endif
83 
84     Mx::MxDbgPrint("WDF detected potentially invalid operation by %s.%s "
85              "Dump the driver log (!wdflogdump %s.%s) for more information.\n",
86              FxDriverGlobals->Public.DriverName, ext,
87              FxDriverGlobals->Public.DriverName, ext
88              );
89 
90     if (FxDriverGlobals->FxVerifierDbgBreakOnError) {
91         Mx::MxDbgBreakPoint();
92     } else {
93         Mx::MxDbgPrint("Turn on framework verifier for %s.%s to automatically "
94             "break into the debugger next time it happens.\n",
95             FxDriverGlobals->Public.DriverName, ext);
96     }
97 }
98 
99 __inline
100 VOID
FxVerifierBreakOnDeviceStateError(__in PFX_DRIVER_GLOBALS FxDriverGlobals)101 FxVerifierBreakOnDeviceStateError(
102     __in PFX_DRIVER_GLOBALS FxDriverGlobals
103     )
104 {
105 #if FX_CORE_MODE == FX_CORE_KERNEL_MODE
106         CHAR ext[] = "sys";
107 #else
108         CHAR ext[] = "dll";
109 #endif
110 
111     Mx::MxDbgPrint("WDF detected potentially invalid device state in %s.%s. "
112              "Dump the driver log (!wdflogdump %s.$s) for more information.\n",
113              FxDriverGlobals->Public.DriverName, ext,
114              FxDriverGlobals->Public.DriverName, ext);
115 
116     if (FxDriverGlobals->FxVerifierDbgBreakOnDeviceStateError) {
117         Mx::MxDbgBreakPoint();
118     } else {
119         Mx::MxDbgPrint("Turn on framework verifier for %s.%s to automatically "
120             "break into the debugger next time it happens.\n",
121             FxDriverGlobals->Public.DriverName, ext);
122     }
123 }
124 
125 __inline
126 BOOLEAN
IsFxVerifierFunctionTableHooking(__in PFX_DRIVER_GLOBALS FxDriverGlobals)127 IsFxVerifierFunctionTableHooking(
128     __in PFX_DRIVER_GLOBALS FxDriverGlobals
129     )
130 {
131     if (FxDriverGlobals->FxEnhancedVerifierOptions &
132             FxEnhancedVerifierFunctionTableHookMask) {
133         return TRUE;
134     }
135     else {
136         return FALSE;
137     }
138 }
139 
140 DECLSPEC_NORETURN
141 VOID
142 FxVerifierBugCheckWorker(
143     __in     PFX_DRIVER_GLOBALS FxDriverGlobals,
144     __in     WDF_BUGCHECK_CODES WdfBugCheckCode,
145     __in_opt ULONG_PTR BugCheckParameter2 = 0,
146     __in_opt ULONG_PTR BugCheckParameter3 = 0
147     );
148 
149 DECLSPEC_NORETURN
150 VOID
151 FxVerifierNullBugCheck(
152     __in PFX_DRIVER_GLOBALS FxDriverGlobals,
153     __in PVOID ReturnAddress
154     );
155 
156 __inline
157 NTSTATUS
FxVerifierCheckIrqlLevel(__in PFX_DRIVER_GLOBALS FxDriverGlobals,__in KIRQL Irql)158 FxVerifierCheckIrqlLevel(
159     __in PFX_DRIVER_GLOBALS FxDriverGlobals,
160     __in KIRQL    Irql
161     )
162 /*++
163 
164 Routine Description:
165     Check that current IRQL matches expected IRQL.
166 
167 Arguments:
168     Irql  -  The expected IRQL
169 
170 Return Value:
171     STATUS_SUCCESS                if expected IRQL matches current IRQL.
172     STATUS_INVALID_DEVICE_REQUEST if expected IRQL does not match current IRQL.
173 
174   --*/
175 {
176     //
177     // Full treatment only if VerifierOn is set.
178     //
179     if (FxDriverGlobals->FxVerifierOn) {
180 
181         KIRQL currentIrql = Mx::MxGetCurrentIrql();
182 
183         if (currentIrql <= Irql) {
184             return STATUS_SUCCESS;
185         }
186 
187         DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
188                             "Called at wrong IRQL; at level %d, should be "
189                             "at level %d", currentIrql, Irql);
190 
191         FxVerifierDbgBreakPoint(FxDriverGlobals);
192 
193         return STATUS_INVALID_DEVICE_REQUEST;
194     }
195 
196     //
197     // If Verifier is turned off, always return success.
198     //
199     return STATUS_SUCCESS;
200 }
201 
202 
203 __inline
204 BOOLEAN
IsFxVerifierTestForwardProgressFailAll(__in PFX_DRIVER_GLOBALS FxDriverGlobals)205 IsFxVerifierTestForwardProgressFailAll(
206     __in PFX_DRIVER_GLOBALS FxDriverGlobals
207     )
208 {
209     if (FxDriverGlobals->FxEnhancedVerifierOptions &
210             FxEnhancedVerifierForwardProgressFailAll) {
211         return TRUE;
212     }
213     else {
214         return FALSE;
215     }
216 }
217 
218 __inline
219 BOOLEAN
IsFxVerifierTestForwardProgressFailRandom(__in PFX_DRIVER_GLOBALS FxDriverGlobals)220 IsFxVerifierTestForwardProgressFailRandom(
221     __in PFX_DRIVER_GLOBALS FxDriverGlobals
222     )
223 {
224     if (FxDriverGlobals->FxEnhancedVerifierOptions &
225             FxEnhancedVerifierForwardProgressFailRandom) {
226         return TRUE;
227     }
228     else {
229         return FALSE;
230     }
231 }
232 
233 __inline
234 BOOLEAN
IsFxVerifierTestForwardProgress(__in PFX_DRIVER_GLOBALS FxDriverGlobals)235 IsFxVerifierTestForwardProgress(
236     __in PFX_DRIVER_GLOBALS FxDriverGlobals
237     )
238 {
239     if (FxDriverGlobals->FxEnhancedVerifierOptions &
240             FxEnhancedVerifierForwardProgressMask) {
241         return TRUE;
242     }
243     else {
244         return FALSE;
245     }
246 }
247 
248 __inline
249 BOOLEAN
IsFxPerformanceAnalysis(__in PFX_DRIVER_GLOBALS FxDriverGlobals)250 IsFxPerformanceAnalysis(
251     __in PFX_DRIVER_GLOBALS FxDriverGlobals
252     )
253 {
254     if (FxDriverGlobals->FxEnhancedVerifierOptions &
255             FxEnhancedVerifierPerformanceAnalysisMask) {
256         return TRUE;
257     }
258     else {
259         return FALSE;
260     }
261 }
262 
263 #endif // _FXVERIFIER_H_
264