mdump.cpp

Go to the documentation of this file.
00001 
00002 // #include <stdafx.h>
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 // because the windows header are polluting the global namespace we can't include basestrm.h :-(
00018 extern int getSearchPathNum();
00019 extern ASCString getSearchPath ( int i );
00020 
00021 LPCSTR MiniDumper::m_szAppName;
00022 
00023 MiniDumper::MiniDumper( LPCSTR szAppName )
00024 {
00025    // if this assert fires then you have two instances of MiniDumper
00026    // which is not allowed
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;                // find a better value for your app
00038 
00039    // firstly see if dbghelp.dll is around and has the function we need
00040    // look next to the EXE first, as the one in System32 might be old
00041    // (e.g. Windows 2000)
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       // load any version we can
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             // work out a good place for the dump file
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          // ask the user if they want to save a dump file
00079          // if (::MessageBox( NULL, "ASC has crashed. would you like to save a diagnostic file?", m_szAppName, MB_YESNO )==IDYES)
00080          if ( true ) {
00081             // create the file
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                // write the dump
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 }

Generated on Mon May 21 01:26:35 2012 for Advanced Strategic Command by  doxygen 1.5.1