diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/engine/apply.cpp | 194 | ||||
| -rw-r--r-- | src/engine/msiengine.cpp | 5 | ||||
| -rw-r--r-- | src/engine/msiengine.h | 1 | ||||
| -rw-r--r-- | src/engine/mspengine.cpp | 5 | ||||
| -rw-r--r-- | src/engine/mspengine.h | 1 | ||||
| -rw-r--r-- | src/engine/package.h | 1 | ||||
| -rw-r--r-- | src/engine/plan.cpp | 86 | ||||
| -rw-r--r-- | src/engine/plan.h | 20 | ||||
| -rw-r--r-- | src/test/BurnUnitTest/PlanTest.cpp | 62 |
9 files changed, 226 insertions, 149 deletions
diff --git a/src/engine/apply.cpp b/src/engine/apply.cpp index 909fb159..53422807 100644 --- a/src/engine/apply.cpp +++ b/src/engine/apply.cpp | |||
| @@ -3,6 +3,12 @@ | |||
| 3 | #include "precomp.h" | 3 | #include "precomp.h" |
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | #ifdef DEBUG | ||
| 7 | #define IgnoreRollbackError(x, f, ...) if (FAILED(x)) { TraceError(x, f, __VA_ARGS__); } | ||
| 8 | #else | ||
| 9 | #define IgnoreRollbackError(x, f, ...) | ||
| 10 | #endif | ||
| 11 | |||
| 6 | const DWORD BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS = 2; | 12 | const DWORD BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS = 2; |
| 7 | 13 | ||
| 8 | // structs | 14 | // structs |
| @@ -134,7 +140,7 @@ static HRESULT DoExecuteAction( | |||
| 134 | __in_opt HANDLE hCacheThread, | 140 | __in_opt HANDLE hCacheThread, |
| 135 | __in BURN_EXECUTE_CONTEXT* pContext, | 141 | __in BURN_EXECUTE_CONTEXT* pContext, |
| 136 | __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary, | 142 | __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary, |
| 137 | __out DWORD* pdwCheckpoint, | 143 | __inout BURN_EXECUTE_ACTION_CHECKPOINT** ppCheckpoint, |
| 138 | __out BOOL* pfKeepRegistration, | 144 | __out BOOL* pfKeepRegistration, |
| 139 | __out BOOL* pfSuspend, | 145 | __out BOOL* pfSuspend, |
| 140 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | 146 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart |
| @@ -143,7 +149,6 @@ static HRESULT DoRollbackActions( | |||
| 143 | __in BURN_ENGINE_STATE* pEngineState, | 149 | __in BURN_ENGINE_STATE* pEngineState, |
| 144 | __in BURN_EXECUTE_CONTEXT* pContext, | 150 | __in BURN_EXECUTE_CONTEXT* pContext, |
| 145 | __in DWORD dwCheckpoint, | 151 | __in DWORD dwCheckpoint, |
| 146 | __in BOOL fInTransaction, | ||
| 147 | __out BOOL* pfKeepRegistration, | 152 | __out BOOL* pfKeepRegistration, |
| 148 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | 153 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart |
| 149 | ); | 154 | ); |
| @@ -200,15 +205,17 @@ static HRESULT ExecuteCompatiblePackageAction( | |||
| 200 | ); | 205 | ); |
| 201 | static HRESULT ExecuteMsiBeginTransaction( | 206 | static HRESULT ExecuteMsiBeginTransaction( |
| 202 | __in BURN_ENGINE_STATE* pEngineState, | 207 | __in BURN_ENGINE_STATE* pEngineState, |
| 203 | __in LPCWSTR wzName, | 208 | __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary, |
| 204 | __in BURN_EXECUTE_CONTEXT* pContext | 209 | __in BURN_EXECUTE_CONTEXT* pContext |
| 205 | ); | 210 | ); |
| 206 | static HRESULT ExecuteMsiCommitTransaction( | 211 | static HRESULT ExecuteMsiCommitTransaction( |
| 207 | __in BURN_ENGINE_STATE* pEngineState, | 212 | __in BURN_ENGINE_STATE* pEngineState, |
| 213 | __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary, | ||
| 208 | __in BURN_EXECUTE_CONTEXT* pContext | 214 | __in BURN_EXECUTE_CONTEXT* pContext |
| 209 | ); | 215 | ); |
| 210 | static HRESULT ExecuteMsiRollbackTransaction( | 216 | static HRESULT ExecuteMsiRollbackTransaction( |
| 211 | __in BURN_ENGINE_STATE* pEngineState, | 217 | __in BURN_ENGINE_STATE* pEngineState, |
| 218 | __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary, | ||
| 212 | __in BURN_EXECUTE_CONTEXT* pContext | 219 | __in BURN_EXECUTE_CONTEXT* pContext |
| 213 | ); | 220 | ); |
| 214 | static HRESULT CleanPackage( | 221 | static HRESULT CleanPackage( |
| @@ -732,11 +739,11 @@ extern "C" HRESULT ApplyExecute( | |||
| 732 | ) | 739 | ) |
| 733 | { | 740 | { |
| 734 | HRESULT hr = S_OK; | 741 | HRESULT hr = S_OK; |
| 735 | DWORD dwCheckpoint = 0; | 742 | HRESULT hrRollback = S_OK; |
| 743 | BURN_EXECUTE_ACTION_CHECKPOINT* pCheckpoint = NULL; | ||
| 736 | BURN_EXECUTE_CONTEXT context = { }; | 744 | BURN_EXECUTE_CONTEXT context = { }; |
| 737 | BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL; | 745 | BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL; |
| 738 | BOOL fSeekNextRollbackBoundary = FALSE; | 746 | BOOL fSeekNextRollbackBoundary = FALSE; |
| 739 | BOOL fInTransaction = FALSE; | ||
| 740 | 747 | ||
| 741 | context.pUX = &pEngineState->userExperience; | 748 | context.pUX = &pEngineState->userExperience; |
| 742 | context.cExecutePackagesTotal = pEngineState->plan.cExecutePackagesTotal; | 749 | context.cExecutePackagesTotal = pEngineState->plan.cExecutePackagesTotal; |
| @@ -755,36 +762,6 @@ extern "C" HRESULT ApplyExecute( | |||
| 755 | continue; | 762 | continue; |
| 756 | } | 763 | } |
| 757 | 764 | ||
| 758 | // Transaction end/start | ||
| 759 | if (BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY == pExecuteAction->type) | ||
| 760 | { | ||
| 761 | // End previous transaction | ||
| 762 | if (fInTransaction) | ||
| 763 | { | ||
| 764 | LogString(REPORT_STANDARD, "Committing MSI transaction\n"); | ||
| 765 | hr = ExecuteMsiCommitTransaction(pEngineState, &context); | ||
| 766 | ExitOnFailure(hr, "Failed committing an MSI transaction"); | ||
| 767 | fInTransaction = FALSE; | ||
| 768 | } | ||
| 769 | |||
| 770 | // Start New transaction | ||
| 771 | if (!fInTransaction && pExecuteAction->rollbackBoundary.pRollbackBoundary && pExecuteAction->rollbackBoundary.pRollbackBoundary->fTransaction) | ||
| 772 | { | ||
| 773 | // Transactions don't go together with DisableRollback. | ||
| 774 | if (pEngineState->fDisableRollback) | ||
| 775 | { | ||
| 776 | LogString(REPORT_STANDARD, "Ignoring Transaction flag due to DisableRollback flag\n"); | ||
| 777 | } | ||
| 778 | else | ||
| 779 | { | ||
| 780 | LogString(REPORT_STANDARD, "Starting a new MSI transaction\n"); | ||
| 781 | hr = ExecuteMsiBeginTransaction(pEngineState, pExecuteAction->rollbackBoundary.pRollbackBoundary->sczId, &context); | ||
| 782 | ExitOnFailure(hr, "Failed beginning an MSI transaction"); | ||
| 783 | fInTransaction = TRUE; | ||
| 784 | } | ||
| 785 | } | ||
| 786 | } | ||
| 787 | |||
| 788 | // If we are seeking the next rollback boundary, skip if this action wasn't it. | 765 | // If we are seeking the next rollback boundary, skip if this action wasn't it. |
| 789 | if (fSeekNextRollbackBoundary) | 766 | if (fSeekNextRollbackBoundary) |
| 790 | { | 767 | { |
| @@ -799,11 +776,11 @@ extern "C" HRESULT ApplyExecute( | |||
| 799 | } | 776 | } |
| 800 | 777 | ||
| 801 | // Execute the action. | 778 | // Execute the action. |
| 802 | hr = DoExecuteAction(pEngineState, pExecuteAction, hCacheThread, &context, &pRollbackBoundary, &dwCheckpoint, pfKeepRegistration, pfSuspend, pRestart); | 779 | hr = DoExecuteAction(pEngineState, pExecuteAction, hCacheThread, &context, &pRollbackBoundary, &pCheckpoint, pfKeepRegistration, pfSuspend, pRestart); |
| 803 | 780 | ||
| 804 | if (*pfSuspend || BOOTSTRAPPER_APPLY_RESTART_INITIATED == *pRestart) | 781 | if (*pfSuspend || BOOTSTRAPPER_APPLY_RESTART_INITIATED == *pRestart) |
| 805 | { | 782 | { |
| 806 | if (fInTransaction) | 783 | if (pCheckpoint && pCheckpoint->pActiveRollbackBoundary && pCheckpoint->pActiveRollbackBoundary->fActiveTransaction) |
| 807 | { | 784 | { |
| 808 | hr = E_INVALIDSTATE; | 785 | hr = E_INVALIDSTATE; |
| 809 | LogString(REPORT_ERROR, "Ilegal state: Reboot requested within an MSI transaction. Transaction will rollback."); | 786 | LogString(REPORT_ERROR, "Ilegal state: Reboot requested within an MSI transaction. Transaction will rollback."); |
| @@ -816,37 +793,43 @@ extern "C" HRESULT ApplyExecute( | |||
| 816 | 793 | ||
| 817 | if (FAILED(hr)) | 794 | if (FAILED(hr)) |
| 818 | { | 795 | { |
| 819 | // If we failed, but rollback is disabled just bail with our error code. | 796 | // If rollback is disabled, keep what we have and always end execution here. |
| 820 | if (pEngineState->fDisableRollback) | 797 | if (pEngineState->plan.fDisableRollback) |
| 821 | { | 798 | { |
| 799 | if (pCheckpoint && pCheckpoint->pActiveRollbackBoundary && pCheckpoint->pActiveRollbackBoundary->fActiveTransaction) | ||
| 800 | { | ||
| 801 | hrRollback = ExecuteMsiCommitTransaction(pEngineState, pCheckpoint->pActiveRollbackBoundary, &context); | ||
| 802 | IgnoreRollbackError(hrRollback, "Failed commit transaction from disable rollback"); | ||
| 803 | } | ||
| 804 | |||
| 822 | *pfRollback = TRUE; | 805 | *pfRollback = TRUE; |
| 823 | break; | 806 | break; |
| 824 | } | 807 | } |
| 825 | else // the action failed, roll back to previous rollback boundary. | 808 | |
| 809 | // If inside a MSI transaction, roll it back. | ||
| 810 | if (pCheckpoint && pCheckpoint->pActiveRollbackBoundary && pCheckpoint->pActiveRollbackBoundary->fActiveTransaction) | ||
| 826 | { | 811 | { |
| 827 | HRESULT hrRollback = DoRollbackActions(pEngineState, &context, dwCheckpoint, fInTransaction, pfKeepRegistration, pRestart); | 812 | hrRollback = ExecuteMsiRollbackTransaction(pEngineState, pCheckpoint->pActiveRollbackBoundary, &context); |
| 828 | UNREFERENCED_PARAMETER(hrRollback); | 813 | IgnoreRollbackError(hrRollback, "Failed rolling back transaction"); |
| 829 | fInTransaction = FALSE; | 814 | } |
| 830 | 815 | ||
| 831 | // If the rollback boundary is vital, end execution here. | 816 | // The action failed, roll back to previous rollback boundary. |
| 832 | if (pRollbackBoundary && pRollbackBoundary->fVital) | 817 | if (pCheckpoint) |
| 833 | { | 818 | { |
| 834 | *pfRollback = TRUE; | 819 | hrRollback = DoRollbackActions(pEngineState, &context, pCheckpoint->dwId, pfKeepRegistration, pRestart); |
| 835 | break; | 820 | IgnoreRollbackError(hrRollback, "Failed rollback actions"); |
| 836 | } | 821 | } |
| 837 | 822 | ||
| 838 | // Move forward to next rollback boundary. | 823 | // If the rollback boundary is vital, end execution here. |
| 839 | fSeekNextRollbackBoundary = TRUE; | 824 | if (pRollbackBoundary && pRollbackBoundary->fVital) |
| 825 | { | ||
| 826 | *pfRollback = TRUE; | ||
| 827 | break; | ||
| 840 | } | 828 | } |
| 841 | } | ||
| 842 | } | ||
| 843 | 829 | ||
| 844 | if (fInTransaction) | 830 | // Move forward to next rollback boundary. |
| 845 | { | 831 | fSeekNextRollbackBoundary = TRUE; |
| 846 | LogString(REPORT_STANDARD, "Committing an MSI transaction\n"); | 832 | } |
| 847 | hr = ExecuteMsiCommitTransaction(pEngineState, &context); | ||
| 848 | ExitOnFailure(hr, "Failed committing an MSI transaction"); | ||
| 849 | fInTransaction = FALSE; | ||
| 850 | } | 833 | } |
| 851 | 834 | ||
| 852 | LExit: | 835 | LExit: |
| @@ -1653,7 +1636,7 @@ static HRESULT DoExecuteAction( | |||
| 1653 | __in_opt HANDLE hCacheThread, | 1636 | __in_opt HANDLE hCacheThread, |
| 1654 | __in BURN_EXECUTE_CONTEXT* pContext, | 1637 | __in BURN_EXECUTE_CONTEXT* pContext, |
| 1655 | __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary, | 1638 | __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary, |
| 1656 | __out DWORD* pdwCheckpoint, | 1639 | __inout BURN_EXECUTE_ACTION_CHECKPOINT** ppCheckpoint, |
| 1657 | __out BOOL* pfKeepRegistration, | 1640 | __out BOOL* pfKeepRegistration, |
| 1658 | __out BOOL* pfSuspend, | 1641 | __out BOOL* pfSuspend, |
| 1659 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | 1642 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart |
| @@ -1674,7 +1657,7 @@ static HRESULT DoExecuteAction( | |||
| 1674 | switch (pExecuteAction->type) | 1657 | switch (pExecuteAction->type) |
| 1675 | { | 1658 | { |
| 1676 | case BURN_EXECUTE_ACTION_TYPE_CHECKPOINT: | 1659 | case BURN_EXECUTE_ACTION_TYPE_CHECKPOINT: |
| 1677 | *pdwCheckpoint = pExecuteAction->checkpoint.dwId; | 1660 | *ppCheckpoint = &pExecuteAction->checkpoint; |
| 1678 | break; | 1661 | break; |
| 1679 | 1662 | ||
| 1680 | case BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT: | 1663 | case BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT: |
| @@ -1748,6 +1731,18 @@ static HRESULT DoExecuteAction( | |||
| 1748 | *ppRollbackBoundary = pExecuteAction->rollbackBoundary.pRollbackBoundary; | 1731 | *ppRollbackBoundary = pExecuteAction->rollbackBoundary.pRollbackBoundary; |
| 1749 | break; | 1732 | break; |
| 1750 | 1733 | ||
| 1734 | case BURN_EXECUTE_ACTION_TYPE_BEGIN_MSI_TRANSACTION: | ||
| 1735 | LogString(REPORT_STANDARD, "Starting a new MSI transaction\n"); | ||
| 1736 | hr = ExecuteMsiBeginTransaction(pEngineState, pExecuteAction->msiTransaction.pRollbackBoundary, pContext); | ||
| 1737 | ExitOnFailure(hr, "Failed to execute begin MSI transaction action."); | ||
| 1738 | break; | ||
| 1739 | |||
| 1740 | case BURN_EXECUTE_ACTION_TYPE_COMMIT_MSI_TRANSACTION: | ||
| 1741 | LogString(REPORT_STANDARD, "Committing MSI transaction\n"); | ||
| 1742 | hr = ExecuteMsiCommitTransaction(pEngineState, pExecuteAction->msiTransaction.pRollbackBoundary, pContext); | ||
| 1743 | ExitOnFailure(hr, "Failed to execute commit MSI transaction action."); | ||
| 1744 | break; | ||
| 1745 | |||
| 1751 | case BURN_EXECUTE_ACTION_TYPE_SERVICE_STOP: __fallthrough; | 1746 | case BURN_EXECUTE_ACTION_TYPE_SERVICE_STOP: __fallthrough; |
| 1752 | case BURN_EXECUTE_ACTION_TYPE_SERVICE_START: __fallthrough; | 1747 | case BURN_EXECUTE_ACTION_TYPE_SERVICE_START: __fallthrough; |
| 1753 | default: | 1748 | default: |
| @@ -1769,7 +1764,6 @@ static HRESULT DoRollbackActions( | |||
| 1769 | __in BURN_ENGINE_STATE* pEngineState, | 1764 | __in BURN_ENGINE_STATE* pEngineState, |
| 1770 | __in BURN_EXECUTE_CONTEXT* pContext, | 1765 | __in BURN_EXECUTE_CONTEXT* pContext, |
| 1771 | __in DWORD dwCheckpoint, | 1766 | __in DWORD dwCheckpoint, |
| 1772 | __in BOOL fInTransaction, | ||
| 1773 | __out BOOL* pfKeepRegistration, | 1767 | __out BOOL* pfKeepRegistration, |
| 1774 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | 1768 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart |
| 1775 | ) | 1769 | ) |
| @@ -1781,13 +1775,6 @@ static HRESULT DoRollbackActions( | |||
| 1781 | 1775 | ||
| 1782 | pContext->fRollback = TRUE; | 1776 | pContext->fRollback = TRUE; |
| 1783 | 1777 | ||
| 1784 | // Rollback MSI transaction | ||
| 1785 | if (fInTransaction) | ||
| 1786 | { | ||
| 1787 | hr = ExecuteMsiRollbackTransaction(pEngineState, pContext); | ||
| 1788 | ExitOnFailure(hr, "Failed rolling back transaction"); | ||
| 1789 | } | ||
| 1790 | |||
| 1791 | // scan to last checkpoint | 1778 | // scan to last checkpoint |
| 1792 | for (DWORD i = 0; i < pEngineState->plan.cRollbackActions; ++i) | 1779 | for (DWORD i = 0; i < pEngineState->plan.cRollbackActions; ++i) |
| 1793 | { | 1780 | { |
| @@ -1827,53 +1814,32 @@ static HRESULT DoRollbackActions( | |||
| 1827 | 1814 | ||
| 1828 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: | 1815 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: |
| 1829 | hr = ExecuteExePackage(pEngineState, pRollbackAction, pContext, TRUE, &fRetryIgnored, &fSuspendIgnored, &restart); | 1816 | hr = ExecuteExePackage(pEngineState, pRollbackAction, pContext, TRUE, &fRetryIgnored, &fSuspendIgnored, &restart); |
| 1830 | TraceError(hr, "Failed to rollback EXE package."); | 1817 | IgnoreRollbackError(hr, "Failed to rollback EXE package."); |
| 1831 | hr = S_OK; | ||
| 1832 | break; | 1818 | break; |
| 1833 | 1819 | ||
| 1834 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: | 1820 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: |
| 1835 | if (fInTransaction) | ||
| 1836 | { | ||
| 1837 | LogString(REPORT_STANDARD, "Skipping rolling back an MSI package- already done in transaction rollback\n"); | ||
| 1838 | break; | ||
| 1839 | } | ||
| 1840 | hr = ExecuteMsiPackage(pEngineState, pRollbackAction, pContext, TRUE, &fRetryIgnored, &fSuspendIgnored, &restart); | 1821 | hr = ExecuteMsiPackage(pEngineState, pRollbackAction, pContext, TRUE, &fRetryIgnored, &fSuspendIgnored, &restart); |
| 1841 | TraceError(hr, "Failed to rollback MSI package."); | 1822 | IgnoreRollbackError(hr, "Failed to rollback MSI package."); |
| 1842 | hr = S_OK; | ||
| 1843 | break; | 1823 | break; |
| 1844 | 1824 | ||
| 1845 | case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: | 1825 | case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: |
| 1846 | if (fInTransaction) | ||
| 1847 | { | ||
| 1848 | LogString(REPORT_STANDARD, "Skipping rolling back an MSP package- already done in transaction rollback\n"); | ||
| 1849 | break; | ||
| 1850 | } | ||
| 1851 | hr = ExecuteMspPackage(pEngineState, pRollbackAction, pContext, TRUE, &fRetryIgnored, &fSuspendIgnored, &restart); | 1826 | hr = ExecuteMspPackage(pEngineState, pRollbackAction, pContext, TRUE, &fRetryIgnored, &fSuspendIgnored, &restart); |
| 1852 | TraceError(hr, "Failed to rollback MSP package."); | 1827 | IgnoreRollbackError(hr, "Failed to rollback MSP package."); |
| 1853 | hr = S_OK; | ||
| 1854 | break; | 1828 | break; |
| 1855 | 1829 | ||
| 1856 | case BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE: | 1830 | case BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE: |
| 1857 | if (fInTransaction) | ||
| 1858 | { | ||
| 1859 | LogString(REPORT_STANDARD, "Skipping rolling back an MSU package- already done in transaction rollback\n"); | ||
| 1860 | break; | ||
| 1861 | } | ||
| 1862 | hr = ExecuteMsuPackage(pEngineState, pRollbackAction, pContext, TRUE, FALSE, &fRetryIgnored, &fSuspendIgnored, &restart); | 1831 | hr = ExecuteMsuPackage(pEngineState, pRollbackAction, pContext, TRUE, FALSE, &fRetryIgnored, &fSuspendIgnored, &restart); |
| 1863 | TraceError(hr, "Failed to rollback MSU package."); | 1832 | IgnoreRollbackError(hr, "Failed to rollback MSU package."); |
| 1864 | hr = S_OK; | ||
| 1865 | break; | 1833 | break; |
| 1866 | 1834 | ||
| 1867 | case BURN_EXECUTE_ACTION_TYPE_PACKAGE_PROVIDER: | 1835 | case BURN_EXECUTE_ACTION_TYPE_PACKAGE_PROVIDER: |
| 1868 | hr = ExecutePackageProviderAction(pEngineState, pRollbackAction, pContext); | 1836 | hr = ExecutePackageProviderAction(pEngineState, pRollbackAction, pContext); |
| 1869 | TraceError(hr, "Failed to rollback package provider action."); | 1837 | IgnoreRollbackError(hr, "Failed to rollback package provider action."); |
| 1870 | hr = S_OK; | ||
| 1871 | break; | 1838 | break; |
| 1872 | 1839 | ||
| 1873 | case BURN_EXECUTE_ACTION_TYPE_PACKAGE_DEPENDENCY: | 1840 | case BURN_EXECUTE_ACTION_TYPE_PACKAGE_DEPENDENCY: |
| 1874 | hr = ExecuteDependencyAction(pEngineState, pRollbackAction, pContext); | 1841 | hr = ExecuteDependencyAction(pEngineState, pRollbackAction, pContext); |
| 1875 | TraceError(hr, "Failed to rollback dependency action."); | 1842 | IgnoreRollbackError(hr, "Failed to rollback dependency action."); |
| 1876 | hr = S_OK; | ||
| 1877 | break; | 1843 | break; |
| 1878 | 1844 | ||
| 1879 | case BURN_EXECUTE_ACTION_TYPE_REGISTRATION: | 1845 | case BURN_EXECUTE_ACTION_TYPE_REGISTRATION: |
| @@ -1885,6 +1851,7 @@ static HRESULT DoRollbackActions( | |||
| 1885 | 1851 | ||
| 1886 | case BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE: | 1852 | case BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE: |
| 1887 | hr = CleanPackage(pEngineState->companionConnection.hPipe, pRollbackAction->uncachePackage.pPackage); | 1853 | hr = CleanPackage(pEngineState->companionConnection.hPipe, pRollbackAction->uncachePackage.pPackage); |
| 1854 | IgnoreRollbackError(hr, "Failed to uncache package for rollback."); | ||
| 1888 | break; | 1855 | break; |
| 1889 | 1856 | ||
| 1890 | case BURN_EXECUTE_ACTION_TYPE_SERVICE_STOP: __fallthrough; | 1857 | case BURN_EXECUTE_ACTION_TYPE_SERVICE_STOP: __fallthrough; |
| @@ -2234,20 +2201,30 @@ LExit: | |||
| 2234 | 2201 | ||
| 2235 | static HRESULT ExecuteMsiBeginTransaction( | 2202 | static HRESULT ExecuteMsiBeginTransaction( |
| 2236 | __in BURN_ENGINE_STATE* pEngineState, | 2203 | __in BURN_ENGINE_STATE* pEngineState, |
| 2237 | __in LPCWSTR wzName, | 2204 | __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary, |
| 2238 | __in BURN_EXECUTE_CONTEXT* /*pContext*/ | 2205 | __in BURN_EXECUTE_CONTEXT* /*pContext*/ |
| 2239 | ) | 2206 | ) |
| 2240 | { | 2207 | { |
| 2241 | HRESULT hr = S_OK; | 2208 | HRESULT hr = S_OK; |
| 2242 | 2209 | ||
| 2210 | if (pRollbackBoundary->fActiveTransaction) | ||
| 2211 | { | ||
| 2212 | ExitFunction1(hr = E_INVALIDSTATE); | ||
| 2213 | } | ||
| 2214 | |||
| 2243 | if (pEngineState->plan.fPerMachine) | 2215 | if (pEngineState->plan.fPerMachine) |
| 2244 | { | 2216 | { |
| 2245 | hr = ElevationMsiBeginTransaction(pEngineState->companionConnection.hPipe, wzName); | 2217 | hr = ElevationMsiBeginTransaction(pEngineState->companionConnection.hPipe, pRollbackBoundary->sczId); |
| 2246 | ExitOnFailure(hr, "Failed to begin an elevated MSI transaction."); | 2218 | ExitOnFailure(hr, "Failed to begin an elevated MSI transaction."); |
| 2247 | } | 2219 | } |
| 2248 | else | 2220 | else |
| 2249 | { | 2221 | { |
| 2250 | hr = MsiEngineBeginTransaction(wzName); | 2222 | hr = MsiEngineBeginTransaction(pRollbackBoundary->sczId); |
| 2223 | } | ||
| 2224 | |||
| 2225 | if (SUCCEEDED(hr)) | ||
| 2226 | { | ||
| 2227 | pRollbackBoundary->fActiveTransaction = TRUE; | ||
| 2251 | } | 2228 | } |
| 2252 | 2229 | ||
| 2253 | LExit: | 2230 | LExit: |
| @@ -2256,11 +2233,17 @@ LExit: | |||
| 2256 | 2233 | ||
| 2257 | static HRESULT ExecuteMsiCommitTransaction( | 2234 | static HRESULT ExecuteMsiCommitTransaction( |
| 2258 | __in BURN_ENGINE_STATE* pEngineState, | 2235 | __in BURN_ENGINE_STATE* pEngineState, |
| 2236 | __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary, | ||
| 2259 | __in BURN_EXECUTE_CONTEXT* /*pContext*/ | 2237 | __in BURN_EXECUTE_CONTEXT* /*pContext*/ |
| 2260 | ) | 2238 | ) |
| 2261 | { | 2239 | { |
| 2262 | HRESULT hr = S_OK; | 2240 | HRESULT hr = S_OK; |
| 2263 | 2241 | ||
| 2242 | if (!pRollbackBoundary->fActiveTransaction) | ||
| 2243 | { | ||
| 2244 | ExitFunction1(hr = E_INVALIDSTATE); | ||
| 2245 | } | ||
| 2246 | |||
| 2264 | if (pEngineState->plan.fPerMachine) | 2247 | if (pEngineState->plan.fPerMachine) |
| 2265 | { | 2248 | { |
| 2266 | hr = ElevationMsiCommitTransaction(pEngineState->companionConnection.hPipe); | 2249 | hr = ElevationMsiCommitTransaction(pEngineState->companionConnection.hPipe); |
| @@ -2271,17 +2254,28 @@ static HRESULT ExecuteMsiCommitTransaction( | |||
| 2271 | hr = MsiEngineCommitTransaction(); | 2254 | hr = MsiEngineCommitTransaction(); |
| 2272 | } | 2255 | } |
| 2273 | 2256 | ||
| 2257 | if (SUCCEEDED(hr)) | ||
| 2258 | { | ||
| 2259 | pRollbackBoundary->fActiveTransaction = FALSE; | ||
| 2260 | } | ||
| 2261 | |||
| 2274 | LExit: | 2262 | LExit: |
| 2275 | return hr; | 2263 | return hr; |
| 2276 | } | 2264 | } |
| 2277 | 2265 | ||
| 2278 | static HRESULT ExecuteMsiRollbackTransaction( | 2266 | static HRESULT ExecuteMsiRollbackTransaction( |
| 2279 | __in BURN_ENGINE_STATE* pEngineState, | 2267 | __in BURN_ENGINE_STATE* pEngineState, |
| 2268 | __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary, | ||
| 2280 | __in BURN_EXECUTE_CONTEXT* /*pContext*/ | 2269 | __in BURN_EXECUTE_CONTEXT* /*pContext*/ |
| 2281 | ) | 2270 | ) |
| 2282 | { | 2271 | { |
| 2283 | HRESULT hr = S_OK; | 2272 | HRESULT hr = S_OK; |
| 2284 | 2273 | ||
| 2274 | if (!pRollbackBoundary->fActiveTransaction) | ||
| 2275 | { | ||
| 2276 | ExitFunction(); | ||
| 2277 | } | ||
| 2278 | |||
| 2285 | if (pEngineState->plan.fPerMachine) | 2279 | if (pEngineState->plan.fPerMachine) |
| 2286 | { | 2280 | { |
| 2287 | hr = ElevationMsiRollbackTransaction(pEngineState->companionConnection.hPipe); | 2281 | hr = ElevationMsiRollbackTransaction(pEngineState->companionConnection.hPipe); |
| @@ -2293,6 +2287,8 @@ static HRESULT ExecuteMsiRollbackTransaction( | |||
| 2293 | } | 2287 | } |
| 2294 | 2288 | ||
| 2295 | LExit: | 2289 | LExit: |
| 2290 | pRollbackBoundary->fActiveTransaction = FALSE; | ||
| 2291 | |||
| 2296 | return hr; | 2292 | return hr; |
| 2297 | } | 2293 | } |
| 2298 | 2294 | ||
diff --git a/src/engine/msiengine.cpp b/src/engine/msiengine.cpp index fcd8817d..b056cb7e 100644 --- a/src/engine/msiengine.cpp +++ b/src/engine/msiengine.cpp | |||
| @@ -717,7 +717,8 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage( | |||
| 717 | __in BURN_PACKAGE* pPackage, | 717 | __in BURN_PACKAGE* pPackage, |
| 718 | __in BURN_VARIABLES* pVariables, | 718 | __in BURN_VARIABLES* pVariables, |
| 719 | __in BURN_USER_EXPERIENCE* pUserExperience, | 719 | __in BURN_USER_EXPERIENCE* pUserExperience, |
| 720 | __out BOOL* pfBARequestedCache | 720 | __in BOOL fInsideMsiTransaction, |
| 721 | __out_opt BOOL* pfBARequestedCache | ||
| 721 | ) | 722 | ) |
| 722 | { | 723 | { |
| 723 | Trace(REPORT_STANDARD, "Planning MSI package 0x%p", pPackage); | 724 | Trace(REPORT_STANDARD, "Planning MSI package 0x%p", pPackage); |
| @@ -853,7 +854,7 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage( | |||
| 853 | } | 854 | } |
| 854 | 855 | ||
| 855 | // Calculate the rollback action if there is an execute action. | 856 | // Calculate the rollback action if there is an execute action. |
| 856 | if (BOOTSTRAPPER_ACTION_STATE_NONE != execute) | 857 | if (BOOTSTRAPPER_ACTION_STATE_NONE != execute && !fInsideMsiTransaction) |
| 857 | { | 858 | { |
| 858 | switch (BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN != pPackage->expected ? pPackage->expected : pPackage->currentState) | 859 | switch (BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN != pPackage->expected ? pPackage->expected : pPackage->currentState) |
| 859 | { | 860 | { |
diff --git a/src/engine/msiengine.h b/src/engine/msiengine.h index 63393006..76030528 100644 --- a/src/engine/msiengine.h +++ b/src/engine/msiengine.h | |||
| @@ -35,6 +35,7 @@ HRESULT MsiEnginePlanCalculatePackage( | |||
| 35 | __in BURN_PACKAGE* pPackage, | 35 | __in BURN_PACKAGE* pPackage, |
| 36 | __in BURN_VARIABLES* pVariables, | 36 | __in BURN_VARIABLES* pVariables, |
| 37 | __in BURN_USER_EXPERIENCE* pUserExperience, | 37 | __in BURN_USER_EXPERIENCE* pUserExperience, |
| 38 | __in BOOL fInsideMsiTransaction, | ||
| 38 | __out_opt BOOL* pfBARequestedCache | 39 | __out_opt BOOL* pfBARequestedCache |
| 39 | ); | 40 | ); |
| 40 | HRESULT MsiEnginePlanAddPackage( | 41 | HRESULT MsiEnginePlanAddPackage( |
diff --git a/src/engine/mspengine.cpp b/src/engine/mspengine.cpp index 0854862b..e14173d1 100644 --- a/src/engine/mspengine.cpp +++ b/src/engine/mspengine.cpp | |||
| @@ -266,6 +266,7 @@ LExit: | |||
| 266 | extern "C" HRESULT MspEnginePlanCalculatePackage( | 266 | extern "C" HRESULT MspEnginePlanCalculatePackage( |
| 267 | __in BURN_PACKAGE* pPackage, | 267 | __in BURN_PACKAGE* pPackage, |
| 268 | __in BURN_USER_EXPERIENCE* pUserExperience, | 268 | __in BURN_USER_EXPERIENCE* pUserExperience, |
| 269 | __in BOOL fInsideMsiTransaction, | ||
| 269 | __out BOOL* pfBARequestedCache | 270 | __out BOOL* pfBARequestedCache |
| 270 | ) | 271 | ) |
| 271 | { | 272 | { |
| @@ -329,7 +330,7 @@ extern "C" HRESULT MspEnginePlanCalculatePackage( | |||
| 329 | } | 330 | } |
| 330 | 331 | ||
| 331 | // Calculate the rollback action if there is an execute action. | 332 | // Calculate the rollback action if there is an execute action. |
| 332 | if (BOOTSTRAPPER_ACTION_STATE_NONE != execute) | 333 | if (BOOTSTRAPPER_ACTION_STATE_NONE != execute && !fInsideMsiTransaction) |
| 333 | { | 334 | { |
| 334 | switch (BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN != pPackage->expected ? pPackage->expected : pPackage->currentState) | 335 | switch (BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN != pPackage->expected ? pPackage->expected : pPackage->currentState) |
| 335 | { | 336 | { |
| @@ -442,7 +443,7 @@ extern "C" HRESULT MspEnginePlanAddPackage( | |||
| 442 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pTargetProduct->rollback) | 443 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pTargetProduct->rollback) |
| 443 | { | 444 | { |
| 444 | hr = PlanTargetProduct(display, pUserExperience, TRUE, pPlan, pLog, pVariables, pTargetProduct->rollback, pPackage, pTargetProduct, hCacheEvent); | 445 | hr = PlanTargetProduct(display, pUserExperience, TRUE, pPlan, pLog, pVariables, pTargetProduct->rollback, pPackage, pTargetProduct, hCacheEvent); |
| 445 | ExitOnFailure(hr, "Failed to plan rollack target product."); | 446 | ExitOnFailure(hr, "Failed to plan rollback target product."); |
| 446 | } | 447 | } |
| 447 | } | 448 | } |
| 448 | 449 | ||
diff --git a/src/engine/mspengine.h b/src/engine/mspengine.h index 1f0c31df..e08fe992 100644 --- a/src/engine/mspengine.h +++ b/src/engine/mspengine.h | |||
| @@ -35,6 +35,7 @@ HRESULT MspEngineDetectPackage( | |||
| 35 | HRESULT MspEnginePlanCalculatePackage( | 35 | HRESULT MspEnginePlanCalculatePackage( |
| 36 | __in BURN_PACKAGE* pPackage, | 36 | __in BURN_PACKAGE* pPackage, |
| 37 | __in BURN_USER_EXPERIENCE* pUserExperience, | 37 | __in BURN_USER_EXPERIENCE* pUserExperience, |
| 38 | __in BOOL fInsideMsiTransaction, | ||
| 38 | __out_opt BOOL* pfBARequestedCache | 39 | __out_opt BOOL* pfBARequestedCache |
| 39 | ); | 40 | ); |
| 40 | HRESULT MspEnginePlanAddPackage( | 41 | HRESULT MspEnginePlanAddPackage( |
diff --git a/src/engine/package.h b/src/engine/package.h index c5873765..f3e817eb 100644 --- a/src/engine/package.h +++ b/src/engine/package.h | |||
| @@ -155,6 +155,7 @@ typedef struct _BURN_ROLLBACK_BOUNDARY | |||
| 155 | LPWSTR sczId; | 155 | LPWSTR sczId; |
| 156 | BOOL fVital; | 156 | BOOL fVital; |
| 157 | BOOL fTransaction; | 157 | BOOL fTransaction; |
| 158 | BOOL fActiveTransaction; // only valid during Apply. | ||
| 158 | } BURN_ROLLBACK_BOUNDARY; | 159 | } BURN_ROLLBACK_BOUNDARY; |
| 159 | 160 | ||
| 160 | typedef struct _BURN_PATCH_TARGETCODE | 161 | typedef struct _BURN_PATCH_TARGETCODE |
diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp index e2a3437d..22b7033e 100644 --- a/src/engine/plan.cpp +++ b/src/engine/plan.cpp | |||
| @@ -23,9 +23,12 @@ static void UninitializeCacheAction( | |||
| 23 | static void ResetPlannedPackageState( | 23 | static void ResetPlannedPackageState( |
| 24 | __in BURN_PACKAGE* pPackage | 24 | __in BURN_PACKAGE* pPackage |
| 25 | ); | 25 | ); |
| 26 | static void ResetPlannedRollbackBoundaryState( | ||
| 27 | __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary | ||
| 28 | ); | ||
| 26 | static HRESULT ProcessPackage( | 29 | static HRESULT ProcessPackage( |
| 27 | __in BOOL fBundlePerMachine, | 30 | __in BOOL fBundlePerMachine, |
| 28 | __in BURN_PACKAGE* pCompatiblePackageParent, | 31 | __in_opt BURN_PACKAGE* pCompatiblePackageParent, |
| 29 | __in BURN_USER_EXPERIENCE* pUX, | 32 | __in BURN_USER_EXPERIENCE* pUX, |
| 30 | __in BURN_PLAN* pPlan, | 33 | __in BURN_PLAN* pPlan, |
| 31 | __in BURN_PACKAGE* pPackage, | 34 | __in BURN_PACKAGE* pPackage, |
| @@ -153,6 +156,7 @@ static HRESULT CalculateExecuteActions( | |||
| 153 | __in BURN_USER_EXPERIENCE* pUserExperience, | 156 | __in BURN_USER_EXPERIENCE* pUserExperience, |
| 154 | __in BURN_PACKAGE* pPackage, | 157 | __in BURN_PACKAGE* pPackage, |
| 155 | __in BURN_VARIABLES* pVariables, | 158 | __in BURN_VARIABLES* pVariables, |
| 159 | __in_opt BURN_ROLLBACK_BOUNDARY* pActiveRollbackBoundary, | ||
| 156 | __out_opt BOOL* pfBARequestedCache | 160 | __out_opt BOOL* pfBARequestedCache |
| 157 | ); | 161 | ); |
| 158 | static BOOL NeedsCache( | 162 | static BOOL NeedsCache( |
| @@ -263,6 +267,15 @@ extern "C" void PlanReset( | |||
| 263 | ResetPlannedPackageState(&pPackages->rgPackages[i]); | 267 | ResetPlannedPackageState(&pPackages->rgPackages[i]); |
| 264 | } | 268 | } |
| 265 | } | 269 | } |
| 270 | |||
| 271 | // Reset the planned state for each rollback boundary. | ||
| 272 | if (pPackages->rgRollbackBoundaries) | ||
| 273 | { | ||
| 274 | for (DWORD i = 0; i < pPackages->cRollbackBoundaries; ++i) | ||
| 275 | { | ||
| 276 | ResetPlannedRollbackBoundaryState(&pPackages->rgRollbackBoundaries[i]); | ||
| 277 | } | ||
| 278 | } | ||
| 266 | } | 279 | } |
| 267 | 280 | ||
| 268 | extern "C" void PlanUninitializeExecuteAction( | 281 | extern "C" void PlanUninitializeExecuteAction( |
| @@ -853,7 +866,7 @@ LExit: | |||
| 853 | 866 | ||
| 854 | static HRESULT ProcessPackage( | 867 | static HRESULT ProcessPackage( |
| 855 | __in BOOL fBundlePerMachine, | 868 | __in BOOL fBundlePerMachine, |
| 856 | __in BURN_PACKAGE* pCompatiblePackageParent, | 869 | __in_opt BURN_PACKAGE* pCompatiblePackageParent, |
| 857 | __in BURN_USER_EXPERIENCE* pUX, | 870 | __in BURN_USER_EXPERIENCE* pUX, |
| 858 | __in BURN_PLAN* pPlan, | 871 | __in BURN_PLAN* pPlan, |
| 859 | __in BURN_PACKAGE* pPackage, | 872 | __in BURN_PACKAGE* pPackage, |
| @@ -1069,7 +1082,7 @@ extern "C" HRESULT PlanCachePackage( | |||
| 1069 | BOOL fBARequestedCache = FALSE; | 1082 | BOOL fBARequestedCache = FALSE; |
| 1070 | 1083 | ||
| 1071 | // Calculate the execute actions because we need them to decide whether the package should be cached. | 1084 | // Calculate the execute actions because we need them to decide whether the package should be cached. |
| 1072 | hr = CalculateExecuteActions(pUserExperience, pPackage, pVariables, &fBARequestedCache); | 1085 | hr = CalculateExecuteActions(pUserExperience, pPackage, pVariables, pPlan->pActiveRollbackBoundary, &fBARequestedCache); |
| 1073 | ExitOnFailure(hr, "Failed to calculate execute actions for package: %ls", pPackage->sczId); | 1086 | ExitOnFailure(hr, "Failed to calculate execute actions for package: %ls", pPackage->sczId); |
| 1074 | 1087 | ||
| 1075 | if (fBARequestedCache || NeedsCache(pPlan, pPackage)) | 1088 | if (fBARequestedCache || NeedsCache(pPlan, pPackage)) |
| @@ -1105,7 +1118,7 @@ extern "C" HRESULT PlanExecutePackage( | |||
| 1105 | HRESULT hr = S_OK; | 1118 | HRESULT hr = S_OK; |
| 1106 | BOOL fBARequestedCache = FALSE; | 1119 | BOOL fBARequestedCache = FALSE; |
| 1107 | 1120 | ||
| 1108 | hr = CalculateExecuteActions(pUserExperience, pPackage, pVariables, &fBARequestedCache); | 1121 | hr = CalculateExecuteActions(pUserExperience, pPackage, pVariables, pPlan->pActiveRollbackBoundary, &fBARequestedCache); |
| 1109 | ExitOnFailure(hr, "Failed to calculate plan actions for package: %ls", pPackage->sczId); | 1122 | ExitOnFailure(hr, "Failed to calculate plan actions for package: %ls", pPackage->sczId); |
| 1110 | 1123 | ||
| 1111 | // Calculate package states based on reference count and plan certain dependency actions prior to planning the package execute action. | 1124 | // Calculate package states based on reference count and plan certain dependency actions prior to planning the package execute action. |
| @@ -1631,6 +1644,7 @@ extern "C" HRESULT PlanExecuteCheckpoint( | |||
| 1631 | 1644 | ||
| 1632 | pAction->type = BURN_EXECUTE_ACTION_TYPE_CHECKPOINT; | 1645 | pAction->type = BURN_EXECUTE_ACTION_TYPE_CHECKPOINT; |
| 1633 | pAction->checkpoint.dwId = dwCheckpointId; | 1646 | pAction->checkpoint.dwId = dwCheckpointId; |
| 1647 | pAction->checkpoint.pActiveRollbackBoundary = pPlan->pActiveRollbackBoundary; | ||
| 1634 | 1648 | ||
| 1635 | // rollback checkpoint | 1649 | // rollback checkpoint |
| 1636 | hr = PlanAppendRollbackAction(pPlan, &pAction); | 1650 | hr = PlanAppendRollbackAction(pPlan, &pAction); |
| @@ -1638,6 +1652,7 @@ extern "C" HRESULT PlanExecuteCheckpoint( | |||
| 1638 | 1652 | ||
| 1639 | pAction->type = BURN_EXECUTE_ACTION_TYPE_CHECKPOINT; | 1653 | pAction->type = BURN_EXECUTE_ACTION_TYPE_CHECKPOINT; |
| 1640 | pAction->checkpoint.dwId = dwCheckpointId; | 1654 | pAction->checkpoint.dwId = dwCheckpointId; |
| 1655 | pAction->checkpoint.pActiveRollbackBoundary = pPlan->pActiveRollbackBoundary; | ||
| 1641 | 1656 | ||
| 1642 | LExit: | 1657 | LExit: |
| 1643 | return hr; | 1658 | return hr; |
| @@ -1783,6 +1798,9 @@ extern "C" HRESULT PlanRollbackBoundaryBegin( | |||
| 1783 | HRESULT hr = S_OK; | 1798 | HRESULT hr = S_OK; |
| 1784 | BURN_EXECUTE_ACTION* pExecuteAction = NULL; | 1799 | BURN_EXECUTE_ACTION* pExecuteAction = NULL; |
| 1785 | 1800 | ||
| 1801 | AssertSz(!pPlan->pActiveRollbackBoundary, "PlanRollbackBoundaryBegin called without completing previous RollbackBoundary"); | ||
| 1802 | pPlan->pActiveRollbackBoundary = pRollbackBoundary; | ||
| 1803 | |||
| 1786 | // Add begin rollback boundary to execute plan. | 1804 | // Add begin rollback boundary to execute plan. |
| 1787 | hr = PlanAppendExecuteAction(pPlan, &pExecuteAction); | 1805 | hr = PlanAppendExecuteAction(pPlan, &pExecuteAction); |
| 1788 | ExitOnFailure(hr, "Failed to append rollback boundary begin action."); | 1806 | ExitOnFailure(hr, "Failed to append rollback boundary begin action."); |
| @@ -1797,6 +1815,19 @@ extern "C" HRESULT PlanRollbackBoundaryBegin( | |||
| 1797 | pExecuteAction->type = BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY; | 1815 | pExecuteAction->type = BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY; |
| 1798 | pExecuteAction->rollbackBoundary.pRollbackBoundary = pRollbackBoundary; | 1816 | pExecuteAction->rollbackBoundary.pRollbackBoundary = pRollbackBoundary; |
| 1799 | 1817 | ||
| 1818 | // Add begin MSI transaction to execute plan. | ||
| 1819 | if (pRollbackBoundary->fTransaction) | ||
| 1820 | { | ||
| 1821 | hr = PlanExecuteCheckpoint(pPlan); | ||
| 1822 | ExitOnFailure(hr, "Failed to append checkpoint before MSI transaction begin action."); | ||
| 1823 | |||
| 1824 | hr = PlanAppendExecuteAction(pPlan, &pExecuteAction); | ||
| 1825 | ExitOnFailure(hr, "Failed to append MSI transaction begin action."); | ||
| 1826 | |||
| 1827 | pExecuteAction->type = BURN_EXECUTE_ACTION_TYPE_BEGIN_MSI_TRANSACTION; | ||
| 1828 | pExecuteAction->msiTransaction.pRollbackBoundary = pRollbackBoundary; | ||
| 1829 | } | ||
| 1830 | |||
| 1800 | LExit: | 1831 | LExit: |
| 1801 | return hr; | 1832 | return hr; |
| 1802 | } | 1833 | } |
| @@ -1807,22 +1838,24 @@ extern "C" HRESULT PlanRollbackBoundaryComplete( | |||
| 1807 | { | 1838 | { |
| 1808 | HRESULT hr = S_OK; | 1839 | HRESULT hr = S_OK; |
| 1809 | BURN_EXECUTE_ACTION* pExecuteAction = NULL; | 1840 | BURN_EXECUTE_ACTION* pExecuteAction = NULL; |
| 1810 | DWORD dwCheckpointId = 0; | 1841 | BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = pPlan->pActiveRollbackBoundary; |
| 1811 | 1842 | ||
| 1812 | // Add checkpoints. | 1843 | AssertSz(pRollbackBoundary, "PlanRollbackBoundaryComplete called without an active RollbackBoundary"); |
| 1813 | dwCheckpointId = GetNextCheckpointId(pPlan); | ||
| 1814 | 1844 | ||
| 1815 | hr = PlanAppendExecuteAction(pPlan, &pExecuteAction); | 1845 | if (pRollbackBoundary && pRollbackBoundary->fTransaction) |
| 1816 | ExitOnFailure(hr, "Failed to append execute action."); | 1846 | { |
| 1847 | // Add commit MSI transaction to execute plan. | ||
| 1848 | hr = PlanAppendExecuteAction(pPlan, &pExecuteAction); | ||
| 1849 | ExitOnFailure(hr, "Failed to append MSI transaction commit action."); | ||
| 1817 | 1850 | ||
| 1818 | pExecuteAction->type = BURN_EXECUTE_ACTION_TYPE_CHECKPOINT; | 1851 | pExecuteAction->type = BURN_EXECUTE_ACTION_TYPE_COMMIT_MSI_TRANSACTION; |
| 1819 | pExecuteAction->checkpoint.dwId = dwCheckpointId; | 1852 | pExecuteAction->msiTransaction.pRollbackBoundary = pRollbackBoundary; |
| 1853 | } | ||
| 1820 | 1854 | ||
| 1821 | hr = PlanAppendRollbackAction(pPlan, &pExecuteAction); | 1855 | pPlan->pActiveRollbackBoundary = NULL; |
| 1822 | ExitOnFailure(hr, "Failed to append rollback action."); | ||
| 1823 | 1856 | ||
| 1824 | pExecuteAction->type = BURN_EXECUTE_ACTION_TYPE_CHECKPOINT; | 1857 | // Add checkpoints. |
| 1825 | pExecuteAction->checkpoint.dwId = dwCheckpointId; | 1858 | hr = PlanExecuteCheckpoint(pPlan); |
| 1826 | 1859 | ||
| 1827 | LExit: | 1860 | LExit: |
| 1828 | return hr; | 1861 | return hr; |
| @@ -1936,6 +1969,13 @@ static void ResetPlannedPackageState( | |||
| 1936 | } | 1969 | } |
| 1937 | } | 1970 | } |
| 1938 | 1971 | ||
| 1972 | static void ResetPlannedRollbackBoundaryState( | ||
| 1973 | __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary | ||
| 1974 | ) | ||
| 1975 | { | ||
| 1976 | pRollbackBoundary->fActiveTransaction = FALSE; | ||
| 1977 | } | ||
| 1978 | |||
| 1939 | static HRESULT GetActionDefaultRequestState( | 1979 | static HRESULT GetActionDefaultRequestState( |
| 1940 | __in BOOTSTRAPPER_ACTION action, | 1980 | __in BOOTSTRAPPER_ACTION action, |
| 1941 | __in BOOL fPermanent, | 1981 | __in BOOL fPermanent, |
| @@ -2848,10 +2888,12 @@ static HRESULT CalculateExecuteActions( | |||
| 2848 | __in BURN_USER_EXPERIENCE* pUserExperience, | 2888 | __in BURN_USER_EXPERIENCE* pUserExperience, |
| 2849 | __in BURN_PACKAGE* pPackage, | 2889 | __in BURN_PACKAGE* pPackage, |
| 2850 | __in BURN_VARIABLES* pVariables, | 2890 | __in BURN_VARIABLES* pVariables, |
| 2891 | __in_opt BURN_ROLLBACK_BOUNDARY* pActiveRollbackBoundary, | ||
| 2851 | __out_opt BOOL* pfBARequestedCache | 2892 | __out_opt BOOL* pfBARequestedCache |
| 2852 | ) | 2893 | ) |
| 2853 | { | 2894 | { |
| 2854 | HRESULT hr = S_OK; | 2895 | HRESULT hr = S_OK; |
| 2896 | BOOL fInsideMsiTransaction = pActiveRollbackBoundary && pActiveRollbackBoundary->fTransaction; | ||
| 2855 | 2897 | ||
| 2856 | // Calculate execute actions. | 2898 | // Calculate execute actions. |
| 2857 | switch (pPackage->type) | 2899 | switch (pPackage->type) |
| @@ -2861,11 +2903,11 @@ static HRESULT CalculateExecuteActions( | |||
| 2861 | break; | 2903 | break; |
| 2862 | 2904 | ||
| 2863 | case BURN_PACKAGE_TYPE_MSI: | 2905 | case BURN_PACKAGE_TYPE_MSI: |
| 2864 | hr = MsiEnginePlanCalculatePackage(pPackage, pVariables, pUserExperience, pfBARequestedCache); | 2906 | hr = MsiEnginePlanCalculatePackage(pPackage, pVariables, pUserExperience, fInsideMsiTransaction, pfBARequestedCache); |
| 2865 | break; | 2907 | break; |
| 2866 | 2908 | ||
| 2867 | case BURN_PACKAGE_TYPE_MSP: | 2909 | case BURN_PACKAGE_TYPE_MSP: |
| 2868 | hr = MspEnginePlanCalculatePackage(pPackage, pUserExperience, pfBARequestedCache); | 2910 | hr = MspEnginePlanCalculatePackage(pPackage, pUserExperience, fInsideMsiTransaction, pfBARequestedCache); |
| 2869 | break; | 2911 | break; |
| 2870 | 2912 | ||
| 2871 | case BURN_PACKAGE_TYPE_MSU: | 2913 | case BURN_PACKAGE_TYPE_MSU: |
| @@ -3065,7 +3107,7 @@ static void ExecuteActionLog( | |||
| 3065 | switch (pAction->type) | 3107 | switch (pAction->type) |
| 3066 | { | 3108 | { |
| 3067 | case BURN_EXECUTE_ACTION_TYPE_CHECKPOINT: | 3109 | case BURN_EXECUTE_ACTION_TYPE_CHECKPOINT: |
| 3068 | LogStringLine(REPORT_STANDARD, "%ls action[%u]: CHECKPOINT id: %u", wzBase, iAction, pAction->checkpoint.dwId); | 3110 | LogStringLine(REPORT_STANDARD, "%ls action[%u]: CHECKPOINT id: %u, msi transaction id: %ls", wzBase, iAction, pAction->checkpoint.dwId, pAction->checkpoint.pActiveRollbackBoundary && pAction->checkpoint.pActiveRollbackBoundary->fTransaction ? pAction->checkpoint.pActiveRollbackBoundary->sczId : L"(none)"); |
| 3069 | break; | 3111 | break; |
| 3070 | 3112 | ||
| 3071 | case BURN_EXECUTE_ACTION_TYPE_PACKAGE_PROVIDER: | 3113 | case BURN_EXECUTE_ACTION_TYPE_PACKAGE_PROVIDER: |
| @@ -3120,6 +3162,14 @@ static void ExecuteActionLog( | |||
| 3120 | LogStringLine(REPORT_STANDARD, "%ls action[%u]: COMPATIBLE_PACKAGE reference id: %ls, installed ProductCode: %ls", wzBase, iAction, pAction->compatiblePackage.pReferencePackage->sczId, pAction->compatiblePackage.sczInstalledProductCode); | 3162 | LogStringLine(REPORT_STANDARD, "%ls action[%u]: COMPATIBLE_PACKAGE reference id: %ls, installed ProductCode: %ls", wzBase, iAction, pAction->compatiblePackage.pReferencePackage->sczId, pAction->compatiblePackage.sczInstalledProductCode); |
| 3121 | break; | 3163 | break; |
| 3122 | 3164 | ||
| 3165 | case BURN_EXECUTE_ACTION_TYPE_BEGIN_MSI_TRANSACTION: | ||
| 3166 | LogStringLine(REPORT_STANDARD, "%ls action[%u]: BEGIN_MSI_TRANSACTION id: %ls", wzBase, iAction, pAction->msiTransaction.pRollbackBoundary->sczId); | ||
| 3167 | break; | ||
| 3168 | |||
| 3169 | case BURN_EXECUTE_ACTION_TYPE_COMMIT_MSI_TRANSACTION: | ||
| 3170 | LogStringLine(REPORT_STANDARD, "%ls action[%u]: COMMIT_MSI_TRANSACTION id: %ls", wzBase, iAction, pAction->msiTransaction.pRollbackBoundary->sczId); | ||
| 3171 | break; | ||
| 3172 | |||
| 3123 | default: | 3173 | default: |
| 3124 | AssertSz(FALSE, "Unknown execute action type."); | 3174 | AssertSz(FALSE, "Unknown execute action type."); |
| 3125 | break; | 3175 | break; |
diff --git a/src/engine/plan.h b/src/engine/plan.h index 5fddd72f..407c1d48 100644 --- a/src/engine/plan.h +++ b/src/engine/plan.h | |||
| @@ -68,6 +68,8 @@ enum BURN_EXECUTE_ACTION_TYPE | |||
| 68 | BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY, | 68 | BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY, |
| 69 | BURN_EXECUTE_ACTION_TYPE_REGISTRATION, | 69 | BURN_EXECUTE_ACTION_TYPE_REGISTRATION, |
| 70 | BURN_EXECUTE_ACTION_TYPE_COMPATIBLE_PACKAGE, | 70 | BURN_EXECUTE_ACTION_TYPE_COMPATIBLE_PACKAGE, |
| 71 | BURN_EXECUTE_ACTION_TYPE_BEGIN_MSI_TRANSACTION, | ||
| 72 | BURN_EXECUTE_ACTION_TYPE_COMMIT_MSI_TRANSACTION, | ||
| 71 | }; | 73 | }; |
| 72 | 74 | ||
| 73 | enum BURN_CLEAN_ACTION_TYPE | 75 | enum BURN_CLEAN_ACTION_TYPE |
| @@ -214,16 +216,19 @@ typedef struct _BURN_ORDERED_PATCHES | |||
| 214 | BURN_PACKAGE* pPackage; | 216 | BURN_PACKAGE* pPackage; |
| 215 | } BURN_ORDERED_PATCHES; | 217 | } BURN_ORDERED_PATCHES; |
| 216 | 218 | ||
| 219 | typedef struct _BURN_EXECUTE_ACTION_CHECKPOINT | ||
| 220 | { | ||
| 221 | DWORD dwId; | ||
| 222 | BURN_ROLLBACK_BOUNDARY* pActiveRollbackBoundary; | ||
| 223 | } BURN_EXECUTE_ACTION_CHECKPOINT; | ||
| 224 | |||
| 217 | typedef struct _BURN_EXECUTE_ACTION | 225 | typedef struct _BURN_EXECUTE_ACTION |
| 218 | { | 226 | { |
| 219 | BURN_EXECUTE_ACTION_TYPE type; | 227 | BURN_EXECUTE_ACTION_TYPE type; |
| 220 | BOOL fDeleted; // used to skip an action after it was planned since deleting actions out of the plan is too hard. | 228 | BOOL fDeleted; // used to skip an action after it was planned since deleting actions out of the plan is too hard. |
| 221 | union | 229 | union |
| 222 | { | 230 | { |
| 223 | struct | 231 | BURN_EXECUTE_ACTION_CHECKPOINT checkpoint; |
| 224 | { | ||
| 225 | DWORD dwId; | ||
| 226 | } checkpoint; | ||
| 227 | struct | 232 | struct |
| 228 | { | 233 | { |
| 229 | HANDLE hEvent; | 234 | HANDLE hEvent; |
| @@ -307,6 +312,10 @@ typedef struct _BURN_EXECUTE_ACTION | |||
| 307 | LPWSTR sczInstalledProductCode; | 312 | LPWSTR sczInstalledProductCode; |
| 308 | VERUTIL_VERSION* pInstalledVersion; | 313 | VERUTIL_VERSION* pInstalledVersion; |
| 309 | } compatiblePackage; | 314 | } compatiblePackage; |
| 315 | struct | ||
| 316 | { | ||
| 317 | BURN_ROLLBACK_BOUNDARY* pRollbackBoundary; | ||
| 318 | } msiTransaction; | ||
| 310 | }; | 319 | }; |
| 311 | } BURN_EXECUTE_ACTION; | 320 | } BURN_EXECUTE_ACTION; |
| 312 | 321 | ||
| @@ -368,7 +377,8 @@ typedef struct _BURN_PLAN | |||
| 368 | DWORD cPayloadProgress; | 377 | DWORD cPayloadProgress; |
| 369 | STRINGDICT_HANDLE shPayloadProgress; | 378 | STRINGDICT_HANDLE shPayloadProgress; |
| 370 | 379 | ||
| 371 | DWORD dwNextCheckpointId; | 380 | DWORD dwNextCheckpointId; // for plan internal use |
| 381 | BURN_ROLLBACK_BOUNDARY* pActiveRollbackBoundary; // for plan internal use | ||
| 372 | } BURN_PLAN; | 382 | } BURN_PLAN; |
| 373 | 383 | ||
| 374 | 384 | ||
diff --git a/src/test/BurnUnitTest/PlanTest.cpp b/src/test/BurnUnitTest/PlanTest.cpp index 86bc646b..d3b10678 100644 --- a/src/test/BurnUnitTest/PlanTest.cpp +++ b/src/test/BurnUnitTest/PlanTest.cpp | |||
| @@ -173,7 +173,7 @@ namespace Bootstrapper | |||
| 173 | ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab1QmlL013Hqv_44W64R0cvnHn_2c", TRUE, FALSE, dwPackageStart); | 173 | ValidateCacheCachePayload(pPlan, fRollback, dwIndex++, L"PackageA", L"cab1QmlL013Hqv_44W64R0cvnHn_2c", TRUE, FALSE, dwPackageStart); |
| 174 | ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE); | 174 | ValidateCachePackageStop(pPlan, fRollback, dwIndex++, L"PackageA", FALSE); |
| 175 | ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE); | 175 | ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, FALSE); |
| 176 | ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 8); | 176 | ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 9); |
| 177 | dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageB", 14, 2, 33753, FALSE); | 177 | dwPackageStart = ValidateCachePackageStart(pPlan, fRollback, dwIndex++, L"PackageB", 14, 2, 33753, FALSE); |
| 178 | ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", TRUE); | 178 | ValidateCacheAcquireContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", TRUE); |
| 179 | ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 2); | 179 | ValidateCacheExtractContainer(pPlan, fRollback, dwIndex++, L"WixAttachedContainer", FALSE, dwPackageStart, 2); |
| @@ -195,10 +195,6 @@ namespace Bootstrapper | |||
| 195 | dwIndex = 0; | 195 | dwIndex = 0; |
| 196 | ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); | 196 | ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); |
| 197 | ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE); | 197 | ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE); |
| 198 | ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 8); | ||
| 199 | ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageB", FALSE); | ||
| 200 | ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 14); | ||
| 201 | ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageC", FALSE); | ||
| 202 | Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); | 198 | Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); |
| 203 | 199 | ||
| 204 | Assert::Equal(106166ull, pPlan->qwEstimatedSize); | 200 | Assert::Equal(106166ull, pPlan->qwEstimatedSize); |
| @@ -220,30 +216,31 @@ namespace Bootstrapper | |||
| 220 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 216 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 221 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 217 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 222 | ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE); | 218 | ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE); |
| 219 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
| 220 | ValidateExecuteBeginMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ"); | ||
| 223 | ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[15].syncpoint.hEvent); | 221 | ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[15].syncpoint.hEvent); |
| 224 | dwExecuteCheckpointId = 9; | 222 | dwExecuteCheckpointId += 1; // cache checkpoints |
| 225 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 223 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 226 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 224 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 227 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_REGISTER); | 225 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_REGISTER); |
| 228 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
| 229 | ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0); | 226 | ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0); |
| 230 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 227 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 231 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_REGISTER); | 228 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_REGISTER); |
| 232 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 229 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 233 | ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[23].syncpoint.hEvent); | 230 | ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[23].syncpoint.hEvent); |
| 234 | dwExecuteCheckpointId = 15; | 231 | dwExecuteCheckpointId += 1; // cache checkpoints |
| 235 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 232 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 236 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 233 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 237 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_REGISTER); | 234 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_REGISTER); |
| 238 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
| 239 | ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0); | 235 | ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0); |
| 240 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 236 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 241 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_REGISTER); | 237 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_REGISTER); |
| 242 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 238 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 239 | ValidateExecuteCommitMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ"); | ||
| 243 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 240 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 244 | ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[23].syncpoint.hEvent); | 241 | ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[23].syncpoint.hEvent); |
| 245 | ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, NULL); | 242 | ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, NULL); |
| 246 | Assert::Equal(34ul, pPlan->cExecuteActions); | 243 | Assert::Equal(dwIndex, pPlan->cExecuteActions); |
| 247 | 244 | ||
| 248 | fRollback = TRUE; | 245 | fRollback = TRUE; |
| 249 | dwIndex = 0; | 246 | dwIndex = 0; |
| @@ -261,29 +258,26 @@ namespace Bootstrapper | |||
| 261 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 258 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 262 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 259 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 263 | ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE); | 260 | ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE); |
| 261 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
| 264 | ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageB"); | 262 | ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageB"); |
| 265 | dwExecuteCheckpointId = 9; | 263 | dwExecuteCheckpointId += 1; // cache checkpoints |
| 266 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 264 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 267 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_UNREGISTER); | 265 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_UNREGISTER); |
| 268 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 266 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 269 | ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0); | ||
| 270 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
| 271 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_UNREGISTER); | 267 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_UNREGISTER); |
| 272 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 268 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 273 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 269 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 274 | ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageC"); | 270 | ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageC"); |
| 275 | dwExecuteCheckpointId = 15; | 271 | dwExecuteCheckpointId += 1; // cache checkpoints |
| 276 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 272 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 277 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_UNREGISTER); | 273 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_UNREGISTER); |
| 278 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 274 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 279 | ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0); | ||
| 280 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
| 281 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_UNREGISTER); | 275 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_UNREGISTER); |
| 282 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 276 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 283 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 277 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 284 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 278 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 285 | ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL); | 279 | ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL); |
| 286 | Assert::Equal(33ul, pPlan->cRollbackActions); | 280 | Assert::Equal(dwIndex, pPlan->cRollbackActions); |
| 287 | 281 | ||
| 288 | Assert::Equal(4ul, pPlan->cExecutePackagesTotal); | 282 | Assert::Equal(4ul, pPlan->cExecutePackagesTotal); |
| 289 | Assert::Equal(7ul, pPlan->cOverallProgressTicksTotal); | 283 | Assert::Equal(7ul, pPlan->cOverallProgressTicksTotal); |
| @@ -331,19 +325,20 @@ namespace Bootstrapper | |||
| 331 | DWORD dwExecuteCheckpointId = 1; | 325 | DWORD dwExecuteCheckpointId = 1; |
| 332 | ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE); | 326 | ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE); |
| 333 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 327 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 328 | ValidateExecuteBeginMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ"); | ||
| 329 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
| 334 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_UNREGISTER); | 330 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_UNREGISTER); |
| 335 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 331 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 336 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_UNREGISTER); | 332 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_UNREGISTER); |
| 337 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
| 338 | ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0); | 333 | ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0); |
| 339 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 334 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 340 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 335 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 341 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_UNREGISTER); | 336 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_UNREGISTER); |
| 342 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 337 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 343 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_UNREGISTER); | 338 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_UNREGISTER); |
| 344 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
| 345 | ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0); | 339 | ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, 0); |
| 346 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 340 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 341 | ValidateExecuteCommitMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ"); | ||
| 347 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 342 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 348 | ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); | 343 | ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); |
| 349 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 344 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| @@ -361,19 +356,16 @@ namespace Bootstrapper | |||
| 361 | dwIndex = 0; | 356 | dwIndex = 0; |
| 362 | dwExecuteCheckpointId = 1; | 357 | dwExecuteCheckpointId = 1; |
| 363 | ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE); | 358 | ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE); |
| 359 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
| 364 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_REGISTER); | 360 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageC", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_REGISTER); |
| 365 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 361 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 366 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_REGISTER); | 362 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_REGISTER); |
| 367 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 363 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 368 | ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0); | ||
| 369 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
| 370 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 364 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 371 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_REGISTER); | 365 | ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{c096190a-8bf3-4342-a1d2-94ea9cb853d6}", BURN_DEPENDENCY_ACTION_REGISTER); |
| 372 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 366 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 373 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_REGISTER); | 367 | ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_REGISTER); |
| 374 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 368 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 375 | ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0); | ||
| 376 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | ||
| 377 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 369 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 378 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); | 370 | ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); |
| 379 | ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); | 371 | ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); |
| @@ -818,6 +810,18 @@ namespace Bootstrapper | |||
| 818 | return (fRollback ? pPlan->rgRollbackActions : pPlan->rgExecuteActions) + dwIndex; | 810 | return (fRollback ? pPlan->rgRollbackActions : pPlan->rgExecuteActions) + dwIndex; |
| 819 | } | 811 | } |
| 820 | 812 | ||
| 813 | void ValidateExecuteBeginMsiTransaction( | ||
| 814 | __in BURN_PLAN* pPlan, | ||
| 815 | __in BOOL fRollback, | ||
| 816 | __in DWORD dwIndex, | ||
| 817 | __in LPCWSTR wzRollbackBoundaryId | ||
| 818 | ) | ||
| 819 | { | ||
| 820 | BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex); | ||
| 821 | Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_BEGIN_MSI_TRANSACTION, pAction->type); | ||
| 822 | NativeAssert::StringEqual(wzRollbackBoundaryId, pAction->msiTransaction.pRollbackBoundary->sczId); | ||
| 823 | } | ||
| 824 | |||
| 821 | void ValidateExecuteCheckpoint( | 825 | void ValidateExecuteCheckpoint( |
| 822 | __in BURN_PLAN* pPlan, | 826 | __in BURN_PLAN* pPlan, |
| 823 | __in BOOL fRollback, | 827 | __in BOOL fRollback, |
| @@ -830,6 +834,18 @@ namespace Bootstrapper | |||
| 830 | Assert::Equal(dwId, pAction->checkpoint.dwId); | 834 | Assert::Equal(dwId, pAction->checkpoint.dwId); |
| 831 | } | 835 | } |
| 832 | 836 | ||
| 837 | void ValidateExecuteCommitMsiTransaction( | ||
| 838 | __in BURN_PLAN* pPlan, | ||
| 839 | __in BOOL fRollback, | ||
| 840 | __in DWORD dwIndex, | ||
| 841 | __in LPCWSTR wzRollbackBoundaryId | ||
| 842 | ) | ||
| 843 | { | ||
| 844 | BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex); | ||
| 845 | Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_COMMIT_MSI_TRANSACTION, pAction->type); | ||
| 846 | NativeAssert::StringEqual(wzRollbackBoundaryId, pAction->msiTransaction.pRollbackBoundary->sczId); | ||
| 847 | } | ||
| 848 | |||
| 833 | void ValidateExecuteExePackage( | 849 | void ValidateExecuteExePackage( |
| 834 | __in BURN_PLAN* pPlan, | 850 | __in BURN_PLAN* pPlan, |
| 835 | __in BOOL fRollback, | 851 | __in BOOL fRollback, |
