Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

256 lines
7.3 KiB

  1. //
  2. // Common defines used in the mars project.
  3. //
  4. #ifndef __MARSDEV_H
  5. #define __MARSDEV_H
  6. // Number of elements in array
  7. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  8. // Size of struct up to but not including specified member
  9. #define STRUCT_SIZE_TO_MEMBER(s,m) ((DWORD_PTR)(&(((s *)0)->m)))
  10. // Size of a single member of a structure
  11. #define SIZEOF_MEMBER(s,m) sizeof(((s *)0)->m)
  12. // Size of struct up to and including specified member
  13. #define STRUCT_SIZE_INCLUDING_MEMBER(s,m) (STRUCT_SIZE_TO_MEMBER(s,m) + SIZEOF_MEMBER(s,m))
  14. #define SAFERELEASE(p) if ((p) != NULL) { (p)->Release(); (p) = NULL; } else;
  15. // For destructor use -- doesn't NULL pointer
  16. #define SAFERELEASE2(p) if ((p) != NULL) { (p)->Release();} else;
  17. // Do strong typechecking
  18. #ifdef SAFECAST
  19. #undef SAFECAST
  20. #endif
  21. #define SAFECAST(_src, _type) (static_cast<_type>(_src))
  22. //
  23. // Validation functions.
  24. //
  25. #define IsValidReadPtr(ptr) \
  26. ((ptr) && !IsBadReadPtr((ptr), sizeof(*(ptr))))
  27. #define IsValidWritePtr(ptr) \
  28. ((ptr) && !IsBadWritePtr((ptr), sizeof(*(ptr))))
  29. #define IsValidStringW(pstr) \
  30. ((pstr) && !IsBadStringPtrW((pstr), (UINT)-1))
  31. #define IsValidReadBuffer(ptr, n) \
  32. ((ptr) && !IsBadReadPtr((ptr), sizeof(*(ptr)) * (n)))
  33. #define IsValidWriteBuffer(ptr, n) \
  34. ((ptr) && !IsBadWritePtr((ptr), sizeof(*(ptr)) * (n)))
  35. #define IsValidInterfacePtr(punk) \
  36. ((punk) && IsValidReadPtr(punk) && \
  37. !IsBadCodePtr(*((FARPROC*)punk)))
  38. #define IsValidFunctionPtr(pfunc) \
  39. ((NULL != pfunc) && \
  40. !IsBadCodePtr((FARPROC)pfunc))
  41. #define IsValidBstr(bstr) \
  42. ((bstr) && IsValidWriteBuffer((BYTE*)(bstr), SysStringByteLen(bstr)))
  43. #define IsValidOptionalBstr(bstr) \
  44. ((!bstr) || IsValidBstr(bstr))
  45. #define IsValidVariantBoolVal(vb) \
  46. (VARIANT_FALSE == vb || VARIANT_TRUE == vb)
  47. #define IsValidVariantI4(var) \
  48. (VT_I4 == (var).vt)
  49. #define IsValidVariantBstr(var) \
  50. (VT_BSTR == (var).vt && IsValidBstr((var).bstrVal))
  51. #define IsValidVariantMissingOptional(var) \
  52. (VT_ERROR == (var).vt && DISP_E_PARAMNOTFOUND == (var).scode)
  53. #define IsValidFlag(f, fAll) \
  54. (!((f) & ~(fAll)))
  55. BOOL IsValidVariant(VARIANT var);
  56. BOOL IsValidStringPtrBufferW(LPOLESTR* ppstr, UINT n);
  57. #define IsValidString IsValidStringW
  58. #define IsValidStringPtrBuffer IsValidStringPtrBufferW
  59. //
  60. // API parameter validation helpers. Use these on public APIs. If a parameter
  61. // is bad on debug build a RIP message will be generated.
  62. //
  63. #ifdef DEBUG
  64. BOOL API_IsValidReadPtr(void* ptr, UINT cbSize);
  65. BOOL API_IsValidWritePtr(void* ptr, UINT cbSize);
  66. BOOL API_IsValidStringW(LPCWSTR psz);
  67. BOOL API_IsValidReadBuffer(void* ptr, UINT cbSize, UINT n);
  68. BOOL API_IsValidWriteBuffer(void* ptr, UINT cbSize, UINT n);
  69. BOOL API_IsValidInterfacePtr(IUnknown* punk);
  70. BOOL API_IsValidFunctionPtr(void *pfunc);
  71. BOOL API_IsValidVariant(VARIANT var);
  72. BOOL API_IsValidVariantI4(VARIANT var);
  73. BOOL API_IsValidVariantBstr(VARIANT var);
  74. BOOL API_IsValidBstr(BSTR bstr);
  75. BOOL API_IsValidOptionalBstr(BSTR bstr);
  76. BOOL API_IsValidFlag(DWORD dwFlag, DWORD dwAllFlags);
  77. BOOL API_IsValidStringPtrBufferW(LPOLESTR* ppStr, UINT n);
  78. #define API_IsValidString API_IsValidStringW
  79. #define API_IsValidStringPtrBuffer API_IsValidStringPtrBufferW
  80. #endif //Debug
  81. #ifdef DEBUG
  82. #define API_IsValidReadPtr(ptr) \
  83. API_IsValidReadPtr((ptr), sizeof(*(ptr)))
  84. #define API_IsValidWritePtr(ptr) \
  85. API_IsValidWritePtr((ptr), sizeof(*(ptr)))
  86. #define API_IsValidReadBuffer(ptr, n) \
  87. API_IsValidReadBuffer((ptr), sizeof(*(ptr)), (n))
  88. #define API_IsValidWriteBuffer(ptr, n) \
  89. API_IsValidWriteBuffer((ptr), sizeof(*(ptr)), (n))
  90. #else // DEBUG
  91. #define API_IsValidReadPtr IsValidReadPtr
  92. #define API_IsValidWritePtr IsValidWritePtr
  93. #define API_IsValidString IsValidString
  94. #define API_IsValidStringW IsValidStringW
  95. #define API_IsValidReadBuffer IsValidReadBuffer
  96. #define API_IsValidWriteBuffer IsValidWriteBuffer
  97. #define API_IsValidInterfacePtr IsValidInterfacePtr
  98. #define API_IsValidFunctionPtr IsValidFunctionPtr
  99. #define API_IsValidVariant IsValidVariant
  100. #define API_IsValidVariantI4 IsValidVariantI4
  101. #define API_IsValidVariantBstr IsValidVariantBstr
  102. #define API_IsValidBstr IsValidBstr
  103. #define API_IsValidOptionalBstr IsValidOptionalBstr
  104. #define API_IsValidFlag IsValidFlag
  105. #define API_IsValidStringPtrBuffer IsValidStringPtrBufferW
  106. #endif // DEBUG
  107. //
  108. // Function prototypes.
  109. //
  110. BOOL StrEqlW(LPCWSTR psz1, LPCWSTR psz2);
  111. BOOL StrEqlA(LPCSTR psz1, LPCSTR psz2);
  112. #define StrEql StrEqlW
  113. UINT64 HexStringToUINT64W(LPCWSTR lpwstr);
  114. //
  115. // Macro magic to help define away functions.
  116. //
  117. // TO USE:
  118. //
  119. // If you don't want a function to be used in the code do the following:
  120. // #undef funcA
  121. // #define funcA DON_USE(funcA, funcB)
  122. //
  123. // This will result in funcA being redefined to Don_not_use_funcA_use_funcB.
  124. // A compilation error complaining that Don_not_use_funcA_use_funcB is undefined
  125. // will be generated whenever anyone tries to use funcA.
  126. //
  127. #define MACRO_CAT(a,b) \
  128. a##b
  129. #define DONT_USE(a,b) \
  130. MACRO_CAT(Do_not_use_##a,_use_##b)
  131. // return SCRIPT_ERROR upon serious error that shouldn't occur; will break in debug builds
  132. #ifdef DEBUG
  133. #define SCRIPT_ERROR E_FAIL
  134. #else
  135. #define SCRIPT_ERROR S_FALSE
  136. #endif
  137. #define RECTWIDTH(rc) ((rc).right-(rc).left)
  138. #define RECTHEIGHT(rc) ((rc).bottom-(rc).top)
  139. HRESULT SanitizeResult(HRESULT hr);
  140. // BITBOOL macros just make using single-bit bools a little safer. You can't nonchalantly assign
  141. // any "int" value to a bit bool and expect it to always work. "BOOLIFY" it first.
  142. //
  143. #define BOOLIFY(expr) (!!(expr))
  144. // BUGBUG (scotth): we should probably make this a 'bool', but be careful
  145. // because the Alpha compiler might not recognize it yet. Talk to AndyP.
  146. // This isn't a BOOL because BOOL is signed and the compiler produces
  147. // sloppy code when testing for a single bit.
  148. typedef DWORD BITBOOL;
  149. //
  150. #define VARIANT_BOOLIFY(expr) ((expr) ? VARIANT_TRUE : VARIANT_FALSE)
  151. /*
  152. TraceResult Macros
  153. The idea behind these macros is to have one entry and exit point per
  154. function to reduce errors (primarily bad state / leaks). They generally
  155. require an HRESULT hr, and an 'exit' label that returns hr and performs
  156. any cleanup that might be needed.
  157. In addition to encouraging a unified exit point, these macros also debug
  158. spew if something fails (try to only use these macros on things that
  159. should never fail). This can be extremely useful when something is
  160. failing many layers deep in the code. To see the spew, you need to set
  161. TF_TRACERESULT. To break on such failures, set BF_TRACERESULT.
  162. Common mistake: you must set hr when you use IF_FAILEXIT as it is not
  163. automatically set to _hresult (for flexibility).
  164. */
  165. #define IF_FAILEXIT(_hresult) \
  166. if (FAILED(_hresult)) { \
  167. TraceResult(hr); \
  168. goto exit; \
  169. } else
  170. #define IF_NULLEXIT(_palloc) \
  171. if (NULL == (_palloc)) { \
  172. hr = TraceResult(E_OUTOFMEMORY); \
  173. goto exit; \
  174. } else
  175. #define IF_TRUEEXIT(_expression, _hresult) \
  176. if (_expression) { \
  177. hr = TraceResult(_hresult); \
  178. goto exit; \
  179. } else
  180. #define IF_FALSEEXIT(_expression, _hresult) \
  181. if (FALSE == _expression) { \
  182. hr = TraceResult(_hresult); \
  183. goto exit; \
  184. } else
  185. #define TraceResult(_hresult) _hresult
  186. #endif // __MARSDEV_H