Leaked source code of windows server 2003
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.
 
 
 
 
 
 

383 lines
9.6 KiB

#include "precomp.h"
#include "logitem.h"
// utility APIs declarations
// these two are identical to _strdate and _strtime respectively
LPCTSTR StrGetDate(LPTSTR pszDate);
LPCTSTR StrGetTime(LPTSTR pszTime);
// string constants
const TCHAR c_szCRLF[] = TEXT("\r\n");
const TCHAR c_szSpace[] = TEXT(" ");
const TCHAR c_szCommaSpace[] = TEXT(", ");
const TCHAR c_szColonColon[] = TEXT("::");
const TCHAR c_szColonSpace[] = TEXT(": ");
const TCHAR c_szLine[] = TEXT("line %i");
/////////////////////////////////////////////////////////////////////////////
// CLogItem
TCHAR CLogItem::m_szModule[MAX_PATH];
BYTE CLogItem::m_bStep = 4;
CLogItem::CLogItem(DWORD dwFlags /*= LIF_DEFAULT*/, LPBOOL pfLogLevels /*= NULL*/, UINT cLogLevels /*= 0*/)
{
if (m_szModule[0] == TEXT('\0')) {
GetModuleFileName(GetModuleHandle(g_szModule), m_szModule, countof(m_szModule));
CharLower(m_szModule);
}
m_nAbsOffset = 0;
m_iRelOffset = 0;
m_nLine = 0;
m_rgfLogLevels = NULL;
m_cLogLevels = cLogLevels;
if (pfLogLevels != NULL) {
ASSERT(cLogLevels > 0);
m_rgfLogLevels = new BOOL[m_cLogLevels];
memcpy(m_rgfLogLevels, pfLogLevels, m_cLogLevels * sizeof(BOOL));
}
else
ASSERT(cLogLevels == 0);
m_nLevel = 0;
SetFlags(dwFlags);
}
CLogItem::~CLogItem()
{
delete[] m_rgfLogLevels;
}
/////////////////////////////////////////////////////////////////////////////
// CLogItem operations
LPCTSTR WINAPIV CLogItem::Log(int iLine, LPCTSTR pszFormat ...)
{
TCHAR szFormat[3 * MAX_PATH],
szBuffer[MAX_PATH];
LPCTSTR pszAux;
UINT nLen, nAuxLen,
cchCRLF;
BOOL fPreviousToken;
szFormat[0] = TEXT('\0');
nLen = 0;
if (hasFlag(LIF_NONE))
return NULL;
if (m_rgfLogLevels != NULL && m_nLevel < m_cLogLevels) {
ASSERT((int)m_nLevel >= 0);
if (!m_rgfLogLevels[m_nLevel])
return NULL;
}
// prepend any CRLF at the beginning
cchCRLF = StrSpn(pszFormat, c_szCRLF);
if (cchCRLF > 0) {
// special case
if (cchCRLF >= (UINT)StrLen(pszFormat)) {
StrCpy(m_szMessage, pszFormat);
if (hasFlag(LIF_DUPLICATEINODS))
OutputDebugString(m_szMessage);
return m_szMessage;
}
StrCpyN(&szFormat[nLen], pszFormat, cchCRLF + 1);
nLen += cchCRLF;
pszFormat += cchCRLF;
}
fPreviousToken = FALSE;
if (hasFlag(LIF_DATE)) {
StrGetDate(szBuffer);
StrCpy(&szFormat[nLen], szBuffer);
nLen += StrLen(szBuffer);
fPreviousToken = TRUE;
}
if (hasFlag(LIF_TIME)) {
if (fPreviousToken) {
StrCpy(&szFormat[nLen], c_szSpace);
nLen += countof(c_szSpace)-1;
}
StrGetTime(szBuffer);
StrCpy(&szFormat[nLen], szBuffer);
nLen += StrLen(szBuffer);
fPreviousToken = TRUE;
}
if (fPreviousToken) {
StrCpy(&szFormat[nLen], c_szSpace);
nLen += countof(c_szSpace)-1;
}
if ((m_nAbsOffset-1 + m_iRelOffset) > 0) {
ASSERT((m_nAbsOffset-1 + m_iRelOffset) * m_bStep < countof(szBuffer));
for (UINT i = 0; i < (m_nAbsOffset-1 + m_iRelOffset) * m_bStep; i++)
szBuffer[i] = TEXT(' ');
StrCpy(&szFormat[nLen], szBuffer);
nLen += i-1;
}
fPreviousToken = FALSE;
if (hasFlag(LIF_MODULE_ALL)) {
pszAux = szBuffer;
if (!hasFlag(LIF_MODULEPATH))
makeRawFileName(m_szModule, szBuffer, countof(szBuffer));
else
pszAux = m_szModule; // should be lowercase already
StrCpy(&szFormat[nLen], pszAux);
nLen += StrLen(pszAux);
fPreviousToken = TRUE;
}
if (hasFlag(LIF_FILE_ALL)) {
if (fPreviousToken) {
StrCpy(&szFormat[nLen], c_szCommaSpace);
nLen += countof(c_szCommaSpace)-1;
}
if (!hasFlag(LIF_FILEPATH))
makeRawFileName(m_szFile, szBuffer, countof(szBuffer));
else {
StrCpy(szBuffer, m_szFile);
CharLower(szBuffer);
}
StrCpy(&szFormat[nLen], szBuffer);
nLen += StrLen(szBuffer);
fPreviousToken = TRUE;
}
if (hasFlag(LIF_CLASS) && hasFlag(LIF_CLASS2)) {
if (fPreviousToken) {
StrCpy(&szFormat[nLen], c_szCommaSpace);
nLen += countof(c_szCommaSpace)-1;
}
StrCpy(&szFormat[nLen], m_szClass);
nLen += StrLen(m_szClass);
fPreviousToken = TRUE;
}
if (hasFlag(LIF_FUNCTION)) {
if (fPreviousToken) {
pszAux = (hasFlag(LIF_CLASS) && hasFlag(LIF_CLASS2)) ?
c_szColonColon : c_szCommaSpace;
StrCpy(&szFormat[nLen], pszAux);
nLen += StrLen(pszAux);
}
StrCpy(&szFormat[nLen], m_szFunction);
nLen += StrLen(m_szFunction);
fPreviousToken = TRUE;
}
if (hasFlag(LIF_LINE) && iLine > 0) {
if (fPreviousToken) {
StrCpy(&szFormat[nLen], c_szCommaSpace);
nLen += countof(c_szCommaSpace)-1;
}
nAuxLen = wnsprintf(szBuffer, countof(szBuffer), c_szLine, iLine);
StrCpy(&szFormat[nLen], szBuffer);
nLen += nAuxLen;
fPreviousToken = TRUE;
}
if (pszFormat == NULL)
StrCpy(m_szMessage, szFormat);
// nLen stays the same
else {
if (fPreviousToken) {
StrCpy(&szFormat[nLen], c_szColonSpace);
nLen += countof(c_szColonSpace)-1;
}
StrCpy(&szFormat[nLen], pszFormat);
va_list arglist;
va_start(arglist, pszFormat);
nAuxLen = wvnsprintf(m_szMessage, countof(m_szMessage), szFormat, arglist);
va_end(arglist);
nLen = nAuxLen;
}
if (hasFlag(LIF_APPENDCRLF))
StrCpy(&m_szMessage[nLen], c_szCRLF);
if (hasFlag(LIF_DUPLICATEINODS))
OutputDebugString(m_szMessage);
return m_szMessage;
}
CLogItem::operator LPCTSTR() const
{
return m_szMessage;
}
/////////////////////////////////////////////////////////////////////////////
// CLogItem implementation helper routines
LPCTSTR CLogItem::makeRawFileName(LPCTSTR pszPath, LPTSTR pszFile, UINT cchFile)
{
TCHAR szBuffer[MAX_PATH];
LPCTSTR pszRawName;
if (pszFile == NULL || cchFile == 0)
return NULL;
*pszFile = TEXT('\0');
if (pszPath == NULL || StrLen(pszPath) == 0)
return NULL;
pszRawName = PathFindFileName(pszPath);
ASSERT(StrLen(pszRawName) > 0);
StrCpy(szBuffer, pszRawName);
CharLower(szBuffer);
if (cchFile <= (UINT)StrLen(szBuffer))
return NULL;
StrCpy(pszFile, szBuffer);
return pszFile;
}
BOOL CLogItem::setFlag(DWORD dwMask, BOOL fSet /*= TRUE*/)
{
BOOL fIsFlag = ((m_dwFlags & dwMask) != 0L);
if (fIsFlag == fSet)
return FALSE;
if (!fIsFlag && fSet)
m_dwFlags |= dwMask;
else {
ASSERT(fIsFlag && !fSet);
m_dwFlags &= ~dwMask;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// Utility functions
// Note. pszDate must point to the buffer of at least 11 characters.
LPCTSTR StrGetDate(LPTSTR pszDate)
{
SYSTEMTIME dt;
UINT nMonth, nDay, nYear;
GetLocalTime(&dt);
nMonth = dt.wMonth;
nDay = dt.wDay;
nYear = dt.wYear;
*(pszDate + 2) = *(pszDate + 5) = TEXT('/');
*(pszDate + 10) = TEXT('\0');
*(pszDate + 0) = (TCHAR)(nMonth / 10 + TEXT('0'));
*(pszDate + 1) = (TCHAR)(nMonth % 10 + TEXT('0'));
*(pszDate + 3) = (TCHAR)(nDay / 10 + TEXT('0'));
*(pszDate + 4) = (TCHAR)(nDay % 10 + TEXT('0'));
*(pszDate + 6) = (TCHAR)(((nYear / 1000) % 10) + TEXT('0'));
*(pszDate + 7) = (TCHAR)(((nYear / 100) % 10) + TEXT('0'));
*(pszDate + 8) = (TCHAR)(((nYear / 10) % 10) + TEXT('0'));
*(pszDate + 9) = (TCHAR)(((nYear / 1) % 10) + TEXT('0'));
return pszDate;
}
// Note. pszTime must point to the buffer of at least 9 characters.
LPCTSTR StrGetTime(LPTSTR pszTime)
{
SYSTEMTIME dt;
int nHours, nMinutes, nSeconds;
GetLocalTime(&dt);
nHours = dt.wHour;
nMinutes = dt.wMinute;
nSeconds = dt.wSecond;
*(pszTime + 2) = *(pszTime + 5) = TEXT(':');
*(pszTime + 8) = TEXT('\0');
*(pszTime + 0) = (TCHAR)(nHours / 10 + TEXT('0'));
*(pszTime + 1) = (TCHAR)(nHours % 10 + TEXT('0'));
*(pszTime + 3) = (TCHAR)(nMinutes / 10 + TEXT('0'));
*(pszTime + 4) = (TCHAR)(nMinutes % 10 + TEXT('0'));
*(pszTime + 6) = (TCHAR)(nSeconds / 10 + TEXT('0'));
*(pszTime + 7) = (TCHAR)(nSeconds % 10 + TEXT('0'));
return pszTime;
}
//----- Testing the stuff -----
/*
struct Test
{
Test();
void foo();
void bar();
};
static Test t;
Test::Test()
{ MACRO_LI_Prolog(Test, Test)
MACRO_LI_SetFlags(MACRO_LI_GetFlags() | LIF_DUPLICATEINODS);
LI0("Calling foo and then bar");
foo();
LI0("foo returned");
bar();
LI0("bar returned");
}
void Test::foo()
{ MACRO_LI_Prolog(Test, foo);
LI0("Calling bar");
bar();
LI0("bar returned");
}
void Test::bar()
{ MACRO_LI_Prolog(Test, bar);
LI0("No arguments");
LI1("One argument: %d", 2*2);
LI2("Two arguments: %i, %s", 15, TEXT("nyah"));
LI3("Three arguments: %d, %s, %x", 5, TEXT("the bar it is"), 0x80FF);
}
*/