418 lines
10 KiB
C++
418 lines
10 KiB
C++
//=======================================================================
|
|
//
|
|
// Copyright (c) 1998-2000 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
// File: IULogger.h: interface for the CIULogger class.
|
|
//
|
|
// Description:
|
|
//
|
|
// CIULogger is a class that output the program logs to
|
|
// a text file, in order to help debugging the program.
|
|
//
|
|
// Programs wish to have this logging function should NOT use
|
|
// class directly. They should only use the macro defined
|
|
// at the end of this file.
|
|
//
|
|
//=======================================================================
|
|
|
|
|
|
|
|
#ifndef _IULOGGER_H_INCLUDED_
|
|
|
|
#include <wtypes.h>
|
|
#include <FreeLog.h>
|
|
|
|
extern const LPCTSTR pszHeapAllocFailed;
|
|
|
|
#if defined(DBG) // full logging for checked builds
|
|
|
|
//
|
|
// Common format strings
|
|
//
|
|
|
|
class CIULogger
|
|
{
|
|
public:
|
|
CIULogger(char* szBlockName);
|
|
~CIULogger();
|
|
|
|
|
|
//
|
|
// log with no flag, so can not be removed by excluding directives
|
|
//
|
|
void Log(LPCTSTR szLogFormat, ...);
|
|
|
|
//
|
|
// log error, can not be removed by excluding directives
|
|
// Key word "Error: " is inserted before the log msg
|
|
//
|
|
void LogError(LPCTSTR szLogFormat, ...);
|
|
|
|
//
|
|
// similar to LogError, but try to log the system msg based
|
|
// on the error code. If the sysmsg not avail, log
|
|
// "Unknown error with error code 0x%08x"
|
|
//
|
|
void LogErrorMsg(DWORD dwErrCode);
|
|
|
|
//
|
|
// similar to LogErrorMsg but prepends with "Info" rather than "Error"
|
|
//
|
|
void LogInfoMsg(DWORD dwErrCode);
|
|
|
|
//
|
|
// log with type INTERNET, this function will do nothing
|
|
// if the Internet exclusion directive is detected from reg
|
|
//
|
|
void LogInternet(LPCTSTR szLogFormat, ...);
|
|
|
|
//
|
|
// log with type XML, this function will do nothing
|
|
// if the XML exclusion directive is detected from reg
|
|
//
|
|
void LogXML(LPCTSTR szLogFormat, ...);
|
|
|
|
//
|
|
// log BSTR containing valid XML. This gets around length limitations
|
|
// of LogOutput and attempts to break lines following ">". This
|
|
// output is sent for both fre and chk builds unless excluded from reg.
|
|
//
|
|
void LogXmlBSTR(BSTR bstrXML);
|
|
|
|
//
|
|
// log with type SOFTWARE, this function will do nothing
|
|
// if the SOFTWARE exclusion directive is detected from reg
|
|
//
|
|
void LogSoftware(LPCTSTR szLogFormat, ...);
|
|
|
|
//
|
|
// log with type DRIVER, this function will do nothing
|
|
// if the DRIVER exclusion directive is detected from reg
|
|
//
|
|
void LogDriver(LPCTSTR szLogFormat, ...);
|
|
|
|
//
|
|
// log with type CHECKTRUST, this function will do nothing
|
|
// if the CHECKTRUST exclusion directive is detected from reg
|
|
//
|
|
void LogTrust(LPCTSTR szLogFormat, ...);
|
|
|
|
//
|
|
// log with type DOWNLOAD, this function will do nothing
|
|
// if the DOWNLOAD exclusion directive is detected from reg
|
|
//
|
|
void LogDownload(LPCTSTR szLogFormat, ...);
|
|
|
|
|
|
int m_LineNum;
|
|
private:
|
|
|
|
//
|
|
// Helper for LogErrorMsg and LogInfoMsg (which supply message to prepend)
|
|
//
|
|
void _LogFormattedMsg(DWORD dwErrCode, LPCTSTR pszErrorInfo);
|
|
|
|
//
|
|
// Overwrite <CR> and <LF> with space
|
|
//
|
|
void _NukeCrLf(LPTSTR pszBuffer);
|
|
|
|
//
|
|
// actual base logging function, returns
|
|
// if it actually logged, or just returned
|
|
// because directives say don't make this kind of log
|
|
//
|
|
void _Log(DWORD LogType, LPCTSTR pszLogFormat, va_list va);
|
|
|
|
//
|
|
// function to write the log to log file
|
|
//
|
|
void _LogOut(LPTSTR pszLog);
|
|
|
|
//
|
|
// functions go guard writing to file
|
|
//
|
|
BOOL AcquireMutex();
|
|
void ReleaseMutex();
|
|
|
|
//
|
|
// structure used to remember indent steps per thread
|
|
//
|
|
struct _THREAD_INDENT
|
|
{
|
|
DWORD dwThreadId;
|
|
int iIndent;
|
|
};
|
|
|
|
//
|
|
// static integer to remember the log indent steps
|
|
//
|
|
static _THREAD_INDENT* m_psIndent;
|
|
|
|
//
|
|
// size of array pointed by m_psIndent
|
|
//
|
|
static int m_Size;
|
|
|
|
//
|
|
// static handle for log file
|
|
//
|
|
static HANDLE m_shFile;
|
|
|
|
//
|
|
// bitmap for logging type
|
|
//
|
|
static DWORD m_sdwLogMask;
|
|
|
|
//
|
|
// indent per step
|
|
//
|
|
// 1~8 - number of spaces
|
|
// other - one tab
|
|
//
|
|
static int m_siIndentStep;
|
|
|
|
//
|
|
// function to retrieve the indent of current thread
|
|
//
|
|
inline int GetIndent(void);
|
|
|
|
//
|
|
// function to change indention of current thread
|
|
//
|
|
void SetIndent(int IndentDelta);
|
|
|
|
|
|
//
|
|
// index of indent array
|
|
//
|
|
int m_Index;
|
|
|
|
//
|
|
// controlling vars
|
|
//
|
|
static bool m_fLogUsable;
|
|
static bool m_fLogFile;
|
|
static bool m_fLogDebugMsg;
|
|
static HANDLE m_hMutex;
|
|
static int m_cFailedWaits;
|
|
|
|
//
|
|
// current block name
|
|
//
|
|
char m_szBlockName[MAX_PATH];
|
|
|
|
//
|
|
// if this log object is for whole process. If yes,
|
|
// no indention will be handled.
|
|
//
|
|
bool m_fProcessLog;
|
|
|
|
//
|
|
// var to remember time elapsed
|
|
//
|
|
DWORD m_dwTickBegin;
|
|
|
|
//
|
|
// disable the default constructor
|
|
//
|
|
CIULogger() {};
|
|
|
|
//
|
|
// timestamp helper
|
|
//
|
|
void GetLogHeader(LPTSTR pszBuffer, DWORD cchBufferLen);
|
|
|
|
//
|
|
// read registry value helper
|
|
//
|
|
void ReadRegistrySettings(void);
|
|
|
|
//
|
|
// remember thread id of itself
|
|
//
|
|
DWORD m_dwThreadId;
|
|
|
|
//
|
|
// flush every time?
|
|
// added by charlma 11/27/01
|
|
// if this flag is set, then flush everytime. otherwise, don't flush in order
|
|
// to improve logging performance.
|
|
//
|
|
static BOOL m_fFlushEveryTime;
|
|
};
|
|
|
|
|
|
|
|
//=======================================================================
|
|
//
|
|
// Define the macros that should be used in the programs to utilize
|
|
// the CIULogger class.
|
|
//
|
|
// Note: each of the following macro will practically doing nothing
|
|
// if the registry of supporting this logging feature does not exist
|
|
// or values not appropriately set.
|
|
//
|
|
//=======================================================================
|
|
|
|
|
|
//
|
|
// LOG_Process, is the one you can use in global namespace.
|
|
// The purpose of this macro is to pump up ref count of log file use so
|
|
// during the whole process this log file will keep open, therefore
|
|
// the actual logging to file feature will have minimum performance
|
|
// impact on your code.
|
|
//
|
|
// This macro is mainly designed for the scenario that you can't use LOG_Block
|
|
// inside main, such as DLL_ATTACH of DllMain() - without this, each
|
|
// function call to a DLL will cause the log file open/close.
|
|
//
|
|
#define LOG_Process CIULogger LogBlock(NULL);
|
|
|
|
//
|
|
// LOG_Block, is the one you should use at the beginning of each
|
|
// function or block. It declares an instance of CIULogger, log the
|
|
// the entering status, and when control goes out of the scope, the
|
|
// exit/end statement is automatically logged
|
|
//
|
|
#define LOG_Block(name) CIULogger LogBlock(name);
|
|
|
|
//
|
|
// the following macro will always send log to log file
|
|
//
|
|
#define LOG_Out LogBlock.Log
|
|
|
|
//
|
|
// the following macro will always send log to log file, even for Free builds
|
|
// This should be used very sparingly to avoid bloating the DLLs
|
|
//
|
|
#define LOG_OutFree LogBlock.Log
|
|
|
|
//
|
|
// the following macro will always send log to log file
|
|
// this should be used to log ANY error case
|
|
//
|
|
#define LOG_Error LogBlock.m_LineNum = __LINE__; LogBlock.LogError
|
|
|
|
//
|
|
// the follwoing macro will always send log to log file
|
|
// prepended with "Error Line..."
|
|
// the log is constructed based on passed in error code
|
|
// if system msg is not available for this error code,
|
|
// a generic error log "Unknown Error 0x%08x" is written.
|
|
//
|
|
#define LOG_ErrorMsg LogBlock.m_LineNum = __LINE__; LogBlock.LogErrorMsg
|
|
|
|
//
|
|
// the follwoing macro will always send log to log file
|
|
// prepended with "Info Line..."
|
|
// the log is constructed based on passed in error code
|
|
// if system msg is not available for this error code,
|
|
// a generic error log "Unknown Info 0x%08x" is written.
|
|
//
|
|
#define LOG_InfoMsg LogBlock.m_LineNum = __LINE__; LogBlock.LogInfoMsg
|
|
|
|
//
|
|
// this is used to log anything related to Internet, such as
|
|
// WinInet info.
|
|
//
|
|
#define LOG_Internet LogBlock.LogInternet
|
|
|
|
//
|
|
// this should be used to log anything directly related to XML
|
|
// operation details
|
|
//
|
|
#define LOG_XML LogBlock.LogXML
|
|
|
|
//
|
|
// this should be used to log BSTRs containing valid XML
|
|
//
|
|
#define LOG_XmlBSTR LogBlock.LogXmlBSTR
|
|
|
|
//
|
|
// this should be used to log anything related to device drivers
|
|
//
|
|
#define LOG_Driver LogBlock.LogDriver
|
|
|
|
//
|
|
// this should be used to log anything related to software, e.g.,
|
|
// detection/installation
|
|
//
|
|
#define LOG_Software LogBlock.LogSoftware
|
|
|
|
|
|
//
|
|
// this should be used to log anything related to check trust
|
|
//
|
|
#define LOG_Trust LogBlock.LogTrust
|
|
|
|
|
|
//
|
|
// this should be used to log anything related to download processing
|
|
//
|
|
#define LOG_Download LogBlock.LogDownload
|
|
|
|
//
|
|
//
|
|
//
|
|
#else
|
|
//
|
|
// Remove all debug style logging for release builds
|
|
// using the compiler __noop intrinsic
|
|
//
|
|
#define LOG_Process __noop
|
|
#define LOG_Block __noop
|
|
#define LOG_Error __noop
|
|
#define LOG_ErrorMsg __noop
|
|
#define LOG_InfoMsg __noop
|
|
#define LOG_OutFree __noop
|
|
#define LOG_XmlBSTR __noop
|
|
|
|
#define LOG_Out __noop
|
|
#define LOG_Internet __noop
|
|
#define LOG_XML __noop
|
|
#define LOG_Driver __noop
|
|
#define LOG_Software __noop
|
|
#define LOG_Trust __noop
|
|
#define LOG_Download __noop
|
|
#endif // defined(DBG)
|
|
|
|
//
|
|
// explanation of registry settings for log feature
|
|
//
|
|
// The registry settings control how the logging feature works.
|
|
//
|
|
// All log related settings are under key
|
|
// \\HKLM\Software\Microsoft\Windows\CurrentVersion\WindowsUpdate\IUControlLogging
|
|
//
|
|
// All values are DWORD except "Logging File"
|
|
//
|
|
// Value "Logging File" - specify the absolute file path, e.g., c:\iuctl.log
|
|
// the actual log file name in this case is "c:\iuctl_xxxx.log",
|
|
// where xxxx is a decimal number represents process id.
|
|
//
|
|
// Value "Logging DebugMsg" - indicate if log should be put onto debug window.
|
|
// true if vlaue is 1, false for other values. this output and log file
|
|
// output control by these 2 values independently.
|
|
//
|
|
// Value "LogIndentStep" - indicates how many space chars to use for each
|
|
// indent. If 0 or negative value, then tab char is used.
|
|
//
|
|
// Value "LogExcludeBlock" - do not output block enter/exit if it's 1
|
|
//
|
|
// Value "LogExcludeXML" - do not output logs you logged with LOG_XML if it's 1
|
|
//
|
|
// Value "LogExcludeXmlBSTR" - do not output logs you logged with LOG_XmlBSTR if 1
|
|
//
|
|
// Value "LogExcludeInternet" - do not output logs you logged with LOG_Internet if 1
|
|
//
|
|
// Value "LogExcludeDriver" - do not output logs you logged with LOG_Driver if 1
|
|
//
|
|
// Value "LogExcludeSoftware - do not output logs you logged with LOG_Software if 1
|
|
//
|
|
// Value "LogExcludeTrust" - do not output logs you logged with LOG_Trust if 1
|
|
//
|
|
|
|
#define _IULOGGER_H_INCLUDED_
|
|
#endif // #ifndef _IULOGGER_H_INCLUDED_
|