diff options
Diffstat (limited to 'src')
31 files changed, 515 insertions, 28 deletions
diff --git a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h index 659901be..5c6258d0 100644 --- a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h +++ b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h | |||
| @@ -209,6 +209,7 @@ enum BOOTSTRAPPER_APPLICATION_MESSAGE | |||
| 209 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN, | 209 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN, |
| 210 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, | 210 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, |
| 211 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE, | 211 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE, |
| 212 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRESTORERELATEDBUNDLE, | ||
| 212 | }; | 213 | }; |
| 213 | 214 | ||
| 214 | enum BOOTSTRAPPER_APPLYCOMPLETE_ACTION | 215 | enum BOOTSTRAPPER_APPLYCOMPLETE_ACTION |
| @@ -1208,6 +1209,20 @@ struct BA_ONPLANRELATEDBUNDLE_RESULTS | |||
| 1208 | BOOTSTRAPPER_REQUEST_STATE requestedState; | 1209 | BOOTSTRAPPER_REQUEST_STATE requestedState; |
| 1209 | }; | 1210 | }; |
| 1210 | 1211 | ||
| 1212 | struct BA_ONPLANRESTORERELATEDBUNDLE_ARGS | ||
| 1213 | { | ||
| 1214 | DWORD cbSize; | ||
| 1215 | LPCWSTR wzBundleId; | ||
| 1216 | BOOTSTRAPPER_REQUEST_STATE recommendedState; | ||
| 1217 | }; | ||
| 1218 | |||
| 1219 | struct BA_ONPLANRESTORERELATEDBUNDLE_RESULTS | ||
| 1220 | { | ||
| 1221 | DWORD cbSize; | ||
| 1222 | BOOL fCancel; | ||
| 1223 | BOOTSTRAPPER_REQUEST_STATE requestedState; | ||
| 1224 | }; | ||
| 1225 | |||
| 1211 | struct BA_ONPLANROLLBACKBOUNDARY_ARGS | 1226 | struct BA_ONPLANROLLBACKBOUNDARY_ARGS |
| 1212 | { | 1227 | { |
| 1213 | DWORD cbSize; | 1228 | DWORD cbSize; |
diff --git a/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs b/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs index f277425e..b08e66c0 100644 --- a/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs +++ b/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs | |||
| @@ -271,6 +271,9 @@ namespace WixToolset.Mba.Core | |||
| 271 | /// <inheritdoc/> | 271 | /// <inheritdoc/> |
| 272 | public event EventHandler<SetUpdateCompleteEventArgs> SetUpdateComplete; | 272 | public event EventHandler<SetUpdateCompleteEventArgs> SetUpdateComplete; |
| 273 | 273 | ||
| 274 | /// <inheritdoc/> | ||
| 275 | public event EventHandler<PlanRestoreRelatedBundleEventArgs> PlanRestoreRelatedBundle; | ||
| 276 | |||
| 274 | /// <summary> | 277 | /// <summary> |
| 275 | /// Entry point that is called when the bootstrapper application is ready to run. | 278 | /// Entry point that is called when the bootstrapper application is ready to run. |
| 276 | /// </summary> | 279 | /// </summary> |
| @@ -1321,6 +1324,19 @@ namespace WixToolset.Mba.Core | |||
| 1321 | } | 1324 | } |
| 1322 | } | 1325 | } |
| 1323 | 1326 | ||
| 1327 | /// <summary> | ||
| 1328 | /// Called by the engine, raises the <see cref="PlanRestoreRelatedBundle"/> event. | ||
| 1329 | /// </summary> | ||
| 1330 | /// <param name="args">Additional arguments for this event.</param> | ||
| 1331 | protected virtual void OnPlanRestoreRelatedBundle(PlanRestoreRelatedBundleEventArgs args) | ||
| 1332 | { | ||
| 1333 | EventHandler<PlanRestoreRelatedBundleEventArgs> handler = this.PlanRestoreRelatedBundle; | ||
| 1334 | if (null != handler) | ||
| 1335 | { | ||
| 1336 | handler(this, args); | ||
| 1337 | } | ||
| 1338 | } | ||
| 1339 | |||
| 1324 | #region IBootstrapperApplication Members | 1340 | #region IBootstrapperApplication Members |
| 1325 | 1341 | ||
| 1326 | int IBootstrapperApplication.BAProc(int message, IntPtr pvArgs, IntPtr pvResults, IntPtr pvContext) | 1342 | int IBootstrapperApplication.BAProc(int message, IntPtr pvArgs, IntPtr pvResults, IntPtr pvContext) |
| @@ -2042,6 +2058,16 @@ namespace WixToolset.Mba.Core | |||
| 2042 | return args.HResult; | 2058 | return args.HResult; |
| 2043 | } | 2059 | } |
| 2044 | 2060 | ||
| 2061 | int IBootstrapperApplication.OnPlanRestoreRelatedBundle(string wzBundleId, RequestState recommendedState, ref RequestState pRequestedState, ref bool fCancel) | ||
| 2062 | { | ||
| 2063 | PlanRestoreRelatedBundleEventArgs args = new PlanRestoreRelatedBundleEventArgs(wzBundleId, recommendedState, pRequestedState, fCancel); | ||
| 2064 | this.OnPlanRestoreRelatedBundle(args); | ||
| 2065 | |||
| 2066 | pRequestedState = args.State; | ||
| 2067 | fCancel = args.Cancel; | ||
| 2068 | return args.HResult; | ||
| 2069 | } | ||
| 2070 | |||
| 2045 | #endregion | 2071 | #endregion |
| 2046 | } | 2072 | } |
| 2047 | } | 2073 | } |
diff --git a/src/api/burn/WixToolset.Mba.Core/EventArgs.cs b/src/api/burn/WixToolset.Mba.Core/EventArgs.cs index d4d70651..2e1e1be3 100644 --- a/src/api/burn/WixToolset.Mba.Core/EventArgs.cs +++ b/src/api/burn/WixToolset.Mba.Core/EventArgs.cs | |||
| @@ -2402,4 +2402,35 @@ namespace WixToolset.Mba.Core | |||
| 2402 | /// </summary> | 2402 | /// </summary> |
| 2403 | public string NewPackageId { get; private set; } | 2403 | public string NewPackageId { get; private set; } |
| 2404 | } | 2404 | } |
| 2405 | |||
| 2406 | /// <summary> | ||
| 2407 | /// Event arguments for <see cref="IDefaultBootstrapperApplication.PlanRestoreRelatedBundle"/> | ||
| 2408 | /// </summary> | ||
| 2409 | [Serializable] | ||
| 2410 | public class PlanRestoreRelatedBundleEventArgs : CancellableHResultEventArgs | ||
| 2411 | { | ||
| 2412 | /// <summary /> | ||
| 2413 | public PlanRestoreRelatedBundleEventArgs(string bundleId, RequestState recommendedState, RequestState state, bool cancelRecommendation) | ||
| 2414 | : base(cancelRecommendation) | ||
| 2415 | { | ||
| 2416 | this.BundleId = bundleId; | ||
| 2417 | this.RecommendedState = recommendedState; | ||
| 2418 | this.State = state; | ||
| 2419 | } | ||
| 2420 | |||
| 2421 | /// <summary> | ||
| 2422 | /// Gets the identity of the bundle to plan for. | ||
| 2423 | /// </summary> | ||
| 2424 | public string BundleId { get; private set; } | ||
| 2425 | |||
| 2426 | /// <summary> | ||
| 2427 | /// Gets the recommended requested state for the bundle. | ||
| 2428 | /// </summary> | ||
| 2429 | public RequestState RecommendedState { get; private set; } | ||
| 2430 | |||
| 2431 | /// <summary> | ||
| 2432 | /// Gets or sets the requested state for the bundle. | ||
| 2433 | /// </summary> | ||
| 2434 | public RequestState State { get; set; } | ||
| 2435 | } | ||
| 2405 | } | 2436 | } |
diff --git a/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs b/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs index 05f96106..4fbe5e18 100644 --- a/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs +++ b/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs | |||
| @@ -1136,6 +1136,18 @@ namespace WixToolset.Mba.Core | |||
| 1136 | [MarshalAs(UnmanagedType.LPWStr)] string wzPreviousPackageId, | 1136 | [MarshalAs(UnmanagedType.LPWStr)] string wzPreviousPackageId, |
| 1137 | [MarshalAs(UnmanagedType.LPWStr)] string wzNewPackageId | 1137 | [MarshalAs(UnmanagedType.LPWStr)] string wzNewPackageId |
| 1138 | ); | 1138 | ); |
| 1139 | |||
| 1140 | /// <summary> | ||
| 1141 | /// See <see cref="IDefaultBootstrapperApplication.PlanRestoreRelatedBundle"/>. | ||
| 1142 | /// </summary> | ||
| 1143 | [PreserveSig] | ||
| 1144 | [return: MarshalAs(UnmanagedType.I4)] | ||
| 1145 | int OnPlanRestoreRelatedBundle( | ||
| 1146 | [MarshalAs(UnmanagedType.LPWStr)] string wzBundleId, | ||
| 1147 | [MarshalAs(UnmanagedType.U4)] RequestState recommendedState, | ||
| 1148 | [MarshalAs(UnmanagedType.U4)] ref RequestState pRequestedState, | ||
| 1149 | [MarshalAs(UnmanagedType.Bool)] ref bool fCancel | ||
| 1150 | ); | ||
| 1139 | } | 1151 | } |
| 1140 | 1152 | ||
| 1141 | /// <summary> | 1153 | /// <summary> |
diff --git a/src/api/burn/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs b/src/api/burn/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs index ce06408e..c237cb9d 100644 --- a/src/api/burn/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs +++ b/src/api/burn/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs | |||
| @@ -334,6 +334,11 @@ namespace WixToolset.Mba.Core | |||
| 334 | event EventHandler<PlanRelatedBundleEventArgs> PlanRelatedBundle; | 334 | event EventHandler<PlanRelatedBundleEventArgs> PlanRelatedBundle; |
| 335 | 335 | ||
| 336 | /// <summary> | 336 | /// <summary> |
| 337 | /// Fired when the engine has begun planning an upgrade related bundle for restoring in case of failure. | ||
| 338 | /// </summary> | ||
| 339 | event EventHandler<PlanRestoreRelatedBundleEventArgs> PlanRestoreRelatedBundle; | ||
| 340 | |||
| 341 | /// <summary> | ||
| 337 | /// Fired when the engine is planning a rollback boundary. | 342 | /// Fired when the engine is planning a rollback boundary. |
| 338 | /// </summary> | 343 | /// </summary> |
| 339 | event EventHandler<PlanRollbackBoundaryEventArgs> PlanRollbackBoundary; | 344 | event EventHandler<PlanRollbackBoundaryEventArgs> PlanRollbackBoundary; |
diff --git a/src/api/burn/balutil/inc/BAFunctions.h b/src/api/burn/balutil/inc/BAFunctions.h index 84359d65..cbef88df 100644 --- a/src/api/burn/balutil/inc/BAFunctions.h +++ b/src/api/burn/balutil/inc/BAFunctions.h | |||
| @@ -88,6 +88,7 @@ enum BA_FUNCTIONS_MESSAGE | |||
| 88 | BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN, | 88 | BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN, |
| 89 | BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, | 89 | BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, |
| 90 | BA_FUNCTIONS_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE, | 90 | BA_FUNCTIONS_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE, |
| 91 | BA_FUNCTIONS_MESSAGE_ONPLANRESTORERELATEDBUNDLE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRESTORERELATEDBUNDLE, | ||
| 91 | 92 | ||
| 92 | BA_FUNCTIONS_MESSAGE_ONTHEMELOADED = 1024, | 93 | BA_FUNCTIONS_MESSAGE_ONTHEMELOADED = 1024, |
| 93 | BA_FUNCTIONS_MESSAGE_WNDPROC, | 94 | BA_FUNCTIONS_MESSAGE_WNDPROC, |
diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctions.h b/src/api/burn/balutil/inc/BalBaseBAFunctions.h index c6d0924f..e98ebc9f 100644 --- a/src/api/burn/balutil/inc/BalBaseBAFunctions.h +++ b/src/api/burn/balutil/inc/BalBaseBAFunctions.h | |||
| @@ -849,6 +849,16 @@ public: // IBootstrapperApplication | |||
| 849 | return S_OK; | 849 | return S_OK; |
| 850 | } | 850 | } |
| 851 | 851 | ||
| 852 | virtual STDMETHODIMP OnPlanRestoreRelatedBundle( | ||
| 853 | __in_z LPCWSTR /*wzBundleId*/, | ||
| 854 | __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/, | ||
| 855 | __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestedState*/, | ||
| 856 | __inout BOOL* /*pfCancel*/ | ||
| 857 | ) | ||
| 858 | { | ||
| 859 | return S_OK; | ||
| 860 | } | ||
| 861 | |||
| 852 | public: // IBAFunctions | 862 | public: // IBAFunctions |
| 853 | virtual STDMETHODIMP OnPlan( | 863 | virtual STDMETHODIMP OnPlan( |
| 854 | ) | 864 | ) |
diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h b/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h index 5d5ff098..09cc189e 100644 --- a/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h +++ b/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h | |||
| @@ -159,6 +159,7 @@ static HRESULT WINAPI BalBaseBAFunctionsProc( | |||
| 159 | case BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN: | 159 | case BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN: |
| 160 | case BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE: | 160 | case BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE: |
| 161 | case BA_FUNCTIONS_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE: | 161 | case BA_FUNCTIONS_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE: |
| 162 | case BA_FUNCTIONS_MESSAGE_ONPLANRESTORERELATEDBUNDLE: | ||
| 162 | hr = BalBaseBootstrapperApplicationProc((BOOTSTRAPPER_APPLICATION_MESSAGE)message, pvArgs, pvResults, pvContext); | 163 | hr = BalBaseBootstrapperApplicationProc((BOOTSTRAPPER_APPLICATION_MESSAGE)message, pvArgs, pvResults, pvContext); |
| 163 | break; | 164 | break; |
| 164 | case BA_FUNCTIONS_MESSAGE_ONTHEMELOADED: | 165 | case BA_FUNCTIONS_MESSAGE_ONTHEMELOADED: |
diff --git a/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h b/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h index e1a36fdf..6a24f24b 100644 --- a/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h +++ b/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h | |||
| @@ -1047,6 +1047,17 @@ public: // IBootstrapperApplication | |||
| 1047 | return S_OK; | 1047 | return S_OK; |
| 1048 | } | 1048 | } |
| 1049 | 1049 | ||
| 1050 | virtual STDMETHODIMP OnPlanRestoreRelatedBundle( | ||
| 1051 | __in_z LPCWSTR /*wzBundleId*/, | ||
| 1052 | __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/, | ||
| 1053 | __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestedState*/, | ||
| 1054 | __inout BOOL* pfCancel | ||
| 1055 | ) | ||
| 1056 | { | ||
| 1057 | *pfCancel |= CheckCanceled(); | ||
| 1058 | return S_OK; | ||
| 1059 | } | ||
| 1060 | |||
| 1050 | public: //CBalBaseBootstrapperApplication | 1061 | public: //CBalBaseBootstrapperApplication |
| 1051 | virtual STDMETHODIMP Initialize( | 1062 | virtual STDMETHODIMP Initialize( |
| 1052 | __in const BOOTSTRAPPER_CREATE_ARGS* pCreateArgs | 1063 | __in const BOOTSTRAPPER_CREATE_ARGS* pCreateArgs |
diff --git a/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h b/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h index 1ee5258e..d40390e5 100644 --- a/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h +++ b/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h | |||
| @@ -720,6 +720,15 @@ static HRESULT BalBaseBAProcOnSetUpdateComplete( | |||
| 720 | return pBA->OnSetUpdateComplete(pArgs->hrStatus, pArgs->wzPreviousPackageId, pArgs->wzNewPackageId); | 720 | return pBA->OnSetUpdateComplete(pArgs->hrStatus, pArgs->wzPreviousPackageId, pArgs->wzNewPackageId); |
| 721 | } | 721 | } |
| 722 | 722 | ||
| 723 | static HRESULT BalBaseBAProcOnPlanRestoreRelatedBundle( | ||
| 724 | __in IBootstrapperApplication* pBA, | ||
| 725 | __in BA_ONPLANRESTORERELATEDBUNDLE_ARGS* pArgs, | ||
| 726 | __inout BA_ONPLANRESTORERELATEDBUNDLE_RESULTS* pResults | ||
| 727 | ) | ||
| 728 | { | ||
| 729 | return pBA->OnPlanRestoreRelatedBundle(pArgs->wzBundleId, pArgs->recommendedState, &pResults->requestedState, &pResults->fCancel); | ||
| 730 | } | ||
| 731 | |||
| 723 | /******************************************************************* | 732 | /******************************************************************* |
| 724 | BalBaseBootstrapperApplicationProc - requires pvContext to be of type IBootstrapperApplication. | 733 | BalBaseBootstrapperApplicationProc - requires pvContext to be of type IBootstrapperApplication. |
| 725 | Provides a default mapping between the new message based BA interface and | 734 | Provides a default mapping between the new message based BA interface and |
| @@ -976,6 +985,9 @@ static HRESULT WINAPI BalBaseBootstrapperApplicationProc( | |||
| 976 | case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE: | 985 | case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE: |
| 977 | hr = BalBaseBAProcOnPlannedCompatiblePackage(pBA, reinterpret_cast<BA_ONPLANNEDCOMPATIBLEPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANNEDCOMPATIBLEPACKAGE_RESULTS*>(pvResults)); | 986 | hr = BalBaseBAProcOnPlannedCompatiblePackage(pBA, reinterpret_cast<BA_ONPLANNEDCOMPATIBLEPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANNEDCOMPATIBLEPACKAGE_RESULTS*>(pvResults)); |
| 978 | break; | 987 | break; |
| 988 | case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRESTORERELATEDBUNDLE: | ||
| 989 | hr = BalBaseBAProcOnPlanRestoreRelatedBundle(pBA, reinterpret_cast<BA_ONPLANRESTORERELATEDBUNDLE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANRESTORERELATEDBUNDLE_RESULTS*>(pvResults)); | ||
| 990 | break; | ||
| 979 | } | 991 | } |
| 980 | } | 992 | } |
| 981 | 993 | ||
diff --git a/src/api/burn/balutil/inc/IBootstrapperApplication.h b/src/api/burn/balutil/inc/IBootstrapperApplication.h index 640f609d..5932c06e 100644 --- a/src/api/burn/balutil/inc/IBootstrapperApplication.h +++ b/src/api/burn/balutil/inc/IBootstrapperApplication.h | |||
| @@ -691,4 +691,12 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A | |||
| 691 | __in_z_opt LPCWSTR wzPreviousPackageId, | 691 | __in_z_opt LPCWSTR wzPreviousPackageId, |
| 692 | __in_z_opt LPCWSTR wzNewPackageId | 692 | __in_z_opt LPCWSTR wzNewPackageId |
| 693 | ) = 0; | 693 | ) = 0; |
| 694 | |||
| 695 | // OnPlanRestoreRelatedBundle - called when the engine begins planning an upgrade related bundle for restoring in case of failure. | ||
| 696 | STDMETHOD(OnPlanRestoreRelatedBundle)( | ||
| 697 | __in_z LPCWSTR wzBundleId, | ||
| 698 | __in BOOTSTRAPPER_REQUEST_STATE recommendedState, | ||
| 699 | __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState, | ||
| 700 | __inout BOOL* pfCancel | ||
| 701 | ) = 0; | ||
| 694 | }; | 702 | }; |
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp index 5cc63d02..73f8fc72 100644 --- a/src/burn/engine/apply.cpp +++ b/src/burn/engine/apply.cpp | |||
| @@ -210,6 +210,11 @@ static HRESULT ExecuteRelatedBundle( | |||
| 210 | __out BOOL* pfSuspend, | 210 | __out BOOL* pfSuspend, |
| 211 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | 211 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart |
| 212 | ); | 212 | ); |
| 213 | static HRESULT DoRestoreRelatedBundleActions( | ||
| 214 | __in BURN_ENGINE_STATE* pEngineState, | ||
| 215 | __in BURN_EXECUTE_CONTEXT* pContext, | ||
| 216 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
| 217 | ); | ||
| 213 | static HRESULT ExecuteExePackage( | 218 | static HRESULT ExecuteExePackage( |
| 214 | __in BURN_ENGINE_STATE* pEngineState, | 219 | __in BURN_ENGINE_STATE* pEngineState, |
| 215 | __in BURN_EXECUTE_ACTION* pExecuteAction, | 220 | __in BURN_EXECUTE_ACTION* pExecuteAction, |
| @@ -788,6 +793,9 @@ extern "C" HRESULT ApplyExecute( | |||
| 788 | { | 793 | { |
| 789 | if (pCheckpoint->pActiveRollbackBoundary->fVital) | 794 | if (pCheckpoint->pActiveRollbackBoundary->fVital) |
| 790 | { | 795 | { |
| 796 | hrRollback = DoRestoreRelatedBundleActions(pEngineState, &context, pRestart); | ||
| 797 | IgnoreRollbackError(hrRollback, "Failed rollback actions"); | ||
| 798 | |||
| 791 | // If the rollback boundary is vital, end execution here. | 799 | // If the rollback boundary is vital, end execution here. |
| 792 | break; | 800 | break; |
| 793 | } | 801 | } |
| @@ -2590,6 +2598,48 @@ LExit: | |||
| 2590 | return hr; | 2598 | return hr; |
| 2591 | } | 2599 | } |
| 2592 | 2600 | ||
| 2601 | static HRESULT DoRestoreRelatedBundleActions( | ||
| 2602 | __in BURN_ENGINE_STATE* pEngineState, | ||
| 2603 | __in BURN_EXECUTE_CONTEXT* pContext, | ||
| 2604 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
| 2605 | ) | ||
| 2606 | { | ||
| 2607 | HRESULT hr = S_OK; | ||
| 2608 | BOOL fRetryIgnored = FALSE; | ||
| 2609 | BOOL fSuspendIgnored = FALSE; | ||
| 2610 | |||
| 2611 | // execute restore related bundle actions | ||
| 2612 | for (DWORD i = 0; i < pEngineState->plan.cRestoreRelatedBundleActions; ++i) | ||
| 2613 | { | ||
| 2614 | BURN_EXECUTE_ACTION* pRestoreRelatedBundleAction = &pEngineState->plan.rgRestoreRelatedBundleActions[i]; | ||
| 2615 | if (pRestoreRelatedBundleAction->fDeleted) | ||
| 2616 | { | ||
| 2617 | continue; | ||
| 2618 | } | ||
| 2619 | |||
| 2620 | BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE; | ||
| 2621 | switch (pRestoreRelatedBundleAction->type) | ||
| 2622 | { | ||
| 2623 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: | ||
| 2624 | hr = ExecuteRelatedBundle(pEngineState, pRestoreRelatedBundleAction, pContext, TRUE, &fRetryIgnored, &fSuspendIgnored, &restart); | ||
| 2625 | IgnoreRollbackError(hr, "Failed to restore related bundle package."); | ||
| 2626 | break; | ||
| 2627 | |||
| 2628 | default: | ||
| 2629 | hr = E_UNEXPECTED; | ||
| 2630 | ExitOnFailure(hr, "Invalid restore related bundle action: %d.", pRestoreRelatedBundleAction->type); | ||
| 2631 | } | ||
| 2632 | |||
| 2633 | if (*pRestart < restart) | ||
| 2634 | { | ||
| 2635 | *pRestart = restart; | ||
| 2636 | } | ||
| 2637 | } | ||
| 2638 | |||
| 2639 | LExit: | ||
| 2640 | return hr; | ||
| 2641 | } | ||
| 2642 | |||
| 2593 | static HRESULT ExecuteExePackage( | 2643 | static HRESULT ExecuteExePackage( |
| 2594 | __in BURN_ENGINE_STATE* pEngineState, | 2644 | __in BURN_ENGINE_STATE* pEngineState, |
| 2595 | __in BURN_EXECUTE_ACTION* pExecuteAction, | 2645 | __in BURN_EXECUTE_ACTION* pExecuteAction, |
diff --git a/src/burn/engine/bundlepackageengine.cpp b/src/burn/engine/bundlepackageengine.cpp index cd84601f..b5fc51e5 100644 --- a/src/burn/engine/bundlepackageengine.cpp +++ b/src/burn/engine/bundlepackageengine.cpp | |||
| @@ -51,7 +51,7 @@ extern "C" HRESULT BundlePackageEnginePlanCalculatePackage( | |||
| 51 | execute = BOOTSTRAPPER_ACTION_STATE_NONE; | 51 | execute = BOOTSTRAPPER_ACTION_STATE_NONE; |
| 52 | break; | 52 | break; |
| 53 | case BOOTSTRAPPER_REQUEST_STATE_REPAIR: | 53 | case BOOTSTRAPPER_REQUEST_STATE_REPAIR: |
| 54 | execute = pPackage->Bundle.fRepairable ? BOOTSTRAPPER_ACTION_STATE_REPAIR : BOOTSTRAPPER_ACTION_STATE_NONE; | 54 | execute = BOOTSTRAPPER_ACTION_STATE_REPAIR; |
| 55 | break; | 55 | break; |
| 56 | case BOOTSTRAPPER_REQUEST_STATE_ABSENT: __fallthrough; | 56 | case BOOTSTRAPPER_REQUEST_STATE_ABSENT: __fallthrough; |
| 57 | case BOOTSTRAPPER_REQUEST_STATE_CACHE: | 57 | case BOOTSTRAPPER_REQUEST_STATE_CACHE: |
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index 7f7a915e..8fac7bd0 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp | |||
| @@ -558,7 +558,7 @@ extern "C" HRESULT CorePlan( | |||
| 558 | ExitOnFailure(hr, "Failed to plan packages."); | 558 | ExitOnFailure(hr, "Failed to plan packages."); |
| 559 | 559 | ||
| 560 | // Schedule the update of related bundles last. | 560 | // Schedule the update of related bundles last. |
| 561 | hr = PlanRelatedBundlesComplete(&pEngineState->registration, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, dwExecuteActionEarlyIndex); | 561 | hr = PlanRelatedBundlesComplete(&pEngineState->userExperience, &pEngineState->registration, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, dwExecuteActionEarlyIndex); |
| 562 | ExitOnFailure(hr, "Failed to schedule related bundles."); | 562 | ExitOnFailure(hr, "Failed to schedule related bundles."); |
| 563 | } | 563 | } |
| 564 | } | 564 | } |
| @@ -2309,7 +2309,7 @@ static void LogRelatedBundles( | |||
| 2309 | 2309 | ||
| 2310 | if (pRelatedBundle->fPlannable) | 2310 | if (pRelatedBundle->fPlannable) |
| 2311 | { | 2311 | { |
| 2312 | LogId(REPORT_STANDARD, MSG_PLANNED_RELATED_BUNDLE, pPackage->sczId, LoggingRelationTypeToString(pRelatedBundle->relationType), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingDependencyActionToString(pPackage->dependencyExecute)); | 2312 | LogId(REPORT_STANDARD, MSG_PLANNED_RELATED_BUNDLE, pPackage->sczId, LoggingRelationTypeToString(pRelatedBundle->relationType), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingRequestStateToString(pRelatedBundle->defaultRequestedRestore), LoggingRequestStateToString(pRelatedBundle->requestedRestore), LoggingActionStateToString(pRelatedBundle->restore), LoggingDependencyActionToString(pPackage->dependencyExecute)); |
| 2313 | } | 2313 | } |
| 2314 | } | 2314 | } |
| 2315 | } | 2315 | } |
diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc index b8c9a2d3..675a5644 100644 --- a/src/burn/engine/engine.mc +++ b/src/burn/engine/engine.mc | |||
| @@ -352,13 +352,6 @@ Language=English | |||
| 352 | Planned package: %1!ls!, state: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute: %5!hs!, rollback: %6!hs!, default cache strategy: %7!hs!, ba requested strategy: %8!hs!, cache: %9!hs!, uncache: %10!hs!, dependency: %11!hs!, expected install registration state: %12!hs!, expected cache registration state: %13!hs! | 352 | Planned package: %1!ls!, state: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute: %5!hs!, rollback: %6!hs!, default cache strategy: %7!hs!, ba requested strategy: %8!hs!, cache: %9!hs!, uncache: %10!hs!, dependency: %11!hs!, expected install registration state: %12!hs!, expected cache registration state: %13!hs! |
| 353 | . | 353 | . |
| 354 | 354 | ||
| 355 | MessageId=202 | ||
| 356 | Severity=Success | ||
| 357 | SymbolicName=MSG_PLANNED_BUNDLE_UX_CHANGED_REQUEST | ||
| 358 | Language=English | ||
| 359 | Planned bundle: %1!ls!, ba requested state: %2!hs! over default: %3!hs! | ||
| 360 | . | ||
| 361 | |||
| 362 | MessageId=203 | 355 | MessageId=203 |
| 363 | Severity=Success | 356 | Severity=Success |
| 364 | SymbolicName=MSG_PLANNED_MSI_FEATURE | 357 | SymbolicName=MSG_PLANNED_MSI_FEATURE |
| @@ -391,7 +384,7 @@ MessageId=207 | |||
| 391 | Severity=Success | 384 | Severity=Success |
| 392 | SymbolicName=MSG_PLANNED_RELATED_BUNDLE | 385 | SymbolicName=MSG_PLANNED_RELATED_BUNDLE |
| 393 | Language=English | 386 | Language=English |
| 394 | Planned related bundle: %1!ls!, type: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute: %5!hs!, rollback: %6!hs!, dependency: %7!hs! | 387 | Planned related bundle: %1!ls!, type: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute: %5!hs!, rollback: %6!hs!, default requested restore: %7!hs!, ba requested restore: %8!hs!, restore: %9!hs!, dependency: %10!hs! |
| 395 | . | 388 | . |
| 396 | 389 | ||
| 397 | MessageId=208 | 390 | MessageId=208 |
diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h index 6d1b5dd9..1e61d92b 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h | |||
| @@ -309,7 +309,6 @@ typedef struct _BURN_PACKAGE | |||
| 309 | LPCWSTR wzAncestors; // points directly into engine state. | 309 | LPCWSTR wzAncestors; // points directly into engine state. |
| 310 | LPCWSTR wzEngineWorkingDirectory; // points directly into engine state. | 310 | LPCWSTR wzEngineWorkingDirectory; // points directly into engine state. |
| 311 | 311 | ||
| 312 | BOOL fRepairable; | ||
| 313 | BOOL fSupportsBurnProtocol; | 312 | BOOL fSupportsBurnProtocol; |
| 314 | 313 | ||
| 315 | BURN_EXE_EXIT_CODE* rgExitCodes; | 314 | BURN_EXE_EXIT_CODE* rgExitCodes; |
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index f850d49c..f1fb87b8 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp | |||
| @@ -103,6 +103,10 @@ static HRESULT AppendCleanAction( | |||
| 103 | __in BURN_PLAN* pPlan, | 103 | __in BURN_PLAN* pPlan, |
| 104 | __out BURN_CLEAN_ACTION** ppCleanAction | 104 | __out BURN_CLEAN_ACTION** ppCleanAction |
| 105 | ); | 105 | ); |
| 106 | static HRESULT AppendRestoreRelatedBundleAction( | ||
| 107 | __in BURN_PLAN* pPlan, | ||
| 108 | __out BURN_EXECUTE_ACTION** ppExecuteAction | ||
| 109 | ); | ||
| 106 | static HRESULT ProcessPayloadGroup( | 110 | static HRESULT ProcessPayloadGroup( |
| 107 | __in BURN_PLAN* pPlan, | 111 | __in BURN_PLAN* pPlan, |
| 108 | __in BURN_PAYLOAD_GROUP* pPayloadGroup | 112 | __in BURN_PAYLOAD_GROUP* pPayloadGroup |
| @@ -196,6 +200,15 @@ extern "C" void PlanReset( | |||
| 196 | MemFree(pPlan->rgRollbackActions); | 200 | MemFree(pPlan->rgRollbackActions); |
| 197 | } | 201 | } |
| 198 | 202 | ||
| 203 | if (pPlan->rgRestoreRelatedBundleActions) | ||
| 204 | { | ||
| 205 | for (DWORD i = 0; i < pPlan->cRestoreRelatedBundleActions; ++i) | ||
| 206 | { | ||
| 207 | PlanUninitializeExecuteAction(&pPlan->rgRestoreRelatedBundleActions[i]); | ||
| 208 | } | ||
| 209 | MemFree(pPlan->rgRestoreRelatedBundleActions); | ||
| 210 | } | ||
| 211 | |||
| 199 | if (pPlan->rgCleanActions) | 212 | if (pPlan->rgCleanActions) |
| 200 | { | 213 | { |
| 201 | // Nothing needs to be freed inside clean actions today. | 214 | // Nothing needs to be freed inside clean actions today. |
| @@ -1276,6 +1289,9 @@ extern "C" HRESULT PlanRelatedBundlesBegin( | |||
| 1276 | continue; | 1289 | continue; |
| 1277 | } | 1290 | } |
| 1278 | 1291 | ||
| 1292 | pRelatedBundle->defaultRequestedRestore = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
| 1293 | pRelatedBundle->requestedRestore = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
| 1294 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
| 1279 | pRelatedBundle->package.defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE; | 1295 | pRelatedBundle->package.defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE; |
| 1280 | pRelatedBundle->package.requested = BOOTSTRAPPER_REQUEST_STATE_NONE; | 1296 | pRelatedBundle->package.requested = BOOTSTRAPPER_REQUEST_STATE_NONE; |
| 1281 | 1297 | ||
| @@ -1312,12 +1328,6 @@ extern "C" HRESULT PlanRelatedBundlesBegin( | |||
| 1312 | hr = UserExperienceOnPlanRelatedBundle(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->package.requested); | 1328 | hr = UserExperienceOnPlanRelatedBundle(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->package.requested); |
| 1313 | ExitOnRootFailure(hr, "BA aborted plan related bundle."); | 1329 | ExitOnRootFailure(hr, "BA aborted plan related bundle."); |
| 1314 | 1330 | ||
| 1315 | // Log when the BA changed the bundle state so the engine doesn't get blamed for planning the wrong thing. | ||
| 1316 | if (pRelatedBundle->package.requested != pRelatedBundle->package.defaultRequested) | ||
| 1317 | { | ||
| 1318 | LogId(REPORT_STANDARD, MSG_PLANNED_BUNDLE_UX_CHANGED_REQUEST, pRelatedBundle->package.sczId, LoggingRequestStateToString(pRelatedBundle->package.requested), LoggingRequestStateToString(pRelatedBundle->package.defaultRequested)); | ||
| 1319 | } | ||
| 1320 | |||
| 1321 | // If uninstalling and the dependent related bundle may be executed, ignore its provider key to allow for downgrades with ref-counting. | 1331 | // If uninstalling and the dependent related bundle may be executed, ignore its provider key to allow for downgrades with ref-counting. |
| 1322 | if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action && BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType && BOOTSTRAPPER_REQUEST_STATE_NONE != pRelatedBundle->package.requested) | 1332 | if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action && BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType && BOOTSTRAPPER_REQUEST_STATE_NONE != pRelatedBundle->package.requested) |
| 1323 | { | 1333 | { |
| @@ -1340,6 +1350,7 @@ LExit: | |||
| 1340 | } | 1350 | } |
| 1341 | 1351 | ||
| 1342 | extern "C" HRESULT PlanRelatedBundlesComplete( | 1352 | extern "C" HRESULT PlanRelatedBundlesComplete( |
| 1353 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
| 1343 | __in BURN_REGISTRATION* pRegistration, | 1354 | __in BURN_REGISTRATION* pRegistration, |
| 1344 | __in BURN_PLAN* pPlan, | 1355 | __in BURN_PLAN* pPlan, |
| 1345 | __in BURN_LOGGING* pLog, | 1356 | __in BURN_LOGGING* pLog, |
| @@ -1359,16 +1370,19 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
| 1359 | ExitOnFailure(hr, "Failed to create dictionary for planned packages."); | 1370 | ExitOnFailure(hr, "Failed to create dictionary for planned packages."); |
| 1360 | 1371 | ||
| 1361 | BOOL fExecutingAnyPackage = FALSE; | 1372 | BOOL fExecutingAnyPackage = FALSE; |
| 1373 | BOOL fInstallingAnyPackage = FALSE; | ||
| 1362 | 1374 | ||
| 1363 | for (DWORD i = 0; i < pPlan->cExecuteActions; ++i) | 1375 | for (DWORD i = 0; i < pPlan->cExecuteActions; ++i) |
| 1364 | { | 1376 | { |
| 1377 | BOOTSTRAPPER_ACTION_STATE packageAction = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
| 1378 | |||
| 1365 | switch (pPlan->rgExecuteActions[i].type) | 1379 | switch (pPlan->rgExecuteActions[i].type) |
| 1366 | { | 1380 | { |
| 1367 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: | 1381 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: |
| 1368 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].relatedBundle.action) | 1382 | packageAction = pPlan->rgExecuteActions[i].relatedBundle.action; |
| 1369 | { | ||
| 1370 | fExecutingAnyPackage = TRUE; | ||
| 1371 | 1383 | ||
| 1384 | if (BOOTSTRAPPER_ACTION_STATE_NONE != packageAction) | ||
| 1385 | { | ||
| 1372 | BURN_PACKAGE* pPackage = &pPlan->rgExecuteActions[i].relatedBundle.pRelatedBundle->package; | 1386 | BURN_PACKAGE* pPackage = &pPlan->rgExecuteActions[i].relatedBundle.pRelatedBundle->package; |
| 1373 | if (pPackage->cDependencyProviders) | 1387 | if (pPackage->cDependencyProviders) |
| 1374 | { | 1388 | { |
| @@ -1380,21 +1394,24 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
| 1380 | break; | 1394 | break; |
| 1381 | 1395 | ||
| 1382 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: | 1396 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: |
| 1383 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].exePackage.action); | 1397 | packageAction = pPlan->rgExecuteActions[i].exePackage.action; |
| 1384 | break; | 1398 | break; |
| 1385 | 1399 | ||
| 1386 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: | 1400 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: |
| 1387 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].msiPackage.action); | 1401 | packageAction = pPlan->rgExecuteActions[i].msiPackage.action; |
| 1388 | break; | 1402 | break; |
| 1389 | 1403 | ||
| 1390 | case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: | 1404 | case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: |
| 1391 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].mspTarget.action); | 1405 | packageAction = pPlan->rgExecuteActions[i].mspTarget.action; |
| 1392 | break; | 1406 | break; |
| 1393 | 1407 | ||
| 1394 | case BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE: | 1408 | case BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE: |
| 1395 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].msuPackage.action); | 1409 | packageAction = pPlan->rgExecuteActions[i].msuPackage.action; |
| 1396 | break; | 1410 | break; |
| 1397 | } | 1411 | } |
| 1412 | |||
| 1413 | fExecutingAnyPackage |= BOOTSTRAPPER_ACTION_STATE_NONE != packageAction; | ||
| 1414 | fInstallingAnyPackage |= BOOTSTRAPPER_ACTION_STATE_INSTALL == packageAction || BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE == packageAction; | ||
| 1398 | } | 1415 | } |
| 1399 | 1416 | ||
| 1400 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) | 1417 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) |
| @@ -1492,6 +1509,62 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
| 1492 | hr = DependencyPlanPackageComplete(&pRelatedBundle->package, pPlan); | 1509 | hr = DependencyPlanPackageComplete(&pRelatedBundle->package, pPlan); |
| 1493 | ExitOnFailure(hr, "Failed to complete plan dependency actions for related bundle package: %ls", pRelatedBundle->package.sczId); | 1510 | ExitOnFailure(hr, "Failed to complete plan dependency actions for related bundle package: %ls", pRelatedBundle->package.sczId); |
| 1494 | } | 1511 | } |
| 1512 | |||
| 1513 | if (fInstallingAnyPackage && BOOTSTRAPPER_RELATION_UPGRADE == pRelatedBundle->relationType) | ||
| 1514 | { | ||
| 1515 | BURN_EXECUTE_ACTION* pAction = NULL; | ||
| 1516 | |||
| 1517 | pRelatedBundle->defaultRequestedRestore = pRelatedBundle->requestedRestore = BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT; | ||
| 1518 | |||
| 1519 | hr = UserExperienceOnPlanRestoreRelatedBundle(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->requestedRestore); | ||
| 1520 | ExitOnRootFailure(hr, "BA aborted plan restore related bundle."); | ||
| 1521 | |||
| 1522 | switch (pRelatedBundle->requestedRestore) | ||
| 1523 | { | ||
| 1524 | case BOOTSTRAPPER_REQUEST_STATE_REPAIR: | ||
| 1525 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_REPAIR; | ||
| 1526 | break; | ||
| 1527 | case BOOTSTRAPPER_REQUEST_STATE_ABSENT: __fallthrough; | ||
| 1528 | case BOOTSTRAPPER_REQUEST_STATE_CACHE: __fallthrough; | ||
| 1529 | case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: | ||
| 1530 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; | ||
| 1531 | break; | ||
| 1532 | case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: | ||
| 1533 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_INSTALL; | ||
| 1534 | break; | ||
| 1535 | default: | ||
| 1536 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
| 1537 | break; | ||
| 1538 | } | ||
| 1539 | |||
| 1540 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pRelatedBundle->restore) | ||
| 1541 | { | ||
| 1542 | hr = AppendRestoreRelatedBundleAction(pPlan, &pAction); | ||
| 1543 | ExitOnFailure(hr, "Failed to append restore related bundle action to plan."); | ||
| 1544 | |||
| 1545 | pAction->type = BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE; | ||
| 1546 | pAction->relatedBundle.pRelatedBundle = pRelatedBundle; | ||
| 1547 | pAction->relatedBundle.action = pRelatedBundle->restore; | ||
| 1548 | |||
| 1549 | if (pRelatedBundle->package.Bundle.sczIgnoreDependencies) | ||
| 1550 | { | ||
| 1551 | hr = StrAllocString(&pAction->relatedBundle.sczIgnoreDependencies, pRelatedBundle->package.Bundle.sczIgnoreDependencies, 0); | ||
| 1552 | ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore."); | ||
| 1553 | } | ||
| 1554 | |||
| 1555 | if (pRelatedBundle->package.Bundle.wzAncestors) | ||
| 1556 | { | ||
| 1557 | hr = StrAllocString(&pAction->relatedBundle.sczAncestors, pRelatedBundle->package.Bundle.wzAncestors, 0); | ||
| 1558 | ExitOnFailure(hr, "Failed to allocate the list of ancestors."); | ||
| 1559 | } | ||
| 1560 | |||
| 1561 | if (pRelatedBundle->package.Bundle.wzEngineWorkingDirectory) | ||
| 1562 | { | ||
| 1563 | hr = StrAllocString(&pAction->relatedBundle.sczEngineWorkingDirectory, pRelatedBundle->package.Bundle.wzEngineWorkingDirectory, 0); | ||
| 1564 | ExitOnFailure(hr, "Failed to allocate the custom working directory."); | ||
| 1565 | } | ||
| 1566 | } | ||
| 1567 | } | ||
| 1495 | } | 1568 | } |
| 1496 | 1569 | ||
| 1497 | LExit: | 1570 | LExit: |
| @@ -2269,6 +2342,23 @@ LExit: | |||
| 2269 | return hr; | 2342 | return hr; |
| 2270 | } | 2343 | } |
| 2271 | 2344 | ||
| 2345 | static HRESULT AppendRestoreRelatedBundleAction( | ||
| 2346 | __in BURN_PLAN* pPlan, | ||
| 2347 | __out BURN_EXECUTE_ACTION** ppExecuteAction | ||
| 2348 | ) | ||
| 2349 | { | ||
| 2350 | HRESULT hr = S_OK; | ||
| 2351 | |||
| 2352 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(&pPlan->rgRestoreRelatedBundleActions), pPlan->cRestoreRelatedBundleActions, 1, sizeof(BURN_EXECUTE_ACTION), 5); | ||
| 2353 | ExitOnFailure(hr, "Failed to grow plan's array of restore related bundle actions."); | ||
| 2354 | |||
| 2355 | *ppExecuteAction = pPlan->rgRestoreRelatedBundleActions + pPlan->cRestoreRelatedBundleActions; | ||
| 2356 | ++pPlan->cRestoreRelatedBundleActions; | ||
| 2357 | |||
| 2358 | LExit: | ||
| 2359 | return hr; | ||
| 2360 | } | ||
| 2361 | |||
| 2272 | static HRESULT ProcessPayloadGroup( | 2362 | static HRESULT ProcessPayloadGroup( |
| 2273 | __in BURN_PLAN* pPlan, | 2363 | __in BURN_PLAN* pPlan, |
| 2274 | __in BURN_PAYLOAD_GROUP* pPayloadGroup | 2364 | __in BURN_PAYLOAD_GROUP* pPayloadGroup |
| @@ -2725,6 +2815,28 @@ static void ExecuteActionLog( | |||
| 2725 | } | 2815 | } |
| 2726 | } | 2816 | } |
| 2727 | 2817 | ||
| 2818 | static void RestoreRelatedBundleActionLog( | ||
| 2819 | __in DWORD iAction, | ||
| 2820 | __in BURN_EXECUTE_ACTION* pAction | ||
| 2821 | ) | ||
| 2822 | { | ||
| 2823 | switch (pAction->type) | ||
| 2824 | { | ||
| 2825 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: | ||
| 2826 | LogStringLine(PlanDumpLevel, "Restore action[%u]: RELATED_BUNDLE package id: %ls, action: %hs, ignore dependencies: %ls", iAction, pAction->relatedBundle.pRelatedBundle->package.sczId, LoggingActionStateToString(pAction->relatedBundle.action), pAction->relatedBundle.sczIgnoreDependencies); | ||
| 2827 | break; | ||
| 2828 | |||
| 2829 | default: | ||
| 2830 | AssertSz(FALSE, "Unknown execute action type."); | ||
| 2831 | break; | ||
| 2832 | } | ||
| 2833 | |||
| 2834 | if (pAction->fDeleted) | ||
| 2835 | { | ||
| 2836 | LogStringLine(PlanDumpLevel, " (deleted action)"); | ||
| 2837 | } | ||
| 2838 | } | ||
| 2839 | |||
| 2728 | static void CleanActionLog( | 2840 | static void CleanActionLog( |
| 2729 | __in DWORD iAction, | 2841 | __in DWORD iAction, |
| 2730 | __in BURN_CLEAN_ACTION* pAction | 2842 | __in BURN_CLEAN_ACTION* pAction |
| @@ -2784,6 +2896,11 @@ extern "C" void PlanDump( | |||
| 2784 | ExecuteActionLog(i, pPlan->rgRollbackActions + i, TRUE); | 2896 | ExecuteActionLog(i, pPlan->rgRollbackActions + i, TRUE); |
| 2785 | } | 2897 | } |
| 2786 | 2898 | ||
| 2899 | for (DWORD i = 0; i < pPlan->cRestoreRelatedBundleActions; ++i) | ||
| 2900 | { | ||
| 2901 | RestoreRelatedBundleActionLog(i, pPlan->rgRestoreRelatedBundleActions + i); | ||
| 2902 | } | ||
| 2903 | |||
| 2787 | for (DWORD i = 0; i < pPlan->cCleanActions; ++i) | 2904 | for (DWORD i = 0; i < pPlan->cCleanActions; ++i) |
| 2788 | { | 2905 | { |
| 2789 | CleanActionLog(i, pPlan->rgCleanActions + i); | 2906 | CleanActionLog(i, pPlan->rgCleanActions + i); |
diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h index 0734e39f..3dce8e5d 100644 --- a/src/burn/engine/plan.h +++ b/src/burn/engine/plan.h | |||
| @@ -280,6 +280,9 @@ typedef struct _BURN_PLAN | |||
| 280 | BURN_EXECUTE_ACTION* rgRollbackActions; | 280 | BURN_EXECUTE_ACTION* rgRollbackActions; |
| 281 | DWORD cRollbackActions; | 281 | DWORD cRollbackActions; |
| 282 | 282 | ||
| 283 | BURN_EXECUTE_ACTION* rgRestoreRelatedBundleActions; | ||
| 284 | DWORD cRestoreRelatedBundleActions; | ||
| 285 | |||
| 283 | BURN_CLEAN_ACTION* rgCleanActions; | 286 | BURN_CLEAN_ACTION* rgCleanActions; |
| 284 | DWORD cCleanActions; | 287 | DWORD cCleanActions; |
| 285 | 288 | ||
| @@ -394,6 +397,7 @@ HRESULT PlanRelatedBundlesBegin( | |||
| 394 | __in BURN_PLAN* pPlan | 397 | __in BURN_PLAN* pPlan |
| 395 | ); | 398 | ); |
| 396 | HRESULT PlanRelatedBundlesComplete( | 399 | HRESULT PlanRelatedBundlesComplete( |
| 400 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
| 397 | __in BURN_REGISTRATION* pRegistration, | 401 | __in BURN_REGISTRATION* pRegistration, |
| 398 | __in BURN_PLAN* pPlan, | 402 | __in BURN_PLAN* pPlan, |
| 399 | __in BURN_LOGGING* pLog, | 403 | __in BURN_LOGGING* pLog, |
diff --git a/src/burn/engine/pseudobundle.cpp b/src/burn/engine/pseudobundle.cpp index 94b095c5..082c4487 100644 --- a/src/burn/engine/pseudobundle.cpp +++ b/src/burn/engine/pseudobundle.cpp | |||
| @@ -51,7 +51,6 @@ extern "C" HRESULT PseudoBundleInitializeRelated( | |||
| 51 | pPackage->fVital = FALSE; | 51 | pPackage->fVital = FALSE; |
| 52 | 52 | ||
| 53 | pPackage->fPermanent = FALSE; | 53 | pPackage->fPermanent = FALSE; |
| 54 | pPackage->Bundle.fRepairable = TRUE; | ||
| 55 | pPackage->Bundle.fSupportsBurnProtocol = fSupportsBurnProtocol; | 54 | pPackage->Bundle.fSupportsBurnProtocol = fSupportsBurnProtocol; |
| 56 | 55 | ||
| 57 | hr = StrAllocString(&pPackage->sczId, wzId, 0); | 56 | hr = StrAllocString(&pPackage->sczId, wzId, 0); |
diff --git a/src/burn/engine/registration.h b/src/burn/engine/registration.h index 0ae61974..64191828 100644 --- a/src/burn/engine/registration.h +++ b/src/burn/engine/registration.h | |||
| @@ -61,6 +61,10 @@ typedef struct _BURN_RELATED_BUNDLE | |||
| 61 | BOOL fPlannable; | 61 | BOOL fPlannable; |
| 62 | 62 | ||
| 63 | BURN_PACKAGE package; | 63 | BURN_PACKAGE package; |
| 64 | |||
| 65 | BOOTSTRAPPER_REQUEST_STATE defaultRequestedRestore; | ||
| 66 | BOOTSTRAPPER_REQUEST_STATE requestedRestore; | ||
| 67 | BOOTSTRAPPER_ACTION_STATE restore; | ||
| 64 | } BURN_RELATED_BUNDLE; | 68 | } BURN_RELATED_BUNDLE; |
| 65 | 69 | ||
| 66 | typedef struct _BURN_RELATED_BUNDLES | 70 | typedef struct _BURN_RELATED_BUNDLES |
diff --git a/src/burn/engine/userexperience.cpp b/src/burn/engine/userexperience.cpp index 1439f5f2..59988bef 100644 --- a/src/burn/engine/userexperience.cpp +++ b/src/burn/engine/userexperience.cpp | |||
| @@ -2176,6 +2176,36 @@ LExit: | |||
| 2176 | return hr; | 2176 | return hr; |
| 2177 | } | 2177 | } |
| 2178 | 2178 | ||
| 2179 | EXTERN_C BAAPI UserExperienceOnPlanRestoreRelatedBundle( | ||
| 2180 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
| 2181 | __in_z LPCWSTR wzBundleId, | ||
| 2182 | __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState | ||
| 2183 | ) | ||
| 2184 | { | ||
| 2185 | HRESULT hr = S_OK; | ||
| 2186 | BA_ONPLANRESTORERELATEDBUNDLE_ARGS args = { }; | ||
| 2187 | BA_ONPLANRESTORERELATEDBUNDLE_RESULTS results = { }; | ||
| 2188 | |||
| 2189 | args.cbSize = sizeof(args); | ||
| 2190 | args.wzBundleId = wzBundleId; | ||
| 2191 | args.recommendedState = *pRequestedState; | ||
| 2192 | |||
| 2193 | results.cbSize = sizeof(results); | ||
| 2194 | results.requestedState = *pRequestedState; | ||
| 2195 | |||
| 2196 | hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRESTORERELATEDBUNDLE, &args, &results); | ||
| 2197 | ExitOnFailure(hr, "BA OnPlanRestoreRelatedBundle failed."); | ||
| 2198 | |||
| 2199 | if (results.fCancel) | ||
| 2200 | { | ||
| 2201 | hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); | ||
| 2202 | } | ||
| 2203 | *pRequestedState = results.requestedState; | ||
| 2204 | |||
| 2205 | LExit: | ||
| 2206 | return hr; | ||
| 2207 | } | ||
| 2208 | |||
| 2179 | EXTERN_C BAAPI UserExperienceOnPlanRollbackBoundary( | 2209 | EXTERN_C BAAPI UserExperienceOnPlanRollbackBoundary( |
| 2180 | __in BURN_USER_EXPERIENCE* pUserExperience, | 2210 | __in BURN_USER_EXPERIENCE* pUserExperience, |
| 2181 | __in_z LPCWSTR wzRollbackBoundaryId, | 2211 | __in_z LPCWSTR wzRollbackBoundaryId, |
diff --git a/src/burn/engine/userexperience.h b/src/burn/engine/userexperience.h index e8341120..8106d7f7 100644 --- a/src/burn/engine/userexperience.h +++ b/src/burn/engine/userexperience.h | |||
| @@ -497,6 +497,11 @@ BAAPI UserExperienceOnPlanRelatedBundle( | |||
| 497 | __in_z LPCWSTR wzBundleId, | 497 | __in_z LPCWSTR wzBundleId, |
| 498 | __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState | 498 | __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState |
| 499 | ); | 499 | ); |
| 500 | BAAPI UserExperienceOnPlanRestoreRelatedBundle( | ||
| 501 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
| 502 | __in_z LPCWSTR wzBundleId, | ||
| 503 | __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState | ||
| 504 | ); | ||
| 500 | BAAPI UserExperienceOnPlanRollbackBoundary( | 505 | BAAPI UserExperienceOnPlanRollbackBoundary( |
| 501 | __in BURN_USER_EXPERIENCE* pUserExperience, | 506 | __in BURN_USER_EXPERIENCE* pUserExperience, |
| 502 | __in_z LPCWSTR wzRollbackBoundaryId, | 507 | __in_z LPCWSTR wzRollbackBoundaryId, |
diff --git a/src/burn/test/BurnUnitTest/PlanTest.cpp b/src/burn/test/BurnUnitTest/PlanTest.cpp index 99644115..81484234 100644 --- a/src/burn/test/BurnUnitTest/PlanTest.cpp +++ b/src/burn/test/BurnUnitTest/PlanTest.cpp | |||
| @@ -170,6 +170,10 @@ namespace Bootstrapper | |||
| 170 | Assert::Equal(7ul, pPlan->cOverallProgressTicksTotal); | 170 | Assert::Equal(7ul, pPlan->cOverallProgressTicksTotal); |
| 171 | 171 | ||
| 172 | dwIndex = 0; | 172 | dwIndex = 0; |
| 173 | ValidateRestoreRelatedBundle(pPlan, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL); | ||
| 174 | Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); | ||
| 175 | |||
| 176 | dwIndex = 0; | ||
| 173 | Assert::Equal(dwIndex, pPlan->cCleanActions); | 177 | Assert::Equal(dwIndex, pPlan->cCleanActions); |
| 174 | 178 | ||
| 175 | UINT uIndex = 0; | 179 | UINT uIndex = 0; |
| @@ -277,6 +281,9 @@ namespace Bootstrapper | |||
| 277 | Assert::Equal(3ul, pPlan->cOverallProgressTicksTotal); | 281 | Assert::Equal(3ul, pPlan->cOverallProgressTicksTotal); |
| 278 | 282 | ||
| 279 | dwIndex = 0; | 283 | dwIndex = 0; |
| 284 | Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); | ||
| 285 | |||
| 286 | dwIndex = 0; | ||
| 280 | ValidateCleanAction(pPlan, dwIndex++, L"PackageC"); | 287 | ValidateCleanAction(pPlan, dwIndex++, L"PackageC"); |
| 281 | ValidateCleanAction(pPlan, dwIndex++, L"PackageB"); | 288 | ValidateCleanAction(pPlan, dwIndex++, L"PackageB"); |
| 282 | ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); | 289 | ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); |
| @@ -350,6 +357,9 @@ namespace Bootstrapper | |||
| 350 | Assert::Equal(1ul, pPlan->cOverallProgressTicksTotal); | 357 | Assert::Equal(1ul, pPlan->cOverallProgressTicksTotal); |
| 351 | 358 | ||
| 352 | dwIndex = 0; | 359 | dwIndex = 0; |
| 360 | Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); | ||
| 361 | |||
| 362 | dwIndex = 0; | ||
| 353 | ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); | 363 | ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); |
| 354 | ValidateCleanCompatibleAction(pPlan, dwIndex++, L"PackageA"); | 364 | ValidateCleanCompatibleAction(pPlan, dwIndex++, L"PackageA"); |
| 355 | Assert::Equal(dwIndex, pPlan->cCleanActions); | 365 | Assert::Equal(dwIndex, pPlan->cCleanActions); |
| @@ -438,6 +448,9 @@ namespace Bootstrapper | |||
| 438 | Assert::Equal(2ul, pPlan->cOverallProgressTicksTotal); | 448 | Assert::Equal(2ul, pPlan->cOverallProgressTicksTotal); |
| 439 | 449 | ||
| 440 | dwIndex = 0; | 450 | dwIndex = 0; |
| 451 | Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); | ||
| 452 | |||
| 453 | dwIndex = 0; | ||
| 441 | Assert::Equal(dwIndex, pPlan->cCleanActions); | 454 | Assert::Equal(dwIndex, pPlan->cCleanActions); |
| 442 | 455 | ||
| 443 | UINT uIndex = 0; | 456 | UINT uIndex = 0; |
| @@ -508,6 +521,9 @@ namespace Bootstrapper | |||
| 508 | Assert::Equal(1ul, pPlan->cOverallProgressTicksTotal); | 521 | Assert::Equal(1ul, pPlan->cOverallProgressTicksTotal); |
| 509 | 522 | ||
| 510 | dwIndex = 0; | 523 | dwIndex = 0; |
| 524 | Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); | ||
| 525 | |||
| 526 | dwIndex = 0; | ||
| 511 | Assert::Equal(dwIndex, pPlan->cCleanActions); | 527 | Assert::Equal(dwIndex, pPlan->cCleanActions); |
| 512 | 528 | ||
| 513 | UINT uIndex = 0; | 529 | UINT uIndex = 0; |
| @@ -579,6 +595,9 @@ namespace Bootstrapper | |||
| 579 | Assert::Equal(2ul, pPlan->cOverallProgressTicksTotal); | 595 | Assert::Equal(2ul, pPlan->cOverallProgressTicksTotal); |
| 580 | 596 | ||
| 581 | dwIndex = 0; | 597 | dwIndex = 0; |
| 598 | Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); | ||
| 599 | |||
| 600 | dwIndex = 0; | ||
| 582 | ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); | 601 | ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); |
| 583 | Assert::Equal(dwIndex, pPlan->cCleanActions); | 602 | Assert::Equal(dwIndex, pPlan->cCleanActions); |
| 584 | 603 | ||
| @@ -658,6 +677,10 @@ namespace Bootstrapper | |||
| 658 | Assert::Equal(3ul, pPlan->cOverallProgressTicksTotal); | 677 | Assert::Equal(3ul, pPlan->cOverallProgressTicksTotal); |
| 659 | 678 | ||
| 660 | dwIndex = 0; | 679 | dwIndex = 0; |
| 680 | ValidateRestoreRelatedBundle(pPlan, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL); | ||
| 681 | Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); | ||
| 682 | |||
| 683 | dwIndex = 0; | ||
| 661 | Assert::Equal(dwIndex, pPlan->cCleanActions); | 684 | Assert::Equal(dwIndex, pPlan->cCleanActions); |
| 662 | 685 | ||
| 663 | UINT uIndex = 0; | 686 | UINT uIndex = 0; |
| @@ -744,6 +767,10 @@ namespace Bootstrapper | |||
| 744 | Assert::Equal(3ul, pPlan->cOverallProgressTicksTotal); | 767 | Assert::Equal(3ul, pPlan->cOverallProgressTicksTotal); |
| 745 | 768 | ||
| 746 | dwIndex = 0; | 769 | dwIndex = 0; |
| 770 | ValidateRestoreRelatedBundle(pPlan, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL); | ||
| 771 | Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); | ||
| 772 | |||
| 773 | dwIndex = 0; | ||
| 747 | Assert::Equal(dwIndex, pPlan->cCleanActions); | 774 | Assert::Equal(dwIndex, pPlan->cCleanActions); |
| 748 | 775 | ||
| 749 | UINT uIndex = 0; | 776 | UINT uIndex = 0; |
| @@ -805,6 +832,9 @@ namespace Bootstrapper | |||
| 805 | Assert::Equal(0ul, pPlan->cOverallProgressTicksTotal); | 832 | Assert::Equal(0ul, pPlan->cOverallProgressTicksTotal); |
| 806 | 833 | ||
| 807 | dwIndex = 0; | 834 | dwIndex = 0; |
| 835 | Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); | ||
| 836 | |||
| 837 | dwIndex = 0; | ||
| 808 | ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); | 838 | ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); |
| 809 | Assert::Equal(dwIndex, pPlan->cCleanActions); | 839 | Assert::Equal(dwIndex, pPlan->cCleanActions); |
| 810 | 840 | ||
| @@ -879,6 +909,9 @@ namespace Bootstrapper | |||
| 879 | Assert::Equal(1ul, pPlan->cOverallProgressTicksTotal); | 909 | Assert::Equal(1ul, pPlan->cOverallProgressTicksTotal); |
| 880 | 910 | ||
| 881 | dwIndex = 0; | 911 | dwIndex = 0; |
| 912 | Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); | ||
| 913 | |||
| 914 | dwIndex = 0; | ||
| 882 | ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); | 915 | ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); |
| 883 | Assert::Equal(dwIndex, pPlan->cCleanActions); | 916 | Assert::Equal(dwIndex, pPlan->cCleanActions); |
| 884 | 917 | ||
| @@ -946,6 +979,9 @@ namespace Bootstrapper | |||
| 946 | Assert::Equal(0ul, pPlan->cOverallProgressTicksTotal); | 979 | Assert::Equal(0ul, pPlan->cOverallProgressTicksTotal); |
| 947 | 980 | ||
| 948 | dwIndex = 0; | 981 | dwIndex = 0; |
| 982 | Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); | ||
| 983 | |||
| 984 | dwIndex = 0; | ||
| 949 | Assert::Equal(dwIndex, pPlan->cCleanActions); | 985 | Assert::Equal(dwIndex, pPlan->cCleanActions); |
| 950 | 986 | ||
| 951 | UINT uIndex = 0; | 987 | UINT uIndex = 0; |
| @@ -1057,6 +1093,9 @@ namespace Bootstrapper | |||
| 1057 | Assert::Equal(5ul, pPlan->cOverallProgressTicksTotal); | 1093 | Assert::Equal(5ul, pPlan->cOverallProgressTicksTotal); |
| 1058 | 1094 | ||
| 1059 | dwIndex = 0; | 1095 | dwIndex = 0; |
| 1096 | Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); | ||
| 1097 | |||
| 1098 | dwIndex = 0; | ||
| 1060 | Assert::Equal(dwIndex, pPlan->cCleanActions); | 1099 | Assert::Equal(dwIndex, pPlan->cCleanActions); |
| 1061 | 1100 | ||
| 1062 | UINT uIndex = 0; | 1101 | UINT uIndex = 0; |
| @@ -1147,6 +1186,9 @@ namespace Bootstrapper | |||
| 1147 | Assert::Equal(2ul, pPlan->cOverallProgressTicksTotal); | 1186 | Assert::Equal(2ul, pPlan->cOverallProgressTicksTotal); |
| 1148 | 1187 | ||
| 1149 | dwIndex = 0; | 1188 | dwIndex = 0; |
| 1189 | Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); | ||
| 1190 | |||
| 1191 | dwIndex = 0; | ||
| 1150 | ValidateCleanAction(pPlan, dwIndex++, L"PatchA"); | 1192 | ValidateCleanAction(pPlan, dwIndex++, L"PatchA"); |
| 1151 | ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); | 1193 | ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); |
| 1152 | Assert::Equal(dwIndex, pPlan->cCleanActions); | 1194 | Assert::Equal(dwIndex, pPlan->cCleanActions); |
| @@ -1829,6 +1871,28 @@ namespace Bootstrapper | |||
| 1829 | NativeAssert::StringEqual(wzName, pProvider->sczName); | 1871 | NativeAssert::StringEqual(wzName, pProvider->sczName); |
| 1830 | } | 1872 | } |
| 1831 | 1873 | ||
| 1874 | void ValidateRestoreRelatedBundle( | ||
| 1875 | __in BURN_PLAN* pPlan, | ||
| 1876 | __in DWORD dwIndex, | ||
| 1877 | __in LPCWSTR wzPackageId, | ||
| 1878 | __in BOOTSTRAPPER_ACTION_STATE action, | ||
| 1879 | __in LPCWSTR wzIgnoreDependencies | ||
| 1880 | ) | ||
| 1881 | { | ||
| 1882 | BURN_EXECUTE_ACTION* pAction = ValidateRestoreRelatedBundleActionExists(pPlan, dwIndex); | ||
| 1883 | Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE, pAction->type); | ||
| 1884 | NativeAssert::StringEqual(wzPackageId, pAction->relatedBundle.pRelatedBundle->package.sczId); | ||
| 1885 | Assert::Equal<DWORD>(action, pAction->relatedBundle.action); | ||
| 1886 | NativeAssert::StringEqual(wzIgnoreDependencies, pAction->relatedBundle.sczIgnoreDependencies); | ||
| 1887 | Assert::Equal<BOOL>(FALSE, pAction->fDeleted); | ||
| 1888 | } | ||
| 1889 | |||
| 1890 | BURN_EXECUTE_ACTION* ValidateRestoreRelatedBundleActionExists(BURN_PLAN* pPlan, DWORD dwIndex) | ||
| 1891 | { | ||
| 1892 | Assert::InRange(dwIndex + 1ul, 1ul, pPlan->cRestoreRelatedBundleActions); | ||
| 1893 | return pPlan->rgRestoreRelatedBundleActions + dwIndex; | ||
| 1894 | } | ||
| 1895 | |||
| 1832 | void ValidateUninstallMsiCompatiblePackage( | 1896 | void ValidateUninstallMsiCompatiblePackage( |
| 1833 | __in BURN_PLAN* pPlan, | 1897 | __in BURN_PLAN* pPlan, |
| 1834 | __in BOOL fRollback, | 1898 | __in BOOL fRollback, |
diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp index 02c10472..8c7bce7e 100644 --- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp +++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp | |||
| @@ -2089,6 +2089,16 @@ private: // privates | |||
| 2089 | m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext); | 2089 | m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext); |
| 2090 | } | 2090 | } |
| 2091 | 2091 | ||
| 2092 | void OnPlanRestoreRelatedBundleFallback( | ||
| 2093 | __in BA_ONPLANRESTORERELATEDBUNDLE_ARGS* pArgs, | ||
| 2094 | __inout BA_ONPLANRESTORERELATEDBUNDLE_RESULTS* pResults | ||
| 2095 | ) | ||
| 2096 | { | ||
| 2097 | BOOTSTRAPPER_REQUEST_STATE requestedState = pResults->requestedState; | ||
| 2098 | m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANRESTORERELATEDBUNDLE, pArgs, pResults, m_pvBAFunctionsProcContext); | ||
| 2099 | BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_RESTORE_RELATED_BUNDLE, m_hModule, pArgs->wzBundleId, LoggingRequestStateToString(requestedState), LoggingRequestStateToString(pResults->requestedState)); | ||
| 2100 | } | ||
| 2101 | |||
| 2092 | 2102 | ||
| 2093 | public: //CBalBaseBootstrapperApplication | 2103 | public: //CBalBaseBootstrapperApplication |
| 2094 | virtual STDMETHODIMP Initialize( | 2104 | virtual STDMETHODIMP Initialize( |
diff --git a/src/ext/Bal/wixstdba/wixstdba.mc b/src/ext/Bal/wixstdba/wixstdba.mc index 40acfe54..eeb69914 100644 --- a/src/ext/Bal/wixstdba/wixstdba.mc +++ b/src/ext/Bal/wixstdba/wixstdba.mc | |||
| @@ -85,3 +85,10 @@ Language=English | |||
| 85 | WIXSTDBA: Planned rollback boundary: %1!ls!, wixstdba requested transaction: %2!hs!, bafunctions requested transaction: %3!hs! | 85 | WIXSTDBA: Planned rollback boundary: %1!ls!, wixstdba requested transaction: %2!hs!, bafunctions requested transaction: %3!hs! |
| 86 | . | 86 | . |
| 87 | 87 | ||
| 88 | MessageId=9 | ||
| 89 | Severity=Success | ||
| 90 | SymbolicName=MSG_WIXSTDBA_PLANNED_RESTORE_RELATED_BUNDLE | ||
| 91 | Language=English | ||
| 92 | WIXSTDBA: Planned restore related bundle: %1!ls!, wixstdba requested: %2!hs!, bafunctions requested: %3!hs! | ||
| 93 | . | ||
| 94 | |||
diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv3/BundleAv3.wixproj b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv3/BundleAv3.wixproj new file mode 100644 index 00000000..958ceb47 --- /dev/null +++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv3/BundleAv3.wixproj | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 2 | <Project Sdk="WixToolset.Sdk"> | ||
| 3 | <Import Project="..\BundleAv1\BundleA.props" /> | ||
| 4 | <PropertyGroup> | ||
| 5 | <Version>3.0.0.0</Version> | ||
| 6 | </PropertyGroup> | ||
| 7 | <ItemGroup> | ||
| 8 | <ProjectReference Include="..\PackageAv3\PackageAv3.wixproj" /> | ||
| 9 | <ProjectReference Include="..\PackageF\PackageF.wixproj" /> | ||
| 10 | <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" /> | ||
| 11 | </ItemGroup> | ||
| 12 | <ItemGroup> | ||
| 13 | <PackageReference Include="WixToolset.Bal.wixext" /> | ||
| 14 | <PackageReference Include="WixToolset.NetFx.wixext" /> | ||
| 15 | </ItemGroup> | ||
| 16 | </Project> \ No newline at end of file | ||
diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv3/BundleAv3.wxs b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv3/BundleAv3.wxs new file mode 100644 index 00000000..b969b504 --- /dev/null +++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/BundleAv3/BundleAv3.wxs | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 2 | |||
| 3 | |||
| 4 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | ||
| 5 | <Fragment> | ||
| 6 | <PackageGroup Id="BundlePackages"> | ||
| 7 | <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv3.TargetPath)" /> | ||
| 8 | <MsiPackage Id="PackageF" SourceFile="$(var.PackageF.TargetPath)" /> | ||
| 9 | </PackageGroup> | ||
| 10 | </Fragment> | ||
| 11 | </Wix> | ||
diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/PackageAv3/PackageAv3.wixproj b/src/test/burn/TestData/UpgradeRelatedBundleTests/PackageAv3/PackageAv3.wixproj new file mode 100644 index 00000000..f3c121af --- /dev/null +++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/PackageAv3/PackageAv3.wixproj | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 2 | <Project Sdk="WixToolset.Sdk"> | ||
| 3 | <Import Project="..\PackageAv1\PackageA.props" /> | ||
| 4 | <PropertyGroup> | ||
| 5 | <Version>3.0.0.0</Version> | ||
| 6 | </PropertyGroup> | ||
| 7 | </Project> \ No newline at end of file | ||
diff --git a/src/test/burn/TestData/UpgradeRelatedBundleTests/PackageF/PackageF.wixproj b/src/test/burn/TestData/UpgradeRelatedBundleTests/PackageF/PackageF.wixproj new file mode 100644 index 00000000..63d32e28 --- /dev/null +++ b/src/test/burn/TestData/UpgradeRelatedBundleTests/PackageF/PackageF.wixproj | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | ||
| 2 | <Project Sdk="WixToolset.Sdk"> | ||
| 3 | <PropertyGroup> | ||
| 4 | <UpgradeCode>{8F6C8C4B-573C-416B-B1B0-467273256BD9}</UpgradeCode> | ||
| 5 | </PropertyGroup> | ||
| 6 | <ItemGroup> | ||
| 7 | <Compile Include="..\..\Templates\PackageFail.wxs" Link="PackageFail.wxs" /> | ||
| 8 | </ItemGroup> | ||
| 9 | <ItemGroup> | ||
| 10 | <PackageReference Include="WixToolset.Util.wixext" /> | ||
| 11 | </ItemGroup> | ||
| 12 | </Project> \ No newline at end of file | ||
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs index 69a1fa68..ba02d8ee 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs | |||
| @@ -539,7 +539,7 @@ namespace WixToolsetTest.BurnE2E | |||
| 539 | } | 539 | } |
| 540 | } | 540 | } |
| 541 | 541 | ||
| 542 | [Fact(Skip = "https://github.com/wixtoolset/issues/issues/3421")] | 542 | [Fact] |
| 543 | public void DoesntLoseDependenciesOnFailedMajorUpgradeBundleFromMajorUpdateMsiFifo() | 543 | public void DoesntLoseDependenciesOnFailedMajorUpgradeBundleFromMajorUpdateMsiFifo() |
| 544 | { | 544 | { |
| 545 | var packageAv1 = this.CreatePackageInstaller("PackageAv1"); | 545 | var packageAv1 = this.CreatePackageInstaller("PackageAv1"); |
| @@ -611,7 +611,7 @@ namespace WixToolsetTest.BurnE2E | |||
| 611 | packageGv2.VerifyInstalled(false); | 611 | packageGv2.VerifyInstalled(false); |
| 612 | } | 612 | } |
| 613 | 613 | ||
| 614 | [Fact(Skip = "https://github.com/wixtoolset/issues/issues/3421")] | 614 | [Fact] |
| 615 | public void DoesntLoseDependenciesOnFailedMajorUpgradeBundleFromMajorUpdateMsiLifo() | 615 | public void DoesntLoseDependenciesOnFailedMajorUpgradeBundleFromMajorUpdateMsiLifo() |
| 616 | { | 616 | { |
| 617 | var packageAv1 = this.CreatePackageInstaller("PackageAv1"); | 617 | var packageAv1 = this.CreatePackageInstaller("PackageAv1"); |
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs index 9eb5081e..32a04e5c 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/UpgradeRelatedBundleTests.cs | |||
| @@ -13,6 +13,33 @@ namespace WixToolsetTest.BurnE2E | |||
| 13 | public UpgradeRelatedBundleTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { } | 13 | public UpgradeRelatedBundleTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { } |
| 14 | 14 | ||
| 15 | [Fact] | 15 | [Fact] |
| 16 | public void ReinstallsOlderBundleAfterFailure() | ||
| 17 | { | ||
| 18 | var packageAv2 = this.CreatePackageInstaller("PackageAv2"); | ||
| 19 | var packageAv3 = this.CreatePackageInstaller("PackageAv3"); | ||
| 20 | var bundleAv2 = this.CreateBundleInstaller("BundleAv2"); | ||
| 21 | var bundleAv3 = this.CreateBundleInstaller("BundleAv3"); | ||
| 22 | |||
| 23 | packageAv2.VerifyInstalled(false); | ||
| 24 | packageAv3.VerifyInstalled(false); | ||
| 25 | |||
| 26 | bundleAv2.Install(); | ||
| 27 | bundleAv2.VerifyRegisteredAndInPackageCache(); | ||
| 28 | |||
| 29 | packageAv2.VerifyInstalled(true); | ||
| 30 | packageAv3.VerifyInstalled(false); | ||
| 31 | |||
| 32 | // Verify https://github.com/wixtoolset/issues/issues/3421 | ||
| 33 | var bundleAv3InstallLogFilePath = bundleAv3.Install((int)MSIExec.MSIExecReturnCode.ERROR_INSTALL_FAILURE); | ||
| 34 | bundleAv3.VerifyUnregisteredAndRemovedFromPackageCache(); | ||
| 35 | |||
| 36 | Assert.True(LogVerifier.MessageInLogFileRegex(bundleAv3InstallLogFilePath, @"Applied execute package: PackageA, result: 0x0, restart: None")); | ||
| 37 | |||
| 38 | packageAv2.VerifyInstalled(true); | ||
| 39 | packageAv3.VerifyInstalled(false); | ||
| 40 | } | ||
| 41 | |||
| 42 | [Fact] | ||
| 16 | public void ReportsRelatedBundleMissingFromCache() | 43 | public void ReportsRelatedBundleMissingFromCache() |
| 17 | { | 44 | { |
| 18 | var packageAv1 = this.CreatePackageInstaller("PackageAv1"); | 45 | var packageAv1 = this.CreatePackageInstaller("PackageAv1"); |
