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 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 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 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 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 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 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 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 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