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.

392 lines
8.5 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1996-1997 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // Barf.cpp
  7. //
  8. // Abstract:
  9. // Implementation of the Basic Artifical Resource Failure classes.
  10. //
  11. // Author:
  12. // David Potter (davidp) April 11, 1997
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #define _NO_BARF_DEFINITIONS_
  21. #include "Barf.h"
  22. #include "TraceTag.h"
  23. #include "ExcOper.h"
  24. #ifdef _USING_BARF_
  25. #error BARF failures should be disabled!
  26. #endif
  27. #ifdef _DEBUG // The entire file!
  28. #define new DEBUG_NEW
  29. #undef THIS_FILE
  30. static char THIS_FILE[] = __FILE__;
  31. /////////////////////////////////////////////////////////////////////////////
  32. // Global Variables
  33. /////////////////////////////////////////////////////////////////////////////
  34. BOOL g_bFailOnNextBarf = FALSE;
  35. CTraceTag g_tagBarf(_T("Debug"), _T("BARF Failures"), CTraceTag::tfDebug);
  36. //*************************************************************************//
  37. /////////////////////////////////////////////////////////////////////////////
  38. // CBarf
  39. /////////////////////////////////////////////////////////////////////////////
  40. BOOL CBarf::s_bGlobalEnable = TRUE;
  41. LONG CBarf::s_nSuspend = 0;
  42. CBarf * CBarf::s_pbarfFirst = NULL;
  43. PFNBARFPOSTUPDATE CBarf::s_pfnPostUpdate = NULL;
  44. PVOID CBarf::s_pvSpecialMem = NULL;
  45. /////////////////////////////////////////////////////////////////////////////
  46. //++
  47. //
  48. // CBarf::CBarf
  49. //
  50. // Routine Description:
  51. // Constructor.
  52. //
  53. // Arguments:
  54. // pszName [IN] Name of the set of APIs to BARF.
  55. //
  56. // Return Value:
  57. // None.
  58. //
  59. //--
  60. /////////////////////////////////////////////////////////////////////////////
  61. CBarf::CBarf(IN LPCTSTR pszName)
  62. {
  63. ASSERT(pszName != NULL);
  64. m_pszName = pszName;
  65. m_bDisabled = FALSE;
  66. m_bContinuous = FALSE;
  67. m_nFail = 0;
  68. m_nCurrent = 0;
  69. m_pbarfNext = s_pbarfFirst;
  70. s_pbarfFirst = this;
  71. } //*** CBarf::CBarf()
  72. /////////////////////////////////////////////////////////////////////////////
  73. //++
  74. //
  75. // CBarf::Init
  76. //
  77. // Routine Description:
  78. // Initializes the BARF counters instance by giving it its name and
  79. // giving it a startup value (from the registry if possible).
  80. //
  81. // Arguments:
  82. // None.
  83. //
  84. // Return Value:
  85. // None.
  86. //
  87. //--
  88. /////////////////////////////////////////////////////////////////////////////
  89. void CBarf::Init(void)
  90. {
  91. CString strSection;
  92. CString strValue;
  93. strSection.Format(BARF_REG_SECTION_FMT, m_pszName);
  94. m_bDisabled = AfxGetApp()->GetProfileInt(strSection, _T("Disabled"), FALSE);
  95. m_bContinuous = AfxGetApp()->GetProfileInt(strSection, _T("Continuous"), FALSE);
  96. m_nFail = AfxGetApp()->GetProfileInt(strSection, _T("Fail"), 0);
  97. } //*** CBarf::Init()
  98. /////////////////////////////////////////////////////////////////////////////
  99. //
  100. // CBarf::BFail
  101. //
  102. // Routine Description:
  103. // Determines if the next call should artificially fail.
  104. // Typical usage of this method is:
  105. // BOOL BARFFoo( void )
  106. // {
  107. // if (barfMyApi.BFail())
  108. // return FALSE;
  109. // else
  110. // return Foo();
  111. // }
  112. //
  113. // Return value:
  114. // bFail TRUE indicates the call should be made to
  115. // artificially fail.
  116. //
  117. /////////////////////////////////////////////////////////////////////////////
  118. BOOL CBarf::BFail(void)
  119. {
  120. BOOL bFail = FALSE;
  121. // If BARF is suspended, don't artificially fail.
  122. // Otherwise, check the counters.
  123. if (s_nSuspend == 0)
  124. {
  125. // Increment the call count.
  126. m_nCurrent++;
  127. // Call the post-update routine to allow UI to be updated.
  128. if (PfnPostUpdate())
  129. ((*PfnPostUpdate())());
  130. // If not disable and not globally disabled, keep checking.
  131. if (!m_bDisabled && s_bGlobalEnable)
  132. {
  133. // If in continuous fail mode, check to see if the counters
  134. // are above the specified range. Otherwise check to see if
  135. // the counter is exactly the same as what was specified.
  136. if (m_bContinuous)
  137. {
  138. if (m_nCurrent >= m_nFail)
  139. bFail = TRUE;
  140. } // if: in continuous fail mode
  141. else
  142. {
  143. if (m_nCurrent == m_nFail)
  144. bFail = TRUE;
  145. } // else: not in continuous fail mode
  146. // If this API set was marked to fail on the next (this) call,
  147. // fail the call and reset the marker.
  148. if (g_bFailOnNextBarf)
  149. {
  150. bFail = TRUE;
  151. g_bFailOnNextBarf = FALSE;
  152. } // if: counters marked to fail on next (this) call
  153. } // if: not disabled and globally enabled
  154. } // if: not suspended
  155. return bFail;
  156. } //*** CBarf::BFail()
  157. //*************************************************************************//
  158. /////////////////////////////////////////////////////////////////////////////
  159. // CBarfSuspend
  160. /////////////////////////////////////////////////////////////////////////////
  161. CRITICAL_SECTION CBarfSuspend::s_critsec;
  162. BOOL CBarfSuspend::s_bCritSecValid = FALSE;
  163. /////////////////////////////////////////////////////////////////////////////
  164. //++
  165. //
  166. // CBarfSuspend::CBarfSuspend
  167. //
  168. // Routine Description:
  169. // Constructor.
  170. //
  171. // Arguments:
  172. // None.
  173. //
  174. // Return Value:
  175. // None.
  176. //
  177. //--
  178. /////////////////////////////////////////////////////////////////////////////
  179. CBarfSuspend::CBarfSuspend(void)
  180. {
  181. if (BCritSecValid())
  182. EnterCriticalSection(Pcritsec());
  183. CBarf::s_nSuspend++;
  184. if (BCritSecValid())
  185. LeaveCriticalSection(Pcritsec());
  186. } //*** CBarfSuspend::CBarfSuspend()
  187. /////////////////////////////////////////////////////////////////////////////
  188. //++
  189. //
  190. // CBarfSuspend::~CBarfSuspend
  191. //
  192. // Routine Description:
  193. // Destructor.
  194. //
  195. // Arguments:
  196. // None.
  197. //
  198. // Return Value:
  199. // None.
  200. //
  201. //--
  202. /////////////////////////////////////////////////////////////////////////////
  203. CBarfSuspend::~CBarfSuspend(void)
  204. {
  205. if (BCritSecValid())
  206. EnterCriticalSection(Pcritsec());
  207. CBarf::s_nSuspend--;
  208. ASSERT(CBarf::s_nSuspend >= 0);
  209. if (BCritSecValid())
  210. LeaveCriticalSection(Pcritsec());
  211. } //*** CBarfSuspend::~CBarfSuspend()
  212. /////////////////////////////////////////////////////////////////////////////
  213. //++
  214. //
  215. // CBarfSuspend::Init
  216. //
  217. // Routine Description:
  218. // Initialize the class.
  219. //
  220. // Arguments:
  221. // None.
  222. //
  223. // Return Value:
  224. // None.
  225. //
  226. //--
  227. /////////////////////////////////////////////////////////////////////////////
  228. void CBarfSuspend::Init(void)
  229. {
  230. InitializeCriticalSection(Pcritsec());
  231. s_bCritSecValid = TRUE;
  232. } //*** CBarfSuspend::Init()
  233. /////////////////////////////////////////////////////////////////////////////
  234. //++
  235. //
  236. // CBarfSuspend::Cleanup
  237. //
  238. // Routine Description:
  239. // Initialize the class.
  240. //
  241. // Arguments:
  242. // None.
  243. //
  244. // Return Value:
  245. // None.
  246. //
  247. //--
  248. /////////////////////////////////////////////////////////////////////////////
  249. void CBarfSuspend::Cleanup(void)
  250. {
  251. if (BCritSecValid())
  252. {
  253. DeleteCriticalSection(Pcritsec());
  254. s_bCritSecValid = FALSE;
  255. } // if: critical section is valid
  256. } //*** CBarfSuspend::Cleanup()
  257. //*************************************************************************//
  258. /////////////////////////////////////////////////////////////////////////////
  259. // Global Functions
  260. /////////////////////////////////////////////////////////////////////////////
  261. /////////////////////////////////////////////////////////////////////////////
  262. //++
  263. //
  264. // InitBarf
  265. //
  266. // Routine Description:
  267. // Initializes all BARF counters in the BARF list.
  268. //
  269. // Arguments:
  270. // None.
  271. //
  272. // Return Value:
  273. // None.
  274. //
  275. //--
  276. /////////////////////////////////////////////////////////////////////////////
  277. void InitBarf(void)
  278. {
  279. CBarf * pbarf;
  280. // Loop through the BARF counter list.
  281. for (pbarf = CBarf::s_pbarfFirst ; pbarf != NULL ; pbarf = pbarf->m_pbarfNext)
  282. pbarf->Init();
  283. CBarfSuspend::Init();
  284. } //*** InitBarf()
  285. /////////////////////////////////////////////////////////////////////////////
  286. //++
  287. //
  288. // CleanupBarf
  289. //
  290. // Routine Description:
  291. // Cleanup after BARF.
  292. //
  293. // Arguments:
  294. // None.
  295. //
  296. // Return Value:
  297. // None.
  298. //
  299. //--
  300. /////////////////////////////////////////////////////////////////////////////
  301. void CleanupBarf(void)
  302. {
  303. CBarfSuspend::Cleanup();
  304. } //*** CleanupBarf()
  305. /////////////////////////////////////////////////////////////////////////////
  306. //++
  307. //
  308. // EnableBarf
  309. //
  310. // Routine Description:
  311. // Allows user code to enable/disable BARF for sections of code.
  312. //
  313. // Arguments:
  314. // bEnable [IN] TRUE = enable BARF, FALSE = disable BARF.
  315. //
  316. // Return Value:
  317. // None.
  318. //
  319. //--
  320. /////////////////////////////////////////////////////////////////////////////
  321. void EnableBarf(IN BOOL bEnable)
  322. {
  323. if (bEnable)
  324. Trace(g_tagBarf, _T("Artificial Failures enabled"));
  325. else
  326. Trace(g_tagBarf, _T("Artificial Failures disabled"));
  327. CBarf::s_bGlobalEnable = bEnable;
  328. } //*** EnableBarf()
  329. #endif // _DEBUG