diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2022-01-14 21:37:24 -0600 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2022-01-16 10:30:28 -0600 |
commit | da1d1376953ef1c9afb32d5eee02b785e52e372e (patch) | |
tree | 0df8550960259d7b13f5cd90f04d21b5576f16b7 | |
parent | abe316b80fae80eba54b0b79e76b6362105fa098 (diff) | |
download | wix-da1d1376953ef1c9afb32d5eee02b785e52e372e.tar.gz wix-da1d1376953ef1c9afb32d5eee02b785e52e372e.tar.bz2 wix-da1d1376953ef1c9afb32d5eee02b785e52e372e.zip |
Remove orphan compatible MSI packages.
Reimplements #3190
43 files changed, 1964 insertions, 84 deletions
diff --git a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h index 4fbfc890..659901be 100644 --- a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h +++ b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h | |||
@@ -205,6 +205,10 @@ enum BOOTSTRAPPER_APPLICATION_MESSAGE | |||
205 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANROLLBACKBOUNDARY, | 205 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANROLLBACKBOUNDARY, |
206 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATEBEGIN, | 206 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATEBEGIN, |
207 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATECOMPLETE, | 207 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATECOMPLETE, |
208 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE, | ||
209 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN, | ||
210 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, | ||
211 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE, | ||
208 | }; | 212 | }; |
209 | 213 | ||
210 | enum BOOTSTRAPPER_APPLYCOMPLETE_ACTION | 214 | enum BOOTSTRAPPER_APPLYCOMPLETE_ACTION |
@@ -648,6 +652,20 @@ struct BA_ONDETECTBEGIN_RESULTS | |||
648 | BOOL fCancel; | 652 | BOOL fCancel; |
649 | }; | 653 | }; |
650 | 654 | ||
655 | struct BA_ONDETECTCOMPATIBLEMSIPACKAGE_ARGS | ||
656 | { | ||
657 | DWORD cbSize; | ||
658 | LPCWSTR wzPackageId; | ||
659 | LPCWSTR wzCompatiblePackageId; | ||
660 | LPCWSTR wzCompatiblePackageVersion; | ||
661 | }; | ||
662 | |||
663 | struct BA_ONDETECTCOMPATIBLEMSIPACKAGE_RESULTS | ||
664 | { | ||
665 | DWORD cbSize; | ||
666 | BOOL fCancel; | ||
667 | }; | ||
668 | |||
651 | struct BA_ONDETECTCOMPLETE_ARGS | 669 | struct BA_ONDETECTCOMPLETE_ARGS |
652 | { | 670 | { |
653 | DWORD cbSize; | 671 | DWORD cbSize; |
@@ -1023,6 +1041,36 @@ struct BA_ONPLANBEGIN_RESULTS | |||
1023 | BOOL fCancel; | 1041 | BOOL fCancel; |
1024 | }; | 1042 | }; |
1025 | 1043 | ||
1044 | struct BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_ARGS | ||
1045 | { | ||
1046 | DWORD cbSize; | ||
1047 | LPCWSTR wzPackageId; | ||
1048 | LPCWSTR wzCompatiblePackageId; | ||
1049 | LPCWSTR wzCompatiblePackageVersion; | ||
1050 | BOOL fRecommendedRemove; | ||
1051 | }; | ||
1052 | |||
1053 | struct BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_RESULTS | ||
1054 | { | ||
1055 | DWORD cbSize; | ||
1056 | BOOL fCancel; | ||
1057 | BOOL fRequestRemove; | ||
1058 | }; | ||
1059 | |||
1060 | struct BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_ARGS | ||
1061 | { | ||
1062 | DWORD cbSize; | ||
1063 | LPCWSTR wzPackageId; | ||
1064 | LPCWSTR wzCompatiblePackageId; | ||
1065 | HRESULT hrStatus; | ||
1066 | BOOL fRequestedRemove; | ||
1067 | }; | ||
1068 | |||
1069 | struct BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_RESULTS | ||
1070 | { | ||
1071 | DWORD cbSize; | ||
1072 | }; | ||
1073 | |||
1026 | struct BA_ONPLANCOMPLETE_ARGS | 1074 | struct BA_ONPLANCOMPLETE_ARGS |
1027 | { | 1075 | { |
1028 | DWORD cbSize; | 1076 | DWORD cbSize; |
@@ -1086,6 +1134,19 @@ struct BA_ONPLANMSIPACKAGE_RESULTS | |||
1086 | BOOTSTRAPPER_MSI_FILE_VERSIONING fileVersioning; | 1134 | BOOTSTRAPPER_MSI_FILE_VERSIONING fileVersioning; |
1087 | }; | 1135 | }; |
1088 | 1136 | ||
1137 | struct BA_ONPLANNEDCOMPATIBLEPACKAGE_ARGS | ||
1138 | { | ||
1139 | DWORD cbSize; | ||
1140 | LPCWSTR wzPackageId; | ||
1141 | LPCWSTR wzCompatiblePackageId; | ||
1142 | BOOL fRemove; | ||
1143 | }; | ||
1144 | |||
1145 | struct BA_ONPLANNEDCOMPATIBLEPACKAGE_RESULTS | ||
1146 | { | ||
1147 | DWORD cbSize; | ||
1148 | }; | ||
1149 | |||
1089 | struct BA_ONPLANNEDPACKAGE_ARGS | 1150 | struct BA_ONPLANNEDPACKAGE_ARGS |
1090 | { | 1151 | { |
1091 | DWORD cbSize; | 1152 | DWORD cbSize; |
diff --git a/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs b/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs index 34b63a50..f277425e 100644 --- a/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs +++ b/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs | |||
@@ -63,6 +63,9 @@ namespace WixToolset.Mba.Core | |||
63 | 63 | ||
64 | /// <inheritdoc/> | 64 | /// <inheritdoc/> |
65 | public event EventHandler<DetectPackageBeginEventArgs> DetectPackageBegin; | 65 | public event EventHandler<DetectPackageBeginEventArgs> DetectPackageBegin; |
66 | |||
67 | /// <inheritdoc/> | ||
68 | public event EventHandler<DetectCompatibleMsiPackageEventArgs> DetectCompatibleMsiPackage; | ||
66 | 69 | ||
67 | /// <inheritdoc/> | 70 | /// <inheritdoc/> |
68 | public event EventHandler<DetectRelatedMsiPackageEventArgs> DetectRelatedMsiPackage; | 71 | public event EventHandler<DetectRelatedMsiPackageEventArgs> DetectRelatedMsiPackage; |
@@ -92,6 +95,12 @@ namespace WixToolset.Mba.Core | |||
92 | public event EventHandler<PlanPackageBeginEventArgs> PlanPackageBegin; | 95 | public event EventHandler<PlanPackageBeginEventArgs> PlanPackageBegin; |
93 | 96 | ||
94 | /// <inheritdoc/> | 97 | /// <inheritdoc/> |
98 | public event EventHandler<PlanCompatibleMsiPackageBeginEventArgs> PlanCompatibleMsiPackageBegin; | ||
99 | |||
100 | /// <inheritdoc/> | ||
101 | public event EventHandler<PlanCompatibleMsiPackageCompleteEventArgs> PlanCompatibleMsiPackageComplete; | ||
102 | |||
103 | /// <inheritdoc/> | ||
95 | public event EventHandler<PlanPatchTargetEventArgs> PlanPatchTarget; | 104 | public event EventHandler<PlanPatchTargetEventArgs> PlanPatchTarget; |
96 | 105 | ||
97 | /// <inheritdoc/> | 106 | /// <inheritdoc/> |
@@ -104,6 +113,9 @@ namespace WixToolset.Mba.Core | |||
104 | public event EventHandler<PlanPackageCompleteEventArgs> PlanPackageComplete; | 113 | public event EventHandler<PlanPackageCompleteEventArgs> PlanPackageComplete; |
105 | 114 | ||
106 | /// <inheritdoc/> | 115 | /// <inheritdoc/> |
116 | public event EventHandler<PlannedCompatiblePackageEventArgs> PlannedCompatiblePackage; | ||
117 | |||
118 | /// <inheritdoc/> | ||
107 | public event EventHandler<PlannedPackageEventArgs> PlannedPackage; | 119 | public event EventHandler<PlannedPackageEventArgs> PlannedPackage; |
108 | 120 | ||
109 | /// <inheritdoc/> | 121 | /// <inheritdoc/> |
@@ -415,6 +427,19 @@ namespace WixToolset.Mba.Core | |||
415 | } | 427 | } |
416 | 428 | ||
417 | /// <summary> | 429 | /// <summary> |
430 | /// Called by the engine, raises the <see cref="DetectCompatibleMsiPackage"/> event. | ||
431 | /// </summary> | ||
432 | /// <param name="args">Additional arguments for this event.</param> | ||
433 | protected virtual void OnDetectCompatibleMsiPackage(DetectCompatibleMsiPackageEventArgs args) | ||
434 | { | ||
435 | EventHandler<DetectCompatibleMsiPackageEventArgs> handler = this.DetectCompatibleMsiPackage; | ||
436 | if (null != handler) | ||
437 | { | ||
438 | handler(this, args); | ||
439 | } | ||
440 | } | ||
441 | |||
442 | /// <summary> | ||
418 | /// Called by the engine, raises the <see cref="DetectRelatedMsiPackage"/> event. | 443 | /// Called by the engine, raises the <see cref="DetectRelatedMsiPackage"/> event. |
419 | /// </summary> | 444 | /// </summary> |
420 | /// <param name="args">Additional arguments for this event.</param> | 445 | /// <param name="args">Additional arguments for this event.</param> |
@@ -531,6 +556,32 @@ namespace WixToolset.Mba.Core | |||
531 | } | 556 | } |
532 | 557 | ||
533 | /// <summary> | 558 | /// <summary> |
559 | /// Called by the engine, raises the <see cref="PlanCompatibleMsiPackageBegin"/> event. | ||
560 | /// </summary> | ||
561 | /// <param name="args">Additional arguments for this event.</param> | ||
562 | protected virtual void OnPlanCompatibleMsiPackageBegin(PlanCompatibleMsiPackageBeginEventArgs args) | ||
563 | { | ||
564 | EventHandler<PlanCompatibleMsiPackageBeginEventArgs> handler = this.PlanCompatibleMsiPackageBegin; | ||
565 | if (null != handler) | ||
566 | { | ||
567 | handler(this, args); | ||
568 | } | ||
569 | } | ||
570 | |||
571 | /// <summary> | ||
572 | /// Called by the engine, raises the <see cref="PlanCompatibleMsiPackageComplete"/> event. | ||
573 | /// </summary> | ||
574 | /// <param name="args">Additional arguments for this event.</param> | ||
575 | protected virtual void OnPlanCompatibleMsiPackageComplete(PlanCompatibleMsiPackageCompleteEventArgs args) | ||
576 | { | ||
577 | EventHandler<PlanCompatibleMsiPackageCompleteEventArgs> handler = this.PlanCompatibleMsiPackageComplete; | ||
578 | if (null != handler) | ||
579 | { | ||
580 | handler(this, args); | ||
581 | } | ||
582 | } | ||
583 | |||
584 | /// <summary> | ||
534 | /// Called by the engine, raises the <see cref="PlanPatchTarget"/> event. | 585 | /// Called by the engine, raises the <see cref="PlanPatchTarget"/> event. |
535 | /// </summary> | 586 | /// </summary> |
536 | /// <param name="args">Additional arguments for this event.</param> | 587 | /// <param name="args">Additional arguments for this event.</param> |
@@ -583,6 +634,19 @@ namespace WixToolset.Mba.Core | |||
583 | } | 634 | } |
584 | 635 | ||
585 | /// <summary> | 636 | /// <summary> |
637 | /// Called by the engine, raises the <see cref="PlannedCompatiblePackage"/> event. | ||
638 | /// </summary> | ||
639 | /// <param name="args">Additional arguments for this event.</param> | ||
640 | protected virtual void OnPlannedCompatiblePackage(PlannedCompatiblePackageEventArgs args) | ||
641 | { | ||
642 | EventHandler<PlannedCompatiblePackageEventArgs> handler = this.PlannedCompatiblePackage; | ||
643 | if (null != handler) | ||
644 | { | ||
645 | handler(this, args); | ||
646 | } | ||
647 | } | ||
648 | |||
649 | /// <summary> | ||
586 | /// Called by the engine, raises the <see cref="PlannedPackage"/> event. | 650 | /// Called by the engine, raises the <see cref="PlannedPackage"/> event. |
587 | /// </summary> | 651 | /// </summary> |
588 | /// <param name="args">Additional arguments for this event.</param> | 652 | /// <param name="args">Additional arguments for this event.</param> |
@@ -1363,6 +1427,15 @@ namespace WixToolset.Mba.Core | |||
1363 | return args.HResult; | 1427 | return args.HResult; |
1364 | } | 1428 | } |
1365 | 1429 | ||
1430 | int IBootstrapperApplication.OnDetectCompatibleMsiPackage(string wzPackageId, string wzCompatiblePackageId, string wzCompatiblePackageVersion, ref bool fCancel) | ||
1431 | { | ||
1432 | DetectCompatibleMsiPackageEventArgs args = new DetectCompatibleMsiPackageEventArgs(wzPackageId, wzCompatiblePackageId, wzCompatiblePackageVersion, fCancel); | ||
1433 | this.OnDetectCompatibleMsiPackage(args); | ||
1434 | |||
1435 | fCancel = args.Cancel; | ||
1436 | return args.HResult; | ||
1437 | } | ||
1438 | |||
1366 | int IBootstrapperApplication.OnDetectRelatedMsiPackage(string wzPackageId, string wzUpgradeCode, string wzProductCode, bool fPerMachine, string wzVersion, RelatedOperation operation, ref bool fCancel) | 1439 | int IBootstrapperApplication.OnDetectRelatedMsiPackage(string wzPackageId, string wzUpgradeCode, string wzProductCode, bool fPerMachine, string wzVersion, RelatedOperation operation, ref bool fCancel) |
1367 | { | 1440 | { |
1368 | DetectRelatedMsiPackageEventArgs args = new DetectRelatedMsiPackageEventArgs(wzPackageId, wzUpgradeCode, wzProductCode, fPerMachine, wzVersion, operation, fCancel); | 1441 | DetectRelatedMsiPackageEventArgs args = new DetectRelatedMsiPackageEventArgs(wzPackageId, wzUpgradeCode, wzProductCode, fPerMachine, wzVersion, operation, fCancel); |
@@ -1445,6 +1518,24 @@ namespace WixToolset.Mba.Core | |||
1445 | return args.HResult; | 1518 | return args.HResult; |
1446 | } | 1519 | } |
1447 | 1520 | ||
1521 | int IBootstrapperApplication.OnPlanCompatibleMsiPackageBegin(string wzPackageId, string wzCompatiblePackageId, string wzCompatiblePackageVersion, bool recommendedRemove, ref bool pRequestedRemove, ref bool fCancel) | ||
1522 | { | ||
1523 | PlanCompatibleMsiPackageBeginEventArgs args = new PlanCompatibleMsiPackageBeginEventArgs(wzPackageId, wzCompatiblePackageId, wzCompatiblePackageVersion, recommendedRemove, pRequestedRemove, fCancel); | ||
1524 | this.OnPlanCompatibleMsiPackageBegin(args); | ||
1525 | |||
1526 | pRequestedRemove = args.RequestRemove; | ||
1527 | fCancel = args.Cancel; | ||
1528 | return args.HResult; | ||
1529 | } | ||
1530 | |||
1531 | int IBootstrapperApplication.OnPlanCompatibleMsiPackageComplete(string wzPackageId, string wzCompatiblePackageId, int hrStatus, bool requestedRemove) | ||
1532 | { | ||
1533 | PlanCompatibleMsiPackageCompleteEventArgs args = new PlanCompatibleMsiPackageCompleteEventArgs(wzPackageId, wzCompatiblePackageId, hrStatus, requestedRemove); | ||
1534 | this.OnPlanCompatibleMsiPackageComplete(args); | ||
1535 | |||
1536 | return args.HResult; | ||
1537 | } | ||
1538 | |||
1448 | int IBootstrapperApplication.OnPlanPatchTarget(string wzPackageId, string wzProductCode, RequestState recommendedState, ref RequestState pRequestedState, ref bool fCancel) | 1539 | int IBootstrapperApplication.OnPlanPatchTarget(string wzPackageId, string wzProductCode, RequestState recommendedState, ref RequestState pRequestedState, ref bool fCancel) |
1449 | { | 1540 | { |
1450 | PlanPatchTargetEventArgs args = new PlanPatchTargetEventArgs(wzPackageId, wzProductCode, recommendedState, pRequestedState, fCancel); | 1541 | PlanPatchTargetEventArgs args = new PlanPatchTargetEventArgs(wzPackageId, wzProductCode, recommendedState, pRequestedState, fCancel); |
@@ -1486,6 +1577,14 @@ namespace WixToolset.Mba.Core | |||
1486 | return args.HResult; | 1577 | return args.HResult; |
1487 | } | 1578 | } |
1488 | 1579 | ||
1580 | int IBootstrapperApplication.OnPlannedCompatiblePackage(string wzPackageId, string wzCompatiblePackageId, bool remove) | ||
1581 | { | ||
1582 | var args = new PlannedCompatiblePackageEventArgs(wzPackageId, wzCompatiblePackageId, remove); | ||
1583 | this.OnPlannedCompatiblePackage(args); | ||
1584 | |||
1585 | return args.HResult; | ||
1586 | } | ||
1587 | |||
1489 | int IBootstrapperApplication.OnPlannedPackage(string wzPackageId, ActionState execute, ActionState rollback, bool fPlannedCache, bool fPlannedUncache) | 1588 | int IBootstrapperApplication.OnPlannedPackage(string wzPackageId, ActionState execute, ActionState rollback, bool fPlannedCache, bool fPlannedUncache) |
1490 | { | 1589 | { |
1491 | var args = new PlannedPackageEventArgs(wzPackageId, execute, rollback, fPlannedCache, fPlannedUncache); | 1590 | var args = new PlannedPackageEventArgs(wzPackageId, execute, rollback, fPlannedCache, fPlannedUncache); |
diff --git a/src/api/burn/WixToolset.Mba.Core/EventArgs.cs b/src/api/burn/WixToolset.Mba.Core/EventArgs.cs index 93831be6..d4d70651 100644 --- a/src/api/burn/WixToolset.Mba.Core/EventArgs.cs +++ b/src/api/burn/WixToolset.Mba.Core/EventArgs.cs | |||
@@ -496,6 +496,37 @@ namespace WixToolset.Mba.Core | |||
496 | } | 496 | } |
497 | 497 | ||
498 | /// <summary> | 498 | /// <summary> |
499 | /// Event arguments for <see cref="IDefaultBootstrapperApplication.DetectCompatibleMsiPackage"/> | ||
500 | /// </summary> | ||
501 | [Serializable] | ||
502 | public class DetectCompatibleMsiPackageEventArgs : CancellableHResultEventArgs | ||
503 | { | ||
504 | /// <summary /> | ||
505 | public DetectCompatibleMsiPackageEventArgs(string packageId, string compatiblePackageId, string compatiblePackageVersion, bool cancelRecommendation) | ||
506 | : base(cancelRecommendation) | ||
507 | { | ||
508 | this.PackageId = packageId; | ||
509 | this.CompatiblePackageId = compatiblePackageId; | ||
510 | this.CompatiblePackageVersion = compatiblePackageVersion; | ||
511 | } | ||
512 | |||
513 | /// <summary> | ||
514 | /// Gets the identity of the package that was not detected. | ||
515 | /// </summary> | ||
516 | public string PackageId { get; private set; } | ||
517 | |||
518 | /// <summary> | ||
519 | /// Gets the identity of the compatible package that was detected. | ||
520 | /// </summary> | ||
521 | public string CompatiblePackageId { get; private set; } | ||
522 | |||
523 | /// <summary> | ||
524 | /// Gets the version of the compatible package that was detected. | ||
525 | /// </summary> | ||
526 | public string CompatiblePackageVersion { get; private set; } | ||
527 | } | ||
528 | |||
529 | /// <summary> | ||
499 | /// Event arguments for <see cref="IDefaultBootstrapperApplication.DetectRelatedMsiPackage"/> | 530 | /// Event arguments for <see cref="IDefaultBootstrapperApplication.DetectRelatedMsiPackage"/> |
500 | /// </summary> | 531 | /// </summary> |
501 | [Serializable] | 532 | [Serializable] |
@@ -776,6 +807,80 @@ namespace WixToolset.Mba.Core | |||
776 | } | 807 | } |
777 | 808 | ||
778 | /// <summary> | 809 | /// <summary> |
810 | /// Event arguments for <see cref="IDefaultBootstrapperApplication.PlanCompatibleMsiPackageBegin"/> | ||
811 | /// </summary> | ||
812 | [Serializable] | ||
813 | public class PlanCompatibleMsiPackageBeginEventArgs : CancellableHResultEventArgs | ||
814 | { | ||
815 | /// <summary /> | ||
816 | public PlanCompatibleMsiPackageBeginEventArgs(string packageId, string compatiblePackageId, string compatiblePackageVersion, bool recommendedRemove, bool requestRemove, bool cancelRecommendation) | ||
817 | : base(cancelRecommendation) | ||
818 | { | ||
819 | this.PackageId = packageId; | ||
820 | this.CompatiblePackageId = compatiblePackageId; | ||
821 | this.CompatiblePackageVersion = compatiblePackageVersion; | ||
822 | this.RecommendedRemove = recommendedRemove; | ||
823 | this.RequestRemove = requestRemove; | ||
824 | } | ||
825 | |||
826 | /// <summary> | ||
827 | /// Gets the identity of the package that was not detected. | ||
828 | /// </summary> | ||
829 | public string PackageId { get; private set; } | ||
830 | |||
831 | /// <summary> | ||
832 | /// Gets the identity of the compatible package detected. | ||
833 | /// </summary> | ||
834 | public string CompatiblePackageId { get; private set; } | ||
835 | |||
836 | /// <summary> | ||
837 | /// Gets the version of the compatible package detected. | ||
838 | /// </summary> | ||
839 | public string CompatiblePackageVersion { get; private set; } | ||
840 | |||
841 | /// <summary> | ||
842 | /// Gets the recommended state to use for the compatible package for planning. | ||
843 | /// </summary> | ||
844 | public bool RecommendedRemove { get; private set; } | ||
845 | |||
846 | /// <summary> | ||
847 | /// Gets or sets whether to uninstall the compatible package. | ||
848 | /// </summary> | ||
849 | public bool RequestRemove { get; set; } | ||
850 | } | ||
851 | |||
852 | /// <summary> | ||
853 | /// Event arguments for <see cref="IDefaultBootstrapperApplication.PlanCompatibleMsiPackageComplete"/> | ||
854 | /// </summary> | ||
855 | [Serializable] | ||
856 | public class PlanCompatibleMsiPackageCompleteEventArgs : StatusEventArgs | ||
857 | { | ||
858 | /// <summary /> | ||
859 | public PlanCompatibleMsiPackageCompleteEventArgs(string packageId, string compatiblePackageId, int hrStatus, bool requestedRemove) | ||
860 | : base(hrStatus) | ||
861 | { | ||
862 | this.PackageId = packageId; | ||
863 | this.CompatiblePackageId = compatiblePackageId; | ||
864 | this.RequestedRemove = requestedRemove; | ||
865 | } | ||
866 | |||
867 | /// <summary> | ||
868 | /// Gets the identity of the package planned for. | ||
869 | /// </summary> | ||
870 | public string PackageId { get; private set; } | ||
871 | |||
872 | /// <summary> | ||
873 | /// Gets the identity of the compatible package detected. | ||
874 | /// </summary> | ||
875 | public string CompatiblePackageId { get; private set; } | ||
876 | |||
877 | /// <summary> | ||
878 | /// Gets the requested state of the package. | ||
879 | /// </summary> | ||
880 | public bool RequestedRemove { get; private set; } | ||
881 | } | ||
882 | |||
883 | /// <summary> | ||
779 | /// Event arguments for <see cref="IDefaultBootstrapperApplication.PlanRollbackBoundary"/> | 884 | /// Event arguments for <see cref="IDefaultBootstrapperApplication.PlanRollbackBoundary"/> |
780 | /// </summary> | 885 | /// </summary> |
781 | [Serializable] | 886 | [Serializable] |
@@ -981,6 +1086,36 @@ namespace WixToolset.Mba.Core | |||
981 | } | 1086 | } |
982 | 1087 | ||
983 | /// <summary> | 1088 | /// <summary> |
1089 | /// Event arguments for <see cref="IDefaultBootstrapperApplication.PlannedCompatiblePackage"/> | ||
1090 | /// </summary> | ||
1091 | [Serializable] | ||
1092 | public class PlannedCompatiblePackageEventArgs : HResultEventArgs | ||
1093 | { | ||
1094 | /// <summary /> | ||
1095 | public PlannedCompatiblePackageEventArgs(string packageId, string compatiblePackageId, bool remove) | ||
1096 | { | ||
1097 | this.PackageId = packageId; | ||
1098 | this.CompatiblePackageId = compatiblePackageId; | ||
1099 | this.Remove = remove; | ||
1100 | } | ||
1101 | |||
1102 | /// <summary> | ||
1103 | /// Gets the identity of the package planned for. | ||
1104 | /// </summary> | ||
1105 | public string PackageId { get; private set; } | ||
1106 | |||
1107 | /// <summary> | ||
1108 | /// Gets the identity of the compatible package detected. | ||
1109 | /// </summary> | ||
1110 | public string CompatiblePackageId { get; private set; } | ||
1111 | |||
1112 | /// <summary> | ||
1113 | /// Gets the planned state of the package. | ||
1114 | /// </summary> | ||
1115 | public bool Remove { get; private set; } | ||
1116 | } | ||
1117 | |||
1118 | /// <summary> | ||
984 | /// Event arguments for <see cref="IDefaultBootstrapperApplication.PlannedPackage"/> | 1119 | /// Event arguments for <see cref="IDefaultBootstrapperApplication.PlannedPackage"/> |
985 | /// </summary> | 1120 | /// </summary> |
986 | [Serializable] | 1121 | [Serializable] |
diff --git a/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs b/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs index babd523a..05f96106 100644 --- a/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs +++ b/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs | |||
@@ -182,16 +182,20 @@ namespace WixToolset.Mba.Core | |||
182 | ); | 182 | ); |
183 | 183 | ||
184 | /// <summary> | 184 | /// <summary> |
185 | /// See <see cref="IDefaultBootstrapperApplication.DetectCompatibleMsiPackage"/>. | ||
186 | /// </summary> | ||
187 | [PreserveSig] | ||
188 | [return: MarshalAs(UnmanagedType.I4)] | ||
189 | int OnDetectCompatibleMsiPackage( | ||
190 | [MarshalAs(UnmanagedType.LPWStr)] string wzPackageId, | ||
191 | [MarshalAs(UnmanagedType.LPWStr)] string wzCompatiblePackageId, | ||
192 | [MarshalAs(UnmanagedType.LPWStr)] string wzCompatiblePackageVersion, | ||
193 | [MarshalAs(UnmanagedType.Bool)] ref bool fCancel | ||
194 | ); | ||
195 | |||
196 | /// <summary> | ||
185 | /// See <see cref="IDefaultBootstrapperApplication.DetectRelatedMsiPackage"/>. | 197 | /// See <see cref="IDefaultBootstrapperApplication.DetectRelatedMsiPackage"/>. |
186 | /// </summary> | 198 | /// </summary> |
187 | /// <param name="wzPackageId"></param> | ||
188 | /// <param name="wzUpgradeCode"></param> | ||
189 | /// <param name="wzProductCode"></param> | ||
190 | /// <param name="fPerMachine"></param> | ||
191 | /// <param name="wzVersion"></param> | ||
192 | /// <param name="operation"></param> | ||
193 | /// <param name="fCancel"></param> | ||
194 | /// <returns></returns> | ||
195 | [PreserveSig] | 199 | [PreserveSig] |
196 | [return: MarshalAs(UnmanagedType.I4)] | 200 | [return: MarshalAs(UnmanagedType.I4)] |
197 | int OnDetectRelatedMsiPackage( | 201 | int OnDetectRelatedMsiPackage( |
@@ -318,6 +322,32 @@ namespace WixToolset.Mba.Core | |||
318 | ); | 322 | ); |
319 | 323 | ||
320 | /// <summary> | 324 | /// <summary> |
325 | /// See <see cref="IDefaultBootstrapperApplication.PlanCompatibleMsiPackageBegin"/>. | ||
326 | /// </summary> | ||
327 | [PreserveSig] | ||
328 | [return: MarshalAs(UnmanagedType.I4)] | ||
329 | int OnPlanCompatibleMsiPackageBegin( | ||
330 | [MarshalAs(UnmanagedType.LPWStr)] string wzPackageId, | ||
331 | [MarshalAs(UnmanagedType.LPWStr)] string wzCompatiblePackageId, | ||
332 | [MarshalAs(UnmanagedType.LPWStr)] string wzCompatiblePackageVersion, | ||
333 | [MarshalAs(UnmanagedType.Bool)] bool fRecommendedRemove, | ||
334 | [MarshalAs(UnmanagedType.Bool)] ref bool fRequestRemove, | ||
335 | [MarshalAs(UnmanagedType.Bool)] ref bool fCancel | ||
336 | ); | ||
337 | |||
338 | /// <summary> | ||
339 | /// See <see cref="IDefaultBootstrapperApplication.PlanCompatibleMsiPackageComplete"/>. | ||
340 | /// </summary> | ||
341 | [PreserveSig] | ||
342 | [return: MarshalAs(UnmanagedType.I4)] | ||
343 | int OnPlanCompatibleMsiPackageComplete( | ||
344 | [MarshalAs(UnmanagedType.LPWStr)] string wzPackageId, | ||
345 | [MarshalAs(UnmanagedType.LPWStr)] string wzCompatiblePackageId, | ||
346 | int hrStatus, | ||
347 | [MarshalAs(UnmanagedType.Bool)] bool fRequestedRemove | ||
348 | ); | ||
349 | |||
350 | /// <summary> | ||
321 | /// See <see cref="IDefaultBootstrapperApplication.PlanPatchTarget"/>. | 351 | /// See <see cref="IDefaultBootstrapperApplication.PlanPatchTarget"/>. |
322 | /// </summary> | 352 | /// </summary> |
323 | /// <param name="wzPackageId"></param> | 353 | /// <param name="wzPackageId"></param> |
@@ -388,6 +418,17 @@ namespace WixToolset.Mba.Core | |||
388 | ); | 418 | ); |
389 | 419 | ||
390 | /// <summary> | 420 | /// <summary> |
421 | /// See <see cref="IDefaultBootstrapperApplication.PlannedCompatiblePackage"/>. | ||
422 | /// </summary> | ||
423 | [PreserveSig] | ||
424 | [return: MarshalAs(UnmanagedType.I4)] | ||
425 | int OnPlannedCompatiblePackage( | ||
426 | [MarshalAs(UnmanagedType.LPWStr)] string wzPackageId, | ||
427 | [MarshalAs(UnmanagedType.LPWStr)] string wzCompatiblePackageId, | ||
428 | [MarshalAs(UnmanagedType.Bool)] bool fRemove | ||
429 | ); | ||
430 | |||
431 | /// <summary> | ||
391 | /// See <see cref="IDefaultBootstrapperApplication.PlannedPackage"/>. | 432 | /// See <see cref="IDefaultBootstrapperApplication.PlannedPackage"/>. |
392 | /// </summary> | 433 | /// </summary> |
393 | [PreserveSig] | 434 | [PreserveSig] |
diff --git a/src/api/burn/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs b/src/api/burn/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs index e809a965..ce06408e 100644 --- a/src/api/burn/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs +++ b/src/api/burn/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs | |||
@@ -134,6 +134,11 @@ namespace WixToolset.Mba.Core | |||
134 | event EventHandler<DetectBeginEventArgs> DetectBegin; | 134 | event EventHandler<DetectBeginEventArgs> DetectBegin; |
135 | 135 | ||
136 | /// <summary> | 136 | /// <summary> |
137 | /// Fired when a package was not detected but a package using the same provider key was. | ||
138 | /// </summary> | ||
139 | event EventHandler<DetectCompatibleMsiPackageEventArgs> DetectCompatibleMsiPackage; | ||
140 | |||
141 | /// <summary> | ||
137 | /// Fired when the detection phase has completed. | 142 | /// Fired when the detection phase has completed. |
138 | /// </summary> | 143 | /// </summary> |
139 | event EventHandler<DetectCompleteEventArgs> DetectComplete; | 144 | event EventHandler<DetectCompleteEventArgs> DetectComplete; |
@@ -269,6 +274,16 @@ namespace WixToolset.Mba.Core | |||
269 | event EventHandler<PlanBeginEventArgs> PlanBegin; | 274 | event EventHandler<PlanBeginEventArgs> PlanBegin; |
270 | 275 | ||
271 | /// <summary> | 276 | /// <summary> |
277 | /// Fired when the engine plans a new, compatible package using the same provider key. | ||
278 | /// </summary> | ||
279 | event EventHandler<PlanCompatibleMsiPackageBeginEventArgs> PlanCompatibleMsiPackageBegin; | ||
280 | |||
281 | /// <summary> | ||
282 | /// Fired when the engine has completed planning the installation of a specific package. | ||
283 | /// </summary> | ||
284 | event EventHandler<PlanCompatibleMsiPackageCompleteEventArgs> PlanCompatibleMsiPackageComplete; | ||
285 | |||
286 | /// <summary> | ||
272 | /// Fired when the engine has completed planning the installation. | 287 | /// Fired when the engine has completed planning the installation. |
273 | /// </summary> | 288 | /// </summary> |
274 | event EventHandler<PlanCompleteEventArgs> PlanComplete; | 289 | event EventHandler<PlanCompleteEventArgs> PlanComplete; |
@@ -279,6 +294,11 @@ namespace WixToolset.Mba.Core | |||
279 | event EventHandler<PlanForwardCompatibleBundleEventArgs> PlanForwardCompatibleBundle; | 294 | event EventHandler<PlanForwardCompatibleBundleEventArgs> PlanForwardCompatibleBundle; |
280 | 295 | ||
281 | /// <summary> | 296 | /// <summary> |
297 | /// Fired when the engine has completed planning a compatible package. | ||
298 | /// </summary> | ||
299 | event EventHandler<PlannedCompatiblePackageEventArgs> PlannedCompatiblePackage; | ||
300 | |||
301 | /// <summary> | ||
282 | /// Fired when the engine has completed planning a package. | 302 | /// Fired when the engine has completed planning a package. |
283 | /// </summary> | 303 | /// </summary> |
284 | event EventHandler<PlannedPackageEventArgs> PlannedPackage; | 304 | event EventHandler<PlannedPackageEventArgs> PlannedPackage; |
@@ -399,4 +419,4 @@ namespace WixToolset.Mba.Core | |||
399 | /// </summary> | 419 | /// </summary> |
400 | event EventHandler<UnregisterCompleteEventArgs> UnregisterComplete; | 420 | event EventHandler<UnregisterCompleteEventArgs> UnregisterComplete; |
401 | } | 421 | } |
402 | } \ No newline at end of file | 422 | } |
diff --git a/src/api/burn/balutil/inc/BAFunctions.h b/src/api/burn/balutil/inc/BAFunctions.h index 2698a6e3..84359d65 100644 --- a/src/api/burn/balutil/inc/BAFunctions.h +++ b/src/api/burn/balutil/inc/BAFunctions.h | |||
@@ -84,6 +84,10 @@ enum BA_FUNCTIONS_MESSAGE | |||
84 | BA_FUNCTIONS_MESSAGE_ONPLANROLLBACKBOUNDARY = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANROLLBACKBOUNDARY, | 84 | BA_FUNCTIONS_MESSAGE_ONPLANROLLBACKBOUNDARY = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANROLLBACKBOUNDARY, |
85 | BA_FUNCTIONS_MESSAGE_ONSETUPDATEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATEBEGIN, | 85 | BA_FUNCTIONS_MESSAGE_ONSETUPDATEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATEBEGIN, |
86 | BA_FUNCTIONS_MESSAGE_ONSETUPDATECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATECOMPLETE, | 86 | BA_FUNCTIONS_MESSAGE_ONSETUPDATECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATECOMPLETE, |
87 | BA_FUNCTIONS_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE, | ||
88 | BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN, | ||
89 | BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, | ||
90 | BA_FUNCTIONS_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE, | ||
87 | 91 | ||
88 | BA_FUNCTIONS_MESSAGE_ONTHEMELOADED = 1024, | 92 | BA_FUNCTIONS_MESSAGE_ONTHEMELOADED = 1024, |
89 | BA_FUNCTIONS_MESSAGE_WNDPROC, | 93 | BA_FUNCTIONS_MESSAGE_WNDPROC, |
diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctions.h b/src/api/burn/balutil/inc/BalBaseBAFunctions.h index 22e16f1b..c6d0924f 100644 --- a/src/api/burn/balutil/inc/BalBaseBAFunctions.h +++ b/src/api/burn/balutil/inc/BalBaseBAFunctions.h | |||
@@ -182,6 +182,16 @@ public: // IBootstrapperApplication | |||
182 | return S_OK; | 182 | return S_OK; |
183 | } | 183 | } |
184 | 184 | ||
185 | virtual STDMETHODIMP OnDetectCompatibleMsiPackage( | ||
186 | __in_z LPCWSTR /*wzPackageId*/, | ||
187 | __in_z LPCWSTR /*wzCompatiblePackageId*/, | ||
188 | __in LPCWSTR /*wzCompatiblePackageVersion*/, | ||
189 | __inout BOOL* /*pfCancel*/ | ||
190 | ) | ||
191 | { | ||
192 | return S_OK; | ||
193 | } | ||
194 | |||
185 | virtual STDMETHODIMP OnDetectRelatedMsiPackage( | 195 | virtual STDMETHODIMP OnDetectRelatedMsiPackage( |
186 | __in_z LPCWSTR /*wzPackageId*/, | 196 | __in_z LPCWSTR /*wzPackageId*/, |
187 | __in_z LPCWSTR /*wzUpgradeCode*/, | 197 | __in_z LPCWSTR /*wzUpgradeCode*/, |
@@ -276,6 +286,28 @@ public: // IBootstrapperApplication | |||
276 | return S_OK; | 286 | return S_OK; |
277 | } | 287 | } |
278 | 288 | ||
289 | virtual STDMETHODIMP OnPlanCompatibleMsiPackageBegin( | ||
290 | __in_z LPCWSTR /*wzPackageId*/, | ||
291 | __in_z LPCWSTR /*wzCompatiblePackageId*/, | ||
292 | __in LPCWSTR /*wzCompatiblePackageVersion*/, | ||
293 | __in BOOL /*fRecommendedRemove*/, | ||
294 | __inout BOOL* /*pfRequestRemove*/, | ||
295 | __inout BOOL* /*pfCancel*/ | ||
296 | ) | ||
297 | { | ||
298 | return S_OK; | ||
299 | } | ||
300 | |||
301 | virtual STDMETHODIMP OnPlanCompatibleMsiPackageComplete( | ||
302 | __in_z LPCWSTR /*wzPackageId*/, | ||
303 | __in_z LPCWSTR /*wzCompatiblePackageId*/, | ||
304 | __in HRESULT /*hrStatus*/, | ||
305 | __in BOOL /*fRequestedRemove*/ | ||
306 | ) | ||
307 | { | ||
308 | return S_OK; | ||
309 | } | ||
310 | |||
279 | virtual STDMETHODIMP OnPlanPatchTarget( | 311 | virtual STDMETHODIMP OnPlanPatchTarget( |
280 | __in_z LPCWSTR /*wzPackageId*/, | 312 | __in_z LPCWSTR /*wzPackageId*/, |
281 | __in_z LPCWSTR /*wzProductCode*/, | 313 | __in_z LPCWSTR /*wzProductCode*/, |
@@ -322,6 +354,15 @@ public: // IBootstrapperApplication | |||
322 | return S_OK; | 354 | return S_OK; |
323 | } | 355 | } |
324 | 356 | ||
357 | virtual STDMETHODIMP OnPlannedCompatiblePackage( | ||
358 | __in_z LPCWSTR /*wzPackageId*/, | ||
359 | __in_z LPCWSTR /*wzCompatiblePackageId*/, | ||
360 | __in BOOL /*fRemove*/ | ||
361 | ) | ||
362 | { | ||
363 | return S_OK; | ||
364 | } | ||
365 | |||
325 | virtual STDMETHODIMP OnPlannedPackage( | 366 | virtual STDMETHODIMP OnPlannedPackage( |
326 | __in_z LPCWSTR /*wzPackageId*/, | 367 | __in_z LPCWSTR /*wzPackageId*/, |
327 | __in BOOTSTRAPPER_ACTION_STATE /*execute*/, | 368 | __in BOOTSTRAPPER_ACTION_STATE /*execute*/, |
diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h b/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h index 1ab0df59..5d5ff098 100644 --- a/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h +++ b/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h | |||
@@ -155,6 +155,10 @@ static HRESULT WINAPI BalBaseBAFunctionsProc( | |||
155 | case BA_FUNCTIONS_MESSAGE_ONPLANROLLBACKBOUNDARY: | 155 | case BA_FUNCTIONS_MESSAGE_ONPLANROLLBACKBOUNDARY: |
156 | case BA_FUNCTIONS_MESSAGE_ONSETUPDATEBEGIN: | 156 | case BA_FUNCTIONS_MESSAGE_ONSETUPDATEBEGIN: |
157 | case BA_FUNCTIONS_MESSAGE_ONSETUPDATECOMPLETE: | 157 | case BA_FUNCTIONS_MESSAGE_ONSETUPDATECOMPLETE: |
158 | case BA_FUNCTIONS_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE: | ||
159 | case BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN: | ||
160 | case BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE: | ||
161 | case BA_FUNCTIONS_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE: | ||
158 | hr = BalBaseBootstrapperApplicationProc((BOOTSTRAPPER_APPLICATION_MESSAGE)message, pvArgs, pvResults, pvContext); | 162 | hr = BalBaseBootstrapperApplicationProc((BOOTSTRAPPER_APPLICATION_MESSAGE)message, pvArgs, pvResults, pvContext); |
159 | break; | 163 | break; |
160 | case BA_FUNCTIONS_MESSAGE_ONTHEMELOADED: | 164 | case BA_FUNCTIONS_MESSAGE_ONTHEMELOADED: |
diff --git a/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h b/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h index 631d3c62..e1a36fdf 100644 --- a/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h +++ b/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h | |||
@@ -189,6 +189,17 @@ public: // IBootstrapperApplication | |||
189 | return S_OK; | 189 | return S_OK; |
190 | } | 190 | } |
191 | 191 | ||
192 | virtual STDMETHODIMP OnDetectCompatibleMsiPackage( | ||
193 | __in_z LPCWSTR /*wzPackageId*/, | ||
194 | __in_z LPCWSTR /*wzCompatiblePackageId*/, | ||
195 | __in LPCWSTR /*wzCompatiblePackageVersion*/, | ||
196 | __inout BOOL* pfCancel | ||
197 | ) | ||
198 | { | ||
199 | *pfCancel |= CheckCanceled(); | ||
200 | return S_OK; | ||
201 | } | ||
202 | |||
192 | virtual STDMETHODIMP OnDetectRelatedMsiPackage( | 203 | virtual STDMETHODIMP OnDetectRelatedMsiPackage( |
193 | __in_z LPCWSTR /*wzPackageId*/, | 204 | __in_z LPCWSTR /*wzPackageId*/, |
194 | __in_z LPCWSTR /*wzUpgradeCode*/, | 205 | __in_z LPCWSTR /*wzUpgradeCode*/, |
@@ -290,6 +301,29 @@ public: // IBootstrapperApplication | |||
290 | return S_OK; | 301 | return S_OK; |
291 | } | 302 | } |
292 | 303 | ||
304 | virtual STDMETHODIMP OnPlanCompatibleMsiPackageBegin( | ||
305 | __in_z LPCWSTR /*wzPackageId*/, | ||
306 | __in_z LPCWSTR /*wzCompatiblePackageId*/, | ||
307 | __in LPCWSTR /*wzCompatiblePackageVersion*/, | ||
308 | __in BOOL /*fRecommendedRemove*/, | ||
309 | __inout BOOL* /*pfRequestRemove*/, | ||
310 | __inout BOOL* pfCancel | ||
311 | ) | ||
312 | { | ||
313 | *pfCancel |= CheckCanceled(); | ||
314 | return S_OK; | ||
315 | } | ||
316 | |||
317 | virtual STDMETHODIMP OnPlanCompatibleMsiPackageComplete( | ||
318 | __in_z LPCWSTR /*wzPackageId*/, | ||
319 | __in_z LPCWSTR /*wzCompatiblePackageId*/, | ||
320 | __in HRESULT /*hrStatus*/, | ||
321 | __in BOOL /*fRequestedRemove*/ | ||
322 | ) | ||
323 | { | ||
324 | return S_OK; | ||
325 | } | ||
326 | |||
293 | virtual STDMETHODIMP OnPlanPatchTarget( | 327 | virtual STDMETHODIMP OnPlanPatchTarget( |
294 | __in_z LPCWSTR /*wzPackageId*/, | 328 | __in_z LPCWSTR /*wzPackageId*/, |
295 | __in_z LPCWSTR /*wzProductCode*/, | 329 | __in_z LPCWSTR /*wzProductCode*/, |
@@ -339,6 +373,15 @@ public: // IBootstrapperApplication | |||
339 | return S_OK; | 373 | return S_OK; |
340 | } | 374 | } |
341 | 375 | ||
376 | virtual STDMETHODIMP OnPlannedCompatiblePackage( | ||
377 | __in_z LPCWSTR /*wzPackageId*/, | ||
378 | __in_z LPCWSTR /*wzCompatiblePackageId*/, | ||
379 | __in BOOL /*fRemove*/ | ||
380 | ) | ||
381 | { | ||
382 | return S_OK; | ||
383 | } | ||
384 | |||
342 | virtual STDMETHODIMP OnPlannedPackage( | 385 | virtual STDMETHODIMP OnPlannedPackage( |
343 | __in_z LPCWSTR /*wzPackageId*/, | 386 | __in_z LPCWSTR /*wzPackageId*/, |
344 | __in BOOTSTRAPPER_ACTION_STATE /*execute*/, | 387 | __in BOOTSTRAPPER_ACTION_STATE /*execute*/, |
diff --git a/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h b/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h index b9866e4b..1ee5258e 100644 --- a/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h +++ b/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h | |||
@@ -126,6 +126,15 @@ static HRESULT BalBaseBAProcOnDetectPackageBegin( | |||
126 | return pBA->OnDetectPackageBegin(pArgs->wzPackageId, &pResults->fCancel); | 126 | return pBA->OnDetectPackageBegin(pArgs->wzPackageId, &pResults->fCancel); |
127 | } | 127 | } |
128 | 128 | ||
129 | static HRESULT BalBaseBAProcOnDetectCompatiblePackage( | ||
130 | __in IBootstrapperApplication* pBA, | ||
131 | __in BA_ONDETECTCOMPATIBLEMSIPACKAGE_ARGS* pArgs, | ||
132 | __inout BA_ONDETECTCOMPATIBLEMSIPACKAGE_RESULTS* pResults | ||
133 | ) | ||
134 | { | ||
135 | return pBA->OnDetectCompatibleMsiPackage(pArgs->wzPackageId, pArgs->wzCompatiblePackageId, pArgs->wzCompatiblePackageVersion, &pResults->fCancel); | ||
136 | } | ||
137 | |||
129 | static HRESULT BalBaseBAProcOnDetectRelatedMsiPackage( | 138 | static HRESULT BalBaseBAProcOnDetectRelatedMsiPackage( |
130 | __in IBootstrapperApplication* pBA, | 139 | __in IBootstrapperApplication* pBA, |
131 | __in BA_ONDETECTRELATEDMSIPACKAGE_ARGS* pArgs, | 140 | __in BA_ONDETECTRELATEDMSIPACKAGE_ARGS* pArgs, |
@@ -189,6 +198,24 @@ static HRESULT BalBaseBAProcOnPlanPackageBegin( | |||
189 | return pBA->OnPlanPackageBegin(pArgs->wzPackageId, pArgs->state, pArgs->fCached, pArgs->installCondition, pArgs->recommendedState, pArgs->recommendedCacheType, &pResults->requestedState, &pResults->requestedCacheType, &pResults->fCancel); | 198 | return pBA->OnPlanPackageBegin(pArgs->wzPackageId, pArgs->state, pArgs->fCached, pArgs->installCondition, pArgs->recommendedState, pArgs->recommendedCacheType, &pResults->requestedState, &pResults->requestedCacheType, &pResults->fCancel); |
190 | } | 199 | } |
191 | 200 | ||
201 | static HRESULT BalBaseBAProcOnPlanCompatibleMsiPackageBegin( | ||
202 | __in IBootstrapperApplication* pBA, | ||
203 | __in BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_ARGS* pArgs, | ||
204 | __inout BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_RESULTS* pResults | ||
205 | ) | ||
206 | { | ||
207 | return pBA->OnPlanCompatibleMsiPackageBegin(pArgs->wzPackageId, pArgs->wzCompatiblePackageId, pArgs->wzCompatiblePackageVersion, pArgs->fRecommendedRemove, &pResults->fRequestRemove, &pResults->fCancel); | ||
208 | } | ||
209 | |||
210 | static HRESULT BalBaseBAProcOnPlanCompatibleMsiPackageComplete( | ||
211 | __in IBootstrapperApplication* pBA, | ||
212 | __in BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_ARGS* pArgs, | ||
213 | __inout BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_RESULTS* /*pResults*/ | ||
214 | ) | ||
215 | { | ||
216 | return pBA->OnPlanCompatibleMsiPackageComplete(pArgs->wzPackageId, pArgs->wzCompatiblePackageId, pArgs->hrStatus, pArgs->fRequestedRemove); | ||
217 | } | ||
218 | |||
192 | static HRESULT BalBaseBAProcOnPlanPatchTarget( | 219 | static HRESULT BalBaseBAProcOnPlanPatchTarget( |
193 | __in IBootstrapperApplication* pBA, | 220 | __in IBootstrapperApplication* pBA, |
194 | __in BA_ONPLANPATCHTARGET_ARGS* pArgs, | 221 | __in BA_ONPLANPATCHTARGET_ARGS* pArgs, |
@@ -216,6 +243,15 @@ static HRESULT BalBaseBAProcOnPlanPackageComplete( | |||
216 | return pBA->OnPlanPackageComplete(pArgs->wzPackageId, pArgs->hrStatus, pArgs->requested); | 243 | return pBA->OnPlanPackageComplete(pArgs->wzPackageId, pArgs->hrStatus, pArgs->requested); |
217 | } | 244 | } |
218 | 245 | ||
246 | static HRESULT BalBaseBAProcOnPlannedCompatiblePackage( | ||
247 | __in IBootstrapperApplication* pBA, | ||
248 | __in BA_ONPLANNEDCOMPATIBLEPACKAGE_ARGS* pArgs, | ||
249 | __inout BA_ONPLANNEDCOMPATIBLEPACKAGE_RESULTS* /*pResults*/ | ||
250 | ) | ||
251 | { | ||
252 | return pBA->OnPlannedCompatiblePackage(pArgs->wzPackageId, pArgs->wzCompatiblePackageId, pArgs->fRemove); | ||
253 | } | ||
254 | |||
219 | static HRESULT BalBaseBAProcOnPlannedPackage( | 255 | static HRESULT BalBaseBAProcOnPlannedPackage( |
220 | __in IBootstrapperApplication* pBA, | 256 | __in IBootstrapperApplication* pBA, |
221 | __in BA_ONPLANNEDPACKAGE_ARGS* pArgs, | 257 | __in BA_ONPLANNEDPACKAGE_ARGS* pArgs, |
@@ -928,6 +964,18 @@ static HRESULT WINAPI BalBaseBootstrapperApplicationProc( | |||
928 | case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATECOMPLETE: | 964 | case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATECOMPLETE: |
929 | hr = BalBaseBAProcOnSetUpdateComplete(pBA, reinterpret_cast<BA_ONSETUPDATECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONSETUPDATECOMPLETE_RESULTS*>(pvResults)); | 965 | hr = BalBaseBAProcOnSetUpdateComplete(pBA, reinterpret_cast<BA_ONSETUPDATECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONSETUPDATECOMPLETE_RESULTS*>(pvResults)); |
930 | break; | 966 | break; |
967 | case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE: | ||
968 | hr = BalBaseBAProcOnDetectCompatiblePackage(pBA, reinterpret_cast<BA_ONDETECTCOMPATIBLEMSIPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTCOMPATIBLEMSIPACKAGE_RESULTS*>(pvResults)); | ||
969 | break; | ||
970 | case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN: | ||
971 | hr = BalBaseBAProcOnPlanCompatibleMsiPackageBegin(pBA, reinterpret_cast<BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_RESULTS*>(pvResults)); | ||
972 | break; | ||
973 | case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE: | ||
974 | hr = BalBaseBAProcOnPlanCompatibleMsiPackageComplete(pBA, reinterpret_cast<BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_RESULTS*>(pvResults)); | ||
975 | break; | ||
976 | case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE: | ||
977 | hr = BalBaseBAProcOnPlannedCompatiblePackage(pBA, reinterpret_cast<BA_ONPLANNEDCOMPATIBLEPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANNEDCOMPATIBLEPACKAGE_RESULTS*>(pvResults)); | ||
978 | break; | ||
931 | } | 979 | } |
932 | } | 980 | } |
933 | 981 | ||
diff --git a/src/api/burn/balutil/inc/IBootstrapperApplication.h b/src/api/burn/balutil/inc/IBootstrapperApplication.h index 577a705b..640f609d 100644 --- a/src/api/burn/balutil/inc/IBootstrapperApplication.h +++ b/src/api/burn/balutil/inc/IBootstrapperApplication.h | |||
@@ -101,6 +101,14 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A | |||
101 | __inout BOOL* pfCancel | 101 | __inout BOOL* pfCancel |
102 | ) = 0; | 102 | ) = 0; |
103 | 103 | ||
104 | // OnDetectCompatibleMsiPackage - called when the engine detects that a package is not installed but a newer package using the same provider key is. | ||
105 | STDMETHOD(OnDetectCompatibleMsiPackage)( | ||
106 | __in_z LPCWSTR wzPackageId, | ||
107 | __in_z LPCWSTR wzCompatiblePackageId, | ||
108 | __in_z LPCWSTR wzCompatiblePackageVersion, | ||
109 | __inout BOOL* pfCancel | ||
110 | ) = 0; | ||
111 | |||
104 | // OnDetectRelatedMsiPackage - called when the engine begins detects a related package. | 112 | // OnDetectRelatedMsiPackage - called when the engine begins detects a related package. |
105 | STDMETHOD(OnDetectRelatedMsiPackage)( | 113 | STDMETHOD(OnDetectRelatedMsiPackage)( |
106 | __in_z LPCWSTR wzPackageId, | 114 | __in_z LPCWSTR wzPackageId, |
@@ -181,6 +189,25 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A | |||
181 | __inout BOOL* pfCancel | 189 | __inout BOOL* pfCancel |
182 | ) = 0; | 190 | ) = 0; |
183 | 191 | ||
192 | // OnPlanCompatibleMsiPackageBegin - called when the engine plans a newer, compatible package using the same provider key. | ||
193 | STDMETHOD(OnPlanCompatibleMsiPackageBegin)( | ||
194 | __in_z LPCWSTR wzPackageId, | ||
195 | __in_z LPCWSTR wzCompatiblePackageId, | ||
196 | __in_z LPCWSTR wzCompatiblePackageVersion, | ||
197 | __in BOOL fRecommendedRemove, | ||
198 | __inout BOOL* pfRequestRemove, | ||
199 | __inout BOOL* pfCancel | ||
200 | ) = 0; | ||
201 | |||
202 | // OnPlanCompatibleMsiPackageComplete - called after the engine plans the package. | ||
203 | // | ||
204 | STDMETHOD(OnPlanCompatibleMsiPackageComplete)( | ||
205 | __in_z LPCWSTR wzPackageId, | ||
206 | __in_z LPCWSTR wzCompatiblePackageId, | ||
207 | __in HRESULT hrStatus, | ||
208 | __in BOOL fRequestedRemove | ||
209 | ) = 0; | ||
210 | |||
184 | // OnPlanPatchTarget - called when the engine is about to plan a target | 211 | // OnPlanPatchTarget - called when the engine is about to plan a target |
185 | // of an MSP package. | 212 | // of an MSP package. |
186 | STDMETHOD(OnPlanPatchTarget)( | 213 | STDMETHOD(OnPlanPatchTarget)( |
@@ -223,6 +250,13 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A | |||
223 | __in BOOTSTRAPPER_REQUEST_STATE requested | 250 | __in BOOTSTRAPPER_REQUEST_STATE requested |
224 | ) = 0; | 251 | ) = 0; |
225 | 252 | ||
253 | // OnPlannedCompatiblePackage - called after the engine has completed planning a compatible package. | ||
254 | STDMETHOD(OnPlannedCompatiblePackage)( | ||
255 | __in_z LPCWSTR wzPackageId, | ||
256 | __in_z LPCWSTR wzCompatiblePackageId, | ||
257 | __in BOOL fRemove | ||
258 | ) = 0; | ||
259 | |||
226 | // OnPlannedPackage - called after the engine has completed planning a package. | 260 | // OnPlannedPackage - called after the engine has completed planning a package. |
227 | STDMETHOD(OnPlannedPackage)( | 261 | STDMETHOD(OnPlannedPackage)( |
228 | __in_z LPCWSTR wzPackageId, | 262 | __in_z LPCWSTR wzPackageId, |
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp index 99884234..6bf3020c 100644 --- a/src/burn/engine/apply.cpp +++ b/src/burn/engine/apply.cpp | |||
@@ -60,7 +60,7 @@ typedef struct _BURN_EXECUTE_CONTEXT | |||
60 | BURN_USER_EXPERIENCE* pUX; | 60 | BURN_USER_EXPERIENCE* pUX; |
61 | BURN_APPLY_CONTEXT* pApplyContext; | 61 | BURN_APPLY_CONTEXT* pApplyContext; |
62 | BOOL fRollback; | 62 | BOOL fRollback; |
63 | BURN_PACKAGE* pExecutingPackage; | 63 | LPCWSTR wzExecutingPackageId; |
64 | DWORD cExecutedPackages; | 64 | DWORD cExecutedPackages; |
65 | DWORD cExecutePackagesTotal; | 65 | DWORD cExecutePackagesTotal; |
66 | } BURN_EXECUTE_CONTEXT; | 66 | } BURN_EXECUTE_CONTEXT; |
@@ -278,6 +278,19 @@ static void ResetTransactionRegistrationState( | |||
278 | __in BURN_ENGINE_STATE* pEngineState, | 278 | __in BURN_ENGINE_STATE* pEngineState, |
279 | __in BOOL fCommit | 279 | __in BOOL fCommit |
280 | ); | 280 | ); |
281 | static HRESULT ExecuteUninstallMsiCompatiblePackage( | ||
282 | __in BURN_ENGINE_STATE* pEngineState, | ||
283 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
284 | __in BURN_EXECUTE_CONTEXT* pContext, | ||
285 | __out BOOL* pfRetry, | ||
286 | __out BOOL* pfSuspend, | ||
287 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
288 | ); | ||
289 | static HRESULT CleanCompatiblePackage( | ||
290 | __in BURN_CACHE* pCache, | ||
291 | __in HANDLE hElevatedPipe, | ||
292 | __in BURN_PACKAGE* pPackage | ||
293 | ); | ||
281 | static HRESULT CleanPackage( | 294 | static HRESULT CleanPackage( |
282 | __in BURN_CACHE* pCache, | 295 | __in BURN_CACHE* pCache, |
283 | __in HANDLE hElevatedPipe, | 296 | __in HANDLE hElevatedPipe, |
@@ -300,7 +313,8 @@ static HRESULT ReportOverallProgressTicks( | |||
300 | static HRESULT ExecutePackageComplete( | 313 | static HRESULT ExecutePackageComplete( |
301 | __in BURN_USER_EXPERIENCE* pUX, | 314 | __in BURN_USER_EXPERIENCE* pUX, |
302 | __in BURN_VARIABLES* pVariables, | 315 | __in BURN_VARIABLES* pVariables, |
303 | __in BURN_PACKAGE* pPackage, | 316 | __in LPCWSTR wzPackageId, |
317 | __in BOOL fPackageVital, | ||
304 | __in HRESULT hrOverall, | 318 | __in HRESULT hrOverall, |
305 | __in HRESULT hrExecute, | 319 | __in HRESULT hrExecute, |
306 | __in BOOL fRollback, | 320 | __in BOOL fRollback, |
@@ -808,7 +822,20 @@ extern "C" void ApplyClean( | |||
808 | BURN_CLEAN_ACTION* pCleanAction = pPlan->rgCleanActions + i; | 822 | BURN_CLEAN_ACTION* pCleanAction = pPlan->rgCleanActions + i; |
809 | BURN_PACKAGE* pPackage = pCleanAction->pPackage; | 823 | BURN_PACKAGE* pPackage = pCleanAction->pPackage; |
810 | 824 | ||
811 | hr = CleanPackage(pPlan->pCache, hPipe, pPackage); | 825 | switch (pCleanAction->type) |
826 | { | ||
827 | case BURN_CLEAN_ACTION_TYPE_COMPATIBLE_PACKAGE: | ||
828 | hr = CleanCompatiblePackage(pPlan->pCache, hPipe, pPackage); | ||
829 | break; | ||
830 | |||
831 | case BURN_CLEAN_ACTION_TYPE_PACKAGE: | ||
832 | hr = CleanPackage(pPlan->pCache, hPipe, pPackage); | ||
833 | break; | ||
834 | |||
835 | default: | ||
836 | AssertSz(FALSE, "Unknown clean action."); | ||
837 | break; | ||
838 | } | ||
812 | } | 839 | } |
813 | } | 840 | } |
814 | 841 | ||
@@ -2350,6 +2377,11 @@ static HRESULT DoExecuteAction( | |||
2350 | ExitOnFailure(hr, "Failed to execute commit MSI transaction action."); | 2377 | ExitOnFailure(hr, "Failed to execute commit MSI transaction action."); |
2351 | break; | 2378 | break; |
2352 | 2379 | ||
2380 | case BURN_EXECUTE_ACTION_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE: | ||
2381 | hr = ExecuteUninstallMsiCompatiblePackage(pEngineState, pExecuteAction, pContext, &fRetry, pfSuspend, &restart); | ||
2382 | ExitOnFailure(hr, "Failed to execute uninstall MSI compatible package."); | ||
2383 | break; | ||
2384 | |||
2353 | default: | 2385 | default: |
2354 | hr = E_UNEXPECTED; | 2386 | hr = E_UNEXPECTED; |
2355 | ExitOnFailure(hr, "Invalid execute action."); | 2387 | ExitOnFailure(hr, "Invalid execute action."); |
@@ -2509,7 +2541,7 @@ static HRESULT ExecuteRelatedBundle( | |||
2509 | } | 2541 | } |
2510 | 2542 | ||
2511 | Assert(pContext->fRollback == fRollback); | 2543 | Assert(pContext->fRollback == fRollback); |
2512 | pContext->pExecutingPackage = pPackage; | 2544 | pContext->wzExecutingPackageId = pPackage->sczId; |
2513 | fBeginCalled = TRUE; | 2545 | fBeginCalled = TRUE; |
2514 | 2546 | ||
2515 | // Send package execute begin to BA. | 2547 | // Send package execute begin to BA. |
@@ -2550,7 +2582,7 @@ static HRESULT ExecuteRelatedBundle( | |||
2550 | LExit: | 2582 | LExit: |
2551 | if (fBeginCalled) | 2583 | if (fBeginCalled) |
2552 | { | 2584 | { |
2553 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 2585 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); |
2554 | } | 2586 | } |
2555 | 2587 | ||
2556 | return hr; | 2588 | return hr; |
@@ -2581,7 +2613,7 @@ static HRESULT ExecuteExePackage( | |||
2581 | } | 2613 | } |
2582 | 2614 | ||
2583 | Assert(pContext->fRollback == fRollback); | 2615 | Assert(pContext->fRollback == fRollback); |
2584 | pContext->pExecutingPackage = pPackage; | 2616 | pContext->wzExecutingPackageId = pPackage->sczId; |
2585 | fBeginCalled = TRUE; | 2617 | fBeginCalled = TRUE; |
2586 | 2618 | ||
2587 | // Send package execute begin to BA. | 2619 | // Send package execute begin to BA. |
@@ -2629,7 +2661,7 @@ LExit: | |||
2629 | 2661 | ||
2630 | if (fBeginCalled) | 2662 | if (fBeginCalled) |
2631 | { | 2663 | { |
2632 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 2664 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); |
2633 | } | 2665 | } |
2634 | 2666 | ||
2635 | return hr; | 2667 | return hr; |
@@ -2659,7 +2691,7 @@ static HRESULT ExecuteMsiPackage( | |||
2659 | } | 2691 | } |
2660 | 2692 | ||
2661 | Assert(pContext->fRollback == fRollback); | 2693 | Assert(pContext->fRollback == fRollback); |
2662 | pContext->pExecutingPackage = pPackage; | 2694 | pContext->wzExecutingPackageId = pPackage->sczId; |
2663 | fBeginCalled = TRUE; | 2695 | fBeginCalled = TRUE; |
2664 | 2696 | ||
2665 | // Send package execute begin to BA. | 2697 | // Send package execute begin to BA. |
@@ -2693,7 +2725,7 @@ LExit: | |||
2693 | 2725 | ||
2694 | if (fBeginCalled) | 2726 | if (fBeginCalled) |
2695 | { | 2727 | { |
2696 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 2728 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); |
2697 | } | 2729 | } |
2698 | 2730 | ||
2699 | return hr; | 2731 | return hr; |
@@ -2723,7 +2755,7 @@ static HRESULT ExecuteMspPackage( | |||
2723 | } | 2755 | } |
2724 | 2756 | ||
2725 | Assert(pContext->fRollback == fRollback); | 2757 | Assert(pContext->fRollback == fRollback); |
2726 | pContext->pExecutingPackage = pPackage; | 2758 | pContext->wzExecutingPackageId = pPackage->sczId; |
2727 | fBeginCalled = TRUE; | 2759 | fBeginCalled = TRUE; |
2728 | 2760 | ||
2729 | // Send package execute begin to BA. | 2761 | // Send package execute begin to BA. |
@@ -2766,7 +2798,7 @@ LExit: | |||
2766 | 2798 | ||
2767 | if (fBeginCalled) | 2799 | if (fBeginCalled) |
2768 | { | 2800 | { |
2769 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 2801 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); |
2770 | } | 2802 | } |
2771 | 2803 | ||
2772 | return hr; | 2804 | return hr; |
@@ -2798,7 +2830,7 @@ static HRESULT ExecuteMsuPackage( | |||
2798 | } | 2830 | } |
2799 | 2831 | ||
2800 | Assert(pContext->fRollback == fRollback); | 2832 | Assert(pContext->fRollback == fRollback); |
2801 | pContext->pExecutingPackage = pPackage; | 2833 | pContext->wzExecutingPackageId = pPackage->sczId; |
2802 | fBeginCalled = TRUE; | 2834 | fBeginCalled = TRUE; |
2803 | 2835 | ||
2804 | // Send package execute begin to BA. | 2836 | // Send package execute begin to BA. |
@@ -2846,7 +2878,7 @@ LExit: | |||
2846 | 2878 | ||
2847 | if (fBeginCalled) | 2879 | if (fBeginCalled) |
2848 | { | 2880 | { |
2849 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 2881 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); |
2850 | } | 2882 | } |
2851 | 2883 | ||
2852 | return hr; | 2884 | return hr; |
@@ -3110,6 +3142,79 @@ static void ResetTransactionRegistrationState( | |||
3110 | } | 3142 | } |
3111 | } | 3143 | } |
3112 | 3144 | ||
3145 | static HRESULT ExecuteUninstallMsiCompatiblePackage( | ||
3146 | __in BURN_ENGINE_STATE* pEngineState, | ||
3147 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
3148 | __in BURN_EXECUTE_CONTEXT* pContext, | ||
3149 | __out BOOL* pfRetry, | ||
3150 | __out BOOL* pfSuspend, | ||
3151 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
3152 | ) | ||
3153 | { | ||
3154 | HRESULT hr = S_OK; | ||
3155 | HRESULT hrExecute = S_OK; | ||
3156 | BOOL fRollback = FALSE; | ||
3157 | BOOTSTRAPPER_ACTION_STATE action = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; | ||
3158 | INSTALLUILEVEL uiLevel = INSTALLUILEVEL_NONE; | ||
3159 | BOOL fDisableExternalUiHandler = FALSE; | ||
3160 | BOOL fBeginCalled = FALSE; | ||
3161 | BURN_PACKAGE* pParentPackage = pExecuteAction->uninstallMsiCompatiblePackage.pParentPackage; | ||
3162 | |||
3163 | Assert(pContext->fRollback == fRollback); | ||
3164 | pContext->wzExecutingPackageId = pParentPackage->compatiblePackage.compatibleEntry.sczId; | ||
3165 | fBeginCalled = TRUE; | ||
3166 | |||
3167 | // Send package execute begin to BA. | ||
3168 | hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pContext->wzExecutingPackageId, !fRollback, action, uiLevel, fDisableExternalUiHandler); | ||
3169 | ExitOnRootFailure(hr, "BA aborted execute MSI compatible package begin."); | ||
3170 | |||
3171 | // execute package | ||
3172 | if (pParentPackage->fPerMachine) | ||
3173 | { | ||
3174 | hrExecute = ElevationUninstallMsiCompatiblePackage(pEngineState->companionConnection.hPipe, pEngineState->userExperience.hwndApply, pExecuteAction, &pEngineState->variables, fRollback, MsiExecuteMessageHandler, pContext, pRestart); | ||
3175 | ExitOnFailure(hrExecute, "Failed to uninstall per-machine MSI compatible package."); | ||
3176 | } | ||
3177 | else | ||
3178 | { | ||
3179 | hrExecute = MsiEngineUninstallCompatiblePackage(pEngineState->userExperience.hwndApply, pExecuteAction, pContext->pCache, &pEngineState->variables, fRollback, MsiExecuteMessageHandler, pContext, pRestart); | ||
3180 | ExitOnFailure(hrExecute, "Failed to uninstall per-user MSI compatible package."); | ||
3181 | } | ||
3182 | |||
3183 | pContext->cExecutedPackages += fRollback ? -1 : 1; | ||
3184 | |||
3185 | hr = ReportOverallProgressTicks(&pEngineState->userExperience, fRollback, pEngineState->plan.cOverallProgressTicksTotal, pContext->pApplyContext); | ||
3186 | ExitOnRootFailure(hr, "BA aborted MSI compatible package execute progress."); | ||
3187 | |||
3188 | LExit: | ||
3189 | |||
3190 | if (fBeginCalled) | ||
3191 | { | ||
3192 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pContext->wzExecutingPackageId, FALSE, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | ||
3193 | } | ||
3194 | |||
3195 | return hr; | ||
3196 | } | ||
3197 | |||
3198 | static HRESULT CleanCompatiblePackage( | ||
3199 | __in BURN_CACHE* pCache, | ||
3200 | __in HANDLE hElevatedPipe, | ||
3201 | __in BURN_PACKAGE* pPackage | ||
3202 | ) | ||
3203 | { | ||
3204 | HRESULT hr = S_OK; | ||
3205 | |||
3206 | if (pPackage->fPerMachine) | ||
3207 | { | ||
3208 | hr = ElevationCleanCompatiblePackage(hElevatedPipe, pPackage); | ||
3209 | } | ||
3210 | else | ||
3211 | { | ||
3212 | hr = CacheRemovePackage(pCache, FALSE, pPackage->compatiblePackage.compatibleEntry.sczId, pPackage->compatiblePackage.sczCacheId); | ||
3213 | } | ||
3214 | |||
3215 | return hr; | ||
3216 | } | ||
3217 | |||
3113 | static HRESULT CleanPackage( | 3218 | static HRESULT CleanPackage( |
3114 | __in BURN_CACHE* pCache, | 3219 | __in BURN_CACHE* pCache, |
3115 | __in HANDLE hElevatedPipe, | 3220 | __in HANDLE hElevatedPipe, |
@@ -3150,16 +3255,16 @@ static int GenericExecuteMessageHandler( | |||
3150 | case GENERIC_EXECUTE_MESSAGE_PROGRESS: | 3255 | case GENERIC_EXECUTE_MESSAGE_PROGRESS: |
3151 | { | 3256 | { |
3152 | DWORD dwOverallProgress = pContext->cExecutePackagesTotal ? (pContext->cExecutedPackages * 100 + pMessage->progress.dwPercentage) / (pContext->cExecutePackagesTotal) : 0; | 3257 | DWORD dwOverallProgress = pContext->cExecutePackagesTotal ? (pContext->cExecutedPackages * 100 + pMessage->progress.dwPercentage) / (pContext->cExecutePackagesTotal) : 0; |
3153 | UserExperienceOnExecuteProgress(pContext->pUX, pContext->pExecutingPackage->sczId, pMessage->progress.dwPercentage, dwOverallProgress, &nResult); // ignore return value. | 3258 | UserExperienceOnExecuteProgress(pContext->pUX, pContext->wzExecutingPackageId, pMessage->progress.dwPercentage, dwOverallProgress, &nResult); // ignore return value. |
3154 | } | 3259 | } |
3155 | break; | 3260 | break; |
3156 | 3261 | ||
3157 | case GENERIC_EXECUTE_MESSAGE_ERROR: | 3262 | case GENERIC_EXECUTE_MESSAGE_ERROR: |
3158 | UserExperienceOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_EXE_PACKAGE, pContext->pExecutingPackage->sczId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwUIHint, 0, NULL, &nResult); // ignore return value. | 3263 | UserExperienceOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_EXE_PACKAGE, pContext->wzExecutingPackageId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwUIHint, 0, NULL, &nResult); // ignore return value. |
3159 | break; | 3264 | break; |
3160 | 3265 | ||
3161 | case GENERIC_EXECUTE_MESSAGE_NETFX_FILES_IN_USE: | 3266 | case GENERIC_EXECUTE_MESSAGE_NETFX_FILES_IN_USE: |
3162 | UserExperienceOnExecuteFilesInUse(pContext->pUX, pContext->pExecutingPackage->sczId, pMessage->filesInUse.cFiles, pMessage->filesInUse.rgwzFiles, BOOTSTRAPPER_FILES_IN_USE_TYPE_NETFX, &nResult); // ignore return value. | 3267 | UserExperienceOnExecuteFilesInUse(pContext->pUX, pContext->wzExecutingPackageId, pMessage->filesInUse.cFiles, pMessage->filesInUse.rgwzFiles, BOOTSTRAPPER_FILES_IN_USE_TYPE_NETFX, &nResult); // ignore return value. |
3163 | fPassthrough = TRUE; | 3268 | fPassthrough = TRUE; |
3164 | break; | 3269 | break; |
3165 | } | 3270 | } |
@@ -3188,25 +3293,25 @@ static int MsiExecuteMessageHandler( | |||
3188 | case WIU_MSI_EXECUTE_MESSAGE_PROGRESS: | 3293 | case WIU_MSI_EXECUTE_MESSAGE_PROGRESS: |
3189 | { | 3294 | { |
3190 | DWORD dwOverallProgress = pContext->cExecutePackagesTotal ? (pContext->cExecutedPackages * 100 + pMessage->progress.dwPercentage) / (pContext->cExecutePackagesTotal) : 0; | 3295 | DWORD dwOverallProgress = pContext->cExecutePackagesTotal ? (pContext->cExecutedPackages * 100 + pMessage->progress.dwPercentage) / (pContext->cExecutePackagesTotal) : 0; |
3191 | UserExperienceOnExecuteProgress(pContext->pUX, pContext->pExecutingPackage->sczId, pMessage->progress.dwPercentage, dwOverallProgress, &nResult); // ignore return value. | 3296 | UserExperienceOnExecuteProgress(pContext->pUX, pContext->wzExecutingPackageId, pMessage->progress.dwPercentage, dwOverallProgress, &nResult); // ignore return value. |
3192 | } | 3297 | } |
3193 | break; | 3298 | break; |
3194 | 3299 | ||
3195 | case WIU_MSI_EXECUTE_MESSAGE_ERROR: | 3300 | case WIU_MSI_EXECUTE_MESSAGE_ERROR: |
3196 | nResult = pMessage->nResultRecommendation; | 3301 | nResult = pMessage->nResultRecommendation; |
3197 | UserExperienceOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_WINDOWS_INSTALLER, pContext->pExecutingPackage->sczId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwUIHint, pMessage->cData, pMessage->rgwzData, &nResult); // ignore return value. | 3302 | UserExperienceOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_WINDOWS_INSTALLER, pContext->wzExecutingPackageId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwUIHint, pMessage->cData, pMessage->rgwzData, &nResult); // ignore return value. |
3198 | break; | 3303 | break; |
3199 | 3304 | ||
3200 | case WIU_MSI_EXECUTE_MESSAGE_MSI_MESSAGE: | 3305 | case WIU_MSI_EXECUTE_MESSAGE_MSI_MESSAGE: |
3201 | nResult = pMessage->nResultRecommendation; | 3306 | nResult = pMessage->nResultRecommendation; |
3202 | UserExperienceOnExecuteMsiMessage(pContext->pUX, pContext->pExecutingPackage->sczId, pMessage->msiMessage.mt, pMessage->dwUIHint, pMessage->msiMessage.wzMessage, pMessage->cData, pMessage->rgwzData, &nResult); // ignore return value. | 3307 | UserExperienceOnExecuteMsiMessage(pContext->pUX, pContext->wzExecutingPackageId, pMessage->msiMessage.mt, pMessage->dwUIHint, pMessage->msiMessage.wzMessage, pMessage->cData, pMessage->rgwzData, &nResult); // ignore return value. |
3203 | break; | 3308 | break; |
3204 | 3309 | ||
3205 | case WIU_MSI_EXECUTE_MESSAGE_MSI_RM_FILES_IN_USE: | 3310 | case WIU_MSI_EXECUTE_MESSAGE_MSI_RM_FILES_IN_USE: |
3206 | fRestartManager = TRUE; | 3311 | fRestartManager = TRUE; |
3207 | __fallthrough; | 3312 | __fallthrough; |
3208 | case WIU_MSI_EXECUTE_MESSAGE_MSI_FILES_IN_USE: | 3313 | case WIU_MSI_EXECUTE_MESSAGE_MSI_FILES_IN_USE: |
3209 | UserExperienceOnExecuteFilesInUse(pContext->pUX, pContext->pExecutingPackage->sczId, pMessage->msiFilesInUse.cFiles, pMessage->msiFilesInUse.rgwzFiles, fRestartManager ? BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI_RM : BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI, &nResult); // ignore return value. | 3314 | UserExperienceOnExecuteFilesInUse(pContext->pUX, pContext->wzExecutingPackageId, pMessage->msiFilesInUse.cFiles, pMessage->msiFilesInUse.rgwzFiles, fRestartManager ? BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI_RM : BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI, &nResult); // ignore return value. |
3210 | fPassthrough = TRUE; | 3315 | fPassthrough = TRUE; |
3211 | break; | 3316 | break; |
3212 | } | 3317 | } |
@@ -3246,7 +3351,8 @@ static HRESULT ReportOverallProgressTicks( | |||
3246 | static HRESULT ExecutePackageComplete( | 3351 | static HRESULT ExecutePackageComplete( |
3247 | __in BURN_USER_EXPERIENCE* pUX, | 3352 | __in BURN_USER_EXPERIENCE* pUX, |
3248 | __in BURN_VARIABLES* pVariables, | 3353 | __in BURN_VARIABLES* pVariables, |
3249 | __in BURN_PACKAGE* pPackage, | 3354 | __in LPCWSTR wzPackageId, |
3355 | __in BOOL fPackageVital, | ||
3250 | __in HRESULT hrOverall, | 3356 | __in HRESULT hrOverall, |
3251 | __in HRESULT hrExecute, | 3357 | __in HRESULT hrExecute, |
3252 | __in BOOL fRollback, | 3358 | __in BOOL fRollback, |
@@ -3256,10 +3362,10 @@ static HRESULT ExecutePackageComplete( | |||
3256 | ) | 3362 | ) |
3257 | { | 3363 | { |
3258 | HRESULT hr = FAILED(hrOverall) ? hrOverall : hrExecute; // if the overall function failed use that otherwise use the execution result. | 3364 | HRESULT hr = FAILED(hrOverall) ? hrOverall : hrExecute; // if the overall function failed use that otherwise use the execution result. |
3259 | BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION executePackageCompleteAction = FAILED(hrOverall) || SUCCEEDED(hrExecute) || pPackage->fVital ? BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_NONE : BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_IGNORE; | 3365 | BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION executePackageCompleteAction = FAILED(hrOverall) || SUCCEEDED(hrExecute) || fPackageVital ? BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_NONE : BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_IGNORE; |
3260 | 3366 | ||
3261 | // Send package execute complete to BA. | 3367 | // Send package execute complete to BA. |
3262 | UserExperienceOnExecutePackageComplete(pUX, pPackage->sczId, hr, *pRestart, &executePackageCompleteAction); | 3368 | UserExperienceOnExecutePackageComplete(pUX, wzPackageId, hr, *pRestart, &executePackageCompleteAction); |
3263 | if (BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_RESTART == executePackageCompleteAction) | 3369 | if (BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_RESTART == executePackageCompleteAction) |
3264 | { | 3370 | { |
3265 | *pRestart = BOOTSTRAPPER_APPLY_RESTART_INITIATED; | 3371 | *pRestart = BOOTSTRAPPER_APPLY_RESTART_INITIATED; |
@@ -3271,23 +3377,23 @@ static HRESULT ExecutePackageComplete( | |||
3271 | if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == *pRestart) | 3377 | if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == *pRestart) |
3272 | { | 3378 | { |
3273 | // Best effort to set the forced restart package variable. | 3379 | // Best effort to set the forced restart package variable. |
3274 | VariableSetString(pVariables, BURN_BUNDLE_FORCED_RESTART_PACKAGE, pPackage->sczId, TRUE, FALSE); | 3380 | VariableSetString(pVariables, BURN_BUNDLE_FORCED_RESTART_PACKAGE, wzPackageId, TRUE, FALSE); |
3275 | } | 3381 | } |
3276 | 3382 | ||
3277 | // If we're retrying, leave a message in the log file and say everything is okay. | 3383 | // If we're retrying, leave a message in the log file and say everything is okay. |
3278 | if (*pfRetry) | 3384 | if (*pfRetry) |
3279 | { | 3385 | { |
3280 | LogId(REPORT_STANDARD, MSG_APPLY_RETRYING_PACKAGE, pPackage->sczId, hrExecute); | 3386 | LogId(REPORT_STANDARD, MSG_APPLY_RETRYING_PACKAGE, wzPackageId, hrExecute); |
3281 | hr = S_OK; | 3387 | hr = S_OK; |
3282 | } | 3388 | } |
3283 | else if (SUCCEEDED(hrOverall) && FAILED(hrExecute) && BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_IGNORE == executePackageCompleteAction && !pPackage->fVital) // If we *only* failed to execute and the BA ignored this *not-vital* package, say everything is okay. | 3389 | else if (SUCCEEDED(hrOverall) && FAILED(hrExecute) && BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_IGNORE == executePackageCompleteAction && !fPackageVital) // If we *only* failed to execute and the BA ignored this *not-vital* package, say everything is okay. |
3284 | { | 3390 | { |
3285 | LogId(REPORT_STANDARD, MSG_APPLY_CONTINUING_NONVITAL_PACKAGE, pPackage->sczId, hrExecute); | 3391 | LogId(REPORT_STANDARD, MSG_APPLY_CONTINUING_NONVITAL_PACKAGE, wzPackageId, hrExecute); |
3286 | hr = S_OK; | 3392 | hr = S_OK; |
3287 | } | 3393 | } |
3288 | else | 3394 | else |
3289 | { | 3395 | { |
3290 | LogId(REPORT_STANDARD, MSG_APPLY_COMPLETED_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, hr, LoggingRestartToString(*pRestart)); | 3396 | LogId(REPORT_STANDARD, MSG_APPLY_COMPLETED_PACKAGE, LoggingRollbackOrExecute(fRollback), wzPackageId, hr, LoggingRestartToString(*pRestart)); |
3291 | } | 3397 | } |
3292 | 3398 | ||
3293 | return hr; | 3399 | return hr; |
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index d70810f2..7f7a915e 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp | |||
@@ -389,6 +389,7 @@ extern "C" HRESULT CoreDetect( | |||
389 | pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN; | 389 | pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN; |
390 | pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; | 390 | pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; |
391 | pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; | 391 | pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; |
392 | pPackage->compatiblePackage.fDetected = FALSE; | ||
392 | } | 393 | } |
393 | } | 394 | } |
394 | 395 | ||
@@ -2240,7 +2241,7 @@ static void LogPackages( | |||
2240 | } | 2241 | } |
2241 | 2242 | ||
2242 | 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)); | 2243 | 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)); |
2243 | 2244 | ||
2244 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type) | 2245 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type) |
2245 | { | 2246 | { |
2246 | if (pPackage->Msi.cFeatures) | 2247 | if (pPackage->Msi.cFeatures) |
@@ -2266,6 +2267,11 @@ static void LogPackages( | |||
2266 | LogId(REPORT_STANDARD, MSG_PLANNED_SLIPSTREAMED_MSP_TARGET, pSlipstreamMsp->pMspPackage->sczId, LoggingActionStateToString(pSlipstreamMsp->execute), LoggingActionStateToString(pSlipstreamMsp->rollback)); | 2267 | LogId(REPORT_STANDARD, MSG_PLANNED_SLIPSTREAMED_MSP_TARGET, pSlipstreamMsp->pMspPackage->sczId, LoggingActionStateToString(pSlipstreamMsp->execute), LoggingActionStateToString(pSlipstreamMsp->rollback)); |
2267 | } | 2268 | } |
2268 | } | 2269 | } |
2270 | |||
2271 | if (pPackage->compatiblePackage.fRemove) | ||
2272 | { | ||
2273 | LogId(REPORT_STANDARD, MSG_PLANNED_ORPHAN_PACKAGE_FROM_PROVIDER, pPackage->sczId, pPackage->compatiblePackage.compatibleEntry.sczId, pPackage->Msi.sczProductCode); | ||
2274 | } | ||
2269 | } | 2275 | } |
2270 | else if (BURN_PACKAGE_TYPE_MSP == pPackage->type && pPackage->Msp.cTargetProductCodes) | 2276 | else if (BURN_PACKAGE_TYPE_MSP == pPackage->type && pPackage->Msp.cTargetProductCodes) |
2271 | { | 2277 | { |
diff --git a/src/burn/engine/dependency.cpp b/src/burn/engine/dependency.cpp index 5d7e1a94..6ee95935 100644 --- a/src/burn/engine/dependency.cpp +++ b/src/burn/engine/dependency.cpp | |||
@@ -54,6 +54,10 @@ static HRESULT AddPackageDependencyActions( | |||
54 | __in const BURN_DEPENDENCY_ACTION dependencyRollbackAction | 54 | __in const BURN_DEPENDENCY_ACTION dependencyRollbackAction |
55 | ); | 55 | ); |
56 | 56 | ||
57 | static LPCWSTR GetPackageProviderId( | ||
58 | __in const BURN_PACKAGE* pPackage | ||
59 | ); | ||
60 | |||
57 | static HRESULT RegisterPackageProvider( | 61 | static HRESULT RegisterPackageProvider( |
58 | __in const BURN_PACKAGE* pPackage | 62 | __in const BURN_PACKAGE* pPackage |
59 | ); | 63 | ); |
@@ -299,6 +303,9 @@ extern "C" HRESULT DependencyDetectChainPackage( | |||
299 | hr = DetectPackageDependents(pPackage, pRegistration); | 303 | hr = DetectPackageDependents(pPackage, pRegistration); |
300 | ExitOnFailure(hr, "Failed to detect dependents for package '%ls'", pPackage->sczId); | 304 | ExitOnFailure(hr, "Failed to detect dependents for package '%ls'", pPackage->sczId); |
301 | 305 | ||
306 | hr = DependencyDetectCompatibleEntry(pPackage, pRegistration); | ||
307 | ExitOnFailure(hr, "Failed to detect compatible package for package '%ls'", pPackage->sczId); | ||
308 | |||
302 | LExit: | 309 | LExit: |
303 | return hr; | 310 | return hr; |
304 | } | 311 | } |
@@ -396,6 +403,8 @@ extern "C" HRESULT DependencyPlanPackageBegin( | |||
396 | STRINGDICT_HANDLE sdIgnoredDependents = NULL; | 403 | STRINGDICT_HANDLE sdIgnoredDependents = NULL; |
397 | BURN_DEPENDENCY_ACTION dependencyExecuteAction = BURN_DEPENDENCY_ACTION_NONE; | 404 | BURN_DEPENDENCY_ACTION dependencyExecuteAction = BURN_DEPENDENCY_ACTION_NONE; |
398 | BURN_DEPENDENCY_ACTION dependencyRollbackAction = BURN_DEPENDENCY_ACTION_NONE; | 405 | BURN_DEPENDENCY_ACTION dependencyRollbackAction = BURN_DEPENDENCY_ACTION_NONE; |
406 | BOOL fDependentBlocksUninstall = FALSE; | ||
407 | BOOL fAttemptingUninstall = BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->execute || pPackage->compatiblePackage.fRemove; | ||
399 | 408 | ||
400 | pPackage->dependencyExecute = BURN_DEPENDENCY_ACTION_NONE; | 409 | pPackage->dependencyExecute = BURN_DEPENDENCY_ACTION_NONE; |
401 | pPackage->dependencyRollback = BURN_DEPENDENCY_ACTION_NONE; | 410 | pPackage->dependencyRollback = BURN_DEPENDENCY_ACTION_NONE; |
@@ -415,7 +424,7 @@ extern "C" HRESULT DependencyPlanPackageBegin( | |||
415 | } | 424 | } |
416 | 425 | ||
417 | // If we're uninstalling the package, check if any dependents are registered. | 426 | // If we're uninstalling the package, check if any dependents are registered. |
418 | if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->execute) | 427 | if (fAttemptingUninstall) |
419 | { | 428 | { |
420 | // Build up a list of dependents to ignore, including the current bundle. | 429 | // Build up a list of dependents to ignore, including the current bundle. |
421 | hr = GetIgnoredDependents(pPackage, pPlan, &sdIgnoredDependents); | 430 | hr = GetIgnoredDependents(pPackage, pPlan, &sdIgnoredDependents); |
@@ -444,9 +453,9 @@ extern "C" HRESULT DependencyPlanPackageBegin( | |||
444 | { | 453 | { |
445 | hr = S_OK; | 454 | hr = S_OK; |
446 | 455 | ||
447 | if (!pPackage->fDependencyManagerWasHere) | 456 | if (!fDependentBlocksUninstall) |
448 | { | 457 | { |
449 | pPackage->fDependencyManagerWasHere = TRUE; | 458 | fDependentBlocksUninstall = TRUE; |
450 | 459 | ||
451 | LogId(REPORT_STANDARD, MSG_DEPENDENCY_PACKAGE_HASDEPENDENTS, pPackage->sczId); | 460 | LogId(REPORT_STANDARD, MSG_DEPENDENCY_PACKAGE_HASDEPENDENTS, pPackage->sczId); |
452 | } | 461 | } |
@@ -459,14 +468,20 @@ extern "C" HRESULT DependencyPlanPackageBegin( | |||
459 | } | 468 | } |
460 | } | 469 | } |
461 | 470 | ||
471 | if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->execute) | ||
472 | { | ||
473 | pPackage->fDependencyManagerWasHere = fDependentBlocksUninstall; | ||
474 | } | ||
475 | |||
462 | // Calculate the dependency actions before the package itself is planned. | 476 | // Calculate the dependency actions before the package itself is planned. |
463 | CalculateDependencyActionStates(pPackage, pPlan->action, &dependencyExecuteAction, &dependencyRollbackAction); | 477 | CalculateDependencyActionStates(pPackage, pPlan->action, &dependencyExecuteAction, &dependencyRollbackAction); |
464 | 478 | ||
465 | // If dependents were found, change the action to not uninstall the package. | 479 | // If dependents were found, change the action to not uninstall the package. |
466 | if (pPackage->fDependencyManagerWasHere) | 480 | if (fDependentBlocksUninstall) |
467 | { | 481 | { |
468 | pPackage->execute = BOOTSTRAPPER_ACTION_STATE_NONE; | 482 | pPackage->execute = BOOTSTRAPPER_ACTION_STATE_NONE; |
469 | pPackage->rollback = BOOTSTRAPPER_ACTION_STATE_NONE; | 483 | pPackage->rollback = BOOTSTRAPPER_ACTION_STATE_NONE; |
484 | pPackage->compatiblePackage.fRemove = FALSE; | ||
470 | } | 485 | } |
471 | else | 486 | else |
472 | { | 487 | { |
@@ -494,7 +509,7 @@ extern "C" HRESULT DependencyPlanPackageBegin( | |||
494 | } | 509 | } |
495 | 510 | ||
496 | // If the package will be removed, add its providers to the growing list in the plan. | 511 | // If the package will be removed, add its providers to the growing list in the plan. |
497 | if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->execute) | 512 | if (fAttemptingUninstall) |
498 | { | 513 | { |
499 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) | 514 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) |
500 | { | 515 | { |
@@ -739,6 +754,73 @@ extern "C" void DependencyUnregisterBundle( | |||
739 | } | 754 | } |
740 | } | 755 | } |
741 | 756 | ||
757 | extern "C" HRESULT DependencyDetectCompatibleEntry( | ||
758 | __in BURN_PACKAGE* pPackage, | ||
759 | __in BURN_REGISTRATION* pRegistration | ||
760 | ) | ||
761 | { | ||
762 | HRESULT hr = S_OK; | ||
763 | LPWSTR sczId = NULL; | ||
764 | LPWSTR sczName = NULL; | ||
765 | LPWSTR sczVersion = NULL; | ||
766 | LPCWSTR wzPackageProviderId = GetPackageProviderId(pPackage); | ||
767 | HKEY hkHive = pRegistration->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | ||
768 | |||
769 | switch (pPackage->type) | ||
770 | { | ||
771 | case BURN_PACKAGE_TYPE_MSI: | ||
772 | // Only MSI packages can handle compatible entries. | ||
773 | break; | ||
774 | default: | ||
775 | ExitFunction(); | ||
776 | } | ||
777 | |||
778 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) | ||
779 | { | ||
780 | BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; | ||
781 | |||
782 | hr = DepGetProviderInformation(hkHive, pProvider->sczKey, &sczId, &sczName, &sczVersion); | ||
783 | if (E_NOTFOUND == hr) | ||
784 | { | ||
785 | hr = S_OK; | ||
786 | continue; | ||
787 | } | ||
788 | ExitOnFailure(hr, "Failed to get provider information for compatible package: %ls", pProvider->sczKey); | ||
789 | |||
790 | // Make sure the compatible package is not the package itself. | ||
791 | if (!wzPackageProviderId) | ||
792 | { | ||
793 | if (!sczId) | ||
794 | { | ||
795 | continue; | ||
796 | } | ||
797 | } | ||
798 | else if (sczId && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, wzPackageProviderId, -1, sczId, -1)) | ||
799 | { | ||
800 | continue; | ||
801 | } | ||
802 | |||
803 | pPackage->compatiblePackage.fDetected = TRUE; | ||
804 | |||
805 | hr = StrAllocString(&pPackage->compatiblePackage.compatibleEntry.sczProviderKey, pProvider->sczKey, 0); | ||
806 | ExitOnFailure(hr, "Failed to copy provider key for compatible entry."); | ||
807 | |||
808 | pPackage->compatiblePackage.compatibleEntry.sczId = sczId; | ||
809 | sczId = NULL; | ||
810 | |||
811 | pPackage->compatiblePackage.compatibleEntry.sczName = sczName; | ||
812 | sczName = NULL; | ||
813 | |||
814 | pPackage->compatiblePackage.compatibleEntry.sczVersion = sczVersion; | ||
815 | sczVersion = NULL; | ||
816 | |||
817 | break; | ||
818 | } | ||
819 | |||
820 | LExit: | ||
821 | return hr; | ||
822 | } | ||
823 | |||
742 | // internal functions | 824 | // internal functions |
743 | 825 | ||
744 | 826 | ||
@@ -1170,24 +1252,35 @@ LExit: | |||
1170 | return hr; | 1252 | return hr; |
1171 | } | 1253 | } |
1172 | 1254 | ||
1255 | static LPCWSTR GetPackageProviderId( | ||
1256 | __in const BURN_PACKAGE* pPackage | ||
1257 | ) | ||
1258 | { | ||
1259 | LPCWSTR wzId = NULL; | ||
1260 | |||
1261 | switch (pPackage->type) | ||
1262 | { | ||
1263 | case BURN_PACKAGE_TYPE_MSI: | ||
1264 | wzId = pPackage->Msi.sczProductCode; | ||
1265 | break; | ||
1266 | case BURN_PACKAGE_TYPE_MSP: | ||
1267 | wzId = pPackage->Msp.sczPatchCode; | ||
1268 | break; | ||
1269 | } | ||
1270 | |||
1271 | return wzId; | ||
1272 | } | ||
1273 | |||
1173 | static HRESULT RegisterPackageProvider( | 1274 | static HRESULT RegisterPackageProvider( |
1174 | __in const BURN_PACKAGE* pPackage | 1275 | __in const BURN_PACKAGE* pPackage |
1175 | ) | 1276 | ) |
1176 | { | 1277 | { |
1177 | HRESULT hr = S_OK; | 1278 | HRESULT hr = S_OK; |
1178 | LPWSTR wzId = NULL; | ||
1179 | HKEY hkRoot = pPackage->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | ||
1180 | 1279 | ||
1181 | if (pPackage->rgDependencyProviders) | 1280 | if (pPackage->rgDependencyProviders) |
1182 | { | 1281 | { |
1183 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type) | 1282 | HKEY hkRoot = pPackage->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
1184 | { | 1283 | LPCWSTR wzId = GetPackageProviderId(pPackage); |
1185 | wzId = pPackage->Msi.sczProductCode; | ||
1186 | } | ||
1187 | else if (BURN_PACKAGE_TYPE_MSP == pPackage->type) | ||
1188 | { | ||
1189 | wzId = pPackage->Msp.sczPatchCode; | ||
1190 | } | ||
1191 | 1284 | ||
1192 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) | 1285 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) |
1193 | { | 1286 | { |
diff --git a/src/burn/engine/dependency.h b/src/burn/engine/dependency.h index 8d7344eb..41718066 100644 --- a/src/burn/engine/dependency.h +++ b/src/burn/engine/dependency.h | |||
@@ -191,6 +191,11 @@ void DependencyUnregisterBundle( | |||
191 | __in const BURN_PACKAGES* pPackages | 191 | __in const BURN_PACKAGES* pPackages |
192 | ); | 192 | ); |
193 | 193 | ||
194 | HRESULT DependencyDetectCompatibleEntry( | ||
195 | __in BURN_PACKAGE* pPackage, | ||
196 | __in BURN_REGISTRATION* pRegistration | ||
197 | ); | ||
198 | |||
194 | #if defined(__cplusplus) | 199 | #if defined(__cplusplus) |
195 | } | 200 | } |
196 | #endif | 201 | #endif |
diff --git a/src/burn/engine/detect.cpp b/src/burn/engine/detect.cpp index be828366..37b034ae 100644 --- a/src/burn/engine/detect.cpp +++ b/src/burn/engine/detect.cpp | |||
@@ -98,6 +98,8 @@ extern "C" void DetectReset( | |||
98 | pProvider->rgDependents = NULL; | 98 | pProvider->rgDependents = NULL; |
99 | pProvider->cDependents = 0; | 99 | pProvider->cDependents = 0; |
100 | } | 100 | } |
101 | |||
102 | PackageUninitializeCompatible(&pPackage->compatiblePackage); | ||
101 | } | 103 | } |
102 | 104 | ||
103 | for (DWORD iPatchInfo = 0; iPatchInfo < pPackages->cPatchInfo; ++iPatchInfo) | 105 | for (DWORD iPatchInfo = 0; iPatchInfo < pPackages->cPatchInfo; ++iPatchInfo) |
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp index 221d8b6d..9ebba7c5 100644 --- a/src/burn/engine/elevation.cpp +++ b/src/burn/engine/elevation.cpp | |||
@@ -32,6 +32,8 @@ typedef enum _BURN_ELEVATION_MESSAGE_TYPE | |||
32 | BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION, | 32 | BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION, |
33 | BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION, | 33 | BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION, |
34 | BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION, | 34 | BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION, |
35 | BURN_ELEVATION_MESSAGE_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE, | ||
36 | BURN_ELEVATION_MESSAGE_TYPE_CLEAN_COMPATIBLE_PACKAGE, | ||
35 | 37 | ||
36 | BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN, | 38 | BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN, |
37 | BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE, | 39 | BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE, |
@@ -168,11 +170,16 @@ static HRESULT OnApplyInitialize( | |||
168 | __in HANDLE hPipe, | 170 | __in HANDLE hPipe, |
169 | __in BURN_VARIABLES* pVariables, | 171 | __in BURN_VARIABLES* pVariables, |
170 | __in BURN_REGISTRATION* pRegistration, | 172 | __in BURN_REGISTRATION* pRegistration, |
173 | __in BURN_PACKAGES* pPackages, | ||
171 | __in HANDLE* phLock, | 174 | __in HANDLE* phLock, |
172 | __in BOOL* pfDisabledWindowsUpdate, | 175 | __in BOOL* pfDisabledWindowsUpdate, |
173 | __in BYTE* pbData, | 176 | __in BYTE* pbData, |
174 | __in SIZE_T cbData | 177 | __in SIZE_T cbData |
175 | ); | 178 | ); |
179 | static HRESULT ElevatedProcessDetect( | ||
180 | __in BURN_REGISTRATION* pRegistration, | ||
181 | __in BURN_PACKAGES* pPackages | ||
182 | ); | ||
176 | static HRESULT OnApplyUninitialize( | 183 | static HRESULT OnApplyUninitialize( |
177 | __in HANDLE* phLock | 184 | __in HANDLE* phLock |
178 | ); | 185 | ); |
@@ -271,6 +278,14 @@ static HRESULT OnExecuteMsuPackage( | |||
271 | __in BYTE* pbData, | 278 | __in BYTE* pbData, |
272 | __in SIZE_T cbData | 279 | __in SIZE_T cbData |
273 | ); | 280 | ); |
281 | static HRESULT OnUninstallMsiCompatiblePackage( | ||
282 | __in HANDLE hPipe, | ||
283 | __in BURN_CACHE* pCache, | ||
284 | __in BURN_PACKAGES* pPackages, | ||
285 | __in BURN_VARIABLES* pVariables, | ||
286 | __in BYTE* pbData, | ||
287 | __in SIZE_T cbData | ||
288 | ); | ||
274 | static HRESULT OnExecutePackageProviderAction( | 289 | static HRESULT OnExecutePackageProviderAction( |
275 | __in BURN_PACKAGES* pPackages, | 290 | __in BURN_PACKAGES* pPackages, |
276 | __in BURN_RELATED_BUNDLES* pRelatedBundles, | 291 | __in BURN_RELATED_BUNDLES* pRelatedBundles, |
@@ -306,6 +321,12 @@ static int MsiExecuteMessageHandler( | |||
306 | __in WIU_MSI_EXECUTE_MESSAGE* pMessage, | 321 | __in WIU_MSI_EXECUTE_MESSAGE* pMessage, |
307 | __in_opt LPVOID pvContext | 322 | __in_opt LPVOID pvContext |
308 | ); | 323 | ); |
324 | static HRESULT OnCleanCompatiblePackage( | ||
325 | __in BURN_CACHE* pCache, | ||
326 | __in BURN_PACKAGES* pPackages, | ||
327 | __in BYTE* pbData, | ||
328 | __in SIZE_T cbData | ||
329 | ); | ||
309 | static HRESULT OnCleanPackage( | 330 | static HRESULT OnCleanPackage( |
310 | __in BURN_CACHE* pCache, | 331 | __in BURN_CACHE* pCache, |
311 | __in BURN_PACKAGES* pPackages, | 332 | __in BURN_PACKAGES* pPackages, |
@@ -1230,6 +1251,58 @@ LExit: | |||
1230 | return hr; | 1251 | return hr; |
1231 | } | 1252 | } |
1232 | 1253 | ||
1254 | extern "C" HRESULT ElevationUninstallMsiCompatiblePackage( | ||
1255 | __in HANDLE hPipe, | ||
1256 | __in_opt HWND hwndParent, | ||
1257 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
1258 | __in BURN_VARIABLES* pVariables, | ||
1259 | __in BOOL fRollback, | ||
1260 | __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler, | ||
1261 | __in LPVOID pvContext, | ||
1262 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
1263 | ) | ||
1264 | { | ||
1265 | HRESULT hr = S_OK; | ||
1266 | BYTE* pbData = NULL; | ||
1267 | SIZE_T cbData = 0; | ||
1268 | BURN_ELEVATION_MSI_MESSAGE_CONTEXT context = { }; | ||
1269 | DWORD dwResult = 0; | ||
1270 | |||
1271 | // serialize message data | ||
1272 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fRollback); | ||
1273 | ExitOnFailure(hr, "Failed to write rollback flag to message buffer."); | ||
1274 | |||
1275 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->uninstallMsiCompatiblePackage.pParentPackage->sczId); | ||
1276 | ExitOnFailure(hr, "Failed to write package id to message buffer."); | ||
1277 | |||
1278 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->uninstallMsiCompatiblePackage.pParentPackage->compatiblePackage.compatibleEntry.sczId); | ||
1279 | ExitOnFailure(hr, "Failed to write compatible package id to message buffer."); | ||
1280 | |||
1281 | hr = BuffWritePointer(&pbData, &cbData, (DWORD_PTR)hwndParent); | ||
1282 | ExitOnFailure(hr, "Failed to write parent hwnd to message buffer."); | ||
1283 | |||
1284 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->uninstallMsiCompatiblePackage.sczLogPath); | ||
1285 | ExitOnFailure(hr, "Failed to write package log to message buffer."); | ||
1286 | |||
1287 | hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData); | ||
1288 | ExitOnFailure(hr, "Failed to write variables."); | ||
1289 | |||
1290 | |||
1291 | // send message | ||
1292 | context.pfnMessageHandler = pfnMessageHandler; | ||
1293 | context.pvContext = pvContext; | ||
1294 | |||
1295 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE, pbData, cbData, ProcessMsiPackageMessages, &context, &dwResult); | ||
1296 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE message to per-machine process."); | ||
1297 | |||
1298 | hr = ProcessResult(dwResult, pRestart); | ||
1299 | |||
1300 | LExit: | ||
1301 | ReleaseBuffer(pbData); | ||
1302 | |||
1303 | return hr; | ||
1304 | } | ||
1305 | |||
1233 | extern "C" HRESULT ElevationExecutePackageProviderAction( | 1306 | extern "C" HRESULT ElevationExecutePackageProviderAction( |
1234 | __in HANDLE hPipe, | 1307 | __in HANDLE hPipe, |
1235 | __in BURN_EXECUTE_ACTION* pExecuteAction | 1308 | __in BURN_EXECUTE_ACTION* pExecuteAction |
@@ -1295,6 +1368,35 @@ LExit: | |||
1295 | return hr; | 1368 | return hr; |
1296 | } | 1369 | } |
1297 | 1370 | ||
1371 | extern "C" HRESULT ElevationCleanCompatiblePackage( | ||
1372 | __in HANDLE hPipe, | ||
1373 | __in BURN_PACKAGE* pPackage | ||
1374 | ) | ||
1375 | { | ||
1376 | HRESULT hr = S_OK; | ||
1377 | BYTE* pbData = NULL; | ||
1378 | SIZE_T cbData = 0; | ||
1379 | DWORD dwResult = 0; | ||
1380 | |||
1381 | // serialize message data | ||
1382 | hr = BuffWriteString(&pbData, &cbData, pPackage->sczId); | ||
1383 | ExitOnFailure(hr, "Failed to write clean package id to message buffer."); | ||
1384 | |||
1385 | hr = BuffWriteString(&pbData, &cbData, pPackage->compatiblePackage.compatibleEntry.sczId); | ||
1386 | ExitOnFailure(hr, "Failed to write compatible package id to message buffer."); | ||
1387 | |||
1388 | // send message | ||
1389 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CLEAN_COMPATIBLE_PACKAGE, pbData, cbData, NULL, NULL, &dwResult); | ||
1390 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CLEAN_COMPATIBLE_PACKAGE message to per-machine process."); | ||
1391 | |||
1392 | hr = (HRESULT)dwResult; | ||
1393 | |||
1394 | LExit: | ||
1395 | ReleaseBuffer(pbData); | ||
1396 | |||
1397 | return hr; | ||
1398 | } | ||
1399 | |||
1298 | /******************************************************************* | 1400 | /******************************************************************* |
1299 | ElevationCleanPackage - | 1401 | ElevationCleanPackage - |
1300 | 1402 | ||
@@ -1940,7 +2042,7 @@ static HRESULT ProcessElevatedChildMessage( | |||
1940 | break; | 2042 | break; |
1941 | 2043 | ||
1942 | case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE: | 2044 | case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE: |
1943 | hrResult = OnApplyInitialize(pContext->hPipe, pContext->pVariables, pContext->pRegistration, pContext->phLock, pContext->pfDisabledAutomaticUpdates, (BYTE*)pMsg->pvData, pMsg->cbData); | 2045 | hrResult = OnApplyInitialize(pContext->hPipe, pContext->pVariables, pContext->pRegistration, pContext->pPackages, pContext->phLock, pContext->pfDisabledAutomaticUpdates, (BYTE*)pMsg->pvData, pMsg->cbData); |
1944 | break; | 2046 | break; |
1945 | 2047 | ||
1946 | case BURN_ELEVATION_MESSAGE_TYPE_APPLY_UNINITIALIZE: | 2048 | case BURN_ELEVATION_MESSAGE_TYPE_APPLY_UNINITIALIZE: |
@@ -2003,6 +2105,14 @@ static HRESULT ProcessElevatedChildMessage( | |||
2003 | hrResult = OnLaunchApprovedExe(pContext->hPipe, pContext->pApprovedExes, pContext->pCache, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); | 2105 | hrResult = OnLaunchApprovedExe(pContext->hPipe, pContext->pApprovedExes, pContext->pCache, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); |
2004 | break; | 2106 | break; |
2005 | 2107 | ||
2108 | case BURN_ELEVATION_MESSAGE_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE: | ||
2109 | hrResult = OnUninstallMsiCompatiblePackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
2110 | break; | ||
2111 | |||
2112 | case BURN_ELEVATION_MESSAGE_TYPE_CLEAN_COMPATIBLE_PACKAGE: | ||
2113 | hrResult = OnCleanCompatiblePackage(pContext->pCache, pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
2114 | break; | ||
2115 | |||
2006 | default: | 2116 | default: |
2007 | hr = E_INVALIDARG; | 2117 | hr = E_INVALIDARG; |
2008 | ExitOnRootFailure(hr, "Unexpected elevated message sent to child process, msg: %u", pMsg->dwMessage); | 2118 | ExitOnRootFailure(hr, "Unexpected elevated message sent to child process, msg: %u", pMsg->dwMessage); |
@@ -2082,6 +2192,7 @@ static HRESULT OnApplyInitialize( | |||
2082 | __in HANDLE hPipe, | 2192 | __in HANDLE hPipe, |
2083 | __in BURN_VARIABLES* pVariables, | 2193 | __in BURN_VARIABLES* pVariables, |
2084 | __in BURN_REGISTRATION* pRegistration, | 2194 | __in BURN_REGISTRATION* pRegistration, |
2195 | __in BURN_PACKAGES* pPackages, | ||
2085 | __in HANDLE* phLock, | 2196 | __in HANDLE* phLock, |
2086 | __in BOOL* pfDisabledWindowsUpdate, | 2197 | __in BOOL* pfDisabledWindowsUpdate, |
2087 | __in BYTE* pbData, | 2198 | __in BYTE* pbData, |
@@ -2113,11 +2224,9 @@ static HRESULT OnApplyInitialize( | |||
2113 | hr = ApplyLock(TRUE, phLock); | 2224 | hr = ApplyLock(TRUE, phLock); |
2114 | ExitOnFailure(hr, "Failed to acquire lock due to setup in other session."); | 2225 | ExitOnFailure(hr, "Failed to acquire lock due to setup in other session."); |
2115 | 2226 | ||
2116 | // Reset and reload the related bundles. | 2227 | // Detect. |
2117 | RelatedBundlesUninitialize(&pRegistration->relatedBundles); | 2228 | hr = ElevatedProcessDetect(pRegistration, pPackages); |
2118 | 2229 | ExitOnFailure(hr, "Failed to run detection in elevated process."); | |
2119 | hr = RelatedBundlesInitializeForScope(TRUE, pRegistration, &pRegistration->relatedBundles); | ||
2120 | ExitOnFailure(hr, "Failed to initialize per-machine related bundles."); | ||
2121 | 2230 | ||
2122 | // Attempt to pause AU with best effort. | 2231 | // Attempt to pause AU with best effort. |
2123 | if (BURN_AU_PAUSE_ACTION_IFELEVATED == dwAUAction || BURN_AU_PAUSE_ACTION_IFELEVATED_NORESUME == dwAUAction) | 2232 | if (BURN_AU_PAUSE_ACTION_IFELEVATED == dwAUAction || BURN_AU_PAUSE_ACTION_IFELEVATED_NORESUME == dwAUAction) |
@@ -2187,6 +2296,39 @@ LExit: | |||
2187 | return hr; | 2296 | return hr; |
2188 | } | 2297 | } |
2189 | 2298 | ||
2299 | static HRESULT ElevatedProcessDetect( | ||
2300 | __in BURN_REGISTRATION* pRegistration, | ||
2301 | __in BURN_PACKAGES* pPackages | ||
2302 | ) | ||
2303 | { | ||
2304 | HRESULT hr = S_OK; | ||
2305 | |||
2306 | DetectReset(pRegistration, pPackages); | ||
2307 | |||
2308 | hr = RelatedBundlesInitializeForScope(TRUE, pRegistration, &pRegistration->relatedBundles); | ||
2309 | ExitOnFailure(hr, "Failed to initialize per-machine related bundles."); | ||
2310 | |||
2311 | for (DWORD i = 0; i < pPackages->cPackages; ++i) | ||
2312 | { | ||
2313 | BURN_PACKAGE* pPackage = pPackages->rgPackages + i; | ||
2314 | |||
2315 | hr = DependencyDetectCompatibleEntry(pPackage, pRegistration); | ||
2316 | ExitOnFailure(hr, "Failed to detect per-machine compatible entry for package: %ls", pPackage->sczId); | ||
2317 | |||
2318 | switch (pPackage->type) | ||
2319 | { | ||
2320 | case BURN_PACKAGE_TYPE_MSI: | ||
2321 | hr = MsiEngineDetectCompatiblePackage(pPackage); | ||
2322 | ExitOnFailure(hr, "Failed to detect per-machine compatible package for package: %ls", pPackage->sczId); | ||
2323 | |||
2324 | break; | ||
2325 | } | ||
2326 | } | ||
2327 | |||
2328 | LExit: | ||
2329 | return hr; | ||
2330 | } | ||
2331 | |||
2190 | static HRESULT OnApplyUninitialize( | 2332 | static HRESULT OnApplyUninitialize( |
2191 | __in HANDLE* phLock | 2333 | __in HANDLE* phLock |
2192 | ) | 2334 | ) |
@@ -2659,6 +2801,11 @@ static HRESULT OnExecuteExePackage( | |||
2659 | hr = PackageFindById(pPackages, sczPackage, &executeAction.exePackage.pPackage); | 2801 | hr = PackageFindById(pPackages, sczPackage, &executeAction.exePackage.pPackage); |
2660 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | 2802 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); |
2661 | 2803 | ||
2804 | if (BURN_PACKAGE_TYPE_EXE != executeAction.exePackage.pPackage->type) | ||
2805 | { | ||
2806 | ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an EXE package: %ls", sczPackage); | ||
2807 | } | ||
2808 | |||
2662 | // Execute EXE package. | 2809 | // Execute EXE package. |
2663 | hr = ExeEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, &exeRestart); | 2810 | hr = ExeEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, &exeRestart); |
2664 | ExitOnFailure(hr, "Failed to execute EXE package."); | 2811 | ExitOnFailure(hr, "Failed to execute EXE package."); |
@@ -2760,6 +2907,11 @@ static HRESULT OnExecuteMsiPackage( | |||
2760 | hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData); | 2907 | hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData); |
2761 | ExitOnFailure(hr, "Failed to read variables."); | 2908 | ExitOnFailure(hr, "Failed to read variables."); |
2762 | 2909 | ||
2910 | if (BURN_PACKAGE_TYPE_MSI != executeAction.msiPackage.pPackage->type) | ||
2911 | { | ||
2912 | ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an MSI package: %ls", sczPackage); | ||
2913 | } | ||
2914 | |||
2763 | // Execute MSI package. | 2915 | // Execute MSI package. |
2764 | hr = MsiEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &msiRestart); | 2916 | hr = MsiEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &msiRestart); |
2765 | ExitOnFailure(hr, "Failed to execute MSI package."); | 2917 | ExitOnFailure(hr, "Failed to execute MSI package."); |
@@ -2859,6 +3011,11 @@ static HRESULT OnExecuteMspPackage( | |||
2859 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback); | 3011 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback); |
2860 | ExitOnFailure(hr, "Failed to read rollback flag."); | 3012 | ExitOnFailure(hr, "Failed to read rollback flag."); |
2861 | 3013 | ||
3014 | if (BURN_PACKAGE_TYPE_MSP != executeAction.mspTarget.pPackage->type) | ||
3015 | { | ||
3016 | ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an MSP package: %ls", sczPackage); | ||
3017 | } | ||
3018 | |||
2862 | // Execute MSP package. | 3019 | // Execute MSP package. |
2863 | hr = MspEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &restart); | 3020 | hr = MspEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &restart); |
2864 | ExitOnFailure(hr, "Failed to execute MSP package."); | 3021 | ExitOnFailure(hr, "Failed to execute MSP package."); |
@@ -2920,6 +3077,11 @@ static HRESULT OnExecuteMsuPackage( | |||
2920 | hr = PackageFindById(pPackages, sczPackage, &executeAction.msuPackage.pPackage); | 3077 | hr = PackageFindById(pPackages, sczPackage, &executeAction.msuPackage.pPackage); |
2921 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | 3078 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); |
2922 | 3079 | ||
3080 | if (BURN_PACKAGE_TYPE_MSU != executeAction.msuPackage.pPackage->type) | ||
3081 | { | ||
3082 | ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an MSU package: %ls", sczPackage); | ||
3083 | } | ||
3084 | |||
2923 | // execute MSU package | 3085 | // execute MSU package |
2924 | hr = MsuEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), static_cast<BOOL>(dwStopWusaService), GenericExecuteMessageHandler, hPipe, &restart); | 3086 | hr = MsuEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), static_cast<BOOL>(dwStopWusaService), GenericExecuteMessageHandler, hPipe, &restart); |
2925 | ExitOnFailure(hr, "Failed to execute MSU package."); | 3087 | ExitOnFailure(hr, "Failed to execute MSU package."); |
@@ -2943,6 +3105,88 @@ LExit: | |||
2943 | return hr; | 3105 | return hr; |
2944 | } | 3106 | } |
2945 | 3107 | ||
3108 | static HRESULT OnUninstallMsiCompatiblePackage( | ||
3109 | __in HANDLE hPipe, | ||
3110 | __in BURN_CACHE* pCache, | ||
3111 | __in BURN_PACKAGES* pPackages, | ||
3112 | __in BURN_VARIABLES* pVariables, | ||
3113 | __in BYTE* pbData, | ||
3114 | __in SIZE_T cbData | ||
3115 | ) | ||
3116 | { | ||
3117 | HRESULT hr = S_OK; | ||
3118 | SIZE_T iData = 0; | ||
3119 | LPWSTR sczPackageId = NULL; | ||
3120 | LPWSTR sczCompatiblePackageId = NULL; | ||
3121 | HWND hwndParent = NULL; | ||
3122 | BOOL fRollback = 0; | ||
3123 | BURN_EXECUTE_ACTION executeAction = { }; | ||
3124 | BURN_PACKAGE* pPackage = NULL; | ||
3125 | BURN_COMPATIBLE_PACKAGE* pCompatiblePackage = NULL; | ||
3126 | BOOTSTRAPPER_APPLY_RESTART msiRestart = BOOTSTRAPPER_APPLY_RESTART_NONE; | ||
3127 | |||
3128 | executeAction.type = BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE; | ||
3129 | |||
3130 | // Deserialize message data. | ||
3131 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback); | ||
3132 | ExitOnFailure(hr, "Failed to read rollback flag."); | ||
3133 | |||
3134 | hr = BuffReadString(pbData, cbData, &iData, &sczPackageId); | ||
3135 | ExitOnFailure(hr, "Failed to read MSI package id."); | ||
3136 | |||
3137 | hr = BuffReadString(pbData, cbData, &iData, &sczCompatiblePackageId); | ||
3138 | ExitOnFailure(hr, "Failed to read MSI compatible package id."); | ||
3139 | |||
3140 | hr = BuffReadPointer(pbData, cbData, &iData, (DWORD_PTR*)&hwndParent); | ||
3141 | ExitOnFailure(hr, "Failed to read parent hwnd."); | ||
3142 | |||
3143 | hr = BuffReadString(pbData, cbData, &iData, &executeAction.uninstallMsiCompatiblePackage.sczLogPath); | ||
3144 | ExitOnFailure(hr, "Failed to read package log."); | ||
3145 | |||
3146 | hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData); | ||
3147 | ExitOnFailure(hr, "Failed to read variables."); | ||
3148 | |||
3149 | hr = PackageFindById(pPackages, sczPackageId, &pPackage); | ||
3150 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackageId); | ||
3151 | |||
3152 | executeAction.uninstallMsiCompatiblePackage.pParentPackage = pPackage; | ||
3153 | pCompatiblePackage = &pPackage->compatiblePackage; | ||
3154 | |||
3155 | if (!pCompatiblePackage->fDetected || BURN_PACKAGE_TYPE_MSI != pCompatiblePackage->type || !pCompatiblePackage->compatibleEntry.sczId) | ||
3156 | { | ||
3157 | ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible MSI package", sczPackageId); | ||
3158 | } | ||
3159 | |||
3160 | if (!sczCompatiblePackageId || !*sczCompatiblePackageId || | ||
3161 | CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pCompatiblePackage->compatibleEntry.sczId, -1, sczCompatiblePackageId, -1)) | ||
3162 | { | ||
3163 | ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible package with id: %ls", sczPackageId, sczCompatiblePackageId); | ||
3164 | } | ||
3165 | |||
3166 | // Uninstall MSI compatible package. | ||
3167 | hr = MsiEngineUninstallCompatiblePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &msiRestart); | ||
3168 | ExitOnFailure(hr, "Failed to execute MSI package."); | ||
3169 | |||
3170 | LExit: | ||
3171 | ReleaseStr(sczPackageId); | ||
3172 | ReleaseStr(sczCompatiblePackageId); | ||
3173 | PlanUninitializeExecuteAction(&executeAction); | ||
3174 | |||
3175 | if (SUCCEEDED(hr)) | ||
3176 | { | ||
3177 | if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == msiRestart) | ||
3178 | { | ||
3179 | hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED); | ||
3180 | } | ||
3181 | else if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == msiRestart) | ||
3182 | { | ||
3183 | hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED); | ||
3184 | } | ||
3185 | } | ||
3186 | |||
3187 | return hr; | ||
3188 | } | ||
3189 | |||
2946 | static HRESULT OnExecutePackageProviderAction( | 3190 | static HRESULT OnExecutePackageProviderAction( |
2947 | __in BURN_PACKAGES* pPackages, | 3191 | __in BURN_PACKAGES* pPackages, |
2948 | __in BURN_RELATED_BUNDLES* pRelatedBundles, | 3192 | __in BURN_RELATED_BUNDLES* pRelatedBundles, |
@@ -3258,6 +3502,53 @@ LExit: | |||
3258 | return nResult; | 3502 | return nResult; |
3259 | } | 3503 | } |
3260 | 3504 | ||
3505 | static HRESULT OnCleanCompatiblePackage( | ||
3506 | __in BURN_CACHE* pCache, | ||
3507 | __in BURN_PACKAGES* pPackages, | ||
3508 | __in BYTE* pbData, | ||
3509 | __in SIZE_T cbData | ||
3510 | ) | ||
3511 | { | ||
3512 | HRESULT hr = S_OK; | ||
3513 | SIZE_T iData = 0; | ||
3514 | LPWSTR sczPackageId = NULL; | ||
3515 | LPWSTR sczCompatiblePackageId = NULL; | ||
3516 | BURN_PACKAGE* pPackage = NULL; | ||
3517 | BURN_COMPATIBLE_PACKAGE* pCompatiblePackage = NULL; | ||
3518 | |||
3519 | // Deserialize message data. | ||
3520 | hr = BuffReadString(pbData, cbData, &iData, &sczPackageId); | ||
3521 | ExitOnFailure(hr, "Failed to read package id."); | ||
3522 | |||
3523 | hr = BuffReadString(pbData, cbData, &iData, &sczCompatiblePackageId); | ||
3524 | ExitOnFailure(hr, "Failed to read compatible package id."); | ||
3525 | |||
3526 | hr = PackageFindById(pPackages, sczPackageId, &pPackage); | ||
3527 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackageId); | ||
3528 | |||
3529 | pCompatiblePackage = &pPackage->compatiblePackage; | ||
3530 | |||
3531 | if (!pCompatiblePackage->fDetected || !pCompatiblePackage->compatibleEntry.sczId || !pCompatiblePackage->sczCacheId || !*pCompatiblePackage->sczCacheId) | ||
3532 | { | ||
3533 | ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible package to clean.", sczPackageId); | ||
3534 | } | ||
3535 | |||
3536 | if (!sczCompatiblePackageId || !*sczCompatiblePackageId || | ||
3537 | CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pCompatiblePackage->compatibleEntry.sczId, -1, sczCompatiblePackageId, -1)) | ||
3538 | { | ||
3539 | ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible package with id: %ls", sczPackageId, sczCompatiblePackageId); | ||
3540 | } | ||
3541 | |||
3542 | // Remove the package from the cache. | ||
3543 | hr = CacheRemovePackage(pCache, TRUE, pCompatiblePackage->compatibleEntry.sczId, pCompatiblePackage->sczCacheId); | ||
3544 | ExitOnFailure(hr, "Failed to remove from cache compatible package: %ls", pCompatiblePackage->compatibleEntry.sczId); | ||
3545 | |||
3546 | LExit: | ||
3547 | ReleaseStr(sczPackageId); | ||
3548 | ReleaseStr(sczCompatiblePackageId); | ||
3549 | return hr; | ||
3550 | } | ||
3551 | |||
3261 | static HRESULT OnCleanPackage( | 3552 | static HRESULT OnCleanPackage( |
3262 | __in BURN_CACHE* pCache, | 3553 | __in BURN_CACHE* pCache, |
3263 | __in BURN_PACKAGES* pPackages, | 3554 | __in BURN_PACKAGES* pPackages, |
diff --git a/src/burn/engine/elevation.h b/src/burn/engine/elevation.h index 0e63c687..b4d0ca83 100644 --- a/src/burn/engine/elevation.h +++ b/src/burn/engine/elevation.h | |||
@@ -127,6 +127,16 @@ HRESULT ElevationExecuteMsuPackage( | |||
127 | __in LPVOID pvContext, | 127 | __in LPVOID pvContext, |
128 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | 128 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart |
129 | ); | 129 | ); |
130 | HRESULT ElevationUninstallMsiCompatiblePackage( | ||
131 | __in HANDLE hPipe, | ||
132 | __in_opt HWND hwndParent, | ||
133 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
134 | __in BURN_VARIABLES* pVariables, | ||
135 | __in BOOL fRollback, | ||
136 | __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler, | ||
137 | __in LPVOID pvContext, | ||
138 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
139 | ); | ||
130 | HRESULT ElevationExecutePackageProviderAction( | 140 | HRESULT ElevationExecutePackageProviderAction( |
131 | __in HANDLE hPipe, | 141 | __in HANDLE hPipe, |
132 | __in BURN_EXECUTE_ACTION* pExecuteAction | 142 | __in BURN_EXECUTE_ACTION* pExecuteAction |
@@ -135,12 +145,9 @@ HRESULT ElevationExecutePackageDependencyAction( | |||
135 | __in HANDLE hPipe, | 145 | __in HANDLE hPipe, |
136 | __in BURN_EXECUTE_ACTION* pExecuteAction | 146 | __in BURN_EXECUTE_ACTION* pExecuteAction |
137 | ); | 147 | ); |
138 | HRESULT ElevationLaunchElevatedChild( | 148 | HRESULT ElevationCleanCompatiblePackage( |
139 | __in HANDLE hPipe, | 149 | __in HANDLE hPipe, |
140 | __in BURN_PACKAGE* pPackage, | 150 | __in BURN_PACKAGE* pPackage |
141 | __in LPCWSTR wzPipeName, | ||
142 | __in LPCWSTR wzPipeToken, | ||
143 | __out DWORD* pdwChildPid | ||
144 | ); | 151 | ); |
145 | HRESULT ElevationCleanPackage( | 152 | HRESULT ElevationCleanPackage( |
146 | __in HANDLE hPipe, | 153 | __in HANDLE hPipe, |
diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc index 5c1b0b69..6ce11564 100644 --- a/src/burn/engine/engine.mc +++ b/src/burn/engine/engine.mc | |||
@@ -262,6 +262,13 @@ Detected forward compatible bundle: %1!ls!, type: %2!hs!, scope: %3!hs!, version | |||
262 | . | 262 | . |
263 | 263 | ||
264 | MessageId=108 | 264 | MessageId=108 |
265 | Severity=Success | ||
266 | SymbolicName=MSG_DETECTED_COMPATIBLE_PACKAGE_FROM_PROVIDER | ||
267 | Language=English | ||
268 | Detected compatible package: %1!ls!, provider: %2!ls!, installed: %3!ls!, version: %4!ls!, chained: %5!ls! | ||
269 | . | ||
270 | |||
271 | MessageId=109 | ||
265 | Severity=Warning | 272 | Severity=Warning |
266 | SymbolicName=MSG_DETECT_RELATED_BUNDLE_NOT_CACHED | 273 | SymbolicName=MSG_DETECT_RELATED_BUNDLE_NOT_CACHED |
267 | Language=English | 274 | Language=English |
@@ -429,6 +436,13 @@ Language=English | |||
429 | Plan skipped related bundle: %1!ls!, type: %2!hs!, because it was previously scheduled. | 436 | Plan skipped related bundle: %1!ls!, type: %2!hs!, because it was previously scheduled. |
430 | . | 437 | . |
431 | 438 | ||
439 | MessageId=215 | ||
440 | Severity=Success | ||
441 | SymbolicName=MSG_PLANNED_ORPHAN_PACKAGE_FROM_PROVIDER | ||
442 | Language=English | ||
443 | Will remove orphan package: %1!ls!, installed: %2!ls!, chained: %3!ls! | ||
444 | . | ||
445 | |||
432 | MessageId=216 | 446 | MessageId=216 |
433 | Severity=Success | 447 | Severity=Success |
434 | SymbolicName=MSG_PLAN_SKIPPED_RELATED_BUNDLE_EMBEDDED_BUNDLE_NEWER | 448 | SymbolicName=MSG_PLAN_SKIPPED_RELATED_BUNDLE_EMBEDDED_BUNDLE_NEWER |
@@ -604,7 +618,6 @@ Language=English | |||
604 | Failed to layout container: %2!ls! to layout directory: %3!ls!, error: %1!ls!. | 618 | Failed to layout container: %2!ls! to layout directory: %3!ls!, error: %1!ls!. |
605 | . | 619 | . |
606 | 620 | ||
607 | |||
608 | MessageId=317 | 621 | MessageId=317 |
609 | Severity=Error | 622 | Severity=Error |
610 | SymbolicName=MSG_FAILED_LAYOUT_PAYLOAD | 623 | SymbolicName=MSG_FAILED_LAYOUT_PAYLOAD |
@@ -927,7 +940,6 @@ Language=English | |||
927 | Calculating whether to keep registration | 940 | Calculating whether to keep registration |
928 | . | 941 | . |
929 | 942 | ||
930 | |||
931 | MessageId=374 | 943 | MessageId=374 |
932 | Severity=Success | 944 | Severity=Success |
933 | SymbolicName=MSG_POST_APPLY_PACKAGE | 945 | SymbolicName=MSG_POST_APPLY_PACKAGE |
@@ -1005,6 +1017,13 @@ Language=English | |||
1005 | Skipping the rest of non-vital rollback boundary, id: %1!ls! | 1017 | Skipping the rest of non-vital rollback boundary, id: %1!ls! |
1006 | . | 1018 | . |
1007 | 1019 | ||
1020 | MessageId=390 | ||
1021 | Severity=Success | ||
1022 | SymbolicName=MSG_APPLYING_ORPHAN_COMPATIBLE_PACKAGE | ||
1023 | Language=English | ||
1024 | Applying %1!hs! compatible package: %2!ls!, parent package: %3!ls!, action: %4!hs!, arguments: '%5!ls!' | ||
1025 | . | ||
1026 | |||
1008 | MessageId=399 | 1027 | MessageId=399 |
1009 | Severity=Success | 1028 | Severity=Success |
1010 | SymbolicName=MSG_APPLY_COMPLETE | 1029 | SymbolicName=MSG_APPLY_COMPLETE |
diff --git a/src/burn/engine/logging.cpp b/src/burn/engine/logging.cpp index 1e436f68..7c048523 100644 --- a/src/burn/engine/logging.cpp +++ b/src/burn/engine/logging.cpp | |||
@@ -227,6 +227,49 @@ extern "C" void LoggingIncrementPackageSequence() | |||
227 | ++vdwPackageSequence; | 227 | ++vdwPackageSequence; |
228 | } | 228 | } |
229 | 229 | ||
230 | extern "C" HRESULT LoggingSetCompatiblePackageVariable( | ||
231 | __in BURN_PACKAGE* pPackage, | ||
232 | __in BURN_LOGGING* pLog, | ||
233 | __in BURN_VARIABLES* pVariables, | ||
234 | __out_opt LPWSTR* psczLogPath | ||
235 | ) | ||
236 | { | ||
237 | HRESULT hr = S_OK; | ||
238 | LPWSTR sczLogPathVariable = NULL; | ||
239 | LPWSTR sczLogPath = NULL; | ||
240 | |||
241 | // Make sure that no package log files are created when logging has been disabled via Log element. | ||
242 | if (BURN_LOGGING_STATE_DISABLED == pLog->state) | ||
243 | { | ||
244 | ExitFunction(); | ||
245 | } | ||
246 | |||
247 | if (pPackage->sczLogPathVariable && *pPackage->sczLogPathVariable) | ||
248 | { | ||
249 | // Format a suitable log path variable from the original package. | ||
250 | hr = StrAllocFormatted(&sczLogPathVariable, L"%ls_Compatible", pPackage->sczLogPathVariable); | ||
251 | ExitOnFailure(hr, "Failed to format log path variable for compatible package."); | ||
252 | |||
253 | hr = StrAllocFormatted(&sczLogPath, L"%ls_%03u_%ls_%ls.%ls", pLog->sczPrefix, vdwPackageSequence, pPackage->sczId, pPackage->compatiblePackage.compatibleEntry.sczId, pLog->sczExtension); | ||
254 | ExitOnFailure(hr, "Failed to allocate path for package log."); | ||
255 | |||
256 | hr = VariableSetString(pVariables, sczLogPathVariable, sczLogPath, FALSE, FALSE); | ||
257 | ExitOnFailure(hr, "Failed to set log path into variable."); | ||
258 | |||
259 | if (psczLogPath) | ||
260 | { | ||
261 | hr = StrAllocString(psczLogPath, sczLogPath, 0); | ||
262 | ExitOnFailure(hr, "Failed to copy package log path."); | ||
263 | } | ||
264 | } | ||
265 | |||
266 | LExit: | ||
267 | ReleaseStr(sczLogPathVariable); | ||
268 | ReleaseStr(sczLogPath); | ||
269 | |||
270 | return hr; | ||
271 | } | ||
272 | |||
230 | extern "C" HRESULT LoggingSetPackageVariable( | 273 | extern "C" HRESULT LoggingSetPackageVariable( |
231 | __in BURN_PACKAGE* pPackage, | 274 | __in BURN_PACKAGE* pPackage, |
232 | __in_z_opt LPCWSTR wzSuffix, | 275 | __in_z_opt LPCWSTR wzSuffix, |
diff --git a/src/burn/engine/logging.h b/src/burn/engine/logging.h index 11f676b3..ef603931 100644 --- a/src/burn/engine/logging.h +++ b/src/burn/engine/logging.h | |||
@@ -53,6 +53,13 @@ void LoggingOpenFailed(); | |||
53 | 53 | ||
54 | void LoggingIncrementPackageSequence(); | 54 | void LoggingIncrementPackageSequence(); |
55 | 55 | ||
56 | HRESULT LoggingSetCompatiblePackageVariable( | ||
57 | __in BURN_PACKAGE* pPackage, | ||
58 | __in BURN_LOGGING* pLog, | ||
59 | __in BURN_VARIABLES* pVariables, | ||
60 | __out_opt LPWSTR* psczLogPath | ||
61 | ); | ||
62 | |||
56 | HRESULT LoggingSetPackageVariable( | 63 | HRESULT LoggingSetPackageVariable( |
57 | __in BURN_PACKAGE* pPackage, | 64 | __in BURN_PACKAGE* pPackage, |
58 | __in_z_opt LPCWSTR wzSuffix, | 65 | __in_z_opt LPCWSTR wzSuffix, |
diff --git a/src/burn/engine/msiengine.cpp b/src/burn/engine/msiengine.cpp index 87ae77e9..68582d29 100644 --- a/src/burn/engine/msiengine.cpp +++ b/src/burn/engine/msiengine.cpp | |||
@@ -506,6 +506,9 @@ extern "C" HRESULT MsiEngineDetectPackage( | |||
506 | { | 506 | { |
507 | BURN_RELATED_MSI* pRelatedMsi = &pPackage->Msi.rgRelatedMsis[i]; | 507 | BURN_RELATED_MSI* pRelatedMsi = &pPackage->Msi.rgRelatedMsis[i]; |
508 | 508 | ||
509 | ReleaseVerutilVersion(pVersion); | ||
510 | pVersion = NULL; | ||
511 | |||
509 | for (DWORD iProduct = 0; ; ++iProduct) | 512 | for (DWORD iProduct = 0; ; ++iProduct) |
510 | { | 513 | { |
511 | // get product | 514 | // get product |
@@ -708,6 +711,46 @@ extern "C" HRESULT MsiEngineDetectPackage( | |||
708 | hr = DependencyDetectChainPackage(pPackage, pRegistration); | 711 | hr = DependencyDetectChainPackage(pPackage, pRegistration); |
709 | ExitOnFailure(hr, "Failed to detect dependencies for MSI package."); | 712 | ExitOnFailure(hr, "Failed to detect dependencies for MSI package."); |
710 | 713 | ||
714 | if (BOOTSTRAPPER_PACKAGE_STATE_PRESENT > pPackage->currentState) | ||
715 | { | ||
716 | hr = MsiEngineDetectCompatiblePackage(pPackage); | ||
717 | ExitOnFailure(hr, "Failed to detect compatible package for MSI package."); | ||
718 | |||
719 | if (BURN_PACKAGE_TYPE_MSI == pPackage->compatiblePackage.type) | ||
720 | { | ||
721 | LPCWSTR wzCompatibleProductCode = pPackage->compatiblePackage.compatibleEntry.sczId; | ||
722 | LPCWSTR wzCompatibleInstalledVersion = pPackage->compatiblePackage.Msi.sczVersion; | ||
723 | |||
724 | ReleaseVerutilVersion(pVersion); | ||
725 | pVersion = NULL; | ||
726 | |||
727 | hr = VerParseVersion(wzCompatibleInstalledVersion, 0, FALSE, &pVersion); | ||
728 | ExitOnFailure(hr, "Failed to parse dependency version: '%ls' for ProductCode: %ls", wzCompatibleInstalledVersion, wzCompatibleProductCode); | ||
729 | |||
730 | if (pVersion->fInvalid) | ||
731 | { | ||
732 | LogId(REPORT_WARNING, MSG_DETECTED_MSI_PACKAGE_INVALID_VERSION, wzCompatibleProductCode, wzCompatibleInstalledVersion); | ||
733 | } | ||
734 | |||
735 | pPackage->compatiblePackage.Msi.pVersion = pVersion; | ||
736 | pVersion = NULL; | ||
737 | |||
738 | // compare versions | ||
739 | hr = VerCompareParsedVersions(pPackage->Msi.pVersion, pPackage->compatiblePackage.Msi.pVersion, &nCompareResult); | ||
740 | ExitOnFailure(hr, "Failed to compare version '%ls' to dependency version: '%ls'", pPackage->Msi.pVersion->sczVersion, wzCompatibleInstalledVersion); | ||
741 | |||
742 | if (nCompareResult < 0) | ||
743 | { | ||
744 | pPackage->compatiblePackage.fPlannable = TRUE; | ||
745 | |||
746 | LogId(REPORT_STANDARD, MSG_DETECTED_COMPATIBLE_PACKAGE_FROM_PROVIDER, pPackage->sczId, pPackage->compatiblePackage.compatibleEntry.sczProviderKey, wzCompatibleProductCode, wzCompatibleInstalledVersion, pPackage->Msi.sczProductCode); | ||
747 | |||
748 | hr = UserExperienceOnDetectCompatibleMsiPackage(pUserExperience, pPackage->sczId, wzCompatibleProductCode, pPackage->compatiblePackage.Msi.pVersion); | ||
749 | ExitOnRootFailure(hr, "BA aborted detect compatible MSI package."); | ||
750 | } | ||
751 | } | ||
752 | } | ||
753 | |||
711 | LExit: | 754 | LExit: |
712 | ReleaseStr(sczInstalledLanguage); | 755 | ReleaseStr(sczInstalledLanguage); |
713 | ReleaseStr(sczInstalledVersion); | 756 | ReleaseStr(sczInstalledVersion); |
@@ -716,8 +759,49 @@ LExit: | |||
716 | return hr; | 759 | return hr; |
717 | } | 760 | } |
718 | 761 | ||
762 | extern "C" HRESULT MsiEngineDetectCompatiblePackage( | ||
763 | __in BURN_PACKAGE* pPackage | ||
764 | ) | ||
765 | { | ||
766 | HRESULT hr = S_OK; | ||
767 | LPWSTR sczVersion = NULL; | ||
768 | LPWSTR sczCacheId = NULL; | ||
769 | LPCWSTR wzCompatibleProductCode = pPackage->compatiblePackage.compatibleEntry.sczId; | ||
770 | |||
771 | if (!pPackage->compatiblePackage.fDetected) | ||
772 | { | ||
773 | ExitFunction(); | ||
774 | } | ||
775 | |||
776 | hr = WiuGetProductInfoEx(wzCompatibleProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczVersion); | ||
777 | if (HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) == hr || HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY) == hr) | ||
778 | { | ||
779 | ExitFunction1(hr = S_OK); | ||
780 | } | ||
781 | ExitOnFailure(hr, "Failed to get product information for compatible ProductCode: %ls", wzCompatibleProductCode); | ||
782 | |||
783 | // Assume the package used the default cache ID generation from the binder. | ||
784 | hr = StrAllocFormatted(&sczCacheId, L"%lsv%ls", wzCompatibleProductCode, sczVersion); | ||
785 | ExitOnFailure(hr, "Failed to format cache ID for compatible package."); | ||
786 | |||
787 | pPackage->compatiblePackage.sczCacheId = sczCacheId; | ||
788 | sczCacheId = NULL; | ||
789 | |||
790 | pPackage->compatiblePackage.Msi.sczVersion = sczVersion; | ||
791 | sczVersion = NULL; | ||
792 | |||
793 | pPackage->compatiblePackage.type = BURN_PACKAGE_TYPE_MSI; | ||
794 | |||
795 | LExit: | ||
796 | ReleaseStr(sczVersion); | ||
797 | ReleaseStr(sczCacheId); | ||
798 | |||
799 | return hr; | ||
800 | } | ||
801 | |||
719 | extern "C" HRESULT MsiEnginePlanInitializePackage( | 802 | extern "C" HRESULT MsiEnginePlanInitializePackage( |
720 | __in BURN_PACKAGE* pPackage, | 803 | __in BURN_PACKAGE* pPackage, |
804 | __in BOOTSTRAPPER_ACTION overallAction, | ||
721 | __in BURN_VARIABLES* pVariables, | 805 | __in BURN_VARIABLES* pVariables, |
722 | __in BURN_USER_EXPERIENCE* pUserExperience | 806 | __in BURN_USER_EXPERIENCE* pUserExperience |
723 | ) | 807 | ) |
@@ -747,6 +831,18 @@ extern "C" HRESULT MsiEnginePlanInitializePackage( | |||
747 | } | 831 | } |
748 | } | 832 | } |
749 | 833 | ||
834 | if (pPackage->compatiblePackage.fPlannable) | ||
835 | { | ||
836 | Assert(BURN_PACKAGE_TYPE_MSI == pPackage->compatiblePackage.type); | ||
837 | |||
838 | pPackage->compatiblePackage.fDefaultRequested = BOOTSTRAPPER_ACTION_UNINSTALL == overallAction; | ||
839 | pPackage->compatiblePackage.fRequested = pPackage->compatiblePackage.fDefaultRequested; | ||
840 | |||
841 | hr = UserExperienceOnPlanCompatibleMsiPackageBegin(pUserExperience, pPackage->sczId, pPackage->compatiblePackage.compatibleEntry.sczId, pPackage->compatiblePackage.Msi.pVersion, &pPackage->compatiblePackage.fRequested); | ||
842 | UserExperienceOnPlanCompatibleMsiPackageComplete(pUserExperience, pPackage->sczId, pPackage->compatiblePackage.compatibleEntry.sczId, hr, pPackage->compatiblePackage.fRequested); | ||
843 | ExitOnRootFailure(hr, "BA aborted plan compatible MSI package begin."); | ||
844 | } | ||
845 | |||
750 | LExit: | 846 | LExit: |
751 | return hr; | 847 | return hr; |
752 | } | 848 | } |
@@ -989,6 +1085,17 @@ extern "C" HRESULT MsiEnginePlanAddPackage( | |||
989 | LoggingSetPackageVariable(pPackage, NULL, FALSE, pLog, pVariables, &pAction->msiPackage.sczLogPath); // ignore errors. | 1085 | LoggingSetPackageVariable(pPackage, NULL, FALSE, pLog, pVariables, &pAction->msiPackage.sczLogPath); // ignore errors. |
990 | pAction->msiPackage.dwLoggingAttributes = pLog->dwAttributes; | 1086 | pAction->msiPackage.dwLoggingAttributes = pLog->dwAttributes; |
991 | } | 1087 | } |
1088 | else if (pPackage->compatiblePackage.fRemove) | ||
1089 | { | ||
1090 | hr = PlanAppendExecuteAction(pPlan, &pAction); | ||
1091 | ExitOnFailure(hr, "Failed to append execute action."); | ||
1092 | |||
1093 | pAction->type = BURN_EXECUTE_ACTION_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE; | ||
1094 | pAction->uninstallMsiCompatiblePackage.pParentPackage = pPackage; | ||
1095 | pAction->uninstallMsiCompatiblePackage.dwLoggingAttributes = pLog->dwAttributes; | ||
1096 | |||
1097 | LoggingSetCompatiblePackageVariable(pPackage, pLog, pVariables, &pAction->uninstallMsiCompatiblePackage.sczLogPath); // ignore errors. | ||
1098 | } | ||
992 | 1099 | ||
993 | LExit: | 1100 | LExit: |
994 | ReleaseMem(rgFeatureActions); | 1101 | ReleaseMem(rgFeatureActions); |
@@ -1246,6 +1353,80 @@ LExit: | |||
1246 | return hr; | 1353 | return hr; |
1247 | } | 1354 | } |
1248 | 1355 | ||
1356 | extern "C" HRESULT MsiEngineUninstallCompatiblePackage( | ||
1357 | __in_opt HWND hwndParent, | ||
1358 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
1359 | __in BURN_CACHE* /*pCache*/, | ||
1360 | __in BURN_VARIABLES* /*pVariables*/, | ||
1361 | __in BOOL fRollback, | ||
1362 | __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler, | ||
1363 | __in LPVOID pvContext, | ||
1364 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
1365 | ) | ||
1366 | { | ||
1367 | HRESULT hr = S_OK; | ||
1368 | WIU_MSI_EXECUTE_CONTEXT context = { }; | ||
1369 | WIU_RESTART restart = WIU_RESTART_NONE; | ||
1370 | LPWSTR sczProperties = NULL; | ||
1371 | BOOTSTRAPPER_ACTION_STATE action = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; | ||
1372 | BURN_MSI_PROPERTY burnMsiProperty = BURN_MSI_PROPERTY_NONE; | ||
1373 | BOOTSTRAPPER_MSI_FILE_VERSIONING fileVersioning = BOOTSTRAPPER_MSI_FILE_VERSIONING_MISSING_OR_OLDER; | ||
1374 | BURN_PACKAGE* pParentPackage = pExecuteAction->uninstallMsiCompatiblePackage.pParentPackage; | ||
1375 | BURN_COMPATIBLE_PROVIDER_ENTRY* pCompatibleEntry = &pExecuteAction->uninstallMsiCompatiblePackage.pParentPackage->compatiblePackage.compatibleEntry; | ||
1376 | |||
1377 | // Default to "verbose" logging and set extra debug mode only if explicitly required. | ||
1378 | DWORD dwLogMode = WIU_LOG_DEFAULT | INSTALLLOGMODE_VERBOSE; | ||
1379 | |||
1380 | if (pExecuteAction->uninstallMsiCompatiblePackage.dwLoggingAttributes & BURN_LOGGING_ATTRIBUTE_EXTRADEBUG) | ||
1381 | { | ||
1382 | dwLogMode |= INSTALLLOGMODE_EXTRADEBUG; | ||
1383 | } | ||
1384 | |||
1385 | hr = WiuInitializeExternalUI(pfnMessageHandler, INSTALLUILEVEL_NONE, hwndParent, pvContext, fRollback, &context); | ||
1386 | ExitOnFailure(hr, "Failed to initialize external UI handler."); | ||
1387 | |||
1388 | if (pExecuteAction->uninstallMsiCompatiblePackage.sczLogPath && *pExecuteAction->uninstallMsiCompatiblePackage.sczLogPath) | ||
1389 | { | ||
1390 | hr = WiuEnableLog(dwLogMode, pExecuteAction->uninstallMsiCompatiblePackage.sczLogPath, INSTALLLOGATTRIBUTES_APPEND); | ||
1391 | ExitOnFailure(hr, "Failed to enable logging for compatible package: %ls to: %ls", pCompatibleEntry->sczId, pExecuteAction->uninstallMsiCompatiblePackage.sczLogPath); | ||
1392 | } | ||
1393 | |||
1394 | hr = MsiEngineConcatBurnProperties(action, burnMsiProperty, fileVersioning, TRUE, FALSE, &sczProperties); | ||
1395 | ExitOnFailure(hr, "Failed to add action property to argument string."); | ||
1396 | |||
1397 | LogId(REPORT_STANDARD, MSG_APPLYING_ORPHAN_COMPATIBLE_PACKAGE, LoggingRollbackOrExecute(fRollback), pCompatibleEntry->sczId, pParentPackage->sczId, LoggingActionStateToString(action), sczProperties ? sczProperties : L""); | ||
1398 | |||
1399 | hr = WiuConfigureProductEx(pCompatibleEntry->sczId, INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT, sczProperties, &restart); | ||
1400 | if (HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) == hr) | ||
1401 | { | ||
1402 | LogId(REPORT_STANDARD, MSG_ATTEMPTED_UNINSTALL_ABSENT_PACKAGE, pCompatibleEntry->sczId); | ||
1403 | hr = S_OK; | ||
1404 | } | ||
1405 | ExitOnFailure(hr, "Failed to uninstall compatible MSI package."); | ||
1406 | |||
1407 | LExit: | ||
1408 | WiuUninitializeExternalUI(&context); | ||
1409 | |||
1410 | StrSecureZeroFreeString(sczProperties); | ||
1411 | |||
1412 | switch (restart) | ||
1413 | { | ||
1414 | case WIU_RESTART_NONE: | ||
1415 | *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE; | ||
1416 | break; | ||
1417 | |||
1418 | case WIU_RESTART_REQUIRED: | ||
1419 | *pRestart = BOOTSTRAPPER_APPLY_RESTART_REQUIRED; | ||
1420 | break; | ||
1421 | |||
1422 | case WIU_RESTART_INITIATED: | ||
1423 | *pRestart = BOOTSTRAPPER_APPLY_RESTART_INITIATED; | ||
1424 | break; | ||
1425 | } | ||
1426 | |||
1427 | return hr; | ||
1428 | } | ||
1429 | |||
1249 | extern "C" HRESULT MsiEngineConcatBurnProperties( | 1430 | extern "C" HRESULT MsiEngineConcatBurnProperties( |
1250 | __in BOOTSTRAPPER_ACTION_STATE action, | 1431 | __in BOOTSTRAPPER_ACTION_STATE action, |
1251 | __in BURN_MSI_PROPERTY actionMsiProperty, | 1432 | __in BURN_MSI_PROPERTY actionMsiProperty, |
diff --git a/src/burn/engine/msiengine.h b/src/burn/engine/msiengine.h index fbb251e0..bc356fab 100644 --- a/src/burn/engine/msiengine.h +++ b/src/burn/engine/msiengine.h | |||
@@ -35,8 +35,12 @@ HRESULT MsiEngineDetectPackage( | |||
35 | __in BURN_REGISTRATION* pRegistration, | 35 | __in BURN_REGISTRATION* pRegistration, |
36 | __in BURN_USER_EXPERIENCE* pUserExperience | 36 | __in BURN_USER_EXPERIENCE* pUserExperience |
37 | ); | 37 | ); |
38 | HRESULT MsiEngineDetectCompatiblePackage( | ||
39 | __in BURN_PACKAGE* pPackage | ||
40 | ); | ||
38 | HRESULT MsiEnginePlanInitializePackage( | 41 | HRESULT MsiEnginePlanInitializePackage( |
39 | __in BURN_PACKAGE* pPackage, | 42 | __in BURN_PACKAGE* pPackage, |
43 | __in BOOTSTRAPPER_ACTION overallAction, | ||
40 | __in BURN_VARIABLES* pVariables, | 44 | __in BURN_VARIABLES* pVariables, |
41 | __in BURN_USER_EXPERIENCE* pUserExperience | 45 | __in BURN_USER_EXPERIENCE* pUserExperience |
42 | ); | 46 | ); |
@@ -71,6 +75,16 @@ HRESULT MsiEngineExecutePackage( | |||
71 | __in LPVOID pvContext, | 75 | __in LPVOID pvContext, |
72 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | 76 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart |
73 | ); | 77 | ); |
78 | HRESULT MsiEngineUninstallCompatiblePackage( | ||
79 | __in_opt HWND hwndParent, | ||
80 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
81 | __in BURN_CACHE* pCache, | ||
82 | __in BURN_VARIABLES* pVariables, | ||
83 | __in BOOL fRollback, | ||
84 | __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler, | ||
85 | __in LPVOID pvContext, | ||
86 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
87 | ); | ||
74 | HRESULT MsiEngineConcatBurnProperties( | 88 | HRESULT MsiEngineConcatBurnProperties( |
75 | __in BOOTSTRAPPER_ACTION_STATE action, | 89 | __in BOOTSTRAPPER_ACTION_STATE action, |
76 | __in BURN_MSI_PROPERTY actionMsiProperty, | 90 | __in BURN_MSI_PROPERTY actionMsiProperty, |
diff --git a/src/burn/engine/package.cpp b/src/burn/engine/package.cpp index d9087f79..d9f92d3d 100644 --- a/src/burn/engine/package.cpp +++ b/src/burn/engine/package.cpp | |||
@@ -366,6 +366,31 @@ extern "C" void PackageUninitialize( | |||
366 | MsuEnginePackageUninitialize(pPackage); // TODO: Modularization | 366 | MsuEnginePackageUninitialize(pPackage); // TODO: Modularization |
367 | break; | 367 | break; |
368 | } | 368 | } |
369 | |||
370 | PackageUninitializeCompatible(&pPackage->compatiblePackage); | ||
371 | } | ||
372 | |||
373 | extern "C" void PackageUninitializeCompatible( | ||
374 | __in BURN_COMPATIBLE_PACKAGE* pCompatiblePackage | ||
375 | ) | ||
376 | { | ||
377 | ReleaseStr(pCompatiblePackage->compatibleEntry.sczId); | ||
378 | ReleaseStr(pCompatiblePackage->compatibleEntry.sczName); | ||
379 | ReleaseStr(pCompatiblePackage->compatibleEntry.sczProviderKey); | ||
380 | ReleaseStr(pCompatiblePackage->compatibleEntry.sczVersion); | ||
381 | |||
382 | ReleaseStr(pCompatiblePackage->sczCacheId); | ||
383 | |||
384 | switch (pCompatiblePackage->type) | ||
385 | { | ||
386 | case BURN_PACKAGE_TYPE_MSI: | ||
387 | ReleaseStr(pCompatiblePackage->Msi.sczVersion); | ||
388 | ReleaseVerutilVersion(pCompatiblePackage->Msi.pVersion); | ||
389 | break; | ||
390 | } | ||
391 | |||
392 | // clear struct | ||
393 | memset(pCompatiblePackage, 0, sizeof(BURN_COMPATIBLE_PACKAGE)); | ||
369 | } | 394 | } |
370 | 395 | ||
371 | extern "C" void PackagesUninitialize( | 396 | extern "C" void PackagesUninitialize( |
diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h index 10b5f33c..934355e1 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h | |||
@@ -147,6 +147,14 @@ typedef struct _BURN_MSIFEATURE | |||
147 | BOOTSTRAPPER_FEATURE_ACTION rollback; // only valid during Plan. | 147 | BOOTSTRAPPER_FEATURE_ACTION rollback; // only valid during Plan. |
148 | } BURN_MSIFEATURE; | 148 | } BURN_MSIFEATURE; |
149 | 149 | ||
150 | typedef struct _BURN_COMPATIBLE_PROVIDER_ENTRY | ||
151 | { | ||
152 | LPWSTR sczProviderKey; | ||
153 | LPWSTR sczId; | ||
154 | LPWSTR sczName; | ||
155 | LPWSTR sczVersion; | ||
156 | } BURN_COMPATIBLE_PROVIDER_ENTRY; | ||
157 | |||
150 | typedef struct _BURN_RELATED_MSI | 158 | typedef struct _BURN_RELATED_MSI |
151 | { | 159 | { |
152 | LPWSTR sczUpgradeCode; | 160 | LPWSTR sczUpgradeCode; |
@@ -206,6 +214,27 @@ typedef struct _BURN_PATCH_TARGETCODE | |||
206 | BURN_PATCH_TARGETCODE_TYPE type; | 214 | BURN_PATCH_TARGETCODE_TYPE type; |
207 | } BURN_PATCH_TARGETCODE; | 215 | } BURN_PATCH_TARGETCODE; |
208 | 216 | ||
217 | typedef struct _BURN_COMPATIBLE_PACKAGE | ||
218 | { | ||
219 | BOOL fDetected; | ||
220 | BOOL fPlannable; | ||
221 | BOOL fDefaultRequested; | ||
222 | BOOL fRequested; | ||
223 | BOOL fRemove; | ||
224 | LPWSTR sczCacheId; | ||
225 | BURN_COMPATIBLE_PROVIDER_ENTRY compatibleEntry; | ||
226 | |||
227 | BURN_PACKAGE_TYPE type; | ||
228 | union | ||
229 | { | ||
230 | struct | ||
231 | { | ||
232 | LPWSTR sczVersion; | ||
233 | VERUTIL_VERSION* pVersion; | ||
234 | } Msi; | ||
235 | }; | ||
236 | } BURN_COMPATIBLE_PACKAGE; | ||
237 | |||
209 | typedef struct _BURN_PACKAGE | 238 | typedef struct _BURN_PACKAGE |
210 | { | 239 | { |
211 | LPWSTR sczId; | 240 | LPWSTR sczId; |
@@ -259,6 +288,8 @@ typedef struct _BURN_PACKAGE | |||
259 | BURN_DEPENDENCY_PROVIDER* rgDependencyProviders; | 288 | BURN_DEPENDENCY_PROVIDER* rgDependencyProviders; |
260 | DWORD cDependencyProviders; | 289 | DWORD cDependencyProviders; |
261 | 290 | ||
291 | BURN_COMPATIBLE_PACKAGE compatiblePackage; | ||
292 | |||
262 | BURN_PACKAGE_TYPE type; | 293 | BURN_PACKAGE_TYPE type; |
263 | union | 294 | union |
264 | { | 295 | { |
@@ -371,6 +402,9 @@ HRESULT PackagesParseFromXml( | |||
371 | void PackageUninitialize( | 402 | void PackageUninitialize( |
372 | __in BURN_PACKAGE* pPackage | 403 | __in BURN_PACKAGE* pPackage |
373 | ); | 404 | ); |
405 | void PackageUninitializeCompatible( | ||
406 | __in BURN_COMPATIBLE_PACKAGE* pCompatiblePackage | ||
407 | ); | ||
374 | void PackagesUninitialize( | 408 | void PackagesUninitialize( |
375 | __in BURN_PACKAGES* pPackages | 409 | __in BURN_PACKAGES* pPackages |
376 | ); | 410 | ); |
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index e0e9a82b..1dd78773 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp | |||
@@ -96,6 +96,10 @@ static HRESULT AppendRollbackCacheAction( | |||
96 | __in BURN_PLAN* pPlan, | 96 | __in BURN_PLAN* pPlan, |
97 | __out BURN_CACHE_ACTION** ppCacheAction | 97 | __out BURN_CACHE_ACTION** ppCacheAction |
98 | ); | 98 | ); |
99 | static HRESULT AppendCleanAction( | ||
100 | __in BURN_PLAN* pPlan, | ||
101 | __out BURN_CLEAN_ACTION** ppCleanAction | ||
102 | ); | ||
99 | static HRESULT ProcessPayloadGroup( | 103 | static HRESULT ProcessPayloadGroup( |
100 | __in BURN_PLAN* pPlan, | 104 | __in BURN_PLAN* pPlan, |
101 | __in BURN_PAYLOAD_GROUP* pPayloadGroup | 105 | __in BURN_PAYLOAD_GROUP* pPayloadGroup |
@@ -286,6 +290,10 @@ extern "C" void PlanUninitializeExecuteAction( | |||
286 | case BURN_EXECUTE_ACTION_TYPE_PACKAGE_DEPENDENCY: | 290 | case BURN_EXECUTE_ACTION_TYPE_PACKAGE_DEPENDENCY: |
287 | ReleaseStr(pExecuteAction->packageDependency.sczBundleProviderKey); | 291 | ReleaseStr(pExecuteAction->packageDependency.sczBundleProviderKey); |
288 | break; | 292 | break; |
293 | |||
294 | case BURN_EXECUTE_ACTION_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE: | ||
295 | ReleaseStr(pExecuteAction->uninstallMsiCompatiblePackage.sczLogPath); | ||
296 | break; | ||
289 | } | 297 | } |
290 | } | 298 | } |
291 | 299 | ||
@@ -823,6 +831,11 @@ static HRESULT PlanPackagesHelper( | |||
823 | BURN_PACKAGE* pPackage = rgPackages + iPackage; | 831 | BURN_PACKAGE* pPackage = rgPackages + iPackage; |
824 | 832 | ||
825 | UserExperienceOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback, pPackage->fPlannedCache, pPackage->fPlannedUncache); | 833 | UserExperienceOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback, pPackage->fPlannedCache, pPackage->fPlannedUncache); |
834 | |||
835 | if (pPackage->compatiblePackage.fPlannable) | ||
836 | { | ||
837 | UserExperienceOnPlannedCompatiblePackage(pUX, pPackage->sczId, pPackage->compatiblePackage.compatibleEntry.sczId, pPackage->compatiblePackage.fRemove); | ||
838 | } | ||
826 | } | 839 | } |
827 | 840 | ||
828 | LExit: | 841 | LExit: |
@@ -878,7 +891,7 @@ static HRESULT InitializePackage( | |||
878 | 891 | ||
879 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type) | 892 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type) |
880 | { | 893 | { |
881 | hr = MsiEnginePlanInitializePackage(pPackage, pVariables, pUX); | 894 | hr = MsiEnginePlanInitializePackage(pPackage, pPlan->action, pVariables, pUX); |
882 | ExitOnFailure(hr, "Failed to initialize plan package: %ls", pPackage->sczId); | 895 | ExitOnFailure(hr, "Failed to initialize plan package: %ls", pPackage->sczId); |
883 | } | 896 | } |
884 | 897 | ||
@@ -918,7 +931,7 @@ static HRESULT ProcessPackage( | |||
918 | } | 931 | } |
919 | else | 932 | else |
920 | { | 933 | { |
921 | if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested) | 934 | if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested || pPackage->compatiblePackage.fRequested) |
922 | { | 935 | { |
923 | // If the package is in a requested state, plan it. | 936 | // If the package is in a requested state, plan it. |
924 | hr = PlanExecutePackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables); | 937 | hr = PlanExecutePackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables); |
@@ -1151,7 +1164,7 @@ extern "C" HRESULT PlanExecutePackage( | |||
1151 | ExitOnFailure(hr, "Failed to complete plan dependency actions for package: %ls", pPackage->sczId); | 1164 | ExitOnFailure(hr, "Failed to complete plan dependency actions for package: %ls", pPackage->sczId); |
1152 | 1165 | ||
1153 | // If we are going to take any action on this package, add progress for it. | 1166 | // If we are going to take any action on this package, add progress for it. |
1154 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute || BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback) | 1167 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute || BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback || pPackage->compatiblePackage.fRemove) |
1155 | { | 1168 | { |
1156 | LoggingIncrementPackageSequence(); | 1169 | LoggingIncrementPackageSequence(); |
1157 | 1170 | ||
@@ -1560,12 +1573,10 @@ extern "C" HRESULT PlanCleanPackage( | |||
1560 | 1573 | ||
1561 | if (fPlanCleanPackage) | 1574 | if (fPlanCleanPackage) |
1562 | { | 1575 | { |
1563 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pPlan->rgCleanActions), pPlan->cCleanActions + 1, sizeof(BURN_CLEAN_ACTION), 5); | 1576 | hr = AppendCleanAction(pPlan, &pCleanAction); |
1564 | ExitOnFailure(hr, "Failed to grow plan's array of clean actions."); | 1577 | ExitOnFailure(hr, "Failed to append clean action to plan."); |
1565 | |||
1566 | pCleanAction = pPlan->rgCleanActions + pPlan->cCleanActions; | ||
1567 | ++pPlan->cCleanActions; | ||
1568 | 1578 | ||
1579 | pCleanAction->type = BURN_CLEAN_ACTION_TYPE_PACKAGE; | ||
1569 | pCleanAction->pPackage = pPackage; | 1580 | pCleanAction->pPackage = pPackage; |
1570 | 1581 | ||
1571 | pPackage->fPlannedUncache = TRUE; | 1582 | pPackage->fPlannedUncache = TRUE; |
@@ -1576,6 +1587,15 @@ extern "C" HRESULT PlanCleanPackage( | |||
1576 | } | 1587 | } |
1577 | } | 1588 | } |
1578 | 1589 | ||
1590 | if (pPackage->compatiblePackage.fRemove) | ||
1591 | { | ||
1592 | hr = AppendCleanAction(pPlan, &pCleanAction); | ||
1593 | ExitOnFailure(hr, "Failed to append clean action to plan."); | ||
1594 | |||
1595 | pCleanAction->type = BURN_CLEAN_ACTION_TYPE_COMPATIBLE_PACKAGE; | ||
1596 | pCleanAction->pPackage = pPackage; | ||
1597 | } | ||
1598 | |||
1579 | LExit: | 1599 | LExit: |
1580 | return hr; | 1600 | return hr; |
1581 | } | 1601 | } |
@@ -2229,6 +2249,24 @@ LExit: | |||
2229 | return hr; | 2249 | return hr; |
2230 | } | 2250 | } |
2231 | 2251 | ||
2252 | static HRESULT AppendCleanAction( | ||
2253 | __in BURN_PLAN* pPlan, | ||
2254 | __out BURN_CLEAN_ACTION** ppCleanAction | ||
2255 | ) | ||
2256 | { | ||
2257 | HRESULT hr = S_OK; | ||
2258 | |||
2259 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(&pPlan->rgCleanActions), pPlan->cCleanActions, 1, sizeof(BURN_CLEAN_ACTION), 5); | ||
2260 | ExitOnFailure(hr, "Failed to grow plan's array of clean actions."); | ||
2261 | |||
2262 | |||
2263 | *ppCleanAction = pPlan->rgCleanActions + pPlan->cCleanActions; | ||
2264 | ++pPlan->cCleanActions; | ||
2265 | |||
2266 | LExit: | ||
2267 | return hr; | ||
2268 | } | ||
2269 | |||
2232 | static HRESULT ProcessPayloadGroup( | 2270 | static HRESULT ProcessPayloadGroup( |
2233 | __in BURN_PLAN* pPlan, | 2271 | __in BURN_PLAN* pPlan, |
2234 | __in BURN_PAYLOAD_GROUP* pPayloadGroup | 2272 | __in BURN_PAYLOAD_GROUP* pPayloadGroup |
@@ -2505,6 +2543,8 @@ static HRESULT CalculateExecuteActions( | |||
2505 | ExitOnFailure(hr, "Invalid package type."); | 2543 | ExitOnFailure(hr, "Invalid package type."); |
2506 | } | 2544 | } |
2507 | 2545 | ||
2546 | pPackage->compatiblePackage.fRemove = pPackage->compatiblePackage.fPlannable && pPackage->compatiblePackage.fRequested; | ||
2547 | |||
2508 | LExit: | 2548 | LExit: |
2509 | return hr; | 2549 | return hr; |
2510 | } | 2550 | } |
@@ -2622,6 +2662,10 @@ static void ExecuteActionLog( | |||
2622 | } | 2662 | } |
2623 | break; | 2663 | break; |
2624 | 2664 | ||
2665 | case BURN_EXECUTE_ACTION_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE: | ||
2666 | LogStringLine(PlanDumpLevel, "%ls action[%u]: UNINSTALL_MSI_COMPATIBLE_PACKAGE package id: %ls, compatible package id: %ls, cache id: %ls, log path: %ls, logging attrib: %u", wzBase, iAction, pAction->uninstallMsiCompatiblePackage.pParentPackage->sczId, pAction->uninstallMsiCompatiblePackage.pParentPackage->compatiblePackage.compatibleEntry.sczId, pAction->uninstallMsiCompatiblePackage.pParentPackage->compatiblePackage.sczCacheId, pAction->uninstallMsiCompatiblePackage.sczLogPath, pAction->uninstallMsiCompatiblePackage.dwLoggingAttributes); | ||
2667 | break; | ||
2668 | |||
2625 | case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: | 2669 | case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: |
2626 | LogStringLine(PlanDumpLevel, "%ls action[%u]: MSP_TARGET package id: %ls, action: %hs, target product code: %ls, target per-machine: %hs, action msi property: %ls, ui level: %u, disable externaluihandler: %hs, file versioning: %hs, log path: %ls", wzBase, iAction, pAction->mspTarget.pPackage->sczId, LoggingActionStateToString(pAction->mspTarget.action), pAction->mspTarget.sczTargetProductCode, LoggingBoolToString(pAction->mspTarget.fPerMachineTarget), LoggingBurnMsiPropertyToString(pAction->mspTarget.actionMsiProperty), pAction->mspTarget.uiLevel, LoggingBoolToString(pAction->mspTarget.fDisableExternalUiHandler), LoggingMsiFileVersioningToString(pAction->mspTarget.fileVersioning), pAction->mspTarget.sczLogPath); | 2670 | LogStringLine(PlanDumpLevel, "%ls action[%u]: MSP_TARGET package id: %ls, action: %hs, target product code: %ls, target per-machine: %hs, action msi property: %ls, ui level: %u, disable externaluihandler: %hs, file versioning: %hs, log path: %ls", wzBase, iAction, pAction->mspTarget.pPackage->sczId, LoggingActionStateToString(pAction->mspTarget.action), pAction->mspTarget.sczTargetProductCode, LoggingBoolToString(pAction->mspTarget.fPerMachineTarget), LoggingBurnMsiPropertyToString(pAction->mspTarget.actionMsiProperty), pAction->mspTarget.uiLevel, LoggingBoolToString(pAction->mspTarget.fDisableExternalUiHandler), LoggingMsiFileVersioningToString(pAction->mspTarget.fileVersioning), pAction->mspTarget.sczLogPath); |
2627 | for (DWORD j = 0; j < pAction->mspTarget.cOrderedPatches; ++j) | 2671 | for (DWORD j = 0; j < pAction->mspTarget.cOrderedPatches; ++j) |
@@ -2669,6 +2713,27 @@ static void ExecuteActionLog( | |||
2669 | } | 2713 | } |
2670 | } | 2714 | } |
2671 | 2715 | ||
2716 | static void CleanActionLog( | ||
2717 | __in DWORD iAction, | ||
2718 | __in BURN_CLEAN_ACTION* pAction | ||
2719 | ) | ||
2720 | { | ||
2721 | switch (pAction->type) | ||
2722 | { | ||
2723 | case BURN_CLEAN_ACTION_TYPE_COMPATIBLE_PACKAGE: | ||
2724 | LogStringLine(PlanDumpLevel, " Clean action[%u]: CLEAN_COMPATIBLE_PACKAGE package id: %ls", iAction, pAction->pPackage->sczId); | ||
2725 | break; | ||
2726 | |||
2727 | case BURN_CLEAN_ACTION_TYPE_PACKAGE: | ||
2728 | LogStringLine(PlanDumpLevel, " Clean action[%u]: CLEAN_PACKAGE package id: %ls", iAction, pAction->pPackage->sczId); | ||
2729 | break; | ||
2730 | |||
2731 | default: | ||
2732 | AssertSz(FALSE, "Unknown clean action type."); | ||
2733 | break; | ||
2734 | } | ||
2735 | } | ||
2736 | |||
2672 | extern "C" void PlanDump( | 2737 | extern "C" void PlanDump( |
2673 | __in BURN_PLAN* pPlan | 2738 | __in BURN_PLAN* pPlan |
2674 | ) | 2739 | ) |
@@ -2709,7 +2774,7 @@ extern "C" void PlanDump( | |||
2709 | 2774 | ||
2710 | for (DWORD i = 0; i < pPlan->cCleanActions; ++i) | 2775 | for (DWORD i = 0; i < pPlan->cCleanActions; ++i) |
2711 | { | 2776 | { |
2712 | LogStringLine(PlanDumpLevel, " Clean action[%u]: CLEAN_PACKAGE package id: %ls", i, pPlan->rgCleanActions[i].pPackage->sczId); | 2777 | CleanActionLog(i, pPlan->rgCleanActions + i); |
2713 | } | 2778 | } |
2714 | 2779 | ||
2715 | for (DWORD i = 0; i < pPlan->cPlannedProviders; ++i) | 2780 | for (DWORD i = 0; i < pPlan->cPlannedProviders; ++i) |
diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h index 6be19a10..9bf72828 100644 --- a/src/burn/engine/plan.h +++ b/src/burn/engine/plan.h | |||
@@ -61,12 +61,13 @@ enum BURN_EXECUTE_ACTION_TYPE | |||
61 | BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY_END, | 61 | BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY_END, |
62 | BURN_EXECUTE_ACTION_TYPE_BEGIN_MSI_TRANSACTION, | 62 | BURN_EXECUTE_ACTION_TYPE_BEGIN_MSI_TRANSACTION, |
63 | BURN_EXECUTE_ACTION_TYPE_COMMIT_MSI_TRANSACTION, | 63 | BURN_EXECUTE_ACTION_TYPE_COMMIT_MSI_TRANSACTION, |
64 | BURN_EXECUTE_ACTION_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE, | ||
64 | }; | 65 | }; |
65 | 66 | ||
66 | enum BURN_CLEAN_ACTION_TYPE | 67 | enum BURN_CLEAN_ACTION_TYPE |
67 | { | 68 | { |
68 | BURN_CLEAN_ACTION_TYPE_NONE, | 69 | BURN_CLEAN_ACTION_TYPE_NONE, |
69 | BURN_CLEAN_ACTION_TYPE_BUNDLE, | 70 | BURN_CLEAN_ACTION_TYPE_COMPATIBLE_PACKAGE, |
70 | BURN_CLEAN_ACTION_TYPE_PACKAGE, | 71 | BURN_CLEAN_ACTION_TYPE_PACKAGE, |
71 | }; | 72 | }; |
72 | 73 | ||
@@ -227,11 +228,18 @@ typedef struct _BURN_EXECUTE_ACTION | |||
227 | { | 228 | { |
228 | BURN_ROLLBACK_BOUNDARY* pRollbackBoundary; | 229 | BURN_ROLLBACK_BOUNDARY* pRollbackBoundary; |
229 | } msiTransaction; | 230 | } msiTransaction; |
231 | struct | ||
232 | { | ||
233 | BURN_PACKAGE* pParentPackage; | ||
234 | LPWSTR sczLogPath; | ||
235 | DWORD dwLoggingAttributes; | ||
236 | } uninstallMsiCompatiblePackage; | ||
230 | }; | 237 | }; |
231 | } BURN_EXECUTE_ACTION; | 238 | } BURN_EXECUTE_ACTION; |
232 | 239 | ||
233 | typedef struct _BURN_CLEAN_ACTION | 240 | typedef struct _BURN_CLEAN_ACTION |
234 | { | 241 | { |
242 | BURN_CLEAN_ACTION_TYPE type; | ||
235 | BURN_PACKAGE* pPackage; | 243 | BURN_PACKAGE* pPackage; |
236 | } BURN_CLEAN_ACTION; | 244 | } BURN_CLEAN_ACTION; |
237 | 245 | ||
diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp index a5b061eb..c76dde53 100644 --- a/src/burn/engine/registration.cpp +++ b/src/burn/engine/registration.cpp | |||
@@ -423,6 +423,10 @@ extern "C" void RegistrationUninitialize( | |||
423 | ReleaseStr(pRegistration->sczBundlePackageAncestors); | 423 | ReleaseStr(pRegistration->sczBundlePackageAncestors); |
424 | RelatedBundlesUninitialize(&pRegistration->relatedBundles); | 424 | RelatedBundlesUninitialize(&pRegistration->relatedBundles); |
425 | 425 | ||
426 | if (pRegistration->rgDependents) | ||
427 | { | ||
428 | ReleaseDependencyArray(pRegistration->rgDependents, pRegistration->cDependents); | ||
429 | } | ||
426 | // clear struct | 430 | // clear struct |
427 | memset(pRegistration, 0, sizeof(BURN_REGISTRATION)); | 431 | memset(pRegistration, 0, sizeof(BURN_REGISTRATION)); |
428 | } | 432 | } |
diff --git a/src/burn/engine/userexperience.cpp b/src/burn/engine/userexperience.cpp index 6ea16905..1439f5f2 100644 --- a/src/burn/engine/userexperience.cpp +++ b/src/burn/engine/userexperience.cpp | |||
@@ -104,7 +104,7 @@ extern "C" HRESULT UserExperienceLoad( | |||
104 | args.pCommand = pCommand; | 104 | args.pCommand = pCommand; |
105 | args.pfnBootstrapperEngineProc = EngineForApplicationProc; | 105 | args.pfnBootstrapperEngineProc = EngineForApplicationProc; |
106 | args.pvBootstrapperEngineProcContext = pEngineContext; | 106 | args.pvBootstrapperEngineProcContext = pEngineContext; |
107 | args.qwEngineAPIVersion = MAKEQWORDVERSION(2021, 12, 30, 0); | 107 | args.qwEngineAPIVersion = MAKEQWORDVERSION(2022, 1, 10, 0); |
108 | 108 | ||
109 | results.cbSize = sizeof(BOOTSTRAPPER_CREATE_RESULTS); | 109 | results.cbSize = sizeof(BOOTSTRAPPER_CREATE_RESULTS); |
110 | 110 | ||
@@ -1015,6 +1015,36 @@ LExit: | |||
1015 | return hr; | 1015 | return hr; |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | EXTERN_C BAAPI UserExperienceOnDetectCompatibleMsiPackage( | ||
1019 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
1020 | __in_z LPCWSTR wzPackageId, | ||
1021 | __in_z LPCWSTR wzCompatiblePackageId, | ||
1022 | __in VERUTIL_VERSION* pCompatiblePackageVersion | ||
1023 | ) | ||
1024 | { | ||
1025 | HRESULT hr = S_OK; | ||
1026 | BA_ONDETECTCOMPATIBLEMSIPACKAGE_ARGS args = { }; | ||
1027 | BA_ONDETECTCOMPATIBLEMSIPACKAGE_RESULTS results = { }; | ||
1028 | |||
1029 | args.cbSize = sizeof(args); | ||
1030 | args.wzPackageId = wzPackageId; | ||
1031 | args.wzCompatiblePackageId = wzCompatiblePackageId; | ||
1032 | args.wzCompatiblePackageVersion = pCompatiblePackageVersion->sczVersion; | ||
1033 | |||
1034 | results.cbSize = sizeof(results); | ||
1035 | |||
1036 | hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE, &args, &results); | ||
1037 | ExitOnFailure(hr, "BA OnDetectCompatibleMsiPackage failed."); | ||
1038 | |||
1039 | if (results.fCancel) | ||
1040 | { | ||
1041 | hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); | ||
1042 | } | ||
1043 | |||
1044 | LExit: | ||
1045 | return hr; | ||
1046 | } | ||
1047 | |||
1018 | EXTERN_C BAAPI UserExperienceOnDetectComplete( | 1048 | EXTERN_C BAAPI UserExperienceOnDetectComplete( |
1019 | __in BURN_USER_EXPERIENCE* pUserExperience, | 1049 | __in BURN_USER_EXPERIENCE* pUserExperience, |
1020 | __in HRESULT hrStatus, | 1050 | __in HRESULT hrStatus, |
@@ -1798,6 +1828,67 @@ LExit: | |||
1798 | return hr; | 1828 | return hr; |
1799 | } | 1829 | } |
1800 | 1830 | ||
1831 | EXTERN_C BAAPI UserExperienceOnPlanCompatibleMsiPackageBegin( | ||
1832 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
1833 | __in_z LPCWSTR wzPackageId, | ||
1834 | __in_z LPCWSTR wzCompatiblePackageId, | ||
1835 | __in VERUTIL_VERSION* pCompatiblePackageVersion, | ||
1836 | __inout BOOL* pfRequested | ||
1837 | ) | ||
1838 | { | ||
1839 | HRESULT hr = S_OK; | ||
1840 | BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_ARGS args = { }; | ||
1841 | BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_RESULTS results = { }; | ||
1842 | |||
1843 | args.cbSize = sizeof(args); | ||
1844 | args.wzPackageId = wzPackageId; | ||
1845 | args.wzCompatiblePackageId = wzCompatiblePackageId; | ||
1846 | args.wzCompatiblePackageVersion = pCompatiblePackageVersion->sczVersion; | ||
1847 | args.fRecommendedRemove = *pfRequested; | ||
1848 | |||
1849 | results.cbSize = sizeof(results); | ||
1850 | results.fRequestRemove = *pfRequested; | ||
1851 | |||
1852 | hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN, &args, &results); | ||
1853 | ExitOnFailure(hr, "BA OnPlanCompatibleMsiPackageBegin failed."); | ||
1854 | |||
1855 | if (results.fCancel) | ||
1856 | { | ||
1857 | hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); | ||
1858 | } | ||
1859 | *pfRequested = results.fRequestRemove; | ||
1860 | |||
1861 | LExit: | ||
1862 | return hr; | ||
1863 | } | ||
1864 | |||
1865 | EXTERN_C BAAPI UserExperienceOnPlanCompatibleMsiPackageComplete( | ||
1866 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
1867 | __in_z LPCWSTR wzPackageId, | ||
1868 | __in_z LPCWSTR wzCompatiblePackageId, | ||
1869 | __in HRESULT hrStatus, | ||
1870 | __in BOOL fRequested | ||
1871 | ) | ||
1872 | { | ||
1873 | HRESULT hr = S_OK; | ||
1874 | BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_ARGS args = { }; | ||
1875 | BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_RESULTS results = { }; | ||
1876 | |||
1877 | args.cbSize = sizeof(args); | ||
1878 | args.wzPackageId = wzPackageId; | ||
1879 | args.wzCompatiblePackageId = wzCompatiblePackageId; | ||
1880 | args.hrStatus = hrStatus; | ||
1881 | args.fRequestedRemove = fRequested; | ||
1882 | |||
1883 | results.cbSize = sizeof(results); | ||
1884 | |||
1885 | hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, &args, &results); | ||
1886 | ExitOnFailure(hr, "BA OnPlanCompatibleMsiPackageComplete failed."); | ||
1887 | |||
1888 | LExit: | ||
1889 | return hr; | ||
1890 | } | ||
1891 | |||
1801 | EXTERN_C BAAPI UserExperienceOnPlanMsiFeature( | 1892 | EXTERN_C BAAPI UserExperienceOnPlanMsiFeature( |
1802 | __in BURN_USER_EXPERIENCE* pUserExperience, | 1893 | __in BURN_USER_EXPERIENCE* pUserExperience, |
1803 | __in_z LPCWSTR wzPackageId, | 1894 | __in_z LPCWSTR wzPackageId, |
@@ -1932,6 +2023,31 @@ LExit: | |||
1932 | return hr; | 2023 | return hr; |
1933 | } | 2024 | } |
1934 | 2025 | ||
2026 | EXTERN_C BAAPI UserExperienceOnPlannedCompatiblePackage( | ||
2027 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
2028 | __in_z LPCWSTR wzPackageId, | ||
2029 | __in_z LPCWSTR wzCompatiblePackageId, | ||
2030 | __in BOOL fRemove | ||
2031 | ) | ||
2032 | { | ||
2033 | HRESULT hr = S_OK; | ||
2034 | BA_ONPLANNEDCOMPATIBLEPACKAGE_ARGS args = { }; | ||
2035 | BA_ONPLANNEDCOMPATIBLEPACKAGE_RESULTS results = { }; | ||
2036 | |||
2037 | args.cbSize = sizeof(args); | ||
2038 | args.wzPackageId = wzPackageId; | ||
2039 | args.wzCompatiblePackageId = wzCompatiblePackageId; | ||
2040 | args.fRemove = fRemove; | ||
2041 | |||
2042 | results.cbSize = sizeof(results); | ||
2043 | |||
2044 | hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE, &args, &results); | ||
2045 | ExitOnFailure(hr, "BA OnPlannedCompatiblePackage failed."); | ||
2046 | |||
2047 | LExit: | ||
2048 | return hr; | ||
2049 | } | ||
2050 | |||
1935 | EXTERN_C BAAPI UserExperienceOnPlannedPackage( | 2051 | EXTERN_C BAAPI UserExperienceOnPlannedPackage( |
1936 | __in BURN_USER_EXPERIENCE* pUserExperience, | 2052 | __in BURN_USER_EXPERIENCE* pUserExperience, |
1937 | __in_z LPCWSTR wzPackageId, | 2053 | __in_z LPCWSTR wzPackageId, |
diff --git a/src/burn/engine/userexperience.h b/src/burn/engine/userexperience.h index e4c5d3ee..e8341120 100644 --- a/src/burn/engine/userexperience.h +++ b/src/burn/engine/userexperience.h | |||
@@ -248,6 +248,12 @@ BAAPI UserExperienceOnDetectBegin( | |||
248 | __in BOOL fInstalled, | 248 | __in BOOL fInstalled, |
249 | __in DWORD cPackages | 249 | __in DWORD cPackages |
250 | ); | 250 | ); |
251 | BAAPI UserExperienceOnDetectCompatibleMsiPackage( | ||
252 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
253 | __in_z LPCWSTR wzPackageId, | ||
254 | __in_z LPCWSTR wzCompatiblePackageId, | ||
255 | __in VERUTIL_VERSION* pCompatiblePackageVersion | ||
256 | ); | ||
251 | BAAPI UserExperienceOnDetectComplete( | 257 | BAAPI UserExperienceOnDetectComplete( |
252 | __in BURN_USER_EXPERIENCE* pUserExperience, | 258 | __in BURN_USER_EXPERIENCE* pUserExperience, |
253 | __in HRESULT hrStatus, | 259 | __in HRESULT hrStatus, |
@@ -414,6 +420,20 @@ BAAPI UserExperienceOnPlanBegin( | |||
414 | __in BURN_USER_EXPERIENCE* pUserExperience, | 420 | __in BURN_USER_EXPERIENCE* pUserExperience, |
415 | __in DWORD cPackages | 421 | __in DWORD cPackages |
416 | ); | 422 | ); |
423 | BAAPI UserExperienceOnPlanCompatibleMsiPackageBegin( | ||
424 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
425 | __in_z LPCWSTR wzPackageId, | ||
426 | __in_z LPCWSTR wzCompatiblePackageId, | ||
427 | __in VERUTIL_VERSION* pCompatiblePackageVersion, | ||
428 | __inout BOOL* pfRequested | ||
429 | ); | ||
430 | BAAPI UserExperienceOnPlanCompatibleMsiPackageComplete( | ||
431 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
432 | __in_z LPCWSTR wzPackageId, | ||
433 | __in_z LPCWSTR wzCompatiblePackageId, | ||
434 | __in HRESULT hrStatus, | ||
435 | __in BOOL fRequested | ||
436 | ); | ||
417 | BAAPI UserExperienceOnPlanComplete( | 437 | BAAPI UserExperienceOnPlanComplete( |
418 | __in BURN_USER_EXPERIENCE* pUserExperience, | 438 | __in BURN_USER_EXPERIENCE* pUserExperience, |
419 | __in HRESULT hrStatus | 439 | __in HRESULT hrStatus |
@@ -443,6 +463,12 @@ BAAPI UserExperienceOnPlanMsiPackage( | |||
443 | __inout BOOL* pfDisableExternalUiHandler, | 463 | __inout BOOL* pfDisableExternalUiHandler, |
444 | __inout BOOTSTRAPPER_MSI_FILE_VERSIONING* pFileVersioning | 464 | __inout BOOTSTRAPPER_MSI_FILE_VERSIONING* pFileVersioning |
445 | ); | 465 | ); |
466 | BAAPI UserExperienceOnPlannedCompatiblePackage( | ||
467 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
468 | __in_z LPCWSTR wzPackageId, | ||
469 | __in_z LPCWSTR wzCompatiblePackageId, | ||
470 | __in BOOL fRemove | ||
471 | ); | ||
446 | BAAPI UserExperienceOnPlannedPackage( | 472 | BAAPI UserExperienceOnPlannedPackage( |
447 | __in BURN_USER_EXPERIENCE* pUserExperience, | 473 | __in BURN_USER_EXPERIENCE* pUserExperience, |
448 | __in_z LPCWSTR wzPackageId, | 474 | __in_z LPCWSTR wzPackageId, |
diff --git a/src/burn/test/BurnUnitTest/PlanTest.cpp b/src/burn/test/BurnUnitTest/PlanTest.cpp index 7e704c23..fc2b8472 100644 --- a/src/burn/test/BurnUnitTest/PlanTest.cpp +++ b/src/burn/test/BurnUnitTest/PlanTest.cpp | |||
@@ -288,6 +288,74 @@ namespace Bootstrapper | |||
288 | } | 288 | } |
289 | 289 | ||
290 | [Fact] | 290 | [Fact] |
291 | void OrphanCompatiblePackageTest() | ||
292 | { | ||
293 | HRESULT hr = S_OK; | ||
294 | BURN_ENGINE_STATE engineState = { }; | ||
295 | BURN_ENGINE_STATE* pEngineState = &engineState; | ||
296 | BURN_PLAN* pPlan = &engineState.plan; | ||
297 | |||
298 | InitializeEngineStateForCorePlan(wzSingleMsiManifestFileName, pEngineState); | ||
299 | DetectPackagesAsAbsent(pEngineState); | ||
300 | DetectCompatibleMsiPackage(pEngineState->packages.rgPackages, L"{C24F3903-38E7-4D44-8037-D9856B3C5046}", L"2.0.0.0"); | ||
301 | |||
302 | hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_UNINSTALL); | ||
303 | NativeAssert::Succeeded(hr, "CorePlan failed"); | ||
304 | |||
305 | Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_UNINSTALL, pPlan->action); | ||
306 | Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine); | ||
307 | Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback); | ||
308 | |||
309 | BOOL fRollback = FALSE; | ||
310 | DWORD dwIndex = 0; | ||
311 | Assert::Equal(dwIndex, pPlan->cCacheActions); | ||
312 | |||
313 | fRollback = TRUE; | ||
314 | dwIndex = 0; | ||
315 | Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); | ||
316 | |||
317 | Assert::Equal(0ull, pPlan->qwEstimatedSize); | ||
318 | Assert::Equal(0ull, pPlan->qwCacheSizeTotal); | ||
319 | |||
320 | fRollback = FALSE; | ||
321 | dwIndex = 0; | ||
322 | DWORD dwExecuteCheckpointId = 1; | ||
323 | ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); | ||
324 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", BURN_DEPENDENCY_ACTION_UNREGISTER); | ||
325 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER); | ||
326 | ValidateUninstallMsiCompatiblePackage(pPlan, fRollback, dwIndex++, L"PackageA", 0); | ||
327 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
328 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
329 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); | ||
330 | Assert::Equal(dwIndex, pPlan->cExecuteActions); | ||
331 | |||
332 | fRollback = TRUE; | ||
333 | dwIndex = 0; | ||
334 | dwExecuteCheckpointId = 1; | ||
335 | ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); | ||
336 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
337 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
338 | ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); | ||
339 | Assert::Equal(dwIndex, pPlan->cRollbackActions); | ||
340 | |||
341 | Assert::Equal(1ul, pPlan->cExecutePackagesTotal); | ||
342 | Assert::Equal(1ul, pPlan->cOverallProgressTicksTotal); | ||
343 | |||
344 | dwIndex = 0; | ||
345 | ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); | ||
346 | ValidateCleanCompatibleAction(pPlan, dwIndex++, L"PackageA"); | ||
347 | Assert::Equal(dwIndex, pPlan->cCleanActions); | ||
348 | |||
349 | UINT uIndex = 0; | ||
350 | ValidatePlannedProvider(pPlan, uIndex++, L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", NULL); | ||
351 | ValidatePlannedProvider(pPlan, uIndex++, L"{64633047-D172-4BBB-B202-64337D15C952}", NULL); | ||
352 | Assert::Equal(uIndex, pPlan->cPlannedProviders); | ||
353 | |||
354 | Assert::Equal(1ul, pEngineState->packages.cPackages); | ||
355 | ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[0], L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_ABSENT, BURN_PACKAGE_REGISTRATION_STATE_ABSENT); | ||
356 | } | ||
357 | |||
358 | [Fact] | ||
291 | void RelatedBundleMissingFromCacheTest() | 359 | void RelatedBundleMissingFromCacheTest() |
292 | { | 360 | { |
293 | HRESULT hr = S_OK; | 361 | HRESULT hr = S_OK; |
@@ -1026,6 +1094,36 @@ namespace Bootstrapper | |||
1026 | } | 1094 | } |
1027 | } | 1095 | } |
1028 | 1096 | ||
1097 | void DetectCompatibleMsiPackage(BURN_PACKAGE* pPackage, LPCWSTR wzProductCode, LPCWSTR wzVersion) | ||
1098 | { | ||
1099 | HRESULT hr = S_OK; | ||
1100 | Assert(BOOTSTRAPPER_PACKAGE_STATE_PRESENT > pPackage->currentState); | ||
1101 | Assert(0 < pPackage->cDependencyProviders); | ||
1102 | BURN_DEPENDENCY_PROVIDER* pProvider = pPackage->rgDependencyProviders; | ||
1103 | BURN_COMPATIBLE_PACKAGE* pCompatiblePackage = &pPackage->compatiblePackage; | ||
1104 | pCompatiblePackage->fDetected = TRUE; | ||
1105 | pCompatiblePackage->fPlannable = TRUE; | ||
1106 | pCompatiblePackage->type = BURN_PACKAGE_TYPE_MSI; | ||
1107 | |||
1108 | hr = StrAllocFormatted(&pCompatiblePackage->sczCacheId, L"%lsv%ls", wzProductCode, wzVersion); | ||
1109 | NativeAssert::Succeeded(hr, "Failed to format cache id"); | ||
1110 | |||
1111 | hr = StrAllocString(&pCompatiblePackage->Msi.sczVersion, wzVersion, 0); | ||
1112 | NativeAssert::Succeeded(hr, "Failed to copy MSI version"); | ||
1113 | |||
1114 | hr = VerParseVersion(wzVersion, 0, FALSE, &pCompatiblePackage->Msi.pVersion); | ||
1115 | NativeAssert::Succeeded(hr, "Failed to parse MSI version"); | ||
1116 | |||
1117 | hr = StrAllocString(&pCompatiblePackage->compatibleEntry.sczId, wzProductCode, 0); | ||
1118 | NativeAssert::Succeeded(hr, "Failed to copy product code"); | ||
1119 | |||
1120 | hr = StrAllocString(&pCompatiblePackage->compatibleEntry.sczVersion, wzVersion, 0); | ||
1121 | NativeAssert::Succeeded(hr, "Failed to copy version"); | ||
1122 | |||
1123 | hr = StrAllocString(&pCompatiblePackage->compatibleEntry.sczProviderKey, pProvider->sczKey, 0); | ||
1124 | NativeAssert::Succeeded(hr, "Failed to copy provider key"); | ||
1125 | } | ||
1126 | |||
1029 | void DetectPackageAsAbsent(BURN_PACKAGE* pPackage) | 1127 | void DetectPackageAsAbsent(BURN_PACKAGE* pPackage) |
1030 | { | 1128 | { |
1031 | pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT; | 1129 | pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT; |
@@ -1262,9 +1360,26 @@ namespace Bootstrapper | |||
1262 | __in LPCWSTR wzPackageId | 1360 | __in LPCWSTR wzPackageId |
1263 | ) | 1361 | ) |
1264 | { | 1362 | { |
1363 | BURN_CLEAN_ACTION* pCleanAction = ValidateCleanActionExists(pPlan, dwIndex); | ||
1364 | Assert::Equal<DWORD>(BURN_CLEAN_ACTION_TYPE_PACKAGE, pCleanAction->type); | ||
1365 | Assert::NotEqual((DWORD_PTR)0, (DWORD_PTR)pCleanAction->pPackage); | ||
1366 | NativeAssert::StringEqual(wzPackageId, pCleanAction->pPackage->sczId); | ||
1367 | } | ||
1368 | |||
1369 | BURN_CLEAN_ACTION* ValidateCleanActionExists(BURN_PLAN* pPlan, DWORD dwIndex) | ||
1370 | { | ||
1265 | Assert::InRange(dwIndex + 1ul, 1ul, pPlan->cCleanActions); | 1371 | Assert::InRange(dwIndex + 1ul, 1ul, pPlan->cCleanActions); |
1372 | return pPlan->rgCleanActions + dwIndex; | ||
1373 | } | ||
1266 | 1374 | ||
1267 | BURN_CLEAN_ACTION* pCleanAction = pPlan->rgCleanActions + dwIndex; | 1375 | void ValidateCleanCompatibleAction( |
1376 | __in BURN_PLAN* pPlan, | ||
1377 | __in DWORD dwIndex, | ||
1378 | __in LPCWSTR wzPackageId | ||
1379 | ) | ||
1380 | { | ||
1381 | BURN_CLEAN_ACTION* pCleanAction = ValidateCleanActionExists(pPlan, dwIndex); | ||
1382 | Assert::Equal<DWORD>(BURN_CLEAN_ACTION_TYPE_COMPATIBLE_PACKAGE, pCleanAction->type); | ||
1268 | Assert::NotEqual((DWORD_PTR)0, (DWORD_PTR)pCleanAction->pPackage); | 1383 | Assert::NotEqual((DWORD_PTR)0, (DWORD_PTR)pCleanAction->pPackage); |
1269 | NativeAssert::StringEqual(wzPackageId, pCleanAction->pPackage->sczId); | 1384 | NativeAssert::StringEqual(wzPackageId, pCleanAction->pPackage->sczId); |
1270 | } | 1385 | } |
@@ -1537,6 +1652,22 @@ namespace Bootstrapper | |||
1537 | NativeAssert::StringEqual(wzKey, pProvider->sczKey); | 1652 | NativeAssert::StringEqual(wzKey, pProvider->sczKey); |
1538 | NativeAssert::StringEqual(wzName, pProvider->sczName); | 1653 | NativeAssert::StringEqual(wzName, pProvider->sczName); |
1539 | } | 1654 | } |
1655 | |||
1656 | void ValidateUninstallMsiCompatiblePackage( | ||
1657 | __in BURN_PLAN* pPlan, | ||
1658 | __in BOOL fRollback, | ||
1659 | __in DWORD dwIndex, | ||
1660 | __in_z LPCWSTR wzPackageId, | ||
1661 | __in DWORD dwLoggingAttributes | ||
1662 | ) | ||
1663 | { | ||
1664 | BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex); | ||
1665 | Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE, pAction->type); | ||
1666 | NativeAssert::StringEqual(wzPackageId, pAction->uninstallMsiCompatiblePackage.pParentPackage->sczId); | ||
1667 | NativeAssert::NotNull(pAction->msiPackage.sczLogPath); | ||
1668 | Assert::Equal<DWORD>(dwLoggingAttributes, pAction->uninstallMsiCompatiblePackage.dwLoggingAttributes); | ||
1669 | Assert::Equal<BOOL>(FALSE, pAction->fDeleted); | ||
1670 | } | ||
1540 | }; | 1671 | }; |
1541 | } | 1672 | } |
1542 | } | 1673 | } |
diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp index 7b70d772..02c10472 100644 --- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp +++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp | |||
@@ -1424,6 +1424,18 @@ public: // IBootstrapperApplication | |||
1424 | case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATECOMPLETE: | 1424 | case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATECOMPLETE: |
1425 | OnSetUpdateCompleteFallback(reinterpret_cast<BA_ONSETUPDATECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONSETUPDATECOMPLETE_RESULTS*>(pvResults)); | 1425 | OnSetUpdateCompleteFallback(reinterpret_cast<BA_ONSETUPDATECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONSETUPDATECOMPLETE_RESULTS*>(pvResults)); |
1426 | break; | 1426 | break; |
1427 | case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE: | ||
1428 | OnDetectCompatibleMsiPackageFallback(reinterpret_cast<BA_ONDETECTCOMPATIBLEMSIPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTCOMPATIBLEMSIPACKAGE_RESULTS*>(pvResults)); | ||
1429 | break; | ||
1430 | case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN: | ||
1431 | OnPlanCompatibleMsiPackageBeginFallback(reinterpret_cast<BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_RESULTS*>(pvResults)); | ||
1432 | break; | ||
1433 | case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE: | ||
1434 | OnPlanCompatibleMsiPackageCompleteFallback(reinterpret_cast<BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_RESULTS*>(pvResults)); | ||
1435 | break; | ||
1436 | case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE: | ||
1437 | OnPlannedCompatiblePackageFallback(reinterpret_cast<BA_ONPLANNEDCOMPATIBLEPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANNEDCOMPATIBLEPACKAGE_RESULTS*>(pvResults)); | ||
1438 | break; | ||
1427 | default: | 1439 | default: |
1428 | #ifdef DEBUG | 1440 | #ifdef DEBUG |
1429 | BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: Forwarding unknown BA message: %d", message); | 1441 | BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: Forwarding unknown BA message: %d", message); |
@@ -1611,6 +1623,14 @@ private: // privates | |||
1611 | m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANPACKAGECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext); | 1623 | m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANPACKAGECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext); |
1612 | } | 1624 | } |
1613 | 1625 | ||
1626 | void OnPlannedCompatiblePackageFallback( | ||
1627 | __in BA_ONPLANNEDCOMPATIBLEPACKAGE_ARGS* pArgs, | ||
1628 | __inout BA_ONPLANNEDCOMPATIBLEPACKAGE_RESULTS* pResults | ||
1629 | ) | ||
1630 | { | ||
1631 | m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE, pArgs, pResults, m_pvBAFunctionsProcContext); | ||
1632 | } | ||
1633 | |||
1614 | void OnPlannedPackageFallback( | 1634 | void OnPlannedPackageFallback( |
1615 | __in BA_ONPLANNEDPACKAGE_ARGS* pArgs, | 1635 | __in BA_ONPLANNEDPACKAGE_ARGS* pArgs, |
1616 | __inout BA_ONPLANNEDPACKAGE_RESULTS* pResults | 1636 | __inout BA_ONPLANNEDPACKAGE_RESULTS* pResults |
@@ -2043,6 +2063,32 @@ private: // privates | |||
2043 | m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONSETUPDATECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext); | 2063 | m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONSETUPDATECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext); |
2044 | } | 2064 | } |
2045 | 2065 | ||
2066 | void OnDetectCompatibleMsiPackageFallback( | ||
2067 | __in BA_ONDETECTCOMPATIBLEMSIPACKAGE_ARGS* pArgs, | ||
2068 | __inout BA_ONDETECTCOMPATIBLEMSIPACKAGE_RESULTS* pResults | ||
2069 | ) | ||
2070 | { | ||
2071 | m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE, pArgs, pResults, m_pvBAFunctionsProcContext); | ||
2072 | } | ||
2073 | |||
2074 | void OnPlanCompatibleMsiPackageBeginFallback( | ||
2075 | __in BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_ARGS* pArgs, | ||
2076 | __inout BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_RESULTS* pResults | ||
2077 | ) | ||
2078 | { | ||
2079 | BOOL fRequestRemove = pResults->fRequestRemove; | ||
2080 | m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext); | ||
2081 | BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_COMPATIBLE_MSI_PACKAGE, m_hModule, pArgs->wzPackageId, pArgs->wzCompatiblePackageId, LoggingBoolToString(fRequestRemove), LoggingBoolToString(pResults->fRequestRemove)); | ||
2082 | } | ||
2083 | |||
2084 | void OnPlanCompatibleMsiPackageCompleteFallback( | ||
2085 | __in BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_ARGS* pArgs, | ||
2086 | __inout BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_RESULTS* pResults | ||
2087 | ) | ||
2088 | { | ||
2089 | m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext); | ||
2090 | } | ||
2091 | |||
2046 | 2092 | ||
2047 | public: //CBalBaseBootstrapperApplication | 2093 | public: //CBalBaseBootstrapperApplication |
2048 | virtual STDMETHODIMP Initialize( | 2094 | virtual STDMETHODIMP Initialize( |
diff --git a/src/ext/Bal/wixstdba/wixstdba.mc b/src/ext/Bal/wixstdba/wixstdba.mc index 659ccd01..40acfe54 100644 --- a/src/ext/Bal/wixstdba/wixstdba.mc +++ b/src/ext/Bal/wixstdba/wixstdba.mc | |||
@@ -50,6 +50,13 @@ Language=English | |||
50 | WIXSTDBA: Planned related bundle: %1!ls!, wixstdba requested: %2!hs!, bafunctions requested: %3!hs! | 50 | WIXSTDBA: Planned related bundle: %1!ls!, wixstdba requested: %2!hs!, bafunctions requested: %3!hs! |
51 | . | 51 | . |
52 | 52 | ||
53 | MessageId=4 | ||
54 | Severity=Success | ||
55 | SymbolicName=MSG_WIXSTDBA_PLANNED_COMPATIBLE_MSI_PACKAGE | ||
56 | Language=English | ||
57 | WIXSTDBA: Planned compatible package: %2!ls! for %1!ls!, wixstdba requested remove: %3!hs!, bafunctions requested remove: %4!hs! | ||
58 | . | ||
59 | |||
53 | MessageId=5 | 60 | MessageId=5 |
54 | Severity=Success | 61 | Severity=Success |
55 | SymbolicName=MSG_WIXSTDBA_PLANNED_TARGET_MSI_PACKAGE | 62 | SymbolicName=MSG_WIXSTDBA_PLANNED_TARGET_MSI_PACKAGE |
diff --git a/src/test/burn/TestData/DependencyTests/BundleAv2/BundleAv2.wixproj b/src/test/burn/TestData/DependencyTests/BundleAv2/BundleAv2.wixproj new file mode 100644 index 00000000..eab737f8 --- /dev/null +++ b/src/test/burn/TestData/DependencyTests/BundleAv2/BundleAv2.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>2.0.0.0</Version> | ||
6 | </PropertyGroup> | ||
7 | <ItemGroup> | ||
8 | <ProjectReference Include="..\PackageAv2\PackageAv2.wixproj" /> | ||
9 | <ProjectReference Include="..\..\TestBA\TestBAWixlib\testbawixlib.wixproj" /> | ||
10 | </ItemGroup> | ||
11 | <ItemGroup> | ||
12 | <PackageReference Include="WixToolset.Bal.wixext" /> | ||
13 | <PackageReference Include="WixToolset.NetFx.wixext" /> | ||
14 | <PackageReference Include="WixToolset.Util.wixext" /> | ||
15 | </ItemGroup> | ||
16 | </Project> \ No newline at end of file | ||
diff --git a/src/test/burn/TestData/DependencyTests/BundleAv2/BundleAv2.wxs b/src/test/burn/TestData/DependencyTests/BundleAv2/BundleAv2.wxs new file mode 100644 index 00000000..570f633f --- /dev/null +++ b/src/test/burn/TestData/DependencyTests/BundleAv2/BundleAv2.wxs | |||
@@ -0,0 +1,21 @@ | |||
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 | <?define TestExeRegistryKey = Software\WiX\Tests\$(var.TestGroupName)\ExeA?> | ||
4 | |||
5 | <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util"> | ||
6 | <Fragment> | ||
7 | <util:RegistrySearch Root="HKLM" Key="$(var.TestExeRegistryKey)" Value="Version" Variable="ExeA_Version" /> | ||
8 | |||
9 | <PackageGroup Id="BundlePackages"> | ||
10 | <MsiPackage Id="PackageA" SourceFile="$(var.PackageAv2.TargetPath)" /> | ||
11 | <ExePackage Id="ExeA" Cache="remove" PerMachine="yes" | ||
12 | DetectCondition="ExeA_Version AND ExeA_Version >= v$(var.Version)" | ||
13 | InstallArguments="/regw "HKLM\$(var.TestExeRegistryKey),Version,String,$(var.Version)"" | ||
14 | RepairArguments="/regw "HKLM\$(var.TestExeRegistryKey),Version,String,$(var.Version)"" | ||
15 | UninstallArguments="/regd "HKLM\$(var.TestExeRegistryKey),Version""> | ||
16 | <Provides Key="$(var.TestGroupName)_ExeA,v1.0" Version="$(var.Version)" /> | ||
17 | <PayloadGroupRef Id="TestExePayloads" /> | ||
18 | </ExePackage> | ||
19 | </PackageGroup> | ||
20 | </Fragment> | ||
21 | </Wix> | ||
diff --git a/src/test/burn/TestData/DependencyTests/PackageAv1/PackageA.props b/src/test/burn/TestData/DependencyTests/PackageAv1/PackageA.props index 8cbe9aa9..d6778261 100644 --- a/src/test/burn/TestData/DependencyTests/PackageAv1/PackageA.props +++ b/src/test/burn/TestData/DependencyTests/PackageAv1/PackageA.props | |||
@@ -3,7 +3,6 @@ | |||
3 | <PropertyGroup> | 3 | <PropertyGroup> |
4 | <PackageName>PackageA</PackageName> | 4 | <PackageName>PackageA</PackageName> |
5 | <ProductComponentsRef>true</ProductComponentsRef> | 5 | <ProductComponentsRef>true</ProductComponentsRef> |
6 | <ProductCode>{6F171EC9-0774-4974-A8D1-493EF53CAB74}</ProductCode> | ||
7 | <UpgradeCode>{45E933B7-B56A-44D5-8EEC-625EC199085E}</UpgradeCode> | 6 | <UpgradeCode>{45E933B7-B56A-44D5-8EEC-625EC199085E}</UpgradeCode> |
8 | </PropertyGroup> | 7 | </PropertyGroup> |
9 | <ItemGroup> | 8 | <ItemGroup> |
diff --git a/src/test/burn/TestData/DependencyTests/PackageAv1/PackageAv1.props b/src/test/burn/TestData/DependencyTests/PackageAv1/PackageAv1.props new file mode 100644 index 00000000..e83247c0 --- /dev/null +++ b/src/test/burn/TestData/DependencyTests/PackageAv1/PackageAv1.props | |||
@@ -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> | ||
3 | <Import Project="PackageA.props" /> | ||
4 | <PropertyGroup> | ||
5 | <ProductCode>{6F171EC9-0774-4974-A8D1-493EF53CAB74}</ProductCode> | ||
6 | </PropertyGroup> | ||
7 | </Project> \ No newline at end of file | ||
diff --git a/src/test/burn/TestData/DependencyTests/PackageAv1/PackageAv1.wixproj b/src/test/burn/TestData/DependencyTests/PackageAv1/PackageAv1.wixproj index 5ebce845..add55d60 100644 --- a/src/test/burn/TestData/DependencyTests/PackageAv1/PackageAv1.wixproj +++ b/src/test/burn/TestData/DependencyTests/PackageAv1/PackageAv1.wixproj | |||
@@ -1,6 +1,6 @@ | |||
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. --> | 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"> | 2 | <Project Sdk="WixToolset.Sdk"> |
3 | <Import Project="PackageA.props" /> | 3 | <Import Project="PackageAv1.props" /> |
4 | <ItemGroup> | 4 | <ItemGroup> |
5 | <PackageReference Include="WixToolset.Dependency.wixext" /> | 5 | <PackageReference Include="WixToolset.Dependency.wixext" /> |
6 | </ItemGroup> | 6 | </ItemGroup> |
diff --git a/src/test/burn/TestData/DependencyTests/PackageAv1_0_1/PackageAv1_0_1.wixproj b/src/test/burn/TestData/DependencyTests/PackageAv1_0_1/PackageAv1_0_1.wixproj index 73a7cb6f..e1081745 100644 --- a/src/test/burn/TestData/DependencyTests/PackageAv1_0_1/PackageAv1_0_1.wixproj +++ b/src/test/burn/TestData/DependencyTests/PackageAv1_0_1/PackageAv1_0_1.wixproj | |||
@@ -1,6 +1,6 @@ | |||
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. --> | 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"> | 2 | <Project Sdk="WixToolset.Sdk"> |
3 | <Import Project="..\PackageAv1\PackageA.props" /> | 3 | <Import Project="..\PackageAv1\PackageAv1.props" /> |
4 | <PropertyGroup> | 4 | <PropertyGroup> |
5 | <Version>1.0.1.0</Version> | 5 | <Version>1.0.1.0</Version> |
6 | </PropertyGroup> | 6 | </PropertyGroup> |
diff --git a/src/test/burn/TestData/DependencyTests/PackageAv1_0_2/PackageAv1_0_2.wixproj b/src/test/burn/TestData/DependencyTests/PackageAv1_0_2/PackageAv1_0_2.wixproj index 37e88de9..60b64c9f 100644 --- a/src/test/burn/TestData/DependencyTests/PackageAv1_0_2/PackageAv1_0_2.wixproj +++ b/src/test/burn/TestData/DependencyTests/PackageAv1_0_2/PackageAv1_0_2.wixproj | |||
@@ -1,6 +1,6 @@ | |||
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. --> | 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"> | 2 | <Project Sdk="WixToolset.Sdk"> |
3 | <Import Project="..\PackageAv1\PackageA.props" /> | 3 | <Import Project="..\PackageAv1\PackageAv1.props" /> |
4 | <PropertyGroup> | 4 | <PropertyGroup> |
5 | <Version>1.0.2.0</Version> | 5 | <Version>1.0.2.0</Version> |
6 | </PropertyGroup> | 6 | </PropertyGroup> |
diff --git a/src/test/burn/TestData/DependencyTests/PackageAv2/PackageAv2.wixproj b/src/test/burn/TestData/DependencyTests/PackageAv2/PackageAv2.wixproj new file mode 100644 index 00000000..b61d09f5 --- /dev/null +++ b/src/test/burn/TestData/DependencyTests/PackageAv2/PackageAv2.wixproj | |||
@@ -0,0 +1,13 @@ | |||
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>2.0.0.0</Version> | ||
6 | </PropertyGroup> | ||
7 | <ItemGroup> | ||
8 | <Compile Include="..\PackageAv1\ProductComponents.wxs" Link="ProductComponents.wxs" /> | ||
9 | </ItemGroup> | ||
10 | <ItemGroup> | ||
11 | <PackageReference Include="WixToolset.Dependency.wixext" /> | ||
12 | </ItemGroup> | ||
13 | </Project> \ No newline at end of file | ||
diff --git a/src/test/burn/WixTestTools/BundleVerifier.cs b/src/test/burn/WixTestTools/BundleVerifier.cs index 54f90870..db14c228 100644 --- a/src/test/burn/WixTestTools/BundleVerifier.cs +++ b/src/test/burn/WixTestTools/BundleVerifier.cs | |||
@@ -124,14 +124,14 @@ namespace WixTestTools | |||
124 | } | 124 | } |
125 | } | 125 | } |
126 | 126 | ||
127 | public void VerifyPackageIsCached(string packageId) | 127 | public void VerifyPackageIsCached(string packageId, bool cached = true) |
128 | { | 128 | { |
129 | using var wixOutput = WixOutput.Read(this.BundlePdb); | 129 | using var wixOutput = WixOutput.Read(this.BundlePdb); |
130 | var intermediate = Intermediate.Load(wixOutput); | 130 | var intermediate = Intermediate.Load(wixOutput); |
131 | var section = intermediate.Sections.Single(); | 131 | var section = intermediate.Sections.Single(); |
132 | var packageSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().Single(p => p.Id.Id == packageId); | 132 | var packageSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().Single(p => p.Id.Id == packageId); |
133 | var cachePath = this.GetPackageCachePathForCacheId(packageSymbol.CacheId, packageSymbol.PerMachine == YesNoDefaultType.Yes); | 133 | var cachePath = this.GetPackageCachePathForCacheId(packageSymbol.CacheId, packageSymbol.PerMachine == YesNoDefaultType.Yes); |
134 | Assert.True(Directory.Exists(cachePath)); | 134 | Assert.Equal(cached, Directory.Exists(cachePath)); |
135 | } | 135 | } |
136 | 136 | ||
137 | public void VerifyExeTestRegistryRootDeleted(string name, bool x64 = false) | 137 | public void VerifyExeTestRegistryRootDeleted(string name, bool x64 = false) |
diff --git a/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs index b08cd54f..825160c5 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs | |||
@@ -123,6 +123,64 @@ namespace WixToolsetTest.BurnE2E | |||
123 | bundleAv1.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.1.0"); | 123 | bundleAv1.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.1.0"); |
124 | } | 124 | } |
125 | 125 | ||
126 | [Fact] | ||
127 | public void UninstallsOrphanCompatiblePackages() | ||
128 | { | ||
129 | var testRegistryValueExe = "ExeA"; | ||
130 | |||
131 | var packageAv1 = this.CreatePackageInstaller("PackageAv1"); | ||
132 | var packageAv2 = this.CreatePackageInstaller("PackageAv2"); | ||
133 | var packageB = this.CreatePackageInstaller("PackageB"); | ||
134 | var bundleAv1 = this.CreateBundleInstaller("BundleAv1"); | ||
135 | var bundleAv2 = this.CreateBundleInstaller("BundleAv2"); | ||
136 | var bundleB = this.CreateBundleInstaller("BundleB"); | ||
137 | |||
138 | packageAv1.VerifyInstalled(false); | ||
139 | packageAv2.VerifyInstalled(false); | ||
140 | packageB.VerifyInstalled(false); | ||
141 | |||
142 | bundleAv1.Install(); | ||
143 | bundleAv1.VerifyRegisteredAndInPackageCache(); | ||
144 | |||
145 | packageAv1.VerifyInstalled(true); | ||
146 | bundleAv1.VerifyPackageIsCached("PackageA"); | ||
147 | bundleAv1.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0"); | ||
148 | |||
149 | bundleB.Install(); | ||
150 | bundleB.VerifyRegisteredAndInPackageCache(); | ||
151 | |||
152 | packageAv1.VerifyInstalled(true); | ||
153 | bundleAv1.VerifyPackageIsCached("PackageA"); | ||
154 | bundleAv1.VerifyExeTestRegistryValue(testRegistryValueExe, "1.0.0.0"); | ||
155 | packageB.VerifyInstalled(true); | ||
156 | |||
157 | bundleAv2.Install(); | ||
158 | bundleAv2.VerifyRegisteredAndInPackageCache(); | ||
159 | bundleAv1.VerifyUnregisteredAndRemovedFromPackageCache(); | ||
160 | |||
161 | packageAv1.VerifyInstalled(false); | ||
162 | bundleAv1.VerifyPackageIsCached("PackageA", false); | ||
163 | packageAv2.VerifyInstalled(true); | ||
164 | bundleAv2.VerifyPackageIsCached("PackageA"); | ||
165 | bundleAv1.VerifyExeTestRegistryValue(testRegistryValueExe, "2.0.0.0"); | ||
166 | |||
167 | bundleAv2.Uninstall(); | ||
168 | bundleAv2.VerifyUnregisteredAndRemovedFromPackageCache(); | ||
169 | |||
170 | packageAv2.VerifyInstalled(true); | ||
171 | bundleAv2.VerifyPackageIsCached("PackageA"); | ||
172 | bundleAv1.VerifyExeTestRegistryValue(testRegistryValueExe, "2.0.0.0"); | ||
173 | |||
174 | // Verify https://github.com/wixtoolset/issues/issues/3190 | ||
175 | bundleB.Uninstall(); | ||
176 | |||
177 | packageAv1.VerifyInstalled(false); | ||
178 | packageAv2.VerifyInstalled(false); | ||
179 | bundleAv2.VerifyPackageIsCached("PackageA", false); | ||
180 | packageB.VerifyInstalled(false); | ||
181 | bundleAv1.VerifyExeTestRegistryRootDeleted(testRegistryValueExe); | ||
182 | } | ||
183 | |||
126 | [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6401")] | 184 | [Fact(Skip = "https://github.com/wixtoolset/issues/issues/6401")] |
127 | public void CanMinorUpgradeDependencyPackageFromPatchBundle() | 185 | public void CanMinorUpgradeDependencyPackageFromPatchBundle() |
128 | { | 186 | { |