Leaked source code of windows server 2003
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.

390 lines
19 KiB

  1. //____________________________________________________________________________
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995 - 1996.
  5. //
  6. // File: macros.h
  7. //
  8. // Contents: Useful macros
  9. //
  10. // Macros: ARRAYLEN
  11. //
  12. // BREAK_ON_FAIL(hresult)
  13. // BREAK_ON_FAIL(hresult)
  14. //
  15. // DECLARE_IUNKNOWN_METHODS
  16. // DECLARE_STANDARD_IUNKNOWN
  17. // IMPLEMENT_STANDARD_IUNKNOWN
  18. //
  19. // SAFE_RELEASE
  20. //
  21. // DECLARE_SAFE_INTERFACE_PTR_MEMBERS
  22. //
  23. // History: 6/3/1996 RaviR Created
  24. // 7/23/1996 JonN Added exception handling macros
  25. //
  26. //____________________________________________________________________________
  27. #ifndef _MACROS_H_
  28. #define _MACROS_H_
  29. //____________________________________________________________________________
  30. //
  31. // Macro: ARRAYLEN
  32. //
  33. // Purpose: To determine the length of an array.
  34. //____________________________________________________________________________
  35. //
  36. #define ARRAYLEN(a) (sizeof(a) / sizeof((a)[0]))
  37. //____________________________________________________________________________
  38. //
  39. // Macros: BREAK_ON_FAIL(hresult), BREAK_ON_ERROR(lastError)
  40. //
  41. // Purpose: To break out of a loop on error.
  42. //____________________________________________________________________________
  43. //
  44. #define BREAK_ON_FAIL(hr) if (FAILED(hr)) { break; } else 1;
  45. #define BREAK_ON_ERROR(lr) if (lr != ERROR_SUCCESS) { break; } else 1;
  46. //____________________________________________________________________________
  47. //
  48. // Macros: DwordAlign(n)
  49. //____________________________________________________________________________
  50. //
  51. #define DwordAlign(n) (((n) + 3) & ~3)
  52. //____________________________________________________________________________
  53. //
  54. // Macros: SAFE_RELEASE
  55. //____________________________________________________________________________
  56. //
  57. #ifndef SAFE_RELEASE
  58. #define SAFE_RELEASE(punk) \
  59. if (punk != NULL) \
  60. { \
  61. punk##->Release(); \
  62. punk = NULL; \
  63. } \
  64. else \
  65. { \
  66. TRACE(_T("Release called on NULL interface ptr")); \
  67. }
  68. #endif // SAFE_RELEASE
  69. //____________________________________________________________________________
  70. //
  71. // Macro: DECLARE_IUNKNOWN_METHODS
  72. //
  73. // Purpose: This declares the set of IUnknown methods and is for
  74. // general-purpose use inside classes that inherit from IUnknown
  75. //____________________________________________________________________________
  76. //
  77. #define DECLARE_IUNKNOWN_METHODS \
  78. STDMETHOD(QueryInterface) (REFIID riid, LPVOID FAR* ppvObj); \
  79. STDMETHOD_(ULONG,AddRef) (void); \
  80. STDMETHOD_(ULONG,Release) (void)
  81. //____________________________________________________________________________
  82. //
  83. // Macro: DECLARE_STANDARD_IUNKNOWN
  84. //
  85. // Purpose: This is for use in declaring non-aggregatable objects. It
  86. // declares the IUnknown methods and reference counter, m_ulRefs.
  87. // m_ulRefs should be initialized to 1 in the constructor of
  88. // the object
  89. //____________________________________________________________________________
  90. //
  91. #define DECLARE_STANDARD_IUNKNOWN \
  92. DECLARE_IUNKNOWN_METHODS; \
  93. ULONG m_ulRefs
  94. //____________________________________________________________________________
  95. //
  96. // Macro: IMPLEMENT_STANDARD_IUNKNOWN
  97. //
  98. // Purpose: Partial implementaion of standard IUnknown.
  99. //
  100. // Note: This does NOT implement QueryInterface, which must be
  101. // implemented by each object
  102. //____________________________________________________________________________
  103. //
  104. #define IMPLEMENT_STANDARD_IUNKNOWN(cls) \
  105. STDMETHODIMP_(ULONG) cls##::AddRef() \
  106. { return InterlockedIncrement((LONG*)&m_ulRefs); } \
  107. STDMETHODIMP_(ULONG) cls##::Release() \
  108. { ULONG ulRet = InterlockedDecrement((LONG*)&m_ulRefs); \
  109. if (0 == ulRet) { delete this; } \
  110. return ulRet; }
  111. // ISSUE-2002/04/01-JonN This is not used, remove it
  112. //____________________________________________________________________________
  113. //
  114. // Macro: DECLARE_SAFE_INTERFACE_PTR_MEMBERS(cls, Interface, m_iptr)
  115. //
  116. // Purpose: Make the interface ptr 'm_iptr' of interface type 'Interface'
  117. // a safe pointer for the given class 'cls', by adding methods and
  118. // overloading operators to manipulate the pointer m_iptr.
  119. //
  120. // History: 6/3/1996 RaviR Created
  121. //
  122. // Notes: Adds safe interface pointer member functions to the given
  123. // class for the given OLE interface. 'm_iptr' is the member
  124. // variable name of the interface ptr in the given class.
  125. //
  126. // The Copy function creates a valid additional copy of
  127. // the captured pointer (following the AddRef/Release protocol)
  128. // so can be used to hand out copies from a safe pointer declared
  129. // as a member of some other class.
  130. //
  131. // The 'Transfer' function transfers the interface pointer, and
  132. // invalidates its member value (by setting it to NULL).
  133. //
  134. // To release the existing interface ptr and set it to a new
  135. // instance use the 'Set' member fuction. This method takes a
  136. // parameter which specifies whether the new pointer should be
  137. // AddRef'd, defaulting to TRUE.
  138. //
  139. // The following methods manipulate the interface pointer with
  140. // out following the AddRef/Release protocol: Transfer, Attach
  141. // and Detach.
  142. //____________________________________________________________________________
  143. //
  144. #define DECLARE_SAFE_INTERFACE_PTR_MEMBERS(cls, Interface, m_iptr) \
  145. \
  146. public: \
  147. cls##(Interface * iptr=NULL, BOOL fInc=TRUE) : m_iptr(iptr) \
  148. { \
  149. if (fInc && (m_iptr != NULL)) \
  150. { \
  151. m_iptr->AddRef(); \
  152. } \
  153. } \
  154. \
  155. ~##cls##() \
  156. { \
  157. if (m_iptr != NULL) \
  158. { \
  159. m_iptr->Release(); \
  160. m_iptr = NULL; \
  161. } \
  162. } \
  163. \
  164. inline BOOL IsNull(void) \
  165. { \
  166. return (m_iptr == NULL); \
  167. } \
  168. \
  169. void Transfer(Interface **piptr) \
  170. { \
  171. *piptr = m_iptr; \
  172. m_iptr = NULL; \
  173. } \
  174. \
  175. void Copy(Interface **piptr) \
  176. { \
  177. *piptr = m_iptr; \
  178. if (m_iptr != NULL) \
  179. m_iptr->AddRef(); \
  180. } \
  181. \
  182. void Set(Interface* iptr, BOOL fInc = TRUE) \
  183. { \
  184. if (m_iptr) \
  185. { \
  186. m_iptr->Release(); \
  187. } \
  188. m_iptr = iptr; \
  189. if (fInc && m_iptr) \
  190. { \
  191. m_iptr->AddRef(); \
  192. } \
  193. } \
  194. \
  195. void SafeRelease(void) \
  196. { \
  197. if (m_iptr) \
  198. { \
  199. m_iptr->Release(); \
  200. m_iptr = NULL; \
  201. } \
  202. } \
  203. \
  204. void SimpleRelease(void) \
  205. { \
  206. ASSERT(m_iptr != NULL); \
  207. m_iptr->Release(); \
  208. m_iptr = NULL; \
  209. } \
  210. \
  211. void Attach(Interface* iptr) \
  212. { \
  213. ASSERT(m_iptr == NULL); \
  214. m_iptr = iptr; \
  215. } \
  216. \
  217. void Detach(void) \
  218. { \
  219. m_iptr = NULL; \
  220. } \
  221. \
  222. Interface * operator-> () { return m_iptr; } \
  223. Interface& operator * () { return *m_iptr; } \
  224. operator Interface *() { return m_iptr; } \
  225. \
  226. Interface ** operator &() \
  227. { \
  228. ASSERT(m_iptr == NULL); \
  229. return &m_iptr; \
  230. } \
  231. \
  232. Interface *Self(void) { return m_iptr; } \
  233. \
  234. private: \
  235. void operator= (const cls &) {;} \
  236. cls(const cls &){;}
  237. //____________________________________________________________________________
  238. //
  239. // Macro: EXCEPTION HANDLING MACROS
  240. //
  241. // Purpose: Provide standard macros for exception-handling in
  242. // OLE servers.
  243. //
  244. // History: 7/23/1996 JonN Created
  245. //
  246. // Notes: Declare USE_HANDLE_MACROS("Component name") in each source
  247. // file before these are used.
  248. //
  249. // These macros can only be used in function calls which return
  250. // type HRESULT.
  251. //
  252. // Bracket routines which can generate exceptions
  253. // with STANDARD_TRY and STANDARD_CATCH.
  254. //
  255. // Where these routines are COM methods requiring MFC
  256. // support, use MFC_TRY and MFC_CATCH instead.
  257. //____________________________________________________________________________
  258. //
  259. #define USE_HANDLE_MACROS(component) \
  260. static TCHAR* You_forgot_to_declare_USE_HANDLE_MACROS = _T(component);
  261. #define STANDARD_TRY \
  262. try {
  263. #define MFC_TRY \
  264. AFX_MANAGE_STATE(AfxGetStaticModuleState( )); \
  265. STANDARD_TRY
  266. // ISSUE-2002/04/01-JonN remove ENDMETHOD_READBLOCK
  267. //
  268. // CODEWORK don't quite have ENDMETHOD_READBLOCK working yet
  269. //
  270. #ifdef DEBUG
  271. #define ENDMETHOD_STRING \
  272. "%s: The unexpected error can be identified as \"%s\" context %n\n"
  273. #define ENDMETHOD_READBLOCK \
  274. { \
  275. TCHAR szError[MAX_PATH]; \
  276. UINT nHelpContext = 0; \
  277. if ( e->GetErrorMessage( szError, MAX_PATH, &nHelpContext ) ) \
  278. { \
  279. TRACE( ENDMETHOD_STRING, \
  280. You_forgot_to_declare_USE_HANDLE_MACROS, \
  281. szError, \
  282. nHelpContext ); \
  283. } \
  284. }
  285. #else
  286. #define ENDMETHOD_READBLOCK
  287. #endif
  288. #define ERRSTRING_MEMORY "%s: An out-of-memory error occurred\n"
  289. #define ERRSTRING_FILE "%s: File error 0x%lx occurred on file \"%s\"\n"
  290. #define ERRSTRING_OLE "%s: OLE error 0x%lx occurred\n"
  291. #define ERRSTRING_UNEXPECTED "%s: An unexpected error occurred\n"
  292. #define BADPARM_STRING "%s: Bad string parameter\n"
  293. #define BADPARM_POINTER "%s: Bad pointer parameter\n"
  294. #define TRACEERR(s) TRACE( s, You_forgot_to_declare_USE_HANDLE_MACROS )
  295. #define TRACEERR1(s,a) TRACE( s, You_forgot_to_declare_USE_HANDLE_MACROS,a )
  296. #define TRACEERR2(s,a,b) TRACE( s, You_forgot_to_declare_USE_HANDLE_MACROS,a,b )
  297. // Note that it is important to use "e->Delete();" and not "delete e;"
  298. #define STANDARD_CATCH \
  299. } \
  300. catch (CMemoryException* e) \
  301. { \
  302. TRACEERR( ERRSTRING_MEMORY ); \
  303. ASSERT( FALSE ); \
  304. e->Delete(); \
  305. return E_OUTOFMEMORY; \
  306. } \
  307. catch (COleException* e) \
  308. { \
  309. HRESULT hr = (HRESULT)e->Process(e); \
  310. TRACEERR1( ERRSTRING_OLE, hr ); \
  311. ASSERT( FALSE ); \
  312. e->Delete(); \
  313. ASSERT( FAILED(hr) ); \
  314. return hr; \
  315. } \
  316. catch (CFileException* e) \
  317. { \
  318. HRESULT hr = (HRESULT)e->m_lOsError; \
  319. TRACEERR2( ERRSTRING_FILE, hr, e->m_strFileName ); \
  320. ASSERT( FALSE ); \
  321. e->Delete(); \
  322. ASSERT( FAILED(hr) ); \
  323. return hr; \
  324. } \
  325. catch (CException* e) \
  326. { \
  327. TRACEERR( ERRSTRING_UNEXPECTED ); \
  328. ASSERT( FALSE ); \
  329. e->Delete(); \
  330. return E_UNEXPECTED; \
  331. }
  332. #define MFC_CATCH \
  333. STANDARD_CATCH
  334. #define TEST_STRING_PARAM(x) \
  335. if ( (x) != NULL && !AfxIsValidString(x) ) { \
  336. TRACEERR( BADPARM_STRING ); return E_POINTER; }
  337. #define TEST_NONNULL_STRING_PARAM(x) \
  338. if ( !AfxIsValidString(x) ) { \
  339. TRACEERR( BADPARM_STRING ); return E_POINTER; }
  340. #define TEST_NONNULL_PTR_PARAM(x) \
  341. if ( (x) == NULL || IsBadWritePtr((x),sizeof(x)) ) { \
  342. TRACEERR( BADPARM_POINTER ); return E_POINTER; }
  343. #endif // _MACROS_H_