//======================================================================= // // 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 #include 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 and 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_