BugSplat Native Windows DLL  3.6.0.0
BugSplat API reference for native Windows applications.
mdump.h
1 #include "dbghelp.h"
2 
3 #include "BugSplat.h"
4 #include "BugSplatImp.h"
5 
6 #include <vector>
7 #include <string>
8 
9 using namespace std;
10 
11 class SendReportProgressDlg;
12 
13 class MiniDumper;
14 
15 struct DumpData
16 {
17  LONG m_hRes;
18  MiniDumper* m_pMiniDumper;
19  CString m_strError;
20  struct _EXCEPTION_POINTERS * m_pExceptInfo;
21  DWORD m_dwThreadId;
22 };
23 
24 void getRegistryRoot(CString &str, const wchar_t * vendor, const wchar_t * app, const wchar_t * version);
25 
26 
27 //This class captures the total accumulated uptime of the application.
29 {
30 public:
31  TotalUptimeAndCrashCalculator(const wchar_t *szVendor, const wchar_t *szApp, const wchar_t *szVersion)
32  : m_strVendor((TCHAR *)szVendor)
33  , m_strApp((TCHAR *)szApp)
34  , m_strVersion((TCHAR *)szVersion)
35  {
36  GetSystemTime(&m_startTime);
37 
38  // Read the existing value from the registry and set the new value.
39  CString strRegRoot;
40  getRegistryRoot(strRegRoot, m_strVendor, m_strApp, m_strVersion);
41 
42  HKEY hKey;
43  LONG lErr = RegOpenKey(HKEY_CURRENT_USER, strRegRoot, &hKey);
44  if (ERROR_SUCCESS != lErr)
45  {
46  lErr = RegCreateKey(HKEY_CURRENT_USER, strRegRoot, &hKey);
47  }
48  if (ERROR_SUCCESS == lErr)
49  {
50  DWORD launchCount = 0L;
51  DWORD type;
52  DWORD size = sizeof(launchCount);
53  LONG ret = RegQueryValueEx(hKey, _T("LaunchCount"), 0, &type, (LPBYTE)&launchCount, &size);
54  if (ret != ERROR_SUCCESS) {
55  launchCount = 0L;
56  }
57  launchCount++;
58 
59  ret = RegSetValueEx(hKey, _T("LaunchCount"), 0, REG_DWORD, (LPBYTE)&launchCount, sizeof(launchCount));
60  ATLASSERT(ERROR_SUCCESS == ret);
61 
62  RegCloseKey(hKey);
63  return;
64  }
65  }
66 
68  {
69  }
70 
72  {
73  capture();
74  }
75 
76  _int64 Delta(const SYSTEMTIME st1, const SYSTEMTIME st2) {
77  union timeunion {
78  FILETIME fileTime;
79  ULARGE_INTEGER ul;
80  };
81 
82  timeunion ft1;
83  timeunion ft2;
84 
85  SystemTimeToFileTime(&st1, &ft1.fileTime);
86  SystemTimeToFileTime(&st2, &ft2.fileTime);
87 
88  return ft2.ul.QuadPart - ft1.ul.QuadPart;
89  }
90 
91  void capture(bool bIncrCrash=false)
92  {
93  // Get the uptime of the process
94  SYSTEMTIME endTime;
95  GetSystemTime(&endTime);
96 
97  // Find time until crash in seconds
98  _int64 toffset = Delta(m_startTime, endTime);
99  _int64 lgAdditionTimeInSecs = (toffset / 10000000);
100 
101  // Read the existing value from the registry and set the new value.
102  CString strRegRoot;
103  getRegistryRoot(strRegRoot, m_strVendor, m_strApp, m_strVersion);
104 
105  HKEY hKey;
106  LONG lErr = RegOpenKey(HKEY_CURRENT_USER, strRegRoot,&hKey);
107  if (ERROR_SUCCESS != lErr)
108  {
109  lErr = RegCreateKey(HKEY_CURRENT_USER, strRegRoot, &hKey);
110  }
111  if (ERROR_SUCCESS == lErr)
112  {
113  DWORD additionalTimeInSecs = (DWORD)(lgAdditionTimeInSecs);
114 
115  LONG ret = RegSetValueEx(hKey, _T("LaunchToLastCrashTime"), 0, REG_DWORD, (LPBYTE)&additionalTimeInSecs, sizeof(additionalTimeInSecs));
116  ATLASSERT(ERROR_SUCCESS == ret);
117 
118  DWORD uptime = 0L;
119  DWORD type;
120  DWORD size = sizeof(uptime);
121  ret = RegQueryValueEx(hKey, _T("TotalUptime"), 0, &type, (LPBYTE)&uptime, &size);
122  ATLASSERT(ERROR_FILE_NOT_FOUND == ret || ERROR_SUCCESS == ret);
123  ATLASSERT(ERROR_SUCCESS == ret);
124 
125  uptime += additionalTimeInSecs;
126  ret = RegSetValueEx(hKey, _T("TotalUptime"), 0, REG_DWORD, (LPBYTE)&uptime, sizeof(uptime));
127  ATLASSERT(ERROR_SUCCESS == ret);
128 
129  if (bIncrCrash)
130  {
131  DWORD crashCount = 0L;
132  size = sizeof(crashCount);
133  ret = RegQueryValueEx(hKey, _T("CrashCount"), 0, &type, (LPBYTE)&crashCount, &size);
134  if (ret != ERROR_SUCCESS) {
135  crashCount = 0L;
136  }
137  crashCount++;
138 
139  ret = RegSetValueEx(hKey, _T("CrashCount"), 0, REG_DWORD, (LPBYTE)&crashCount, sizeof(crashCount));
140  ATLASSERT(ERROR_SUCCESS == ret);
141  }
142 
143  RegCloseKey(hKey);
144  return;
145  }
146  //failure in RegOpenKey is ignorable, not all products enable CER
147  }
148 
149  DWORD getTotalTime()
150  {
151  //Get the existing value from the registry.
152  DWORD uptime = 0;
153  HKEY hKey;
154  CString strRegRoot;
155  getRegistryRoot(strRegRoot, m_strVendor, m_strApp, m_strVersion);
156  if (ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER, strRegRoot,&hKey))
157  {
158  DWORD type;
159  DWORD size = sizeof(uptime);
160  LONG ret = RegQueryValueEx(hKey, _T("TotalUptime"), 0, &type, (LPBYTE)&uptime, &size);
161  ATLASSERT(ERROR_SUCCESS == ret);
162  RegCloseKey(hKey);
163  }
164  else
165  {
166  ATLASSERT(false);//shouldn't get here
167  }
168  return uptime;
169  }
170  DWORD getCrashCount()
171  {
172  //Get the existing value from the registry.
173  DWORD crashCount = 0;
174  HKEY hKey;
175  CString strRegRoot;
176  getRegistryRoot(strRegRoot, m_strVendor, m_strApp, m_strVersion);
177  if (ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER, strRegRoot,&hKey))
178  {
179  DWORD type;
180  DWORD size = sizeof(crashCount);
181  LONG ret = RegQueryValueEx(hKey, _T("CrashCount"), 0, &type, (LPBYTE)&crashCount, &size);
182  ATLASSERT(ERROR_SUCCESS == ret);
183  RegCloseKey(hKey);
184  }
185  else
186  {
187  ATLASSERT(false);//shouldn't get here
188  }
189  return crashCount;
190  }
191  DWORD captureAndGet(int &crashCount, bool bIncrCrash=false)
192  {
193  //if this method is called we are crashing. The destructor of this class will not be called (we call TerminateProcess)
194  capture(bIncrCrash);
195  crashCount = getCrashCount();
196  return getTotalTime();
197  }
198 private:
199  CString m_strVendor;
200  CString m_strApp;
201  CString m_strVersion;
202  SYSTEMTIME m_startTime;
203  CString m_strUserName;
204  CString m_strUserEmail;
205  CString m_strUserDescription;
206 }; //here's the one and only instance
207 
208 // Simple class to automate restoring original resource handle
209 class ResourceSwitch {
210  HINSTANCE m_hClientResources;
211  HINSTANCE m_localRes;
212 public:
213  ResourceSwitch( const wchar_t * dllName ) {
214  // Store the current resource handle
215  m_hClientResources = _Module.GetResourceInstance();
216 
217  // Tell the client to use the .DLL's resources
218  m_localRes = (HINSTANCE)LoadLibrary(dllName);
219  if( m_localRes != NULL )
220  {
221  _Module.SetResourceInstance(m_localRes);
222  }
223  }
224 
225  ~ResourceSwitch()
226  {
227  // Restore the client application resource handle
228  _Module.SetResourceInstance(m_hClientResources);
229  FreeLibrary(m_localRes);
230  }
231 
232  void SetResourceDll(const wchar_t * dllName) {
233  // Tell the client to use the .DLL's resources
234  m_localRes = (HINSTANCE)LoadLibrary(dllName);
235  if( m_localRes != NULL )
236  {
237  _Module.SetResourceInstance(m_localRes);
238  }
239  }
240 
241  bool foundResources()
242  {
243  return (m_localRes != NULL);
244  }
245 };
246 
247 
248 
249 class MiniDumper
250 {
251 public:
252  MiniDumper();
253  virtual ~MiniDumper();
254 
255  void initExceptionHandler(const wchar_t *szVendor, const wchar_t *szAppName, const wchar_t *szVersion, const wchar_t *szDescription, DWORD dwFlags);
256 
257  bool enableExceptionFilter(bool enable = true);
258  bool isExceptionFilterEnabled() const;
259 
260  bool enableFullMemoryDumpAndExit(bool enable = true);
261  bool isFullMemoryDumpAndExitEnabled() const;
262 
263  // get/set the option flags
264  DWORD getFlags() const { return m_dwFlags; };
265  bool setFlags( DWORD dwFlags );
266 
267  // Get/set the minidump type.
268  MiniDmpSender::BS_MINIDUMP_TYPE getMiniDumpType() const;
269  void setMiniDumpType(MiniDmpSender::BS_MINIDUMP_TYPE m_eMiniDumpType);
270 
271  void resetVersionString(const wchar_t * szPath);
272  void resetDescriptionString(const wchar_t * szPath);
273  void sendAdditionalFile(const wchar_t * szPath);
274  bool removeAdditionalFile(const wchar_t * szPath);
275  void setUserZipPath(const wchar_t * szPath);
276  void setResourceDllPath(const wchar_t * szPath);
277 
278  void setDefaultUserName(const wchar_t * szPath);
279  void setDefaultUserEmail(const wchar_t * szPath);
280  void setDefaultUserDescription(const wchar_t * szPath);
281 
282  static LONG WINAPI TopLevelUnhandledExceptionFilter( PEXCEPTION_POINTERS pExceptionInfo );
283 
284  static LONG WINAPI ExceptionHandler( PEXCEPTION_POINTERS pExceptionInfo, DWORD dwThreadId=0L );
285 
286  static unsigned WINAPI CreateReportThreaded(PVOID);
287  static unsigned WINAPI SendReportThreaded(PVOID);
288 
289  // creates and sends a report
290  void createReport(DWORD dwThreadId = 0L);
291  void createReport(EXCEPTION_POINTERS * pExcepInfo);
292  void createReport(const wchar_t *szStackTracePath);
293  CString m_strStackTracePath;
294 
295  static UINT bugsplatMessage(const wchar_t * szMsg, UINT nCode= MB_ICONINFORMATION, UINT nDflt = MB_OK);
296 
297  static bool GetMFA(void * pAddress, LPTSTR pszMfa, int nSizeMFA);
298 
299  void setCallback(MiniDmpSenderCallback fnCallback);
300 
301  bool AllocGuardMemory();
302  bool FreeGuardMemory();
303  void LaunchHangDetection();
304  void TerminateHangDetection();
305 
306  LPVOID imp() { return &m_imp;}
307 
308  MiniDmpSenderCallback m_fnCallback;
309  CString m_strVendor;
310  CString m_strAppName;
311  CString m_strVersion;
312  CString m_strDescription;
313  CString m_strUserZipPath;
314  CString m_strResourceDllPath;
315  vector<CString> m_strAdditionalFiles;
316  CString m_strUserName; // Optional default value for user name
317  CString m_strUserEmail; // Optional default value for user email
318  CString m_strUserDescription; // Optional default value for user description
319  CString m_strDmpFile;
320  DWORD m_dwFlags;
321  MINIDUMP_TYPE m_eMiniDumpType;
322  DWORD m_hangProcess;
323 
324  TotalUptimeAndCrashCalculator * m_pUptimeAndCrashCalc;
325  char* m_pGuardBytes;
326 
327  static bool m_enableFilter;
328 
329  static bool m_doFullMemoryDumpThenExit;
330 
331  static MiniDumper * s_pThis;
332 
333  static LPTOP_LEVEL_EXCEPTION_FILTER m_previousExceptionFilter;
334 
335  static bool m_exceptionCaught;
336 
337  static int m_waitCreateReportThreaded;
338  static int m_waitSendReportThreaded;
339 
340 protected:
341  static BugSplatImp m_imp;
342 };
Definition: BugSplatImp.h:38
Definition: mdump - Copy.h:15
Definition: mdump - Copy.h:28
Definition: mdump - Copy.h:220
Definition: mdump - Copy.h:260