예제 #1
0
void CCrashHandler::GenerateErrorReport(PEXCEPTION_POINTERS pExInfo)
{
   CExceptionReport  rpt(pExInfo);
   CMainDlg          mainDlg;
   CZLib             zlib;
   CString           sTempFileName = CUtility::getTempFileName();
   unsigned int      i;

   // let client add application specific files to report
   if (m_lpfnCallback && !m_lpfnCallback(this))
      return;

	//Определеяем, что делать с отчетом
	DumpType dumpType = Referenced;//По умолчанию сбрасываем только ту память, на которую идут ссылки в стеке
	ActionType actionType = GUI;//По умолчанию - выводим пользователю диалог
	CString action, storeFolder, dump;

	ATL::CRegKey rk;
	//Читаем из ключа с именем приложения
	int32_t lRet = rk.Open(HKEY_LOCAL_MACHINE,
	   TEXT("SOFTWARE\\Cognitive Technologies Ltd.\\CuneiForm\\PumaCrashRpt\\")
	   + CUtility::getAppName(), KEY_QUERY_VALUE);
	if(lRet != ERROR_SUCCESS)
	{
		//Читаем из дефолтного ключа
		lRet = rk.Open(HKEY_LOCAL_MACHINE,
			TEXT("SOFTWARE\\Cognitive Technologies Ltd.\\CuneiForm\\PumaCrashRpt\\Default"),
			KEY_QUERY_VALUE);
	}
	if(lRet == ERROR_SUCCESS)
	{
		//Читаем дейтсвие
		uint32_t dwBufLen = 1000;
		rk.QueryValue(action.GetBuffer(1000), "Action", &dwBufLen);
	    action.ReleaseBuffer(MAX(dwBufLen - 1, 0));

		//Читаем папку для автосохранения
		dwBufLen = 1000;
		rk.QueryValue(storeFolder.GetBuffer(1000), "StoreFolder", &dwBufLen);
	    storeFolder.ReleaseBuffer(MAX(dwBufLen - 1, 0));

		//Читаем тип дампа
		dwBufLen = 1000;
		rk.QueryValue(dump.GetBuffer(1000), "DumpType", &dwBufLen);
	    dump.ReleaseBuffer(MAX(dwBufLen - 1, 0));

		rk.Close();

		if (!action.IsEmpty())
		{
			if (action.CompareNoCase("GUI") == 0)
				actionType = GUI;
			else if (action.CompareNoCase("QuietStore") == 0)
				actionType = QuietStore;
			else if (action.CompareNoCase("NoAction") == 0)
				actionType = NoAction;

		}
		if (!dump.IsEmpty())
		{
			if (dump.CompareNoCase("Mini") == 0)
				dumpType = Mini;
			else if (dump.CompareNoCase("Referenced") == 0)
				dumpType = Referenced;
			else if (dump.CompareNoCase("Full") == 0)
				dumpType = Full;

		}
		if (storeFolder.CompareNoCase("Temp folder") == 0)
			storeFolder = getenv("TEMP");
	}

	if (actionType == NoAction)
		return;

   // add crash files to report
   m_files[rpt.getCrashFile(dumpType)] = CString((const char *)IDS_CRASH_DUMP);
   m_files[rpt.getCrashLog()] = CString((const char *)IDS_CRASH_LOG);

   // add symbol files to report
   for (i = 0; i < (uint)rpt.getNumSymbolFiles(); i++)
      m_files[(const char *)rpt.getSymbolFile(i)] =
      CString((const char *)IDS_SYMBOL_FILE);

   // zip the report
   if (!zlib.Open(sTempFileName))
      return;

   // add report files to zip
   TStrStrMap::iterator cur = m_files.begin();
   for (i = 0; i < m_files.size(); i++, cur++)
      zlib.AddFile((*cur).first);

   zlib.Close();

   if (actionType == GUI)
   {
	   // display main dialog
	   mainDlg.m_pUDFiles = &m_files;

	   //Сохраняем флаги по исключениям с плавающей точкой - кто-то их злобно сбрасывает при показе диалога
	   uint oldFpState = _controlfp(0, 0);
	   if (IDOK == mainDlg.DoModal())
	   {
	      if (m_sTo.IsEmpty() ||
		      !MailReport(rpt, sTempFileName, mainDlg.m_sEmail, mainDlg.m_sDescription))
		  {
			 SaveReport(rpt, sTempFileName);
		  }
	   }
	   //Восстанавливаем флаги
	   _controlfp(oldFpState, _MCW_DN | _MCW_EM | _MCW_IC | _MCW_RC | _MCW_PC);
   }
   else if (actionType == QuietStore)
   {
		// Just in-case it already exist
		::DeleteFile(storeFolder + '\\' + CUtility::formatSaveFileName() + ".zip");
		::CopyFile(sTempFileName, storeFolder + '\\' + CUtility::formatSaveFileName() + ".zip", TRUE);
   }
   DeleteFile(sTempFileName);
}
예제 #2
0
int CCrashHandler::GenerateErrorReport(
  PCR_EXCEPTION_INFO pExceptionInfo)
{  
  crSetErrorMsg(_T("Unspecified error."));

  // Validate input parameters 
  if(pExceptionInfo==NULL)
  {
    crSetErrorMsg(_T("Exception info is NULL."));
    return 1;
  }

  // Get exception pointers if not provided. 
  if(pExceptionInfo->pexcptrs==NULL)
  {
    GetExceptionPointers(pExceptionInfo->code, &pExceptionInfo->pexcptrs);
  }

  // Collect miscellaneous crash info (current time etc.) 
  CollectMiscCrashInfo();

  // If error report is being generated manually, disable app restart.
  if(pExceptionInfo->bManual)
    m_bAppRestart = FALSE;

  // Let client add application-specific files / desktop screenshot 
  // to the report via the crash callback function. 

  if (m_lpfnCallback!=NULL && m_lpfnCallback(NULL)==FALSE)
  {
    crSetErrorMsg(_T("The operation was cancelled by client application."));
    return 2;
  }

  if(m_bAddScreenshot)
  {
    m_rcAppWnd.SetRectEmpty();
    // Find main app window
    HWND hWndMain = Utility::FindAppWindow();
    if(hWndMain)
    {
      GetWindowRect(hWndMain, &m_rcAppWnd);
    }
  }

  // Create directory for the error report. 
  
  BOOL bCreateDir = Utility::CreateFolder(m_sReportFolderName);
  if(!bCreateDir)
  {    
    ATLASSERT(bCreateDir);
    CString szCaption;
    szCaption.Format(_T("%s has stopped working"), Utility::getAppName());
    CString szMessage;
    // Try notify user about crash using message box.
    szMessage.Format(_T("Couldn't save error report."));
    MessageBox(NULL, szMessage, szCaption, MB_OK|MB_ICONERROR);    
    return 1; // Failed to create directory
  }
    
  // Create crash description file in XML format. 
  CString sFileName;
  sFileName.Format(_T("%s\\crashrpt.xml"), m_sReportFolderName);
  AddFile(sFileName, NULL, _T("Crash Log"), CR_AF_MISSING_FILE_OK);        
  int result = CreateCrashDescriptionXML(sFileName.GetBuffer(0), pExceptionInfo);
  ATLASSERT(result==0);
  
  // Write internal crash info to file. This info is required by 
  // CrashSender.exe only and will not be sent anywhere. 
  
  sFileName = m_sReportFolderName + _T("\\~CrashRptInternal.xml");
  result = CreateInternalCrashInfoFile(sFileName, pExceptionInfo->pexcptrs);
  ATLASSERT(result==0);
  SetFileAttributes(sFileName, FILE_ATTRIBUTE_HIDDEN);

  // Start the CrashSender process which will take the dekstop screenshot, 
  // copy user-specified files to the error report folder, create minidump, 
  // notify user about crash, compress the report into ZIP archive and send 
  // the error report. 
    
  result = LaunchCrashSender(sFileName, TRUE);
  if(result!=0)
  {
    ATLASSERT(result==0);
    crSetErrorMsg(_T("Error launching CrashSender.exe"));
    
    // Failed to launch crash sender process.
    // Try notify user about crash using message box.
    CString szCaption;
    szCaption.Format(_T("%s has stopped working"), Utility::getAppName());
    CString szMessage;
    szMessage.Format(_T("Error launching CrashSender.exe"));
    MessageBox(NULL, szMessage, szCaption, MB_OK|MB_ICONERROR);    
    return 3;
  }
  
  // OK
  crSetErrorMsg(_T("Success."));
  return 0; 
}
ULONG CExMapiSink::OnNotify(ULONG cNotification,LPNOTIFICATION lpNotifications)
{
	if(m_lpfnCallback) m_lpfnCallback(m_lpvContext,cNotification,lpNotifications);
	return 0;
}