text: // HashTest.cpp : Defines the entry point for the console application.
  //
  
  #include "stdafx.h"
  
  //https://docs.microsoft.com/zh-cn/windows/desktop/SecCrypto/example-c-program--creating-an-md-5-hash-from-file-content
  
  #include <stdio.h>
  #include <windows.h>
  #include <Wincrypt.h>
  
  #define BUFSIZE 1024
  #define SHA256LEN  64
  
  DWORD main()
  {
  	DWORD dwStatus = 0;
  	BOOL bResult = FALSE;
  	HCRYPTPROV hProv = 0;
  	HCRYPTHASH hHash = 0;
  	HANDLE hFile = NULL;
  	BYTE rgbFile[BUFSIZE];
  	DWORD cbRead = 0;
  	BYTE rgbHash[SHA256LEN];
  	DWORD cbHash = 0;
  	CHAR rgbDigits[] = "0123456789abcdef";
  	LPCWSTR filename = L"../TestFile.txt";
  	// Logic to check usage goes here.
  
  	hFile = CreateFile(filename,
  		GENERIC_READ,
  		FILE_SHARE_READ,
  		NULL,
  		OPEN_EXISTING,
  		FILE_FLAG_SEQUENTIAL_SCAN,
  		NULL);
  
  	if (INVALID_HANDLE_VALUE == hFile)
  	{
  		dwStatus = GetLastError();
  		printf("Error opening file %s\nError: %d\n", filename,
  			dwStatus);
  		return dwStatus;
  	}
  
  	// Get handle to the crypto provider
  	if (!CryptAcquireContext(&hProv,
  		NULL,
  		NULL,
  		PROV_RSA_AES,
  		CRYPT_VERIFYCONTEXT))
  	{
  		dwStatus = GetLastError();
  		printf("CryptAcquireContext failed: %d\n", dwStatus);
  		CloseHandle(hFile);
  		return dwStatus;
  	}
  
  	if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash))
  	{
  		dwStatus = GetLastError();
  		printf("CryptAcquireContext failed: %d\n", dwStatus);
  		CloseHandle(hFile);
  		CryptReleaseContext(hProv, 0);
  		return dwStatus;
  	}
  
  	while (bResult = ReadFile(hFile, rgbFile, BUFSIZE,
  		&cbRead, NULL))
  	{
  		if (0 == cbRead)
  		{
  			break;
  		}
  
  		if (!CryptHashData(hHash, rgbFile, cbRead, 0))
  		{
  			dwStatus = GetLastError();
  			printf("CryptHashData failed: %d\n", dwStatus);
  			CryptReleaseContext(hProv, 0);
  			CryptDestroyHash(hHash);
  			CloseHandle(hFile);
  			return dwStatus;
  		}
  	}
  
  	if (!bResult)
  	{
  		dwStatus = GetLastError();
  		printf("ReadFile failed: %d\n", dwStatus);
  		CryptReleaseContext(hProv, 0);
  		CryptDestroyHash(hHash);
  		CloseHandle(hFile);
  		return dwStatus;
  	}
  
  	cbHash = SHA256LEN;
  	if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
  	{
  		printf("MD5 hash of file %s is: ", filename);
  		for (DWORD i = 0; i < cbHash; i++)
  		{
  			printf("%c%c", rgbDigits[rgbHash[i] >> 4],
  				rgbDigits[rgbHash[i] & 0xf]);
  		}
  		printf("\n");
  	}
  	else
  	{
  		dwStatus = GetLastError();
  		printf("CryptGetHashParam failed: %d\n", dwStatus);
  	}
  
  	CryptDestroyHash(hHash);
  	CryptReleaseContext(hProv, 0);
  	CloseHandle(hFile);
  
  	return dwStatus;
  }
  