ReactOS  0.4.15-dev-2700-g4b4ffa9
fxmacros.hpp
Go to the documentation of this file.
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_