@joebigelow / wix / commits / 846f5a03

Clean up the elevation code for MSI transactions.

Sean Hall committed Nov 15, 2020 at 20:23 UTC 846f5a033d346c1bac51c56d4936cd3118ebea7a
5 files changed +213 -261
src/engine/apply.cpp
+82 -150
@@ -198,6 +198,19 @@ static HRESULT ExecuteCompatiblePackageAction(
198 __in BURN_ENGINE_STATE* pEngineState,
199 __in BURN_EXECUTE_ACTION* pAction
200 );
201 +static HRESULT ExecuteMsiBeginTransaction(
202 + __in BURN_ENGINE_STATE* pEngineState,
203 + __in LPCWSTR wzName,
204 + __in BURN_EXECUTE_CONTEXT* pContext
205 + );
206 +static HRESULT ExecuteMsiCommitTransaction(
207 + __in BURN_ENGINE_STATE* pEngineState,
208 + __in BURN_EXECUTE_CONTEXT* pContext
209 + );
210 +static HRESULT ExecuteMsiRollbackTransaction(
211 + __in BURN_ENGINE_STATE* pEngineState,
212 + __in BURN_EXECUTE_CONTEXT* pContext
213 + );
214 static HRESULT CleanPackage(
215 __in HANDLE hElevatedPipe,
216 __in BURN_PACKAGE* pPackage
@@ -228,30 +241,6 @@ static HRESULT ExecutePackageComplete(
241 __out BOOL* pfSuspend
242 );
243
231 -static HRESULT DoMsiBeginTransaction(
232 - __in BURN_EXECUTE_CONTEXT *context
233 - , __in BURN_ENGINE_STATE* pEngineState
234 -);
235 -static HRESULT DoMsiCommitTransaction(
236 - __in BURN_EXECUTE_CONTEXT *context
237 - , __in BURN_ENGINE_STATE* pEngineState
238 -);
239 -static HRESULT DoMsiRollbackTransaction(
240 - __in BURN_EXECUTE_CONTEXT *context
241 - , __in BURN_ENGINE_STATE* pEngineState
242 -);
243 -static HRESULT ExecuteMsiBeginTransaction(
244 - __in BURN_EXECUTE_CONTEXT* pContext
245 - , __in BURN_ENGINE_STATE* pEngineState
246 -);
247 -static HRESULT ExecuteMsiCommitTransaction(
248 - __in BURN_EXECUTE_CONTEXT* pContext
249 - , __in BURN_ENGINE_STATE* pEngineState
250 -);
251 -static HRESULT ExecuteMsiRollbackTransaction(
252 - __in BURN_EXECUTE_CONTEXT* pContext
253 - , __in BURN_ENGINE_STATE* pEngineState
254 -);
244
245 // function definitions
246
@@ -773,7 +762,7 @@ extern "C" HRESULT ApplyExecute(
762 if (fInTransaction)
763 {
764 LogString(REPORT_STANDARD, "Committing MSI transaction\n");
776 - hr = DoMsiCommitTransaction(&context, pEngineState);
765 + hr = ExecuteMsiCommitTransaction(pEngineState, &context);
766 ExitOnFailure(hr, "Failed committing an MSI transaction");
767 fInTransaction = FALSE;
768 }
@@ -789,7 +778,7 @@ extern "C" HRESULT ApplyExecute(
778 else
779 {
780 LogString(REPORT_STANDARD, "Starting a new MSI transaction\n");
792 - hr = DoMsiBeginTransaction(&context, pEngineState);
781 + hr = ExecuteMsiBeginTransaction(pEngineState, pExecuteAction->rollbackBoundary.pRollbackBoundary->sczId, &context);
782 ExitOnFailure(hr, "Failed beginning an MSI transaction");
783 fInTransaction = TRUE;
784 }
@@ -855,7 +844,7 @@ extern "C" HRESULT ApplyExecute(
844 if (fInTransaction)
845 {
846 LogString(REPORT_STANDARD, "Committing an MSI transaction\n");
858 - hr = DoMsiCommitTransaction(&context, pEngineState);
847 + hr = ExecuteMsiCommitTransaction(pEngineState, &context);
848 ExitOnFailure(hr, "Failed committing an MSI transaction");
849 fInTransaction = FALSE;
850 }
@@ -1658,127 +1647,6 @@ static void DoRollbackCache(
1647 }
1648 }
1649
1661 -/* MSI Transactions:
1662 - * All MSI/MSP/MSU packages wrapped in MsiBeginTranasaction-MsiEndTransaction pair are installed or uninstalled together.
1663 -*/
1664 -static HRESULT ExecuteMsiBeginTransaction(
1665 - __in BURN_EXECUTE_CONTEXT* pContext
1666 - , __in BURN_ENGINE_STATE* pEngineState
1667 -)
1668 -{
1669 - HRESULT hr = S_OK;
1670 - UINT uResult = ERROR_SUCCESS;
1671 -
1672 - // Per user/machine context
1673 - if (pEngineState->plan.fPerMachine)
1674 - {
1675 - hr = ElevationMsiBeginTransaction(pEngineState->companionConnection.hPipe, pEngineState->userExperience.hwndApply, pContext);
1676 - ExitOnFailure(hr, "Failed to begin an MSI transaction.");
1677 - }
1678 - else
1679 - {
1680 - MSIHANDLE hMsiTrns = NULL;
1681 - HANDLE hMsiTrnsEvent = NULL;
1682 - uResult = MsiBeginTransaction(L"WiX", 0, &hMsiTrns, &hMsiTrnsEvent);
1683 - ExitOnWin32Error(uResult, hr, "Failed beginning an MSI transaction");
1684 - }
1685 -
1686 -LExit:
1687 - return hr;
1688 -}
1689 -
1690 -static HRESULT ExecuteMsiCommitTransaction(
1691 - __in BURN_EXECUTE_CONTEXT* pContext
1692 - , __in BURN_ENGINE_STATE* pEngineState
1693 -)
1694 -{
1695 - HRESULT hr = S_OK;
1696 - UINT uResult = ERROR_SUCCESS;
1697 -
1698 - // Per user/machine context
1699 - if (pEngineState->plan.fPerMachine)
1700 - {
1701 - hr = ElevationMsiCommitTransaction(pEngineState->companionConnection.hPipe, pEngineState->userExperience.hwndApply, pContext);
1702 - ExitOnFailure(hr, "Failed to commit an MSI transaction.");
1703 - }
1704 - else
1705 - {
1706 - uResult = MsiEndTransaction(MSITRANSACTIONSTATE_COMMIT);
1707 - ExitOnWin32Error(uResult, hr, "Failed beginning an MSI transaction");
1708 - }
1709 -
1710 -LExit:
1711 - return hr;
1712 -}
1713 -
1714 -static HRESULT ExecuteMsiRollbackTransaction(
1715 - __in BURN_EXECUTE_CONTEXT* pContext
1716 - , __in BURN_ENGINE_STATE* pEngineState
1717 -)
1718 -{
1719 - HRESULT hr = S_OK;
1720 - UINT uResult = ERROR_SUCCESS;
1721 -
1722 - // Per user/machine context
1723 - if (pEngineState->plan.fPerMachine)
1724 - {
1725 - hr = ElevationMsiRollbackTransaction(pEngineState->companionConnection.hPipe, pEngineState->userExperience.hwndApply, pContext);
1726 - ExitOnFailure(hr, "Failed to rollback an MSI transaction.");
1727 - }
1728 - else
1729 - {
1730 - uResult = MsiEndTransaction(MSITRANSACTIONSTATE_ROLLBACK);
1731 - ExitOnWin32Error(uResult, hr, "Failed beginning an MSI transaction");
1732 - }
1733 -
1734 -LExit:
1735 - return hr;
1736 -}
1737 -
1738 -// Currently, supporting only elevated transactions.
1739 -static HRESULT DoMsiBeginTransaction(
1740 - __in BURN_EXECUTE_CONTEXT *pContext
1741 - , __in BURN_ENGINE_STATE* pEngineState
1742 -)
1743 -{
1744 - HRESULT hr = S_OK;
1745 -
1746 - hr = ExecuteMsiBeginTransaction(pContext, pEngineState);
1747 - ExitOnFailure(hr, "Failed to execute EXE package.");
1748 -
1749 -LExit:
1750 - return hr;
1751 -}
1752 -
1753 -static HRESULT DoMsiCommitTransaction(
1754 - __in BURN_EXECUTE_CONTEXT *pContext
1755 - , __in BURN_ENGINE_STATE* pEngineState
1756 -)
1757 -{
1758 - HRESULT hr = S_OK;
1759 -
1760 - hr = ExecuteMsiCommitTransaction(pContext, pEngineState);
1761 - ExitOnFailure(hr, "Failed to execute EXE package.");
1762 -
1763 -LExit:
1764 - return hr;
1765 -}
1766 -
1767 -static HRESULT DoMsiRollbackTransaction(
1768 - __in BURN_EXECUTE_CONTEXT *pContext
1769 - , __in BURN_ENGINE_STATE* pEngineState
1770 -)
1771 -{
1772 - HRESULT hr = S_OK;
1773 -
1774 - hr = ExecuteMsiRollbackTransaction(pContext, pEngineState);
1775 - ExitOnFailure(hr, "Failed to execute EXE package.");
1776 -
1777 -LExit:
1778 - return hr;
1779 -}
1780 -
1781 -
1650 static HRESULT DoExecuteAction(
1651 __in BURN_ENGINE_STATE* pEngineState,
1652 __in BURN_EXECUTE_ACTION* pExecuteAction,
@@ -1904,7 +1772,7 @@ static HRESULT DoRollbackActions(
1772 __in BOOL fInTransaction,
1773 __out BOOL* pfKeepRegistration,
1774 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
1907 -)
1775 + )
1776 {
1777 HRESULT hr = S_OK;
1778 DWORD iCheckpoint = 0;
@@ -1916,7 +1784,7 @@ static HRESULT DoRollbackActions(
1784 // Rollback MSI transaction
1785 if (fInTransaction)
1786 {
1919 - hr = DoMsiRollbackTransaction(pContext, pEngineState);
1787 + hr = ExecuteMsiRollbackTransaction(pEngineState, pContext);
1788 ExitOnFailure(hr, "Failed rolling back transaction");
1789 }
1790
@@ -2364,6 +2232,70 @@ LExit:
2232 return hr;
2233 }
2234
2235 +static HRESULT ExecuteMsiBeginTransaction(
2236 + __in BURN_ENGINE_STATE* pEngineState,
2237 + __in LPCWSTR wzName,
2238 + __in BURN_EXECUTE_CONTEXT* /*pContext*/
2239 + )
2240 +{
2241 + HRESULT hr = S_OK;
2242 +
2243 + if (pEngineState->plan.fPerMachine)
2244 + {
2245 + hr = ElevationMsiBeginTransaction(pEngineState->companionConnection.hPipe, wzName);
2246 + ExitOnFailure(hr, "Failed to begin an elevated MSI transaction.");
2247 + }
2248 + else
2249 + {
2250 + hr = MsiEngineBeginTransaction(wzName);
2251 + }
2252 +
2253 +LExit:
2254 + return hr;
2255 +}
2256 +
2257 +static HRESULT ExecuteMsiCommitTransaction(
2258 + __in BURN_ENGINE_STATE* pEngineState,
2259 + __in BURN_EXECUTE_CONTEXT* /*pContext*/
2260 + )
2261 +{
2262 + HRESULT hr = S_OK;
2263 +
2264 + if (pEngineState->plan.fPerMachine)
2265 + {
2266 + hr = ElevationMsiCommitTransaction(pEngineState->companionConnection.hPipe);
2267 + ExitOnFailure(hr, "Failed to commit an elevated MSI transaction.");
2268 + }
2269 + else
2270 + {
2271 + hr = MsiEngineCommitTransaction();
2272 + }
2273 +
2274 +LExit:
2275 + return hr;
2276 +}
2277 +
2278 +static HRESULT ExecuteMsiRollbackTransaction(
2279 + __in BURN_ENGINE_STATE* pEngineState,
2280 + __in BURN_EXECUTE_CONTEXT* /*pContext*/
2281 + )
2282 +{
2283 + HRESULT hr = S_OK;
2284 +
2285 + if (pEngineState->plan.fPerMachine)
2286 + {
2287 + hr = ElevationMsiRollbackTransaction(pEngineState->companionConnection.hPipe);
2288 + ExitOnFailure(hr, "Failed to rollback an elevated MSI transaction.");
2289 + }
2290 + else
2291 + {
2292 + hr = MsiEngineRollbackTransaction();
2293 + }
2294 +
2295 +LExit:
2296 + return hr;
2297 +}
2298 +
2299 static HRESULT CleanPackage(
2300 __in HANDLE hElevatedPipe,
2301 __in BURN_PACKAGE* pPackage
src/engine/elevation.cpp
+78 -100
@@ -28,17 +28,15 @@ typedef enum _BURN_ELEVATION_MESSAGE_TYPE
28 BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_EMBEDDED_CHILD,
29 BURN_ELEVATION_MESSAGE_TYPE_CLEAN_PACKAGE,
30 BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE,
31 + BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION,
32 + BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION,
33 + BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION,
34
35 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS,
36 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR,
37 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE,
38 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_FILES_IN_USE,
39 BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE_PROCESSID,
37 -
38 - BURN_ELEVATION_TRANSACTION_BEGIN,
39 - BURN_ELEVATION_TRANSACTION_COMMIT,
40 - BURN_ELEVATION_TRANSACTION_ROLLBACK
41 -
40 } BURN_ELEVATION_MESSAGE_TYPE;
41
42
@@ -74,24 +72,11 @@ typedef struct _BURN_ELEVATION_CHILD_MESSAGE_CONTEXT
72 BURN_VARIABLES* pVariables;
73 BURN_REGISTRATION* pRegistration;
74 BURN_USER_EXPERIENCE* pUserExperience;
77 -
78 - MSIHANDLE hMsiTrns;
79 - HANDLE hMsiTrnsEvent;
75 } BURN_ELEVATION_CHILD_MESSAGE_CONTEXT;
76
77
78 // internal function declarations
79
85 -static HRESULT OnMsiBeginTransaction(
86 - __in BURN_ELEVATION_CHILD_MESSAGE_CONTEXT* pContext
87 -);
88 -static HRESULT OnMsiCommitTransaction(
89 - __in BURN_ELEVATION_CHILD_MESSAGE_CONTEXT* pContext
90 -);
91 -static HRESULT OnMsiRollbackTransaction(
92 - __in BURN_ELEVATION_CHILD_MESSAGE_CONTEXT* pContext
93 -);
94 -
80 static DWORD WINAPI ElevatedChildCacheThreadProc(
81 __in LPVOID lpThreadParameter
82 );
@@ -248,6 +233,13 @@ static HRESULT OnLaunchApprovedExe(
233 __in BYTE* pbData,
234 __in DWORD cbData
235 );
236 +static HRESULT OnMsiBeginTransaction(
237 + __in BYTE* pbData,
238 + __in DWORD cbData
239 + );
240 +static HRESULT OnMsiCommitTransaction();
241 +static HRESULT OnMsiRollbackTransaction();
242 +
243
244
245 // function definitions
@@ -726,62 +718,56 @@ LExit:
718
719 extern "C" HRESULT ElevationMsiBeginTransaction(
720 __in HANDLE hPipe,
729 - __in_opt HWND hwndParent,
730 - __in LPVOID pvContext
731 -)
721 + __in LPCWSTR wzName
722 + )
723 {
733 - UNREFERENCED_PARAMETER(hwndParent);
724 HRESULT hr = S_OK;
735 - BURN_ELEVATION_MSI_MESSAGE_CONTEXT context = {};
725 + BYTE* pbData = NULL;
726 + SIZE_T cbData = 0;
727 DWORD dwResult = ERROR_SUCCESS;
728
738 - context.pvContext = pvContext;
729 + // serialize message data
730 + hr = BuffWriteString(&pbData, &cbData, wzName);
731 + ExitOnFailure(hr, "Failed to write transaction name to message buffer.");
732
740 - hr = PipeSendMessage(hPipe, BURN_ELEVATION_TRANSACTION_BEGIN, NULL, 0, NULL, &context, &dwResult);
741 - ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE message to per-machine process.");
742 - ExitOnWin32Error(dwResult, hr, "Failed beginning an elevated MSI transaction");
733 + hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION, NULL, 0, NULL, NULL, &dwResult);
734 + ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION message to per-machine process.");
735 +
736 + hr = static_cast<HRESULT>(dwResult);
737
738 LExit:
739 + ReleaseBuffer(pbData);
740 +
741 return hr;
742 }
743
744 extern "C" HRESULT ElevationMsiCommitTransaction(
749 - __in HANDLE hPipe,
750 - __in_opt HWND hwndParent,
751 - __in LPVOID pvContext
752 -)
745 + __in HANDLE hPipe
746 + )
747 {
754 - UNREFERENCED_PARAMETER(hwndParent);
748 HRESULT hr = S_OK;
756 - BURN_ELEVATION_MSI_MESSAGE_CONTEXT context = {};
749 DWORD dwResult = ERROR_SUCCESS;
750
759 - context.pvContext = pvContext;
751 + hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION, NULL, 0, NULL, NULL, &dwResult);
752 + ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION message to per-machine process.");
753
761 - hr = PipeSendMessage(hPipe, BURN_ELEVATION_TRANSACTION_COMMIT, NULL, 0, NULL, &context, &dwResult);
762 - ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE message to per-machine process.");
763 - ExitOnWin32Error(dwResult, hr, "Failed committing an elevated MSI transaction");
754 + hr = static_cast<HRESULT>(dwResult);
755
756 LExit:
757 return hr;
758 }
759
760 extern "C" HRESULT ElevationMsiRollbackTransaction(
770 - __in HANDLE hPipe,
771 - __in_opt HWND hwndParent,
772 - __in LPVOID pvContext
773 -)
761 + __in HANDLE hPipe
762 + )
763 {
775 - UNREFERENCED_PARAMETER(hwndParent);
764 HRESULT hr = S_OK;
777 - BURN_ELEVATION_MSI_MESSAGE_CONTEXT context = {};
765 DWORD dwResult = ERROR_SUCCESS;
766
780 - context.pvContext = pvContext;
767 + hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION, NULL, 0, NULL, NULL, &dwResult);
768 + ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION message to per-machine process.");
769
782 - hr = PipeSendMessage(hPipe, BURN_ELEVATION_TRANSACTION_ROLLBACK, NULL, 0, NULL, &context, &dwResult);
783 - ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE message to per-machine process.");
784 - ExitOnWin32Error(dwResult, hr, "Failed rolling back an elevated MSI transaction");
770 + hr = static_cast<HRESULT>(dwResult);
771
772 LExit:
773 return hr;
@@ -1543,16 +1529,16 @@ static HRESULT ProcessElevatedChildMessage(
1529
1530 switch (pMsg->dwMessage)
1531 {
1546 - case BURN_ELEVATION_TRANSACTION_BEGIN:
1547 - hrResult = OnMsiBeginTransaction(pContext);
1532 + case BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION:
1533 + hrResult = OnMsiBeginTransaction((BYTE*)pMsg->pvData, pMsg->cbData);
1534 break;
1535
1550 - case BURN_ELEVATION_TRANSACTION_COMMIT:
1551 - hrResult = OnMsiCommitTransaction(pContext);
1536 + case BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION:
1537 + hrResult = OnMsiCommitTransaction();
1538 break;
1539
1554 - case BURN_ELEVATION_TRANSACTION_ROLLBACK:
1555 - hrResult = OnMsiRollbackTransaction(pContext);
1540 + case BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION:
1541 + hrResult = OnMsiRollbackTransaction();
1542 break;
1543
1544 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE:
@@ -1690,53 +1676,6 @@ static HRESULT ProcessResult(
1676 return hr;
1677 }
1678
1693 -static HRESULT OnMsiBeginTransaction(
1694 - __in BURN_ELEVATION_CHILD_MESSAGE_CONTEXT* pContext
1695 -)
1696 -{
1697 - UINT uResult = ERROR_SUCCESS;
1698 - HRESULT hr = S_OK;
1699 -
1700 - pContext->hMsiTrns = NULL;
1701 - pContext->hMsiTrnsEvent = NULL;
1702 - uResult = MsiBeginTransaction(L"WiX", 0, &pContext->hMsiTrns, &pContext->hMsiTrnsEvent);
1703 - ExitOnWin32Error(uResult, hr, "Failed beginning an MSI transaction");
1704 -
1705 -LExit:
1706 - return hr;
1707 -}
1708 -
1709 -static HRESULT OnMsiCommitTransaction(
1710 - __in BURN_ELEVATION_CHILD_MESSAGE_CONTEXT* pContext
1711 -)
1712 -{
1713 - UINT uResult = ERROR_SUCCESS;
1714 - HRESULT hr = S_OK;
1715 -
1716 - uResult = MsiEndTransaction(MSITRANSACTIONSTATE_COMMIT);
1717 - ExitOnWin32Error(uResult, hr, "Failed committing an MSI transaction");
1718 -
1719 -LExit:
1720 - pContext->hMsiTrns = NULL;
1721 - pContext->hMsiTrnsEvent = NULL;
1722 - return hr;
1723 -}
1724 -
1725 -static HRESULT OnMsiRollbackTransaction(
1726 - __in BURN_ELEVATION_CHILD_MESSAGE_CONTEXT* pContext
1727 -) {
1728 - UINT uResult = ERROR_SUCCESS;
1729 - HRESULT hr = S_OK;
1730 -
1731 - uResult = MsiEndTransaction(MSITRANSACTIONSTATE_ROLLBACK);
1732 - ExitOnWin32Error(uResult, hr, "Failed rolling back an MSI transaction");
1733 -
1734 -LExit:
1735 - pContext->hMsiTrns = NULL;
1736 - pContext->hMsiTrnsEvent = NULL;
1737 - return hr;
1738 -}
1739 -
1679 static HRESULT OnApplyInitialize(
1680 __in BURN_VARIABLES* pVariables,
1681 __in BURN_REGISTRATION* pRegistration,
@@ -2845,3 +2784,42 @@ LExit:
2784 ApprovedExesUninitializeLaunch(pLaunchApprovedExe);
2785 return hr;
2786 }
2787 +
2788 +static HRESULT OnMsiBeginTransaction(
2789 + __in BYTE* pbData,
2790 + __in DWORD cbData
2791 + )
2792 +{
2793 + HRESULT hr = S_OK;
2794 + SIZE_T iData = 0;
2795 + LPWSTR sczName = NULL;
2796 +
2797 + // Deserialize message data.
2798 + hr = BuffReadString(pbData, cbData, &iData, &sczName);
2799 + ExitOnFailure(hr, "Failed to read transaction name.");
2800 +
2801 + hr = MsiEngineBeginTransaction(sczName);
2802 +
2803 +LExit:
2804 + ReleaseStr(sczName);
2805 +
2806 + return hr;
2807 +}
2808 +
2809 +static HRESULT OnMsiCommitTransaction()
2810 +{
2811 + HRESULT hr = S_OK;
2812 +
2813 + hr = MsiEngineCommitTransaction();
2814 +
2815 + return hr;
2816 +}
2817 +
2818 +static HRESULT OnMsiRollbackTransaction()
2819 +{
2820 + HRESULT hr = S_OK;
2821 +
2822 + hr = MsiEngineRollbackTransaction();
2823 +
2824 + return hr;
2825 +}
src/engine/elevation.h
+6 -11
@@ -159,19 +159,14 @@ HRESULT ElevationChildResumeAutomaticUpdates();
159
160 HRESULT ElevationMsiBeginTransaction(
161 __in HANDLE hPipe,
162 - __in_opt HWND hwndParent,
163 - __in LPVOID pvContext
164 -);
162 + __in LPCWSTR wzName
163 + );
164 HRESULT ElevationMsiCommitTransaction(
166 - __in HANDLE hPipe,
167 - __in_opt HWND hwndParent,
168 - __in LPVOID pvContext
169 -);
165 + __in HANDLE hPipe
166 + );
167 HRESULT ElevationMsiRollbackTransaction(
171 - __in HANDLE hPipe,
172 - __in_opt HWND hwndParent,
173 - __in LPVOID pvContext
174 -);
168 + __in HANDLE hPipe
169 + );
170
171 #ifdef __cplusplus
172 }
src/engine/msiengine.cpp
+42
@@ -1137,6 +1137,48 @@ LExit:
1137 return hr;
1138 }
1139
1140 +extern "C" HRESULT MsiEngineBeginTransaction(
1141 + __in LPCWSTR wzName
1142 + )
1143 +{
1144 + HRESULT hr = S_OK;
1145 + UINT uResult = ERROR_SUCCESS;
1146 + MSIHANDLE hTransactionHandle = NULL;
1147 + HANDLE hChangeOfOwnerEvent = NULL;
1148 +
1149 + uResult = ::MsiBeginTransaction(wzName, 0, &hTransactionHandle, &hChangeOfOwnerEvent);
1150 + ExitOnWin32Error(uResult, hr, "Failed to begin an MSI transaction");
1151 +
1152 +LExit:
1153 + return hr;
1154 +}
1155 +
1156 +extern "C" HRESULT MsiEngineCommitTransaction()
1157 +{
1158 + HRESULT hr = S_OK;
1159 + UINT uResult = ERROR_SUCCESS;
1160 +
1161 + uResult = ::MsiEndTransaction(MSITRANSACTIONSTATE_COMMIT);
1162 + ExitOnWin32Error(uResult, hr, "Failed to commit the MSI transaction");
1163 +
1164 +LExit:
1165 +
1166 + return hr;
1167 +}
1168 +
1169 +extern "C" HRESULT MsiEngineRollbackTransaction()
1170 +{
1171 + HRESULT hr = S_OK;
1172 + UINT uResult = ERROR_SUCCESS;
1173 +
1174 + uResult = ::MsiEndTransaction(MSITRANSACTIONSTATE_ROLLBACK);
1175 + ExitOnWin32Error(uResult, hr, "Failed to rollback the MSI transaction");
1176 +
1177 +LExit:
1178 +
1179 + return hr;
1180 +}
1181 +
1182 extern "C" HRESULT MsiEngineExecutePackage(
1183 __in_opt HWND hwndParent,
1184 __in BURN_EXECUTE_ACTION* pExecuteAction,
src/engine/msiengine.h
+5
@@ -52,6 +52,11 @@ HRESULT MsiEngineAddCompatiblePackage(
52 __in const BURN_PACKAGE* pPackage,
53 __out_opt BURN_PACKAGE** ppCompatiblePackage
54 );
55 +HRESULT MsiEngineBeginTransaction(
56 + __in LPCWSTR wzName
57 + );
58 +HRESULT MsiEngineCommitTransaction();
59 +HRESULT MsiEngineRollbackTransaction();
60 HRESULT MsiEngineExecutePackage(
61 __in_opt HWND hwndParent,
62 __in BURN_EXECUTE_ACTION* pExecuteAction,