You are not doing any error handling at all. All of the API functions you are calling have return values and error codes, none of which you are checking.
You are also not managing bytesRead
correctly. CryptEncrypt()
modifies the variable you pass to it, which then affects your call to CreateDecrypt()
, which also modifies it, and that then affects subsequent calls to SetFilePointer()
, which you should not be calling in your loop to begin with. You are not validating that you have as many bytes as you are expecting, or that bytesRead
ends up back at the original value that ReadFile()
returned, so you may end up skipping bytes in the source file.
Try something more like this instead:
bool ReadFromFile(HANDLE hFile, void *Buffer, DWORD BufSize, DWORD *BytesRead)
{
if (BytesRead)
*BytesRead = 0;
LPBYTE pBuffer = (LPBYTE) Buffer;
DWORD dwRead;
while (BufSize > 0)
{
if (!ReadFile(hFile, pBuffer, BufSize, &dwRead, NULL))
return false;
if (dwRead == 0)
break;
pBuffer += dwRead;
BufSize -= dwRead;
if (BytesRead)
*BytesRead += dwRead;
}
return true;
}
bool WriteToFile(HANDLE hFile, void *Buffer, DWORD BufSize)
{
LPBYTE pBuffer = (LPBYTE) Buffer;
DWORD dwWritten;
while (BufSize > 0)
{
if (!WriteFile(hFile, pBuffer, BufSize, &dwWritten, NULL))
return false;
pBuffer += dwWritten;
BufSize -= dwWritten;
}
return true;
}
DWORD bytesRead;
const UINT blockSize = 4000;
LPBYTE fileBuffer = new BYTE[blockSize+16];
bool EOF;
if (SetFilePointer(hFileOrginal, 0, NULL, FILE_BEGIN) != 0)
{
errorCode = GetLastError();
...
}
else
{
do
{
if (!ReadFromFile(hFileOrginal, fileBuffer, blockSize, &bytesRead))
{
errorCode = GetLastError();
...
break;
}
EOF = (bytesRead < blockSize);
bytesEncrypted = bytesRead;
if (!CryptEncrypt(aesKey, NULL, EOF, 0, fileBuffer, &bytesEncrypted, blockSize+16))
{
errorCode = GetLastError();
...
break;
}
bytesDecrypted = bytesEncrypted;
if (!CryptDecrypt(aesKey, NULL, EOF, 0, fileBuffer, &bytesDecrypted))
{
errorCode = GetLastError();
...
break;
}
if (!WriteToFile(hTempFile, fileBuffer, bytesDecrypted))
{
errorCode = GetLastError();
...
break;
}
if (bytesDecrypted != bytesRead)
{
...
break;
}
}
while (!EOF);
}
delete[] fileBuffer;