windows-nt/Source/XPSP1/NT/net/config/tools/ncbrowse/ncspewfile.cpp
2020-09-26 16:20:57 +08:00

332 lines
9.5 KiB
C++

// NCSpewFile.cpp: implementation of the CNCSpewFile class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ncbrowse.h"
#include "mainfrm.h"
using namespace std;
#include "NCSpewFile.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CNCEntry::CNCEntry(DWORD dwLineNumber, tstring szTag, time_t tmTime, tstring szDescription, DWORD dwProcessID, DWORD dwThreadID)
{
m_dwLineNumber = dwLineNumber;
m_szTag = szTag;
m_tmTime = tmTime;
m_szDescription = szDescription;
m_dwLevel = 0;
m_dwProcessId = dwProcessID;
m_dwThreadId = dwThreadID;
}
CNCThread::CNCThread()
{
m_dwProcessId = 0;
m_dwThreadID = 0;
}
class CProtectedArchive : public CArchive
{
public:
LPTSTR ReadString(LPTSTR lpsz, UINT nMax);
};
#ifdef _DEBUG
#define DELETE_EXCEPTION(e) do { e->Delete(); } while (0)
#else
#define DELETE_EXCEPTION(e)
#endif
LPTSTR CProtectedArchive::ReadString(LPTSTR lpsz, UINT nMax)
{
// if nMax is negative (such a large number doesn't make sense given today's
// 2gb address space), then assume it to mean "keep the newline".
int nStop = (int)nMax < 0 ? -(int)nMax : (int)nMax;
ASSERT(AfxIsValidAddress(lpsz, (nStop+1) * sizeof(TCHAR)));
_TUCHAR ch;
int nRead = 0;
TRY
{
while (nRead < nStop)
{
*this >> ch;
// stop and end-of-line (trailing '\n' is ignored)
if (ch == '\n' || ch == '\r')
{
BOOL bBreak = TRUE;
if (ch == '\r')
{
BYTE by;
if (m_lpBufCur + sizeof(BYTE) > m_lpBufMax)
{
FillBuffer(sizeof(BYTE) - (UINT)(m_lpBufMax - m_lpBufCur));
}
by = *(UNALIGNED BYTE*)m_lpBufCur;
if (by == '\n')
{
ch = by;
m_lpBufCur += sizeof(BYTE);
}
else
{
ch = by;
bBreak = FALSE;
}
}
// store the newline when called with negative nMax
if ((int)nMax != nStop)
{
lpsz[nRead++] = ch;
}
if (bBreak)
{
break;
}
}
lpsz[nRead++] = ch;
}
}
CATCH(CArchiveException, e)
{
if (e->m_cause == CArchiveException::endOfFile)
{
DELETE_EXCEPTION(e);
if (nRead == 0)
return NULL;
}
else
{
THROW_LAST();
}
}
END_CATCH
lpsz[nRead] = '\0';
return lpsz;
}
enum NETCFG_LOGTYPE
{
LOGTYPE_UNKNOWN = 0,
LOGTYPE_PROC_THREAD = 1,
LOGTYPE_PROC_THREAD_TIME = 2,
};
CNCSpewFile::CNCSpewFile(CArchive& ar)
{
TCHAR szCurrentLine[8192];
DWORD dwLineNum = 0;
const CFile &fp = *(ar.GetFile());
DWORD dwTotalSize = fp.GetLength();
DWORD dwTotalSpews = 1;
CSpew spew;
spew.szSpewName = _T("01. Unknown O/S");
m_Spews[1] = spew;
CSpew *m_pCurrentSpew = &(m_Spews[1]);
m_pCNCurrentThread = &(m_pCurrentSpew->m_NCThreadList);
NETCFG_LOGTYPE ncfLogType = LOGTYPE_UNKNOWN;
CProtectedArchive &arP = *reinterpret_cast<CProtectedArchive *>(&ar);
while (arP.ReadString(szCurrentLine, 8192))
{
dwLineNum++;
LPCTSTR sztstring = szCurrentLine;
rpattern *pPat = NULL;
switch (ncfLogType)
{
case LOGTYPE_UNKNOWN:
case LOGTYPE_PROC_THREAD:
pPat = new rpattern( _T(".*(ETCFG) ([0-9a-fA-F]*)\\.([0-9a-fA-F]*) (?:\\(|\\*)((?:\\s|\\w)*)(?:\\)|\\*)(.*)") );
break;
case LOGTYPE_PROC_THREAD_TIME:
pPat = new rpattern( _T(".*(ETCFG) ([0-9a-fA-F]*)\\.([0-9a-fA-F]*) \\[.*\\] (?:\\(|\\*)((?:\\s|\\w)*)(?:\\)|\\*)(.*)") );
break;
default:
ASSERT(FALSE);
return;
}
//rpattern pat( _T("NETCFG (\\{a-f0-9}+)\\.(\\{a-f0-9}+)") );
DWORD dwPosition = fp.GetPosition();
TCHAR szStatusBarText[MAX_PATH];
DWORD dwPercentage = 100 * dwPosition / dwTotalSize;
_stprintf(szStatusBarText, _T("%d%% complete"), dwPercentage);
CStatusBar &StatusBar = ((CMainFrame *)AfxGetMainWnd())->m_wndStatusBar;
StatusBar.SetPaneText (0, szStatusBarText, TRUE);
BOOL bProcessed = FALSE;
BOOL bMatched = FALSE;
BOOL bHalfMatched = FALSE;
regexpr::backref_vector rgbackrefs;
if (regexpr::match( sztstring, *pPat, &rgbackrefs ) )
{
bMatched = TRUE;
if (LOGTYPE_UNKNOWN == ncfLogType)
{
ncfLogType = LOGTYPE_PROC_THREAD;
}
}
else
{
if (LOGTYPE_UNKNOWN == ncfLogType)
{
delete pPat;
pPat = new rpattern( _T(".*(ETCFG) ([0-9a-fA-F]*)\\.([0-9a-fA-F]*) \\[.*\\] (?:\\(|\\*)((?:\\s|\\w)*)(?:\\)|\\*)(.*)") );
if (regexpr::match( sztstring, *pPat, &rgbackrefs ) )
{
bMatched = TRUE;
ncfLogType = LOGTYPE_PROC_THREAD_TIME;
}
}
}
if (!bMatched)
{
rpattern pat( _T(".*(ETCFG) ([0-9a-fA-F]*)\\.([0-9a-fA-F]*)(.*)") );
if( regexpr::match( sztstring, pat, &rgbackrefs ) )
{
bHalfMatched = TRUE;
}
}
delete pPat;
if (bMatched | bHalfMatched)
{
// Backref 0 -> Full tstring
// Backref 1 -> NETCFG
// Backref 2 -> ProcId
// Backref 3 -> ThreadId
// Backref 4 -> TagName
// Backref 5 -> tstring
ASSERT(rgbackrefs.size() >= 5);
TCHAR szProcID[MAX_PATH];
TCHAR szThreadID[MAX_PATH];
TCHAR szTagName[MAX_PATH];
TCHAR szDescription[8192];
bProcessed = TRUE;
regexpr::backref_type br = rgbackrefs[2];
_stprintf(szProcID, _T("%.*s"), br.second - br.first, br.first );
StrTrim(szProcID, _T(" "));
LPTSTR szEndChar;
DWORD dwProcId = _tcstoul(szProcID, &szEndChar, 16);
br = rgbackrefs[3];
_stprintf(szThreadID, _T("%.*s"), br.second - br.first, br.first );
StrTrim(szThreadID, _T(" "));
DWORD dwThreadId = _tcstoul(szThreadID, &szEndChar, 16);
DWORD iProcThread = (dwProcId << 16) | dwThreadId;
if (bMatched)
{
br = rgbackrefs[4];
_stprintf(szTagName, _T("%.*s"), br.second - br.first, br.first );
StrTrim(szTagName, _T(" "));
br = rgbackrefs[5];
_stprintf(szDescription, _T("%.*s"), br.second - br.first, br.first );
StrTrim(szDescription, _T(" "));
if (!_tcscmp(szTagName, _T("ERROR")))
{
_tcscpy(szTagName, _T("*ERROR*"));
StrTrim(szDescription, _T(":"));
StrTrim(szDescription, _T(" "));
}
}
else
{
_tcscpy(szTagName, _T("*Unknown*"));
br = rgbackrefs[4];
_stprintf(szDescription, _T("%.*s"), br.second - br.first, br.first );
StrTrim(szDescription, _T(" "));
}
CNCEntry NCEntry(dwLineNum, szTagName, 0, szDescription, dwProcId, dwThreadId);
CNCThread &NCThread = (*m_pCNCurrentThread)[iProcThread];
if (!NCThread.m_dwProcessId)
{
NCThread.m_dwProcessId = dwProcId;
NCThread.m_dwThreadID = dwThreadId;
}
else
{
ASSERT(NCThread.m_dwProcessId == dwProcId);
ASSERT(NCThread.m_dwThreadID == dwThreadId);
}
NCThread.m_lsLines.push_back(NCEntry);
NCThread.m_Tags[szTagName]++;
m_pCurrentSpew->m_lsLines.push_back(NCEntry);
m_pCurrentSpew->m_Tags[szTagName]++;
}
if (*szCurrentLine == _T('C'))
{
rpattern connPat( _T("Connected to Windows (.*) compatible target") );
regexpr::backref_vector rgbackrefs;
if( regexpr::match( sztstring, connPat, &rgbackrefs ) )
{
bProcessed = TRUE;
dwTotalSpews++;
ASSERT(rgbackrefs.size() >= 2);
regexpr::backref_type br = rgbackrefs[1];
TCHAR szDescription[MAX_PATH];
_stprintf(szDescription, _T("%02d. %.*s"), dwTotalSpews, br.second - br.first, br.first );
CSpew spew;
spew.szSpewName = szDescription;
m_Spews[dwTotalSpews] = spew;
m_pCurrentSpew = &(m_Spews[dwTotalSpews]);
m_pCNCurrentThread = &(m_pCurrentSpew->m_NCThreadList);
}
}
if (!bProcessed)
{
m_pCurrentSpew->m_SpareLines[dwLineNum] = szCurrentLine;
}
}
}
CNCSpewFile::~CNCSpewFile()
{
}