#include "HL_CrashRpt.h" #if defined(USE_CRASHRPT) #include "HL_String.h" // Define this if CrashRpt has to be deployed as .dll // #define CRASHRPT_DYNAMIC // --- CrashReporer --- #if defined(TARGET_WIN) #include "CrashRpt.h" BOOL WINAPI CrashReporter::Callback(LPVOID arg) { return TRUE; } typedef int(__stdcall *CrInstallProc)(__in PCR_INSTALL_INFOW pInfo); static CrInstallProc CrInstall = nullptr; typedef int(__stdcall *CrUninstallProc)(); static CrUninstallProc CrUninstall = nullptr; typedef int(__stdcall *CrInstallIntoCurrentThreadProc)(DWORD dwFlags); static CrInstallIntoCurrentThreadProc CrInstallIntoCurrentThread = nullptr; typedef int(__stdcall *CrUninstallFromCurrentThreadProc)(); static CrUninstallFromCurrentThreadProc CrUninstallFromCurrentThread = nullptr; typedef int(__stdcall *CrGetLastErrorMsgProc)(LPWSTR buffer, UINT size); static CrGetLastErrorMsgProc CrGetLastErrorMsg = nullptr; static HMODULE CrLibraryHandle = NULL; #endif void CrashReporter::init(const std::string& appname, const std::string& version, const std::string& url) { #if defined(TARGET_WIN) #if defined(CRASHRPT_DYNAMIC) // Check if DLL functions are here if (CrLibraryHandle) return; // Library is loaded already - so initialized already CrLibraryHandle = ::LoadLibrary(TEXT("crashrpt.dll")); if (!CrLibraryHandle) return; // No logging here - initialization happens on very first stages, no chance to log anything CrInstall = (CrInstallProc)::GetProcAddress(CrLibraryHandle, "crInstallW"); CrUninstall = (CrUninstallProc)::GetProcAddress(CrLibraryHandle, "crUninstall"); CrInstallIntoCurrentThread = (CrInstallIntoCurrentThreadProc)::GetProcAddress(CrLibraryHandle, "crInstallToCurrentThread2"); CrUninstallFromCurrentThread = (CrUninstallFromCurrentThreadProc)::GetProcAddress(CrLibraryHandle, "crUninstallFromCurrentThread"); CrGetLastErrorMsg = (CrGetLastErrorMsgProc)::GetProcAddress(CrLibraryHandle, "crGetLastErrorMsgW"); #else CrInstall = &crInstallW; CrUninstall = &crUninstall; CrInstallIntoCurrentThread = &crInstallToCurrentThread2; CrUninstallFromCurrentThread = &crUninstallFromCurrentThread; CrGetLastErrorMsg = &crGetLastErrorMsgW; #endif if (!isLoaded()) return; CR_INSTALL_INFO info; memset(&info, 0, sizeof(CR_INSTALL_INFO)); info.cb = sizeof(CR_INSTALL_INFO); struct { std::wstring appname, version, url; } unicode; unicode.appname = StringHelper::makeTstring(appname), unicode.version = StringHelper::makeTstring(version), unicode.url = StringHelper::makeTstring(url); if (unicode.appname.empty()) unicode.appname = L"App"; if (unicode.url.empty()) unicode.url = L"https://voipobjects.com/crashrpt/crashrpt.php"; if (unicode.version.empty()) unicode.version = L"General version"; info.pszAppName = unicode.appname.c_str(); info.pszAppVersion = unicode.version.c_str(); info.pszEmailSubject = TEXT("Crash report"); //info.pszEmailTo = L"amegyeri@minerva-soft.com"; //info.pszUrl = L"http://ftp.minerva-soft.com/crashlog/crashrpt.php"; //info.pszUrl = L"http://sip.crypttalk.com/crashlog/crashrpt.php"; info.pszUrl = unicode.url.c_str(); info.pfnCrashCallback = Callback; info.uPriorities[CR_HTTP] = 1; info.uPriorities[CR_SMTP] = CR_NEGATIVE_PRIORITY; info.uPriorities[CR_SMAPI] = CR_NEGATIVE_PRIORITY; info.dwFlags = 0; info.pszCrashSenderPath = TEXT("."); int nResult = CrInstall(&info); if (nResult) { wchar_t errorMsg[512] = L""; CrGetLastErrorMsg(errorMsg, 512); OutputDebugStringW(errorMsg); //LogCritical("Core", << "Failed to install CrashReporter with code " << nResult << " and message " << errorMsg); } #endif } void CrashReporter::free() { #if defined(TARGET_WIN) if (isLoaded()) { CrUninstall(); CrInstall = nullptr; CrUninstall = nullptr; CrInstallIntoCurrentThread = nullptr; CrUninstallFromCurrentThread = nullptr; CrGetLastErrorMsg = nullptr; #if defined(CRASHRPT_DYNAMIC) ::FreeLibrary(CrLibraryHandle); CrLibraryHandle = NULL; #endif } #endif } bool CrashReporter::isLoaded() { #if defined(TARGET_WIN) return !(!CrInstall || !CrUninstall || !CrGetLastErrorMsg || !CrInstallIntoCurrentThread || !CrUninstallFromCurrentThread); #else return false; #endif } void CrashReporter::initThread() { #if defined(TARGET_WIN) if (isLoaded()) CrInstallIntoCurrentThread(0); #endif } void CrashReporter::freeThread() { #if defined(TARGET_WIN) if (isLoaded()) CrUninstallFromCurrentThread(); #endif } CrashReporterThreadPoint::CrashReporterThreadPoint() { CrashReporter::initThread(); } CrashReporterThreadPoint::~CrashReporterThreadPoint() { CrashReporter::freeThread(); } CrashReporterGuard::CrashReporterGuard() { CrashReporter::init("generic"); } CrashReporterGuard::~CrashReporterGuard() { CrashReporter::free(); } #else CrashReporterThreadPoint::CrashReporterThreadPoint() { } CrashReporterThreadPoint::~CrashReporterThreadPoint() { } CrashReporterGuard::CrashReporterGuard() { } CrashReporterGuard::~CrashReporterGuard() { } #endif