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

📄 dlgrecoveprogress.cpp

📁 COM 组建的开发
💻 CPP
字号:
// DlgRecoveProgress.cpp : implementation file
//

#include "stdafx.h"
#include "resource.h"
#include "DlgRecoveProgress.h"
#include <io.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDlgRecoveProgress dialog


CDlgRecoveProgress::CDlgRecoveProgress(CWnd* pParent /*=NULL*/)
	: CDialog(CDlgRecoveProgress::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDlgRecoveProgress)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT

	m_hExitFlag = NULL;// 是否退出工作线程 [5/7/2008 By willing]
	m_hThreadHandle = NULL;// 线程句柄 [5/7/2008 By willing]
	m_dwEncryptThreadID = 0;// 线程ID [5/7/2008 By willing]
}


void CDlgRecoveProgress::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlgRecoveProgress)
	DDX_Control(pDX, IDC_LISTBOX, m_listbox);
	DDX_Control(pDX, IDC_PROGRESS, m_ProgressCtrl);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDlgRecoveProgress, CDialog)
	//{{AFX_MSG_MAP(CDlgRecoveProgress)
		ON_MESSAGE(WM_SETTITLE, OnSetTitle)
		ON_MESSAGE(WM_RC_SENDMSG, OnRcSendMsg)
		ON_MESSAGE(WM_RC_POSTMSG, OnRcPostMsg)
		ON_MESSAGE(WM_RC_SETPOS,OnPostProgressMsg)
		ON_MESSAGE(WM_RC_AUTOEXIT,OnAutoExit)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgRecoveProgress message handlers

void CDlgRecoveProgress::SetPwd(const CString strPwd)
{
	m_strPwd = strPwd;
}
// 修改还原窗口的Title [5/16/2008 By willing]
LRESULT CDlgRecoveProgress::OnSetTitle(WPARAM wParam,LPARAM lParam)
{
	if (NULL == wParam)
	{
		return 0;
	}
	DLG_TITLE* ptrDlgTitle = (DLG_TITLE*)wParam;
	CString strMsg = "";
	strMsg.Format("还原文件 [%d/%d]",ptrDlgTitle->nCurIndex,ptrDlgTitle->nTotalCount);
	SetWindowText(strMsg);
	if (NULL != ptrDlgTitle)
	{
		delete ptrDlgTitle;
		ptrDlgTitle = NULL;
	}
	return 0;
}
// 将收到的文本消息显示到ListBox中 [5/16/2008 By willing]
LRESULT CDlgRecoveProgress::OnRcSendMsg(WPARAM wParam,LPARAM lParam)
{
	if (NULL == wParam)
	{
		return 0;
	}
	RCV_MSG* ptrRcvMsg = (RCV_MSG*)wParam;
	SetMsg(CString(ptrRcvMsg->szMsg),ptrRcvMsg->nTextColor);
	return 0;
}
LRESULT CDlgRecoveProgress::OnRcPostMsg(WPARAM wParam,LPARAM lParam)
{
	if (NULL == wParam)
	{
		return 0;
	}
	RCV_MSG* ptrRcvMsg = (RCV_MSG*)wParam;
	SetMsg(CString(ptrRcvMsg->szMsg),ptrRcvMsg->nTextColor);
	return 0;
}
// 启动工作线程 [5/16/2008 By willing]
int CDlgRecoveProgress::Run()
{
	// 创建停止线程标志 [5/16/2008 By willing]
	Sleep(20);
	m_hWaitFlag = ::CreateEvent(NULL, FALSE, FALSE, NULL);
	::SetEvent(m_hWaitFlag);
	m_hExitFlag = ::CreateEvent(NULL,TRUE,FALSE,NULL);
	if (NULL == m_hExitFlag)
	{
		return ERR_CRT_EXITFLAG;
	}
	m_hThreadHandle = CreateThread( NULL, 0, RecoveThread,
									   ( LPVOID )this, NULL, &m_dwEncryptThreadID );
	if (NULL == m_hThreadHandle)
	{
		return ERR_CRT_RECOVETHREAD;
	}
	return 0;
}
// 还原文件主线程 [5/16/2008 By willing]
DWORD WINAPI CDlgRecoveProgress::RecoveThread(LPVOID lParam)
{
	if (NULL == lParam)
	{
		return -1;
	}
	CDlgRecoveProgress* _this = (CDlgRecoveProgress*)lParam;
	// 获取要还原的文件数量 [5/16/2008 By willing]
	int nTotalFileCount = g_SelectFileList.GetItemCount();
	if (0 == nTotalFileCount)
	{
		RCV_MSG* ptrRcvMsg = new RCV_MSG;
		if (NULL != ptrRcvMsg)
		{
			sprintf(ptrRcvMsg->szMsg,"%s","待还原文件列表为空!");
			ptrRcvMsg->nTextColor = CXListBox::Red;
			::PostMessage(_this->m_hWnd,WM_RC_SENDMSG,(WPARAM)ptrRcvMsg,NULL);
			return 0;
		}
	}
	CSelectFile SelectFile;
	CString strMsg = "";
	// 以下实现还原 [5/27/2008 By willing]
	for (int i=0;i<nTotalFileCount;i++)
	{
		Sleep(300);
		DLG_TITLE* ptrDlgTitle = new DLG_TITLE;
		if (NULL == ptrDlgTitle)
		{
			strMsg.Format("申请内存失败!");
			_this->SetMsg(strMsg,CXListBox::Red);
			SelectFile.SetRunState(error);// 将状态修改为错误 [5/8/2008 By willing]
			continue;
		}
		ptrDlgTitle->nCurIndex = i+1;
		ptrDlgTitle->nTotalCount = nTotalFileCount;
		::PostMessage(_this->m_hWnd,WM_SETTITLE,(WPARAM)ptrDlgTitle,NULL);
		if (FALSE == g_SelectFileList.GetHeadItem(SelectFile))
		{
			strMsg.Format("从链表中获取第%d待还原文件信息失败!",i+1);
			_this->SetMsg(strMsg,CXListBox::Red);
			SelectFile.SetRunState(error);// 将状态修改为错误 [5/8/2008 By willing]
			continue;
		}
		CRecoveSelectFile RecoveSelectFile;
		RecoveSelectFile.SetDlgWnd(_this->m_hWnd);
		RecoveSelectFile.SetPwd(_this->m_strPwd);
		strMsg.Format("开始校验 %s",SelectFile.GetFileName());
		_this->SetMsg(strMsg,CXListBox::Blue);
		OutputDebugString("开始判断是否是加密文件");
		if (0 != RecoveSelectFile.IsEncFile(SelectFile))
		{
			strMsg.Format("从链表中获取第%d待还原文件信息失败!",i+1);
			_this->SetMsg("验证失败,无法完成还原!",CXListBox::Red);
			SelectFile.SetRunState(error);
			continue;
		}
		OutputDebugString("输出还原后的文件名称");
		OutputDebugString(RecoveSelectFile.GetFileName());

		CFile outFile;
		if (FALSE == outFile.Open(RecoveSelectFile.GetFileName(),CFile::modeCreate|CFile::modeWrite))
		{
			strMsg = "创建输出文件失败!";
			_this->SetMsg(strMsg,CXListBox::Red);
			// 创建输出文件失败 [5/14/2008 By willing]
			SelectFile.SetRunState(error);
			continue;
		}
		// 已经判断是加密过的文件,下面开始实现解密 [5/30/2008 By willing]
		CFile encFile;
		if (FALSE == encFile.Open(SelectFile.GetFilePatchName(),CFile::modeRead|CFile::typeBinary))
		{
			SelectFile.SetRunState(error);
			_this->SetMsg("还原文件内容时打开文件失败!",CXListBox::Red);
			outFile.Close();
			// 删除输出文件 [8/13/2008 By willing]
			CFile::Remove(RecoveSelectFile.GetFileName());
			continue;
		}
		DWORD dwFileLen = encFile.GetLength();
		::PostMessage(_this->m_hWnd,WM_RC_SETPOS,2,(LPARAM)dwFileLen);
		int nTotal = RecoveSelectFile.GetHeadLen();
		encFile.Seek(nTotal,0);
		char* pszEncBuffer = new char[BUFFER_SIZE];
		if (NULL == pszEncBuffer)
		{
			SelectFile.SetRunState(error);
			_this->SetMsg("读取加密过的文件时,申请内存失败!",CXListBox::Red);
			encFile.Close();
			outFile.Close();
			// 删除输出文件 [8/13/2008 By willing]
			CFile::Remove(RecoveSelectFile.GetFileName());
			continue;
		}
		memset(pszEncBuffer,0,BUFFER_SIZE);
		UINT unTempReadLen = 0;
		int nExit = 0;
		do 
		{
			// 判断是否需要退出 [5/15/2008 By willing]
			if (::WaitForSingleObject(_this->m_hExitFlag,1) == WAIT_OBJECT_0)
			{
				// 等待到了信号,用户强制要退出了。 [5/15/2008 By willing]
				OutputDebugString("等待到了信号,用户强制要退出了。");
				nExit = 1;
				break;
			}
			unTempReadLen = encFile.Read(pszEncBuffer,BUFFER_SIZE);
			if (0 > unTempReadLen)
			{
				// 还原完成了 [6/18/2008 By willing]
				break;
			}
			// 还原并写入 [6/18/2008 By willing]
			if (0 != _this->WriteBuffer(outFile,pszEncBuffer,unTempReadLen,RecoveSelectFile.GetEncMethod()))
			{
				// 写入失败 [6/18/2008 By willing]
				SelectFile.SetRunState(error);
				_this->SetMsg("还原文件时,写数据失败!",CXListBox::Red);
				encFile.Close();
				continue;
			}
			nTotal+=unTempReadLen;
			// 报告进度 [6/18/2008 By willing]
			::PostMessage(_this->m_hWnd,WM_RC_SETPOS,1,(LPARAM)nTotal);
		} while(nTotal < (int)dwFileLen);
		encFile.Close();
		outFile.Close();
		if (nExit == 0)
		{
			_this->SetMsg("还原完毕!",CXListBox::Red);
		}else if ( 1 == nExit)
		{
			// 删除输出的文件 [8/18/2008 By willing]
			CFile::Remove(RecoveSelectFile.GetFileName());
			return 0;
		}
		// 删除还原过的文件 [8/13/2008 By willing]
		CFile::Remove(SelectFile.GetFilePatchName());
	}
	// 清理操作 [6/18/2008 By willing]
	// 删除加密文件等操作 [8/7/2008 By willing]
	// 自动关闭窗体 [5/16/2008 By willing]
	::PostMessage(_this->m_hWnd,WM_RC_AUTOEXIT,NULL,NULL);
	return 0;
}
// 停止工作线程 [5/16/2008 By willing]
int CDlgRecoveProgress::Stop()
{
	if (NULL != m_hExitFlag)
	{
		// 设置退出标志 [1/16/2008 By willing]
		OutputDebugString("CDlgRecoveProgress::Stop() SetEvent");
		::SetEvent(m_hExitFlag);
	}

	if (NULL != m_hThreadHandle)
	{
		if (::WaitForSingleObject(this->m_hThreadHandle, 1000*10) == WAIT_TIMEOUT)
		{
			//线程退出超时,强制结束线程
			OutputDebugString("线程退出超时,强制结束线程");
			TerminateThread(this->m_hThreadHandle,0);
		}
	}
	if(this->m_hExitFlag != NULL)
	{
		::CloseHandle(this->m_hExitFlag);
		this->m_hExitFlag = NULL;
	}

	this->m_hThreadHandle = NULL;
	return 0;
}

BOOL CDlgRecoveProgress::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	SetWindowText("还原文件");
	int nRe = Run();// 启动还原线程 [5/16/2008 By willing]
	if (ERR_CRT_EXITFLAG == nRe)
	{
		// 创建退出线程标志失败 [5/16/2008 By willing]
	}else if (ERR_CRT_RECOVETHREAD)
	{
		// 启动还原线程失败 [5/16/2008 By willing]
	}
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}
// 设置要显示的信息 [6/1/2007 by willing]
void CDlgRecoveProgress::SetMsg(CString strMsg,int nColorIndex)
{
	if ("" == strMsg)
	{
		return;
	}
	char szTemp[MAX_PATH]={0};
	sprintf(szTemp,"%s",strMsg);
	m_listbox.AddLine((CXListBox::Color)nColorIndex, (CXListBox::Color)CXListBox::White, szTemp);
	return ;
}
int CDlgRecoveProgress::WriteBuffer(CFile &m_File,
								 char *ptrBuffer,
								 DWORD dwLen,
								 const int nSuanFa)
{
	if (ptrBuffer == NULL)
	{
		return -1;
	}
	char szBuffer[BUFFER_SIZE]={0}; 
	CToolsKit ToolsKit;
	BOOL bResult = FALSE;
	CMD5Checksum MD5Checksum;
	CString strPwdMD5 = ""; 
	// 构造密钥 [5/9/2008 By willing]
	if ("" == m_strPwd)
	{
		strPwdMD5 = (MD5Checksum.GetMD5(DES_MIYAO)).Left(8);
	}else{
		strPwdMD5 = (MD5Checksum.GetMD5(m_strPwd)).Left(8);
	}
	char szPwdMd5[9]={0};
	sprintf(szPwdMd5,"%s",strPwdMD5);

	if( nSuanFa == ENCTYPE_DES)
	{
		bResult = ToolsKit.Recove(szBuffer,ptrBuffer,dwLen,szPwdMd5,8);
	}else if (nSuanFa == ENCTYPE_3DES)
	{
		bResult = ToolsKit.Recove(szBuffer,ptrBuffer,dwLen,szPwdMd5,16);
	}
	if (bResult)
	{
		m_File.Write(szBuffer,BUFFER_SIZE);
	}else{
		OutputDebugString("加密失败");
		return -2;
	}
	return 0;
}
// 修改当前进度条的进度 [6/18/2008 By willing]
LRESULT CDlgRecoveProgress::OnPostProgressMsg(WPARAM wParam,LPARAM lParam)
{
	int nType = (int)wParam;
	int nNum = (int)lParam;
	if (1 == nType)
	{
		m_ProgressCtrl.SetPos((int)nNum);
	}else{
		m_ProgressCtrl.SetRange32(0,nNum);
		m_ProgressCtrl.SetStep(1);
		m_ProgressCtrl.SetPos(0);
	}
	return 0;
}
LRESULT CDlgRecoveProgress::OnAutoExit(WPARAM wParam,LPARAM lParam)
{
	SetDlgItemText(IDCANCEL,"关闭");
	CButton* ptrButton = (CButton*)GetDlgItem(IDC_CHECK);
	if (NULL == ptrButton)
	{
		return 0;
	}
	if (ptrButton->GetCheck() == BST_CHECKED)
	{
		OnOK();
	}
	return 0;
}
void CDlgRecoveProgress::OnCancel() 
{
	// TODO: Add extra cleanup here
	if (::WaitForSingleObject(this->m_hThreadHandle, 1) == WAIT_OBJECT_0)
	{
		// 加密工作已经结束 [5/15/2008 By willing]
		CDialog::OnCancel();
		return;
	}else{
		if (NULL != m_hWaitFlag)
		{
			SuspendThread(m_hThreadHandle);
			if (IDYES == MessageBox("确定要取消还原吗?","提示",MB_YESNO))
			{
				ResumeThread(m_hThreadHandle);
				Stop();
				CDialog::OnCancel();
			}else{
				ResumeThread(m_hThreadHandle);
			}
		}
		
	}
}

⌨️ 快捷键说明

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