18a978a17SVictor Perevertkin //
28a978a17SVictor Perevertkin //    Copyright (C) Microsoft.  All rights reserved.
38a978a17SVictor Perevertkin //
48a978a17SVictor Perevertkin #ifndef _FX_MACROS_H_
58a978a17SVictor Perevertkin #define _FX_MACROS_H_
68a978a17SVictor Perevertkin 
78a978a17SVictor Perevertkin //
88a978a17SVictor Perevertkin // at is for argument type
98a978a17SVictor Perevertkin // a is for argument
108a978a17SVictor Perevertkin // rt is for return type
118a978a17SVictor Perevertkin // fn or FN is for function
128a978a17SVictor Perevertkin // qf is for qualifiers
138a978a17SVictor Perevertkin // rtDef is for return type default value
148a978a17SVictor Perevertkin //
158a978a17SVictor Perevertkin #define WDF_FX_VF_SECTION_NAME PAGEWdfV
168a978a17SVictor Perevertkin #define QUOTE_EXPANSION(tok) #tok
178a978a17SVictor Perevertkin #define FX_VF_SECTION_NAME_QUOTED(tok) QUOTE_EXPANSION(tok)
188a978a17SVictor Perevertkin 
198a978a17SVictor Perevertkin 
208a978a17SVictor Perevertkin 
218a978a17SVictor Perevertkin 
228a978a17SVictor Perevertkin 
238a978a17SVictor Perevertkin 
248a978a17SVictor Perevertkin 
25*1f377076SVictor Perevertkin #if defined(_M_ARM) || defined(__REACTOS__)
268a978a17SVictor Perevertkin #define FX_VF_PAGING
278a978a17SVictor Perevertkin #else
288a978a17SVictor Perevertkin #define FX_VF_PAGING __declspec(code_seg(FX_VF_SECTION_NAME_QUOTED(WDF_FX_VF_SECTION_NAME)))
298a978a17SVictor Perevertkin #endif
308a978a17SVictor Perevertkin 
318a978a17SVictor Perevertkin #define FX_VF_NAME_TO_IMP_NAME( fnName ) Vf_##fnName
32*1f377076SVictor Perevertkin #define FX_VF_NAME_TO_SCOPED_IMP_NAME( classname, fnName ) classname::Vf_##fnName
338a978a17SVictor Perevertkin #define FX_VF_QF_VOID
348a978a17SVictor Perevertkin #define FX_VF_QF_NTSTATUS _Must_inspect_result_
358a978a17SVictor Perevertkin #define FX_VF_DEFAULT_RT_VOID
368a978a17SVictor Perevertkin #define FX_VF_DEFAULT_RT_NTSTATUS STATUS_SUCCESS
378a978a17SVictor Perevertkin 
388a978a17SVictor Perevertkin #define FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName, ...)       \
398a978a17SVictor Perevertkin qf                                                           \
408a978a17SVictor Perevertkin rt                                                           \
418a978a17SVictor Perevertkin FX_VF_FUNCTION( fnName )( _In_ PFX_DRIVER_GLOBALS, ##__VA_ARGS__ );
428a978a17SVictor Perevertkin 
438a978a17SVictor Perevertkin #define FX_VF_METHOD( classname, fnName )   \
448a978a17SVictor Perevertkin FX_VF_PAGING                                \
458a978a17SVictor Perevertkin FX_VF_NAME_TO_SCOPED_IMP_NAME( classname, fnName )
468a978a17SVictor Perevertkin 
478a978a17SVictor Perevertkin #define FX_VF_FUNCTION( fnName )  \
488a978a17SVictor Perevertkin FX_VF_PAGING                      \
498a978a17SVictor Perevertkin FX_VF_NAME_TO_IMP_NAME( fnName )
508a978a17SVictor Perevertkin 
518a978a17SVictor Perevertkin #define FX_VF_GLOBAL_CHECK_SCOPE( rt, rtDef, fnName, params )  \
528a978a17SVictor Perevertkin {                                                              \
538a978a17SVictor Perevertkin     if( FxDriverGlobals->FxVerifierOn ) {                      \
548a978a17SVictor Perevertkin         return FX_VF_NAME_TO_IMP_NAME( fnName ) params;        \
558a978a17SVictor Perevertkin     }                                                          \
568a978a17SVictor Perevertkin     else {                                                     \
578a978a17SVictor Perevertkin         return rtDef;                                          \
588a978a17SVictor Perevertkin     }                                                          \
598a978a17SVictor Perevertkin }
608a978a17SVictor Perevertkin 
618a978a17SVictor Perevertkin //
628a978a17SVictor Perevertkin // zero parameters
638a978a17SVictor Perevertkin //
648a978a17SVictor Perevertkin #define FX_VF_STUB( qf, rt, rtDef, fnName )                        \
658a978a17SVictor Perevertkin __inline                                                           \
668a978a17SVictor Perevertkin qf                                                                 \
678a978a17SVictor Perevertkin rt                                                                 \
688a978a17SVictor Perevertkin fnName( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals )                  \
698a978a17SVictor Perevertkin FX_VF_GLOBAL_CHECK_SCOPE( rt, rtDef, fnName, ( FxDriverGlobals ) )
708a978a17SVictor Perevertkin 
718a978a17SVictor Perevertkin #define FX_DECLARE_VF_FUNCTION_EX( qf, rt, rtDef, fnName ) \
728a978a17SVictor Perevertkin FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName )                 \
738a978a17SVictor Perevertkin FX_VF_STUB( qf, rt, rtDef, fnName )
748a978a17SVictor Perevertkin 
758a978a17SVictor Perevertkin #define FX_DECLARE_VF_FUNCTION( rt, fnName )      \
768a978a17SVictor Perevertkin FX_DECLARE_VF_FUNCTION_EX( FX_VF_QF_ ## rt, rt, FX_VF_DEFAULT_RT_ ## rt, fnName )
778a978a17SVictor Perevertkin 
788a978a17SVictor Perevertkin //
798a978a17SVictor Perevertkin // 1-Parameter Stub Macro
808a978a17SVictor Perevertkin //
818a978a17SVictor Perevertkin #define FX_VF_STUB_P1( qf, rt, rtDef, fnName, at1 )                  \
828a978a17SVictor Perevertkin __inline                                                             \
838a978a17SVictor Perevertkin qf                                                                   \
848a978a17SVictor Perevertkin rt                                                                   \
858a978a17SVictor Perevertkin fnName( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,  at1 a1 )           \
868a978a17SVictor Perevertkin FX_VF_GLOBAL_CHECK_SCOPE( rt, rtDef, fnName, (FxDriverGlobals, a1 ))
878a978a17SVictor Perevertkin 
888a978a17SVictor Perevertkin // 1-Parameter Extended FUNCTION Declaration Macro
898a978a17SVictor Perevertkin #define FX_DECLARE_VF_FUNCTION_P1_EX( qf, rt, rtDef, fnName, at1 ) \
908a978a17SVictor Perevertkin FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName, at1 )                    \
918a978a17SVictor Perevertkin FX_VF_STUB_P1( qf, rt, rtDef, fnName, at1 )
928a978a17SVictor Perevertkin 
938a978a17SVictor Perevertkin // 1-Parameter FUNCTION Declaration Macro
948a978a17SVictor Perevertkin #define FX_DECLARE_VF_FUNCTION_P1( rt, fnName, at1 )           \
958a978a17SVictor Perevertkin FX_DECLARE_VF_FUNCTION_P1_EX( FX_VF_QF_ ## rt, rt, FX_VF_DEFAULT_RT_ ## rt, fnName, at1 )
968a978a17SVictor Perevertkin 
978a978a17SVictor Perevertkin //
988a978a17SVictor Perevertkin // 2-Parameter Stub Macro
998a978a17SVictor Perevertkin //
1008a978a17SVictor Perevertkin #define FX_VF_STUB_P2( qf, rt, rtDef, fnName, at1, at2 )                  \
1018a978a17SVictor Perevertkin __inline                                                               \
1028a978a17SVictor Perevertkin qf                                                                        \
1038a978a17SVictor Perevertkin rt                                                                        \
1048a978a17SVictor Perevertkin fnName( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,  at1 a1, at2 a2 )        \
1058a978a17SVictor Perevertkin FX_VF_GLOBAL_CHECK_SCOPE( rt, rtDef, fnName, (FxDriverGlobals, a1, a2 ))
1068a978a17SVictor Perevertkin 
1078a978a17SVictor Perevertkin // 2-Parameter Extended FUNCTION Declaration Macro
1088a978a17SVictor Perevertkin #define FX_DECLARE_VF_FUNCTION_P2_EX( qf, rt, rtDef, fnName, at1, at2 )  \
1098a978a17SVictor Perevertkin FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName, at1, at2 )                     \
1108a978a17SVictor Perevertkin FX_VF_STUB_P2( qf, rt, rtDef, fnName, at1, at2 )
1118a978a17SVictor Perevertkin 
1128a978a17SVictor Perevertkin // 2-Parameter FUNCTION Declaration Macro
1138a978a17SVictor Perevertkin #define FX_DECLARE_VF_FUNCTION_P2( rt, fnName, at1, at2 )        \
1148a978a17SVictor Perevertkin FX_DECLARE_VF_FUNCTION_P2_EX( FX_VF_QF_ ## rt, rt, FX_VF_DEFAULT_RT_ ## rt, fnName, at1, at2 )
1158a978a17SVictor Perevertkin 
1168a978a17SVictor Perevertkin //
1178a978a17SVictor Perevertkin // 3-Parameter Stub Macro
1188a978a17SVictor Perevertkin //
1198a978a17SVictor Perevertkin #define FX_VF_STUB_P3( qf, rt, rtDef, fnName, at1, at2, at3 )              \
1208a978a17SVictor Perevertkin __inline                                                                \
1218a978a17SVictor Perevertkin qf                                                                         \
1228a978a17SVictor Perevertkin rt                                                                         \
1238a978a17SVictor Perevertkin fnName( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,  at1 a1, at2 a2, at3 a3 ) \
1248a978a17SVictor Perevertkin FX_VF_GLOBAL_CHECK_SCOPE( rt, rtDef, fnName, (FxDriverGlobals, a1, a2, a3))
1258a978a17SVictor Perevertkin 
1268a978a17SVictor Perevertkin // 3-Parameter Extended FUNCTION Declaration Macro
1278a978a17SVictor Perevertkin #define FX_DECLARE_VF_FUNCTION_P3_EX( qf, rt, rtDef, fnName, at1, at2,  at3 ) \
1288a978a17SVictor Perevertkin FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName, at1, at2, at3)                      \
1298a978a17SVictor Perevertkin FX_VF_STUB_P3( qf, rt, rtDef, fnName, at1, at2, at3 )
1308a978a17SVictor Perevertkin 
1318a978a17SVictor Perevertkin // 3-Parameter FUNCTION Declaration Macro
1328a978a17SVictor Perevertkin #define FX_DECLARE_VF_FUNCTION_P3( rt, fnName, at1, at2, at3 )       \
1338a978a17SVictor Perevertkin FX_DECLARE_VF_FUNCTION_P3_EX( FX_VF_QF_ ## rt, rt, FX_VF_DEFAULT_RT_ ## rt, fnName, at1, at2, at3 )
1348a978a17SVictor Perevertkin 
1358a978a17SVictor Perevertkin //
1368a978a17SVictor Perevertkin // 4-Parameter Stub Macro
1378a978a17SVictor Perevertkin //
1388a978a17SVictor Perevertkin #define FX_VF_STUB_P4( qf, rt, rtDef, fnName, at1, at2, at3, at4 )                  \
1398a978a17SVictor Perevertkin __inline                                                                         \
1408a978a17SVictor Perevertkin qf                                                                                  \
1418a978a17SVictor Perevertkin rt                                                                                  \
1428a978a17SVictor Perevertkin fnName( _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,  at1 a1, at2 a2, at3 a3,  at4 a4 ) \
1438a978a17SVictor Perevertkin FX_VF_GLOBAL_CHECK_SCOPE( rt, rtDef, fnName, (FxDriverGlobals, a1, a2, a3, a4))
1448a978a17SVictor Perevertkin 
1458a978a17SVictor Perevertkin // 4-Parameter Extended FUNCTION Declaration Macro
1468a978a17SVictor Perevertkin #define FX_DECLARE_VF_FUNCTION_P4_EX( qf, rt, rtDef, fnName, at1, at2,  at3, at4 ) \
1478a978a17SVictor Perevertkin FX_VF_FUNCTION_PROTOTYPE( qf, rt, fnName, at1, at2, at3, at4 )                     \
1488a978a17SVictor Perevertkin FX_VF_STUB_P4( qf, rt, rtDef, fnName, at1, at2, at3, at4 )
1498a978a17SVictor Perevertkin 
1508a978a17SVictor Perevertkin // 4-Parameter FUNCTION Declaration Macro
1518a978a17SVictor Perevertkin #define FX_DECLARE_VF_FUNCTION_P4( rt, fnName, at1, at2, at3, at4 )        \
1528a978a17SVictor Perevertkin FX_DECLARE_VF_FUNCTION_P4_EX( FX_VF_QF_ ## rt, rt, FX_VF_DEFAULT_RT_ ## rt, fnName, at1, at2, at3, at4 )
1538a978a17SVictor Perevertkin 
1548a978a17SVictor Perevertkin 
1558a978a17SVictor Perevertkin #define FX_TAG 'rDxF'
1568a978a17SVictor Perevertkin 
1578a978a17SVictor Perevertkin #define WDFEXPORT(a) imp_ ## a
1588a978a17SVictor Perevertkin #define VFWDFEXPORT(a) imp_Vf ## a
1598a978a17SVictor Perevertkin 
1608a978a17SVictor Perevertkin #ifndef ARRAY_SIZE
1618a978a17SVictor Perevertkin #define ARRAY_SIZE(_x) (sizeof((_x))/sizeof((_x)[0]))
1628a978a17SVictor Perevertkin #endif
1638a978a17SVictor Perevertkin 
1648a978a17SVictor Perevertkin // VOID
1658a978a17SVictor Perevertkin // FXVERIFY(
1668a978a17SVictor Perevertkin //     PFX_DRIVER_GLOBALS FxDriverGlobals,
1678a978a17SVictor Perevertkin //     <expression>
1688a978a17SVictor Perevertkin //     );
1698a978a17SVictor Perevertkin 
1708a978a17SVictor Perevertkin #define FXVERIFY(_globals, exp)                     \
1718a978a17SVictor Perevertkin {                                                   \
1728a978a17SVictor Perevertkin     if (!(exp)) {                                   \
1738a978a17SVictor Perevertkin         RtlAssert( #exp, __FILE__, __LINE__, NULL );\
1748a978a17SVictor Perevertkin     }                                               \
1758a978a17SVictor Perevertkin }
1768a978a17SVictor Perevertkin 
1778a978a17SVictor Perevertkin // These 2 macros are the equivalent of WDF_ALIGN_SIZE_DOWN and
1788a978a17SVictor Perevertkin // WDF_ALIGN_SIZE_UP.  The difference is that these can evaluate to a constant
1798a978a17SVictor Perevertkin // while the WDF versions will on a fre build, but not on a chk build.  By
1808a978a17SVictor Perevertkin // evaluating to a constant, we can use this in WDFCASSERT.
1818a978a17SVictor Perevertkin 
1828a978a17SVictor Perevertkin // size_t
1838a978a17SVictor Perevertkin // __inline
1848a978a17SVictor Perevertkin // FX_ALIGN_SIZE_DOWN_CONSTANT(
1858a978a17SVictor Perevertkin //     IN size_t Length,
1868a978a17SVictor Perevertkin //     IN size_t AlignTo
1878a978a17SVictor Perevertkin //     )
1888a978a17SVictor Perevertkin #define FX_ALIGN_SIZE_DOWN_CONSTANT(Length, AlignTo) ((Length) & ~((AlignTo) - 1))
1898a978a17SVictor Perevertkin 
1908a978a17SVictor Perevertkin // size_t
1918a978a17SVictor Perevertkin // __inline
1928a978a17SVictor Perevertkin // FX_ALIGN_SIZE_UP_CONSTANT(
1938a978a17SVictor Perevertkin //     IN size_t Length,
1948a978a17SVictor Perevertkin //     IN size_t AlignTo
1958a978a17SVictor Perevertkin //     )
1968a978a17SVictor Perevertkin #define FX_ALIGN_SIZE_UP_CONSTANT(Length, AlignTo)  \
1978a978a17SVictor Perevertkin     FX_ALIGN_SIZE_DOWN_CONSTANT((Length) + (AlignTo) - 1, (AlignTo))
1988a978a17SVictor Perevertkin 
1998a978a17SVictor Perevertkin //
2008a978a17SVictor Perevertkin // Macro which will declare a field within a structure.  This field can then be
2018a978a17SVictor Perevertkin // used to return a WDF handle to the driver since it contains the required
2028a978a17SVictor Perevertkin // FxContextHeader alongside the object itself.
2038a978a17SVictor Perevertkin //
2048a978a17SVictor Perevertkin // DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) is required because FxObject
2058a978a17SVictor Perevertkin // rounds up m_ObjectSize to be a multiple of MEMORY_ALLOCATION_ALIGNMENT.
2068a978a17SVictor Perevertkin // Since we cannot compute this value at runtime in operator new, we must
2078a978a17SVictor Perevertkin // be very careful here and force the alignment ourselves.
2088a978a17SVictor Perevertkin //
2098a978a17SVictor Perevertkin #define DEFINE_EMBEDDED_OBJECT_HANDLE(_type, _fieldname)                       \
2108a978a17SVictor Perevertkin DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _type _fieldname;                  \
2118a978a17SVictor Perevertkin DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) FxContextHeader _fieldname##Context
2128a978a17SVictor Perevertkin 
2138a978a17SVictor Perevertkin //
2148a978a17SVictor Perevertkin // Computes the size of an embedded object in a structure.  To be used on a
2158a978a17SVictor Perevertkin // _embeddedFieldName declared with DEFINE_EMBEDDED_OBJECT_HANDLE.
2168a978a17SVictor Perevertkin //
2178a978a17SVictor Perevertkin #define EMBEDDED_OBJECT_SIZE(_owningClass, _embeddedFieldName)          \
2188a978a17SVictor Perevertkin     (FIELD_OFFSET(_owningClass, _embeddedFieldName ## Context) -        \
2198a978a17SVictor Perevertkin         FIELD_OFFSET(_owningClass, _embeddedFieldName))
2208a978a17SVictor Perevertkin //
2218a978a17SVictor Perevertkin // Placeholder macro for a no-op
2228a978a17SVictor Perevertkin //
2238a978a17SVictor Perevertkin #define DO_NOTHING()                            (0)
2248a978a17SVictor Perevertkin 
2258a978a17SVictor Perevertkin // 4127 -- Conditional Expression is Constant warning
2268a978a17SVictor Perevertkin #define WHILE(constant) \
2278a978a17SVictor Perevertkin __pragma(warning(suppress: 4127)) while(constant)
2288a978a17SVictor Perevertkin 
2298a978a17SVictor Perevertkin #if DBG
2308a978a17SVictor Perevertkin   #if defined(_X86_)
2318a978a17SVictor Perevertkin     #define TRAP() {_asm {int 3}}
2328a978a17SVictor Perevertkin   #else
2338a978a17SVictor Perevertkin     #define TRAP() DbgBreakPoint()
2348a978a17SVictor Perevertkin   #endif
2358a978a17SVictor Perevertkin #else // DBG
2368a978a17SVictor Perevertkin   #define TRAP()
2378a978a17SVictor Perevertkin #endif // DBG
2388a978a17SVictor Perevertkin 
2398a978a17SVictor Perevertkin #if FX_SUPER_DBG
2408a978a17SVictor Perevertkin   #if defined(_X86_)
2418a978a17SVictor Perevertkin     #define COVERAGE_TRAP() {_asm {int 3}}
2428a978a17SVictor Perevertkin   #else
2438a978a17SVictor Perevertkin     #define COVERAGE_TRAP() DbgBreakPoint()
2448a978a17SVictor Perevertkin   #endif
2458a978a17SVictor Perevertkin #else // FX_SUPER_DBG
2468a978a17SVictor Perevertkin     #define COVERAGE_TRAP()
2478a978a17SVictor Perevertkin #endif // FX_SUPER_DBG
2488a978a17SVictor Perevertkin 
2498a978a17SVictor Perevertkin //
2508a978a17SVictor Perevertkin // This is a macro to keep it as cheap as possible.
2518a978a17SVictor Perevertkin //
2528a978a17SVictor Perevertkin #if (FX_CORE_MODE == FX_CORE_USER_MODE)
2538a978a17SVictor Perevertkin #define FxPointerNotNull(FxDriverGlobals, Ptr) \
2548a978a17SVictor Perevertkin     FX_VERIFY_WITH_NAME(DRIVER(BadArgument, TODO), CHECK_NOT_NULL(Ptr), \
2558a978a17SVictor Perevertkin        FxDriverGlobals->Public.DriverName)
2568a978a17SVictor Perevertkin #else
2578a978a17SVictor Perevertkin #define FxPointerNotNull(FxDriverGlobals, Ptr) \
2588a978a17SVictor Perevertkin     (((Ptr) == NULL) ? \
2598a978a17SVictor Perevertkin         FxVerifierNullBugCheck(FxDriverGlobals, _ReturnAddress()), FALSE : \
2608a978a17SVictor Perevertkin         TRUE )
2618a978a17SVictor Perevertkin #endif
2628a978a17SVictor Perevertkin 
2638a978a17SVictor Perevertkin #define FX_MAKE_WSTR_WORKER(x) L ## #x
2648a978a17SVictor Perevertkin #define FX_MAKE_WSTR(x) FX_MAKE_WSTR_WORKER(x)
2658a978a17SVictor Perevertkin 
2668a978a17SVictor Perevertkin #define FX_LITERAL_WORKER(a)    # a
2678a978a17SVictor Perevertkin #define FX_LITERAL(a) FX_LITERAL_WORKER(a)
2688a978a17SVictor Perevertkin 
2698a978a17SVictor Perevertkin //
2708a978a17SVictor Perevertkin // In some cases we assert for some condition to hold (such as asserting a ptr
2718a978a17SVictor Perevertkin // to be non-NULL before accessing it), but prefast will still complain
2728a978a17SVictor Perevertkin // (e.g., in the example given, about NULL ptr access).
2738a978a17SVictor Perevertkin //
2748a978a17SVictor Perevertkin // This macro combines the assert with corresponding assume for prefast.
2758a978a17SVictor Perevertkin //
2768a978a17SVictor Perevertkin #ifdef _PREFAST_
2778a978a17SVictor Perevertkin #define FX_ASSERT_AND_ASSUME_FOR_PREFAST(b) \
2788a978a17SVictor Perevertkin { \
2798a978a17SVictor Perevertkin     bool result=(b); \
2808a978a17SVictor Perevertkin     ASSERTMSG(#b, result); \
2818a978a17SVictor Perevertkin     __assume(result == true); \
2828a978a17SVictor Perevertkin }
2838a978a17SVictor Perevertkin #else
2848a978a17SVictor Perevertkin #define FX_ASSERT_AND_ASSUME_FOR_PREFAST(b) \
2858a978a17SVictor Perevertkin { \
2868a978a17SVictor Perevertkin     ASSERT(b); \
2878a978a17SVictor Perevertkin }
2888a978a17SVictor Perevertkin #endif
2898a978a17SVictor Perevertkin 
2908a978a17SVictor Perevertkin //
2918a978a17SVictor Perevertkin // Macro to make sure that the code is not invoked for UM.
2928a978a17SVictor Perevertkin //
2938a978a17SVictor Perevertkin // Although it is usually preferable to move such code to *um file
2948a978a17SVictor Perevertkin // so that it does not get compiled at all for um, in some cases such approach
2958a978a17SVictor Perevertkin // might fragment the code too much. In such situation this macro can be used.
2968a978a17SVictor Perevertkin //
2978a978a17SVictor Perevertkin #if (FX_CORE_MODE == FX_CORE_USER_MODE)
2988a978a17SVictor Perevertkin #define WDF_VERIFY_KM_ONLY_CODE() \
2998a978a17SVictor Perevertkin     Mx::MxAssertMsg("Unexpected invocation in user mode", FALSE);
3008a978a17SVictor Perevertkin #else
3018a978a17SVictor Perevertkin #define WDF_VERIFY_KM_ONLY_CODE()
3028a978a17SVictor Perevertkin #endif
3038a978a17SVictor Perevertkin 
3048a978a17SVictor Perevertkin //
3058a978a17SVictor Perevertkin // MIN, MAX macros.
3068a978a17SVictor Perevertkin //
3078a978a17SVictor Perevertkin #ifndef MAX
3088a978a17SVictor Perevertkin #define MAX(x,y) ((x) > (y) ? (x) : (y))
3098a978a17SVictor Perevertkin #endif
3108a978a17SVictor Perevertkin 
3118a978a17SVictor Perevertkin #ifndef MIN
3128a978a17SVictor Perevertkin #define MIN(x,y) ((x) < (y) ? (x) : (y))
3138a978a17SVictor Perevertkin #endif
3148a978a17SVictor Perevertkin 
3158a978a17SVictor Perevertkin #ifndef SAFE_RELEASE
3168a978a17SVictor Perevertkin #define SAFE_RELEASE(p) if( NULL != p ) { ( p )->Release(); p = NULL; }
3178a978a17SVictor Perevertkin #endif
3188a978a17SVictor Perevertkin 
3198a978a17SVictor Perevertkin #endif // _FX_MACROS_H_
320