/*=================================================================== 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 #include #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