diff options
Diffstat (limited to 'src/engine/apply.cpp')
-rw-r--r-- | src/engine/apply.cpp | 194 |
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 | |||
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 | ||