Example #1
0
void CNeoCore::LoadLoginTokens()
{
	QMutexLocker Locker(&m_Mutex);

	time_t uNow = GetTime();
	time_t TimeOut = Cfg(false)->GetUInt("Core/TockenTimeOut");
	foreach(const QString& Token, Cfg(false)->GetStringList("Core/ValidTockens"))
	{
		StrPair TD = Split2(Token,":");
		time_t Time = QDateTime::fromString(TD.second).toTime_t();
		if(Time + TimeOut < uNow)
			continue;
		m_Logins.insert(TD.first, Time);
	}
}
Example #2
0
bool CKademlia::LoadData()
{
	m_pKadKey = new CPrivateKey(CAbstractKey::eUndefined);
	wstring ConfigPath = Cfg()->GetString("ConfigPath");
	if(!ConfigPath.empty())
	{
		CVariant Data;
		if(ReadFile(ConfigPath + L"NeoKad.dat", Data))
		{
			try
			{
				const CVariant& Info = Data["INFO"];

				string Version = Info["VER"];

				const CVariant& KeyValue = Info["PK"];
				if(!m_pKadKey->SetKey(KeyValue.GetData(), KeyValue.GetSize()))
					LogLine(LOG_ERROR, L"Loaded Invalid private Key from file");

				/*CBuffer PL = QByteArray("1234567890ABCDEF");
				CBuffer Sig;
				m_pKadKey->Sign(&PL, &Sig);
				Sig.GetSize();*/
			}
			catch(const CException&)
			{
				ASSERT(0);
				return false;
			}
		}
	}
	return true;
}
Example #3
0
uint32 CKademlia::LoadNodes()
{
	wstring ConfigPath = Cfg()->GetString("ConfigPath");
	if(ConfigPath.empty())
		return 0;

	uint32 Count = 0;
	try
	{
		CVariant NeoNodes;
		ReadFile(ConfigPath + L"NeoNodes.dat", NeoNodes);
		const CVariant& NodeList = NeoNodes["Nodes"];
		for(uint32 i=0; i < NodeList.Count(); i++)
		{
			CPointer<CKadNode> pNode = new CKadNode(m_pRootZone);

			pNode->Load(NodeList.At(i), true);
			if(pNode->GetAddresses().empty())
				continue;

			Count++;
			m_pRootZone->AddNode(pNode);
		}
		m_pKadHandler->SetLastContact(NeoNodes["LastContact"]);
	}
	catch(const CException&)
	{
		ASSERT(0);
	}
	return Count;
}
Example #4
0
QString CNeoCore::GetTempDir(bool bCreate)
{
	QString Path = Cfg()->GetString("Content/Temp");
	if(Path.isEmpty())
	{
		if(Cfg()->IsPortable())
			Path = Cfg()->GetAppDir();
		else
			QDir::homePath() + "/Downloads/NeoLoader";
		Path += "/Temp/";
	}
	if(Path.right(1) != "/")
		Path.append("/");
	if(bCreate)
		CreateDir(Path);
	return Path;
}
Example #5
0
CUInt128 CKademlia::MakeCloseTarget(int *pDistance)
{
	if(!m_pKadHandler)
	{
		if(pDistance)
			*pDistance = -1;
		return 0;
	}

	CUInt128 uMyID = m_pRootZone->GetID();
	NodeMap Nodes;
	m_pRootZone->GetClosestNodes(uMyID, Nodes, Cfg()->GetInt("BucketSize"));
	if(Nodes.size() < 2)
	{
		if(pDistance)
			*pDistance = -1;
		return 0;
	}
	
	// Find Median distance difference between nodes closest to us
	vector<CUInt128> Diff;
	for(NodeMap::iterator np = Nodes.begin(), n = np++; np != Nodes.end(); n = np++)
		Diff.push_back(np->first - n->first);
	CUInt128 Sep = Median(Diff);

	// generate ID that is closer to us than the closest node by a few difference
	CUInt128 uDistance = Nodes.begin()->first;
	for(int i=0; i < 3 && uDistance > Sep; i++)
		uDistance = uDistance - Sep;
	CUInt128 uCloser = uMyID ^ uDistance;

	// count the matchign bits
	UINT uLevel=0;
	for(; uLevel < uMyID.GetBitSize(); uLevel++)
	{
		if(uCloser.GetBit(uLevel) != uMyID.GetBit(uLevel))
			break;
	}

	// add a few more matching bytes
	for(UINT i=0; i < 4 && uLevel < uMyID.GetBitSize() - 1; i++)
	{
		uCloser.SetBit(uLevel, uMyID.GetBit(uLevel));
		uLevel++;
	}

	if(pDistance)
		*pDistance = (int)uMyID.GetBitSize() - uLevel;

	// create a random ID that we are closest to
	CUInt128 uRandom(uCloser, uLevel);
	//wstring sTest = (uMyID ^ uRandom).ToBin();
	return uRandom;
}
Example #6
0
bool CNeoCore::CheckLogin(const QString &LoginToken)
{
	QMutexLocker Locker(&m_Mutex);

	//if(Cfg(false)->GetString("Core/UserName").isEmpty() && Cfg(false)->GetString("Core/Password").isEmpty())
	if(Cfg(false)->GetString("Core/Password").isEmpty())
		return true;
	if(m_Logins.contains(LoginToken))
	{
		if(m_Logins.value(LoginToken) + Cfg(false)->GetUInt("Core/TockenTimeOut") > GetTime()
		 || m_Server->HasLoginToken(LoginToken)) // in this order the slower server sheck will be done selfom if at all
		{
			m_Logins[LoginToken] = GetTime();
			return true;
		}
		m_Logins.remove(LoginToken);
		Locker.unlock();
		SaveLoginTokens();
	}
	return false;
}
Example #7
0
void CNeoCore::SaveLoginTokens()
{
	QMutexLocker Locker(&m_Mutex);

	QStringList Tokens;
	foreach(const QString& Token, m_Logins.keys())
	{
		if(m_Server->HasLoginToken(Token)) // don't save internal login tockens
			continue;
		Tokens.append(Token + ":" + QDateTime::fromTime_t(m_Logins.value(Token)).toString());
	}
	Cfg(false)->SetSetting("Core/ValidTockens", Tokens);
}
Example #8
0
void OptionWindow::writeSettings()
{
OHDebug("Writing Configs ...");
QFile Cfg(QString(QDir().home().absolutePath()).append("/.OpenHanse/cfg.ohc"));
Cfg.open(QIODevice::WriteOnly);
QXmlStreamWriter writer(&Cfg);
writer.setAutoFormatting(true);
writer.writeStartElement("conf");
writer.writeEmptyElement("resolution");
// writer.writeStartElement("height");
writer.writeAttribute(QXmlStreamAttribute("width", QString("%1").arg(XResolutionBox.value())));
writer.writeAttribute(QXmlStreamAttribute("height", QString("%1").arg(YResolutionBox.value())));
writer.writeStartElement("fullscreen");
if(FullScreenCheck.isChecked())
	writer.writeCharacters("true");
else
	writer.writeCharacters("false");

writer.writeEndElement();

writer.writeStartElement("fps");
writer.writeCharacters(QString("%1").arg(FPSSlider.value()));
writer.writeEndElement();

writer.writeStartElement("opengl");
if(OpenGLCheck.isChecked())
	writer.writeCharacters("true");
else
	writer.writeCharacters("false");
writer.writeEndElement();

float miscvolume = MiscVolumeSlider.value()/100;
float musicvolume = MusicVolumeSlider.value()/100;

writer.writeStartElement("misc-volume");
writer.writeCharacters(QString("%1").arg(miscvolume));
writer.writeEndElement();

writer.writeStartElement("music-volume");
writer.writeCharacters(QString("%1").arg(musicvolume));
writer.writeEndElement();


writer.writeEndDocument();
Cfg.close();
// QFile(QString(QDir().home().absolutePath()).append("/.OpenHanse/cfg_old.ohc")).remove();
// QFile(QString(QDir().home().absolutePath()).append("/.OpenHanse/cfg.ohc")).rename("cfg_old.ohc");
// Cfg.rename("cfg.ohc");
OHDebug("End of Writing Configs");
SETTINGS->readConfigs(QFileInfo(Cfg).absoluteFilePath());
}
Example #9
0
void CKademlia::SaveData()
{
	wstring ConfigPath = Cfg()->GetString("ConfigPath");
	if(!ConfigPath.empty())
	{
		CVariant Data;
		CVariant Info;
		Info["VER"] = GetVersion();
		Info["PK"] = CVariant(m_pKadKey->GetKey(), m_pKadKey->GetSize());
		Data["INFO"] = Info;

		WriteFile(ConfigPath + L"NeoKad.dat", Data);
	}
}
Example #10
0
void CKademlia::SaveNodes()
{
	wstring ConfigPath = Cfg()->GetString("ConfigPath");
	if(ConfigPath.empty())
		return;

	NodeList Nodes = m_pRootZone->GetAllNodes();

	CVariant NodeList;
	for (NodeList::iterator I = Nodes.begin(); I != Nodes.end(); I++)
	{
		CKadNode* pNode = *I;
		NodeList.Append(pNode->Store(true));
	}
	CVariant NeoNodes;
	NeoNodes["Nodes"] = NodeList;
	NeoNodes["LastContact"] = m_pKadHandler->GetLastContact();
	WriteFile(ConfigPath + L"NeoNodes.dat", NeoNodes);
}
Example #11
0
void CKademlia::Process(UINT Tick)
{
	m_pSocket->Process((Tick & EPerSec) != 0);

	if(!m_pKadHandler)
		return;

	if((Tick & E2PerSec) != 0) // 2 times a second
	{
		m_pFirewallHandler->Process(Tick);

		m_pKadHandler->Process(Tick);
		m_pRootZone->Process(Tick);
			
		m_pPayloadIndex->Process(Tick);
	}

#ifndef _DEBUG
	if(IsConnected())
#endif
	{
		m_pLookupManager->Process(Tick);

		if((Tick & E10PerSec) != 0) // 10 times a second
			m_pKadEngine->Process(Tick);

		if((Tick & EPer10Sec) != 0) // every 10 seconds
		{	
			if(GetCurTick() - m_uLastSave > SEC2MS(Cfg()->GetInt("NodeSaveInterval")))
			{
				SaveNodes();
				m_uLastSave = GetCurTick();
			}
		}
	}
}
Example #12
0
std::string MyApp::GetMyExten()
{
    return Cfg("dialplan/exten");
}
Example #13
0
std::string MyApp::GetMyChannel()
{
    return Cfg("dialplan/channel");
}
Example #14
0
void MyApp::Originate(const std::string &number)
{
    asterisk->Originate(GetMyChannel(), Cfg("dialplan/context"), number, GetMyExten());
}
Example #15
0
//bool CNeoCore::TestLogin(const QString &UserName, const QString &Password)
bool CNeoCore::TestLogin(const QString &Password)
{
	//return (Cfg(false)->GetString("Core/UserName") == UserName &6 Cfg(false)->GetString("Core/Password") == Password);
	return Cfg(false)->GetString("Core/Password") == Password;
}
Example #16
0
void CNeoCore::Uninitialise()
{
	killTimer(m_uTimerID);

	LogLine(LOG_INFO,tr("NeoLoader Core closing"));

	QString LogPath = Cfg()->GetSettingsDir() + "/Logs/";
	CreateDir(LogPath);

	emit SplashMessage(tr("Saving FileList"));
	m_IOManager->Stop(); // this ends all IO operations
	m_FileManager->Suspend(); // this closes all IO
	if(theCore->Cfg()->GetBool("Content/SaveSearch"))
	{
		m_SearchManager->StoreToFile();
		m_FileGrabber->StoreToFile();
	}
	else
	{
		QFile::remove(theCore->Cfg()->GetSettingsDir() + "/SearchLists.xml");
		QFile::remove(theCore->Cfg()->GetSettingsDir() + "/GrabberList.xml");
	}
	m_Hashing->Stop(); // this stops hashing, doe to cloded IO this should be done instantly
	

	// Note: we can not use delete later here, as this thread is about to terminate and no events will be handled in time
	emit SplashMessage(tr("Ininitialising NeoCore"));
	delete m_RequestManager;
	m_RequestManager = NULL;
	delete m_Server;
	m_Server = NULL;
#ifdef CRAWLER
	delete m_CrawlerManager;
	m_CrawlerManager = NULL;
#endif
	delete m_FileManager;
	m_FileManager = NULL;
	delete m_DownloadManager;
	m_DownloadManager = NULL;
	delete m_UploadManager;
	m_UploadManager = NULL;
	delete m_Hashing;
	m_Hashing = NULL;
	delete m_FileGrabber;
	m_FileGrabber = NULL;
	delete m_SearchManager;
	m_SearchManager = NULL;
	delete m_TorrentManager;
	m_TorrentManager = NULL;
	delete m_MuleManager;
	m_MuleManager = NULL;
	delete m_NeoManager;
	m_NeoManager = NULL;
#ifdef CRAWLER
	delete m_CrawlingManager;
	m_CrawlingManager = NULL;
	delete m_FileArchiver;
	m_FileArchiver = NULL;
#endif
	delete m_Interfaces;
	m_Interfaces = NULL;
	delete m_HttpServer;
	m_HttpServer = NULL;
	delete m_Network;
	m_Network = NULL;
	delete m_Pinger;
	m_Pinger = NULL;
	delete m_IOManager;
	m_IOManager = NULL;
	delete m_PeerWatch;
	m_PeerWatch = NULL;
	delete m_MiniUPnP;
	m_MiniUPnP = NULL;
	delete m_Caffeine;
	m_Caffeine = NULL;
#ifndef NO_HOSTERS
	delete m_ArchiveDownloader;
	m_ArchiveDownloader = NULL;
	delete m_ArchiveUploader;
	m_ArchiveUploader = NULL;
	delete m_WebManager;
	m_WebManager = NULL;
	delete m_WebRepository;
	m_WebRepository = NULL;
	m_LoginManager->sync();
	delete m_LoginManager;
	m_LoginManager = NULL;
	delete m_CaptchaManager;
	m_CaptchaManager = NULL;
	delete m_ConnectorManager;
	m_ConnectorManager = NULL;
#endif

	m_CoreSettings->sync();
	delete m_CoreSettings;
	m_CoreSettings = NULL;
}
Example #17
0
void CNeoCore::Initialise()	
{
	qsrand(QTime::currentTime().msec()); // needs to be done in every thread we use random numbers

	m_CoreSettings = new CSettings("NeoCore", GetDefaultCoreSettings(), this);

	SetLogLimit(Cfg()->GetInt("Log/Limit"));
	if(Cfg()->GetBool("Log/Store"))
		SetLogPath(Cfg()->GetSettingsDir() + "/Logs");

	LoadLoginTokens();

	emit SplashMessage(tr("Initialising NeoCore"));
	m_Interfaces = new CInterfaceManager(this);
	m_RequestManager = new CRequestManager(theCore->Cfg()->GetInt("Browser/TimeoutSecs"), this);
	m_HttpServer = new CHttpServer(theCore->Cfg(false)->GetUInt("HttpServer/Port"),this);
	m_HttpServer->SetKeepAlive(theCore->Cfg(false)->GetUInt("HttpServer/KeepAlive"));
	m_HttpServer->SetTransferBufferSize(theCore->Cfg(false)->GetUInt("HttpServer/TransferBuffer"));
	m_IOManager = new CIOManager(this);
	m_PeerWatch = new CPeerWatch(this);
	m_MiniUPnP = new CMiniUPnP(this);
	m_Caffeine = new CCaffeine(this);
	m_SearchManager = new CSearchManager(this);
#ifdef CRAWLER
	m_CrawlingManager = new CCrawlingManager(this);
	m_FileArchiver = new CFileArchiver(this);
#endif
	m_Hashing = new CHashingThread(this);
	m_Network = new CSocketThread(this);
	m_Network->StartThread();
	m_Pinger = new CPinger(this);
	m_TorrentManager = new CTorrentManager(this);
	m_MuleManager = new CMuleManager(this);
	m_NeoManager = new CNeoManager(this);
	m_FileManager = new CFileManager(this);
	m_DownloadManager = new CDownloadManager(this);
	m_UploadManager = new CUploadManager(this);
	m_FileGrabber = new CFileGrabber(this);
#ifndef NO_HOSTERS
	m_ArchiveDownloader = new CArchiveDownloader(this);
	m_ArchiveUploader = new CArchiveUploader(this);
	m_WebManager = new CWebManager(this);
	m_WebManager->LoadScripts();
	m_WebRepository = new CWebRepository(this);
	m_ConnectorManager = new CConnectorManager(this);
	m_LoginManager = new CLoginManager(this);
	m_CaptchaManager = new CCaptchaManager(this);
#endif

	emit SplashMessage(tr("Loading FileList"));
	m_FileManager->Resume();
	m_SearchManager->LoadFromFile();
	m_FileGrabber->LoadFromFile();
	m_Hashing->start();

#ifdef CRAWLER
	m_CrawlerManager = new CCrawlerManager(this);
#endif

	m_Server = new CCoreServer(this);

	LogLine(LOG_INFO,tr("NeoLoader Core initialised"));

	m_uTimerID = startTimer(10);
}
Example #18
0
bool CKademlia::IsConnected() const
{
	if(!m_pKadHandler)
		return false;
	return m_pRootZone->GetNodeCount() > 0 && (GetTime() - m_pKadHandler->GetLastContact()) < (Cfg()->GetInt64("SelfLookupInterval") * 2);
	//return !m_pFirewallHandler->AddrPool().empty();
}
Example #19
0
CKademlia::CKademlia(uint16 Port, bool bIPv6, const CVariant& Config, const string& Version)
{
	m_Protocol = KAD_PROT_VER;

	if(!Version.empty())
		m_Version += Version;
	else
		m_Version = "v " STR(KAD_PROT_MJR) "." STR(KAD_PROT_MIN);

	m_pConfig = new CKadConfig(this);
	if(Config.IsValid())
		m_pConfig->Merge(Config);

	LoadData();

	if(m_pKadKey->GetAlgorithm() == CAbstractKey::eUndefined)
	{
		m_pKadKey->SetAlgorithm(CAbstractKey::eECP);
		//m_pKadKey->GenerateKey("secp256r1"); // NIST: P-256
		m_pKadKey->GenerateKey("brainpoolP256r1"); // dont trust NIST (NSA) curves, use brainpool
		LogLine(LOG_INFO, L"Generated new Private NodeKey");
		SaveData();
	}

	m_pSocket = new CSmartSocket(SEC2MS(Cfg()->GetInt("ConnectionTimeout")), this);

	CScoped<CPublicKey> pKey = m_pKadKey->PublicKey();

	CUInt128 ID;
	CKadID::MakeID(pKey, ID.GetData(), ID.GetSize());
	LogLine(LOG_INFO, L"Neo Kad ID: %s", ID.ToHex().c_str());

	uint64 RecvKey;
	CAbstractKey::Fold(ID.GetData(), ID.GetSize(),(byte*)&RecvKey, sizeof(RecvKey));
	m_pSocket->SetupCrypto(RecvKey, m_pKadKey);

#ifdef _DEBUG
	LogLine(LOG_INFO, L"Socket PassKey is %I64u", RecvKey);
#endif

	m_Port = 0;
	m_IPv4 = CAddress(CAddress::IPv4);
	m_IPv6 = CAddress(CAddress::IPv6);

	for(int i=Port; i < Port + 1000; i++)
	{
		CUTPSocketListner* pSocketListner = new CUTPSocketListner(m_pSocket);
		CUTPSocketListner* pSocketListnerV6 = bIPv6 ? new CUTPSocketListner(m_pSocket) : NULL;
		bool bV4 = pSocketListner->Bind(i, CAddress(CAddress::IPv4));
		bool bV6 = !pSocketListnerV6 || pSocketListnerV6->Bind(i, CAddress(CAddress::IPv6));
		if(bV4 && bV6)
		{
			m_pSocket->InstallListener(pSocketListner);
			if(pSocketListnerV6)
				m_pSocket->InstallListener(pSocketListnerV6);
			m_Port = i;
			break;
		}
		delete pSocketListner;
		delete pSocketListnerV6;
	}
}
Example #20
0
bool MyApp::OnInit()
{
#ifndef __WXMSW__
    if (wxPlatformInfo::Get().GetOperatingSystemId() & wxOS_UNIX)
    {
        wxStandardPaths::Get().SetInstallPrefix("/usr");
    }
#endif
    wxString datadir = wxStandardPaths::Get().GetDataDir() + wxFileName::GetPathSeparator();
    if (!setlocale(LC_CTYPE, ""))
    {
        fprintf(stderr, "Can't set the specified locale! "
                    "Check LANG, LC_CTYPE, LC_ALL.\n");
    return 1;
    }
    m_locale.Init();
    m_locale.AddCatalog("astercti");

    m_start_gui = ParseCmdLine();
    if (!m_start_gui) return true;

    m_config = NULL;
    m_config = new wxFileConfig(wxT("astercti"),
                                wxEmptyString,
                                wxT("astercti.ini"),
                                wxEmptyString,
                                wxCONFIG_USE_SUBDIR);
    wxFileName configfile = m_config->GetLocalFile("astercti.ini", wxCONFIG_USE_SUBDIR);
    if (!configfile.IsFileReadable())
    {
        std::ostringstream msg;
        msg << _("Error opening config file.") << std::endl
            << _("Sample config is at ") << configfile.GetFullPath() << ".default" << std::endl
            << _("Rename it to astercti.ini and edit.");
        wxLogError("%s", msg.str());
        return false;
    }

    m_chanstatuspool = new ChannelStatusPool(m_config->Read("dialplan/channel").ToStdString());
    if (m_config->HasEntry("lookup/lookup_url"))
    {
        m_lookuper = new CallerInfoLookuperURL(Cfg("lookup/lookup_url"));
    }
    else if (m_config->HasEntry("lookup/lookup_cmd"))
    {
        m_lookuper = new CallerInfoLookuperCmd(Cfg("lookup/lookup_cmd"));
    }
    else
    {
        m_lookuper = NULL;
    }
    wxPoint pos = m_config->ReadObject("autosave/position", wxDefaultPosition);
    wxSize size = m_config->ReadObject("autosave/size", wxSize(600, 400));
    asterisk = new Asterisk(m_config->Read("server/address").ToStdString(),
        5038,
        m_config->Read("server/username").ToStdString(),
        m_config->Read("server/password").ToStdString());
    bool maximized = m_config->ReadBool("autosave/maximized", false);
    m_mainframe = new MyFrame( "AsterCTI", pos, size, m_chanstatuspool, asterisk, m_lookuper, Cfg("lookup/caller_name_field"));
    if (maximized) m_mainframe->Maximize();
    m_mychanfilter = new MyChanFilter(m_config->Read("dialplan/channel").ToStdString());
    m_intmsgfilter = new InternalMessageFilter();
    m_numbershortener = new ShortenNumberModifier(m_config->Read("lookup/replace_number_prefix").ToStdString());
    asterisk->observable_descr = "asterisk";
    m_mychanfilter->observable_descr = "mychanfilter";
    m_intmsgfilter->observable_descr = "intmsgfilter";
    asterisk->broadcast(*m_mychanfilter);
    asterisk->broadcast(*m_intmsgfilter);
    asterisk->broadcast(*m_chanstatuspool);
    m_mychanfilter->broadcast(*m_numbershortener);
    m_numbershortener->broadcast(*m_mainframe);
    m_intmsgfilter->broadcast(*m_mainframe);
    notificationFrame *notifyframe = new notificationFrame(m_mainframe, m_chanstatuspool, asterisk, m_lookuper);
    Executer *executer = new Executer(m_lookuper);
    m_events = new EventGenerator(m_config->Read("dialplan/exten").ToStdString());
    m_events->broadcast(*m_mainframe);
    m_events->broadcast(*notifyframe);
    m_events->broadcast(*executer);
    m_numbershortener->broadcast(*m_events);
    m_intmsgfilter->broadcast(*m_events);
    wxIcon defaultIcon(ACTI_ICON("astercti"));
    wxIcon  missedIcon(ACTI_ICON("astercti-missed"));
    m_mainframe->SetIcon(defaultIcon);
    m_taskbaricon = new MyTaskBarIcon(defaultIcon, missedIcon, "AsterCTI: " + m_config->Read("dialplan/exten"));
    m_taskbaricon->SetMainFrame(m_mainframe);
    m_mainframe->SetTaskBarIcon(m_taskbaricon);
    m_mainframe->Show(!start_iconified);
    SetTopWindow(m_mainframe);
    SetExitOnFrameDelete(true);
    if (!m_lookuper)
    {
        m_mainframe->Log(_("Lookup URL and Lookup command are both unconfigured.\nLookup disabled."));
    }
    m_ipcServer = new IpcServer();
    if (!m_ipcServer->Create(IPC_SERVICENAME))
        wxLogMessage("Failure creating IPC Server %s", IPC_SERVICENAME);
#ifndef __WXMSW__
    wxHandleFatalExceptions();
#endif
    return true;
}