⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tools.cpp

📁 一个邮件客户端源代码,包括收发邮件,安排日程等很多内容
💻 CPP
字号:
#include "stdafx.h"
#include "tools.h"
#include "blowfish.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

BOOL	FindLocalFile(LPCTSTR sFile, CString& s, BOOL bCreate)
{
	if (strchr(sFile, '\\')!=NULL)	// expect full or partial path, let file finder work
	{
		CFileFind finder;
		if ( finder.FindFile(sFile) )
		{
			finder.FindNextFile();
			s = finder.GetFilePath();
			return TRUE;
		}
	}
	// try at exe path
	CString sPath;
	GetModuleFileName(NULL, sPath.GetBuffer(MAX_PATH), MAX_PATH-1);
	sPath.ReleaseBuffer();
	int nPos = sPath.ReverseFind('\\');
	if (nPos<0)
		return FALSE;
	s = sPath.Left(nPos+1);
	s += sFile;
	DWORD dwA = GetFileAttributes(s);
	if ((dwA & FILE_ATTRIBUTE_DIRECTORY) == 0)
		return TRUE;
	if (dwA == (DWORD)-1 && bCreate)
	{
		CFile file;
		file.Open(s, CFile::modeCreate, NULL);
		file.Close();
		return TRUE;
	}
	return FALSE;
}

BOOL LoadTextFile(LPCTSTR sFile, CStringArray& asValues, TCHAR cRem, BOOL bCaseSens)
{
	CString sPath;
	if ( !FindLocalFile(sFile, sPath) )
		return FALSE;
	CStdioFile file;

	try
	{
		if (!file.Open(sPath, CFile::modeRead|CFile::typeText))
			return FALSE;
		asValues.SetSize(1, 10);
		int nCur = 0;
		while (file.ReadString(asValues[nCur]))
		{
			if (!asValues[nCur].IsEmpty() && asValues[nCur].GetAt(0)!=cRem)
			{
				if (!bCaseSens)
					asValues.ElementAt(nCur).MakeLower();
				nCur++;
				asValues.Add("");
			}
		}
		asValues.RemoveAt(asValues.GetSize()-1);
	}
	catch(CException* e)
	{
		e->Delete();
	}
	catch(...)
	{
	}
	file.Close();
	return TRUE;
}

BOOL IsStringMatch(LPCTSTR sV, LPCTSTR sM)
{
	CString sMask = sM;
	CString sStr = sV;

	if (sStr == sMask)
		return TRUE;
	
	LPCTSTR str=(LPCTSTR)sStr;
	LPCTSTR mask=(LPCTSTR)sMask;

	LPCTSTR pMask=mask;
	LPCTSTR pAsterisk=NULL;
	LPCTSTR pStoredPos=NULL;
	if (!str || !_tcslen(str))
		return FALSE;
	if (!mask || !_tcslen(mask) || !_tcscmp(mask, _T("*")))
		return TRUE;
	while (*pMask)
	{
		TCHAR cM=*pMask++;
		if (!*str && cM!='*')	// for case like _T("aaa") && _T("aaa*")
			return FALSE;
		switch (cM)
		{
			case '?':
				str++;
				break;
			case '*':
			{
				TCHAR c=*pMask;
				if (!c)	// last *
					return TRUE;
				TCHAR* t=_tcschr(str, c);
				if (!t)
					return FALSE;	// unable to continue
				pAsterisk=pMask-1;
				pMask++;
				pStoredPos=t+1;
				str=t+1;
				break;
			}
			default:
			{
				TCHAR cS=*str++;
				if (cS==cM)		//ok
					continue;
				// failed!, try to move back
				if (!pAsterisk)
					return FALSE;
				// assign last found char to * and goon
				pMask=pAsterisk;
				str=pStoredPos;
			}
		}	// switch
	}	// while
	return (!*str);
}

#define TXTFILE_KEY "\\txtfile\\shell\\open\\command\\"

BOOL GetTextHandler(CString& sRet, LPCTSTR sFile)
{
	CString sApp;
	HKEY key;
	if (RegOpenKey(HKEY_CLASSES_ROOT, TXTFILE_KEY, &key)==ERROR_SUCCESS)
	{
		LONG lLen = MAX_PATH-1;
		RegQueryValue(key, NULL, sApp.GetBuffer(MAX_PATH), &lLen);
		sApp.ReleaseBuffer();
		RegCloseKey(key);
	}
	if (sApp.IsEmpty())
		sApp = _T("notepad.exe");
	
	if (sApp.Find("%1")>0)
	{
		sApp.Replace("%1", "%s");
		sRet.Format(sApp, sFile);
	}
	else
		sRet.Format("\"%s\" \"%s\"", sApp, sFile);

	return TRUE;
}

BOOL GetAddressesFrom(CString& sFull, CStringArray& as)
{
	if (sFull.Find('<')<0)
	{
		as.Add(sFull);
		return FALSE;
	}
	CString sAddr;
	int nCur = 0;
	while (1)
	{
		int nOpen =	sFull.Find('<', nCur);
		if (nOpen<0)
			break;
		int nClose = sFull.Find('>', nOpen);
		if (nClose<0)
			break;
		sAddr = sFull.Mid(nOpen+1, nClose-nOpen-1);
		nCur = nClose;
		if (sAddr.IsEmpty())
			continue;
		as.Add(sAddr);
	}
	return TRUE;
}
BOOL GetAddressFrom(CString& sFull, CString& sAddr)
{
	int nOpen =	sFull.Find('<');
	if (nOpen<0)
	{
		sAddr = sFull;
		return FALSE;
	}
	int nClose = sFull.Find('>', nOpen);
	if (nClose <= nOpen)
		sAddr = sFull.Mid(nOpen+1);
	else
		sAddr = sFull.Mid(nOpen+1, nClose-nOpen-1);
	return TRUE;
}


//////////////////
CLog::CLog(LPCTSTR filename, int nMaxSize)
{
	CString sPath;
	if (!FindLocalFile(filename, sPath, TRUE))
		return;
	try
	{
		BOOL bExist = (BOOL)(::GetFileAttributes(sPath)!=(DWORD)-1);
		if (!bExist)
			m_bOpen = Open(sPath, CFile::modeCreate|CFile::modeWrite|CFile::typeText);
		else
		{
			m_bOpen = Open(sPath, CFile::modeRead|CFile::modeWrite|CFile::typeText);
			if (!m_bOpen)
				return;
			DWORD dwLen = GetLength();
			if (nMaxSize > 0 && dwLen > (DWORD)nMaxSize )
			{
				Close();
				m_bOpen = FALSE;
				CFile cut;
				cut.Open(sPath, CFile::modeReadWrite|CFile::typeBinary);
				// reset file
				// load 2/3 at file end
				BYTE* pBytes = new BYTE[nMaxSize];
				cut.Seek(nMaxSize/3, CFile::begin);
				DWORD dwRead = cut.Read(pBytes, nMaxSize);
				for (DWORD nOffs = 0; nOffs<dwRead; nOffs++)
				{
					if (pBytes[nOffs]=='\n')
						break;
				}
				cut.SeekToBegin();
				cut.Write(pBytes+nOffs+1, dwRead-nOffs-1);
				delete pBytes;
				cut.SetLength(dwRead-nOffs-1);
				cut.Close();
				m_bOpen = Open(sPath, CFile::modeWrite|CFile::typeText);
				SeekToEnd();
			}
			else 
				SeekToEnd();	// append
		}
	}
	catch (CException*e)
	{
		e->Delete();
	}
	catch (...)
	{
		return;
	}
}
CLog::~CLog()
{
	try
	{
		if (m_bOpen)
			Close();
	}
	catch(CFileException* e)
	{
		e->Delete();
	}
}
void AFX_CDECL CLog::Log(LPCTSTR lpszFormat, ...)
{
	if (!m_bOpen)
		return;
	va_list args;
	va_start(args, lpszFormat);
	_vstprintf(m_szText, lpszFormat, args);
	va_end(args);
	try
	{
		WriteString(m_szText);
	}
	catch(CFileException* e)
	{
		e->Delete();
	}
}

void BFPack(LPBYTE pData, int nLen, BYTE* pKey, int nKeyLen, int nCode)
{
	// prepare BF key
	BFkey_type mainkey;
	if (blowfish_make_bfkey(pKey, nKeyLen, &mainkey))
		return;
	
	// code it by 8 bytes blocks
	int nBlocks = nLen/8;
	LPBYTE pPrev = NULL;	// used in blocks chaining
	bf_cblock  src;
	bf_cblock dst;
	bf_cblock prev;
	for (int bl=0; bl<nBlocks; bl++)
	{
		memset(src, 0, sizeof(src));
		int nSize = sizeof(src);
		memcpy(src, pData, nSize);
		if (pPrev && nCode)
		{
			for (int i=0; i<sizeof(src); i++)
			{
				src[i] ^= prev[i];
			}
		}
		blowfish_crypt(src, dst, &mainkey, (short)nCode);
		if (!nCode && pPrev)
		{	// xor to decode
			for (int i=0; i<sizeof(src); i++)
			{
				dst[i] ^= prev[i];
			}
		}
		if (nCode)
			memcpy(prev, dst, sizeof(src));
		else
			memcpy(prev, src, sizeof(src));
		memcpy(pData, dst, nSize);
		pPrev = pData;
		pData+=nSize;
	}
}


static BYTE EncSign[] = {'M', 'P', 'P', 'F'};	// Magic Password Protected File

// simple hash - CRC32 is slower, fast table implementation is big
// finally, who care about strong encryption here :-))
DWORD GetDataHash(LPBYTE pData, DWORD dwLen)
{
	register DWORD h=0;
	for (DWORD i=0; i<dwLen; i++, pData++)
    {
        h = h * 9551 + (*pData);
    }
    return h;
}


BOOL IsEncrypted(LPBYTE pData, DWORD dwSize)
{
	DWORD SSize = sizeof(EncSign)/sizeof(EncSign[0]);
	if (dwSize<SSize+1)
		return FALSE;
	if (memcmp(pData, EncSign, SSize)!=0)
		return FALSE;
	return TRUE;
}

BOOL DecryptData(LPBYTE &pData, DWORD &dwSize, LPCTSTR sPass)
{
	if (!IsEncrypted(pData, dwSize))
		return FALSE;
	int SSize = sizeof(EncSign)/sizeof(EncSign[0]);
	LPBYTE pTmp = new BYTE[dwSize];
	memcpy(pTmp, pData, dwSize);
	LPBYTE pWork = pTmp + SSize;
	DWORD dwCRC = *((DWORD*)pWork);
	pWork += sizeof(DWORD);
	DWORD dwRealLen = *((DWORD*)pWork);
	pWork += sizeof(DWORD);
	if (dwRealLen>=dwSize)
		return FALSE;

	BFPack(pWork, dwSize-SSize-sizeof(DWORD)*2, (LPBYTE)sPass, strlen(sPass), FALSE);
	DWORD dwCalcCrc = GetDataHash(pWork, dwRealLen);
	if (dwCalcCrc == dwCRC)
	{
		memcpy(pData, pWork, dwRealLen);
		dwSize = dwRealLen;
	}
	delete pTmp;
	return (dwCalcCrc == dwCRC);
}

BOOL EncryptData(LPBYTE &pData, DWORD &dwSize, LPCTSTR sPass)
{
	// prepare new buffer - with padding(10) and place for sign, crc and len
	int SSize = sizeof(EncSign)/sizeof(EncSign[0]);
	DWORD dwNewSize = dwSize + sizeof(DWORD)*2 + SSize + 8;
	LPBYTE pEnc = new BYTE[dwNewSize];
	// signature
	memcpy(pEnc, EncSign, SSize);
	// crc
	DWORD dwCRC = GetDataHash(pData, dwSize);
	*((DWORD*)(pEnc+SSize)) = dwCRC;
	SSize += sizeof(DWORD);
	// size
	*((DWORD*)(pEnc+SSize)) = dwSize;
	SSize += sizeof(DWORD);
	// data
	memcpy(pEnc+SSize, pData, dwSize);
	// padding - with any data, use crc for it
	memcpy(pEnc+SSize+dwSize, &dwCRC, sizeof(DWORD));
	memcpy(pEnc+SSize+dwSize+sizeof(DWORD), &dwCRC, sizeof(DWORD));
	// encryption
	BFPack(pEnc+SSize, dwNewSize-SSize, (LPBYTE)sPass, strlen(sPass), TRUE);
	// return values
	delete pData;	
	pData = pEnc;
	dwSize = dwNewSize;
	return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CColorSample

CColorSample::CColorSample()
{
}

CColorSample::~CColorSample()
{
}


BEGIN_MESSAGE_MAP(CColorSample, CStatic)
	//{{AFX_MSG_MAP(CColorSample)
	ON_WM_CTLCOLOR_REFLECT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CColorSample message handlers

HBRUSH CColorSample::CtlColor(CDC* pDC, UINT ) 
{
	if (m_bStd)
		return NULL;
	if (!m_brSample.m_hObject)
		m_brSample.CreateSolidBrush(GetSysColor(COLOR_WINDOW));
	pDC->SetTextColor(m_clrText);
	pDC->SetBkColor(GetSysColor(COLOR_WINDOW));
	return m_brSample;
}
void CColorSample::SetColor(BOOL bStd, COLORREF rgb)
{
	m_bStd = bStd;
	if (!m_bStd)
		m_clrText = rgb;
	if (m_hWnd)
		Invalidate();
}

BOOL FindIgnoreCase(LPCTSTR s, LPCTSTR SubS)
{
	CString sMain(s);
	CString sSub(SubS);
	sMain.MakeUpper();
	sSub.MakeUpper();
    return sMain.Find(sSub) >= 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -