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.

322 lines
7.4 KiB

  1. /*===================================================================
  2. Microsoft Confidential.
  3. Copyright 1997 Microsoft Corporation. All Rights Reserved.
  4. Component: RFS
  5. File: rfs.cpp
  6. Owner: EricN
  7. This the Resource failure objects.
  8. ===================================================================*/
  9. #include "denpre.h"
  10. #pragma hdrstop
  11. #ifdef _RFS
  12. #include <tchar.h>
  13. #include <stdio.h>
  14. #include "rfs.h"
  15. //constructor
  16. RFS::RFS(DWORD dwFailOn, DWORD dwThreadID)
  17. {
  18. __asm {int 3}
  19. m_dwFailOn = dwFailOn;
  20. m_dwTtlNumAllocs = 0;
  21. m_dwCurrentAlloc = 0;
  22. m_dwThreadID = dwThreadID;
  23. m_fFail = FALSE;
  24. m_bType = -1;
  25. }
  26. //*****************************************************************************
  27. // Name: RFS::SetFailOn
  28. // Args: Changes the fail on value and spcifies what the number means
  29. // bType = COUNT | ALLOCATE
  30. // Author: EricN
  31. // History: Created 4/15/97 (tax day)
  32. // Notes:
  33. //*****************************************************************************
  34. void
  35. RFS::SetFailOn(DWORD dwFailOn, BYTE bType)
  36. {
  37. m_dwFailOn = dwFailOn;
  38. m_bType = bType;
  39. }
  40. //*****************************************************************************
  41. // Name: RFS::SetFailOn
  42. // Args: Causes a failure on a line or allocation form a specific file
  43. // pszFile - the file (a .cpp file)
  44. // lLine - the line number
  45. // the type is forced to FILE_LINE
  46. // Author: EricN
  47. // History: Created 7/8/97
  48. // Notes:
  49. //*****************************************************************************
  50. void
  51. RFS::SetFailOn(LPSTR pszFile, long lLine)
  52. {
  53. strcpy(m_szFailIn, pszFile);
  54. m_dwFailOn = lLine;
  55. m_bType = FILE_LINE;
  56. }
  57. //*****************************************************************************
  58. // Name: RFS::WriteData
  59. // Args: none
  60. // Author: EricN
  61. // History: Created 4/22/97 (tax day)
  62. // Notes: writes out any interesting data
  63. //*****************************************************************************
  64. void
  65. RFS::WriteData()
  66. {
  67. char szOutput[200];
  68. sprintf(szOutput, "\n\nTotal Number of allocations: %ld\n", m_dwTtlNumAllocs);
  69. Log(MFSLOGFILE, szOutput);
  70. }
  71. //*****************************************************************************
  72. // Name: RFS::DetermineFailure
  73. // Args: None
  74. // Author: EricN
  75. // History: Created 4/15/97 (tax day)
  76. // Notes:
  77. // This determines if the particular resource should fail
  78. // Currently it just logs the failure to a file, but will eventually
  79. // communicate with an outside application
  80. //*****************************************************************************
  81. BOOL
  82. RFS::DetermineFailure(LPCSTR szFile, int iLineNo)
  83. {
  84. BOOL fFail = FALSE;
  85. DWORD dwThreadID = GetCurrentThreadId();
  86. char szOutput[200];
  87. //verify the we're being called on the correct threadid
  88. if (dwThreadID != m_dwThreadID)
  89. {
  90. //sprintf(szOutput, "Called on differnt thread. Exp: %ld, Rec: %ld\n", m_dwThreadID, dwThreadID);
  91. //Log(MFSLOGFILE, szOutput);
  92. return FALSE;
  93. }
  94. m_dwTtlNumAllocs++;
  95. m_dwCurrentAlloc++;
  96. switch(m_bType)
  97. {
  98. case COUNT:
  99. if (m_fFail && m_dwCurrentAlloc == m_dwFailOn)
  100. {
  101. fFail = TRUE;
  102. m_dwFailOn++;
  103. m_dwCurrentAlloc = 0;
  104. }
  105. break;
  106. case MEM:
  107. break;
  108. case FILE_LINE:
  109. if (m_fFail && m_dwFailOn == iLineNo)
  110. {
  111. if (_stricmp(m_szFailIn, szFile) == 0)
  112. {
  113. fFail = TRUE;
  114. }
  115. }
  116. break;
  117. default:
  118. sprintf(szOutput, "BAD failure type specified: %d\n",m_bType);
  119. Log(MFSLOGFILE, szOutput);
  120. break;
  121. }//switch
  122. if (fFail)
  123. {
  124. if (szFile != NULL)
  125. sprintf(szOutput, "Failing Allocation: %ld File: %s, Line: %d\n", m_dwCurrentAlloc,
  126. szFile, iLineNo);
  127. else
  128. sprintf(szOutput, "Failing Allocation: %ld\n", m_dwCurrentAlloc);
  129. Log(MFSLOGFILE, szOutput);
  130. return TRUE;
  131. }
  132. return FALSE;
  133. }
  134. void
  135. RFS::SetThreadID(DWORD dwThreadID)
  136. {
  137. m_dwThreadID = dwThreadID;
  138. }
  139. void
  140. RFS::Log(LPSTR pszFileName, LPSTR pszMsg)
  141. {
  142. int fh;
  143. fh = _open(pszFileName,
  144. _O_WRONLY | _O_CREAT | _O_APPEND | _O_BINARY,
  145. _S_IREAD | _S_IWRITE );
  146. if (fh == -1)
  147. {
  148. DBG_PRINTF((DBG_CONTEXT, "FAIL: Could not open RFS log\n"));
  149. }
  150. _write( fh, (void*)pszMsg, strlen(pszMsg));
  151. _close(fh);
  152. }
  153. //construstor
  154. MemRFS::MemRFS(DWORD dwFailOn, DWORD dwThreadID) : RFS(dwFailOn, dwThreadID)
  155. {
  156. }
  157. //*****************************************************************************
  158. // Name: MemRFS::Init
  159. // Args: None
  160. // Author: EricN
  161. // History: Created 4/15/97 (tax day)
  162. // Notes:
  163. //*****************************************************************************
  164. HRESULT
  165. MemRFS::Init()
  166. {
  167. int fh;
  168. long lVal;
  169. char szBuff[MAX_PATH];
  170. //only read the file the first time the RFS stuff is instantiated
  171. if (m_dwCurrentAlloc == 0)
  172. {
  173. fh = _open(MFSINIFILE,
  174. _O_RDONLY | _O_BINARY, _S_IREAD | _S_IWRITE );
  175. //init doesn't fail if there is no init file,
  176. if (fh != -1)
  177. {
  178. DWORD dwBytes = _read( fh, (void*)szBuff, MAX_PATH);
  179. _close(fh);
  180. szBuff[dwBytes-1] = '\0';
  181. //determine type of failure requested
  182. lVal = atol(szBuff);
  183. //if lval is 0 then a file name was specified
  184. if (lVal == 0)
  185. {
  186. LPSTR pStr;
  187. pStr = strstr(szBuff, ",");
  188. if (pStr != NULL)
  189. {
  190. //replace ',' with \0
  191. *pStr = '\0';
  192. pStr++;
  193. lVal = atol(pStr);
  194. SetFailOn(szBuff, lVal);
  195. }
  196. else
  197. {
  198. //having a line of zero will force a failure on the
  199. //first request from a file
  200. SetFailOn(szBuff, 0);
  201. }
  202. }
  203. else
  204. {
  205. LPSTR pStr;
  206. pStr = strstr(szBuff, ",");
  207. if (!pStr != NULL)
  208. {
  209. pStr++;
  210. SetFailOn(lVal, (BYTE)atoi(pStr));
  211. }
  212. else
  213. SetFailOn(lVal, COUNT);
  214. }
  215. }
  216. }
  217. //reset the allocations for this request.
  218. m_dwCurrentAlloc = 0;
  219. return S_OK;
  220. }
  221. //*****************************************************************************
  222. // Name: MemRFS::FailAlloc
  223. // Args: None
  224. // Author: EricN
  225. // History: Created 4/15/97 (tax day)
  226. // Notes: Just calls base class
  227. //*****************************************************************************
  228. BOOL
  229. MemRFS::FailAlloc(void *cSize, LPCSTR szFile, int iLineNo)
  230. {
  231. //need to add code to handle size stuff.
  232. return DetermineFailure(szFile, iLineNo);
  233. }
  234. //*****************************************************************************
  235. // Name: MemRFS::SetRFSOn
  236. // Args: fRFSOn - determines if RFS is on or off
  237. // Author: EricN
  238. // History: Created 4/15/97 (tax day)
  239. // Notes: This turns on and off RFS
  240. //*****************************************************************************
  241. void
  242. MemRFS::SetRFSOn(BOOL fRFSOn)
  243. {
  244. m_fFail = fRFSOn;
  245. }
  246. //*****************************************************************************
  247. // Name: MemRFS::SetFailOn
  248. // Args: Changes the fail on value
  249. // Author: EricN
  250. // History: Created 4/15/97 (tax day)
  251. // Notes: This turns on and off RFS
  252. //*****************************************************************************
  253. void
  254. MemRFS::SetFailOn(DWORD dwFailOn, BYTE bType)
  255. {
  256. RFS::SetFailOn(dwFailOn, bType);
  257. }
  258. //*****************************************************************************
  259. // Name: MemRFS::SetFailOn
  260. // Args: Changes the fail on value
  261. // Author: EricN
  262. // History: Created 4/15/97 (tax day)
  263. // Notes: This turns on and off RFS
  264. //*****************************************************************************
  265. void
  266. MemRFS::SetFailOn(LPSTR pszFile, long lLine)
  267. {
  268. RFS::SetFailOn(pszFile, lLine);
  269. }
  270. //*****************************************************************************
  271. // Name: MemRFS::WriteData
  272. // Args: None
  273. // Author: EricN
  274. // History: Created 4/22/97
  275. // Notes: Writes out any data of interest
  276. //*****************************************************************************
  277. void
  278. MemRFS::WriteData()
  279. {
  280. RFS::WriteData();
  281. }
  282. #endif // _RFS