// A helper function that creates a error report for testing BOOL TestUtils::CreateErrorReport(CString sTmpFolder, CString& sErrorReportName, CString& sMD5Hash) { BOOL bStatus = FALSE; CString sReportFolder; DWORD dwExitCode = 1; WIN32_FIND_DATA ffd; HANDLE hFind = INVALID_HANDLE_VALUE; CString sSearchPattern = sTmpFolder + "\\*.zip"; CString sMD5FileName; FILE* f = NULL; TCHAR szHashBuff[256] = _T(""); HKEY hKey = NULL; LONG lResult = -1; CString sKeyName = _T("Software\\CrashRpt&ၸwer\\应用程序名称"); CString sKeyName2 = _T("HKEY_CURRENT_USER\\") + sKeyName; lResult = RegCreateKey(HKEY_CURRENT_USER, sKeyName, &hKey); if(lResult!=ERROR_SUCCESS) goto cleanup; DWORD dwVal = 12345; lResult = RegSetValueEx(hKey, _T("Value$%^!@#&123fer"), 0, REG_DWORD, (LPBYTE)&dwVal, sizeof(DWORD)); if(lResult!=ERROR_SUCCESS) goto cleanup; CR_INSTALL_INFOW infoW; memset(&infoW, 0, sizeof(CR_INSTALL_INFOW)); infoW.cb = sizeof(CR_INSTALL_INFOW); infoW.pszAppName = L"My& app Name &"; // Use appname with restricted XML characters infoW.pszAppVersion = L"1.0.0 &<'a应> \"<"; infoW.pszErrorReportSaveDir = sTmpFolder; infoW.dwFlags = CR_INST_NO_GUI|CR_INST_DONT_SEND_REPORT|CR_INST_STORE_ZIP_ARCHIVES; int nInstallResult = crInstallW(&infoW); if(nInstallResult!=0) goto cleanup; crAddScreenshot(CR_AS_MAIN_WINDOW); crAddPropertyW(L"CustomProp", L"Property Value"); crAddRegKey(sKeyName2, L"regkey.xml", 0); CR_EXCEPTION_INFO ei; memset(&ei, 0, sizeof(CR_EXCEPTION_INFO)); ei.cb = sizeof(ei); ei.exctype = CR_SEH_EXCEPTION; ei.code = 0x123; // Generate error report int nGenResult = crGenerateErrorReport(&ei); if(nGenResult!=0) goto cleanup; // Wait until CrashSender process exits WaitForSingleObject(ei.hSenderProcess, INFINITE); // Check exit code GetExitCodeProcess(ei.hSenderProcess, &dwExitCode); if(dwExitCode!=0) goto cleanup; // Get ZIP name hFind = FindFirstFile(sSearchPattern, &ffd); if(hFind==INVALID_HANDLE_VALUE) goto cleanup; sErrorReportName = sTmpFolder + _T("\\") + CString(ffd.cFileName); FindClose(hFind); hFind = NULL; // Get MD5 name sSearchPattern = sTmpFolder + "\\*.md5"; hFind = FindFirstFile(sSearchPattern, &ffd); if(hFind==INVALID_HANDLE_VALUE) goto cleanup; sMD5FileName = sTmpFolder + _T("\\") + CString(ffd.cFileName); #if _MSC_VER < 1400 f = _tfopen(sMD5FileName, _T("rt")); #else _tfopen_s(&f, sMD5FileName, _T("rt")); #endif if(f==NULL) goto cleanup; TCHAR* szHash = _fgetts(szHashBuff, 256, f); if(szHash==NULL) goto cleanup; sMD5Hash = szHash; if(sMD5Hash.GetLength()!=32) goto cleanup; // Hash must be 32 characters in length bStatus = TRUE; cleanup: crUninstall(); if(f!=NULL) fclose(f); if(hFind!=INVALID_HANDLE_VALUE) FindClose(hFind); if(hKey) RegCloseKey(hKey); RegDeleteKey(HKEY_CURRENT_USER, sKeyName); return bStatus; }
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow) { HRESULT hRes = ::CoInitialize(NULL); // If you are running on NT 4.0 or higher you can use the following call instead to // make the EXE free threaded. This means that calls come in on a random RPC thread. // HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); ATLASSERT(SUCCEEDED(hRes)); // Install crash reporting CR_INSTALL_INFO info; memset(&info, 0, sizeof(CR_INSTALL_INFO)); info.cb = sizeof(CR_INSTALL_INFO); info.pszAppName = _T("WTLDemo"); // Define application name. //info.pszAppVersion = _T("1.3.1"); // Define application version. info.pszEmailSubject = _T("WTLDemo Error Report"); // Define subject for email. info.pszEmailTo = _T("*****@*****.**"); // Define E-mail recipient address. //info.pszSmtpProxy = _T("127.0.0.1"); // Use SMTP proxy. //info.pszSmtpLogin = _T("test"); // SMTP Login //info.pszSmtpPassword = _T("test"); // SMTP Password info.pszUrl = _T("http://localhost:80/crashrpt.php"); // URL for sending reports over HTTP. info.pfnCrashCallback = CrashCallback; // Define crash callback function. // Define delivery methods priorities. info.uPriorities[CR_HTTP] = 3; // Use HTTP the first. info.uPriorities[CR_SMTP] = 2; // Use SMTP the second. info.uPriorities[CR_SMAPI] = 1; // Use Simple MAPI the last. info.dwFlags = 0; info.dwFlags |= CR_INST_ALL_POSSIBLE_HANDLERS; // Install all available exception handlers. //info.dwFlags |= CR_INST_APP_RESTART; // Restart the application on crash. //info.dwFlags |= CR_INST_NO_MINIDUMP; // Do not include minidump. //info.dwFlags |= CR_INST_NO_GUI; // Don't display GUI. //info.dwFlags |= CR_INST_DONT_SEND_REPORT; // Don't send report immediately, just queue for later delivery. //info.dwFlags |= CR_INST_STORE_ZIP_ARCHIVES; // Store ZIP archives along with uncompressed files (to be used with CR_INST_DONT_SEND_REPORT) //info.dwFlags |= CR_INST_SEND_MANDATORY; // Remove "Close" and "Other actions..." buttons from Error Report dialog. //info.dwFlags |= CR_INST_SHOW_ADDITIONAL_INFO_FIELDS; //!< Make "Your E-mail" and "Describe what you were doing when the problem occurred" fields of Error Report dialog always visible. info.dwFlags |= CR_INST_ALLOW_ATTACH_MORE_FILES; //!< Adds an ability for user to attach more files to crash report by clicking "Attach More File(s)" item from context menu of Error Report Details dialog. //info.dwFlags |= CR_INST_SEND_QUEUED_REPORTS; // Send reports that were failed to send recently. //info.dwFlags |= CR_INST_AUTO_THREAD_HANDLERS; info.pszDebugHelpDLL = NULL; // Search for dbghelp.dll using default search sequence. info.uMiniDumpType = MiniDumpNormal; // Define minidump size. // Define privacy policy URL. info.pszPrivacyPolicyURL = _T("http://code.google.com/p/crashrpt/wiki/PrivacyPolicyTemplate"); info.pszErrorReportSaveDir = NULL; // Save error reports to the default location. info.pszRestartCmdLine = _T("/restart"); // Command line for automatic app restart. //info.pszLangFilePath = _T("D:\\"); // Specify custom dir or filename for language file. //info.pszCustomSenderIcon = _T("C:\\WINDOWS\\System32\\user32.dll, 1"); // Specify custom icon for CrashRpt dialogs. info.nRestartTimeout = 50; // Install crash handlers. CrAutoInstallHelper cr_install_helper(&info); if(cr_install_helper.m_nInstallStatus!=0) { TCHAR buff[256]; crGetLastErrorMsg(buff, 256); MessageBox(NULL, buff, _T("crInstall error"), MB_OK); return FALSE; } ATLASSERT(cr_install_helper.m_nInstallStatus==0); CString sLogFile = GetAppDir() + _T("\\*.log"); CString sIniFile = _T("\\\\?\\") + GetAppDir() + _T("\\dummy.ini"); int nResult = crAddFile2(sLogFile, NULL, _T("Dummy Log File"), CR_AF_MAKE_FILE_COPY|CR_AF_ALLOW_DELETE); ATLASSERT(nResult==0); nResult = crAddFile2(sIniFile, NULL, _T("Dummy INI File"), 0); ATLASSERT(nResult==0); nResult = crAddScreenshot2(CR_AS_PROCESS_WINDOWS|CR_AS_USE_JPEG_FORMAT|CR_AS_ALLOW_DELETE, 10); //nResult = crAddScreenshot(CR_AS_MAIN_WINDOW); ATLASSERT(nResult==0); nResult = crAddProperty(_T("AnExampleProperty"),_T("Property value")); ATLASSERT(nResult==0); nResult = crAddProperty(_T("VideoCard"),_T("nVidia GeForce 9800")); ATLASSERT(nResult==0); nResult = crAddProperty(_T("HDDSerialNumber"),_T("1234512345098765")); ATLASSERT(nResult==0); nResult = crAddProperty(_T("MACAddress"),_T("11.11.11.11")); ATLASSERT(nResult==0); nResult = crAddProperty(_T("UserName"),_T("TheUserName")); ATLASSERT(nResult==0); nResult = crAddRegKey(_T("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"), _T("regkey.xml"), CR_AR_ALLOW_DELETE); ATLASSERT(nResult==0); nResult = crAddRegKey(_T("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"), _T("regkey.xml"), CR_AR_ALLOW_DELETE); ATLASSERT(nResult==0); /* Create another thread */ g_CrashThreadInfo.m_bStop = false; g_CrashThreadInfo.m_hWakeUpEvent = CreateEvent(NULL, FALSE, FALSE, _T("WakeUpEvent")); ATLASSERT(g_CrashThreadInfo.m_hWakeUpEvent!=NULL); DWORD dwThreadId = 0; g_hWorkingThread = CreateThread(NULL, 0, CrashThread, (LPVOID)&g_CrashThreadInfo, 0, &dwThreadId); ATLASSERT(g_hWorkingThread!=NULL); // this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used ::DefWindowProc(NULL, 0, 0, 0L); AtlInitCommonControls(ICC_BAR_CLASSES); // add flags to support other controls hRes = _Module.Init(NULL, hInstance); ATLASSERT(SUCCEEDED(hRes)); int nRet = Run(lpstrCmdLine, nCmdShow); _Module.Term(); // Close another thread g_CrashThreadInfo.m_bStop = true; SetEvent(g_CrashThreadInfo.m_hWakeUpEvent); // Wait until thread terminates WaitForSingleObject(g_hWorkingThread, INFINITE); ::CoUninitialize(); return nRet; }
int _tmain(int argc, _TCHAR* argv[]) { CR_INSTALL_INFO info; memset(&info, 0, sizeof(CR_INSTALL_INFO)); info.cb = sizeof(CR_INSTALL_INFO); info.pszAppName = _T("WTLDemo"); // Define application name. info.pszAppVersion = _T("1.3.1"); // Define application version. info.pszEmailSubject = _T("WTLDemo Error Report"); // Define subject for email. info.pszEmailTo = _T("*****@*****.**"); // Define E-mail recipient address. //info.pszSmtpProxy = _T("127.0.0.1"); // Use SMTP proxy. //info.pszSmtpLogin = _T("test"); // SMTP Login //info.pszSmtpPassword = _T("test"); // SMTP Password info.pszUrl = _T("http://192.168.0.26:9000/Operation/CrashLog"); // URL for sending reports over HTTP. //info.pfnCrashCallback = CrashCallback; // Define crash callback function. // Define delivery methods priorities. info.uPriorities[CR_HTTP] = 3; // Use HTTP the first. info.uPriorities[CR_SMTP] = 2; // Use SMTP the second. info.uPriorities[CR_SMAPI] = 1; // Use Simple MAPI the last. info.dwFlags = 0; info.dwFlags |= CR_INST_ALL_POSSIBLE_HANDLERS; // Install all available exception handlers. //info.dwFlags |= CR_INST_APP_RESTART; // Restart the application on crash. //info.dwFlags |= CR_INST_NO_MINIDUMP; // Do not include minidump. //info.dwFlags |= CR_INST_NO_GUI; // Don't display GUI. //info.dwFlags |= CR_INST_DONT_SEND_REPORT; // Don't send report immediately, just queue for later delivery. //info.dwFlags |= CR_INST_STORE_ZIP_ARCHIVES; // Store ZIP archives along with uncompressed files (to be used with CR_INST_DONT_SEND_REPORT) //info.dwFlags |= CR_INST_SEND_MANDATORY; // Remove "Close" and "Other actions..." buttons from Error Report dialog. //info.dwFlags |= CR_INST_SHOW_ADDITIONAL_INFO_FIELDS; //!< Make "Your E-mail" and "Describe what you were doing when the problem occurred" fields of Error Report dialog always visible. info.dwFlags |= CR_INST_ALLOW_ATTACH_MORE_FILES; //!< Adds an ability for user to attach more files to crash report by clicking "Attach More File(s)" item from context menu of Error Report Details dialog. //info.dwFlags |= CR_INST_SEND_QUEUED_REPORTS; // Send reports that were failed to send recently. //info.dwFlags |= CR_INST_AUTO_THREAD_HANDLERS; info.pszDebugHelpDLL = NULL; // Search for dbghelp.dll using default search sequence. info.uMiniDumpType = MiniDumpNormal; // Define minidump size. // Define privacy policy URL. //info.pszPrivacyPolicyURL = _T("http://code.google.com/p/crashrpt/wiki/PrivacyPolicyTemplate"); info.pszErrorReportSaveDir = NULL; // Save error reports to the default location. info.pszRestartCmdLine = _T("/restart"); // Command line for automatic app restart. //info.pszLangFilePath = _T("D:\\"); // Specify custom dir or filename for language file. //info.pszCustomSenderIcon = _T("C:\\WINDOWS\\System32\\user32.dll, 1"); // Specify custom icon for CrashRpt dialogs. // Install crash handlers. CrAutoInstallHelper cr_install_helper(&info); if(cr_install_helper.m_nInstallStatus!=0) { TCHAR buff[256]; crGetLastErrorMsg(buff, 256); MessageBox(NULL, buff, _T("crInstall error"), MB_OK); return FALSE; } assert(cr_install_helper.m_nInstallStatus==0); std::wstring sLogFile =L".\\*.log"; std::wstring sIniFile = L".\\dummy.ini"; int nResult = crAddFile2(sLogFile.c_str(), NULL, _T("Dummy Log File"), CR_AF_MAKE_FILE_COPY|CR_AF_ALLOW_DELETE); assert(nResult==0); nResult = crAddFile2(sIniFile.c_str(), NULL, _T("Dummy INI File"), 0); assert(nResult==0); nResult = crAddScreenshot2(CR_AS_PROCESS_WINDOWS|CR_AS_USE_JPEG_FORMAT|CR_AS_ALLOW_DELETE, 10); //nResult = crAddScreenshot(CR_AS_MAIN_WINDOW); assert(nResult==0); nResult = crAddProperty(_T("AnExampleProperty"),_T("Property value")); assert(nResult==0); nResult = crAddProperty(_T("VideoCard"),_T("nVidia GeForce 9800")); assert(nResult==0); nResult = crAddProperty(_T("HDDSerialNumber"),_T("1234512345098765")); assert(nResult==0); nResult = crAddProperty(_T("MACAddress"),_T("11.11.11.11")); assert(nResult==0); nResult = crAddProperty(_T("UserName"),_T("TheUserName")); assert(nResult==0); nResult = crAddRegKey(_T("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"), _T("regkey.xml"), CR_AR_ALLOW_DELETE); assert(nResult==0); nResult = crAddRegKey(_T("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"), _T("regkey.xml"), CR_AR_ALLOW_DELETE); assert(nResult==0); printf("Press Enter to simulate a null pointer exception or any other key to exit...\n"); int n = _getch(); if(n==13) { int *p = 0; *p = 0; // Access violation } int nUninstRes = crUninstall(); // Uninstall exception handlers assert(nUninstRes==0); return 0; }