mirror of
https://github.com/veracrypt/VeraCrypt
synced 2024-11-28 05:53:29 +01:00
Windows: better workaround for cases where ERROR_INVALID_PARAMETER is returned during system encryption which is due to 4096-bytes alignment of disk.
This commit is contained in:
parent
fe26ed8a5d
commit
3021745f67
@ -474,12 +474,12 @@ namespace VeraCrypt
|
||||
|
||||
#endif // SETUP
|
||||
|
||||
File::File (wstring path, bool readOnly, bool create, bool useNormalAttributes) : Elevated (false), FileOpen (false), ReadOnly (readOnly), LastError(0)
|
||||
File::File (wstring path, bool readOnly, bool create) : Elevated (false), FileOpen (false), ReadOnly (readOnly), LastError(0)
|
||||
{
|
||||
Handle = CreateFile (path.c_str(),
|
||||
readOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, create ? CREATE_ALWAYS : OPEN_EXISTING,
|
||||
useNormalAttributes? FILE_ATTRIBUTE_NORMAL : (FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_WRITE_THROUGH), NULL);
|
||||
FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_WRITE_THROUGH, NULL);
|
||||
|
||||
if (Handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
@ -530,7 +530,45 @@ namespace VeraCrypt
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
throw_sys_if (!ReadFile (Handle, buffer, size, &bytesRead, NULL));
|
||||
if (!ReadFile (Handle, buffer, size, &bytesRead, NULL))
|
||||
{
|
||||
DWORD dwLastError = GetLastError();
|
||||
if ((dwLastError == ERROR_INVALID_PARAMETER) && IsDevice && (size % 4096))
|
||||
{
|
||||
DWORD remainingSize = (size % 4096);
|
||||
DWORD alignedSize = size - remainingSize;
|
||||
LARGE_INTEGER offset;
|
||||
|
||||
if (alignedSize)
|
||||
{
|
||||
if (ReadFile (Handle, buffer, alignedSize, &bytesRead, NULL))
|
||||
{
|
||||
if (bytesRead < alignedSize)
|
||||
return bytesRead;
|
||||
|
||||
buffer += alignedSize;
|
||||
size -= alignedSize;
|
||||
}
|
||||
else
|
||||
throw SystemException (SRC_POS);
|
||||
}
|
||||
|
||||
|
||||
if (ReadFile (Handle, ReadBuffer, 4096, &bytesRead, NULL))
|
||||
{
|
||||
DWORD effectiveSize = min (bytesRead, remainingSize);
|
||||
memcpy (buffer, ReadBuffer, effectiveSize);
|
||||
offset.QuadPart = - ((LONGLONG) bytesRead) + (LONGLONG) effectiveSize;
|
||||
SetFilePointerEx (Handle, offset, NULL, FILE_CURRENT);
|
||||
return alignedSize + effectiveSize;
|
||||
}
|
||||
else
|
||||
throw SystemException (SRC_POS);
|
||||
}
|
||||
else
|
||||
throw SystemException (SRC_POS);
|
||||
}
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
@ -600,7 +638,63 @@ namespace VeraCrypt
|
||||
}
|
||||
else
|
||||
{
|
||||
throw_sys_if (!WriteFile (Handle, buffer, size, &bytesWritten, NULL) || bytesWritten != size);
|
||||
if (!WriteFile (Handle, buffer, size, &bytesWritten, NULL))
|
||||
{
|
||||
DWORD dwLastError = GetLastError ();
|
||||
if ((ERROR_INVALID_PARAMETER == dwLastError) && IsDevice && !ReadOnly && (size % 4096))
|
||||
{
|
||||
bool bSuccess = false;
|
||||
DWORD remainingSize = (size % 4096);
|
||||
DWORD alignedSize = size - remainingSize;
|
||||
DWORD bytesRead = 0;
|
||||
bytesWritten = 0;
|
||||
if (alignedSize)
|
||||
{
|
||||
if (WriteFile (Handle, buffer, alignedSize, &bytesWritten, NULL))
|
||||
{
|
||||
throw_sys_if (bytesWritten != alignedSize);
|
||||
buffer += alignedSize;
|
||||
size -= alignedSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytesWritten = 0;
|
||||
dwLastError = GetLastError ();
|
||||
}
|
||||
}
|
||||
|
||||
if (!alignedSize || (alignedSize && bytesWritten))
|
||||
{
|
||||
LARGE_INTEGER offset;
|
||||
|
||||
throw_sys_if (!ReadFile (Handle, ReadBuffer, 4096, &bytesRead, NULL) || (bytesRead != 4096));
|
||||
offset.QuadPart = -4096;
|
||||
throw_sys_if (!SetFilePointerEx (Handle, offset, NULL, FILE_CURRENT));
|
||||
|
||||
memcpy (ReadBuffer, buffer, remainingSize);
|
||||
|
||||
if (WriteFile (Handle, ReadBuffer, 4096, &bytesWritten, NULL))
|
||||
{
|
||||
throw_sys_if (bytesWritten != 4096);
|
||||
bSuccess = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
dwLastError = GetLastError ();
|
||||
}
|
||||
}
|
||||
|
||||
if (!bSuccess)
|
||||
{
|
||||
SetLastError (dwLastError);
|
||||
throw SystemException (SRC_POS);
|
||||
}
|
||||
}
|
||||
else
|
||||
throw SystemException (SRC_POS);
|
||||
}
|
||||
else
|
||||
throw_sys_if (bytesWritten != size);
|
||||
}
|
||||
}
|
||||
catch (SystemException &e)
|
||||
@ -2134,21 +2228,10 @@ namespace VeraCrypt
|
||||
memcpy (fileContent.data(), "\xEF\xBB\xBF", 3);
|
||||
memcpy (&fileContent[dwOffset], pbData, dwDataLen);
|
||||
|
||||
try
|
||||
{
|
||||
File f(pathESP + szFilePath, false, true);
|
||||
f.Write(fileContent.data(), dwSize);
|
||||
f.Close();
|
||||
}
|
||||
catch (SystemException &e)
|
||||
{
|
||||
if (e.ErrorCode != ERROR_INVALID_PARAMETER)
|
||||
throw;
|
||||
// try again with normal attributes
|
||||
File f(pathESP + szFilePath, false, true, true);
|
||||
f.Write(fileContent.data(), dwSize);
|
||||
f.Close();
|
||||
}
|
||||
File f(pathESP + szFilePath, false, true);
|
||||
f.Write(fileContent.data(), dwSize);
|
||||
f.Close();
|
||||
|
||||
}
|
||||
|
||||
EfiBoot::EfiBoot() {
|
||||
@ -2436,22 +2519,11 @@ namespace VeraCrypt
|
||||
void EfiBoot::SaveFile(const wchar_t* name, byte* data, DWORD size) {
|
||||
wstring path = EfiBootPartPath;
|
||||
path += name;
|
||||
try
|
||||
{
|
||||
File f(path, false, true);
|
||||
f.Write(data, size);
|
||||
f.Close();
|
||||
}
|
||||
catch (SystemException &e)
|
||||
{
|
||||
if (e.ErrorCode != ERROR_INVALID_PARAMETER)
|
||||
throw;
|
||||
|
||||
// try again with normal attributes
|
||||
File f(path, false, true, true);
|
||||
f.Write(data, size);
|
||||
f.Close();
|
||||
}
|
||||
File f(path, false, true);
|
||||
f.Write(data, size);
|
||||
f.Close();
|
||||
|
||||
}
|
||||
|
||||
void EfiBoot::GetFileSize(const wchar_t* name, unsigned __int64& size) {
|
||||
|
@ -37,7 +37,7 @@ namespace VeraCrypt
|
||||
{
|
||||
public:
|
||||
File () : Elevated (false), FileOpen (false), ReadOnly (false), FilePointerPosition(0), Handle(INVALID_HANDLE_VALUE), IsDevice(false), LastError(0) { }
|
||||
File (wstring path,bool readOnly = false, bool create = false, bool useNormalAttributes = false);
|
||||
File (wstring path,bool readOnly = false, bool create = false);
|
||||
virtual ~File () { Close(); }
|
||||
|
||||
void CheckOpened (const char* srcPos) { if (!FileOpen) { SetLastError (LastError); throw SystemException (srcPos);} }
|
||||
@ -58,6 +58,7 @@ namespace VeraCrypt
|
||||
bool IsDevice;
|
||||
wstring Path;
|
||||
DWORD LastError;
|
||||
BYTE ReadBuffer[4096];
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user