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.
 
 
 
 
 
 

370 lines
14 KiB

#ifndef _LOGITEM_H_
#define _LOGITEM_H_
// determine the number of elements in array (not bytes)
#ifndef countof
#define countof(array) (sizeof(array)/sizeof(array[0]))
#endif
#define LIF_NONE 0x80000000
#define LIF_DATE 0x00000001
#define LIF_TIME 0x00000002
#define LIF_DATETIME 0x00000003
#define LIF_MODULE 0x00000004
#define LIF_MODULEPATH 0x00000008
#define LIF_MODULE_ALL 0x0000000C
#define LIF_FILE 0x00000010
#define LIF_FILEPATH 0x00000020
#define LIF_FILE_ALL 0x00000030
#define LIF_CLASS 0x00000040
#define LIF_FUNCTION 0x00000080
#define LIF_LINE 0x00000100
#define LIF_DUPLICATEINODS 0x00000200
#define LIF_APPENDCRLF 0x00000400
#define LIF_DEFAULT 0x000005D0
// private for context switch from C to C++ and back again
#define LIF_CLASS2 0x01000000
/////////////////////////////////////////////////////////////////////////////
// Initialization
class CLogItem; // forward declaration
extern CLogItem g_li;
#define MACRO_LI_Initialize() \
CLogItem g_li \
#define MACRO_LI_Initialize2(dwFlags) \
CLogItem g_li(dwFlags) \
#define MACRO_LI_InitializeEx(dwFlags, pfLevels, cLevels) \
CLogItem g_li(dwFlags, pfLevels, cLevels) \
/////////////////////////////////////////////////////////////////////////////
// Helpers for individual CLogItem attributes
// file
#define MACRO_LI_SmartFile() \
CSmartItem<LPCTSTR> siFile(g_li.m_szFile, TEXT(__FILE__)) \
#define MACRO_LI_SmartFileEx(dwItems) \
CSmartItemEx<LPCTSTR> siFileEx(dwItems, LIF_FILE_ALL, \
g_li.m_szFile, TEXT(__FILE__)) \
// class
#define MACRO_LI_SmartClass(Class) \
CSmartItem<LPCTSTR> siClass(g_li.m_szClass, TEXT(#Class)) \
#define MACRO_LI_SmartClassEx(dwItems, Class) \
CSmartItemEx<LPCTSTR> siClassEx(dwItems, LIF_CLASS, \
g_li.m_szClass, TEXT(#Class)) \
// function
#define MACRO_LI_SmartFunction(Function) \
CSmartItem<LPCTSTR> siFunction(g_li.m_szFunction, TEXT(#Function)) \
#define MACRO_LI_SmartFunctionEx(dwItems, Function) \
CSmartItemEx<LPCTSTR> siFunctionEx(dwItems, LIF_FUNCTION, \
g_li.m_szFunction, TEXT(#Function)) \
// level, indent and flags
#define MACRO_LI_SmartLevel() \
CSmartItem<UINT> siLevel(g_li.m_nLevel, g_li.m_nLevel+1) \
#define MACRO_LI_SmartIndent() \
CSmartItem<UINT> siIndent(g_li.m_nAbsOffset, g_li.m_nAbsOffset+1) \
#define MACRO_LI_SmartFlags(dwFlags) \
CSmartItem<DWORD> siFlags(g_li.m_dwFlags, dwFlags) \
// wrappers to manipulate flags, offset and relative offset
#define MACRO_LI_SmartAddFlags(dwFlag) \
CSmartItem<DWORD> siAddFlags(g_li.m_dwFlags, g_li.m_dwFlags | (dwFlag))\
#define MACRO_LI_SmartRemoveFlags(dwFlag) \
CSmartItem<DWORD> siRemFlags(g_li.m_dwFlags, g_li.m_dwFlags & ~(dwFlag))\
#define MACRO_LI_Offset(iOffset) \
CSmartItem<int> siOffset(g_li.m_iRelOffset, g_li.m_iRelOffset + iOffset)\
#define MACRO_LI_SmartRelativeOffset(iRelOffset) \
CSmartItem<int> siRelOffset(g_li.m_iRelOffset, iRelOffset) \
// private for context switch from C to C++ and back again
#define MACRO_LI_AddClass2() \
CSmartItem<DWORD> siAddClass2(g_li.m_dwFlags, \
g_li.m_dwFlags | (LIF_CLASS2)) \
#define MACRO_LI_RemClass2() \
CSmartItem<DWORD> siRemClass2(g_li.m_dwFlags, \
g_li.m_dwFlags & ~(LIF_CLASS2)) \
/////////////////////////////////////////////////////////////////////////////
// Prologs
// rarely used standalone, is the foundation for the rest
#define MACRO_LI_PrologSameFunction() \
MACRO_LI_SmartIndent(); \
MACRO_LI_SmartLevel(); \
//----- More macros, a little more lean -------------------------------------
// for protected or private functions in the same file as caller
#define MACRO_LI_PrologSameClass(Function) \
MACRO_LI_SmartFunction(Function); \
MACRO_LI_PrologSameFunction(); \
// for protected or private functions in a different file than caller
#define MACRO_LI_PrologSameClass2(Function) \
MACRO_LI_SmartFile(); \
MACRO_LI_SmartFunction(Function); \
MACRO_LI_PrologSameFunction(); \
// for C APIs across files
#define MACRO_LI_PrologC(Function) \
MACRO_LI_RemClass2(); \
\
MACRO_LI_SmartFile(); \
MACRO_LI_SmartFunction(Function); \
MACRO_LI_PrologSameFunction(); \
// for C APIs with no prototype in the (respective) *.h file
#define MACRO_LI_PrologSameFileC(Function) \
MACRO_LI_RemClass2(); \
\
MACRO_LI_SmartFunction(Function); \
MACRO_LI_PrologSameFunction(); \
// for things like friends (two friend classes in one file and methods
// of one class are calling private or protected methods of the other, so
// these private or protected methods can have this prolog)
#define MACRO_LI_PrologSameFile(Class, Function) \
MACRO_LI_AddClass2(); \
\
MACRO_LI_SmartClass(Class); \
MACRO_LI_PrologSameClass(Function); \
// general version, common case
#define MACRO_LI_Prolog(Class, Function) \
MACRO_LI_SmartFile(); \
MACRO_LI_PrologSameFile(Class, Function); \
//----- Less macros, a little more overhead ---------------------------------
#define PIF_SAMEFUNC 0x00000000
#define PIF_SAMECLASS 0x00000080
#define PIF_SAMECLASS2 0x000000B0
#define PIF_STD_C 0x00000090
#define PIF_SAMEFILE_C 0x000000B0
#define PIF_SAMEFILE 0x000000C0
#define PIF_STD 0x000000F0
#define MACRO_LI_PrologEx(dwItems, Class, Function) \
MACRO_LI_AddClass2(); \
\
MACRO_LI_SmartFileEx(dwItems); \
MACRO_LI_SmartClassEx(dwItems, Class); \
MACRO_LI_SmartFunctionEx(dwItems, Function); \
MACRO_LI_PrologSameFunction(); \
#define MACRO_LI_PrologSameClassEx(dwItems, Function) \
MACRO_LI_AddClass2(); \
\
MACRO_LI_SmartFileEx(dwItems); \
MACRO_LI_SmartFunctionEx(dwItems, Function); \
MACRO_LI_PrologSameFunction(); \
#define MACRO_LI_PrologEx_C(dwItems, Function) \
MACRO_LI_RemClass2(); \
\
MACRO_LI_SmartFileEx(dwItems); \
MACRO_LI_SmartFunctionEx(dwItems, Function); \
MACRO_LI_PrologSameFunction(); \
/////////////////////////////////////////////////////////////////////////////
// Logging
#define LI0(pszFormat) \
g_li.Log(__LINE__, pszFormat) \
#define LI1(pszFormat, arg1) \
g_li.Log(__LINE__, pszFormat, arg1) \
#define LI2(pszFormat, arg1, arg2) \
g_li.Log(__LINE__, pszFormat, arg1, arg2) \
#define LI3(pszFormat, arg1, arg2, arg3) \
g_li.Log(__LINE__, pszFormat, arg1, arg2, arg3) \
/////////////////////////////////////////////////////////////////////////////
// Additional helpers
#define MACRO_LI_GetFlags() \
g_li.GetFlags() \
#define MACRO_LI_SetFlags(dwFlags) \
g_li.SetFlags(dwFlags) \
#define MACRO_LI_GetRelativeOffset() \
(const int&)g_li.m_iRelOffset \
#define MACRO_LI_SetRelativeOffset(iRelOffset) \
g_li.m_iRelOffset = iRelOffset \
/////////////////////////////////////////////////////////////////////////////
// CLogItem declaration
class CLogItem
{
// Constructors
public:
CLogItem(DWORD dwFlags = LIF_DEFAULT, LPBOOL pfLogLevels = NULL, UINT cLogLevels = 0);
// Attributes
public:
TCHAR m_szMessage[3 * MAX_PATH];
// offset management
UINT m_nAbsOffset;
int m_iRelOffset;
static BYTE m_bStep;
// module, path, file, class, function, line of code
LPCTSTR m_szFile;
LPCTSTR m_szClass;
LPCTSTR m_szFunction;
UINT m_nLine;
// customization
DWORD m_dwFlags;
UINT m_nLevel;
// Operations
public:
void SetFlags(DWORD dwFlags)
{ m_dwFlags = dwFlags; }
DWORD GetFlags() const
{ return m_dwFlags; }
virtual LPCTSTR WINAPIV Log(int iLine, LPCTSTR pszFormat ...);
// Overridables
public:
virtual operator LPCTSTR() const;
// Implementation
public:
virtual ~CLogItem();
protected:
// implementation data helpers
static TCHAR m_szModule[MAX_PATH];
PBOOL m_rgfLogLevels;
UINT m_cLogLevels;
// implementation helper routines
LPCTSTR makeRawFileName(LPCTSTR pszPath, LPTSTR pszFile, UINT cchFile);
BOOL setFlag(DWORD dwMask, BOOL fSet = TRUE);
BOOL hasFlag(DWORD dwMask) const
{ return hasFlag(m_dwFlags, dwMask); }
static BOOL hasFlag(DWORD dwFlags, DWORD dwMask)
{ return ((dwFlags & dwMask) != 0L); }
};
// Note. (andrewgu) Right now there seems to be no need to create a special
// CSmartItem<TCHAR> and CSmartItemEx<TCHAR> classes that would
// store internally the string passed into it. Also, the parameter
// isn't necessary TCHAR it's just a placeholder for an idea.
/////////////////////////////////////////////////////////////////////////////
// CSmartItem definition
template <class T> class CSmartItem
{
public:
CSmartItem(T& tOld, const T& tNew)
{
m_pitem = NULL;
if (tOld == tNew)
return;
m_item = tOld; m_pitem = &tOld; tOld = tNew;
}
~CSmartItem()
{
if (m_pitem == NULL)
return;
*m_pitem = m_item; m_pitem = NULL;
}
// Attributes
T *m_pitem,
m_item;
protected:
// disable the copy constructor and assignment operator
CSmartItem(const CSmartItem&)
{}
const CSmartItem& operator=(const CSmartItem&)
{ return *this; }
};
/////////////////////////////////////////////////////////////////////////////
// CSmartItemEx definition
template <class T> class CSmartItemEx
{
public:
CSmartItemEx(DWORD dwAllItems, DWORD dwThisItem, T& tOld, const T& tNew)
{
m_pitem = NULL;
m_fNoSwap = ((dwAllItems & dwThisItem) == 0);
if (m_fNoSwap)
return;
if (tOld == tNew)
return;
m_item = tOld; m_pitem = &tOld; tOld = tNew;
}
~CSmartItemEx()
{
if (m_fNoSwap)
return;
if (m_pitem == NULL)
return;
*m_pitem = m_item; m_pitem = NULL;
}
// Attributes
T *m_pitem,
m_item;
protected:
// disable the copy constructor and assignment operator
CSmartItemEx(const CSmartItem<T>&)
{}
const CSmartItemEx<T>& operator=(const CSmartItemEx<T>&)
{ return *this; }
// implementation data helpers
BOOL m_fNoSwap;
};
#endif