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.

303 lines
11 KiB

  1. //=--------------------------------------------------------------------------=
  2. // Macros.h
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1997 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. // Handy macros like the ones we use in the VB code base.
  12. //=--------------------------------------------------------------------------=
  13. #ifndef _MACROS_H_
  14. #include <globals.h>
  15. //---------------------------------------------------------------------------
  16. // Debugging Heap Memory Leaks:
  17. // Macros and definitions
  18. //---------------------------------------------------------------------------
  19. #ifdef DEBUG
  20. typedef char * LPSZ;
  21. #define NUM_INST_TABLE_ENTRIES 1024
  22. #define Deb_FILELINEPROTO , LPSTR lpszFile, UINT line
  23. #define Deb_FILELINECALL , __FILE__, __LINE__
  24. #define Deb_FILELINEPASS , lpszFile, line
  25. #else // DEBUG
  26. #define Deb_FILELINEPROTO
  27. #define Deb_FILELINECALL
  28. #define Deb_FILELINEPASS
  29. #endif // DEBUG
  30. // Function prototypes for the actual implementations of the debug heap wrapper functions.
  31. #ifdef DEBUG
  32. LPVOID CtlHeapAllocImpl(HANDLE g_hHeap, DWORD dwFlags, DWORD dwBytes Deb_FILELINEPROTO);
  33. LPVOID CtlHeapReAllocImpl(HANDLE g_hHeap, DWORD dwFlags, LPVOID lpvMem, DWORD dwBytes Deb_FILELINEPROTO);
  34. BOOL CtlHeapFreeImpl(HANDLE g_hHeap, DWORD dwFlags, LPVOID lpvMem);
  35. extern VOID CheckForLeaks(VOID);
  36. inline UINT HashInst(VOID * pv) { return ((UINT) ((ULONG)pv >> 4)) % NUM_INST_TABLE_ENTRIES; } // Hashing function
  37. #endif // DEBUG
  38. #define OleAlloc(dwBytes) CoTaskMemAlloc(dwBytes)
  39. #define OleReAlloc(lpvMem, dwBytes) CoTaskMemReAlloc(lpvMem, dwBytes)
  40. #define OleFree(lpvMem) CoTaskMemFree(lpvMem)
  41. #define New new (g_hHeap Deb_FILELINECALL)
  42. //--------------------------------------------------------------------------------------------------
  43. // Macros for our memory leak detection
  44. #ifdef DEBUG
  45. // Use these functions to allocate memory from the global heap.
  46. #define CtlHeapAlloc(g_hHeap, dwFlags, dwBytes) CtlHeapAllocImpl(g_hHeap, dwFlags, dwBytes Deb_FILELINECALL)
  47. #define CtlHeapReAlloc(g_hHeap, dwFlags, lpvMem, dwBytes) CtlHeapReAllocImpl(g_hHeap, dwFlags, lpvMem, dwBytes Deb_FILELINECALL)
  48. #define CtlHeapFree(g_hHeap, dwFlags, lpvMem) CtlHeapFreeImpl(g_hHeap, dwFlags, lpvMem)
  49. #define CtlAlloc(dwBytes) CtlHeapAllocImpl(g_hHeap, 0, dwBytes Deb_FILELINECALL)
  50. #define CtlAllocZero(dwBytes) CtlHeapAllocImpl(g_hHeap, HEAP_ZERO_MEMORY, dwBytes Deb_FILELINECALL)
  51. #define CtlReAlloc(lpvMem, dwBytes) CtlHeapReAllocImpl(g_hHeap, 0, lpvMem, dwBytes Deb_FILELINECALL)
  52. #define CtlReAllocZero(lpvMem, dwBytes) CtlHeapReAllocImpl(g_hHeap, HEAP_ZERO_MEMORY, lpvMem, dwBytes Deb_FILELINECALL)
  53. #define CtlFree(lpvMem) CtlHeapFreeImpl(g_hHeap, 0, lpvMem)
  54. #define NewCtlHeapAlloc(g_hHeap, dwFlags, dwBytes) CtlHeapAllocImpl(g_hHeap, dwFlags, dwBytes Deb_FILELINEPASS)
  55. #else
  56. // In retail on Win32 we map directly to the Win32 Heap API
  57. #define CtlHeapAlloc(g_hHeap, dwFlags, dwBytes) HeapAlloc(g_hHeap, dwFlags, dwBytes)
  58. #define CtlHeapReAlloc(g_hHeap, dwFlags, lpvMem, dwBytes) HeapReAlloc(g_hHeap, dwFlags, lpvMem, dwBytes)
  59. #define CtlHeapFree(g_hHeap, dwFlags, lpvMem) HeapFree(g_hHeap, dwFlags, lpvMem)
  60. #define CtlAlloc(dwBytes) HeapAlloc(g_hHeap, 0, dwBytes)
  61. #define CtlAllocZero(dwBytes) HeapAlloc(g_hHeap, HEAP_ZERO_MEMORY, dwBytes)
  62. #define CtlReAlloc(lpvMem, dwBytes) HeapReAlloc(g_hHeap, 0, lpvMem, dwBytes)
  63. #define CtlReAllocZero(lpvMem, dwBytes) HeapReAlloc(g_hHeap, HEAP_ZERO_MEMORY, lpvMem, dwBytes)
  64. #define CtlFree(lpvMem) HeapFree(g_hHeap, 0, lpvMem)
  65. #define NewCtlHeapAlloc(g_hHeap, dwFlags, dwBytes) HeapAlloc(g_hHeap, dwFlags, dwBytes)
  66. #endif // DEBUG
  67. // Macros for header files
  68. // SZTHISFILE cannot be defined in header files. These macros avoid its re-definition
  69. #ifdef DEBUG
  70. #define CtlHeapAlloc_Header_Util(g_hHeap, dwFlags, dwBytes) CtlHeapAllocImpl(g_hHeap, dwFlags, dwBytes, __FILE__, __LINE__);
  71. #else
  72. #define CtlHeapAlloc_Header_Util(g_hHeap, dwFlags, dwBytes) HeapAlloc (g_hHeap, dwFlags, dwBytes);
  73. #endif // DEBUG
  74. //=---------------------------------------------------------------------------=
  75. // class CtlNewDelete
  76. //
  77. // This class MUST be inherited by any class in the CTLS Tree that wants
  78. // to use "new" or "delete" to allocate/free.
  79. //
  80. // This class has no data members or virtual functions, so it does not
  81. // change the size of any instances of classes which inherit from it.
  82. //=---------------------------------------------------------------------------=
  83. class CtlNewDelete
  84. {
  85. public:
  86. inline void * _cdecl operator new (size_t size, HANDLE g_hHeap Deb_FILELINEPROTO);
  87. inline void _cdecl operator delete (LPVOID pv, HANDLE g_hHeap Deb_FILELINEPROTO);
  88. inline void _cdecl operator delete (LPVOID pv);
  89. };
  90. //=---------------------------------------------------------------------------=
  91. // CtlNewDelete::operator new
  92. //=---------------------------------------------------------------------------=
  93. // Parameters:
  94. // size_t - [in] what size do we alloc
  95. // g_hHeap - [in] our global heap
  96. // lpszFile - [in] what file are we allocating from
  97. // line - [in] what line # do we allocate from
  98. //
  99. // Output:
  100. // VOID * - new memory.
  101. //
  102. // Notes:
  103. //
  104. // We don't need to worry about ENTERCRITICALSECTION1 here.
  105. // New is either called by the c run-time or after
  106. // g_hHeap has been initialized in DllMain PROCESS_ATTACH.
  107. // In either case this call is synchronized.
  108. // If we try putting ENTERCRITICALSECTION1 here, we will
  109. // blow up if the c run-time is attempting to initialize
  110. // our static objects such as objects w/ global constructors.
  111. inline void * _cdecl CtlNewDelete::operator new (size_t size, HANDLE g_hHeap Deb_FILELINEPROTO)
  112. {
  113. if (!g_hHeap)
  114. {
  115. g_hHeap = GetProcessHeap();
  116. return g_hHeap ? NewCtlHeapAlloc(g_hHeap, 0, size) : NULL;
  117. }
  118. return NewCtlHeapAlloc(g_hHeap, 0, size);
  119. }
  120. //=---------------------------------------------------------------------------=
  121. // CtlNewDelete::operator delete
  122. //=---------------------------------------------------------------------------=
  123. // retail case just uses win32 Local* heap mgmt functions
  124. //
  125. // Parameters:
  126. // void * - [in] free me!
  127. //
  128. // Notes:
  129. //
  130. inline void _cdecl CtlNewDelete::operator delete ( void *ptr, HANDLE g_hHeap Deb_FILELINEPROTO)
  131. {
  132. if (ptr)
  133. CtlHeapFree(g_hHeap, 0, ptr);
  134. }
  135. inline void _cdecl CtlNewDelete::operator delete ( void *ptr)
  136. {
  137. if (ptr)
  138. CtlHeapFree(g_hHeap, 0, ptr);
  139. }
  140. //---------------------------------------------------------------------------
  141. // Convert C's BOOL to Basic's BOOL
  142. //---------------------------------------------------------------------------
  143. #define BASICBOOLOF(f) ((f) ? -1 : 0 )
  144. #define FMAKEBOOL(f) (!!(f))
  145. //---------------------------------------------------------------------------
  146. // Code macros
  147. //---------------------------------------------------------------------------
  148. #define SWAP(type, a, b) { type _z_=(a); (a)=(b); (b)=_z_; }
  149. #if 0
  150. #define loop while(1) // "loop" keyword for infinite loops
  151. #endif // 0
  152. // "scope" keyword for { } that are used just to introduce a new name scope.
  153. // It's disconcerting to see { } without some keyword in front of the {...
  154. #define scope
  155. #define ADDREF(PUNK) \
  156. {if (PUNK) (PUNK)->AddRef();}
  157. #ifndef RELEASE
  158. #define RELEASE(PUNK) \
  159. {if (PUNK) {LPUNKNOWN punkXXX = (PUNK); (PUNK) = NULL; punkXXX->Release();}}
  160. #endif //RELEASE
  161. // In some multiple inheritance cases you need to dis-ambiguate which IUnknown implementation to use
  162. #define RELEASETYPE(PUNK,TYPE) \
  163. {if (PUNK) {LPUNKNOWN punkXXX = (TYPE *)(PUNK); (PUNK) = NULL; punkXXX->Release();}}
  164. #define FREESTRING(bstrVal) \
  165. {if((bstrVal) != NULL) {SysFreeString((bstrVal)); (bstrVal) = NULL; }}
  166. //---------------------------------------------------------------------
  167. // Debug macros
  168. //---------------------------------------------------------------------
  169. #if DEBUG
  170. void _DebugPrintf(char* pszFormat, ...);
  171. void _DebugPrintIf(BOOL fPrint, char* pszFormat, ...);
  172. #define DebugPrintf _DebugPrintf
  173. #define DebugPrintIf _DebugPrintIf
  174. #else // DEBUG || DEBUG_OUTPUT_ON
  175. inline void _DebugNop(...) {}
  176. #define DebugPrintf 1 ? (void)0 : _DebugNop
  177. #define DebugPrintIf 1 ? (void)0 : _DebugNop
  178. #define DebugMessageBox 1 ? (void)0 : _DebugNop
  179. #endif // DEBUG
  180. //---------------------------------------------------------------------
  181. // Error handling macros
  182. //---------------------------------------------------------------------
  183. #ifdef DEBUG
  184. extern HRESULT HrDebugTraceReturn(HRESULT hr, char *szFile, int iLine);
  185. #define RRETURN(hr) return HrDebugTraceReturn(hr, _szThisFile, __LINE__)
  186. #else
  187. #define RRETURN(hr) return (hr)
  188. #endif //DEBUG
  189. // FAILEDHR : Same as FAILED(hr), but prints a debug message if the test failed.
  190. #if DEBUG
  191. #define FAILEDHR(HR) _FAILEDHR(HR, _szThisFile, __LINE__)
  192. inline BOOL _FAILEDHR(HRESULT hr, char* pszFile, int iLine)
  193. {
  194. if (FAILED(hr))
  195. HrDebugTraceReturn(hr, pszFile, iLine);
  196. return FAILED(hr);
  197. }
  198. #else
  199. #define FAILEDHR(HR) FAILED(HR)
  200. #endif
  201. // SUCCEEDEDHR : Same as SUCCEEDED(hr), but prints a debug message if the test failed.
  202. #define SUCCEEDEDHR(HR) (!FAILEDHR(HR))
  203. // Print a debug message if FAILED(hr).
  204. #if DEBUG
  205. #define CHECKHR(HR) _CHECKHR(HR, _szThisFile, __LINE__)
  206. inline void _CHECKHR(HRESULT hr, char* pszFile, int iLine)
  207. {
  208. if (FAILED(hr))
  209. HrDebugTraceReturn(hr, pszFile, iLine);
  210. }
  211. #else
  212. #define CHECKHR(HR) HR
  213. #endif
  214. #define IfErrGoto(EXPR, LABEL) \
  215. { err = (EXPR); if (err) goto LABEL; }
  216. #define IfErrRet(EXPR) \
  217. { err = (EXPR); if (err) return err; };
  218. #define IfErrGo(EXPR) IfErrGoto(EXPR, Error)
  219. #define IfFailGoto(EXPR, LABEL) \
  220. { hr = (EXPR); if(FAILEDHR(hr)) goto LABEL; }
  221. #ifndef IfFailRet
  222. #define IfFailRet(EXPR) \
  223. { hr = (EXPR); if(FAILED(hr)) RRETURN(hr); }
  224. #endif // IfFailRet
  225. #define IfFailGo(EXPR) IfFailGoto(EXPR, Error)
  226. #define IfFalseGoto(EXPR, HR, LABEL) \
  227. { if(!(EXPR)) { hr = (HR); goto LABEL; } }
  228. #define IfFalseRet(EXPR, HR) \
  229. { if(!(EXPR)) RRETURN(HR); }
  230. #define IfFalseGo(EXPR, HR) IfFalseGoto(EXPR, HR, Error)
  231. #if DEBUG
  232. #define CHECKRESULT(x) ASSERT((x)==NOERROR,"");
  233. #else // DEBUG
  234. #define CHECKRESULT(x) (x)
  235. #endif // DEBUG
  236. //---------------------------------------------------------------------------
  237. // STATICF is for static functions. In retail we disable this in order to
  238. // do better function reordering via the linker.
  239. //---------------------------------------------------------------------------
  240. #if !defined(STATICF)
  241. #ifdef DEBUG
  242. #define STATICF static
  243. #else // DEBUG
  244. #define STATICF
  245. #endif // DEBUG
  246. #endif
  247. #define _MACROS_H_
  248. #endif // _MACROS_H_