LONG Mini_Dump::WriteMiniDump(_EXCEPTION_POINTERS *pExceptionInfo)
{
	LONG retvel = EXCEPTION_CONTINUE_SEARCH;

	m_pExceptionInfo = pExceptionInfo;
	HMODULE	hDll	 = NULL;
	
	TCHAR	szDbgHelpPath[_MAX_PATH];

	if(GetModuleFileName(NULL,m_szAppPath,_MAX_PATH))
	{
		TCHAR *pSlash = _tcsrchr(m_szAppPath, '\\');
		if(pSlash)
		{
			_tcscpy(m_szAppBaseName,pSlash +1);
			*(pSlash+1) = 0;
		}
		_tcscpy(szDbgHelpPath,m_szAppPath);
		_tcscat(szDbgHelpPath,_T("DBGHELP.DLL"));	
		hDll = ::LoadLibrary(szDbgHelpPath);
	}
	
	if(hDll == NULL)
	{
		hDll = ::LoadLibrary(_T("DBGHELP.DLL"));
	}
	
	LPCTSTR	szResult = NULL;
	
	if(hDll)
	{
		MINIDUMPWRITEDUMP	pMiniDumpWriteDump = (MINIDUMPWRITEDUMP)::GetProcAddress(hDll,"MiniDumpWriteDump");
		if(pMiniDumpWriteDump)
		{
			TCHAR szScratch[_MAX_PATH];

			VSetDumpFileName();
			HANDLE	hFile = ::CreateFile(m_szDumpPath,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
			
			if(hFile != INVALID_HANDLE_VALUE)
			{
				_MINIDUMP_EXCEPTION_INFORMATION	ExInfo;

				ExInfo.ThreadId = ::GetCurrentThreadId();
				ExInfo.ExceptionPointers = pExceptionInfo;
				ExInfo.ClientPointers = NULL;
		
				BOOL bOK = pMiniDumpWriteDump(GetCurrentProcess(),GetCurrentProcessId(), hFile,MiniDumpNormal,&ExInfo,VGetUserStreamArray(),NULL);
				
				if(bOK)
				{
					szResult = NULL;
					retvel = EXCEPTION_EXECUTE_HANDLER;
				}
				else
				{
//					_stprintf((wchar_t*)szResult, _T("에러 파일 저장 오류"));
					szResult = szScratch;
				}
				::CloseHandle(hFile);
			}
			else
			{
//				_stprintf((wchar_t*)szResult, _T("에러 파일 생성 오류"));
				szResult = szScratch;
			}
		}
		else
		{
			szResult = _T("DGBHELP.DLL too Old");
		}
	}
	else
	{
		szResult = _T("DGBHELP.DLL not found");		
	}
	
	if(szResult)
		::MessageBox(NULL,szResult,NULL,MB_OK);
	TerminateProcess(GetCurrentProcess(),0);
	return retvel;
}
Пример #2
0
//
// MiniDumper::WriteMiniDump	- Chapter 21, page 814
//
LONG MiniDumper::WriteMiniDump(_EXCEPTION_POINTERS *pExceptionInfo )
{
    time( &m_lTime );

	LONG retval = EXCEPTION_CONTINUE_SEARCH;
	m_pExceptionInfo = pExceptionInfo;

	// You have to find the right dbghelp.dll. 
	// Look next to the EXE first since the one in System32 might be old (Win2k)
	
	HMODULE hDll = NULL;
	TCHAR szDbgHelpPath[_MAX_PATH];

	if (GetModuleFileName( NULL, m_szAppPath, _MAX_PATH ))
	{
		TCHAR *pSlash = _tcsrchr( m_szAppPath, '\\' );
		if (pSlash)
		{
#ifdef _VS2005_
			_tcscpy_s( m_szAppBaseName, pSlash + 1);
#else
			_tcscpy( m_szAppBaseName, pSlash + 1 );
#endif
			*(pSlash+1) = 0;
		}

#ifdef _VS2005_
		_tcscpy_s( szDbgHelpPath, m_szAppPath );
        _tcscat_s( szDbgHelpPath, _T("DBGHELP.DLL") );
#else
		_tcscpy( szDbgHelpPath, m_szAppPath );
        _tcscat( szDbgHelpPath, _T("DBGHELP.DLL") );
#endif
		hDll = ::LoadLibrary( szDbgHelpPath );
	}

	if (hDll==NULL)
	{
		// If we haven't found it yet - try one more time.
		hDll = ::LoadLibrary( _T("DBGHELP.DLL") );
	}

	LPCTSTR szResult = NULL;

	if (hDll)
	{
		MINIDUMPWRITEDUMP pMiniDumpWriteDump = (MINIDUMPWRITEDUMP)::GetProcAddress( hDll, "MiniDumpWriteDump" );
		if (pMiniDumpWriteDump)
		{
			TCHAR szScratch [USER_DATA_BUFFER_SIZE];

			VSetDumpFileName();

			// ask the user if they want to save a dump file
			_tcssprintf(szScratch, _T("There was an unexpected error:\n\n%s\nWould you like to save a diagnostic file?\n\nFilename: %s"), VGetUserMessage(), m_szDumpPath);
			if (m_bHeadless || (::MessageBox( NULL, szScratch, NULL, MB_YESNO )==IDYES))
			{
				// create the file
				HANDLE hFile = ::CreateFile( m_szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
											FILE_ATTRIBUTE_NORMAL, NULL );

				if (hFile!=INVALID_HANDLE_VALUE)
				{
					_MINIDUMP_EXCEPTION_INFORMATION ExInfo;

					ExInfo.ThreadId = ::GetCurrentThreadId();
					ExInfo.ExceptionPointers = pExceptionInfo;
					ExInfo.ClientPointers = NULL;

					// write the dump
					BOOL bOK = pMiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, VGetUserStreamArray(), NULL );
					if (bOK)
					{
						szResult = NULL;
						retval = EXCEPTION_EXECUTE_HANDLER;
					}
					else
					{
						_tcssprintf( szScratch, _T("Failed to save dump file to '%s' (error %d)"), m_szDumpPath, GetLastError() );
						szResult = szScratch;
					}
					::CloseHandle(hFile);
				}
				else
				{
					_tcssprintf( szScratch, _T("Failed to create dump file '%s' (error %d)"), m_szDumpPath, GetLastError() );
					szResult = szScratch;
				}
			}
		}
		else
		{
			szResult = _T("DBGHELP.DLL too old");
		}
	}
	else
	{
		szResult = _T("DBGHELP.DLL not found");
	}

	if (szResult && !m_bHeadless)
		::MessageBox( NULL, szResult, NULL, MB_OK );

	TerminateProcess(GetCurrentProcess(), 0);
	
	// MLM Note: ExitThread will work, and it allows the MiniDumper to kill a crashed thread
	// without affecting the rest of the application. The question of the day:
	//   Is That A Good Idea??? Answer: ABSOLUTELY NOT!!!!!!!
	//
	//ExitThread(0);

	return retval;
}