API を使ってファイルのハッシュ値(SHA-1、MD5 など)を計算する

Windows XP より Windows にはファイルのハッシュ値を計算するための API が組み込まれています。今回はその API を使用してファイルのハッシュ値を求めるための関数のコードを書いたので紹介します。

lpszFilePath: ファイルパス
ALG_ID: ハッシュ値を計算するためのアルゴリズム(CALG_SHA1、CALG_MD5など)
lpszHashValue: ハッシュ値を格納するための文字列バッファ
戻り値: 関数が成功した場合は TRUE。失敗した場合は FALSE。

プロジェクトのダウンロード

BOOL CalcFileHash(LPCTSTR lpszFilePath, ALG_ID Algid, LPTSTR lpszHashValue)
{
	if (PathFileExists(lpszFilePath) == FALSE) return FALSE;
	if (lpszHashValue == NULL) return FALSE;
	if ((Algid & ALG_CLASS_HASH) == 0) return FALSE;
	HANDLE hFile = CreateFile(lpszFilePath, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}
	HCRYPTPROV hProv = 0;
	if (!CryptAcquireContext(&hProv, 0, 0, PROV_RSA_AES, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET))
	{
		CloseHandle(hFile);
		return FALSE;
	}
	HCRYPTHASH hHash = 0;
	if (!CryptCreateHash(hProv, Algid, 0, 0, &hHash))
	{
		CloseHandle(hFile);
		CryptReleaseContext(hProv, 0);
		return FALSE;
	}
	BOOL bRet = FALSE;
	for (;;)
	{
		BYTE Buffer[64 * 1024];
		DWORD wReadSize;
		if (ReadFile(hFile, Buffer, sizeof(Buffer), &wReadSize, 0) == FALSE)
			break;
		if (!wReadSize)
			break;
		bRet = CryptHashData(hHash, Buffer, wReadSize, 0) ? TRUE : FALSE;
		if (!bRet)
			break;
	}
	CloseHandle(hFile);
	if (!bRet)
	{
		CryptDestroyHash(hHash);
		CryptReleaseContext(hProv, 0);
		return FALSE;
	}
	DWORD dwHashLen = 0;
	if (!CryptGetHashParam(hHash, HP_HASHVAL, 0, &dwHashLen, 0) || !dwHashLen)
	{
		CryptDestroyHash(hHash);
		CryptReleaseContext(hProv, 0);
		return FALSE;
	}
	LPBYTE lpHash = (LPBYTE)GlobalAlloc(GMEM_FIXED, dwHashLen);
	if (!lpHash)
	{
		CryptDestroyHash(hHash);
		CryptReleaseContext(hProv, 0);
		return FALSE;
	}
	if (!CryptGetHashParam(hHash, HP_HASHVAL, lpHash, &dwHashLen, 0))
	{
		GlobalFree(lpHash);
		CryptDestroyHash(hHash);
		CryptReleaseContext(hProv, 0);
		return FALSE;
	}
	CryptDestroyHash(hHash);
	CryptReleaseContext(hProv, 0);
	lpszHashValue[0] = 0;
	for (DWORD i = 0; i < dwHashLen; ++i)
	{
		TCHAR tmp[3] = { 0 };
		wsprintf(tmp, TEXT("%02X"), lpHash[i]);
		lstrcat(lpszHashValue, tmp);
	}
	GlobalFree(lpHash);
	return TRUE;
}

スポンサーリンク
広告1
広告1

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
広告1