1 //
2 //    Copyright (C) Microsoft.  All rights reserved.
3 //
4 #ifndef _FX_MACROS_H_
5 #define _FX_MACROS_H_
6 
7 //
8 // at is for argument type
9 // a is for argument
10 // rt is for return type
11 // fn or FN is for function
12 // qf is for qualifiers
13 // rtDef is for return type default value
14 //
15 #define WDF_FX_VF_SECTION_NAME PAGEWdfV
16 #define QUOTE_EXPANSION(tok) #tok
17 #define FX_VF_SECTION_NAME_QUOTED(tok) QUOTE_EXPANSION(tok)
18 
19 
20 
21 
22 
23 
24 
25 #if defined(_M_ARM) || defined(__REACTOS__)
26 #define FX_VF_PAGING
27 #else
28 #define FX_VF_PAGING __declspec(code_seg(FX_VF_SECTION_NAME_QUOTED(WDF_FX_VF_SECTION_NAME)))
29 #endif
30 
31 #define FX_VF_NAME_TO_IMP_NAME( fnName ) Vf_##fnName
32 #define FX_VF_NAME_TO_SCOPED_IMP_NAME( classname, fnName ) classname::Vf_##fnName
33 #define FX_VF_QF_VOID
34 #define FX_VF_QF_NTSTATUS _Must_inspect_result_
35 #define FX_VF_DEFAULT_RT_VOID
36 #define FX_VF_DEFAULT_RT_NTSTATUS STATUS_SUCCESS
37 
38 #define FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName, ...)       \
39 qf                                                           \
40 rt                                                           \
41 FX_VF_FUNCTION( fnName )( _In_ PFX_DRIVER_GLOBALS, ##__VA_ARGS__ );
42 
43 #define FX_VF_METHOD( classname, fnName )   \
44 FX_VF_PAGING                                \
45 FX_VF_NAME_TO_SCOPED_IMP_NAME( classname, fnName )
46 
47 #define FX_VF_FUNCTION( fnName )  \
48 FX_VF_PAGING                      \
49 FX_VF_NAME_TO_IMP_NAME( fnName )
50 
51 #define FX_VF_GLOBAL_CHECK_SCOPE( rt, rtDef, fnName, params )  \
52 {                                                              \
53     if( FxDriverGlobals->FxVerifierOn ) {                      \
54         return FX_VF_NAME_TO_IMP_NAME( fnName ) params;        \
55     }                                                          \
56     else {                                                     \
57         return rtDef;                                          \
58     }                                                          \
59 }
60 
61 //
62 // zero parameters
63 //
64 #define FX_VF_STUB( qf, rt, rtDef, fnName )                        \
65 __inline                                                           \
66 qf                                                                 \
67 rt                                                                 \
68 fnName( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals )                  \
69 FX_VF_GLOBAL_CHECK_SCOPE( rt, rtDef, fnName, ( FxDriverGlobals ) )
70 
71 #define FX_DECLARE_VF_FUNCTION_EX( qf, rt, rtDef, fnName ) \
72 FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName )                 \
73 FX_VF_STUB( qf, rt, rtDef, fnName )
74 
75 #define FX_DECLARE_VF_FUNCTION( rt, fnName )      \
76 FX_DECLARE_VF_FUNCTION_EX( FX_VF_QF_ ## rt, rt, FX_VF_DEFAULT_RT_ ## rt, fnName )
77 
78 //
79 // 1-Parameter Stub Macro
80 //
81 #define FX_VF_STUB_P1( qf, rt, rtDef, fnName, at1 )                  \
82 __inline                                                             \
83 qf                                                                   \
84 rt                                                                   \
85 fnName( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,  at1 a1 )           \
86 FX_VF_GLOBAL_CHECK_SCOPE( rt, rtDef, fnName, (FxDriverGlobals, a1 ))
87 
88 // 1-Parameter Extended FUNCTION Declaration Macro
89 #define FX_DECLARE_VF_FUNCTION_P1_EX( qf, rt, rtDef, fnName, at1 ) \
90 FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName, at1 )                    \
91 FX_VF_STUB_P1( qf, rt, rtDef, fnName, at1 )
92 
93 // 1-Parameter FUNCTION Declaration Macro
94 #define FX_DECLARE_VF_FUNCTION_P1( rt, fnName, at1 )           \
95 FX_DECLARE_VF_FUNCTION_P1_EX( FX_VF_QF_ ## rt, rt, FX_VF_DEFAULT_RT_ ## rt, fnName, at1 )
96 
97 //
98 // 2-Parameter Stub Macro
99 //
100 #define FX_VF_STUB_P2( qf, rt, rtDef, fnName, at1, at2 )                  \
101 __inline                                                               \
102 qf                                                                        \
103 rt                                                                        \
104 fnName( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,  at1 a1, at2 a2 )        \
105 FX_VF_GLOBAL_CHECK_SCOPE( rt, rtDef, fnName, (FxDriverGlobals, a1, a2 ))
106 
107 // 2-Parameter Extended FUNCTION Declaration Macro
108 #define FX_DECLARE_VF_FUNCTION_P2_EX( qf, rt, rtDef, fnName, at1, at2 )  \
109 FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName, at1, at2 )                     \
110 FX_VF_STUB_P2( qf, rt, rtDef, fnName, at1, at2 )
111 
112 // 2-Parameter FUNCTION Declaration Macro
113 #define FX_DECLARE_VF_FUNCTION_P2( rt, fnName, at1, at2 )        \
114 FX_DECLARE_VF_FUNCTION_P2_EX( FX_VF_QF_ ## rt, rt, FX_VF_DEFAULT_RT_ ## rt, fnName, at1, at2 )
115 
116 //
117 // 3-Parameter Stub Macro
118 //
119 #define FX_VF_STUB_P3( qf, rt, rtDef, fnName, at1, at2, at3 )              \
120 __inline                                                                \
121 qf                                                                         \
122 rt                                                                         \
123 fnName( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,  at1 a1, at2 a2, at3 a3 ) \
124 FX_VF_GLOBAL_CHECK_SCOPE( rt, rtDef, fnName, (FxDriverGlobals, a1, a2, a3))
125 
126 // 3-Parameter Extended FUNCTION Declaration Macro
127 #define FX_DECLARE_VF_FUNCTION_P3_EX( qf, rt, rtDef, fnName, at1, at2,  at3 ) \
128 FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName, at1, at2, at3)                      \
129 FX_VF_STUB_P3( qf, rt, rtDef, fnName, at1, at2, at3 )
130 
131 // 3-Parameter FUNCTION Declaration Macro
132 #define FX_DECLARE_VF_FUNCTION_P3( rt, fnName, at1, at2, at3 )       \
133 FX_DECLARE_VF_FUNCTION_P3_EX( FX_VF_QF_ ## rt, rt, FX_VF_DEFAULT_RT_ ## rt, fnName, at1, at2, at3 )
134 
135 //
136 // 4-Parameter Stub Macro
137 //
138 #define FX_VF_STUB_P4( qf, rt, rtDef, fnName, at1, at2, at3, at4 )                  \
139 __inline                                                                         \
140 qf                                                                                  \
141 rt                                                                                  \
142 fnName( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,  at1 a1, at2 a2, at3 a3,  at4 a4 ) \
143 FX_VF_GLOBAL_CHECK_SCOPE( rt, rtDef, fnName, (FxDriverGlobals, a1, a2, a3, a4))
144 
145 // 4-Parameter Extended FUNCTION Declaration Macro
146 #define FX_DECLARE_VF_FUNCTION_P4_EX( qf, rt, rtDef, fnName, at1, at2,  at3, at4 ) \
147 FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName, at1, at2, at3, at4 )                     \
148 FX_VF_STUB_P4( qf, rt, rtDef, fnName, at1, at2, at3, at4 )
149 
150 // 4-Parameter FUNCTION Declaration Macro
151 #define FX_DECLARE_VF_FUNCTION_P4( rt, fnName, at1, at2, at3, at4 )        \
152 FX_DECLARE_VF_FUNCTION_P4_EX( FX_VF_QF_ ## rt, rt, FX_VF_DEFAULT_RT_ ## rt, fnName, at1, at2, at3, at4 )
153 
154 
155 #define FX_TAG 'rDxF'
156 
157 #define WDFEXPORT(a) imp_ ## a
158 #define VFWDFEXPORT(a) imp_Vf ## a
159 
160 #ifndef ARRAY_SIZE
161 #define ARRAY_SIZE(_x) (sizeof((_x))/sizeof((_x)[0]))
162 #endif
163 
164 // VOID
165 // FXVERIFY(
166 //     PFX_DRIVER_GLOBALS FxDriverGlobals,
167 //     <expression>
168 //     );
169 
170 #define FXVERIFY(_globals, exp)                     \
171 {                                                   \
172     if (!(exp)) {                                   \
173         RtlAssert( #exp, __FILE__, __LINE__, NULL );\
174     }                                               \
175 }
176 
177 // These 2 macros are the equivalent of WDF_ALIGN_SIZE_DOWN and
178 // WDF_ALIGN_SIZE_UP.  The difference is that these can evaluate to a constant
179 // while the WDF versions will on a fre build, but not on a chk build.  By
180 // evaluating to a constant, we can use this in WDFCASSERT.
181 
182 // size_t
183 // __inline
184 // FX_ALIGN_SIZE_DOWN_CONSTANT(
185 //     IN size_t Length,
186 //     IN size_t AlignTo
187 //     )
188 #define FX_ALIGN_SIZE_DOWN_CONSTANT(Length, AlignTo) ((Length) & ~((AlignTo) - 1))
189 
190 // size_t
191 // __inline
192 // FX_ALIGN_SIZE_UP_CONSTANT(
193 //     IN size_t Length,
194 //     IN size_t AlignTo
195 //     )
196 #define FX_ALIGN_SIZE_UP_CONSTANT(Length, AlignTo)  \
197     FX_ALIGN_SIZE_DOWN_CONSTANT((Length) + (AlignTo) - 1, (AlignTo))
198 
199 //
200 // Macro which will declare a field within a structure.  This field can then be
201 // used to return a WDF handle to the driver since it contains the required
202 // FxContextHeader alongside the object itself.
203 //
204 // DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) is required because FxObject
205 // rounds up m_ObjectSize to be a multiple of MEMORY_ALLOCATION_ALIGNMENT.
206 // Since we cannot compute this value at runtime in operator new, we must
207 // be very careful here and force the alignment ourselves.
208 //
209 #define DEFINE_EMBEDDED_OBJECT_HANDLE(_type, _fieldname)                       \
210 DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _type _fieldname;                  \
211 DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) FxContextHeader _fieldname##Context
212 
213 //
214 // Computes the size of an embedded object in a structure.  To be used on a
215 // _embeddedFieldName declared with DEFINE_EMBEDDED_OBJECT_HANDLE.
216 //
217 #define EMBEDDED_OBJECT_SIZE(_owningClass, _embeddedFieldName)          \
218     (FIELD_OFFSET(_owningClass, _embeddedFieldName ## Context) -        \
219         FIELD_OFFSET(_owningClass, _embeddedFieldName))
220 //
221 // Placeholder macro for a no-op
222 //
223 #define DO_NOTHING()                            (0)
224 
225 // 4127 -- Conditional Expression is Constant warning
226 #define WHILE(constant) \
227 __pragma(warning(suppress: 4127)) while(constant)
228 
229 #if DBG
230   #if defined(_X86_)
231     #define TRAP() {_asm {int 3}}
232   #else
233     #define TRAP() DbgBreakPoint()
234   #endif
235 #else // DBG
236   #define TRAP()
237 #endif // DBG
238 
239 #if FX_SUPER_DBG
240   #if defined(_X86_)
241     #define COVERAGE_TRAP() {_asm {int 3}}
242   #else
243     #define COVERAGE_TRAP() DbgBreakPoint()
244   #endif
245 #else // FX_SUPER_DBG
246     #define COVERAGE_TRAP()
247 #endif // FX_SUPER_DBG
248 
249 //
250 // This is a macro to keep it as cheap as possible.
251 //
252 #if (FX_CORE_MODE == FX_CORE_USER_MODE)
253 #define FxPointerNotNull(FxDriverGlobals, Ptr) \
254     FX_VERIFY_WITH_NAME(DRIVER(BadArgument, TODO), CHECK_NOT_NULL(Ptr), \
255        FxDriverGlobals->Public.DriverName)
256 #else
257 #define FxPointerNotNull(FxDriverGlobals, Ptr) \
258     (((Ptr) == NULL) ? \
259         FxVerifierNullBugCheck(FxDriverGlobals, _ReturnAddress()), FALSE : \
260         TRUE )
261 #endif
262 
263 #define FX_MAKE_WSTR_WORKER(x) L ## #x
264 #define FX_MAKE_WSTR(x) FX_MAKE_WSTR_WORKER(x)
265 
266 #define FX_LITERAL_WORKER(a)    # a
267 #define FX_LITERAL(a) FX_LITERAL_WORKER(a)
268 
269 //
270 // In some cases we assert for some condition to hold (such as asserting a ptr
271 // to be non-NULL before accessing it), but prefast will still complain
272 // (e.g., in the example given, about NULL ptr access).
273 //
274 // This macro combines the assert with corresponding assume for prefast.
275 //
276 #ifdef _PREFAST_
277 #define FX_ASSERT_AND_ASSUME_FOR_PREFAST(b) \
278 { \
279     bool result=(b); \
280     ASSERTMSG(#b, result); \
281     __assume(result == true); \
282 }
283 #else
284 #define FX_ASSERT_AND_ASSUME_FOR_PREFAST(b) \
285 { \
286     ASSERT(b); \
287 }
288 #endif
289 
290 //
291 // Macro to make sure that the code is not invoked for UM.
292 //
293 // Although it is usually preferable to move such code to *um file
294 // so that it does not get compiled at all for um, in some cases such approach
295 // might fragment the code too much. In such situation this macro can be used.
296 //
297 #if (FX_CORE_MODE == FX_CORE_USER_MODE)
298 #define WDF_VERIFY_KM_ONLY_CODE() \
299     Mx::MxAssertMsg("Unexpected invocation in user mode", FALSE);
300 #else
301 #define WDF_VERIFY_KM_ONLY_CODE()
302 #endif
303 
304 //
305 // MIN, MAX macros.
306 //
307 #ifndef MAX
308 #define MAX(x,y) ((x) > (y) ? (x) : (y))
309 #endif
310 
311 #ifndef MIN
312 #define MIN(x,y) ((x) < (y) ? (x) : (y))
313 #endif
314 
315 #ifndef SAFE_RELEASE
316 #define SAFE_RELEASE(p) if( NULL != p ) { ( p )->Release(); p = NULL; }
317 #endif
318 
319 #endif // _FX_MACROS_H_
320