mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 11:08:02 -06:00
Windows: Fix system encryption issues on machines that always force booting on Microsoft bootloader (e.g. HP).
This commit is contained in:
@@ -17,7 +17,7 @@
|
|||||||
#include "BootDefs.h"
|
#include "BootDefs.h"
|
||||||
|
|
||||||
// The user will be advised to upgrade the rescue disk if upgrading from the following or any previous version
|
// The user will be advised to upgrade the rescue disk if upgrading from the following or any previous version
|
||||||
#define TC_RESCUE_DISK_UPGRADE_NOTICE_MAX_VERSION 0x0121
|
#define TC_RESCUE_DISK_UPGRADE_NOTICE_MAX_VERSION 0x0122
|
||||||
|
|
||||||
#define TC_BOOT_LOADER_AREA_SIZE (TC_BOOT_LOADER_AREA_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS)
|
#define TC_BOOT_LOADER_AREA_SIZE (TC_BOOT_LOADER_AREA_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS)
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "Mount/MainCom.h"
|
#include "Mount/MainCom.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <Strsafe.h>
|
#include <Strsafe.h>
|
||||||
|
|
||||||
bool ZipAdd (zip_t *z, const char* name, const unsigned char* pbData, DWORD cbData)
|
bool ZipAdd (zip_t *z, const char* name, const unsigned char* pbData, DWORD cbData)
|
||||||
@@ -2081,6 +2082,7 @@ namespace VeraCrypt
|
|||||||
authorizeRetry = ReadConfigInteger (configContent, "AuthorizeRetry", 0);
|
authorizeRetry = ReadConfigInteger (configContent, "AuthorizeRetry", 0);
|
||||||
bmlLockFlags = ReadConfigInteger (configContent, "DcsBmlLockFlags", 0);
|
bmlLockFlags = ReadConfigInteger (configContent, "DcsBmlLockFlags", 0);
|
||||||
bmlDriverEnabled = ReadConfigInteger (configContent, "DcsBmlDriver", 0);
|
bmlDriverEnabled = ReadConfigInteger (configContent, "DcsBmlDriver", 0);
|
||||||
|
actionSuccessValue = ReadConfigString (configContent, "ActionSuccess", "", buffer, sizeof (buffer));
|
||||||
|
|
||||||
burn (buffer, sizeof (buffer));
|
burn (buffer, sizeof (buffer));
|
||||||
}
|
}
|
||||||
@@ -2116,6 +2118,8 @@ namespace VeraCrypt
|
|||||||
WriteConfigInteger (configFile, configContent, "AuthorizeRetry", authorizeRetry);
|
WriteConfigInteger (configFile, configContent, "AuthorizeRetry", authorizeRetry);
|
||||||
WriteConfigInteger (configFile, configContent, "DcsBmlLockFlags", bmlLockFlags);
|
WriteConfigInteger (configFile, configContent, "DcsBmlLockFlags", bmlLockFlags);
|
||||||
WriteConfigInteger (configFile, configContent, "DcsBmlDriver", bmlDriverEnabled);
|
WriteConfigInteger (configFile, configContent, "DcsBmlDriver", bmlDriverEnabled);
|
||||||
|
if (strlen(actionSuccessValue.c_str()))
|
||||||
|
WriteConfigString (configFile, configContent, "ActionSuccess", actionSuccessValue.c_str());
|
||||||
|
|
||||||
// Write unmodified values
|
// Write unmodified values
|
||||||
char* xml = configContent;
|
char* xml = configContent;
|
||||||
@@ -2539,6 +2543,15 @@ namespace VeraCrypt
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EfiBoot::FileExists(const wchar_t* name) {
|
||||||
|
wstring path = EfiBootPartPath;
|
||||||
|
path += name;
|
||||||
|
File f(path, true);
|
||||||
|
bool bRet = f.IsOpened ();
|
||||||
|
f.Close();
|
||||||
|
return bRet;
|
||||||
|
}
|
||||||
|
|
||||||
void EfiBoot::GetFileSize(const wchar_t* name, unsigned __int64& size) {
|
void EfiBoot::GetFileSize(const wchar_t* name, unsigned __int64& size) {
|
||||||
wstring path = EfiBootPartPath;
|
wstring path = EfiBootPartPath;
|
||||||
path += name;
|
path += name;
|
||||||
@@ -2837,6 +2850,66 @@ namespace VeraCrypt
|
|||||||
{
|
{
|
||||||
// Save modules
|
// Save modules
|
||||||
bool bAlreadyExist;
|
bool bAlreadyExist;
|
||||||
|
unsigned __int64 loaderSize = 0;
|
||||||
|
bool bModifiedMsBoot = false;
|
||||||
|
|
||||||
|
if (preserveUserConfig && !EfiBootInst.FileExists (L"\\EFI\\Microsoft\\Boot\\bootmgfw_ms.vc"))
|
||||||
|
{
|
||||||
|
EfiBootInst.GetFileSize(L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", loaderSize);
|
||||||
|
|
||||||
|
// DcsBoot.efi is always smaller than 32KB
|
||||||
|
if (loaderSize < 32768)
|
||||||
|
{
|
||||||
|
std::vector<byte> bootLoaderBuf ((size_t) loaderSize);
|
||||||
|
|
||||||
|
EfiBootInst.ReadFile(L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", &bootLoaderBuf[0], (DWORD) loaderSize);
|
||||||
|
|
||||||
|
// Prevent VeraCrypt EFI loader from being backed up
|
||||||
|
for (size_t i = 0; i < (size_t) loaderSize - (wcslen (_T(TC_APP_NAME)) * 2); ++i)
|
||||||
|
{
|
||||||
|
if (memcmp (&bootLoaderBuf[i], _T(TC_APP_NAME), wcslen (_T(TC_APP_NAME)) * 2) == 0)
|
||||||
|
{
|
||||||
|
bModifiedMsBoot = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bModifiedMsBoot)
|
||||||
|
{
|
||||||
|
EfiBootInst.RenameFile (L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", L"\\EFI\\Microsoft\\Boot\\bootmgfw_ms.vc", FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool bFound = false;
|
||||||
|
EfiBootConf conf;
|
||||||
|
if (EfiBootInst.ReadConfig (L"\\EFI\\VeraCrypt\\DcsProp", conf) && strlen (conf.actionSuccessValue.c_str()))
|
||||||
|
{
|
||||||
|
string actionValue = conf.actionSuccessValue;
|
||||||
|
std::transform(actionValue.begin(), actionValue.end(), actionValue.begin(), ::tolower);
|
||||||
|
|
||||||
|
if (strstr (actionValue.c_str(), "postexec") && strstr (actionValue.c_str(), "file("))
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
const char* ptr = strstr (actionValue.c_str(), "file(");
|
||||||
|
ptr += 5;
|
||||||
|
wstring loaderPath = L"\\";
|
||||||
|
while ((c = *ptr))
|
||||||
|
{
|
||||||
|
if (c == ')' || c == ' ')
|
||||||
|
break;
|
||||||
|
loaderPath += (wchar_t) c;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
bFound = true;
|
||||||
|
EfiBootInst.RenameFile(loaderPath.c_str(), L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bFound)
|
||||||
|
throw ErrorException ("WINDOWS_EFI_BOOT_LOADER_MISSING", SRC_POS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EfiBootInst.MkDir(L"\\EFI\\VeraCrypt", bAlreadyExist);
|
EfiBootInst.MkDir(L"\\EFI\\VeraCrypt", bAlreadyExist);
|
||||||
EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\DcsBoot.efi", dcsBootImg, sizeDcsBoot);
|
EfiBootInst.SaveFile(L"\\EFI\\VeraCrypt\\DcsBoot.efi", dcsBootImg, sizeDcsBoot);
|
||||||
@@ -2849,6 +2922,7 @@ namespace VeraCrypt
|
|||||||
EfiBootInst.DelFile(L"\\EFI\\VeraCrypt\\PlatformInfo");
|
EfiBootInst.DelFile(L"\\EFI\\VeraCrypt\\PlatformInfo");
|
||||||
EfiBootInst.SetStartExec(L"VeraCrypt BootLoader (DcsBoot)", L"\\EFI\\VeraCrypt\\DcsBoot.efi");
|
EfiBootInst.SetStartExec(L"VeraCrypt BootLoader (DcsBoot)", L"\\EFI\\VeraCrypt\\DcsBoot.efi");
|
||||||
|
|
||||||
|
EfiBootInst.SaveFile(L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", dcsBootImg, sizeDcsBoot);
|
||||||
// move configuration file from old location (if it exists) to new location
|
// move configuration file from old location (if it exists) to new location
|
||||||
// we don't force the move operation if the new location already exists
|
// we don't force the move operation if the new location already exists
|
||||||
EfiBootInst.RenameFile (L"\\DcsProp", L"\\EFI\\VeraCrypt\\DcsProp", FALSE);
|
EfiBootInst.RenameFile (L"\\DcsProp", L"\\EFI\\VeraCrypt\\DcsProp", FALSE);
|
||||||
@@ -3724,9 +3798,6 @@ namespace VeraCrypt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define VC_EFI_BOOTLOADER_NAME L"DcsBoot"
|
|
||||||
|
|
||||||
void BootEncryption::BackupSystemLoader ()
|
void BootEncryption::BackupSystemLoader ()
|
||||||
{
|
{
|
||||||
if (GetSystemDriveConfiguration().SystemPartition.IsGPT)
|
if (GetSystemDriveConfiguration().SystemPartition.IsGPT)
|
||||||
@@ -3743,21 +3814,42 @@ namespace VeraCrypt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsigned __int64 loaderSize = 0;
|
unsigned __int64 loaderSize = 0;
|
||||||
|
std::vector<byte> bootLoaderBuf;
|
||||||
|
|
||||||
finally_do ({ EfiBootInst.DismountBootPartition(); });
|
finally_do ({ EfiBootInst.DismountBootPartition(); });
|
||||||
|
|
||||||
EfiBootInst.MountBootPartition(0);
|
EfiBootInst.MountBootPartition(0);
|
||||||
|
|
||||||
|
EfiBootInst.GetFileSize(L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", loaderSize);
|
||||||
|
|
||||||
|
// DcsBoot.efi is always smaller than 32KB
|
||||||
|
if (loaderSize < 32768)
|
||||||
|
{
|
||||||
|
bootLoaderBuf.resize ((size_t) loaderSize);
|
||||||
|
|
||||||
|
EfiBootInst.ReadFile(L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", &bootLoaderBuf[0], (DWORD) loaderSize);
|
||||||
|
|
||||||
|
// Prevent VeraCrypt EFI loader from being backed up
|
||||||
|
for (size_t i = 0; i < (size_t) loaderSize - (wcslen (_T(TC_APP_NAME)) * 2); ++i)
|
||||||
|
{
|
||||||
|
if (memcmp (&bootLoaderBuf[i], _T(TC_APP_NAME), wcslen (_T(TC_APP_NAME)) * 2) == 0)
|
||||||
|
{
|
||||||
|
Error ("WINDOWS_EFI_BOOT_LOADER_MISSING", ParentWindow);
|
||||||
|
throw UserAbort (SRC_POS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EfiBootInst.GetFileSize(Is64BitOs()? L"\\EFI\\Boot\\bootx64.efi" : L"\\EFI\\Boot\\bootia32.efi", loaderSize);
|
EfiBootInst.GetFileSize(Is64BitOs()? L"\\EFI\\Boot\\bootx64.efi" : L"\\EFI\\Boot\\bootia32.efi", loaderSize);
|
||||||
|
|
||||||
std::vector<byte> bootLoaderBuf ((size_t) loaderSize);
|
bootLoaderBuf.resize ((size_t) loaderSize);
|
||||||
|
|
||||||
EfiBootInst.ReadFile(Is64BitOs()? L"\\EFI\\Boot\\bootx64.efi": L"\\EFI\\Boot\\bootia32.efi", &bootLoaderBuf[0], (DWORD) loaderSize);
|
EfiBootInst.ReadFile(Is64BitOs()? L"\\EFI\\Boot\\bootx64.efi": L"\\EFI\\Boot\\bootia32.efi", &bootLoaderBuf[0], (DWORD) loaderSize);
|
||||||
|
|
||||||
// Prevent VeraCrypt EFI loader from being backed up
|
// Prevent VeraCrypt EFI loader from being backed up
|
||||||
for (size_t i = 0; i < (size_t) loaderSize - (wcslen (VC_EFI_BOOTLOADER_NAME) * 2); ++i)
|
for (size_t i = 0; i < (size_t) loaderSize - (wcslen (_T(TC_APP_NAME)) * 2); ++i)
|
||||||
{
|
{
|
||||||
if (memcmp (&bootLoaderBuf[i], VC_EFI_BOOTLOADER_NAME, wcslen (VC_EFI_BOOTLOADER_NAME) * 2) == 0)
|
if (memcmp (&bootLoaderBuf[i], _T(TC_APP_NAME), wcslen (_T(TC_APP_NAME)) * 2) == 0)
|
||||||
{
|
{
|
||||||
if (AskWarnNoYes ("TC_BOOT_LOADER_ALREADY_INSTALLED", ParentWindow) == IDNO)
|
if (AskWarnNoYes ("TC_BOOT_LOADER_ALREADY_INSTALLED", ParentWindow) == IDNO)
|
||||||
throw UserAbort (SRC_POS);
|
throw UserAbort (SRC_POS);
|
||||||
@@ -3775,6 +3867,8 @@ namespace VeraCrypt
|
|||||||
EfiBootInst.CopyFile(L"\\EFI\\Boot\\bootia32.efi", GetSystemLoaderBackupPath().c_str());
|
EfiBootInst.CopyFile(L"\\EFI\\Boot\\bootia32.efi", GetSystemLoaderBackupPath().c_str());
|
||||||
EfiBootInst.CopyFile(L"\\EFI\\Boot\\bootia32.efi", L"\\EFI\\Boot\\original_bootia32.vc_backup");
|
EfiBootInst.CopyFile(L"\\EFI\\Boot\\bootia32.efi", L"\\EFI\\Boot\\original_bootia32.vc_backup");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EfiBootInst.CopyFile (L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", L"\\EFI\\Microsoft\\Boot\\bootmgfw_ms.vc");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -3829,6 +3923,34 @@ namespace VeraCrypt
|
|||||||
else
|
else
|
||||||
EfiBootInst.RenameFile(L"\\EFI\\Boot\\original_bootia32.vc_backup", L"\\EFI\\Boot\\bootia32.efi", TRUE);
|
EfiBootInst.RenameFile(L"\\EFI\\Boot\\original_bootia32.vc_backup", L"\\EFI\\Boot\\bootia32.efi", TRUE);
|
||||||
|
|
||||||
|
if (!EfiBootInst.RenameFile(L"\\EFI\\Microsoft\\Boot\\bootmgfw_ms.vc", L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", TRUE))
|
||||||
|
{
|
||||||
|
EfiBootConf conf;
|
||||||
|
if (EfiBootInst.ReadConfig (L"\\EFI\\VeraCrypt\\DcsProp", conf) && strlen (conf.actionSuccessValue.c_str()))
|
||||||
|
{
|
||||||
|
string actionValue = conf.actionSuccessValue;
|
||||||
|
std::transform(actionValue.begin(), actionValue.end(), actionValue.begin(), ::tolower);
|
||||||
|
|
||||||
|
if (strstr (actionValue.c_str(), "postexec") && strstr (actionValue.c_str(), "file("))
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
const char* ptr = strstr (actionValue.c_str(), "file(");
|
||||||
|
ptr += 5;
|
||||||
|
wstring loaderPath = L"\\";
|
||||||
|
while ((c = *ptr))
|
||||||
|
{
|
||||||
|
if (c == ')' || c == ' ')
|
||||||
|
break;
|
||||||
|
loaderPath += (wchar_t) c;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
EfiBootInst.RenameFile(loaderPath.c_str(), L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi", TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EfiBootInst.DelFile(L"\\DcsBoot.efi");
|
EfiBootInst.DelFile(L"\\DcsBoot.efi");
|
||||||
EfiBootInst.DelFile(L"\\DcsInt.efi");
|
EfiBootInst.DelFile(L"\\DcsInt.efi");
|
||||||
EfiBootInst.DelFile(L"\\DcsCfg.efi");
|
EfiBootInst.DelFile(L"\\DcsCfg.efi");
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ namespace VeraCrypt
|
|||||||
File (wstring path,bool readOnly = false, bool create = false);
|
File (wstring path,bool readOnly = false, bool create = false);
|
||||||
virtual ~File () { Close(); }
|
virtual ~File () { Close(); }
|
||||||
|
|
||||||
|
bool IsOpened () const { return FileOpen;}
|
||||||
void CheckOpened (const char* srcPos) { if (!FileOpen) { SetLastError (LastError); throw SystemException (srcPos);} }
|
void CheckOpened (const char* srcPos) { if (!FileOpen) { SetLastError (LastError); throw SystemException (srcPos);} }
|
||||||
void Close ();
|
void Close ();
|
||||||
DWORD Read (byte *buffer, DWORD size);
|
DWORD Read (byte *buffer, DWORD size);
|
||||||
@@ -176,6 +177,7 @@ namespace VeraCrypt
|
|||||||
int authorizeRetry;
|
int authorizeRetry;
|
||||||
int bmlLockFlags;
|
int bmlLockFlags;
|
||||||
int bmlDriverEnabled;
|
int bmlDriverEnabled;
|
||||||
|
string actionSuccessValue;
|
||||||
|
|
||||||
EfiBootConf();
|
EfiBootConf();
|
||||||
|
|
||||||
@@ -207,6 +209,7 @@ namespace VeraCrypt
|
|||||||
void GetFileSize(const wchar_t* name, unsigned __int64& size);
|
void GetFileSize(const wchar_t* name, unsigned __int64& size);
|
||||||
void ReadFile(const wchar_t* name, byte* data, DWORD size);
|
void ReadFile(const wchar_t* name, byte* data, DWORD size);
|
||||||
void CopyFile(const wchar_t* name, const wchar_t* targetName);
|
void CopyFile(const wchar_t* name, const wchar_t* targetName);
|
||||||
|
bool FileExists(const wchar_t* name);
|
||||||
|
|
||||||
BOOL RenameFile(const wchar_t* name, wchar_t* nameNew, BOOL bForce);
|
BOOL RenameFile(const wchar_t* name, wchar_t* nameNew, BOOL bForce);
|
||||||
BOOL DelFile(const wchar_t* name);
|
BOOL DelFile(const wchar_t* name);
|
||||||
|
|||||||
@@ -1419,6 +1419,7 @@
|
|||||||
<entry lang="en" key="AFTER_UPGRADE_RESCUE_DISK">It is strongly recommended that you create a new VeraCrypt Rescue Disk (which will contain the new version of the VeraCrypt Boot Loader) by selecting 'System' > 'Create Rescue Disk'.\nDo you want to do it now?</entry>
|
<entry lang="en" key="AFTER_UPGRADE_RESCUE_DISK">It is strongly recommended that you create a new VeraCrypt Rescue Disk (which will contain the new version of the VeraCrypt Boot Loader) by selecting 'System' > 'Create Rescue Disk'.\nDo you want to do it now?</entry>
|
||||||
<entry lang="en" key="IDC_ALLOW_TRIM_NONSYS_SSD">Allow TRIM command for non-system SSD partition/drive</entry>
|
<entry lang="en" key="IDC_ALLOW_TRIM_NONSYS_SSD">Allow TRIM command for non-system SSD partition/drive</entry>
|
||||||
<entry lang="en" key="IDC_BLOCK_SYSENC_TRIM">Block TRIM command on system partition/drive</entry>
|
<entry lang="en" key="IDC_BLOCK_SYSENC_TRIM">Block TRIM command on system partition/drive</entry>
|
||||||
|
<entry lang="en" key="WINDOWS_EFI_BOOT_LOADER_MISSING">ERROR: Windows EFI system loader could not be located on the disk. Operation will be aborted.</entry>
|
||||||
</localization>
|
</localization>
|
||||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||||
<xs:element name="VeraCrypt">
|
<xs:element name="VeraCrypt">
|
||||||
|
|||||||
@@ -8180,7 +8180,7 @@ retryCDDriveCheck:
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
BootEncObj->RestartComputer (bSystemIsGPT);
|
BootEncObj->RestartComputer ();
|
||||||
}
|
}
|
||||||
catch (Exception &e)
|
catch (Exception &e)
|
||||||
{
|
{
|
||||||
@@ -10139,7 +10139,7 @@ static void AfterWMInitTasks (HWND hwndDlg)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
BootEncObj->RestartComputer (bSystemIsGPT);
|
BootEncObj->RestartComputer ();
|
||||||
}
|
}
|
||||||
catch (Exception &e)
|
catch (Exception &e)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user