MFC版哈希值计算器的实现(二)
2012-01-29 13:57
218 查看
1 开始相关函数
2 计算相关函数
3 停止计算
如果完全转载,请注明出处,谢谢
void CHashToolDlg::BeginComputeHashInfo(CString filePath) { CString *tmp = new CString(); *tmp = filePath.GetBuffer(); if(PathIsDirectory(*tmp)) { MessageBox("Does not support directory","Warning", MB_OK|MB_ICONWARNING); return; } HWND hWnd = AfxGetMainWnd()->GetSafeHwnd(); if(::SendMessage(hWnd, WM_Create_Progress_Bar, (WPARAM)tmp, NULL)) { //exist same file return; } AfxBeginThread(ThreadComputeHashInfo, tmp); } UINT CHashToolDlg::ThreadComputeHashInfo(LPVOID pParam) { CString* filePath = (CString*)pParam; CHashTool hashTool; HWND hWndMainDlg = AfxGetMainWnd()->GetSafeHwnd(); if(!hashTool.GetHashInfo(*filePath, hWndMainDlg)) { ::SendMessage(hWndMainDlg, WM_Delete_Progress_Bar, (WPARAM)filePath, NULL); } delete filePath; return 0; }
2 计算相关函数
BOOL CHashTool::GetHashInfo(CString filePath, HWND mainDlg) { BOOL result; bStopHash = FALSE; fileInfo.FilePath = filePath; hWndMainDlg = mainDlg; CFileStatus fileStatus; if(CFile::GetStatus(filePath, fileStatus)) { fileInfo.Size = fileStatus.m_size; fileInfo.LastModifyTime = fileStatus.m_mtime.Format("Modify on: %Y-%m-%d %H:%M:%S"); result = ComputeHash(fileInfo.FilePath); } else { AfxMessageBox("Get file status error: {0}", GetLastError(), MB_OK|MB_ICONWARNING); result = FALSE; } return result; }
BOOL CHashTool::InitCreateHash(HCRYPTPROV* hProv, HCRYPTHASH* hHash, ALG_ID algID) { if (!CryptAcquireContext(hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return FALSE; /* BOOL WINAPI CryptCreateHash( HCRYPTPROV hProv, //CSP句柄 ALG_ID Algid, //选择hash算法,比如CALG_MD5等 HCRYPTKEY hKey, //HMAC 和MAC算法时有用 DWORD dwFlags, //保留,传入0即可 HCRYPTHASH* phHash); //返回hash句柄 */ if(!CryptCreateHash(*hProv, algID, 0, 0, hHash)) { CryptReleaseContext(*hProv, 0); return FALSE; } return TRUE; } BOOL CHashTool::ComputeHashValue(HCRYPTPROV* hProv, HCRYPTHASH* hHash, BYTE* input, DWORD inputLength) { /* BOOL WINAPI CryptHashData( HCRYPTHASH hHash, //hash对象 BYTE* pbData, //被hash的数据 DWORD dwDataLen, //数据的长度 DWORD dwFlags); //微软的CSP这个值会被忽略 */ if(!CryptHashData(*hHash, (BYTE*)input, inputLength, 0)) { CryptDestroyHash(*hHash); CryptReleaseContext(*hProv, 0); return FALSE; } if(fileInfo.Percent >= 100) { DWORD dwSize; DWORD dwLen = sizeof(dwSize); CryptGetHashParam(*hHash, HP_HASHSIZE, (BYTE*)(&dwSize), &dwLen, 0); BYTE* pHash = new BYTE[dwSize]; dwLen = dwSize; CryptGetHashParam(*hHash, HP_HASHVAL, pHash, &dwLen, 0); CString hash = ""; for(unsigned int i = 0 ; i < dwLen ; i++) { hash.Format("%02X", pHash[i]); if(dwLen == 16) fileInfo.MD5 += hash; if(dwLen == 20) fileInfo.SHA1 += hash; } ClearHash(hProv, hHash); } return TRUE; } void CHashTool::ClearHash(HCRYPTPROV* hProv, HCRYPTHASH* hHash) { if(*hHash) CryptDestroyHash(*hHash); if(*hProv) CryptReleaseContext(*hProv, 0); } // //ALG_ID: CALG_MD5, CALG_SHA1 // BOOL CHashTool::ComputeHash(CString filePath) { HCRYPTPROV hProv_MD5 = 0; //CSP指针 HCRYPTHASH hHash_MD5 = 0; HCRYPTPROV hProv_SHA1 = 0; //CSP指针 HCRYPTHASH hHash_SHA1 = 0; if(!InitCreateHash(&hProv_MD5,&hHash_MD5, CALG_MD5)) { CString errorInitMD5; errorInitMD5.Format("Init MD5 error: %d" , GetLastError()); AfxMessageBox(errorInitMD5, MB_OK|MB_ICONWARNING); return FALSE; } if(!InitCreateHash(&hProv_SHA1,&hHash_SHA1, CALG_SHA1)) { CString errorInitSHA1; errorInitSHA1.Format("Init SHA1 error: %d" , GetLastError()); AfxMessageBox(errorInitSHA1, MB_OK|MB_ICONWARNING); return FALSE; } CFile file; if(!file.Open(filePath, CFile::typeBinary|CFile::modeRead|CFile::shareDenyNone)) { CString errorOpenFile; errorOpenFile.Format("Open file error: %d" , GetLastError()); AfxMessageBox(errorOpenFile, MB_OK|MB_ICONWARNING); return FALSE; } ULONG read = 0; ULONGLONG position = 0; ULONGLONG length = file.GetLength(); char buffer[BYTES_PER_READ] = {0}; do { if(bStopHash) { break; } read = file.Read(buffer, BYTES_PER_READ); position += read; if(length == 0) { fileInfo.Percent = 100; } else { fileInfo.Percent = (int)((double)position/length*100); } if(!ComputeHashValue(&hProv_MD5, &hHash_MD5, (BYTE*)buffer, read)) { CString errorComputeMD5; errorComputeMD5.Format("Compute MD5 error: %d" , GetLastError()); AfxMessageBox(errorComputeMD5, MB_OK|MB_ICONWARNING); return FALSE; } if(!ComputeHashValue(&hProv_SHA1, &hHash_SHA1, (BYTE*)buffer, read)) { CString errorComputeSHA1; errorComputeSHA1.Format("Compute SHA1 error: %d" , GetLastError()); AfxMessageBox(errorComputeSHA1, MB_OK|MB_ICONWARNING); return FALSE; } if(hWndMainDlg != NULL) { ::SendMessage(hWndMainDlg, WM_Update_Progress_Step, (WPARAM)&fileInfo, NULL); } }while(position < length); file.Close(); if(bStopHash) return FALSE; else return TRUE; }
3 停止计算
void CHashToolDlg::OnDestroy() { CHashTool::StopHash(); Sleep(3000); CDialog::OnDestroy(); }
void CHashToolDlg::OnBnClickedStophashButton() { CHashTool::StopHash(); }这个地方遇到个问题,关闭窗口后,需要等待所有线程正常退出才可以。搜了会解决方案,有人建议用WaitForMultipleObjects。但是感觉比较麻烦。暂时先Sleep 3s解决
如果完全转载,请注明出处,谢谢
相关文章推荐
- MFC版哈希值计算器的实现(一)
- MFC第一天——Win32实现计算器
- MFC计算器 用vector实现和计算逆波兰表达式
- MFC 实现计算器
- 第六次作业——利用MFC实现计算器图形界面以及简单四则运算表达式批处理
- 第六次作业——利用MFC实现计算器图形界面以及简单四则运算表达式批处理
- 2012-11-17 12:28 用MFC实现的计算器(详细版)
- MFC 编写计算器功能实现
- 简单工厂模式——MFC计算器实现(连续操作)
- 采用文法思想用MFC实现简单的计算器程序
- MFC实现简单功能计算器
- MFC 实现 加减乘除,括号,乘方的 计算器
- 一个仿系统自带计算器程序MFC实现
- 我的c++之路-MFC计算器的实现
- 爱尔兰B计算器的MFC实现
- MFC实现一个简单的计算器
- 设计一个计算器类Claculator,它只有一个用于计数的数据成员count。该计算器的有效计数范围是0~65535,实现计数器的前自增、后自增、前自减、后自减、两个计算器相加减运算
- Java按钮控件数组实现计算器界面
- 用HTML、CSS、JavaScript 实现一个简单的计算器
- MFC的浏览器初实现 之 vs2008