aboutsummaryrefslogtreecommitdiff
path: root/src/burn
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-12-15 10:48:06 -0600
committerSean Hall <r.sean.hall@gmail.com>2021-12-30 15:00:45 -0600
commit9e2cda60e3852660f235beb5e0af1c746d0045e6 (patch)
tree8fca357e80bf638750fe900c4803a081e16adee8 /src/burn
parent07599b27596af68f0917c1afc6a748af3a3cda2f (diff)
downloadwix-9e2cda60e3852660f235beb5e0af1c746d0045e6.tar.gz
wix-9e2cda60e3852660f235beb5e0af1c746d0045e6.tar.bz2
wix-9e2cda60e3852660f235beb5e0af1c746d0045e6.zip
FilesInUse messages are too different to unify in the Burn engine.
Fixes #6348
Diffstat (limited to 'src/burn')
-rw-r--r--src/burn/engine/apply.cpp44
-rw-r--r--src/burn/engine/apply.h4
-rw-r--r--src/burn/engine/detect.cpp4
-rw-r--r--src/burn/engine/elevation.cpp36
-rw-r--r--src/burn/engine/embedded.cpp4
-rw-r--r--src/burn/engine/exeengine.cpp2
-rw-r--r--src/burn/engine/msuengine.cpp2
-rw-r--r--src/burn/engine/netfxchainer.cpp8
-rw-r--r--src/burn/engine/userexperience.cpp56
-rw-r--r--src/burn/engine/userexperience.h6
10 files changed, 117 insertions, 49 deletions
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp
index dfaba3f2..9e552ee0 100644
--- a/src/burn/engine/apply.cpp
+++ b/src/burn/engine/apply.cpp
@@ -1931,8 +1931,8 @@ static HRESULT WINAPI AuthenticationRequired(
1931 1931
1932 APPLY_AUTHENTICATION_REQUIRED_DATA* authenticationData = reinterpret_cast<APPLY_AUTHENTICATION_REQUIRED_DATA*>(pData); 1932 APPLY_AUTHENTICATION_REQUIRED_DATA* authenticationData = reinterpret_cast<APPLY_AUTHENTICATION_REQUIRED_DATA*>(pData);
1933 1933
1934 UserExperienceOnError(authenticationData->pUX, errorType, authenticationData->wzPackageOrContainerId, ERROR_ACCESS_DENIED, sczError, MB_RETRYTRYAGAIN, 0, NULL, &nResult); // ignore return value; 1934 UserExperienceOnError(authenticationData->pUX, errorType, authenticationData->wzPackageOrContainerId, ERROR_ACCESS_DENIED, sczError, MB_RETRYCANCEL, 0, NULL, &nResult); // ignore return value;
1935 nResult = UserExperienceCheckExecuteResult(authenticationData->pUX, FALSE, MB_RETRYTRYAGAIN, nResult); 1935 nResult = UserExperienceCheckExecuteResult(authenticationData->pUX, FALSE, BURN_MB_RETRYTRYAGAIN, nResult);
1936 if (IDTRYAGAIN == nResult && authenticationData->pUX->hwndApply) 1936 if (IDTRYAGAIN == nResult && authenticationData->pUX->hwndApply)
1937 { 1937 {
1938 er = ::InternetErrorDlg(authenticationData->pUX->hwndApply, hUrl, ERROR_INTERNET_INCORRECT_PASSWORD, FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA, NULL); 1938 er = ::InternetErrorDlg(authenticationData->pUX->hwndApply, hUrl, ERROR_INTERNET_INCORRECT_PASSWORD, FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA, NULL);
@@ -2495,10 +2495,10 @@ static HRESULT ExecuteExePackage(
2495 ExitOnRootFailure(hr, "BA aborted execute EXE package begin."); 2495 ExitOnRootFailure(hr, "BA aborted execute EXE package begin.");
2496 2496
2497 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; 2497 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS;
2498 message.dwAllowedResults = MB_OKCANCEL; 2498 message.dwUIHint = MB_OKCANCEL;
2499 message.progress.dwPercentage = fRollback ? 100 : 0; 2499 message.progress.dwPercentage = fRollback ? 100 : 0;
2500 nResult = GenericExecuteMessageHandler(&message, pContext); 2500 nResult = GenericExecuteMessageHandler(&message, pContext);
2501 hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwAllowedResults, nResult); 2501 hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult);
2502 ExitOnRootFailure(hr, "BA aborted EXE progress."); 2502 ExitOnRootFailure(hr, "BA aborted EXE progress.");
2503 2503
2504 fExecuted = TRUE; 2504 fExecuted = TRUE;
@@ -2516,10 +2516,10 @@ static HRESULT ExecuteExePackage(
2516 } 2516 }
2517 2517
2518 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; 2518 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS;
2519 message.dwAllowedResults = MB_OKCANCEL; 2519 message.dwUIHint = MB_OKCANCEL;
2520 message.progress.dwPercentage = fRollback ? 0 : 100; 2520 message.progress.dwPercentage = fRollback ? 0 : 100;
2521 nResult = GenericExecuteMessageHandler(&message, pContext); 2521 nResult = GenericExecuteMessageHandler(&message, pContext);
2522 hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwAllowedResults, nResult); 2522 hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult);
2523 ExitOnRootFailure(hr, "BA aborted EXE progress."); 2523 ExitOnRootFailure(hr, "BA aborted EXE progress.");
2524 2524
2525 pContext->cExecutedPackages += fRollback ? -1 : 1; 2525 pContext->cExecutedPackages += fRollback ? -1 : 1;
@@ -2712,10 +2712,10 @@ static HRESULT ExecuteMsuPackage(
2712 ExitOnRootFailure(hr, "BA aborted execute MSU package begin."); 2712 ExitOnRootFailure(hr, "BA aborted execute MSU package begin.");
2713 2713
2714 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; 2714 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS;
2715 message.dwAllowedResults = MB_OKCANCEL; 2715 message.dwUIHint = MB_OKCANCEL;
2716 message.progress.dwPercentage = fRollback ? 100 : 0; 2716 message.progress.dwPercentage = fRollback ? 100 : 0;
2717 nResult = GenericExecuteMessageHandler(&message, pContext); 2717 nResult = GenericExecuteMessageHandler(&message, pContext);
2718 hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwAllowedResults, nResult); 2718 hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult);
2719 ExitOnRootFailure(hr, "BA aborted MSU progress."); 2719 ExitOnRootFailure(hr, "BA aborted MSU progress.");
2720 2720
2721 fExecuted = TRUE; 2721 fExecuted = TRUE;
@@ -2733,10 +2733,10 @@ static HRESULT ExecuteMsuPackage(
2733 } 2733 }
2734 2734
2735 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; 2735 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS;
2736 message.dwAllowedResults = MB_OKCANCEL; 2736 message.dwUIHint = MB_OKCANCEL;
2737 message.progress.dwPercentage = fRollback ? 0 : 100; 2737 message.progress.dwPercentage = fRollback ? 0 : 100;
2738 nResult = GenericExecuteMessageHandler(&message, pContext); 2738 nResult = GenericExecuteMessageHandler(&message, pContext);
2739 hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwAllowedResults, nResult); 2739 hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult);
2740 ExitOnRootFailure(hr, "BA aborted MSU progress."); 2740 ExitOnRootFailure(hr, "BA aborted MSU progress.");
2741 2741
2742 pContext->cExecutedPackages += fRollback ? -1 : 1; 2742 pContext->cExecutedPackages += fRollback ? -1 : 1;
@@ -3047,6 +3047,7 @@ static int GenericExecuteMessageHandler(
3047 ) 3047 )
3048{ 3048{
3049 BURN_EXECUTE_CONTEXT* pContext = (BURN_EXECUTE_CONTEXT*)pvContext; 3049 BURN_EXECUTE_CONTEXT* pContext = (BURN_EXECUTE_CONTEXT*)pvContext;
3050 DWORD dwAllowedResults = pMessage->dwUIHint & MB_TYPEMASK;
3050 int nResult = IDNOACTION; 3051 int nResult = IDNOACTION;
3051 3052
3052 switch (pMessage->type) 3053 switch (pMessage->type)
@@ -3059,15 +3060,16 @@ static int GenericExecuteMessageHandler(
3059 break; 3060 break;
3060 3061
3061 case GENERIC_EXECUTE_MESSAGE_ERROR: 3062 case GENERIC_EXECUTE_MESSAGE_ERROR:
3062 UserExperienceOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_EXE_PACKAGE, pContext->pExecutingPackage->sczId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwAllowedResults, 0, NULL, &nResult); // ignore return value. 3063 UserExperienceOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_EXE_PACKAGE, pContext->pExecutingPackage->sczId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwUIHint, 0, NULL, &nResult); // ignore return value.
3063 break; 3064 break;
3064 3065
3065 case GENERIC_EXECUTE_MESSAGE_FILES_IN_USE: 3066 case GENERIC_EXECUTE_MESSAGE_NETFX_FILES_IN_USE:
3066 UserExperienceOnExecuteFilesInUse(pContext->pUX, pContext->pExecutingPackage->sczId, pMessage->filesInUse.cFiles, pMessage->filesInUse.rgwzFiles, &nResult); // ignore return value. 3067 UserExperienceOnExecuteFilesInUse(pContext->pUX, pContext->pExecutingPackage->sczId, pMessage->filesInUse.cFiles, pMessage->filesInUse.rgwzFiles, BOOTSTRAPPER_FILES_IN_USE_TYPE_NETFX, &nResult); // ignore return value.
3068 dwAllowedResults = BURN_MB_NETFX_FILES_IN_USE;
3067 break; 3069 break;
3068 } 3070 }
3069 3071
3070 nResult = UserExperienceCheckExecuteResult(pContext->pUX, pContext->fRollback, pMessage->dwAllowedResults, nResult); 3072 nResult = UserExperienceCheckExecuteResult(pContext->pUX, pContext->fRollback, dwAllowedResults, nResult);
3071 return nResult; 3073 return nResult;
3072} 3074}
3073 3075
@@ -3077,7 +3079,9 @@ static int MsiExecuteMessageHandler(
3077 ) 3079 )
3078{ 3080{
3079 BURN_EXECUTE_CONTEXT* pContext = (BURN_EXECUTE_CONTEXT*)pvContext; 3081 BURN_EXECUTE_CONTEXT* pContext = (BURN_EXECUTE_CONTEXT*)pvContext;
3082 DWORD dwAllowedResults = pMessage->dwUIHint & MB_TYPEMASK;
3080 int nResult = IDNOACTION; 3083 int nResult = IDNOACTION;
3084 BOOL fRestartManager = FALSE;
3081 3085
3082 switch (pMessage->type) 3086 switch (pMessage->type)
3083 { 3087 {
@@ -3090,20 +3094,24 @@ static int MsiExecuteMessageHandler(
3090 3094
3091 case WIU_MSI_EXECUTE_MESSAGE_ERROR: 3095 case WIU_MSI_EXECUTE_MESSAGE_ERROR:
3092 nResult = pMessage->nResultRecommendation; 3096 nResult = pMessage->nResultRecommendation;
3093 UserExperienceOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_WINDOWS_INSTALLER, pContext->pExecutingPackage->sczId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwAllowedResults, pMessage->cData, pMessage->rgwzData, &nResult); // ignore return value. 3097 UserExperienceOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_WINDOWS_INSTALLER, pContext->pExecutingPackage->sczId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwUIHint, pMessage->cData, pMessage->rgwzData, &nResult); // ignore return value.
3094 break; 3098 break;
3095 3099
3096 case WIU_MSI_EXECUTE_MESSAGE_MSI_MESSAGE: 3100 case WIU_MSI_EXECUTE_MESSAGE_MSI_MESSAGE:
3097 nResult = pMessage->nResultRecommendation; 3101 nResult = pMessage->nResultRecommendation;
3098 UserExperienceOnExecuteMsiMessage(pContext->pUX, pContext->pExecutingPackage->sczId, pMessage->msiMessage.mt, pMessage->dwAllowedResults, pMessage->msiMessage.wzMessage, pMessage->cData, pMessage->rgwzData, &nResult); // ignore return value. 3102 UserExperienceOnExecuteMsiMessage(pContext->pUX, pContext->pExecutingPackage->sczId, pMessage->msiMessage.mt, pMessage->dwUIHint, pMessage->msiMessage.wzMessage, pMessage->cData, pMessage->rgwzData, &nResult); // ignore return value.
3099 break; 3103 break;
3100 3104
3105 case WIU_MSI_EXECUTE_MESSAGE_MSI_RM_FILES_IN_USE:
3106 fRestartManager = TRUE;
3107 __fallthrough;
3101 case WIU_MSI_EXECUTE_MESSAGE_MSI_FILES_IN_USE: 3108 case WIU_MSI_EXECUTE_MESSAGE_MSI_FILES_IN_USE:
3102 UserExperienceOnExecuteFilesInUse(pContext->pUX, pContext->pExecutingPackage->sczId, pMessage->msiFilesInUse.cFiles, pMessage->msiFilesInUse.rgwzFiles, &nResult); // ignore return value. 3109 UserExperienceOnExecuteFilesInUse(pContext->pUX, pContext->pExecutingPackage->sczId, pMessage->msiFilesInUse.cFiles, pMessage->msiFilesInUse.rgwzFiles, fRestartManager ? BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI_RM : BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI, &nResult); // ignore return value.
3110 dwAllowedResults = fRestartManager ? BURN_MB_MSI_RM_FILES_IN_USE : BURN_MB_MSI_FILES_IN_USE;
3103 break; 3111 break;
3104 } 3112 }
3105 3113
3106 nResult = UserExperienceCheckExecuteResult(pContext->pUX, pContext->fRollback, pMessage->dwAllowedResults, nResult); 3114 nResult = UserExperienceCheckExecuteResult(pContext->pUX, pContext->fRollback, dwAllowedResults, nResult);
3107 return nResult; 3115 return nResult;
3108} 3116}
3109 3117
diff --git a/src/burn/engine/apply.h b/src/burn/engine/apply.h
index 45270f92..1717a71a 100644
--- a/src/burn/engine/apply.h
+++ b/src/burn/engine/apply.h
@@ -12,7 +12,7 @@ enum GENERIC_EXECUTE_MESSAGE_TYPE
12 GENERIC_EXECUTE_MESSAGE_NONE, 12 GENERIC_EXECUTE_MESSAGE_NONE,
13 GENERIC_EXECUTE_MESSAGE_ERROR, 13 GENERIC_EXECUTE_MESSAGE_ERROR,
14 GENERIC_EXECUTE_MESSAGE_PROGRESS, 14 GENERIC_EXECUTE_MESSAGE_PROGRESS,
15 GENERIC_EXECUTE_MESSAGE_FILES_IN_USE, 15 GENERIC_EXECUTE_MESSAGE_NETFX_FILES_IN_USE,
16}; 16};
17 17
18typedef struct _APPLY_AUTHENTICATION_REQUIRED_DATA 18typedef struct _APPLY_AUTHENTICATION_REQUIRED_DATA
@@ -25,7 +25,7 @@ typedef struct _APPLY_AUTHENTICATION_REQUIRED_DATA
25typedef struct _GENERIC_EXECUTE_MESSAGE 25typedef struct _GENERIC_EXECUTE_MESSAGE
26{ 26{
27 GENERIC_EXECUTE_MESSAGE_TYPE type; 27 GENERIC_EXECUTE_MESSAGE_TYPE type;
28 DWORD dwAllowedResults; 28 DWORD dwUIHint;
29 29
30 union 30 union
31 { 31 {
diff --git a/src/burn/engine/detect.cpp b/src/burn/engine/detect.cpp
index 5f68a240..4eda240e 100644
--- a/src/burn/engine/detect.cpp
+++ b/src/burn/engine/detect.cpp
@@ -306,8 +306,8 @@ static HRESULT WINAPI AuthenticationRequired(
306 hr = StrAllocFromError(&sczError, HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED), NULL); 306 hr = StrAllocFromError(&sczError, HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED), NULL);
307 ExitOnFailure(hr, "Failed to allocation error string."); 307 ExitOnFailure(hr, "Failed to allocation error string.");
308 308
309 UserExperienceOnError(pAuthenticationData->pUX, errorType, pAuthenticationData->wzPackageOrContainerId, ERROR_ACCESS_DENIED, sczError, MB_RETRYTRYAGAIN, 0, NULL, &nResult); // ignore return value. 309 UserExperienceOnError(pAuthenticationData->pUX, errorType, pAuthenticationData->wzPackageOrContainerId, ERROR_ACCESS_DENIED, sczError, MB_RETRYCANCEL, 0, NULL, &nResult); // ignore return value.
310 nResult = UserExperienceCheckExecuteResult(pAuthenticationData->pUX, FALSE, MB_RETRYTRYAGAIN, nResult); 310 nResult = UserExperienceCheckExecuteResult(pAuthenticationData->pUX, FALSE, BURN_MB_RETRYTRYAGAIN, nResult);
311 if (IDTRYAGAIN == nResult && pAuthenticationData->pUX->hwndDetect) 311 if (IDTRYAGAIN == nResult && pAuthenticationData->pUX->hwndDetect)
312 { 312 {
313 er = ::InternetErrorDlg(pAuthenticationData->pUX->hwndDetect, hUrl, ERROR_INTERNET_INCORRECT_PASSWORD, FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA, NULL); 313 er = ::InternetErrorDlg(pAuthenticationData->pUX->hwndDetect, hUrl, ERROR_INTERNET_INCORRECT_PASSWORD, FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA, NULL);
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp
index 12c9f296..6c4a775f 100644
--- a/src/burn/engine/elevation.cpp
+++ b/src/burn/engine/elevation.cpp
@@ -42,7 +42,8 @@ typedef enum _BURN_ELEVATION_MESSAGE_TYPE
42 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS, 42 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS,
43 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR, 43 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR,
44 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE, 44 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE,
45 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_FILES_IN_USE, 45 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_FILES_IN_USE,
46 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_NETFX_FILES_IN_USE,
46 BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE_PROCESSID, 47 BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE_PROCESSID,
47 BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE, 48 BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE,
48} BURN_ELEVATION_MESSAGE_TYPE; 49} BURN_ELEVATION_MESSAGE_TYPE;
@@ -1618,7 +1619,7 @@ static HRESULT ProcessGenericExecuteMessages(
1618 LPWSTR* rgwzFiles = NULL; 1619 LPWSTR* rgwzFiles = NULL;
1619 GENERIC_EXECUTE_MESSAGE message = { }; 1620 GENERIC_EXECUTE_MESSAGE message = { };
1620 1621
1621 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.dwAllowedResults); 1622 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.dwUIHint);
1622 ExitOnFailure(hr, "Failed to allowed results."); 1623 ExitOnFailure(hr, "Failed to allowed results.");
1623 1624
1624 // Process the message. 1625 // Process the message.
@@ -1645,8 +1646,8 @@ static HRESULT ProcessGenericExecuteMessages(
1645 message.error.wzMessage = sczMessage; 1646 message.error.wzMessage = sczMessage;
1646 break; 1647 break;
1647 1648
1648 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_FILES_IN_USE: 1649 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_NETFX_FILES_IN_USE:
1649 message.type = GENERIC_EXECUTE_MESSAGE_FILES_IN_USE; 1650 message.type = GENERIC_EXECUTE_MESSAGE_NETFX_FILES_IN_USE;
1650 1651
1651 // read message parameters 1652 // read message parameters
1652 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &cFiles); 1653 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &cFiles);
@@ -1701,6 +1702,7 @@ static HRESULT ProcessMsiPackageMessages(
1701 LPWSTR* rgwzMsiData = NULL; 1702 LPWSTR* rgwzMsiData = NULL;
1702 BURN_ELEVATION_MSI_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_MSI_MESSAGE_CONTEXT*>(pvContext); 1703 BURN_ELEVATION_MSI_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_MSI_MESSAGE_CONTEXT*>(pvContext);
1703 LPWSTR sczMessage = NULL; 1704 LPWSTR sczMessage = NULL;
1705 BOOL fRestartManager = FALSE;
1704 1706
1705 // Read MSI extended message data. 1707 // Read MSI extended message data.
1706 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &cMsiData); 1708 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &cMsiData);
@@ -1721,7 +1723,7 @@ static HRESULT ProcessMsiPackageMessages(
1721 message.rgwzData = (LPCWSTR*)rgwzMsiData; 1723 message.rgwzData = (LPCWSTR*)rgwzMsiData;
1722 } 1724 }
1723 1725
1724 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.dwAllowedResults); 1726 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.dwUIHint);
1725 ExitOnFailure(hr, "Failed to read UI flags."); 1727 ExitOnFailure(hr, "Failed to read UI flags.");
1726 1728
1727 // Process the rest of the message. 1729 // Process the rest of the message.
@@ -1759,8 +1761,11 @@ static HRESULT ProcessMsiPackageMessages(
1759 message.msiMessage.wzMessage = sczMessage; 1761 message.msiMessage.wzMessage = sczMessage;
1760 break; 1762 break;
1761 1763
1762 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_FILES_IN_USE: 1764 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_FILES_IN_USE:
1763 message.type = WIU_MSI_EXECUTE_MESSAGE_MSI_FILES_IN_USE; 1765 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, (DWORD*)&fRestartManager);
1766 ExitOnFailure(hr, "Failed to read fRestartManager.");
1767
1768 message.type = fRestartManager ? WIU_MSI_EXECUTE_MESSAGE_MSI_RM_FILES_IN_USE : WIU_MSI_EXECUTE_MESSAGE_MSI_FILES_IN_USE;
1764 message.msiFilesInUse.cFiles = cMsiData; 1769 message.msiFilesInUse.cFiles = cMsiData;
1765 message.msiFilesInUse.rgwzFiles = (LPCWSTR*)rgwzMsiData; 1770 message.msiFilesInUse.rgwzFiles = (LPCWSTR*)rgwzMsiData;
1766 break; 1771 break;
@@ -3006,7 +3011,7 @@ static int GenericExecuteMessageHandler(
3006 SIZE_T cbData = 0; 3011 SIZE_T cbData = 0;
3007 DWORD dwMessage = 0; 3012 DWORD dwMessage = 0;
3008 3013
3009 hr = BuffWriteNumber(&pbData, &cbData, pMessage->dwAllowedResults); 3014 hr = BuffWriteNumber(&pbData, &cbData, pMessage->dwUIHint);
3010 ExitOnFailure(hr, "Failed to write UI flags."); 3015 ExitOnFailure(hr, "Failed to write UI flags.");
3011 3016
3012 switch(pMessage->type) 3017 switch(pMessage->type)
@@ -3030,7 +3035,7 @@ static int GenericExecuteMessageHandler(
3030 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR; 3035 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR;
3031 break; 3036 break;
3032 3037
3033 case GENERIC_EXECUTE_MESSAGE_FILES_IN_USE: 3038 case GENERIC_EXECUTE_MESSAGE_NETFX_FILES_IN_USE:
3034 hr = BuffWriteNumber(&pbData, &cbData, pMessage->filesInUse.cFiles); 3039 hr = BuffWriteNumber(&pbData, &cbData, pMessage->filesInUse.cFiles);
3035 ExitOnFailure(hr, "Failed to count of files in use to message buffer."); 3040 ExitOnFailure(hr, "Failed to count of files in use to message buffer.");
3036 3041
@@ -3040,7 +3045,7 @@ static int GenericExecuteMessageHandler(
3040 ExitOnFailure(hr, "Failed to write file in use to message buffer."); 3045 ExitOnFailure(hr, "Failed to write file in use to message buffer.");
3041 } 3046 }
3042 3047
3043 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_FILES_IN_USE; 3048 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_NETFX_FILES_IN_USE;
3044 break; 3049 break;
3045 } 3050 }
3046 3051
@@ -3065,6 +3070,7 @@ static int MsiExecuteMessageHandler(
3065 BYTE* pbData = NULL; 3070 BYTE* pbData = NULL;
3066 SIZE_T cbData = 0; 3071 SIZE_T cbData = 0;
3067 DWORD dwMessage = 0; 3072 DWORD dwMessage = 0;
3073 BOOL fRestartManager = FALSE;
3068 3074
3069 // Always send any extra data via the struct first. 3075 // Always send any extra data via the struct first.
3070 hr = BuffWriteNumber(&pbData, &cbData, pMessage->cData); 3076 hr = BuffWriteNumber(&pbData, &cbData, pMessage->cData);
@@ -3076,7 +3082,7 @@ static int MsiExecuteMessageHandler(
3076 ExitOnFailure(hr, "Failed to write MSI data to message buffer."); 3082 ExitOnFailure(hr, "Failed to write MSI data to message buffer.");
3077 } 3083 }
3078 3084
3079 hr = BuffWriteNumber(&pbData, &cbData, pMessage->dwAllowedResults); 3085 hr = BuffWriteNumber(&pbData, &cbData, pMessage->dwUIHint);
3080 ExitOnFailure(hr, "Failed to write UI flags."); 3086 ExitOnFailure(hr, "Failed to write UI flags.");
3081 3087
3082 switch (pMessage->type) 3088 switch (pMessage->type)
@@ -3114,11 +3120,15 @@ static int MsiExecuteMessageHandler(
3114 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE; 3120 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE;
3115 break; 3121 break;
3116 3122
3123 case WIU_MSI_EXECUTE_MESSAGE_MSI_RM_FILES_IN_USE:
3124 fRestartManager = TRUE;
3125 __fallthrough;
3117 case WIU_MSI_EXECUTE_MESSAGE_MSI_FILES_IN_USE: 3126 case WIU_MSI_EXECUTE_MESSAGE_MSI_FILES_IN_USE:
3118 // NOTE: we do not serialize other message data here because all the "files in use" are in the data above. 3127 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fRestartManager);
3128 ExitOnFailure(hr, "Failed to write fRestartManager to message buffer.");
3119 3129
3120 // set message id 3130 // set message id
3121 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_FILES_IN_USE; 3131 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_FILES_IN_USE;
3122 break; 3132 break;
3123 3133
3124 default: 3134 default:
diff --git a/src/burn/engine/embedded.cpp b/src/burn/engine/embedded.cpp
index 03898ebd..1c295d59 100644
--- a/src/burn/engine/embedded.cpp
+++ b/src/burn/engine/embedded.cpp
@@ -161,7 +161,7 @@ static HRESULT OnEmbeddedErrorMessage(
161 161
162 message.error.wzMessage = sczMessage; 162 message.error.wzMessage = sczMessage;
163 163
164 hr = BuffReadNumber(pbData, cbData, &iData, &message.dwAllowedResults); 164 hr = BuffReadNumber(pbData, cbData, &iData, &message.dwUIHint);
165 ExitOnFailure(hr, "Failed to read UI hint from buffer."); 165 ExitOnFailure(hr, "Failed to read UI hint from buffer.");
166 166
167 *pdwResult = (DWORD)pfnMessageHandler(&message, pvContext); 167 *pdwResult = (DWORD)pfnMessageHandler(&message, pvContext);
@@ -185,7 +185,7 @@ static HRESULT OnEmbeddedProgress(
185 GENERIC_EXECUTE_MESSAGE message = { }; 185 GENERIC_EXECUTE_MESSAGE message = { };
186 186
187 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; 187 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS;
188 message.dwAllowedResults = MB_OKCANCEL; 188 message.dwUIHint = MB_OKCANCEL;
189 189
190 hr = BuffReadNumber(pbData, cbData, &iData, &message.progress.dwPercentage); 190 hr = BuffReadNumber(pbData, cbData, &iData, &message.progress.dwPercentage);
191 ExitOnFailure(hr, "Failed to read progress from buffer."); 191 ExitOnFailure(hr, "Failed to read progress from buffer.");
diff --git a/src/burn/engine/exeengine.cpp b/src/burn/engine/exeengine.cpp
index 67da3bdd..b728f599 100644
--- a/src/burn/engine/exeengine.cpp
+++ b/src/burn/engine/exeengine.cpp
@@ -533,7 +533,7 @@ extern "C" HRESULT ExeEngineExecutePackage(
533 do 533 do
534 { 534 {
535 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; 535 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS;
536 message.dwAllowedResults = MB_OKCANCEL; 536 message.dwUIHint = MB_OKCANCEL;
537 message.progress.dwPercentage = 50; 537 message.progress.dwPercentage = 50;
538 nResult = pfnGenericMessageHandler(&message, pvContext); 538 nResult = pfnGenericMessageHandler(&message, pvContext);
539 hr = (IDOK == nResult || IDNOACTION == nResult) ? S_OK : IDCANCEL == nResult ? HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) : HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE); 539 hr = (IDOK == nResult || IDNOACTION == nResult) ? S_OK : IDCANCEL == nResult ? HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) : HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE);
diff --git a/src/burn/engine/msuengine.cpp b/src/burn/engine/msuengine.cpp
index 1ce2dd11..693bb64b 100644
--- a/src/burn/engine/msuengine.cpp
+++ b/src/burn/engine/msuengine.cpp
@@ -339,7 +339,7 @@ extern "C" HRESULT MsuEngineExecutePackage(
339 do 339 do
340 { 340 {
341 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; 341 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS;
342 message.dwAllowedResults = MB_OKCANCEL; 342 message.dwUIHint = MB_OKCANCEL;
343 message.progress.dwPercentage = 50; 343 message.progress.dwPercentage = 50;
344 nResult = pfnGenericMessageHandler(&message, pvContext); 344 nResult = pfnGenericMessageHandler(&message, pvContext);
345 hr = (IDOK == nResult || IDNOACTION == nResult) ? S_OK : IDCANCEL == nResult ? HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) : HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE); 345 hr = (IDOK == nResult || IDNOACTION == nResult) ? S_OK : IDCANCEL == nResult ? HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) : HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE);
diff --git a/src/burn/engine/netfxchainer.cpp b/src/burn/engine/netfxchainer.cpp
index 4e7a7720..af4f03f5 100644
--- a/src/burn/engine/netfxchainer.cpp
+++ b/src/burn/engine/netfxchainer.cpp
@@ -233,8 +233,8 @@ static HRESULT OnNetFxFilesInUse(
233 } 233 }
234 234
235 // send message 235 // send message
236 message.type = GENERIC_EXECUTE_MESSAGE_FILES_IN_USE; 236 message.type = GENERIC_EXECUTE_MESSAGE_NETFX_FILES_IN_USE;
237 message.dwAllowedResults = MB_ABORTRETRYIGNORE; 237 message.dwUIHint = MB_ABORTRETRYIGNORE;
238 message.filesInUse.cFiles = cFiles; 238 message.filesInUse.cFiles = cFiles;
239 message.filesInUse.rgwzFiles = (LPCWSTR*)rgwzFiles; 239 message.filesInUse.rgwzFiles = (LPCWSTR*)rgwzFiles;
240 dwResponse = (DWORD)pfnMessageHandler(&message, pvContext); 240 dwResponse = (DWORD)pfnMessageHandler(&message, pvContext);
@@ -259,7 +259,7 @@ static HRESULT OnNetFxProgress(
259 259
260 // send message 260 // send message
261 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; 261 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS;
262 message.dwAllowedResults = MB_OKCANCEL; 262 message.dwUIHint = MB_OKCANCEL;
263 message.progress.dwPercentage = 100 * (DWORD)bProgress / BYTE_MAX; 263 message.progress.dwPercentage = 100 * (DWORD)bProgress / BYTE_MAX;
264 dwResponse = (DWORD)pfnMessageHandler(&message, pvContext); 264 dwResponse = (DWORD)pfnMessageHandler(&message, pvContext);
265 265
@@ -283,7 +283,7 @@ static HRESULT OnNetFxError(
283 283
284 // send message 284 // send message
285 message.type = GENERIC_EXECUTE_MESSAGE_ERROR; 285 message.type = GENERIC_EXECUTE_MESSAGE_ERROR;
286 message.dwAllowedResults = MB_OK; 286 message.dwUIHint = MB_OK;
287 message.error.dwErrorCode = hrError; 287 message.error.dwErrorCode = hrError;
288 message.error.wzMessage = NULL; 288 message.error.wzMessage = NULL;
289 dwResponse = (DWORD)pfnMessageHandler(&message, pvContext); 289 dwResponse = (DWORD)pfnMessageHandler(&message, pvContext);
diff --git a/src/burn/engine/userexperience.cpp b/src/burn/engine/userexperience.cpp
index a6d670ea..7cc6f049 100644
--- a/src/burn/engine/userexperience.cpp
+++ b/src/burn/engine/userexperience.cpp
@@ -1494,6 +1494,7 @@ EXTERN_C BAAPI UserExperienceOnExecuteFilesInUse(
1494 __in_z LPCWSTR wzPackageId, 1494 __in_z LPCWSTR wzPackageId,
1495 __in DWORD cFiles, 1495 __in DWORD cFiles,
1496 __in_ecount_z_opt(cFiles) LPCWSTR* rgwzFiles, 1496 __in_ecount_z_opt(cFiles) LPCWSTR* rgwzFiles,
1497 __in BOOTSTRAPPER_FILES_IN_USE_TYPE source,
1497 __inout int* pnResult 1498 __inout int* pnResult
1498 ) 1499 )
1499{ 1500{
@@ -1506,6 +1507,7 @@ EXTERN_C BAAPI UserExperienceOnExecuteFilesInUse(
1506 args.cFiles = cFiles; 1507 args.cFiles = cFiles;
1507 args.rgwzFiles = rgwzFiles; 1508 args.rgwzFiles = rgwzFiles;
1508 args.nRecommendation = *pnResult; 1509 args.nRecommendation = *pnResult;
1510 args.source = source;
1509 1511
1510 results.cbSize = sizeof(results); 1512 results.cbSize = sizeof(results);
1511 results.nResult = *pnResult; 1513 results.nResult = *pnResult;
@@ -2492,13 +2494,12 @@ static int FilterResult(
2492 __in int nResult 2494 __in int nResult
2493 ) 2495 )
2494{ 2496{
2495 DWORD dwFilteredAllowedResults = dwAllowedResults & MB_TYPEMASK;
2496 if (IDNOACTION == nResult || IDERROR == nResult) // do nothing and errors pass through. 2497 if (IDNOACTION == nResult || IDERROR == nResult) // do nothing and errors pass through.
2497 { 2498 {
2498 } 2499 }
2499 else 2500 else
2500 { 2501 {
2501 switch (dwFilteredAllowedResults) 2502 switch (dwAllowedResults)
2502 { 2503 {
2503 case MB_OK: 2504 case MB_OK:
2504 nResult = IDOK; 2505 nResult = IDOK;
@@ -2606,7 +2607,28 @@ static int FilterResult(
2606 } 2607 }
2607 break; 2608 break;
2608 2609
2609 case WIU_MB_OKIGNORECANCELRETRY: // custom Windows Installer utility return code. 2610 case BURN_MB_MSI_FILES_IN_USE:
2611 // https://docs.microsoft.com/en-us/windows/win32/msi/installvalidate-action
2612 if (IDRETRY == nResult || IDTRYAGAIN == nResult)
2613 {
2614 nResult = IDRETRY;
2615 }
2616 else if (IDCANCEL == nResult || IDABORT == nResult)
2617 {
2618 nResult = IDCANCEL;
2619 }
2620 else if (IDCONTINUE == nResult || IDIGNORE == nResult)
2621 {
2622 nResult = IDIGNORE;
2623 }
2624 else
2625 {
2626 nResult = IDNOACTION;
2627 }
2628 break;
2629
2630 case BURN_MB_MSI_RM_FILES_IN_USE:
2631 // https://docs.microsoft.com/en-us/windows/win32/msi/using-restart-manager-with-an-external-ui-
2610 if (IDOK == nResult || IDYES == nResult) 2632 if (IDOK == nResult || IDYES == nResult)
2611 { 2633 {
2612 nResult = IDOK; 2634 nResult = IDOK;
@@ -2615,11 +2637,15 @@ static int FilterResult(
2615 { 2637 {
2616 nResult = IDIGNORE; 2638 nResult = IDIGNORE;
2617 } 2639 }
2640 else if (IDNO == nResult)
2641 {
2642 nResult = IDNO;
2643 }
2618 else if (IDCANCEL == nResult || IDABORT == nResult) 2644 else if (IDCANCEL == nResult || IDABORT == nResult)
2619 { 2645 {
2620 nResult = IDCANCEL; 2646 nResult = IDCANCEL;
2621 } 2647 }
2622 else if (IDRETRY == nResult || IDTRYAGAIN == nResult || IDNO == nResult) 2648 else if (IDRETRY == nResult || IDTRYAGAIN == nResult)
2623 { 2649 {
2624 nResult = IDRETRY; 2650 nResult = IDRETRY;
2625 } 2651 }
@@ -2629,13 +2655,33 @@ static int FilterResult(
2629 } 2655 }
2630 break; 2656 break;
2631 2657
2632 case MB_RETRYTRYAGAIN: // custom return code. 2658 case BURN_MB_RETRYTRYAGAIN: // custom return code.
2633 if (IDRETRY != nResult && IDTRYAGAIN != nResult) 2659 if (IDRETRY != nResult && IDTRYAGAIN != nResult)
2634 { 2660 {
2635 nResult = IDNOACTION; 2661 nResult = IDNOACTION;
2636 } 2662 }
2637 break; 2663 break;
2638 2664
2665 case BURN_MB_NETFX_FILES_IN_USE:
2666 // https://docs.microsoft.com/en-us/dotnet/framework/deployment/how-to-get-progress-from-the-dotnet-installer
2667 if (IDOK == nResult || IDYES == nResult)
2668 {
2669 nResult = IDYES;
2670 }
2671 else if (IDRETRY == nResult || IDTRYAGAIN == nResult)
2672 {
2673 nResult = IDRETRY;
2674 }
2675 else if (IDCANCEL == nResult || IDABORT == nResult)
2676 {
2677 nResult = IDCANCEL;
2678 }
2679 else
2680 {
2681 nResult = IDNO;
2682 }
2683 break;
2684
2639 default: 2685 default:
2640 AssertSz(FALSE, "Unknown allowed results."); 2686 AssertSz(FALSE, "Unknown allowed results.");
2641 break; 2687 break;
diff --git a/src/burn/engine/userexperience.h b/src/burn/engine/userexperience.h
index f7ac962c..75723afa 100644
--- a/src/burn/engine/userexperience.h
+++ b/src/burn/engine/userexperience.h
@@ -10,7 +10,10 @@ extern "C" {
10 10
11// constants 11// constants
12 12
13const DWORD MB_RETRYTRYAGAIN = 0xF; 13const DWORD BURN_MB_RETRYTRYAGAIN = 0x10;
14const DWORD BURN_MB_MSI_FILES_IN_USE = 0x11;
15const DWORD BURN_MB_MSI_RM_FILES_IN_USE = 0x12;
16const DWORD BURN_MB_NETFX_FILES_IN_USE = 0x13;
14 17
15 18
16// structs 19// structs
@@ -356,6 +359,7 @@ BAAPI UserExperienceOnExecuteFilesInUse(
356 __in_z LPCWSTR wzPackageId, 359 __in_z LPCWSTR wzPackageId,
357 __in DWORD cFiles, 360 __in DWORD cFiles,
358 __in_ecount_z_opt(cFiles) LPCWSTR* rgwzFiles, 361 __in_ecount_z_opt(cFiles) LPCWSTR* rgwzFiles,
362 __in BOOTSTRAPPER_FILES_IN_USE_TYPE source,
359 __inout int* pnResult 363 __inout int* pnResult
360 ); 364 );
361BAAPI UserExperienceOnExecuteMsiMessage( 365BAAPI UserExperienceOnExecuteMsiMessage(