diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2021-07-02 10:18:08 -0500 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2021-07-02 12:50:09 -0500 |
| commit | f43d176f95601ff7524e06247166d4f3b6e61c05 (patch) | |
| tree | 2e3580ca60c85e1d07a0ab4a2b1279d25fd41f6c /src/ext | |
| parent | 9bdf3730cd43e1af8a4ea9be6cf2fba77fcff2d2 (diff) | |
| download | wix-f43d176f95601ff7524e06247166d4f3b6e61c05.tar.gz wix-f43d176f95601ff7524e06247166d4f3b6e61c05.tar.bz2 wix-f43d176f95601ff7524e06247166d4f3b6e61c05.zip | |
Make the BA responsible for parsing restart prompt behavior.
Fixes #4975
Diffstat (limited to 'src/ext')
| -rw-r--r-- | src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp | 127 | ||||
| -rw-r--r-- | src/ext/Util/be/UtilBundleExtension.cpp | 4 |
2 files changed, 74 insertions, 57 deletions
diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp index 9f0b0082..bbe926f1 100644 --- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp +++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp | |||
| @@ -206,7 +206,7 @@ public: // IBootstrapperApplication | |||
| 206 | m_hUiThread = ::CreateThread(NULL, 0, UiThreadProc, this, 0, &dwUIThreadId); | 206 | m_hUiThread = ::CreateThread(NULL, 0, UiThreadProc, this, 0, &dwUIThreadId); |
| 207 | if (!m_hUiThread) | 207 | if (!m_hUiThread) |
| 208 | { | 208 | { |
| 209 | ExitWithLastError(hr, "Failed to create UI thread."); | 209 | BalExitWithLastError(hr, "Failed to create UI thread."); |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | LExit: | 212 | LExit: |
| @@ -1100,10 +1100,10 @@ public: // IBootstrapperApplication | |||
| 1100 | m_fRestartRequired = BOOTSTRAPPER_APPLY_RESTART_NONE != restart; | 1100 | m_fRestartRequired = BOOTSTRAPPER_APPLY_RESTART_NONE != restart; |
| 1101 | BalSetStringVariable(WIXSTDBA_VARIABLE_RESTART_REQUIRED, m_fRestartRequired ? L"1" : NULL, FALSE); | 1101 | BalSetStringVariable(WIXSTDBA_VARIABLE_RESTART_REQUIRED, m_fRestartRequired ? L"1" : NULL, FALSE); |
| 1102 | 1102 | ||
| 1103 | m_fShouldRestart = m_fRestartRequired && BOOTSTRAPPER_RESTART_NEVER < m_command.restart; | 1103 | m_fShouldRestart = m_fRestartRequired && BAL_INFO_RESTART_NEVER < m_BalInfoCommand.restart; |
| 1104 | 1104 | ||
| 1105 | // Automatically restart if we're not displaying a UI or the command line said to always allow restarts. | 1105 | // Automatically restart if we're not displaying a UI or the command line said to always allow restarts. |
| 1106 | m_fAllowRestart = m_fShouldRestart && (BOOTSTRAPPER_DISPLAY_FULL > m_command.display || BOOTSTRAPPER_RESTART_PROMPT < m_command.restart); | 1106 | m_fAllowRestart = m_fShouldRestart && (BOOTSTRAPPER_DISPLAY_FULL > m_command.display || BAL_INFO_RESTART_PROMPT < m_BalInfoCommand.restart); |
| 1107 | 1107 | ||
| 1108 | if (m_fPrereq) | 1108 | if (m_fPrereq) |
| 1109 | { | 1109 | { |
| @@ -1986,6 +1986,62 @@ private: // privates | |||
| 1986 | m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEPAYLOADEXTRACTPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext); | 1986 | m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEPAYLOADEXTRACTPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext); |
| 1987 | } | 1987 | } |
| 1988 | 1988 | ||
| 1989 | |||
| 1990 | public: //CBalBaseBootstrapperApplication | ||
| 1991 | virtual STDMETHODIMP Initialize( | ||
| 1992 | __in const BOOTSTRAPPER_CREATE_ARGS* pCreateArgs | ||
| 1993 | ) | ||
| 1994 | { | ||
| 1995 | HRESULT hr = S_OK; | ||
| 1996 | LONGLONG llInstalled = 0; | ||
| 1997 | |||
| 1998 | hr = __super::Initialize(pCreateArgs); | ||
| 1999 | BalExitOnFailure(hr, "CBalBaseBootstrapperApplication initialization failed."); | ||
| 2000 | |||
| 2001 | memcpy_s(&m_command, sizeof(m_command), pCreateArgs->pCommand, sizeof(BOOTSTRAPPER_COMMAND)); | ||
| 2002 | memcpy_s(&m_createArgs, sizeof(m_createArgs), pCreateArgs, sizeof(BOOTSTRAPPER_CREATE_ARGS)); | ||
| 2003 | m_createArgs.pCommand = &m_command; | ||
| 2004 | |||
| 2005 | if (m_fPrereq) | ||
| 2006 | { | ||
| 2007 | // Pre-req BA should only show help or do an install (to launch the Managed BA which can then do the right action). | ||
| 2008 | if (BOOTSTRAPPER_ACTION_HELP != m_command.action) | ||
| 2009 | { | ||
| 2010 | m_command.action = BOOTSTRAPPER_ACTION_INSTALL; | ||
| 2011 | } | ||
| 2012 | } | ||
| 2013 | else // maybe modify the action state if the bundle is or is not already installed. | ||
| 2014 | { | ||
| 2015 | hr = BalGetNumericVariable(L"WixBundleInstalled", &llInstalled); | ||
| 2016 | if (SUCCEEDED(hr) && BOOTSTRAPPER_RESUME_TYPE_REBOOT != m_command.resumeType && llInstalled && BOOTSTRAPPER_ACTION_INSTALL == m_command.action) | ||
| 2017 | { | ||
| 2018 | m_command.action = BOOTSTRAPPER_ACTION_MODIFY; | ||
| 2019 | } | ||
| 2020 | else if (!llInstalled && (BOOTSTRAPPER_ACTION_MODIFY == m_command.action || BOOTSTRAPPER_ACTION_REPAIR == m_command.action)) | ||
| 2021 | { | ||
| 2022 | m_command.action = BOOTSTRAPPER_ACTION_INSTALL; | ||
| 2023 | } | ||
| 2024 | } | ||
| 2025 | |||
| 2026 | // When resuming from restart doing some install-like operation, try to find the package that forced the | ||
| 2027 | // restart. We'll use this information during planning. | ||
| 2028 | if (BOOTSTRAPPER_RESUME_TYPE_REBOOT == m_command.resumeType && BOOTSTRAPPER_ACTION_UNINSTALL < m_command.action) | ||
| 2029 | { | ||
| 2030 | // Ensure the forced restart package variable is null when it is an empty string. | ||
| 2031 | hr = BalGetStringVariable(L"WixBundleForcedRestartPackage", &m_sczAfterForcedRestartPackage); | ||
| 2032 | if (FAILED(hr) || !m_sczAfterForcedRestartPackage || !*m_sczAfterForcedRestartPackage) | ||
| 2033 | { | ||
| 2034 | ReleaseNullStr(m_sczAfterForcedRestartPackage); | ||
| 2035 | } | ||
| 2036 | } | ||
| 2037 | |||
| 2038 | hr = S_OK; | ||
| 2039 | |||
| 2040 | LExit: | ||
| 2041 | return hr; | ||
| 2042 | } | ||
| 2043 | |||
| 2044 | private: | ||
| 1989 | // | 2045 | // |
| 1990 | // UiThreadProc - entrypoint for UI thread. | 2046 | // UiThreadProc - entrypoint for UI thread. |
| 1991 | // | 2047 | // |
| @@ -2172,9 +2228,6 @@ private: // privates | |||
| 2172 | LPWSTR* argv = NULL; | 2228 | LPWSTR* argv = NULL; |
| 2173 | BOOL fUnknownArg = FALSE; | 2229 | BOOL fUnknownArg = FALSE; |
| 2174 | 2230 | ||
| 2175 | hr = BalInfoParseCommandLine(&m_BalInfoCommand, m_command.wzCommandLine); | ||
| 2176 | BalExitOnFailure(hr, "Failed to parse command line with balutil."); | ||
| 2177 | |||
| 2178 | argc = m_BalInfoCommand.cUnknownArgs; | 2231 | argc = m_BalInfoCommand.cUnknownArgs; |
| 2179 | argv = m_BalInfoCommand.rgUnknownArgs; | 2232 | argv = m_BalInfoCommand.rgUnknownArgs; |
| 2180 | 2233 | ||
| @@ -3139,7 +3192,7 @@ private: // privates | |||
| 3139 | BOOL fLaunchTargetExists = FALSE; | 3192 | BOOL fLaunchTargetExists = FALSE; |
| 3140 | if (m_fShouldRestart) | 3193 | if (m_fShouldRestart) |
| 3141 | { | 3194 | { |
| 3142 | if (BOOTSTRAPPER_RESTART_PROMPT == m_command.restart) | 3195 | if (BAL_INFO_RESTART_PROMPT == m_BalInfoCommand.restart) |
| 3143 | { | 3196 | { |
| 3144 | fEnableRestartButton = TRUE; | 3197 | fEnableRestartButton = TRUE; |
| 3145 | } | 3198 | } |
| @@ -3240,7 +3293,7 @@ private: // privates | |||
| 3240 | 3293 | ||
| 3241 | if (m_fShouldRestart) | 3294 | if (m_fShouldRestart) |
| 3242 | { | 3295 | { |
| 3243 | if (BOOTSTRAPPER_RESTART_PROMPT == m_command.restart) | 3296 | if (BAL_INFO_RESTART_PROMPT == m_BalInfoCommand.restart) |
| 3244 | { | 3297 | { |
| 3245 | fEnableRestartButton = TRUE; | 3298 | fEnableRestartButton = TRUE; |
| 3246 | } | 3299 | } |
| @@ -3832,57 +3885,20 @@ public: | |||
| 3832 | __in HMODULE hModule, | 3885 | __in HMODULE hModule, |
| 3833 | __in BOOL fPrereq, | 3886 | __in BOOL fPrereq, |
| 3834 | __in HRESULT hrHostInitialization, | 3887 | __in HRESULT hrHostInitialization, |
| 3835 | __in IBootstrapperEngine* pEngine, | 3888 | __in IBootstrapperEngine* pEngine |
| 3836 | __in const BOOTSTRAPPER_CREATE_ARGS* pArgs | 3889 | ) : CBalBaseBootstrapperApplication(pEngine, 3, 3000) |
| 3837 | ) : CBalBaseBootstrapperApplication(pEngine, pArgs, 3, 3000) | ||
| 3838 | { | 3890 | { |
| 3839 | m_hModule = hModule; | 3891 | m_hModule = hModule; |
| 3840 | memcpy_s(&m_command, sizeof(m_command), pArgs->pCommand, sizeof(BOOTSTRAPPER_COMMAND)); | 3892 | m_command = { }; |
| 3841 | memcpy_s(&m_createArgs, sizeof(m_createArgs), pArgs, sizeof(BOOTSTRAPPER_CREATE_ARGS)); | 3893 | m_createArgs = { }; |
| 3842 | m_createArgs.pCommand = &m_command; | ||
| 3843 | |||
| 3844 | if (fPrereq) | ||
| 3845 | { | ||
| 3846 | // Pre-req BA should only show help or do an install (to launch the Managed BA which can then do the right action). | ||
| 3847 | if (BOOTSTRAPPER_ACTION_HELP != m_command.action) | ||
| 3848 | { | ||
| 3849 | m_command.action = BOOTSTRAPPER_ACTION_INSTALL; | ||
| 3850 | } | ||
| 3851 | } | ||
| 3852 | else // maybe modify the action state if the bundle is or is not already installed. | ||
| 3853 | { | ||
| 3854 | LONGLONG llInstalled = 0; | ||
| 3855 | HRESULT hr = BalGetNumericVariable(L"WixBundleInstalled", &llInstalled); | ||
| 3856 | if (SUCCEEDED(hr) && BOOTSTRAPPER_RESUME_TYPE_REBOOT != m_command.resumeType && 0 < llInstalled && BOOTSTRAPPER_ACTION_INSTALL == m_command.action) | ||
| 3857 | { | ||
| 3858 | m_command.action = BOOTSTRAPPER_ACTION_MODIFY; | ||
| 3859 | } | ||
| 3860 | else if (0 == llInstalled && (BOOTSTRAPPER_ACTION_MODIFY == m_command.action || BOOTSTRAPPER_ACTION_REPAIR == m_command.action)) | ||
| 3861 | { | ||
| 3862 | m_command.action = BOOTSTRAPPER_ACTION_INSTALL; | ||
| 3863 | } | ||
| 3864 | } | ||
| 3865 | 3894 | ||
| 3866 | m_plannedAction = BOOTSTRAPPER_ACTION_UNKNOWN; | 3895 | m_plannedAction = BOOTSTRAPPER_ACTION_UNKNOWN; |
| 3867 | 3896 | ||
| 3868 | // When resuming from restart doing some install-like operation, try to find the package that forced the | ||
| 3869 | // restart. We'll use this information during planning. | ||
| 3870 | m_sczAfterForcedRestartPackage = NULL; | 3897 | m_sczAfterForcedRestartPackage = NULL; |
| 3871 | 3898 | ||
| 3872 | if (BOOTSTRAPPER_RESUME_TYPE_REBOOT == m_command.resumeType && BOOTSTRAPPER_ACTION_UNINSTALL < m_command.action) | ||
| 3873 | { | ||
| 3874 | // Ensure the forced restart package variable is null when it is an empty string. | ||
| 3875 | HRESULT hr = BalGetStringVariable(L"WixBundleForcedRestartPackage", &m_sczAfterForcedRestartPackage); | ||
| 3876 | if (FAILED(hr) || !m_sczAfterForcedRestartPackage || !*m_sczAfterForcedRestartPackage) | ||
| 3877 | { | ||
| 3878 | ReleaseNullStr(m_sczAfterForcedRestartPackage); | ||
| 3879 | } | ||
| 3880 | } | ||
| 3881 | |||
| 3882 | m_pWixLoc = NULL; | 3899 | m_pWixLoc = NULL; |
| 3883 | memset(&m_Bundle, 0, sizeof(m_Bundle)); | 3900 | m_Bundle = { }; |
| 3884 | memset(&m_BalInfoCommand, 0, sizeof(m_BalInfoCommand)); | 3901 | m_Conditions = { }; |
| 3885 | memset(&m_Conditions, 0, sizeof(m_Conditions)); | ||
| 3886 | m_sczConfirmCloseMessage = NULL; | 3902 | m_sczConfirmCloseMessage = NULL; |
| 3887 | m_sczFailedMessage = NULL; | 3903 | m_sczFailedMessage = NULL; |
| 3888 | 3904 | ||
| @@ -3947,7 +3963,6 @@ public: | |||
| 3947 | ReleaseStr(m_sczConfirmCloseMessage); | 3963 | ReleaseStr(m_sczConfirmCloseMessage); |
| 3948 | BalConditionsUninitialize(&m_Conditions); | 3964 | BalConditionsUninitialize(&m_Conditions); |
| 3949 | BalInfoUninitialize(&m_Bundle); | 3965 | BalInfoUninitialize(&m_Bundle); |
| 3950 | BalInfoUninitializeCommandLine(&m_BalInfoCommand); | ||
| 3951 | LocFree(m_pWixLoc); | 3966 | LocFree(m_pWixLoc); |
| 3952 | 3967 | ||
| 3953 | ReleaseStr(m_sczLanguage); | 3968 | ReleaseStr(m_sczLanguage); |
| @@ -3980,7 +3995,6 @@ private: | |||
| 3980 | 3995 | ||
| 3981 | WIX_LOCALIZATION* m_pWixLoc; | 3996 | WIX_LOCALIZATION* m_pWixLoc; |
| 3982 | BAL_INFO_BUNDLE m_Bundle; | 3997 | BAL_INFO_BUNDLE m_Bundle; |
| 3983 | BAL_INFO_COMMAND m_BalInfoCommand; | ||
| 3984 | BAL_CONDITIONS m_Conditions; | 3998 | BAL_CONDITIONS m_Conditions; |
| 3985 | LPWSTR m_sczFailedMessage; | 3999 | LPWSTR m_sczFailedMessage; |
| 3986 | LPWSTR m_sczConfirmCloseMessage; | 4000 | LPWSTR m_sczConfirmCloseMessage; |
| @@ -4049,8 +4063,11 @@ HRESULT CreateBootstrapperApplication( | |||
| 4049 | BalExitOnFailure(hr = E_INVALIDARG, "Engine requested Unknown display type."); | 4063 | BalExitOnFailure(hr = E_INVALIDARG, "Engine requested Unknown display type."); |
| 4050 | } | 4064 | } |
| 4051 | 4065 | ||
| 4052 | pApplication = new CWixStandardBootstrapperApplication(hModule, fPrereq, hrHostInitialization, pEngine, pArgs); | 4066 | pApplication = new CWixStandardBootstrapperApplication(hModule, fPrereq, hrHostInitialization, pEngine); |
| 4053 | ExitOnNull(pApplication, hr, E_OUTOFMEMORY, "Failed to create new standard bootstrapper application object."); | 4067 | BalExitOnNull(pApplication, hr, E_OUTOFMEMORY, "Failed to create new standard bootstrapper application object."); |
| 4068 | |||
| 4069 | hr = pApplication->Initialize(pArgs); | ||
| 4070 | ExitOnFailure(hr, "CWixStandardBootstrapperApplication initialization failed."); | ||
| 4054 | 4071 | ||
| 4055 | pResults->pfnBootstrapperApplicationProc = BalBaseBootstrapperApplicationProc; | 4072 | pResults->pfnBootstrapperApplicationProc = BalBaseBootstrapperApplicationProc; |
| 4056 | pResults->pvBootstrapperApplicationProcContext = pApplication; | 4073 | pResults->pvBootstrapperApplicationProcContext = pApplication; |
diff --git a/src/ext/Util/be/UtilBundleExtension.cpp b/src/ext/Util/be/UtilBundleExtension.cpp index 2ac842a5..110599fa 100644 --- a/src/ext/Util/be/UtilBundleExtension.cpp +++ b/src/ext/Util/be/UtilBundleExtension.cpp | |||
| @@ -27,7 +27,7 @@ public: //CBextBaseBundleExtension | |||
| 27 | IXMLDOMDocument* pixdManifest = NULL; | 27 | IXMLDOMDocument* pixdManifest = NULL; |
| 28 | IXMLDOMNode* pixnBundleExtension = NULL; | 28 | IXMLDOMNode* pixnBundleExtension = NULL; |
| 29 | 29 | ||
| 30 | hr = CBextBaseBundleExtension::Initialize(pCreateArgs); | 30 | hr = __super::Initialize(pCreateArgs); |
| 31 | ExitOnFailure(hr, "CBextBaseBundleExtension initialization failed."); | 31 | ExitOnFailure(hr, "CBextBaseBundleExtension initialization failed."); |
| 32 | 32 | ||
| 33 | hr = XmlLoadDocumentFromFile(m_sczBundleExtensionDataPath, &pixdManifest); | 33 | hr = XmlLoadDocumentFromFile(m_sczBundleExtensionDataPath, &pixdManifest); |
| @@ -76,7 +76,7 @@ HRESULT UtilBundleExtensionCreate( | |||
| 76 | ExitOnNull(pExtension, hr, E_OUTOFMEMORY, "Failed to create new CWixUtilBundleExtension."); | 76 | ExitOnNull(pExtension, hr, E_OUTOFMEMORY, "Failed to create new CWixUtilBundleExtension."); |
| 77 | 77 | ||
| 78 | hr = pExtension->Initialize(pArgs); | 78 | hr = pExtension->Initialize(pArgs); |
| 79 | ExitOnFailure(hr, "CWixUtilBundleExtension initialization failed"); | 79 | ExitOnFailure(hr, "CWixUtilBundleExtension initialization failed."); |
| 80 | 80 | ||
| 81 | *ppBundleExtension = pExtension; | 81 | *ppBundleExtension = pExtension; |
| 82 | pExtension = NULL; | 82 | pExtension = NULL; |
