📄 dtslog.cpp
字号:
// ============================================================
// 文 件 名:DtsLog.cpp
// 版 权:Copyright(C) 2007-2008 国富安应用项目部
// 版 本:1.0
// 功能描述:系统日志操作类,提供读写日志等功能
// 创建时间:2007.05.10
// 作 者:吴涛
// 备 注:
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DtsLog.h"
#include <math.h>
#ifdef _DEBUG
#undef THIS_FILE
static TCHAR THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#include "assert.h"
#include "AesInterface.h"
#pragma comment(lib,"MyAesLib.lib")
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
const char AES_KEY[] = {"1234567890123456"};
enum CRYPT_FLAG
{
ENCRPT = 0,
DECRPT
};
CString CryptString(const char* _str,CRYPT_FLAG _flag)
{
int keyLen = strlen(AES_KEY);
int len = strlen(_str);
CString result = "";
IAesInterface* IAes = CreateAesInstance();
if(IAes&&_str)
{
try
{
IAes->MakeKey(AES_KEY, keyLen, keyLen);
int newLen = ( ceil(len/keyLen)+1 ) * keyLen;
char* inTmp = new char[newLen+1];
memset(inTmp,0,newLen*sizeof(char));
inTmp[newLen] = '\0';
strncpy( inTmp,_str,len );
char* outTmp = new char[newLen+1];
memset(outTmp,0,newLen*sizeof(char));
if(_flag==ENCRPT)
IAes->Encrypt(inTmp, outTmp, newLen, IAes->ECB);
else
IAes->Decrypt(inTmp, outTmp, newLen, IAes->ECB);
outTmp[len] = '\0';
result = outTmp;
delete[] inTmp;
delete[] outTmp;
DestroyAesInstance(IAes);
}
catch(exception& roException)
{
DestroyAesInstance(IAes);
::OutputDebugString(roException.what());
}
}
return result;
}
CString EnCryptString(const char* _str)
{
CString result = "";
IAesInterface* IAes = CreateAesInstance();
if(IAes&&_str)
{
try
{
IAes->MakeKey(AES_KEY, 16, 16);
int len = strlen(_str);
char* out = new char[len+1];
out[len] = '\0';
IAes->Decrypt(_str, out, len, IAes->ECB);
result = out;
DestroyAesInstance(IAes);
}
catch(exception& roException)
{
DestroyAesInstance(IAes);
::OutputDebugString(roException.what());
}
}
return result;
}
CDtsLog::CDtsLog()
{
TCHAR szPath[MAX_PATH] = {0};
GetTempPath(MAX_PATH, szPath);
m_strFilePath = szPath;
m_strFilePath += _T("DtsLog.log");
m_iCountMax = 50;
m_iCountMin = 40;
m_iLogNum = 0;
}
CDtsLog::~CDtsLog()
{
}
void CDtsLog::SetFilePath(LPCTSTR _fileName)
{
m_strFilePath = _fileName;
}
void CDtsLog::SetMinCount(int minCnt)
{
m_iCountMin = minCnt;
}
void CDtsLog::SetMaxCount(int maxCnt)
{
m_iCountMax = maxCnt;
}
void CDtsLog::AddLog(LPCTSTR _subject, LPCTSTR _desc)
{
SYSTEMTIME st;
GetLocalTime(&st);
TCHAR time[64] = {0};
_sntprintf(time,64,TEXT("%d/%d/%d/%d:%d:%d"),st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
int size_hdr = sizeof(_DTS_LOG_HDR);
int size_con = sizeof(_DTS_LOG_CONTENT);
//int size_desc = strlen(_desc);
int size_desc = _tcslen(_desc);
_DTS_LOG_CONTENT con;
memset(&con,0,size_con);
//strcpy(con.cSubject,_subject);
_tcsncpy(con.cSubject,_subject,sizeof(con.cSubject)/*_tcsclen(_subject)*sizeof(TCHAR)*/);
con.dwDescNum = size_desc;
//strcpy(con.cTime,time);
_tcsncpy(con.cTime,time,sizeof(con.cTime)/*_tcsclen(time)*sizeof(TCHAR)*/);
if(!ReadLogFile(m_strFilePath))
return;
if(m_iLogNum==0) //没有文件记录
{
//建立文件目录
CreateFolder(GetFileDir(m_strFilePath));
m_iLogNum = 1;
m_que.push(con);
m_queDesc.push(_desc);
WriteLogFile();
}
else if(m_iLogNum<m_iCountMax) //数量没有达到最大数,直接添加在文件尾部
{
CStdioFile file(m_strFilePath,CFile::modeWrite|CFile::modeNoTruncate|CFile::typeBinary);
//insert to the file end
//计算移动到文件尾部需要的大小,分两部分:固定大小的结构+不定长的字符累加
//文件头大小+日志记录个数字段大小+日志记录大小×记录数+日志描述大小×记录数
int size = size_hdr + sizeof(DWORD) + size_con*m_iLogNum;
//不定长的字符累加
std::queue<_DTS_LOG_CONTENT> m_queTmp = m_que;
_DTS_LOG_CONTENT conTmp;
while(!m_queTmp.empty())
{
conTmp = m_queTmp.front();
size+=conTmp.dwDescNum;
m_queTmp.pop();
}
//添加记录
m_que.push(con);
m_queDesc.push(_desc);
m_iLogNum++;
//添加记录到文件尾部,并修改记录数
file.Seek(size_hdr,CFile::begin);
file.Write(&m_iLogNum,sizeof(DWORD));
file.Seek(size,CFile::begin);
file.Write(&con,size_con);
CString str_desc = CryptString(_desc,ENCRPT);
int str_length = str_desc.GetLength();
LPTSTR pstr_Data = str_desc.GetBuffer(str_length);
file.Write(pstr_Data,size_desc*sizeof(TCHAR));
file.Close();
}
else //日志数量已经达到最大数,删除日志文件,重新写入
{
//删除队列的前m_iCountMax-m_iCountMin+1条记录
for(int i=0; i<=m_iCountMax-m_iCountMin; i++)
{
m_que.pop();
m_queDesc.pop();
}
//添加新记录
m_que.push(con);
m_queDesc.push(_desc);
m_iLogNum = m_iCountMin;
//删除原文件,重新写文件
WriteLogFile();
}
}
void CDtsLog::DelLogFile()
{
if(WaitUtilLogFileCanUse())
{
DeleteFile(m_strFilePath);
while(!m_que.empty())
{
m_que.pop();
}
while(!m_queDesc.empty())
{
m_queDesc.pop();
}
m_iLogNum = 0;
}
}
//读文件到日志队列中
bool CDtsLog::ReadLogFile(CString _filename)
{
if(_filename==m_strFilePath && !WaitUtilLogFileCanUse(FILE_SHARE_READ))
{
return false;
}
while(!m_que.empty())
{
m_que.pop();
}
while(!m_queDesc.empty())
{
m_queDesc.pop();
}
m_iLogNum = 0;
//先判断文件是否存在,存在则读出日志记录
if (GetFileAttributes(_filename) != -1)
{
CStdioFile file(_filename,CFile::shareDenyNone|CFile::typeBinary);
int size_con = sizeof(_DTS_LOG_CONTENT);
int size_hdr = sizeof(_DTS_LOG_HDR);
_DTS_LOG_CONTENT con;
memset(&con,0,size_con);
_DTS_LOG_HDR t_head;
memset(&t_head,0,size_hdr);
file.Read(&t_head,size_hdr);
if(t_head.dwSignature!=0x8CA53903||
t_head.wVersion[0]!=1||
t_head.wVersion[1]!=0||
t_head.wVersion[2]!=1||
t_head.wVersion[3]!=0)
{
file.Close();
return false;
}
file.Read(&m_iLogNum,sizeof(DWORD));
for(int i=0;i<m_iLogNum;++i)
{
file.Read(&con,size_con);
//char* str = new char[con.dwDescNum+1];
TCHAR* str = new TCHAR[con.dwDescNum+1];
str[con.dwDescNum] = TEXT('\0');
file.Read(str,con.dwDescNum*sizeof(TCHAR));
CString str_desc = CryptString(str,DECRPT);
m_que.push(con);
m_queDesc.push(str_desc);
delete[] str;
}
//Sleep(10000);
file.Close();
//从其他文件中读取记录时,重写入当前文件
if(_filename!=m_strFilePath)
WriteLogFile();
}
return true;
}
//写入文件,写入前删除log文件
bool CDtsLog::WriteLogFile()
{
//等文件可用,即没有其他在读取,超时返回不做任何动作
if(!WaitUtilLogFileCanUse())
{
return false;
}
int size_hdr = sizeof(_DTS_LOG_HDR);
int size_con = sizeof(_DTS_LOG_CONTENT);
_DTS_LOG_HDR t_head;
memset(&t_head,0,size_hdr);
t_head.dwSignature = 0x8CA53903;
t_head.wVersion[0] = 1;
t_head.wVersion[1] = 0;
t_head.wVersion[2] = 1;
t_head.wVersion[3] = 0;
DeleteFile(m_strFilePath);
CStdioFile file(m_strFilePath,CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);
file.Write(&t_head,size_hdr);
file.Write(&m_iLogNum,sizeof(DWORD));
std::queue<_DTS_LOG_CONTENT> m_queTmp = m_que;
std::queue<CString> m_queDescTmp = m_queDesc;
_DTS_LOG_CONTENT con;
memset(&con,0,size_con);
CString str = _T("");
if(m_iLogNum==m_queTmp.size()&&m_iLogNum==m_queDescTmp.size())
{
while(!m_queTmp.empty())
//for(int i=0;i<m_iLogNum;++i)
{
con = m_queTmp.front();
str = m_queDescTmp.front();
int str_length = str.GetLength();
LPTSTR pstr_Data = str.GetBuffer(str_length);
file.Write(&con ,size_con);
CString str_desc = CryptString(pstr_Data,ENCRPT);
str_length = str_desc.GetLength();
pstr_Data = str_desc.GetBuffer(str_length);
file.Write(pstr_Data, con.dwDescNum*sizeof(TCHAR));
m_queTmp.pop();
m_queDescTmp.pop();
}
}
else
assert(TEXT("WriteLogFile--Error!"));
file.Close();
return true;
}
bool CDtsLog::IsLogExist()
{
return (GetFileAttributes(m_strFilePath) != -1);
}
//如果有其他程序在读取该文件,则等待
//超过规定时间,则显示超时,返回false
bool CDtsLog::WaitUtilLogFileCanUse(int flag /*= 0*/)
{
int time = 0;
bool result = true;
if(IsLogExist())
{
HANDLE hFile;
hFile = CreateFile(m_strFilePath, // file to open
GENERIC_READ, // open for writing
flag, // do not share
NULL, // default security
OPEN_EXISTING, // overwrite existing
FILE_ATTRIBUTE_NORMAL, // normal
NULL); // no attr. template
int errorcode = GetLastError();
while(hFile == INVALID_HANDLE_VALUE)
{
hFile = CreateFile(m_strFilePath, // file to open
GENERIC_READ, // open for writing
flag, // do not share
NULL, // default security
OPEN_EXISTING, // overwrite existing
FILE_ATTRIBUTE_NORMAL, // normal
NULL); // no attr. template
Sleep(100);
time += 100;
//2秒没响应,显示超时提示用户重新操作
if(time>2000)
{
result = false;
break;
}
}
CloseHandle(hFile);
}
return result;
}
//通过完整文件名得到文件目录
CString CDtsLog::GetFileDir(CString _filename)
{
int pos = _filename.ReverseFind('\\');
CString tmp = _filename.Left(pos+1);
return tmp;
}
//递归创建多级目录
BOOL CDtsLog::CreateFolder(CString cstrPath)
{
BOOL bRet = TRUE;
LPCSTR lpcstrParent;
CString cstrParent;
int iPos = 0;
int iLen;
if(cstrPath.IsEmpty())
return FALSE;
iLen = cstrPath.GetLength();
iPos = cstrPath.ReverseFind('\\');
cstrParent = cstrPath.Left(iPos);
// 目录名称错误
if(cstrParent.IsEmpty())
return FALSE;
lpcstrParent = cstrParent.Left(cstrParent.GetLength());
//如果长度小于3,表示为磁盘根目录
if(cstrParent.GetLength() > 3)
bRet = IsExistDirectory(lpcstrParent);// 检查父目录是否存在
if(!bRet) //父目录不存在,递归调用创建父目录
bRet = CreateFolder(lpcstrParent);
if(bRet) //父目录存在,直接创建目录
{
bRet = CreateDirectory(cstrPath, NULL);
}
return bRet;
}
//判断文件夹是否存在
BOOL CDtsLog::IsExistDirectory(CString cstrPath)
{
return (GetFileAttributes(cstrPath) == FILE_ATTRIBUTE_DIRECTORY);
}
void CDtsLog::DelLastLog()
{
std::queue<_DTS_LOG_CONTENT> t_que = m_que;
std::queue<CString> t_queDesc = m_queDesc;
if(m_iLogNum>0)
{
while(!m_que.empty())
{
m_que.pop();
}
while(!m_queDesc.empty())
{
m_queDesc.pop();
}
for(int i=0;i<m_iLogNum-1;++i)
{
m_que.push(t_que.front());
m_queDesc.push(t_queDesc.front());
t_que.pop();
t_queDesc.pop();
}
m_iLogNum--;
WriteLogFile();
}
}
CString CDtsLog::GetDtsLogFileName()
{
return m_strFilePath;
}
//返回值为0则创建失败,返回值为1则表示有实例存在,否则返回创建的值
HANDLE CDtsLog::EnableLog(LPCTSTR szKey)
{
if(!IsLogEnabled(szKey))
{
HANDLE handle = ::CreateMutex(NULL, FALSE, szKey);
return handle;
}
return (HANDLE)1;
}
void CDtsLog::DisableLog(HANDLE hKey)
{
if((DWORD)hKey > 10)
{
CloseHandle(hKey);
hKey = NULL;
}
}
BOOL CDtsLog::IsLogEnabled(LPCTSTR szKey)
{
/*
////////////////////////////
BOOL bRet = TRUE;
//中国建设银行 客户端检测工具 1.0.1.0
HWND hWnd = FindWindow(NULL,szKey);
if(hWnd)
bRet = TRUE;
else
bRet = FALSE;
return bRet;
*/
/*
////////////////////////////
BOOL bRet = TRUE;
HANDLE handle = ::CreateMutex(NULL,FALSE,szKey);
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
bRet = FALSE;
}
CloseHandle(handle);
return bRet;
*/
////////////////////////////
BOOL bRet = FALSE;
HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, szKey);
if(hMutex != NULL)
{
bRet = TRUE;
CloseHandle(hMutex);
hMutex = NULL;
}
return bRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -