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 {
00047 char *pSlash = _tcsrchr( szDbgHelpPath, '\\' );
00048 if (pSlash)
00049 {
00050 _tcscpy( pSlash+1, "DBGHELP.DLL" );
00051 hDll = ::LoadLibrary( szDbgHelpPath );
00052 }
00053 }
00054
00055 if (hDll==NULL)
00056 {
00057
00058 hDll = ::LoadLibrary( "DBGHELP.DLL" );
00059 }
00060
00061 LPCTSTR szResult = NULL;
00062
00063 if (hDll)
00064 {
00065 MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress( hDll, "MiniDumpWriteDump" );
00066 if (pDump)
00067 {
00068 char szDumpPath[_MAX_PATH];
00069 char szScratch [_MAX_PATH];
00070
00071 if ( getSearchPathNum() ) {
00072 _tcscpy( szDumpPath, getSearchPath(0).c_str() );
00073 } else {
00074
00075 if (!GetTempPath( _MAX_PATH, szDumpPath ))
00076 _tcscpy( szDumpPath, "c:\\temp\\" );
00077 }
00078
00079 _tcscat( szDumpPath, getFullVersionString() );
00080 _tcscat( szDumpPath, m_szAppName );
00081 _tcscat( szDumpPath, ".dmp" );
00082
00083
00084
00085 if ( true ) {
00086
00087 HANDLE hFile = ::CreateFile( szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
00088
00089 if (hFile!=INVALID_HANDLE_VALUE)
00090 {
00091 _MINIDUMP_EXCEPTION_INFORMATION ExInfo;
00092
00093 ExInfo.ThreadId = ::GetCurrentThreadId();
00094 ExInfo.ExceptionPointers = pExceptionInfo;
00095 ExInfo.ClientPointers = NULL;
00096
00097
00098 BOOL bOK = pDump( GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL );
00099 if (bOK)
00100 {
00101 sprintf( szScratch, "ASC has crashed :-(\nSaved dump file to '%s'\nPlease send it to bugs@asc-hq.org", szDumpPath );
00102 szResult = szScratch;
00103 retval = EXCEPTION_EXECUTE_HANDLER;
00104 }
00105 else
00106 {
00107 sprintf( szScratch, "Failed to save dump file to '%s' (error %d)", szDumpPath, GetLastError() );
00108 szResult = szScratch;
00109 }
00110 ::CloseHandle(hFile);
00111 ::MessageBox( NULL, szResult, m_szAppName, MB_OK | MB_ICONERROR );
00112 return retval;
00113 }
00114 else
00115 {
00116 sprintf( szScratch, "Failed to create dump file '%s' (error %d)", szDumpPath, GetLastError() );
00117 szResult = szScratch;
00118 }
00119 }
00120 }
00121 else
00122 {
00123 szResult = "DBGHELP.DLL too old";
00124 ::MessageBox( NULL, szDbgHelpPath, m_szAppName, MB_OK | MB_ICONERROR);
00125 return retval;
00126 }
00127 }
00128 else
00129 {
00130 szResult = "DBGHELP.DLL not found";
00131 }
00132
00133 if (szResult)
00134 ::MessageBox( NULL, szResult, m_szAppName, MB_OK | MB_ICONERROR );
00135
00136 return retval;
00137 }