From ca46cf928ae763aab639ac943a40633fdac3389e Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sat, 26 Oct 2019 22:49:37 +0200 Subject: Windows: Update EFI NVRAM variable only if changed or doesn't exist and add configuration to force setting EFI BootNext to veraCrypt bootloader before each shutdown --- src/Common/BootEncryption.cpp | 28 +++++++++++++++++++--------- src/Common/BootEncryption.h | 6 ++++-- src/Mount/Mount.c | 5 ++++- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp index a784f57f..ac873048 100644 --- a/src/Common/BootEncryption.cpp +++ b/src/Common/BootEncryption.cpp @@ -1030,7 +1030,7 @@ namespace VeraCrypt static EfiBoot EfiBootInst; - BootEncryption::BootEncryption (HWND parent, bool postOOBE) + BootEncryption::BootEncryption (HWND parent, bool postOOBE, bool setBootNext) : DriveConfigValid (false), ParentWindow (parent), RealSystemDriveSizeValid (false), @@ -1041,7 +1041,8 @@ namespace VeraCrypt SelectedEncryptionAlgorithmId (0), SelectedPrfAlgorithmId (0), VolumeHeaderValid (false), - PostOOBEMode (postOOBE) + PostOOBEMode (postOOBE), + SetBootNext (setBootNext) { HiddenOSCandidatePartition.IsGPT = FALSE; HiddenOSCandidatePartition.Number = (size_t) -1; @@ -2693,7 +2694,7 @@ namespace VeraCrypt } } - void EfiBoot::SetStartExec(wstring description, wstring execPath, uint16 statrtOrderNum , wchar_t* type, uint32 attr) { + void EfiBoot::SetStartExec(wstring description, wstring execPath, bool setBootNext, uint16 statrtOrderNum , wchar_t* type, uint32 attr) { SetPrivilege(SE_SYSTEM_ENVIRONMENT_NAME, TRUE); // Check EFI if (!IsEfiBoot()) { @@ -2783,8 +2784,14 @@ namespace VeraCrypt // Set variable wchar_t varName[256]; StringCchPrintfW(varName, ARRAYSIZE (varName), L"%s%04X", type == NULL ? L"Boot" : type, statrtOrderNum); - SetFirmwareEnvironmentVariable(varName, EfiVarGuid, startVar, varSize); + + // only set value if it doesn't already exist + byte* existingVar = new byte[varSize]; + DWORD existingVarLen = GetFirmwareEnvironmentVariableW (varName, EfiVarGuid, existingVar, varSize); + if ((existingVarLen != varSize) || (0 != memcmp (existingVar, startVar, varSize))) + SetFirmwareEnvironmentVariable(varName, EfiVarGuid, startVar, varSize); delete [] startVar; + delete [] existingVar; // Update order wstring order = L"Order"; @@ -2821,12 +2828,15 @@ namespace VeraCrypt SetFirmwareEnvironmentVariable(order.c_str(), EfiVarGuid, startOrder, startOrderLen); } - // set BootNext value - wstring next = L"Next"; - next.insert(0, type == NULL ? L"Boot" : type); + if (setBootNext) + { + // set BootNext value + wstring next = L"Next"; + next.insert(0, type == NULL ? L"Boot" : type); - SetFirmwareEnvironmentVariable(next.c_str(), EfiVarGuid, &statrtOrderNum, 2); + SetFirmwareEnvironmentVariable(next.c_str(), EfiVarGuid, &statrtOrderNum, 2); + } } bool EfiBoot::CompareFiles (const wchar_t* fileName1, const wchar_t* fileName2) @@ -3329,7 +3339,7 @@ namespace VeraCrypt // restore boot menu entry in case of PostOOBE if (PostOOBEMode) - EfiBootInst.SetStartExec(L"VeraCrypt BootLoader (DcsBoot)", L"\\EFI\\VeraCrypt\\DcsBoot.efi"); + EfiBootInst.SetStartExec(L"VeraCrypt BootLoader (DcsBoot)", L"\\EFI\\VeraCrypt\\DcsBoot.efi", SetBootNext); if (EfiBootInst.FileExists (L"\\EFI\\Microsoft\\Boot\\bootmgfw_ms.vc")) { diff --git a/src/Common/BootEncryption.h b/src/Common/BootEncryption.h index 9ae90942..ec54b3ab 100644 --- a/src/Common/BootEncryption.h +++ b/src/Common/BootEncryption.h @@ -205,7 +205,7 @@ namespace VeraCrypt bool IsEfiBoot(); void DeleteStartExec(uint16 statrtOrderNum = 0xDC5B, wchar_t* type = NULL); - void SetStartExec(wstring description, wstring execPath, uint16 statrtOrderNum = 0xDC5B, wchar_t* type = NULL, uint32 attr = 1); + void SetStartExec(wstring description, wstring execPath, bool setBootNext = true, uint16 statrtOrderNum = 0xDC5B, wchar_t* type = NULL, uint32 attr = 1); void SaveFile(const wchar_t* name, byte* data, DWORD size); void GetFileSize(const wchar_t* name, unsigned __int64& size); void ReadFile(const wchar_t* name, byte* data, DWORD size); @@ -237,7 +237,7 @@ namespace VeraCrypt class BootEncryption { public: - BootEncryption (HWND parent, bool postOOBE = false); + BootEncryption (HWND parent, bool postOOBE = false, bool setBootNext = false); ~BootEncryption (); enum FilterType @@ -349,6 +349,7 @@ namespace VeraCrypt bool RescueVolumeHeaderValid; bool VolumeHeaderValid; bool PostOOBEMode; + bool SetBootNext; }; } @@ -366,6 +367,7 @@ namespace VeraCrypt #define VC_SYSTEM_FAVORITES_SERVICE_ARG_SKIP_MOUNT L"/SkipMount" #define VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_UPDATE_LOADER 0x1 +#define VC_SYSTEM_FAVORITES_SERVICE_CONFIG_FORCE_SET_BOOTNEXT 0x2 #define VC_WINDOWS_UPGRADE_POSTOOBE_CMDLINE_OPTION L"/PostOOBE" diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index 2837d449..bde729ee 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -9430,7 +9430,10 @@ static DWORD WINAPI SystemFavoritesServiceCtrlHandler ( DWORD dwControl, if (!BootEncStatus.HiddenSystem) { // re-install our bootloader again in case the update process has removed it. - BootEncryption bootEnc (NULL, true); + bool bForceSetNextBoot = false; + if (BootEncObj->ReadServiceConfigurationFlags () & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_FORCE_SET_BOOTNEXT) + bForceSetNextBoot = true; + BootEncryption bootEnc (NULL, true, bForceSetNextBoot); bootEnc.InstallBootLoader (true); } } -- cgit v1.2.3