From 8c9ca787bee29f969cd7ca9aeaa46626d557d196 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Wed, 16 Mar 2022 15:20:15 -0500 Subject: Add WixBundleCommandLineAction, don't set dynamic variables at startup. Fixes 6736 --- src/burn/engine/core.cpp | 10 +- src/burn/engine/core.h | 1 + src/burn/engine/engine.cpp | 4 +- src/burn/engine/plan.cpp | 3 + src/burn/engine/plan.h | 1 + src/burn/engine/registration.cpp | 3 - src/burn/engine/variable.cpp | 1 + src/burn/test/BurnUnitTest/PlanTest.cpp | 2 +- src/burn/test/BurnUnitTest/RegistrationTest.cpp | 7 +- .../WixStandardBootstrapperApplication.cpp | 103 ++++++++++++--------- src/wix/WixToolset.Core/CompilerCore.cs | 1 + 11 files changed, 78 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index 37872e52..becece86 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp @@ -309,7 +309,7 @@ extern "C" HRESULT CoreDetect( pEngineState->fDetected = FALSE; pEngineState->fPlanned = FALSE; DetectReset(&pEngineState->registration, &pEngineState->packages); - PlanReset(&pEngineState->plan, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads); + PlanReset(&pEngineState->plan, &pEngineState->variables, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads); hr = RegistrationSetDynamicVariables(&pEngineState->registration, &pEngineState->variables); ExitOnFailure(hr, "Failed to reset the dynamic registration variables during detect."); @@ -441,6 +441,9 @@ extern "C" HRESULT CorePlan( BURN_PACKAGE* pForwardCompatibleBundlePackage = NULL; BOOL fContinuePlanning = TRUE; // assume we won't skip planning due to dependencies. + hr = PlanSetVariables(action, &pEngineState->variables); + ExitOnFailure(hr, "Failed to update action."); + LogId(REPORT_STANDARD, MSG_PLAN_BEGIN, pEngineState->packages.cPackages, LoggingBurnActionToString(action)); fPlanBegan = TRUE; @@ -458,7 +461,7 @@ extern "C" HRESULT CorePlan( // Always reset the plan. pEngineState->fPlanned = FALSE; - PlanReset(&pEngineState->plan, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads); + PlanReset(&pEngineState->plan, &pEngineState->variables, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads); // Remember the overall action state in the plan since it shapes the changes // we make everywhere. @@ -472,9 +475,6 @@ extern "C" HRESULT CorePlan( pEngineState->plan.fDisableRollback = pEngineState->fDisableRollback || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == pEngineState->plan.action; pEngineState->plan.fPlanPackageCacheRollback = BOOTSTRAPPER_REGISTRATION_TYPE_NONE == pEngineState->registration.detectedRegistrationType; - hr = PlanSetVariables(action, &pEngineState->variables); - ExitOnFailure(hr, "Failed to update action."); - // Set resume commandline hr = PlanSetResumeCommand(&pEngineState->plan, &pEngineState->registration, &pEngineState->log); ExitOnFailure(hr, "Failed to set resume command"); diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h index ff983d60..6ba1aa2a 100644 --- a/src/burn/engine/core.h +++ b/src/burn/engine/core.h @@ -37,6 +37,7 @@ const LPCWSTR BURN_COMMANDLINE_SWITCH_PREFIX = L"burn."; const LPCWSTR BURN_BUNDLE_LAYOUT_DIRECTORY = L"WixBundleLayoutDirectory"; const LPCWSTR BURN_BUNDLE_ACTION = L"WixBundleAction"; const LPCWSTR BURN_BUNDLE_ACTIVE_PARENT = L"WixBundleActiveParent"; +const LPCWSTR BURN_BUNDLE_COMMAND_LINE_ACTION = L"WixBundleCommandLineAction"; const LPCWSTR BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER = L"WixBundleExecutePackageCacheFolder"; const LPCWSTR BURN_BUNDLE_EXECUTE_PACKAGE_ACTION = L"WixBundleExecutePackageAction"; const LPCWSTR BURN_BUNDLE_FORCED_RESTART_PACKAGE = L"WixBundleForcedRestartPackage"; diff --git a/src/burn/engine/engine.cpp b/src/burn/engine/engine.cpp index 1f2dac3c..9b94552b 100644 --- a/src/burn/engine/engine.cpp +++ b/src/burn/engine/engine.cpp @@ -557,8 +557,8 @@ static HRESULT RunNormal( hr = S_OK; // Set some built-in variables before loading the BA. - hr = PlanSetVariables(pEngineState->command.action, &pEngineState->variables); - ExitOnFailure(hr, "Failed to set action variables."); + hr = VariableSetNumeric(&pEngineState->variables, BURN_BUNDLE_COMMAND_LINE_ACTION, pEngineState->command.action, TRUE); + ExitOnFailure(hr, "Failed to set command line action variable."); hr = RegistrationSetVariables(&pEngineState->registration, &pEngineState->variables); ExitOnFailure(hr, "Failed to set registration variables."); diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index 46680636..5e1d2654 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp @@ -147,6 +147,7 @@ static BOOL ForceCache( extern "C" void PlanReset( __in BURN_PLAN* pPlan, + __in BURN_VARIABLES* pVariables, __in BURN_CONTAINERS* pContainers, __in BURN_PACKAGES* pPackages, __in BURN_PAYLOAD_GROUP* pLayoutPayloads @@ -274,6 +275,8 @@ extern "C" void PlanReset( ResetPlannedRollbackBoundaryState(&pPackages->rgRollbackBoundaries[i]); } } + + PlanSetVariables(BOOTSTRAPPER_ACTION_UNKNOWN, pVariables); } extern "C" void PlanUninitializeExecuteAction( diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h index e73cbcfa..834d2567 100644 --- a/src/burn/engine/plan.h +++ b/src/burn/engine/plan.h @@ -306,6 +306,7 @@ typedef struct _BURN_PLAN void PlanReset( __in BURN_PLAN* pPlan, + __in BURN_VARIABLES* pVariables, __in BURN_CONTAINERS* pContainers, __in BURN_PACKAGES* pPackages, __in BURN_PAYLOAD_GROUP* pLayoutPayloads diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp index 6bae2e7b..a65c30d3 100644 --- a/src/burn/engine/registration.cpp +++ b/src/burn/engine/registration.cpp @@ -445,9 +445,6 @@ extern "C" HRESULT RegistrationSetVariables( HRESULT hr = S_OK; LPWSTR scz = NULL; - hr = RegistrationSetDynamicVariables(pRegistration, pVariables); - ExitOnFailure(hr, "Failed to set the dynamic registration variables."); - // Ensure the registration bundle name is updated. hr = GetBundleInProgressName(pRegistration, pVariables, &scz); ExitOnFailure(hr, "Failed to initialize bundle name."); diff --git a/src/burn/engine/variable.cpp b/src/burn/engine/variable.cpp index ae06c1d5..718751e5 100644 --- a/src/burn/engine/variable.cpp +++ b/src/burn/engine/variable.cpp @@ -268,6 +268,7 @@ extern "C" HRESULT VariableInitialize( {L"WindowsFolder", InitializeVariableCsidlFolder, CSIDL_WINDOWS}, {L"WindowsVolume", InitializeVariableWindowsVolumeFolder, 0}, {BURN_BUNDLE_ACTION, InitializeVariableNumeric, 0, FALSE, TRUE}, + {BURN_BUNDLE_COMMAND_LINE_ACTION, InitializeVariableNumeric, 0, FALSE, TRUE}, {BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, InitializeVariableString, NULL, FALSE, TRUE}, {BURN_BUNDLE_EXECUTE_PACKAGE_ACTION, InitializeVariableString, NULL, FALSE, TRUE}, {BURN_BUNDLE_FORCED_RESTART_PACKAGE, InitializeVariableString, NULL, TRUE, TRUE}, diff --git a/src/burn/test/BurnUnitTest/PlanTest.cpp b/src/burn/test/BurnUnitTest/PlanTest.cpp index 0a8ac369..4d726fb4 100644 --- a/src/burn/test/BurnUnitTest/PlanTest.cpp +++ b/src/burn/test/BurnUnitTest/PlanTest.cpp @@ -2040,7 +2040,7 @@ namespace Bootstrapper void PlanTestDetect(BURN_ENGINE_STATE* pEngineState) { DetectReset(&pEngineState->registration, &pEngineState->packages); - PlanReset(&pEngineState->plan, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads); + PlanReset(&pEngineState->plan, &pEngineState->variables, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads); pEngineState->userExperience.fEngineActive = TRUE; pEngineState->fDetected = TRUE; diff --git a/src/burn/test/BurnUnitTest/RegistrationTest.cpp b/src/burn/test/BurnUnitTest/RegistrationTest.cpp index 86ea86b0..f01d92a4 100644 --- a/src/burn/test/BurnUnitTest/RegistrationTest.cpp +++ b/src/burn/test/BurnUnitTest/RegistrationTest.cpp @@ -313,6 +313,9 @@ namespace Bootstrapper plan.pCommand = &command; plan.pInternalCommand = &internalCommand; + hr = RegistrationSetVariables(®istration, &variables); + TestThrowOnFailure(hr, L"Failed to set registration variables."); + hr = PlanSetResumeCommand(&plan, ®istration, &logging); TestThrowOnFailure(hr, L"Failed to set registration resume command."); @@ -339,8 +342,8 @@ namespace Bootstrapper this->ValidateUninstallKeyDisplayName(L"Product1"); registration.detectedRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_FULL; - hr = RegistrationSetVariables(®istration, &variables); - TestThrowOnFailure(hr, L"Failed to set registration variables."); + hr = RegistrationSetDynamicVariables(®istration, &variables); + TestThrowOnFailure(hr, L"Failed to set dynamic registration variables."); Assert::Equal(1ll, VariableGetNumericHelper(&variables, BURN_BUNDLE_INSTALLED)); Assert::Equal(gcnew String(L"foo"), VariableGetStringHelper(&variables, BURN_BUNDLE_TAG)); diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp index 2a5d839a..84e32867 100644 --- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp +++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp @@ -242,6 +242,60 @@ public: // IBootstrapperApplication return hr; } + virtual STDMETHODIMP OnDetectBegin( + __in BOOL fCached, + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType, + __in DWORD cPackages, + __inout BOOL* pfCancel + ) + { + HRESULT hr = S_OK; + BOOL fInstalled = BOOTSTRAPPER_REGISTRATION_TYPE_FULL == registrationType; + + if (m_fPrereq) + { + // Pre-req BA should only show help or do an install (to launch the Managed BA which can then do the right action). + if (BOOTSTRAPPER_ACTION_HELP != m_command.action) + { + m_command.action = BOOTSTRAPPER_ACTION_INSTALL; + } + } + else // maybe modify the action state if the bundle is or is not already installed. + { + if (fInstalled && BOOTSTRAPPER_RESUME_TYPE_REBOOT != m_command.resumeType && BOOTSTRAPPER_ACTION_INSTALL == m_command.action) + { + m_command.action = BOOTSTRAPPER_ACTION_MODIFY; + } + else if (!fInstalled && (BOOTSTRAPPER_ACTION_MODIFY == m_command.action || BOOTSTRAPPER_ACTION_REPAIR == m_command.action)) + { + m_command.action = BOOTSTRAPPER_ACTION_INSTALL; + } + } + + // When resuming from restart doing some install-like operation, try to find the package that forced the + // restart. We'll use this information during planning. + if (BOOTSTRAPPER_RESUME_TYPE_REBOOT == m_command.resumeType && BOOTSTRAPPER_ACTION_UNINSTALL < m_command.action) + { + // Ensure the forced restart package variable is null when it is an empty string. + hr = BalGetStringVariable(L"WixBundleForcedRestartPackage", &m_sczAfterForcedRestartPackage); + if (FAILED(hr) || !m_sczAfterForcedRestartPackage || !*m_sczAfterForcedRestartPackage) + { + ReleaseNullStr(m_sczAfterForcedRestartPackage); + } + + hr = S_OK; + } + + // If the UI should be visible, display it now and hide the splash screen + if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display) + { + ::ShowWindow(m_pTheme->hwndParent, SW_SHOW); + } + + m_pEngine->CloseSplashScreen(); + + return __super::OnDetectBegin(fCached, registrationType, cPackages, pfCancel); + } virtual STDMETHODIMP OnDetectRelatedBundle( __in LPCWSTR wzBundleId, @@ -2123,7 +2177,6 @@ public: //CBalBaseBootstrapperApplication ) { HRESULT hr = S_OK; - LONGLONG llInstalled = 0; hr = __super::Initialize(pCreateArgs); BalExitOnFailure(hr, "CBalBaseBootstrapperApplication initialization failed."); @@ -2132,39 +2185,6 @@ public: //CBalBaseBootstrapperApplication memcpy_s(&m_createArgs, sizeof(m_createArgs), pCreateArgs, sizeof(BOOTSTRAPPER_CREATE_ARGS)); m_createArgs.pCommand = &m_command; - if (m_fPrereq) - { - // Pre-req BA should only show help or do an install (to launch the Managed BA which can then do the right action). - if (BOOTSTRAPPER_ACTION_HELP != m_command.action) - { - m_command.action = BOOTSTRAPPER_ACTION_INSTALL; - } - } - else // maybe modify the action state if the bundle is or is not already installed. - { - hr = BalGetNumericVariable(L"WixBundleInstalled", &llInstalled); - if (SUCCEEDED(hr) && BOOTSTRAPPER_RESUME_TYPE_REBOOT != m_command.resumeType && llInstalled && BOOTSTRAPPER_ACTION_INSTALL == m_command.action) - { - m_command.action = BOOTSTRAPPER_ACTION_MODIFY; - } - else if (!llInstalled && (BOOTSTRAPPER_ACTION_MODIFY == m_command.action || BOOTSTRAPPER_ACTION_REPAIR == m_command.action)) - { - m_command.action = BOOTSTRAPPER_ACTION_INSTALL; - } - } - - // When resuming from restart doing some install-like operation, try to find the package that forced the - // restart. We'll use this information during planning. - if (BOOTSTRAPPER_RESUME_TYPE_REBOOT == m_command.resumeType && BOOTSTRAPPER_ACTION_UNINSTALL < m_command.action) - { - // Ensure the forced restart package variable is null when it is an empty string. - hr = BalGetStringVariable(L"WixBundleForcedRestartPackage", &m_sczAfterForcedRestartPackage); - if (FAILED(hr) || !m_sczAfterForcedRestartPackage || !*m_sczAfterForcedRestartPackage) - { - ReleaseNullStr(m_sczAfterForcedRestartPackage); - } - } - hr = BalGetStringVariable(L"WixBundleVersion", &m_sczBundleVersion); BalExitOnFailure(hr, "CWixStandardBootstrapperApplication initialization failed."); @@ -2320,7 +2340,7 @@ private: BalExitOnFailure(hr, "Failed to read bootstrapper application data."); } - if (BOOTSTRAPPER_ACTION_CACHE == m_plannedAction) + if (m_fRequestedCacheOnly) { if (m_fSupportCacheOnly) { @@ -2335,7 +2355,6 @@ private: else { BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Ignoring attempt to only cache a bundle that does not explicitly support it."); - m_plannedAction = BOOTSTRAPPER_ACTION_UNKNOWN; } } @@ -2385,7 +2404,7 @@ private: } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"cache", -1)) { - m_plannedAction = BOOTSTRAPPER_ACTION_CACHE; + m_fRequestedCacheOnly = TRUE; } else { @@ -3227,14 +3246,6 @@ private: SetState(WIXSTDBA_STATE_DETECTING, hr); - // If the UI should be visible, display it now and hide the splash screen - if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display) - { - ::ShowWindow(m_pTheme->hwndParent, SW_SHOW); - } - - m_pEngine->CloseSplashScreen(); - // Tell the core we're ready for the packages to be processed now. hr = m_pEngine->Detect(); BalExitOnFailure(hr, "Failed to start detecting chain."); @@ -4232,6 +4243,7 @@ public: m_fSuppressDowngradeFailure = FALSE; m_fSuppressRepair = FALSE; m_fSupportCacheOnly = FALSE; + m_fRequestedCacheOnly = FALSE; m_pTaskbarList = NULL; m_uTaskbarButtonCreatedMessage = UINT_MAX; @@ -4536,6 +4548,7 @@ private: BOOL m_fSuppressDowngradeFailure; BOOL m_fSuppressRepair; BOOL m_fSupportCacheOnly; + BOOL m_fRequestedCacheOnly; BOOL m_fPrereq; BOOL m_fPrereqInstalled; diff --git a/src/wix/WixToolset.Core/CompilerCore.cs b/src/wix/WixToolset.Core/CompilerCore.cs index 98bbd19e..dc44f1b6 100644 --- a/src/wix/WixToolset.Core/CompilerCore.cs +++ b/src/wix/WixToolset.Core/CompilerCore.cs @@ -94,6 +94,7 @@ namespace WixToolset.Core "WindowsFolder", "WindowsVolume", "WixBundleAction", + "WixBundleCommandLineAction", "WixBundleForcedRestartPackage", "WixBundleElevated", "WixBundleInstalled", -- cgit v1.2.3-55-g6feb