📄 emule.cpp
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#endif
#include "stdafx.h"
#include <locale.h>
#include <io.h>
#include <share.h>
#include "emule.h"
#include "version.h"
#include "opcodes.h"
#ifdef _DUMP
#include "mdump.h"
#endif
#include "Scheduler.h"
#include "SearchList.h"
#include "kademlia/kademlia/Kademlia.h"
#include "kademlia/kademlia/Error.h"
#include "kademlia/utils/UInt128.h"
#include "PerfLog.h"
#include <..\src\mfc\sockimpl.h>
#include <..\src\mfc\afximpl.h>
#include "LastCommonRouteFinder.h"
#include "UploadBandwidthThrottler.h"
#include "ClientList.h"
#include "FriendList.h"
#include "ClientUDPSocket.h"
#include "DownloadQueue.h"
#include "IPFilter.h"
#include "MMServer.h"
#include "Statistics.h"
#include "OtherFunctions.h"
#include "WebServer.h"
#include "UploadQueue.h"
#include "SharedFileList.h"
#include "ServerList.h"
#include "Sockets.h"
#include "ListenSocket.h"
#include "ClientCredits.h"
#include "KnownFileList.h"
#include "Server.h"
#include "UpDownClient.h"
#include "ED2KLink.h"
#include "Preferences.h"
#include "secrunasuser.h"
#include "SafeFile.h"
#include "PeerCacheFinder.h"
#include "emuleDlg.h"
#include "SearchDlg.h"
#include "enbitmap.h"
#include "FirewallOpener.h"
CLog theLog;
CLog theVerboseLog;
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#ifdef _DEBUG
static CMemoryState oldMemState, newMemState, diffMemState;
_CRT_ALLOC_HOOK g_pfnPrevCrtAllocHook = NULL;
CMap<const unsigned char*, const unsigned char*, UINT, UINT> g_allocations;
int eMuleAllocHook(int mode, void* pUserData, size_t nSize, int nBlockUse, long lRequest, const unsigned char* pszFileName, int nLine);
//CString _strCrtDebugReportFilePath(_T("eMule CRT Debug Log.txt"));
// don't use a CString for that memory - it will not be available on application termination!
#define APP_CRT_DEBUG_LOG_FILE _T("eMule CRT Debug Log.txt")
static TCHAR _szCrtDebugReportFilePath[MAX_PATH] = APP_CRT_DEBUG_LOG_FILE;
#endif
struct SLogItem
{
bool addtostatusbar;
CString line;
};
void CALLBACK myErrHandler(Kademlia::CKademliaError *error)
{
CString msg;
msg.Format(_T("\r\nError 0x%08X : %hs\r\n"), error->m_ErrorCode, error->m_ErrorDescription);
if(theApp.emuledlg && theApp.emuledlg->IsRunning())
theApp.QueueDebugLogLine(false, msg);
}
void CALLBACK myDebugAndLogHandler(LPCSTR lpMsg)
{
if(theApp.emuledlg && theApp.emuledlg->IsRunning())
theApp.QueueDebugLogLine(false, _T("%hs"), lpMsg);
}
void CALLBACK myLogHandler(LPCSTR lpMsg)
{
if(theApp.emuledlg && theApp.emuledlg->IsRunning())
theApp.QueueLogLine(false, _T("%hs"), lpMsg);
}
const static UINT UWM_ARE_YOU_EMULE=RegisterWindowMessage(EMULE_GUID);
// CemuleApp
BEGIN_MESSAGE_MAP(CemuleApp, CWinApp)
ON_COMMAND(ID_HELP, OnHelp)
END_MESSAGE_MAP()
CemuleApp::CemuleApp(LPCTSTR lpszAppName)
:CWinApp(lpszAppName)
{
srand(time(NULL));
m_dwPublicIP = 0;
m_ullComCtrlVer = MAKEDLLVERULL(4,0,0,0);
m_hSystemImageList = NULL;
m_sizSmallSystemIcon.cx = 16;
m_sizSmallSystemIcon.cy = 16;
m_iDfltImageListColorFlags = ILC_COLOR;
// MOD Note: Do not change this part - Merkur
// this is the "base" version number <major>.<minor>.<update>.<build>
m_dwProductVersionMS = MAKELONG(VERSION_MIN, VERSION_MJR);
m_dwProductVersionLS = MAKELONG(VERSION_BUILD, VERSION_UPDATE);
// create a string version (e.g. "0.30a")
ASSERT( VERSION_UPDATE + 'a' <= 'f' );
#ifdef _DEBUG
m_strCurVersionLong.Format(_T("%u.%u%c.%u"), VERSION_MJR, VERSION_MIN, _T('a') + VERSION_UPDATE, VERSION_BUILD);
#else
m_strCurVersionLong.Format(_T("%u.%u%c"), VERSION_MJR, VERSION_MIN, _T('a') + VERSION_UPDATE);
#endif
#ifdef _DUMP
m_strCurVersionLong += _T(" DEBUG");
#endif
// create the protocol version number
CString strTmp;
strTmp.Format(_T("0x%u"), m_dwProductVersionMS);
VERIFY( _stscanf(strTmp, _T("0x%x"), &m_uCurVersionShort) == 1 );
ASSERT( m_uCurVersionShort < 0x99 );
// create the version check number
strTmp.Format(_T("0x%u%c"), m_dwProductVersionMS, _T('A') + VERSION_UPDATE);
VERIFY( _stscanf(strTmp, _T("0x%x"), &m_uCurVersionCheck) == 1 );
ASSERT( m_uCurVersionCheck < 0x999 );
// MOD Note: end
m_bGuardClipboardPrompt = false;
EnableHtmlHelp();
}
CemuleApp theApp(_T("eMule"));
// Workaround for buggy 'AfxSocketTerm' (needed at least for MFC 7.0)
#if _MFC_VER==0x0700 || _MFC_VER==0x0710
void __cdecl __AfxSocketTerm()
{
#if defined(_AFXDLL) && (_MFC_VER==0x0700 || _MFC_VER==0x0710)
VERIFY( WSACleanup() == 0 );
#else
_AFX_SOCK_STATE* pState = _afxSockState.GetData();
if (pState->m_pfnSockTerm != NULL){
VERIFY( WSACleanup() == 0 );
pState->m_pfnSockTerm = NULL;
}
#endif
}
#else
#error "You are using an MFC version which may require a special version of the above function!"
#endif
// CemuleApp Initialisierung
BOOL CemuleApp::InitInstance()
{
#ifdef _DEBUG
// set Floating Point Processor to throw several exceptions, in particular the 'Floating point devide by zero'
UINT uEmCtrlWord = _control87(0, 0) & _MCW_EM;
_control87(uEmCtrlWord & ~(/*_EM_INEXACT |*/ _EM_UNDERFLOW | _EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID), _MCW_EM);
// output all ASSERT messages to debug device
_CrtSetReportMode(_CRT_ASSERT, _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_REPORT_MODE) | _CRTDBG_MODE_DEBUG);
#endif
TCHAR szAppDir[MAX_PATH];
VERIFY( GetModuleFileName(m_hInstance, szAppDir, ARRSIZE(szAppDir)) );
VERIFY( PathRemoveFileSpec(szAppDir) );
TCHAR szPrefFilePath[MAX_PATH];
PathCombine(szPrefFilePath, szAppDir, CONFIGFOLDER _T("preferences.ini"));
if (m_pszProfileName)
free((void*)m_pszProfileName);
m_pszProfileName = _tcsdup(szPrefFilePath);
#ifdef _DEBUG
oldMemState.Checkpoint();
// Installing that memory debug code works fine in Debug builds when running within VS Debugger,
// but some other test applications don't like that all....
//g_pfnPrevCrtAllocHook = _CrtSetAllocHook(&eMuleAllocHook);
#endif
//afxMemDF = allocMemDF | delayFreeMemDF;
#ifdef _DUMP
MiniDumper dumper(m_strCurVersionLong);
#endif
_tsetlocale(LC_ALL, _T("")); // set all categories of locale to user-default ANSI code page obtained from the OS.
_tsetlocale(LC_NUMERIC, _T("C")); // set numeric category to 'C'
//_tsetlocale(LC_CTYPE, _T("C")); // set character types category to 'C' (VERY IMPORTANT, we need binary string compares!)
AfxOleInit();
pendinglink = 0;
if (ProcessCommandline())
return false;
// InitCommonControls() ist f黵 Windows XP erforderlich, wenn ein Anwendungsmanifest
// die Verwendung von ComCtl32.dll Version 6 oder h鰄er zum Aktivieren
// von visuellen Stilen angibt. Ansonsten treten beim Erstellen von Fenstern Fehler auf.
InitCommonControls();
DWORD dwComCtrlMjr = 4;
DWORD dwComCtrlMin = 0;
AtlGetCommCtrlVersion(&dwComCtrlMjr, &dwComCtrlMin);
m_ullComCtrlVer = MAKEDLLVERULL(dwComCtrlMjr,dwComCtrlMin,0,0);
m_sizSmallSystemIcon.cx = GetSystemMetrics(SM_CXSMICON);
m_sizSmallSystemIcon.cy = GetSystemMetrics(SM_CYSMICON);
m_iDfltImageListColorFlags = GetAppImageListColorFlag();
// don't use 32bit color resources if not supported by commctl
if (m_iDfltImageListColorFlags == ILC_COLOR32 && m_ullComCtrlVer < MAKEDLLVERULL(6,0,0,0))
m_iDfltImageListColorFlags = ILC_COLOR16;
// don't use >8bit color resources with OSs with restricted memory for GDI resources
if (afxData.bWin95)
m_iDfltImageListColorFlags = ILC_COLOR8;
CWinApp::InitInstance();
if (!AfxSocketInit())
{
AfxMessageBox(GetResString(IDS_SOCKETS_INIT_FAILED));
return FALSE;
}
#if _MFC_VER==0x0700 || _MFC_VER==0x0710
atexit(__AfxSocketTerm);
#else
#error "You are using an MFC version which may require a special version of the above function!"
#endif
AfxEnableControlContainer();
if (!AfxInitRichEdit2()){
if (!AfxInitRichEdit())
AfxMessageBox(_T("No Rich Edit control library found!")); // should never happen..
}
// create & initalize all the important stuff
thePrefs.Init();
theStats.Init();
// check if we have to restart eMule as Secure user
if (thePrefs.IsRunAsUserEnabled()){
CSecRunAsUser rau;
if ( rau.PrepareUser() && rau.RestartAsUser() )
return FALSE; // emule restart as secure user, kill this instance
else if ( !rau.IsRunningEmuleAccount() ){
// something went wrong
theApp.QueueLogLine(false, GetResString(IDS_RAU_FAILED), rau.GetCurrentUserW());
}
}
#ifdef _DEBUG
_sntprintf(_szCrtDebugReportFilePath, ARRSIZE(_szCrtDebugReportFilePath), _T("%s\\%s"), thePrefs.GetAppDir(), APP_CRT_DEBUG_LOG_FILE);
#endif
VERIFY( theLog.SetFilePath(thePrefs.GetAppDir() + _T("eMule.log")) );
VERIFY( theVerboseLog.SetFilePath(thePrefs.GetAppDir() + _T("eMule_Verbose.log")) );
theLog.SetMaxFileSize(thePrefs.GetMaxLogFileSize());
theVerboseLog.SetMaxFileSize(thePrefs.GetMaxLogFileSize());
if (thePrefs.GetLog2Disk())
theLog.Open();
if (thePrefs.GetDebug2Disk())
theVerboseLog.Open();
CemuleDlg dlg;
emuledlg = &dlg;
m_pMainWnd = &dlg;
// Barry - Auto-take ed2k links
if (thePrefs.AutoTakeED2KLinks())
Ask4RegFix(false, true);
m_pFirewallOpener = new CFirewallOpener();
m_pFirewallOpener->Init(true); // we need to init it now (even if we may not use it yet) because of CoInitializeSecurity - which kinda ruins the sense of the class interface but ooohh well :P
// Open WinXP firewallports if set in preferences and possible
if (thePrefs.IsOpenPortsOnStartupEnabled()){
if (m_pFirewallOpener->DoesFWConnectionExist()){
// delete old rules added by eMule
m_pFirewallOpener->RemoveRule(EMULE_DEFAULTRULENAME_UDP);
m_pFirewallOpener->RemoveRule(EMULE_DEFAULTRULENAME_TCP);
// open port for this session
if (m_pFirewallOpener->OpenPort(thePrefs.GetPort(), NAT_PROTOCOL_TCP, EMULE_DEFAULTRULENAME_TCP, true))
QueueLogLine(false, GetResString(IDS_FO_TEMPTCP_S), thePrefs.GetPort());
else
QueueLogLine(false, GetResString(IDS_FO_TEMPTCP_F), thePrefs.GetPort());
if (thePrefs.GetUDPPort()){
// open port for this session
if (m_pFirewallOpener->OpenPort(thePrefs.GetUDPPort(), NAT_PROTOCOL_UDP, EMULE_DEFAULTRULENAME_UDP, true))
QueueLogLine(false, GetResString(IDS_FO_TEMPUDP_S), thePrefs.GetUDPPort());
else
QueueLogLine(false, GetResString(IDS_FO_TEMPUDP_F), thePrefs.GetUDPPort());
}
}
}
// ZZ:UploadSpeedSense -->
lastCommonRouteFinder = new LastCommonRouteFinder();
uploadBandwidthThrottler = new UploadBandwidthThrottler();
// ZZ:UploadSpeedSense <--
clientlist = new CClientList();
friendlist = new CFriendList();
searchlist = new CSearchList();
knownfiles = new CKnownFileList();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -