ReactOS 0.4.15-dev-7918-g2a2556c
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, ...) \
39qf \
40rt \
41FX_VF_FUNCTION( fnName )( _In_ PFX_DRIVER_GLOBALS, ##__VA_ARGS__ );
42
43#define FX_VF_METHOD( classname, fnName ) \
44FX_VF_PAGING \
45FX_VF_NAME_TO_SCOPED_IMP_NAME( classname, fnName )
46
47#define FX_VF_FUNCTION( fnName ) \
48FX_VF_PAGING \
49FX_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 \
66qf \
67rt \
68fnName( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals ) \
69FX_VF_GLOBAL_CHECK_SCOPE( rt, rtDef, fnName, ( FxDriverGlobals ) )
70
71#define FX_DECLARE_VF_FUNCTION_EX( qf, rt, rtDef, fnName ) \
72FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName ) \
73FX_VF_STUB( qf, rt, rtDef, fnName )
74
75#define FX_DECLARE_VF_FUNCTION( rt, fnName ) \
76FX_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 \
83qf \
84rt \
85fnName( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals, at1 a1 ) \
86FX_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 ) \
90FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName, at1 ) \
91FX_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 ) \
95FX_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 \
102qf \
103rt \
104fnName( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals, at1 a1, at2 a2 ) \
105FX_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 ) \
109FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName, at1, at2 ) \
110FX_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 ) \
114FX_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 \
121qf \
122rt \
123fnName( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals, at1 a1, at2 a2, at3 a3 ) \
124FX_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 ) \
128FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName, at1, at2, at3) \
129FX_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 ) \
133FX_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 \
140qf \
141rt \
142fnName( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals, at1 a1, at2 a2, at3 a3, at4 a4 ) \
143FX_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 ) \
147FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName, at1, at2, at3, at4 ) \
148FX_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 ) \
152FX_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) \
210DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _type _fieldname; \
211DECLSPEC_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_