From 60069b189db09521558b99827aee47fe3f81309b Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Sat, 29 Dec 2018 22:24:05 -0600 Subject: Import code from old v4 repo --- src/balutil/BalBootstrapperEngine.cpp | 720 +++++++++++++++++ src/balutil/balcondition.cpp | 124 +++ src/balutil/balinfo.cpp | 288 +++++++ src/balutil/balretry.cpp | 191 +++++ src/balutil/balutil.cpp | 382 +++++++++ src/balutil/inc/BAFunctions.h | 130 +++ src/balutil/inc/BalBaseBAFunctions.h | 700 ++++++++++++++++ src/balutil/inc/BalBaseBAFunctionsProc.h | 114 +++ src/balutil/inc/BalBaseBootstrapperApplication.h | 900 +++++++++++++++++++++ .../inc/BalBaseBootstrapperApplicationProc.h | 698 ++++++++++++++++ src/balutil/inc/BalBootstrapperEngine.h | 17 + src/balutil/inc/IBAFunctions.h | 34 + src/balutil/inc/balcondition.h | 58 ++ src/balutil/inc/balinfo.h | 107 +++ src/balutil/inc/balretry.h | 65 ++ src/balutil/inc/balutil.h | 165 ++++ src/balutil/precomp.h | 31 + 17 files changed, 4724 insertions(+) create mode 100644 src/balutil/BalBootstrapperEngine.cpp create mode 100644 src/balutil/balcondition.cpp create mode 100644 src/balutil/balinfo.cpp create mode 100644 src/balutil/balretry.cpp create mode 100644 src/balutil/balutil.cpp create mode 100644 src/balutil/inc/BAFunctions.h create mode 100644 src/balutil/inc/BalBaseBAFunctions.h create mode 100644 src/balutil/inc/BalBaseBAFunctionsProc.h create mode 100644 src/balutil/inc/BalBaseBootstrapperApplication.h create mode 100644 src/balutil/inc/BalBaseBootstrapperApplicationProc.h create mode 100644 src/balutil/inc/BalBootstrapperEngine.h create mode 100644 src/balutil/inc/IBAFunctions.h create mode 100644 src/balutil/inc/balcondition.h create mode 100644 src/balutil/inc/balinfo.h create mode 100644 src/balutil/inc/balretry.h create mode 100644 src/balutil/inc/balutil.h create mode 100644 src/balutil/precomp.h (limited to 'src/balutil') diff --git a/src/balutil/BalBootstrapperEngine.cpp b/src/balutil/BalBootstrapperEngine.cpp new file mode 100644 index 00000000..945940c5 --- /dev/null +++ b/src/balutil/BalBootstrapperEngine.cpp @@ -0,0 +1,720 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" + + +class CBalBootstrapperEngine : public IBootstrapperEngine, public IMarshal +{ +public: // IUnknown + virtual STDMETHODIMP QueryInterface( + __in REFIID riid, + __out LPVOID *ppvObject + ) + { + if (!ppvObject) + { + return E_INVALIDARG; + } + + *ppvObject = NULL; + + if (::IsEqualIID(__uuidof(IBootstrapperEngine), riid)) + { + *ppvObject = static_cast(this); + } + else if (::IsEqualIID(IID_IMarshal, riid)) + { + *ppvObject = static_cast(this); + } + else if (::IsEqualIID(IID_IUnknown, riid)) + { + *ppvObject = reinterpret_cast(this); + } + else // no interface for requested iid + { + return E_NOINTERFACE; + } + + AddRef(); + return S_OK; + } + + virtual STDMETHODIMP_(ULONG) AddRef() + { + return ::InterlockedIncrement(&this->m_cReferences); + } + + virtual STDMETHODIMP_(ULONG) Release() + { + long l = ::InterlockedDecrement(&this->m_cReferences); + if (0 < l) + { + return l; + } + + delete this; + return 0; + } + +public: // IBootstrapperEngine + virtual STDMETHODIMP GetPackageCount( + __out DWORD* pcPackages + ) + { + HRESULT hr = S_OK; + BAENGINE_GETPACKAGECOUNT_ARGS args = { }; + BAENGINE_GETPACKAGECOUNT_RESULTS results = { }; + + ExitOnNull(pcPackages, hr, E_INVALIDARG, "pcPackages is required"); + + args.cbSize = sizeof(args); + + results.cbSize = sizeof(results); + + hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_GETPACKAGECOUNT, &args, &results, m_pvBAEngineProcContext); + + *pcPackages = results.cPackages; + + LExit: + return hr; + } + + virtual STDMETHODIMP GetVariableNumeric( + __in_z LPCWSTR wzVariable, + __out LONGLONG* pllValue + ) + { + HRESULT hr = S_OK; + BAENGINE_GETVARIABLENUMERIC_ARGS args = { }; + BAENGINE_GETVARIABLENUMERIC_RESULTS results = { }; + + ExitOnNull(pllValue, hr, E_INVALIDARG, "pllValue is required"); + + args.cbSize = sizeof(args); + args.wzVariable = wzVariable; + + results.cbSize = sizeof(results); + + hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_GETVARIABLENUMERIC, &args, &results, m_pvBAEngineProcContext); + + *pllValue = results.llValue; + + LExit: + SecureZeroMemory(&results, sizeof(results)); + return hr; + } + + virtual STDMETHODIMP GetVariableString( + __in_z LPCWSTR wzVariable, + __out_ecount_opt(*pcchValue) LPWSTR wzValue, + __inout DWORD* pcchValue + ) + { + HRESULT hr = S_OK; + BAENGINE_GETVARIABLESTRING_ARGS args = { }; + BAENGINE_GETVARIABLESTRING_RESULTS results = { }; + + ExitOnNull(pcchValue, hr, E_INVALIDARG, "pcchValue is required"); + + args.cbSize = sizeof(args); + args.wzVariable = wzVariable; + + results.cbSize = sizeof(results); + results.wzValue = wzValue; + results.cchValue = *pcchValue; + + hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_GETVARIABLESTRING, &args, &results, m_pvBAEngineProcContext); + + *pcchValue = results.cchValue; + + LExit: + return hr; + } + + virtual STDMETHODIMP GetVariableVersion( + __in_z LPCWSTR wzVariable, + __out DWORD64* pqwValue + ) + { + HRESULT hr = S_OK; + BAENGINE_GETVARIABLEVERSION_ARGS args = { }; + BAENGINE_GETVARIABLEVERSION_RESULTS results = { }; + + ExitOnNull(pqwValue, hr, E_INVALIDARG, "pqwValue is required"); + + args.cbSize = sizeof(args); + args.wzVariable = wzVariable; + + results.cbSize = sizeof(results); + + hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_GETVARIABLEVERSION, &args, &results, m_pvBAEngineProcContext); + + *pqwValue = results.qwValue; + + LExit: + SecureZeroMemory(&results, sizeof(results)); + return hr; + } + + virtual STDMETHODIMP FormatString( + __in_z LPCWSTR wzIn, + __out_ecount_opt(*pcchOut) LPWSTR wzOut, + __inout DWORD* pcchOut + ) + { + HRESULT hr = S_OK; + BAENGINE_FORMATSTRING_ARGS args = { }; + BAENGINE_FORMATSTRING_RESULTS results = { }; + + ExitOnNull(pcchOut, hr, E_INVALIDARG, "pcchOut is required"); + + args.cbSize = sizeof(args); + args.wzIn = wzIn; + + results.cbSize = sizeof(results); + results.wzOut = wzOut; + results.cchOut = *pcchOut; + + hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_FORMATSTRING, &args, &results, m_pvBAEngineProcContext); + + *pcchOut = results.cchOut; + + LExit: + return hr; + } + + virtual STDMETHODIMP EscapeString( + __in_z LPCWSTR wzIn, + __out_ecount_opt(*pcchOut) LPWSTR wzOut, + __inout DWORD* pcchOut + ) + { + HRESULT hr = S_OK; + BAENGINE_ESCAPESTRING_ARGS args = { }; + BAENGINE_ESCAPESTRING_RESULTS results = { }; + + ExitOnNull(pcchOut, hr, E_INVALIDARG, "pcchOut is required"); + + args.cbSize = sizeof(args); + args.wzIn = wzIn; + + results.cbSize = sizeof(results); + results.wzOut = wzOut; + results.cchOut = *pcchOut; + + hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_ESCAPESTRING, &args, &results, m_pvBAEngineProcContext); + + *pcchOut = results.cchOut; + + LExit: + return hr; + } + + virtual STDMETHODIMP EvaluateCondition( + __in_z LPCWSTR wzCondition, + __out BOOL* pf + ) + { + HRESULT hr = S_OK; + BAENGINE_EVALUATECONDITION_ARGS args = { }; + BAENGINE_EVALUATECONDITION_RESULTS results = { }; + + ExitOnNull(pf, hr, E_INVALIDARG, "pf is required"); + + args.cbSize = sizeof(args); + args.wzCondition = wzCondition; + + results.cbSize = sizeof(results); + + hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_EVALUATECONDITION, &args, &results, m_pvBAEngineProcContext); + + *pf = results.f; + + LExit: + return hr; + } + + virtual STDMETHODIMP Log( + __in BOOTSTRAPPER_LOG_LEVEL level, + __in_z LPCWSTR wzMessage + ) + { + BAENGINE_LOG_ARGS args = { }; + BAENGINE_LOG_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.level = level; + args.wzMessage = wzMessage; + + results.cbSize = sizeof(results); + + return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_LOG, &args, &results, m_pvBAEngineProcContext); + } + + virtual STDMETHODIMP SendEmbeddedError( + __in DWORD dwErrorCode, + __in_z_opt LPCWSTR wzMessage, + __in DWORD dwUIHint, + __out int* pnResult + ) + { + HRESULT hr = S_OK; + BAENGINE_SENDEMBEDDEDERROR_ARGS args = { }; + BAENGINE_SENDEMBEDDEDERROR_RESULTS results = { }; + + ExitOnNull(pnResult, hr, E_INVALIDARG, "pnResult is required"); + + args.cbSize = sizeof(args); + args.dwErrorCode = dwErrorCode; + args.wzMessage = wzMessage; + args.dwUIHint = dwUIHint; + + results.cbSize = sizeof(results); + + hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SENDEMBEDDEDERROR, &args, &results, m_pvBAEngineProcContext); + + *pnResult = results.nResult; + + LExit: + return hr; + } + + virtual STDMETHODIMP SendEmbeddedProgress( + __in DWORD dwProgressPercentage, + __in DWORD dwOverallProgressPercentage, + __out int* pnResult + ) + { + HRESULT hr = S_OK; + BAENGINE_SENDEMBEDDEDPROGRESS_ARGS args = { }; + BAENGINE_SENDEMBEDDEDPROGRESS_RESULTS results = { }; + + ExitOnNull(pnResult, hr, E_INVALIDARG, "pnResult is required"); + + args.cbSize = sizeof(args); + args.dwProgressPercentage = dwProgressPercentage; + args.dwOverallProgressPercentage = dwOverallProgressPercentage; + + results.cbSize = sizeof(results); + + hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SENDEMBEDDEDPROGRESS, &args, &results, m_pvBAEngineProcContext); + + *pnResult = results.nResult; + + LExit: + return hr; + } + + virtual STDMETHODIMP SetUpdate( + __in_z_opt LPCWSTR wzLocalSource, + __in_z_opt LPCWSTR wzDownloadSource, + __in DWORD64 qwSize, + __in BOOTSTRAPPER_UPDATE_HASH_TYPE hashType, + __in_bcount_opt(cbHash) BYTE* rgbHash, + __in DWORD cbHash + ) + { + BAENGINE_SETUPDATE_ARGS args = { }; + BAENGINE_SETUPDATE_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.wzLocalSource = wzLocalSource; + args.wzDownloadSource = wzDownloadSource; + args.qwSize = qwSize; + args.hashType = hashType; + args.rgbHash = rgbHash; + args.cbHash = cbHash; + + results.cbSize = sizeof(results); + + return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETUPDATE, &args, &results, m_pvBAEngineProcContext); + } + + virtual STDMETHODIMP SetLocalSource( + __in_z LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in_z LPCWSTR wzPath + ) + { + BAENGINE_SETLOCALSOURCE_ARGS args = { }; + BAENGINE_SETLOCALSOURCE_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.wzPackageOrContainerId = wzPackageOrContainerId; + args.wzPayloadId = wzPayloadId; + args.wzPath = wzPath; + + results.cbSize = sizeof(results); + + return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETLOCALSOURCE, &args, &results, m_pvBAEngineProcContext); + } + + virtual STDMETHODIMP SetDownloadSource( + __in_z LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in_z LPCWSTR wzUrl, + __in_z_opt LPCWSTR wzUser, + __in_z_opt LPCWSTR wzPassword + ) + { + BAENGINE_SETDOWNLOADSOURCE_ARGS args = { }; + BAENGINE_SETDOWNLOADSOURCE_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.wzPackageOrContainerId = wzPackageOrContainerId; + args.wzPayloadId = wzPayloadId; + args.wzUrl = wzUrl; + args.wzUser = wzUser; + args.wzPassword = wzPassword; + + results.cbSize = sizeof(results); + + return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETDOWNLOADSOURCE, &args, &results, m_pvBAEngineProcContext); + } + + virtual STDMETHODIMP SetVariableNumeric( + __in_z LPCWSTR wzVariable, + __in LONGLONG llValue + ) + { + BAENGINE_SETVARIABLENUMERIC_ARGS args = { }; + BAENGINE_SETVARIABLENUMERIC_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.wzVariable = wzVariable; + args.llValue = llValue; + + results.cbSize = sizeof(results); + + return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETVARIABLENUMERIC, &args, &results, m_pvBAEngineProcContext); + } + + virtual STDMETHODIMP SetVariableString( + __in_z LPCWSTR wzVariable, + __in_z_opt LPCWSTR wzValue + ) + { + BAENGINE_SETVARIABLESTRING_ARGS args = { }; + BAENGINE_SETVARIABLESTRING_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.wzVariable = wzVariable; + args.wzValue = wzValue; + + results.cbSize = sizeof(results); + + return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETVARIABLESTRING, &args, &results, m_pvBAEngineProcContext); + } + + virtual STDMETHODIMP SetVariableVersion( + __in_z LPCWSTR wzVariable, + __in DWORD64 qwValue + ) + { + BAENGINE_SETVARIABLEVERSION_ARGS args = { }; + BAENGINE_SETVARIABLEVERSION_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.wzVariable = wzVariable; + args.qwValue = qwValue; + + results.cbSize = sizeof(results); + + return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETVARIABLEVERSION, &args, &results, m_pvBAEngineProcContext); + } + + virtual STDMETHODIMP CloseSplashScreen() + { + BAENGINE_CLOSESPLASHSCREEN_ARGS args = { }; + BAENGINE_CLOSESPLASHSCREEN_RESULTS results = { }; + + args.cbSize = sizeof(args); + + results.cbSize = sizeof(results); + + return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_CLOSESPLASHSCREEN, &args, &results, m_pvBAEngineProcContext); + } + + virtual STDMETHODIMP Detect( + __in_opt HWND hwndParent + ) + { + BAENGINE_DETECT_ARGS args = { }; + BAENGINE_DETECT_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.hwndParent = hwndParent; + + results.cbSize = sizeof(results); + + return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_DETECT, &args, &results, m_pvBAEngineProcContext); + } + + virtual STDMETHODIMP Plan( + __in BOOTSTRAPPER_ACTION action + ) + { + BAENGINE_PLAN_ARGS args = { }; + BAENGINE_PLAN_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.action = action; + + results.cbSize = sizeof(results); + + return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_PLAN, &args, &results, m_pvBAEngineProcContext); + } + + virtual STDMETHODIMP Elevate( + __in_opt HWND hwndParent + ) + { + BAENGINE_ELEVATE_ARGS args = { }; + BAENGINE_ELEVATE_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.hwndParent = hwndParent; + + results.cbSize = sizeof(results); + + return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_ELEVATE, &args, &results, m_pvBAEngineProcContext); + } + + virtual STDMETHODIMP Apply( + __in_opt HWND hwndParent + ) + { + BAENGINE_APPLY_ARGS args = { }; + BAENGINE_APPLY_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.hwndParent = hwndParent; + + results.cbSize = sizeof(results); + + return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_APPLY, &args, &results, m_pvBAEngineProcContext); + } + + virtual STDMETHODIMP Quit( + __in DWORD dwExitCode + ) + { + BAENGINE_QUIT_ARGS args = { }; + BAENGINE_QUIT_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.dwExitCode = dwExitCode; + + results.cbSize = sizeof(results); + + return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_QUIT, &args, &results, m_pvBAEngineProcContext); + } + + virtual STDMETHODIMP LaunchApprovedExe( + __in_opt HWND hwndParent, + __in_z LPCWSTR wzApprovedExeForElevationId, + __in_z_opt LPCWSTR wzArguments, + __in DWORD dwWaitForInputIdleTimeout + ) + { + BAENGINE_LAUNCHAPPROVEDEXE_ARGS args = { }; + BAENGINE_LAUNCHAPPROVEDEXE_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.hwndParent = hwndParent; + args.wzApprovedExeForElevationId = wzApprovedExeForElevationId; + args.wzArguments = wzArguments; + args.dwWaitForInputIdleTimeout = dwWaitForInputIdleTimeout; + + results.cbSize = sizeof(results); + + return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_LAUNCHAPPROVEDEXE, &args, &results, m_pvBAEngineProcContext); + } + +public: // IMarshal + virtual STDMETHODIMP GetUnmarshalClass( + __in REFIID /*riid*/, + __in_opt LPVOID /*pv*/, + __in DWORD /*dwDestContext*/, + __reserved LPVOID /*pvDestContext*/, + __in DWORD /*mshlflags*/, + __out LPCLSID /*pCid*/ + ) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP GetMarshalSizeMax( + __in REFIID riid, + __in_opt LPVOID /*pv*/, + __in DWORD dwDestContext, + __reserved LPVOID /*pvDestContext*/, + __in DWORD /*mshlflags*/, + __out DWORD *pSize + ) + { + HRESULT hr = S_OK; + + // We only support marshaling the IBootstrapperEngine interface in-proc. + if (__uuidof(IBootstrapperEngine) != riid) + { + // Skip logging the following message since it appears way too often in the log. + // "Unexpected IID requested to be marshalled. BootstrapperEngineForApplication can only marshal the IBootstrapperEngine interface." + ExitFunction1(hr = E_NOINTERFACE); + } + else if (0 == (MSHCTX_INPROC & dwDestContext)) + { + hr = E_FAIL; + ExitOnRootFailure(hr, "Cannot marshal IBootstrapperEngine interface out of proc."); + } + + // E_FAIL is used because E_INVALIDARG is not a supported return value. + ExitOnNull(pSize, hr, E_FAIL, "Invalid size output parameter is NULL."); + + // Specify enough size to marshal just the interface pointer across threads. + *pSize = sizeof(LPVOID); + + LExit: + return hr; + } + + virtual STDMETHODIMP MarshalInterface( + __in IStream* pStm, + __in REFIID riid, + __in_opt LPVOID pv, + __in DWORD dwDestContext, + __reserved LPVOID /*pvDestContext*/, + __in DWORD /*mshlflags*/ + ) + { + HRESULT hr = S_OK; + IBootstrapperEngine *pThis = NULL; + ULONG ulWritten = 0; + + // We only support marshaling the IBootstrapperEngine interface in-proc. + if (__uuidof(IBootstrapperEngine) != riid) + { + // Skip logging the following message since it appears way too often in the log. + // "Unexpected IID requested to be marshalled. BootstrapperEngineForApplication can only marshal the IBootstrapperEngine interface." + ExitFunction1(hr = E_NOINTERFACE); + } + else if (0 == (MSHCTX_INPROC & dwDestContext)) + { + hr = E_FAIL; + ExitOnRootFailure(hr, "Cannot marshal IBootstrapperEngine interface out of proc."); + } + + // "pv" may not be set, so we should us "this" otherwise. + if (pv) + { + pThis = reinterpret_cast(pv); + } + else + { + pThis = static_cast(this); + } + + // E_INVALIDARG is not a supported return value. + ExitOnNull(pStm, hr, E_FAIL, "The marshaling stream parameter is NULL."); + + // Marshal the interface pointer in-proc as is. + hr = pStm->Write(pThis, sizeof(pThis), &ulWritten); + if (STG_E_MEDIUMFULL == hr) + { + ExitOnFailure(hr, "Failed to write the stream because the stream is full."); + } + else if (FAILED(hr)) + { + // All other STG error must be converted into E_FAIL based on IMarshal documentation. + hr = E_FAIL; + ExitOnFailure(hr, "Failed to write the IBootstrapperEngine interface pointer to the marshaling stream."); + } + + LExit: + return hr; + } + + virtual STDMETHODIMP UnmarshalInterface( + __in IStream* pStm, + __in REFIID riid, + __deref_out LPVOID* ppv + ) + { + HRESULT hr = S_OK; + ULONG ulRead = 0; + + // We only support marshaling the engine in-proc. + if (__uuidof(IBootstrapperEngine) != riid) + { + // Skip logging the following message since it appears way too often in the log. + // "Unexpected IID requested to be marshalled. BootstrapperEngineForApplication can only marshal the IBootstrapperEngine interface." + ExitFunction1(hr = E_NOINTERFACE); + } + + // E_FAIL is used because E_INVALIDARG is not a supported return value. + ExitOnNull(pStm, hr, E_FAIL, "The marshaling stream parameter is NULL."); + ExitOnNull(ppv, hr, E_FAIL, "The interface output parameter is NULL."); + + // Unmarshal the interface pointer in-proc as is. + hr = pStm->Read(*ppv, sizeof(LPVOID), &ulRead); + if (FAILED(hr)) + { + // All STG errors must be converted into E_FAIL based on IMarshal documentation. + hr = E_FAIL; + ExitOnFailure(hr, "Failed to read the IBootstrapperEngine interface pointer from the marshaling stream."); + } + + LExit: + return hr; + } + + virtual STDMETHODIMP ReleaseMarshalData( + __in IStream* /*pStm*/ + ) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP DisconnectObject( + __in DWORD /*dwReserved*/ + ) + { + return E_NOTIMPL; + } + +public: + CBalBootstrapperEngine( + __in PFN_BOOTSTRAPPER_ENGINE_PROC pfnBAEngineProc, + __in_opt LPVOID pvBAEngineProcContext + ) + { + m_cReferences = 1; + m_pfnBAEngineProc = pfnBAEngineProc; + m_pvBAEngineProcContext = pvBAEngineProcContext; + } + +private: + long m_cReferences; + PFN_BOOTSTRAPPER_ENGINE_PROC m_pfnBAEngineProc; + LPVOID m_pvBAEngineProcContext; +}; + +HRESULT BalBootstrapperEngineCreate( + __in PFN_BOOTSTRAPPER_ENGINE_PROC pfnBAEngineProc, + __in_opt LPVOID pvBAEngineProcContext, + __out IBootstrapperEngine** ppBootstrapperEngine + ) +{ + HRESULT hr = S_OK; + CBalBootstrapperEngine* pBootstrapperEngine = NULL; + + pBootstrapperEngine = new CBalBootstrapperEngine(pfnBAEngineProc, pvBAEngineProcContext); + ExitOnNull(pBootstrapperEngine, hr, E_OUTOFMEMORY, "Failed to allocate new BalBootstrapperEngine object."); + + hr = pBootstrapperEngine->QueryInterface(IID_PPV_ARGS(ppBootstrapperEngine)); + ExitOnFailure(hr, "Failed to QI for IBootstrapperEngine from BalBootstrapperEngine object."); + +LExit: + ReleaseObject(pBootstrapperEngine); + return hr; +} diff --git a/src/balutil/balcondition.cpp b/src/balutil/balcondition.cpp new file mode 100644 index 00000000..11d3e218 --- /dev/null +++ b/src/balutil/balcondition.cpp @@ -0,0 +1,124 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" + +// prototypes + + +DAPI_(HRESULT) BalConditionsParseFromXml( + __in BAL_CONDITIONS* pConditions, + __in IXMLDOMDocument* pixdManifest, + __in_opt WIX_LOCALIZATION* pWixLoc + ) +{ + HRESULT hr = S_OK; + IXMLDOMNodeList* pNodeList = NULL; + IXMLDOMNode* pNode = NULL; + BAL_CONDITION* prgConditions = NULL; + DWORD cConditions = 0; + + hr = XmlSelectNodes(pixdManifest, L"/BootstrapperApplicationData/WixBalCondition", &pNodeList); + ExitOnFailure(hr, "Failed to select all conditions."); + + hr = pNodeList->get_length(reinterpret_cast(&cConditions)); + ExitOnFailure(hr, "Failed to get the condition count."); + + if (!cConditions) + { + ExitFunction(); + } + + prgConditions = static_cast(MemAlloc(sizeof(BAL_CONDITION) * cConditions, TRUE)); + ExitOnNull(prgConditions, hr, E_OUTOFMEMORY, "Failed to allocate memory for conditions."); + + DWORD iCondition = 0; + while (S_OK == (hr = XmlNextElement(pNodeList, &pNode, NULL))) + { + hr = XmlGetAttributeEx(pNode, L"Condition", &prgConditions[iCondition].sczCondition); + ExitOnFailure(hr, "Failed to get condition for condition."); + + hr = XmlGetAttributeEx(pNode, L"Message", &prgConditions[iCondition].sczMessage); + ExitOnFailure(hr, "Failed to get message for condition."); + + if (pWixLoc && prgConditions[iCondition].sczMessage && *prgConditions[iCondition].sczMessage) + { + hr = LocLocalizeString(pWixLoc, &prgConditions[iCondition].sczMessage); + ExitOnFailure(hr, "Failed to localize condition message."); + } + + ++iCondition; + ReleaseNullObject(pNode); + } + ExitOnFailure(hr, "Failed to parse all condition elements."); + + if (S_FALSE == hr) + { + hr = S_OK; + } + + pConditions->cConditions = cConditions; + pConditions->rgConditions = prgConditions; + prgConditions = NULL; + +LExit: + ReleaseMem(prgConditions); + ReleaseObject(pNode); + ReleaseObject(pNodeList); + + return hr; +} + + +//the contents of psczMessage may be sensitive, should keep encrypted and SecureZeroFree +DAPI_(HRESULT) BalConditionEvaluate( + __in BAL_CONDITION* pCondition, + __in IBootstrapperEngine* pEngine, + __out BOOL* pfResult, + __out_z_opt LPWSTR* psczMessage + ) +{ + HRESULT hr = S_OK; + DWORD_PTR cchMessage = 0; + + hr = pEngine->EvaluateCondition(pCondition->sczCondition, pfResult); + ExitOnFailure(hr, "Failed to evaluate condition with bootstrapper engine."); + + if (psczMessage) + { + if (*psczMessage) + { + hr = StrMaxLength(*psczMessage, &cchMessage); + ExitOnFailure(hr, "Failed to get length of message."); + } + + hr = pEngine->FormatString(pCondition->sczMessage, *psczMessage, reinterpret_cast(&cchMessage)); + if (E_MOREDATA == hr) + { + ++cchMessage; + + hr = StrAllocSecure(psczMessage, cchMessage); + ExitOnFailure(hr, "Failed to allocate string for condition's formatted message."); + + hr = pEngine->FormatString(pCondition->sczMessage, *psczMessage, reinterpret_cast(&cchMessage)); + } + ExitOnFailure(hr, "Failed to format condition's message."); + } + +LExit: + return hr; +} + + +DAPI_(void) BalConditionsUninitialize( + __in BAL_CONDITIONS* pConditions + ) +{ + for (DWORD i = 0; i < pConditions->cConditions; ++i) + { + ReleaseStr(pConditions->rgConditions[i].sczMessage); + ReleaseStr(pConditions->rgConditions[i].sczCondition); + } + + ReleaseMem(pConditions->rgConditions); + memset(pConditions, 0, sizeof(BAL_CONDITIONS)); +} diff --git a/src/balutil/balinfo.cpp b/src/balutil/balinfo.cpp new file mode 100644 index 00000000..b36e3741 --- /dev/null +++ b/src/balutil/balinfo.cpp @@ -0,0 +1,288 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" + +// prototypes +static HRESULT ParsePackagesFromXml( + __in BAL_INFO_PACKAGES* pPackages, + __in IXMLDOMDocument* pixdManifest + ); + + +DAPI_(HRESULT) BalInfoParseFromXml( + __in BAL_INFO_BUNDLE* pBundle, + __in IXMLDOMDocument* pixdManifest + ) +{ + HRESULT hr = S_OK; + IXMLDOMNode* pNode = NULL; + + hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixBundleProperties", &pNode); + ExitOnFailure(hr, "Failed to select bundle information."); + + if (S_OK == hr) + { + hr = XmlGetYesNoAttribute(pNode, L"PerMachine", &pBundle->fPerMachine); + if (E_NOTFOUND != hr) + { + ExitOnFailure(hr, "Failed to read bundle information per-machine."); + } + + hr = XmlGetAttributeEx(pNode, L"DisplayName", &pBundle->sczName); + if (E_NOTFOUND != hr) + { + ExitOnFailure(hr, "Failed to read bundle information display name."); + } + + hr = XmlGetAttributeEx(pNode, L"LogPathVariable", &pBundle->sczLogVariable); + if (E_NOTFOUND != hr) + { + ExitOnFailure(hr, "Failed to read bundle information log path variable."); + } + } + + hr = ParsePackagesFromXml(&pBundle->packages, pixdManifest); + BalExitOnFailure(hr, "Failed to parse package information from bootstrapper application data."); + +LExit: + ReleaseObject(pNode); + + return hr; +} + + +DAPI_(HRESULT) BalInfoAddRelatedBundleAsPackage( + __in BAL_INFO_PACKAGES* pPackages, + __in LPCWSTR wzId, + __in BOOTSTRAPPER_RELATION_TYPE relationType, + __in BOOL /*fPerMachine*/ + ) +{ + HRESULT hr = S_OK; + BAL_INFO_PACKAGE_TYPE type = BAL_INFO_PACKAGE_TYPE_UNKNOWN; + BAL_INFO_PACKAGE* pPackage = NULL; + + // Ensure we have a supported relation type. + switch (relationType) + { + case BOOTSTRAPPER_RELATION_ADDON: + type = BAL_INFO_PACKAGE_TYPE_BUNDLE_ADDON; + break; + + case BOOTSTRAPPER_RELATION_PATCH: + type = BAL_INFO_PACKAGE_TYPE_BUNDLE_PATCH; + break; + + case BOOTSTRAPPER_RELATION_UPGRADE: + type = BAL_INFO_PACKAGE_TYPE_BUNDLE_UPGRADE; + break; + + default: + ExitOnFailure(hr = E_INVALIDARG, "Unknown related bundle type: %u", relationType); + } + + // Check to see if the bundle is already in the list of packages. + for (DWORD i = 0; i < pPackages->cPackages; ++i) + { + if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzId, -1, pPackages->rgPackages[i].sczId, -1)) + { + ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)); + } + } + + // Add the related bundle as a package. + hr = MemEnsureArraySize(reinterpret_cast(&pPackages->rgPackages), pPackages->cPackages + 1, sizeof(BAL_INFO_PACKAGE), 2); + ExitOnFailure(hr, "Failed to allocate memory for related bundle package information."); + + pPackage = pPackages->rgPackages + pPackages->cPackages; + ++pPackages->cPackages; + + hr = StrAllocString(&pPackage->sczId, wzId, 0); + ExitOnFailure(hr, "Failed to copy related bundle package id."); + + pPackage->type = type; + + // TODO: try to look up the DisplayName and Description in Add/Remove Programs with the wzId. + +LExit: + return hr; +} + + +DAPI_(HRESULT) BalInfoFindPackageById( + __in BAL_INFO_PACKAGES* pPackages, + __in LPCWSTR wzId, + __out BAL_INFO_PACKAGE** ppPackage + ) +{ + *ppPackage = NULL; + + for (DWORD i = 0; i < pPackages->cPackages; ++i) + { + if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzId, -1, pPackages->rgPackages[i].sczId, -1)) + { + *ppPackage = pPackages->rgPackages + i; + break; + } + } + + return *ppPackage ? S_OK : E_NOTFOUND; +} + + +DAPI_(void) BalInfoUninitialize( + __in BAL_INFO_BUNDLE* pBundle + ) +{ + for (DWORD i = 0; i < pBundle->packages.cPackages; ++i) + { + ReleaseStr(pBundle->packages.rgPackages[i].sczDisplayName); + ReleaseStr(pBundle->packages.rgPackages[i].sczDescription); + ReleaseStr(pBundle->packages.rgPackages[i].sczId); + ReleaseStr(pBundle->packages.rgPackages[i].sczProductCode); + ReleaseStr(pBundle->packages.rgPackages[i].sczUpgradeCode); + ReleaseStr(pBundle->packages.rgPackages[i].sczVersion); + ReleaseStr(pBundle->packages.rgPackages[i].sczInstallCondition); + } + + ReleaseMem(pBundle->packages.rgPackages); + + ReleaseStr(pBundle->sczName); + ReleaseStr(pBundle->sczLogVariable); + memset(pBundle, 0, sizeof(BAL_INFO_BUNDLE)); +} + + +static HRESULT ParsePackagesFromXml( + __in BAL_INFO_PACKAGES* pPackages, + __in IXMLDOMDocument* pixdManifest + ) +{ + HRESULT hr = S_OK; + IXMLDOMNodeList* pNodeList = NULL; + IXMLDOMNode* pNode = NULL; + BAL_INFO_PACKAGE* prgPackages = NULL; + DWORD cPackages = 0; + LPWSTR scz = NULL; + + hr = XmlSelectNodes(pixdManifest, L"/BootstrapperApplicationData/WixPackageProperties", &pNodeList); + ExitOnFailure(hr, "Failed to select all packages."); + + hr = pNodeList->get_length(reinterpret_cast(&cPackages)); + ExitOnFailure(hr, "Failed to get the package count."); + + prgPackages = static_cast(MemAlloc(sizeof(BAL_INFO_PACKAGE) * cPackages, TRUE)); + ExitOnNull(prgPackages, hr, E_OUTOFMEMORY, "Failed to allocate memory for packages."); + + DWORD iPackage = 0; + while (S_OK == (hr = XmlNextElement(pNodeList, &pNode, NULL))) + { + hr = XmlGetAttributeEx(pNode, L"Package", &prgPackages[iPackage].sczId); + ExitOnFailure(hr, "Failed to get package identifier for package."); + + hr = XmlGetAttributeEx(pNode, L"DisplayName", &prgPackages[iPackage].sczDisplayName); + if (E_NOTFOUND != hr) + { + ExitOnFailure(hr, "Failed to get display name for package."); + } + + hr = XmlGetAttributeEx(pNode, L"Description", &prgPackages[iPackage].sczDescription); + if (E_NOTFOUND != hr) + { + ExitOnFailure(hr, "Failed to get description for package."); + } + + hr = XmlGetAttributeEx(pNode, L"PackageType", &scz); + ExitOnFailure(hr, "Failed to get package type for package."); + + if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, L"Exe", -1, scz, -1)) + { + prgPackages[iPackage].type = BAL_INFO_PACKAGE_TYPE_EXE; + } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, L"Msi", -1, scz, -1)) + { + prgPackages[iPackage].type = BAL_INFO_PACKAGE_TYPE_MSI; + } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, L"Msp", -1, scz, -1)) + { + prgPackages[iPackage].type = BAL_INFO_PACKAGE_TYPE_MSP; + } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, L"Msu", -1, scz, -1)) + { + prgPackages[iPackage].type = BAL_INFO_PACKAGE_TYPE_MSU; + } + + hr = XmlGetYesNoAttribute(pNode, L"Permanent", &prgPackages[iPackage].fPermanent); + ExitOnFailure(hr, "Failed to get permanent setting for package."); + + hr = XmlGetYesNoAttribute(pNode, L"Vital", &prgPackages[iPackage].fVital); + ExitOnFailure(hr, "Failed to get vital setting for package."); + + hr = XmlGetYesNoAttribute(pNode, L"DisplayInternalUI", &prgPackages[iPackage].fDisplayInternalUI); + if (E_NOTFOUND != hr) + { + ExitOnFailure(hr, "Failed to get DisplayInternalUI setting for package."); + } + + hr = XmlGetAttributeEx(pNode, L"ProductCode", &prgPackages[iPackage].sczProductCode); + if (E_NOTFOUND != hr) + { + ExitOnFailure(hr, "Failed to get product code for package."); + } + + hr = XmlGetAttributeEx(pNode, L"UpgradeCode", &prgPackages[iPackage].sczUpgradeCode); + if (E_NOTFOUND != hr) + { + ExitOnFailure(hr, "Failed to get upgrade code for package."); + } + + hr = XmlGetAttributeEx(pNode, L"Version", &prgPackages[iPackage].sczVersion); + if (E_NOTFOUND != hr) + { + ExitOnFailure(hr, "Failed to get version for package."); + } + + hr = XmlGetAttributeEx(pNode, L"InstallCondition", &prgPackages[iPackage].sczInstallCondition); + if (E_NOTFOUND != hr) + { + ExitOnFailure(hr, "Failed to get install condition for package."); + } + + hr = XmlGetAttributeEx(pNode, L"Cache", &scz); + ExitOnFailure(hr, "Failed to get cache type for package."); + + if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, scz, -1, L"no", -1)) + { + prgPackages[iPackage].cacheType = BAL_INFO_CACHE_TYPE_NO; + } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, scz, -1, L"yes", -1)) + { + prgPackages[iPackage].cacheType = BAL_INFO_CACHE_TYPE_YES; + } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, scz, -1, L"always", -1)) + { + prgPackages[iPackage].cacheType = BAL_INFO_CACHE_TYPE_ALWAYS; + } + + ++iPackage; + ReleaseNullObject(pNode); + } + ExitOnFailure(hr, "Failed to parse all package property elements."); + + if (S_FALSE == hr) + { + hr = S_OK; + } + + pPackages->cPackages = cPackages; + pPackages->rgPackages = prgPackages; + prgPackages = NULL; + +LExit: + ReleaseStr(scz); + ReleaseMem(prgPackages); + ReleaseObject(pNode); + ReleaseObject(pNodeList); + + return hr; +} diff --git a/src/balutil/balretry.cpp b/src/balutil/balretry.cpp new file mode 100644 index 00000000..d95d86b2 --- /dev/null +++ b/src/balutil/balretry.cpp @@ -0,0 +1,191 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" + +struct BALRETRY_INFO +{ + LPWSTR sczId; // package or container id. + LPWSTR sczPayloadId; // optional payload id. + DWORD cRetries; + DWORD dwLastError; +}; + +static DWORD vdwMaxRetries = 0; +static DWORD vdwTimeout = 0; +static BALRETRY_INFO vrgRetryInfo[2]; + +// prototypes +static BOOL IsActiveRetryEntry( + __in BALRETRY_TYPE type, + __in_z LPCWSTR wzPackageId, + __in_z_opt LPCWSTR wzPayloadId + ); + + +DAPI_(void) BalRetryInitialize( + __in DWORD dwMaxRetries, + __in DWORD dwTimeout + ) +{ + BalRetryUninitialize(); // clean everything out. + + vdwMaxRetries = dwMaxRetries; + vdwTimeout = dwTimeout; +} + + +DAPI_(void) BalRetryUninitialize() +{ + for (DWORD i = 0; i < countof(vrgRetryInfo); ++i) + { + ReleaseStr(vrgRetryInfo[i].sczId); + ReleaseStr(vrgRetryInfo[i].sczPayloadId); + memset(vrgRetryInfo + i, 0, sizeof(BALRETRY_INFO)); + } + + vdwMaxRetries = 0; + vdwTimeout = 0; +} + + +DAPI_(void) BalRetryStartPackage( + __in BALRETRY_TYPE type, + __in_z_opt LPCWSTR wzPackageId, + __in_z_opt LPCWSTR wzPayloadId + ) +{ + if (!wzPackageId || !*wzPackageId) + { + ReleaseNullStr(vrgRetryInfo[type].sczId); + ReleaseNullStr(vrgRetryInfo[type].sczPayloadId); + } + else if (IsActiveRetryEntry(type, wzPackageId, wzPayloadId)) + { + ++vrgRetryInfo[type].cRetries; + ::Sleep(vdwTimeout); + } + else + { + StrAllocString(&vrgRetryInfo[type].sczId, wzPackageId, 0); + if (wzPayloadId) + { + StrAllocString(&vrgRetryInfo[type].sczPayloadId, wzPayloadId, 0); + } + + vrgRetryInfo[type].cRetries = 0; + } + + vrgRetryInfo[type].dwLastError = ERROR_SUCCESS; +} + + +DAPI_(void) BalRetryErrorOccurred( + __in_z LPCWSTR wzPackageId, + __in DWORD dwError + ) +{ + if (IsActiveRetryEntry(BALRETRY_TYPE_CACHE, wzPackageId, NULL)) + { + vrgRetryInfo[BALRETRY_TYPE_CACHE].dwLastError = dwError; + } + else if (IsActiveRetryEntry(BALRETRY_TYPE_EXECUTE, wzPackageId, NULL)) + { + vrgRetryInfo[BALRETRY_TYPE_EXECUTE].dwLastError = dwError; + } +} + + +DAPI_(HRESULT) BalRetryEndPackage( + __in BALRETRY_TYPE type, + __in_z_opt LPCWSTR wzPackageId, + __in_z_opt LPCWSTR wzPayloadId, + __in HRESULT hrError, + __inout BOOL* pfRetry + ) +{ + HRESULT hr = S_OK; + + if (!wzPackageId || !*wzPackageId) + { + ReleaseNullStr(vrgRetryInfo[type].sczId); + ReleaseNullStr(vrgRetryInfo[type].sczPayloadId); + } + else if (FAILED(hrError) && vrgRetryInfo[type].cRetries < vdwMaxRetries && IsActiveRetryEntry(type, wzPackageId, wzPayloadId)) + { + if (BALRETRY_TYPE_CACHE == type) + { + // Retry on all errors except the following. + if (HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) != hrError && + BG_E_NETWORK_DISCONNECTED != hrError && + HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hrError && + HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED) != hrError) + { + *pfRetry = TRUE; + } + } + else if (BALRETRY_TYPE_EXECUTE == type) + { + // If the service is out of whack, just try again. + if (HRESULT_FROM_WIN32(ERROR_INSTALL_SERVICE_FAILURE) == hrError) + { + *pfRetry = TRUE; + } + else if (HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE) == hrError) + { + DWORD dwError = vrgRetryInfo[type].dwLastError; + + // If we failed with one of these specific error codes, then retry since + // we've seen these have a high success of succeeding on retry. + if (1303 == dwError || + 1304 == dwError || + 1306 == dwError || + 1307 == dwError || + 1309 == dwError || + 1310 == dwError || + 1311 == dwError || + 1312 == dwError || + 1316 == dwError || + 1317 == dwError || + 1321 == dwError || + 1335 == dwError || + 1402 == dwError || + 1406 == dwError || + 1606 == dwError || + 1706 == dwError || + 1719 == dwError || + 1723 == dwError || + 1923 == dwError || + 1931 == dwError) + { + *pfRetry = TRUE; + } + } + else if (HRESULT_FROM_WIN32(ERROR_INSTALL_ALREADY_RUNNING) == hrError) + { + *pfRetry = TRUE; + } + } + } + + return hr; +} + + +// Internal functions. + +static BOOL IsActiveRetryEntry( + __in BALRETRY_TYPE type, + __in_z LPCWSTR wzPackageId, + __in_z_opt LPCWSTR wzPayloadId + ) +{ + BOOL fActive = FALSE; + + fActive = vrgRetryInfo[type].sczId && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPackageId, -1, vrgRetryInfo[type].sczId, -1); + if (fActive && wzPayloadId) // if a payload id was provided ensure it matches. + { + fActive = vrgRetryInfo[type].sczPayloadId && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPayloadId, -1, vrgRetryInfo[type].sczPayloadId, -1); + } + + return fActive; +} diff --git a/src/balutil/balutil.cpp b/src/balutil/balutil.cpp new file mode 100644 index 00000000..df254359 --- /dev/null +++ b/src/balutil/balutil.cpp @@ -0,0 +1,382 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" + +const DWORD VARIABLE_GROW_FACTOR = 80; +static IBootstrapperEngine* vpEngine = NULL; + +// prototypes + +DAPI_(void) BalInitialize( + __in IBootstrapperEngine* pEngine + ) +{ + pEngine->AddRef(); + + ReleaseObject(vpEngine); + vpEngine = pEngine; +} + +DAPI_(HRESULT) BalInitializeFromCreateArgs( + __in const BOOTSTRAPPER_CREATE_ARGS* pArgs, + __out_opt IBootstrapperEngine** ppEngine + ) +{ + HRESULT hr = S_OK; + IBootstrapperEngine* pEngine = NULL; + + hr = BalBootstrapperEngineCreate(pArgs->pfnBootstrapperEngineProc, pArgs->pvBootstrapperEngineProcContext, &pEngine); + ExitOnFailure(hr, "Failed to create BalBootstrapperEngine."); + + BalInitialize(pEngine); + + if (ppEngine) + { + *ppEngine = pEngine; + } + pEngine = NULL; + +LExit: + ReleaseObject(pEngine); + + return hr; +} + + +DAPI_(void) BalUninitialize() +{ + ReleaseNullObject(vpEngine); +} + + +DAPI_(HRESULT) BalManifestLoad( + __in HMODULE hBootstrapperApplicationModule, + __out IXMLDOMDocument** ppixdManifest + ) +{ + HRESULT hr = S_OK; + LPWSTR sczPath = NULL; + + hr = PathRelativeToModule(&sczPath, BAL_MANIFEST_FILENAME, hBootstrapperApplicationModule); + ExitOnFailure(hr, "Failed to get path to bootstrapper application manifest: %ls", BAL_MANIFEST_FILENAME); + + hr = XmlLoadDocumentFromFile(sczPath, ppixdManifest); + ExitOnFailure(hr, "Failed to load bootstrapper application manifest '%ls' from path: %ls", BAL_MANIFEST_FILENAME, sczPath); + +LExit: + ReleaseStr(sczPath); + return hr; +} + + +DAPI_(HRESULT) BalEvaluateCondition( + __in_z LPCWSTR wzCondition, + __out BOOL* pf + ) +{ + HRESULT hr = S_OK; + + if (!vpEngine) + { + hr = E_POINTER; + ExitOnRootFailure(hr, "BalInitialize() must be called first."); + } + + hr = vpEngine->EvaluateCondition(wzCondition, pf); + +LExit: + return hr; +} + + +// The contents of psczOut may be sensitive, should keep encrypted and SecureZeroFree. +DAPI_(HRESULT) BalFormatString( + __in_z LPCWSTR wzFormat, + __inout LPWSTR* psczOut + ) +{ + HRESULT hr = S_OK; + DWORD cch = 0; + + if (!vpEngine) + { + hr = E_POINTER; + ExitOnRootFailure(hr, "BalInitialize() must be called first."); + } + + if (*psczOut) + { + hr = StrMaxLength(*psczOut, reinterpret_cast(&cch)); + ExitOnFailure(hr, "Failed to determine length of value."); + } + + hr = vpEngine->FormatString(wzFormat, *psczOut, &cch); + if (E_MOREDATA == hr) + { + ++cch; + + hr = StrAllocSecure(psczOut, cch); + ExitOnFailure(hr, "Failed to allocate value."); + + hr = vpEngine->FormatString(wzFormat, *psczOut, &cch); + } + +LExit: + return hr; +} + + +// The contents of pllValue may be sensitive, if variable is hidden should keep value encrypted and SecureZeroMemory. +DAPI_(HRESULT) BalGetNumericVariable( + __in_z LPCWSTR wzVariable, + __out LONGLONG* pllValue + ) +{ + HRESULT hr = S_OK; + + if (!vpEngine) + { + hr = E_POINTER; + ExitOnRootFailure(hr, "BalInitialize() must be called first."); + } + + hr = vpEngine->GetVariableNumeric(wzVariable, pllValue); + +LExit: + return hr; +} + + +DAPI_(HRESULT) BalSetNumericVariable( + __in_z LPCWSTR wzVariable, + __in LONGLONG llValue + ) +{ + HRESULT hr = S_OK; + + if (!vpEngine) + { + hr = E_POINTER; + ExitOnRootFailure(hr, "BalInitialize() must be called first."); + } + + hr = vpEngine->SetVariableNumeric(wzVariable, llValue); + +LExit: + return hr; +} + + +DAPI_(BOOL) BalStringVariableExists( + __in_z LPCWSTR wzVariable + ) +{ + HRESULT hr = S_OK; + DWORD cch = 0; + + if (!vpEngine) + { + hr = E_POINTER; + ExitOnRootFailure(hr, "BalInitialize() must be called first."); + } + + hr = vpEngine->GetVariableString(wzVariable, NULL, &cch); + +LExit: + return E_MOREDATA == hr; // string exists only if there are more than zero characters in the variable. +} + + +// The contents of psczValue may be sensitive, if variable is hidden should keep value encrypted and SecureZeroFree. +DAPI_(HRESULT) BalGetStringVariable( + __in_z LPCWSTR wzVariable, + __inout LPWSTR* psczValue + ) +{ + HRESULT hr = S_OK; + DWORD cch = 0; + + if (!vpEngine) + { + hr = E_POINTER; + ExitOnRootFailure(hr, "BalInitialize() must be called first."); + } + + if (*psczValue) + { + hr = StrMaxLength(*psczValue, reinterpret_cast(&cch)); + ExitOnFailure(hr, "Failed to determine length of value."); + } + + hr = vpEngine->GetVariableString(wzVariable, *psczValue, &cch); + if (E_MOREDATA == hr) + { + ++cch; + + hr = StrAllocSecure(psczValue, cch); + ExitOnFailure(hr, "Failed to allocate value."); + + hr = vpEngine->GetVariableString(wzVariable, *psczValue, &cch); + } + +LExit: + return hr; +} + +DAPI_(HRESULT) BalSetStringVariable( + __in_z LPCWSTR wzVariable, + __in_z_opt LPCWSTR wzValue + ) +{ + HRESULT hr = S_OK; + + if (!vpEngine) + { + hr = E_POINTER; + ExitOnRootFailure(hr, "BalInitialize() must be called first."); + } + + hr = vpEngine->SetVariableString(wzVariable, wzValue); + +LExit: + return hr; +} + + +DAPIV_(HRESULT) BalLog( + __in BOOTSTRAPPER_LOG_LEVEL level, + __in_z __format_string LPCSTR szFormat, + ... + ) +{ + HRESULT hr = S_OK; + va_list args; + LPSTR sczFormattedAnsi = NULL; + LPWSTR sczMessage = NULL; + + if (!vpEngine) + { + hr = E_POINTER; + ExitOnRootFailure(hr, "BalInitialize() must be called first."); + } + + va_start(args, szFormat); + hr = StrAnsiAllocFormattedArgs(&sczFormattedAnsi, szFormat, args); + va_end(args); + ExitOnFailure(hr, "Failed to format log string."); + + hr = StrAllocStringAnsi(&sczMessage, sczFormattedAnsi, 0, CP_UTF8); + ExitOnFailure(hr, "Failed to convert log string to Unicode."); + + hr = vpEngine->Log(level, sczMessage); + +LExit: + ReleaseStr(sczMessage); + ReleaseStr(sczFormattedAnsi); + return hr; +} + + +DAPIV_(HRESULT) BalLogError( + __in HRESULT hrError, + __in_z __format_string LPCSTR szFormat, + ... + ) +{ + HRESULT hr = S_OK; + va_list args; + LPSTR sczFormattedAnsi = NULL; + LPWSTR sczMessage = NULL; + + if (!vpEngine) + { + hr = E_POINTER; + ExitOnRootFailure(hr, "BalInitialize() must be called first."); + } + + va_start(args, szFormat); + hr = StrAnsiAllocFormattedArgs(&sczFormattedAnsi, szFormat, args); + va_end(args); + ExitOnFailure(hr, "Failed to format error log string."); + + hr = StrAllocFormatted(&sczMessage, L"Error 0x%08x: %S", hrError, sczFormattedAnsi); + ExitOnFailure(hr, "Failed to prepend error number to error log string."); + + hr = vpEngine->Log(BOOTSTRAPPER_LOG_LEVEL_ERROR, sczMessage); + +LExit: + ReleaseStr(sczMessage); + ReleaseStr(sczFormattedAnsi); + return hr; +} + +DAPIV_(HRESULT) BalLogId( + __in BOOTSTRAPPER_LOG_LEVEL level, + __in DWORD dwLogId, + __in HMODULE hModule, + ... + ) +{ + HRESULT hr = S_OK; + va_list args; + + if (!vpEngine) + { + hr = E_POINTER; + ExitOnRootFailure(hr, "BalInitialize() must be called first."); + } + + va_start(args, hModule); + hr = BalLogIdArgs(level, dwLogId, hModule, args); + va_end(args); + +LExit: + return hr; +} + +DAPI_(HRESULT) BalLogIdArgs( + __in BOOTSTRAPPER_LOG_LEVEL level, + __in DWORD dwLogId, + __in HMODULE hModule, + __in va_list args + ) +{ + + HRESULT hr = S_OK; + LPWSTR pwz = NULL; + DWORD cch = 0; + + if (!vpEngine) + { + hr = E_POINTER; + ExitOnRootFailure(hr, "BalInitialize() must be called first."); + } + + // Get the string for the id. +#pragma prefast(push) +#pragma prefast(disable:25028) +#pragma prefast(disable:25068) + cch = ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE, + static_cast(hModule), dwLogId, 0, reinterpret_cast(&pwz), 0, &args); +#pragma prefast(pop) + + if (0 == cch) + { + ExitOnLastError(hr, "Failed to log id: %d", dwLogId); + } + + if (2 <= cch && L'\r' == pwz[cch - 2] && L'\n' == pwz[cch - 1]) + { + pwz[cch - 2] = L'\0'; // remove newline from message table. + } + + hr = vpEngine->Log(level, pwz); + +LExit: + if (pwz) + { + ::LocalFree(pwz); + } + + return hr; +} diff --git a/src/balutil/inc/BAFunctions.h b/src/balutil/inc/BAFunctions.h new file mode 100644 index 00000000..1338253d --- /dev/null +++ b/src/balutil/inc/BAFunctions.h @@ -0,0 +1,130 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +#ifdef __cplusplus +extern "C" { +#endif + +// The first 1024 messages are reserved so that the BA messages have the same value here. +enum BA_FUNCTIONS_MESSAGE +{ + BA_FUNCTIONS_MESSAGE_ONDETECTBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTBEGIN, + BA_FUNCTIONS_MESSAGE_ONDETECTCOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPLETE, + BA_FUNCTIONS_MESSAGE_ONPLANBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANBEGIN, + BA_FUNCTIONS_MESSAGE_ONPLANCOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPLETE, + BA_FUNCTIONS_MESSAGE_ONSTARTUP = BOOTSTRAPPER_APPLICATION_MESSAGE_ONSTARTUP, + BA_FUNCTIONS_MESSAGE_ONSHUTDOWN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONSHUTDOWN, + BA_FUNCTIONS_MESSAGE_ONSYSTEMSHUTDOWN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMSHUTDOWN, + BA_FUNCTIONS_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE, + BA_FUNCTIONS_MESSAGE_ONDETECTUPDATEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATEBEGIN, + BA_FUNCTIONS_MESSAGE_ONDETECTUPDATE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATE, + BA_FUNCTIONS_MESSAGE_ONDETECTUPDATECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATECOMPLETE, + BA_FUNCTIONS_MESSAGE_ONDETECTRELATEDBUNDLE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDBUNDLE, + BA_FUNCTIONS_MESSAGE_ONDETECTPACKAGEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGEBEGIN, + BA_FUNCTIONS_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE, + BA_FUNCTIONS_MESSAGE_ONDETECTRELATEDMSIPACKAGE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDMSIPACKAGE, + BA_FUNCTIONS_MESSAGE_ONDETECTTARGETMSIPACKAGE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTTARGETMSIPACKAGE, + BA_FUNCTIONS_MESSAGE_ONDETECTMSIFEATURE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTMSIFEATURE, + BA_FUNCTIONS_MESSAGE_ONDETECTPACKAGECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGECOMPLETE, + BA_FUNCTIONS_MESSAGE_ONPLANRELATEDBUNDLE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRELATEDBUNDLE, + BA_FUNCTIONS_MESSAGE_ONPLANPACKAGEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGEBEGIN, + BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN, + BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, + BA_FUNCTIONS_MESSAGE_ONPLANTARGETMSIPACKAGE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANTARGETMSIPACKAGE, + BA_FUNCTIONS_MESSAGE_ONPLANMSIFEATURE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIFEATURE, + BA_FUNCTIONS_MESSAGE_ONPLANPACKAGECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGECOMPLETE, + BA_FUNCTIONS_MESSAGE_ONAPPLYBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYBEGIN, + BA_FUNCTIONS_MESSAGE_ONELEVATEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATEBEGIN, + BA_FUNCTIONS_MESSAGE_ONELEVATECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATECOMPLETE, + BA_FUNCTIONS_MESSAGE_ONPROGRESS = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPROGRESS, + BA_FUNCTIONS_MESSAGE_ONERROR = BOOTSTRAPPER_APPLICATION_MESSAGE_ONERROR, + BA_FUNCTIONS_MESSAGE_ONREGISTERBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERBEGIN, + BA_FUNCTIONS_MESSAGE_ONREGISTERCOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERCOMPLETE, + BA_FUNCTIONS_MESSAGE_ONCACHEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEBEGIN, + BA_FUNCTIONS_MESSAGE_ONCACHEPACKAGEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGEBEGIN, + BA_FUNCTIONS_MESSAGE_ONCACHEACQUIREBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREBEGIN, + BA_FUNCTIONS_MESSAGE_ONCACHEACQUIREPROGRESS = BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREPROGRESS, + BA_FUNCTIONS_MESSAGE_ONRESOLVESOURCE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONRESOLVESOURCE, + BA_FUNCTIONS_MESSAGE_ONCACHEACQUIRECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRECOMPLETE, + BA_FUNCTIONS_MESSAGE_ONCACHEVERIFYBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYBEGIN, + BA_FUNCTIONS_MESSAGE_ONCACHEVERIFYCOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYCOMPLETE, + BA_FUNCTIONS_MESSAGE_ONCACHEPACKAGECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGECOMPLETE, + BA_FUNCTIONS_MESSAGE_ONCACHECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECOMPLETE, + BA_FUNCTIONS_MESSAGE_ONEXECUTEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEBEGIN, + BA_FUNCTIONS_MESSAGE_ONEXECUTEPACKAGEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGEBEGIN, + BA_FUNCTIONS_MESSAGE_ONEXECUTEPATCHTARGET = BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPATCHTARGET, + BA_FUNCTIONS_MESSAGE_ONEXECUTEPROGRESS = BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPROGRESS, + BA_FUNCTIONS_MESSAGE_ONEXECUTEMSIMESSAGE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEMSIMESSAGE, + BA_FUNCTIONS_MESSAGE_ONEXECUTEFILESINUSE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEFILESINUSE, + BA_FUNCTIONS_MESSAGE_ONEXECUTEPACKAGECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGECOMPLETE, + BA_FUNCTIONS_MESSAGE_ONEXECUTECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTECOMPLETE, + BA_FUNCTIONS_MESSAGE_ONUNREGISTERBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERBEGIN, + BA_FUNCTIONS_MESSAGE_ONUNREGISTERCOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERCOMPLETE, + BA_FUNCTIONS_MESSAGE_ONAPPLYCOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYCOMPLETE, + BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN, + BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE, + + BA_FUNCTIONS_MESSAGE_ONTHEMELOADED = 1024, + BA_FUNCTIONS_MESSAGE_WNDPROC, +}; + +typedef HRESULT(WINAPI *PFN_BA_FUNCTIONS_PROC)( + __in BA_FUNCTIONS_MESSAGE message, + __in const LPVOID pvArgs, + __inout LPVOID pvResults, + __in_opt LPVOID pvContext + ); + +struct BA_FUNCTIONS_CREATE_ARGS +{ + DWORD cbSize; + DWORD64 qwBAFunctionsAPIVersion; + BOOTSTRAPPER_CREATE_ARGS* pBootstrapperCreateArgs; +}; + +struct BA_FUNCTIONS_CREATE_RESULTS +{ + DWORD cbSize; + PFN_BA_FUNCTIONS_PROC pfnBAFunctionsProc; + LPVOID pvBAFunctionsProcContext; +}; + +struct BA_FUNCTIONS_ONTHEMELOADED_ARGS +{ + DWORD cbSize; + THEME* pTheme; + WIX_LOCALIZATION* pWixLoc; +}; + +struct BA_FUNCTIONS_ONTHEMELOADED_RESULTS +{ + DWORD cbSize; +}; + +struct BA_FUNCTIONS_WNDPROC_ARGS +{ + DWORD cbSize; + THEME* pTheme; + HWND hWnd; + UINT uMsg; + WPARAM wParam; + LPARAM lParam; +}; + +struct BA_FUNCTIONS_WNDPROC_RESULTS +{ + DWORD cbSize; + LRESULT lres; +}; + +typedef HRESULT(WINAPI *PFN_BA_FUNCTIONS_CREATE)( + __in const BA_FUNCTIONS_CREATE_ARGS* pArgs, + __inout BA_FUNCTIONS_CREATE_RESULTS* pResults + ); + +typedef void (WINAPI *PFN_BA_FUNCTIONS_DESTROY)(); + +#ifdef __cplusplus +} +#endif diff --git a/src/balutil/inc/BalBaseBAFunctions.h b/src/balutil/inc/BalBaseBAFunctions.h new file mode 100644 index 00000000..dd190ee9 --- /dev/null +++ b/src/balutil/inc/BalBaseBAFunctions.h @@ -0,0 +1,700 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +#include +#include + +#include "dutil.h" +#include "locutil.h" +#include "thmutil.h" +#include "BAFunctions.h" +#include "IBAFunctions.h" +#include "BootstrapperEngine.h" +#include "BootstrapperApplication.h" +#include "IBootstrapperEngine.h" +#include "IBootstrapperApplication.h" + +class CBalBaseBAFunctions : public IBAFunctions +{ +public: // IUnknown + virtual STDMETHODIMP QueryInterface( + __in REFIID riid, + __out LPVOID *ppvObject + ) + { + if (!ppvObject) + { + return E_INVALIDARG; + } + + *ppvObject = NULL; + + if (::IsEqualIID(__uuidof(IBAFunctions), riid)) + { + *ppvObject = static_cast(this); + } + else if (::IsEqualIID(__uuidof(IBootstrapperApplication), riid)) + { + *ppvObject = static_cast(this); + } + else if (::IsEqualIID(IID_IUnknown, riid)) + { + *ppvObject = static_cast(this); + } + else // no interface for requested iid + { + return E_NOINTERFACE; + } + + AddRef(); + return S_OK; + } + + virtual STDMETHODIMP_(ULONG) AddRef() + { + return ::InterlockedIncrement(&this->m_cReferences); + } + + virtual STDMETHODIMP_(ULONG) Release() + { + long l = ::InterlockedDecrement(&this->m_cReferences); + if (0 < l) + { + return l; + } + + delete this; + return 0; + } + +public: // IBootstrapperApplication + virtual STDMETHODIMP OnStartup() + { + return S_OK; + } + + virtual STDMETHODIMP OnShutdown( + __inout BOOTSTRAPPER_SHUTDOWN_ACTION* /*pAction*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnSystemShutdown( + __in DWORD /*dwEndSession*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnDetectBegin( + __in BOOL /*fInstalled*/, + __in DWORD /*cPackages*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnDetectForwardCompatibleBundle( + __in_z LPCWSTR /*wzBundleId*/, + __in BOOTSTRAPPER_RELATION_TYPE /*relationType*/, + __in_z LPCWSTR /*wzBundleTag*/, + __in BOOL /*fPerMachine*/, + __in DWORD64 /*dw64Version*/, + __inout BOOL* /*pfCancel*/, + __inout BOOL* /*pfIgnoreBundle*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnDetectUpdateBegin( + __in_z LPCWSTR /*wzUpdateLocation*/, + __inout BOOL* /*pfCancel*/, + __inout BOOL* /*pfSkip*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnDetectUpdate( + __in_z LPCWSTR /*wzUpdateLocation*/, + __in DWORD64 /*dw64Size*/, + __in DWORD64 /*dw64Version*/, + __in_z LPCWSTR /*wzTitle*/, + __in_z LPCWSTR /*wzSummary*/, + __in_z LPCWSTR /*wzContentType*/, + __in_z LPCWSTR /*wzContent*/, + __inout BOOL* /*pfCancel*/, + __inout BOOL* /*pfStopProcessingUpdates*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnDetectUpdateComplete( + __in HRESULT /*hrStatus*/, + __inout BOOL* /*pfIgnoreError*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnDetectRelatedBundle( + __in_z LPCWSTR /*wzBundleId*/, + __in BOOTSTRAPPER_RELATION_TYPE /*relationType*/, + __in_z LPCWSTR /*wzBundleTag*/, + __in BOOL /*fPerMachine*/, + __in DWORD64 /*dw64Version*/, + __in BOOTSTRAPPER_RELATED_OPERATION /*operation*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnDetectPackageBegin( + __in_z LPCWSTR /*wzPackageId*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnDetectCompatibleMsiPackage( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzCompatiblePackageId*/, + __in DWORD64 /*dw64CompatiblePackageVersion*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnDetectRelatedMsiPackage( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzUpgradeCode*/, + __in_z LPCWSTR /*wzProductCode*/, + __in BOOL /*fPerMachine*/, + __in DWORD64 /*dw64Version*/, + __in BOOTSTRAPPER_RELATED_OPERATION /*operation*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnDetectTargetMsiPackage( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzProductCode*/, + __in BOOTSTRAPPER_PACKAGE_STATE /*patchState*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnDetectMsiFeature( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzFeatureId*/, + __in BOOTSTRAPPER_FEATURE_STATE /*state*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnDetectPackageComplete( + __in_z LPCWSTR /*wzPackageId*/, + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_PACKAGE_STATE /*state*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnDetectComplete( + __in HRESULT /*hrStatus*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnPlanBegin( + __in DWORD /*cPackages*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnPlanRelatedBundle( + __in_z LPCWSTR /*wzBundleId*/, + __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/, + __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestedState*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnPlanPackageBegin( + __in_z LPCWSTR /*wzPackageId*/, + __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/, + __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestState*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnPlanCompatibleMsiPackageBegin( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzCompatiblePackageId*/, + __in DWORD64 /*dw64CompatiblePackageVersion*/, + __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/, + __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestedState*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnPlanCompatibleMsiPackageComplete( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzCompatiblePackageId*/, + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_PACKAGE_STATE /*state*/, + __in BOOTSTRAPPER_REQUEST_STATE /*requested*/, + __in BOOTSTRAPPER_ACTION_STATE /*execute*/, + __in BOOTSTRAPPER_ACTION_STATE /*rollback*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnPlanTargetMsiPackage( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzProductCode*/, + __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/, + __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestedState*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnPlanMsiFeature( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzFeatureId*/, + __in BOOTSTRAPPER_FEATURE_STATE /*recommendedState*/, + __inout BOOTSTRAPPER_FEATURE_STATE* /*pRequestedState*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnPlanPackageComplete( + __in_z LPCWSTR /*wzPackageId*/, + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_PACKAGE_STATE /*state*/, + __in BOOTSTRAPPER_REQUEST_STATE /*requested*/, + __in BOOTSTRAPPER_ACTION_STATE /*execute*/, + __in BOOTSTRAPPER_ACTION_STATE /*rollback*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnPlanComplete( + __in HRESULT /*hrStatus*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnApplyBegin( + __in DWORD /*dwPhaseCount*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnElevateBegin( + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnElevateComplete( + __in HRESULT /*hrStatus*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnProgress( + __in DWORD /*dwProgressPercentage*/, + __in DWORD /*dwOverallProgressPercentage*/, + __inout BOOL* /*pfCancel*/ + ) + { + return IDNOACTION; + } + + virtual STDMETHODIMP OnError( + __in BOOTSTRAPPER_ERROR_TYPE /*errorType*/, + __in_z LPCWSTR /*wzPackageId*/, + __in DWORD /*dwCode*/, + __in_z LPCWSTR /*wzError*/, + __in DWORD /*dwUIHint*/, + __in DWORD /*cData*/, + __in_ecount_z_opt(cData) LPCWSTR* /*rgwzData*/, + __in int /*nRecommendation*/, + __inout int* /*pResult*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnRegisterBegin( + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnRegisterComplete( + __in HRESULT /*hrStatus*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnCacheBegin( + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnCachePackageBegin( + __in_z LPCWSTR /*wzPackageId*/, + __in DWORD /*cCachePayloads*/, + __in DWORD64 /*dw64PackageCacheSize*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnCacheAcquireBegin( + __in_z LPCWSTR /*wzPackageOrContainerId*/, + __in_z_opt LPCWSTR /*wzPayloadId*/, + __in BOOTSTRAPPER_CACHE_OPERATION /*operation*/, + __in_z LPCWSTR /*wzSource*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnCacheAcquireProgress( + __in_z LPCWSTR /*wzPackageOrContainerId*/, + __in_z_opt LPCWSTR /*wzPayloadId*/, + __in DWORD64 /*dw64Progress*/, + __in DWORD64 /*dw64Total*/, + __in DWORD /*dwOverallPercentage*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnResolveSource( + __in_z LPCWSTR /*wzPackageOrContainerId*/, + __in_z_opt LPCWSTR /*wzPayloadId*/, + __in_z LPCWSTR /*wzLocalSource*/, + __in_z_opt LPCWSTR /*wzDownloadSource*/, + __in BOOTSTRAPPER_RESOLVESOURCE_ACTION /*recommendation*/, + __inout BOOTSTRAPPER_RESOLVESOURCE_ACTION* /*pAction*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnCacheAcquireComplete( + __in_z LPCWSTR /*wzPackageOrContainerId*/, + __in_z_opt LPCWSTR /*wzPayloadId*/, + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION /*recommendation*/, + __inout BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION* /*pAction*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnCacheVerifyBegin( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzPayloadId*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnCacheVerifyComplete( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzPayloadId*/, + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION /*recommendation*/, + __inout BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION* /*pAction*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnCachePackageComplete( + __in_z LPCWSTR /*wzPackageId*/, + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION /*recommendation*/, + __inout BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION* /*pAction*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnCacheComplete( + __in HRESULT /*hrStatus*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnExecuteBegin( + __in DWORD /*cExecutingPackages*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnExecutePackageBegin( + __in_z LPCWSTR /*wzPackageId*/, + __in BOOL /*fExecute*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnExecutePatchTarget( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzTargetProductCode*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnExecuteProgress( + __in_z LPCWSTR /*wzPackageId*/, + __in DWORD /*dwProgressPercentage*/, + __in DWORD /*dwOverallProgressPercentage*/, + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnExecuteMsiMessage( + __in_z LPCWSTR /*wzPackageId*/, + __in INSTALLMESSAGE /*messageType*/, + __in DWORD /*dwUIHint*/, + __in_z LPCWSTR /*wzMessage*/, + __in DWORD /*cData*/, + __in_ecount_z_opt(cData) LPCWSTR* /*rgwzData*/, + __in int /*nRecommendation*/, + __inout int* /*pResult*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnExecuteFilesInUse( + __in_z LPCWSTR /*wzPackageId*/, + __in DWORD /*cFiles*/, + __in_ecount_z(cFiles) LPCWSTR* /*rgwzFiles*/, + __in int /*nRecommendation*/, + __inout int* /*pResult*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnExecutePackageComplete( + __in_z LPCWSTR /*wzPackageId*/, + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_APPLY_RESTART /*restart*/, + __in BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION /*recommendation*/, + __inout BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION* /*pAction*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnExecuteComplete( + __in HRESULT /*hrStatus*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnUnregisterBegin( + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnUnregisterComplete( + __in HRESULT /*hrStatus*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnApplyComplete( + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_APPLY_RESTART /*restart*/, + __in BOOTSTRAPPER_APPLYCOMPLETE_ACTION /*recommendation*/, + __inout BOOTSTRAPPER_APPLYCOMPLETE_ACTION* /*pAction*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnLaunchApprovedExeBegin( + __inout BOOL* /*pfCancel*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnLaunchApprovedExeComplete( + __in HRESULT /*hrStatus*/, + __in DWORD /*dwProcessId*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP_(HRESULT) BAProc( + __in BOOTSTRAPPER_APPLICATION_MESSAGE /*message*/, + __in const LPVOID /*pvArgs*/, + __inout LPVOID /*pvResults*/, + __in_opt LPVOID /*pvContext*/ + ) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP_(void) BAProcFallback( + __in BOOTSTRAPPER_APPLICATION_MESSAGE /*message*/, + __in const LPVOID /*pvArgs*/, + __inout LPVOID /*pvResults*/, + __inout HRESULT* /*phr*/, + __in_opt LPVOID /*pvContext*/ + ) + { + } + +public: // IBAFunctions + virtual STDMETHODIMP OnPlan( + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnThemeLoaded( + THEME* pTheme, + WIX_LOCALIZATION* pWixLoc + ) + { + HRESULT hr = S_OK; + + m_pTheme = pTheme; + m_pWixLoc = pWixLoc; + + return hr; + } + + virtual STDMETHODIMP WndProc( + __in THEME* pTheme, + __in HWND hWnd, + __in UINT uMsg, + __in WPARAM wParam, + __in LPARAM lParam, + __inout LRESULT* plRes + ) + { + HRESULT hr = S_OK; + + *plRes = ThemeDefWindowProc(pTheme, hWnd, uMsg, wParam, lParam); + + return hr; + } + + virtual STDMETHODIMP BAFunctionsProc( + __in BA_FUNCTIONS_MESSAGE /*message*/, + __in const LPVOID /*pvArgs*/, + __inout LPVOID /*pvResults*/, + __in_opt LPVOID /*pvContext*/ + ) + { + return E_NOTIMPL; + } + +protected: + CBalBaseBAFunctions( + __in HMODULE hModule, + __in IBootstrapperEngine* pEngine, + __in const BA_FUNCTIONS_CREATE_ARGS* pArgs + ) + { + m_cReferences = 1; + m_hModule = hModule; + pEngine->AddRef(); + m_pEngine = pEngine; + + memcpy_s(&m_command, sizeof(m_command), pArgs->pBootstrapperCreateArgs->pCommand, sizeof(BOOTSTRAPPER_COMMAND)); + memcpy_s(&m_baCreateArgs, sizeof(m_baCreateArgs), pArgs->pBootstrapperCreateArgs, sizeof(BOOTSTRAPPER_CREATE_ARGS)); + memcpy_s(&m_bafCreateArgs, sizeof(m_bafCreateArgs), pArgs, sizeof(BA_FUNCTIONS_CREATE_ARGS)); + m_baCreateArgs.pCommand = &m_command; + m_bafCreateArgs.pBootstrapperCreateArgs = &m_baCreateArgs; + } + + virtual ~CBalBaseBAFunctions() + { + ReleaseNullObject(m_pEngine); + } + +private: + long m_cReferences; + +protected: + IBootstrapperEngine* m_pEngine; + HMODULE m_hModule; + BA_FUNCTIONS_CREATE_ARGS m_bafCreateArgs; + BOOTSTRAPPER_CREATE_ARGS m_baCreateArgs; + BOOTSTRAPPER_COMMAND m_command; + THEME* m_pTheme; + WIX_LOCALIZATION* m_pWixLoc; +}; diff --git a/src/balutil/inc/BalBaseBAFunctionsProc.h b/src/balutil/inc/BalBaseBAFunctionsProc.h new file mode 100644 index 00000000..da0a71f7 --- /dev/null +++ b/src/balutil/inc/BalBaseBAFunctionsProc.h @@ -0,0 +1,114 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +#include "BalBaseBootstrapperApplicationProc.h" +#include "BAFunctions.h" +#include "IBAFunctions.h" + +static HRESULT BalBaseBAFunctionsProcOnThemeLoaded( + __in IBAFunctions* pBAFunctions, + __in BA_FUNCTIONS_ONTHEMELOADED_ARGS* pArgs, + __inout BA_FUNCTIONS_ONTHEMELOADED_RESULTS* /*pResults*/ + ) +{ + return pBAFunctions->OnThemeLoaded(pArgs->pTheme, pArgs->pWixLoc); +} + +static HRESULT BalBaseBAFunctionsProcWndProc( + __in IBAFunctions* pBAFunctions, + __in BA_FUNCTIONS_WNDPROC_ARGS* pArgs, + __inout BA_FUNCTIONS_WNDPROC_RESULTS* pResults + ) +{ + return pBAFunctions->WndProc(pArgs->pTheme, pArgs->hWnd, pArgs->uMsg, pArgs->wParam, pArgs->lParam, &pResults->lres); +} + +/******************************************************************* +BalBaseBAFunctionsProc - requires pvContext to be of type IBAFunctions. +Provides a default mapping between the message based BAFunctions interface and +the COM-based BAFunctions interface. + +*******************************************************************/ +static HRESULT WINAPI BalBaseBAFunctionsProc( + __in BA_FUNCTIONS_MESSAGE message, + __in const LPVOID pvArgs, + __inout LPVOID pvResults, + __in_opt LPVOID pvContext + ) +{ + IBAFunctions* pBAFunctions = reinterpret_cast(pvContext); + HRESULT hr = pBAFunctions->BAFunctionsProc(message, pvArgs, pvResults, pvContext); + + if (E_NOTIMPL == hr) + { + switch (message) + { + case BA_FUNCTIONS_MESSAGE_ONDETECTBEGIN: + case BA_FUNCTIONS_MESSAGE_ONDETECTCOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONPLANBEGIN: + case BA_FUNCTIONS_MESSAGE_ONPLANCOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONSTARTUP: + case BA_FUNCTIONS_MESSAGE_ONSHUTDOWN: + case BA_FUNCTIONS_MESSAGE_ONSYSTEMSHUTDOWN: + case BA_FUNCTIONS_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE: + case BA_FUNCTIONS_MESSAGE_ONDETECTUPDATEBEGIN: + case BA_FUNCTIONS_MESSAGE_ONDETECTUPDATE: + case BA_FUNCTIONS_MESSAGE_ONDETECTUPDATECOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONDETECTRELATEDBUNDLE: + case BA_FUNCTIONS_MESSAGE_ONDETECTPACKAGEBEGIN: + case BA_FUNCTIONS_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE: + case BA_FUNCTIONS_MESSAGE_ONDETECTRELATEDMSIPACKAGE: + case BA_FUNCTIONS_MESSAGE_ONDETECTTARGETMSIPACKAGE: + case BA_FUNCTIONS_MESSAGE_ONDETECTMSIFEATURE: + case BA_FUNCTIONS_MESSAGE_ONDETECTPACKAGECOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONPLANRELATEDBUNDLE: + case BA_FUNCTIONS_MESSAGE_ONPLANPACKAGEBEGIN: + case BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN: + case BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONPLANTARGETMSIPACKAGE: + case BA_FUNCTIONS_MESSAGE_ONPLANMSIFEATURE: + case BA_FUNCTIONS_MESSAGE_ONPLANPACKAGECOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONAPPLYBEGIN: + case BA_FUNCTIONS_MESSAGE_ONELEVATEBEGIN: + case BA_FUNCTIONS_MESSAGE_ONELEVATECOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONPROGRESS: + case BA_FUNCTIONS_MESSAGE_ONERROR: + case BA_FUNCTIONS_MESSAGE_ONREGISTERBEGIN: + case BA_FUNCTIONS_MESSAGE_ONREGISTERCOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONCACHEBEGIN: + case BA_FUNCTIONS_MESSAGE_ONCACHEPACKAGEBEGIN: + case BA_FUNCTIONS_MESSAGE_ONCACHEACQUIREBEGIN: + case BA_FUNCTIONS_MESSAGE_ONCACHEACQUIREPROGRESS: + case BA_FUNCTIONS_MESSAGE_ONRESOLVESOURCE: + case BA_FUNCTIONS_MESSAGE_ONCACHEACQUIRECOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONCACHEVERIFYBEGIN: + case BA_FUNCTIONS_MESSAGE_ONCACHEVERIFYCOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONCACHEPACKAGECOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONCACHECOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONEXECUTEBEGIN: + case BA_FUNCTIONS_MESSAGE_ONEXECUTEPACKAGEBEGIN: + case BA_FUNCTIONS_MESSAGE_ONEXECUTEPATCHTARGET: + case BA_FUNCTIONS_MESSAGE_ONEXECUTEPROGRESS: + case BA_FUNCTIONS_MESSAGE_ONEXECUTEMSIMESSAGE: + case BA_FUNCTIONS_MESSAGE_ONEXECUTEFILESINUSE: + case BA_FUNCTIONS_MESSAGE_ONEXECUTEPACKAGECOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONEXECUTECOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONUNREGISTERBEGIN: + case BA_FUNCTIONS_MESSAGE_ONUNREGISTERCOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONAPPLYCOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN: + case BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE: + hr = BalBaseBootstrapperApplicationProc((BOOTSTRAPPER_APPLICATION_MESSAGE)message, pvArgs, pvResults, pvContext); + break; + case BA_FUNCTIONS_MESSAGE_ONTHEMELOADED: + hr = BalBaseBAFunctionsProcOnThemeLoaded(pBAFunctions, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BA_FUNCTIONS_MESSAGE_WNDPROC: + hr = BalBaseBAFunctionsProcWndProc(pBAFunctions, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + } + } + + return hr; +} diff --git a/src/balutil/inc/BalBaseBootstrapperApplication.h b/src/balutil/inc/BalBaseBootstrapperApplication.h new file mode 100644 index 00000000..ac354e7b --- /dev/null +++ b/src/balutil/inc/BalBaseBootstrapperApplication.h @@ -0,0 +1,900 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include +#include + +#include "BootstrapperEngine.h" +#include "BootstrapperApplication.h" +#include "IBootstrapperEngine.h" +#include "IBootstrapperApplication.h" + +#include "balutil.h" +#include "balretry.h" + +class CBalBaseBootstrapperApplication : public IBootstrapperApplication +{ +public: // IUnknown + virtual STDMETHODIMP QueryInterface( + __in REFIID riid, + __out LPVOID *ppvObject + ) + { + if (!ppvObject) + { + return E_INVALIDARG; + } + + *ppvObject = NULL; + + if (::IsEqualIID(__uuidof(IBootstrapperApplication), riid)) + { + *ppvObject = static_cast(this); + } + else if (::IsEqualIID(IID_IUnknown, riid)) + { + *ppvObject = static_cast(this); + } + else // no interface for requested iid + { + return E_NOINTERFACE; + } + + AddRef(); + return S_OK; + } + + virtual STDMETHODIMP_(ULONG) AddRef() + { + return ::InterlockedIncrement(&this->m_cReferences); + } + + virtual STDMETHODIMP_(ULONG) Release() + { + long l = ::InterlockedDecrement(&this->m_cReferences); + if (0 < l) + { + return l; + } + + delete this; + return 0; + } + +public: // IBootstrapperApplication + virtual STDMETHODIMP OnStartup() + { + return S_OK; + } + + virtual STDMETHODIMP OnShutdown( + __inout BOOTSTRAPPER_SHUTDOWN_ACTION* /*pAction*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnSystemShutdown( + __in DWORD dwEndSession, + __inout BOOL* pfCancel + ) + { + HRESULT hr = S_OK; + + // Allow requests to shut down when critical or not applying. + *pfCancel = !(ENDSESSION_CRITICAL & dwEndSession || !m_fApplying); + + return hr; + } + + virtual STDMETHODIMP OnDetectBegin( + __in BOOL /*fInstalled*/, + __in DWORD /*cPackages*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnDetectForwardCompatibleBundle( + __in_z LPCWSTR /*wzBundleId*/, + __in BOOTSTRAPPER_RELATION_TYPE /*relationType*/, + __in_z LPCWSTR /*wzBundleTag*/, + __in BOOL /*fPerMachine*/, + __in DWORD64 /*dw64Version*/, + __inout BOOL* pfCancel, + __inout BOOL* /*pfIgnoreBundle*/ + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnDetectUpdateBegin( + __in_z LPCWSTR /*wzUpdateLocation*/, + __inout BOOL* pfCancel, + __inout BOOL* /*pfSkip*/ + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnDetectUpdate( + __in_z LPCWSTR /*wzUpdateLocation*/, + __in DWORD64 /*dw64Size*/, + __in DWORD64 /*dw64Version*/, + __in_z LPCWSTR /*wzTitle*/, + __in_z LPCWSTR /*wzSummary*/, + __in_z LPCWSTR /*wzContentType*/, + __in_z LPCWSTR /*wzContent*/, + __inout BOOL* pfCancel, + __inout BOOL* /*pfStopProcessingUpdates*/ + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnDetectUpdateComplete( + __in HRESULT /*hrStatus*/, + __inout BOOL* /*pfIgnoreError*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnDetectRelatedBundle( + __in_z LPCWSTR /*wzBundleId*/, + __in BOOTSTRAPPER_RELATION_TYPE /*relationType*/, + __in_z LPCWSTR /*wzBundleTag*/, + __in BOOL /*fPerMachine*/, + __in DWORD64 /*dw64Version*/, + __in BOOTSTRAPPER_RELATED_OPERATION /*operation*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnDetectPackageBegin( + __in_z LPCWSTR /*wzPackageId*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnDetectCompatibleMsiPackage( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzCompatiblePackageId*/, + __in DWORD64 /*dw64CompatiblePackageVersion*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnDetectRelatedMsiPackage( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzUpgradeCode*/, + __in_z LPCWSTR /*wzProductCode*/, + __in BOOL /*fPerMachine*/, + __in DWORD64 /*dw64Version*/, + __in BOOTSTRAPPER_RELATED_OPERATION /*operation*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnDetectTargetMsiPackage( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzProductCode*/, + __in BOOTSTRAPPER_PACKAGE_STATE /*patchState*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnDetectMsiFeature( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzFeatureId*/, + __in BOOTSTRAPPER_FEATURE_STATE /*state*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnDetectPackageComplete( + __in_z LPCWSTR /*wzPackageId*/, + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_PACKAGE_STATE /*state*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnDetectComplete( + __in HRESULT /*hrStatus*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnPlanBegin( + __in DWORD /*cPackages*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnPlanRelatedBundle( + __in_z LPCWSTR /*wzBundleId*/, + __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/, + __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestedState*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnPlanPackageBegin( + __in_z LPCWSTR /*wzPackageId*/, + __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/, + __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestState*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnPlanCompatibleMsiPackageBegin( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzCompatiblePackageId*/, + __in DWORD64 /*dw64CompatiblePackageVersion*/, + __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/, + __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestedState*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnPlanCompatibleMsiPackageComplete( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzCompatiblePackageId*/, + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_PACKAGE_STATE /*state*/, + __in BOOTSTRAPPER_REQUEST_STATE /*requested*/, + __in BOOTSTRAPPER_ACTION_STATE /*execute*/, + __in BOOTSTRAPPER_ACTION_STATE /*rollback*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnPlanTargetMsiPackage( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzProductCode*/, + __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/, + __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestedState*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnPlanMsiFeature( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzFeatureId*/, + __in BOOTSTRAPPER_FEATURE_STATE /*recommendedState*/, + __inout BOOTSTRAPPER_FEATURE_STATE* /*pRequestedState*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnPlanPackageComplete( + __in_z LPCWSTR /*wzPackageId*/, + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_PACKAGE_STATE /*state*/, + __in BOOTSTRAPPER_REQUEST_STATE /*requested*/, + __in BOOTSTRAPPER_ACTION_STATE /*execute*/, + __in BOOTSTRAPPER_ACTION_STATE /*rollback*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnPlanComplete( + __in HRESULT /*hrStatus*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnApplyBegin( + __in DWORD /*dwPhaseCount*/, + __inout BOOL* pfCancel + ) + { + m_fApplying = TRUE; + + m_dwProgressPercentage = 0; + m_dwOverallProgressPercentage = 0; + + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnElevateBegin( + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnElevateComplete( + __in HRESULT /*hrStatus*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnProgress( + __in DWORD dwProgressPercentage, + __in DWORD dwOverallProgressPercentage, + __inout BOOL* pfCancel + ) + { + HRESULT hr = S_OK; + int nResult = IDNOACTION; + + m_dwProgressPercentage = dwProgressPercentage; + m_dwOverallProgressPercentage = dwOverallProgressPercentage; + + if (BOOTSTRAPPER_DISPLAY_EMBEDDED == m_display) + { + hr = m_pEngine->SendEmbeddedProgress(m_dwProgressPercentage, m_dwOverallProgressPercentage, &nResult); + BalExitOnFailure(hr, "Failed to send embedded overall progress."); + + if (IDERROR == nResult) + { + hr = E_FAIL; + } + else if (IDCANCEL == nResult) + { + *pfCancel = TRUE; + } + } + + LExit: + *pfCancel |= CheckCanceled(); + return hr; + } + + virtual STDMETHODIMP OnError( + __in BOOTSTRAPPER_ERROR_TYPE errorType, + __in_z LPCWSTR wzPackageId, + __in DWORD dwCode, + __in_z LPCWSTR /*wzError*/, + __in DWORD /*dwUIHint*/, + __in DWORD /*cData*/, + __in_ecount_z_opt(cData) LPCWSTR* /*rgwzData*/, + __in int /*nRecommendation*/, + __inout int* pResult + ) + { + BalRetryErrorOccurred(wzPackageId, dwCode); + + if (CheckCanceled()) + { + *pResult = IDCANCEL; + } + else if (BOOTSTRAPPER_DISPLAY_FULL == m_display) + { + if (BOOTSTRAPPER_ERROR_TYPE_HTTP_AUTH_SERVER == errorType || BOOTSTRAPPER_ERROR_TYPE_HTTP_AUTH_PROXY == errorType) + { + *pResult = IDTRYAGAIN; + } + } + + return S_OK; + } + + virtual STDMETHODIMP OnRegisterBegin( + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnRegisterComplete( + __in HRESULT /*hrStatus*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnCacheBegin( + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnCachePackageBegin( + __in_z LPCWSTR /*wzPackageId*/, + __in DWORD /*cCachePayloads*/, + __in DWORD64 /*dw64PackageCacheSize*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnCacheAcquireBegin( + __in_z LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in BOOTSTRAPPER_CACHE_OPERATION /*operation*/, + __in_z LPCWSTR /*wzSource*/, + __inout BOOL* pfCancel + ) + { + BalRetryStartPackage(BALRETRY_TYPE_CACHE, wzPackageOrContainerId, wzPayloadId); + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnCacheAcquireProgress( + __in_z LPCWSTR /*wzPackageOrContainerId*/, + __in_z_opt LPCWSTR /*wzPayloadId*/, + __in DWORD64 /*dw64Progress*/, + __in DWORD64 /*dw64Total*/, + __in DWORD /*dwOverallPercentage*/, + __inout BOOL* pfCancel + ) + { + HRESULT hr = S_OK; + int nResult = IDNOACTION; + + // Send progress even though we don't update the numbers to at least give the caller an opportunity + // to cancel. + if (BOOTSTRAPPER_DISPLAY_EMBEDDED == m_display) + { + hr = m_pEngine->SendEmbeddedProgress(m_dwProgressPercentage, m_dwOverallProgressPercentage, &nResult); + BalExitOnFailure(hr, "Failed to send embedded cache progress."); + + if (IDERROR == nResult) + { + hr = E_FAIL; + } + else if (IDCANCEL == nResult) + { + *pfCancel = TRUE; + } + } + + LExit: + *pfCancel |= CheckCanceled(); + return hr; + } + + virtual STDMETHODIMP OnResolveSource( + __in_z LPCWSTR /*wzPackageOrContainerId*/, + __in_z_opt LPCWSTR /*wzPayloadId*/, + __in_z LPCWSTR /*wzLocalSource*/, + __in_z_opt LPCWSTR /*wzDownloadSource*/, + __in BOOTSTRAPPER_RESOLVESOURCE_ACTION /*recommendation*/, + __inout BOOTSTRAPPER_RESOLVESOURCE_ACTION* /*pAction*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnCacheAcquireComplete( + __in_z LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in HRESULT hrStatus, + __in BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION /*recommendation*/, + __inout BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION* pAction + ) + { + HRESULT hr = S_OK; + BOOL fRetry = FALSE; + + if (CheckCanceled()) + { + ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT)); + } + + hr = BalRetryEndPackage(BALRETRY_TYPE_CACHE, wzPackageOrContainerId, wzPayloadId, hrStatus, &fRetry); + ExitOnFailure(hr, "BalRetryEndPackage for cache failed"); + + if (fRetry) + { + *pAction = BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION_RETRY; + } + + LExit: + return hr; + } + + virtual STDMETHODIMP OnCacheVerifyBegin( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzPayloadId*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnCacheVerifyComplete( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzPayloadId*/, + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION /*recommendation*/, + __inout BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION* pAction + ) + { + if (CheckCanceled()) + { + *pAction = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE; + } + + return S_OK; + } + + virtual STDMETHODIMP OnCachePackageComplete( + __in_z LPCWSTR /*wzPackageId*/, + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION /*recommendation*/, + __inout BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION* pAction + ) + { + if (CheckCanceled()) + { + *pAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE; + } + + return S_OK; + } + + virtual STDMETHODIMP OnCacheComplete( + __in HRESULT /*hrStatus*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnExecuteBegin( + __in DWORD /*cExecutingPackages*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnExecutePackageBegin( + __in_z LPCWSTR wzPackageId, + __in BOOL fExecute, + __inout BOOL* pfCancel + ) + { + // Only track retry on execution (not rollback). + if (fExecute) + { + BalRetryStartPackage(BALRETRY_TYPE_EXECUTE, wzPackageId, NULL); + } + + m_fRollingBack = !fExecute; + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnExecutePatchTarget( + __in_z LPCWSTR /*wzPackageId*/, + __in_z LPCWSTR /*wzTargetProductCode*/, + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnExecuteProgress( + __in_z LPCWSTR /*wzPackageId*/, + __in DWORD /*dwProgressPercentage*/, + __in DWORD /*dwOverallProgressPercentage*/, + __inout BOOL* pfCancel + ) + { + HRESULT hr = S_OK; + int nResult = IDNOACTION; + + // Send progress even though we don't update the numbers to at least give the caller an opportunity + // to cancel. + if (BOOTSTRAPPER_DISPLAY_EMBEDDED == m_display) + { + hr = m_pEngine->SendEmbeddedProgress(m_dwProgressPercentage, m_dwOverallProgressPercentage, &nResult); + BalExitOnFailure(hr, "Failed to send embedded execute progress."); + + if (IDERROR == nResult) + { + hr = E_FAIL; + } + else if (IDCANCEL == nResult) + { + *pfCancel = TRUE; + } + } + + LExit: + *pfCancel |= CheckCanceled(); + return hr; + } + + virtual STDMETHODIMP OnExecuteMsiMessage( + __in_z LPCWSTR /*wzPackageId*/, + __in INSTALLMESSAGE /*messageType*/, + __in DWORD /*dwUIHint*/, + __in_z LPCWSTR /*wzMessage*/, + __in DWORD /*cData*/, + __in_ecount_z_opt(cData) LPCWSTR* /*rgwzData*/, + __in int /*nRecommendation*/, + __inout int* pResult + ) + { + if (CheckCanceled()) + { + *pResult = IDCANCEL; + } + + return S_OK; + } + + virtual STDMETHODIMP OnExecuteFilesInUse( + __in_z LPCWSTR /*wzPackageId*/, + __in DWORD /*cFiles*/, + __in_ecount_z(cFiles) LPCWSTR* /*rgwzFiles*/, + __in int /*nRecommendation*/, + __inout int* pResult + ) + { + if (CheckCanceled()) + { + *pResult = IDCANCEL; + } + + return S_OK; + } + + virtual STDMETHODIMP OnExecutePackageComplete( + __in_z LPCWSTR wzPackageId, + __in HRESULT hrStatus, + __in BOOTSTRAPPER_APPLY_RESTART /*restart*/, + __in BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION /*recommendation*/, + __inout BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION* pAction + ) + { + HRESULT hr = S_OK; + BOOL fRetry = FALSE; + + if (CheckCanceled()) + { + ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT)); + } + + hr = BalRetryEndPackage(BALRETRY_TYPE_EXECUTE, wzPackageId, NULL, hrStatus, &fRetry); + ExitOnFailure(hr, "BalRetryEndPackage for execute failed"); + + if (fRetry) + { + *pAction = BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_RETRY; + } + + LExit: + return hr; + } + + virtual STDMETHODIMP OnExecuteComplete( + __in HRESULT /*hrStatus*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnUnregisterBegin( + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnUnregisterComplete( + __in HRESULT /*hrStatus*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP OnApplyComplete( + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_APPLY_RESTART restart, + __in BOOTSTRAPPER_APPLYCOMPLETE_ACTION /*recommendation*/, + __inout BOOTSTRAPPER_APPLYCOMPLETE_ACTION* pAction + ) + { + HRESULT hr = S_OK; + BOOL fRestartRequired = BOOTSTRAPPER_APPLY_RESTART_REQUIRED == restart; + BOOL fShouldBlockRestart = BOOTSTRAPPER_DISPLAY_FULL <= m_display && BOOTSTRAPPER_RESTART_PROMPT >= m_restart; + + if (fRestartRequired && !fShouldBlockRestart) + { + *pAction = BOOTSTRAPPER_APPLYCOMPLETE_ACTION_RESTART; + } + + m_fApplying = FALSE; + + return hr; + } + + virtual STDMETHODIMP OnLaunchApprovedExeBegin( + __inout BOOL* pfCancel + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + + virtual STDMETHODIMP OnLaunchApprovedExeComplete( + __in HRESULT /*hrStatus*/, + __in DWORD /*dwProcessId*/ + ) + { + return S_OK; + } + + virtual STDMETHODIMP_(HRESULT) BAProc( + __in BOOTSTRAPPER_APPLICATION_MESSAGE /*message*/, + __in const LPVOID /*pvArgs*/, + __inout LPVOID /*pvResults*/, + __in_opt LPVOID /*pvContext*/ + ) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP_(void) BAProcFallback( + __in BOOTSTRAPPER_APPLICATION_MESSAGE /*message*/, + __in const LPVOID /*pvArgs*/, + __inout LPVOID /*pvResults*/, + __inout HRESULT* /*phr*/, + __in_opt LPVOID /*pvContext*/ + ) + { + } + +protected: + // + // PromptCancel - prompts the user to close (if not forced). + // + virtual BOOL PromptCancel( + __in HWND hWnd, + __in BOOL fForceCancel, + __in_z_opt LPCWSTR wzMessage, + __in_z_opt LPCWSTR wzCaption + ) + { + ::EnterCriticalSection(&m_csCanceled); + + // Only prompt the user to close if we have not canceled already. + if (!m_fCanceled) + { + if (fForceCancel) + { + m_fCanceled = TRUE; + } + else + { + m_fCanceled = (IDYES == ::MessageBoxW(hWnd, wzMessage, wzCaption, MB_YESNO | MB_ICONEXCLAMATION)); + } + } + + ::LeaveCriticalSection(&m_csCanceled); + + return m_fCanceled; + } + + // + // CheckCanceled - waits if the cancel dialog is up and checks to see if the user canceled the operation. + // + BOOL CheckCanceled() + { + ::EnterCriticalSection(&m_csCanceled); + ::LeaveCriticalSection(&m_csCanceled); + return m_fRollingBack ? FALSE : m_fCanceled; + } + + BOOL IsRollingBack() + { + return m_fRollingBack; + } + + BOOL IsCanceled() + { + return m_fCanceled; + } + + CBalBaseBootstrapperApplication( + __in IBootstrapperEngine* pEngine, + __in const BOOTSTRAPPER_CREATE_ARGS* pArgs, + __in DWORD dwRetryCount = 0, + __in DWORD dwRetryTimeout = 1000 + ) + { + m_cReferences = 1; + m_display = pArgs->pCommand->display; + m_restart = pArgs->pCommand->restart; + + pEngine->AddRef(); + m_pEngine = pEngine; + + ::InitializeCriticalSection(&m_csCanceled); + m_fCanceled = FALSE; + m_fApplying = FALSE; + m_fRollingBack = FALSE; + + BalRetryInitialize(dwRetryCount, dwRetryTimeout); + } + + virtual ~CBalBaseBootstrapperApplication() + { + BalRetryUninitialize(); + ::DeleteCriticalSection(&m_csCanceled); + + ReleaseNullObject(m_pEngine); + } + +protected: + CRITICAL_SECTION m_csCanceled; + BOOL m_fCanceled; + +private: + long m_cReferences; + BOOTSTRAPPER_DISPLAY m_display; + BOOTSTRAPPER_RESTART m_restart; + IBootstrapperEngine* m_pEngine; + + BOOL m_fApplying; + BOOL m_fRollingBack; + + DWORD m_dwProgressPercentage; + DWORD m_dwOverallProgressPercentage; +}; diff --git a/src/balutil/inc/BalBaseBootstrapperApplicationProc.h b/src/balutil/inc/BalBaseBootstrapperApplicationProc.h new file mode 100644 index 00000000..4b8f4ca7 --- /dev/null +++ b/src/balutil/inc/BalBaseBootstrapperApplicationProc.h @@ -0,0 +1,698 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +#include + +#include "BootstrapperEngine.h" +#include "BootstrapperApplication.h" +#include "IBootstrapperEngine.h" +#include "IBootstrapperApplication.h" + +static HRESULT BalBaseBAProcOnDetectBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONDETECTBEGIN_ARGS* pArgs, + __inout BA_ONDETECTBEGIN_RESULTS* pResults + ) +{ + return pBA->OnDetectBegin(pArgs->fInstalled, pArgs->cPackages, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnDetectComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONDETECTCOMPLETE_ARGS* pArgs, + __inout BA_ONDETECTCOMPLETE_RESULTS* /*pResults*/ + ) +{ + return pBA->OnDetectComplete(pArgs->hrStatus); +} + +static HRESULT BalBaseBAProcOnPlanBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONPLANBEGIN_ARGS* pArgs, + __inout BA_ONPLANBEGIN_RESULTS* pResults + ) +{ + return pBA->OnPlanBegin(pArgs->cPackages, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnPlanComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONPLANCOMPLETE_ARGS* pArgs, + __inout BA_ONPLANCOMPLETE_RESULTS* /*pResults*/ + ) +{ + return pBA->OnPlanComplete(pArgs->hrStatus); +} + +static HRESULT BalBaseBAProcOnStartup( + __in IBootstrapperApplication* pBA, + __in BA_ONSTARTUP_ARGS* /*pArgs*/, + __inout BA_ONSTARTUP_RESULTS* /*pResults*/ + ) +{ + return pBA->OnStartup(); +} + +static HRESULT BalBaseBAProcOnShutdown( + __in IBootstrapperApplication* pBA, + __in BA_ONSHUTDOWN_ARGS* /*pArgs*/, + __inout BA_ONSHUTDOWN_RESULTS* pResults + ) +{ + return pBA->OnShutdown(&pResults->action); +} + +static HRESULT BalBaseBAProcOnSystemShutdown( + __in IBootstrapperApplication* pBA, + __in BA_ONSYSTEMSHUTDOWN_ARGS* pArgs, + __inout BA_ONSYSTEMSHUTDOWN_RESULTS* pResults + ) +{ + return pBA->OnSystemShutdown(pArgs->dwEndSession, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnDetectForwardCompatibleBundle( + __in IBootstrapperApplication* pBA, + __in BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS* pArgs, + __inout BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS* pResults + ) +{ + return pBA->OnDetectForwardCompatibleBundle(pArgs->wzBundleId, pArgs->relationType, pArgs->wzBundleTag, pArgs->fPerMachine, pArgs->dw64Version, &pResults->fCancel, &pResults->fIgnoreBundle); +} + +static HRESULT BalBaseBAProcOnDetectUpdateBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONDETECTUPDATEBEGIN_ARGS* pArgs, + __inout BA_ONDETECTUPDATEBEGIN_RESULTS* pResults + ) +{ + return pBA->OnDetectUpdateBegin(pArgs->wzUpdateLocation, &pResults->fCancel, &pResults->fSkip); +} + +static HRESULT BalBaseBAProcOnDetectUpdate( + __in IBootstrapperApplication* pBA, + __in BA_ONDETECTUPDATE_ARGS* pArgs, + __inout BA_ONDETECTUPDATE_RESULTS* pResults + ) +{ + return pBA->OnDetectUpdate(pArgs->wzUpdateLocation, pArgs->dw64Size, pArgs->dw64Version, pArgs->wzTitle, pArgs->wzSummary, pArgs->wzContentType, pArgs->wzContent, &pResults->fCancel, &pResults->fStopProcessingUpdates); +} + +static HRESULT BalBaseBAProcOnDetectUpdateComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONDETECTUPDATECOMPLETE_ARGS* pArgs, + __inout BA_ONDETECTUPDATECOMPLETE_RESULTS* pResults + ) +{ + return pBA->OnDetectUpdateComplete(pArgs->hrStatus, &pResults->fIgnoreError); +} + +static HRESULT BalBaseBAProcOnDetectRelatedBundle( + __in IBootstrapperApplication* pBA, + __in BA_ONDETECTRELATEDBUNDLE_ARGS* pArgs, + __inout BA_ONDETECTRELATEDBUNDLE_RESULTS* pResults + ) +{ + return pBA->OnDetectRelatedBundle(pArgs->wzBundleId, pArgs->relationType, pArgs->wzBundleTag, pArgs->fPerMachine, pArgs->dw64Version, pArgs->operation, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnDetectPackageBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONDETECTPACKAGEBEGIN_ARGS* pArgs, + __inout BA_ONDETECTPACKAGEBEGIN_RESULTS* pResults + ) +{ + return pBA->OnDetectPackageBegin(pArgs->wzPackageId, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnDetectCompatiblePackage( + __in IBootstrapperApplication* pBA, + __in BA_ONDETECTCOMPATIBLEMSIPACKAGE_ARGS* pArgs, + __inout BA_ONDETECTCOMPATIBLEMSIPACKAGE_RESULTS* pResults + ) +{ + return pBA->OnDetectCompatibleMsiPackage(pArgs->wzPackageId, pArgs->wzCompatiblePackageId, pArgs->dw64CompatiblePackageVersion, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnDetectRelatedMsiPackage( + __in IBootstrapperApplication* pBA, + __in BA_ONDETECTRELATEDMSIPACKAGE_ARGS* pArgs, + __inout BA_ONDETECTRELATEDMSIPACKAGE_RESULTS* pResults + ) +{ + return pBA->OnDetectRelatedMsiPackage(pArgs->wzPackageId, pArgs->wzUpgradeCode, pArgs->wzProductCode, pArgs->fPerMachine, pArgs->dw64Version, pArgs->operation, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnDetectTargetMsiPackage( + __in IBootstrapperApplication* pBA, + __in BA_ONDETECTTARGETMSIPACKAGE_ARGS* pArgs, + __inout BA_ONDETECTTARGETMSIPACKAGE_RESULTS* pResults + ) +{ + return pBA->OnDetectTargetMsiPackage(pArgs->wzPackageId, pArgs->wzProductCode, pArgs->patchState, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnDetectMsiFeature( + __in IBootstrapperApplication* pBA, + __in BA_ONDETECTMSIFEATURE_ARGS* pArgs, + __inout BA_ONDETECTMSIFEATURE_RESULTS* pResults + ) +{ + return pBA->OnDetectMsiFeature(pArgs->wzPackageId, pArgs->wzFeatureId, pArgs->state, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnDetectPackageComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONDETECTPACKAGECOMPLETE_ARGS* pArgs, + __inout BA_ONDETECTPACKAGECOMPLETE_RESULTS* /*pResults*/ + ) +{ + return pBA->OnDetectPackageComplete(pArgs->wzPackageId, pArgs->hrStatus, pArgs->state); +} + +static HRESULT BalBaseBAProcOnPlanRelatedBundle( + __in IBootstrapperApplication* pBA, + __in BA_ONPLANRELATEDBUNDLE_ARGS* pArgs, + __inout BA_ONPLANRELATEDBUNDLE_RESULTS* pResults + ) +{ + return pBA->OnPlanRelatedBundle(pArgs->wzBundleId, pArgs->recommendedState, &pResults->requestedState, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnPlanPackageBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONPLANPACKAGEBEGIN_ARGS* pArgs, + __inout BA_ONPLANPACKAGEBEGIN_RESULTS* pResults + ) +{ + return pBA->OnPlanPackageBegin(pArgs->wzPackageId, pArgs->recommendedState, &pResults->requestedState, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnPlanCompatibleMsiPackageBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_ARGS* pArgs, + __inout BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_RESULTS* pResults + ) +{ + return pBA->OnPlanCompatibleMsiPackageBegin(pArgs->wzPackageId, pArgs->wzCompatiblePackageId, pArgs->dw64CompatiblePackageVersion, pArgs->recommendedState, &pResults->requestedState, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnPlanCompatibleMsiPackageComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_ARGS* pArgs, + __inout BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_RESULTS* /*pResults*/ + ) +{ + return pBA->OnPlanCompatibleMsiPackageComplete(pArgs->wzPackageId, pArgs->wzCompatiblePackageId, pArgs->hrStatus, pArgs->state, pArgs->requested, pArgs->execute, pArgs->rollback); +} + +static HRESULT BalBaseBAProcOnPlanTargetMsiPackage( + __in IBootstrapperApplication* pBA, + __in BA_ONPLANTARGETMSIPACKAGE_ARGS* pArgs, + __inout BA_ONPLANTARGETMSIPACKAGE_RESULTS* pResults + ) +{ + return pBA->OnPlanTargetMsiPackage(pArgs->wzPackageId, pArgs->wzProductCode, pArgs->recommendedState, &pResults->requestedState, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnPlanMsiFeature( + __in IBootstrapperApplication* pBA, + __in BA_ONPLANMSIFEATURE_ARGS* pArgs, + __inout BA_ONPLANMSIFEATURE_RESULTS* pResults + ) +{ + return pBA->OnPlanMsiFeature(pArgs->wzPackageId, pArgs->wzFeatureId, pArgs->recommendedState, &pResults->requestedState, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnPlanPackageComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONPLANPACKAGECOMPLETE_ARGS* pArgs, + __inout BA_ONPLANPACKAGECOMPLETE_RESULTS* /*pResults*/ + ) +{ + return pBA->OnPlanPackageComplete(pArgs->wzPackageId, pArgs->hrStatus, pArgs->state, pArgs->requested, pArgs->execute, pArgs->rollback); +} + +static HRESULT BalBaseBAProcOnApplyBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONAPPLYBEGIN_ARGS* pArgs, + __inout BA_ONAPPLYBEGIN_RESULTS* pResults + ) +{ + return pBA->OnApplyBegin(pArgs->dwPhaseCount, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnElevateBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONELEVATEBEGIN_ARGS* /*pArgs*/, + __inout BA_ONELEVATEBEGIN_RESULTS* pResults + ) +{ + return pBA->OnElevateBegin(&pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnElevateComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONELEVATECOMPLETE_ARGS* pArgs, + __inout BA_ONELEVATECOMPLETE_RESULTS* /*pResults*/ + ) +{ + return pBA->OnElevateComplete(pArgs->hrStatus); +} + +static HRESULT BalBaseBAProcOnProgress( + __in IBootstrapperApplication* pBA, + __in BA_ONPROGRESS_ARGS* pArgs, + __inout BA_ONPROGRESS_RESULTS* pResults + ) +{ + return pBA->OnProgress(pArgs->dwProgressPercentage, pArgs->dwOverallPercentage, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnError( + __in IBootstrapperApplication* pBA, + __in BA_ONERROR_ARGS* pArgs, + __inout BA_ONERROR_RESULTS* pResults + ) +{ + return pBA->OnError(pArgs->errorType, pArgs->wzPackageId, pArgs->dwCode, pArgs->wzError, pArgs->dwUIHint, pArgs->cData, pArgs->rgwzData, pArgs->nRecommendation, &pResults->nResult); +} + +static HRESULT BalBaseBAProcOnRegisterBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONREGISTERBEGIN_ARGS* /*pArgs*/, + __inout BA_ONREGISTERBEGIN_RESULTS* pResults + ) +{ + return pBA->OnRegisterBegin(&pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnRegisterComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONREGISTERCOMPLETE_ARGS* pArgs, + __inout BA_ONREGISTERCOMPLETE_RESULTS* /*pResults*/ + ) +{ + return pBA->OnRegisterComplete(pArgs->hrStatus); +} + +static HRESULT BalBaseBAProcOnCacheBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONCACHEBEGIN_ARGS* /*pArgs*/, + __inout BA_ONCACHEBEGIN_RESULTS* pResults + ) +{ + return pBA->OnCacheBegin(&pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnCachePackageBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONCACHEPACKAGEBEGIN_ARGS* pArgs, + __inout BA_ONCACHEPACKAGEBEGIN_RESULTS* pResults + ) +{ + return pBA->OnCachePackageBegin(pArgs->wzPackageId, pArgs->cCachePayloads, pArgs->dw64PackageCacheSize, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnCacheAcquireBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONCACHEACQUIREBEGIN_ARGS* pArgs, + __inout BA_ONCACHEACQUIREBEGIN_RESULTS* pResults + ) +{ + return pBA->OnCacheAcquireBegin(pArgs->wzPackageOrContainerId, pArgs->wzPayloadId, pArgs->operation, pArgs->wzSource, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnCacheAcquireProgress( + __in IBootstrapperApplication* pBA, + __in BA_ONCACHEACQUIREPROGRESS_ARGS* pArgs, + __inout BA_ONCACHEACQUIREPROGRESS_RESULTS* pResults + ) +{ + return pBA->OnCacheAcquireProgress(pArgs->wzPackageOrContainerId, pArgs->wzPayloadId, pArgs->dw64Progress, pArgs->dw64Total, pArgs->dwOverallPercentage, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnResolveSource( + __in IBootstrapperApplication* pBA, + __in BA_ONRESOLVESOURCE_ARGS* pArgs, + __inout BA_ONRESOLVESOURCE_RESULTS* pResults + ) +{ + return pBA->OnResolveSource(pArgs->wzPackageOrContainerId, pArgs->wzPayloadId, pArgs->wzLocalSource, pArgs->wzDownloadSource, pArgs->recommendation, &pResults->action, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnCacheAcquireComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONCACHEACQUIRECOMPLETE_ARGS* pArgs, + __inout BA_ONCACHEACQUIRECOMPLETE_RESULTS* pResults + ) +{ + return pBA->OnCacheAcquireComplete(pArgs->wzPackageOrContainerId, pArgs->wzPayloadId, pArgs->hrStatus, pArgs->recommendation, &pResults->action); +} + +static HRESULT BalBaseBAProcOnCacheVerifyBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONCACHEVERIFYBEGIN_ARGS* pArgs, + __inout BA_ONCACHEVERIFYBEGIN_RESULTS* pResults + ) +{ + return pBA->OnCacheVerifyBegin(pArgs->wzPackageOrContainerId, pArgs->wzPayloadId, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnCacheVerifyComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONCACHEVERIFYCOMPLETE_ARGS* pArgs, + __inout BA_ONCACHEVERIFYCOMPLETE_RESULTS* pResults + ) +{ + return pBA->OnCacheVerifyComplete(pArgs->wzPackageOrContainerId, pArgs->wzPayloadId, pArgs->hrStatus, pArgs->recommendation, &pResults->action); +} + +static HRESULT BalBaseBAProcOnCachePackageComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONCACHEPACKAGECOMPLETE_ARGS* pArgs, + __inout BA_ONCACHEPACKAGECOMPLETE_RESULTS* pResults + ) +{ + return pBA->OnCachePackageComplete(pArgs->wzPackageId, pArgs->hrStatus, pArgs->recommendation, &pResults->action); +} + +static HRESULT BalBaseBAProcOnCacheComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONCACHECOMPLETE_ARGS* pArgs, + __inout BA_ONCACHECOMPLETE_RESULTS* /*pResults*/ + ) +{ + return pBA->OnCacheComplete(pArgs->hrStatus); +} + +static HRESULT BalBaseBAProcOnExecuteBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONEXECUTEBEGIN_ARGS* pArgs, + __inout BA_ONEXECUTEBEGIN_RESULTS* pResults + ) +{ + return pBA->OnExecuteBegin(pArgs->cExecutingPackages, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnExecutePackageBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONEXECUTEPACKAGEBEGIN_ARGS* pArgs, + __inout BA_ONEXECUTEPACKAGEBEGIN_RESULTS* pResults + ) +{ + return pBA->OnExecutePackageBegin(pArgs->wzPackageId, pArgs->fExecute, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnExecutePatchTarget( + __in IBootstrapperApplication* pBA, + __in BA_ONEXECUTEPATCHTARGET_ARGS* pArgs, + __inout BA_ONEXECUTEPATCHTARGET_RESULTS* pResults + ) +{ + return pBA->OnExecutePatchTarget(pArgs->wzPackageId, pArgs->wzTargetProductCode, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnExecuteProgress( + __in IBootstrapperApplication* pBA, + __in BA_ONEXECUTEPROGRESS_ARGS* pArgs, + __inout BA_ONEXECUTEPROGRESS_RESULTS* pResults + ) +{ + return pBA->OnExecuteProgress(pArgs->wzPackageId, pArgs->dwProgressPercentage, pArgs->dwOverallPercentage, &pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnExecuteMsiMessage( + __in IBootstrapperApplication* pBA, + __in BA_ONEXECUTEMSIMESSAGE_ARGS* pArgs, + __inout BA_ONEXECUTEMSIMESSAGE_RESULTS* pResults + ) +{ + return pBA->OnExecuteMsiMessage(pArgs->wzPackageId, pArgs->messageType, pArgs->dwUIHint, pArgs->wzMessage, pArgs->cData, pArgs->rgwzData, pArgs->nRecommendation, &pResults->nResult); +} + +static HRESULT BalBaseBAProcOnExecuteFilesInUse( + __in IBootstrapperApplication* pBA, + __in BA_ONEXECUTEFILESINUSE_ARGS* pArgs, + __inout BA_ONEXECUTEFILESINUSE_RESULTS* pResults + ) +{ + return pBA->OnExecuteFilesInUse(pArgs->wzPackageId, pArgs->cFiles, pArgs->rgwzFiles, pArgs->nRecommendation, &pResults->nResult); +} + +static HRESULT BalBaseBAProcOnExecutePackageComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONEXECUTEPACKAGECOMPLETE_ARGS* pArgs, + __inout BA_ONEXECUTEPACKAGECOMPLETE_RESULTS* pResults + ) +{ + return pBA->OnExecutePackageComplete(pArgs->wzPackageId, pArgs->hrStatus, pArgs->restart, pArgs->recommendation, &pResults->action); +} + +static HRESULT BalBaseBAProcOnExecuteComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONEXECUTECOMPLETE_ARGS* pArgs, + __inout BA_ONEXECUTECOMPLETE_RESULTS* /*pResults*/ + ) +{ + return pBA->OnExecuteComplete(pArgs->hrStatus); +} + +static HRESULT BalBaseBAProcOnUnregisterBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONUNREGISTERBEGIN_ARGS* /*pArgs*/, + __inout BA_ONUNREGISTERBEGIN_RESULTS* pResults + ) +{ + return pBA->OnUnregisterBegin(&pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnUnregisterComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONUNREGISTERCOMPLETE_ARGS* pArgs, + __inout BA_ONUNREGISTERCOMPLETE_RESULTS* /*pResults*/ + ) +{ + return pBA->OnUnregisterComplete(pArgs->hrStatus); +} + +static HRESULT BalBaseBAProcOnApplyComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONAPPLYCOMPLETE_ARGS* pArgs, + __inout BA_ONAPPLYCOMPLETE_RESULTS* pResults + ) +{ + return pBA->OnApplyComplete(pArgs->hrStatus, pArgs->restart, pArgs->recommendation, &pResults->action); +} + +static HRESULT BalBaseBAProcOnLaunchApprovedExeBegin( + __in IBootstrapperApplication* pBA, + __in BA_ONLAUNCHAPPROVEDEXEBEGIN_ARGS* /*pArgs*/, + __inout BA_ONLAUNCHAPPROVEDEXEBEGIN_RESULTS* pResults + ) +{ + return pBA->OnLaunchApprovedExeBegin(&pResults->fCancel); +} + +static HRESULT BalBaseBAProcOnLaunchApprovedExeComplete( + __in IBootstrapperApplication* pBA, + __in BA_ONLAUNCHAPPROVEDEXECOMPLETE_ARGS* pArgs, + __inout BA_ONLAUNCHAPPROVEDEXECOMPLETE_RESULTS* /*pResults*/ + ) +{ + return pBA->OnLaunchApprovedExeComplete(pArgs->hrStatus, pArgs->dwProcessId); +} + +/******************************************************************* +BalBaseBootstrapperApplicationProc - requires pvContext to be of type IBootstrapperApplication. + Provides a default mapping between the new message based BA interface and + the old COM-based BA interface. + +*******************************************************************/ +static HRESULT WINAPI BalBaseBootstrapperApplicationProc( + __in BOOTSTRAPPER_APPLICATION_MESSAGE message, + __in const LPVOID pvArgs, + __inout LPVOID pvResults, + __in_opt LPVOID pvContext + ) +{ + IBootstrapperApplication* pBA = reinterpret_cast(pvContext); + HRESULT hr = pBA->BAProc(message, pvArgs, pvResults, pvContext); + + if (E_NOTIMPL == hr) + { + switch (message) + { + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTBEGIN: + hr = BalBaseBAProcOnDetectBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPLETE: + hr = BalBaseBAProcOnDetectComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANBEGIN: + hr = BalBaseBAProcOnPlanBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPLETE: + hr = BalBaseBAProcOnPlanComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSTARTUP: + hr = BalBaseBAProcOnStartup(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSHUTDOWN: + hr = BalBaseBAProcOnShutdown(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMSHUTDOWN: + hr = BalBaseBAProcOnSystemShutdown(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE: + hr = BalBaseBAProcOnDetectForwardCompatibleBundle(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATEBEGIN: + hr = BalBaseBAProcOnDetectUpdateBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATE: + hr = BalBaseBAProcOnDetectUpdate(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATECOMPLETE: + hr = BalBaseBAProcOnDetectUpdateComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDBUNDLE: + hr = BalBaseBAProcOnDetectRelatedBundle(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGEBEGIN: + hr = BalBaseBAProcOnDetectPackageBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE: + hr = BalBaseBAProcOnDetectCompatiblePackage(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDMSIPACKAGE: + hr = BalBaseBAProcOnDetectRelatedMsiPackage(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTTARGETMSIPACKAGE: + hr = BalBaseBAProcOnDetectTargetMsiPackage(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTMSIFEATURE: + hr = BalBaseBAProcOnDetectMsiFeature(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGECOMPLETE: + hr = BalBaseBAProcOnDetectPackageComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRELATEDBUNDLE: + hr = BalBaseBAProcOnPlanRelatedBundle(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGEBEGIN: + hr = BalBaseBAProcOnPlanPackageBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN: + hr = BalBaseBAProcOnPlanCompatibleMsiPackageBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE: + hr = BalBaseBAProcOnPlanCompatibleMsiPackageComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANTARGETMSIPACKAGE: + hr = BalBaseBAProcOnPlanTargetMsiPackage(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIFEATURE: + hr = BalBaseBAProcOnPlanMsiFeature(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGECOMPLETE: + hr = BalBaseBAProcOnPlanPackageComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYBEGIN: + hr = BalBaseBAProcOnApplyBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATEBEGIN: + hr = BalBaseBAProcOnElevateBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATECOMPLETE: + hr = BalBaseBAProcOnElevateComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPROGRESS: + hr = BalBaseBAProcOnProgress(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONERROR: + hr = BalBaseBAProcOnError(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERBEGIN: + hr = BalBaseBAProcOnRegisterBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERCOMPLETE: + hr = BalBaseBAProcOnRegisterComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEBEGIN: + hr = BalBaseBAProcOnCacheBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGEBEGIN: + hr = BalBaseBAProcOnCachePackageBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREBEGIN: + hr = BalBaseBAProcOnCacheAcquireBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREPROGRESS: + hr = BalBaseBAProcOnCacheAcquireProgress(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONRESOLVESOURCE: + hr = BalBaseBAProcOnResolveSource(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRECOMPLETE: + hr = BalBaseBAProcOnCacheAcquireComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYBEGIN: + hr = BalBaseBAProcOnCacheVerifyBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYCOMPLETE: + hr = BalBaseBAProcOnCacheVerifyComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGECOMPLETE: + hr = BalBaseBAProcOnCachePackageComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECOMPLETE: + hr = BalBaseBAProcOnCacheComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEBEGIN: + hr = BalBaseBAProcOnExecuteBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGEBEGIN: + hr = BalBaseBAProcOnExecutePackageBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPATCHTARGET: + hr = BalBaseBAProcOnExecutePatchTarget(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPROGRESS: + hr = BalBaseBAProcOnExecuteProgress(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEMSIMESSAGE: + hr = BalBaseBAProcOnExecuteMsiMessage(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEFILESINUSE: + hr = BalBaseBAProcOnExecuteFilesInUse(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGECOMPLETE: + hr = BalBaseBAProcOnExecutePackageComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTECOMPLETE: + hr = BalBaseBAProcOnExecuteComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERBEGIN: + hr = BalBaseBAProcOnUnregisterBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERCOMPLETE: + hr = BalBaseBAProcOnUnregisterComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYCOMPLETE: + hr = BalBaseBAProcOnApplyComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN: + hr = BalBaseBAProcOnLaunchApprovedExeBegin(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE: + hr = BalBaseBAProcOnLaunchApprovedExeComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; + } + } + + pBA->BAProcFallback(message, pvArgs, pvResults, &hr, pvContext); + + return hr; +} diff --git a/src/balutil/inc/BalBootstrapperEngine.h b/src/balutil/inc/BalBootstrapperEngine.h new file mode 100644 index 00000000..45131d98 --- /dev/null +++ b/src/balutil/inc/BalBootstrapperEngine.h @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#ifdef __cplusplus +extern "C" { +#endif + +// function declarations + +HRESULT BalBootstrapperEngineCreate( + __in PFN_BOOTSTRAPPER_ENGINE_PROC pfnBAEngineProc, + __in_opt LPVOID pvBAEngineProcContext, + __out IBootstrapperEngine** ppEngineForApplication + ); + +#ifdef __cplusplus +} +#endif diff --git a/src/balutil/inc/IBAFunctions.h b/src/balutil/inc/IBAFunctions.h new file mode 100644 index 00000000..7d8a07fa --- /dev/null +++ b/src/balutil/inc/IBAFunctions.h @@ -0,0 +1,34 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +DECLARE_INTERFACE_IID_(IBAFunctions, IBootstrapperApplication, "0FB445ED-17BD-49C7-BE19-479776F8AE96") +{ + // OnThemeLoaded - Called after the BA finished loading all the controls for the theme. + // + STDMETHOD(OnThemeLoaded)( + THEME* pTheme, + WIX_LOCALIZATION* pWixLoc + ) = 0; + + // WndProc - Called if the BA hasn't handled the message. + // The implementation must either return E_NOTIMPL or call ThemeDefWindowProc for unhandled messages. + // + STDMETHOD(WndProc)( + __in THEME* pTheme, + __in HWND hWnd, + __in UINT uMsg, + __in WPARAM wParam, + __in LPARAM lParam, + __inout LRESULT* plRes + ) = 0; + + // BAFunctionsProc - The PFN_BA_FUNCTIONS_PROC can call this method to give the BAFunctions raw access to the callback from WixStdBA. + // This might be used to help the BAFunctions support more than one version of the engine/WixStdBA. + STDMETHOD(BAFunctionsProc)( + __in BA_FUNCTIONS_MESSAGE message, + __in const LPVOID pvArgs, + __inout LPVOID pvResults, + __in_opt LPVOID pvContext + ) = 0; +}; diff --git a/src/balutil/inc/balcondition.h b/src/balutil/inc/balcondition.h new file mode 100644 index 00000000..677c593f --- /dev/null +++ b/src/balutil/inc/balcondition.h @@ -0,0 +1,58 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _BAL_CONDITION +{ + LPWSTR sczCondition; + LPWSTR sczMessage; +} BAL_CONDITION; + + +typedef struct _BAL_CONDITIONS +{ + BAL_CONDITION* rgConditions; + DWORD cConditions; +} BAL_CONDITIONS; + + +/******************************************************************* + BalConditionsParseFromXml - loads the conditions from the UX manifest. + +********************************************************************/ +DAPI_(HRESULT) BalConditionsParseFromXml( + __in BAL_CONDITIONS* pConditions, + __in IXMLDOMDocument* pixdManifest, + __in_opt WIX_LOCALIZATION* pWixLoc + ); + + +/******************************************************************* + BalConditionEvaluate - evaluates condition against the provided IBurnCore. + + NOTE: psczMessage is optional. +********************************************************************/ +DAPI_(HRESULT) BalConditionEvaluate( + __in BAL_CONDITION* pCondition, + __in IBootstrapperEngine* pEngine, + __out BOOL* pfResult, + __out_z_opt LPWSTR* psczMessage + ); + + +/******************************************************************* + BalConditionsUninitialize - uninitializes any conditions previously loaded. + +********************************************************************/ +DAPI_(void) BalConditionsUninitialize( + __in BAL_CONDITIONS* pConditions + ); + + +#ifdef __cplusplus +} +#endif diff --git a/src/balutil/inc/balinfo.h b/src/balutil/inc/balinfo.h new file mode 100644 index 00000000..be4b75d0 --- /dev/null +++ b/src/balutil/inc/balinfo.h @@ -0,0 +1,107 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum BAL_INFO_PACKAGE_TYPE +{ + BAL_INFO_PACKAGE_TYPE_UNKNOWN, + BAL_INFO_PACKAGE_TYPE_EXE, + BAL_INFO_PACKAGE_TYPE_MSI, + BAL_INFO_PACKAGE_TYPE_MSP, + BAL_INFO_PACKAGE_TYPE_MSU, + BAL_INFO_PACKAGE_TYPE_BUNDLE_UPGRADE, + BAL_INFO_PACKAGE_TYPE_BUNDLE_ADDON, + BAL_INFO_PACKAGE_TYPE_BUNDLE_PATCH, +} BAL_INFO_PACKAGE_TYPE; + +typedef enum BAL_INFO_CACHE_TYPE +{ + BAL_INFO_CACHE_TYPE_NO, + BAL_INFO_CACHE_TYPE_YES, + BAL_INFO_CACHE_TYPE_ALWAYS, +} BAL_INFO_CACHE_TYPE; + + +typedef struct _BAL_INFO_PACKAGE +{ + LPWSTR sczId; + LPWSTR sczDisplayName; + LPWSTR sczDescription; + BAL_INFO_PACKAGE_TYPE type; + BOOL fPermanent; + BOOL fVital; + BOOL fDisplayInternalUI; + LPWSTR sczProductCode; + LPWSTR sczUpgradeCode; + LPWSTR sczVersion; + LPWSTR sczInstallCondition; + BAL_INFO_CACHE_TYPE cacheType; +} BAL_INFO_PACKAGE; + + +typedef struct _BAL_INFO_PACKAGES +{ + BAL_INFO_PACKAGE* rgPackages; + DWORD cPackages; +} BAL_INFO_PACKAGES; + + +typedef struct _BAL_INFO_BUNDLE +{ + BOOL fPerMachine; + LPWSTR sczName; + LPWSTR sczLogVariable; + BAL_INFO_PACKAGES packages; +} BAL_INFO_BUNDLE; + + +/******************************************************************* + BalInfoParseFromXml - loads the bundle and package info from the UX + manifest. + +********************************************************************/ +DAPI_(HRESULT) BalInfoParseFromXml( + __in BAL_INFO_BUNDLE* pBundle, + __in IXMLDOMDocument* pixdManifest + ); + + +/******************************************************************* + BalInfoAddRelatedBundleAsPackage - adds a related bundle as a package. + + ********************************************************************/ +DAPI_(HRESULT) BalInfoAddRelatedBundleAsPackage( + __in BAL_INFO_PACKAGES* pPackages, + __in LPCWSTR wzId, + __in BOOTSTRAPPER_RELATION_TYPE relationType, + __in BOOL fPerMachine + ); + + +/******************************************************************* + BalInfoFindPackageById - finds a package by its id. + + ********************************************************************/ +DAPI_(HRESULT) BalInfoFindPackageById( + __in BAL_INFO_PACKAGES* pPackages, + __in LPCWSTR wzId, + __out BAL_INFO_PACKAGE** ppPackage + ); + + +/******************************************************************* + BalInfoUninitialize - uninitializes any info previously loaded. + +********************************************************************/ +DAPI_(void) BalInfoUninitialize( + __in BAL_INFO_BUNDLE* pBundle + ); + + +#ifdef __cplusplus +} +#endif diff --git a/src/balutil/inc/balretry.h b/src/balutil/inc/balretry.h new file mode 100644 index 00000000..040ab4ae --- /dev/null +++ b/src/balutil/inc/balretry.h @@ -0,0 +1,65 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum BALRETRY_TYPE +{ + BALRETRY_TYPE_CACHE, + BALRETRY_TYPE_EXECUTE, +} BALRETRY_TYPE; + +/******************************************************************* + BalRetryInitialize - initialize the retry count and timeout between + retries (in milliseconds). +********************************************************************/ +DAPI_(void) BalRetryInitialize( + __in DWORD dwMaxRetries, + __in DWORD dwTimeout + ); + +/******************************************************************* + BalRetryUninitialize - call to cleanup any memory allocated during + use of the retry utility. +********************************************************************/ +DAPI_(void) BalRetryUninitialize(); + +/******************************************************************* + BalRetryStartPackage - call when a package begins to be modified. If + the package is being retried, the function will + wait the specified timeout. +********************************************************************/ +DAPI_(void) BalRetryStartPackage( + __in BALRETRY_TYPE type, + __in_z_opt LPCWSTR wzPackageId, + __in_z_opt LPCWSTR wzPayloadId + ); + +/******************************************************************* + BalRetryErrorOccured - call when an error occurs for the retry utility + to consider. +********************************************************************/ +DAPI_(void) BalRetryErrorOccurred( + __in_z_opt LPCWSTR wzPackageId, + __in DWORD dwError + ); + +/******************************************************************* + BalRetryEndPackage - returns IDRETRY is a retry is recommended or + IDNOACTION if a retry is not recommended. +********************************************************************/ +DAPI_(HRESULT) BalRetryEndPackage( + __in BALRETRY_TYPE type, + __in_z_opt LPCWSTR wzPackageId, + __in_z_opt LPCWSTR wzPayloadId, + __in HRESULT hrError, + __inout BOOL* pfRetry + ); + + +#ifdef __cplusplus +} +#endif diff --git a/src/balutil/inc/balutil.h b/src/balutil/inc/balutil.h new file mode 100644 index 00000000..0fbaab97 --- /dev/null +++ b/src/balutil/inc/balutil.h @@ -0,0 +1,165 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +#include "dutil.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +#define BalExitOnFailure(x, f, ...) if (FAILED(x)) { BalLogError(x, f, __VA_ARGS__); ExitTrace(x, f, __VA_ARGS__); goto LExit; } +#define BalExitOnRootFailure(x, f, ...) if (FAILED(x)) { BalLogError(x, f, __VA_ARGS__); Dutil_RootFailure(__FILE__, __LINE__, x); ExitTrace(x, f, __VA_ARGS__); goto LExit; } +#define BalExitOnNullWithLastError(p, x, f, ...) if (NULL == p) { DWORD Dutil_er = ::GetLastError(); x = HRESULT_FROM_WIN32(Dutil_er); if (!FAILED(x)) { x = E_FAIL; } BalLogError(x, f, __VA_ARGS__); ExitTrace(x, f, __VA_ARGS__); goto LExit; } + +#define FACILITY_WIX 500 + +const LPCWSTR BAL_MANIFEST_FILENAME = L"BootstrapperApplicationData.xml"; + +static const HRESULT E_WIXSTDBA_CONDITION_FAILED = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIX, 1); + +static const HRESULT E_MBAHOST_NET452_ON_WIN7RTM = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIX, 1000); + + +/******************************************************************* + BalInitialize - remembers the engine interface to enable logging and + other functions. + +********************************************************************/ +DAPI_(void) BalInitialize( + __in IBootstrapperEngine* pEngine + ); + +/******************************************************************* + BalInitializeFromCreateArgs - convenience function to call BalBootstrapperEngineCreate + then pass it along to BalInitialize. + +********************************************************************/ +DAPI_(HRESULT) BalInitializeFromCreateArgs( + __in const BOOTSTRAPPER_CREATE_ARGS* pArgs, + __out IBootstrapperEngine** ppEngine + ); + +/******************************************************************* + BalUninitialize - cleans up utility layer internals. + +********************************************************************/ +DAPI_(void) BalUninitialize(); + +/******************************************************************* + BalManifestLoad - loads the Application manifest into an XML document. + +********************************************************************/ +DAPI_(HRESULT) BalManifestLoad( + __in HMODULE hUXModule, + __out IXMLDOMDocument** ppixdManifest + ); + +/******************************************************************* +BalEvaluateCondition - evaluates a condition using variables in the engine. + +********************************************************************/ +DAPI_(HRESULT) BalEvaluateCondition( + __in_z LPCWSTR wzCondition, + __out BOOL* pf + ); + +/******************************************************************* +BalFormatString - formats a string using variables in the engine. + + Note: Use StrFree() to release psczOut. +********************************************************************/ +DAPI_(HRESULT) BalFormatString( + __in_z LPCWSTR wzFormat, + __inout LPWSTR* psczOut + ); + +/******************************************************************* +BalGetNumericVariable - gets a number from a variable in the engine. + + Note: Returns E_NOTFOUND if variable does not exist. +********************************************************************/ +DAPI_(HRESULT) BalGetNumericVariable( + __in_z LPCWSTR wzVariable, + __out LONGLONG* pllValue + ); + +/******************************************************************* +BalSetNumericVariable - sets a numeric variable in the engine. + +********************************************************************/ +DAPI_(HRESULT) BalSetNumericVariable( + __in_z LPCWSTR wzVariable, + __in LONGLONG llValue + ); + +/******************************************************************* +BalStringVariableExists - checks if a string variable exists in the engine. + +********************************************************************/ +DAPI_(BOOL) BalStringVariableExists( + __in_z LPCWSTR wzVariable + ); + +/******************************************************************* +BalGetStringVariable - gets a string from a variable in the engine. + + Note: Use StrFree() to release psczValue. +********************************************************************/ +DAPI_(HRESULT) BalGetStringVariable( + __in_z LPCWSTR wzVariable, + __inout LPWSTR* psczValue + ); + +/******************************************************************* +BalSetStringVariable - sets a string variable in the engine. + +********************************************************************/ +DAPI_(HRESULT) BalSetStringVariable( + __in_z LPCWSTR wzVariable, + __in_z_opt LPCWSTR wzValue + ); + +/******************************************************************* + BalLog - logs a message with the engine. + +********************************************************************/ +DAPIV_(HRESULT) BalLog( + __in BOOTSTRAPPER_LOG_LEVEL level, + __in_z __format_string LPCSTR szFormat, + ... + ); + +/******************************************************************* + BalLogError - logs an error message with the engine. + +********************************************************************/ +DAPIV_(HRESULT) BalLogError( + __in HRESULT hr, + __in_z __format_string LPCSTR szFormat, + ... + ); + +/******************************************************************* +BalLogId - logs a message with the engine with a string embedded in a + MESSAGETABLE resource. + +********************************************************************/ +DAPIV_(HRESULT) BalLogId( + __in BOOTSTRAPPER_LOG_LEVEL level, + __in DWORD dwLogId, + __in HMODULE hModule, + ... + ); + +DAPI_(HRESULT) BalLogIdArgs( + __in BOOTSTRAPPER_LOG_LEVEL level, + __in DWORD dwLogId, + __in HMODULE hModule, + __in va_list args + ); + +#ifdef __cplusplus +} +#endif diff --git a/src/balutil/precomp.h b/src/balutil/precomp.h new file mode 100644 index 00000000..89607416 --- /dev/null +++ b/src/balutil/precomp.h @@ -0,0 +1,31 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "BootstrapperEngine.h" +#include "BootstrapperApplication.h" +#include "IBootstrapperEngine.h" +#include "IBootstrapperApplication.h" + +#include "BAFunctions.h" +#include "IBAFunctions.h" + +#include "balutil.h" +#include "BalBootstrapperEngine.h" +#include "balcondition.h" +#include "balinfo.h" +#include "balretry.h" -- cgit v1.2.3-55-g6feb