獲取文件的MD5值

#include <Wincrypt.h>

#pragma comment(lib, "advapi32.lib") 

void GetFileMD5(IN const CString& sFilePath, OUT CString& sMd5)
{
    sMd5 = _T("");
    HANDLE hFile = NULL;
    HCRYPTPROV hCryptProv=NULL;
    HCRYPTPROV hHash = NULL;
    PBYTE pReadFileBuffer = NULL;
    PBYTE pbMd5 = NULL;

    do 
    {
        hFile = CreateFile(sFilePath, GENERIC_READ,
            FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
        if( hFile == INVALID_HANDLE_VALUE )
        {
            break;
        }
        // 獲得CSP中一個密鑰容器的句柄
        if( FALSE == CryptAcquireContext(&hCryptProv, NULL, NULL,
            PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) )
        {
            break;
        }
        // 初始化對數據流的hash,創建並返回一個與CSP的hash對象相關的句柄。
        // 這個句柄接下來將被CryptHashData調用。
        if( FALSE == CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash) )
        {
            break;
        }
        DWORD dwFileSize = GetFileSize(hFile,0);
        if( dwFileSize == 0xFFFFFFFF )  
        {
            break;
        }
        pReadFileBuffer = new BYTE[dwFileSize];
        DWORD dwReadNumber = 0;
        if( FALSE == ReadFile( hFile, pReadFileBuffer, dwFileSize,
            &dwReadNumber, NULL ) ) 
        {
            break;
        }

        if( FALSE == CryptHashData(hHash, pReadFileBuffer,
            dwReadNumber, 0) )
        {
            break;
        }

        DWORD dwHashLen = sizeof(DWORD);
        if( FALSE == CryptGetHashParam(hHash, HP_HASHVAL, NULL,
            &dwHashLen, 0) )
        {
            break;
        }
        // 獲得md5值
        pbMd5 = new BYTE[dwHashLen];
        ZeroMemory(pbMd5, dwHashLen);
        if( FALSE == CryptGetHashParam(hHash, HP_HASHVAL,
            (PBYTE)pbMd5, &dwHashLen, 0) ) 
        {
            break;
        }

        CString sSub(_T(""));
        for( UINT i=0; i<dwHashLen; i++ )
        {
            sSub.Format(_T("%0.2x"), pbMd5[i]);
            sMd5 += sSub;
        }
    }while( FALSE );

    if( pbMd5 )
    {
        delete []pbMd5;
    }

    if( pReadFileBuffer )
    {
        delete []pReadFileBuffer;
    }

    if( hHash )
    {
        CryptDestroyHash(hHash);
    }

    if( hCryptProv )
    {
        CryptReleaseContext(hCryptProv, 0);
    }

    if( hFile )
    {
        CloseHandle(hFile);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章