diff options
Diffstat (limited to 'src')
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 | { |
