Advanced Strategic Command
mdump.cpp
Go to the documentation of this file.
1 
2 // #include <stdafx.h>
3 #include "mdump.h"
4 
5 
6 #include <assert.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <mbstring.h>
10 #include <wchar.h>
11 #include <TCHAR.H>
12 
13 #include "../../ascstring.h"
14 #include "../../strtmesg.h"
15 
16 
17 // because the windows header are polluting the global namespace we can't include basestrm.h :-(
18 extern int getSearchPathNum();
19 extern ASCString getSearchPath ( int i );
20 
21 LPCSTR MiniDumper::m_szAppName;
22 
23 MiniDumper::MiniDumper( LPCSTR szAppName )
24 {
25  // if this assert fires then you have two instances of MiniDumper
26  // which is not allowed
27  assert( m_szAppName==NULL );
28 
29  m_szAppName = szAppName ? strdup(szAppName) : "Application";
30 
31  ::SetUnhandledExceptionFilter( TopLevelFilter );
32 }
33 
34 LONG MiniDumper::TopLevelFilter( struct _EXCEPTION_POINTERS *pExceptionInfo )
35 {
36  LONG retval = EXCEPTION_CONTINUE_SEARCH;
37  HWND hParent = NULL; // find a better value for your app
38 
39  // firstly see if dbghelp.dll is around and has the function we need
40  // look next to the EXE first, as the one in System32 might be old
41  // (e.g. Windows 2000)
42  HMODULE hDll = NULL;
43  char szDbgHelpPath[_MAX_PATH];
44 
45  if (GetModuleFileName( NULL, szDbgHelpPath, _MAX_PATH )) {
46  char *pSlash = _tcsrchr( szDbgHelpPath, '\\' );
47  if (pSlash) {
48  _tcscpy( pSlash+1, "DBGHELP.DLL" );
49  hDll = ::LoadLibrary( szDbgHelpPath );
50  }
51  }
52 
53  if (hDll==NULL) {
54  // load any version we can
55  hDll = ::LoadLibrary( "DBGHELP.DLL" );
56  }
57 
58  LPCTSTR szResult = NULL;
59 
60  if (hDll) {
61  MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress( hDll, "MiniDumpWriteDump" );
62  if (pDump) {
63  char szDumpPath[_MAX_PATH];
64  char szScratch [_MAX_PATH];
65 
66  if ( getSearchPathNum() ) {
67  _tcscpy( szDumpPath, getSearchPath(0).c_str() );
68  } else {
69  // work out a good place for the dump file
70  if (!GetTempPath( _MAX_PATH, szDumpPath ))
71  _tcscpy( szDumpPath, "c:\\temp\\" );
72  }
73 
74  _tcscat( szDumpPath, getFullVersionString() );
75  _tcscat( szDumpPath, m_szAppName );
76  _tcscat( szDumpPath, ".dmp" );
77 
78  // ask the user if they want to save a dump file
79  // if (::MessageBox( NULL, "ASC has crashed. would you like to save a diagnostic file?", m_szAppName, MB_YESNO )==IDYES)
80  if ( true ) {
81  // create the file
82  HANDLE hFile = ::CreateFile( szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
83 
84  if (hFile!=INVALID_HANDLE_VALUE) {
85  _MINIDUMP_EXCEPTION_INFORMATION ExInfo;
86 
87  ExInfo.ThreadId = ::GetCurrentThreadId();
88  ExInfo.ExceptionPointers = pExceptionInfo;
89  ExInfo.ClientPointers = NULL;
90 
91  // write the dump
92  BOOL bOK = pDump( GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL );
93  if (bOK) {
94  sprintf( szScratch, "ASC has crashed :-(\nSaved dump file to '%s'\nPlease send it to bugs@asc-hq.org", szDumpPath );
95  szResult = szScratch;
96  retval = EXCEPTION_EXECUTE_HANDLER;
97  } else {
98  sprintf( szScratch, "Failed to save dump file to '%s' (error %d)", szDumpPath, GetLastError() );
99  szResult = szScratch;
100  }
101  ::CloseHandle(hFile);
102  ::MessageBox( NULL, szResult, m_szAppName, MB_OK | MB_ICONERROR );
103  return retval;
104  } else {
105  sprintf( szScratch, "Failed to create dump file '%s' (error %d)", szDumpPath, GetLastError() );
106  szResult = szScratch;
107  }
108  }
109  } else {
110  szResult = "DBGHELP.DLL too old";
111  ::MessageBox( NULL, szDbgHelpPath, m_szAppName, MB_OK | MB_ICONERROR);
112  return retval;
113  }
114  } else {
115  szResult = "DBGHELP.DLL not found";
116  }
117 
118  if (szResult)
119  ::MessageBox( NULL, szResult, m_szAppName, MB_OK | MB_ICONERROR );
120 
121  return retval;
122 }
BOOL(WINAPI * MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam)
Definition: mdump.h:14
const char * getFullVersionString()
Definition: strtmesg.cpp:58
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
ASCString getSearchPath(int i)
Definition: basestrm.cpp:2539
MiniDumper(LPCSTR szAppName)
Definition: mdump.cpp:23
int getSearchPathNum()
Definition: basestrm.cpp:2534