?? tools.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);
{ // 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;
}
BOOL DoChangeFont(CFont & font, LOGFONT* pLF, BOOL bFixed)
{
LOGFONT bck;
memcpy(&bck, pLF, sizeof(LOGFONT));
CFontDialog dlg;
dlg.m_cf.lpLogFont=&bck;
dlg.m_cf.Flags |= (CF_INITTOLOGFONTSTRUCT);
if (bFixed)
dlg.m_cf.Flags |= CF_FIXEDPITCHONLY;
dlg.m_cf.Flags&=~(CF_EFFECTS);
if (dlg.DoModal()!=IDOK)
return FALSE;
if (memcmp(&bck, pLF, sizeof(LOGFONT))==0)
return FALSE;
font.DeleteObject();
font.CreateFontIndirect(&bck);
memcpy(pLF, &bck, sizeof(LOGFONT));
return TRUE;
}
void GetFontName(const LOGFONT& lf, CString& s)
{
int nTextSize;
CWindowDC dc(NULL);
int npx=dc.GetDeviceCaps(LOGPIXELSY);
nTextSize = -MulDiv(lf.lfHeight, 72, npx);
if (nTextSize < 0)
nTextSize = -nTextSize;
s.Format(_T("%s , %d"), lf.lfFaceName,nTextSize);
}
static const TCHAR* pszL = NULL;
CString _S(int i)
{
CString sTemp; AfxExtractSubString(sTemp, pszL, i, TCHAR(','));
return sTemp;
}
#ifdef _UNICODE
#define _L(i) _wtol(_S(i))
#else
#define _L(i) atol(_S(i))
#endif
#define _B(i) (BYTE)_L(i)
#define StartConversion(s) pszL = s
BOOL LF2String(LOGFONT& lf, CString& s, BOOL bToString)
{
if (bToString)
{
static const TCHAR szLogFontMatch[] = _T("%d,%d,%d,%d,%d,%u,%u,%u,%u,%u,%u,%u,%u,%s");
s.Format(szLogFontMatch, lf.lfHeight, lf.lfWidth, lf.lfEscapement, lf.lfOrientation,
lf.lfWeight, lf.lfItalic,lf.lfUnderline, lf.lfStrikeOut,
lf.lfCharSet,lf.lfOutPrecision, lf.lfClipPrecision, lf.lfQuality,
lf.lfPitchAndFamily, lf.lfFaceName);
return TRUE;
}
StartConversion(s);
lf.lfHeight = _L(0);
lf.lfWidth = _L(1);
lf.lfEscapement = _L(2);
lf.lfOrientation = _L(3);
lf.lfWeight = _L(4);
lf.lfItalic = _B(5);
lf.lfUnderline = _B(6);
lf.lfStrikeOut = _B(7);
lf.lfCharSet = _B(8);
lf.lfOutPrecision = _B(9);
lf.lfClipPrecision = _B(10);
lf.lfQuality = _B(11);
lf.lfPitchAndFamily = _B(12);
memcpy(lf.lfFaceName, _S(13), LF_FACESIZE);
return (_tcslen(lf.lfFaceName)>3);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -