BOOL CCalcHash::GetMD2(__in LPCSTR lpcszFileName, __inout BYTE pbData[16])
{
return GetFileHashA(lpcszFileName, pbData, 16, CALG_MD2);
}
BOOL CCalcHash::GetMD4(__in LPCSTR lpcszFileName, __inout BYTE pbData[16])
{
return GetFileHashA(lpcszFileName, pbData, 16, CALG_MD4);
}
BOOL CCalcHash::GetMD5(__in LPCSTR lpcszFileName, __inout BYTE pbData[16])
{
return GetFileHashA(lpcszFileName, pbData, 16, CALG_MD5);
}
BOOL CCalcHash::GetSHA1(__in LPCSTR lpcszFileName, __inout BYTE pbData[20])
{
return GetFileHashA(lpcszFileName, pbData, 20, CALG_SHA1);
}
BOOL CCalcHash::GetMD2(__in LPCWSTR lpcwszFileName, __inout BYTE pbData[16])
{
return GetFileHashW(lpcwszFileName, pbData, 16, CALG_MD2);
}
BOOL CCalcHash::GetMD4(__in LPCWSTR lpcwszFileName, __inout BYTE pbData[16])
{
return GetFileHashW(lpcwszFileName, pbData, 16, CALG_MD4);
}
BOOL CCalcHash::GetMD5(__in LPCWSTR lpcwszFileName, __inout BYTE pbData[16])
{
return GetFileHashW(lpcwszFileName, pbData, 16, CALG_MD5);
}
BOOL CCalcHash::GetSHA1(__in LPCWSTR lpcwszFileName, __inout BYTE pbData[20])
{
return GetFileHashW(lpcwszFileName, pbData, 20, CALG_SHA1);
}
BOOL CCalcHash::GetFileHashA(__in LPCSTR lpcszFileName, __inout BYTE* pbData, __in DWORD dwLength, __in DWORD dwFlags)
{
INT nLength = MultiByteToWideChar(CP_ACP, 0, lpcszFileName, -1, NULL, 0);
if (nLength == 0)
return FALSE;
std::unique_ptr<WCHAR> wszBuffer(new WCHAR[nLength]);
if (MultiByteToWideChar(CP_ACP, 0, lpcszFileName, nLength, wszBuffer.get(), nLength) == 0)
return FALSE;
return GetFileHashW(wszBuffer.get(), pbData, dwLength, dwFlags);
}
BOOL CCalcHash::GetFileHashW(__in LPCWSTR lpcwszFileName, __inout BYTE* pbData, __in DWORD dwLength, __in DWORD dwFlags)
{
BOOL bResult;
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HANDLE hFile;
ULARGE_INTEGER lSize;
BYTE pbHash[MAX_HASH_SIZE];
if (lpcwszFileName == NULL || dwLength == 0 || dwLength > _countof(pbHash))
return FALSE;
ZeroMemory(pbHash, dwLength);
hFile = CreateFile(lpcwszFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return FALSE;
lSize.LowPart = GetFileSize(hFile, &lSize.HighPart);
bResult = FALSE;
hProv = NULL;
hHash = NULL;
if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET))
{
ULARGE_INTEGER lPos;
DWORD dwReadBytes;
BYTE pbTemp[64000];
if (CryptCreateHash(hProv, dwFlags, NULL, 0, &hHash))
{
lPos.QuadPart = 0;
while (TRUE)
{
ReadFile(hFile, pbTemp, _countof(pbTemp), &dwReadBytes, NULL);
if (dwReadBytes <= 0)
break;
lPos.QuadPart += dwReadBytes;
if (!CryptHashData(hHash, pbTemp, dwReadBytes, 0))
break;
if (lPos.QuadPart == lSize.QuadPart)
{
if (CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &dwLength, 0))
{
memcpy_s(pbData, dwLength, pbHash, dwLength);
if (!bResult)
{
bResult = TRUE;
break;
}
}
}
}
}
}
if (!bResult)
ZeroMemory(pbHash, dwLength);
if (hHash)
CryptDestroyHash(hHash);
if (hProv)
CryptReleaseContext(hProv, 0);
CloseHandle(hFile);
return bResult;
}