aboutsummaryrefslogtreecommitdiff
path: root/src/engine/apply.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/apply.cpp')
-rw-r--r--src/engine/apply.cpp194
1 files changed, 95 insertions, 99 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
6const DWORD BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS = 2; 12const 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 );
201static HRESULT ExecuteMsiBeginTransaction( 206static 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 );
206static HRESULT ExecuteMsiCommitTransaction( 211static 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 );
210static HRESULT ExecuteMsiRollbackTransaction( 216static 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 );
214static HRESULT CleanPackage( 221static 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
852LExit: 835LExit:
@@ -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
2235static HRESULT ExecuteMsiBeginTransaction( 2202static 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
2253LExit: 2230LExit:
@@ -2256,11 +2233,17 @@ LExit:
2256 2233
2257static HRESULT ExecuteMsiCommitTransaction( 2234static 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
2274LExit: 2262LExit:
2275 return hr; 2263 return hr;
2276} 2264}
2277 2265
2278static HRESULT ExecuteMsiRollbackTransaction( 2266static 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
2295LExit: 2289LExit:
2290 pRollbackBoundary->fActiveTransaction = FALSE;
2291
2296 return hr; 2292 return hr;
2297} 2293}
2298 2294