void CMiniDumper::Enable(LPCTSTR pszAppName, bool bShowErrors,bool b_user_mode)
{
	TCHAR s_process_name[MAX_PATH];
	LPCTSTR p_app_name = NULL;
	s_process_name[0] = 0x0;
	theCrashDumper.mb_user_mode=b_user_mode;
	//if (p_app_name == NULL)
	{
		TCHAR s_buf[MAX_PATH];
		s_buf[0] = 0x0;
		DWORD n_result = ::GetModuleFileName(NULL, s_buf, sizeof(TCHAR) * MAX_PATH);
		TCHAR	s_file_name[MAX_PATH];
		s_file_name[0] = 0x0;
		_tsplitpath(s_buf, NULL, NULL, s_file_name, NULL);
		_tcscpy_s(s_process_name, MAX_PATH, s_file_name);
		if (pszAppName == NULL || _tcslen(pszAppName) == 0)
			p_app_name = s_process_name;
		else
			p_app_name = pszAppName;
	}
	assert(p_app_name != NULL);
	assert( m_szAppName[0] == _T('\0') );
	_tcsncpy(m_szAppName, p_app_name, wcslen(p_app_name));  
     
	MINIDUMPWRITEDUMP pfnMiniDumpWriteDump = NULL;
	HMODULE hDbgHelpDll = GetDebugHelperDll((FARPROC*)&pfnMiniDumpWriteDump, bShowErrors);
	if (hDbgHelpDll)
	{
		if (pfnMiniDumpWriteDump)
			SetUnhandledExceptionFilter(TopLevelFilter);
		FreeLibrary(hDbgHelpDll);
		hDbgHelpDll = NULL;
		pfnMiniDumpWriteDump = NULL;
	}
}
void CMiniDumper::Enable(LPCTSTR pszAppName, bool bShowErrors, LPCTSTR pszDumpDir)
{
	// if this assert fires then you have two instances of CMiniDumper which is not allowed
	ASSERT( m_szAppName[0] == _T('\0') );
	_tcsncpy(m_szAppName, pszAppName, _countof(m_szAppName) - 1);
	m_szAppName[_countof(m_szAppName) - 1] = _T('\0');

	// eMule may not have the permission to create a DMP file in the directory where the "emule.exe" is located.
	// Need to pre-determine a valid directory.
	_tcsncpy(m_szDumpDir, pszDumpDir, _countof(m_szDumpDir) - 1);
	m_szDumpDir[_countof(m_szDumpDir) - 1] = _T('\0');
	PathAddBackslash(m_szDumpDir);

	MINIDUMPWRITEDUMP pfnMiniDumpWriteDump = NULL;
	HMODULE hDbgHelpDll = GetDebugHelperDll((FARPROC*)&pfnMiniDumpWriteDump, bShowErrors);
	if (hDbgHelpDll)
	{
		if (pfnMiniDumpWriteDump)
			SetUnhandledExceptionFilter(TopLevelFilter);
		FreeLibrary(hDbgHelpDll);
		hDbgHelpDll = NULL;
		pfnMiniDumpWriteDump = NULL;
	}
}
LONG CMiniDumper::TopLevelFilter(struct _EXCEPTION_POINTERS* pExceptionInfo)
{
	LONG lRetValue = EXCEPTION_CONTINUE_SEARCH;
	TCHAR szResult[MAX_PATH + 1024] = {0};
	MINIDUMPWRITEDUMP pfnMiniDumpWriteDump = NULL;
	HMODULE hDll = GetDebugHelperDll((FARPROC*)&pfnMiniDumpWriteDump, true);
	if (hDll)
	{
		if (pfnMiniDumpWriteDump)
		{
			// Ask user if they want to save a dump file
			// Do *NOT* localize that string (in fact, do not use MFC to load it)!
			if (MessageBox(NULL, _T("eMule crashed :-(\r\n\r\nA diagnostic file can be created which will help the author to resolve this problem. This file will be saved on your Disk (and not sent).\r\n\r\nDo you want to create this file now?"), m_szAppName, MB_ICONSTOP | MB_YESNO) == IDYES)
			{
				// Create full path for DUMP file
				TCHAR szDumpPath[MAX_PATH];
				_tcsncpy(szDumpPath, m_szDumpDir, _countof(szDumpPath) - 1);
				szDumpPath[_countof(szDumpPath) - 1] = _T('\0');
				size_t uDumpPathLen = _tcslen(szDumpPath);

				TCHAR szBaseName[MAX_PATH];
				_tcsncpy(szBaseName, m_szAppName, _countof(szBaseName) - 1);
				szBaseName[_countof(szBaseName) - 1] = _T('\0');
				size_t uBaseNameLen = _tcslen(szBaseName);

				time_t tNow = time(NULL);
				_tcsftime(szBaseName + uBaseNameLen, _countof(szBaseName) - uBaseNameLen, _T("_%Y%m%d-%H%M%S"), localtime(&tNow));
				szBaseName[_countof(szBaseName) - 1] = _T('\0');

				// Replace spaces and dots in file name.
				LPTSTR psz = szBaseName;
				while (*psz != _T('\0')) {
					if (*psz == _T('.'))
						*psz = _T('-');
					else if (*psz == _T(' '))
						*psz = _T('_');
					psz++;
				}
				if (uDumpPathLen < _countof(szDumpPath) - 1) {
					_tcsncat(szDumpPath, szBaseName, _countof(szDumpPath) - uDumpPathLen - 1);
					szDumpPath[_countof(szDumpPath) - 1] = _T('\0');
					uDumpPathLen = _tcslen(szDumpPath);
					if (uDumpPathLen < _countof(szDumpPath) - 1) {
						_tcsncat(szDumpPath, _T(".dmp"), _countof(szDumpPath) - uDumpPathLen - 1);
						szDumpPath[_countof(szDumpPath) - 1] = _T('\0');
					}
				}

				HANDLE hFile = CreateFile(szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
				if (hFile != INVALID_HANDLE_VALUE)
				{
					_MINIDUMP_EXCEPTION_INFORMATION ExInfo = {0};
					ExInfo.ThreadId = GetCurrentThreadId();
					ExInfo.ExceptionPointers = pExceptionInfo;
					ExInfo.ClientPointers = NULL;

					BOOL bOK = (*pfnMiniDumpWriteDump)(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL);
					if (bOK)
					{
						// Do *NOT* localize that string (in fact, do not use MFC to load it)!
						//Xman Xtreme Mod
						/*
						_sntprintf(szResult, _countof(szResult) - 1, _T("Saved dump file to \"%s\".\r\n\r\nPlease send this file together with a detailed bug report to [email protected] !\r\n\r\nThank you for helping to improve eMule."), szDumpPath);
						*/
						_sntprintf(szResult, _countof(szResult) - 1, _T("Saved dump file to \"%s\".\r\n\r\nPlease send this file together with a detailed bug report to [email protected] !\r\n\r\nThank you for helping to improve eMule."), szDumpPath);
						//Xman end
						szResult[_countof(szResult) - 1] = _T('\0');
						lRetValue = EXCEPTION_EXECUTE_HANDLER;
					}
					else
					{
						// Do *NOT* localize that string (in fact, do not use MFC to load it)!
						_sntprintf(szResult, _countof(szResult) - 1, _T("Failed to save dump file to \"%s\".\r\n\r\nError: %u"), szDumpPath, GetLastError());
						szResult[_countof(szResult) - 1] = _T('\0');
					}
					CloseHandle(hFile);
				}
				else
				{
					// Do *NOT* localize that string (in fact, do not use MFC to load it)!
					_sntprintf(szResult, _countof(szResult) - 1, _T("Failed to create dump file \"%s\".\r\n\r\nError: %u"), szDumpPath, GetLastError());
					szResult[_countof(szResult) - 1] = _T('\0');
				}
			}
		}
		FreeLibrary(hDll);
		hDll = NULL;
		pfnMiniDumpWriteDump = NULL;
	}

	if (szResult[0] != _T('\0'))
		MessageBox(NULL, szResult, m_szAppName, MB_ICONINFORMATION | MB_OK);

#ifndef _DEBUG
	// Exit the process only in release builds, so that in debug builds the exceptio is passed to a possible
	// installed debugger
	ExitProcess(0);
#else
	return lRetValue;
#endif
}
LONG CMiniDumper::TopLevelFilter(struct _EXCEPTION_POINTERS* pExceptionInfo)
{
	   
	LONG lRetValue = EXCEPTION_CONTINUE_SEARCH;
	TCHAR szResult[_MAX_PATH + 1024] = {0};
	MINIDUMPWRITEDUMP pfnMiniDumpWriteDump = NULL;
	HMODULE hDll = GetDebugHelperDll((FARPROC*)&pfnMiniDumpWriteDump, true);
	HINSTANCE	hInstCrashReporter = NULL;	
	if (hDll)
	{
		if (pfnMiniDumpWriteDump)
		{

			{
				// Create full path for BugReport.exe
				TCHAR szSharkPath[_MAX_PATH] = {0};
				TCHAR szDumpPath_no_time[_MAX_PATH] = {0};
				GetModuleFileName(NULL, szSharkPath, wcslen(szSharkPath));
				LPTSTR pszFileName = _tcsrchr(szSharkPath, _T('\\'));
				if (pszFileName) {
					pszFileName++;
					*pszFileName = _T('\0');
				}

				TCHAR szCrashReport[MAX_PATH] = {0};
				_tcsncat(szCrashReport,szSharkPath,wcslen(szCrashReport) - 1);
				_tcsncat(szCrashReport,_T("BugReport.exe"),wcslen(szCrashReport) - 1);

				// Create full path for DUMP file
				TCHAR szDumpPath[MAX_PATH]={0};
				SHGetFolderPath(NULL, CSIDL_APPDATA,NULL,SHGFP_TYPE_CURRENT,szDumpPath);
				_tcsncat(szDumpPath,_T("\\XiaTing\\"),wcslen(szDumpPath) - 1);

				// Replace spaces and dots in file name.
				TCHAR szBaseName[_MAX_PATH] = {0};
				_tcsncat(szBaseName, m_szAppName, wcslen(szBaseName) - 1);
				LPTSTR psz = szBaseName;
				while (*psz != _T('\0')) {
					if (*psz == _T('.'))
						*psz = _T('-');
					else if (*psz == _T(' '))
						*psz = _T('_');
					psz++;
				}
				_tcsncat(szDumpPath, szBaseName, wcslen(szDumpPath) - 1);
				_tcsncat(szDumpPath_no_time, szBaseName, wcslen(szDumpPath_no_time) - 1);				
				
				if (!theCrashDumper.mb_user_mode)
				{
					time_t n_now = time(NULL);
					struct tm* p_time = localtime(&n_now);
					if (p_time != NULL)
					{
						TCHAR s_format[256];
						s_format[0] = 0x0;
						_tcsftime(s_format, 255, _T("-%Y.%m.%d - %H-%M-%S"), p_time);
						_tcsncat(szDumpPath, s_format, _tcslen(s_format) -1);
					}
				}                
				_tcsncat(szDumpPath, _T(".dmp"), wcslen(szDumpPath) - 1);
				_tcsncat(szDumpPath_no_time, _T(".dmp"), wcslen(szDumpPath_no_time) - 1);

               
				HANDLE hFile = CreateFile(szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
				if (hFile != INVALID_HANDLE_VALUE)
				{
					_MINIDUMP_EXCEPTION_INFORMATION ExInfo = {0};
					ExInfo.ThreadId = GetCurrentThreadId();
					ExInfo.ExceptionPointers = pExceptionInfo;
					ExInfo.ClientPointers = NULL;

					BOOL bOK = (*pfnMiniDumpWriteDump)(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL);
					if (bOK)
					{
						
						_sntprintf(szResult, wcslen(szResult), _T("Saved dump file to \"%s\".\r\n\r\nPlease send this file together with a detailed bug report to [email protected] !\r\n\r\nThank you for helping to improve eMule."), szDumpPath);
						lRetValue = EXCEPTION_EXECUTE_HANDLER;
						
						CString cs_cmd_line;
						cs_cmd_line.Format(_T("%s%s"),_T("Cmd|"),szDumpPath_no_time);						
						
						hInstCrashReporter = ShellExecuteW(NULL, _T("open"), szCrashReport, cs_cmd_line.GetBuffer(), NULL, SW_SHOW);
						if (hInstCrashReporter <= (HINSTANCE)32)
							lRetValue = EXCEPTION_CONTINUE_SEARCH;
						
					}
					else
					{						
						_sntprintf(szResult, wcslen(szResult), _T("Failed to save dump file to \"%s\".\r\n\r\nError: %u"), szDumpPath, GetLastError());
					}
					CloseHandle(hFile);
				}
				else
				{					
					_sntprintf(szResult, wcslen(szResult), _T("Failed to create dump file \"%s\".\r\n\r\nError: %u"), szDumpPath, GetLastError());
				}
			}
		}
		FreeLibrary(hDll);
		hDll = NULL;
		pfnMiniDumpWriteDump = NULL;
	}

#ifndef _DEBUG
	if (EXCEPTION_EXECUTE_HANDLER == lRetValue)		
	{
		exit(0);
	}
	else
		return lRetValue;

#else

	return lRetValue;
#endif
}