00001
00002
00003 #include "mdump.h"
00004
00005
00006 #include <assert.h>
00007 #include <string.h>
00008 #include <stdio.h>
00009 #include <mbstring.h>
00010 #include <wchar.h>
00011 #include <TCHAR.H>
00012
00013 #include "../../ascstring.h"
00014 #include "../../strtmesg.h"
00015
00016
00017
00018 extern int getSearchPathNum();
00019 extern ASCString getSearchPath ( int i );
00020
00021 LPCSTR MiniDumper::m_szAppName;
00022
00023 MiniDumper::MiniDumper( LPCSTR szAppName )
00024 {
00025
00026
00027 assert( m_szAppName==NULL );
00028
00029 m_szAppName = szAppName ? strdup(szAppName) : "Application";
00030
00031 ::SetUnhandledExceptionFilter( TopLevelFilter );
00032 }
00033
00034 LONG MiniDumper::TopLevelFilter( struct _EXCEPTION_POINTERS *pExceptionInfo )
00035 {
00036 LONG retval = EXCEPTION_CONTINUE_SEARCH;
00037 HWND hParent = NULL;
00038
00039
00040
00041
00042 HMODULE hDll = NULL;
00043 char szDbgHelpPath[_MAX_PATH];
00044
00045 if (GetModuleFileName( NULL, szDbgHelpPath, _MAX_PATH )) {
00046 char *pSlash = _tcsrchr( szDbgHelpPath, '\\' );
00047 if (pSlash) {
00048 _tcscpy( pSlash+1, "DBGHELP.DLL" );
00049 hDll = ::LoadLibrary( szDbgHelpPath );
00050 }
00051 }
00052
00053 if (hDll==NULL) {
00054
00055 hDll = ::LoadLibrary( "DBGHELP.DLL" );
00056 }
00057
00058 LPCTSTR szResult = NULL;
00059
00060 if (hDll) {
00061 MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress( hDll, "MiniDumpWriteDump" );
00062 if (pDump) {
00063 char szDumpPath[_MAX_PATH];
00064 char szScratch [_MAX_PATH];
00065
00066 if ( getSearchPathNum() ) {
00067 _tcscpy( szDumpPath, getSearchPath(0).c_str() );
00068 } else {
00069
00070 if (!GetTempPath( _MAX_PATH, szDumpPath ))
00071 _tcscpy( szDumpPath, "c:\\temp\\" );
00072 }
00073
00074 _tcscat( szDumpPath, getFullVersionString() );
00075 _tcscat( szDumpPath, m_szAppName );
00076 _tcscat( szDumpPath, ".dmp" );
00077
00078
00079
00080 if ( true ) {
00081
00082 HANDLE hFile = ::CreateFile( szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
00083
00084 if (hFile!=INVALID_HANDLE_VALUE) {
00085 _MINIDUMP_EXCEPTION_INFORMATION ExInfo;
00086
00087 ExInfo.ThreadId = ::GetCurrentThreadId();
00088 ExInfo.ExceptionPointers = pExceptionInfo;
00089 ExInfo.ClientPointers = NULL;
00090
00091
00092 BOOL bOK = pDump( GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL );
00093 if (bOK) {
00094 sprintf( szScratch, "ASC has crashed :-(\nSaved dump file to '%s'\nPlease send it to bugs@asc-hq.org", szDumpPath );
00095 szResult = szScratch;
00096 retval = EXCEPTION_EXECUTE_HANDLER;
00097 } else {
00098 sprintf( szScratch, "Failed to save dump file to '%s' (error %d)", szDumpPath, GetLastError() );
00099 szResult = szScratch;
00100 }
00101 ::CloseHandle(hFile);
00102 ::MessageBox( NULL, szResult, m_szAppName, MB_OK | MB_ICONERROR );
00103 return retval;
00104 } else {
00105 sprintf( szScratch, "Failed to create dump file '%s' (error %d)", szDumpPath, GetLastError() );
00106 szResult = szScratch;
00107 }
00108 }
00109 } else {
00110 szResult = "DBGHELP.DLL too old";
00111 ::MessageBox( NULL, szDbgHelpPath, m_szAppName, MB_OK | MB_ICONERROR);
00112 return retval;
00113 }
00114 } else {
00115 szResult = "DBGHELP.DLL not found";
00116 }
00117
00118 if (szResult)
00119 ::MessageBox( NULL, szResult, m_szAppName, MB_OK | MB_ICONERROR );
00120
00121 return retval;
00122 }