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); }
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; }