323 lines
7.4 KiB
C++
323 lines
7.4 KiB
C++
|
/*===================================================================
|
||
|
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
|