From 0042e3d4554a0d92e1da6141854b0f1aafa07d5b Mon Sep 17 00:00:00 2001 From: Nir Bar Date: Wed, 11 Aug 2021 15:37:34 -0500 Subject: Allow BA to opt out of MSI transaction. --- src/burn/engine/core.cpp | 25 +++++++++++++++++++++++-- src/burn/engine/engine.mc | 7 +++++++ src/burn/engine/package.cpp | 2 +- src/burn/engine/package.h | 1 + src/burn/engine/plan.cpp | 26 ++++++++++++++++++++++---- src/burn/engine/plan.h | 3 +++ src/burn/engine/userexperience.cpp | 32 +++++++++++++++++++++++++++++++- src/burn/engine/userexperience.h | 5 +++++ 8 files changed, 93 insertions(+), 8 deletions(-) (limited to 'src/burn') diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index 87d748cc..bbd0ff96 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp @@ -79,6 +79,9 @@ static void LogRelatedBundles( __in const BURN_RELATED_BUNDLES* pRelatedBundles, __in BOOL fReverse ); +static void LogRollbackBoundary( + __in const BURN_ROLLBACK_BOUNDARY* pRollbackBoundary + ); // function definitions @@ -2222,6 +2225,8 @@ static void LogPackages( __in const BOOTSTRAPPER_ACTION action ) { + BOOL fUninstalling = BOOTSTRAPPER_ACTION_UNINSTALL == action; + if (pUpgradeBundlePackage) { LogId(REPORT_STANDARD, MSG_PLANNED_UPGRADE_BUNDLE, pUpgradeBundlePackage->sczId, LoggingRequestStateToString(pUpgradeBundlePackage->defaultRequested), LoggingRequestStateToString(pUpgradeBundlePackage->requested), LoggingActionStateToString(pUpgradeBundlePackage->execute), LoggingActionStateToString(pUpgradeBundlePackage->rollback), LoggingDependencyActionToString(pUpgradeBundlePackage->dependencyExecute)); @@ -2233,7 +2238,7 @@ static void LogPackages( else { // Display related bundles first if uninstalling. - if (BOOTSTRAPPER_ACTION_UNINSTALL == action) + if (fUninstalling) { LogRelatedBundles(pRelatedBundles, TRUE); } @@ -2241,9 +2246,18 @@ static void LogPackages( // Display all the packages in the log. for (DWORD i = 0; i < pPackages->cPackages; ++i) { - const DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == action) ? pPackages->cPackages - 1 - i : i; + const DWORD iPackage = fUninstalling ? pPackages->cPackages - 1 - i : i; const BURN_PACKAGE* pPackage = &pPackages->rgPackages[iPackage]; + if (!fUninstalling && pPackage->pRollbackBoundaryForward) + { + LogRollbackBoundary(pPackage->pRollbackBoundaryForward); + } + else if (fUninstalling && pPackage->pRollbackBoundaryBackward) + { + LogRollbackBoundary(pPackage->pRollbackBoundaryBackward); + } + LogId(REPORT_STANDARD, MSG_PLANNED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingCacheTypeToString(pPackage->authoredCacheType), LoggingCacheTypeToString(pPackage->cacheType), LoggingBoolToString(pPackage->fPlannedCache), LoggingBoolToString(pPackage->fPlannedUncache), LoggingDependencyActionToString(pPackage->dependencyExecute), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedInstallRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedCacheRegistrationState)); if (BURN_PACKAGE_TYPE_MSI == pPackage->type) @@ -2313,3 +2327,10 @@ static void LogRelatedBundles( } } } + +static void LogRollbackBoundary( + __in const BURN_ROLLBACK_BOUNDARY* pRollbackBoundary + ) +{ + LogId(REPORT_STANDARD, MSG_PLANNED_ROLLBACK_BOUNDARY, pRollbackBoundary->sczId, LoggingBoolToString(pRollbackBoundary->fVital), LoggingBoolToString(pRollbackBoundary->fTransaction), LoggingBoolToString(pRollbackBoundary->fTransactionAuthored)); +} diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc index f1ecebcd..dcd18074 100644 --- a/src/burn/engine/engine.mc +++ b/src/burn/engine/engine.mc @@ -471,6 +471,13 @@ Language=English Planned slipstreamed patch: %1!ls!, execute: %2!hs!, rollback: %3!hs! . +MessageId=222 +Severity=Success +SymbolicName=MSG_PLANNED_ROLLBACK_BOUNDARY +Language=English +Planned rollback boundary: '%1!ls!', vital: %2!hs!, transaction: %3!hs! (default: %4!hs!) +. + MessageId=299 Severity=Success SymbolicName=MSG_PLAN_COMPLETE diff --git a/src/burn/engine/package.cpp b/src/burn/engine/package.cpp index 0d52d575..cd871bc5 100644 --- a/src/burn/engine/package.cpp +++ b/src/burn/engine/package.cpp @@ -70,7 +70,7 @@ extern "C" HRESULT PackagesParseFromXml( ExitOnFailure(hr, "Failed to get @Vital."); // @Transaction - hr = XmlGetYesNoAttribute(pixnNode, L"Transaction", &pRollbackBoundary->fTransaction); + hr = XmlGetYesNoAttribute(pixnNode, L"Transaction", &pRollbackBoundary->fTransactionAuthored); ExitOnFailure(hr, "Failed to get @Transaction."); // prepare next iteration diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h index f14064db..3d8233d1 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h @@ -192,6 +192,7 @@ typedef struct _BURN_ROLLBACK_BOUNDARY { LPWSTR sczId; BOOL fVital; + BOOL fTransactionAuthored; BOOL fTransaction; BOOL fActiveTransaction; // only valid during Apply. LPWSTR sczLogPath; diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index d78f2846..85d958a6 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp @@ -59,6 +59,9 @@ static HRESULT ProcessPackage( ); static HRESULT ProcessPackageRollbackBoundary( __in BURN_PLAN* pPlan, + __in BURN_USER_EXPERIENCE* pUX, + __in BURN_LOGGING* pLog, + __in BURN_VARIABLES* pVariables, __in_opt BURN_ROLLBACK_BOUNDARY* pEffectiveRollbackBoundary, __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary ); @@ -901,7 +904,7 @@ static HRESULT ProcessPackage( BURN_ROLLBACK_BOUNDARY* pEffectiveRollbackBoundary = NULL; pEffectiveRollbackBoundary = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? pPackage->pRollbackBoundaryBackward : pPackage->pRollbackBoundaryForward; - hr = ProcessPackageRollbackBoundary(pPlan, pEffectiveRollbackBoundary, ppRollbackBoundary); + hr = ProcessPackageRollbackBoundary(pPlan, pUX, pLog, pVariables, pEffectiveRollbackBoundary, ppRollbackBoundary); ExitOnFailure(hr, "Failed to process package rollback boundary."); if (BOOTSTRAPPER_ACTION_LAYOUT == pPlan->action) @@ -952,6 +955,9 @@ LExit: static HRESULT ProcessPackageRollbackBoundary( __in BURN_PLAN* pPlan, + __in BURN_USER_EXPERIENCE* pUX, + __in BURN_LOGGING* pLog, + __in BURN_VARIABLES* pVariables, __in_opt BURN_ROLLBACK_BOUNDARY* pEffectiveRollbackBoundary, __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary ) @@ -969,7 +975,7 @@ static HRESULT ProcessPackageRollbackBoundary( } // Start new rollback boundary. - hr = PlanRollbackBoundaryBegin(pPlan, pEffectiveRollbackBoundary); + hr = PlanRollbackBoundaryBegin(pPlan, pUX, pLog, pVariables, pEffectiveRollbackBoundary); ExitOnFailure(hr, "Failed to plan rollback boundary begin."); *ppRollbackBoundary = pEffectiveRollbackBoundary; @@ -1702,6 +1708,9 @@ LExit: extern "C" HRESULT PlanRollbackBoundaryBegin( __in BURN_PLAN* pPlan, + __in BURN_USER_EXPERIENCE* pUX, + __in BURN_LOGGING* /*pLog*/, + __in BURN_VARIABLES* /*pVariables*/, __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary ) { @@ -1725,9 +1734,17 @@ extern "C" HRESULT PlanRollbackBoundaryBegin( pExecuteAction->type = BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY; pExecuteAction->rollbackBoundary.pRollbackBoundary = pRollbackBoundary; - // Add begin MSI transaction to execute plan. - if (pRollbackBoundary->fTransaction) + hr = UserExperienceOnPlanRollbackBoundary(pUX, pRollbackBoundary->sczId, &pRollbackBoundary->fTransaction); + ExitOnRootFailure(hr, "BA aborted plan rollback boundary."); + + // Only use MSI transaction if authored and the BA requested it. + if (!pRollbackBoundary->fTransactionAuthored || !pRollbackBoundary->fTransaction) + { + pRollbackBoundary->fTransaction = FALSE; + } + else { + // Add begin MSI transaction to execute plan. hr = PlanExecuteCheckpoint(pPlan); ExitOnFailure(hr, "Failed to append checkpoint before MSI transaction begin action."); @@ -1925,6 +1942,7 @@ static void ResetPlannedRollbackBoundaryState( ) { pRollbackBoundary->fActiveTransaction = FALSE; + pRollbackBoundary->fTransaction = pRollbackBoundary->fTransactionAuthored; ReleaseNullStr(pRollbackBoundary->sczLogPath); } diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h index b148c75b..b8bb8c3d 100644 --- a/src/burn/engine/plan.h +++ b/src/burn/engine/plan.h @@ -438,6 +438,9 @@ HRESULT PlanAppendRollbackAction( ); HRESULT PlanRollbackBoundaryBegin( __in BURN_PLAN* pPlan, + __in BURN_USER_EXPERIENCE* pUX, + __in BURN_LOGGING* pLog, + __in BURN_VARIABLES* pVariables, __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary ); HRESULT PlanRollbackBoundaryComplete( diff --git a/src/burn/engine/userexperience.cpp b/src/burn/engine/userexperience.cpp index f48e60de..c974f4d4 100644 --- a/src/burn/engine/userexperience.cpp +++ b/src/burn/engine/userexperience.cpp @@ -104,7 +104,7 @@ extern "C" HRESULT UserExperienceLoad( args.pCommand = pCommand; args.pfnBootstrapperEngineProc = EngineForApplicationProc; args.pvBootstrapperEngineProcContext = pEngineContext; - args.qwEngineAPIVersion = MAKEQWORDVERSION(2021, 4, 27, 0); + args.qwEngineAPIVersion = MAKEQWORDVERSION(2021, 8, 10, 0); results.cbSize = sizeof(BOOTSTRAPPER_CREATE_RESULTS); @@ -2056,6 +2056,36 @@ LExit: return hr; } +EXTERN_C BAAPI UserExperienceOnPlanRollbackBoundary( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzRollbackBoundaryId, + __inout BOOL* pfTransaction + ) +{ + HRESULT hr = S_OK; + BA_ONPLANROLLBACKBOUNDARY_ARGS args = { }; + BA_ONPLANROLLBACKBOUNDARY_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.wzRollbackBoundaryId = wzRollbackBoundaryId; + args.fRecommendedTransaction = *pfTransaction; + + results.cbSize = sizeof(results); + results.fTransaction = *pfTransaction; + + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANROLLBACKBOUNDARY, &args, &results); + ExitOnFailure(hr, "BA OnPlanRollbackBoundary failed."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + *pfTransaction = results.fTransaction; + +LExit: + return hr; +} + EXTERN_C BAAPI UserExperienceOnPlanPatchTarget( __in BURN_USER_EXPERIENCE* pUserExperience, __in_z LPCWSTR wzPackageId, diff --git a/src/burn/engine/userexperience.h b/src/burn/engine/userexperience.h index aaf69083..c2219f7e 100644 --- a/src/burn/engine/userexperience.h +++ b/src/burn/engine/userexperience.h @@ -470,6 +470,11 @@ BAAPI UserExperienceOnPlanRelatedBundle( __in_z LPCWSTR wzBundleId, __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState ); +BAAPI UserExperienceOnPlanRollbackBoundary( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzRollbackBoundaryId, + __inout BOOL *pfTransaction + ); BAAPI UserExperienceOnPlanPatchTarget( __in BURN_USER_EXPERIENCE* pUserExperience, __in_z LPCWSTR wzPackageId, -- cgit v1.2.3-55-g6feb