std::wstring
PkyProperty::GetStringW( const char* pszSect, const char* pszKey, std::wstring const& strDefault)
{
	auto const strSect= StringConvert::toWstring( pszSect );
	auto const strKey = StringConvert::toWstring( pszKey );
	return GetStringW( strSect.c_str(), strKey.c_str(), strDefault );
}
std::string
PkyProperty::GetStringA( const wchar_t* pszSect, const wchar_t* pszKey, std::string const& strDefault)
{
	auto const strDef =StringConvert::toWstring( strDefault );
	auto const ret = GetStringW( pszSect, pszKey, strDef );
	return StringConvert::toString( ret );
}
Example #3
0
GXLRESULT CMOListBox::GetStringA(GXINT nIndex, clStringA& str)
{
  clStringW wstr;
  GXLRESULT lr = GetStringW(nIndex, wstr);
  str = wstr;
  return lr;
}
Example #4
0
BOOL CMenuOrder::LoadMenuOrder(LPCSTR sFolderPath)
{
	if(mois)
		delete[] mois;
	if(index)
		delete[] index;
	mois = NULL;
	index = NULL;
	len = 0;

	HKEY hKey;
	BOOL ret = FALSE;
	lpSubKey = MENU_ORDER_KEY;
	lpSubKey += sFolderPath;
	HRESULT hr = RegOpenKey(HKEY_CURRENT_USER, lpSubKey, &hKey);
	if(hr == ERROR_SUCCESS)
	{
		BYTE* lpBuf = NULL;
		DWORD size = 0;
		DWORD type = 0;
		hr = RegQueryValueEx(hKey, "Order", NULL, &type, NULL, &size);
		if(size>0)
		{
			try
			{
			lpBuf = new BYTE[size];
			}
			catch(...)
			{
				RegCloseKey(hKey);
//				if(e!=NULL)e->Delete();
				return FALSE;
			}

			hr = RegQueryValueEx(hKey, "Order", NULL, &type, lpBuf, &size);

			if(type == REG_BINARY)
			{
				BYTE* lpData = lpBuf;
				lpData += 8;
				cbsize = GetDWORD(lpData, NULL);
				reserved = GetDWORD(lpData, NULL);
				len = GetDWORD(lpData, NULL);
				if(len>0)
				{
					try
					{
					mois = new CMenuOrderItem[len];
					index = new int[len];
					ZeroMemory(index, len*sizeof(int));
					}
					catch(...)
					{
//						if(e!=NULL)e->Delete();
						len = 0;
					}

				}
				
				int len1, len2;
				for(int i =0; i< len && mois!= NULL; i++)
				{
					BYTE* lpend = lpBuf+size;
					BYTE* lpbt = lpData;
					len1 = mois[i].cbsize = GetDWORD(lpData, lpend);

					lpend = lpbt + len1;
					mois[i].order = GetDWORD(lpData, lpend);
					len2 = mois[i].len = GetWORD(lpData, lpend);
					mois[i].itemtype = GetWORD(lpData, lpend);
					mois[i].filesize = GetDWORD(lpData, lpend);
					mois[i].filedate = GetWORD(lpData, lpend);
					mois[i].filetime = GetWORD(lpData, lpend);
					mois[i].filetype = GetWORD(lpData, lpend);
					if((mois[i].itemtype & 4) != 0)
					{
						mois[i].longname = GetStringW(lpData, lpend);
					}
					else
						mois[i].longname = GetString(lpData, lpend);
					mois[i].shortname = GetString(lpData, lpend);
					if(mois[i].order>=0 && mois[i].order<len)
						index[mois[i].order] = i;

					lpData = lpbt + len1;
					ret = TRUE;
				}
			}
			delete[] lpBuf;
		}
		RegCloseKey(hKey);
	}
 
	return ret;
}
Example #5
0
/* for use from fish_inject.dll */
EXPORT_SIG(__declspec(dllexport) char*) _OnIncomingIRCLine(HANDLE a_socket, const char* a_line, size_t a_len)
{
	if(!a_socket || !a_line || a_len < 1 || *a_line != ':')
		return NULL;

	if(strstr(a_line, " ") == strstr(a_line, " 005 "))
	{
		std::string l_line(a_line, a_len);
		std::string::size_type l_pos = l_line.find(" NETWORK=");

		if(l_pos != std::string::npos)
		{
			l_pos += 9; // strlen(" NETWORK=")
			std::string::size_type l_endPos = l_line.find(" ", l_pos);
			if(l_endPos == std::string::npos) l_endPos = l_line.size();

			::EnterCriticalSection(&s_socketMapLock);
			// allow overwriting network names for dis/re-connecting BNCs and such:
			s_socketMap[a_socket] = l_line.substr(l_pos, l_endPos - l_pos);
			::LeaveCriticalSection(&s_socketMapLock);

			return NULL;
		}
	}

	// quick exit to save some CPU cycles:
	if(!strstr(a_line, "+OK ") && !strstr(a_line, "mcps "))
		return NULL;

	auto l_ini = GetBlowIni();

	if(!l_ini->GetBool(L"process_incoming", true))
		return NULL;

	/** list of stuff we possibly need to decrypt: **
		:nick!ident@host PRIVMSG #chan :+OK 2T5zD0mPgMn
		:nick!ident@host PRIVMSG #chan :\x01ACTION +OK 2T5zD0mPgMn\x01
		:nick!ident@host PRIVMSG ownNick :+OK 2T5zD0mPgMn
		:nick!ident@host PRIVMSG ownNick :\x01ACTION +OK 2T5zD0mPgMn\x01
		:nick!ident@host NOTICE ownNick :+OK 2T5zD0mPgMn
		:nick!ident@host NOTICE #chan :+OK 2T5zD0mPgMn
		:nick!ident@host NOTICE @#chan :+OK 2T5zD0mPgMn
		:nick!ident@host NOTICE ~#chan :+OK 2T5zD0mPgMn
		(topic) :irc.tld 332 nick #chan :+OK hqnSD1kaIaE00uei/.3LjAO1Den3t/iMNsc1
		:nick!ident@host TOPIC #chan :+OK JRFEAKWS
		(topic /list) :irc.tld 322 nick #chan 2 :[+snt] +OK BLAH
	*/

	std::string l_line(a_line, a_len);
	std::string l_cmd, l_contact, l_message;
	std::string::size_type l_cmdPos, l_tmpPos, l_targetPos, l_msgPos;

	StrTrimRight(l_line);

	l_cmdPos = l_line.find(' ');
	if(l_cmdPos != std::string::npos)
	{
		while(l_line[l_cmdPos] == ' ') l_cmdPos++;
		l_tmpPos = l_line.find(' ', l_cmdPos);

		if(l_tmpPos != std::string::npos)
		{
			while(l_line[l_tmpPos + 1] == ' ') l_tmpPos++;
			l_cmd = l_line.substr(l_cmdPos, l_tmpPos - l_cmdPos);

			l_msgPos = l_line.find(" :", l_tmpPos + 1);

			if(l_msgPos != std::string::npos)
			{
				l_msgPos += 2;
				l_message = l_line.substr(l_msgPos);
			}
		}
	}

	if(l_cmd.empty() || l_message.empty())
		return NULL;

	// check if +OK is in the message part of the line:
	if(l_message.find("+OK ") == std::string::npos && l_message.find("mcps ") == std::string::npos)
		return NULL;

	enum {
		CMD_PRIVMSG = 1,
		CMD_ACTION,
		CMD_NOTICE,
		CMD_N332, // 332 channel :topic
		CMD_TOPIC,
		CMD_N322 // 322 channel users :topic
	} l_cmd_type;

	if(!_stricmp(l_cmd.c_str(), "PRIVMSG"))
		l_cmd_type = CMD_PRIVMSG;
	else if(!_stricmp(l_cmd.c_str(), "NOTICE"))
		l_cmd_type = CMD_NOTICE;
	else if(!strcmp(l_cmd.c_str(), "332"))
		l_cmd_type = CMD_N332;
	else if(!_stricmp(l_cmd.c_str(), "TOPIC"))
		l_cmd_type = CMD_TOPIC;
	else if(!strcmp(l_cmd.c_str(), "322"))
		l_cmd_type = CMD_N322;
	else
		return NULL;

	std::string l_leading, l_trailing;

	if(l_cmd_type == CMD_N322 || l_cmd_type == CMD_N332 || l_cmd_type == CMD_TOPIC)
	{
		l_targetPos = l_line.rfind(" #", l_msgPos);

		if(l_targetPos != std::string::npos && l_targetPos >= l_cmdPos + l_cmd.size())
			/* >= because of the leading space in the find string */
		{
			l_targetPos++; // skip the leading space
			l_tmpPos = l_line.find(' ', l_targetPos + 1);

			if(l_tmpPos != std::string::npos)
			{
				l_contact = l_line.substr(l_targetPos, l_tmpPos - l_targetPos);
			}
		}

		if(l_cmd_type == CMD_N322 && !l_message.empty())
		{
			// account for channel modes in /list, like "[+nts] +OK BLAH"
			if(l_message[0] == '[')
			{
				l_tmpPos = l_message.find("] +OK ");

				if(l_tmpPos != std::string::npos)
				{
					l_leading = l_message.substr(0, l_tmpPos + 2);
					l_message.erase(0, l_tmpPos + 2);
				}
			}
		}
	}
	else
	{
		l_contact = l_line.substr(l_tmpPos + 1, l_msgPos - 2 - l_tmpPos - 1);

		if(!l_contact.empty())
		{
			switch(l_contact[0])
			{
			case '#':
			case '&':
				// channel, l_contact = channel name, all is fine.
				break;
			case '@':
			case '+':
			case '%':
				// onotice or something like that.
				l_contact.erase(0, 1);
				// left in l_contact is the channel name.
				break;
			default:
				// probably a query message. Need to make l_contact the nick name:
				{
					l_tmpPos = l_line.find('!');

					if(l_tmpPos != std::string::npos)
					{
						l_contact = l_line.substr(1, l_tmpPos - 1);
					}
					else
					{
						l_contact.clear();
					}
				}
				// :TODO: for future versions: keep track of local nickname and use that to determine channel/query.
			}
		}
	}

	if(l_contact.empty())
		return NULL;

	if(l_cmd_type == CMD_PRIVMSG && l_message.find("\x01""ACTION ") == 0)
	{
		l_message.erase(0, 8);
		if(l_message.size() > 0 && l_message[l_message.size() - 1] == 0x01) l_message.erase(l_message.size() - 1);
		l_cmd_type = CMD_ACTION;
	}

	if(l_message.find("+OK ") == 0)
		l_message.erase(0, 4);
	else if(l_message.find("mcps ") == 0)
		l_message.erase(0, 5);
	else
		return NULL; // something must have gone awry.

	// account for stuff like trailing time stamps from BNCs:
	if((l_tmpPos = l_message.find(' ')) != std::string::npos)
	{
		l_trailing = l_message.substr(l_tmpPos);
		l_message.erase(l_tmpPos);
	}

	// get blowfish key...
	bool l_cbc;
	std::string l_blowKey, l_networkName;

	::EnterCriticalSection(&s_socketMapLock);
	l_networkName = s_socketMap[a_socket];
	::LeaveCriticalSection(&s_socketMapLock);

	l_blowKey = l_ini->GetBlowKey(l_networkName, l_contact, l_cbc);

	if(l_blowKey.empty())
		return NULL;

	// put together new message:
	std::string l_newMsg;

	if(l_cbc && !l_message.empty() && l_message[0] != '*')
	{
		// silent fallback to old style
		l_cbc = false;
	}
	else if(!l_cbc && !l_message.empty() && l_message[0] == '*')
	{
		// auto-enable new style even for non-prefixed keys
		l_cbc = true;
	}

	if(l_cbc && !l_message.empty() && l_message[0] == '*')
	{
		// strip asterisk
		l_message.erase(0, 1);
	}

	int l_decryptionResult = blowfish_decrypt_auto(l_cbc, l_message, l_newMsg, l_blowKey);

	if(l_decryptionResult == 0)
	{
		// compatibility fix
		// (we only encode the actual MSG part of CTCP ACTIONs, but the old FiSH.dll and some scripts etc.
		// encode the whole thing including \x01 and so on)
		if(l_cmd_type == CMD_PRIVMSG && l_newMsg.find("\x01""ACTION ") == 0)
		{
			l_newMsg.erase(0, 8);
			if(l_newMsg.size() > 0 && l_newMsg[l_newMsg.size() - 1] == 0x01) l_newMsg.erase(l_newMsg.size() - 1);
			l_cmd_type = CMD_ACTION;
		}
		// this obviously needs to be done before appending the crypt mark... fixed 2011-11.
	}

	switch(l_decryptionResult)
	{
	case -1:
		l_newMsg = l_message + "=[FiSH: DECRYPTION FAILED!]=";
		break;
	case 1:
		l_newMsg += "\x02&\x02";
		 /* fall through */
	case 0:
		l_newMsg += l_trailing;
		if(l_ini->GetSectionBool(l_networkName, l_contact, L"mark_encrypted", !l_ini->GetStringW(L"mark_encrypted", L"").empty()))
		{ // try local setting and use global setting as default ^^
			int l_markPos = l_ini->GetInt(L"mark_position"); // 1 = append, 2 = prepend, 0 = disabled
			if(l_markPos > 0 && l_markPos <= 2)
			{
				const std::wstring l_markWide = l_ini->GetStringW(L"mark_encrypted");
				std::string l_mark;

				if(l_ini->NoLegacy())
				{
					std::string l_markDumb;
					// if the .ini file is UTF-8 encoded, UnicodeToCp would double-encode
					// the characters, so try this dumbfolded approach of conversion.

					for each(wchar_t ch in l_markWide)
					{
						if(ch && ch <= std::numeric_limits<unsigned char>::max()) l_markDumb += (unsigned char)ch;
					}

					if(l_markDumb.empty() || !Utf8Validate(l_markDumb.c_str()))
					{
						l_mark = UnicodeToCp(CP_UTF8, l_markWide);
					}
					else
					{
						l_mark = l_markDumb;
					}
				}
				else
				{
					l_mark = UnicodeToCp(CP_UTF8, l_markWide);
				}

				l_mark = SimpleMIRCParser(l_mark);

#if 0
				bool l_msgValid = Utf8Validate(l_newMsg.c_str();
				bool l_markValid = Utf8Validate(l_mark.c_str());

				if(!l_msgValid && l_markValid)
				{
					// prevent total message corruption by using
					// "neutral" crypt-mark
					l_mark = " \x0315*\x03";
				}
#endif

				if(l_markPos == 1)
					l_newMsg.append(l_mark);
				else
					l_newMsg.insert(0, l_mark);
			}