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

📄 dtslog.cpp

📁 本程序是一个用于写日志的库
💻 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 + -