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.

342 lines
7.8 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. dbgstate.hxx
  6. Abstract:
  7. auto log
  8. Author:
  9. Larry Zhu (LZhu) December 8, 2001
  10. Revision History:
  11. --*/
  12. #ifndef _DBGSTATE_HXX_
  13. #define _DBGSTATE_HXX_
  14. extern "C" {
  15. #define SECURITY_KERNEL
  16. #include <ntosp.h>
  17. #include <zwapi.h>
  18. #include <security.h>
  19. #include <ntlmsp.h>
  20. #include <string.h>
  21. #include <wcstr.h>
  22. #include <ntiologc.h>
  23. #include <tchar.h>
  24. #include <tchar.h>
  25. #include <stdio.h>
  26. }
  27. /********************************************************************
  28. Automatic status logging.
  29. Use TNtStatus instead of NTSTATUS:
  30. NTSTATUS Status; -> TNtStatus Status;
  31. NTSTATUS Status = ERROR_ACCESS_DENIED -> TNtStatus Status = ERROR_ACCESS_DENIED;
  32. Status = ERROR_SUCCESS -> Status DBGNOCHK = ERROR_SUCCESS;
  33. Status = xxx; -> Status DBGCHK = xxx;
  34. if(Status){ -> if(Status != 0){
  35. Anytime Status is set, the DBGCHK macro must be added before
  36. the '=.'
  37. If the variable must be set to a failure value at compile time
  38. and logging is therefore not needed, then the DBGNOCHK macro
  39. should be used.
  40. There is a method to control the wether a message is
  41. printed if an error value is assigned as well as 3 "benign"
  42. errors that can be ignored.
  43. DBGCFG(Status, DBG_ERROR);
  44. DBGCFG1(Status, DBG_ERROR, ERROR_ACCESS_DENIED);
  45. DBGCFG2(Status, DBG_ERROR, ERROR_INVALID_HANDLE, ERROR_ARENA_TRASHED);
  46. DBGCFG3(Status, DBG_ERROR, ERROR_INVALID_HANDLE, ERROR_ARENA_TRASHED, ERROR_NOT_ENOUGH_MEMORY);
  47. ********************************************************************/
  48. #ifdef DBG
  49. #define DBGCHK .pSetInfo(__LINE__, TEXT(__FILE__))
  50. #define DBGNOCHK .pNoChk()
  51. #define DBGCFG1(TStatusX, Safe1) (TStatusX).pConfig((Safe1))
  52. #define DBGCFG2(TStatusX, Safe1, Safe2) (TStatusX).pConfig((Safe1), (Safe2))
  53. #define DBGCFG3(TStatusX, Safe1, Safe2, Safe3) (TStatusX).pConfig((Safe1), (Safe2), (Safe3))
  54. #define AUTO_LOG(Msg) do { OutputDebugString(Msg); } while (0)
  55. #define AUTO_LOG_OPEN(pszPrompt) do { g_DbgGlobals.pszDbgPrompt = (pszPrompt); } while (0)
  56. #define AUTO_LOG_CLOSE() do { g_DbgGlobals.pszDbgPrompt = NULL; } while (0)
  57. #ifndef DebugPrint
  58. #define DebugPrint(_x_) DbgPrint _x_
  59. #endif
  60. #else
  61. #define DBGCHK // Empty
  62. #define DBGNOCHK // Empty
  63. #define DBGCFG(TStatusX) // Empty
  64. #define DBGCFG1(TStatusX, Safe1) // Empty
  65. #define DBGCFG2(TStatusX, Safe1, Safe2) // Empty
  66. #define DBGCFG3(TStatusX, Safe1, Safe2, Safe3) // Empty
  67. #define AUTO_LOG_LOG(Msg) // Empty
  68. #define AUTO_LOG_OPEN(pszPrompt) // Empty
  69. #define AUTO_LOG_CLOSE() // Empty
  70. #ifndef DebugPrint
  71. #define DebugPrint(_x_) // Empty
  72. #endif
  73. #endif // DBG
  74. #ifndef COUNTOF
  75. #define COUNTOF(s) ( sizeof( (s) ) / sizeof( *(s) ) )
  76. #endif // COUNTOF
  77. #ifndef IN
  78. #define IN
  79. #endif // IN
  80. #ifndef OUT
  81. #define OUT
  82. #endif // OUT
  83. void
  84. OutputDebugString(
  85. IN PCTSTR pszBuffer
  86. );
  87. //
  88. // DBG build only
  89. //
  90. #ifdef DBG
  91. extern "C" {
  92. #include <kbfiltr.h>
  93. #include <assert.h>
  94. }
  95. #ifndef ASSERT
  96. #define ASSERT( exp ) assert((exp))
  97. #endif // #ifndef ASSERT
  98. typedef struct _TDbgGlobals
  99. {
  100. ULONG uMajorVersion;
  101. ULONG uMinorVersion;
  102. PCTSTR pszDbgPrompt;
  103. } TDbgGlobals;
  104. extern TDbgGlobals g_DbgGlobals;
  105. /********************************************************************
  106. Base class
  107. ********************************************************************/
  108. template <typename TStatusCode>
  109. class TStatusBase {
  110. public:
  111. enum { kUnInitializedValue = 0xabababab };
  112. TStatusBase&
  113. pSetInfo(
  114. IN ULONG uLine,
  115. IN PCTSTR pszFile
  116. )
  117. {
  118. m_uLine = uLine;
  119. m_pszFile = pszFile;
  120. return (TStatusBase&) *this;
  121. }
  122. TStatusBase&
  123. pNoChk(
  124. VOID
  125. )
  126. {
  127. m_pszFile = NULL;
  128. m_uLine = 0;
  129. return (TStatusBase&) *this;
  130. }
  131. VOID
  132. pConfig(
  133. IN TStatusCode StatusSafe1 = -1,
  134. IN TStatusCode StatusSafe2 = -1,
  135. IN TStatusCode StatusSafe3 = -1
  136. )
  137. {
  138. m_StatusSafe1 = StatusSafe1;
  139. m_StatusSafe2 = StatusSafe2;
  140. m_StatusSafe3 = StatusSafe3;
  141. }
  142. ///////////////////////////////////////////////////////////////////////////
  143. virtual
  144. ~TStatusBase(
  145. VOID
  146. )
  147. {
  148. }
  149. TStatusCode
  150. GetTStatusBase(
  151. VOID
  152. ) const
  153. {
  154. //
  155. // Assert if we are reading an UnInitalized variable.
  156. //
  157. if (m_Status == kUnInitializedValue)
  158. {
  159. AUTO_LOG((TEXT("***Read of UnInitialized TStatus variable!***\n")));
  160. ASSERT(FALSE);
  161. }
  162. //
  163. // Return the error value.
  164. //
  165. return m_Status;
  166. }
  167. operator TStatusCode(
  168. VOID
  169. ) const
  170. {
  171. return GetTStatusBase();
  172. }
  173. TStatusCode
  174. operator=(
  175. IN TStatusCode Status
  176. )
  177. {
  178. m_Status = Status;
  179. //
  180. // Do nothing if the file and line number are cleared.
  181. // This is the case when the NoChk method is used.
  182. //
  183. if (m_uLine && m_pszFile)
  184. {
  185. //
  186. // Check if we have an error, and it's not one of the accepted
  187. // "safe" errors.
  188. //
  189. if ( IsErrorSevereEnough() &&
  190. Status != m_StatusSafe1 &&
  191. Status != m_StatusSafe2 &&
  192. Status != m_StatusSafe3 )
  193. {
  194. TCHAR szOutput[256] = {0};
  195. _sntprintf(szOutput, COUNTOF(szOutput) - 1,
  196. g_DbgGlobals.pszDbgPrompt ? TEXT("[%s] [%s] %#x at %s %d\n") : TEXT("%s[%s] %#x at %s %d\n"),
  197. g_DbgGlobals.pszDbgPrompt ? g_DbgGlobals.pszDbgPrompt : TEXT(""),
  198. GetErrorServerityDescription(), m_Status, m_pszFile, m_uLine);
  199. AUTO_LOG(szOutput);
  200. }
  201. }
  202. return m_Status;
  203. }
  204. //////////////////////////////////////////////////////////////////////////
  205. virtual PCTSTR
  206. GetErrorServerityDescription(
  207. VOID
  208. ) const
  209. {
  210. return IsErrorSevereEnough() ? TEXT("ERROR") : TEXT("SUCCESSFUL");
  211. }
  212. virtual bool
  213. IsErrorSevereEnough(
  214. VOID
  215. ) const
  216. {
  217. return m_Status != 0; // 0 for success
  218. }
  219. /////////////////////////////////////////////////////////////////////////
  220. protected:
  221. TStatusBase(
  222. IN TStatusCode Status
  223. ) : m_Status(Status),
  224. m_StatusSafe1(-1),
  225. m_StatusSafe2(-1),
  226. m_StatusSafe3(-1),
  227. m_uLine(0),
  228. m_pszFile(NULL)
  229. {
  230. }
  231. private:
  232. TStatusCode m_Status;
  233. TStatusCode m_StatusSafe1;
  234. TStatusCode m_StatusSafe2;
  235. TStatusCode m_StatusSafe3;
  236. ULONG m_uLine;
  237. PCTSTR m_pszFile;
  238. };
  239. template <typename TStatusCode>
  240. class TStatusDerived : public TStatusBase<TStatusCode> {
  241. public:
  242. TStatusDerived(
  243. IN TStatusCode Status = kUnInitializedValue
  244. ): TStatusBase<TStatusCode>(Status)
  245. {
  246. }
  247. virtual
  248. ~TStatusDerived(
  249. VOID
  250. )
  251. {
  252. }
  253. private:
  254. TStatusDerived(const TStatusDerived& rhs);
  255. TStatusCode
  256. operator=(
  257. IN TStatusCode Status
  258. );
  259. };
  260. #endif // #ifdef DBG
  261. #endif // _DBGSTATE_HXX_