void CMiniDumper::Enable(LPCTSTR pszAppName, bool bShowErrors,bool b_user_mode) { TCHAR s_process_name[MAX_PATH]; LPCTSTR p_app_name = NULL; s_process_name[0] = 0x0; theCrashDumper.mb_user_mode=b_user_mode; //if (p_app_name == NULL) { TCHAR s_buf[MAX_PATH]; s_buf[0] = 0x0; DWORD n_result = ::GetModuleFileName(NULL, s_buf, sizeof(TCHAR) * MAX_PATH); TCHAR s_file_name[MAX_PATH]; s_file_name[0] = 0x0; _tsplitpath(s_buf, NULL, NULL, s_file_name, NULL); _tcscpy_s(s_process_name, MAX_PATH, s_file_name); if (pszAppName == NULL || _tcslen(pszAppName) == 0) p_app_name = s_process_name; else p_app_name = pszAppName; } assert(p_app_name != NULL); assert( m_szAppName[0] == _T('\0') ); _tcsncpy(m_szAppName, p_app_name, wcslen(p_app_name)); MINIDUMPWRITEDUMP pfnMiniDumpWriteDump = NULL; HMODULE hDbgHelpDll = GetDebugHelperDll((FARPROC*)&pfnMiniDumpWriteDump, bShowErrors); if (hDbgHelpDll) { if (pfnMiniDumpWriteDump) SetUnhandledExceptionFilter(TopLevelFilter); FreeLibrary(hDbgHelpDll); hDbgHelpDll = NULL; pfnMiniDumpWriteDump = NULL; } }
void CMiniDumper::Enable(LPCTSTR pszAppName, bool bShowErrors, LPCTSTR pszDumpDir) { // if this assert fires then you have two instances of CMiniDumper which is not allowed ASSERT( m_szAppName[0] == _T('\0') ); _tcsncpy(m_szAppName, pszAppName, _countof(m_szAppName) - 1); m_szAppName[_countof(m_szAppName) - 1] = _T('\0'); // eMule may not have the permission to create a DMP file in the directory where the "emule.exe" is located. // Need to pre-determine a valid directory. _tcsncpy(m_szDumpDir, pszDumpDir, _countof(m_szDumpDir) - 1); m_szDumpDir[_countof(m_szDumpDir) - 1] = _T('\0'); PathAddBackslash(m_szDumpDir); MINIDUMPWRITEDUMP pfnMiniDumpWriteDump = NULL; HMODULE hDbgHelpDll = GetDebugHelperDll((FARPROC*)&pfnMiniDumpWriteDump, bShowErrors); if (hDbgHelpDll) { if (pfnMiniDumpWriteDump) SetUnhandledExceptionFilter(TopLevelFilter); FreeLibrary(hDbgHelpDll); hDbgHelpDll = NULL; pfnMiniDumpWriteDump = NULL; } }
LONG CMiniDumper::TopLevelFilter(struct _EXCEPTION_POINTERS* pExceptionInfo) { LONG lRetValue = EXCEPTION_CONTINUE_SEARCH; TCHAR szResult[MAX_PATH + 1024] = {0}; MINIDUMPWRITEDUMP pfnMiniDumpWriteDump = NULL; HMODULE hDll = GetDebugHelperDll((FARPROC*)&pfnMiniDumpWriteDump, true); if (hDll) { if (pfnMiniDumpWriteDump) { // Ask user if they want to save a dump file // Do *NOT* localize that string (in fact, do not use MFC to load it)! if (MessageBox(NULL, _T("eMule crashed :-(\r\n\r\nA diagnostic file can be created which will help the author to resolve this problem. This file will be saved on your Disk (and not sent).\r\n\r\nDo you want to create this file now?"), m_szAppName, MB_ICONSTOP | MB_YESNO) == IDYES) { // Create full path for DUMP file TCHAR szDumpPath[MAX_PATH]; _tcsncpy(szDumpPath, m_szDumpDir, _countof(szDumpPath) - 1); szDumpPath[_countof(szDumpPath) - 1] = _T('\0'); size_t uDumpPathLen = _tcslen(szDumpPath); TCHAR szBaseName[MAX_PATH]; _tcsncpy(szBaseName, m_szAppName, _countof(szBaseName) - 1); szBaseName[_countof(szBaseName) - 1] = _T('\0'); size_t uBaseNameLen = _tcslen(szBaseName); time_t tNow = time(NULL); _tcsftime(szBaseName + uBaseNameLen, _countof(szBaseName) - uBaseNameLen, _T("_%Y%m%d-%H%M%S"), localtime(&tNow)); szBaseName[_countof(szBaseName) - 1] = _T('\0'); // Replace spaces and dots in file name. LPTSTR psz = szBaseName; while (*psz != _T('\0')) { if (*psz == _T('.')) *psz = _T('-'); else if (*psz == _T(' ')) *psz = _T('_'); psz++; } if (uDumpPathLen < _countof(szDumpPath) - 1) { _tcsncat(szDumpPath, szBaseName, _countof(szDumpPath) - uDumpPathLen - 1); szDumpPath[_countof(szDumpPath) - 1] = _T('\0'); uDumpPathLen = _tcslen(szDumpPath); if (uDumpPathLen < _countof(szDumpPath) - 1) { _tcsncat(szDumpPath, _T(".dmp"), _countof(szDumpPath) - uDumpPathLen - 1); szDumpPath[_countof(szDumpPath) - 1] = _T('\0'); } } HANDLE hFile = CreateFile(szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { _MINIDUMP_EXCEPTION_INFORMATION ExInfo = {0}; ExInfo.ThreadId = GetCurrentThreadId(); ExInfo.ExceptionPointers = pExceptionInfo; ExInfo.ClientPointers = NULL; BOOL bOK = (*pfnMiniDumpWriteDump)(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL); if (bOK) { // Do *NOT* localize that string (in fact, do not use MFC to load it)! //Xman Xtreme Mod /* _sntprintf(szResult, _countof(szResult) - 1, _T("Saved dump file to \"%s\".\r\n\r\nPlease send this file together with a detailed bug report to [email protected] !\r\n\r\nThank you for helping to improve eMule."), szDumpPath); */ _sntprintf(szResult, _countof(szResult) - 1, _T("Saved dump file to \"%s\".\r\n\r\nPlease send this file together with a detailed bug report to [email protected] !\r\n\r\nThank you for helping to improve eMule."), szDumpPath); //Xman end szResult[_countof(szResult) - 1] = _T('\0'); lRetValue = EXCEPTION_EXECUTE_HANDLER; } else { // Do *NOT* localize that string (in fact, do not use MFC to load it)! _sntprintf(szResult, _countof(szResult) - 1, _T("Failed to save dump file to \"%s\".\r\n\r\nError: %u"), szDumpPath, GetLastError()); szResult[_countof(szResult) - 1] = _T('\0'); } CloseHandle(hFile); } else { // Do *NOT* localize that string (in fact, do not use MFC to load it)! _sntprintf(szResult, _countof(szResult) - 1, _T("Failed to create dump file \"%s\".\r\n\r\nError: %u"), szDumpPath, GetLastError()); szResult[_countof(szResult) - 1] = _T('\0'); } } } FreeLibrary(hDll); hDll = NULL; pfnMiniDumpWriteDump = NULL; } if (szResult[0] != _T('\0')) MessageBox(NULL, szResult, m_szAppName, MB_ICONINFORMATION | MB_OK); #ifndef _DEBUG // Exit the process only in release builds, so that in debug builds the exceptio is passed to a possible // installed debugger ExitProcess(0); #else return lRetValue; #endif }
LONG CMiniDumper::TopLevelFilter(struct _EXCEPTION_POINTERS* pExceptionInfo) { LONG lRetValue = EXCEPTION_CONTINUE_SEARCH; TCHAR szResult[_MAX_PATH + 1024] = {0}; MINIDUMPWRITEDUMP pfnMiniDumpWriteDump = NULL; HMODULE hDll = GetDebugHelperDll((FARPROC*)&pfnMiniDumpWriteDump, true); HINSTANCE hInstCrashReporter = NULL; if (hDll) { if (pfnMiniDumpWriteDump) { { // Create full path for BugReport.exe TCHAR szSharkPath[_MAX_PATH] = {0}; TCHAR szDumpPath_no_time[_MAX_PATH] = {0}; GetModuleFileName(NULL, szSharkPath, wcslen(szSharkPath)); LPTSTR pszFileName = _tcsrchr(szSharkPath, _T('\\')); if (pszFileName) { pszFileName++; *pszFileName = _T('\0'); } TCHAR szCrashReport[MAX_PATH] = {0}; _tcsncat(szCrashReport,szSharkPath,wcslen(szCrashReport) - 1); _tcsncat(szCrashReport,_T("BugReport.exe"),wcslen(szCrashReport) - 1); // Create full path for DUMP file TCHAR szDumpPath[MAX_PATH]={0}; SHGetFolderPath(NULL, CSIDL_APPDATA,NULL,SHGFP_TYPE_CURRENT,szDumpPath); _tcsncat(szDumpPath,_T("\\XiaTing\\"),wcslen(szDumpPath) - 1); // Replace spaces and dots in file name. TCHAR szBaseName[_MAX_PATH] = {0}; _tcsncat(szBaseName, m_szAppName, wcslen(szBaseName) - 1); LPTSTR psz = szBaseName; while (*psz != _T('\0')) { if (*psz == _T('.')) *psz = _T('-'); else if (*psz == _T(' ')) *psz = _T('_'); psz++; } _tcsncat(szDumpPath, szBaseName, wcslen(szDumpPath) - 1); _tcsncat(szDumpPath_no_time, szBaseName, wcslen(szDumpPath_no_time) - 1); if (!theCrashDumper.mb_user_mode) { time_t n_now = time(NULL); struct tm* p_time = localtime(&n_now); if (p_time != NULL) { TCHAR s_format[256]; s_format[0] = 0x0; _tcsftime(s_format, 255, _T("-%Y.%m.%d - %H-%M-%S"), p_time); _tcsncat(szDumpPath, s_format, _tcslen(s_format) -1); } } _tcsncat(szDumpPath, _T(".dmp"), wcslen(szDumpPath) - 1); _tcsncat(szDumpPath_no_time, _T(".dmp"), wcslen(szDumpPath_no_time) - 1); HANDLE hFile = CreateFile(szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { _MINIDUMP_EXCEPTION_INFORMATION ExInfo = {0}; ExInfo.ThreadId = GetCurrentThreadId(); ExInfo.ExceptionPointers = pExceptionInfo; ExInfo.ClientPointers = NULL; BOOL bOK = (*pfnMiniDumpWriteDump)(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL); if (bOK) { _sntprintf(szResult, wcslen(szResult), _T("Saved dump file to \"%s\".\r\n\r\nPlease send this file together with a detailed bug report to [email protected] !\r\n\r\nThank you for helping to improve eMule."), szDumpPath); lRetValue = EXCEPTION_EXECUTE_HANDLER; CString cs_cmd_line; cs_cmd_line.Format(_T("%s%s"),_T("Cmd|"),szDumpPath_no_time); hInstCrashReporter = ShellExecuteW(NULL, _T("open"), szCrashReport, cs_cmd_line.GetBuffer(), NULL, SW_SHOW); if (hInstCrashReporter <= (HINSTANCE)32) lRetValue = EXCEPTION_CONTINUE_SEARCH; } else { _sntprintf(szResult, wcslen(szResult), _T("Failed to save dump file to \"%s\".\r\n\r\nError: %u"), szDumpPath, GetLastError()); } CloseHandle(hFile); } else { _sntprintf(szResult, wcslen(szResult), _T("Failed to create dump file \"%s\".\r\n\r\nError: %u"), szDumpPath, GetLastError()); } } } FreeLibrary(hDll); hDll = NULL; pfnMiniDumpWriteDump = NULL; } #ifndef _DEBUG if (EXCEPTION_EXECUTE_HANDLER == lRetValue) { exit(0); } else return lRetValue; #else return lRetValue; #endif }