aboutsummaryrefslogtreecommitdiff
path: root/src/engine/elevation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/elevation.cpp')
-rw-r--r--src/engine/elevation.cpp208
1 files changed, 200 insertions, 8 deletions
diff --git a/src/engine/elevation.cpp b/src/engine/elevation.cpp
index 1d0e1f1d..af5610dc 100644
--- a/src/engine/elevation.cpp
+++ b/src/engine/elevation.cpp
@@ -32,6 +32,10 @@ typedef enum _BURN_ELEVATION_MESSAGE_TYPE
32 BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION, 32 BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION,
33 BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION, 33 BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION,
34 34
35 BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN,
36 BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE,
37 BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_BEGIN,
38 BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE,
35 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS, 39 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS,
36 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR, 40 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR,
37 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE, 41 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE,
@@ -42,6 +46,13 @@ typedef enum _BURN_ELEVATION_MESSAGE_TYPE
42 46
43// struct 47// struct
44 48
49typedef struct _BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT
50{
51 BURN_USER_EXPERIENCE* pBA;
52 BOOL fPauseCompleteNeeded;
53 BOOL fSrpCompleteNeeded;
54} BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT;
55
45typedef struct _BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT 56typedef struct _BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT
46{ 57{
47 PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler; 58 PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler;
@@ -89,6 +100,11 @@ static HRESULT OnLoadCompatiblePackage(
89 __in BYTE* pbData, 100 __in BYTE* pbData,
90 __in DWORD cbData 101 __in DWORD cbData
91 ); 102 );
103static HRESULT ProcessApplyInitializeMessages(
104 __in BURN_PIPE_MESSAGE* pMsg,
105 __in_opt LPVOID pvContext,
106 __out DWORD* pdwResult
107 );
92static HRESULT ProcessGenericExecuteMessages( 108static HRESULT ProcessGenericExecuteMessages(
93 __in BURN_PIPE_MESSAGE* pMsg, 109 __in BURN_PIPE_MESSAGE* pMsg,
94 __in_opt LPVOID pvContext, 110 __in_opt LPVOID pvContext,
@@ -119,6 +135,7 @@ static HRESULT ProcessResult(
119 __out BOOTSTRAPPER_APPLY_RESTART* pRestart 135 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
120 ); 136 );
121static HRESULT OnApplyInitialize( 137static HRESULT OnApplyInitialize(
138 __in HANDLE hPipe,
122 __in BURN_VARIABLES* pVariables, 139 __in BURN_VARIABLES* pVariables,
123 __in BURN_REGISTRATION* pRegistration, 140 __in BURN_REGISTRATION* pRegistration,
124 __in HANDLE* phLock, 141 __in HANDLE* phLock,
@@ -245,7 +262,20 @@ static HRESULT OnMsiRollbackTransaction(
245 __in BYTE* pbData, 262 __in BYTE* pbData,
246 __in DWORD cbData 263 __in DWORD cbData
247 ); 264 );
248 265static HRESULT ElevatedOnPauseAUBegin(
266 __in HANDLE hPipe
267 );
268static HRESULT ElevatedOnPauseAUComplete(
269 __in HANDLE hPipe,
270 __in HRESULT hrStatus
271 );
272static HRESULT ElevatedOnSystemRestorePointBegin(
273 __in HANDLE hPipe
274 );
275static HRESULT ElevatedOnSystemRestorePointComplete(
276 __in HANDLE hPipe,
277 __in HRESULT hrStatus
278 );
249 279
250 280
251// function definitions 281// function definitions
@@ -321,6 +351,7 @@ LExit:
321 351
322extern "C" HRESULT ElevationApplyInitialize( 352extern "C" HRESULT ElevationApplyInitialize(
323 __in HANDLE hPipe, 353 __in HANDLE hPipe,
354 __in BURN_USER_EXPERIENCE* pBA,
324 __in BURN_VARIABLES* pVariables, 355 __in BURN_VARIABLES* pVariables,
325 __in BOOTSTRAPPER_ACTION action, 356 __in BOOTSTRAPPER_ACTION action,
326 __in BURN_AU_PAUSE_ACTION auAction, 357 __in BURN_AU_PAUSE_ACTION auAction,
@@ -331,6 +362,9 @@ extern "C" HRESULT ElevationApplyInitialize(
331 BYTE* pbData = NULL; 362 BYTE* pbData = NULL;
332 SIZE_T cbData = 0; 363 SIZE_T cbData = 0;
333 DWORD dwResult = 0; 364 DWORD dwResult = 0;
365 BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT context = { };
366
367 context.pBA = pBA;
334 368
335 // serialize message data 369 // serialize message data
336 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)action); 370 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)action);
@@ -346,11 +380,21 @@ extern "C" HRESULT ElevationApplyInitialize(
346 ExitOnFailure(hr, "Failed to write variables."); 380 ExitOnFailure(hr, "Failed to write variables.");
347 381
348 // send message 382 // send message
349 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE, pbData, cbData, NULL, NULL, &dwResult); 383 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE, pbData, cbData, ProcessApplyInitializeMessages, &context, &dwResult);
350 ExitOnFailure(hr, "Failed to send message to per-machine process."); 384 ExitOnFailure(hr, "Failed to send message to per-machine process.");
351 385
352 hr = (HRESULT)dwResult; 386 hr = (HRESULT)dwResult;
353 387
388 // Best effort to keep the sequence of BA events sane.
389 if (context.fPauseCompleteNeeded)
390 {
391 UserExperienceOnPauseAUComplete(pBA, hr);
392 }
393 if (context.fSrpCompleteNeeded)
394 {
395 UserExperienceOnSystemRestorePointComplete(pBA, hr);
396 }
397
354LExit: 398LExit:
355 ReleaseBuffer(pbData); 399 ReleaseBuffer(pbData);
356 400
@@ -1317,6 +1361,68 @@ LExit:
1317 return hr; 1361 return hr;
1318} 1362}
1319 1363
1364static HRESULT ProcessApplyInitializeMessages(
1365 __in BURN_PIPE_MESSAGE* pMsg,
1366 __in_opt LPVOID pvContext,
1367 __out DWORD* pdwResult
1368 )
1369{
1370 HRESULT hr = S_OK;
1371 BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT*>(pvContext);
1372 BYTE* pbData = (BYTE*)pMsg->pvData;
1373 SIZE_T iData = 0;
1374 HRESULT hrStatus = S_OK;
1375 HRESULT hrBA = S_OK;
1376
1377 // Process the message.
1378 switch (pMsg->dwMessage)
1379 {
1380 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN:
1381 pContext->fPauseCompleteNeeded = TRUE;
1382 hrBA = UserExperienceOnPauseAUBegin(pContext->pBA);
1383 break;
1384
1385 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE:
1386 // read hrStatus
1387 hr = BuffReadNumber(pbData, pMsg->cbData, &iData, reinterpret_cast<DWORD*>(&hrStatus));
1388 ExitOnFailure(hr, "Failed to read pause AU hrStatus.");
1389
1390 pContext->fPauseCompleteNeeded = FALSE;
1391 hrBA = UserExperienceOnPauseAUComplete(pContext->pBA, hrStatus);
1392 break;
1393
1394 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_BEGIN:
1395 if (pContext->fPauseCompleteNeeded)
1396 {
1397 pContext->fPauseCompleteNeeded = FALSE;
1398 hrBA = UserExperienceOnPauseAUComplete(pContext->pBA, E_INVALIDSTATE);
1399 }
1400
1401 pContext->fSrpCompleteNeeded = TRUE;
1402 hrBA = UserExperienceOnSystemRestorePointBegin(pContext->pBA);
1403 break;
1404
1405 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE:
1406 // read hrStatus
1407 hr = BuffReadNumber(pbData, pMsg->cbData, &iData, reinterpret_cast<DWORD*>(&hrStatus));
1408 ExitOnFailure(hr, "Failed to read system restore point hrStatus.");
1409
1410 pContext->fSrpCompleteNeeded = FALSE;
1411 hrBA = UserExperienceOnSystemRestorePointComplete(pContext->pBA, hrStatus);
1412 break;
1413
1414 default:
1415 hr = E_INVALIDARG;
1416 ExitOnRootFailure(hr, "Invalid apply initialize message.");
1417 break;
1418 }
1419
1420 *pdwResult = static_cast<DWORD>(hrBA);
1421
1422LExit:
1423 return hr;
1424}
1425
1320static HRESULT ProcessGenericExecuteMessages( 1426static HRESULT ProcessGenericExecuteMessages(
1321 __in BURN_PIPE_MESSAGE* pMsg, 1427 __in BURN_PIPE_MESSAGE* pMsg,
1322 __in_opt LPVOID pvContext, 1428 __in_opt LPVOID pvContext,
@@ -1385,7 +1491,7 @@ static HRESULT ProcessGenericExecuteMessages(
1385 } 1491 }
1386 1492
1387 // send message 1493 // send message
1388 *pdwResult = (DWORD)pContext->pfnGenericMessageHandler(&message, pContext->pvContext);; 1494 *pdwResult = (DWORD)pContext->pfnGenericMessageHandler(&message, pContext->pvContext);
1389 1495
1390LExit: 1496LExit:
1391 ReleaseStr(sczMessage); 1497 ReleaseStr(sczMessage);
@@ -1562,7 +1668,7 @@ static HRESULT ProcessElevatedChildMessage(
1562 break; 1668 break;
1563 1669
1564 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE: 1670 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE:
1565 hrResult = OnApplyInitialize(pContext->pVariables, pContext->pRegistration, pContext->phLock, pContext->pfDisabledAutomaticUpdates, (BYTE*)pMsg->pvData, pMsg->cbData); 1671 hrResult = OnApplyInitialize(pContext->hPipe, pContext->pVariables, pContext->pRegistration, pContext->phLock, pContext->pfDisabledAutomaticUpdates, (BYTE*)pMsg->pvData, pMsg->cbData);
1566 break; 1672 break;
1567 1673
1568 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_UNINITIALIZE: 1674 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_UNINITIALIZE:
@@ -1697,6 +1803,7 @@ static HRESULT ProcessResult(
1697} 1803}
1698 1804
1699static HRESULT OnApplyInitialize( 1805static HRESULT OnApplyInitialize(
1806 __in HANDLE hPipe,
1700 __in BURN_VARIABLES* pVariables, 1807 __in BURN_VARIABLES* pVariables,
1701 __in BURN_REGISTRATION* pRegistration, 1808 __in BURN_REGISTRATION* pRegistration,
1702 __in HANDLE* phLock, 1809 __in HANDLE* phLock,
@@ -1711,6 +1818,7 @@ static HRESULT OnApplyInitialize(
1711 DWORD dwAUAction = 0; 1818 DWORD dwAUAction = 0;
1712 DWORD dwTakeSystemRestorePoint = 0; 1819 DWORD dwTakeSystemRestorePoint = 0;
1713 LPWSTR sczBundleName = NULL; 1820 LPWSTR sczBundleName = NULL;
1821 HRESULT hrStatus = S_OK;
1714 1822
1715 // Deserialize message data. 1823 // Deserialize message data.
1716 hr = BuffReadNumber(pbData, cbData, &iData, &dwAction); 1824 hr = BuffReadNumber(pbData, cbData, &iData, &dwAction);
@@ -1738,9 +1846,12 @@ static HRESULT OnApplyInitialize(
1738 // Attempt to pause AU with best effort. 1846 // Attempt to pause AU with best effort.
1739 if (BURN_AU_PAUSE_ACTION_IFELEVATED == dwAUAction || BURN_AU_PAUSE_ACTION_IFELEVATED_NORESUME == dwAUAction) 1847 if (BURN_AU_PAUSE_ACTION_IFELEVATED == dwAUAction || BURN_AU_PAUSE_ACTION_IFELEVATED_NORESUME == dwAUAction)
1740 { 1848 {
1849 hr = ElevatedOnPauseAUBegin(hPipe);
1850 ExitOnFailure(hr, "ElevatedOnPauseAUBegin failed.");
1851
1741 LogId(REPORT_STANDARD, MSG_PAUSE_AU_STARTING); 1852 LogId(REPORT_STANDARD, MSG_PAUSE_AU_STARTING);
1742 1853
1743 hr = WuaPauseAutomaticUpdates(); 1854 hrStatus = hr = WuaPauseAutomaticUpdates();
1744 if (FAILED(hr)) 1855 if (FAILED(hr))
1745 { 1856 {
1746 LogId(REPORT_STANDARD, MSG_FAILED_PAUSE_AU, hr); 1857 LogId(REPORT_STANDARD, MSG_FAILED_PAUSE_AU, hr);
@@ -1754,6 +1865,9 @@ static HRESULT OnApplyInitialize(
1754 *pfDisabledWindowsUpdate = TRUE; 1865 *pfDisabledWindowsUpdate = TRUE;
1755 } 1866 }
1756 } 1867 }
1868
1869 hr = ElevatedOnPauseAUComplete(hPipe, hrStatus);
1870 ExitOnFailure(hr, "ElevatedOnPauseAUComplete failed.");
1757 } 1871 }
1758 1872
1759 if (dwTakeSystemRestorePoint) 1873 if (dwTakeSystemRestorePoint)
@@ -1765,11 +1879,14 @@ static HRESULT OnApplyInitialize(
1765 ExitFunction(); 1879 ExitFunction();
1766 } 1880 }
1767 1881
1882 hr = ElevatedOnSystemRestorePointBegin(hPipe);
1883 ExitOnFailure(hr, "ElevatedOnSystemRestorePointBegin failed.");
1884
1768 LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_STARTING); 1885 LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_STARTING);
1769 1886
1770 BOOTSTRAPPER_ACTION action = static_cast<BOOTSTRAPPER_ACTION>(dwAction); 1887 BOOTSTRAPPER_ACTION action = static_cast<BOOTSTRAPPER_ACTION>(dwAction);
1771 SRP_ACTION restoreAction = (BOOTSTRAPPER_ACTION_INSTALL == action) ? SRP_ACTION_INSTALL : (BOOTSTRAPPER_ACTION_UNINSTALL == action) ? SRP_ACTION_UNINSTALL : SRP_ACTION_MODIFY; 1888 SRP_ACTION restoreAction = (BOOTSTRAPPER_ACTION_INSTALL == action) ? SRP_ACTION_INSTALL : (BOOTSTRAPPER_ACTION_UNINSTALL == action) ? SRP_ACTION_UNINSTALL : SRP_ACTION_MODIFY;
1772 hr = SrpCreateRestorePoint(sczBundleName, restoreAction); 1889 hrStatus = hr = SrpCreateRestorePoint(sczBundleName, restoreAction);
1773 if (SUCCEEDED(hr)) 1890 if (SUCCEEDED(hr))
1774 { 1891 {
1775 LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_SUCCEEDED); 1892 LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_SUCCEEDED);
@@ -1779,11 +1896,14 @@ static HRESULT OnApplyInitialize(
1779 LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_DISABLED); 1896 LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_DISABLED);
1780 hr = S_OK; 1897 hr = S_OK;
1781 } 1898 }
1782 else if (FAILED(hr)) 1899 else
1783 { 1900 {
1784 LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_FAILED, hr); 1901 LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_FAILED, hr);
1785 hr = S_OK; 1902 hr = S_OK;
1786 } 1903 }
1904
1905 hr = ElevatedOnSystemRestorePointComplete(hPipe, hrStatus);
1906 ExitOnFailure(hr, "ElevatedOnSystemRestorePointComplete failed.");
1787 } 1907 }
1788 1908
1789LExit: 1909LExit:
@@ -2699,7 +2819,7 @@ static int MsiExecuteMessageHandler(
2699 2819
2700 // send message 2820 // send message
2701 hr = PipeSendMessage(hPipe, dwMessage, pbData, cbData, NULL, NULL, (DWORD*)&nResult); 2821 hr = PipeSendMessage(hPipe, dwMessage, pbData, cbData, NULL, NULL, (DWORD*)&nResult);
2702 ExitOnFailure(hr, "Failed to send message to per-machine process."); 2822 ExitOnFailure(hr, "Failed to send msi message to per-user process.");
2703 2823
2704LExit: 2824LExit:
2705 ReleaseBuffer(pbData); 2825 ReleaseBuffer(pbData);
@@ -2867,3 +2987,75 @@ LExit:
2867 2987
2868 return hr; 2988 return hr;
2869} 2989}
2990
2991static HRESULT ElevatedOnPauseAUBegin(
2992 __in HANDLE hPipe
2993 )
2994{
2995 HRESULT hr = S_OK;
2996 DWORD dwResult = 0;
2997
2998 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN, NULL, 0, NULL, NULL, &dwResult);
2999 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN message to per-user process.");
3000
3001LExit:
3002 return hr;
3003}
3004
3005static HRESULT ElevatedOnPauseAUComplete(
3006 __in HANDLE hPipe,
3007 __in HRESULT hrStatus
3008 )
3009{
3010 HRESULT hr = S_OK;
3011 BYTE* pbSendData = NULL;
3012 SIZE_T cbSendData = 0;
3013 DWORD dwResult = 0;
3014
3015 hr = BuffWriteNumber(&pbSendData, &cbSendData, hrStatus);
3016 ExitOnFailure(hr, "Failed to write the pause au status to message buffer.");
3017
3018 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE, pbSendData, cbSendData, NULL, NULL, &dwResult);
3019 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE message to per-user process.");
3020
3021LExit:
3022 ReleaseBuffer(pbSendData);
3023
3024 return hr;
3025}
3026
3027static HRESULT ElevatedOnSystemRestorePointBegin(
3028 __in HANDLE hPipe
3029 )
3030{
3031 HRESULT hr = S_OK;
3032 DWORD dwResult = 0;
3033
3034 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_BEGIN, NULL, 0, NULL, NULL, &dwResult);
3035 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_BEGIN message to per-user process.");
3036
3037LExit:
3038 return hr;
3039}
3040
3041static HRESULT ElevatedOnSystemRestorePointComplete(
3042 __in HANDLE hPipe,
3043 __in HRESULT hrStatus
3044 )
3045{
3046 HRESULT hr = S_OK;
3047 BYTE* pbSendData = NULL;
3048 SIZE_T cbSendData = 0;
3049 DWORD dwResult = 0;
3050
3051 hr = BuffWriteNumber(&pbSendData, &cbSendData, hrStatus);
3052 ExitOnFailure(hr, "Failed to write the system restore point status to message buffer.");
3053
3054 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE, pbSendData, cbSendData, NULL, NULL, &dwResult);
3055 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE message to per-user process.");
3056
3057LExit:
3058 ReleaseBuffer(pbSendData);
3059
3060 return hr;
3061}