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.

370 lines
14 KiB

  1. #ifndef _LOGITEM_H_
  2. #define _LOGITEM_H_
  3. // determine the number of elements in array (not bytes)
  4. #ifndef countof
  5. #define countof(array) (sizeof(array)/sizeof(array[0]))
  6. #endif
  7. #define LIF_NONE 0x80000000
  8. #define LIF_DATE 0x00000001
  9. #define LIF_TIME 0x00000002
  10. #define LIF_DATETIME 0x00000003
  11. #define LIF_MODULE 0x00000004
  12. #define LIF_MODULEPATH 0x00000008
  13. #define LIF_MODULE_ALL 0x0000000C
  14. #define LIF_FILE 0x00000010
  15. #define LIF_FILEPATH 0x00000020
  16. #define LIF_FILE_ALL 0x00000030
  17. #define LIF_CLASS 0x00000040
  18. #define LIF_FUNCTION 0x00000080
  19. #define LIF_LINE 0x00000100
  20. #define LIF_DUPLICATEINODS 0x00000200
  21. #define LIF_APPENDCRLF 0x00000400
  22. #define LIF_DEFAULT 0x000005D0
  23. // private for context switch from C to C++ and back again
  24. #define LIF_CLASS2 0x01000000
  25. /////////////////////////////////////////////////////////////////////////////
  26. // Initialization
  27. class CLogItem; // forward declaration
  28. extern CLogItem g_li;
  29. #define MACRO_LI_Initialize() \
  30. CLogItem g_li \
  31. #define MACRO_LI_Initialize2(dwFlags) \
  32. CLogItem g_li(dwFlags) \
  33. #define MACRO_LI_InitializeEx(dwFlags, pfLevels, cLevels) \
  34. CLogItem g_li(dwFlags, pfLevels, cLevels) \
  35. /////////////////////////////////////////////////////////////////////////////
  36. // Helpers for individual CLogItem attributes
  37. // file
  38. #define MACRO_LI_SmartFile() \
  39. CSmartItem<LPCTSTR> siFile(g_li.m_szFile, TEXT(__FILE__)) \
  40. #define MACRO_LI_SmartFileEx(dwItems) \
  41. CSmartItemEx<LPCTSTR> siFileEx(dwItems, LIF_FILE_ALL, \
  42. g_li.m_szFile, TEXT(__FILE__)) \
  43. // class
  44. #define MACRO_LI_SmartClass(Class) \
  45. CSmartItem<LPCTSTR> siClass(g_li.m_szClass, TEXT(#Class)) \
  46. #define MACRO_LI_SmartClassEx(dwItems, Class) \
  47. CSmartItemEx<LPCTSTR> siClassEx(dwItems, LIF_CLASS, \
  48. g_li.m_szClass, TEXT(#Class)) \
  49. // function
  50. #define MACRO_LI_SmartFunction(Function) \
  51. CSmartItem<LPCTSTR> siFunction(g_li.m_szFunction, TEXT(#Function)) \
  52. #define MACRO_LI_SmartFunctionEx(dwItems, Function) \
  53. CSmartItemEx<LPCTSTR> siFunctionEx(dwItems, LIF_FUNCTION, \
  54. g_li.m_szFunction, TEXT(#Function)) \
  55. // level, indent and flags
  56. #define MACRO_LI_SmartLevel() \
  57. CSmartItem<UINT> siLevel(g_li.m_nLevel, g_li.m_nLevel+1) \
  58. #define MACRO_LI_SmartIndent() \
  59. CSmartItem<UINT> siIndent(g_li.m_nAbsOffset, g_li.m_nAbsOffset+1) \
  60. #define MACRO_LI_SmartFlags(dwFlags) \
  61. CSmartItem<DWORD> siFlags(g_li.m_dwFlags, dwFlags) \
  62. // wrappers to manipulate flags, offset and relative offset
  63. #define MACRO_LI_SmartAddFlags(dwFlag) \
  64. CSmartItem<DWORD> siAddFlags(g_li.m_dwFlags, g_li.m_dwFlags | (dwFlag))\
  65. #define MACRO_LI_SmartRemoveFlags(dwFlag) \
  66. CSmartItem<DWORD> siRemFlags(g_li.m_dwFlags, g_li.m_dwFlags & ~(dwFlag))\
  67. #define MACRO_LI_Offset(iOffset) \
  68. CSmartItem<int> siOffset(g_li.m_iRelOffset, g_li.m_iRelOffset + iOffset)\
  69. #define MACRO_LI_SmartRelativeOffset(iRelOffset) \
  70. CSmartItem<int> siRelOffset(g_li.m_iRelOffset, iRelOffset) \
  71. // private for context switch from C to C++ and back again
  72. #define MACRO_LI_AddClass2() \
  73. CSmartItem<DWORD> siAddClass2(g_li.m_dwFlags, \
  74. g_li.m_dwFlags | (LIF_CLASS2)) \
  75. #define MACRO_LI_RemClass2() \
  76. CSmartItem<DWORD> siRemClass2(g_li.m_dwFlags, \
  77. g_li.m_dwFlags & ~(LIF_CLASS2)) \
  78. /////////////////////////////////////////////////////////////////////////////
  79. // Prologs
  80. // rarely used standalone, is the foundation for the rest
  81. #define MACRO_LI_PrologSameFunction() \
  82. MACRO_LI_SmartIndent(); \
  83. MACRO_LI_SmartLevel(); \
  84. //----- More macros, a little more lean -------------------------------------
  85. // for protected or private functions in the same file as caller
  86. #define MACRO_LI_PrologSameClass(Function) \
  87. MACRO_LI_SmartFunction(Function); \
  88. MACRO_LI_PrologSameFunction(); \
  89. // for protected or private functions in a different file than caller
  90. #define MACRO_LI_PrologSameClass2(Function) \
  91. MACRO_LI_SmartFile(); \
  92. MACRO_LI_SmartFunction(Function); \
  93. MACRO_LI_PrologSameFunction(); \
  94. // for C APIs across files
  95. #define MACRO_LI_PrologC(Function) \
  96. MACRO_LI_RemClass2(); \
  97. \
  98. MACRO_LI_SmartFile(); \
  99. MACRO_LI_SmartFunction(Function); \
  100. MACRO_LI_PrologSameFunction(); \
  101. // for C APIs with no prototype in the (respective) *.h file
  102. #define MACRO_LI_PrologSameFileC(Function) \
  103. MACRO_LI_RemClass2(); \
  104. \
  105. MACRO_LI_SmartFunction(Function); \
  106. MACRO_LI_PrologSameFunction(); \
  107. // for things like friends (two friend classes in one file and methods
  108. // of one class are calling private or protected methods of the other, so
  109. // these private or protected methods can have this prolog)
  110. #define MACRO_LI_PrologSameFile(Class, Function) \
  111. MACRO_LI_AddClass2(); \
  112. \
  113. MACRO_LI_SmartClass(Class); \
  114. MACRO_LI_PrologSameClass(Function); \
  115. // general version, common case
  116. #define MACRO_LI_Prolog(Class, Function) \
  117. MACRO_LI_SmartFile(); \
  118. MACRO_LI_PrologSameFile(Class, Function); \
  119. //----- Less macros, a little more overhead ---------------------------------
  120. #define PIF_SAMEFUNC 0x00000000
  121. #define PIF_SAMECLASS 0x00000080
  122. #define PIF_SAMECLASS2 0x000000B0
  123. #define PIF_STD_C 0x00000090
  124. #define PIF_SAMEFILE_C 0x000000B0
  125. #define PIF_SAMEFILE 0x000000C0
  126. #define PIF_STD 0x000000F0
  127. #define MACRO_LI_PrologEx(dwItems, Class, Function) \
  128. MACRO_LI_AddClass2(); \
  129. \
  130. MACRO_LI_SmartFileEx(dwItems); \
  131. MACRO_LI_SmartClassEx(dwItems, Class); \
  132. MACRO_LI_SmartFunctionEx(dwItems, Function); \
  133. MACRO_LI_PrologSameFunction(); \
  134. #define MACRO_LI_PrologSameClassEx(dwItems, Function) \
  135. MACRO_LI_AddClass2(); \
  136. \
  137. MACRO_LI_SmartFileEx(dwItems); \
  138. MACRO_LI_SmartFunctionEx(dwItems, Function); \
  139. MACRO_LI_PrologSameFunction(); \
  140. #define MACRO_LI_PrologEx_C(dwItems, Function) \
  141. MACRO_LI_RemClass2(); \
  142. \
  143. MACRO_LI_SmartFileEx(dwItems); \
  144. MACRO_LI_SmartFunctionEx(dwItems, Function); \
  145. MACRO_LI_PrologSameFunction(); \
  146. /////////////////////////////////////////////////////////////////////////////
  147. // Logging
  148. #define LI0(pszFormat) \
  149. g_li.Log(__LINE__, pszFormat) \
  150. #define LI1(pszFormat, arg1) \
  151. g_li.Log(__LINE__, pszFormat, arg1) \
  152. #define LI2(pszFormat, arg1, arg2) \
  153. g_li.Log(__LINE__, pszFormat, arg1, arg2) \
  154. #define LI3(pszFormat, arg1, arg2, arg3) \
  155. g_li.Log(__LINE__, pszFormat, arg1, arg2, arg3) \
  156. /////////////////////////////////////////////////////////////////////////////
  157. // Additional helpers
  158. #define MACRO_LI_GetFlags() \
  159. g_li.GetFlags() \
  160. #define MACRO_LI_SetFlags(dwFlags) \
  161. g_li.SetFlags(dwFlags) \
  162. #define MACRO_LI_GetRelativeOffset() \
  163. (const int&)g_li.m_iRelOffset \
  164. #define MACRO_LI_SetRelativeOffset(iRelOffset) \
  165. g_li.m_iRelOffset = iRelOffset \
  166. /////////////////////////////////////////////////////////////////////////////
  167. // CLogItem declaration
  168. class CLogItem
  169. {
  170. // Constructors
  171. public:
  172. CLogItem(DWORD dwFlags = LIF_DEFAULT, LPBOOL pfLogLevels = NULL, UINT cLogLevels = 0);
  173. // Attributes
  174. public:
  175. TCHAR m_szMessage[3 * MAX_PATH];
  176. // offset management
  177. UINT m_nAbsOffset;
  178. int m_iRelOffset;
  179. static BYTE m_bStep;
  180. // module, path, file, class, function, line of code
  181. LPCTSTR m_szFile;
  182. LPCTSTR m_szClass;
  183. LPCTSTR m_szFunction;
  184. UINT m_nLine;
  185. // customization
  186. DWORD m_dwFlags;
  187. UINT m_nLevel;
  188. // Operations
  189. public:
  190. void SetFlags(DWORD dwFlags)
  191. { m_dwFlags = dwFlags; }
  192. DWORD GetFlags() const
  193. { return m_dwFlags; }
  194. virtual LPCTSTR WINAPIV Log(int iLine, LPCTSTR pszFormat ...);
  195. // Overridables
  196. public:
  197. virtual operator LPCTSTR() const;
  198. // Implementation
  199. public:
  200. virtual ~CLogItem();
  201. protected:
  202. // implementation data helpers
  203. static TCHAR m_szModule[MAX_PATH];
  204. PBOOL m_rgfLogLevels;
  205. UINT m_cLogLevels;
  206. // implementation helper routines
  207. LPCTSTR makeRawFileName(LPCTSTR pszPath, LPTSTR pszFile, UINT cchFile);
  208. BOOL setFlag(DWORD dwMask, BOOL fSet = TRUE);
  209. BOOL hasFlag(DWORD dwMask) const
  210. { return hasFlag(m_dwFlags, dwMask); }
  211. static BOOL hasFlag(DWORD dwFlags, DWORD dwMask)
  212. { return ((dwFlags & dwMask) != 0L); }
  213. };
  214. // Note. (andrewgu) Right now there seems to be no need to create a special
  215. // CSmartItem<TCHAR> and CSmartItemEx<TCHAR> classes that would
  216. // store internally the string passed into it. Also, the parameter
  217. // isn't necessary TCHAR it's just a placeholder for an idea.
  218. /////////////////////////////////////////////////////////////////////////////
  219. // CSmartItem definition
  220. template <class T> class CSmartItem
  221. {
  222. public:
  223. CSmartItem(T& tOld, const T& tNew)
  224. {
  225. m_pitem = NULL;
  226. if (tOld == tNew)
  227. return;
  228. m_item = tOld; m_pitem = &tOld; tOld = tNew;
  229. }
  230. ~CSmartItem()
  231. {
  232. if (m_pitem == NULL)
  233. return;
  234. *m_pitem = m_item; m_pitem = NULL;
  235. }
  236. // Attributes
  237. T *m_pitem,
  238. m_item;
  239. protected:
  240. // disable the copy constructor and assignment operator
  241. CSmartItem(const CSmartItem&)
  242. {}
  243. const CSmartItem& operator=(const CSmartItem&)
  244. { return *this; }
  245. };
  246. /////////////////////////////////////////////////////////////////////////////
  247. // CSmartItemEx definition
  248. template <class T> class CSmartItemEx
  249. {
  250. public:
  251. CSmartItemEx(DWORD dwAllItems, DWORD dwThisItem, T& tOld, const T& tNew)
  252. {
  253. m_pitem = NULL;
  254. m_fNoSwap = ((dwAllItems & dwThisItem) == 0);
  255. if (m_fNoSwap)
  256. return;
  257. if (tOld == tNew)
  258. return;
  259. m_item = tOld; m_pitem = &tOld; tOld = tNew;
  260. }
  261. ~CSmartItemEx()
  262. {
  263. if (m_fNoSwap)
  264. return;
  265. if (m_pitem == NULL)
  266. return;
  267. *m_pitem = m_item; m_pitem = NULL;
  268. }
  269. // Attributes
  270. T *m_pitem,
  271. m_item;
  272. protected:
  273. // disable the copy constructor and assignment operator
  274. CSmartItemEx(const CSmartItem<T>&)
  275. {}
  276. const CSmartItemEx<T>& operator=(const CSmartItemEx<T>&)
  277. { return *this; }
  278. // implementation data helpers
  279. BOOL m_fNoSwap;
  280. };
  281. #endif