コード例 #1
0
ファイル: CrashHandler.cpp プロジェクト: doo/CrashRpt
// Launches CrashSender.exe process
int CCrashHandler::LaunchCrashSender(CString sCmdLineParams, BOOL bWait)
{
  crSetErrorMsg(_T("Success."));
  
  /* Create CrashSender process */

  STARTUPINFO si;
  memset(&si, 0, sizeof(STARTUPINFO));
  si.cb = sizeof(STARTUPINFO);

  PROCESS_INFORMATION pi;
  memset(&pi, 0, sizeof(PROCESS_INFORMATION));  

  CString sCmdLine;
  sCmdLine.Format(_T("\"%s\" \"%s\""), sCmdLineParams, sCmdLineParams.GetBuffer(0));
  BOOL bCreateProcess = CreateProcess(
    m_sPathToCrashSender, sCmdLine.GetBuffer(0), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
  if(!bCreateProcess)
  {
    ATLASSERT(bCreateProcess);
    crSetErrorMsg(_T("Error creating CrashSender process."));
    return 1;
  }
  

  if(bWait)
  {
    /* Wait until CrashSender finishes with making screenshot, 
      copying files, creating minidump. */  

    WaitForSingleObject(m_hEvent, INFINITE);  
  }

  return 0;
}
コード例 #2
0
ファイル: CrashRpt.cpp プロジェクト: doo/CrashRpt
crExceptionFilter(unsigned int code, struct _EXCEPTION_POINTERS* ep)
{
  crSetErrorMsg(_T("Unspecified error."));

  CCrashHandler *pCrashHandler = 
    CCrashHandler::GetCurrentProcessCrashHandler();

  if(pCrashHandler==NULL)
  {    
    crSetErrorMsg(_T("Crash handler wasn't previously installed for current process."));
    return EXCEPTION_CONTINUE_SEARCH; 
  }

  CR_EXCEPTION_INFO ei;
  memset(&ei, 0, sizeof(CR_EXCEPTION_INFO));
  ei.cb = sizeof(CR_EXCEPTION_INFO);  
  ei.exctype = CR_SEH_EXCEPTION;
  ei.pexcptrs = ep;
  ei.code = code;

  int res = pCrashHandler->GenerateErrorReport(&ei);
  if(res!=0)
  {
    // If goes here than GenerateErrorReport() failed  
    return EXCEPTION_CONTINUE_SEARCH;  
  }  
  
  crSetErrorMsg(_T("Success."));
  return EXCEPTION_EXECUTE_HANDLER;  
}
コード例 #3
0
ファイル: CrashRpt.cpp プロジェクト: doo/CrashRpt
crGenerateErrorReport(
  CR_EXCEPTION_INFO* pExceptionInfo)
{
  crSetErrorMsg(_T("Unspecified error."));

  if(pExceptionInfo==NULL || 
     pExceptionInfo->cb!=sizeof(CR_EXCEPTION_INFO))
  {
    crSetErrorMsg(_T("Exception info is NULL or invalid."));    
    return 1;
  }

  CCrashHandler *pCrashHandler = 
    CCrashHandler::GetCurrentProcessCrashHandler();

  if(pCrashHandler==NULL)
  {    
    // Handler is not installed for current process 
    crSetErrorMsg(_T("Crash handler wasn't previously installed for current process."));
    ATLASSERT(pCrashHandler!=NULL);
    return 2;
  } 

  return pCrashHandler->GenerateErrorReport(pExceptionInfo);  
}
コード例 #4
0
ファイル: CrashRpt.cpp プロジェクト: doo/CrashRpt
crAddRegKeyW(   
   LPCWSTR pszRegKey,
   LPCWSTR pszDstFileName,
   DWORD dwFlags
   )
{
  crSetErrorMsg(_T("Unspecified error."));

  strconv_t strconv;
  LPCTSTR pszRegKeyT = strconv.w2t(pszRegKey);
  LPCTSTR pszDstFileNameT = strconv.w2t(pszDstFileName);  

  CCrashHandler *pCrashHandler = 
    CCrashHandler::GetCurrentProcessCrashHandler();

  if(pCrashHandler==NULL)
  {    
    crSetErrorMsg(_T("Crash handler wasn't previously installed for current process."));
    return 1; // No handler installed for current process?
  }

  int nResult = pCrashHandler->AddRegKey(pszRegKeyT, pszDstFileNameT, dwFlags);
  if(nResult!=0)
  {    
    crSetErrorMsg(_T("Invalid parameter or key doesn't exist."));
    return 2; // Failed to add the property
  }
  
  crSetErrorMsg(_T("Success."));
  return 0;
}
コード例 #5
0
ファイル: CrashRpt.cpp プロジェクト: doo/CrashRpt
crAddPropertyW(
   LPCWSTR pszPropName,
   LPCWSTR pszPropValue
   )
{
  crSetErrorMsg(_T("Unspecified error."));

  strconv_t strconv;
  LPCTSTR pszPropNameT = strconv.w2t(pszPropName);
  LPCTSTR pszPropValueT = strconv.w2t(pszPropValue);

  CCrashHandler *pCrashHandler = 
    CCrashHandler::GetCurrentProcessCrashHandler();

  if(pCrashHandler==NULL)
  {   
    crSetErrorMsg(_T("Crash handler wasn't previously installed for current process."));
    return 1; // No handler installed for current process?
  }

  int nResult = pCrashHandler->AddProperty(CString(pszPropNameT), CString(pszPropValueT));
  if(nResult!=0)
  {    
    crSetErrorMsg(_T("Invalid property name specified."));
    return 2; // Failed to add the property
  }
  
  crSetErrorMsg(_T("Success."));
  return 0;
}
コード例 #6
0
ファイル: CrashRpt.cpp プロジェクト: doo/CrashRpt
crAddFile2W(PCWSTR pszFile, PCWSTR pszDestFile, PCWSTR pszDesc, DWORD dwFlags)
{
  crSetErrorMsg(_T("Success."));

  strconv_t strconv;

  CCrashHandler *pCrashHandler = 
    CCrashHandler::GetCurrentProcessCrashHandler();

  if(pCrashHandler==NULL)
  {    
    crSetErrorMsg(_T("Crash handler wasn't previously installed for current process."));
    return 1; // No handler installed for current process?
  }
  
  LPCTSTR lptszFile = strconv.w2t((LPWSTR)pszFile);
  LPCTSTR lptszDestFile = strconv.w2t((LPWSTR)pszDestFile);
  LPCTSTR lptszDesc = strconv.w2t((LPWSTR)pszDesc);

  int nAddResult = pCrashHandler->AddFile(lptszFile, lptszDestFile, lptszDesc, dwFlags);
  if(nAddResult!=0)
  {    
    // Couldn't add file
    return 2; 
  }

  // OK.
  return 0;
}
コード例 #7
0
ファイル: CrashHandler.cpp プロジェクト: doo/CrashRpt
int CCrashHandler::Destroy()
{
  crSetErrorMsg(_T("Unspecified error."));

  if(!m_bInitialized)
  {
    crSetErrorMsg(_T("Can't destroy not initialized handler."));
    return 1;
  }  

  // Reset exception callback
  if (m_oldSehHandler)
    SetUnhandledExceptionFilter(m_oldSehHandler);

  m_oldSehHandler = NULL;

  // All installed per-thread C++ exception handlers should be uninstalled 
  // using crUninstallFromCurrentThread() before calling Destroy()

  {
    CAutoLock lock(&m_csThreadExceptionHandlers);
    ATLASSERT(m_ThreadExceptionHandlers.size()==0);          
  }

  m_pProcessCrashHandler = NULL;

  // OK.
  m_bInitialized = FALSE;
  crSetErrorMsg(_T("Success."));
  return 0;
}
コード例 #8
0
ファイル: CrashRpt.cpp プロジェクト: doo/CrashRpt
CRASHRPTAPI(int) crUninstall()
{
  crSetErrorMsg(_T("Success."));

  CCrashHandler *pCrashHandler = 
    CCrashHandler::GetCurrentProcessCrashHandler();
  
  if(pCrashHandler==NULL ||
     !pCrashHandler->IsInitialized())
  {     
    crSetErrorMsg(_T("Crash handler wasn't preiviously installed for this process."));
    return 1; 
  }

  // Uninstall main thread's C++ exception handlers
  int nUnset = pCrashHandler->UnSetThreadExceptionHandlers();
  if(nUnset!=0)
    return 2;

  int nDestroy = pCrashHandler->Destroy();
  if(nDestroy!=0)
    return 3;

  delete pCrashHandler;
    
  return 0;
}
コード例 #9
0
ファイル: CrashHandler.cpp プロジェクト: doo/CrashRpt
int CCrashHandler::AddProperty(CString sPropName, CString sPropValue)
{
  crSetErrorMsg(_T("Unspecified error."));

  if(sPropName.IsEmpty())
  {
    crSetErrorMsg(_T("Invalid property name specified."));
    return 1;
  }

  m_props[sPropName] = sPropValue;

  // OK.
  crSetErrorMsg(_T("Success."));
  return 0;
}
コード例 #10
0
ファイル: CrashHandler.cpp プロジェクト: doo/CrashRpt
int CCrashHandler::AddScreenshot(DWORD dwFlags)
{  
  m_bAddScreenshot = TRUE;
  m_dwScreenshotFlags = dwFlags;
  crSetErrorMsg(_T("Success."));
  return 0;
}
コード例 #11
0
ファイル: CrashRpt.cpp プロジェクト: doo/CrashRpt
crAddScreenshot(
   DWORD dwFlags
   )
{
  crSetErrorMsg(_T("Unspecified error."));
  
  CCrashHandler *pCrashHandler = 
    CCrashHandler::GetCurrentProcessCrashHandler();

  if(pCrashHandler==NULL)
  {    
    crSetErrorMsg(_T("Crash handler wasn't previously installed for current thread."));
    return 1; // Invalid parameter?
  }

  return pCrashHandler->AddScreenshot(dwFlags);
}
コード例 #12
0
ファイル: CrashHandler.cpp プロジェクト: doo/CrashRpt
int CCrashHandler::UnSetThreadExceptionHandlers()
{
  crSetErrorMsg(_T("Unspecified error."));

  DWORD dwThreadId = GetCurrentThreadId();

  CAutoLock lock(&m_csThreadExceptionHandlers);

  std::map<DWORD, ThreadExceptionHandlers>::iterator it = 
    m_ThreadExceptionHandlers.find(dwThreadId);

  if(it==m_ThreadExceptionHandlers.end())
  {
    // No exception handlers were installed for the caller thread?
    ATLASSERT(0);
    crSetErrorMsg(_T("Crash handler wasn't previously installed for current thread."));
    return 1;
  }
  
  ThreadExceptionHandlers* handlers = &(it->second);

  if(handlers->m_prevTerm!=NULL)
    set_terminate(handlers->m_prevTerm);

  if(handlers->m_prevUnexp!=NULL)
    set_unexpected(handlers->m_prevUnexp);

  if(handlers->m_prevSigFPE!=NULL)
    signal(SIGFPE, handlers->m_prevSigFPE);     

  if(handlers->m_prevSigILL!=NULL)
    signal(SIGINT, handlers->m_prevSigILL);     

  if(handlers->m_prevSigSEGV!=NULL)
    signal(SIGSEGV, handlers->m_prevSigSEGV); 

  // Remove from the list
  m_ThreadExceptionHandlers.erase(it);

  // OK.
  crSetErrorMsg(_T("Success."));
  return 0;
}
コード例 #13
0
ファイル: CrashRpt.cpp プロジェクト: doo/CrashRpt
crInstallToCurrentThread2(DWORD dwFlags)
{
  crSetErrorMsg(_T("Success."));

  CCrashHandler *pCrashHandler = 
    CCrashHandler::GetCurrentProcessCrashHandler();
  
  if(pCrashHandler==NULL)
  {    
    crSetErrorMsg(_T("Crash handler was already installed for current thread."));
    return 1; 
  }

  int nResult = pCrashHandler->SetThreadExceptionHandlers(dwFlags);
  if(nResult!=0)
    return 2; // Error?

  // Ok.
  return 0;
}
コード例 #14
0
ファイル: CrashRpt.cpp プロジェクト: doo/CrashRpt
crUninstallFromCurrentThread()
{
  crSetErrorMsg(_T("Success."));

  CCrashHandler *pCrashHandler = 
    CCrashHandler::GetCurrentProcessCrashHandler();

  if(pCrashHandler==NULL)
  {
    ATLASSERT(pCrashHandler!=NULL);
    crSetErrorMsg(_T("Crash handler wasn't previously installed for current thread."));
    return 1; // Invalid parameter?
  }

  int nResult = pCrashHandler->UnSetThreadExceptionHandlers();
  if(nResult!=0)
    return 2; // Error?

  // OK.
  return 0;
}
コード例 #15
0
ファイル: CrashRpt.cpp プロジェクト: doo/CrashRpt
crAddVideo(
            DWORD dwFlags,
			int nDuration,
			int nFrameInterval,
            SIZE* pDesiredFrameSize,
			HWND hWndParent
            )
{
	crSetErrorMsg(_T("Unspecified error."));

	CCrashHandler *pCrashHandler = 
        CCrashHandler::GetCurrentProcessCrashHandler();

    if(pCrashHandler==NULL)
    {    
        crSetErrorMsg(_T("Crash handler wasn't previously installed for current process."));
        return 1; // Invalid parameter?
    }

    return pCrashHandler->AddVideo(dwFlags, nDuration, nFrameInterval, pDesiredFrameSize, hWndParent);
}
コード例 #16
0
ファイル: CrashRpt.cpp プロジェクト: cedral/crashrptex
crInstallToCurrentThread2(DWORD dwFlags)
{
    crSetErrorMsg(_T("Success."));

    CCrashHandler *pCrashHandler = 
        CCrashHandler::GetCurrentProcessCrashHandler();

    if(pCrashHandler==NULL)
    {
	    // AS: Correction of error message    
        crSetErrorMsg(_T("Crash handler not installed for this process."));
        return 1; 
    }

    int nResult = pCrashHandler->SetThreadExceptionHandlers(dwFlags);
    if(nResult!=0)
        return 2; // Error?

    // Ok.
    return 0;
}
コード例 #17
0
ファイル: CrashRpt.cpp プロジェクト: doo/CrashRpt
crSetCrashCallbackA(   
             PFNCRASHCALLBACKA pfnCallbackFunc,
			 LPVOID lpParam
             )
{
	crSetErrorMsg(_T("Unspecified error."));

	CCrashHandler *pCrashHandler = 
        CCrashHandler::GetCurrentProcessCrashHandler();

    if(pCrashHandler==NULL)
    {    
        crSetErrorMsg(_T("Crash handler wasn't previously installed for current process."));
        return 1; // No handler installed for current process?
    }

	pCrashHandler->SetCrashCallbackA(pfnCallbackFunc, lpParam);

	// OK
	crSetErrorMsg(_T("Success."));
	return 0;
}
コード例 #18
0
ファイル: CrashHandler.cpp プロジェクト: doo/CrashRpt
int CCrashHandler::AddFile(LPCTSTR pszFile, LPCTSTR pszDestFile, LPCTSTR pszDesc, DWORD dwFlags)
{
  crSetErrorMsg(_T("Unspecified error."));

  // make sure the file exist
  struct _stat st;
  int result = _tstat(pszFile, &st);

  if (result!=0 && (dwFlags&CR_AF_MISSING_FILE_OK)==0)
  {
   ATLASSERT(0);
   crSetErrorMsg(_T("Couldn't stat file. File may not exist."));
   return 1;
  }

  // Add file to file list.
  FileItem fi;
  fi.m_sDescription = pszDesc;
  fi.m_sFileName = pszFile;
  fi.m_bMakeCopy = (dwFlags&CR_AF_MAKE_FILE_COPY)!=0;
  if(pszDestFile!=NULL)
    m_files[pszDestFile] = fi;
  else
  {
    CString sDestFile = pszFile;
    int pos = -1;
    sDestFile.Replace('/', '\\');
    pos = sDestFile.ReverseFind('\\');
    if(pos!=-1)
      sDestFile = sDestFile.Mid(pos+1);

    m_files[sDestFile] = fi;
  }

  // OK.
  crSetErrorMsg(_T("Success."));
  return 0;
}
コード例 #19
0
ファイル: CrashHandler.cpp プロジェクト: doo/CrashRpt
int CCrashHandler::UnSetProcessExceptionHandlers()
{
  crSetErrorMsg(_T("Unspecified error."));

  // Unset all previously set handlers

#if _MSC_VER>=1300
  if(m_prevPurec!=NULL)
    _set_purecall_handler(m_prevPurec);

  if(m_prevNewHandler!=NULL)
    _set_new_handler(m_prevNewHandler);
#endif

#if _MSC_VER>=1400
  if(m_prevInvpar!=NULL)
    _set_invalid_parameter_handler(m_prevInvpar);
#endif //_MSC_VER>=1400  

#if _MSC_VER>=1300 && _MSC_VER<1400    
  if(m_prevSec!=NULL)
    _set_security_error_handler(m_prevSec);
#endif //_MSC_VER<1400
     
  if(m_prevSigABRT!=NULL)
    signal(SIGABRT, m_prevSigABRT);  
  
  if(m_prevSigINT!=NULL)
    signal(SIGINT, m_prevSigINT);     

  if(m_prevSigTERM!=NULL)
   signal(SIGTERM, m_prevSigTERM);    

  crSetErrorMsg(_T("Success."));
  return 0;
}
コード例 #20
0
ファイル: CrashRpt.cpp プロジェクト: cedral/crashrptex
crExceptionFilter(unsigned int code, struct _EXCEPTION_POINTERS* ep)
{
    crSetErrorMsg(_T("Unspecified error."));

    CCrashHandler *pCrashHandler = 
        CCrashHandler::GetCurrentProcessCrashHandler();

    if(pCrashHandler==NULL)
    {    
        crSetErrorMsg(_T("Crash handler wasn't previously installed for current process."));
        return EXCEPTION_CONTINUE_SEARCH; 
    }

#ifdef CRASHRPT_EX
    // AS: Unless the user will indeed check for the user choice this makes no real
    //     sense here.
    //     We assume that the execute_handler does what it should -> close the app.
    pCrashHandler ->AllowContinue(0);
#endif
    CR_EXCEPTION_INFO ei;
    memset(&ei, 0, sizeof(CR_EXCEPTION_INFO));
    ei.cb = sizeof(CR_EXCEPTION_INFO);  
    ei.exctype = CR_SEH_EXCEPTION;
    ei.pexcptrs = ep;
    ei.code = code;

    int res = pCrashHandler->GenerateErrorReport(&ei);
    if(res!=0)
    {
        // If goes here than GenerateErrorReport() failed  
        return EXCEPTION_CONTINUE_SEARCH;  
    }  

    crSetErrorMsg(_T("Success."));
    return EXCEPTION_EXECUTE_HANDLER;  
}
コード例 #21
0
ファイル: CrashRpt.cpp プロジェクト: doo/CrashRpt
CRASHRPTAPI(int) crUninstall()
{
    crSetErrorMsg(_T("Success."));

	// Get crash handler singleton
    CCrashHandler *pCrashHandler = 
        CCrashHandler::GetCurrentProcessCrashHandler();

	// Check if found
    if(pCrashHandler==NULL ||
        !pCrashHandler->IsInitialized())
    {     
        crSetErrorMsg(_T("Crash handler wasn't preiviously installed for this process."));
        return 1; 
    }

    // Uninstall main thread's C++ exception handlers
    int nUnset = pCrashHandler->UnSetThreadExceptionHandlers();
    if(nUnset!=0)
        return 2;

	// Destroy the crash handler.
    int nDestroy = pCrashHandler->Destroy();
    if(nDestroy!=0)
        return 3;

	// Free the crash handler object.
    delete pCrashHandler;

	// Clear last error message list.
	g_cs.Lock();
    g_sErrorMsg.clear();
    g_cs.Unlock();

    return 0;
}
コード例 #22
0
ファイル: CrashHandler.cpp プロジェクト: doo/CrashRpt
int CCrashHandler::Init(
  LPCTSTR lpcszAppName,
  LPCTSTR lpcszAppVersion,
  LPCTSTR lpcszCrashSenderPath,
  LPGETLOGFILE lpfnCallback, 
  LPCTSTR lpcszTo, 
  LPCTSTR lpcszSubject,
  LPCTSTR lpcszUrl,
  UINT (*puPriorities)[5],
  DWORD dwFlags,
  LPCTSTR lpcszPrivacyPolicyURL)
{ 
  crSetErrorMsg(_T("Unspecified error."));
  
  // save user supplied callback
  if (lpfnCallback)
    m_lpfnCallback = lpfnCallback;

  // Get handle to the EXE module used to create this process
  HMODULE hExeModule = GetModuleHandle(NULL);
  if(hExeModule==NULL)
  {
    ATLASSERT(hExeModule!=NULL);
    crSetErrorMsg(_T("Couldn't get module handle for the executable."));
    return 1;
  }

  TCHAR szExeName[_MAX_PATH];
  DWORD dwLength = GetModuleFileName(hExeModule, szExeName, _MAX_PATH);  
  if(dwLength==0)
  {
    // Couldn't get the name of EXE that was used to create current process
    ATLASSERT(0);
    crSetErrorMsg(_T("Couldn't get the name of EXE that was used to create current process."));
    return 1;
  }  

  // Save EXE image name
  m_sImageName = CString(szExeName, dwLength);

  // Save application name
  m_sAppName = lpcszAppName;

  // If no app name provided, use the default (EXE name)
  if(m_sAppName.IsEmpty())
    m_sAppName = CUtility::getAppName();

  // Save app version
  m_sAppVersion = lpcszAppVersion;

  // If no app version provided, use the default (EXE product version)
  if(m_sAppVersion.IsEmpty())
  {
    DWORD dwBuffSize = GetFileVersionInfoSize(szExeName, 0);
    LPBYTE pBuff = new BYTE[dwBuffSize];
    
    if(0!=GetFileVersionInfo(szExeName, 0, dwBuffSize, pBuff))
    {
      VS_FIXEDFILEINFO* fi = NULL;
      UINT uLen = 0;
      VerQueryValue(pBuff, _T("\\"), (LPVOID*)&fi, &uLen);

      WORD dwVerMajor = (WORD)(fi->dwProductVersionMS>>16);
      WORD dwVerMinor = (WORD)(fi->dwProductVersionMS&0xFF);
      WORD dwPatchLevel = (WORD)(fi->dwProductVersionLS>>16);
      WORD dwVerBuild = (WORD)(fi->dwProductVersionLS&0xFF);

      m_sAppVersion.Format(_T("%u.%u.%u.%u"), 
        dwVerMajor, dwVerMinor, dwPatchLevel, dwVerBuild);
    }
コード例 #23
0
ファイル: CrashHandler.cpp プロジェクト: doo/CrashRpt
int CCrashHandler::CreateInternalCrashInfoFile(CString sFileName, EXCEPTION_POINTERS* pExInfo)
{
  crSetErrorMsg(_T("Unspecified error."));
  
  strconv_t strconv;  

  DWORD dwProcessId = GetCurrentProcessId();
  DWORD dwThreadId = GetCurrentThreadId();

  FILE* f = NULL;

#if _MSC_VER>=1400
  _tfopen_s(&f, sFileName, _T("wt"));
#else
  f = _tfopen(sFileName, _T("wt"));
#endif
  
  if(f==NULL)
  {
    crSetErrorMsg(_T("Couldn't create internal crash info file."));
    return 1; // Couldn't create file
  }
  
  // Add <?xml version="1.0" encoding="utf-8" ?> element
  fprintf(f, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");

  // Add root element
  fprintf(f, "<CrashRptInternal version=\"%d\">\n", CRASHRPT_VER);

  // Add CrashGUID tag
  fprintf(f, "  <CrashGUID>%s</CrashGUID>\n", 
    XmlEncodeStr(m_sCrashGUID).c_str());

  // Add ReportFolder tag
  fprintf(f, "  <ReportFolder>%s</ReportFolder>\n", 
    XmlEncodeStr(m_sReportFolderName).c_str());

  // Add DbgHelpPath tag
  fprintf(f, "  <DbgHelpPath>%s</DbgHelpPath>\n", 
    XmlEncodeStr(m_sPathToDebugHelpDll).c_str());

  // Add MinidumpType tag
  fprintf(f, "  <MinidumpType>%lu</MinidumpType>\n", m_MiniDumpType);

  // Add ProcessId tag
  fprintf(f, "  <ProcessId>%lu</ProcessId>\n", dwProcessId);

  // Add ThreadId tag
  fprintf(f, "  <ThreadId>%lu</ThreadId>\n", dwThreadId);

  // Add ExceptionPointersAddress tag
  fprintf(f, "  <ExceptionPointersAddress>%p</ExceptionPointersAddress>\n", pExInfo);

  // Add EmailSubject tag
  fprintf(f, "  <EmailSubject>%s</EmailSubject>\n", 
    XmlEncodeStr(m_sEmailSubject).c_str());

  // Add EmailTo tag
  fprintf(f, "  <EmailTo>%s</EmailTo>\n", 
    XmlEncodeStr(m_sEmailTo).c_str());

  // Add EmailText tag
  fprintf(f, "  <EmailText>%s</EmailText>\n", 
    XmlEncodeStr(m_sEmailText).c_str());

  // Add SmtpPort tag
  fprintf(f, "  <SmtpPort>%d</SmtpPort>\n", m_nSmtpPort);

  // Add SmtpProxyServer tag
  fprintf(f, "  <SmtpProxyServer>%s</SmtpProxyServer>\n", 
    XmlEncodeStr(m_sSmtpProxyServer).c_str());

  // Add SmtpProxyPort tag
  fprintf(f, "  <SmtpProxyPort>%d</SmtpProxyPort>\n", m_nSmtpProxyPort);

  // Add Url tag
  fprintf(f, "  <Url>%s</Url>\n", 
    XmlEncodeStr(m_sUrl).c_str());

  // Add PrivacyPolicyUrl tag
  fprintf(f, "  <PrivacyPolicyUrl>%s</PrivacyPolicyUrl>\n", 
    XmlEncodeStr(m_sPrivacyPolicyURL).c_str());

  // Add HttpPriority tag
  fprintf(f, "  <HttpPriority>%d</HttpPriority>\n", m_uPriorities[CR_HTTP]);

  // Add SmtpPriority tag
  fprintf(f, "  <SmtpPriority>%d</SmtpPriority>\n", m_uPriorities[CR_SMTP]);

  // Add MapiPriority tag
  fprintf(f, "  <MapiPriority>%d</MapiPriority>\n", m_uPriorities[CR_SMAPI]);

  // Add AddScreenshot tag
  fprintf(f, "  <AddScreenshot>%d</AddScreenshot>\n", m_bAddScreenshot);

  // Add ScreenshotFlags tag
  fprintf(f, "  <ScreenshotFlags>%lu</ScreenshotFlags>\n", m_dwScreenshotFlags);

  // Add AppWindowRect tag
  fprintf(f, "  <AppWindowRect left=\"%d\" top=\"%d\" right=\"%d\" bottom=\"%d\" />\n", 
    m_rcAppWnd.left, m_rcAppWnd.top, m_rcAppWnd.right, m_rcAppWnd.bottom);

  // Add CursorPos tag
  fprintf(f, "  <CursorPos x=\"%d\" y=\"%d\" />\n", 
    m_ptCursorPos.x, m_ptCursorPos.y);

  // Add MultiPartHttpUploads tag
  fprintf(f, "  <HttpBinaryEncoding>%d</HttpBinaryEncoding>\n", m_bHttpBinaryEncoding);

  // Add SilentMode tag
  fprintf(f, "  <SilentMode>%d</SilentMode>\n", m_bSilentMode);

  // Add SendErrorReport tag
  fprintf(f, "  <SendErrorReport>%d</SendErrorReport>\n", m_bSendErrorReport);

  // Add AppRestart tag
  fprintf(f, "  <AppRestart>%d</AppRestart>\n", m_bAppRestart);

  // Add RestartCmdLine tag
  fprintf(f, "  <RestartCmdLine>%s</RestartCmdLine>\n", 
    XmlEncodeStr(m_sRestartCmdLine).c_str());

  // Add GenerateMinidump tag
  fprintf(f, "  <GenerateMinidump>%d</GenerateMinidump>\n", m_bGenerateMinidump);

  // Add LangFileName tag
  fprintf(f, "  <LangFileName>%s</LangFileName>\n", 
    XmlEncodeStr(m_sLangFileName).c_str());

  // Write file list
  fprintf(f, "  <FileList>\n");
   
  std::map<CString, FileItem>::iterator it;
  for(it=m_files.begin(); it!=m_files.end(); it++)
  {
    fprintf(f, "    <FileItem destfile=\"%s\" srcfile=\"%s\" description=\"%s\" makecopy=\"%d\" />\n",
      XmlEncodeStr(it->first).c_str(), 
      XmlEncodeStr(it->second.m_sFileName).c_str(), 
      XmlEncodeStr(it->second.m_sDescription).c_str(), 
      it->second.m_bMakeCopy?1:0 );    
  }

  fprintf(f, "  </FileList>\n");
  
  fprintf(f, "</CrashRptInternal>\n");

  fclose(f);

  crSetErrorMsg(_T("Success."));
  return 0;
}
コード例 #24
0
ファイル: CrashHandler.cpp プロジェクト: doo/CrashRpt
int CCrashHandler::CreateCrashDescriptionXML(
	LPTSTR pszFileName,          
    PCR_EXCEPTION_INFO pExceptionInfo)
{
  crSetErrorMsg(_T("Unspecified error."));

  strconv_t strconv;  
  FILE* f = NULL;

#if _MSC_VER>=1400
  _tfopen_s(&f, pszFileName, _T("wt"));
#else
  f = _tfopen(pszFileName, _T("wt"));
#endif
  
  if(f==NULL)
    return 1; // Couldn't create file

  // Add <?xml version="1.0" encoding="utf-8" ?> element
  fprintf(f, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");

  // Add root element
  fprintf(f, "<CrashRpt version=\"%d\">\n", CRASHRPT_VER);
  
  // Write crash GUID
  fprintf(f, "  <CrashGUID>%s</CrashGUID>\n", 
    XmlEncodeStr(m_sCrashGUID.GetBuffer(0)).c_str());

  // Write application name 
  fprintf(f, "  <AppName>%s</AppName>\n", 
    XmlEncodeStr(m_sAppName.GetBuffer(0)).c_str());

  // Write application version 
  fprintf(f, "  <AppVersion>%s</AppVersion>\n", 
    XmlEncodeStr(m_sAppVersion.GetBuffer(0)).c_str());
  
  // Write EXE image name
  fprintf(f, "  <ImageName>%s</ImageName>\n", 
    XmlEncodeStr(m_sImageName.GetBuffer(0)).c_str());

  // Write operating system friendly name  
  fprintf(f, "  <OperatingSystem>%s</OperatingSystem>\n", 
    XmlEncodeStr(m_sOSName.GetBuffer(0)).c_str());
  
  // Write system time in UTC format
  fprintf(f, "  <SystemTimeUTC>%s</SystemTimeUTC>\n", 
    XmlEncodeStr(m_sCrashTime.GetBuffer(0)).c_str());
  
  // Write exception type
  fprintf(f, "  <ExceptionType>%d</ExceptionType>\n", 
    pExceptionInfo->exctype);

  if(pExceptionInfo->exctype==CR_SEH_EXCEPTION)
  {
    // Write exception code
    fprintf(f, "  <ExceptionCode>0x%X</ExceptionCode>\n", 
      pExceptionInfo->pexcptrs->ExceptionRecord->ExceptionCode);
  }

  if(pExceptionInfo->exctype==CR_CPP_SIGFPE)
  {
    // Write FPE exception subcode
    fprintf(f, "  <FPESubcode>%d</FPESubcode>\n", 
      pExceptionInfo->fpe_subcode);
  }

#if _MSC_VER>=1400
  if(pExceptionInfo->exctype==CR_CPP_INVALID_PARAMETER)
  {
    if(pExceptionInfo->expression!=NULL)
    {
      // Write expression      
      fprintf(f, "  <InvParamExpression>%s</InvParamExpression>\n", 
        XmlEncodeStr(pExceptionInfo->expression).c_str());
    }

    if(pExceptionInfo->function!=NULL)
    {
      // Write function      
      fprintf(f, "  <InvParamFunction>%s</InvParamFunction>\n", 
        XmlEncodeStr(pExceptionInfo->function).c_str());
    }

    if(pExceptionInfo->file!=NULL)
    {
      // Write file
      fprintf(f, "  <InvParamFile>%s</InvParamFile>\n", 
        XmlEncodeStr(pExceptionInfo->file).c_str());

      // Write line number
      fprintf(f, "  <InvParamLine>%d</InvParamLine>\n", 
        pExceptionInfo->line);
    }    
  }
#endif 

  // Write the number of GUI resources in use
  fprintf(f, "  <GUIResourceCount>%lu</GUIResourceCount>\n", 
      m_dwGuiResources);

  // Write count of open handles that belong to current process
  fprintf(f, "  <OpenHandleCount>%lu</OpenHandleCount>\n", 
    m_dwProcessHandleCount);  

  // Write memory usage info
  fprintf(f, "  <MemoryUsageKbytes>%s</MemoryUsageKbytes>\n", 
    XmlEncodeStr(m_sMemUsage.GetBuffer(0)).c_str());  

  // Write list of custom user-added properties
  fprintf(f, "  <CustomProps>\n");
  
  std::map<CString, CString>::iterator pit = m_props.begin();
  unsigned i;
  for (i = 0; i < m_props.size(); i++, pit++)
  {    
    CString sPropName = pit->first;
    CString sPropValue = pit->second;

    fprintf(f, "    <Prop name=\"%s\" value=\"%s\" />\n",
      XmlEncodeStr(sPropName).c_str(), XmlEncodeStr(sPropValue).c_str());
  }

  fprintf(f, "  </CustomProps>\n");
  
  // Write list of files that present in this crash report

  fprintf(f, "  <FileList>\n");
  
  std::map<CString, FileItem>::iterator cur = m_files.begin();
  for (i = 0; i < m_files.size(); i++, cur++)
  {    
    CString sDestFile = (*cur).first;

    int pos = -1;
    sDestFile.Replace('/', '\\');
    pos = sDestFile.ReverseFind('\\');
    if(pos!=-1)
      sDestFile = sDestFile.Mid(pos+1);

    FileItem& fi = cur->second;

    fprintf(f, "    <FileItem name=\"%s\" description=\"%s\" />\n",
      XmlEncodeStr(sDestFile).c_str(), XmlEncodeStr(fi.m_sDescription).c_str());  
  }

  fprintf(f, "  </FileList>\n");

  fprintf(f, "</CrashRpt>\n");

  fclose(f);  

  crSetErrorMsg(_T("Success."));
  return 0;
}
コード例 #25
0
ファイル: CrashHandler.cpp プロジェクト: doo/CrashRpt
int CCrashHandler::SetProcessExceptionHandlers(DWORD dwFlags)
{
  crSetErrorMsg(_T("Unspecified error."));

  // If 0 is specified as dwFlags, assume all handlers should be
  // installed
  if((dwFlags&0x1FF)==0)
    dwFlags |= 0x1FFF;
  
  if(dwFlags&CR_INST_STRUCTURED_EXCEPTION_HANDLER)
  {
    // Install top-level SEH handler
    m_oldSehHandler = SetUnhandledExceptionFilter(SehHandler);    
  }

  _set_error_mode(_OUT_TO_STDERR);

#if _MSC_VER>=1300
  if(dwFlags&CR_INST_PURE_CALL_HANDLER)
  {
    // Catch pure virtual function calls.
    // Because there is one _purecall_handler for the whole process, 
    // calling this function immediately impacts all threads. The last 
    // caller on any thread sets the handler. 
    // http://msdn.microsoft.com/en-us/library/t296ys27.aspx
    m_prevPurec = _set_purecall_handler(PureCallHandler);    
  }

  if(dwFlags&CR_INST_NEW_OPERATOR_ERROR_HANDLER)
  {
    // Catch new operator memory allocation exceptions
    _set_new_mode(1); // Force malloc() to call new handler too
    m_prevNewHandler = _set_new_handler(NewHandler);
  }
#endif

#if _MSC_VER>=1400
  if(dwFlags&CR_INST_INVALID_PARAMETER_HANDLER)
  {
    // Catch invalid parameter exceptions.
    m_prevInvpar = _set_invalid_parameter_handler(InvalidParameterHandler); 
  }
#endif


#if _MSC_VER>=1300 && _MSC_VER<1400    
  if(dwFlags&CR_INST_SECURITY_ERROR_HANDLER)
  {
    // Catch buffer overrun exceptions
    // The _set_security_error_handler is deprecated in VC8 C++ run time library
    m_prevSec = _set_security_error_handler(SecurityHandler);
  }
#endif

   // Set up C++ signal handlers
  
  
  if(dwFlags&CR_INST_SIGABRT_HANDLER)
  {
#if _MSC_VER>=1400  
  _set_abort_behavior(_CALL_REPORTFAULT, _CALL_REPORTFAULT);
#endif
  // Catch an abnormal program termination
  m_prevSigABRT = signal(SIGABRT, SigabrtHandler);  
  }
   
  if(dwFlags&CR_INST_SIGILL_HANDLER)
  {
    // Catch illegal instruction handler
    m_prevSigINT = signal(SIGINT, SigintHandler);     
  }
  
  if(dwFlags&CR_INST_TERMINATE_HANDLER)
  {
    // Catch a termination request
    m_prevSigTERM = signal(SIGTERM, SigtermHandler);          
  }

  crSetErrorMsg(_T("Success."));
  return 0;
}
コード例 #26
0
ファイル: CrashHandler.cpp プロジェクト: doo/CrashRpt
// Installs C++ exception handlers that function on per-thread basis
int CCrashHandler::SetThreadExceptionHandlers(DWORD dwFlags)
{
  crSetErrorMsg(_T("Unspecified error."));

  // If 0 is specified as dwFlags, assume all available exception handlers should be
  // installed  
  if((dwFlags&0x1FFF)==0)
    dwFlags |= 0x1FFF;

  DWORD dwThreadId = GetCurrentThreadId();

  CAutoLock lock(&m_csThreadExceptionHandlers);

  std::map<DWORD, ThreadExceptionHandlers>::iterator it = 
    m_ThreadExceptionHandlers.find(dwThreadId);

  if(it!=m_ThreadExceptionHandlers.end())
  {
    // handlers are already set for the thread
    ATLASSERT(0);
    crSetErrorMsg(_T("Can't install handlers for current thread twice."));
    return 1; // failed
  }
  
  ThreadExceptionHandlers handlers;

  if(dwFlags&CR_INST_TERMINATE_HANDLER)
  {
    // Catch terminate() calls. 
    // In a multithreaded environment, terminate functions are maintained 
    // separately for each thread. Each new thread needs to install its own 
    // terminate function. Thus, each thread is in charge of its own termination handling.
    // http://msdn.microsoft.com/en-us/library/t6fk7h29.aspx
    handlers.m_prevTerm = set_terminate(TerminateHandler);       
  }

  if(dwFlags&CR_INST_UNEXPECTED_HANDLER)
  {
    // Catch unexpected() calls.
    // In a multithreaded environment, unexpected functions are maintained 
    // separately for each thread. Each new thread needs to install its own 
    // unexpected function. Thus, each thread is in charge of its own unexpected handling.
    // http://msdn.microsoft.com/en-us/library/h46t5b69.aspx  
    handlers.m_prevUnexp = set_unexpected(UnexpectedHandler);    
  }

  if(dwFlags&CR_INST_SIGFPE_HANDLER)
  {
    // Catch a floating point error
    typedef void (*sigh)(int);
    handlers.m_prevSigFPE = signal(SIGFPE, (sigh)SigfpeHandler);     
  }

  
  if(dwFlags&CR_INST_SIGILL_HANDLER)
  {
    // Catch an illegal instruction
    handlers.m_prevSigILL = signal(SIGILL, SigillHandler);     
  }

  if(dwFlags&CR_INST_SIGSEGV_HANDLER)
  {
    // Catch illegal storage access errors
    handlers.m_prevSigSEGV = signal(SIGSEGV, SigsegvHandler);   
  }

  // Insert the structure to the list of handlers  
  m_ThreadExceptionHandlers[dwThreadId] = handlers;

  // OK.
  crSetErrorMsg(_T("Success."));
  return 0;
}
コード例 #27
0
ファイル: CrashHandler.cpp プロジェクト: doo/CrashRpt
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; 
}
コード例 #28
0
ファイル: CrashHandler.cpp プロジェクト: doo/CrashRpt
int CCrashHandler::Init(
  LPCTSTR lpcszAppName,
  LPCTSTR lpcszAppVersion,
  LPCTSTR lpcszCrashSenderPath,
  LPGETLOGFILE lpfnCallback, 
  LPCTSTR lpcszTo, 
  LPCTSTR lpcszSubject,
  LPCTSTR lpcszUrl,
  UINT (*puPriorities)[5],
  DWORD dwFlags,
  LPCTSTR lpcszPrivacyPolicyURL,
  LPCTSTR lpcszDebugHelpDLLPath,
  MINIDUMP_TYPE MiniDumpType,
  LPCTSTR lpcszErrorReportSaveDir,
  LPCTSTR lpcszRestartCmdLine,
  LPCTSTR lpcszLangFilePath,
  LPCTSTR lpcszEmailText,
  LPCTSTR lpcszSmtpProxy)
{ 
  crSetErrorMsg(_T("Unspecified error."));
  
  // Save application start time
  GetSystemTime(&m_AppStartTime);

  // Save minidump type
  m_bGenerateMinidump = (dwFlags&CR_INST_NO_MINIDUMP)?FALSE:TRUE;
  m_MiniDumpType = MiniDumpType;

  // Determine if should work in silent mode. FALSE is the default.
  m_bSilentMode = (dwFlags&CR_INST_NO_GUI)?TRUE:FALSE;

  // Save user supplied callback
  m_lpfnCallback = lpfnCallback;
  
  // Get handle to the EXE module used to create this process
  HMODULE hExeModule = GetModuleHandle(NULL);
  if(hExeModule==NULL)
  {
    ATLASSERT(hExeModule!=NULL);
    crSetErrorMsg(_T("Couldn't get module handle for the executable."));
    return 1;
  }

  // Save EXE image name
  m_sImageName = Utility::GetModuleName(hExeModule);

  // Save application name
  m_sAppName = lpcszAppName;

  // If no app name provided, use the default (EXE name)
  if(m_sAppName.IsEmpty())
  {
    m_sAppName = Utility::getAppName();
  }

  // Save app version
  m_sAppVersion = lpcszAppVersion;

  // If no app version provided, use the default (EXE product version)
  if(m_sAppVersion.IsEmpty())
  {
    m_sAppVersion = Utility::GetProductVersion(m_sImageName);
  }

  // Save URL to send reports via HTTP
  if(lpcszUrl!=NULL)
  {
    m_sUrl = CString(lpcszUrl);
  }

  // Determine what encoding to use when sending reports over HTTP.
  // FALSE is the default (use Base64 encoding for attachment).
  m_bHttpBinaryEncoding = (dwFlags&CR_INST_HTTP_BINARY_ENCODING)?TRUE:FALSE;

  m_bSendErrorReport = (dwFlags&CR_INST_DONT_SEND_REPORT)?FALSE:TRUE;

  if(!m_bSilentMode && !m_bSendErrorReport)
  {    
    crSetErrorMsg(_T("Can't disable error sending when in GUI mode (incompatible flags specified)."));
    return 1;
  }

  m_bAppRestart = (dwFlags&CR_INST_APP_RESTART)?TRUE:FALSE;
  m_sRestartCmdLine = lpcszRestartCmdLine;

  // Save Email recipient address
  m_sEmailTo = lpcszTo;
  m_nSmtpPort = 25;
  
  // Check for custom SMTP port
  int pos = m_sEmailTo.ReverseFind(':');
  if(pos>=0)
  {
    CString sServer = m_sEmailTo.Mid(0, pos);
    CString sPort = m_sEmailTo.Mid(pos+1);
    m_sEmailTo = sServer;
    m_nSmtpPort = _ttoi(sPort);
  }

  if(lpcszSmtpProxy!=NULL)
  {
    m_sSmtpProxyServer = lpcszSmtpProxy;  
    m_nSmtpProxyPort = 25;
    int pos = m_sSmtpProxyServer.ReverseFind(':');
    if(pos>=0)
    {
      CString sServer = m_sSmtpProxyServer.Mid(0, pos);
      CString sPort = m_sSmtpProxyServer.Mid(pos+1);
      m_sSmtpProxyServer = sServer;
      m_nSmtpProxyPort = _ttoi(sPort);
    }
  }

  // Save E-mail subject
  m_sEmailSubject = lpcszSubject;

  // If the subject is empty...
  if(m_sEmailSubject.IsEmpty())
  {
    // Generate the default subject
    m_sEmailSubject.Format(_T("%s %s Error Report"), m_sAppName, 
      m_sAppVersion.IsEmpty()?_T("[unknown_ver]"):m_sAppVersion);
  }

  // Save Email text.
  m_sEmailText = lpcszEmailText;

  // Save report sending priorities
  if(puPriorities!=NULL)
    memcpy(&m_uPriorities, puPriorities, 3*sizeof(UINT));
  else
    memset(&m_uPriorities, 0, 3*sizeof(UINT));

  // Save privacy policy URL (if exists)
  if(lpcszPrivacyPolicyURL!=NULL)
    m_sPrivacyPolicyURL = lpcszPrivacyPolicyURL;

  // Get the name of CrashRpt DLL
  LPTSTR pszCrashRptModule = NULL;

#ifndef CRASHRPT_LIB
  #ifdef _DEBUG
    pszCrashRptModule = _T("CrashRptd.dll");
  #else
    pszCrashRptModule = _T("CrashRpt.dll");
  #endif //_DEBUG
#else //!CRASHRPT_LIB
  pszCrashRptModule = NULL;
#endif

  // Get handle to the CrashRpt module that is loaded by the current process
  HMODULE hCrashRptModule = GetModuleHandle(pszCrashRptModule);
  if(hCrashRptModule==NULL)
  {
    ATLASSERT(hCrashRptModule!=NULL);
    crSetErrorMsg(_T("Couldn't get handle to CrashRpt.dll."));
    return 1;
  }  
  
  // Save path to CrashSender.exe
  if(lpcszCrashSenderPath==NULL)
  {
    // By default assume that CrashSender.exe is located in the same dir as CrashRpt.dll
    m_sPathToCrashSender = Utility::GetModulePath(hCrashRptModule);   
  }
  else
  {
    // Save user-specified path
    m_sPathToCrashSender = CString(lpcszCrashSenderPath);    
  }

  // Remove ending backslash if any
  if(m_sPathToCrashSender.Right(1)!='\\')
      m_sPathToCrashSender+="\\";
    
  // Determine where to look for language file.
  if(lpcszLangFilePath!=NULL)
  {
    // User has provided the custom lang file path.
    m_sLangFileName = lpcszLangFilePath;
  }
  else
  {
    // Look for crashrpt_lang.ini in the same folder as CrashSender.exe.
    m_sLangFileName = m_sPathToCrashSender + _T("crashrpt_lang.ini");
  }
  
  CString sLangFileVer = Utility::GetINIString(m_sLangFileName, _T("Settings"), _T("CrashRptVersion"));
  int lang_file_ver = _ttoi(sLangFileVer);
  if(lang_file_ver!=CRASHRPT_VER)
  {
    ATLASSERT(lang_file_ver==CRASHRPT_VER);
    crSetErrorMsg(_T("Missing language file or wrong language file version."));
    return 1; // Language INI file has wrong version!
  }

  // Get CrashSender EXE name
  CString sCrashSenderName;

#ifdef _DEBUG
  sCrashSenderName = _T("CrashSenderd.exe");
#else
  sCrashSenderName = _T("CrashSender.exe");
#endif //_DEBUG

  m_sPathToCrashSender+=sCrashSenderName;   

  // Check that CrashSender.exe file exists
  HANDLE hFile = CreateFile(m_sPathToCrashSender, FILE_GENERIC_READ, 
    FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);  
  if(hFile==INVALID_HANDLE_VALUE)
  {
    ATLASSERT(hFile!=INVALID_HANDLE_VALUE);
    crSetErrorMsg(_T("Couldn't locate CrashSender.exe in specified directory."));
    return 1; // CrashSender not found!
  }
  CloseHandle(hFile);

  if(lpcszDebugHelpDLLPath==NULL)
  {
    // By default assume that debughlp.dll is located in the same dir as CrashRpt.dll
    m_sPathToDebugHelpDll = Utility::GetModulePath(hCrashRptModule);   
  }
  else
    m_sPathToDebugHelpDll = CString(lpcszDebugHelpDLLPath);    

  if(m_sPathToDebugHelpDll.Right(1)!='\\')
    m_sPathToDebugHelpDll+="\\";

  const CString sDebugHelpDLL_name = "dbghelp.dll";
  m_sPathToDebugHelpDll+=sDebugHelpDLL_name;

  m_hDbgHelpDll = LoadLibrary(m_sPathToDebugHelpDll);
  if(!m_hDbgHelpDll)
  {
    //try again ... fallback to dbghelp.dll in path
    m_hDbgHelpDll = LoadLibrary(sDebugHelpDLL_name);
    if(!m_hDbgHelpDll)
    {
      ATLASSERT(m_hDbgHelpDll);
      crSetErrorMsg(_T("Couldn't load dbghelp.dll."));      
      return 1;
    }
  }

  FreeLibrary(m_hDbgHelpDll);

  // Generate unique GUID for this crash report.
  if(0!=Utility::GenerateGUID(m_sCrashGUID))
  {
    ATLASSERT(0);
    crSetErrorMsg(_T("Couldn't generate crash GUID."));
    return 1; 
  }

  // Create event that will be used to synchronize with CrashSender.exe process
  CString sEventName;
  sEventName.Format(_T("Local\\CrashRptEvent_%s"), m_sCrashGUID);
  m_hEvent = CreateEvent(NULL, FALSE, FALSE, sEventName);
  if(m_hEvent==NULL)
  {
    ATLASSERT(0);
    crSetErrorMsg(_T("Couldn't create synchronization event."));
    return 1; 
  }

  // Get operating system friendly name.
  if(0!=Utility::GetOSFriendlyName(m_sOSName))
  {
    ATLASSERT(0);
    crSetErrorMsg(_T("Couldn't get operating system's friendly name."));
    return 1; 
  }

  if(lpcszErrorReportSaveDir==NULL)
  {
    // Create %LOCAL_APPDATA%\CrashRpt\UnsavedCrashReports\AppName_AppVer folder.
    CString sLocalAppDataFolder;
    DWORD dwCSIDL = CSIDL_LOCAL_APPDATA;
    Utility::GetSpecialFolder(dwCSIDL, sLocalAppDataFolder);
    m_sUnsentCrashReportsFolder.Format(_T("%s\\CrashRpt\\UnsentCrashReports\\%s_%s"), 
      sLocalAppDataFolder, m_sAppName, m_sAppVersion);
  }
  else
  {
    m_sUnsentCrashReportsFolder = lpcszErrorReportSaveDir;
  }

  BOOL bCreateDir = Utility::CreateFolder(m_sUnsentCrashReportsFolder);
  if(!bCreateDir)
  {
    ATLASSERT(0);
    crSetErrorMsg(_T("Couldn't create crash report directory."));
    return 1; 
  }
    
  // Save the name of the folder we will save this crash report (if occur)
  m_sReportFolderName = m_sUnsentCrashReportsFolder + _T("\\") + m_sCrashGUID;

  // Set exception handlers with initial values (NULLs)
  InitPrevExceptionHandlerPointers();
   
  // Set exception handlers that work on per-process basis
  int nSetProcessHandlers = SetProcessExceptionHandlers(dwFlags);   
  if(nSetProcessHandlers!=0)
  {
    ATLASSERT(nSetProcessHandlers==0);
    crSetErrorMsg(_T("Couldn't set C++ exception handlers for current process."));
    return 1;
  }

  // Set exception handlers that work on per-thread basis
  int nSetThreadHandlers = SetThreadExceptionHandlers(dwFlags);
  if(nSetThreadHandlers!=0)
  {
    ATLASSERT(nSetThreadHandlers==0);
    crSetErrorMsg(_T("Couldn't set C++ exception handlers for main execution thread."));
    return 1;
  }
  
  // Associate this handler with the caller process
  m_pProcessCrashHandler =  this;
  

  //LaunchCrashSender(_T("/resend"), FALSE);

  // OK.
  m_bInitialized = TRUE;
  crSetErrorMsg(_T("Success."));
  return 0;
}
コード例 #29
0
ファイル: CrashRpt.cpp プロジェクト: doo/CrashRpt
CRASHRPTAPI(int) crInstallW(CR_INSTALL_INFOW* pInfo)
{
  int nStatus = -1;
  crSetErrorMsg(_T("Success."));
  strconv_t strconv;
  CCrashHandler *pCrashHandler = NULL;

  // Validate input parameters.
  if(pInfo==NULL || 
     pInfo->cb!=sizeof(CR_INSTALL_INFOW))     
  {     
    crSetErrorMsg(_T("pInfo is NULL or pInfo->cb member is not valid."));
    nStatus = 1;
    goto cleanup;
  }

  // Check if crInstall() already was called for current process.
  pCrashHandler = CCrashHandler::GetCurrentProcessCrashHandler();

  if(pCrashHandler!=NULL &&
     pCrashHandler->IsInitialized())
  {    
    crSetErrorMsg(_T("Can't install crash handler to the same process twice."));
    nStatus = 2; 
    goto cleanup;
  }
  
  if(pCrashHandler==NULL)
  {
    pCrashHandler = new CCrashHandler();
    if(pCrashHandler==NULL)
    {    
      crSetErrorMsg(_T("Error allocating memory for crash handler."));
      nStatus = 3; 
      goto cleanup;
    }
  }
  
  LPCTSTR ptszAppName = strconv.w2t((LPWSTR)pInfo->pszAppName);
  LPCTSTR ptszAppVersion = strconv.w2t((LPWSTR)pInfo->pszAppVersion);
  LPCTSTR ptszCrashSenderPath = strconv.w2t((LPWSTR)pInfo->pszCrashSenderPath);
  LPCTSTR ptszEmailTo = strconv.w2t((LPWSTR)pInfo->pszEmailTo);
  LPCTSTR ptszEmailSubject = strconv.w2t((LPWSTR)pInfo->pszEmailSubject);
  LPCTSTR ptszUrl = strconv.w2t((LPWSTR)pInfo->pszUrl);
  LPCTSTR ptszPrivacyPolicyURL = strconv.w2t((LPWSTR)pInfo->pszPrivacyPolicyURL);
  LPCTSTR ptszDebugHelpDLL_file = strconv.w2t((LPWSTR)pInfo->pszDebugHelpDLL);
  MINIDUMP_TYPE miniDumpType = pInfo->uMiniDumpType;
  LPCTSTR ptszErrorReportSaveDir = strconv.w2t((LPWSTR)pInfo->pszErrorReportSaveDir);
  LPCTSTR ptszRestartCmdLine = strconv.w2t((LPWSTR)pInfo->pszRestartCmdLine);
  LPCTSTR ptszLangFilePath = strconv.w2t((LPWSTR)pInfo->pszLangFilePath);
  LPCTSTR ptszEmailText = strconv.w2t((LPWSTR)pInfo->pszEmailText);
  LPCTSTR ptszSmtpProxy = strconv.w2t((LPWSTR)pInfo->pszSmtpProxy);

  int nInitResult = pCrashHandler->Init(
    ptszAppName, 
    ptszAppVersion, 
    ptszCrashSenderPath,
    pInfo->pfnCrashCallback,
    ptszEmailTo,
    ptszEmailSubject,
    ptszUrl,
    &pInfo->uPriorities,
    pInfo->dwFlags,
    ptszPrivacyPolicyURL,
    ptszDebugHelpDLL_file,
    miniDumpType,
    ptszErrorReportSaveDir,
    ptszRestartCmdLine,
    ptszLangFilePath,
    ptszEmailText,
    ptszSmtpProxy
    );
  
  if(nInitResult!=0)
  {    
    nStatus = 4;
    goto cleanup;
  }

  // OK.
  nStatus = 0;

cleanup:
  
  if(nStatus!=0) // If failed
  {
    if(pCrashHandler!=NULL && 
       !pCrashHandler->IsInitialized())
    {
      // Release crash handler object
      CCrashHandler::ReleaseCurrentProcessCrashHandler();
    }
  }

  return nStatus;
}