Windows: Make MSI installer compatible with System Encryption by leveraging VeraCrypt service capabilities

This commit is contained in:
Mounir IDRASSI 2022-02-01 23:25:07 +01:00
parent 8ad93e6648
commit 9b88625d97
No known key found for this signature in database
GPG Key ID: 02C30AE90FAE4A6F
4 changed files with 80 additions and 30 deletions

View File

@ -360,6 +360,7 @@ namespace VeraCrypt
#define TC_SYSTEM_FAVORITES_SERVICE_LOAD_ORDER_GROUP L"Event Log" #define TC_SYSTEM_FAVORITES_SERVICE_LOAD_ORDER_GROUP L"Event Log"
#define TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION L"/systemFavoritesService" #define TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION L"/systemFavoritesService"
#define VC_SYSTEM_FAVORITES_SERVICE_ARG_SKIP_MOUNT L"/SkipMount" #define VC_SYSTEM_FAVORITES_SERVICE_ARG_SKIP_MOUNT L"/SkipMount"
#define VC_SYSTEM_FAVORITES_SERVICE_ARG_UPDATE_LOADER L"/UpdateLoader"
#define VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_UPDATE_LOADER 0x1 #define VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_UPDATE_LOADER 0x1
#define VC_SYSTEM_FAVORITES_SERVICE_CONFIG_FORCE_SET_BOOTNEXT 0x2 #define VC_SYSTEM_FAVORITES_SERVICE_CONFIG_FORCE_SET_BOOTNEXT 0x2

View File

@ -175,6 +175,10 @@ BOOL bLanguageSetInSetup = FALSE;
extern BOOL bMakePackage; extern BOOL bMakePackage;
#endif #endif
#ifdef TCMOUNT
extern BOOL ServiceMode;
#endif
// Status of detection of hidden sectors (whole-system-drive encryption). // Status of detection of hidden sectors (whole-system-drive encryption).
// 0 - Unknown/undetermined/completed, 1: Detection is or was in progress (but did not complete e.g. due to system crash). // 0 - Unknown/undetermined/completed, 1: Detection is or was in progress (but did not complete e.g. due to system crash).
int HiddenSectorDetectionStatus = 0; int HiddenSectorDetectionStatus = 0;
@ -4759,10 +4763,16 @@ int DriverAttach (void)
if (IsNonInstallMode () && CreateDriverSetupMutex () && DriverUnload () && nLoadRetryCount++ < 3) if (IsNonInstallMode () && CreateDriverSetupMutex () && DriverUnload () && nLoadRetryCount++ < 3)
goto load; goto load;
CloseDriverSetupMutex (); #ifdef TCMOUNT
CloseHandle (hDriver); // don't fail in case of service. This solves issues during upgrade when system encryption is enabled
hDriver = INVALID_HANDLE_VALUE; if (!ServiceMode)
return ERR_DRIVER_VERSION; #endif
{
CloseDriverSetupMutex ();
CloseHandle (hDriver);
hDriver = INVALID_HANDLE_VALUE;
return ERR_DRIVER_VERSION;
}
} }
#else #else
if (!bResult) if (!bResult)

View File

@ -9663,28 +9663,39 @@ static void SystemFavoritesServiceSetStatus (DWORD status, DWORD waitHint = 0)
SetServiceStatus (SystemFavoritesServiceStatusHandle, &SystemFavoritesServiceStatus); SetServiceStatus (SystemFavoritesServiceStatusHandle, &SystemFavoritesServiceStatus);
} }
static void SystemFavoritesServiceUpdateLoaderProcessing () static void SystemFavoritesServiceUpdateLoaderProcessing (BOOL bForce)
{ {
if (!(BootEncObj->ReadServiceConfigurationFlags () & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_UPDATE_LOADER)) SystemFavoritesServiceLogInfo (L"SystemFavoritesServiceUpdateLoaderProcessing called");
if (bForce || !(BootEncObj->ReadServiceConfigurationFlags () & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_UPDATE_LOADER))
{ {
SystemFavoritesServiceLogInfo (L"SystemFavoritesServiceUpdateLoaderProcessing processing");
try try
{ {
BootEncryption::UpdateSetupConfigFile (true); BootEncryption::UpdateSetupConfigFile (true);
SystemFavoritesServiceLogInfo (L"SystemFavoritesServiceUpdateLoaderProcessing: UpdateSetupConfigFile called");
if (!BootEncStatus.HiddenSystem) if (!BootEncStatus.HiddenSystem)
{ {
// re-install our bootloader again in case the update process has removed it. // re-install our bootloader again in case the update process has removed it.
bool bForceSetNextBoot = false; bool bForceSetNextBoot = false;
bool bSetBootentry = true; bool bSetBootentry = true;
bool bForceFirstBootEntry = true; bool bForceFirstBootEntry = true;
uint32 flags = BootEncObj->ReadServiceConfigurationFlags (); bool bPostOOBE = true;
if (flags & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_FORCE_SET_BOOTNEXT) if (bForce)
bForceSetNextBoot = true; bPostOOBE = false;
if (flags & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_SET_BOOTENTRY) else
bSetBootentry = false; {
if (flags & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_FORCE_FIRST_BOOTENTRY) uint32 flags = BootEncObj->ReadServiceConfigurationFlags ();
bForceFirstBootEntry = false; if (flags & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_FORCE_SET_BOOTNEXT)
BootEncryption bootEnc (NULL, true, bSetBootentry, bForceFirstBootEntry, bForceSetNextBoot); bForceSetNextBoot = true;
if (flags & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_SET_BOOTENTRY)
bSetBootentry = false;
if (flags & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_FORCE_FIRST_BOOTENTRY)
bForceFirstBootEntry = false;
}
BootEncryption bootEnc (NULL, bPostOOBE, bSetBootentry, bForceFirstBootEntry, bForceSetNextBoot);
SystemFavoritesServiceLogInfo (L"SystemFavoritesServiceUpdateLoaderProcessing: InstallBootLoader calling");
bootEnc.InstallBootLoader (true); bootEnc.InstallBootLoader (true);
SystemFavoritesServiceLogInfo (L"SystemFavoritesServiceUpdateLoaderProcessing: InstallBootLoader called");
} }
} }
catch (...) catch (...)
@ -9704,7 +9715,7 @@ static DWORD WINAPI SystemFavoritesServiceCtrlHandler ( DWORD dwControl,
case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_STOP:
SystemFavoritesServiceSetStatus (SERVICE_STOP_PENDING); SystemFavoritesServiceSetStatus (SERVICE_STOP_PENDING);
SystemFavoritesServiceUpdateLoaderProcessing (); SystemFavoritesServiceUpdateLoaderProcessing (FALSE);
/* clear VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION flag */ /* clear VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION flag */
SetDriverConfigurationFlag (VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION, FALSE); SetDriverConfigurationFlag (VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION, FALSE);
@ -9717,7 +9728,7 @@ static DWORD WINAPI SystemFavoritesServiceCtrlHandler ( DWORD dwControl,
/* perform fixing of bootloader and SetupConfig.ini when the system resumes from sleep */ /* perform fixing of bootloader and SetupConfig.ini when the system resumes from sleep */
if (dwEventType == PBT_APMRESUMEAUTOMATIC) if (dwEventType == PBT_APMRESUMEAUTOMATIC)
{ {
SystemFavoritesServiceUpdateLoaderProcessing (); SystemFavoritesServiceUpdateLoaderProcessing (FALSE);
} }
} }
break; break;
@ -9726,7 +9737,7 @@ static DWORD WINAPI SystemFavoritesServiceCtrlHandler ( DWORD dwControl,
/* perform fixing of bootloader and SetupConfig.ini when the user logs in or when he unlocks his locked session */ /* perform fixing of bootloader and SetupConfig.ini when the user logs in or when he unlocks his locked session */
if ((dwEventType == WTS_SESSION_UNLOCK) || (dwEventType == WTS_SESSION_LOGON)) if ((dwEventType == WTS_SESSION_UNLOCK) || (dwEventType == WTS_SESSION_LOGON))
{ {
SystemFavoritesServiceUpdateLoaderProcessing (); SystemFavoritesServiceUpdateLoaderProcessing (FALSE);
} }
} }
break; break;
@ -9791,14 +9802,21 @@ static VOID WINAPI SystemFavoritesServiceMain (DWORD argc, LPTSTR *argv)
BOOL status = FALSE; BOOL status = FALSE;
DEV_BROADCAST_DEVICEINTERFACE hdr; DEV_BROADCAST_DEVICEINTERFACE hdr;
BOOL bSkipMount = FALSE; BOOL bSkipMount = FALSE;
BOOL bUpdateLoader = FALSE;
DWORD i;
memset (&SystemFavoritesServiceStatus, 0, sizeof (SystemFavoritesServiceStatus)); memset (&SystemFavoritesServiceStatus, 0, sizeof (SystemFavoritesServiceStatus));
SystemFavoritesServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; SystemFavoritesServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
SystemFavoritesServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; SystemFavoritesServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
if (IsOSAtLeast (WIN_VISTA)) if (IsOSAtLeast (WIN_VISTA))
SystemFavoritesServiceStatus.dwControlsAccepted |= SERVICE_ACCEPT_PRESHUTDOWN | SERVICE_ACCEPT_SESSIONCHANGE | SERVICE_ACCEPT_POWEREVENT; SystemFavoritesServiceStatus.dwControlsAccepted |= SERVICE_ACCEPT_PRESHUTDOWN | SERVICE_ACCEPT_SESSIONCHANGE | SERVICE_ACCEPT_POWEREVENT;
if ((argc >= 2) && (0 == _wcsicmp (argv[1], VC_SYSTEM_FAVORITES_SERVICE_ARG_SKIP_MOUNT))) for (i = 1; i < argc; i++)
bSkipMount = TRUE; {
if (0 == _wcsicmp (argv[i], VC_SYSTEM_FAVORITES_SERVICE_ARG_SKIP_MOUNT))
bSkipMount = TRUE;
else if (0 == _wcsicmp (argv[i], VC_SYSTEM_FAVORITES_SERVICE_ARG_UPDATE_LOADER))
bUpdateLoader = TRUE;
}
ZeroMemory (&hdr, sizeof(hdr)); ZeroMemory (&hdr, sizeof(hdr));
hdr.dbcc_size = sizeof (hdr); hdr.dbcc_size = sizeof (hdr);
@ -9817,6 +9835,12 @@ static VOID WINAPI SystemFavoritesServiceMain (DWORD argc, LPTSTR *argv)
SetUnhandledExceptionFilter (SystemFavoritesServiceExceptionHandler); SetUnhandledExceptionFilter (SystemFavoritesServiceExceptionHandler);
_set_invalid_parameter_handler (SystemFavoritesServiceInvalidParameterHandler); _set_invalid_parameter_handler (SystemFavoritesServiceInvalidParameterHandler);
if (bUpdateLoader)
{
SystemFavoritesServiceSetStatus (SERVICE_START_PENDING, 120000);
SystemFavoritesServiceUpdateLoaderProcessing (TRUE);
}
if (!bSkipMount) if (!bSkipMount)
{ {
InitGlobalLocks (); InitGlobalLocks ();
@ -9846,7 +9870,7 @@ static VOID WINAPI SystemFavoritesServiceMain (DWORD argc, LPTSTR *argv)
if (!(ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD)) if (!(ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD))
WipeCache (NULL, TRUE); WipeCache (NULL, TRUE);
SystemFavoritesServiceUpdateLoaderProcessing (); SystemFavoritesServiceUpdateLoaderProcessing (FALSE);
} }
SystemFavoritesServiceSetStatus (SERVICE_RUNNING); SystemFavoritesServiceSetStatus (SERVICE_RUNNING);

View File

@ -1360,7 +1360,10 @@ BOOL StartStopService_Dll (MSIHANDLE hInstaller, wchar_t *lpszService, BOOL bSta
if (bStart) if (bStart)
{ {
if (!StartService (hService, argc, argv) && (GetLastError () != ERROR_SERVICE_ALREADY_RUNNING)) if (!StartService (hService, argc, argv) && (GetLastError () != ERROR_SERVICE_ALREADY_RUNNING))
{
MSILog(hInstaller, MSI_ERROR_LEVEL, L"Failed to start %s. Error 0x%.8X", lpszService, GetLastError ());
goto error; goto error;
}
} }
else else
ControlService (hService, SERVICE_CONTROL_STOP, &status); ControlService (hService, SERVICE_CONTROL_STOP, &status);
@ -1379,10 +1382,16 @@ BOOL StartStopService_Dll (MSIHANDLE hInstaller, wchar_t *lpszService, BOOL bSta
bRet = QueryServiceStatus (hService, &status); bRet = QueryServiceStatus (hService, &status);
if (bRet != TRUE) if (bRet != TRUE)
{
MSILog(hInstaller, MSI_ERROR_LEVEL, L"Failed to query status of %s. Error 0x%.8X", lpszService, GetLastError ());
goto error; goto error;
}
if (status.dwCurrentState != dwExpectedState) if (status.dwCurrentState != dwExpectedState)
{
MSILog(hInstaller, MSI_ERROR_LEVEL, L"Current state of %s (0x%.8X) is different from expected one (0x%.8X).", lpszService, status.dwCurrentState, dwExpectedState);
goto error; goto error;
}
bOK = TRUE; bOK = TRUE;
@ -1511,11 +1520,6 @@ BOOL DoDriverUnload_Dll (MSIHANDLE hInstaller, HWND hwnd)
BootEncryption bootEnc (hwnd); BootEncryption bootEnc (hwnd);
if (bootEnc.GetDriverServiceStartType() == SERVICE_BOOT_START) if (bootEnc.GetDriverServiceStartType() == SERVICE_BOOT_START)
{ {
MSILogAndShow(hInstaller, MSI_ERROR_LEVEL, L"VeraCrypt MSI installation is currently not compatible with Windows System Encryption");
bOK = FALSE;
goto end;
/************* TODO: find a workaround to the fact that MSI service cannot access EFI environment variable
try try
{ {
// Check hidden OS update consistency // Check hidden OS update consistency
@ -1559,7 +1563,6 @@ BOOL DoDriverUnload_Dll (MSIHANDLE hInstaller, HWND hwnd)
SystemEncryptionUpdate = TRUE; SystemEncryptionUpdate = TRUE;
PortableMode = FALSE; PortableMode = FALSE;
} }
*****************************************/
} }
} }
catch (...) { } catch (...) { }
@ -1612,6 +1615,12 @@ BOOL DoDriverUnload_Dll (MSIHANDLE hInstaller, HWND hwnd)
if (TCWindowClosed) if (TCWindowClosed)
Sleep (2000); Sleep (2000);
// stop service
if (SystemEncryptionUpdate)
{
StartStopService_Dll (hInstaller, TC_SYSTEM_FAVORITES_SERVICE_NAME, FALSE, 0, NULL);
}
} }
// Test for any applications attached to driver // Test for any applications attached to driver
@ -1928,7 +1937,8 @@ BOOL UpgradeBootLoader_Dll (MSIHANDLE hInstaller, HWND hwndDlg)
{ {
MSILog (hInstaller, MSI_INFO_LEVEL, GetString("INSTALLER_UPDATING_BOOT_LOADER")); MSILog (hInstaller, MSI_INFO_LEVEL, GetString("INSTALLER_UPDATING_BOOT_LOADER"));
bootEnc.InstallBootLoader (true); // this is done by the service now
//bootEnc.InstallBootLoader (true);
if (bootEnc.GetInstalledBootLoaderVersion() <= TC_RESCUE_DISK_UPGRADE_NOTICE_MAX_VERSION) if (bootEnc.GetInstalledBootLoaderVersion() <= TC_RESCUE_DISK_UPGRADE_NOTICE_MAX_VERSION)
{ {
@ -2776,15 +2786,20 @@ EXTERN_C UINT STDAPICALLTYPE VC_CustomAction_PostInstall(MSIHANDLE hInstaller)
if (StartStopService_Dll (hInstaller, TC_SYSTEM_FAVORITES_SERVICE_NAME, FALSE, 0, NULL)) if (StartStopService_Dll (hInstaller, TC_SYSTEM_FAVORITES_SERVICE_NAME, FALSE, 0, NULL))
{ {
// we tell the service not to load system favorites on startup // we tell the service not to load system favorites on startup and to update bootloader on startup
LPCWSTR szArgs[2] = { TC_SYSTEM_FAVORITES_SERVICE_NAME, VC_SYSTEM_FAVORITES_SERVICE_ARG_SKIP_MOUNT}; LPCWSTR szArgs[3] = { TC_SYSTEM_FAVORITES_SERVICE_NAME, VC_SYSTEM_FAVORITES_SERVICE_ARG_SKIP_MOUNT, VC_SYSTEM_FAVORITES_SERVICE_ARG_UPDATE_LOADER};
if (!CopyFile (szTmp, servicePath.c_str(), FALSE)) if (!CopyFile (szTmp, servicePath.c_str(), FALSE))
ForceCopyFile (szTmp, servicePath.c_str()); ForceCopyFile (szTmp, servicePath.c_str());
StartStopService_Dll (hInstaller, TC_SYSTEM_FAVORITES_SERVICE_NAME, TRUE, 2, szArgs); MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostInstall: SystemEncryptionUpdate = %s", SystemEncryptionUpdate? L"TRUE" : L"FALSE");
StartStopService_Dll (hInstaller, TC_SYSTEM_FAVORITES_SERVICE_NAME, TRUE, SystemEncryptionUpdate? 3 : 2, szArgs);
} }
else else
{
MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostInstall: failed to stop %S", servicePath.c_str());
ForceCopyFile (szTmp, servicePath.c_str()); ForceCopyFile (szTmp, servicePath.c_str());
}
BootEncObj.SetDriverConfigurationFlag (driverFlags, true); BootEncObj.SetDriverConfigurationFlag (driverFlags, true);