|
|
/*===================================================================
Microsoft Confidential. Copyright 1997 Microsoft Corporation. All Rights Reserved.
Component: RFS
File: rfs.cpp
Owner: EricN
This the Resource failure objects. ===================================================================*/
#include "denpre.h"
#pragma hdrstop
#ifdef _RFS
#include <tchar.h>
#include <stdio.h>
#include "rfs.h"
//constructor
RFS::RFS(DWORD dwFailOn, DWORD dwThreadID) { __asm {int 3} m_dwFailOn = dwFailOn; m_dwTtlNumAllocs = 0; m_dwCurrentAlloc = 0; m_dwThreadID = dwThreadID; m_fFail = FALSE; m_bType = -1; }
//*****************************************************************************
// Name: RFS::SetFailOn
// Args: Changes the fail on value and spcifies what the number means
// bType = COUNT | ALLOCATE
// Author: EricN
// History: Created 4/15/97 (tax day)
// Notes:
//*****************************************************************************
void RFS::SetFailOn(DWORD dwFailOn, BYTE bType) { m_dwFailOn = dwFailOn; m_bType = bType; }
//*****************************************************************************
// Name: RFS::SetFailOn
// Args: Causes a failure on a line or allocation form a specific file
// pszFile - the file (a .cpp file)
// lLine - the line number
// the type is forced to FILE_LINE
// Author: EricN
// History: Created 7/8/97
// Notes:
//*****************************************************************************
void RFS::SetFailOn(LPSTR pszFile, long lLine) { strcpy(m_szFailIn, pszFile); m_dwFailOn = lLine; m_bType = FILE_LINE; }
//*****************************************************************************
// Name: RFS::WriteData
// Args: none
// Author: EricN
// History: Created 4/22/97 (tax day)
// Notes: writes out any interesting data
//*****************************************************************************
void RFS::WriteData() { char szOutput[200];
sprintf(szOutput, "\n\nTotal Number of allocations: %ld\n", m_dwTtlNumAllocs); Log(MFSLOGFILE, szOutput); }
//*****************************************************************************
// Name: RFS::DetermineFailure
// Args: None
// Author: EricN
// History: Created 4/15/97 (tax day)
// Notes:
// This determines if the particular resource should fail
// Currently it just logs the failure to a file, but will eventually
// communicate with an outside application
//*****************************************************************************
BOOL RFS::DetermineFailure(LPCSTR szFile, int iLineNo) { BOOL fFail = FALSE; DWORD dwThreadID = GetCurrentThreadId(); char szOutput[200];
//verify the we're being called on the correct threadid
if (dwThreadID != m_dwThreadID) { //sprintf(szOutput, "Called on differnt thread. Exp: %ld, Rec: %ld\n", m_dwThreadID, dwThreadID);
//Log(MFSLOGFILE, szOutput);
return FALSE; } m_dwTtlNumAllocs++; m_dwCurrentAlloc++;
switch(m_bType) { case COUNT:
if (m_fFail && m_dwCurrentAlloc == m_dwFailOn) { fFail = TRUE; m_dwFailOn++; m_dwCurrentAlloc = 0; }
break; case MEM: break; case FILE_LINE: if (m_fFail && m_dwFailOn == iLineNo) { if (_stricmp(m_szFailIn, szFile) == 0) { fFail = TRUE; } }
break; default: sprintf(szOutput, "BAD failure type specified: %d\n",m_bType); Log(MFSLOGFILE, szOutput); break; }//switch
if (fFail) { if (szFile != NULL) sprintf(szOutput, "Failing Allocation: %ld File: %s, Line: %d\n", m_dwCurrentAlloc, szFile, iLineNo); else sprintf(szOutput, "Failing Allocation: %ld\n", m_dwCurrentAlloc);
Log(MFSLOGFILE, szOutput); return TRUE; }
return FALSE; }
void RFS::SetThreadID(DWORD dwThreadID) { m_dwThreadID = dwThreadID; }
void RFS::Log(LPSTR pszFileName, LPSTR pszMsg) { int fh;
fh = _open(pszFileName, _O_WRONLY | _O_CREAT | _O_APPEND | _O_BINARY, _S_IREAD | _S_IWRITE );
if (fh == -1) { DBG_PRINTF((DBG_CONTEXT, "FAIL: Could not open RFS log\n")); }
_write( fh, (void*)pszMsg, strlen(pszMsg)); _close(fh); }
//construstor
MemRFS::MemRFS(DWORD dwFailOn, DWORD dwThreadID) : RFS(dwFailOn, dwThreadID) { }
//*****************************************************************************
// Name: MemRFS::Init
// Args: None
// Author: EricN
// History: Created 4/15/97 (tax day)
// Notes:
//*****************************************************************************
HRESULT MemRFS::Init() { int fh; long lVal; char szBuff[MAX_PATH];
//only read the file the first time the RFS stuff is instantiated
if (m_dwCurrentAlloc == 0) { fh = _open(MFSINIFILE, _O_RDONLY | _O_BINARY, _S_IREAD | _S_IWRITE );
//init doesn't fail if there is no init file,
if (fh != -1) { DWORD dwBytes = _read( fh, (void*)szBuff, MAX_PATH); _close(fh); szBuff[dwBytes-1] = '\0'; //determine type of failure requested
lVal = atol(szBuff); //if lval is 0 then a file name was specified
if (lVal == 0) { LPSTR pStr; pStr = strstr(szBuff, ","); if (pStr != NULL) { //replace ',' with \0
*pStr = '\0';
pStr++; lVal = atol(pStr); SetFailOn(szBuff, lVal); } else { //having a line of zero will force a failure on the
//first request from a file
SetFailOn(szBuff, 0); } } else { LPSTR pStr; pStr = strstr(szBuff, ","); if (!pStr != NULL) { pStr++; SetFailOn(lVal, (BYTE)atoi(pStr)); } else SetFailOn(lVal, COUNT); } } }
//reset the allocations for this request.
m_dwCurrentAlloc = 0;
return S_OK; }
//*****************************************************************************
// Name: MemRFS::FailAlloc
// Args: None
// Author: EricN
// History: Created 4/15/97 (tax day)
// Notes: Just calls base class
//*****************************************************************************
BOOL MemRFS::FailAlloc(void *cSize, LPCSTR szFile, int iLineNo) { //need to add code to handle size stuff.
return DetermineFailure(szFile, iLineNo); }
//*****************************************************************************
// Name: MemRFS::SetRFSOn
// Args: fRFSOn - determines if RFS is on or off
// Author: EricN
// History: Created 4/15/97 (tax day)
// Notes: This turns on and off RFS
//*****************************************************************************
void MemRFS::SetRFSOn(BOOL fRFSOn) { m_fFail = fRFSOn; }
//*****************************************************************************
// Name: MemRFS::SetFailOn
// Args: Changes the fail on value
// Author: EricN
// History: Created 4/15/97 (tax day)
// Notes: This turns on and off RFS
//*****************************************************************************
void MemRFS::SetFailOn(DWORD dwFailOn, BYTE bType) { RFS::SetFailOn(dwFailOn, bType); }
//*****************************************************************************
// Name: MemRFS::SetFailOn
// Args: Changes the fail on value
// Author: EricN
// History: Created 4/15/97 (tax day)
// Notes: This turns on and off RFS
//*****************************************************************************
void MemRFS::SetFailOn(LPSTR pszFile, long lLine) { RFS::SetFailOn(pszFile, lLine); }
//*****************************************************************************
// Name: MemRFS::WriteData
// Args: None
// Author: EricN
// History: Created 4/22/97
// Notes: Writes out any data of interest
//*****************************************************************************
void MemRFS::WriteData() { RFS::WriteData(); }
#endif // _RFS
|