Figure 1: A hook function to do error reporting within a Windows NT service

int __cdecl 
ReporterFunction(int reportType,
   char *message, int *returnValue)
{
   cerr << endl;
   cerr << timestamp << "===========" 
        << endl;
   cerr << timestamp << "Report Type: ";
   switch(reportType)
   {
      case _CRT_WARN  :
         cerr << "Warning";
         break;
      case _CRT_ERROR :
         cerr << "Error";
         break;
      case _CRT_ASSERT:
         cerr << "Assertion";
         break;
      case _CRT_ERRCNT:
         cerr << "Error Cnt";
         break;
      default:
         cerr << "Unknown";
   }
   cerr << endl;
   cerr << timestamp << message;
   cerr << timestamp << "===========" 
        << endl;
   *returnValue = 1; //To break into the 
                     //debugger
   // if we are in a debugging session
   // (our old friend asm int -3)
   return TRUE;
}

BOOL CMyApp::InitInstance()
{
   m_pOldcout = &cout;
   m_pOldcerr = &cerr;
   m_pOldclog = &clog;
   _CrtSetReportHook(ReporterFunction);
//This sets up a hook that
//traps any unwanted system message boxes!

//Do this only if we have file logging 
//turned on
   if(bLoggingOn == TRUE)
   {
      //Create a log file to store 
      //information
      CString sLogPath;
      GetTempPath(_MAX_PATH, 
         sLogPath.GetBuffer(_MAX_PATH + 
            1));
         sLogPath.ReleaseBuffer();
         sLogPath += "TacRemedyLib.log";

      //Check if the file should be 
      //truncated (i.e. contents discarded)
      //or appended
      DWORD nMaxLogFileSize;
      rexSetup.get_MaxLogFileSize
         (&nMaxLogFileSize);

      CFile file;

      if(file.Open(sLogPath,
            CFile::modeRead | 
            CFile::shareExclusive) != 0 
         && file.GetLength() > 
            nMaxLogFileSize)
         //the limit has been reached
         {
            file.Close();
            applog.open(sLogPath,
               ios_base::out | 
               ios_base::trunc);
         }
         else
         {
            applog.open(sLogPath,
               ios_base::out | 
               ios_base::app);
         }

         cout = applog;
         clog = applog;
         cerr = applog;
         cout << endl 
              << "------------------" 
              << endl;
         cout << timestamp
              << ": CMyApp::InitInstance()" 
              << endl;
   }
   return CWinApp::InitInstance();
}

int CMyApp::ExitInstance()
{
   cout << timestamp 
        << ": CMyApp::ExitInstance()" 
        << endl;

// Be nice and put things back the way
// you found them, or else, if this is a 
// DLL the app will crash when it tries to 
// write something to cout!
   _CrtSetReportHook(NULL);
   cout = *m_pOldcout;
   cerr = *m_pOldcerr;
   clog = *m_pOldclog;

   return CWinApp::ExitInstance();
}