|
|
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
Debug.h
Abstract:
Interface for the CDebug class.
Author:
Eran Yariv (EranY) Jul, 1999
Revision History:
--*/
#if !defined(AFX_DEBUG_H__DDEC9CAD_CF2D_4F3F_9538_2F6041A022B6__INCLUDED_)
#define AFX_DEBUG_H__DDEC9CAD_CF2D_4F3F_9538_2F6041A022B6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#if !defined(DEBUG)
#if defined(_DEBUG)
#define DEBUG
#elif defined(DBG)
#define DEBUG
#endif
#endif
//
// Remove previous declarations:
//
#if defined(ASSERTION)
#undef ASSERTION
#endif
#ifdef VERBOSE
#undef VERBOSE
#endif
#ifdef ASSERTION_FAILURE
#undef ASSERTION_FAILURE
#endif
#include <FaxDebug.h>
//
// Bit-mask of errors / messages :
//
typedef enum { DBG_MSG = 0x00000001, // General messages (not warnings or errors)
DBG_WARNING = 0x00000002, // Warnings
GENERAL_ERR = 0x00000004, TAPI_MSG = 0x00000008, ASSERTION_FAILED = 0x00000010, // Debug messages are displayed when an assertion fails
FUNC_TRACE = 0x00000020, // Function entry / exit traces
MEM_ERR = 0x00000040, // Errors start from here...
COM_ERR = 0x00000080, RESOURCE_ERR = 0x00000100, EXCEPTION_ERR = 0x00000200, RPC_ERR = 0x00000400, WINDOW_ERR = 0x00000800, FILE_ERR = 0x00001000, SECURITY_ERR = 0x00002000, REGISTRY_ERR = 0x00004000, PRINT_ERR = 0x00008000, SETUP_ERR = 0x00010000, NET_ERR = 0x00020000, SCM_ERR = 0x00040000, STARTUP_ERR = 0x00080000, DBG_ERRORS_ONLY = 0xFFFFFFDC, // everything but DBG_MSG,FUNC_TRACE,DBG_WARNING
DBG_ERRORS_WARNINGS = 0xFFFFFFDE, // everything but DBG_MSG,FUNC_TRACE
DBG_ALL = 0xFFFFFFFF } DbgMsgType;
#ifdef ENABLE_FRE_LOGGING
#define ENABLE_LOGGING
#endif
#ifdef DEBUG
#define ENABLE_LOGGING
#endif
#ifdef ENABLE_LOGGING
#define DEFAULT_DEBUG_MASK ASSERTION_FAILED
#define DEFAULT_FORMAT_MASK DBG_PRNT_ALL_TO_STD
// use these in your debugging sessions
#define DBG_ENTER CDebug debugObject
#define VERBOSE debugObject.Trace
#ifndef DEBUG
#define DebugBreak() ;
#endif
#define ASSERTION_FAILURE { \
debugObject.DbgPrint (ASSERTION_FAILED, \ TEXT(__FILE__), \ __LINE__, \ TEXT("ASSERTION FAILURE!!!")); \ DebugBreak(); \ }
#define ASSERTION(x) if (!(x)) ASSERTION_FAILURE
#define CALL_FAIL(t,szFunc,hr) \
debugObject.DbgPrint(t, \ TEXT(__FILE__), \ __LINE__, \ TEXT("Call to function %s failed with 0x%08X"), \ szFunc, \ hr); //////////////////////////////////////////
// use these to cofigure the debug output
#define SET_DEBUG_MASK(m) CDebug::SetDebugMask(m)
#define SET_FORMAT_MASK(m) CDebug::SetFormatMask(m)
#define SET_DEBUG_FLUSH(m) CDebug::SetDebugFlush(m)
#define GET_DEBUG_MASK CDebug::GetDebugMask()
#define GET_FORMAT_MASK CDebug::GetFormatMask()
#define MODIFY_DEBUG_MASK(a,b) CDebug::ModifyDebugMask(a,b)
#define MODIFY_FORMAT_MASK(a,b) CDebug::ModifyFormatMask(a,b)
#define IS_DEBUG_SESSION_FROM_REG CDebug::DebugFromRegistry()
#define OPEN_DEBUG_LOG_FILE(f) CDebug::OpenLogFile(f)
#define CLOSE_DEBUG_LOG_FILE CDebug::CloseLogFile()
#define SET_DEBUG_FILE_HANDLE(h) CDebug::SetLogFile(h)
//////////////////////////////////////////
#ifndef _DEBUG_INDENT_SIZE
#define _DEBUG_INDENT_SIZE 3
#endif // #ifndef _DEBUG_INDENT_SIZE
class CDebug { public:
CDebug (LPCTSTR lpctstrModule) : m_ReturnType (DBG_FUNC_RET_UNKNOWN) { EnterModule (lpctstrModule); }
CDebug (LPCTSTR lpctstrModule, LPCTSTR lpctstrFormat, ...) : m_ReturnType (DBG_FUNC_RET_UNKNOWN) { va_list arg_ptr; va_start(arg_ptr, lpctstrFormat); EnterModuleWithParams (lpctstrModule, lpctstrFormat, arg_ptr); }
CDebug (LPCTSTR lpctstrModule, HRESULT &hr) { EnterModule (lpctstrModule); SetHR (hr); }
CDebug (LPCTSTR lpctstrModule, HRESULT &hr, LPCTSTR lpctstrFormat, ...) { va_list arg_ptr; va_start(arg_ptr, lpctstrFormat); EnterModuleWithParams (lpctstrModule, lpctstrFormat, arg_ptr); SetHR (hr); }
CDebug (LPCTSTR lpctstrModule, DWORD &dw) { EnterModule (lpctstrModule); SetDWRes (dw); }
CDebug (LPCTSTR lpctstrModule, UINT &dw) { EnterModule (lpctstrModule); SetDWRes ((DWORD &)dw); }
CDebug (LPCTSTR lpctstrModule, DWORD &dw, LPCTSTR lpctstrFormat, ...) { va_list arg_ptr; va_start(arg_ptr, lpctstrFormat); EnterModuleWithParams (lpctstrModule, lpctstrFormat, arg_ptr); SetDWRes (dw); }
CDebug (LPCTSTR lpctstrModule, UINT &dw, LPCTSTR lpctstrFormat, ...) { va_list arg_ptr; va_start(arg_ptr, lpctstrFormat); EnterModuleWithParams (lpctstrModule, lpctstrFormat, arg_ptr); SetDWRes ((DWORD &)dw); }
CDebug (LPCTSTR lpctstrModule, BOOL &b) { EnterModule (lpctstrModule); SetBOOL (b); }
CDebug (LPCTSTR lpctstrModule, BOOL &b, LPCTSTR lpctstrFormat, ...) { va_list arg_ptr; va_start(arg_ptr, lpctstrFormat); EnterModuleWithParams (lpctstrModule, lpctstrFormat, arg_ptr); SetBOOL (b); }
virtual ~CDebug();
static void DbgPrint ( DbgMsgType type, LPCTSTR lpctstrFileName, DWORD dwLine, LPCTSTR lpctstrFormat, ... );
void Trace ( DbgMsgType type, LPCTSTR lpctstrFormat, ... );
static void ResetIndent() { InterlockedExchange(&m_sdwIndent,0); } static void Indent() { InterlockedIncrement(&m_sdwIndent); } static void Unindent();
// calling any of those functions overrides the registry entries
// SetDebugMask - overrides the DebugLevelEx entry
// SetFormatMask - overrides the DebugFormatEx entry
static void SetDebugMask(DWORD dwMask); static void SetFormatMask(DWORD dwMask);
static DWORD GetDebugMask() { return m_sDbgMask; } static DWORD GetFormatMask() { return m_sFmtMask; }
static DWORD ModifyDebugMask(DWORD dwAdd,DWORD dwRemove); static DWORD ModifyFormatMask(DWORD dwAdd,DWORD dwRemove); static void SetDebugFlush(BOOL fFlush);
static HANDLE SetLogFile(HANDLE hFile); static BOOL OpenLogFile(LPCTSTR lpctstrFilename); static void CloseLogFile();
// returns whether we find debug setting in the registry
// call this before using SetDebugMask or SetFormatMask to verify
// if the registry is being used, so registry will decide on
// debug level
static BOOL DebugFromRegistry();
private:
static void Print ( DbgMsgType type, LPCTSTR lpctstrFileName, DWORD dwLine, LPCTSTR lpctstrFormat, va_list arg_ptr );
void EnterModuleWithParams (LPCTSTR lpctstrModule, LPCTSTR lpctstrFormat, va_list arg_ptr);
void EnterModule (LPCTSTR lpctstrModule);
void SetHR (HRESULT &hr) { m_ReturnType = DBG_FUNC_RET_HR; m_phr = &hr; } void SetDWRes (DWORD &dw) { m_ReturnType = DBG_FUNC_RET_DWORD; m_pDword = &dw; } void SetBOOL (BOOL &b) { m_ReturnType = DBG_FUNC_RET_BOOL; m_pBool = &b; }
static LONG m_sdwIndent; static DWORD m_sDbgMask; // a combination of DbgMsgType values
static DWORD m_sFmtMask; // a combination of DbgMsgFormat values
static HANDLE m_shLogFile; static BOOL m_sbMaskReadFromReg; // Did we already read the debug & format mask from the registry?
static BOOL m_sbRegistryExist; // Do we use debug mask of registry?
static BOOL m_sbFlush; // Do we run FlushFileBuffer after writing to log file
static BOOL ReadMaskFromReg(); // Attempt to read debug & format mask from registry.
static LPCTSTR GetMsgTypeString(DWORD dwMask); static BOOL OutputFileString(LPCTSTR szMsg);
TCHAR m_tszModuleName[MAX_PATH];
typedef enum { DBG_FUNC_RET_UNKNOWN, DBG_FUNC_RET_HR, DBG_FUNC_RET_DWORD, DBG_FUNC_RET_BOOL } DbgFuncRetType;
DbgFuncRetType m_ReturnType; HRESULT *m_phr; DWORD *m_pDword; BOOL *m_pBool;
};
#define START_RPC_TIME(f) DWORD dwRPCTimeCheck=GetTickCount();
#define END_RPC_TIME(f) VERBOSE (DBG_MSG, TEXT("%s took %ld millisecs"), \
f, GetTickCount()-dwRPCTimeCheck);
#else // ENABLE_LOGGING
#define DBG_ENTER void(0);
#define VERBOSE void(0);
#define ASSERTION_FAILURE void(0);
#define ASSERTION(x) void(0);
#define CALL_FAIL(t,szFunc,hr) void(0);
#define START_RPC_TIME(f) void(0);
#define END_RPC_TIME(f) void(0);
#define SET_DEBUG_MASK(m) void(0);
#define SET_FORMAT_MASK(m) void(0);
#define GET_DEBUG_MASK 0;
#define GET_FORMAT_MASK 0;
#define MODIFY_DEBUG_MASK(a,b) 0;
#define MODIFY_FORMAT_MASK(a,b) 0;
#define IS_DEBUG_SESSION_FROM_REG FALSE;
#define OPEN_DEBUG_LOG_FILE(f) FALSE;
#define CLOSE_DEBUG_LOG_FILE void(0);
#define SET_DEBUG_FILE_HANDLE(h) void(0);
#endif // ENABLE_LOGGING
#endif // !defined(AFX_DEBUG_H__DDEC9CAD_CF2D_4F3F_9538_2F6041A022B6__INCLUDED_)
|