From 0d3d54992104288e9ee0c834d0b96e8502fd2d42 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Thu, 11 Jan 2024 18:26:20 -0800 Subject: Move the BootstrapperApplication out of proc --- src/burn/engine/EngineForApplication.cpp | 548 -- src/burn/engine/EngineForApplication.h | 59 - src/burn/engine/apply.cpp | 157 +- src/burn/engine/bacallback.cpp | 5893 ++++++++++++++++++++ src/burn/engine/bacallback.h | 520 ++ src/burn/engine/baengine.cpp | 1532 +++++ src/burn/engine/baengine.h | 84 + src/burn/engine/bootstrapperapplication.cpp | 692 +++ src/burn/engine/bootstrapperapplication.h | 160 + src/burn/engine/bundlepackageengine.cpp | 2 +- src/burn/engine/burnpipe.cpp | 6 +- src/burn/engine/cache.cpp | 46 +- src/burn/engine/cache.h | 8 +- src/burn/engine/core.cpp | 225 +- src/burn/engine/core.h | 18 +- src/burn/engine/detect.cpp | 15 +- src/burn/engine/elevation.cpp | 92 +- src/burn/engine/engine.cpp | 243 +- src/burn/engine/engine.mc | 9 +- src/burn/engine/engine.vcxproj | 33 +- src/burn/engine/externalengine.cpp | 163 +- src/burn/engine/externalengine.h | 21 +- src/burn/engine/inc/engine.h | 4 - src/burn/engine/logging.cpp | 5 +- src/burn/engine/manifest.cpp | 6 +- src/burn/engine/msiengine.cpp | 16 +- src/burn/engine/mspengine.cpp | 4 +- src/burn/engine/payload.cpp | 1 + src/burn/engine/plan.cpp | 32 +- src/burn/engine/platform.h | 5 +- src/burn/engine/precomp.h | 8 +- src/burn/engine/registration.cpp | 12 +- src/burn/engine/splashscreen.cpp | 2 +- src/burn/engine/uithread.cpp | 2 +- src/burn/engine/update.cpp | 1 + src/burn/engine/update.h | 1 + src/burn/engine/userexperience.cpp | 5782 ++++++++++--------- src/burn/engine/userexperience.h | 88 +- src/burn/engine/variable.cpp | 6 +- src/burn/stub/stub.cpp | 15 +- src/burn/stub/stub.manifest | 18 + src/burn/stub/stub.vcxproj | 7 +- src/burn/test/BurnUnitTest/ElevationTest.cpp | 1 - src/burn/test/BurnUnitTest/EmbeddedTest.cpp | 1 - src/burn/test/BurnUnitTest/ExitCodeTest.cpp | 1 - src/burn/test/BurnUnitTest/ManifestTest.cpp | 4 +- src/burn/test/BurnUnitTest/PlanTest.cpp | 18 +- src/burn/test/BurnUnitTest/RegistrationTest.cpp | 56 +- src/burn/test/BurnUnitTest/RelatedBundleTest.cpp | 4 +- .../BasicFunctionality_BundleA_manifest.xml | 37 +- .../PlanTest/BundlePackage_Multiple_manifest.xml | 68 +- .../ExePackage_PerUserArpEntry_manifest.xml | 62 +- .../TestData/PlanTest/Failure_BundleD_manifest.xml | 63 +- .../PlanTest/MsiTransaction_BundleAv1_manifest.xml | 68 +- .../PlanTest/MsuPackageFixture_manifest.xml | 22 +- .../PlanTest/Slipstream_BundleA_manifest.xml | 75 +- .../Slipstream_BundleA_modified_manifest.xml | 69 +- src/burn/test/BurnUnitTest/VariableTest.cpp | 2 +- src/burn/test/BurnUnitTest/precomp.h | 5 +- 59 files changed, 12688 insertions(+), 4409 deletions(-) delete mode 100644 src/burn/engine/EngineForApplication.cpp delete mode 100644 src/burn/engine/EngineForApplication.h create mode 100644 src/burn/engine/bacallback.cpp create mode 100644 src/burn/engine/bacallback.h create mode 100644 src/burn/engine/baengine.cpp create mode 100644 src/burn/engine/baengine.h create mode 100644 src/burn/engine/bootstrapperapplication.cpp create mode 100644 src/burn/engine/bootstrapperapplication.h create mode 100644 src/burn/stub/stub.manifest (limited to 'src/burn') diff --git a/src/burn/engine/EngineForApplication.cpp b/src/burn/engine/EngineForApplication.cpp deleted file mode 100644 index eb77cc50..00000000 --- a/src/burn/engine/EngineForApplication.cpp +++ /dev/null @@ -1,548 +0,0 @@ -// 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" - - -static HRESULT BAEngineGetPackageCount( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_GETPACKAGECOUNT_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_GETPACKAGECOUNT_RESULTS, pResults); - - ExternalEngineGetPackageCount(pContext->pEngineState, &pResults->cPackages); - -LExit: - return hr; -} - -static HRESULT BAEngineGetVariableNumeric( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_GETVARIABLENUMERIC_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_GETVARIABLENUMERIC_RESULTS, pResults); - - hr = ExternalEngineGetVariableNumeric(pContext->pEngineState, pArgs->wzVariable, &pResults->llValue); - -LExit: - return hr; -} - -static HRESULT BAEngineGetVariableString( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_GETVARIABLESTRING_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_GETVARIABLESTRING_RESULTS, pResults); - - hr = ExternalEngineGetVariableString(pContext->pEngineState, pArgs->wzVariable, pResults->wzValue, &pResults->cchValue); - -LExit: - return hr; -} - -static HRESULT BAEngineGetVariableVersion( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_GETVARIABLEVERSION_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_GETVARIABLEVERSION_RESULTS, pResults); - - hr = ExternalEngineGetVariableVersion(pContext->pEngineState, pArgs->wzVariable, pResults->wzValue, &pResults->cchValue); - -LExit: - return hr; -} - -static HRESULT BAEngineFormatString( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_FORMATSTRING_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_FORMATSTRING_RESULTS, pResults); - - hr = ExternalEngineFormatString(pContext->pEngineState, pArgs->wzIn, pResults->wzOut, &pResults->cchOut); - -LExit: - return hr; -} - -static HRESULT BAEngineEscapeString( - __in BOOTSTRAPPER_ENGINE_CONTEXT* /*pContext*/, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_ESCAPESTRING_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_ESCAPESTRING_RESULTS, pResults); - - hr = ExternalEngineEscapeString(pArgs->wzIn, pResults->wzOut, &pResults->cchOut); - -LExit: - return hr; -} - -static HRESULT BAEngineEvaluateCondition( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_EVALUATECONDITION_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_EVALUATECONDITION_RESULTS, pResults); - - hr = ExternalEngineEvaluateCondition(pContext->pEngineState, pArgs->wzCondition, &pResults->f); - -LExit: - return hr; -} - -static HRESULT BAEngineLog( - __in BOOTSTRAPPER_ENGINE_CONTEXT* /*pContext*/, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - REPORT_LEVEL rl = REPORT_NONE; - ValidateMessageArgs(hr, pvArgs, BAENGINE_LOG_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_LOG_RESULTS, pResults); - - switch (pArgs->level) - { - case BOOTSTRAPPER_LOG_LEVEL_STANDARD: - rl = REPORT_STANDARD; - break; - - case BOOTSTRAPPER_LOG_LEVEL_VERBOSE: - rl = REPORT_VERBOSE; - break; - - case BOOTSTRAPPER_LOG_LEVEL_DEBUG: - rl = REPORT_DEBUG; - break; - - case BOOTSTRAPPER_LOG_LEVEL_ERROR: - rl = REPORT_ERROR; - break; - - default: - ExitFunction1(hr = E_INVALIDARG); - } - - hr = ExternalEngineLog(rl, pArgs->wzMessage); - ExitOnFailure(hr, "Failed to log BA message."); - -LExit: - return hr; -} - -static HRESULT BAEngineSendEmbeddedError( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_SENDEMBEDDEDERROR_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_SENDEMBEDDEDERROR_RESULTS, pResults); - - hr = ExternalEngineSendEmbeddedError(pContext->pEngineState, pArgs->dwErrorCode, pArgs->wzMessage, pArgs->dwUIHint, &pResults->nResult); - -LExit: - return hr; -} - -static HRESULT BAEngineSendEmbeddedProgress( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_SENDEMBEDDEDPROGRESS_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_SENDEMBEDDEDPROGRESS_RESULTS, pResults); - - hr = ExternalEngineSendEmbeddedProgress(pContext->pEngineState, pArgs->dwProgressPercentage, pArgs->dwOverallProgressPercentage, &pResults->nResult); - -LExit: - return hr; -} - -static HRESULT BAEngineSetUpdate( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_SETUPDATE_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_SETUPDATE_RESULTS, pResults); - - hr = ExternalEngineSetUpdate(pContext->pEngineState, pArgs->wzLocalSource, pArgs->wzDownloadSource, pArgs->qwSize, pArgs->hashType, pArgs->wzHash); - -LExit: - return hr; -} - -static HRESULT BAEngineSetLocalSource( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_SETLOCALSOURCE_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_SETLOCALSOURCE_RESULTS, pResults); - - hr = ExternalEngineSetLocalSource(pContext->pEngineState, pArgs->wzPackageOrContainerId, pArgs->wzPayloadId, pArgs->wzPath); - -LExit: - return hr; -} - -static HRESULT BAEngineSetDownloadSource( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_SETDOWNLOADSOURCE_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_SETDOWNLOADSOURCE_RESULTS, pResults); - - hr = ExternalEngineSetDownloadSource(pContext->pEngineState, pArgs->wzPackageOrContainerId, pArgs->wzPayloadId, pArgs->wzUrl, pArgs->wzUser, pArgs->wzPassword); - -LExit: - return hr; -} - -static HRESULT BAEngineSetVariableNumeric( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_SETVARIABLENUMERIC_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_SETVARIABLENUMERIC_RESULTS, pResults); - - hr = ExternalEngineSetVariableNumeric(pContext->pEngineState, pArgs->wzVariable, pArgs->llValue); - -LExit: - return hr; -} - -static HRESULT BAEngineSetVariableString( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_SETVARIABLESTRING_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_SETVARIABLESTRING_RESULTS, pResults); - - hr = ExternalEngineSetVariableString(pContext->pEngineState, pArgs->wzVariable, pArgs->wzValue, pArgs->fFormatted); - -LExit: - return hr; -} - -static HRESULT BAEngineSetVariableVersion( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_SETVARIABLEVERSION_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_SETVARIABLEVERSION_RESULTS, pResults); - - hr = ExternalEngineSetVariableVersion(pContext->pEngineState, pArgs->wzVariable, pArgs->wzValue); - -LExit: - return hr; -} - -static HRESULT BAEngineCloseSplashScreen( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_CLOSESPLASHSCREEN_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_CLOSESPLASHSCREEN_RESULTS, pResults); - - ExternalEngineCloseSplashScreen(pContext->pEngineState); - -LExit: - return hr; -} - -static HRESULT BAEngineCompareVersions( - __in BOOTSTRAPPER_ENGINE_CONTEXT* /*pContext*/, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_COMPAREVERSIONS_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_COMPAREVERSIONS_RESULTS, pResults); - - hr = ExternalEngineCompareVersions(pArgs->wzVersion1, pArgs->wzVersion2, &pResults->nResult); - -LExit: - return hr; -} - -static HRESULT BAEngineDetect( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_DETECT_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_DETECT_RESULTS, pResults); - - hr = ExternalEngineDetect(pContext, pArgs->hwndParent); - -LExit: - return hr; -} - -static HRESULT BAEnginePlan( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_PLAN_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_PLAN_RESULTS, pResults); - - hr = ExternalEnginePlan(pContext, pArgs->action); - -LExit: - return hr; -} - -static HRESULT BAEngineElevate( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_ELEVATE_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_ELEVATE_RESULTS, pResults); - - hr = ExternalEngineElevate(pContext, pArgs->hwndParent); - -LExit: - return hr; -} - -static HRESULT BAEngineApply( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_APPLY_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_APPLY_RESULTS, pResults); - - hr = ExternalEngineApply(pContext, pArgs->hwndParent); - -LExit: - return hr; -} - -static HRESULT BAEngineQuit( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_QUIT_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_QUIT_RESULTS, pResults); - - hr = ExternalEngineQuit(pContext, pArgs->dwExitCode); - -LExit: - return hr; -} - -static HRESULT BAEngineLaunchApprovedExe( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_LAUNCHAPPROVEDEXE_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_LAUNCHAPPROVEDEXE_RESULTS, pResults); - - hr = ExternalEngineLaunchApprovedExe(pContext, pArgs->hwndParent, pArgs->wzApprovedExeForElevationId, pArgs->wzArguments, pArgs->dwWaitForInputIdleTimeout); - -LExit: - return hr; -} - -static HRESULT BAEngineSetUpdateSource( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_SETUPDATESOURCE_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_SETUPDATESOURCE_RESULTS, pResults); - - hr = ExternalEngineSetUpdateSource(pContext->pEngineState, pArgs->wzUrl); - -LExit: - return hr; -} - -static HRESULT BAEngineGetRelatedBundleVariable( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pContext, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - ValidateMessageArgs(hr, pvArgs, BAENGINE_GETRELATEDBUNDLEVARIABLE_ARGS, pArgs); - ValidateMessageResults(hr, pvResults, BAENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS, pResults); - - hr = ExternalEngineGetRelatedBundleVariable(pContext->pEngineState, pArgs->wzBundleId, pArgs->wzVariable, pResults->wzValue, &pResults->cchValue); - -LExit: - return hr; -} - -HRESULT WINAPI EngineForApplicationProc( - __in BOOTSTRAPPER_ENGINE_MESSAGE message, - __in const LPVOID pvArgs, - __inout LPVOID pvResults, - __in_opt LPVOID pvContext - ) -{ - HRESULT hr = S_OK; - BOOTSTRAPPER_ENGINE_CONTEXT* pContext = reinterpret_cast(pvContext); - - if (!pContext || !pvArgs || !pvResults) - { - ExitFunction1(hr = E_INVALIDARG); - } - - switch (message) - { - case BOOTSTRAPPER_ENGINE_MESSAGE_GETPACKAGECOUNT: - hr = BAEngineGetPackageCount(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_GETVARIABLENUMERIC: - hr = BAEngineGetVariableNumeric(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_GETVARIABLESTRING: - hr = BAEngineGetVariableString(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_GETVARIABLEVERSION: - hr = BAEngineGetVariableVersion(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_FORMATSTRING: - hr = BAEngineFormatString(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_ESCAPESTRING: - hr = BAEngineEscapeString(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_EVALUATECONDITION: - hr = BAEngineEvaluateCondition(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_LOG: - hr = BAEngineLog(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_SENDEMBEDDEDERROR: - hr = BAEngineSendEmbeddedError(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_SENDEMBEDDEDPROGRESS: - hr = BAEngineSendEmbeddedProgress(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_SETUPDATE: - hr = BAEngineSetUpdate(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_SETLOCALSOURCE: - hr = BAEngineSetLocalSource(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_SETDOWNLOADSOURCE: - hr = BAEngineSetDownloadSource(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_SETVARIABLENUMERIC: - hr = BAEngineSetVariableNumeric(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_SETVARIABLESTRING: - hr = BAEngineSetVariableString(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_SETVARIABLEVERSION: - hr = BAEngineSetVariableVersion(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_CLOSESPLASHSCREEN: - hr = BAEngineCloseSplashScreen(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_DETECT: - hr = BAEngineDetect(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_PLAN: - hr = BAEnginePlan(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_ELEVATE: - hr = BAEngineElevate(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_APPLY: - hr = BAEngineApply(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_QUIT: - hr = BAEngineQuit(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_LAUNCHAPPROVEDEXE: - hr = BAEngineLaunchApprovedExe(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_SETUPDATESOURCE: - hr = BAEngineSetUpdateSource(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_COMPAREVERSIONS: - hr = BAEngineCompareVersions(pContext, pvArgs, pvResults); - break; - case BOOTSTRAPPER_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE: - hr = BAEngineGetRelatedBundleVariable(pContext, pvArgs, pvResults); - break; - default: - hr = E_NOTIMPL; - break; - } - -LExit: - return hr; -} diff --git a/src/burn/engine/EngineForApplication.h b/src/burn/engine/EngineForApplication.h deleted file mode 100644 index bf86b7ee..00000000 --- a/src/burn/engine/EngineForApplication.h +++ /dev/null @@ -1,59 +0,0 @@ -#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. - - -#if defined(__cplusplus) -extern "C" { -#endif - -// structs - -typedef struct _BOOTSTRAPPER_ENGINE_CONTEXT -{ - BURN_ENGINE_STATE* pEngineState; - QUEUTIL_QUEUE_HANDLE hQueue; - HANDLE hQueueSemaphore; - CRITICAL_SECTION csQueue; -} BOOTSTRAPPER_ENGINE_CONTEXT; - -typedef struct _BOOTSTRAPPER_ENGINE_ACTION -{ - WM_BURN dwMessage; - union - { - struct - { - HWND hwndParent; - } detect; - struct - { - BOOTSTRAPPER_ACTION action; - } plan; - struct - { - HWND hwndParent; - } elevate; - struct - { - HWND hwndParent; - } apply; - BURN_LAUNCH_APPROVED_EXE launchApprovedExe; - struct - { - DWORD dwExitCode; - } quit; - }; -} BOOTSTRAPPER_ENGINE_ACTION; - -// function declarations - -HRESULT WINAPI EngineForApplicationProc( - __in BOOTSTRAPPER_ENGINE_MESSAGE message, - __in const LPVOID pvArgs, - __inout LPVOID pvResults, - __in_opt LPVOID pvContext - ); - -#if defined(__cplusplus) -} -#endif diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp index f3b05cf8..6908e955 100644 --- a/src/burn/engine/apply.cpp +++ b/src/burn/engine/apply.cpp @@ -390,7 +390,7 @@ extern "C" void ApplyReset( __in BURN_PACKAGES* pPackages ) { - UserExperienceExecuteReset(pUX); + BootstrapperApplicationExecuteReset(pUX); for (DWORD i = 0; i < pPackages->cPackages; ++i) { @@ -444,7 +444,7 @@ extern "C" HRESULT ApplyRegister( CalculateKeepRegistration(pEngineState, FALSE, ®istrationType, &qwEstimatedSize); - hr = UserExperienceOnRegisterBegin(&pEngineState->userExperience, ®istrationType); + hr = BACallbackOnRegisterBegin(&pEngineState->userExperience, ®istrationType); ExitOnRootFailure(hr, "BA aborted register begin."); hr = CacheCalculateBundleWorkingPath(pEngineState->plan.pCache, pEngineState->registration.sczExecutableName, &sczEngineWorkingPath); @@ -474,7 +474,7 @@ extern "C" HRESULT ApplyRegister( } LExit: - UserExperienceOnRegisterComplete(&pEngineState->userExperience, hr); + BACallbackOnRegisterComplete(&pEngineState->userExperience, hr); ReleaseStr(sczEngineWorkingPath); return hr; @@ -518,7 +518,7 @@ extern "C" HRESULT ApplyUnregister( registrationType = defaultRegistrationType; - UserExperienceOnUnregisterBegin(&pEngineState->userExperience, ®istrationType); + BACallbackOnUnregisterBegin(&pEngineState->userExperience, ®istrationType); // Barring the special cases, if it was determined that we should keep the registration then // do that, otherwise the resume mode is NONE and registration will be removed. @@ -560,7 +560,7 @@ extern "C" HRESULT ApplyUnregister( pEngineState->resumeMode = resumeMode; LExit: - UserExperienceOnUnregisterComplete(&pEngineState->userExperience, hr); + BACallbackOnUnregisterComplete(&pEngineState->userExperience, hr); return hr; } @@ -579,7 +579,7 @@ extern "C" HRESULT ApplyCache( BURN_CACHE_CONTEXT cacheContext = { }; BURN_PACKAGE* pPackage = NULL; - hr = UserExperienceOnCacheBegin(pUX); + hr = BACallbackOnCacheBegin(pUX); ExitOnRootFailure(hr, "BA aborted cache."); hr = CacheEnsureAcquisitionFolder(pPlan->pCache); @@ -681,7 +681,7 @@ LExit: ReleaseMem(cacheContext.rgSearchPaths); ReleaseStr(cacheContext.sczLocalAcquisitionSourcePath); - UserExperienceOnCacheComplete(pUX, hr); + BACallbackOnCacheComplete(pUX, hr); return hr; } @@ -716,7 +716,7 @@ extern "C" HRESULT ApplyExecute( *pfSuspend = FALSE; // Send execute begin to BA. - hr = UserExperienceOnExecuteBegin(&pEngineState->userExperience, pEngineState->plan.cExecutePackagesTotal); + hr = BACallbackOnExecuteBegin(&pEngineState->userExperience, pEngineState->plan.cExecutePackagesTotal); ExitOnRootFailure(hr, "BA aborted execute begin."); // Do execute actions. @@ -840,7 +840,7 @@ extern "C" HRESULT ApplyExecute( LExit: // Send execute complete to BA. - UserExperienceOnExecuteComplete(&pEngineState->userExperience, hr); + BACallbackOnExecuteComplete(&pEngineState->userExperience, hr); return hr; } @@ -983,7 +983,7 @@ static HRESULT ApplyCachePackage( { fCanceledBegin = FALSE; - hr = UserExperienceOnCachePackageBegin(pContext->pUX, pPackage->sczId, pPackage->payloads.cItems, pPackage->payloads.qwTotalSize, fVital); + hr = BACallbackOnCachePackageBegin(pContext->pUX, pPackage->sczId, pPackage->payloads.cItems, pPackage->payloads.qwTotalSize, fVital); if (FAILED(hr)) { fCanceledBegin = TRUE; @@ -1004,7 +1004,7 @@ static HRESULT ApplyCachePackage( pPackage->hrCacheResult = hr; cachePackageCompleteAction = SUCCEEDED(hr) || (pPackage->fVital && fVital) || fCanceledBegin ? BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE : BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE; - UserExperienceOnCachePackageComplete(pContext->pUX, pPackage->sczId, hr, &cachePackageCompleteAction); + BACallbackOnCachePackageComplete(pContext->pUX, pPackage->sczId, hr, &cachePackageCompleteAction); if (SUCCEEDED(hr)) { @@ -1248,7 +1248,7 @@ static HRESULT ApplyProcessPayload( } else if (pPackage && !pPackage->fAcquireOptionalSource && !fVital) { - HRESULT hrResponse = UserExperienceOnCachePackageNonVitalValidationFailure(pContext->pUX, pPackage->sczId, hr, &action); + HRESULT hrResponse = BACallbackOnCachePackageNonVitalValidationFailure(pContext->pUX, pPackage->sczId, hr, &action); ExitOnRootFailure(hrResponse, "BA aborted cache package non-vital failure."); if (BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION_ACQUIRE != action) @@ -1369,10 +1369,10 @@ static HRESULT ExtractContainer( hr = PreparePayloadDestinationPath(pExtract->sczUnverifiedPath); ExitOnFailure(hr, "Failed to prepare payload destination path: %ls", pExtract->sczUnverifiedPath); - hr = UserExperienceOnCachePayloadExtractBegin(pContext->pUX, pContainer->sczId, pExtract->sczKey); + hr = BACallbackOnCachePayloadExtractBegin(pContext->pUX, pContainer->sczId, pExtract->sczKey); if (FAILED(hr)) { - UserExperienceOnCachePayloadExtractComplete(pContext->pUX, pContainer->sczId, pExtract->sczKey, hr); + BACallbackOnCachePayloadExtractComplete(pContext->pUX, pContainer->sczId, pExtract->sczKey, hr); ExitOnRootFailure(hr, "BA aborted cache payload extract begin."); } @@ -1386,7 +1386,7 @@ static HRESULT ExtractContainer( hr = CompleteCacheProgress(&progress, pExtract->qwFileSize); } - UserExperienceOnCachePayloadExtractComplete(pContext->pUX, pContainer->sczId, pExtract->sczKey, hr); + BACallbackOnCachePayloadExtractComplete(pContext->pUX, pContainer->sczId, pExtract->sczKey, hr); ExitOnFailure(hr, "Failed to extract payload: %ls from container: %ls", sczStreamName, pContainer->sczId); fExtracted = TRUE; @@ -1433,17 +1433,8 @@ static HRESULT LayoutBundle( progress.pCacheContext = pContext; - hr = VariableGetString(pContext->pVariables, BURN_BUNDLE_SOURCE_PROCESS_PATH, &sczBundlePath); - if (FAILED(hr)) - { - if (E_NOTFOUND != hr) - { - ExitOnFailure(hr, "Failed to get path to bundle source process path to layout."); - } - - hr = PathForCurrentProcess(&sczBundlePath, NULL); - ExitOnFailure(hr, "Failed to get path to bundle to layout."); - } + hr = PathForCurrentProcess(&sczBundlePath, NULL); + ExitOnFailure(hr, "Failed to get path to bundle to layout."); hr = PathConcatRelativeToFullyQualifiedBase(pContext->wzLayoutDirectory, wzExecutableName, &sczDestinationPath); ExitOnFailure(hr, "Failed to concat layout path for bundle."); @@ -1454,17 +1445,17 @@ static HRESULT LayoutBundle( if (fPathEqual && FileExistsEx(sczDestinationPath, NULL)) { - hr = UserExperienceOnCacheContainerOrPayloadVerifyBegin(pContext->pUX, NULL, NULL); + hr = BACallbackOnCacheContainerOrPayloadVerifyBegin(pContext->pUX, NULL, NULL); if (FAILED(hr)) { - UserExperienceOnCacheContainerOrPayloadVerifyComplete(pContext->pUX, NULL, NULL, hr); + BACallbackOnCacheContainerOrPayloadVerifyComplete(pContext->pUX, NULL, NULL, hr); ExitOnRootFailure(hr, "BA aborted cache payload verify begin."); } progress.type = BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY; hr = CompleteCacheProgress(&progress, qwBundleSize); - UserExperienceOnCacheContainerOrPayloadVerifyComplete(pContext->pUX, NULL, NULL, hr); + BACallbackOnCacheContainerOrPayloadVerifyComplete(pContext->pUX, NULL, NULL, hr); ExitFunction(); } @@ -1481,7 +1472,7 @@ static HRESULT LayoutBundle( progress.fCancel = FALSE; fCanceledBegin = FALSE; - hr = UserExperienceOnCacheAcquireBegin(pContext->pUX, NULL, NULL, &sczBundlePath, &sczBundleDownloadUrl, NULL, &cacheOperation); + hr = BACallbackOnCacheAcquireBegin(pContext->pUX, NULL, NULL, &sczBundlePath, &sczBundleDownloadUrl, NULL, &cacheOperation); if (FAILED(hr)) { @@ -1499,7 +1490,7 @@ static HRESULT LayoutBundle( } } - UserExperienceOnCacheAcquireComplete(pContext->pUX, NULL, NULL, hr, &fRetryAcquire); + BACallbackOnCacheAcquireComplete(pContext->pUX, NULL, NULL, hr, &fRetryAcquire); if (fRetryAcquire) { continue; @@ -1517,7 +1508,7 @@ static HRESULT LayoutBundle( { fCanceledBegin = FALSE; - hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, NULL, NULL); + hr = BACallbackOnCacheVerifyBegin(pContext->pUX, NULL, NULL); if (FAILED(hr)) { @@ -1529,7 +1520,7 @@ static HRESULT LayoutBundle( } BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE; - UserExperienceOnCacheVerifyComplete(pContext->pUX, NULL, NULL, hr, &action); + BACallbackOnCacheVerifyComplete(pContext->pUX, NULL, NULL, hr, &action); if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action) { hr = S_FALSE; // retry verify. @@ -1646,7 +1637,7 @@ static HRESULT AcquireContainerOrPayload( *pfRetry = FALSE; pProgress->fCancel = FALSE; - hr = UserExperienceOnCacheAcquireBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId, pwzSourcePath, pwzDownloadUrl, wzPayloadContainerId, &cacheOperation); + hr = BACallbackOnCacheAcquireBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId, pwzSourcePath, pwzDownloadUrl, wzPayloadContainerId, &cacheOperation); ExitOnRootFailure(hr, "BA aborted cache acquire begin."); // Skip the Resolving event and probing local paths if the BA already knew it wanted to download or extract. @@ -1746,7 +1737,7 @@ static HRESULT AcquireContainerOrPayload( } // Let the BA have a chance to override the source. - hr = UserExperienceOnCacheAcquireResolving(pContext->pUX, wzPackageOrContainerId, wzPayloadId, pContext->rgSearchPaths, pContext->cSearchPaths, fFoundLocal, &dwChosenSearchPath, pwzDownloadUrl, wzPayloadContainerId, &resolveOperation); + hr = BACallbackOnCacheAcquireResolving(pContext->pUX, wzPackageOrContainerId, wzPayloadId, pContext->rgSearchPaths, pContext->cSearchPaths, fFoundLocal, &dwChosenSearchPath, pwzDownloadUrl, wzPayloadContainerId, &resolveOperation); ExitOnRootFailure(hr, "BA aborted cache acquire resolving."); switch (resolveOperation) @@ -1816,7 +1807,7 @@ LExit: } pPayload->pContainer->fExtracted = TRUE; } - UserExperienceOnCacheAcquireComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, pfRetry); + BACallbackOnCacheAcquireComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, pfRetry); pContext->cSearchPathsMax = max(pContext->cSearchPaths, pContext->cSearchPathsMax); @@ -1891,7 +1882,7 @@ static HRESULT LayoutOrCacheContainerOrPayload( { fCanceledBegin = FALSE; - hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId); + hr = BACallbackOnCacheVerifyBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId); if (FAILED(hr)) { @@ -1926,7 +1917,7 @@ static HRESULT LayoutOrCacheContainerOrPayload( } BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = FAILED(hr) && !fCanceledBegin && cTryAgainAttempts < BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS ? BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYACQUISITION : BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE; - UserExperienceOnCacheVerifyComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, &action); + BACallbackOnCacheVerifyComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, &action); if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action) { hr = S_FALSE; // retry verify. @@ -2098,8 +2089,8 @@ static HRESULT WINAPI AuthenticationRequired( APPLY_AUTHENTICATION_REQUIRED_DATA* authenticationData = reinterpret_cast(pData); - UserExperienceOnError(authenticationData->pUX, errorType, authenticationData->wzPackageOrContainerId, ERROR_ACCESS_DENIED, sczError, MB_RETRYCANCEL, 0, NULL, &nResult); // ignore return value; - nResult = UserExperienceCheckExecuteResult(authenticationData->pUX, FALSE, BURN_MB_RETRYTRYAGAIN, nResult); + BACallbackOnError(authenticationData->pUX, errorType, authenticationData->wzPackageOrContainerId, ERROR_ACCESS_DENIED, sczError, MB_RETRYCANCEL, 0, NULL, &nResult); // ignore return value; + nResult = BootstrapperApplicationCheckExecuteResult(authenticationData->pUX, FALSE, BURN_MB_RETRYTRYAGAIN, nResult); if (IDTRYAGAIN == nResult && authenticationData->pUX->hwndApply) { er = ::InternetErrorDlg(authenticationData->pUX->hwndApply, hUrl, ERROR_INTERNET_INCORRECT_PASSWORD, FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA, NULL); @@ -2150,7 +2141,7 @@ static HRESULT CALLBACK CacheMessageHandler( { case BURN_CACHE_STEP_HASH_TO_SKIP_ACQUIRE: pProgress->type = BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY; - hr = UserExperienceOnCacheContainerOrPayloadVerifyBegin(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId); + hr = BACallbackOnCacheContainerOrPayloadVerifyBegin(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId); break; case BURN_CACHE_STEP_HASH_TO_SKIP_VERIFY: pProgress->type = BURN_CACHE_PROGRESS_TYPE_PAYLOAD_VERIFY; @@ -2173,7 +2164,7 @@ static HRESULT CALLBACK CacheMessageHandler( switch (pProgress->type) { case BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY: - hr = UserExperienceOnCacheContainerOrPayloadVerifyComplete(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, hr); + hr = BACallbackOnCacheContainerOrPayloadVerifyComplete(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, hr); break; } case BURN_CACHE_MESSAGE_FAILURE: @@ -2321,31 +2312,31 @@ static DWORD CALLBACK CacheProgressRoutine( switch (pProgress->type) { case BURN_CACHE_PROGRESS_TYPE_ACQUIRE: - hr = UserExperienceOnCacheAcquireProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage); + hr = BACallbackOnCacheAcquireProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage); ExitOnRootFailure(hr, "BA aborted acquire of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId); break; case BURN_CACHE_PROGRESS_TYPE_PAYLOAD_VERIFY: - hr = UserExperienceOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_HASH); + hr = BACallbackOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_HASH); ExitOnRootFailure(hr, "BA aborted payload verify step during verify of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId); break; case BURN_CACHE_PROGRESS_TYPE_STAGE: - hr = UserExperienceOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_STAGE); + hr = BACallbackOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_STAGE); ExitOnRootFailure(hr, "BA aborted stage step during verify of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId); break; case BURN_CACHE_PROGRESS_TYPE_HASH: - hr = UserExperienceOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_HASH); + hr = BACallbackOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_HASH); ExitOnRootFailure(hr, "BA aborted hash step during verify of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId); break; case BURN_CACHE_PROGRESS_TYPE_FINALIZE: - hr = UserExperienceOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_FINALIZE); + hr = BACallbackOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_FINALIZE); ExitOnRootFailure(hr, "BA aborted finalize step during verify of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId); break; case BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY: - hr = UserExperienceOnCacheContainerOrPayloadVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage); + hr = BACallbackOnCacheContainerOrPayloadVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage); ExitOnRootFailure(hr, "BA aborted container or payload verify: %ls", wzPayloadId); break; case BURN_CACHE_PROGRESS_TYPE_EXTRACT: - hr = UserExperienceOnCachePayloadExtractProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage); + hr = BACallbackOnCachePayloadExtractProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage); ExitOnRootFailure(hr, "BA aborted extract container: %ls, payload: %ls", wzPackageOrContainerId, wzPayloadId); break; } @@ -2752,14 +2743,14 @@ static HRESULT ExecuteRelatedBundle( fBeginCalled = TRUE; // Send package execute begin to BA. - hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->relatedBundle.action, INSTALLUILEVEL_NOCHANGE, FALSE); + hr = BACallbackOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->relatedBundle.action, INSTALLUILEVEL_NOCHANGE, FALSE); ExitOnRootFailure(hr, "BA aborted execute related bundle begin."); message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; message.dwUIHint = MB_OKCANCEL; message.progress.dwPercentage = fRollback ? 100 : 0; nResult = GenericExecuteMessageHandler(&message, pContext); - hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); + hr = BootstrapperApplicationInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); ExitOnRootFailure(hr, "BA aborted related bundle progress."); // Execute package. @@ -2778,7 +2769,7 @@ static HRESULT ExecuteRelatedBundle( message.dwUIHint = MB_OKCANCEL; message.progress.dwPercentage = fRollback ? 0 : 100; nResult = GenericExecuteMessageHandler(&message, pContext); - hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); + hr = BootstrapperApplicationInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); ExitOnRootFailure(hr, "BA aborted related bundle progress."); pContext->cExecutedPackages += fRollback ? -1 : 1; @@ -2877,14 +2868,14 @@ static HRESULT ExecuteBundlePackage( fBeginCalled = TRUE; // Send package execute begin to BA. - hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->bundlePackage.action, INSTALLUILEVEL_NOCHANGE, FALSE); + hr = BACallbackOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->bundlePackage.action, INSTALLUILEVEL_NOCHANGE, FALSE); ExitOnRootFailure(hr, "BA aborted execute BUNDLE package begin."); message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; message.dwUIHint = MB_OKCANCEL; message.progress.dwPercentage = fRollback ? 100 : 0; nResult = GenericExecuteMessageHandler(&message, pContext); - hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); + hr = BootstrapperApplicationInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); ExitOnRootFailure(hr, "BA aborted BUNDLE progress."); fExecuted = TRUE; @@ -2905,7 +2896,7 @@ static HRESULT ExecuteBundlePackage( message.dwUIHint = MB_OKCANCEL; message.progress.dwPercentage = fRollback ? 0 : 100; nResult = GenericExecuteMessageHandler(&message, pContext); - hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); + hr = BootstrapperApplicationInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); ExitOnRootFailure(hr, "BA aborted BUNDLE progress."); pContext->cExecutedPackages += fRollback ? -1 : 1; @@ -2957,14 +2948,14 @@ static HRESULT ExecuteExePackage( fBeginCalled = TRUE; // Send package execute begin to BA. - hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->exePackage.action, INSTALLUILEVEL_NOCHANGE, FALSE); + hr = BACallbackOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->exePackage.action, INSTALLUILEVEL_NOCHANGE, FALSE); ExitOnRootFailure(hr, "BA aborted execute EXE package begin."); message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; message.dwUIHint = MB_OKCANCEL; message.progress.dwPercentage = fRollback ? 100 : 0; nResult = GenericExecuteMessageHandler(&message, pContext); - hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); + hr = BootstrapperApplicationInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); ExitOnRootFailure(hr, "BA aborted EXE progress."); fExecuted = TRUE; @@ -2985,7 +2976,7 @@ static HRESULT ExecuteExePackage( message.dwUIHint = MB_OKCANCEL; message.progress.dwPercentage = fRollback ? 0 : 100; nResult = GenericExecuteMessageHandler(&message, pContext); - hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); + hr = BootstrapperApplicationInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); ExitOnRootFailure(hr, "BA aborted EXE progress."); pContext->cExecutedPackages += fRollback ? -1 : 1; @@ -3036,7 +3027,7 @@ static HRESULT ExecuteMsiPackage( fBeginCalled = TRUE; // Send package execute begin to BA. - hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->msiPackage.action, pExecuteAction->msiPackage.uiLevel, pExecuteAction->msiPackage.fDisableExternalUiHandler); + hr = BACallbackOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->msiPackage.action, pExecuteAction->msiPackage.uiLevel, pExecuteAction->msiPackage.fDisableExternalUiHandler); ExitOnRootFailure(hr, "BA aborted execute MSI package begin."); fExecuted = TRUE; @@ -3101,7 +3092,7 @@ static HRESULT ExecuteMspPackage( fBeginCalled = TRUE; // Send package execute begin to BA. - hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->mspTarget.action, pExecuteAction->mspTarget.uiLevel, pExecuteAction->mspTarget.fDisableExternalUiHandler); + hr = BACallbackOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->mspTarget.action, pExecuteAction->mspTarget.uiLevel, pExecuteAction->mspTarget.fDisableExternalUiHandler); ExitOnRootFailure(hr, "BA aborted execute MSP package begin."); // Now send all the patches that target this product code. @@ -3109,7 +3100,7 @@ static HRESULT ExecuteMspPackage( { BURN_PACKAGE* pMspPackage = pExecuteAction->mspTarget.rgOrderedPatches[i].pPackage; - hr = UserExperienceOnExecutePatchTarget(&pEngineState->userExperience, pMspPackage->sczId, pExecuteAction->mspTarget.sczTargetProductCode); + hr = BACallbackOnExecutePatchTarget(&pEngineState->userExperience, pMspPackage->sczId, pExecuteAction->mspTarget.sczTargetProductCode); ExitOnRootFailure(hr, "BA aborted execute MSP target."); } @@ -3177,14 +3168,14 @@ static HRESULT ExecuteMsuPackage( fBeginCalled = TRUE; // Send package execute begin to BA. - hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->msuPackage.action, INSTALLUILEVEL_NOCHANGE, FALSE); + hr = BACallbackOnExecutePackageBegin(&pEngineState->userExperience, pPackage->sczId, !fRollback, pExecuteAction->msuPackage.action, INSTALLUILEVEL_NOCHANGE, FALSE); ExitOnRootFailure(hr, "BA aborted execute MSU package begin."); message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; message.dwUIHint = MB_OKCANCEL; message.progress.dwPercentage = fRollback ? 100 : 0; nResult = GenericExecuteMessageHandler(&message, pContext); - hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); + hr = BootstrapperApplicationInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); ExitOnRootFailure(hr, "BA aborted MSU progress."); fExecuted = TRUE; @@ -3205,7 +3196,7 @@ static HRESULT ExecuteMsuPackage( message.dwUIHint = MB_OKCANCEL; message.progress.dwPercentage = fRollback ? 0 : 100; nResult = GenericExecuteMessageHandler(&message, pContext); - hr = UserExperienceInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); + hr = BootstrapperApplicationInterpretExecuteResult(&pEngineState->userExperience, fRollback, message.dwUIHint, nResult); ExitOnRootFailure(hr, "BA aborted MSU progress."); pContext->cExecutedPackages += fRollback ? -1 : 1; @@ -3351,7 +3342,7 @@ static HRESULT ExecuteMsiBeginTransaction( } fBeginCalled = TRUE; - hr = UserExperienceOnBeginMsiTransactionBegin(&pEngineState->userExperience, pRollbackBoundary->sczId); + hr = BACallbackOnBeginMsiTransactionBegin(&pEngineState->userExperience, pRollbackBoundary->sczId); ExitOnRootFailure(hr, "BA aborted execute begin MSI transaction."); if (pEngineState->plan.fPerMachine) @@ -3374,7 +3365,7 @@ static HRESULT ExecuteMsiBeginTransaction( LExit: if (fBeginCalled) { - UserExperienceOnBeginMsiTransactionComplete(&pEngineState->userExperience, pRollbackBoundary->sczId, hr); + BACallbackOnBeginMsiTransactionComplete(&pEngineState->userExperience, pRollbackBoundary->sczId, hr); } return hr; @@ -3397,7 +3388,7 @@ static HRESULT ExecuteMsiCommitTransaction( } fCommitBeginCalled = TRUE; - hr = UserExperienceOnCommitMsiTransactionBegin(&pEngineState->userExperience, pRollbackBoundary->sczId); + hr = BACallbackOnCommitMsiTransactionBegin(&pEngineState->userExperience, pRollbackBoundary->sczId); ExitOnRootFailure(hr, "BA aborted execute commit MSI transaction."); if (pEngineState->plan.fPerMachine) @@ -3418,7 +3409,7 @@ static HRESULT ExecuteMsiCommitTransaction( LExit: if (fCommitBeginCalled) { - UserExperienceOnCommitMsiTransactionComplete(&pEngineState->userExperience, pRollbackBoundary->sczId, hr, *pRestart, &action); + BACallbackOnCommitMsiTransactionComplete(&pEngineState->userExperience, pRollbackBoundary->sczId, hr, *pRestart, &action); if (action == BOOTSTRAPPER_EXECUTEMSITRANSACTIONCOMPLETE_ACTION_RESTART) { @@ -3446,7 +3437,7 @@ static HRESULT ExecuteMsiRollbackTransaction( } fRollbackBeginCalled = TRUE; - UserExperienceOnRollbackMsiTransactionBegin(&pEngineState->userExperience, pRollbackBoundary->sczId); + BACallbackOnRollbackMsiTransactionBegin(&pEngineState->userExperience, pRollbackBoundary->sczId); if (pEngineState->plan.fPerMachine) { @@ -3465,7 +3456,7 @@ LExit: if (fRollbackBeginCalled) { - UserExperienceOnRollbackMsiTransactionComplete(&pEngineState->userExperience, pRollbackBoundary->sczId, hr, *pRestart, &action); + BACallbackOnRollbackMsiTransactionComplete(&pEngineState->userExperience, pRollbackBoundary->sczId, hr, *pRestart, &action); if (action == BOOTSTRAPPER_EXECUTEMSITRANSACTIONCOMPLETE_ACTION_RESTART) { @@ -3531,7 +3522,7 @@ static HRESULT ExecuteUninstallMsiCompatiblePackage( fBeginCalled = TRUE; // Send package execute begin to BA. - hr = UserExperienceOnExecutePackageBegin(&pEngineState->userExperience, pContext->wzExecutingPackageId, !fRollback, action, uiLevel, fDisableExternalUiHandler); + hr = BACallbackOnExecutePackageBegin(&pEngineState->userExperience, pContext->wzExecutingPackageId, !fRollback, action, uiLevel, fDisableExternalUiHandler); ExitOnRootFailure(hr, "BA aborted execute MSI compatible package begin."); // execute package @@ -3622,14 +3613,14 @@ static int GenericExecuteMessageHandler( case GENERIC_EXECUTE_MESSAGE_PROGRESS: { DWORD dwOverallProgress = pContext->cExecutePackagesTotal ? (pContext->cExecutedPackages * 100 + pMessage->progress.dwPercentage) / (pContext->cExecutePackagesTotal) : 0; - UserExperienceOnExecuteProgress(pContext->pUX, pContext->wzExecutingPackageId, pMessage->progress.dwPercentage, dwOverallProgress, &nResult); // ignore return value. + BACallbackOnExecuteProgress(pContext->pUX, pContext->wzExecutingPackageId, pMessage->progress.dwPercentage, dwOverallProgress, &nResult); // ignore return value. } break; case GENERIC_EXECUTE_MESSAGE_PROCESS_CANCEL: { BOOTSTRAPPER_EXECUTEPROCESSCANCEL_ACTION action = BOOTSTRAPPER_EXECUTEPROCESSCANCEL_ACTION_ABANDON; - UserExperienceOnExecuteProcessCancel(pContext->pUX, pContext->wzExecutingPackageId, pMessage->processCancel.dwProcessId, &action); // ignore return value. + BACallbackOnExecuteProcessCancel(pContext->pUX, pContext->wzExecutingPackageId, pMessage->processCancel.dwProcessId, &action); // ignore return value. nResult = BOOTSTRAPPER_EXECUTEPROCESSCANCEL_ACTION_WAIT == action ? IDRETRY : IDIGNORE; } break; @@ -3643,18 +3634,18 @@ static int GenericExecuteMessageHandler( break; case GENERIC_EXECUTE_MESSAGE_ERROR: - UserExperienceOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_EXE_PACKAGE, pContext->wzExecutingPackageId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwUIHint, 0, NULL, &nResult); // ignore return value. + BACallbackOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_EXE_PACKAGE, pContext->wzExecutingPackageId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwUIHint, 0, NULL, &nResult); // ignore return value. break; case GENERIC_EXECUTE_MESSAGE_NETFX_FILES_IN_USE: - UserExperienceOnExecuteFilesInUse(pContext->pUX, pContext->wzExecutingPackageId, pMessage->filesInUse.cFiles, pMessage->filesInUse.rgwzFiles, BOOTSTRAPPER_FILES_IN_USE_TYPE_NETFX, &nResult); // ignore return value. + BACallbackOnExecuteFilesInUse(pContext->pUX, pContext->wzExecutingPackageId, pMessage->filesInUse.cFiles, pMessage->filesInUse.rgwzFiles, BOOTSTRAPPER_FILES_IN_USE_TYPE_NETFX, &nResult); // ignore return value. fPassthrough = TRUE; break; } if (!fPassthrough) { - nResult = UserExperienceCheckExecuteResult(pContext->pUX, pContext->fRollback, dwAllowedResults, nResult); + nResult = BootstrapperApplicationCheckExecuteResult(pContext->pUX, pContext->fRollback, dwAllowedResults, nResult); } return nResult; @@ -3676,32 +3667,32 @@ static int MsiExecuteMessageHandler( case WIU_MSI_EXECUTE_MESSAGE_PROGRESS: { DWORD dwOverallProgress = pContext->cExecutePackagesTotal ? (pContext->cExecutedPackages * 100 + pMessage->progress.dwPercentage) / (pContext->cExecutePackagesTotal) : 0; - UserExperienceOnExecuteProgress(pContext->pUX, pContext->wzExecutingPackageId, pMessage->progress.dwPercentage, dwOverallProgress, &nResult); // ignore return value. + BACallbackOnExecuteProgress(pContext->pUX, pContext->wzExecutingPackageId, pMessage->progress.dwPercentage, dwOverallProgress, &nResult); // ignore return value. } break; case WIU_MSI_EXECUTE_MESSAGE_ERROR: nResult = pMessage->nResultRecommendation; - UserExperienceOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_WINDOWS_INSTALLER, pContext->wzExecutingPackageId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwUIHint, pMessage->cData, pMessage->rgwzData, &nResult); // ignore return value. + BACallbackOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_WINDOWS_INSTALLER, pContext->wzExecutingPackageId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwUIHint, pMessage->cData, pMessage->rgwzData, &nResult); // ignore return value. break; case WIU_MSI_EXECUTE_MESSAGE_MSI_MESSAGE: nResult = pMessage->nResultRecommendation; - UserExperienceOnExecuteMsiMessage(pContext->pUX, pContext->wzExecutingPackageId, pMessage->msiMessage.mt, pMessage->dwUIHint, pMessage->msiMessage.wzMessage, pMessage->cData, pMessage->rgwzData, &nResult); // ignore return value. + BACallbackOnExecuteMsiMessage(pContext->pUX, pContext->wzExecutingPackageId, pMessage->msiMessage.mt, pMessage->dwUIHint, pMessage->msiMessage.wzMessage, pMessage->cData, pMessage->rgwzData, &nResult); // ignore return value. break; case WIU_MSI_EXECUTE_MESSAGE_MSI_RM_FILES_IN_USE: fRestartManager = TRUE; __fallthrough; case WIU_MSI_EXECUTE_MESSAGE_MSI_FILES_IN_USE: - UserExperienceOnExecuteFilesInUse(pContext->pUX, pContext->wzExecutingPackageId, pMessage->msiFilesInUse.cFiles, pMessage->msiFilesInUse.rgwzFiles, fRestartManager ? BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI_RM : BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI, &nResult); // ignore return value. + BACallbackOnExecuteFilesInUse(pContext->pUX, pContext->wzExecutingPackageId, pMessage->msiFilesInUse.cFiles, pMessage->msiFilesInUse.rgwzFiles, fRestartManager ? BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI_RM : BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI, &nResult); // ignore return value. fPassthrough = TRUE; break; } if (!fPassthrough) { - nResult = UserExperienceCheckExecuteResult(pContext->pUX, pContext->fRollback, dwAllowedResults, nResult); + nResult = BootstrapperApplicationCheckExecuteResult(pContext->pUX, pContext->fRollback, dwAllowedResults, nResult); } return nResult; @@ -3724,7 +3715,7 @@ static HRESULT ReportOverallProgressTicks( dwProgress = cOverallProgressTicksTotal ? (pApplyContext->cOverallProgressTicks * 100 / cOverallProgressTicksTotal) : 0; // TODO: consider sending different progress numbers in the future. - hr = UserExperienceOnProgress(pUX, fRollback, dwProgress, dwProgress); + hr = BACallbackOnProgress(pUX, fRollback, dwProgress, dwProgress); ::LeaveCriticalSection(&pApplyContext->csApply); @@ -3755,7 +3746,7 @@ static HRESULT ExecutePackageComplete( } // Send package execute complete to BA. - UserExperienceOnExecutePackageComplete(pUX, wzPackageId, hr, *pRestart, &executePackageCompleteAction); + BACallbackOnExecutePackageComplete(pUX, wzPackageId, hr, *pRestart, &executePackageCompleteAction); if (BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_RESTART == executePackageCompleteAction) { *pRestart = BOOTSTRAPPER_APPLY_RESTART_INITIATED; diff --git a/src/burn/engine/bacallback.cpp b/src/burn/engine/bacallback.cpp new file mode 100644 index 00000000..f4e6894d --- /dev/null +++ b/src/burn/engine/bacallback.cpp @@ -0,0 +1,5893 @@ +// 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" + +// internal function declarations + +static HRESULT FilterExecuteResult( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus, + __in BOOL fRollback, + __in BOOL fCancel, + __in LPCWSTR sczEventName + ); +static HRESULT SendBAMessage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOTSTRAPPER_APPLICATION_MESSAGE message, + __in BUFF_BUFFER* pBufferArgs, + __in BUFF_BUFFER* pBufferResults, + __in PIPE_RPC_RESULT* pResult + ); +static HRESULT SendBAMessageFromInactiveEngine( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOTSTRAPPER_APPLICATION_MESSAGE message, + __in BUFF_BUFFER* pBufferArgs, + __in BUFF_BUFFER* pBufferResults, + __in PIPE_RPC_RESULT* pResult + ); +static HRESULT CombineArgsAndResults( + __in BUFF_BUFFER* pBufferArgs, + __in BUFF_BUFFER* pBufferResults, + __in BUFF_BUFFER* pBufferCombined + ); + +// function definitions + +EXTERN_C HRESULT BACallbackOnApplyBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in DWORD dwPhaseCount + ) +{ + HRESULT hr = S_OK; + BA_ONAPPLYBEGIN_ARGS args = { }; + BA_ONAPPLYBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.dwPhaseCount = dwPhaseCount; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnApplyBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwPhaseCount); + ExitOnFailure(hr, "Failed to write phase count of OnApplyBegin args command."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnApplyBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnApplyBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnApplyBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnApplyBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnApplyComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus, + __in BOOTSTRAPPER_APPLY_RESTART restart, + __inout BOOTSTRAPPER_APPLYCOMPLETE_ACTION* pAction + ) +{ + HRESULT hr = S_OK; + BA_ONAPPLYCOMPLETE_ARGS args = { }; + BA_ONAPPLYCOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.hrStatus = hrStatus; + args.restart = restart; + args.recommendation = *pAction; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.action = *pAction; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnApplyComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnApplyComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.restart); + ExitOnFailure(hr, "Failed to write restart of OnApplyComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendation); + ExitOnFailure(hr, "Failed to write recommended action of OnApplyComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnApplyComplete results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.action); + ExitOnFailure(hr, "Failed to write default action of OnApplyComplete results."); + + // Callback. + hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYCOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnApplyComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnApplyComplete result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.action)); + ExitOnFailure(hr, "Failed to read action of OnApplyComplete result."); + + *pAction = results.action; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnApplyDowngrade( + __in BURN_USER_EXPERIENCE* pUserExperience, + __inout HRESULT* phrStatus + ) +{ + HRESULT hr = S_OK; + BA_ONAPPLYDOWNGRADE_ARGS args = { }; + BA_ONAPPLYDOWNGRADE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.hrRecommended = *phrStatus; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.hrStatus = *phrStatus; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnApplyDowngrade args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrRecommended); + ExitOnFailure(hr, "Failed to write recommended status of OnApplyDowngrade args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnApplyDowngrade results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.hrStatus); + ExitOnFailure(hr, "Failed to write default action of OnApplyDowngrade results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYDOWNGRADE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnApplyDowngrade failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnApplyDowngrade result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.hrStatus)); + ExitOnFailure(hr, "Failed to read action of OnApplyDowngrade result."); + + *phrStatus = results.hrStatus; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnBeginMsiTransactionBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in LPCWSTR wzTransactionId + ) +{ + HRESULT hr = S_OK; + BA_ONBEGINMSITRANSACTIONBEGIN_ARGS args = { }; + BA_ONBEGINMSITRANSACTIONBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzTransactionId = wzTransactionId; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnBeginMsiTransactionBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzTransactionId); + ExitOnFailure(hr, "Failed to write recommended status of OnBeginMsiTransactionBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnBeginMsiTransactionBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONBEGINMSITRANSACTIONBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnBeginMsiTransactionBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnBeginMsiTransactionBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read action of OnBeginMsiTransactionBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnBeginMsiTransactionComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in LPCWSTR wzTransactionId, + __in HRESULT hrStatus + ) +{ + HRESULT hr = S_OK; + BA_ONBEGINMSITRANSACTIONCOMPLETE_ARGS args = { }; + BA_ONBEGINMSITRANSACTIONCOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzTransactionId = wzTransactionId; + args.hrStatus = hrStatus; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnBeginMsiTransactionComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzTransactionId); + ExitOnFailure(hr, "Failed to write recommended status of OnBeginMsiTransactionComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnBeginMsiTransactionComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnBeginMsiTransactionComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONBEGINMSITRANSACTIONCOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnBeginMsiTransactionComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCacheAcquireBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in_z LPWSTR* pwzSource, + __in_z LPWSTR* pwzDownloadUrl, + __in_z_opt LPCWSTR wzPayloadContainerId, + __out BOOTSTRAPPER_CACHE_OPERATION* pCacheOperation + ) +{ + HRESULT hr = S_OK; + BA_ONCACHEACQUIREBEGIN_ARGS args = { }; + BA_ONCACHEACQUIREBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + *pCacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageOrContainerId = wzPackageOrContainerId; + args.wzPayloadId = wzPayloadId; + args.wzSource = *pwzSource; + args.wzDownloadUrl = *pwzDownloadUrl; + args.wzPayloadContainerId = wzPayloadContainerId; + args.recommendation = *pCacheOperation; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.action = *pCacheOperation; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheAcquireBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageOrContainerId); + ExitOnFailure(hr, "Failed to write package or container of OnCacheAcquireBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPayloadId); + ExitOnFailure(hr, "Failed to write payload id of OnCacheAcquireBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzSource); + ExitOnFailure(hr, "Failed to write source of OnCacheAcquireBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzDownloadUrl); + ExitOnFailure(hr, "Failed to write download url of OnCacheAcquireBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPayloadContainerId); + ExitOnFailure(hr, "Failed to write payload container id of OnCacheAcquireBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendation); + ExitOnFailure(hr, "Failed to write recommendation of OnCacheAcquireBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheAcquireBegin results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.action); + ExitOnFailure(hr, "Failed to write action of OnCacheAcquireBegin results."); + + // Callback. + hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCacheAcquireBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCacheAcquireBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnCacheAcquireBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.action)); + ExitOnFailure(hr, "Failed to read action of OnCacheAcquireBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + else + { + // Verify the BA requested an action that is possible. + if (BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD == results.action && *pwzDownloadUrl && **pwzDownloadUrl || + BOOTSTRAPPER_CACHE_OPERATION_EXTRACT == results.action && wzPayloadContainerId || + BOOTSTRAPPER_CACHE_OPERATION_COPY == results.action || + BOOTSTRAPPER_CACHE_OPERATION_NONE == results.action) + { + *pCacheOperation = results.action; + } + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCacheAcquireComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in HRESULT hrStatus, + __inout BOOL* pfRetry + ) +{ + HRESULT hr = S_OK; + BA_ONCACHEACQUIRECOMPLETE_ARGS args = { }; + BA_ONCACHEACQUIRECOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageOrContainerId = wzPackageOrContainerId; + args.wzPayloadId = wzPayloadId; + args.hrStatus = hrStatus; + args.recommendation = *pfRetry ? BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION_RETRY : BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION_NONE; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.action = args.recommendation; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheAcquireComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageOrContainerId); + ExitOnFailure(hr, "Failed to write package or container of OnCacheAcquireComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPayloadId); + ExitOnFailure(hr, "Failed to write payload id of OnCacheAcquireComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnCacheAcquireComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendation); + ExitOnFailure(hr, "Failed to write recommendation of OnCacheAcquireComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheAcquireComplete results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.action); + ExitOnFailure(hr, "Failed to write action of OnCacheAcquireComplete results."); + + // Callback. + hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRECOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCacheAcquireComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCacheAcquireComplete result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.action)); + ExitOnFailure(hr, "Failed to read action of OnCacheAcquireComplete result."); + + if (FAILED(hrStatus)) + { + *pfRetry = BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION_RETRY == results.action; + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C BAAPI BACallbackOnCacheAcquireProgress( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in DWORD64 dw64Progress, + __in DWORD64 dw64Total, + __in DWORD dwOverallPercentage + ) +{ + HRESULT hr = S_OK; + BA_ONCACHEACQUIREPROGRESS_ARGS args = { }; + BA_ONCACHEACQUIREPROGRESS_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageOrContainerId = wzPackageOrContainerId; + args.wzPayloadId = wzPayloadId; + args.dw64Progress = dw64Progress; + args.dw64Total = dw64Total; + args.dwOverallPercentage = dwOverallPercentage; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheAcquireProgress args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageOrContainerId); + ExitOnFailure(hr, "Failed to write package or container of OnCacheAcquireProgress args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPayloadId); + ExitOnFailure(hr, "Failed to write payload id of OnCacheAcquireProgress args."); + + hr = BuffWriteNumber64ToBuffer(&bufferArgs, args.dw64Progress); + ExitOnFailure(hr, "Failed to write progress of OnCacheAcquireProgress args."); + + hr = BuffWriteNumber64ToBuffer(&bufferArgs, args.dw64Total); + ExitOnFailure(hr, "Failed to write total progress of OnCacheAcquireProgress args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwOverallPercentage); + ExitOnFailure(hr, "Failed to write overall percentage of OnCacheAcquireProgress args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheAcquireProgress results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREPROGRESS, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCacheAcquireProgress failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCacheAcquireProgress result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnCacheAcquireProgress result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCacheAcquireResolving( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in_ecount_z(cSearchPaths) LPWSTR* rgSearchPaths, + __in DWORD cSearchPaths, + __in BOOL fFoundLocal, + __in DWORD* pdwChosenSearchPath, + __in_z_opt LPWSTR* pwzDownloadUrl, + __in_z_opt LPCWSTR wzPayloadContainerId, + __inout BOOTSTRAPPER_CACHE_RESOLVE_OPERATION* pCacheOperation + ) +{ + HRESULT hr = S_OK; + BA_ONCACHEACQUIRERESOLVING_ARGS args = { }; + BA_ONCACHEACQUIRERESOLVING_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageOrContainerId = wzPackageOrContainerId; + args.wzPayloadId = wzPayloadId; + args.rgSearchPaths = const_cast(rgSearchPaths); + args.cSearchPaths = cSearchPaths; + args.fFoundLocal = fFoundLocal; + args.dwRecommendedSearchPath = *pdwChosenSearchPath; + args.wzDownloadUrl = *pwzDownloadUrl; + args.recommendation = *pCacheOperation; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.dwChosenSearchPath = *pdwChosenSearchPath; + results.action = *pCacheOperation; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheAcquireResolving args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageOrContainerId); + ExitOnFailure(hr, "Failed to write package or container of OnCacheAcquireResolving args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPayloadId); + ExitOnFailure(hr, "Failed to write payload id of OnCacheAcquireResolving args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.cSearchPaths); + ExitOnFailure(hr, "Failed to write count of search paths of OnCacheAcquireResolving args."); + + for (DWORD i = 0; i < args.cSearchPaths; ++i) + { + hr = BuffWriteStringToBuffer(&bufferArgs, args.rgSearchPaths[i]); + ExitOnFailure(hr, "Failed to write search path[%u] of OnCacheAcquireResolving args.", i); + } + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fFoundLocal); + ExitOnFailure(hr, "Failed to write found local of OnCacheAcquireResolving args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwRecommendedSearchPath); + ExitOnFailure(hr, "Failed to write recommended search path of OnCacheAcquireResolving args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzDownloadUrl); + ExitOnFailure(hr, "Failed to write download url of OnCacheAcquireResolving args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPayloadContainerId); + ExitOnFailure(hr, "Failed to write payload container id of OnCacheAcquireResolving args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendation); + ExitOnFailure(hr, "Failed to write recommendation of OnCacheAcquireResolving args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheAcquireResolving results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwChosenSearchPath); + ExitOnFailure(hr, "Failed to write chose search path of OnCacheAcquireResolving results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.action); + ExitOnFailure(hr, "Failed to write action of OnCacheAcquireResolving results."); + + // Callback. + hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRERESOLVING, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCacheAcquireResolving failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCacheAcquireResolving result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwChosenSearchPath); + ExitOnFailure(hr, "Failed to read chosen search path of OnCacheAcquireResolving result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.action)); + ExitOnFailure(hr, "Failed to read action of OnCacheAcquireResolving result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnCacheAcquireResolving result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + else + { + // Verify the BA requested an action that is possible. + if (BOOTSTRAPPER_CACHE_RESOLVE_DOWNLOAD == results.action && *pwzDownloadUrl && **pwzDownloadUrl || + BOOTSTRAPPER_CACHE_RESOLVE_CONTAINER == results.action && wzPayloadContainerId || + BOOTSTRAPPER_CACHE_RESOLVE_RETRY == results.action || + BOOTSTRAPPER_CACHE_RESOLVE_NONE == results.action) + { + *pCacheOperation = results.action; + } + else if (BOOTSTRAPPER_CACHE_RESOLVE_LOCAL == results.action && results.dwChosenSearchPath < cSearchPaths) + { + *pdwChosenSearchPath = results.dwChosenSearchPath; + *pCacheOperation = results.action; + } + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCacheBegin( + __in BURN_USER_EXPERIENCE* pUserExperience + ) +{ + HRESULT hr = S_OK; + BA_ONCACHEBEGIN_ARGS args = { }; + BA_ONCACHEBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCacheBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCacheBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnCacheBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCacheComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ) +{ + HRESULT hr = S_OK; + BA_ONCACHECOMPLETE_ARGS args = { }; + BA_ONCACHECOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.hrStatus = hrStatus; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnCacheComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCacheComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C BAAPI BACallbackOnCacheContainerOrPayloadVerifyBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId + ) +{ + HRESULT hr = S_OK; + BA_ONCACHECONTAINERORPAYLOADVERIFYBEGIN_ARGS args = { }; + BA_ONCACHECONTAINERORPAYLOADVERIFYBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageOrContainerId = wzPackageOrContainerId; + args.wzPayloadId = wzPayloadId; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheContainerOrPayloadVerifyBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageOrContainerId); + ExitOnFailure(hr, "Failed to write package or container id of OnCacheContainerOrPayloadVerifyBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPayloadId); + ExitOnFailure(hr, "Failed to write payload id of OnCacheContainerOrPayloadVerifyBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheContainerOrPayloadVerifyBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCacheContainerOrPayloadVerifyBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCacheContainerOrPayloadVerifyBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnCacheContainerOrPayloadVerifyBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCacheContainerOrPayloadVerifyComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in HRESULT hrStatus + ) +{ + HRESULT hr = S_OK; + BA_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE_ARGS args = { }; + BA_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageOrContainerId = wzPackageOrContainerId; + args.wzPayloadId = wzPayloadId; + args.hrStatus = hrStatus; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheContainerOrPayloadVerifyComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageOrContainerId); + ExitOnFailure(hr, "Failed to write package or container id of OnCacheContainerOrPayloadVerifyComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPayloadId); + ExitOnFailure(hr, "Failed to write payload id of OnCacheContainerOrPayloadVerifyComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnCacheContainerOrPayloadVerifyComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheContainerOrPayloadVerifyComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCacheContainerOrPayloadVerifyComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCacheContainerOrPayloadVerifyProgress( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in DWORD64 dw64Progress, + __in DWORD64 dw64Total, + __in DWORD dwOverallPercentage + ) +{ + HRESULT hr = S_OK; + BA_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS_ARGS args = { }; + BA_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageOrContainerId = wzPackageOrContainerId; + args.wzPayloadId = wzPayloadId; + args.dw64Progress = dw64Progress; + args.dw64Total = dw64Total; + args.dwOverallPercentage = dwOverallPercentage; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheContainerOrPayloadVerifyProgress args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageOrContainerId); + ExitOnFailure(hr, "Failed to write package or container id of OnCacheContainerOrPayloadVerifyProgress args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPayloadId); + ExitOnFailure(hr, "Failed to write payload id of OnCacheContainerOrPayloadVerifyProgress args."); + + hr = BuffWriteNumber64ToBuffer(&bufferArgs, args.dw64Progress); + ExitOnFailure(hr, "Failed to write progress of OnCacheContainerOrPayloadVerifyProgress args."); + + hr = BuffWriteNumber64ToBuffer(&bufferArgs, args.dw64Total); + ExitOnFailure(hr, "Failed to write total progress of OnCacheContainerOrPayloadVerifyProgress args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwOverallPercentage); + ExitOnFailure(hr, "Failed to write overall percentage of OnCacheContainerOrPayloadVerifyProgress args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheContainerOrPayloadVerifyProgress results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCacheContainerOrPayloadVerifyProgress failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCacheContainerOrPayloadVerifyProgress result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnCacheContainerOrPayloadVerifyProgress result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCachePackageBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in DWORD cCachePayloads, + __in DWORD64 dw64PackageCacheSize, + __in BOOL fVital + ) +{ + HRESULT hr = S_OK; + BA_ONCACHEPACKAGEBEGIN_ARGS args = { }; + BA_ONCACHEPACKAGEBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.cCachePayloads = cCachePayloads; + args.dw64PackageCacheSize = dw64PackageCacheSize; + args.fVital = fVital; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCachePackageBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnCachePackageBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.cCachePayloads); + ExitOnFailure(hr, "Failed to write count of cached payloads of OnCachePackageBegin args."); + + hr = BuffWriteNumber64ToBuffer(&bufferArgs, args.dw64PackageCacheSize); + ExitOnFailure(hr, "Failed to write package cache size of OnCachePackageBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fVital); + ExitOnFailure(hr, "Failed to write vital of OnCachePackageBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCachePackageBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGEBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCachePackageBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCachePackageBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnCachePackageBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCachePackageComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in HRESULT hrStatus, + __inout BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION* pAction + ) +{ + HRESULT hr = S_OK; + BA_ONCACHEPACKAGECOMPLETE_ARGS args = { }; + BA_ONCACHEPACKAGECOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.hrStatus = hrStatus; + args.recommendation = *pAction; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.action = *pAction; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCachePackageComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnCachePackageComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnCachePackageComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendation); + ExitOnFailure(hr, "Failed to write recommendation of OnCachePackageComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCachePackageComplete results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.action); + ExitOnFailure(hr, "Failed to write action of OnCachePackageComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGECOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCachePackageComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCachePackageComplete result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.action)); + ExitOnFailure(hr, "Failed to read cancel of OnCachePackageComplete result."); + + if (FAILED(hrStatus)) + { + *pAction = results.action; + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCachePackageNonVitalValidationFailure( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in HRESULT hrStatus, + __inout BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION* pAction + ) +{ + HRESULT hr = S_OK; + BA_ONCACHEPACKAGENONVITALVALIDATIONFAILURE_ARGS args = { }; + BA_ONCACHEPACKAGENONVITALVALIDATIONFAILURE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.hrStatus = hrStatus; + args.recommendation = *pAction; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.action = *pAction; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCachePackageNonVitalValidationFailure args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnCachePackageNonVitalValidationFailure args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnCachePackageNonVitalValidationFailure args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendation); + ExitOnFailure(hr, "Failed to write recommendation of OnCachePackageNonVitalValidationFailure args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCachePackageNonVitalValidationFailure results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.action); + ExitOnFailure(hr, "Failed to write API version of OnCachePackageNonVitalValidationFailure results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGENONVITALVALIDATIONFAILURE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCachePackageNonVitalValidationFailure failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCachePackageNonVitalValidationFailure result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.action)); + ExitOnFailure(hr, "Failed to read cancel of OnCachePackageNonVitalValidationFailure result."); + + switch (results.action) + { + case BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION_NONE: __fallthrough; + case BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION_ACQUIRE: + *pAction = results.action; + break; + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCachePayloadExtractBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzContainerId, + __in_z_opt LPCWSTR wzPayloadId + ) +{ + HRESULT hr = S_OK; + BA_ONCACHEPAYLOADEXTRACTBEGIN_ARGS args = { }; + BA_ONCACHEPAYLOADEXTRACTBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzContainerId = wzContainerId; + args.wzPayloadId = wzPayloadId; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCachePayloadExtractBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzContainerId); + ExitOnFailure(hr, "Failed to write container id of OnCachePayloadExtractBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPayloadId); + ExitOnFailure(hr, "Failed to write payload id of OnCachePayloadExtractBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCachePayloadExtractBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCachePayloadExtractBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCachePayloadExtractBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnCachePayloadExtractBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCachePayloadExtractComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in HRESULT hrStatus + ) +{ + HRESULT hr = S_OK; + BA_ONCACHEPAYLOADEXTRACTCOMPLETE_ARGS args = { }; + BA_ONCACHEPAYLOADEXTRACTCOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzContainerId = wzContainerId; + args.wzPayloadId = wzPayloadId; + args.hrStatus = hrStatus; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCachePayloadExtractComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzContainerId); + ExitOnFailure(hr, "Failed to write container id of OnCachePayloadExtractComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPayloadId); + ExitOnFailure(hr, "Failed to write payload id of OnCachePayloadExtractComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnCachePayloadExtractComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCachePayloadExtractComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTCOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCachePayloadExtractComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCachePayloadExtractProgress( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in DWORD64 dw64Progress, + __in DWORD64 dw64Total, + __in DWORD dwOverallPercentage + ) +{ + HRESULT hr = S_OK; + BA_ONCACHEPAYLOADEXTRACTPROGRESS_ARGS args = { }; + BA_ONCACHEPAYLOADEXTRACTPROGRESS_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzContainerId = wzContainerId; + args.wzPayloadId = wzPayloadId; + args.dw64Progress = dw64Progress; + args.dw64Total = dw64Total; + args.dwOverallPercentage = dwOverallPercentage; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCachePayloadExtractProgress args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzContainerId); + ExitOnFailure(hr, "Failed to write container id of OnCachePayloadExtractProgress args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPayloadId); + ExitOnFailure(hr, "Failed to write payload id of OnCachePayloadExtractProgress args."); + + hr = BuffWriteNumber64ToBuffer(&bufferArgs, args.dw64Progress); + ExitOnFailure(hr, "Failed to write progress of OnCachePayloadExtractProgress args."); + + hr = BuffWriteNumber64ToBuffer(&bufferArgs, args.dw64Total); + ExitOnFailure(hr, "Failed to write total progress of OnCachePayloadExtractProgress args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwOverallPercentage); + ExitOnFailure(hr, "Failed to write overall percentage of OnCachePayloadExtractProgress args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCachePayloadExtractProgress results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTPROGRESS, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCachePayloadExtractProgress failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCachePayloadExtractProgress result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnCachePayloadExtractProgress result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCacheVerifyBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId + ) +{ + HRESULT hr = S_OK; + BA_ONCACHEVERIFYBEGIN_ARGS args = { }; + BA_ONCACHEVERIFYBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageOrContainerId = wzPackageOrContainerId; + args.wzPayloadId = wzPayloadId; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheVerifyBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageOrContainerId); + ExitOnFailure(hr, "Failed to write package or container id of OnCacheVerifyBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPayloadId); + ExitOnFailure(hr, "Failed to write payload id of OnCacheVerifyBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheVerifyBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCacheVerifyBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCacheVerifyBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnCacheVerifyBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCacheVerifyComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in HRESULT hrStatus, + __inout BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION* pAction + ) +{ + HRESULT hr = S_OK; + BA_ONCACHEVERIFYCOMPLETE_ARGS args = { }; + BA_ONCACHEVERIFYCOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageOrContainerId = wzPackageOrContainerId; + args.wzPayloadId = wzPayloadId; + args.hrStatus = hrStatus; + args.recommendation = *pAction; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.action = *pAction; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheVerifyComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageOrContainerId); + ExitOnFailure(hr, "Failed to write package or container id of OnCacheVerifyComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPayloadId); + ExitOnFailure(hr, "Failed to write payload id of OnCacheVerifyComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnCacheVerifyComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendation); + ExitOnFailure(hr, "Failed to write recommendation of OnCacheVerifyComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheVerifyComplete results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.action); + ExitOnFailure(hr, "Failed to write action of OnCacheVerifyComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYCOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCacheVerifyComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCacheVerifyComplete result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.action)); + ExitOnFailure(hr, "Failed to read action of OnCacheVerifyComplete result."); + + if (FAILED(hrStatus)) + { + *pAction = results.action; + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCacheVerifyProgress( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in DWORD64 dw64Progress, + __in DWORD64 dw64Total, + __in DWORD dwOverallPercentage, + __in BOOTSTRAPPER_CACHE_VERIFY_STEP verifyStep + ) +{ + HRESULT hr = S_OK; + BA_ONCACHEVERIFYPROGRESS_ARGS args = { }; + BA_ONCACHEVERIFYPROGRESS_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageOrContainerId = wzPackageOrContainerId; + args.wzPayloadId = wzPayloadId; + args.dw64Progress = dw64Progress; + args.dw64Total = dw64Total; + args.dwOverallPercentage = dwOverallPercentage; + args.verifyStep = verifyStep; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheVerifyProgress args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageOrContainerId); + ExitOnFailure(hr, "Failed to write package or container id of OnCacheVerifyProgress args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPayloadId); + ExitOnFailure(hr, "Failed to write payload id of OnCacheVerifyProgress args."); + + hr = BuffWriteNumber64ToBuffer(&bufferArgs, args.dw64Progress); + ExitOnFailure(hr, "Failed to write progress of OnCacheVerifyProgress args."); + + hr = BuffWriteNumber64ToBuffer(&bufferArgs, args.dw64Total); + ExitOnFailure(hr, "Failed to write total progress of OnCacheVerifyProgress args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwOverallPercentage); + ExitOnFailure(hr, "Failed to write overall percentage of OnCacheVerifyProgress args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.verifyStep); + ExitOnFailure(hr, "Failed to write verify step of OnCacheVerifyProgress args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCacheVerifyProgress results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYPROGRESS, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCacheVerifyProgress failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCacheVerifyProgress result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnCacheVerifyProgress result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCommitMsiTransactionBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in LPCWSTR wzTransactionId + ) +{ + HRESULT hr = S_OK; + BA_ONCOMMITMSITRANSACTIONBEGIN_ARGS args = { }; + BA_ONCOMMITMSITRANSACTIONBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzTransactionId = wzTransactionId; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCommitMsiTransactionBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzTransactionId); + ExitOnFailure(hr, "Failed to write transaction id of OnCommitMsiTransactionBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCommitMsiTransactionBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCOMMITMSITRANSACTIONBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCommitMsiTransactionBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCommitMsiTransactionBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnCommitMsiTransactionBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCommitMsiTransactionComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in LPCWSTR wzTransactionId, + __in HRESULT hrStatus, + __in BOOTSTRAPPER_APPLY_RESTART restart, + __inout BOOTSTRAPPER_EXECUTEMSITRANSACTIONCOMPLETE_ACTION* pAction +) +{ + HRESULT hr = S_OK; + BA_ONCOMMITMSITRANSACTIONCOMPLETE_ARGS args = { }; + BA_ONCOMMITMSITRANSACTIONCOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzTransactionId = wzTransactionId; + args.hrStatus = hrStatus; + args.restart = restart; + args.recommendation = *pAction; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.action = *pAction; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCommitMsiTransactionComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzTransactionId); + ExitOnFailure(hr, "Failed to write transaction id of OnCommitMsiTransactionComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnCommitMsiTransactionComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.restart); + ExitOnFailure(hr, "Failed to write restart of OnCommitMsiTransactionComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendation); + ExitOnFailure(hr, "Failed to write recommendation of OnCommitMsiTransactionComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCommitMsiTransactionComplete results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.action); + ExitOnFailure(hr, "Failed to write API version of OnCommitMsiTransactionComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCOMMITMSITRANSACTIONCOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCommitMsiTransactionComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnCommitMsiTransactionComplete result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.action)); + ExitOnFailure(hr, "Failed to read action of OnCommitMsiTransactionComplete result."); + + *pAction = results.action; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnCreate( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOTSTRAPPER_COMMAND* pCommand +) +{ + HRESULT hr = S_OK; + BA_ONCREATE_ARGS args = { }; + BA_ONCREATE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCreate args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, pCommand->cbSize); + ExitOnFailure(hr, "Failed to write size of OnCreate args command."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, pCommand->action); + ExitOnFailure(hr, "Failed to write action of OnCreate args command."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, pCommand->display); + ExitOnFailure(hr, "Failed to write display of OnCreate args command."); + + hr = BuffWriteStringToBuffer(&bufferArgs, pCommand->wzCommandLine); + ExitOnFailure(hr, "Failed to write command-line of OnCreate args command."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, pCommand->nCmdShow); + ExitOnFailure(hr, "Failed to write show command of OnCreate args command."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, pCommand->resumeType); + ExitOnFailure(hr, "Failed to write resume type of OnCreate args command."); + + hr = BuffWriteNumber64ToBuffer(&bufferArgs, reinterpret_cast(pCommand->hwndSplashScreen)); + ExitOnFailure(hr, "Failed to write splash screen handle of OnCreate args command."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, pCommand->relationType); + ExitOnFailure(hr, "Failed to write relation type of OnCreate args command."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, pCommand->fPassthrough); + ExitOnFailure(hr, "Failed to write passthrough of OnCreate args command."); + + hr = BuffWriteStringToBuffer(&bufferArgs, pCommand->wzLayoutDirectory); + ExitOnFailure(hr, "Failed to write layout directory of OnCreate args command."); + + hr = BuffWriteStringToBuffer(&bufferArgs, pCommand->wzBootstrapperWorkingFolder); + ExitOnFailure(hr, "Failed to write working folder of OnCreate args command."); + + hr = BuffWriteStringToBuffer(&bufferArgs, pCommand->wzBootstrapperApplicationDataPath); + ExitOnFailure(hr, "Failed to write application data path of OnCreate args command."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnCreate results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCREATE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnCreate failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnDestroy( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOL fReload +) +{ + HRESULT hr = S_OK; + BA_ONDESTROY_ARGS args = { }; + BA_ONDESTROY_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.fReload = fReload; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDestroy args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fReload); + ExitOnFailure(hr, "Failed to write reload of OnDestroy args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDestroy results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDESTROY, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnDestroy failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnDetectBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOL fCached, + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType, + __in DWORD cPackages + ) +{ + HRESULT hr = S_OK; + BA_ONDETECTBEGIN_ARGS args = { }; + BA_ONDETECTBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.registrationType = registrationType; + args.cPackages = cPackages; + args.fCached = fCached; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.registrationType); + ExitOnFailure(hr, "Failed to write restart of OnDetectBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.cPackages); + ExitOnFailure(hr, "Failed to write package count of OnDetectBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fCached); + ExitOnFailure(hr, "Failed to write cached of OnDetectBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnDetectBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnDetectBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnDetectBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnDetectCompatibleMsiPackage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzCompatiblePackageId, + __in VERUTIL_VERSION* pCompatiblePackageVersion + ) +{ + HRESULT hr = S_OK; + BA_ONDETECTCOMPATIBLEMSIPACKAGE_ARGS args = { }; + BA_ONDETECTCOMPATIBLEMSIPACKAGE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.wzCompatiblePackageId = wzCompatiblePackageId; + args.wzCompatiblePackageVersion = pCompatiblePackageVersion->sczVersion; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectCompatibleMsiPackage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnDetectCompatibleMsiPackage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzCompatiblePackageId); + ExitOnFailure(hr, "Failed to write compatible package id of OnDetectCompatibleMsiPackage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzCompatiblePackageVersion); + ExitOnFailure(hr, "Failed to write compatible package version of OnDetectCompatibleMsiPackage args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectCompatibleMsiPackage results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnDetectCompatibleMsiPackage failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnDetectCompatibleMsiPackage result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnDetectCompatibleMsiPackage result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnDetectComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus, + __in BOOL fEligibleForCleanup + ) +{ + HRESULT hr = S_OK; + BA_ONDETECTCOMPLETE_ARGS args = { }; + BA_ONDETECTCOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.hrStatus = hrStatus; + args.fEligibleForCleanup = fEligibleForCleanup; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnDetectComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fEligibleForCleanup); + ExitOnFailure(hr, "Failed to write eligible for cleanup of OnDetectComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectComplete results."); + + // Callback. + hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnDetectComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnDetectForwardCompatibleBundle( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzBundleId, + __in BOOTSTRAPPER_RELATION_TYPE relationType, + __in_z LPCWSTR wzBundleTag, + __in BOOL fPerMachine, + __in VERUTIL_VERSION* pVersion, + __in BOOL fMissingFromCache + ) +{ + HRESULT hr = S_OK; + BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS args = { }; + BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzBundleId = wzBundleId; + args.relationType = relationType; + args.wzBundleTag = wzBundleTag; + args.fPerMachine = fPerMachine; + args.wzVersion = pVersion->sczVersion; + args.fMissingFromCache = fMissingFromCache; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectForwardCompatibleBundle args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzBundleId); + ExitOnFailure(hr, "Failed to write bundle id of OnDetectForwardCompatibleBundle args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.relationType); + ExitOnFailure(hr, "Failed to write relation type of OnDetectForwardCompatibleBundle args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzBundleTag); + ExitOnFailure(hr, "Failed to write bundle tag of OnDetectForwardCompatibleBundle args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fPerMachine); + ExitOnFailure(hr, "Failed to write per-machine of OnDetectForwardCompatibleBundle args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzVersion); + ExitOnFailure(hr, "Failed to write version of OnDetectForwardCompatibleBundle args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fMissingFromCache); + ExitOnFailure(hr, "Failed to write missing from cache of OnDetectForwardCompatibleBundle args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectForwardCompatibleBundle results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnDetectForwardCompatibleBundle failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnDetectForwardCompatibleBundle result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnDetectForwardCompatibleBundle result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnDetectMsiFeature( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzFeatureId, + __in BOOTSTRAPPER_FEATURE_STATE state + ) +{ + HRESULT hr = S_OK; + BA_ONDETECTMSIFEATURE_ARGS args = { }; + BA_ONDETECTMSIFEATURE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.wzFeatureId = wzFeatureId; + args.state = state; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectMsiFeature args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnDetectMsiFeature args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzFeatureId); + ExitOnFailure(hr, "Failed to write feature id of OnDetectMsiFeature args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.state); + ExitOnFailure(hr, "Failed to write state of OnDetectMsiFeature args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectMsiFeature results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTMSIFEATURE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnDetectMsiFeature failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnDetectMsiFeature result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnDetectMsiFeature result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnDetectPackageBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId + ) +{ + HRESULT hr = S_OK; + BA_ONDETECTPACKAGEBEGIN_ARGS args = { }; + BA_ONDETECTPACKAGEBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectPackageBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnDetectPackageBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectPackageBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGEBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnDetectPackageBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnDetectPackageBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnDetectPackageBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnDetectPackageComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in HRESULT hrStatus, + __in BOOTSTRAPPER_PACKAGE_STATE state, + __in BOOL fCached + ) +{ + HRESULT hr = S_OK; + BA_ONDETECTPACKAGECOMPLETE_ARGS args = { }; + BA_ONDETECTPACKAGECOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.hrStatus = hrStatus; + args.state = state; + args.fCached = fCached; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectPackageComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnDetectPackageComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnDetectPackageComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.state); + ExitOnFailure(hr, "Failed to write state of OnDetectPackageComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fCached); + ExitOnFailure(hr, "Failed to write cached of OnDetectPackageComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectPackageComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGECOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnDetectPackageComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnDetectRelatedBundle( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzBundleId, + __in BOOTSTRAPPER_RELATION_TYPE relationType, + __in_z LPCWSTR wzBundleTag, + __in BOOL fPerMachine, + __in VERUTIL_VERSION* pVersion, + __in BOOL fMissingFromCache + ) +{ + HRESULT hr = S_OK; + BA_ONDETECTRELATEDBUNDLE_ARGS args = { }; + BA_ONDETECTRELATEDBUNDLE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzBundleId = wzBundleId; + args.relationType = relationType; + args.wzBundleTag = wzBundleTag; + args.fPerMachine = fPerMachine; + args.wzVersion = pVersion->sczVersion; + args.fMissingFromCache = fMissingFromCache; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectRelatedBundle args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzBundleId); + ExitOnFailure(hr, "Failed to write bundle id of OnDetectRelatedBundle args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.relationType); + ExitOnFailure(hr, "Failed to write relation type of OnDetectRelatedBundle args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzBundleTag); + ExitOnFailure(hr, "Failed to write bundle tag of OnDetectRelatedBundle args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fPerMachine); + ExitOnFailure(hr, "Failed to write per-machine of OnDetectRelatedBundle args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzVersion); + ExitOnFailure(hr, "Failed to write version of OnDetectRelatedBundle args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fMissingFromCache); + ExitOnFailure(hr, "Failed to write cached of OnDetectRelatedBundle args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectRelatedBundle results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDBUNDLE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnDetectRelatedBundle failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnDetectRelatedBundle result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnDetectRelatedBundle result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnDetectRelatedBundlePackage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzBundleId, + __in BOOTSTRAPPER_RELATION_TYPE relationType, + __in BOOL fPerMachine, + __in VERUTIL_VERSION* pVersion + ) +{ + HRESULT hr = S_OK; + BA_ONDETECTRELATEDBUNDLEPACKAGE_ARGS args = { }; + BA_ONDETECTRELATEDBUNDLEPACKAGE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.wzBundleId = wzBundleId; + args.relationType = relationType; + args.fPerMachine = fPerMachine; + args.wzVersion = pVersion->sczVersion; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectRelatedBundlePackage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnDetectRelatedBundlePackage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzBundleId); + ExitOnFailure(hr, "Failed to write bundle id of OnDetectRelatedBundlePackage args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.relationType); + ExitOnFailure(hr, "Failed to write relation type of OnDetectRelatedBundlePackage args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fPerMachine); + ExitOnFailure(hr, "Failed to write per-machine of OnDetectRelatedBundlePackage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzVersion); + ExitOnFailure(hr, "Failed to write version of OnDetectRelatedBundlePackage args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectRelatedBundlePackage results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDBUNDLEPACKAGE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnDetectRelatedBundlePackage failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnDetectRelatedBundlePackage result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnDetectRelatedBundlePackage result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnDetectRelatedMsiPackage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzUpgradeCode, + __in_z LPCWSTR wzProductCode, + __in BOOL fPerMachine, + __in VERUTIL_VERSION* pVersion, + __in BOOTSTRAPPER_RELATED_OPERATION operation + ) +{ + HRESULT hr = S_OK; + BA_ONDETECTRELATEDMSIPACKAGE_ARGS args = { }; + BA_ONDETECTRELATEDMSIPACKAGE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.wzUpgradeCode = wzUpgradeCode; + args.wzProductCode = wzProductCode; + args.fPerMachine = fPerMachine; + args.wzVersion = pVersion->sczVersion; + args.operation = operation; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectRelatedMsiPackage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnDetectRelatedMsiPackage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzUpgradeCode); + ExitOnFailure(hr, "Failed to write upgrade code of OnDetectRelatedMsiPackage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzProductCode); + ExitOnFailure(hr, "Failed to write product code of OnDetectRelatedMsiPackage args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fPerMachine); + ExitOnFailure(hr, "Failed to write per-machine of OnDetectRelatedMsiPackage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzVersion); + ExitOnFailure(hr, "Failed to write version of OnDetectRelatedMsiPackage args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.operation); + ExitOnFailure(hr, "Failed to write operation OnDetectRelatedMsiPackage args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectRelatedMsiPackage results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDMSIPACKAGE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnDetectRelatedMsiPackage failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnDetectRelatedMsiPackage result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnDetectRelatedMsiPackage result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnDetectPatchTarget( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzProductCode, + __in BOOTSTRAPPER_PACKAGE_STATE patchState + ) +{ + HRESULT hr = S_OK; + BA_ONDETECTPATCHTARGET_ARGS args = { }; + BA_ONDETECTPATCHTARGET_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.wzProductCode = wzProductCode; + args.patchState = patchState; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectPatchTarget args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnDetectPatchTarget args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzProductCode); + ExitOnFailure(hr, "Failed to write product code of OnDetectPatchTarget args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.patchState); + ExitOnFailure(hr, "Failed to write patch state OnDetectPatchTarget args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectPatchTarget results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPATCHTARGET, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnDetectPatchTarget failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnDetectPatchTarget result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnDetectPatchTarget result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnDetectUpdate( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzUpdateLocation, + __in DWORD64 dw64Size, + __in_z_opt LPCWSTR wzHash, + __in BOOTSTRAPPER_UPDATE_HASH_TYPE hashAlgorithm, + __in VERUTIL_VERSION* pVersion, + __in_z_opt LPCWSTR wzTitle, + __in_z_opt LPCWSTR wzSummary, + __in_z_opt LPCWSTR wzContentType, + __in_z_opt LPCWSTR wzContent, + __inout BOOL* pfStopProcessingUpdates + ) +{ + HRESULT hr = S_OK; + BA_ONDETECTUPDATE_ARGS args = { }; + BA_ONDETECTUPDATE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzUpdateLocation = wzUpdateLocation; + args.dw64Size = dw64Size; + args.wzHash = wzHash; + args.hashAlgorithm = hashAlgorithm; + args.wzVersion = pVersion->sczVersion; + args.wzTitle = wzTitle; + args.wzSummary = wzSummary; + args.wzContentType = wzContentType; + args.wzContent = wzContent; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.fStopProcessingUpdates = *pfStopProcessingUpdates; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectUpdate args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzUpdateLocation); + ExitOnFailure(hr, "Failed to write update location of OnDetectUpdate args."); + + hr = BuffWriteNumber64ToBuffer(&bufferArgs, args.dw64Size); + ExitOnFailure(hr, "Failed to write update size OnDetectUpdate args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzHash); + ExitOnFailure(hr, "Failed to write hash of OnDetectUpdate args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hashAlgorithm); + ExitOnFailure(hr, "Failed to write hash algorithm OnDetectUpdate args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzVersion); + ExitOnFailure(hr, "Failed to write version of OnDetectUpdate args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzTitle); + ExitOnFailure(hr, "Failed to write title of OnDetectUpdate args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzSummary); + ExitOnFailure(hr, "Failed to write summary of OnDetectUpdate args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzContentType); + ExitOnFailure(hr, "Failed to write content type of OnDetectUpdate args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzContent); + ExitOnFailure(hr, "Failed to write content of OnDetectUpdate args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectUpdate results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.fStopProcessingUpdates); + ExitOnFailure(hr, "Failed to write stop processing updates of OnDetectUpdate results."); + + // Callback. + hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnDetectUpdate failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnDetectUpdate result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnDetectUpdate result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fStopProcessingUpdates)); + ExitOnFailure(hr, "Failed to read stop processing updates of OnDetectUpdate result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + + *pfStopProcessingUpdates = results.fStopProcessingUpdates; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnDetectUpdateBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzUpdateLocation, + __inout BOOL* pfSkip + ) +{ + HRESULT hr = S_OK; + BA_ONDETECTUPDATEBEGIN_ARGS args = { }; + BA_ONDETECTUPDATEBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzUpdateLocation = wzUpdateLocation; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.fSkip = *pfSkip; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectUpdateBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzUpdateLocation); + ExitOnFailure(hr, "Failed to write update location of OnDetectUpdateBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectUpdateBegin results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.fSkip); + ExitOnFailure(hr, "Failed to write skip of OnDetectUpdateBegin results."); + + // Callback. + hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATEBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnDetectUpdateBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnDetectUpdateBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnDetectUpdateBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fSkip)); + ExitOnFailure(hr, "Failed to read cancel of OnDetectUpdateBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + + *pfSkip = results.fSkip; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnDetectUpdateComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus, + __inout BOOL* pfIgnoreError + ) +{ + HRESULT hr = S_OK; + BA_ONDETECTUPDATECOMPLETE_ARGS args = { }; + BA_ONDETECTUPDATECOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.hrStatus = hrStatus; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.fIgnoreError = *pfIgnoreError; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectUpdateComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnDetectUpdateComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnDetectUpdateComplete results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.fIgnoreError); + ExitOnFailure(hr, "Failed to write ignore error of OnDetectUpdateComplete results."); + + // Callback. + hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATECOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnDetectUpdateComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnDetectUpdateComplete result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fIgnoreError)); + ExitOnFailure(hr, "Failed to read ignore error of OnDetectUpdateComplete result."); + + if (FAILED(hrStatus)) + { + *pfIgnoreError = results.fIgnoreError; + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnElevateBegin( + __in BURN_USER_EXPERIENCE* pUserExperience + ) +{ + HRESULT hr = S_OK; + BA_ONELEVATEBEGIN_ARGS args = { }; + BA_ONELEVATEBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnElevateBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnElevateBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATEBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnElevateBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnElevateBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnElevateBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnElevateComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ) +{ + HRESULT hr = S_OK; + BA_ONELEVATECOMPLETE_ARGS args = { }; + BA_ONELEVATECOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.hrStatus = hrStatus; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnElevateComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnElevateComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnElevateComplete results."); + + // Callback. + hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATECOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnElevateComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnError( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOTSTRAPPER_ERROR_TYPE errorType, + __in_z_opt LPCWSTR wzPackageId, + __in DWORD dwCode, + __in_z_opt LPCWSTR wzError, + __in DWORD dwUIHint, + __in DWORD cData, + __in_ecount_z_opt(cData) LPCWSTR* rgwzData, + __inout int* pnResult + ) +{ + HRESULT hr = S_OK; + BA_ONERROR_ARGS args = { }; + BA_ONERROR_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.errorType = errorType; + args.wzPackageId = wzPackageId; + args.dwCode = dwCode; + args.wzError = wzError; + args.dwUIHint = dwUIHint; + args.cData = cData; + args.rgwzData = rgwzData; + args.nRecommendation = *pnResult; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.nResult = *pnResult; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnError args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.errorType); + ExitOnFailure(hr, "Failed to write error type OnError args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnError args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwCode); + ExitOnFailure(hr, "Failed to write code OnError args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzError); + ExitOnFailure(hr, "Failed to write error of OnError args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwUIHint); + ExitOnFailure(hr, "Failed to write UI hint OnError args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.cData); + ExitOnFailure(hr, "Failed to write count of data of OnError args."); + + for (DWORD i = 0; i < args.cData; ++i) + { + hr = BuffWriteStringToBuffer(&bufferArgs, args.rgwzData[i]); + ExitOnFailure(hr, "Failed to write data[%u] of OnError args.", i); + } + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.nRecommendation); + ExitOnFailure(hr, "Failed to write recommendation of OnError args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnError results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.nResult); + ExitOnFailure(hr, "Failed to write result of OnError results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONERROR, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnError failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnError result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.nResult)); + ExitOnFailure(hr, "Failed to read result of OnError result."); + + *pnResult = results.nResult; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnExecuteBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in DWORD cExecutingPackages + ) +{ + HRESULT hr = S_OK; + BA_ONEXECUTEBEGIN_ARGS args = { }; + BA_ONEXECUTEBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.cExecutingPackages = cExecutingPackages; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecuteBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.cExecutingPackages); + ExitOnFailure(hr, "Failed to write executing packages OnExecuteBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecuteBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnExecuteBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnExecuteBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnExecuteBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnExecuteComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ) +{ + HRESULT hr = S_OK; + BA_ONEXECUTECOMPLETE_ARGS args = { }; + BA_ONEXECUTECOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.hrStatus = hrStatus; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecuteComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status OnExecuteComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecuteComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTECOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnExecuteComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnExecuteFilesInUse( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in DWORD cFiles, + __in_ecount_z_opt(cFiles) LPCWSTR* rgwzFiles, + __in BOOTSTRAPPER_FILES_IN_USE_TYPE source, + __inout int* pnResult + ) +{ + HRESULT hr = S_OK; + BA_ONEXECUTEFILESINUSE_ARGS args = { }; + BA_ONEXECUTEFILESINUSE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.cFiles = cFiles; + args.rgwzFiles = rgwzFiles; + args.nRecommendation = *pnResult; + args.source = source; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.nResult = *pnResult; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecuteFilesInUse args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnExecuteFilesInUse args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.cFiles); + ExitOnFailure(hr, "Failed to write count of files of OnExecuteFilesInUse args."); + + for (DWORD i = 0; i < args.cFiles; ++i) + { + hr = BuffWriteStringToBuffer(&bufferArgs, args.rgwzFiles[i]); + ExitOnFailure(hr, "Failed to write file[%u] of OnExecuteFilesInUse args.", i); + } + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.nRecommendation); + ExitOnFailure(hr, "Failed to write recommendation of OnExecuteFilesInUse args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.source); + ExitOnFailure(hr, "Failed to write source of OnExecuteFilesInUse args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecuteFilesInUse results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.nResult); + ExitOnFailure(hr, "Failed to write result of OnExecuteFilesInUse results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEFILESINUSE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnExecuteFilesInUse failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnExecuteFilesInUse result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.nResult)); + ExitOnFailure(hr, "Failed to read result of OnExecuteFilesInUse result."); + + *pnResult = results.nResult; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnExecuteMsiMessage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in INSTALLMESSAGE messageType, + __in DWORD dwUIHint, + __in_z LPCWSTR wzMessage, + __in DWORD cData, + __in_ecount_z_opt(cData) LPCWSTR* rgwzData, + __inout int* pnResult + ) +{ + HRESULT hr = S_OK; + BA_ONEXECUTEMSIMESSAGE_ARGS args = { }; + BA_ONEXECUTEMSIMESSAGE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.messageType = messageType; + args.dwUIHint = dwUIHint; + args.wzMessage = wzMessage; + args.cData = cData; + args.rgwzData = rgwzData; + args.nRecommendation = *pnResult; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.nResult = *pnResult; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecuteMsiMessage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnExecuteMsiMessage args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.messageType); + ExitOnFailure(hr, "Failed to write message type OnExecuteMsiMessage args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwUIHint); + ExitOnFailure(hr, "Failed to write UI hint OnExecuteMsiMessage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzMessage); + ExitOnFailure(hr, "Failed to write message of OnExecuteMsiMessage args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.cData); + ExitOnFailure(hr, "Failed to write count of data of OnExecuteMsiMessage args."); + + for (DWORD i = 0; i < args.cData; ++i) + { + hr = BuffWriteStringToBuffer(&bufferArgs, args.rgwzData[i]); + ExitOnFailure(hr, "Failed to write data[%u] of OnExecuteMsiMessage args.", i); + } + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.nRecommendation); + ExitOnFailure(hr, "Failed to write recommendation of OnExecuteMsiMessage args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecuteMsiMessage results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.nResult); + ExitOnFailure(hr, "Failed to write result of OnExecuteMsiMessage results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEMSIMESSAGE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnExecuteMsiMessage failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnExecuteMsiMessage result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.nResult)); + ExitOnFailure(hr, "Failed to read cancel of OnExecuteMsiMessage result."); + + *pnResult = results.nResult; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnExecutePackageBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in BOOL fExecute, + __in BOOTSTRAPPER_ACTION_STATE action, + __in INSTALLUILEVEL uiLevel, + __in BOOL fDisableExternalUiHandler + ) +{ + HRESULT hr = S_OK; + BA_ONEXECUTEPACKAGEBEGIN_ARGS args = { }; + BA_ONEXECUTEPACKAGEBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.fExecute = fExecute; + args.action = action; + args.uiLevel = uiLevel; + args.fDisableExternalUiHandler = fDisableExternalUiHandler; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecutePackageBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnExecutePackageBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fExecute); + ExitOnFailure(hr, "Failed to write execute OnExecutePackageBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.action); + ExitOnFailure(hr, "Failed to write action OnExecutePackageBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.uiLevel); + ExitOnFailure(hr, "Failed to write UI level of OnExecutePackageBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fDisableExternalUiHandler); + ExitOnFailure(hr, "Failed to write disable external UI handler of OnExecutePackageBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecutePackageBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGEBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnExecutePackageBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnExecutePackageBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnExecutePackageBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnExecutePackageComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in HRESULT hrStatus, + __in BOOTSTRAPPER_APPLY_RESTART restart, + __inout BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION* pAction + ) +{ + HRESULT hr = S_OK; + BA_ONEXECUTEPACKAGECOMPLETE_ARGS args = { }; + BA_ONEXECUTEPACKAGECOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.hrStatus = hrStatus; + args.restart = restart; + args.recommendation = *pAction; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.action = *pAction; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecutePackageComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnExecutePackageComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnExecutePackageComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.restart); + ExitOnFailure(hr, "Failed to write restart of OnExecutePackageComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendation); + ExitOnFailure(hr, "Failed to write recommendation of OnExecutePackageComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecutePackageComplete results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.action); + ExitOnFailure(hr, "Failed to write action of OnExecutePackageComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGECOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnExecutePackageComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnExecutePackageComplete result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.action)); + ExitOnFailure(hr, "Failed to read action of OnExecutePackageComplete result."); + + *pAction = results.action; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnExecutePatchTarget( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzTargetProductCode + ) +{ + HRESULT hr = S_OK; + BA_ONEXECUTEPATCHTARGET_ARGS args = { }; + BA_ONEXECUTEPATCHTARGET_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.wzTargetProductCode = wzTargetProductCode; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecutePatchTarget args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnExecutePatchTarget args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzTargetProductCode); + ExitOnFailure(hr, "Failed to write target product code of OnExecutePatchTarget args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecutePatchTarget results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPATCHTARGET, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnExecutePatchTarget failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnExecutePatchTarget result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnExecutePatchTarget result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnExecuteProcessCancel( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in DWORD dwProcessId, + __inout BOOTSTRAPPER_EXECUTEPROCESSCANCEL_ACTION* pAction + ) +{ + HRESULT hr = S_OK; + BA_ONEXECUTEPROCESSCANCEL_ARGS args = { }; + BA_ONEXECUTEPROCESSCANCEL_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.dwProcessId = dwProcessId; + args.recommendation = *pAction; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.action = *pAction; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecuteProcessCancel args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnExecuteProcessCancel args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwProcessId); + ExitOnFailure(hr, "Failed to write process id of OnExecuteProcessCancel args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendation); + ExitOnFailure(hr, "Failed to write recommendation of OnExecuteProcessCancel args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecuteProcessCancel results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.action); + ExitOnFailure(hr, "Failed to write action of OnExecuteProcessCancel results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPROCESSCANCEL, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnExecuteProcessCancel failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnExecuteProcessCancel result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.action)); + ExitOnFailure(hr, "Failed to read action of OnExecuteProcessCancel result."); + + *pAction = results.action; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnExecuteProgress( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in DWORD dwProgressPercentage, + __in DWORD dwOverallPercentage, + __out int* pnResult + ) +{ + HRESULT hr = S_OK; + BA_ONEXECUTEPROGRESS_ARGS args = { }; + BA_ONEXECUTEPROGRESS_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.dwProgressPercentage = dwProgressPercentage; + args.dwOverallPercentage = dwOverallPercentage; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecuteProgress args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnExecuteProgress args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwProgressPercentage); + ExitOnFailure(hr, "Failed to write progress of OnExecuteProgress args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwOverallPercentage); + ExitOnFailure(hr, "Failed to write overall progress of OnExecuteProgress args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnExecuteProgress results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPROGRESS, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnExecuteProgress failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnExecuteProgress result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnExecuteProgress result."); + +LExit: + if (FAILED(hr)) + { + *pnResult = IDERROR; + } + else if (results.fCancel) + { + *pnResult = IDCANCEL; + } + else + { + *pnResult = IDNOACTION; + } + + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnLaunchApprovedExeBegin( + __in BURN_USER_EXPERIENCE* pUserExperience + ) +{ + HRESULT hr = S_OK; + BA_ONLAUNCHAPPROVEDEXEBEGIN_ARGS args = { }; + BA_ONLAUNCHAPPROVEDEXEBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnLaunchApprovedExeBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnLaunchApprovedExeBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnLaunchApprovedExeBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnLaunchApprovedExeBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnLaunchApprovedExeBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnLaunchApprovedExeComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus, + __in DWORD dwProcessId + ) +{ + HRESULT hr = S_OK; + BA_ONLAUNCHAPPROVEDEXECOMPLETE_ARGS args = { }; + BA_ONLAUNCHAPPROVEDEXECOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.hrStatus = hrStatus; + args.dwProcessId = dwProcessId; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnLaunchApprovedExeComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnLaunchApprovedExeComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwProcessId); + ExitOnFailure(hr, "Failed to write process id of OnLaunchApprovedExeComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnLaunchApprovedExeComplete results."); + + // Callback. + hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnLaunchApprovedExeComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPauseAUBegin( + __in BURN_USER_EXPERIENCE* pUserExperience + ) +{ + HRESULT hr = S_OK; + BA_ONPAUSEAUTOMATICUPDATESBEGIN_ARGS args = { }; + BA_ONPAUSEAUTOMATICUPDATESBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPauseAUBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPauseAUBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPAUSEAUTOMATICUPDATESBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPauseAUBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPauseAUComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ) +{ + HRESULT hr = S_OK; + BA_ONPAUSEAUTOMATICUPDATESCOMPLETE_ARGS args = { }; + BA_ONPAUSEAUTOMATICUPDATESCOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.hrStatus = hrStatus; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPauseAUComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnPauseAUComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPauseAUComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPAUSEAUTOMATICUPDATESCOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPauseAUComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlanBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in DWORD cPackages + ) +{ + HRESULT hr = S_OK; + BA_ONPLANBEGIN_ARGS args = { }; + BA_ONPLANBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.cPackages = cPackages; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.cPackages); + ExitOnFailure(hr, "Failed to write count of packages of OnPlanBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlanBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnPlanBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnPlanBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlanCompatibleMsiPackageBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzCompatiblePackageId, + __in VERUTIL_VERSION* pCompatiblePackageVersion, + __inout BOOL* pfRequested + ) +{ + HRESULT hr = S_OK; + BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_ARGS args = { }; + BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.wzCompatiblePackageId = wzCompatiblePackageId; + args.wzCompatiblePackageVersion = pCompatiblePackageVersion->sczVersion; + args.fRecommendedRemove = *pfRequested; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.fRequestRemove = *pfRequested; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanCompatibleMsiPackageBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnPlanCompatibleMsiPackageBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzCompatiblePackageId); + ExitOnFailure(hr, "Failed to write compatible package id of OnPlanCompatibleMsiPackageBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzCompatiblePackageVersion); + ExitOnFailure(hr, "Failed to write compatible package version of OnPlanCompatibleMsiPackageBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fRecommendedRemove); + ExitOnFailure(hr, "Failed to write recommend remove of OnPlanCompatibleMsiPackageBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanCompatibleMsiPackageBegin results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.fRequestRemove); + ExitOnFailure(hr, "Failed to write request remove of OnPlanCompatibleMsiPackageBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlanCompatibleMsiPackageBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnPlanCompatibleMsiPackageBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnPlanCompatibleMsiPackageBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fRequestRemove)); + ExitOnFailure(hr, "Failed to read requested remove of OnPlanCompatibleMsiPackageBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + + *pfRequested = results.fRequestRemove; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlanCompatibleMsiPackageComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzCompatiblePackageId, + __in HRESULT hrStatus, + __in BOOL fRequested + ) +{ + HRESULT hr = S_OK; + BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_ARGS args = { }; + BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.wzCompatiblePackageId = wzCompatiblePackageId; + args.hrStatus = hrStatus; + args.fRequestedRemove = fRequested; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanCompatibleMsiPackageComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnPlanCompatibleMsiPackageComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzCompatiblePackageId); + ExitOnFailure(hr, "Failed to write compatible package id of OnPlanCompatibleMsiPackageComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnPlanCompatibleMsiPackageComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fRequestedRemove); + ExitOnFailure(hr, "Failed to write requested remove of OnPlanCompatibleMsiPackageComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanCompatibleMsiPackageComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlanCompatibleMsiPackageComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlanMsiFeature( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzFeatureId, + __inout BOOTSTRAPPER_FEATURE_STATE* pRequestedState + ) +{ + HRESULT hr = S_OK; + BA_ONPLANMSIFEATURE_ARGS args = { }; + BA_ONPLANMSIFEATURE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.wzFeatureId = wzFeatureId; + args.recommendedState = *pRequestedState; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.requestedState = *pRequestedState; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanMsiFeature args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnPlanMsiFeature args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzFeatureId); + ExitOnFailure(hr, "Failed to write feature id of OnPlanMsiFeature args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendedState); + ExitOnFailure(hr, "Failed to write recommended state of OnPlanMsiFeature args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanMsiFeature results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.requestedState); + ExitOnFailure(hr, "Failed to write requested state of OnPlanMsiFeature results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIFEATURE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlanMsiFeature failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnPlanMsiFeature result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.requestedState)); + ExitOnFailure(hr, "Failed to read requested state of OnPlanMsiFeature result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnPlanMsiFeature result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + + *pRequestedState = results.requestedState; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlanComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ) +{ + HRESULT hr = S_OK; + BA_ONPLANCOMPLETE_ARGS args = { }; + BA_ONPLANCOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.hrStatus = hrStatus; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnPlanComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanComplete results."); + + // Callback. + hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlanComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlanForwardCompatibleBundle( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzBundleId, + __in BOOTSTRAPPER_RELATION_TYPE relationType, + __in_z LPCWSTR wzBundleTag, + __in BOOL fPerMachine, + __in VERUTIL_VERSION* pVersion, + __inout BOOL* pfIgnoreBundle + ) +{ + HRESULT hr = S_OK; + BA_ONPLANFORWARDCOMPATIBLEBUNDLE_ARGS args = { }; + BA_ONPLANFORWARDCOMPATIBLEBUNDLE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzBundleId = wzBundleId; + args.relationType = relationType; + args.wzBundleTag = wzBundleTag; + args.fPerMachine = fPerMachine; + args.wzVersion = pVersion->sczVersion; + args.fRecommendedIgnoreBundle = *pfIgnoreBundle; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.fIgnoreBundle = *pfIgnoreBundle; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanForwardCompatibleBundle args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzBundleId); + ExitOnFailure(hr, "Failed to write bundle id of OnPlanForwardCompatibleBundle args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.relationType); + ExitOnFailure(hr, "Failed to write relation type of OnPlanForwardCompatibleBundle args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzBundleTag); + ExitOnFailure(hr, "Failed to write bundle tag of OnPlanForwardCompatibleBundle args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fPerMachine); + ExitOnFailure(hr, "Failed to write per-machine of OnPlanForwardCompatibleBundle args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzVersion); + ExitOnFailure(hr, "Failed to write version of OnPlanForwardCompatibleBundle args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fRecommendedIgnoreBundle); + ExitOnFailure(hr, "Failed to write recommended ignore bundle of OnPlanForwardCompatibleBundle args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanForwardCompatibleBundle results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.fIgnoreBundle); + ExitOnFailure(hr, "Failed to write ignore bundle of OnPlanForwardCompatibleBundle results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANFORWARDCOMPATIBLEBUNDLE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlanForwardCompatibleBundle failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnPlanForwardCompatibleBundle result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnPlanForwardCompatibleBundle result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fIgnoreBundle)); + ExitOnFailure(hr, "Failed to read ignore bundle of OnPlanForwardCompatibleBundle result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + + *pfIgnoreBundle = results.fIgnoreBundle; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlanMsiPackage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in BOOL fExecute, + __in BOOTSTRAPPER_ACTION_STATE action, + __inout BURN_MSI_PROPERTY* pActionMsiProperty, + __inout INSTALLUILEVEL* pUiLevel, + __inout BOOL* pfDisableExternalUiHandler, + __inout BOOTSTRAPPER_MSI_FILE_VERSIONING* pFileVersioning + ) +{ + HRESULT hr = S_OK; + BA_ONPLANMSIPACKAGE_ARGS args = { }; + BA_ONPLANMSIPACKAGE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.fExecute = fExecute; + args.action = action; + args.recommendedFileVersioning = *pFileVersioning; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.actionMsiProperty = *pActionMsiProperty; + results.uiLevel = *pUiLevel; + results.fDisableExternalUiHandler = *pfDisableExternalUiHandler; + results.fileVersioning = args.recommendedFileVersioning; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanMsiPackage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnPlanMsiPackage args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fExecute); + ExitOnFailure(hr, "Failed to write execute of OnPlanMsiPackage args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.action); + ExitOnFailure(hr, "Failed to write action of OnPlanMsiPackage args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendedFileVersioning); + ExitOnFailure(hr, "Failed to write recommended file versioning of OnPlanMsiPackage args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanMsiPackage results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.actionMsiProperty); + ExitOnFailure(hr, "Failed to write action msi property of OnPlanMsiPackage results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.uiLevel); + ExitOnFailure(hr, "Failed to write UI level of OnPlanMsiPackage results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.fDisableExternalUiHandler); + ExitOnFailure(hr, "Failed to write disable external UI handler of OnPlanMsiPackage results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.fileVersioning); + ExitOnFailure(hr, "Failed to write file versioning of OnPlanMsiPackage results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIPACKAGE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlanMsiPackage failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnPlanMsiPackage result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnPlanMsiPackage result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.actionMsiProperty)); + ExitOnFailure(hr, "Failed to read action MSI property of OnPlanMsiPackage result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.uiLevel)); + ExitOnFailure(hr, "Failed to read UI level of OnPlanMsiPackage result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fDisableExternalUiHandler)); + ExitOnFailure(hr, "Failed to read disable external UI handler of OnPlanMsiPackage result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fileVersioning)); + ExitOnFailure(hr, "Failed to read file versioning of OnPlanMsiPackage result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + + *pActionMsiProperty = results.actionMsiProperty; + *pUiLevel = results.uiLevel; + *pfDisableExternalUiHandler = results.fDisableExternalUiHandler; + *pFileVersioning = results.fileVersioning; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlannedCompatiblePackage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzCompatiblePackageId, + __in BOOL fRemove + ) +{ + HRESULT hr = S_OK; + BA_ONPLANNEDCOMPATIBLEPACKAGE_ARGS args = { }; + BA_ONPLANNEDCOMPATIBLEPACKAGE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.wzCompatiblePackageId = wzCompatiblePackageId; + args.fRemove = fRemove; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlannedCompatiblePackage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnPlannedCompatiblePackage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzCompatiblePackageId); + ExitOnFailure(hr, "Failed to write compatible package id of OnPlannedCompatiblePackage args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fRemove); + ExitOnFailure(hr, "Failed to write remove of OnPlannedCompatiblePackage args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlannedCompatiblePackage results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlannedCompatiblePackage failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlannedPackage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in BOOTSTRAPPER_ACTION_STATE execute, + __in BOOTSTRAPPER_ACTION_STATE rollback, + __in BOOL fPlannedCache, + __in BOOL fPlannedUncache + ) +{ + HRESULT hr = S_OK; + BA_ONPLANNEDPACKAGE_ARGS args = { }; + BA_ONPLANNEDPACKAGE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.execute = execute; + args.rollback = rollback; + args.fPlannedCache = fPlannedCache; + args.fPlannedUncache = fPlannedUncache; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlannedPackage args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnPlannedPackage args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.execute); + ExitOnFailure(hr, "Failed to write execute of OnPlannedPackage args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.rollback); + ExitOnFailure(hr, "Failed to write rollback of OnPlannedPackage args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fPlannedCache); + ExitOnFailure(hr, "Failed to write planned cache of OnPlannedPackage args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fPlannedUncache); + ExitOnFailure(hr, "Failed to write planned uncache of OnPlannedPackage args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlannedPackage results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDPACKAGE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlannedPackage failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlanPackageBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in BOOTSTRAPPER_PACKAGE_STATE state, + __in BOOL fCached, + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition, + __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState, + __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType + ) +{ + HRESULT hr = S_OK; + BA_ONPLANPACKAGEBEGIN_ARGS args = { }; + BA_ONPLANPACKAGEBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.state = state; + args.fCached = fCached; + args.installCondition = installCondition; + args.repairCondition = repairCondition; + args.recommendedState = *pRequestedState; + args.recommendedCacheType = *pRequestedCacheType; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.requestedState = *pRequestedState; + results.requestedCacheType = *pRequestedCacheType; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanPackageBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnPlanPackageBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.state); + ExitOnFailure(hr, "Failed to write state of OnPlanPackageBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fCached); + ExitOnFailure(hr, "Failed to write cached of OnPlanPackageBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.installCondition); + ExitOnFailure(hr, "Failed to write install condition of OnPlanPackageBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.repairCondition); + ExitOnFailure(hr, "Failed to write repair condition of OnPlanPackageBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendedState); + ExitOnFailure(hr, "Failed to write recommended state of OnPlanPackageBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendedCacheType); + ExitOnFailure(hr, "Failed to write recommended cache type of OnPlanPackageBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanPackageBegin results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.requestedState); + ExitOnFailure(hr, "Failed to write requested state of OnPlanPackageBegin results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.requestedCacheType); + ExitOnFailure(hr, "Failed to write requested cache type of OnPlanPackageBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGEBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlanPackageBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnPlanPackageBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnPlanPackageBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.requestedState)); + ExitOnFailure(hr, "Failed to read requested state of OnPlanPackageBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.requestedCacheType)); + ExitOnFailure(hr, "Failed to read requested cache type of OnPlanPackageBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + + *pRequestedState = results.requestedState; + + if (BOOTSTRAPPER_CACHE_TYPE_REMOVE <= results.requestedCacheType && BOOTSTRAPPER_CACHE_TYPE_FORCE >= results.requestedCacheType) + { + *pRequestedCacheType = results.requestedCacheType; + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlanPackageComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in HRESULT hrStatus, + __in BOOTSTRAPPER_REQUEST_STATE requested + ) +{ + HRESULT hr = S_OK; + BA_ONPLANPACKAGECOMPLETE_ARGS args = { }; + BA_ONPLANPACKAGECOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.hrStatus = hrStatus; + args.requested = requested; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanPackageComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnPlanPackageComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnPlanPackageComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.requested); + ExitOnFailure(hr, "Failed to write requested of OnPlanPackageComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanPackageComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGECOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlanPackageComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlanRelatedBundle( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzBundleId, + __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState + ) +{ + HRESULT hr = S_OK; + BA_ONPLANRELATEDBUNDLE_ARGS args = { }; + BA_ONPLANRELATEDBUNDLE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzBundleId = wzBundleId; + args.recommendedState = *pRequestedState; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.requestedState = *pRequestedState; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanRelatedBundle args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzBundleId); + ExitOnFailure(hr, "Failed to write bundle id of OnPlanRelatedBundle args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendedState); + ExitOnFailure(hr, "Failed to write recommended state of OnPlanRelatedBundle args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanRelatedBundle results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.requestedState); + ExitOnFailure(hr, "Failed to write requested state of OnPlanRelatedBundle results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRELATEDBUNDLE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlanRelatedBundle failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnPlanRelatedBundle result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnPlanRelatedBundle result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.requestedState)); + ExitOnFailure(hr, "Failed to read requested state of OnPlanRelatedBundle result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + + *pRequestedState = results.requestedState; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlanRelatedBundleType( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzBundleId, + __inout BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE* pRequestedType + ) +{ + HRESULT hr = S_OK; + BA_ONPLANRELATEDBUNDLETYPE_ARGS args = { }; + BA_ONPLANRELATEDBUNDLETYPE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzBundleId = wzBundleId; + args.recommendedType = *pRequestedType; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.requestedType = *pRequestedType; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanRelatedBundleType args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzBundleId); + ExitOnFailure(hr, "Failed to write bundle id of OnPlanRelatedBundleType args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendedType); + ExitOnFailure(hr, "Failed to write recommended type of OnPlanRelatedBundleType args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanRelatedBundleType results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.requestedType); + ExitOnFailure(hr, "Failed to write requested type of OnPlanRelatedBundleType results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRELATEDBUNDLETYPE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlanRelatedBundleType failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnPlanRelatedBundleType result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnPlanRelatedBundleType result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.requestedType)); + ExitOnFailure(hr, "Failed to read requested type of OnPlanRelatedBundleType result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + + *pRequestedType = results.requestedType; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlanRestoreRelatedBundle( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzBundleId, + __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState + ) +{ + HRESULT hr = S_OK; + BA_ONPLANRESTORERELATEDBUNDLE_ARGS args = { }; + BA_ONPLANRESTORERELATEDBUNDLE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzBundleId = wzBundleId; + args.recommendedState = *pRequestedState; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.requestedState = *pRequestedState; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanRestoreRelatedBundle args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzBundleId); + ExitOnFailure(hr, "Failed to write bundle id of OnPlanRestoreRelatedBundle args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendedState); + ExitOnFailure(hr, "Failed to write recommended state of OnPlanRestoreRelatedBundle args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanRestoreRelatedBundle results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.requestedState); + ExitOnFailure(hr, "Failed to write requested state of OnPlanRestoreRelatedBundle results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRESTORERELATEDBUNDLE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlanRestoreRelatedBundle failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnPlanRestoreRelatedBundle result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnPlanRestoreRelatedBundle result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.requestedState)); + ExitOnFailure(hr, "Failed to read requested state of OnPlanRestoreRelatedBundle result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + + *pRequestedState = results.requestedState; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlanRollbackBoundary( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzRollbackBoundaryId, + __inout BOOL* pfTransaction + ) +{ + HRESULT hr = S_OK; + BA_ONPLANROLLBACKBOUNDARY_ARGS args = { }; + BA_ONPLANROLLBACKBOUNDARY_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzRollbackBoundaryId = wzRollbackBoundaryId; + args.fRecommendedTransaction = *pfTransaction; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.fTransaction = *pfTransaction; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanRollbackBoundary args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzRollbackBoundaryId); + ExitOnFailure(hr, "Failed to write rollback boundary id of OnPlanRollbackBoundary args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.fRecommendedTransaction); + ExitOnFailure(hr, "Failed to write recommended transaction of OnPlanRollbackBoundary args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanRollbackBoundary results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.fTransaction); + ExitOnFailure(hr, "Failed to write transaction of OnPlanRollbackBoundary results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANROLLBACKBOUNDARY, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlanRollbackBoundary failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnPlanRollbackBoundary result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fTransaction)); + ExitOnFailure(hr, "Failed to read transaction of OnPlanRollbackBoundary result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnPlanRollbackBoundary result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + + *pfTransaction = results.fTransaction; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnPlanPatchTarget( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzProductCode, + __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState + ) +{ + HRESULT hr = S_OK; + BA_ONPLANPATCHTARGET_ARGS args = { }; + BA_ONPLANPATCHTARGET_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzPackageId = wzPackageId; + args.wzProductCode = wzProductCode; + args.recommendedState = *pRequestedState; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.requestedState = *pRequestedState; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanPatchTarget args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzPackageId); + ExitOnFailure(hr, "Failed to write package id of OnPlanPatchTarget args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzProductCode); + ExitOnFailure(hr, "Failed to write product code of OnPlanPatchTarget args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendedState); + ExitOnFailure(hr, "Failed to write recommended state of OnPlanPatchTarget args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnPlanPatchTarget results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.requestedState); + ExitOnFailure(hr, "Failed to write requested state of OnPlanPatchTarget results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPATCHTARGET, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnPlanPatchTarget failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnPlanPatchTarget result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnPlanPatchTarget result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.requestedState)); + ExitOnFailure(hr, "Failed to read requrested state of OnPlanPatchTarget result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + + *pRequestedState = results.requestedState; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnProgress( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOL fRollback, + __in DWORD dwProgressPercentage, + __in DWORD dwOverallPercentage + ) +{ + HRESULT hr = S_OK; + BA_ONPROGRESS_ARGS args = { }; + BA_ONPROGRESS_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.dwProgressPercentage = dwProgressPercentage; + args.dwOverallPercentage = dwOverallPercentage; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnProgress args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwProgressPercentage); + ExitOnFailure(hr, "Failed to write progress of OnProgress args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwOverallPercentage); + ExitOnFailure(hr, "Failed to write overall progress of OnProgress args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnProgress results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPROGRESS, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnProgress failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnProgress result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnProgress result."); + +LExit: + hr = FilterExecuteResult(pUserExperience, hr, fRollback, results.fCancel, L"OnProgress"); + + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnRegisterBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType + ) +{ + HRESULT hr = S_OK; + BA_ONREGISTERBEGIN_ARGS args = { }; + BA_ONREGISTERBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.recommendedRegistrationType = *pRegistrationType; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.registrationType = *pRegistrationType; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnRegisterBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendedRegistrationType); + ExitOnFailure(hr, "Failed to write recommended registration type of OnRegisterBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnRegisterBegin results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.registrationType); + ExitOnFailure(hr, "Failed to write registration type of OnRegisterBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnRegisterBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnRegisterBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.fCancel)); + ExitOnFailure(hr, "Failed to read cancel of OnRegisterBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.registrationType)); + ExitOnFailure(hr, "Failed to read registration type of OnRegisterBegin result."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + else if (BOOTSTRAPPER_REGISTRATION_TYPE_NONE < results.registrationType && BOOTSTRAPPER_REGISTRATION_TYPE_FULL >= results.registrationType) + { + *pRegistrationType = results.registrationType; + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnRegisterComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ) +{ + HRESULT hr = S_OK; + BA_ONREGISTERCOMPLETE_ARGS args = { }; + BA_ONREGISTERCOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.hrStatus = hrStatus; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnRegisterComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status type of OnRegisterComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnRegisterComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERCOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnRegisterComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnRollbackMsiTransactionBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in LPCWSTR wzTransactionId + ) +{ + HRESULT hr = S_OK; + BA_ONROLLBACKMSITRANSACTIONBEGIN_ARGS args = { }; + BA_ONROLLBACKMSITRANSACTIONBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzTransactionId = wzTransactionId; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnRollbackMsiTransactionBegin args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzTransactionId); + ExitOnFailure(hr, "Failed to write transaction id of OnRollbackMsiTransactionBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnRollbackMsiTransactionBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONROLLBACKMSITRANSACTIONBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnRollbackMsiTransactionBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnRollbackMsiTransactionComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in LPCWSTR wzTransactionId, + __in HRESULT hrStatus, + __in BOOTSTRAPPER_APPLY_RESTART restart, + __inout BOOTSTRAPPER_EXECUTEMSITRANSACTIONCOMPLETE_ACTION *pAction + ) +{ + HRESULT hr = S_OK; + BA_ONROLLBACKMSITRANSACTIONCOMPLETE_ARGS args = { }; + BA_ONROLLBACKMSITRANSACTIONCOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.wzTransactionId = wzTransactionId; + args.hrStatus = hrStatus; + args.restart = restart; + args.recommendation = *pAction; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.action = *pAction; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnRollbackMsiTransactionComplete args."); + + hr = BuffWriteStringToBuffer(&bufferArgs, args.wzTransactionId); + ExitOnFailure(hr, "Failed to write transaction id of OnRollbackMsiTransactionComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status type of OnRollbackMsiTransactionComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.restart); + ExitOnFailure(hr, "Failed to write restart of OnRollbackMsiTransactionComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendation); + ExitOnFailure(hr, "Failed to write recommedation of OnRollbackMsiTransactionComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnRollbackMsiTransactionComplete results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.action); + ExitOnFailure(hr, "Failed to write action of OnRollbackMsiTransactionComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONROLLBACKMSITRANSACTIONCOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnRollbackMsiTransactionComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnRollbackMsiTransactionComplete result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.action)); + ExitOnFailure(hr, "Failed to read cancel of OnRollbackMsiTransactionComplete result."); + + *pAction = results.action; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnShutdown( + __in BURN_USER_EXPERIENCE* pUserExperience, + __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction + ) +{ + HRESULT hr = S_OK; + BA_ONSHUTDOWN_ARGS args = { sizeof(args) }; + BA_ONSHUTDOWN_RESULTS results = { sizeof(results) }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.action = *pAction; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnShutdown args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnShutdown results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.action); + ExitOnFailure(hr, "Failed to write action of OnShutdown results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSHUTDOWN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnShutdown failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnShutdown result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.action)); + ExitOnFailure(hr, "Failed to read result action of OnShutdown result."); + + *pAction = results.action; + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnStartup( + __in BURN_USER_EXPERIENCE* pUserExperience +) +{ + HRESULT hr = S_OK; + BA_ONSTARTUP_ARGS args = { }; + BA_ONSTARTUP_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnStartup args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnStartup results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSTARTUP, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnStartup failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnSystemRestorePointBegin( + __in BURN_USER_EXPERIENCE* pUserExperience + ) +{ + HRESULT hr = S_OK; + BA_ONSYSTEMRESTOREPOINTBEGIN_ARGS args = { }; + BA_ONSYSTEMRESTOREPOINTBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnSystemRestorePointBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnSystemRestorePointBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnSystemRestorePointBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnSystemRestorePointComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ) +{ + HRESULT hr = S_OK; + BA_ONSYSTEMRESTOREPOINTCOMPLETE_ARGS args = { }; + BA_ONSYSTEMRESTOREPOINTCOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.hrStatus = hrStatus; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnSystemRestorePointComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnSystemRestorePointComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnSystemRestorePointComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTCOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnSystemRestorePointComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnUnregisterBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType + ) +{ + HRESULT hr = S_OK; + BA_ONUNREGISTERBEGIN_ARGS args = { }; + BA_ONUNREGISTERBEGIN_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + SIZE_T iBuffer = 0; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.recommendedRegistrationType = *pRegistrationType; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + results.registrationType = *pRegistrationType; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnUnregisterBegin args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.recommendedRegistrationType); + ExitOnFailure(hr, "Failed to write recommended registration type of OnUnregisterBegin args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnUnregisterBegin results."); + + hr = BuffWriteNumberToBuffer(&bufferResults, results.registrationType); + ExitOnFailure(hr, "Failed to write registration type of OnUnregisterBegin results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERBEGIN, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnUnregisterBegin failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + + // Read results. + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read size of OnUnregisterBegin result."); + + hr = BuffReadNumber(rpc.pbData, rpc.cbData, &iBuffer, reinterpret_cast(&results.registrationType)); + ExitOnFailure(hr, "Failed to read registration type of OnUnregisterBegin result."); + + if (BOOTSTRAPPER_REGISTRATION_TYPE_NONE < results.registrationType && BOOTSTRAPPER_REGISTRATION_TYPE_FULL >= results.registrationType) + { + *pRegistrationType = results.registrationType; + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +EXTERN_C HRESULT BACallbackOnUnregisterComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ) +{ + HRESULT hr = S_OK; + BA_ONUNREGISTERCOMPLETE_ARGS args = { }; + BA_ONUNREGISTERCOMPLETE_RESULTS results = { }; + BUFF_BUFFER bufferArgs = { }; + BUFF_BUFFER bufferResults = { }; + PIPE_RPC_RESULT rpc = { }; + + // Init structs. + args.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + args.hrStatus = hrStatus; + + results.dwApiVersion = WIX_5_BOOTSTRAPPER_APPLICATION_API_VERSION; + + // Send args. + hr = BuffWriteNumberToBuffer(&bufferArgs, args.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnUnregisterComplete args."); + + hr = BuffWriteNumberToBuffer(&bufferArgs, args.hrStatus); + ExitOnFailure(hr, "Failed to write status of OnUnregisterComplete args."); + + // Send results. + hr = BuffWriteNumberToBuffer(&bufferResults, results.dwApiVersion); + ExitOnFailure(hr, "Failed to write API version of OnUnregisterComplete results."); + + // Callback. + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERCOMPLETE, &bufferArgs, &bufferResults, &rpc); + ExitOnFailure(hr, "BA OnUnregisterComplete failed."); + + if (S_FALSE == hr) + { + ExitFunction(); + } + +LExit: + PipeFreeRpcResult(&rpc); + ReleaseBuffer(bufferResults); + ReleaseBuffer(bufferArgs); + + return hr; +} + +// internal functions + +// This filters the BA's responses to events during apply. +// If an apply thread failed, then return its error so this thread will bail out. +// During rollback, the BA can't cancel. +static HRESULT FilterExecuteResult( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus, + __in BOOL fRollback, + __in BOOL fCancel, + __in LPCWSTR sczEventName + ) +{ + HRESULT hr = hrStatus; + HRESULT hrApplyError = pUserExperience->hrApplyError; // make sure to use the same value for the whole method, since it can be changed in other threads. + + // If we failed return that error unless this is rollback which should roll on. + if (FAILED(hrApplyError) && !fRollback) + { + hr = hrApplyError; + } + else if (fRollback) + { + if (fCancel) + { + LogId(REPORT_STANDARD, MSG_APPLY_CANCEL_IGNORED_DURING_ROLLBACK, sczEventName); + } + // TODO: since cancel isn't allowed, should the BA's HRESULT be ignored as well? + // In the previous code, they could still alter rollback by returning IDERROR. + } + else + { + ExitOnFailure(hr, "BA %ls failed.", sczEventName); + + if (fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + } + +LExit: + return hr; +} + +static HRESULT SendBAMessage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOTSTRAPPER_APPLICATION_MESSAGE message, + __in BUFF_BUFFER* pBufferArgs, + __in BUFF_BUFFER* pBufferResults, + __in PIPE_RPC_RESULT* pResult + ) +{ + HRESULT hr = S_OK; + BUFF_BUFFER buffer = { }; + + if (PipeRpcInitialized(&pUserExperience->hBARpcPipe)) + { + // Send the combined counted args and results buffer to the BA. + hr = CombineArgsAndResults(pBufferArgs, pBufferResults, &buffer); + if (SUCCEEDED(hr)) + { + hr = PipeRpcRequest(&pUserExperience->hBARpcPipe, message, buffer.pbData, buffer.cbData, pResult); + } + } + else + { + hr = S_FALSE; + } + + ReleaseBuffer(buffer); + return hr; +} + +static HRESULT SendBAMessageFromInactiveEngine( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOTSTRAPPER_APPLICATION_MESSAGE message, + __in BUFF_BUFFER* pBufferArgs, + __in BUFF_BUFFER* pBufferResults, + __in PIPE_RPC_RESULT* pResult +) +{ + HRESULT hr = S_OK; + BUFF_BUFFER buffer = { }; + + if (PipeRpcInitialized(&pUserExperience->hBARpcPipe)) + { + BootstrapperApplicationDeactivateEngine(pUserExperience); + + // Send the combined counted args and results buffer to the BA. + hr = CombineArgsAndResults(pBufferArgs, pBufferResults, &buffer); + if (SUCCEEDED(hr)) + { + hr = PipeRpcRequest(&pUserExperience->hBARpcPipe, message, buffer.pbData, buffer.cbData, pResult); + } + + BootstrapperApplicationActivateEngine(pUserExperience); + } + else + { + hr = S_FALSE; + } + + ReleaseBuffer(buffer); + return hr; +} + +static HRESULT CombineArgsAndResults( + __in BUFF_BUFFER* pBufferArgs, + __in BUFF_BUFFER* pBufferResults, + __in BUFF_BUFFER* pBufferCombined + ) +{ + HRESULT hr = S_OK; + + // Write args to buffer. + hr = BuffWriteStreamToBuffer(pBufferCombined, pBufferArgs->pbData, pBufferArgs->cbData); + ExitOnFailure(hr, "Failed to write args buffer."); + + // Write results to buffer. + hr = BuffWriteStreamToBuffer(pBufferCombined, pBufferResults->pbData, pBufferResults->cbData); + ExitOnFailure(hr, "Failed to write results buffer."); + +LExit: + return hr; +} diff --git a/src/burn/engine/bacallback.h b/src/burn/engine/bacallback.h new file mode 100644 index 00000000..8d1f41c4 --- /dev/null +++ b/src/burn/engine/bacallback.h @@ -0,0 +1,520 @@ +#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. + + +#if defined(__cplusplus) +extern "C" { +#endif + +// structs + + +// function declarations + +HRESULT BACallbackOnApplyBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in DWORD dwPhaseCount + ); +HRESULT BACallbackOnApplyComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus, + __in BOOTSTRAPPER_APPLY_RESTART restart, + __inout BOOTSTRAPPER_APPLYCOMPLETE_ACTION* pAction + ); +HRESULT BACallbackOnApplyDowngrade( + __in BURN_USER_EXPERIENCE* pUserExperience, + __inout HRESULT* phrStatus + ); +HRESULT BACallbackOnBeginMsiTransactionBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in LPCWSTR wzTransactionId + ); +HRESULT BACallbackOnBeginMsiTransactionComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in LPCWSTR wzTransactionId, + __in HRESULT hrStatus + ); +HRESULT BACallbackOnCacheAcquireBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in_z LPWSTR* pwzSource, + __in_z LPWSTR* pwzDownloadUrl, + __in_z_opt LPCWSTR wzPayloadContainerId, + __out BOOTSTRAPPER_CACHE_OPERATION* pCacheOperation + ); +HRESULT BACallbackOnCacheAcquireComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in HRESULT hrStatus, + __inout BOOL* pfRetry + ); +HRESULT BACallbackOnCacheAcquireProgress( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in DWORD64 dw64Progress, + __in DWORD64 dw64Total, + __in DWORD dwOverallPercentage + ); +HRESULT BACallbackOnCacheAcquireResolving( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in_z LPWSTR* rgSearchPaths, + __in DWORD cSearchPaths, + __in BOOL fFoundLocal, + __in DWORD* pdwChosenSearchPath, + __in_z_opt LPWSTR* pwzDownloadUrl, + __in_z_opt LPCWSTR wzPayloadContainerId, + __inout BOOTSTRAPPER_CACHE_RESOLVE_OPERATION* pCacheOperation + ); +HRESULT BACallbackOnCacheBegin( + __in BURN_USER_EXPERIENCE* pUserExperience + ); +HRESULT BACallbackOnCacheComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ); +HRESULT BACallbackOnCacheContainerOrPayloadVerifyBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId + ); +HRESULT BACallbackOnCacheContainerOrPayloadVerifyComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in HRESULT hrStatus + ); +HRESULT BACallbackOnCacheContainerOrPayloadVerifyProgress( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in DWORD64 dw64Progress, + __in DWORD64 dw64Total, + __in DWORD dwOverallPercentage + ); +HRESULT BACallbackOnCachePackageBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in DWORD cCachePayloads, + __in DWORD64 dw64PackageCacheSize, + __in BOOL fVital + ); +HRESULT BACallbackOnCachePackageNonVitalValidationFailure( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in HRESULT hrStatus, + __inout BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION* pAction + ); +HRESULT BACallbackOnCachePackageComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in HRESULT hrStatus, + __inout BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION* pAction + ); +HRESULT BACallbackOnCachePayloadExtractBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzContainerId, + __in_z_opt LPCWSTR wzPayloadId + ); +HRESULT BACallbackOnCachePayloadExtractComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in HRESULT hrStatus + ); +HRESULT BACallbackOnCachePayloadExtractProgress( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in DWORD64 dw64Progress, + __in DWORD64 dw64Total, + __in DWORD dwOverallPercentage + ); +HRESULT BACallbackOnCacheVerifyBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId + ); +HRESULT BACallbackOnCacheVerifyComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in HRESULT hrStatus, + __inout BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION* pAction + ); +HRESULT BACallbackOnCacheVerifyProgress( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in DWORD64 dw64Progress, + __in DWORD64 dw64Total, + __in DWORD dwOverallPercentage, + __in BOOTSTRAPPER_CACHE_VERIFY_STEP verifyStep + ); +HRESULT BACallbackOnCommitMsiTransactionBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in LPCWSTR wzTransactionId + ); +HRESULT BACallbackOnCommitMsiTransactionComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in LPCWSTR wzTransactionId, + __in HRESULT hrStatus, + __in BOOTSTRAPPER_APPLY_RESTART restart, + __inout BOOTSTRAPPER_EXECUTEMSITRANSACTIONCOMPLETE_ACTION* pAction +); +HRESULT BACallbackOnCreate( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOTSTRAPPER_COMMAND* pCommand +); +HRESULT BACallbackOnDestroy( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOL fReload +); +HRESULT BACallbackOnDetectBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOL fCached, + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType, + __in DWORD cPackages + ); +HRESULT BACallbackOnDetectCompatibleMsiPackage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzCompatiblePackageId, + __in VERUTIL_VERSION* pCompatiblePackageVersion + ); +HRESULT BACallbackOnDetectComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus, + __in BOOL fEligibleForCleanup + ); +HRESULT BACallbackOnDetectForwardCompatibleBundle( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzBundleId, + __in BOOTSTRAPPER_RELATION_TYPE relationType, + __in_z LPCWSTR wzBundleTag, + __in BOOL fPerMachine, + __in VERUTIL_VERSION* pVersion, + __in BOOL fMissingFromCache + ); +HRESULT BACallbackOnDetectMsiFeature( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzFeatureId, + __in BOOTSTRAPPER_FEATURE_STATE state + ); +HRESULT BACallbackOnDetectPackageBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId + ); +HRESULT BACallbackOnDetectPackageComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in HRESULT hrStatus, + __in BOOTSTRAPPER_PACKAGE_STATE state, + __in BOOL fCached + ); +HRESULT BACallbackOnDetectRelatedBundle( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzBundleId, + __in BOOTSTRAPPER_RELATION_TYPE relationType, + __in_z LPCWSTR wzBundleTag, + __in BOOL fPerMachine, + __in VERUTIL_VERSION* pVersion, + __in BOOL fMissingFromCache + ); +HRESULT BACallbackOnDetectRelatedBundlePackage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzBundleId, + __in BOOTSTRAPPER_RELATION_TYPE relationType, + __in BOOL fPerMachine, + __in VERUTIL_VERSION* pVersion + ); +HRESULT BACallbackOnDetectRelatedMsiPackage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzUpgradeCode, + __in_z LPCWSTR wzProductCode, + __in BOOL fPerMachine, + __in VERUTIL_VERSION* pVersion, + __in BOOTSTRAPPER_RELATED_OPERATION operation + ); +HRESULT BACallbackOnDetectPatchTarget( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzProductCode, + __in BOOTSTRAPPER_PACKAGE_STATE patchState + ); +HRESULT BACallbackOnDetectUpdate( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzUpdateLocation, + __in DWORD64 dw64Size, + __in_z_opt LPCWSTR wzHash, + __in BOOTSTRAPPER_UPDATE_HASH_TYPE hashAlgorithm, + __in VERUTIL_VERSION* pVersion, + __in_z_opt LPCWSTR wzTitle, + __in_z_opt LPCWSTR wzSummary, + __in_z_opt LPCWSTR wzContentType, + __in_z_opt LPCWSTR wzContent, + __inout BOOL* pfStopProcessingUpdates + ); +HRESULT BACallbackOnDetectUpdateBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzUpdateLocation, + __inout BOOL* pfSkip + ); +HRESULT BACallbackOnDetectUpdateComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus, + __inout BOOL* pfIgnoreError + ); +HRESULT BACallbackOnElevateBegin( + __in BURN_USER_EXPERIENCE* pUserExperience + ); +HRESULT BACallbackOnElevateComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ); +HRESULT BACallbackOnError( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOTSTRAPPER_ERROR_TYPE errorType, + __in_z_opt LPCWSTR wzPackageId, + __in DWORD dwCode, + __in_z_opt LPCWSTR wzError, + __in DWORD dwUIHint, + __in DWORD cData, + __in_ecount_z_opt(cData) LPCWSTR* rgwzData, + __inout int* pnResult + ); +HRESULT BACallbackOnExecuteBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in DWORD cExecutingPackages + ); +HRESULT BACallbackOnExecuteComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ); +HRESULT BACallbackOnExecuteFilesInUse( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in DWORD cFiles, + __in_ecount_z_opt(cFiles) LPCWSTR* rgwzFiles, + __in BOOTSTRAPPER_FILES_IN_USE_TYPE source, + __inout int* pnResult + ); +HRESULT BACallbackOnExecuteMsiMessage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in INSTALLMESSAGE messageType, + __in DWORD dwUIHint, + __in_z LPCWSTR wzMessage, + __in DWORD cData, + __in_ecount_z_opt(cData) LPCWSTR* rgwzData, + __inout int* pnResult + ); +HRESULT BACallbackOnExecutePackageBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in BOOL fExecute, + __in BOOTSTRAPPER_ACTION_STATE action, + __in INSTALLUILEVEL uiLevel, + __in BOOL fDisableExternalUiHandler + ); +HRESULT BACallbackOnExecutePackageComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in HRESULT hrStatus, + __in BOOTSTRAPPER_APPLY_RESTART restart, + __inout BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION* pAction + ); +HRESULT BACallbackOnExecutePatchTarget( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzTargetProductCode + ); +HRESULT BACallbackOnExecuteProcessCancel( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in DWORD dwProcessId, + __inout BOOTSTRAPPER_EXECUTEPROCESSCANCEL_ACTION* pAction + ); +HRESULT BACallbackOnExecuteProgress( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in DWORD dwProgressPercentage, + __in DWORD dwOverallPercentage, + __out int* pnResult + ); +HRESULT BACallbackOnLaunchApprovedExeBegin( + __in BURN_USER_EXPERIENCE* pUserExperience + ); +HRESULT BACallbackOnLaunchApprovedExeComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus, + __in DWORD dwProcessId + ); +HRESULT BACallbackOnPauseAUBegin( + __in BURN_USER_EXPERIENCE* pUserExperience + ); +HRESULT BACallbackOnPauseAUComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ); +HRESULT BACallbackOnPlanBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in DWORD cPackages + ); +HRESULT BACallbackOnPlanCompatibleMsiPackageBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzCompatiblePackageId, + __in VERUTIL_VERSION* pCompatiblePackageVersion, + __inout BOOL* pfRequested + ); +HRESULT BACallbackOnPlanCompatibleMsiPackageComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzCompatiblePackageId, + __in HRESULT hrStatus, + __in BOOL fRequested + ); +HRESULT BACallbackOnPlanComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ); +HRESULT BACallbackOnPlanForwardCompatibleBundle( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzBundleId, + __in BOOTSTRAPPER_RELATION_TYPE relationType, + __in_z LPCWSTR wzBundleTag, + __in BOOL fPerMachine, + __in VERUTIL_VERSION* pVersion, + __inout BOOL* pfIgnoreBundle + ); +HRESULT BACallbackOnPlanMsiFeature( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzFeatureId, + __inout BOOTSTRAPPER_FEATURE_STATE* pRequestedState + ); +HRESULT BACallbackOnPlanMsiPackage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in BOOL fExecute, + __in BOOTSTRAPPER_ACTION_STATE action, + __inout BURN_MSI_PROPERTY* pActionMsiProperty, + __inout INSTALLUILEVEL* pUiLevel, + __inout BOOL* pfDisableExternalUiHandler, + __inout BOOTSTRAPPER_MSI_FILE_VERSIONING* pFileVersioning + ); +HRESULT BACallbackOnPlannedCompatiblePackage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzCompatiblePackageId, + __in BOOL fRemove + ); +HRESULT BACallbackOnPlannedPackage( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in BOOTSTRAPPER_ACTION_STATE execute, + __in BOOTSTRAPPER_ACTION_STATE rollback, + __in BOOL fPlannedCache, + __in BOOL fPlannedUncache + ); +HRESULT BACallbackOnPlanPackageBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in BOOTSTRAPPER_PACKAGE_STATE state, + __in BOOL fCached, + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition, + __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState, + __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType + ); +HRESULT BACallbackOnPlanPackageComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in HRESULT hrStatus, + __in BOOTSTRAPPER_REQUEST_STATE requested + ); +HRESULT BACallbackOnPlanRelatedBundle( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzBundleId, + __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState + ); +HRESULT BACallbackOnPlanRelatedBundleType( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzBundleId, + __inout BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE* pRequestedType + ); +HRESULT BACallbackOnPlanRestoreRelatedBundle( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzBundleId, + __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState + ); +HRESULT BACallbackOnPlanRollbackBoundary( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzRollbackBoundaryId, + __inout BOOL *pfTransaction + ); +HRESULT BACallbackOnPlanPatchTarget( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzProductCode, + __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState + ); +HRESULT BACallbackOnProgress( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOL fRollback, + __in DWORD dwProgressPercentage, + __in DWORD dwOverallPercentage + ); +HRESULT BACallbackOnRegisterBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType + ); +HRESULT BACallbackOnRegisterComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ); +HRESULT BACallbackOnRollbackMsiTransactionBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in LPCWSTR wzTransactionId + ); +HRESULT BACallbackOnRollbackMsiTransactionComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in LPCWSTR wzTransactionId, + __in HRESULT hrStatus, + __in BOOTSTRAPPER_APPLY_RESTART restart, + __inout BOOTSTRAPPER_EXECUTEMSITRANSACTIONCOMPLETE_ACTION* pAction +); +HRESULT BACallbackOnShutdown( + __in BURN_USER_EXPERIENCE* pUserExperience, + __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction + ); +HRESULT BACallbackOnStartup( + __in BURN_USER_EXPERIENCE* pUserExperience + ); +HRESULT BACallbackOnSystemRestorePointBegin( + __in BURN_USER_EXPERIENCE* pUserExperience + ); +HRESULT BACallbackOnSystemRestorePointComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ); +HRESULT BACallbackOnUnregisterBegin( + __in BURN_USER_EXPERIENCE* pUserExperience, + __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType + ); +HRESULT BACallbackOnUnregisterComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrStatus + ); + +#if defined(__cplusplus) +} +#endif diff --git a/src/burn/engine/baengine.cpp b/src/burn/engine/baengine.cpp new file mode 100644 index 00000000..e63836f4 --- /dev/null +++ b/src/burn/engine/baengine.cpp @@ -0,0 +1,1532 @@ +// 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" + + +static DWORD WINAPI BAEngineMessagePumpThreadProc( + __in LPVOID lpThreadParameter +); +static void CALLBACK FreeQueueItem( + __in void* pvValue, + __in void* /*pvContext*/ +); + + +extern "C" HRESULT BAEngineCreateContext( + __in BURN_ENGINE_STATE *pEngineState, + __inout BAENGINE_CONTEXT** ppContext +) +{ + HRESULT hr = S_OK; + BAENGINE_CONTEXT* pContext = NULL; + + pContext = static_cast(MemAlloc(sizeof(BAENGINE_CONTEXT), TRUE)); + ExitOnNull(pContext, hr, E_OUTOFMEMORY, "Failed to allocate bootstrapper application engine context."); + + ::InitializeCriticalSection(&pContext->csQueue); + + pContext->hQueueSemaphore = ::CreateSemaphoreW(NULL, 0, LONG_MAX, NULL); + ExitOnNullWithLastError(pContext->hQueueSemaphore, hr, "Failed to create semaphore for queue."); + + hr = QueCreate(&pContext->hQueue); + ExitOnFailure(hr, "Failed to create queue for bootstrapper engine."); + + pContext->pEngineState = pEngineState; + + *ppContext = pContext; + pContext = NULL; + +LExit: + if (pContext) + { + BAEngineFreeContext(pContext); + pContext = NULL; + } + + return hr; +} + +extern "C" void BAEngineFreeContext( + __in BAENGINE_CONTEXT* pContext +) +{ + PipeRpcUninitiailize(&pContext->hRpcPipe); + ReleaseQueue(pContext->hQueue, FreeQueueItem, pContext); + ReleaseHandle(pContext->hQueueSemaphore); + ::DeleteCriticalSection(&pContext->csQueue); +} + +extern "C" void DAPI BAEngineFreeAction( + __in BAENGINE_ACTION * pAction +) +{ + switch (pAction->dwMessage) + { + case WM_BURN_LAUNCH_APPROVED_EXE: + ApprovedExesUninitializeLaunch(&pAction->launchApprovedExe); + break; + } + + MemFree(pAction); +} + +extern "C" HRESULT BAEngineStartListening( + __in BAENGINE_CONTEXT *pContext, + __in HANDLE hBAEnginePipe +) +{ + HRESULT hr = S_OK; + + if (PipeRpcInitialized(&pContext->hRpcPipe)) + { + ExitWithRootFailure(hr, E_INVALIDARG, "Bootstrapper application engine already listening on a pipe."); + } + + PipeRpcInitialize(&pContext->hRpcPipe, hBAEnginePipe, TRUE); + + pContext->hThread = ::CreateThread(NULL, 0, BAEngineMessagePumpThreadProc, pContext, 0, NULL); + ExitOnNullWithLastError(pContext->hThread, hr, "Failed to create bootstrapper application engine thread."); + +LExit: + return hr; +} + +extern "C" HRESULT BAEngineStopListening( + __in BAENGINE_CONTEXT * pContext +) +{ + HRESULT hr = S_OK; + + // If the pipe was open, this should cause the bootstrapper application engine pipe thread to stop pumping messages and exit. + if (PipeRpcInitialized(&pContext->hRpcPipe)) + { + PipeWriteDisconnect(pContext->hRpcPipe.hPipe); + + PipeRpcUninitiailize(&pContext->hRpcPipe); + } + + if (pContext->hThread) + { + hr = AppWaitForSingleObject(pContext->hThread, INFINITE); + + ReleaseHandle(pContext->hThread); // always release the thread, no matter if we were able to wait for it to join or not. + + ExitOnFailure(hr, "Failed to wait for bootstrapper application engine pipe thread."); + } + +LExit: + return hr; +} + +static void CALLBACK FreeQueueItem( + __in void* pvValue, + __in void* /*pvContext*/ +) +{ + BAENGINE_ACTION* pAction = reinterpret_cast(pvValue); + + LogId(REPORT_WARNING, MSG_IGNORE_OPERATION_AFTER_QUIT, LoggingBurnMessageToString(pAction->dwMessage)); + + BAEngineFreeAction(pAction); + MemFree(pAction); +} + +static HRESULT BAEngineGetPackageCount( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_GETPACKAGECOUNT_ARGS args = { }; + BAENGINE_GETPACKAGECOUNT_RESULTS results = { }; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineGetPackageCount args."); + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineGetPackageCount results."); + + // Execute. + ExternalEngineGetPackageCount(pContext->pEngineState, &results.cPackages); + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineGetPackageCount struct."); + + hr = BuffWriteNumberToBuffer(pBuffer, results.cPackages); + ExitOnFailure(hr, "Failed to write length of value of BAEngineGetPackageCount struct."); + +LExit: + return hr; +} + +static HRESULT BAEngineGetVariableNumeric( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_GETVARIABLENUMERIC_ARGS args = { }; + BAENGINE_GETVARIABLENUMERIC_RESULTS results = { }; + LPWSTR sczVariable = NULL; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineGetVariableNumeric args."); + + hr = BuffReaderReadString(pReaderArgs, &sczVariable); + ExitOnFailure(hr, "Failed to read variable name of BAEngineGetVariableNumeric args."); + + args.wzVariable = sczVariable; + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineGetVariableNumeric results."); + + // Execute. + hr = ExternalEngineGetVariableNumeric(pContext->pEngineState, args.wzVariable, &results.llValue); + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineGetVariableNumeric struct."); + + hr = BuffWriteNumber64ToBuffer(pBuffer, (DWORD64)results.llValue); + ExitOnFailure(hr, "Failed to write length of value of BAEngineGetVariableNumeric struct."); + +LExit: + ReleaseStr(sczVariable); + return hr; +} + +static HRESULT BAEngineGetVariableString( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_GETVARIABLESTRING_ARGS args = { }; + BAENGINE_GETVARIABLESTRING_RESULTS results = { }; + LPWSTR sczVariable = NULL; + LPWSTR sczValue = NULL; + DWORD cchValue = 0; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineGetVariableString args."); + + hr = BuffReaderReadString(pReaderArgs, &sczVariable); + ExitOnFailure(hr, "Failed to read variable name of BAEngineGetVariableString args."); + + args.wzVariable = sczVariable; + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineGetVariableString results."); + + hr = BuffReaderReadNumber(pReaderResults, &cchValue); + ExitOnFailure(hr, "Failed to read API version of BAEngineGetVariableString results."); + + results.cchValue = cchValue; + + // Execute. + hr = VariableGetString(&pContext->pEngineState->variables, args.wzVariable, &sczValue); + if (E_NOTFOUND == hr) + { + ExitFunction(); + } + ExitOnFailure(hr, "Failed to get string variable: %ls", sczVariable); + + results.cchValue = lstrlenW(sczValue); + results.wzValue = sczValue; + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineGetVariableString struct."); + + hr = BuffWriteNumberToBuffer(pBuffer, results.cchValue); + ExitOnFailure(hr, "Failed to write length of value of BAEngineGetVariableString struct."); + + hr = BuffWriteStringToBuffer(pBuffer, results.wzValue); + ExitOnFailure(hr, "Failed to write value of BAEngineGetVariableString struct."); + +LExit: + ReleaseStr(sczValue); + ReleaseStr(sczVariable); + + return hr; +} + +static HRESULT BAEngineGetVariableVersion( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_GETVARIABLEVERSION_ARGS args = { }; + BAENGINE_GETVARIABLEVERSION_RESULTS results = { }; + LPWSTR sczVariable = NULL; + VERUTIL_VERSION* pVersion = NULL; + DWORD cchValue = 0; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineGetVariableVersion args."); + + hr = BuffReaderReadString(pReaderArgs, &sczVariable); + ExitOnFailure(hr, "Failed to read variable name of BAEngineGetVariableVersion args."); + + args.wzVariable = sczVariable; + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineGetVariableVersion results."); + + hr = BuffReaderReadNumber(pReaderResults, &cchValue); + ExitOnFailure(hr, "Failed to read API version of BAEngineGetVariableVersion results."); + + results.cchValue = cchValue; + + // Execute. + hr = VariableGetVersion(&pContext->pEngineState->variables, args.wzVariable, &pVersion); + ExitOnFailure(hr, "Failed to get version variable: %ls", sczVariable); + + results.cchValue = lstrlenW(pVersion->sczVersion); + results.wzValue = pVersion->sczVersion; + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineGetVariableVersion struct."); + + hr = BuffWriteNumberToBuffer(pBuffer, results.cchValue); + ExitOnFailure(hr, "Failed to write length of value of BAEngineGetVariableVersion struct."); + + hr = BuffWriteStringToBuffer(pBuffer, results.wzValue); + ExitOnFailure(hr, "Failed to write value of BAEngineGetVariableVersion struct."); + +LExit: + ReleaseVerutilVersion(pVersion); + ReleaseStr(sczVariable); + + return hr; +} + +static HRESULT BAEngineGetRelatedBundleVariable( + __in BAENGINE_CONTEXT* /* pContext */, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_GETRELATEDBUNDLEVARIABLE_ARGS args = { }; + BAENGINE_GETRELATEDBUNDLEVARIABLE_RESULTS results = { }; + LPWSTR sczBundleId = NULL; + LPWSTR sczVariable = NULL; + LPWSTR sczValue = NULL; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineGetRelatedBundleVariable args."); + + hr = BuffReaderReadString(pReaderArgs, &sczBundleId); + ExitOnFailure(hr, "Failed to read bundle id of BAEngineGetRelatedBundleVariable args."); + + hr = BuffReaderReadString(pReaderArgs, &sczVariable); + ExitOnFailure(hr, "Failed to read variable name of BAEngineGetRelatedBundleVariable args."); + + args.wzBundleId = sczBundleId; + args.wzVariable = sczVariable; + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineGetRelatedBundleVariable results."); + + hr = BuffReaderReadNumber(pReaderResults, &results.cchValue); // ignored, overwritten below. + ExitOnFailure(hr, "Failed to read API version of BAEngineGetRelatedBundleVariable results."); + + // Execute. + hr = BundleGetBundleVariable(args.wzBundleId, args.wzVariable, &sczValue); + ExitOnFailure(hr, "Failed to get related bundle variable: %ls", sczVariable); + + results.cchValue = lstrlenW(sczValue); + results.wzValue = sczValue; + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineGetRelatedBundleVariable struct."); + + hr = BuffWriteNumberToBuffer(pBuffer, results.cchValue); + ExitOnFailure(hr, "Failed to write length of value of BAEngineGetRelatedBundleVariable struct."); + + hr = BuffWriteStringToBuffer(pBuffer, results.wzValue); + ExitOnFailure(hr, "Failed to write value of BAEngineGetRelatedBundleVariable struct."); + +LExit: + ReleaseStr(sczValue); + ReleaseStr(sczVariable); + ReleaseStr(sczBundleId); + + return hr; +} + +static HRESULT BAEngineFormatString( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_FORMATSTRING_ARGS args = { }; + BAENGINE_FORMATSTRING_RESULTS results = { }; + LPWSTR sczIn = NULL; + LPWSTR sczOut = NULL; + SIZE_T cchOut = 0; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineFormatString args."); + + hr = BuffReaderReadString(pReaderArgs, &sczIn); + ExitOnFailure(hr, "Failed to read string to format of BAEngineFormatString args."); + + args.wzIn = sczIn; + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineFormatString results."); + + hr = BuffReaderReadNumber(pReaderResults, &results.cchOut); // ignored, overwritten below. + ExitOnFailure(hr, "Failed to read allowed length of formatted string of BAEngineFormatString results."); + + // Execute. + hr = VariableFormatString(&pContext->pEngineState->variables, args.wzIn, &sczOut, &cchOut); + ExitOnFailure(hr, "Failed to format string"); + + results.cchOut = (cchOut > DWORD_MAX) ? DWORD_MAX : static_cast(cchOut); + results.wzOut = sczOut; + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineFormatString struct."); + + hr = BuffWriteNumberToBuffer(pBuffer, results.cchOut); + ExitOnFailure(hr, "Failed to write length of formatted string of BAEngineFormatString struct."); + + hr = BuffWriteStringToBuffer(pBuffer, results.wzOut); + ExitOnFailure(hr, "Failed to write formatted string of BAEngineFormatString struct."); + +LExit: + ReleaseStr(sczOut); + ReleaseStr(sczIn); + + return hr; +} + +static HRESULT BAEngineEscapeString( + __in BAENGINE_CONTEXT* /* pContext */, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_ESCAPESTRING_ARGS args = { }; + BAENGINE_ESCAPESTRING_RESULTS results = { }; + LPWSTR sczIn = NULL; + LPWSTR sczOut = NULL; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineEscapeString args."); + + hr = BuffReaderReadString(pReaderArgs, &sczIn); + ExitOnFailure(hr, "Failed to read string to escape of BAEngineEscapeString args."); + + args.wzIn = sczIn; + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineEscapeString results."); + + hr = BuffReaderReadNumber(pReaderResults, &results.cchOut); // ignored, overwritten below. + ExitOnFailure(hr, "Failed to read allowed length of escaped string of BAEngineEscapeString results."); + + // Execute. + hr = VariableEscapeString(args.wzIn, &sczOut); + ExitOnFailure(hr, "Failed to format string"); + + results.cchOut = lstrlenW(sczOut); + results.wzOut = sczOut; + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineEscapeString struct."); + + hr = BuffWriteNumberToBuffer(pBuffer, results.cchOut); + ExitOnFailure(hr, "Failed to write length of formatted string of BAEngineEscapeString struct."); + + hr = BuffWriteStringToBuffer(pBuffer, results.wzOut); + ExitOnFailure(hr, "Failed to write formatted string of BAEngineEscapeString struct."); + +LExit: + ReleaseStr(sczOut); + ReleaseStr(sczIn); + + return hr; +} + +static HRESULT BAEngineEvaluateCondition( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_EVALUATECONDITION_ARGS args = { }; + BAENGINE_EVALUATECONDITION_RESULTS results = { }; + LPWSTR sczCondition = NULL; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineEvaluateCondition args."); + + hr = BuffReaderReadString(pReaderArgs, &sczCondition); + ExitOnFailure(hr, "Failed to read condition of BAEngineEvaluateCondition args."); + + args.wzCondition = sczCondition; + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineEvaluateCondition results."); + + // Execute. + hr = ConditionEvaluate(&pContext->pEngineState->variables, args.wzCondition, &results.f); + ExitOnFailure(hr, "Failed to evalute condition."); + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineEvaluateCondition struct."); + + hr = BuffWriteNumberToBuffer(pBuffer, results.f); + ExitOnFailure(hr, "Failed to result of BAEngineEvaluateCondition struct."); + +LExit: + ReleaseStr(sczCondition); + + return hr; +} + +static HRESULT BAEngineLog( + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_LOG_ARGS args = { }; + BAENGINE_LOG_RESULTS results = { }; + LPWSTR sczMessage = NULL; + REPORT_LEVEL rl = REPORT_NONE; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineLog args."); + + hr = BuffReaderReadNumber(pReaderArgs, reinterpret_cast(&args.level)); + ExitOnFailure(hr, "Failed to read API version of BAEngineLog args."); + + hr = BuffReaderReadString(pReaderArgs, &sczMessage); + ExitOnFailure(hr, "Failed to read variable name of BAEngineLog args."); + + switch (args.level) + { + case BOOTSTRAPPER_LOG_LEVEL_STANDARD: + rl = REPORT_STANDARD; + break; + + case BOOTSTRAPPER_LOG_LEVEL_VERBOSE: + rl = REPORT_VERBOSE; + break; + + case BOOTSTRAPPER_LOG_LEVEL_DEBUG: + rl = REPORT_DEBUG; + break; + + case BOOTSTRAPPER_LOG_LEVEL_ERROR: + rl = REPORT_ERROR; + break; + + default: + ExitFunction1(hr = E_INVALIDARG); + } + + args.wzMessage = sczMessage; + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineLog results."); + + // Execute. + hr = ExternalEngineLog(rl, args.wzMessage); + ExitOnFailure(hr, "Failed to log BA message."); + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineLog struct."); + +LExit: + ReleaseStr(sczMessage); + return hr; +} + +static HRESULT BAEngineSendEmbeddedError( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_SENDEMBEDDEDERROR_ARGS args = { }; + BAENGINE_SENDEMBEDDEDERROR_RESULTS results = { }; + LPWSTR sczMessage = NULL; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSendEmbeddedError args."); + + hr = BuffReaderReadNumber(pReaderArgs, &args.dwErrorCode); + ExitOnFailure(hr, "Failed to read error code of BAEngineSendEmbeddedError args."); + + hr = BuffReaderReadString(pReaderArgs, &sczMessage); + ExitOnFailure(hr, "Failed to read condition of BAEngineSendEmbeddedError args."); + + args.wzMessage = sczMessage; + + hr = BuffReaderReadNumber(pReaderArgs, &args.dwUIHint); + ExitOnFailure(hr, "Failed to read UI hint of BAEngineSendEmbeddedError args."); + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSendEmbeddedError results."); + + // Execute. + hr = ExternalEngineSendEmbeddedError(pContext->pEngineState, args.dwErrorCode, args.wzMessage, args.dwUIHint, &results.nResult); + ExitOnFailure(hr, "Failed to send embedded error."); + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineSendEmbeddedError struct."); + + hr = BuffWriteNumberToBuffer(pBuffer, results.nResult); + ExitOnFailure(hr, "Failed to result of BAEngineSendEmbeddedError struct."); + +LExit: + ReleaseStr(sczMessage); + return hr; +} + +static HRESULT BAEngineSendEmbeddedProgress( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_SENDEMBEDDEDPROGRESS_ARGS args = { }; + BAENGINE_SENDEMBEDDEDPROGRESS_RESULTS results = { }; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSendEmbeddedProgress args."); + + hr = BuffReaderReadNumber(pReaderArgs, &args.dwProgressPercentage); + ExitOnFailure(hr, "Failed to read progress of BAEngineSendEmbeddedProgress args."); + + hr = BuffReaderReadNumber(pReaderArgs, &args.dwOverallProgressPercentage); + ExitOnFailure(hr, "Failed to read overall progress of BAEngineSendEmbeddedProgress args."); + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSendEmbeddedProgress results."); + + // Execute. + hr = ExternalEngineSendEmbeddedProgress(pContext->pEngineState, args.dwProgressPercentage, args.dwOverallProgressPercentage, &results.nResult); + ExitOnFailure(hr, "Failed to send embedded error."); + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineSendEmbeddedProgress struct."); + + hr = BuffWriteNumberToBuffer(pBuffer, results.nResult); + ExitOnFailure(hr, "Failed to result of BAEngineSendEmbeddedProgress struct."); + +LExit: + return hr; +} + +static HRESULT BAEngineSetUpdate( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_SETUPDATE_ARGS args = { }; + BAENGINE_SETUPDATE_RESULTS results = { }; + LPWSTR sczLocalSource = NULL; + LPWSTR sczDownloadSource = NULL; + LPWSTR sczHash = NULL; + LPWSTR sczUpdatePackageId = NULL; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSetUpdate args."); + + hr = BuffReaderReadString(pReaderArgs, &sczLocalSource); + ExitOnFailure(hr, "Failed to read local source of BAEngineSetUpdate args."); + + args.wzLocalSource = sczLocalSource; + + hr = BuffReaderReadString(pReaderArgs, &sczDownloadSource); + ExitOnFailure(hr, "Failed to read download source of BAEngineSetUpdate args."); + + args.wzDownloadSource = sczDownloadSource; + + hr = BuffReaderReadNumber64(pReaderArgs, &args.qwSize); + ExitOnFailure(hr, "Failed to read update size of BAEngineSetUpdate args."); + + hr = BuffReaderReadNumber(pReaderArgs, reinterpret_cast(&args.hashType)); + ExitOnFailure(hr, "Failed to read hash type of BAEngineSetUpdate args."); + + hr = BuffReaderReadString(pReaderArgs, &sczHash); + ExitOnFailure(hr, "Failed to read hash of BAEngineSetUpdate args."); + + args.wzHash = sczHash; + + hr = BuffReaderReadString(pReaderArgs, &sczUpdatePackageId); + ExitOnFailure(hr, "Failed to read update package id of BAEngineSetUpdate args."); + + args.wzUpdatePackageId = sczUpdatePackageId; + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSetUpdate results."); + + // Execute. + hr = ExternalEngineSetUpdate(pContext->pEngineState, args.wzLocalSource, args.wzDownloadSource, args.qwSize, args.hashType, args.wzHash, args.wzUpdatePackageId); + ExitOnFailure(hr, "Failed to set update."); + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineSetUpdate struct."); + +LExit: + ReleaseStr(sczUpdatePackageId); + ReleaseStr(sczHash); + ReleaseStr(sczDownloadSource); + ReleaseStr(sczLocalSource); + return hr; +} + +static HRESULT BAEngineSetLocalSource( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_SETLOCALSOURCE_ARGS args = { }; + BAENGINE_SETLOCALSOURCE_RESULTS results = { }; + LPWSTR sczPackageOrContainerId = NULL; + LPWSTR sczPayloadId = NULL; + LPWSTR sczPath = NULL; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSetLocalSource args."); + + hr = BuffReaderReadString(pReaderArgs, &sczPackageOrContainerId); + ExitOnFailure(hr, "Failed to read package or container id of BAEngineSetLocalSource args."); + + args.wzPackageOrContainerId = sczPackageOrContainerId; + + hr = BuffReaderReadString(pReaderArgs, &sczPayloadId); + ExitOnFailure(hr, "Failed to read payload id of BAEngineSetLocalSource args."); + + args.wzPayloadId = sczPayloadId; + + hr = BuffReaderReadString(pReaderArgs, &sczPath); + ExitOnFailure(hr, "Failed to read path of BAEngineSetLocalSource args."); + + args.wzPath = sczPath; + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSetLocalSource results."); + + // Execute. + hr = ExternalEngineSetLocalSource(pContext->pEngineState, args.wzPackageOrContainerId, args.wzPayloadId, args.wzPath); + ExitOnFailure(hr, "Failed to set local source."); + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineSetLocalSource struct."); + +LExit: + ReleaseStr(sczPath); + ReleaseStr(sczPayloadId); + ReleaseStr(sczPackageOrContainerId); + return hr; +} + +static HRESULT BAEngineSetDownloadSource( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_SETDOWNLOADSOURCE_ARGS args = { }; + BAENGINE_SETDOWNLOADSOURCE_RESULTS results = { }; + LPWSTR sczPackageOrContainerId = NULL; + LPWSTR sczPayloadId = NULL; + LPWSTR sczUrl = NULL; + LPWSTR sczUser = NULL; + LPWSTR sczPassword = NULL; + LPWSTR sczAuthorizationHeader = NULL; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSetDownloadSource args."); + + hr = BuffReaderReadString(pReaderArgs, &sczPackageOrContainerId); + ExitOnFailure(hr, "Failed to read package or container id of BAEngineSetDownloadSource args."); + + args.wzPackageOrContainerId = sczPackageOrContainerId; + + hr = BuffReaderReadString(pReaderArgs, &sczPayloadId); + ExitOnFailure(hr, "Failed to read payload id of BAEngineSetDownloadSource args."); + + args.wzPayloadId = sczPayloadId; + + hr = BuffReaderReadString(pReaderArgs, &sczUrl); + ExitOnFailure(hr, "Failed to read url of BAEngineSetDownloadSource args."); + + args.wzUrl = sczUrl; + + hr = BuffReaderReadString(pReaderArgs, &sczUser); + ExitOnFailure(hr, "Failed to read user of BAEngineSetDownloadSource args."); + + args.wzUser = sczUser; + + hr = BuffReaderReadString(pReaderArgs, &sczPassword); + ExitOnFailure(hr, "Failed to read password of BAEngineSetDownloadSource args."); + + args.wzPassword = sczPassword; + + hr = BuffReaderReadString(pReaderArgs, &sczAuthorizationHeader); + ExitOnFailure(hr, "Failed to read authorization header of BAEngineSetDownloadSource args."); + + args.wzAuthorizationHeader = sczAuthorizationHeader; + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSetDownloadSource results."); + + // Execute. + hr = ExternalEngineSetDownloadSource(pContext->pEngineState, args.wzPackageOrContainerId, args.wzPayloadId, args.wzUrl, args.wzUser, args.wzPassword, args.wzAuthorizationHeader); + ExitOnFailure(hr, "Failed to set download source."); + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineSetDownloadSource struct."); + +LExit: + ReleaseStr(sczAuthorizationHeader); + ReleaseStr(sczPassword); + ReleaseStr(sczUser); + ReleaseStr(sczUrl); + ReleaseStr(sczPayloadId); + ReleaseStr(sczPackageOrContainerId); + return hr; +} + + +static HRESULT BAEngineSetVariableNumeric( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_SETVARIABLENUMERIC_ARGS args = { }; + BAENGINE_SETVARIABLENUMERIC_RESULTS results = { }; + LPWSTR sczVariable = NULL; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSetVariableNumeric args."); + + hr = BuffReaderReadString(pReaderArgs, &sczVariable); + ExitOnFailure(hr, "Failed to read variable of BAEngineSetVariableNumeric args."); + + args.wzVariable = sczVariable; + + hr = BuffReaderReadNumber64(pReaderArgs, reinterpret_cast(&args.llValue)); + ExitOnFailure(hr, "Failed to read formatted flag of BAEngineSetVariableNumeric results."); + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSetVariableNumeric results."); + + // Execute. + hr = ExternalEngineSetVariableNumeric(pContext->pEngineState, args.wzVariable, args.llValue); + ExitOnFailure(hr, "Failed to set numeric variable."); + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineSetVariableNumeric struct."); + +LExit: + ReleaseStr(sczVariable); + return hr; +} + +static HRESULT BAEngineSetVariableString( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_SETVARIABLESTRING_ARGS args = { }; + BAENGINE_SETVARIABLESTRING_RESULTS results = { }; + LPWSTR sczVariable = NULL; + LPWSTR sczValue = NULL; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSetVariableString args."); + + hr = BuffReaderReadString(pReaderArgs, &sczVariable); + ExitOnFailure(hr, "Failed to read variable of BAEngineSetVariableString args."); + + args.wzVariable = sczVariable; + + hr = BuffReaderReadString(pReaderArgs, &sczValue); + ExitOnFailure(hr, "Failed to read value of BAEngineSetVariableString args."); + + args.wzValue = sczValue; + + hr = BuffReaderReadNumber(pReaderArgs, reinterpret_cast(&args.fFormatted)); + ExitOnFailure(hr, "Failed to read formatted flag of BAEngineSetVariableString results."); + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSetVariableString results."); + + // Execute. + hr = ExternalEngineSetVariableString(pContext->pEngineState, args.wzVariable, args.wzValue, args.fFormatted); + ExitOnFailure(hr, "Failed to set string variable."); + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineSetVariableString struct."); + +LExit: + ReleaseStr(sczValue); + ReleaseStr(sczVariable); + return hr; +} + +static HRESULT BAEngineSetVariableVersion( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_SETVARIABLEVERSION_ARGS args = { }; + BAENGINE_SETVARIABLEVERSION_RESULTS results = { }; + LPWSTR sczVariable = NULL; + LPWSTR sczValue = NULL; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSetVariableVersion args."); + + hr = BuffReaderReadString(pReaderArgs, &sczVariable); + ExitOnFailure(hr, "Failed to read variable of BAEngineSetVariableVersion args."); + + args.wzVariable = sczVariable; + + hr = BuffReaderReadString(pReaderArgs, &sczValue); + ExitOnFailure(hr, "Failed to read value of BAEngineSetVariableVersion args."); + + args.wzValue = sczValue; + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSetVariableVersion results."); + + // Execute. + hr = ExternalEngineSetVariableVersion(pContext->pEngineState, args.wzVariable, args.wzValue); + ExitOnFailure(hr, "Failed to set variable version."); + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineSetVariableVersion struct."); + +LExit: + ReleaseStr(sczValue); + ReleaseStr(sczVariable); + return hr; +} + +static HRESULT BAEngineCloseSplashScreen( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_CLOSESPLASHSCREEN_ARGS args = { }; + BAENGINE_CLOSESPLASHSCREEN_RESULTS results = { }; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineCloseSplashScreen args."); + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineCloseSplashScreen results."); + + // Execute. + ExternalEngineCloseSplashScreen(pContext->pEngineState); + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineCloseSplashScreen struct."); + +LExit: + return hr; +} + +static HRESULT BAEngineCompareVersions( + __in BAENGINE_CONTEXT* /* pContext */, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_COMPAREVERSIONS_ARGS args = { }; + BAENGINE_COMPAREVERSIONS_RESULTS results = { }; + LPWSTR sczVersion1 = NULL; + LPWSTR sczVersion2 = NULL; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineCompareVersions args."); + + hr = BuffReaderReadString(pReaderArgs, &sczVersion1); + ExitOnFailure(hr, "Failed to read first input of BAEngineCompareVersions args."); + + args.wzVersion1 = sczVersion1; + + hr = BuffReaderReadString(pReaderArgs, &sczVersion2); + ExitOnFailure(hr, "Failed to read second input of BAEngineCompareVersions args."); + + args.wzVersion2 = sczVersion2; + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineCompareVersions results."); + + // Execute. + hr = ExternalEngineCompareVersions(args.wzVersion1, args.wzVersion2, &results.nResult); + ExitOnFailure(hr, "Failed to compare versions."); + + // Write results. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineCompareVersions struct."); + + hr = BuffWriteNumberToBuffer(pBuffer, results.nResult); + ExitOnFailure(hr, "Failed to result of BAEngineCompareVersions struct."); + +LExit: + ReleaseStr(sczVersion2); + ReleaseStr(sczVersion1); + + return hr; +} + +static HRESULT BAEngineDetect( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_DETECT_ARGS args = { }; + BAENGINE_DETECT_RESULTS results = { }; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineDetect args."); + + hr = BuffReaderReadNumber64(pReaderArgs, &args.hwndParent); + ExitOnFailure(hr, "Failed to read parent window of BAEngineDetect args."); + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineDetect results."); + + // Execute. + hr = ExternalEngineDetect(pContext, reinterpret_cast(args.hwndParent)); + ExitOnFailure(hr, "Failed to detect in the engine."); + + // Pack result. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineDetect struct."); + +LExit: + return hr; +} + +static HRESULT BAEnginePlan( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_PLAN_ARGS args = { }; + BAENGINE_PLAN_RESULTS results = { }; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEnginePlan args."); + + hr = BuffReaderReadNumber(pReaderArgs, reinterpret_cast(&args.action)); + ExitOnFailure(hr, "Failed to read plan action of BAEnginePlan args."); + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEnginePlan results."); + + // Execute. + hr = ExternalEnginePlan(pContext, args.action); + ExitOnFailure(hr, "Failed to plan in the engine."); + + // Pack result. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEnginePlan struct."); + +LExit: + return hr; +} + +static HRESULT BAEngineElevate( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_ELEVATE_ARGS args = { }; + BAENGINE_ELEVATE_RESULTS results = { }; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineElevate args."); + + hr = BuffReaderReadNumber64(pReaderArgs, &args.hwndParent); + ExitOnFailure(hr, "Failed to read parent window of BAEngineElevate args."); + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineElevate results."); + + // Execute. + hr = ExternalEngineElevate(pContext, reinterpret_cast(args.hwndParent)); + ExitOnFailure(hr, "Failed to detect in the engine."); + + // Pack result. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineElevate struct."); + +LExit: + return hr; +} + +static HRESULT BAEngineApply( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_APPLY_ARGS args = { }; + BAENGINE_APPLY_RESULTS results = { }; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineApply args."); + + hr = BuffReaderReadNumber64(pReaderArgs, &args.hwndParent); + ExitOnFailure(hr, "Failed to read parent window of BAEngineApply args."); + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineApply results."); + + // Execute. + hr = ExternalEngineApply(pContext, reinterpret_cast(args.hwndParent)); + ExitOnFailure(hr, "Failed to detect in the engine."); + + // Pack result. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineApply struct."); + +LExit: + return hr; +} + +static HRESULT BAEngineQuit( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_QUIT_ARGS args = { }; + BAENGINE_QUIT_RESULTS results = { }; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineQuit args."); + + hr = BuffReaderReadNumber(pReaderArgs, &args.dwExitCode); + ExitOnFailure(hr, "Failed to read API version of BAEngineQuit args."); + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineQuit results."); + + // Execute. + hr = ExternalEngineQuit(pContext, args.dwExitCode); + ExitOnFailure(hr, "Failed to quit the engine."); + + // Pack result. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineQuit struct."); + +LExit: + return hr; +} + +static HRESULT BAEngineLaunchApprovedExe( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_LAUNCHAPPROVEDEXE_ARGS args = { }; + BAENGINE_LAUNCHAPPROVEDEXE_RESULTS results = { }; + LPWSTR sczApprovedExeForElevationId = NULL; + LPWSTR sczArguments = NULL; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineLaunchApprovedExe args."); + + hr = BuffReaderReadNumber64(pReaderArgs, &args.hwndParent); + ExitOnFailure(hr, "Failed to read parent window of BAEngineLaunchApprovedExe args."); + + hr = BuffReaderReadString(pReaderArgs, &sczApprovedExeForElevationId); + ExitOnFailure(hr, "Failed to read approved exe elevation id of BAEngineLaunchApprovedExe args."); + + args.wzApprovedExeForElevationId = sczApprovedExeForElevationId; + + hr = BuffReaderReadString(pReaderArgs, &sczArguments); + ExitOnFailure(hr, "Failed to read arguments of BAEngineLaunchApprovedExe args."); + + args.wzArguments = sczArguments; + + hr = BuffReaderReadNumber(pReaderArgs, &args.dwWaitForInputIdleTimeout); + ExitOnFailure(hr, "Failed to read wait for idle input timeout of BAEngineLaunchApprovedExe args."); + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineLaunchApprovedExe results."); + + // Execute. + hr = ExternalEngineLaunchApprovedExe(pContext, reinterpret_cast(args.hwndParent), args.wzApprovedExeForElevationId, args.wzArguments, args.dwWaitForInputIdleTimeout); + ExitOnFailure(hr, "Failed to quit the engine."); + + // Pack result. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineLaunchApprovedExe struct."); + +LExit: + ReleaseStr(sczArguments); + ReleaseStr(sczApprovedExeForElevationId); + return hr; +} + +static HRESULT BAEngineSetUpdateSource( + __in BAENGINE_CONTEXT* pContext, + __in BUFF_READER* pReaderArgs, + __in BUFF_READER* pReaderResults, + __in BUFF_BUFFER* pBuffer + ) +{ + HRESULT hr = S_OK; + BAENGINE_SETUPDATESOURCE_ARGS args = { }; + BAENGINE_SETUPDATESOURCE_RESULTS results = { }; + LPWSTR sczUrl = NULL; + LPWSTR sczAuthorizationHeader = NULL; + + // Read args. + hr = BuffReaderReadNumber(pReaderArgs, &args.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSetUpdateSource args."); + + hr = BuffReaderReadString(pReaderArgs, &sczUrl); + ExitOnFailure(hr, "Failed to read url of BAEngineSetUpdateSource args."); + + args.wzUrl = sczUrl; + + hr = BuffReaderReadString(pReaderArgs, &sczAuthorizationHeader); + ExitOnFailure(hr, "Failed to read authorization header of BAEngineSetUpdateSource args."); + + args.wzAuthorizationHeader = sczAuthorizationHeader; + + // Read results. + hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); + ExitOnFailure(hr, "Failed to read API version of BAEngineSetUpdateSource results."); + + // Execute. + hr = ExternalEngineSetUpdateSource(pContext->pEngineState, args.wzUrl, args.wzAuthorizationHeader); + ExitOnFailure(hr, "Failed to set update source in the engine."); + + // Pack result. + hr = BuffWriteNumberToBuffer(pBuffer, sizeof(results)); + ExitOnFailure(hr, "Failed to write size of BAEngineSetUpdateSource struct."); + +LExit: + ReleaseStr(sczAuthorizationHeader); + ReleaseStr(sczUrl); + + return hr; +} + +static HRESULT ParseArgsAndResults( + __in_bcount(cbData) LPCBYTE pbData, + __in SIZE_T cbData, + __in BUFF_READER* pBufferArgs, + __in BUFF_READER* pBufferResults +) +{ + HRESULT hr = S_OK; + SIZE_T iData = 0; + DWORD dw = 0; + + // Get the args reader size and point to the data just after the size. + hr = BuffReadNumber(pbData, cbData, &iData, &dw); + ExitOnFailure(hr, "Failed to parse size of args"); + + pBufferArgs->pbData = pbData + iData; + pBufferArgs->cbData = dw; + pBufferArgs->iBuffer = 0; + + // Get the results reader size and point to the data just after the size. + hr = ::SIZETAdd(iData, dw, &iData); + ExitOnFailure(hr, "Failed to advance index beyond args"); + + hr = BuffReadNumber(pbData, cbData, &iData, &dw); + ExitOnFailure(hr, "Failed to parse size of results"); + + pBufferResults->pbData = pbData + iData; + pBufferResults->cbData = dw; + pBufferResults->iBuffer = 0; + +LExit: + return hr; +} + +HRESULT WINAPI EngineForApplicationProc( + __in BAENGINE_CONTEXT* pContext, + __in BOOTSTRAPPER_ENGINE_MESSAGE message, + __in_bcount(cbData) LPCBYTE pbData, + __in SIZE_T cbData + ) +{ + HRESULT hr = S_OK; + BUFF_READER readerArgs = { }; + BUFF_READER readerResults = { }; + BUFF_BUFFER bufferResponse = { }; + + hr = ParseArgsAndResults(pbData, cbData, &readerArgs, &readerResults); + if (SUCCEEDED(hr)) + { + switch (message) + { + case BOOTSTRAPPER_ENGINE_MESSAGE_GETPACKAGECOUNT: + hr = BAEngineGetPackageCount(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_GETVARIABLENUMERIC: + hr = BAEngineGetVariableNumeric(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_GETVARIABLESTRING: + hr = BAEngineGetVariableString(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_GETVARIABLEVERSION: + hr = BAEngineGetVariableVersion(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_FORMATSTRING: + hr = BAEngineFormatString(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_ESCAPESTRING: + hr = BAEngineEscapeString(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_EVALUATECONDITION: + hr = BAEngineEvaluateCondition(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_LOG: + hr = BAEngineLog(&readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_SENDEMBEDDEDERROR: + hr = BAEngineSendEmbeddedError(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_SENDEMBEDDEDPROGRESS: + hr = BAEngineSendEmbeddedProgress(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_SETUPDATE: + hr = BAEngineSetUpdate(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_SETLOCALSOURCE: + hr = BAEngineSetLocalSource(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_SETDOWNLOADSOURCE: + hr = BAEngineSetDownloadSource(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_SETVARIABLENUMERIC: + hr = BAEngineSetVariableNumeric(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_SETVARIABLESTRING: + hr = BAEngineSetVariableString(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_SETVARIABLEVERSION: + hr = BAEngineSetVariableVersion(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_CLOSESPLASHSCREEN: + hr = BAEngineCloseSplashScreen(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_DETECT: + hr = BAEngineDetect(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_PLAN: + hr = BAEnginePlan(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_ELEVATE: + hr = BAEngineElevate(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_APPLY: + hr = BAEngineApply(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_QUIT: + hr = BAEngineQuit(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_LAUNCHAPPROVEDEXE: + hr = BAEngineLaunchApprovedExe(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_SETUPDATESOURCE: + hr = BAEngineSetUpdateSource(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_COMPAREVERSIONS: + hr = BAEngineCompareVersions(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + case BOOTSTRAPPER_ENGINE_MESSAGE_GETRELATEDBUNDLEVARIABLE: + hr = BAEngineGetRelatedBundleVariable(pContext, &readerArgs, &readerResults, &bufferResponse); + break; + default: + hr = E_NOTIMPL; + break; + } + } + + hr = PipeRpcResponse(&pContext->hRpcPipe, message, hr, bufferResponse.pbData, bufferResponse.cbData); + ExitOnFailure(hr, "Failed to send engine result to bootstrapper application."); + +LExit: + ReleaseBuffer(bufferResponse); + return hr; +} + +static DWORD WINAPI BAEngineMessagePumpThreadProc( + __in LPVOID lpThreadParameter +) +{ + HRESULT hr = S_OK; + BOOL fComInitialized = FALSE; + BAENGINE_CONTEXT* pContext = reinterpret_cast(lpThreadParameter); + PIPE_MESSAGE msg = { }; + + // initialize COM + hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); + ExitOnFailure(hr, "Failed to initialize COM."); + fComInitialized = TRUE; + + // Pump messages from bootstrapper application for engine messages until the pipe is closed. + while (S_OK == (hr = PipeRpcReadMessage(&pContext->hRpcPipe, &msg))) + { + EngineForApplicationProc(pContext, static_cast(msg.dwMessageType), reinterpret_cast(msg.pvData), msg.cbData); + + ReleasePipeMessage(&msg); + } + ExitOnFailure(hr, "Failed to get message over bootstrapper application pipe"); + + if (S_FALSE == hr) + { + hr = S_OK; + } + +LExit: + ReleasePipeMessage(&msg); + + if (fComInitialized) + { + ::CoUninitialize(); + } + + return (DWORD)hr; +} diff --git a/src/burn/engine/baengine.h b/src/burn/engine/baengine.h new file mode 100644 index 00000000..97cfea9c --- /dev/null +++ b/src/burn/engine/baengine.h @@ -0,0 +1,84 @@ +#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. + + +#if defined(__cplusplus) +extern "C" { +#endif + +// structs + +typedef struct _BAENGINE_CONTEXT +{ + BURN_ENGINE_STATE* pEngineState; + QUEUTIL_QUEUE_HANDLE hQueue; + HANDLE hQueueSemaphore; + CRITICAL_SECTION csQueue; + + PIPE_RPC_HANDLE hRpcPipe; + HANDLE hThread; +} BAENGINE_CONTEXT; + +typedef struct _BAENGINE_ACTION +{ + WM_BURN dwMessage; + union + { + struct + { + HWND hwndParent; + } detect; + struct + { + BOOTSTRAPPER_ACTION action; + } plan; + struct + { + HWND hwndParent; + } elevate; + struct + { + HWND hwndParent; + } apply; + BURN_LAUNCH_APPROVED_EXE launchApprovedExe; + struct + { + DWORD dwExitCode; + } quit; + }; +} BAENGINE_ACTION; + +// function declarations + +HRESULT BAEngineCreateContext( + __in BURN_ENGINE_STATE* pEngineState, + __inout BAENGINE_CONTEXT** ppContext +); + +void BAEngineFreeContext( + __in BAENGINE_CONTEXT* pContext +); + +void DAPI BAEngineFreeAction( + __in BAENGINE_ACTION* pAction +); + +HRESULT BAEngineStartListening( + __in BAENGINE_CONTEXT* pContext, + __in HANDLE hBAEnginePipe +); + +HRESULT BAEngineStopListening( + __in BAENGINE_CONTEXT * pContext +); + +HRESULT WINAPI EngineForApplicationProc( + __in BAENGINE_CONTEXT* pvContext, + __in BOOTSTRAPPER_ENGINE_MESSAGE message, + __in_bcount(cbArgs) const LPVOID pvArgs, + __in DWORD /*cbArgs*/ +); + +#if defined(__cplusplus) +} +#endif diff --git a/src/burn/engine/bootstrapperapplication.cpp b/src/burn/engine/bootstrapperapplication.cpp new file mode 100644 index 00000000..402f7015 --- /dev/null +++ b/src/burn/engine/bootstrapperapplication.cpp @@ -0,0 +1,692 @@ +// 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" + +static const LPCWSTR BA_PIPE_NAME_FORMAT_STRING = L"%ls.BA"; +static const LPCWSTR ENGINE_PIPE_NAME_FORMAT_STRING = L"%ls.BAEngine"; + +// internal function declarations + +static HRESULT CreateBootstrapperApplicationPipes( + __in_z LPCWSTR wzBasePipeName, + __out HANDLE* phBAPipe, + __out HANDLE* phBAEnginePipe +); +static HRESULT CreateBootstrapperApplicationProcess( + __in_z LPCWSTR wzBootstrapperApplicationPath, + __in int nCmdShow, + __in_z LPCWSTR wzPipeName, + __in_z LPCWSTR wzSecret, + __out HANDLE* phProcess +); +static void Disconnect( + __in BURN_USER_EXPERIENCE* pUserExperience +); +static int FilterResult( + __in DWORD dwAllowedResults, + __in int nResult + ); +static HRESULT WaitForBootstrapperApplicationConnect( + __in HANDLE hBAProcess, + __in HANDLE hBAPipe, + __in HANDLE hBAEnginePipe, + __in_z LPCWSTR wzSecret +); +static HRESULT VerifyPipeSecret( + __in HANDLE hPipe, + __in_z LPCWSTR wzSecret +); + + +// function definitions + +EXTERN_C HRESULT BootstrapperApplicationParseFromXml( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in IXMLDOMNode* pixnBundle +) +{ + HRESULT hr = S_OK; + IXMLDOMNode* pixnUserExperienceNode = NULL; + LPWSTR sczPrimaryId = NULL; + LPWSTR sczSecondaryId = NULL; + BOOL fFoundSecondary = FALSE; + + // select UX node + hr = XmlSelectSingleNode(pixnBundle, L"UX", &pixnUserExperienceNode); + if (S_FALSE == hr) + { + hr = E_NOTFOUND; + } + ExitOnFailure(hr, "Failed to select user experience node."); + + // @PrimaryPayloadId + hr = XmlGetAttributeEx(pixnUserExperienceNode, L"PrimaryPayloadId", &sczPrimaryId); + ExitOnRequiredXmlQueryFailure(hr, "Failed to get @PrimaryPayloadId."); + + // @SecondaryPayloadId + hr = XmlGetAttributeEx(pixnUserExperienceNode, L"SecondaryPayloadId", &sczSecondaryId); + ExitOnOptionalXmlQueryFailure(hr, fFoundSecondary, "Failed to get @SecondaryPayloadId."); + + // parse payloads + hr = PayloadsParseFromXml(&pUserExperience->payloads, NULL, NULL, pixnUserExperienceNode); + ExitOnFailure(hr, "Failed to parse user experience payloads."); + + // make sure we have at least one payload + if (0 == pUserExperience->payloads.cPayloads) + { + hr = E_UNEXPECTED; + ExitOnFailure(hr, "Too few UX payloads."); + } + + // Find the primary and secondary bootstrapper application payloads. + for (DWORD i = 0; i < pUserExperience->payloads.cPayloads; ++i) + { + BURN_PAYLOAD* pPayload = pUserExperience->payloads.rgPayloads + i; + + if (!pUserExperience->pPrimaryExePayload && CSTR_EQUAL == ::CompareStringOrdinal(pPayload->sczKey, -1, sczPrimaryId, -1, FALSE)) + { + pUserExperience->pPrimaryExePayload = pPayload; + } + else if (fFoundSecondary && !pUserExperience->pSecondaryExePayload && CSTR_EQUAL == ::CompareStringOrdinal(pPayload->sczKey, -1, sczSecondaryId, -1, FALSE)) + { + pUserExperience->pSecondaryExePayload = pPayload; + } + } + + if (!pUserExperience->pPrimaryExePayload) + { + hr = E_UNEXPECTED; + ExitOnFailure(hr, "Failed to find primary bootstrapper application payload."); + } + +LExit: + ReleaseStr(sczSecondaryId); + ReleaseStr(sczPrimaryId); + ReleaseObject(pixnUserExperienceNode); + + return hr; +} + +EXTERN_C void BootstrapperApplicationUninitialize( + __in BURN_USER_EXPERIENCE* pUserExperience +) +{ + if (pUserExperience->pEngineContext) + { + BAEngineFreeContext(pUserExperience->pEngineContext); + pUserExperience->pEngineContext = NULL; + } + + ReleaseStr(pUserExperience->sczTempDirectory); + PayloadsUninitialize(&pUserExperience->payloads); + + // clear struct + memset(pUserExperience, 0, sizeof(BURN_USER_EXPERIENCE)); +} + +EXTERN_C HRESULT BootstrapperApplicationStart( + __in BURN_ENGINE_STATE* pEngineState, + __in BOOL fSecondary +) +{ + HRESULT hr = S_OK; + LPWSTR sczBasePipeName = NULL; + LPWSTR sczSecret = NULL; + HANDLE hBAPipe = INVALID_HANDLE_VALUE; + HANDLE hBAEnginePipe = INVALID_HANDLE_VALUE; + BAENGINE_CONTEXT* pEngineContext = NULL; + + BURN_USER_EXPERIENCE* pUserExperience = &pEngineState->userExperience; + BOOTSTRAPPER_COMMAND* pCommand = &pEngineState->command; + LPCWSTR wzBootstrapperApplicationPath = fSecondary && pUserExperience->pSecondaryExePayload ? pUserExperience->pSecondaryExePayload->sczLocalFilePath : pUserExperience->pPrimaryExePayload->sczLocalFilePath; + + if (!wzBootstrapperApplicationPath) + { + hr = E_UNEXPECTED; + ExitOnFailure(hr, "Failed to find bootstrapper application path."); + } + + hr = BurnPipeCreateNameAndSecret(&sczBasePipeName, &sczSecret); + ExitOnFailure(hr, "Failed to create bootstrapper application pipename and secret"); + + hr = CreateBootstrapperApplicationPipes(sczBasePipeName, &hBAPipe, &hBAEnginePipe); + ExitOnFailure(hr, "Failed to create bootstrapper application pipes"); + + hr = CreateBootstrapperApplicationProcess(wzBootstrapperApplicationPath, pCommand->nCmdShow, sczBasePipeName, sczSecret, &pUserExperience->hBAProcess); + ExitOnFailure(hr, "Failed to create bootstrapper application process: %ls", wzBootstrapperApplicationPath); + + hr = WaitForBootstrapperApplicationConnect(pUserExperience->hBAProcess, hBAPipe, hBAEnginePipe, sczSecret); + ExitOnFailure(hr, "Failed while waiting for bootstrapper application to connect."); + + hr = BAEngineCreateContext(pEngineState, &pEngineContext); + ExitOnFailure(hr, "Failed to create bootstrapper application engine context."); + + pUserExperience->pEngineContext = pEngineContext; + pEngineContext = NULL; + + PipeRpcInitialize(&pUserExperience->hBARpcPipe, hBAPipe, TRUE); + hBAPipe = INVALID_HANDLE_VALUE; + + hr = BAEngineStartListening(pUserExperience->pEngineContext, hBAEnginePipe); + ExitOnFailure(hr, "Failed to start listening to bootstrapper application engine pipe."); + + hBAEnginePipe = INVALID_HANDLE_VALUE; + + hr = BACallbackOnCreate(pUserExperience, pCommand); + ExitOnFailure(hr, "Failed to create bootstrapper application"); + +LExit: + if (pEngineContext) + { + BAEngineFreeContext(pEngineContext); + pEngineContext = NULL; + } + + ReleasePipeHandle(hBAEnginePipe); + ReleasePipeHandle(hBAPipe); + ReleaseStr(sczSecret); + ReleaseStr(sczBasePipeName); + + return hr; +} + +EXTERN_C HRESULT BootstrapperApplicationStop( + __in BURN_USER_EXPERIENCE* pUserExperience, + __inout BOOL* pfReload +) +{ + HRESULT hr = S_OK; + DWORD dwExitCode = ERROR_SUCCESS; + + BACallbackOnDestroy(pUserExperience, *pfReload); + + Disconnect(pUserExperience); + + if (pUserExperience->pEngineContext) + { + BAEngineStopListening(pUserExperience->pEngineContext); + } + + if (pUserExperience->hBAProcess) + { + hr = AppWaitForSingleObject(pUserExperience->hBAProcess, INFINITE); + + ::GetExitCodeProcess(pUserExperience->hBAProcess, &dwExitCode); + + ReleaseHandle(pUserExperience->hBAProcess); + } + + // If the bootstrapper application process has already requested to reload, no need + // to check any further. But if the bootstrapper application process exited + // with anything but success then fallback to the other bootstrapper application. + // This should enable bootstrapper applications that fail to start due to missing + // prerequisites to fallback to the prerequisite bootstrapper application to install + // the necessary prerequisites. + if (!*pfReload) + { + *pfReload = (ERROR_SUCCESS != dwExitCode); + } + + return hr; +} + +EXTERN_C int BootstrapperApplicationCheckExecuteResult( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOL fRollback, + __in DWORD dwAllowedResults, + __in int nResult + ) +{ + // Do not allow canceling while rolling back. + if (fRollback && (IDCANCEL == nResult || IDABORT == nResult)) + { + nResult = IDNOACTION; + } + else if (FAILED(pUserExperience->hrApplyError) && !fRollback) // if we failed cancel except not during rollback. + { + nResult = IDCANCEL; + } + + nResult = FilterResult(dwAllowedResults, nResult); + + return nResult; +} + +EXTERN_C HRESULT BootstrapperApplicationInterpretExecuteResult( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOL fRollback, + __in DWORD dwAllowedResults, + __in int nResult + ) +{ + HRESULT hr = S_OK; + + // If we failed return that error unless this is rollback which should roll on. + if (FAILED(pUserExperience->hrApplyError) && !fRollback) + { + hr = pUserExperience->hrApplyError; + } + else + { + int nCheckedResult = BootstrapperApplicationCheckExecuteResult(pUserExperience, fRollback, dwAllowedResults, nResult); + hr = IDOK == nCheckedResult || IDNOACTION == nCheckedResult ? S_OK : IDCANCEL == nCheckedResult || IDABORT == nCheckedResult ? HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) : HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE); + } + + return hr; +} + +EXTERN_C HRESULT BootstrapperApplicationEnsureWorkingFolder( + __in BURN_CACHE* pCache, + __deref_out_z LPWSTR* psczUserExperienceWorkingFolder + ) +{ + HRESULT hr = S_OK; + LPWSTR sczWorkingFolder = NULL; + + hr = CacheEnsureBaseWorkingFolder(pCache, &sczWorkingFolder); + ExitOnFailure(hr, "Failed to create working folder."); + + hr = StrAllocFormatted(psczUserExperienceWorkingFolder, L"%ls%ls\\", sczWorkingFolder, L".ba"); + ExitOnFailure(hr, "Failed to calculate the bootstrapper application working path."); + + hr = DirEnsureExists(*psczUserExperienceWorkingFolder, NULL); + ExitOnFailure(hr, "Failed create bootstrapper application working folder."); + +LExit: + ReleaseStr(sczWorkingFolder); + + return hr; +} + + +EXTERN_C HRESULT BootstrapperApplicationRemove( + __in BURN_USER_EXPERIENCE* pUserExperience + ) +{ + HRESULT hr = S_OK; + + // Remove temporary UX directory + if (pUserExperience->sczTempDirectory) + { + hr = DirEnsureDeleteEx(pUserExperience->sczTempDirectory, DIR_DELETE_FILES | DIR_DELETE_RECURSE | DIR_DELETE_SCHEDULE); + TraceError(hr, "Could not delete bootstrapper application folder. Some files will be left in the temp folder."); + } + +//LExit: + return hr; +} + +EXTERN_C int BootstrapperApplicationSendError( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOTSTRAPPER_ERROR_TYPE errorType, + __in_z_opt LPCWSTR wzPackageId, + __in HRESULT hrCode, + __in_z_opt LPCWSTR wzError, + __in DWORD uiFlags, + __in int nRecommendation + ) +{ + int nResult = nRecommendation; + DWORD dwCode = HRESULT_CODE(hrCode); + LPWSTR sczError = NULL; + + // If no error string was provided, try to get the error string from the HRESULT. + if (!wzError) + { + if (SUCCEEDED(StrAllocFromError(&sczError, hrCode, NULL))) + { + wzError = sczError; + } + } + + BACallbackOnError(pUserExperience, errorType, wzPackageId, dwCode, wzError, uiFlags, 0, NULL, &nResult); // ignore return value. + + ReleaseStr(sczError); + return nResult; +} + +EXTERN_C void BootstrapperApplicationActivateEngine( + __in BURN_USER_EXPERIENCE* pUserExperience + ) +{ + ::EnterCriticalSection(&pUserExperience->csEngineActive); + AssertSz(!pUserExperience->fEngineActive, "Engine should have been deactivated before activating it."); + pUserExperience->fEngineActive = TRUE; + ::LeaveCriticalSection(&pUserExperience->csEngineActive); +} + +EXTERN_C void BootstrapperApplicationDeactivateEngine( + __in BURN_USER_EXPERIENCE* pUserExperience + ) +{ + ::EnterCriticalSection(&pUserExperience->csEngineActive); + AssertSz(pUserExperience->fEngineActive, "Engine should have been active before deactivating it."); + pUserExperience->fEngineActive = FALSE; + ::LeaveCriticalSection(&pUserExperience->csEngineActive); +} + +EXTERN_C HRESULT BootstrapperApplicationEnsureEngineInactive( + __in BURN_USER_EXPERIENCE* pUserExperience + ) +{ + // Make a slight optimization here by ignoring the critical section, because all callers should have needed to enter it for their operation anyway. + HRESULT hr = pUserExperience->fEngineActive ? HRESULT_FROM_WIN32(ERROR_BUSY) : S_OK; + ExitOnRootFailure(hr, "Engine is active, cannot proceed."); + +LExit: + return hr; +} + +EXTERN_C void BootstrapperApplicationExecuteReset( + __in BURN_USER_EXPERIENCE* pUserExperience + ) +{ + pUserExperience->hrApplyError = S_OK; + pUserExperience->hwndApply = NULL; +} + +EXTERN_C void BootstrapperApplicationExecutePhaseComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrResult + ) +{ + if (FAILED(hrResult)) + { + pUserExperience->hrApplyError = hrResult; + } +} + + +// internal function definitions + +static HRESULT CreateBootstrapperApplicationPipes( + __in_z LPCWSTR wzBasePipeName, + __out HANDLE* phBAPipe, + __out HANDLE* phBAEnginePipe + ) +{ + HRESULT hr = S_OK; + LPWSTR sczPipeName = NULL; + HANDLE hBAPipe = INVALID_HANDLE_VALUE; + HANDLE hBAEnginePipe = INVALID_HANDLE_VALUE; + + // Create the bootstrapper application pipe. + hr = StrAllocFormatted(&sczPipeName, BA_PIPE_NAME_FORMAT_STRING, wzBasePipeName); + ExitOnFailure(hr, "Failed to allocate full name of bootstrapper pipe: %ls", wzBasePipeName); + + hr = PipeCreate(sczPipeName, NULL, &hBAPipe); + ExitOnFailure(hr, "Failed to create cache pipe: %ls", sczPipeName); + + // Create the bootstrapper application's engine pipe. + hr = StrAllocFormatted(&sczPipeName, ENGINE_PIPE_NAME_FORMAT_STRING, wzBasePipeName); + ExitOnFailure(hr, "Failed to allocate full name of bootstrapper application engine pipe: %ls", wzBasePipeName); + + hr = PipeCreate(sczPipeName, NULL, &hBAEnginePipe); + ExitOnFailure(hr, "Failed to create cache pipe: %ls", sczPipeName); + + *phBAEnginePipe = hBAEnginePipe; + hBAEnginePipe = INVALID_HANDLE_VALUE; + + *phBAPipe = hBAPipe; + hBAPipe = INVALID_HANDLE_VALUE; + +LExit: + ReleasePipeHandle(hBAEnginePipe); + ReleasePipeHandle(hBAPipe); + + return hr; +} + +static HRESULT CreateBootstrapperApplicationProcess( + __in_z LPCWSTR wzBootstrapperApplicationPath, + __in int nCmdShow, + __in_z LPCWSTR wzPipeName, + __in_z LPCWSTR wzSecret, + __out HANDLE* phProcess +) +{ + HRESULT hr = S_OK; + LPWSTR sczParameters = NULL; + LPWSTR sczFullCommandLine = NULL; + PROCESS_INFORMATION pi = { }; + + hr = StrAllocFormatted(&sczParameters, L"-%ls %llu -%ls %ls %ls", BOOTSTRAPPER_APPLICATION_COMMANDLINE_SWITCH_API_VERSION, BOOTSTRAPPER_APPLICATION_API_VERSION, BOOTSTRAPPER_APPLICATION_COMMANDLINE_SWITCH_PIPE_NAME, wzPipeName, wzSecret); + ExitOnFailure(hr, "Failed to allocate parameters for bootstrapper application process."); + + hr = StrAllocFormattedSecure(&sczFullCommandLine, L"\"%ls\" %ls", wzBootstrapperApplicationPath, sczParameters); + ExitOnFailure(hr, "Failed to allocate full command-line for bootstrapper application process."); + + hr = CoreCreateProcess(wzBootstrapperApplicationPath, sczFullCommandLine, FALSE, 0, NULL, static_cast(nCmdShow), &pi); + ExitOnFailure(hr, "Failed to launch bootstrapper application process: %ls", sczFullCommandLine); + + *phProcess = pi.hProcess; + pi.hProcess = NULL; + +LExit: + ReleaseHandle(pi.hThread); + ReleaseHandle(pi.hProcess); + StrSecureZeroFreeString(sczFullCommandLine); + StrSecureZeroFreeString(sczParameters); + + return hr; +} + +static void Disconnect( + __in BURN_USER_EXPERIENCE* pUserExperience +) +{ + if (PipeRpcInitialized(&pUserExperience->hBARpcPipe)) + { + PipeWriteDisconnect(pUserExperience->hBARpcPipe.hPipe); + + PipeRpcUninitiailize(&pUserExperience->hBARpcPipe); + } +} + +static int FilterResult( + __in DWORD dwAllowedResults, + __in int nResult + ) +{ + if (IDNOACTION == nResult || IDERROR == nResult) // do nothing and errors pass through. + { + } + else + { + switch (dwAllowedResults) + { + case MB_OK: + nResult = IDOK; + break; + + case MB_OKCANCEL: + if (IDOK == nResult || IDYES == nResult) + { + nResult = IDOK; + } + else if (IDCANCEL == nResult || IDABORT == nResult || IDNO == nResult) + { + nResult = IDCANCEL; + } + else + { + nResult = IDNOACTION; + } + break; + + case MB_ABORTRETRYIGNORE: + if (IDCANCEL == nResult || IDABORT == nResult) + { + nResult = IDABORT; + } + else if (IDRETRY == nResult || IDTRYAGAIN == nResult) + { + nResult = IDRETRY; + } + else if (IDIGNORE == nResult) + { + nResult = IDIGNORE; + } + else + { + nResult = IDNOACTION; + } + break; + + case MB_YESNO: + if (IDOK == nResult || IDYES == nResult) + { + nResult = IDYES; + } + else if (IDCANCEL == nResult || IDABORT == nResult || IDNO == nResult) + { + nResult = IDNO; + } + else + { + nResult = IDNOACTION; + } + break; + + case MB_YESNOCANCEL: + if (IDOK == nResult || IDYES == nResult) + { + nResult = IDYES; + } + else if (IDNO == nResult) + { + nResult = IDNO; + } + else if (IDCANCEL == nResult || IDABORT == nResult) + { + nResult = IDCANCEL; + } + else + { + nResult = IDNOACTION; + } + break; + + case MB_RETRYCANCEL: + if (IDRETRY == nResult || IDTRYAGAIN == nResult) + { + nResult = IDRETRY; + } + else if (IDCANCEL == nResult || IDABORT == nResult) + { + nResult = IDABORT; + } + else + { + nResult = IDNOACTION; + } + break; + + case MB_CANCELTRYCONTINUE: + if (IDCANCEL == nResult || IDABORT == nResult) + { + nResult = IDABORT; + } + else if (IDRETRY == nResult || IDTRYAGAIN == nResult) + { + nResult = IDRETRY; + } + else if (IDCONTINUE == nResult || IDIGNORE == nResult) + { + nResult = IDCONTINUE; + } + else + { + nResult = IDNOACTION; + } + break; + + case BURN_MB_RETRYTRYAGAIN: // custom return code. + if (IDRETRY != nResult && IDTRYAGAIN != nResult) + { + nResult = IDNOACTION; + } + break; + + default: + AssertSz(FALSE, "Unknown allowed results."); + break; + } + } + + return nResult; +} + +static HRESULT WaitForBootstrapperApplicationConnect( + __in HANDLE hBAProcess, + __in HANDLE hBAPipe, + __in HANDLE hBAEnginePipe, + __in_z LPCWSTR wzSecret +) +{ + HRESULT hr = S_OK; + HANDLE hPipes[2] = { hBAPipe, hBAEnginePipe }; + + for (DWORD i = 0; i < countof(hPipes); ++i) + { + HANDLE hPipe = hPipes[i]; + + hr = PipeServerWaitForClientConnect(hBAProcess, hPipe); + ExitOnFailure(hr, "Failed to wait for bootstrapper application to connect to pipe."); + + hr = VerifyPipeSecret(hPipe, wzSecret); + ExitOnFailure(hr, "Failed to verify bootstrapper application pipe"); + } + +LExit: + return hr; +} + +static HRESULT VerifyPipeSecret( + __in HANDLE hPipe, + __in_z LPCWSTR wzSecret +) +{ + HRESULT hr = S_OK; + HRESULT hrResponse = S_OK; + LPWSTR sczVerificationSecret = NULL; + DWORD cbVerificationSecret = 0; + + // Read the verification secret. + hr = FileReadHandle(hPipe, reinterpret_cast(&cbVerificationSecret), sizeof(cbVerificationSecret)); + ExitOnFailure(hr, "Failed to read size of verification secret from bootstrapper application pipe."); + + if (255 < cbVerificationSecret / sizeof(WCHAR)) + { + hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + ExitOnRootFailure(hr, "Verification secret from bootstrapper application is too big."); + } + + hr = StrAlloc(&sczVerificationSecret, cbVerificationSecret / sizeof(WCHAR) + 1); + ExitOnFailure(hr, "Failed to allocate buffer for bootstrapper application verification secret."); + + FileReadHandle(hPipe, reinterpret_cast(sczVerificationSecret), cbVerificationSecret); + ExitOnFailure(hr, "Failed to read verification secret from bootstrapper application pipe."); + + // Verify the secrets match. + if (CSTR_EQUAL != ::CompareStringOrdinal(sczVerificationSecret, -1, wzSecret, -1, FALSE)) + { + hrResponse = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); + } + + // Send the response. + hr = FileWriteHandle(hPipe, reinterpret_cast(&hrResponse), sizeof(hrResponse)); + ExitOnFailure(hr, "Failed to write response to pipe."); + + if (FAILED(hrResponse)) + { + hr = hrResponse; + ExitOnRootFailure(hr, "Verification secret from bootstrapper application does not match."); + } + +LExit: + + ReleaseStr(sczVerificationSecret); + + return hr; +} diff --git a/src/burn/engine/bootstrapperapplication.h b/src/burn/engine/bootstrapperapplication.h new file mode 100644 index 00000000..c092fedf --- /dev/null +++ b/src/burn/engine/bootstrapperapplication.h @@ -0,0 +1,160 @@ +#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. + +#define BAAPI HRESULT __stdcall + +#if defined(__cplusplus) +extern "C" { +#endif + + +// constants + +const DWORD BURN_MB_RETRYTRYAGAIN = 0x10; +const DWORD64 BOOTSTRAPPER_APPLICATION_API_VERSION = MAKEQWORDVERSION(2024, 1, 1, 0); + + +// structs + +typedef struct _BURN_USER_EXPERIENCE +{ + BURN_PAYLOADS payloads; + + BURN_PAYLOAD* pPrimaryExePayload; + BURN_PAYLOAD* pSecondaryExePayload; + + //HMODULE hUXModule; + //PFN_BOOTSTRAPPER_APPLICATION_PROC pfnBAProc; + //LPVOID pvBAProcContext; + HANDLE hBAProcess; + PIPE_RPC_HANDLE hBARpcPipe; + BAENGINE_CONTEXT* pEngineContext; + + LPWSTR sczTempDirectory; + + CRITICAL_SECTION csEngineActive; // Changing the engine active state in the user experience must be + // syncronized through this critical section. + // Note: The engine must never do a UX callback while in this critical section. + + BOOL fEngineActive; // Indicates that the engine is currently active with one of the execution + // steps (detect, plan, apply), and cannot accept requests from the UX. + // This flag should be cleared by the engine prior to UX callbacks that + // allow altering of the engine state. + + HRESULT hrApplyError; // Tracks if an error occurs during apply that requires the cache or + // execute threads to bail. + + HWND hwndApply; // The window handle provided at the beginning of Apply(). Only valid + // during apply. + + HWND hwndDetect; // The window handle provided at the beginning of Detect(). Only valid + // during Detect. + + DWORD dwExitCode; // Exit code returned by the user experience for the engine overall. +} BURN_USER_EXPERIENCE; + + +// functions + +/******************************************************************* + BootstrapperApplicationParseFromXml - parses the bootstrapper application + data embedded in the bundle. + +*******************************************************************/ +HRESULT BootstrapperApplicationParseFromXml( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in IXMLDOMNode* pixnBundle +); + +/******************************************************************* + BootstrapperApplicationUninitialize - uninitializes the bootstrapper + application data. + +*******************************************************************/ +void BootstrapperApplicationUninitialize( + __in BURN_USER_EXPERIENCE* pUserExperience +); + +/******************************************************************* + BootstrapperApplicationStart - starts the bootstrapper application + process and creates the bootstrapper application in it. + +*******************************************************************/ +HRESULT BootstrapperApplicationStart( + __in BURN_ENGINE_STATE* pEngineState, + __in BOOL fSecondary +); + +/******************************************************************* + BootstrapperApplicationStop - destroys the bootstrapper application + in the bootstrapper application process, disconnects and waits + for the process to exit. + +*******************************************************************/ +HRESULT BootstrapperApplicationStop( + __in BURN_USER_EXPERIENCE* pUserExperience, + __inout BOOL* pfReload +); + +int BootstrapperApplicationCheckExecuteResult( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOL fRollback, + __in DWORD dwAllowedResults, + __in int nResult +); + +HRESULT BootstrapperApplicationInterpretExecuteResult( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOL fRollback, + __in DWORD dwAllowedResults, + __in int nResult +); + +HRESULT BootstrapperApplicationEnsureWorkingFolder( + __in BURN_CACHE* pCache, + __deref_out_z LPWSTR* psczUserExperienceWorkingFolder +); + +HRESULT BootstrapperApplicationRemove( + __in BURN_USER_EXPERIENCE* pUserExperience +); + +int BootstrapperApplicationSendError( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in BOOTSTRAPPER_ERROR_TYPE errorType, + __in_z_opt LPCWSTR wzPackageId, + __in HRESULT hrCode, + __in_z_opt LPCWSTR wzError, + __in DWORD uiFlags, + __in int nRecommendation +); + +void BootstrapperApplicationActivateEngine( + __in BURN_USER_EXPERIENCE* pUserExperience +); + +void BootstrapperApplicationDeactivateEngine( + __in BURN_USER_EXPERIENCE* pUserExperience +); + +/******************************************************************** + BootstrapperApplicationEnsureEngineInactive - Verifies the engine is inactive. + The caller MUST enter the csActive critical section before calling. + +*********************************************************************/ +HRESULT BootstrapperApplicationEnsureEngineInactive( + __in BURN_USER_EXPERIENCE* pUserExperience + ); + +void BootstrapperApplicationExecuteReset( + __in BURN_USER_EXPERIENCE* pUserExperience + ); + +void BootstrapperApplicationExecutePhaseComplete( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in HRESULT hrResult + ); + +#if defined(__cplusplus) +} +#endif diff --git a/src/burn/engine/bundlepackageengine.cpp b/src/burn/engine/bundlepackageengine.cpp index d3f59e5d..90262638 100644 --- a/src/burn/engine/bundlepackageengine.cpp +++ b/src/burn/engine/bundlepackageengine.cpp @@ -719,7 +719,7 @@ static BUNDLE_QUERY_CALLBACK_RESULT CALLBACK QueryRelatedBundlesCallback( result = BUNDLE_QUERY_CALLBACK_RESULT_CANCEL; // Pass to BA. - hr = UserExperienceOnDetectRelatedBundlePackage(pContext->pUserExperience, pPackage->sczId, pBundle->wzBundleId, relationType, fPerMachine, pVersion); + hr = BACallbackOnDetectRelatedBundlePackage(pContext->pUserExperience, pPackage->sczId, pBundle->wzBundleId, relationType, fPerMachine, pVersion); ExitOnRootFailure(hr, "BA aborted detect related BUNDLE package."); result = BUNDLE_QUERY_CALLBACK_RESULT_CONTINUE; diff --git a/src/burn/engine/burnpipe.cpp b/src/burn/engine/burnpipe.cpp index d106e7ae..25d602b1 100644 --- a/src/burn/engine/burnpipe.cpp +++ b/src/burn/engine/burnpipe.cpp @@ -305,7 +305,7 @@ extern "C" HRESULT BurnPipeWaitForChildConnect( { HANDLE hPipe = hPipes[i]; - hr = PipeServerWaitForClientConnect(hPipe); + hr = PipeServerWaitForClientConnect(pConnection->hProcess, hPipe); ExitOnRootFailure(hr, "Failed to wait for child to connect to pipe."); // Prove we are the one that created the elevated process by passing the secret. @@ -355,7 +355,7 @@ extern "C" HRESULT BurnPipeTerminateLoggingPipe( ExitOnFailure(hr, "Failed to post complete message to logging pipe."); LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -419,7 +419,7 @@ extern "C" HRESULT BurnPipeTerminateChildProcess( #endif LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } diff --git a/src/burn/engine/cache.cpp b/src/burn/engine/cache.cpp index 251cd24b..c0ac3ecd 100644 --- a/src/burn/engine/cache.cpp +++ b/src/burn/engine/cache.cpp @@ -2,7 +2,6 @@ #include "precomp.h" -static const LPCWSTR BUNDLE_CLEAN_ROOM_WORKING_FOLDER_NAME = L".cr"; static const LPCWSTR BUNDLE_WORKING_FOLDER_NAME = L".be"; static const LPCWSTR UNVERIFIED_CACHE_FOLDER_NAME = L".unverified"; static const LPCWSTR PACKAGE_CACHE_FOLDER_NAME = L"Package Cache"; @@ -242,8 +241,7 @@ LExit: extern "C" HRESULT CacheInitializeSources( __in BURN_CACHE* pCache, __in BURN_REGISTRATION* pRegistration, - __in BURN_VARIABLES* pVariables, - __in BURN_ENGINE_COMMAND* pInternalCommand + __in BURN_VARIABLES* pVariables ) { Assert(!pCache->fInitializedCacheSources); @@ -255,7 +253,6 @@ extern "C" HRESULT CacheInitializeSources( LPWSTR sczOriginalSource = NULL; LPWSTR sczOriginalSourceFolder = NULL; BOOL fPathEqual = FALSE; - LPCWSTR wzSourceProcessPath = pInternalCommand->sczSourceProcessPath; hr = PathForCurrentProcess(&sczCurrentPath, NULL); ExitOnFailure(hr, "Failed to get current process path."); @@ -272,15 +269,7 @@ extern "C" HRESULT CacheInitializeSources( pCache->fRunningFromCache = fPathEqual; - // If a source process path was not provided (e.g. we are not being - // run in a clean room) then use the current process path as the - // source process path. - if (!wzSourceProcessPath) - { - wzSourceProcessPath = sczCurrentPath; - } - - hr = PathGetDirectory(wzSourceProcessPath, &pCache->sczSourceProcessFolder); + hr = PathGetDirectory(sczCurrentPath, &pCache->sczSourceProcessFolder); ExitOnFailure(hr, "Failed to initialize cache source folder."); // If we're not running from the cache, ensure the original source is set. @@ -288,15 +277,14 @@ extern "C" HRESULT CacheInitializeSources( { // If the original source has not been set already then set it where the bundle is // running from right now. This value will be persisted and we'll use it when launched - // from the clean room or package cache since none of our packages will be relative to - // those locations. + // from the package cache since none of our packages will be relative to those locations. hr = VariableGetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE, &sczOriginalSource); if (E_NOTFOUND == hr) { - hr = VariableSetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE, wzSourceProcessPath, FALSE, FALSE); + hr = VariableSetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE, sczCurrentPath, FALSE, FALSE); ExitOnFailure(hr, "Failed to set original source variable."); - hr = StrAllocString(&sczOriginalSource, wzSourceProcessPath, 0); + hr = StrAllocString(&sczOriginalSource, sczCurrentPath, 0); ExitOnFailure(hr, "Failed to copy current path to original source."); } @@ -899,30 +887,6 @@ extern "C" HRESULT CachePreparePackage( return hr; } -extern "C" HRESULT CacheBundleToCleanRoom( - __in BURN_CACHE* pCache, - __in BURN_SECTION* pSection, - __deref_out_z_opt LPWSTR* psczCleanRoomBundlePath - ) -{ - HRESULT hr = S_OK; - LPWSTR sczSourcePath = NULL; - LPWSTR wzExecutableName = NULL; - - hr = PathForCurrentProcess(&sczSourcePath, NULL); - ExitOnFailure(hr, "Failed to get current path for process to cache to clean room."); - - wzExecutableName = PathFile(sczSourcePath); - - hr = CopyEngineToWorkingFolder(pCache, sczSourcePath, BUNDLE_CLEAN_ROOM_WORKING_FOLDER_NAME, wzExecutableName, pSection, psczCleanRoomBundlePath); - ExitOnFailure(hr, "Failed to cache bundle to clean room."); - -LExit: - ReleaseStr(sczSourcePath); - - return hr; -} - extern "C" HRESULT CacheBundleToWorkingDirectory( __in BURN_CACHE* pCache, __in_z LPCWSTR wzExecutableName, diff --git a/src/burn/engine/cache.h b/src/burn/engine/cache.h index cc28166e..3f0ba749 100644 --- a/src/burn/engine/cache.h +++ b/src/burn/engine/cache.h @@ -90,8 +90,7 @@ HRESULT CacheInitialize( HRESULT CacheInitializeSources( __in BURN_CACHE* pCache, __in BURN_REGISTRATION* pRegistration, - __in BURN_VARIABLES* pVariables, - __in BURN_ENGINE_COMMAND* pInternalCommand + __in BURN_VARIABLES* pVariables ); HRESULT CacheEnsureAcquisitionFolder( __in BURN_CACHE* pCache @@ -171,11 +170,6 @@ HRESULT CachePreparePackage( __in BURN_CACHE* pCache, __in BURN_PACKAGE* pPackage ); -HRESULT CacheBundleToCleanRoom( - __in BURN_CACHE* pCache, - __in BURN_SECTION* pSection, - __deref_out_z_opt LPWSTR* psczCleanRoomBundlePath - ); HRESULT CacheBundleToWorkingDirectory( __in BURN_CACHE* pCache, __in_z LPCWSTR wzExecutableName, diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index ca2e41c2..ae74fdfd 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp @@ -43,11 +43,6 @@ static HRESULT EscapeAndAppendArgumentToCommandLineFormattedArgs( __in __format_string LPCWSTR wzFormat, __in va_list args ); -static HRESULT AppendLayoutToCommandLine( - __in BOOTSTRAPPER_ACTION action, - __in_z LPCWSTR wzLayoutDirectory, - __deref_inout_z LPWSTR* psczCommandLine - ); static HRESULT GetSanitizedCommandLine( __in BURN_ENGINE_COMMAND* pInternalCommand, __in BOOTSTRAPPER_COMMAND* pCommand, @@ -151,18 +146,6 @@ extern "C" HRESULT CoreInitialize( ExitOnFailure(hr, "Failed to overwrite the bundle active parent built-in variable."); } - if (pEngineState->internalCommand.sczSourceProcessPath) - { - hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_SOURCE_PROCESS_PATH, pEngineState->internalCommand.sczSourceProcessPath, TRUE, FALSE); - ExitOnFailure(hr, "Failed to set source process path variable."); - - hr = PathGetDirectory(pEngineState->internalCommand.sczSourceProcessPath, &sczSourceProcessFolder); - ExitOnFailure(hr, "Failed to get source process folder from path."); - - hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER, sczSourceProcessFolder, TRUE, FALSE); - ExitOnFailure(hr, "Failed to set source process folder variable."); - } - // Set BURN_BUNDLE_ORIGINAL_SOURCE, if it was passed in on the command line. // Needs to be done after ManifestLoadXmlFromBuffer. if (pEngineState->internalCommand.sczOriginalSource) @@ -171,9 +154,9 @@ extern "C" HRESULT CoreInitialize( ExitOnFailure(hr, "Failed to set original source variable."); } - if (BURN_MODE_UNTRUSTED == pEngineState->internalCommand.mode || BURN_MODE_NORMAL == pEngineState->internalCommand.mode || BURN_MODE_EMBEDDED == pEngineState->internalCommand.mode) + if (BURN_MODE_NORMAL == pEngineState->internalCommand.mode || BURN_MODE_EMBEDDED == pEngineState->internalCommand.mode) { - hr = CacheInitializeSources(&pEngineState->cache, &pEngineState->registration, &pEngineState->variables, &pEngineState->internalCommand); + hr = CacheInitializeSources(&pEngineState->cache, &pEngineState->registration, &pEngineState->variables); ExitOnFailure(hr, "Failed to initialize internal cache source functionality."); } @@ -182,7 +165,7 @@ extern "C" HRESULT CoreInitialize( if (BURN_MODE_NORMAL == pEngineState->internalCommand.mode || BURN_MODE_EMBEDDED == pEngineState->internalCommand.mode) { // Extract all UX payloads to working folder. - hr = UserExperienceEnsureWorkingFolder(&pEngineState->cache, &pEngineState->userExperience.sczTempDirectory); + hr = BootstrapperApplicationEnsureWorkingFolder(&pEngineState->cache, &pEngineState->userExperience.sczTempDirectory); ExitOnFailure(hr, "Failed to get unique temporary folder for bootstrapper application."); hr = PayloadExtractUXContainer(&pEngineState->userExperience.payloads, &containerContext, pEngineState->userExperience.sczTempDirectory); @@ -297,7 +280,7 @@ extern "C" HRESULT CoreQueryRegistration( } LExit: - ReleaseBuffer(pbBuffer); + ReleaseMem(pbBuffer); return hr; } @@ -324,7 +307,7 @@ extern "C" HRESULT CoreDetect( ExitOnFailure(hr, "Failed to reset the dynamic registration variables during detect."); fDetectBegan = TRUE; - hr = UserExperienceOnDetectBegin(&pEngineState->userExperience, pEngineState->registration.fCached, pEngineState->registration.detectedRegistrationType, pEngineState->packages.cPackages); + hr = BACallbackOnDetectBegin(&pEngineState->userExperience, pEngineState->registration.fCached, pEngineState->registration.detectedRegistrationType, pEngineState->packages.cPackages); ExitOnRootFailure(hr, "UX aborted detect begin."); pEngineState->userExperience.hwndDetect = hwndParent; @@ -429,7 +412,7 @@ LExit: if (fDetectBegan) { - UserExperienceOnDetectComplete(&pEngineState->userExperience, hr, pEngineState->registration.fEligibleForCleanup); + BACallbackOnDetectComplete(&pEngineState->userExperience, hr, pEngineState->registration.fEligibleForCleanup); } pEngineState->userExperience.hwndDetect = NULL; @@ -453,7 +436,7 @@ extern "C" HRESULT CorePlan( LogId(REPORT_STANDARD, MSG_PLAN_BEGIN, pEngineState->packages.cPackages, LoggingBurnActionToString(action)); fPlanBegan = TRUE; - hr = UserExperienceOnPlanBegin(&pEngineState->userExperience, pEngineState->packages.cPackages); + hr = BACallbackOnPlanBegin(&pEngineState->userExperience, pEngineState->packages.cPackages); ExitOnRootFailure(hr, "BA aborted plan begin."); if (!pEngineState->fDetected) @@ -583,7 +566,7 @@ LExit: if (fPlanBegan) { - UserExperienceOnPlanComplete(&pEngineState->userExperience, hr); + BACallbackOnPlanComplete(&pEngineState->userExperience, hr); } LogId(REPORT_STANDARD, MSG_PLAN_COMPLETE, hr); @@ -674,13 +657,13 @@ extern "C" HRESULT CoreApply( ++dwPhaseCount; } - hr = UserExperienceOnApplyBegin(&pEngineState->userExperience, dwPhaseCount); + hr = BACallbackOnApplyBegin(&pEngineState->userExperience, dwPhaseCount); ExitOnRootFailure(hr, "BA aborted apply begin."); if (pEngineState->plan.fDowngrade) { hr = HRESULT_FROM_WIN32(ERROR_PRODUCT_VERSION); - UserExperienceOnApplyDowngrade(&pEngineState->userExperience, &hr); + BACallbackOnApplyDowngrade(&pEngineState->userExperience, &hr); ExitFunction(); } @@ -767,7 +750,7 @@ extern "C" HRESULT CoreApply( if (pEngineState->plan.cExecuteActions) { hr = ApplyExecute(pEngineState, &applyContext, &fSuspend, &restart); - UserExperienceExecutePhaseComplete(&pEngineState->userExperience, hr); // signal that execute completed. + BootstrapperApplicationExecutePhaseComplete(&pEngineState->userExperience, hr); // signal that execute completed. } // Wait for cache thread to terminate, this should return immediately unless we're waiting for layout to complete. @@ -847,7 +830,7 @@ LExit: if (fApplyBegan) { - UserExperienceOnApplyComplete(&pEngineState->userExperience, hr, restart, &applyCompleteAction); + BACallbackOnApplyComplete(&pEngineState->userExperience, hr, restart, &applyCompleteAction); if (BOOTSTRAPPER_APPLYCOMPLETE_ACTION_RESTART == applyCompleteAction) { pEngineState->fRestart = TRUE; @@ -869,7 +852,7 @@ extern "C" HRESULT CoreLaunchApprovedExe( LogId(REPORT_STANDARD, MSG_LAUNCH_APPROVED_EXE_BEGIN, pLaunchApprovedExe->sczId); - hr = UserExperienceOnLaunchApprovedExeBegin(&pEngineState->userExperience); + hr = BACallbackOnLaunchApprovedExeBegin(&pEngineState->userExperience); ExitOnRootFailure(hr, "BA aborted LaunchApprovedExe begin."); // Elevate. @@ -880,7 +863,7 @@ extern "C" HRESULT CoreLaunchApprovedExe( hr = ElevationLaunchApprovedExe(pEngineState->companionConnection.hPipe, pLaunchApprovedExe, &dwProcessId); LExit: - UserExperienceOnLaunchApprovedExeComplete(&pEngineState->userExperience, hr, dwProcessId); + BACallbackOnLaunchApprovedExeComplete(&pEngineState->userExperience, hr, dwProcessId); LogId(REPORT_STANDARD, MSG_LAUNCH_APPROVED_EXE_COMPLETE, hr, dwProcessId); @@ -888,7 +871,7 @@ LExit: } extern "C" void CoreQuit( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, + __in BAENGINE_CONTEXT* pEngineContext, __in DWORD dwExitCode ) { @@ -942,7 +925,7 @@ extern "C" HRESULT CoreSaveEngineState( } LExit: - ReleaseBuffer(pbBuffer); + ReleaseMem(pbBuffer); return hr; } @@ -1087,95 +1070,6 @@ LExit: return hr; } -extern "C" HRESULT CoreCreateCleanRoomCommandLine( - __deref_inout_z LPWSTR* psczCommandLine, - __in BURN_ENGINE_STATE* pEngineState, - __in_z LPCWSTR wzCleanRoomBundlePath, - __in_z LPCWSTR wzCurrentProcessPath, - __inout HANDLE* phFileAttached, - __inout HANDLE* phFileSelf - ) -{ - HRESULT hr = S_OK; - BOOTSTRAPPER_COMMAND* pCommand = &pEngineState->command; - BURN_ENGINE_COMMAND* pInternalCommand = &pEngineState->internalCommand; - - // The clean room switch must always be at the front of the command line so - // the EngineInCleanRoom function will operate correctly. - hr = StrAllocFormatted(psczCommandLine, L"-%ls=\"%ls\"", BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, wzCurrentProcessPath); - ExitOnFailure(hr, "Failed to allocate parameters for unelevated process."); - - // Send a file handle for the child Burn process to access the attached container. - hr = CoreAppendFileHandleAttachedToCommandLine(pEngineState->section.hEngineFile, phFileAttached, psczCommandLine); - ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED); - - // Grab a file handle for the child Burn process. - hr = CoreAppendFileHandleSelfToCommandLine(wzCleanRoomBundlePath, phFileSelf, psczCommandLine, NULL); - ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF); - - hr = CoreAppendSplashScreenWindowToCommandLine(pCommand->hwndSplashScreen, psczCommandLine); - ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN); - - if (pInternalCommand->sczLogFile) - { - LPCWSTR wzLogParameter = (BURN_LOGGING_ATTRIBUTE_EXTRADEBUG & pInternalCommand->dwLoggingAttributes) ? L"xlog" : L"log"; - hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", wzLogParameter); - ExitOnFailure(hr, "Failed to append logging switch."); - - hr = AppAppendCommandLineArgument(psczCommandLine, pInternalCommand->sczLogFile); - ExitOnFailure(hr, "Failed to append custom log path."); - } - - hr = AppendLayoutToCommandLine(pCommand->action, pCommand->wzLayoutDirectory, psczCommandLine); - ExitOnFailure(hr, "Failed to append layout."); - - switch (pInternalCommand->automaticUpdates) - { - case BURN_AU_PAUSE_ACTION_NONE: - hr = StrAllocConcat(psczCommandLine, L" /noaupause", 0); - ExitOnFailure(hr, "Failed to append /noaupause."); - break; - case BURN_AU_PAUSE_ACTION_IFELEVATED_NORESUME: - hr = StrAllocConcat(psczCommandLine, L" /keepaupaused", 0); - ExitOnFailure(hr, "Failed to append /keepaupaused."); - break; - } - - // TODO: This should only be added if it was enabled from the command line. - if (pInternalCommand->fDisableSystemRestore) - { - hr = StrAllocConcat(psczCommandLine, L" /disablesystemrestore", 0); - ExitOnFailure(hr, "Failed to append /disablesystemrestore."); - } - - if (pInternalCommand->sczOriginalSource) - { - hr = StrAllocConcat(psczCommandLine, L" /originalsource", 0); - ExitOnFailure(hr, "Failed to append /originalsource."); - - hr = AppAppendCommandLineArgument(psczCommandLine, pInternalCommand->sczOriginalSource); - ExitOnFailure(hr, "Failed to append original source."); - } - - if (pEngineState->embeddedConnection.sczName) - { - hr = StrAllocConcatFormatted(psczCommandLine, L" -%ls %ls %ls %u", BURN_COMMANDLINE_SWITCH_EMBEDDED, pEngineState->embeddedConnection.sczName, pEngineState->embeddedConnection.sczSecret, pEngineState->embeddedConnection.dwProcessId); - ExitOnFailure(hr, "Failed to allocate embedded command."); - } - - if (pInternalCommand->sczIgnoreDependencies) - { - hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, pInternalCommand->sczIgnoreDependencies); - ExitOnFailure(hr, "Failed to append ignored dependencies to command-line."); - } - - hr = CoreRecreateCommandLine(psczCommandLine, pCommand->action, pInternalCommand, pCommand, pCommand->relationType, pCommand->fPassthrough); - ExitOnFailure(hr, "Failed to recreate clean room command-line."); - -LExit: - return hr; -} - extern "C" HRESULT CoreCreatePassthroughBundleCommandLine( __deref_inout_z LPWSTR* psczCommandLine, __in BURN_ENGINE_COMMAND* pInternalCommand, @@ -1201,9 +1095,6 @@ extern "C" HRESULT CoreCreateResumeCommandLine( { HRESULT hr = S_OK; - hr = StrAllocFormatted(psczCommandLine, L"/%ls", BURN_COMMANDLINE_SWITCH_CLEAN_ROOM); - ExitOnFailure(hr, "Failed to alloc resume command-line."); - if (BURN_LOGGING_ATTRIBUTE_EXTRADEBUG & pPlan->pInternalCommand->dwLoggingAttributes) { hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_LOG_MODE, L"x"); @@ -1694,40 +1585,6 @@ extern "C" HRESULT CoreParseCommandLine( i += 2; } - else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_CLEAN_ROOM), BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, lstrlenW(BURN_COMMANDLINE_SWITCH_CLEAN_ROOM))) - { - if (0 != i) - { - fInvalidCommandLine = TRUE; - TraceLog(E_INVALIDARG, "Clean room command-line switch must be first argument on command-line."); - } - - if (BURN_MODE_UNKNOWN == pInternalCommand->mode) - { - pInternalCommand->mode = BURN_MODE_NORMAL; - } - else - { - fInvalidCommandLine = TRUE; - TraceLog(E_INVALIDARG, "Multiple mode command-line switches were provided."); - } - - // Get a pointer to the next character after the switch. - LPCWSTR wzParam = &argv[i][1 + lstrlenW(BURN_COMMANDLINE_SWITCH_CLEAN_ROOM)]; - if (L'\0' != wzParam[0]) - { - if (L'=' != wzParam[0]) - { - fInvalidCommandLine = TRUE; - TraceLog(E_INVALIDARG, "Invalid switch: %ls", argv[i]); - } - else if (L'\0' != wzParam[1]) - { - hr = PathExpand(&pInternalCommand->sczSourceProcessPath, wzParam + 1, PATH_EXPAND_FULLPATH); - ExitOnFailure(hr, "Failed to copy source process path."); - } - } - } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_SYSTEM_COMPONENT), BURN_COMMANDLINE_SWITCH_SYSTEM_COMPONENT, lstrlenW(BURN_COMMANDLINE_SWITCH_SYSTEM_COMPONENT))) { // Get a pointer to the next character after the switch. @@ -1762,13 +1619,7 @@ extern "C" HRESULT CoreParseCommandLine( switch (pInternalCommand->mode) { case BURN_MODE_UNKNOWN: - // Set mode to UNTRUSTED to ensure multiple modes weren't specified. - pInternalCommand->mode = BURN_MODE_UNTRUSTED; - break; case BURN_MODE_NORMAL: - // The initialization code already assumes that the - // clean room switch is at the beginning of the command line, - // so it's safe to assume that the mode is NORMAL in the clean room. pInternalCommand->mode = BURN_MODE_EMBEDDED; break; default: @@ -2012,7 +1863,7 @@ extern "C" HRESULT CoreParseCommandLine( if (BURN_MODE_UNKNOWN == pInternalCommand->mode) { - pInternalCommand->mode = BURN_MODE_UNTRUSTED; + pInternalCommand->mode = BURN_MODE_NORMAL; } LExit: @@ -2132,18 +1983,6 @@ LExit: return hr; } -extern "C" void DAPI CoreBootstrapperEngineActionUninitialize( - __in BOOTSTRAPPER_ENGINE_ACTION* pAction - ) -{ - switch (pAction->dwMessage) - { - case WM_BURN_LAUNCH_APPROVED_EXE: - ApprovedExesUninitializeLaunch(&pAction->launchApprovedExe); - break; - } -} - // internal helper functions static HRESULT AppendEscapedArgumentToCommandLine( @@ -2219,30 +2058,6 @@ LExit: return hr; } -static HRESULT AppendLayoutToCommandLine( - __in BOOTSTRAPPER_ACTION action, - __in_z LPCWSTR wzLayoutDirectory, - __deref_inout_z LPWSTR* psczCommandLine - ) -{ - HRESULT hr = S_OK; - - if (BOOTSTRAPPER_ACTION_LAYOUT == action || wzLayoutDirectory) - { - hr = StrAllocConcat(psczCommandLine, L" /layout", 0); - ExitOnFailure(hr, "Failed to append layout switch."); - - if (wzLayoutDirectory) - { - hr = AppAppendCommandLineArgument(psczCommandLine, wzLayoutDirectory); - ExitOnFailure(hr, "Failed to append layout directory."); - } - } - -LExit: - return hr; -} - static HRESULT GetSanitizedCommandLine( __in BURN_ENGINE_COMMAND* pInternalCommand, __in BOOTSTRAPPER_COMMAND* pCommand, @@ -2347,7 +2162,7 @@ static HRESULT DetectPackage( BOOL fBegan = FALSE; fBegan = TRUE; - hr = UserExperienceOnDetectPackageBegin(&pEngineState->userExperience, pPackage->sczId); + hr = BACallbackOnDetectPackageBegin(&pEngineState->userExperience, pPackage->sczId); ExitOnRootFailure(hr, "BA aborted detect package begin."); // Detect the cache state of the package. @@ -2389,7 +2204,7 @@ LExit: if (fBegan) { - UserExperienceOnDetectPackageComplete(&pEngineState->userExperience, pPackage->sczId, hr, pPackage->currentState, pPackage->fCached); + BACallbackOnDetectPackageComplete(&pEngineState->userExperience, pPackage->sczId, hr, pPackage->currentState, pPackage->fCached); } return hr; @@ -2465,7 +2280,7 @@ static DWORD WINAPI CacheThreadProc( hr = ApplyCache(pEngineState->section.hSourceEngineFile, &pEngineState->userExperience, &pEngineState->variables, &pEngineState->plan, pEngineState->companionConnection.hCachePipe, pContext->pApplyContext); LExit: - UserExperienceExecutePhaseComplete(&pEngineState->userExperience, hr); // signal that cache completed. + BootstrapperApplicationExecutePhaseComplete(&pEngineState->userExperience, hr); // signal that cache completed. if (fComInitialized) { diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h index 1e672651..787100b7 100644 --- a/src/burn/engine/core.h +++ b/src/burn/engine/core.h @@ -13,7 +13,6 @@ const LPCWSTR BURN_POLICY_REGISTRY_PATH = L"WiX\\Burn"; const LPCWSTR BURN_COMMANDLINE_SWITCH_PARENT = L"parent"; const LPCWSTR BURN_COMMANDLINE_SWITCH_PARENT_NONE = L"parent:none"; -const LPCWSTR BURN_COMMANDLINE_SWITCH_CLEAN_ROOM = L"burn.clean.room"; const LPCWSTR BURN_COMMANDLINE_SWITCH_WORKING_DIRECTORY = L"burn.engine.working.directory"; const LPCWSTR BURN_COMMANDLINE_SWITCH_ELEVATED = L"burn.elevated"; const LPCWSTR BURN_COMMANDLINE_SWITCH_EMBEDDED = L"burn.embedded"; @@ -47,8 +46,6 @@ const LPCWSTR BURN_BUNDLE_FORCED_RESTART_PACKAGE = L"WixBundleForcedRestartPacka const LPCWSTR BURN_BUNDLE_INSTALLED = L"WixBundleInstalled"; const LPCWSTR BURN_BUNDLE_ELEVATED = L"WixBundleElevated"; const LPCWSTR BURN_BUNDLE_PROVIDER_KEY = L"WixBundleProviderKey"; -const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_PATH = L"WixBundleSourceProcessPath"; -const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_FOLDER = L"WixBundleSourceProcessFolder"; const LPCWSTR BURN_BUNDLE_TAG = L"WixBundleTag"; const LPCWSTR BURN_BUNDLE_UILEVEL = L"WixBundleUILevel"; const LPCWSTR BURN_BUNDLE_VERSION = L"WixBundleVersion"; @@ -68,7 +65,6 @@ const LPCWSTR BURN_BUNDLE_LAST_USED_SOURCE = L"WixBundleLastUsedSource"; enum BURN_MODE { BURN_MODE_UNKNOWN, - BURN_MODE_UNTRUSTED, BURN_MODE_NORMAL, BURN_MODE_ELEVATED, BURN_MODE_EMBEDDED, @@ -115,7 +111,6 @@ typedef struct _BURN_ENGINE_COMMAND LPWSTR sczAncestors; LPWSTR sczIgnoreDependencies; - LPWSTR sczSourceProcessPath; LPWSTR sczOriginalSource; LPWSTR sczEngineWorkingDirectory; @@ -263,7 +258,7 @@ HRESULT CoreLaunchApprovedExe( __in BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe ); void CoreQuit( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, + __in BAENGINE_CONTEXT* pEngineContext, __in DWORD dwExitCode ); HRESULT CoreSaveEngineState( @@ -272,14 +267,6 @@ HRESULT CoreSaveEngineState( LPCWSTR CoreRelationTypeToCommandLineString( __in BOOTSTRAPPER_RELATION_TYPE relationType ); -HRESULT CoreCreateCleanRoomCommandLine( - __deref_inout_z LPWSTR* psczCommandLine, - __in BURN_ENGINE_STATE* pEngineState, - __in_z LPCWSTR wzCleanRoomBundlePath, - __in_z LPCWSTR wzCurrentProcessPath, - __inout HANDLE* phFileAttached, - __inout HANDLE* phFileSelf - ); HRESULT CoreCreatePassthroughBundleCommandLine( __deref_inout_z LPWSTR* psczCommandLine, __in BURN_ENGINE_COMMAND* pInternalCommand, @@ -361,9 +348,6 @@ HRESULT DAPI CoreCloseElevatedLoggingThread( HRESULT DAPI CoreWaitForUnelevatedLoggingThread( __in HANDLE hUnelevatedLoggingThread ); -void DAPI CoreBootstrapperEngineActionUninitialize( - __in BOOTSTRAPPER_ENGINE_ACTION* pAction - ); #if defined(__cplusplus) } diff --git a/src/burn/engine/detect.cpp b/src/burn/engine/detect.cpp index f573e259..18820c5d 100644 --- a/src/burn/engine/detect.cpp +++ b/src/burn/engine/detect.cpp @@ -143,7 +143,7 @@ extern "C" HRESULT DetectForwardCompatibleBundles( pRegistration->fForwardCompatibleBundleExists = TRUE; } - hr = UserExperienceOnDetectForwardCompatibleBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->detectRelationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, !pRelatedBundle->package.fCached); + hr = BACallbackOnDetectForwardCompatibleBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->detectRelationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, !pRelatedBundle->package.fCached); ExitOnRootFailure(hr, "BA aborted detect forward compatible bundle."); LogId(REPORT_STANDARD, MSG_DETECTED_FORWARD_COMPATIBLE_BUNDLE, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->detectRelationType), LoggingPerMachineToString(pRelatedBundle->package.fPerMachine), pRelatedBundle->pVersion->sczVersion, LoggingBoolToString(pRelatedBundle->package.fCached)); @@ -174,7 +174,7 @@ extern "C" HRESULT DetectReportRelatedBundles( LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_BUNDLE, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->detectRelationType), LoggingPerMachineToString(pRelatedBundle->package.fPerMachine), pRelatedBundle->pVersion->sczVersion, LoggingBoolToString(pRelatedBundle->package.fCached)); - hr = UserExperienceOnDetectRelatedBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->detectRelationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, !pRelatedBundle->package.fCached); + hr = BACallbackOnDetectRelatedBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->detectRelationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, !pRelatedBundle->package.fCached); ExitOnRootFailure(hr, "BA aborted detect related bundle."); // For now, if any related bundles will be executed during uninstall by default then never automatically clean up the bundle. @@ -223,7 +223,7 @@ extern "C" HRESULT DetectUpdate( hr = StrAllocString(&sczOriginalSource, pUpdate->sczUpdateSource, 0); ExitOnFailure(hr, "Failed to duplicate update feed source."); - hr = UserExperienceOnDetectUpdateBegin(pUX, sczOriginalSource, &fSkip); + hr = BACallbackOnDetectUpdateBegin(pUX, sczOriginalSource, &fSkip); ExitOnRootFailure(hr, "BA aborted detect update begin."); if (!fSkip) @@ -237,7 +237,7 @@ LExit: if (fBeginCalled) { - UserExperienceOnDetectUpdateComplete(pUX, hr, &fIgnoreError); + BACallbackOnDetectUpdateComplete(pUX, hr, &fIgnoreError); if (fIgnoreError) { hr = S_OK; @@ -270,8 +270,8 @@ static HRESULT WINAPI AuthenticationRequired( hr = StrAllocFromError(&sczError, HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED), NULL); ExitOnFailure(hr, "Failed to allocation error string."); - UserExperienceOnError(pAuthenticationData->pUX, errorType, pAuthenticationData->wzPackageOrContainerId, ERROR_ACCESS_DENIED, sczError, MB_RETRYCANCEL, 0, NULL, &nResult); // ignore return value. - nResult = UserExperienceCheckExecuteResult(pAuthenticationData->pUX, FALSE, BURN_MB_RETRYTRYAGAIN, nResult); + BACallbackOnError(pAuthenticationData->pUX, errorType, pAuthenticationData->wzPackageOrContainerId, ERROR_ACCESS_DENIED, sczError, MB_RETRYCANCEL, 0, NULL, &nResult); // ignore return value. + nResult = BootstrapperApplicationCheckExecuteResult(pAuthenticationData->pUX, FALSE, BURN_MB_RETRYTRYAGAIN, nResult); if (IDTRYAGAIN == nResult && pAuthenticationData->pUX->hwndDetect) { er = ::InternetErrorDlg(pAuthenticationData->pUX->hwndDetect, hUrl, ERROR_INTERNET_INCORRECT_PASSWORD, FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA, NULL); @@ -356,6 +356,7 @@ LExit: ReleaseStr(downloadSource.sczUrl); ReleaseStr(downloadSource.sczUser); ReleaseStr(downloadSource.sczPassword); + ReleaseStr(downloadSource.sczAuthorizationHeader); ReleaseStr(sczUpdateId); ReleaseStr(sczError); return hr; @@ -411,7 +412,7 @@ static HRESULT DetectAtomFeedUpdate( hashType = BOOTSTRAPPER_UPDATE_HASH_TYPE_SHA512; } - hr = UserExperienceOnDetectUpdate(pUX, + hr = BACallbackOnDetectUpdate(pUX, pEnclosure ? pEnclosure->wzUrl : NULL, pEnclosure ? pEnclosure->dw64Size : 0, wzHash, diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp index f357a8fc..924d2184 100644 --- a/src/burn/engine/elevation.cpp +++ b/src/burn/engine/elevation.cpp @@ -420,7 +420,7 @@ extern "C" HRESULT ElevationElevate( HRESULT hr = S_OK; int nResult = IDOK; - hr = UserExperienceOnElevateBegin(&pEngineState->userExperience); + hr = BACallbackOnElevateBegin(&pEngineState->userExperience); ExitOnRootFailure(hr, "BA aborted elevation requirement."); hr = BurnPipeCreateNameAndSecret(&pEngineState->companionConnection.sczName, &pEngineState->companionConnection.sczSecret); @@ -458,7 +458,7 @@ extern "C" HRESULT ElevationElevate( hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); } - nResult = UserExperienceSendError(&pEngineState->userExperience, BOOTSTRAPPER_ERROR_TYPE_ELEVATE, NULL, hr, NULL, MB_ICONERROR | MB_RETRYCANCEL, IDNOACTION); + nResult = BootstrapperApplicationSendError(&pEngineState->userExperience, BOOTSTRAPPER_ERROR_TYPE_ELEVATE, NULL, hr, NULL, MB_ICONERROR | MB_RETRYCANCEL, IDNOACTION); } } while (IDRETRY == nResult); ExitOnFailure(hr, "Failed to elevate."); @@ -469,7 +469,7 @@ LExit: BurnPipeConnectionUninitialize(&pEngineState->companionConnection); } - UserExperienceOnElevateComplete(&pEngineState->userExperience, hr); + BACallbackOnElevateComplete(&pEngineState->userExperience, hr); return hr; } @@ -511,15 +511,15 @@ extern "C" HRESULT ElevationApplyInitialize( // Best effort to keep the sequence of BA events sane. if (context.fPauseCompleteNeeded) { - UserExperienceOnPauseAUComplete(pBA, hr); + BACallbackOnPauseAUComplete(pBA, hr); } if (context.fSrpCompleteNeeded) { - UserExperienceOnSystemRestorePointComplete(pBA, hr); + BACallbackOnSystemRestorePointComplete(pBA, hr); } LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -540,7 +540,7 @@ extern "C" HRESULT ElevationApplyUninitialize( hr = (HRESULT)dwResult; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -598,7 +598,7 @@ extern "C" HRESULT ElevationSessionBegin( hr = (HRESULT)dwResult; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -644,7 +644,7 @@ extern "C" HRESULT ElevationSessionEnd( hr = (HRESULT)dwResult; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -693,7 +693,7 @@ extern "C" HRESULT ElevationCachePreparePackage( hr = (HRESULT)dwResult; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -743,7 +743,7 @@ extern "C" HRESULT ElevationCacheCompletePayload( hr = (HRESULT)dwResult; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -781,7 +781,7 @@ extern "C" HRESULT ElevationCacheVerifyPayload( hr = (HRESULT)dwResult; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -834,7 +834,7 @@ extern "C" HRESULT ElevationProcessDependentRegistration( hr = (HRESULT)dwResult; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -895,7 +895,7 @@ extern "C" HRESULT ElevationExecuteRelatedBundle( *pRestart = context.restart; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -959,7 +959,7 @@ extern "C" HRESULT ElevationExecuteBundlePackage( *pRestart = context.restart; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -1014,7 +1014,7 @@ extern "C" HRESULT ElevationExecuteExePackage( *pRestart = context.restart; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -1042,7 +1042,7 @@ extern "C" HRESULT ElevationMsiBeginTransaction( hr = static_cast(dwResult); LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -1079,7 +1079,7 @@ extern "C" HRESULT ElevationMsiCommitTransaction( *pRestart = context.restart; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -1116,7 +1116,7 @@ extern "C" HRESULT ElevationMsiRollbackTransaction( *pRestart = context.restart; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -1203,7 +1203,7 @@ extern "C" HRESULT ElevationExecuteMsiPackage( *pRestart = context.restart; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -1283,7 +1283,7 @@ extern "C" HRESULT ElevationExecuteMspPackage( *pRestart = context.restart; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -1335,7 +1335,7 @@ extern "C" HRESULT ElevationExecuteMsuPackage( *pRestart = context.restart; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -1388,7 +1388,7 @@ extern "C" HRESULT ElevationUninstallMsiCompatiblePackage( *pRestart = context.restart; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -1425,7 +1425,7 @@ extern "C" HRESULT ElevationExecutePackageProviderAction( ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_PROVIDER message to per-machine process."); LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -1465,7 +1465,7 @@ extern "C" HRESULT ElevationExecutePackageDependencyAction( ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_DEPENDENCY message to per-machine process."); LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -1494,7 +1494,7 @@ extern "C" HRESULT ElevationCleanCompatiblePackage( hr = (HRESULT)dwResult; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -1524,7 +1524,7 @@ extern "C" HRESULT ElevationCleanPackage( hr = (HRESULT)dwResult; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -1559,7 +1559,7 @@ extern "C" HRESULT ElevationLaunchApprovedExe( *pdwProcessId = context.dwProcessId; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -1756,7 +1756,7 @@ static HRESULT ProcessApplyInitializeMessages( { case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN: pContext->fPauseCompleteNeeded = TRUE; - hrBA = UserExperienceOnPauseAUBegin(pContext->pBA); + hrBA = BACallbackOnPauseAUBegin(pContext->pBA); break; case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE: @@ -1765,18 +1765,18 @@ static HRESULT ProcessApplyInitializeMessages( ExitOnFailure(hr, "Failed to read pause AU hrStatus."); pContext->fPauseCompleteNeeded = FALSE; - hrBA = UserExperienceOnPauseAUComplete(pContext->pBA, hrStatus); + hrBA = BACallbackOnPauseAUComplete(pContext->pBA, hrStatus); break; case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_BEGIN: if (pContext->fPauseCompleteNeeded) { pContext->fPauseCompleteNeeded = FALSE; - hrBA = UserExperienceOnPauseAUComplete(pContext->pBA, E_INVALIDSTATE); + hrBA = BACallbackOnPauseAUComplete(pContext->pBA, E_INVALIDSTATE); } pContext->fSrpCompleteNeeded = TRUE; - hrBA = UserExperienceOnSystemRestorePointBegin(pContext->pBA); + hrBA = BACallbackOnSystemRestorePointBegin(pContext->pBA); break; case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE: @@ -1785,7 +1785,7 @@ static HRESULT ProcessApplyInitializeMessages( ExitOnFailure(hr, "Failed to read system restore point hrStatus."); pContext->fSrpCompleteNeeded = FALSE; - hrBA = UserExperienceOnSystemRestorePointComplete(pContext->pBA, hrStatus); + hrBA = BACallbackOnSystemRestorePointComplete(pContext->pBA, hrStatus); break; default: @@ -1930,7 +1930,7 @@ static HRESULT ProcessGenericExecuteMessages( ExitOnFailure(hr, "Failed to read error code."); hr = BuffReadString((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &sczMessage); - ExitOnFailure(hr, "Failed to read message."); + ExitOnFailure(hr, "Failed to read error message."); message.error.wzMessage = sczMessage; break; @@ -2042,7 +2042,7 @@ static HRESULT ProcessMsiPackageMessages( ExitOnFailure(hr, "Failed to read error code."); hr = BuffReadString((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &sczMessage); - ExitOnFailure(hr, "Failed to read message."); + ExitOnFailure(hr, "Failed to read MSI execute error message."); message.error.wzMessage = sczMessage; break; @@ -2051,10 +2051,10 @@ static HRESULT ProcessMsiPackageMessages( message.type = WIU_MSI_EXECUTE_MESSAGE_MSI_MESSAGE; hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, (DWORD*)&message.msiMessage.mt); - ExitOnFailure(hr, "Failed to read message type."); + ExitOnFailure(hr, "Failed to read MSI execute message type."); hr = BuffReadString((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &sczMessage); - ExitOnFailure(hr, "Failed to read message."); + ExitOnFailure(hr, "Failed to read MSI execute message."); message.msiMessage.wzMessage = sczMessage; break; @@ -3558,7 +3558,7 @@ static HRESULT CALLBACK BurnCacheMessageHandler( hr = dwResult; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -3593,7 +3593,7 @@ static DWORD CALLBACK ElevatedProgressRoutine( ExitOnFailure(hr, "Failed to send progress routine message to per-user process."); LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return dwResult; } @@ -3668,7 +3668,7 @@ static int GenericExecuteMessageHandler( ExitOnFailure(hr, "Failed to send message to per-user process."); LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return nResult; } @@ -3747,7 +3747,7 @@ static int MsiExecuteMessageHandler( default: hr = E_UNEXPECTED; - ExitOnFailure(hr, "Invalid message type: %d", pMessage->type); + ExitOnFailure(hr, "Invalid MSI execute message type: %d", pMessage->type); } // send message @@ -3755,7 +3755,7 @@ static int MsiExecuteMessageHandler( ExitOnFailure(hr, "Failed to send msi message to per-user process."); LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return nResult; } @@ -3895,7 +3895,7 @@ static HRESULT OnLaunchApprovedExe( ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE_PROCESSID message to per-user process."); LExit: - ReleaseBuffer(pbSendData); + ReleaseMem(pbSendData); ApprovedExesUninitializeLaunch(pLaunchApprovedExe); return hr; } @@ -4056,7 +4056,7 @@ static HRESULT ElevatedOnPauseAUComplete( ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE message to per-user process."); LExit: - ReleaseBuffer(pbSendData); + ReleaseMem(pbSendData); return hr; } @@ -4092,7 +4092,7 @@ static HRESULT ElevatedOnSystemRestorePointComplete( ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE message to per-user process."); LExit: - ReleaseBuffer(pbSendData); + ReleaseMem(pbSendData); return hr; } @@ -4114,7 +4114,7 @@ static HRESULT ElevatedOnExecuteActionComplete( ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ACTION_COMPLETE message to per-user process."); LExit: - ReleaseBuffer(pbSendData); + ReleaseMem(pbSendData); return hr; } diff --git a/src/burn/engine/engine.cpp b/src/burn/engine/engine.cpp index f5ea5332..9daa18a1 100644 --- a/src/burn/engine/engine.cpp +++ b/src/burn/engine/engine.cpp @@ -16,9 +16,11 @@ static HRESULT InitializeEngineState( static void UninitializeEngineState( __in BURN_ENGINE_STATE* pEngineState ); +#if 0 static HRESULT RunUntrusted( __in BURN_ENGINE_STATE* pEngineState ); +#endif static HRESULT RunNormal( __in HINSTANCE hInstance, __in BURN_ENGINE_STATE* pEngineState @@ -38,12 +40,13 @@ static HRESULT RunRunOnce( ); static HRESULT RunApplication( __in BURN_ENGINE_STATE* pEngineState, + __in BOOL fSecondaryBootstrapperApplication, __out BOOL* pfReloadApp, __out BOOL* pfSkipCleanup ); static HRESULT ProcessMessage( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, - __in BOOTSTRAPPER_ENGINE_ACTION* pAction + __in BAENGINE_CONTEXT* pEngineContext, + __in BAENGINE_ACTION* pAction ); static HRESULT DAPI RedirectLoggingOverPipe( __in_z LPCSTR szString, @@ -72,28 +75,6 @@ static void CALLBACK BurnTraceError( // function definitions -extern "C" BOOL EngineInCleanRoom( - __in_z_opt LPCWSTR wzCommandLine - ) -{ - // Be very careful with the functions you call from here. - // This function will be called before ::SetDefaultDllDirectories() - // has been called so dependencies outside of kernel32.dll are - // very likely to introduce DLL hijacking opportunities. - - static DWORD cchCleanRoomSwitch = lstrlenW(BURN_COMMANDLINE_SWITCH_CLEAN_ROOM); - - // This check is wholly dependent on the clean room command line switch being - // present at the beginning of the command line. Since Burn is the only thing - // that should be setting this command line option, that is in our control. - BOOL fInCleanRoom = (wzCommandLine && - (wzCommandLine[0] == L'-' || wzCommandLine[0] == L'/') && - CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, wzCommandLine + 1, cchCleanRoomSwitch, BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, cchCleanRoomSwitch) - ); - - return fInCleanRoom; -} - extern "C" HRESULT EngineRun( __in HINSTANCE hInstance, __in HANDLE hEngineFile, @@ -113,7 +94,6 @@ extern "C" HRESULT EngineRun( SYSTEM_INFO si = { }; RTL_OSVERSIONINFOEXW ovix = { }; LPWSTR sczExePath = NULL; - BOOL fRunUntrusted = FALSE; BOOL fRunNormal = FALSE; BOOL fRunElevated = FALSE; BOOL fRunRunOnce = FALSE; @@ -214,25 +194,18 @@ extern "C" HRESULT EngineRun( // Select run mode. switch (engineState.internalCommand.mode) { - case BURN_MODE_UNTRUSTED: - fRunUntrusted = TRUE; - - hr = RunUntrusted(&engineState); - ExitOnFailure(hr, "Failed to run untrusted mode."); - break; - case BURN_MODE_NORMAL: fRunNormal = TRUE; hr = RunNormal(hInstance, &engineState); - ExitOnFailure(hr, "Failed to run per-user mode."); + ExitOnFailure(hr, "Failed to run normal mode."); break; case BURN_MODE_ELEVATED: fRunElevated = TRUE; hr = RunElevated(hInstance, wzCommandLine, &engineState); - ExitOnFailure(hr, "Failed to run per-machine mode."); + ExitOnFailure(hr, "Failed to run elevated mode."); break; case BURN_MODE_EMBEDDED: @@ -266,7 +239,7 @@ LExit: LoggingOpenFailed(); } - UserExperienceRemove(&engineState.userExperience); + BootstrapperApplicationRemove(&engineState.userExperience); CacheRemoveBaseWorkingFolder(&engineState.cache); CacheUninitialize(&engineState.cache); @@ -284,10 +257,6 @@ LExit: { LogId(REPORT_STANDARD, MSG_EXITING, FAILED(hr) ? (int)hr : *pdwExitCode, LoggingBoolToString(engineState.fRestart)); } - else if (fRunUntrusted) - { - LogId(REPORT_STANDARD, MSG_EXITING_CLEAN_ROOM, FAILED(hr) ? (int)hr : *pdwExitCode); - } else if (fRunRunOnce) { LogId(REPORT_STANDARD, MSG_EXITING_RUN_ONCE, FAILED(hr) ? (int)hr : *pdwExitCode); @@ -452,7 +421,7 @@ static void UninitializeEngineState( BurnExtensionUninitialize(&pEngineState->extensions); ::DeleteCriticalSection(&pEngineState->userExperience.csEngineActive); - UserExperienceUninitialize(&pEngineState->userExperience); + BootstrapperApplicationUninitialize(&pEngineState->userExperience); ApprovedExesUninitialize(&pEngineState->approvedExes); DependencyUninitialize(&pEngineState->dependencies); @@ -475,7 +444,6 @@ static void UninitializeEngineState( ReleaseStr(pEngineState->internalCommand.sczIgnoreDependencies); ReleaseStr(pEngineState->internalCommand.sczLogFile); ReleaseStr(pEngineState->internalCommand.sczOriginalSource); - ReleaseStr(pEngineState->internalCommand.sczSourceProcessPath); ReleaseStr(pEngineState->internalCommand.sczEngineWorkingDirectory); ReleaseStr(pEngineState->log.sczExtension); @@ -489,82 +457,6 @@ static void UninitializeEngineState( memset(pEngineState, 0, sizeof(BURN_ENGINE_STATE)); } -static HRESULT RunUntrusted( - __in BURN_ENGINE_STATE* pEngineState - ) -{ - HRESULT hr = S_OK; - LPWSTR sczCurrentProcessPath = NULL; - LPWSTR wzCleanRoomBundlePath = NULL; - LPWSTR sczCachedCleanRoomBundlePath = NULL; - LPWSTR sczParameters = NULL; - LPWSTR sczFullCommandLine = NULL; - PROCESS_INFORMATION pi = { }; - HANDLE hFileAttached = NULL; - HANDLE hFileSelf = NULL; - HANDLE hProcess = NULL; - - // Initialize logging. - hr = LoggingOpen(&pEngineState->log, &pEngineState->internalCommand, &pEngineState->command, &pEngineState->variables, pEngineState->registration.sczDisplayName); - ExitOnFailure(hr, "Failed to open clean room log."); - - hr = PathForCurrentProcess(&sczCurrentProcessPath, NULL); - ExitOnFailure(hr, "Failed to get path for current process."); - - // If we're running from the package cache, we're in a secure - // folder (DLLs cannot be inserted here for hijacking purposes) - // so just launch the current process's path as the clean room - // process. Technically speaking, we'd be able to skip creating - // a clean room process at all (since we're already running from - // a secure folder) but it makes the code that only wants to run - // in clean room more complicated if we don't launch an explicit - // clean room process. - if (CacheBundleRunningFromCache(&pEngineState->cache)) - { - wzCleanRoomBundlePath = sczCurrentProcessPath; - } - else - { - hr = CacheBundleToCleanRoom(&pEngineState->cache, &pEngineState->section, &sczCachedCleanRoomBundlePath); - ExitOnFailure(hr, "Failed to cache to clean room."); - - wzCleanRoomBundlePath = sczCachedCleanRoomBundlePath; - } - - hr = CoreCreateCleanRoomCommandLine(&sczParameters, pEngineState, wzCleanRoomBundlePath, sczCurrentProcessPath, &hFileAttached, &hFileSelf); - ExitOnFailure(hr, "Failed to create clean room command-line."); - - hr = StrAllocFormattedSecure(&sczFullCommandLine, L"\"%ls\" %ls", wzCleanRoomBundlePath, sczParameters); - ExitOnFailure(hr, "Failed to allocate full command-line."); - - hr = CoreCreateProcess(wzCleanRoomBundlePath, sczFullCommandLine, TRUE, 0, NULL, static_cast(pEngineState->command.nCmdShow), &pi); - ExitOnFailure(hr, "Failed to launch clean room process: %ls", sczFullCommandLine); - - hProcess = pi.hProcess; - pi.hProcess = NULL; - - hr = ProcWaitForCompletion(hProcess, INFINITE, &pEngineState->userExperience.dwExitCode); - ExitOnFailure(hr, "Failed to wait for clean room process: %ls", wzCleanRoomBundlePath); - -LExit: - // If the splash screen is still around, close it. - if (::IsWindow(pEngineState->command.hwndSplashScreen)) - { - ::PostMessageW(pEngineState->command.hwndSplashScreen, WM_CLOSE, 0, 0); - } - - ReleaseHandle(pi.hThread); - ReleaseFileHandle(hFileSelf); - ReleaseFileHandle(hFileAttached); - ReleaseHandle(hProcess); - StrSecureZeroFreeString(sczFullCommandLine); - StrSecureZeroFreeString(sczParameters); - ReleaseStr(sczCachedCleanRoomBundlePath); - ReleaseStr(sczCurrentProcessPath); - - return hr; -} - static HRESULT RunNormal( __in HINSTANCE hInstance, __in BURN_ENGINE_STATE* pEngineState @@ -574,9 +466,10 @@ static HRESULT RunNormal( LPWSTR sczOriginalSource = NULL; LPWSTR sczCopiedOriginalSource = NULL; BOOL fContinueExecution = TRUE; - BOOL fReloadApp = FALSE; + BOOL fReloadApp = TRUE; BOOL fSkipCleanup = FALSE; BURN_EXTENSION_ENGINE_CONTEXT extensionEngineContext = { }; + BOOL fRunSecondaryBootstrapperApplication = FALSE; // Initialize logging. hr = LoggingOpen(&pEngineState->log, &pEngineState->internalCommand, &pEngineState->command, &pEngineState->variables, pEngineState->registration.sczDisplayName); @@ -644,14 +537,27 @@ static HRESULT RunNormal( hr = BurnExtensionLoad(&pEngineState->extensions, &extensionEngineContext); ExitOnFailure(hr, "Failed to load BundleExtensions."); - do + // The secondary bootstrapper application only gets one chance to execute. That means + // first time through we run the primary bootstrapper application and on reload we run + // the secondary bootstrapper application, and if the secondary bootstrapper application + // requests a reload, we load the primary bootstrapper application one last time. + for (DWORD i = 0; i < 3 && fReloadApp; i++) { fReloadApp = FALSE; pEngineState->fQuit = FALSE; - hr = RunApplication(pEngineState, &fReloadApp, &fSkipCleanup); - ExitOnFailure(hr, "Failed while running "); - } while (fReloadApp); + hr = RunApplication(pEngineState, fRunSecondaryBootstrapperApplication, &fReloadApp, &fSkipCleanup); + + // If reloading, switch to the other bootstrapper application. + if (fReloadApp) + { + fRunSecondaryBootstrapperApplication = !fRunSecondaryBootstrapperApplication; + } + else if (FAILED(hr)) + { + break; + } + } LExit: if (!fSkipCleanup) @@ -790,73 +696,64 @@ LExit: return hr; } -static void CALLBACK FreeQueueItem( - __in void* pvValue, - __in void* /*pvContext*/ - ) -{ - BOOTSTRAPPER_ENGINE_ACTION* pAction = reinterpret_cast(pvValue); - - LogId(REPORT_WARNING, MSG_IGNORE_OPERATION_AFTER_QUIT, LoggingBurnMessageToString(pAction->dwMessage)); - - CoreBootstrapperEngineActionUninitialize(pAction); - MemFree(pAction); -} - static HRESULT RunApplication( __in BURN_ENGINE_STATE* pEngineState, + __in BOOL fSecondaryBootstrapperApplication, __out BOOL* pfReloadApp, __out BOOL* pfSkipCleanup ) { HRESULT hr = S_OK; - BOOTSTRAPPER_ENGINE_CONTEXT engineContext = { }; BOOL fStartupCalled = FALSE; + BAENGINE_CONTEXT* pEngineContext = NULL; + HANDLE rghWait[2] = { }; + DWORD dwSignaled = 0; + BAENGINE_ACTION* pAction = NULL; BOOTSTRAPPER_SHUTDOWN_ACTION shutdownAction = BOOTSTRAPPER_SHUTDOWN_ACTION_NONE; - BOOTSTRAPPER_ENGINE_ACTION* pAction = NULL; - - // Setup the bootstrapper engine. - engineContext.pEngineState = pEngineState; - ::InitializeCriticalSection(&engineContext.csQueue); - - engineContext.hQueueSemaphore = ::CreateSemaphoreW(NULL, 0, LONG_MAX, NULL); - ExitOnNullWithLastError(engineContext.hQueueSemaphore, hr, "Failed to create semaphore for queue."); - - hr = QueCreate(&engineContext.hQueue); - ExitOnFailure(hr, "Failed to create queue for bootstrapper engine."); + // Start the bootstrapper application. + hr = BootstrapperApplicationStart(pEngineState, fSecondaryBootstrapperApplication); + ExitOnFailure(hr, "Failed to start bootstrapper application."); - // Load the bootstrapper application. - hr = UserExperienceLoad(&pEngineState->userExperience, &engineContext, &pEngineState->command); - ExitOnFailure(hr, "Failed to load BA."); + pEngineContext = pEngineState->userExperience.pEngineContext; fStartupCalled = TRUE; - hr = UserExperienceOnStartup(&pEngineState->userExperience); + hr = BACallbackOnStartup(&pEngineState->userExperience); ExitOnFailure(hr, "Failed to start bootstrapper application."); + rghWait[0] = pEngineState->userExperience.hBAProcess; + rghWait[1] = pEngineContext->hQueueSemaphore; + while (!pEngineState->fQuit) { - hr = AppWaitForSingleObject(engineContext.hQueueSemaphore, INFINITE); + hr = AppWaitForMultipleObjects(countof(rghWait), rghWait, FALSE, INFINITE, &dwSignaled); ExitOnFailure(hr, "Failed to wait on queue event."); - ::EnterCriticalSection(&engineContext.csQueue); + // If the bootstrapper application process exited, bail. + if (0 == dwSignaled) + { + pEngineState->fQuit = TRUE; + break; + } + + ::EnterCriticalSection(&pEngineContext->csQueue); - hr = QueDequeue(engineContext.hQueue, reinterpret_cast(&pAction)); + hr = QueDequeue(pEngineContext->hQueue, reinterpret_cast(&pAction)); - ::LeaveCriticalSection(&engineContext.csQueue); + ::LeaveCriticalSection(&pEngineContext->csQueue); ExitOnFailure(hr, "Failed to dequeue action."); - ProcessMessage(&engineContext, pAction); + ProcessMessage(pEngineContext, pAction); - CoreBootstrapperEngineActionUninitialize(pAction); - MemFree(pAction); + BAEngineFreeAction(pAction); + pAction = NULL; } LExit: if (fStartupCalled) { - UserExperienceOnShutdown(&pEngineState->userExperience, &shutdownAction); + BACallbackOnShutdown(&pEngineState->userExperience, &shutdownAction); if (BOOTSTRAPPER_SHUTDOWN_ACTION_RESTART == shutdownAction) { LogId(REPORT_STANDARD, MSG_BA_REQUESTED_RESTART, LoggingBoolToString(pEngineState->fRestart)); @@ -873,26 +770,34 @@ LExit: *pfSkipCleanup = TRUE; } } + else // if the bootstrapper application did not start, there won't be anything to clean up. + { + *pfSkipCleanup = TRUE; + } - // Unload BA. - UserExperienceUnload(&pEngineState->userExperience, *pfReloadApp); + // Stop the BA. + BootstrapperApplicationStop(&pEngineState->userExperience, pfReloadApp); - ::DeleteCriticalSection(&engineContext.csQueue); - ReleaseHandle(engineContext.hQueueSemaphore); - ReleaseQueue(engineContext.hQueue, FreeQueueItem, &engineContext); + if (*pfReloadApp && !pEngineState->userExperience.pSecondaryExePayload) + { + // If the BA requested a reload but we do not have a secondary EXE, + // then log a message and do not reload. + LogId(REPORT_STANDARD, MSG_BA_NO_SECONDARY_BOOSTRAPPER_SO_RELOAD_NOT_SUPPORTED); + *pfReloadApp = FALSE; + } return hr; } static HRESULT ProcessMessage( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, - __in BOOTSTRAPPER_ENGINE_ACTION* pAction + __in BAENGINE_CONTEXT* pEngineContext, + __in BAENGINE_ACTION* pAction ) { HRESULT hr = S_OK; BURN_ENGINE_STATE* pEngineState = pEngineContext->pEngineState; - UserExperienceActivateEngine(&pEngineState->userExperience); + BootstrapperApplicationActivateEngine(&pEngineState->userExperience); switch (pAction->dwMessage) { @@ -921,7 +826,7 @@ static HRESULT ProcessMessage( break; } - UserExperienceDeactivateEngine(&pEngineState->userExperience); + BootstrapperApplicationDeactivateEngine(&pEngineState->userExperience); return hr; } @@ -971,7 +876,7 @@ static HRESULT LogStringOverPipe( hr = (HRESULT)dwResult; LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc index 39aea60e..932b6931 100644 --- a/src/burn/engine/engine.mc +++ b/src/burn/engine/engine.mc @@ -253,6 +253,13 @@ Language=English Bootstrapper application already requested to quit, ignoring request: '%1!hs!'. . +MessageId=59 +Severity=Warning +SymbolicName=MSG_BA_NO_SECONDARY_BOOSTRAPPER_SO_RELOAD_NOT_SUPPORTED +Language=English +Bootstrapper application requested reload but there is no secondary bootstrapper application, ignoring the request to reload. +. + MessageId=100 Severity=Success SymbolicName=MSG_DETECT_BEGIN @@ -1076,7 +1083,7 @@ MessageId=381 Severity=Warning SymbolicName=MSG_APPLY_CANCEL_IGNORED_DURING_ROLLBACK Language=English -Ignoring application request to cancel from %1!ls! during rollback. +Ignoring application request to cancel from %1!ls! during rollback. . MessageId=382 diff --git a/src/burn/engine/engine.vcxproj b/src/burn/engine/engine.vcxproj index 152e9cec..7a2447f8 100644 --- a/src/burn/engine/engine.vcxproj +++ b/src/burn/engine/engine.vcxproj @@ -47,17 +47,20 @@ + + + - + @@ -99,10 +102,12 @@ - - + + + + @@ -114,7 +119,7 @@ - + @@ -164,32 +169,14 @@ rc.exe -fo "$(OutDir)engine.res" "$(IntDir)engine.messages.rc" $(rmj).$(rmm).$(rup).$(rpr) $(InformationalVersion) - - + - - diff --git a/src/burn/engine/externalengine.cpp b/src/burn/engine/externalengine.cpp index df01d53b..1c775e23 100644 --- a/src/burn/engine/externalengine.cpp +++ b/src/burn/engine/externalengine.cpp @@ -14,8 +14,8 @@ static HRESULT ProcessUnknownEmbeddedMessages( __out DWORD* pdwResult ); static HRESULT EnqueueAction( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, - __inout BOOTSTRAPPER_ENGINE_ACTION** ppAction + __in BAENGINE_CONTEXT* pEngineContext, + __inout BAENGINE_ACTION** ppAction ); // function definitions @@ -227,7 +227,7 @@ HRESULT ExternalEngineSendEmbeddedError( *pnResult = static_cast(dwResult); LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -262,7 +262,7 @@ HRESULT ExternalEngineSendEmbeddedProgress( *pnResult = static_cast(dwResult); LExit: - ReleaseBuffer(pbData); + ReleaseMem(pbData); return hr; } @@ -273,25 +273,25 @@ HRESULT ExternalEngineSetUpdate( __in_z_opt LPCWSTR wzDownloadSource, __in const DWORD64 qwSize, __in const BOOTSTRAPPER_UPDATE_HASH_TYPE hashType, - __in_opt LPCWSTR wzHash + __in_opt LPCWSTR wzHash, + __in_z_opt LPCWSTR wzUpdatePackageId ) { HRESULT hr = S_OK; BOOL fLeaveCriticalSection = FALSE; - LPWSTR sczFilePath = NULL; + LPWSTR sczFileRelativePath = NULL; LPWSTR sczCommandline = NULL; - LPWSTR sczPreviousId = NULL; - LPCWSTR wzNewId = NULL; UUID guid = { }; - WCHAR wzGuid[39]; + WCHAR wzCacheId[39]; RPC_STATUS rs = RPC_S_OK; BOOL fRemove = (!wzLocalSource || !*wzLocalSource) && (!wzDownloadSource || !*wzDownloadSource); - UserExperienceOnSetUpdateBegin(&pEngineState->userExperience); + // Consider allowing the BA to pass this name in, like the UpdatePackageId can be passed in. + LPCWSTR wzFileName = NULL; ::EnterCriticalSection(&pEngineState->userExperience.csEngineActive); fLeaveCriticalSection = TRUE; - hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience); + hr = BootstrapperApplicationEnsureEngineInactive(&pEngineState->userExperience); ExitOnFailure(hr, "Engine is active, cannot change engine state."); if (!fRemove) @@ -306,8 +306,6 @@ HRESULT ExternalEngineSetUpdate( } } - sczPreviousId = pEngineState->update.package.sczId; - pEngineState->update.package.sczId = NULL; UpdateUninitialize(&pEngineState->update); if (fRemove) @@ -318,31 +316,46 @@ HRESULT ExternalEngineSetUpdate( hr = CoreCreateUpdateBundleCommandLine(&sczCommandline, &pEngineState->internalCommand, &pEngineState->command); ExitOnFailure(hr, "Failed to create command-line for update bundle."); - // Bundles would fail to use the downloaded update bundle, as the running bundle would be one of the search paths. - // Here I am generating a random guid, but in the future it would be nice if the feed would provide the ID of the update. + // Always generate a new CacheId for a location to where we can download then cache the update bundle. This running + // bundle will clean that cached location when it is done while the update bundle caches itself in its official cache + // location during its execution. rs = ::UuidCreate(&guid); hr = HRESULT_FROM_RPC(rs); ExitOnFailure(hr, "Failed to create bundle update guid."); - if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid))) + if (!::StringFromGUID2(guid, wzCacheId, countof(wzCacheId))) { - hr = E_OUTOFMEMORY; + hr = E_INSUFFICIENT_BUFFER; ExitOnRootFailure(hr, "Failed to convert bundle update guid into string."); } - hr = StrAllocFormatted(&sczFilePath, L"%ls\\%ls", wzGuid, pEngineState->registration.sczExecutableName); + // If the update package id is not provided, use the cache id. + if (!wzUpdatePackageId || !*wzUpdatePackageId) + { + wzUpdatePackageId = wzCacheId; + } + + // If the file name is not provided, use the current bundle's name. Not a great option but it is the best we have. + if (!wzFileName || !*wzFileName) + { + wzFileName = pEngineState->registration.sczExecutableName; + } + + // Download the update bundle into a relative folder using the update package id. Ths is important because this running bundle is + // in the root of one of search paths used in source resolution. Thus, if when wzFileName is the same as the running bundle, the + // running bundle will be found first and the updated bundle will not actually be downloaded. + hr = StrAllocFormatted(&sczFileRelativePath, L"%ls\\%ls", wzUpdatePackageId, wzFileName); ExitOnFailure(hr, "Failed to build bundle update file path."); if (!wzLocalSource || !*wzLocalSource) { - wzLocalSource = sczFilePath; + wzLocalSource = sczFileRelativePath; } - hr = PseudoBundleInitializeUpdateBundle(&pEngineState->update.package, wzGuid, pEngineState->registration.sczId, sczFilePath, wzLocalSource, wzDownloadSource, qwSize, sczCommandline, wzHash); + hr = PseudoBundleInitializeUpdateBundle(&pEngineState->update.package, wzUpdatePackageId, wzCacheId, sczFileRelativePath, wzLocalSource, wzDownloadSource, qwSize, sczCommandline, wzHash); ExitOnFailure(hr, "Failed to set update bundle."); pEngineState->update.fUpdateAvailable = TRUE; - wzNewId = wzGuid; LExit: if (fLeaveCriticalSection) @@ -350,11 +363,8 @@ LExit: ::LeaveCriticalSection(&pEngineState->userExperience.csEngineActive); } - UserExperienceOnSetUpdateComplete(&pEngineState->userExperience, hr, sczPreviousId, wzNewId); - - ReleaseStr(sczPreviousId); ReleaseStr(sczCommandline); - ReleaseStr(sczFilePath); + ReleaseStr(sczFileRelativePath); return hr; } @@ -371,7 +381,7 @@ HRESULT ExternalEngineSetLocalSource( BURN_PAYLOAD* pPayload = NULL; ::EnterCriticalSection(&pEngineState->userExperience.csEngineActive); - hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience); + hr = BootstrapperApplicationEnsureEngineInactive(&pEngineState->userExperience); ExitOnFailure(hr, "Engine is active, cannot change engine state."); if (!wzPath || !*wzPath) @@ -411,7 +421,8 @@ HRESULT ExternalEngineSetDownloadSource( __in_z_opt LPCWSTR wzPayloadId, __in_z_opt LPCWSTR wzUrl, __in_z_opt LPCWSTR wzUser, - __in_z_opt LPCWSTR wzPassword + __in_z_opt LPCWSTR wzPassword, + __in_z_opt LPCWSTR wzAuthorizationHeader ) { HRESULT hr = S_OK; @@ -420,7 +431,7 @@ HRESULT ExternalEngineSetDownloadSource( DOWNLOAD_SOURCE* pDownloadSource = NULL; ::EnterCriticalSection(&pEngineState->userExperience.csEngineActive); - hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience); + hr = BootstrapperApplicationEnsureEngineInactive(&pEngineState->userExperience); ExitOnFailure(hr, "Engine is active, cannot change engine state."); if (wzPayloadId && *wzPayloadId) @@ -443,7 +454,16 @@ HRESULT ExternalEngineSetDownloadSource( ExitOnFailure(hr, "BA did not provide container or payload id."); } - if (wzUrl && *wzUrl) + if (wzAuthorizationHeader && *wzAuthorizationHeader) + { + hr = StrAllocString(&pDownloadSource->sczAuthorizationHeader, wzAuthorizationHeader, 0); + ExitOnFailure(hr, "Failed to set download authorization header."); + + // Authorization header means no user. + ReleaseNullStr(pDownloadSource->sczUser); + ReleaseNullStr(pDownloadSource->sczPassword); + } + else if (wzUrl && *wzUrl) { hr = StrAllocString(&pDownloadSource->sczUrl, wzUrl, 0); ExitOnFailure(hr, "Failed to set download URL."); @@ -462,6 +482,9 @@ HRESULT ExternalEngineSetDownloadSource( { ReleaseNullStr(pDownloadSource->sczPassword); } + + // User means no authorization header. + ReleaseNullStr(pDownloadSource->sczAuthorizationHeader); } else // no user means no password either. { @@ -586,15 +609,15 @@ HRESULT ExternalEngineCompareVersions( } HRESULT ExternalEngineDetect( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, + __in BAENGINE_CONTEXT* pEngineContext, __in_opt const HWND hwndParent ) { HRESULT hr = S_OK; - BOOTSTRAPPER_ENGINE_ACTION* pAction = NULL; + BAENGINE_ACTION* pAction = NULL; - pAction = (BOOTSTRAPPER_ENGINE_ACTION*)MemAlloc(sizeof(BOOTSTRAPPER_ENGINE_ACTION), TRUE); - ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BOOTSTRAPPER_ENGINE_ACTION"); + pAction = (BAENGINE_ACTION*)MemAlloc(sizeof(BAENGINE_ACTION), TRUE); + ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BAENGINE_ACTION"); pAction->dwMessage = WM_BURN_DETECT; pAction->detect.hwndParent = hwndParent; @@ -609,20 +632,20 @@ LExit: } HRESULT ExternalEnginePlan( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, + __in BAENGINE_CONTEXT* pEngineContext, __in const BOOTSTRAPPER_ACTION action ) { HRESULT hr = S_OK; - BOOTSTRAPPER_ENGINE_ACTION* pAction = NULL; + BAENGINE_ACTION* pAction = NULL; if (BOOTSTRAPPER_ACTION_LAYOUT > action || BOOTSTRAPPER_ACTION_UPDATE_REPLACE_EMBEDDED < action) { ExitOnRootFailure(hr = E_INVALIDARG, "BA passed invalid action to Plan: %u.", action); } - pAction = (BOOTSTRAPPER_ENGINE_ACTION*)MemAlloc(sizeof(BOOTSTRAPPER_ENGINE_ACTION), TRUE); - ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BOOTSTRAPPER_ENGINE_ACTION"); + pAction = (BAENGINE_ACTION*)MemAlloc(sizeof(BAENGINE_ACTION), TRUE); + ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BAENGINE_ACTION"); pAction->dwMessage = WM_BURN_PLAN; pAction->plan.action = action; @@ -637,20 +660,20 @@ LExit: } HRESULT ExternalEngineElevate( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, + __in BAENGINE_CONTEXT* pEngineContext, __in_opt const HWND hwndParent ) { HRESULT hr = S_OK; - BOOTSTRAPPER_ENGINE_ACTION* pAction = NULL; + BAENGINE_ACTION* pAction = NULL; if (INVALID_HANDLE_VALUE != pEngineContext->pEngineState->companionConnection.hPipe) { ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED)); } - pAction = (BOOTSTRAPPER_ENGINE_ACTION*)MemAlloc(sizeof(BOOTSTRAPPER_ENGINE_ACTION), TRUE); - ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BOOTSTRAPPER_ENGINE_ACTION"); + pAction = (BAENGINE_ACTION*)MemAlloc(sizeof(BAENGINE_ACTION), TRUE); + ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BAENGINE_ACTION"); pAction->dwMessage = WM_BURN_ELEVATE; pAction->elevate.hwndParent = hwndParent; @@ -665,12 +688,12 @@ LExit: } HRESULT ExternalEngineApply( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, + __in BAENGINE_CONTEXT* pEngineContext, __in_opt const HWND hwndParent ) { HRESULT hr = S_OK; - BOOTSTRAPPER_ENGINE_ACTION* pAction = NULL; + BAENGINE_ACTION* pAction = NULL; ExitOnNull(hwndParent, hr, E_INVALIDARG, "BA passed NULL hwndParent to Apply."); if (!::IsWindow(hwndParent)) @@ -678,8 +701,8 @@ HRESULT ExternalEngineApply( ExitOnRootFailure(hr = E_INVALIDARG, "BA passed invalid hwndParent to Apply."); } - pAction = (BOOTSTRAPPER_ENGINE_ACTION*)MemAlloc(sizeof(BOOTSTRAPPER_ENGINE_ACTION), TRUE); - ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BOOTSTRAPPER_ENGINE_ACTION"); + pAction = (BAENGINE_ACTION*)MemAlloc(sizeof(BAENGINE_ACTION), TRUE); + ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BAENGINE_ACTION"); pAction->dwMessage = WM_BURN_APPLY; pAction->apply.hwndParent = hwndParent; @@ -694,15 +717,15 @@ LExit: } HRESULT ExternalEngineQuit( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, + __in BAENGINE_CONTEXT* pEngineContext, __in const DWORD dwExitCode ) { HRESULT hr = S_OK; - BOOTSTRAPPER_ENGINE_ACTION* pAction = NULL; + BAENGINE_ACTION* pAction = NULL; - pAction = (BOOTSTRAPPER_ENGINE_ACTION*)MemAlloc(sizeof(BOOTSTRAPPER_ENGINE_ACTION), TRUE); - ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BOOTSTRAPPER_ENGINE_ACTION"); + pAction = (BAENGINE_ACTION*)MemAlloc(sizeof(BAENGINE_ACTION), TRUE); + ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BAENGINE_ACTION"); pAction->dwMessage = WM_BURN_QUIT; pAction->quit.dwExitCode = dwExitCode; @@ -717,7 +740,7 @@ LExit: } HRESULT ExternalEngineLaunchApprovedExe( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, + __in BAENGINE_CONTEXT* pEngineContext, __in_opt const HWND hwndParent, __in_z LPCWSTR wzApprovedExeForElevationId, __in_z_opt LPCWSTR wzArguments, @@ -727,7 +750,7 @@ HRESULT ExternalEngineLaunchApprovedExe( HRESULT hr = S_OK; BURN_APPROVED_EXE* pApprovedExe = NULL; BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe = NULL; - BOOTSTRAPPER_ENGINE_ACTION* pAction = NULL; + BAENGINE_ACTION* pAction = NULL; if (!wzApprovedExeForElevationId || !*wzApprovedExeForElevationId) { @@ -737,8 +760,8 @@ HRESULT ExternalEngineLaunchApprovedExe( hr = ApprovedExesFindById(&pEngineContext->pEngineState->approvedExes, wzApprovedExeForElevationId, &pApprovedExe); ExitOnFailure(hr, "BA requested unknown approved exe with id: %ls", wzApprovedExeForElevationId); - pAction = (BOOTSTRAPPER_ENGINE_ACTION*)MemAlloc(sizeof(BOOTSTRAPPER_ENGINE_ACTION), TRUE); - ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BOOTSTRAPPER_ENGINE_ACTION"); + pAction = (BAENGINE_ACTION*)MemAlloc(sizeof(BAENGINE_ACTION), TRUE); + ExitOnNull(pAction, hr, E_OUTOFMEMORY, "Failed to alloc BAENGINE_ACTION"); pAction->dwMessage = WM_BURN_LAUNCH_APPROVED_EXE; pLaunchApprovedExe = &pAction->launchApprovedExe; @@ -762,8 +785,7 @@ HRESULT ExternalEngineLaunchApprovedExe( LExit: if (pAction) { - CoreBootstrapperEngineActionUninitialize(pAction); - MemFree(pAction); + BAEngineFreeAction(pAction); } return hr; @@ -771,7 +793,8 @@ LExit: HRESULT ExternalEngineSetUpdateSource( __in BURN_ENGINE_STATE* pEngineState, - __in_z LPCWSTR wzUrl + __in_z LPCWSTR wzUrl, + __in_z_opt LPCWSTR wzAuthorizationHeader ) { HRESULT hr = S_OK; @@ -779,16 +802,27 @@ HRESULT ExternalEngineSetUpdateSource( ::EnterCriticalSection(&pEngineState->userExperience.csEngineActive); fLeaveCriticalSection = TRUE; - hr = UserExperienceEnsureEngineInactive(&pEngineState->userExperience); + hr = BootstrapperApplicationEnsureEngineInactive(&pEngineState->userExperience); ExitOnFailure(hr, "Engine is active, cannot change engine state."); if (wzUrl && *wzUrl) { hr = StrAllocString(&pEngineState->update.sczUpdateSource, wzUrl, 0); ExitOnFailure(hr, "Failed to set feed download URL."); + + if (wzAuthorizationHeader && *wzAuthorizationHeader) + { + hr = StrAllocString(&pEngineState->update.sczAuthorizationHeader, wzAuthorizationHeader, 0); + ExitOnFailure(hr, "Failed to set feed authorization header."); + } + else + { + ReleaseNullStr(pEngineState->update.sczAuthorizationHeader); + } } else // no URL provided means clear out the whole download source. { + ReleaseNullStr(pEngineState->update.sczAuthorizationHeader); ReleaseNullStr(pEngineState->update.sczUpdateSource); } @@ -810,14 +844,23 @@ HRESULT ExternalEngineGetRelatedBundleVariable( ) { HRESULT hr = S_OK; + LPWSTR sczValue = NULL; + if (wzVariable && *wzVariable && pcchValue) { - hr = BundleGetBundleVariableFixed(wzBundleId, wzVariable, wzValue, pcchValue); + hr = BundleGetBundleVariable(wzBundleId, wzVariable, &sczValue); + if (SUCCEEDED(hr)) + { + hr = CopyStringToExternal(sczValue, wzValue, pcchValue); + } } else { hr = E_INVALIDARG; } + + StrSecureZeroFreeString(sczValue); + return hr; } @@ -888,8 +931,8 @@ static HRESULT ProcessUnknownEmbeddedMessages( } static HRESULT EnqueueAction( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, - __inout BOOTSTRAPPER_ENGINE_ACTION** ppAction + __in BAENGINE_CONTEXT* pEngineContext, + __inout BAENGINE_ACTION** ppAction ) { HRESULT hr = S_OK; diff --git a/src/burn/engine/externalengine.h b/src/burn/engine/externalengine.h index 0c8a8cbb..3569392d 100644 --- a/src/burn/engine/externalengine.h +++ b/src/burn/engine/externalengine.h @@ -81,7 +81,8 @@ HRESULT ExternalEngineSetUpdate( __in_z_opt LPCWSTR wzDownloadSource, __in const DWORD64 qwSize, __in const BOOTSTRAPPER_UPDATE_HASH_TYPE hashType, - __in_opt LPCWSTR wzHash + __in_opt LPCWSTR wzHash, + __in_opt LPCWSTR wzUpdatePackageId ); HRESULT ExternalEngineSetLocalSource( @@ -97,7 +98,8 @@ HRESULT ExternalEngineSetDownloadSource( __in_z_opt LPCWSTR wzPayloadId, __in_z_opt LPCWSTR wzUrl, __in_z_opt LPCWSTR wzUser, - __in_z_opt LPCWSTR wzPassword + __in_z_opt LPCWSTR wzPassword, + __in_z_opt LPCWSTR wzAuthorizationHeader ); HRESULT ExternalEngineSetVariableNumeric( @@ -138,32 +140,32 @@ HRESULT ExternalEngineGetRelatedBundleVariable( ); HRESULT ExternalEngineDetect( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, + __in BAENGINE_CONTEXT* pEngineContext, __in_opt const HWND hwndParent ); HRESULT ExternalEnginePlan( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, + __in BAENGINE_CONTEXT* pEngineContext, __in const BOOTSTRAPPER_ACTION action ); HRESULT ExternalEngineElevate( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, + __in BAENGINE_CONTEXT* pEngineContext, __in_opt const HWND hwndParent ); HRESULT ExternalEngineApply( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, + __in BAENGINE_CONTEXT* pEngineContext, __in_opt const HWND hwndParent ); HRESULT ExternalEngineQuit( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, + __in BAENGINE_CONTEXT* pEngineContext, __in const DWORD dwExitCode ); HRESULT ExternalEngineLaunchApprovedExe( - __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext, + __in BAENGINE_CONTEXT* pEngineContext, __in_opt const HWND hwndParent, __in_z LPCWSTR wzApprovedExeForElevationId, __in_z_opt LPCWSTR wzArguments, @@ -172,7 +174,8 @@ HRESULT ExternalEngineLaunchApprovedExe( HRESULT ExternalEngineSetUpdateSource( __in BURN_ENGINE_STATE* pEngineState, - __in_z LPCWSTR wzUrl + __in_z LPCWSTR wzUrl, + __in_z_opt LPCWSTR wzAuthorizationHeader ); HRESULT WINAPI ExternalEngineValidateMessageParameter( diff --git a/src/burn/engine/inc/engine.h b/src/burn/engine/inc/engine.h index 9b29dd84..33d9e77b 100644 --- a/src/burn/engine/inc/engine.h +++ b/src/burn/engine/inc/engine.h @@ -19,10 +19,6 @@ extern "C" { // function declarations -BOOL EngineInCleanRoom( - __in_z_opt LPCWSTR wzCommandLine - ); - HRESULT EngineRun( __in HINSTANCE hInstance, __in HANDLE hEngineFile, diff --git a/src/burn/engine/logging.cpp b/src/burn/engine/logging.cpp index 630598ae..f381193f 100644 --- a/src/burn/engine/logging.cpp +++ b/src/burn/engine/logging.cpp @@ -74,9 +74,6 @@ extern "C" HRESULT LoggingOpen( switch (pInternalCommand->mode) { - case BURN_MODE_UNTRUSTED: - wzPostfix = L".cleanroom"; - break; case BURN_MODE_ELEVATED: wzPostfix = L".elevated"; break; @@ -1014,7 +1011,7 @@ static HRESULT InitializeLogging( // The untrusted process needs a separate log file. // TODO: Burn crashes if they do try to use the same log file. - if (pInternalCommand->sczLogFile && BURN_MODE_UNTRUSTED != pInternalCommand->mode) + if (pInternalCommand->sczLogFile) { hr = StrAllocString(&pLog->sczPath, pInternalCommand->sczLogFile, 0); ExitOnFailure(hr, "Failed to copy log file path from command line."); diff --git a/src/burn/engine/manifest.cpp b/src/burn/engine/manifest.cpp index c0d67c19..266d1987 100644 --- a/src/burn/engine/manifest.cpp +++ b/src/burn/engine/manifest.cpp @@ -104,7 +104,7 @@ static HRESULT ParseFromXml( } } - // parse built-in condition + // parse built-in condition hr = ConditionGlobalParseFromXml(&pEngineState->condition, pixeBundle); ExitOnFailure(hr, "Failed to parse global condition."); @@ -113,8 +113,8 @@ static HRESULT ParseFromXml( ExitOnFailure(hr, "Failed to parse variables."); // parse user experience - hr = UserExperienceParseFromXml(&pEngineState->userExperience, pixeBundle); - ExitOnFailure(hr, "Failed to parse user experience."); + hr = BootstrapperApplicationParseFromXml(&pEngineState->userExperience, pixeBundle); + ExitOnFailure(hr, "Failed to parse bootstrapper application."); // parse extensions hr = BurnExtensionParseFromXml(&pEngineState->extensions, &pEngineState->userExperience.payloads, pixeBundle); diff --git a/src/burn/engine/msiengine.cpp b/src/burn/engine/msiengine.cpp index 32b6660e..d5268b17 100644 --- a/src/burn/engine/msiengine.cpp +++ b/src/burn/engine/msiengine.cpp @@ -489,7 +489,7 @@ extern "C" HRESULT MsiEngineDetectPackage( { LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_PACKAGE, pPackage->Msi.sczProductCode, LoggingPerMachineToString(pPackage->fPerMachine), pVersion->sczVersion, pPackage->Msi.dwLanguage, LoggingRelatedOperationToString(pPackage->Msi.operation)); - hr = UserExperienceOnDetectRelatedMsiPackage(pUserExperience, pPackage->sczId, pPackage->Msi.sczUpgradeCode, pPackage->Msi.sczProductCode, pPackage->fPerMachine, pVersion, pPackage->Msi.operation); + hr = BACallbackOnDetectRelatedMsiPackage(pUserExperience, pPackage->sczId, pPackage->Msi.sczUpgradeCode, pPackage->Msi.sczProductCode, pPackage->fPerMachine, pVersion, pPackage->Msi.operation); ExitOnRootFailure(hr, "BA aborted detect related MSI package."); } } @@ -651,7 +651,7 @@ extern "C" HRESULT MsiEngineDetectPackage( LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_PACKAGE, wzProductCode, LoggingPerMachineToString(fPerMachine), pVersion->sczVersion, uLcid, LoggingRelatedOperationToString(relatedMsiOperation)); // Pass to BA. - hr = UserExperienceOnDetectRelatedMsiPackage(pUserExperience, pPackage->sczId, pRelatedMsi->sczUpgradeCode, wzProductCode, fPerMachine, pVersion, relatedMsiOperation); + hr = BACallbackOnDetectRelatedMsiPackage(pUserExperience, pPackage->sczId, pRelatedMsi->sczUpgradeCode, wzProductCode, fPerMachine, pVersion, relatedMsiOperation); ExitOnRootFailure(hr, "BA aborted detect related MSI package."); } } @@ -700,7 +700,7 @@ extern "C" HRESULT MsiEngineDetectPackage( } // Pass to BA. - hr = UserExperienceOnDetectMsiFeature(pUserExperience, pPackage->sczId, pFeature->sczId, pFeature->currentState); + hr = BACallbackOnDetectMsiFeature(pUserExperience, pPackage->sczId, pFeature->sczId, pFeature->currentState); ExitOnRootFailure(hr, "BA aborted detect MSI feature."); } } @@ -747,7 +747,7 @@ extern "C" HRESULT MsiEngineDetectPackage( LogId(REPORT_STANDARD, MSG_DETECTED_COMPATIBLE_PACKAGE_FROM_PROVIDER, pPackage->sczId, pPackage->compatiblePackage.compatibleEntry.sczProviderKey, wzCompatibleProductCode, wzCompatibleInstalledVersion, pPackage->Msi.sczProductCode); - hr = UserExperienceOnDetectCompatibleMsiPackage(pUserExperience, pPackage->sczId, wzCompatibleProductCode, pPackage->compatiblePackage.Msi.pVersion); + hr = BACallbackOnDetectCompatibleMsiPackage(pUserExperience, pPackage->sczId, wzCompatibleProductCode, pPackage->compatiblePackage.Msi.pVersion); ExitOnRootFailure(hr, "BA aborted detect compatible MSI package."); } } @@ -828,7 +828,7 @@ extern "C" HRESULT MsiEnginePlanInitializePackage( pFeature->requested = pFeature->defaultRequested; // Send plan MSI feature message to BA. - hr = UserExperienceOnPlanMsiFeature(pUserExperience, pPackage->sczId, pFeature->sczId, &pFeature->requested); + hr = BACallbackOnPlanMsiFeature(pUserExperience, pPackage->sczId, pFeature->sczId, &pFeature->requested); ExitOnRootFailure(hr, "BA aborted plan MSI feature."); } } @@ -840,8 +840,8 @@ extern "C" HRESULT MsiEnginePlanInitializePackage( pPackage->compatiblePackage.fDefaultRequested = BOOTSTRAPPER_ACTION_UNINSTALL == overallAction || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == overallAction; pPackage->compatiblePackage.fRequested = pPackage->compatiblePackage.fDefaultRequested; - hr = UserExperienceOnPlanCompatibleMsiPackageBegin(pUserExperience, pPackage->sczId, pPackage->compatiblePackage.compatibleEntry.sczId, pPackage->compatiblePackage.Msi.pVersion, &pPackage->compatiblePackage.fRequested); - UserExperienceOnPlanCompatibleMsiPackageComplete(pUserExperience, pPackage->sczId, pPackage->compatiblePackage.compatibleEntry.sczId, hr, pPackage->compatiblePackage.fRequested); + hr = BACallbackOnPlanCompatibleMsiPackageBegin(pUserExperience, pPackage->sczId, pPackage->compatiblePackage.compatibleEntry.sczId, pPackage->compatiblePackage.Msi.pVersion, &pPackage->compatiblePackage.fRequested); + BACallbackOnPlanCompatibleMsiPackageComplete(pUserExperience, pPackage->sczId, pPackage->compatiblePackage.compatibleEntry.sczId, hr, pPackage->compatiblePackage.fRequested); ExitOnRootFailure(hr, "BA aborted plan compatible MSI package begin."); } @@ -1679,7 +1679,7 @@ extern "C" HRESULT MsiEnginePlanPackageOptions( break; } - return UserExperienceOnPlanMsiPackage(pUserExperience, wzPackageId, fExecute, actionState, pActionMsiProperty, pUiLevel, pfDisableExternalUiHandler, pFileVersioning); + return BACallbackOnPlanMsiPackage(pUserExperience, wzPackageId, fExecute, actionState, pActionMsiProperty, pUiLevel, pfDisableExternalUiHandler, pFileVersioning); } extern "C" void MsiEngineUpdateInstallRegistrationState( diff --git a/src/burn/engine/mspengine.cpp b/src/burn/engine/mspengine.cpp index 089262e1..c057c06d 100644 --- a/src/burn/engine/mspengine.cpp +++ b/src/burn/engine/mspengine.cpp @@ -324,7 +324,7 @@ extern "C" HRESULT MspEngineDetectPackage( } } - hr = UserExperienceOnDetectPatchTarget(pUserExperience, pPackage->sczId, pTargetProduct->wzTargetProductCode, pTargetProduct->patchPackageState); + hr = BACallbackOnDetectPatchTarget(pUserExperience, pPackage->sczId, pTargetProduct->wzTargetProductCode, pTargetProduct->patchPackageState); ExitOnRootFailure(hr, "BA aborted detect patch target."); } } @@ -358,7 +358,7 @@ extern "C" HRESULT MspEnginePlanInitializePackage( pTargetProduct->defaultRequested = pTargetProduct->requested = pPackage->requested; - hr = UserExperienceOnPlanPatchTarget(pUserExperience, pPackage->sczId, pTargetProduct->wzTargetProductCode, &pTargetProduct->requested); + hr = BACallbackOnPlanPatchTarget(pUserExperience, pPackage->sczId, pTargetProduct->wzTargetProductCode, &pTargetProduct->requested); ExitOnRootFailure(hr, "BA aborted plan patch target."); } diff --git a/src/burn/engine/payload.cpp b/src/burn/engine/payload.cpp index fe3d673e..1d8328e3 100644 --- a/src/burn/engine/payload.cpp +++ b/src/burn/engine/payload.cpp @@ -244,6 +244,7 @@ extern "C" void PayloadUninitialize( ReleaseStr(pPayload->downloadSource.sczUrl); ReleaseStr(pPayload->downloadSource.sczUser); ReleaseStr(pPayload->downloadSource.sczPassword); + ReleaseStr(pPayload->downloadSource.sczAuthorizationHeader); ReleaseStr(pPayload->sczUnverifiedPath); } } diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index b7703869..be281827 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp @@ -441,15 +441,11 @@ extern "C" HRESULT PlanLayoutBundle( hr = VariableGetString(pVariables, BURN_BUNDLE_LAYOUT_DIRECTORY, &sczLayoutDirectory); if (E_NOTFOUND == hr) // if not set, use the current directory as the layout directory. { - hr = VariableGetString(pVariables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER, &sczLayoutDirectory); - if (E_NOTFOUND == hr) // if not set, use the current directory as the layout directory. - { - hr = PathForCurrentProcess(&sczExecutablePath, NULL); - ExitOnFailure(hr, "Failed to get path for current executing process as layout directory."); + hr = PathForCurrentProcess(&sczExecutablePath, NULL); + ExitOnFailure(hr, "Failed to get path for current executing process as layout directory."); - hr = PathGetDirectory(sczExecutablePath, &sczLayoutDirectory); - ExitOnFailure(hr, "Failed to get executing process as layout directory."); - } + hr = PathGetDirectory(sczExecutablePath, &sczLayoutDirectory); + ExitOnFailure(hr, "Failed to get executing process as layout directory."); } ExitOnFailure(hr, "Failed to get bundle layout directory property."); @@ -538,7 +534,7 @@ extern "C" HRESULT PlanForwardCompatibleBundles( fIgnoreBundle = fRecommendIgnore; - hr = UserExperienceOnPlanForwardCompatibleBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->detectRelationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, &fIgnoreBundle); + hr = BACallbackOnPlanForwardCompatibleBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->detectRelationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, &fIgnoreBundle); ExitOnRootFailure(hr, "BA aborted plan forward compatible bundle."); if (!fIgnoreBundle) @@ -564,7 +560,7 @@ extern "C" HRESULT PlanPackages( ) { HRESULT hr = S_OK; - + hr = PlanPackagesHelper(pPackages->rgPackages, pPackages->cPackages, pUX, pPlan, pLog, pVariables); return hr; @@ -896,11 +892,11 @@ static HRESULT PlanPackagesHelper( DWORD iPackage = fReverseOrder ? cPackages - 1 - i : i; BURN_PACKAGE* pPackage = rgPackages + iPackage; - UserExperienceOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback, NULL != pPackage->hCacheEvent, pPackage->fPlannedUncache); + BACallbackOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback, NULL != pPackage->hCacheEvent, pPackage->fPlannedUncache); if (pPackage->compatiblePackage.fPlannable) { - UserExperienceOnPlannedCompatiblePackage(pUX, pPackage->sczId, pPackage->compatiblePackage.compatibleEntry.sczId, pPackage->compatiblePackage.fRemove); + BACallbackOnPlannedCompatiblePackage(pUX, pPackage->sczId, pPackage->compatiblePackage.compatibleEntry.sczId, pPackage->compatiblePackage.fRemove); } } @@ -961,7 +957,7 @@ static HRESULT InitializePackage( pPackage->requested = pPackage->defaultRequested; fBeginCalled = TRUE; - hr = UserExperienceOnPlanPackageBegin(pUX, pPackage->sczId, pPackage->currentState, pPackage->fCached, installCondition, repairCondition, &pPackage->requested, &pPackage->cacheType); + hr = BACallbackOnPlanPackageBegin(pUX, pPackage->sczId, pPackage->currentState, pPackage->fCached, installCondition, repairCondition, &pPackage->requested, &pPackage->cacheType); ExitOnRootFailure(hr, "BA aborted plan package begin."); if (BURN_PACKAGE_TYPE_MSI == pPackage->type) @@ -973,7 +969,7 @@ static HRESULT InitializePackage( LExit: if (fBeginCalled) { - UserExperienceOnPlanPackageComplete(pUX, pPackage->sczId, hr, pPackage->requested); + BACallbackOnPlanPackageComplete(pUX, pPackage->sczId, hr, pPackage->requested); } return hr; @@ -1375,7 +1371,7 @@ extern "C" HRESULT PlanRelatedBundlesInitialize( pRelatedBundle->planRelationType = pRelatedBundle->defaultPlanRelationType; - hr = UserExperienceOnPlanRelatedBundleType(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->planRelationType); + hr = BACallbackOnPlanRelatedBundleType(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->planRelationType); ExitOnRootFailure(hr, "BA aborted plan related bundle type."); if (BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DOWNGRADE == pRelatedBundle->planRelationType && @@ -1462,7 +1458,7 @@ extern "C" HRESULT PlanRelatedBundlesBegin( pRelatedBundle->package.defaultRequested = pRelatedBundle->package.requested; - hr = UserExperienceOnPlanRelatedBundle(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->package.requested); + hr = BACallbackOnPlanRelatedBundle(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->package.requested); ExitOnRootFailure(hr, "BA aborted plan related bundle."); // If uninstalling and the dependent related bundle may be executed, ignore its provider key to allow for downgrades with ref-counting. @@ -1662,7 +1658,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete( pRelatedBundle->defaultRequestedRestore = pRelatedBundle->requestedRestore = BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT; - hr = UserExperienceOnPlanRestoreRelatedBundle(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->requestedRestore); + hr = BACallbackOnPlanRestoreRelatedBundle(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->requestedRestore); ExitOnRootFailure(hr, "BA aborted plan restore related bundle."); switch (pRelatedBundle->requestedRestore) @@ -1966,7 +1962,7 @@ extern "C" HRESULT PlanRollbackBoundaryBegin( pExecuteAction->type = BURN_EXECUTE_ACTION_TYPE_ROLLBACK_BOUNDARY_START; pExecuteAction->rollbackBoundary.pRollbackBoundary = pRollbackBoundary; - hr = UserExperienceOnPlanRollbackBoundary(pUX, pRollbackBoundary->sczId, &pRollbackBoundary->fTransaction); + hr = BACallbackOnPlanRollbackBoundary(pUX, pRollbackBoundary->sczId, &pRollbackBoundary->fTransaction); ExitOnRootFailure(hr, "BA aborted plan rollback boundary."); // Only use MSI transaction if authored and the BA requested it. diff --git a/src/burn/engine/platform.h b/src/burn/engine/platform.h index 5896a5ca..e355e793 100644 --- a/src/burn/engine/platform.h +++ b/src/burn/engine/platform.h @@ -27,10 +27,11 @@ enum WM_BURN // forward declare enum BURN_MODE; -typedef struct _BOOTSTRAPPER_ENGINE_CONTEXT BOOTSTRAPPER_ENGINE_CONTEXT; -typedef struct _BOOTSTRAPPER_ENGINE_ACTION BOOTSTRAPPER_ENGINE_ACTION; +typedef struct _BAENGINE_CONTEXT BAENGINE_CONTEXT; +typedef struct _BAENGINE_ACTION BAENGINE_ACTION; typedef struct _BURN_CACHE BURN_CACHE; typedef struct _BURN_DEPENDENCIES BURN_DEPENDENCIES; +typedef struct _BURN_ENGINE_STATE BURN_ENGINE_STATE; typedef struct _BURN_ENGINE_COMMAND BURN_ENGINE_COMMAND; typedef struct _BURN_LOGGING BURN_LOGGING; typedef struct _BURN_PACKAGES BURN_PACKAGES; diff --git a/src/burn/engine/precomp.h b/src/burn/engine/precomp.h index 50df77ca..1150b2a0 100644 --- a/src/burn/engine/precomp.h +++ b/src/burn/engine/precomp.h @@ -61,8 +61,8 @@ #include #include -#include "BootstrapperEngine.h" -#include "BootstrapperApplication.h" +#include "baenginetypes.h" +#include "batypes.h" #include "BundleExtensionEngine.h" #include "BundleExtension.h" @@ -77,6 +77,7 @@ #include "cabextract.h" #include "burnextension.h" #include "search.h" +#include "bootstrapperapplication.h" #include "userexperience.h" #include "package.h" #include "update.h" @@ -104,7 +105,8 @@ #include "netfxchainer.h" #include "externalengine.h" -#include "EngineForApplication.h" +#include "bacallback.h" +#include "baengine.h" #include "EngineForExtension.h" #include "engine.messages.h" #include "engine.version.h" diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp index 01ed30d7..fd8a32a4 100644 --- a/src/burn/engine/registration.cpp +++ b/src/burn/engine/registration.cpp @@ -299,7 +299,7 @@ LExit: } /******************************************************************* - RegistrationUninitialize - + RegistrationUninitialize - *******************************************************************/ extern "C" void RegistrationUninitialize( @@ -550,7 +550,7 @@ LExit: } /******************************************************************* - RegistrationDetectRelatedBundles - finds the bundles with same + RegistrationDetectRelatedBundles - finds the bundles with same upgrade/detect/addon/patch codes. *******************************************************************/ @@ -761,7 +761,7 @@ extern "C" HRESULT RegistrationSessionBegin( else if (BURN_REGISTRATION_MODIFY_DISABLE_BUTTON != pRegistration->modify) // if support modify (aka: did not disable anything) { // ModifyPath: [path to exe] /modify - hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_MODIFY_PATH, L"\"%ls\" /%ls /modify", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_CLEAN_ROOM); + hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_MODIFY_PATH, L"\"%ls\" /modify", pRegistration->sczCacheExecutablePath); ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_MODIFY_PATH); // NoElevateOnModify: 1 @@ -793,14 +793,14 @@ extern "C" HRESULT RegistrationSessionBegin( } // QuietUninstallString: [path to exe] /uninstall /quiet - hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_QUIET_UNINSTALL_STRING, L"\"%ls\" /%ls /uninstall /quiet", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_CLEAN_ROOM); + hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_QUIET_UNINSTALL_STRING, L"\"%ls\" /uninstall /quiet", pRegistration->sczCacheExecutablePath); ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_QUIET_UNINSTALL_STRING); // UninstallString, [path to exe] // If the modify button is to be disabled, we'll add "/modify" to the uninstall string because the button is "Uninstall/Change". Otherwise, // it's just the "Uninstall" button so we add "/uninstall" to make the program just go away. LPCWSTR wzUninstallParameters = (BURN_REGISTRATION_MODIFY_DISABLE_BUTTON == pRegistration->modify) ? L"/modify" : L" /uninstall"; - hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_UNINSTALL_STRING, L"\"%ls\" /%ls %ls", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, wzUninstallParameters); + hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_UNINSTALL_STRING, L"\"%ls\" %ls", pRegistration->sczCacheExecutablePath, wzUninstallParameters); ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_UNINSTALL_STRING); if (pRegistration->softwareTags.cSoftwareTags) @@ -1281,7 +1281,7 @@ static HRESULT UpdateResumeMode( if ((BURN_RESUME_MODE_ACTIVE == resumeMode || fRestartInitiated) && !pRegistration->fDisableResume) { // append RunOnce switch - hr = StrAllocFormatted(&sczRunOnceCommandLine, L"\"%ls\" /%ls /%ls", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, BURN_COMMANDLINE_SWITCH_RUNONCE); + hr = StrAllocFormatted(&sczRunOnceCommandLine, L"\"%ls\" /%ls", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_RUNONCE); ExitOnFailure(hr, "Failed to format resume command line for RunOnce."); // write run key diff --git a/src/burn/engine/splashscreen.cpp b/src/burn/engine/splashscreen.cpp index b9dc9f55..0bfa00aa 100644 --- a/src/burn/engine/splashscreen.cpp +++ b/src/burn/engine/splashscreen.cpp @@ -337,7 +337,7 @@ static HRESULT LoadSplashScreen( } pSplashScreen->hWnd = ::CreateWindowExW(WS_EX_TOOLWINDOW, BURN_SPLASHSCREEN_CLASS_WINDOW, pContext->wzCaption, WS_POPUP | WS_VISIBLE, x, y, pSplashScreen->size.cx, pSplashScreen->size.cy, HWND_DESKTOP, NULL, pContext->hInstance, pSplashScreen); - ExitOnNullWithLastError(pSplashScreen->hWnd, hr, "Failed to create window."); + ExitOnNullWithLastError(pSplashScreen->hWnd, hr, "Failed to create splash screen window."); LExit: MemFree(pMonitorContext); diff --git a/src/burn/engine/uithread.cpp b/src/burn/engine/uithread.cpp index 8ddd51bd..9beb9f80 100644 --- a/src/burn/engine/uithread.cpp +++ b/src/burn/engine/uithread.cpp @@ -124,7 +124,7 @@ static DWORD WINAPI ThreadProc( // Create the window to handle reboots without activating it. hWnd = ::CreateWindowExW(WS_EX_NOACTIVATE, wc.lpszClassName, NULL, WS_POPUP, 0, 0, 0, 0, HWND_DESKTOP, NULL, pContext->hInstance, &info); - ExitOnNullWithLastError(hWnd, hr, "Failed to create window."); + ExitOnNullWithLastError(hWnd, hr, "Failed to create Burn UI thread window."); ::ShowWindow(hWnd, SW_SHOWNA); diff --git a/src/burn/engine/update.cpp b/src/burn/engine/update.cpp index b04fa9a4..70cb8a8d 100644 --- a/src/burn/engine/update.cpp +++ b/src/burn/engine/update.cpp @@ -39,6 +39,7 @@ extern "C" void UpdateUninitialize( { PackageUninitialize(&pUpdate->package); + ReleaseStr(pUpdate->sczAuthorizationHeader); ReleaseStr(pUpdate->sczUpdateSource); memset(pUpdate, 0, sizeof(BURN_UPDATE)); } diff --git a/src/burn/engine/update.h b/src/burn/engine/update.h index 67d40481..ef45c4cf 100644 --- a/src/burn/engine/update.h +++ b/src/burn/engine/update.h @@ -13,6 +13,7 @@ typedef struct _BURN_UPDATE { BOOL fUpdateAvailable; LPWSTR sczUpdateSource; + LPWSTR sczAuthorizationHeader; BURN_PACKAGE package; } BURN_UPDATE; diff --git a/src/burn/engine/userexperience.cpp b/src/burn/engine/userexperience.cpp index 372ca901..99561f35 100644 --- a/src/burn/engine/userexperience.cpp +++ b/src/burn/engine/userexperience.cpp @@ -4,88 +4,60 @@ // internal function declarations -static int FilterResult( - __in DWORD dwAllowedResults, - __in int nResult - ); - -static HRESULT FilterExecuteResult( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrStatus, - __in BOOL fRollback, - __in BOOL fCancel, - __in LPCWSTR sczEventName - ); - -static HRESULT SendBAMessage( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in BOOTSTRAPPER_APPLICATION_MESSAGE message, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ); - -static HRESULT SendBAMessageFromInactiveEngine( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in BOOTSTRAPPER_APPLICATION_MESSAGE message, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ); +// static int FilterResult( +// __in DWORD dwAllowedResults, +// __in int nResult +// ); + +// static HRESULT FilterExecuteResult( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in HRESULT hrStatus, +// __in BOOL fRollback, +// __in BOOL fCancel, +// __in LPCWSTR sczEventName +// ); + +// static HRESULT SendBAMessage( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in BOOTSTRAPPER_APPLICATION_MESSAGE message, +// __in_bcount(cbArgs) const LPVOID pvArgs, +// __in const DWORD cbArgs, +// __in PIPE_RPC_RESULT* pResult +// ); + +// static HRESULT SendBAMessageFromInactiveEngine( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in BOOTSTRAPPER_APPLICATION_MESSAGE message, +// __in const LPVOID pvArgs, +// __in const DWORD cbArgs, +// __in PIPE_RPC_RESULT* pResult +// ); // function definitions -/******************************************************************* - UserExperienceParseFromXml - - -*******************************************************************/ -extern "C" HRESULT UserExperienceParseFromXml( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in IXMLDOMNode* pixnBundle - ) -{ - HRESULT hr = S_OK; - IXMLDOMNode* pixnUserExperienceNode = NULL; - - // select UX node - hr = XmlSelectSingleNode(pixnBundle, L"UX", &pixnUserExperienceNode); - if (S_FALSE == hr) - { - hr = E_NOTFOUND; - } - ExitOnFailure(hr, "Failed to select user experience node."); - - // parse payloads - hr = PayloadsParseFromXml(&pUserExperience->payloads, NULL, NULL, pixnUserExperienceNode); - ExitOnFailure(hr, "Failed to parse user experience payloads."); - - // make sure we have at least one payload - if (0 == pUserExperience->payloads.cPayloads) - { - hr = E_UNEXPECTED; - ExitOnFailure(hr, "Too few UX payloads."); - } - -LExit: - ReleaseObject(pixnUserExperienceNode); - - return hr; -} +// /******************************************************************* +// UserExperienceUninitialize - -/******************************************************************* - UserExperienceUninitialize - +// *******************************************************************/ +// extern "C" void UserExperienceUninitialize( +// __in BURN_USER_EXPERIENCE* pUserExperience +// ) +// { +// if (pUserExperience->pEngineContext) +// { +// BAEngineFreeContext(pUserExperience->pEngineContext); +// pUserExperience->pEngineContext = NULL; +// } -*******************************************************************/ -extern "C" void UserExperienceUninitialize( - __in BURN_USER_EXPERIENCE* pUserExperience - ) -{ - ReleaseStr(pUserExperience->sczTempDirectory); - PayloadsUninitialize(&pUserExperience->payloads); +// ReleaseStr(pUserExperience->sczTempDirectory); +// PayloadsUninitialize(&pUserExperience->payloads); - // clear struct - memset(pUserExperience, 0, sizeof(BURN_USER_EXPERIENCE)); -} +// // clear struct +// memset(pUserExperience, 0, sizeof(BURN_USER_EXPERIENCE)); +// } +#ifdef TODO_DELETE /******************************************************************* UserExperienceLoad - @@ -167,2848 +139,2820 @@ extern "C" HRESULT UserExperienceUnload( //LExit: return hr; } - -extern "C" HRESULT UserExperienceEnsureWorkingFolder( - __in BURN_CACHE* pCache, - __deref_out_z LPWSTR* psczUserExperienceWorkingFolder - ) -{ - HRESULT hr = S_OK; - LPWSTR sczWorkingFolder = NULL; - - hr = CacheEnsureBaseWorkingFolder(pCache, &sczWorkingFolder); - ExitOnFailure(hr, "Failed to create working folder."); - - hr = StrAllocFormatted(psczUserExperienceWorkingFolder, L"%ls%ls\\", sczWorkingFolder, L".ba"); - ExitOnFailure(hr, "Failed to calculate the bootstrapper application working path."); - - hr = DirEnsureExists(*psczUserExperienceWorkingFolder, NULL); - ExitOnFailure(hr, "Failed create bootstrapper application working folder."); - -LExit: - ReleaseStr(sczWorkingFolder); - - return hr; -} - - -extern "C" HRESULT UserExperienceRemove( - __in BURN_USER_EXPERIENCE* pUserExperience - ) -{ - HRESULT hr = S_OK; - - // Remove temporary UX directory - if (pUserExperience->sczTempDirectory) - { - hr = DirEnsureDeleteEx(pUserExperience->sczTempDirectory, DIR_DELETE_FILES | DIR_DELETE_RECURSE | DIR_DELETE_SCHEDULE); - TraceError(hr, "Could not delete bootstrapper application folder. Some files will be left in the temp folder."); - } - -//LExit: - return hr; -} - -extern "C" int UserExperienceSendError( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in BOOTSTRAPPER_ERROR_TYPE errorType, - __in_z_opt LPCWSTR wzPackageId, - __in HRESULT hrCode, - __in_z_opt LPCWSTR wzError, - __in DWORD uiFlags, - __in int nRecommendation - ) -{ - int nResult = nRecommendation; - DWORD dwCode = HRESULT_CODE(hrCode); - LPWSTR sczError = NULL; - - // If no error string was provided, try to get the error string from the HRESULT. - if (!wzError) - { - if (SUCCEEDED(StrAllocFromError(&sczError, hrCode, NULL))) - { - wzError = sczError; - } - } - - UserExperienceOnError(pUserExperience, errorType, wzPackageId, dwCode, wzError, uiFlags, 0, NULL, &nResult); // ignore return value. - - ReleaseStr(sczError); - return nResult; -} - -extern "C" void UserExperienceActivateEngine( - __in BURN_USER_EXPERIENCE* pUserExperience - ) -{ - ::EnterCriticalSection(&pUserExperience->csEngineActive); - AssertSz(!pUserExperience->fEngineActive, "Engine should have been deactivated before activating it."); - pUserExperience->fEngineActive = TRUE; - ::LeaveCriticalSection(&pUserExperience->csEngineActive); -} - -extern "C" void UserExperienceDeactivateEngine( - __in BURN_USER_EXPERIENCE* pUserExperience - ) -{ - ::EnterCriticalSection(&pUserExperience->csEngineActive); - AssertSz(pUserExperience->fEngineActive, "Engine should have been active before deactivating it."); - pUserExperience->fEngineActive = FALSE; - ::LeaveCriticalSection(&pUserExperience->csEngineActive); -} - -extern "C" HRESULT UserExperienceEnsureEngineInactive( - __in BURN_USER_EXPERIENCE* pUserExperience - ) -{ - // Make a slight optimization here by ignoring the critical section, because all callers should have needed to enter it for their operation anyway. - HRESULT hr = pUserExperience->fEngineActive ? HRESULT_FROM_WIN32(ERROR_BUSY) : S_OK; - ExitOnRootFailure(hr, "Engine is active, cannot proceed."); - -LExit: - return hr; -} - -extern "C" void UserExperienceExecuteReset( - __in BURN_USER_EXPERIENCE* pUserExperience - ) -{ - pUserExperience->hrApplyError = S_OK; - pUserExperience->hwndApply = NULL; -} - -extern "C" void UserExperienceExecutePhaseComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrResult - ) -{ - if (FAILED(hrResult)) - { - pUserExperience->hrApplyError = hrResult; - } -} - -EXTERN_C BAAPI UserExperienceOnApplyBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in DWORD dwPhaseCount - ) -{ - HRESULT hr = S_OK; - BA_ONAPPLYBEGIN_ARGS args = { }; - BA_ONAPPLYBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.dwPhaseCount = dwPhaseCount; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnApplyBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnApplyComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrStatus, - __in BOOTSTRAPPER_APPLY_RESTART restart, - __inout BOOTSTRAPPER_APPLYCOMPLETE_ACTION* pAction - ) -{ - HRESULT hr = S_OK; - BA_ONAPPLYCOMPLETE_ARGS args = { }; - BA_ONAPPLYCOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.hrStatus = hrStatus; - args.restart = restart; - args.recommendation = *pAction; - - results.cbSize = sizeof(results); - results.action = *pAction; - - hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYCOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnApplyComplete failed."); - - *pAction = results.action; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnApplyDowngrade( - __in BURN_USER_EXPERIENCE* pUserExperience, - __inout HRESULT* phrStatus - ) -{ - HRESULT hr = S_OK; - BA_ONAPPLYDOWNGRADE_ARGS args = { }; - BA_ONAPPLYDOWNGRADE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.hrRecommended = *phrStatus; - - results.cbSize = sizeof(results); - results.hrStatus = *phrStatus; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYDOWNGRADE, &args, &results); - ExitOnFailure(hr, "BA OnApplyDowngrade failed."); - - *phrStatus = results.hrStatus; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnBeginMsiTransactionBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in LPCWSTR wzTransactionId - ) -{ - HRESULT hr = S_OK; - BA_ONBEGINMSITRANSACTIONBEGIN_ARGS args = { }; - BA_ONBEGINMSITRANSACTIONBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzTransactionId = wzTransactionId; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONBEGINMSITRANSACTIONBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnBeginMsiTransactionBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnBeginMsiTransactionComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in LPCWSTR wzTransactionId, - __in HRESULT hrStatus - ) -{ - HRESULT hr = S_OK; - BA_ONBEGINMSITRANSACTIONCOMPLETE_ARGS args = { }; - BA_ONBEGINMSITRANSACTIONCOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzTransactionId = wzTransactionId; - args.hrStatus = hrStatus; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONBEGINMSITRANSACTIONCOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnBeginMsiTransactionComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCacheAcquireBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z_opt LPCWSTR wzPackageOrContainerId, - __in_z_opt LPCWSTR wzPayloadId, - __in_z LPWSTR* pwzSource, - __in_z LPWSTR* pwzDownloadUrl, - __in_z_opt LPCWSTR wzPayloadContainerId, - __out BOOTSTRAPPER_CACHE_OPERATION* pCacheOperation - ) -{ - HRESULT hr = S_OK; - BA_ONCACHEACQUIREBEGIN_ARGS args = { }; - BA_ONCACHEACQUIREBEGIN_RESULTS results = { }; - *pCacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE; - - args.cbSize = sizeof(args); - args.wzPackageOrContainerId = wzPackageOrContainerId; - args.wzPayloadId = wzPayloadId; - args.wzSource = *pwzSource; - args.wzDownloadUrl = *pwzDownloadUrl; - args.wzPayloadContainerId = wzPayloadContainerId; - args.recommendation = *pCacheOperation; - - results.cbSize = sizeof(results); - results.action = *pCacheOperation; - - hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnCacheAcquireBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - else - { - // Verify the BA requested an action that is possible. - if (BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD == results.action && *pwzDownloadUrl && **pwzDownloadUrl || - BOOTSTRAPPER_CACHE_OPERATION_EXTRACT == results.action && wzPayloadContainerId || - BOOTSTRAPPER_CACHE_OPERATION_COPY == results.action || - BOOTSTRAPPER_CACHE_OPERATION_NONE == results.action) - { - *pCacheOperation = results.action; - } - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCacheAcquireComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z_opt LPCWSTR wzPackageOrContainerId, - __in_z_opt LPCWSTR wzPayloadId, - __in HRESULT hrStatus, - __inout BOOL* pfRetry - ) -{ - HRESULT hr = S_OK; - BA_ONCACHEACQUIRECOMPLETE_ARGS args = { }; - BA_ONCACHEACQUIRECOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageOrContainerId = wzPackageOrContainerId; - args.wzPayloadId = wzPayloadId; - args.hrStatus = hrStatus; - args.recommendation = *pfRetry ? BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION_RETRY : BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION_NONE; - - results.cbSize = sizeof(results); - results.action = args.recommendation; - - hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRECOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnCacheAcquireComplete failed."); - - if (FAILED(hrStatus)) - { - *pfRetry = BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION_RETRY == results.action; - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCacheAcquireProgress( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z_opt LPCWSTR wzPackageOrContainerId, - __in_z_opt LPCWSTR wzPayloadId, - __in DWORD64 dw64Progress, - __in DWORD64 dw64Total, - __in DWORD dwOverallPercentage - ) -{ - HRESULT hr = S_OK; - BA_ONCACHEACQUIREPROGRESS_ARGS args = { }; - BA_ONCACHEACQUIREPROGRESS_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageOrContainerId = wzPackageOrContainerId; - args.wzPayloadId = wzPayloadId; - args.dw64Progress = dw64Progress; - args.dw64Total = dw64Total; - args.dwOverallPercentage = dwOverallPercentage; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREPROGRESS, &args, &results); - ExitOnFailure(hr, "BA OnCacheAcquireProgress failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCacheAcquireResolving( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z_opt LPCWSTR wzPackageOrContainerId, - __in_z_opt LPCWSTR wzPayloadId, - __in_z LPWSTR* rgSearchPaths, - __in DWORD cSearchPaths, - __in BOOL fFoundLocal, - __in DWORD* pdwChosenSearchPath, - __in_z_opt LPWSTR* pwzDownloadUrl, - __in_z_opt LPCWSTR wzPayloadContainerId, - __inout BOOTSTRAPPER_CACHE_RESOLVE_OPERATION* pCacheOperation - ) -{ - HRESULT hr = S_OK; - BA_ONCACHEACQUIRERESOLVING_ARGS args = { }; - BA_ONCACHEACQUIRERESOLVING_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageOrContainerId = wzPackageOrContainerId; - args.wzPayloadId = wzPayloadId; - args.rgSearchPaths = const_cast(rgSearchPaths); - args.cSearchPaths = cSearchPaths; - args.fFoundLocal = fFoundLocal; - args.dwRecommendedSearchPath = *pdwChosenSearchPath; - args.wzDownloadUrl = *pwzDownloadUrl; - args.recommendation = *pCacheOperation; - - results.cbSize = sizeof(results); - results.dwChosenSearchPath = *pdwChosenSearchPath; - results.action = *pCacheOperation; - - hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRERESOLVING, &args, &results); - ExitOnFailure(hr, "BA OnCacheAcquireResolving failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - else - { - // Verify the BA requested an action that is possible. - if (BOOTSTRAPPER_CACHE_RESOLVE_DOWNLOAD == results.action && *pwzDownloadUrl && **pwzDownloadUrl || - BOOTSTRAPPER_CACHE_RESOLVE_CONTAINER == results.action && wzPayloadContainerId || - BOOTSTRAPPER_CACHE_RESOLVE_RETRY == results.action || - BOOTSTRAPPER_CACHE_RESOLVE_NONE == results.action) - { - *pCacheOperation = results.action; - } - else if (BOOTSTRAPPER_CACHE_RESOLVE_LOCAL == results.action && results.dwChosenSearchPath < cSearchPaths) - { - *pdwChosenSearchPath = results.dwChosenSearchPath; - *pCacheOperation = results.action; - } - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCacheBegin( - __in BURN_USER_EXPERIENCE* pUserExperience - ) -{ - HRESULT hr = S_OK; - BA_ONCACHEBEGIN_ARGS args = { }; - BA_ONCACHEBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnCacheBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCacheComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrStatus - ) -{ - HRESULT hr = S_OK; - BA_ONCACHECOMPLETE_ARGS args = { }; - BA_ONCACHECOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.hrStatus = hrStatus; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnCacheComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCacheContainerOrPayloadVerifyBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z_opt LPCWSTR wzPackageOrContainerId, - __in_z_opt LPCWSTR wzPayloadId - ) -{ - HRESULT hr = S_OK; - BA_ONCACHECONTAINERORPAYLOADVERIFYBEGIN_ARGS args = { }; - BA_ONCACHECONTAINERORPAYLOADVERIFYBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageOrContainerId = wzPackageOrContainerId; - args.wzPayloadId = wzPayloadId; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnCacheContainerOrPayloadVerifyBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCacheContainerOrPayloadVerifyComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z_opt LPCWSTR wzPackageOrContainerId, - __in_z_opt LPCWSTR wzPayloadId, - __in HRESULT hrStatus - ) -{ - HRESULT hr = S_OK; - BA_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE_ARGS args = { }; - BA_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageOrContainerId = wzPackageOrContainerId; - args.wzPayloadId = wzPayloadId; - args.hrStatus = hrStatus; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnCacheContainerOrPayloadVerifyComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCacheContainerOrPayloadVerifyProgress( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z_opt LPCWSTR wzPackageOrContainerId, - __in_z_opt LPCWSTR wzPayloadId, - __in DWORD64 dw64Progress, - __in DWORD64 dw64Total, - __in DWORD dwOverallPercentage - ) -{ - HRESULT hr = S_OK; - BA_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS_ARGS args = { }; - BA_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageOrContainerId = wzPackageOrContainerId; - args.wzPayloadId = wzPayloadId; - args.dw64Progress = dw64Progress; - args.dw64Total = dw64Total; - args.dwOverallPercentage = dwOverallPercentage; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS, &args, &results); - ExitOnFailure(hr, "BA OnCacheContainerOrPayloadVerifyProgress failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCachePackageBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in DWORD cCachePayloads, - __in DWORD64 dw64PackageCacheSize, - __in BOOL fVital - ) -{ - HRESULT hr = S_OK; - BA_ONCACHEPACKAGEBEGIN_ARGS args = { }; - BA_ONCACHEPACKAGEBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.cCachePayloads = cCachePayloads; - args.dw64PackageCacheSize = dw64PackageCacheSize; - args.fVital = fVital; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGEBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnCachePackageBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCachePackageComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in HRESULT hrStatus, - __inout BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION* pAction - ) -{ - HRESULT hr = S_OK; - BA_ONCACHEPACKAGECOMPLETE_ARGS args = { }; - BA_ONCACHEPACKAGECOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.hrStatus = hrStatus; - args.recommendation = *pAction; - - results.cbSize = sizeof(results); - results.action = *pAction; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGECOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnCachePackageComplete failed."); - - if (FAILED(hrStatus)) - { - *pAction = results.action; - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCachePackageNonVitalValidationFailure( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in HRESULT hrStatus, - __inout BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION* pAction - ) -{ - HRESULT hr = S_OK; - BA_ONCACHEPACKAGENONVITALVALIDATIONFAILURE_ARGS args = { }; - BA_ONCACHEPACKAGENONVITALVALIDATIONFAILURE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.hrStatus = hrStatus; - args.recommendation = *pAction; - - results.cbSize = sizeof(results); - results.action = *pAction; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGENONVITALVALIDATIONFAILURE, &args, &results); - ExitOnFailure(hr, "BA OnCachePackageNonVitalValidationFailure failed."); - - switch (results.action) - { - case BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION_NONE: __fallthrough; - case BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION_ACQUIRE: - *pAction = results.action; - break; - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCachePayloadExtractBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z_opt LPCWSTR wzContainerId, - __in_z_opt LPCWSTR wzPayloadId - ) -{ - HRESULT hr = S_OK; - BA_ONCACHEPAYLOADEXTRACTBEGIN_ARGS args = { }; - BA_ONCACHEPAYLOADEXTRACTBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzContainerId = wzContainerId; - args.wzPayloadId = wzPayloadId; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnCachePayloadExtractBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCachePayloadExtractComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z_opt LPCWSTR wzContainerId, - __in_z_opt LPCWSTR wzPayloadId, - __in HRESULT hrStatus - ) -{ - HRESULT hr = S_OK; - BA_ONCACHEPAYLOADEXTRACTCOMPLETE_ARGS args = { }; - BA_ONCACHEPAYLOADEXTRACTCOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzContainerId = wzContainerId; - args.wzPayloadId = wzPayloadId; - args.hrStatus = hrStatus; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTCOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnCachePayloadExtractComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCachePayloadExtractProgress( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z_opt LPCWSTR wzContainerId, - __in_z_opt LPCWSTR wzPayloadId, - __in DWORD64 dw64Progress, - __in DWORD64 dw64Total, - __in DWORD dwOverallPercentage - ) -{ - HRESULT hr = S_OK; - BA_ONCACHEPAYLOADEXTRACTPROGRESS_ARGS args = { }; - BA_ONCACHEPAYLOADEXTRACTPROGRESS_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzContainerId = wzContainerId; - args.wzPayloadId = wzPayloadId; - args.dw64Progress = dw64Progress; - args.dw64Total = dw64Total; - args.dwOverallPercentage = dwOverallPercentage; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTPROGRESS, &args, &results); - ExitOnFailure(hr, "BA OnCachePayloadExtractProgress failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCacheVerifyBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z_opt LPCWSTR wzPackageOrContainerId, - __in_z_opt LPCWSTR wzPayloadId - ) -{ - HRESULT hr = S_OK; - BA_ONCACHEVERIFYBEGIN_ARGS args = { }; - BA_ONCACHEVERIFYBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageOrContainerId = wzPackageOrContainerId; - args.wzPayloadId = wzPayloadId; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnCacheVerifyBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCacheVerifyComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z_opt LPCWSTR wzPackageOrContainerId, - __in_z_opt LPCWSTR wzPayloadId, - __in HRESULT hrStatus, - __inout BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION* pAction - ) -{ - HRESULT hr = S_OK; - BA_ONCACHEVERIFYCOMPLETE_ARGS args = { }; - BA_ONCACHEVERIFYCOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageOrContainerId = wzPackageOrContainerId; - args.wzPayloadId = wzPayloadId; - args.hrStatus = hrStatus; - args.recommendation = *pAction; - - results.cbSize = sizeof(results); - results.action = *pAction; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYCOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnCacheVerifyComplete failed."); - - if (FAILED(hrStatus)) - { - *pAction = results.action; - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCacheVerifyProgress( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z_opt LPCWSTR wzPackageOrContainerId, - __in_z_opt LPCWSTR wzPayloadId, - __in DWORD64 dw64Progress, - __in DWORD64 dw64Total, - __in DWORD dwOverallPercentage, - __in BOOTSTRAPPER_CACHE_VERIFY_STEP verifyStep - ) -{ - HRESULT hr = S_OK; - BA_ONCACHEVERIFYPROGRESS_ARGS args = { }; - BA_ONCACHEVERIFYPROGRESS_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageOrContainerId = wzPackageOrContainerId; - args.wzPayloadId = wzPayloadId; - args.dw64Progress = dw64Progress; - args.dw64Total = dw64Total; - args.dwOverallPercentage = dwOverallPercentage; - args.verifyStep = verifyStep; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYPROGRESS, &args, &results); - ExitOnFailure(hr, "BA OnCacheVerifyProgress failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCommitMsiTransactionBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in LPCWSTR wzTransactionId - ) -{ - HRESULT hr = S_OK; - BA_ONCOMMITMSITRANSACTIONBEGIN_ARGS args = { }; - BA_ONCOMMITMSITRANSACTIONBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzTransactionId = wzTransactionId; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCOMMITMSITRANSACTIONBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnCommitMsiTransactionBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnCommitMsiTransactionComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in LPCWSTR wzTransactionId, - __in HRESULT hrStatus, - __in BOOTSTRAPPER_APPLY_RESTART restart, - __inout BOOTSTRAPPER_EXECUTEMSITRANSACTIONCOMPLETE_ACTION* pAction -) -{ - HRESULT hr = S_OK; - BA_ONCOMMITMSITRANSACTIONCOMPLETE_ARGS args = { }; - BA_ONCOMMITMSITRANSACTIONCOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzTransactionId = wzTransactionId; - args.hrStatus = hrStatus; - args.restart = restart; - args.recommendation = *pAction; - - results.cbSize = sizeof(results); - results.action = *pAction; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCOMMITMSITRANSACTIONCOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnCommitMsiTransactionComplete failed."); - - *pAction = results.action; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnDetectBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in BOOL fCached, - __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType, - __in DWORD cPackages - ) -{ - HRESULT hr = S_OK; - BA_ONDETECTBEGIN_ARGS args = { }; - BA_ONDETECTBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.cPackages = cPackages; - args.registrationType = registrationType; - args.fCached = fCached; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnDetectBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnDetectCompatibleMsiPackage( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in_z LPCWSTR wzCompatiblePackageId, - __in VERUTIL_VERSION* pCompatiblePackageVersion - ) -{ - HRESULT hr = S_OK; - BA_ONDETECTCOMPATIBLEMSIPACKAGE_ARGS args = { }; - BA_ONDETECTCOMPATIBLEMSIPACKAGE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.wzCompatiblePackageId = wzCompatiblePackageId; - args.wzCompatiblePackageVersion = pCompatiblePackageVersion->sczVersion; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE, &args, &results); - ExitOnFailure(hr, "BA OnDetectCompatibleMsiPackage failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnDetectComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrStatus, - __in BOOL fEligibleForCleanup - ) -{ - HRESULT hr = S_OK; - BA_ONDETECTCOMPLETE_ARGS args = { }; - BA_ONDETECTCOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.hrStatus = hrStatus; - args.fEligibleForCleanup = fEligibleForCleanup; - - results.cbSize = sizeof(results); - - hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnDetectComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnDetectForwardCompatibleBundle( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzBundleId, - __in BOOTSTRAPPER_RELATION_TYPE relationType, - __in_z LPCWSTR wzBundleTag, - __in BOOL fPerMachine, - __in VERUTIL_VERSION* pVersion, - __in BOOL fMissingFromCache - ) -{ - HRESULT hr = S_OK; - BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS args = { }; - BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzBundleId = wzBundleId; - args.relationType = relationType; - args.wzBundleTag = wzBundleTag; - args.fPerMachine = fPerMachine; - args.wzVersion = pVersion->sczVersion; - args.fMissingFromCache = fMissingFromCache; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE, &args, &results); - ExitOnFailure(hr, "BA OnDetectForwardCompatibleBundle failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnDetectMsiFeature( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in_z LPCWSTR wzFeatureId, - __in BOOTSTRAPPER_FEATURE_STATE state - ) -{ - HRESULT hr = S_OK; - BA_ONDETECTMSIFEATURE_ARGS args = { }; - BA_ONDETECTMSIFEATURE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.wzFeatureId = wzFeatureId; - args.state = state; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTMSIFEATURE, &args, &results); - ExitOnFailure(hr, "BA OnDetectMsiFeature failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnDetectPackageBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId - ) -{ - HRESULT hr = S_OK; - BA_ONDETECTPACKAGEBEGIN_ARGS args = { }; - BA_ONDETECTPACKAGEBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGEBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnDetectPackageBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnDetectPackageComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in HRESULT hrStatus, - __in BOOTSTRAPPER_PACKAGE_STATE state, - __in BOOL fCached - ) -{ - HRESULT hr = S_OK; - BA_ONDETECTPACKAGECOMPLETE_ARGS args = { }; - BA_ONDETECTPACKAGECOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.hrStatus = hrStatus; - args.state = state; - args.fCached = fCached; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGECOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnDetectPackageComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnDetectRelatedBundle( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzBundleId, - __in BOOTSTRAPPER_RELATION_TYPE relationType, - __in_z LPCWSTR wzBundleTag, - __in BOOL fPerMachine, - __in VERUTIL_VERSION* pVersion, - __in BOOL fMissingFromCache - ) -{ - HRESULT hr = S_OK; - BA_ONDETECTRELATEDBUNDLE_ARGS args = { }; - BA_ONDETECTRELATEDBUNDLE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzBundleId = wzBundleId; - args.relationType = relationType; - args.wzBundleTag = wzBundleTag; - args.fPerMachine = fPerMachine; - args.wzVersion = pVersion->sczVersion; - args.fMissingFromCache = fMissingFromCache; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDBUNDLE, &args, &results); - ExitOnFailure(hr, "BA OnDetectRelatedBundle failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnDetectRelatedBundlePackage( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in_z LPCWSTR wzBundleId, - __in BOOTSTRAPPER_RELATION_TYPE relationType, - __in BOOL fPerMachine, - __in VERUTIL_VERSION* pVersion - ) -{ - HRESULT hr = S_OK; - BA_ONDETECTRELATEDBUNDLEPACKAGE_ARGS args = { }; - BA_ONDETECTRELATEDBUNDLEPACKAGE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.wzBundleId = wzBundleId; - args.relationType = relationType; - args.fPerMachine = fPerMachine; - args.wzVersion = pVersion->sczVersion; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDBUNDLEPACKAGE, &args, &results); - ExitOnFailure(hr, "BA OnDetectRelatedBundlePackage failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnDetectRelatedMsiPackage( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in_z LPCWSTR wzUpgradeCode, - __in_z LPCWSTR wzProductCode, - __in BOOL fPerMachine, - __in VERUTIL_VERSION* pVersion, - __in BOOTSTRAPPER_RELATED_OPERATION operation - ) -{ - HRESULT hr = S_OK; - BA_ONDETECTRELATEDMSIPACKAGE_ARGS args = { }; - BA_ONDETECTRELATEDMSIPACKAGE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.wzUpgradeCode = wzUpgradeCode; - args.wzProductCode = wzProductCode; - args.fPerMachine = fPerMachine; - args.wzVersion = pVersion->sczVersion; - args.operation = operation; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDMSIPACKAGE, &args, &results); - ExitOnFailure(hr, "BA OnDetectRelatedMsiPackage failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnDetectPatchTarget( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in_z LPCWSTR wzProductCode, - __in BOOTSTRAPPER_PACKAGE_STATE patchState - ) -{ - HRESULT hr = S_OK; - BA_ONDETECTPATCHTARGET_ARGS args = { }; - BA_ONDETECTPATCHTARGET_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.wzProductCode = wzProductCode; - args.patchState = patchState; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPATCHTARGET, &args, &results); - ExitOnFailure(hr, "BA OnDetectPatchTarget failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnDetectUpdate( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z_opt LPCWSTR wzUpdateLocation, - __in DWORD64 dw64Size, - __in_z_opt LPCWSTR wzHash, - __in BOOTSTRAPPER_UPDATE_HASH_TYPE hashAlgorithm, - __in VERUTIL_VERSION* pVersion, - __in_z_opt LPCWSTR wzTitle, - __in_z_opt LPCWSTR wzSummary, - __in_z_opt LPCWSTR wzContentType, - __in_z_opt LPCWSTR wzContent, - __inout BOOL* pfStopProcessingUpdates - ) -{ - HRESULT hr = S_OK; - BA_ONDETECTUPDATE_ARGS args = { }; - BA_ONDETECTUPDATE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzUpdateLocation = wzUpdateLocation; - args.dw64Size = dw64Size; - args.wzHash = wzHash; - args.hashAlgorithm = hashAlgorithm; - args.wzVersion = pVersion->sczVersion; - args.wzTitle = wzTitle; - args.wzSummary = wzSummary; - args.wzContentType = wzContentType; - args.wzContent = wzContent; - - results.cbSize = sizeof(results); - results.fStopProcessingUpdates = *pfStopProcessingUpdates; - - hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATE, &args, &results); - ExitOnFailure(hr, "BA OnDetectUpdate failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - - *pfStopProcessingUpdates = results.fStopProcessingUpdates; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnDetectUpdateBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzUpdateLocation, - __inout BOOL* pfSkip - ) -{ - HRESULT hr = S_OK; - BA_ONDETECTUPDATEBEGIN_ARGS args = { }; - BA_ONDETECTUPDATEBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzUpdateLocation = wzUpdateLocation; - - results.cbSize = sizeof(results); - results.fSkip = *pfSkip; - - hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATEBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnDetectUpdateBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - *pfSkip = results.fSkip; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnDetectUpdateComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrStatus, - __inout BOOL* pfIgnoreError - ) -{ - HRESULT hr = S_OK; - BA_ONDETECTUPDATECOMPLETE_ARGS args = { }; - BA_ONDETECTUPDATECOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.hrStatus = hrStatus; - - results.cbSize = sizeof(results); - results.fIgnoreError = *pfIgnoreError; - - hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATECOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnDetectUpdateComplete failed."); - - if (FAILED(hrStatus)) - { - *pfIgnoreError = results.fIgnoreError; - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnElevateBegin( - __in BURN_USER_EXPERIENCE* pUserExperience - ) -{ - HRESULT hr = S_OK; - BA_ONELEVATEBEGIN_ARGS args = { }; - BA_ONELEVATEBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATEBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnElevateBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnElevateComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrStatus - ) -{ - HRESULT hr = S_OK; - BA_ONELEVATECOMPLETE_ARGS args = { }; - BA_ONELEVATECOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.hrStatus = hrStatus; - - results.cbSize = sizeof(results); - - hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATECOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnElevateComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnError( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in BOOTSTRAPPER_ERROR_TYPE errorType, - __in_z_opt LPCWSTR wzPackageId, - __in DWORD dwCode, - __in_z_opt LPCWSTR wzError, - __in DWORD dwUIHint, - __in DWORD cData, - __in_ecount_z_opt(cData) LPCWSTR* rgwzData, - __inout int* pnResult - ) -{ - HRESULT hr = S_OK; - BA_ONERROR_ARGS args = { }; - BA_ONERROR_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.errorType = errorType; - args.wzPackageId = wzPackageId; - args.dwCode = dwCode; - args.wzError = wzError; - args.dwUIHint = dwUIHint; - args.cData = cData; - args.rgwzData = rgwzData; - args.nRecommendation = *pnResult; - - results.cbSize = sizeof(results); - results.nResult = *pnResult; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONERROR, &args, &results); - ExitOnFailure(hr, "BA OnError failed."); - - *pnResult = results.nResult; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnExecuteBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in DWORD cExecutingPackages - ) -{ - HRESULT hr = S_OK; - BA_ONEXECUTEBEGIN_ARGS args = { }; - BA_ONEXECUTEBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.cExecutingPackages = cExecutingPackages; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnExecuteBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnExecuteComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrStatus - ) -{ - HRESULT hr = S_OK; - BA_ONEXECUTECOMPLETE_ARGS args = { }; - BA_ONEXECUTECOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.hrStatus = hrStatus; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTECOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnExecuteComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnExecuteFilesInUse( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in DWORD cFiles, - __in_ecount_z_opt(cFiles) LPCWSTR* rgwzFiles, - __in BOOTSTRAPPER_FILES_IN_USE_TYPE source, - __inout int* pnResult - ) -{ - HRESULT hr = S_OK; - BA_ONEXECUTEFILESINUSE_ARGS args = { }; - BA_ONEXECUTEFILESINUSE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.cFiles = cFiles; - args.rgwzFiles = rgwzFiles; - args.nRecommendation = *pnResult; - args.source = source; - - results.cbSize = sizeof(results); - results.nResult = *pnResult; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEFILESINUSE, &args, &results); - ExitOnFailure(hr, "BA OnExecuteFilesInUse failed."); - - *pnResult = results.nResult; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnExecuteMsiMessage( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in INSTALLMESSAGE messageType, - __in DWORD dwUIHint, - __in_z LPCWSTR wzMessage, - __in DWORD cData, - __in_ecount_z_opt(cData) LPCWSTR* rgwzData, - __inout int* pnResult - ) -{ - HRESULT hr = S_OK; - BA_ONEXECUTEMSIMESSAGE_ARGS args = { }; - BA_ONEXECUTEMSIMESSAGE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.messageType = messageType; - args.dwUIHint = dwUIHint; - args.wzMessage = wzMessage; - args.cData = cData; - args.rgwzData = rgwzData; - args.nRecommendation = *pnResult; - - results.cbSize = sizeof(results); - results.nResult = *pnResult; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEMSIMESSAGE, &args, &results); - ExitOnFailure(hr, "BA OnExecuteMsiMessage failed."); - - *pnResult = results.nResult; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnExecutePackageBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in BOOL fExecute, - __in BOOTSTRAPPER_ACTION_STATE action, - __in INSTALLUILEVEL uiLevel, - __in BOOL fDisableExternalUiHandler - ) -{ - HRESULT hr = S_OK; - BA_ONEXECUTEPACKAGEBEGIN_ARGS args = { }; - BA_ONEXECUTEPACKAGEBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.fExecute = fExecute; - args.action = action; - args.uiLevel = uiLevel; - args.fDisableExternalUiHandler = fDisableExternalUiHandler; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGEBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnExecutePackageBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnExecutePackageComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in HRESULT hrStatus, - __in BOOTSTRAPPER_APPLY_RESTART restart, - __inout BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION* pAction - ) -{ - HRESULT hr = S_OK; - BA_ONEXECUTEPACKAGECOMPLETE_ARGS args = { }; - BA_ONEXECUTEPACKAGECOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.hrStatus = hrStatus; - args.restart = restart; - args.recommendation = *pAction; - - results.cbSize = sizeof(results); - results.action = *pAction; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGECOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnExecutePackageComplete failed."); - - *pAction = results.action; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnExecutePatchTarget( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in_z LPCWSTR wzTargetProductCode - ) -{ - HRESULT hr = S_OK; - BA_ONEXECUTEPATCHTARGET_ARGS args = { }; - BA_ONEXECUTEPATCHTARGET_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.wzTargetProductCode = wzTargetProductCode; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPATCHTARGET, &args, &results); - ExitOnFailure(hr, "BA OnExecutePatchTarget failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -BAAPI UserExperienceOnExecuteProcessCancel( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in DWORD dwProcessId, - __inout BOOTSTRAPPER_EXECUTEPROCESSCANCEL_ACTION* pAction - ) -{ - HRESULT hr = S_OK; - BA_ONEXECUTEPROCESSCANCEL_ARGS args = { }; - BA_ONEXECUTEPROCESSCANCEL_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.dwProcessId = dwProcessId; - args.recommendation = *pAction; - - results.cbSize = sizeof(results); - results.action = *pAction; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPROCESSCANCEL, &args, &results); - ExitOnFailure(hr, "BA OnExecuteProcessCancel failed."); - - *pAction = results.action; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnExecuteProgress( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in DWORD dwProgressPercentage, - __in DWORD dwOverallPercentage, - __out int* pnResult - ) -{ - HRESULT hr = S_OK; - BA_ONEXECUTEPROGRESS_ARGS args = { }; - BA_ONEXECUTEPROGRESS_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.dwProgressPercentage = dwProgressPercentage; - args.dwOverallPercentage = dwOverallPercentage; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPROGRESS, &args, &results); - ExitOnFailure(hr, "BA OnExecuteProgress failed."); - -LExit: - if (FAILED(hr)) - { - *pnResult = IDERROR; - } - else if (results.fCancel) - { - *pnResult = IDCANCEL; - } - else - { - *pnResult = IDNOACTION; - } - return hr; -} - -EXTERN_C BAAPI UserExperienceOnLaunchApprovedExeBegin( - __in BURN_USER_EXPERIENCE* pUserExperience - ) -{ - HRESULT hr = S_OK; - BA_ONLAUNCHAPPROVEDEXEBEGIN_ARGS args = { }; - BA_ONLAUNCHAPPROVEDEXEBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnLaunchApprovedExeBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnLaunchApprovedExeComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrStatus, - __in DWORD dwProcessId - ) -{ - HRESULT hr = S_OK; - BA_ONLAUNCHAPPROVEDEXECOMPLETE_ARGS args = { }; - BA_ONLAUNCHAPPROVEDEXECOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.hrStatus = hrStatus; - args.dwProcessId = dwProcessId; - - results.cbSize = sizeof(results); - - hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnLaunchApprovedExeComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPauseAUBegin( - __in BURN_USER_EXPERIENCE* pUserExperience - ) -{ - HRESULT hr = S_OK; - BA_ONPAUSEAUTOMATICUPDATESBEGIN_ARGS args = { }; - BA_ONPAUSEAUTOMATICUPDATESBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPAUSEAUTOMATICUPDATESBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnPauseAUBegin failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPauseAUComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrStatus - ) -{ - HRESULT hr = S_OK; - BA_ONPAUSEAUTOMATICUPDATESCOMPLETE_ARGS args = { }; - BA_ONPAUSEAUTOMATICUPDATESCOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.hrStatus = hrStatus; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPAUSEAUTOMATICUPDATESCOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnPauseAUComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlanBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in DWORD cPackages - ) -{ - HRESULT hr = S_OK; - BA_ONPLANBEGIN_ARGS args = { }; - BA_ONPLANBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.cPackages = cPackages; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnPlanBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlanCompatibleMsiPackageBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in_z LPCWSTR wzCompatiblePackageId, - __in VERUTIL_VERSION* pCompatiblePackageVersion, - __inout BOOL* pfRequested - ) -{ - HRESULT hr = S_OK; - BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_ARGS args = { }; - BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.wzCompatiblePackageId = wzCompatiblePackageId; - args.wzCompatiblePackageVersion = pCompatiblePackageVersion->sczVersion; - args.fRecommendedRemove = *pfRequested; - - results.cbSize = sizeof(results); - results.fRequestRemove = *pfRequested; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnPlanCompatibleMsiPackageBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - *pfRequested = results.fRequestRemove; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlanCompatibleMsiPackageComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in_z LPCWSTR wzCompatiblePackageId, - __in HRESULT hrStatus, - __in BOOL fRequested - ) -{ - HRESULT hr = S_OK; - BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_ARGS args = { }; - BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.wzCompatiblePackageId = wzCompatiblePackageId; - args.hrStatus = hrStatus; - args.fRequestedRemove = fRequested; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnPlanCompatibleMsiPackageComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlanMsiFeature( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in_z LPCWSTR wzFeatureId, - __inout BOOTSTRAPPER_FEATURE_STATE* pRequestedState - ) -{ - HRESULT hr = S_OK; - BA_ONPLANMSIFEATURE_ARGS args = { }; - BA_ONPLANMSIFEATURE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.wzFeatureId = wzFeatureId; - args.recommendedState = *pRequestedState; - - results.cbSize = sizeof(results); - results.requestedState = *pRequestedState; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIFEATURE, &args, &results); - ExitOnFailure(hr, "BA OnPlanMsiFeature failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - *pRequestedState = results.requestedState; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlanComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrStatus - ) -{ - HRESULT hr = S_OK; - BA_ONPLANCOMPLETE_ARGS args = { }; - BA_ONPLANCOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.hrStatus = hrStatus; - - results.cbSize = sizeof(results); - - hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnPlanComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlanForwardCompatibleBundle( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzBundleId, - __in BOOTSTRAPPER_RELATION_TYPE relationType, - __in_z LPCWSTR wzBundleTag, - __in BOOL fPerMachine, - __in VERUTIL_VERSION* pVersion, - __inout BOOL* pfIgnoreBundle - ) -{ - HRESULT hr = S_OK; - BA_ONPLANFORWARDCOMPATIBLEBUNDLE_ARGS args = { }; - BA_ONPLANFORWARDCOMPATIBLEBUNDLE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzBundleId = wzBundleId; - args.relationType = relationType; - args.wzBundleTag = wzBundleTag; - args.fPerMachine = fPerMachine; - args.wzVersion = pVersion->sczVersion; - args.fRecommendedIgnoreBundle = *pfIgnoreBundle; - - results.cbSize = sizeof(results); - results.fIgnoreBundle = *pfIgnoreBundle; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANFORWARDCOMPATIBLEBUNDLE, &args, &results); - ExitOnFailure(hr, "BA OnPlanForwardCompatibleBundle failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - *pfIgnoreBundle = results.fIgnoreBundle; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlanMsiPackage( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in BOOL fExecute, - __in BOOTSTRAPPER_ACTION_STATE action, - __inout BURN_MSI_PROPERTY* pActionMsiProperty, - __inout INSTALLUILEVEL* pUiLevel, - __inout BOOL* pfDisableExternalUiHandler, - __inout BOOTSTRAPPER_MSI_FILE_VERSIONING* pFileVersioning - ) -{ - HRESULT hr = S_OK; - BA_ONPLANMSIPACKAGE_ARGS args = { }; - BA_ONPLANMSIPACKAGE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.fExecute = fExecute; - args.action = action; - args.recommendedFileVersioning = *pFileVersioning; - - results.cbSize = sizeof(results); - results.actionMsiProperty = *pActionMsiProperty; - results.uiLevel = *pUiLevel; - results.fDisableExternalUiHandler = *pfDisableExternalUiHandler; - results.fileVersioning = args.recommendedFileVersioning; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIPACKAGE, &args, &results); - ExitOnFailure(hr, "BA OnPlanMsiPackage failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - *pActionMsiProperty = results.actionMsiProperty; - *pUiLevel = results.uiLevel; - *pfDisableExternalUiHandler = results.fDisableExternalUiHandler; - *pFileVersioning = results.fileVersioning; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlannedCompatiblePackage( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in_z LPCWSTR wzCompatiblePackageId, - __in BOOL fRemove - ) -{ - HRESULT hr = S_OK; - BA_ONPLANNEDCOMPATIBLEPACKAGE_ARGS args = { }; - BA_ONPLANNEDCOMPATIBLEPACKAGE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.wzCompatiblePackageId = wzCompatiblePackageId; - args.fRemove = fRemove; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE, &args, &results); - ExitOnFailure(hr, "BA OnPlannedCompatiblePackage failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlannedPackage( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in BOOTSTRAPPER_ACTION_STATE execute, - __in BOOTSTRAPPER_ACTION_STATE rollback, - __in BOOL fPlannedCache, - __in BOOL fPlannedUncache - ) -{ - HRESULT hr = S_OK; - BA_ONPLANNEDPACKAGE_ARGS args = { }; - BA_ONPLANNEDPACKAGE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.execute = execute; - args.rollback = rollback; - args.fPlannedCache = fPlannedCache; - args.fPlannedUncache = fPlannedUncache; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDPACKAGE, &args, &results); - ExitOnFailure(hr, "BA OnPlannedPackage failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlanPackageBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in BOOTSTRAPPER_PACKAGE_STATE state, - __in BOOL fCached, - __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, - __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition, - __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState, - __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType - ) -{ - HRESULT hr = S_OK; - BA_ONPLANPACKAGEBEGIN_ARGS args = { }; - BA_ONPLANPACKAGEBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.state = state; - args.fCached = fCached; - args.installCondition = installCondition; - args.repairCondition = repairCondition; - args.recommendedState = *pRequestedState; - args.recommendedCacheType = *pRequestedCacheType; - - results.cbSize = sizeof(results); - results.requestedState = *pRequestedState; - results.requestedCacheType = *pRequestedCacheType; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGEBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnPlanPackageBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - *pRequestedState = results.requestedState; - - if (BOOTSTRAPPER_CACHE_TYPE_REMOVE <= results.requestedCacheType && BOOTSTRAPPER_CACHE_TYPE_FORCE >= results.requestedCacheType) - { - *pRequestedCacheType = results.requestedCacheType; - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlanPackageComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in HRESULT hrStatus, - __in BOOTSTRAPPER_REQUEST_STATE requested - ) -{ - HRESULT hr = S_OK; - BA_ONPLANPACKAGECOMPLETE_ARGS args = { }; - BA_ONPLANPACKAGECOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.hrStatus = hrStatus; - args.requested = requested; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGECOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnPlanPackageComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlanRelatedBundle( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzBundleId, - __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState - ) -{ - HRESULT hr = S_OK; - BA_ONPLANRELATEDBUNDLE_ARGS args = { }; - BA_ONPLANRELATEDBUNDLE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzBundleId = wzBundleId; - args.recommendedState = *pRequestedState; - - results.cbSize = sizeof(results); - results.requestedState = *pRequestedState; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRELATEDBUNDLE, &args, &results); - ExitOnFailure(hr, "BA OnPlanRelatedBundle failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - *pRequestedState = results.requestedState; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlanRelatedBundleType( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzBundleId, - __inout BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE* pRequestedType - ) -{ - HRESULT hr = S_OK; - BA_ONPLANRELATEDBUNDLETYPE_ARGS args = { }; - BA_ONPLANRELATEDBUNDLETYPE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzBundleId = wzBundleId; - args.recommendedType = *pRequestedType; - - results.cbSize = sizeof(results); - results.requestedType = *pRequestedType; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRELATEDBUNDLETYPE, &args, &results); - ExitOnFailure(hr, "BA OnPlanRelatedBundleType failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - *pRequestedType = results.requestedType; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlanRestoreRelatedBundle( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzBundleId, - __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState - ) -{ - HRESULT hr = S_OK; - BA_ONPLANRESTORERELATEDBUNDLE_ARGS args = { }; - BA_ONPLANRESTORERELATEDBUNDLE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzBundleId = wzBundleId; - args.recommendedState = *pRequestedState; - - results.cbSize = sizeof(results); - results.requestedState = *pRequestedState; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRESTORERELATEDBUNDLE, &args, &results); - ExitOnFailure(hr, "BA OnPlanRestoreRelatedBundle failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - *pRequestedState = results.requestedState; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlanRollbackBoundary( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzRollbackBoundaryId, - __inout BOOL* pfTransaction - ) -{ - HRESULT hr = S_OK; - BA_ONPLANROLLBACKBOUNDARY_ARGS args = { }; - BA_ONPLANROLLBACKBOUNDARY_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzRollbackBoundaryId = wzRollbackBoundaryId; - args.fRecommendedTransaction = *pfTransaction; - - results.cbSize = sizeof(results); - results.fTransaction = *pfTransaction; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANROLLBACKBOUNDARY, &args, &results); - ExitOnFailure(hr, "BA OnPlanRollbackBoundary failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - *pfTransaction = results.fTransaction; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnPlanPatchTarget( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in_z LPCWSTR wzPackageId, - __in_z LPCWSTR wzProductCode, - __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState - ) -{ - HRESULT hr = S_OK; - BA_ONPLANPATCHTARGET_ARGS args = { }; - BA_ONPLANPATCHTARGET_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzPackageId = wzPackageId; - args.wzProductCode = wzProductCode; - args.recommendedState = *pRequestedState; - - results.cbSize = sizeof(results); - results.requestedState = *pRequestedState; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPATCHTARGET, &args, &results); - ExitOnFailure(hr, "BA OnPlanPatchTarget failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - *pRequestedState = results.requestedState; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnProgress( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in BOOL fRollback, - __in DWORD dwProgressPercentage, - __in DWORD dwOverallPercentage - ) -{ - HRESULT hr = S_OK; - BA_ONPROGRESS_ARGS args = { }; - BA_ONPROGRESS_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.dwProgressPercentage = dwProgressPercentage; - args.dwOverallPercentage = dwOverallPercentage; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPROGRESS, &args, &results); - hr = FilterExecuteResult(pUserExperience, hr, fRollback, results.fCancel, L"OnProgress"); - - return hr; -} - -EXTERN_C BAAPI UserExperienceOnRegisterBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType - ) -{ - HRESULT hr = S_OK; - BA_ONREGISTERBEGIN_ARGS args = { }; - BA_ONREGISTERBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.recommendedRegistrationType = *pRegistrationType; - - results.cbSize = sizeof(results); - results.registrationType = *pRegistrationType; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnRegisterBegin failed."); - - if (results.fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - else if (BOOTSTRAPPER_REGISTRATION_TYPE_NONE < results.registrationType && BOOTSTRAPPER_REGISTRATION_TYPE_FULL >= results.registrationType) - { - *pRegistrationType = results.registrationType; - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnRegisterComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrStatus - ) -{ - HRESULT hr = S_OK; - BA_ONREGISTERCOMPLETE_ARGS args = { }; - BA_ONREGISTERCOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.hrStatus = hrStatus; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERCOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnRegisterComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnRollbackMsiTransactionBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in LPCWSTR wzTransactionId - ) -{ - HRESULT hr = S_OK; - BA_ONROLLBACKMSITRANSACTIONBEGIN_ARGS args = { }; - BA_ONROLLBACKMSITRANSACTIONBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzTransactionId = wzTransactionId; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONROLLBACKMSITRANSACTIONBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnRollbackMsiTransactionBegin failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnRollbackMsiTransactionComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in LPCWSTR wzTransactionId, - __in HRESULT hrStatus, - __in BOOTSTRAPPER_APPLY_RESTART restart, - __inout BOOTSTRAPPER_EXECUTEMSITRANSACTIONCOMPLETE_ACTION *pAction - ) -{ - HRESULT hr = S_OK; - BA_ONROLLBACKMSITRANSACTIONCOMPLETE_ARGS args = { }; - BA_ONROLLBACKMSITRANSACTIONCOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.wzTransactionId = wzTransactionId; - args.hrStatus = hrStatus; - args.restart = restart; - args.recommendation = *pAction; - - results.cbSize = sizeof(results); - results.action = *pAction; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONROLLBACKMSITRANSACTIONCOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnRollbackMsiTransactionComplete failed."); - - *pAction = results.action; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnSetUpdateBegin( - __in BURN_USER_EXPERIENCE* pUserExperience - ) -{ - HRESULT hr = S_OK; - BA_ONSETUPDATEBEGIN_ARGS args = { }; - BA_ONSETUPDATEBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATEBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnSetUpdateBegin failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnSetUpdateComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrStatus, - __in_z_opt LPCWSTR wzPreviousPackageId, - __in_z_opt LPCWSTR wzNewPackageId - ) -{ - HRESULT hr = S_OK; - BA_ONSETUPDATECOMPLETE_ARGS args = { }; - BA_ONSETUPDATECOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.hrStatus = hrStatus; - args.wzPreviousPackageId = wzPreviousPackageId; - args.wzNewPackageId = wzNewPackageId; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATECOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnSetUpdateComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnShutdown( - __in BURN_USER_EXPERIENCE* pUserExperience, - __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction - ) -{ - HRESULT hr = S_OK; - BA_ONSHUTDOWN_ARGS args = { }; - BA_ONSHUTDOWN_RESULTS results = { }; - - args.cbSize = sizeof(args); - - results.cbSize = sizeof(results); - results.action = *pAction; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSHUTDOWN, &args, &results); - ExitOnFailure(hr, "BA OnShutdown failed."); - - *pAction = results.action; - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnStartup( - __in BURN_USER_EXPERIENCE* pUserExperience - ) -{ - HRESULT hr = S_OK; - BA_ONSTARTUP_ARGS args = { }; - BA_ONSTARTUP_RESULTS results = { }; - - args.cbSize = sizeof(args); - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSTARTUP, &args, &results); - ExitOnFailure(hr, "BA OnStartup failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnSystemRestorePointBegin( - __in BURN_USER_EXPERIENCE* pUserExperience - ) -{ - HRESULT hr = S_OK; - BA_ONSYSTEMRESTOREPOINTBEGIN_ARGS args = { }; - BA_ONSYSTEMRESTOREPOINTBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnSystemRestorePointBegin failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnSystemRestorePointComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrStatus - ) -{ - HRESULT hr = S_OK; - BA_ONSYSTEMRESTOREPOINTCOMPLETE_ARGS args = { }; - BA_ONSYSTEMRESTOREPOINTCOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.hrStatus = hrStatus; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTCOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnSystemRestorePointComplete failed."); - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnUnregisterBegin( - __in BURN_USER_EXPERIENCE* pUserExperience, - __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType - ) -{ - HRESULT hr = S_OK; - BA_ONUNREGISTERBEGIN_ARGS args = { }; - BA_ONUNREGISTERBEGIN_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.recommendedRegistrationType = *pRegistrationType; - - results.cbSize = sizeof(results); - results.registrationType = *pRegistrationType; - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERBEGIN, &args, &results); - ExitOnFailure(hr, "BA OnUnregisterBegin failed."); - - if (BOOTSTRAPPER_REGISTRATION_TYPE_NONE < results.registrationType && BOOTSTRAPPER_REGISTRATION_TYPE_FULL >= results.registrationType) - { - *pRegistrationType = results.registrationType; - } - -LExit: - return hr; -} - -EXTERN_C BAAPI UserExperienceOnUnregisterComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrStatus - ) -{ - HRESULT hr = S_OK; - BA_ONUNREGISTERCOMPLETE_ARGS args = { }; - BA_ONUNREGISTERCOMPLETE_RESULTS results = { }; - - args.cbSize = sizeof(args); - args.hrStatus = hrStatus; - - results.cbSize = sizeof(results); - - hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERCOMPLETE, &args, &results); - ExitOnFailure(hr, "BA OnUnregisterComplete failed."); - -LExit: - return hr; -} - -extern "C" int UserExperienceCheckExecuteResult( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in BOOL fRollback, - __in DWORD dwAllowedResults, - __in int nResult - ) -{ - // Do not allow canceling while rolling back. - if (fRollback && (IDCANCEL == nResult || IDABORT == nResult)) - { - nResult = IDNOACTION; - } - else if (FAILED(pUserExperience->hrApplyError) && !fRollback) // if we failed cancel except not during rollback. - { - nResult = IDCANCEL; - } - - nResult = FilterResult(dwAllowedResults, nResult); - return nResult; -} - -extern "C" HRESULT UserExperienceInterpretExecuteResult( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in BOOL fRollback, - __in DWORD dwAllowedResults, - __in int nResult - ) -{ - HRESULT hr = S_OK; - - // If we failed return that error unless this is rollback which should roll on. - if (FAILED(pUserExperience->hrApplyError) && !fRollback) - { - hr = pUserExperience->hrApplyError; - } - else - { - int nCheckedResult = UserExperienceCheckExecuteResult(pUserExperience, fRollback, dwAllowedResults, nResult); - hr = IDOK == nCheckedResult || IDNOACTION == nCheckedResult ? S_OK : IDCANCEL == nCheckedResult || IDABORT == nCheckedResult ? HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) : HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE); - } - - return hr; -} - - -// internal functions - -static int FilterResult( - __in DWORD dwAllowedResults, - __in int nResult - ) -{ - if (IDNOACTION == nResult || IDERROR == nResult) // do nothing and errors pass through. - { - } - else - { - switch (dwAllowedResults) - { - case MB_OK: - nResult = IDOK; - break; - - case MB_OKCANCEL: - if (IDOK == nResult || IDYES == nResult) - { - nResult = IDOK; - } - else if (IDCANCEL == nResult || IDABORT == nResult || IDNO == nResult) - { - nResult = IDCANCEL; - } - else - { - nResult = IDNOACTION; - } - break; - - case MB_ABORTRETRYIGNORE: - if (IDCANCEL == nResult || IDABORT == nResult) - { - nResult = IDABORT; - } - else if (IDRETRY == nResult || IDTRYAGAIN == nResult) - { - nResult = IDRETRY; - } - else if (IDIGNORE == nResult) - { - nResult = IDIGNORE; - } - else - { - nResult = IDNOACTION; - } - break; - - case MB_YESNO: - if (IDOK == nResult || IDYES == nResult) - { - nResult = IDYES; - } - else if (IDCANCEL == nResult || IDABORT == nResult || IDNO == nResult) - { - nResult = IDNO; - } - else - { - nResult = IDNOACTION; - } - break; - - case MB_YESNOCANCEL: - if (IDOK == nResult || IDYES == nResult) - { - nResult = IDYES; - } - else if (IDNO == nResult) - { - nResult = IDNO; - } - else if (IDCANCEL == nResult || IDABORT == nResult) - { - nResult = IDCANCEL; - } - else - { - nResult = IDNOACTION; - } - break; - - case MB_RETRYCANCEL: - if (IDRETRY == nResult || IDTRYAGAIN == nResult) - { - nResult = IDRETRY; - } - else if (IDCANCEL == nResult || IDABORT == nResult) - { - nResult = IDABORT; - } - else - { - nResult = IDNOACTION; - } - break; - - case MB_CANCELTRYCONTINUE: - if (IDCANCEL == nResult || IDABORT == nResult) - { - nResult = IDABORT; - } - else if (IDRETRY == nResult || IDTRYAGAIN == nResult) - { - nResult = IDRETRY; - } - else if (IDCONTINUE == nResult || IDIGNORE == nResult) - { - nResult = IDCONTINUE; - } - else - { - nResult = IDNOACTION; - } - break; - - case BURN_MB_RETRYTRYAGAIN: // custom return code. - if (IDRETRY != nResult && IDTRYAGAIN != nResult) - { - nResult = IDNOACTION; - } - break; - - default: - AssertSz(FALSE, "Unknown allowed results."); - break; - } - } - - return nResult; -} - -// This filters the BA's responses to events during apply. -// If an apply thread failed, then return its error so this thread will bail out. -// During rollback, the BA can't cancel. -static HRESULT FilterExecuteResult( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrStatus, - __in BOOL fRollback, - __in BOOL fCancel, - __in LPCWSTR sczEventName - ) -{ - HRESULT hr = hrStatus; - HRESULT hrApplyError = pUserExperience->hrApplyError; // make sure to use the same value for the whole method, since it can be changed in other threads. - - // If we failed return that error unless this is rollback which should roll on. - if (FAILED(hrApplyError) && !fRollback) - { - hr = hrApplyError; - } - else if (fRollback) - { - if (fCancel) - { - LogId(REPORT_STANDARD, MSG_APPLY_CANCEL_IGNORED_DURING_ROLLBACK, sczEventName); - } - // TODO: since cancel isn't allowed, should the BA's HRESULT be ignored as well? - // In the previous code, they could still alter rollback by returning IDERROR. - } - else - { - ExitOnFailure(hr, "BA %ls failed.", sczEventName); - - if (fCancel) - { - hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); - } - } - -LExit: - return hr; -} - -static HRESULT SendBAMessage( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in BOOTSTRAPPER_APPLICATION_MESSAGE message, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - - if (!pUserExperience->hUXModule) - { - ExitFunction(); - } - - hr = pUserExperience->pfnBAProc(message, pvArgs, pvResults, pUserExperience->pvBAProcContext); - if (hr == E_NOTIMPL) - { - hr = S_OK; - } - -LExit: - return hr; -} - -static HRESULT SendBAMessageFromInactiveEngine( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in BOOTSTRAPPER_APPLICATION_MESSAGE message, - __in const LPVOID pvArgs, - __inout LPVOID pvResults - ) -{ - HRESULT hr = S_OK; - - if (!pUserExperience->hUXModule) - { - ExitFunction(); - } - - UserExperienceDeactivateEngine(pUserExperience); - - hr = SendBAMessage(pUserExperience, message, pvArgs, pvResults); - - UserExperienceActivateEngine(pUserExperience); - -LExit: - return hr; -} +#endif + +// EXTERN_C BAAPI UserExperienceOnApplyBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in DWORD dwPhaseCount +// ) +// { +// HRESULT hr = S_OK; +// BA_ONAPPLYBEGIN_ARGS args = { }; +// BA_ONAPPLYBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.dwPhaseCount = dwPhaseCount; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnApplyBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnApplyComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in HRESULT hrStatus, +// __in BOOTSTRAPPER_APPLY_RESTART restart, +// __inout BOOTSTRAPPER_APPLYCOMPLETE_ACTION* pAction +// ) +// { +// HRESULT hr = S_OK; +// BA_ONAPPLYCOMPLETE_ARGS args = { }; +// BA_ONAPPLYCOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.hrStatus = hrStatus; +// args.restart = restart; +// args.recommendation = *pAction; + +// results.cbSize = sizeof(results); +// results.action = *pAction; + +// hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYCOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnApplyComplete failed."); + +// *pAction = results.action; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnApplyDowngrade( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __inout HRESULT* phrStatus +// ) +// { +// HRESULT hr = S_OK; +// BA_ONAPPLYDOWNGRADE_ARGS args = { }; +// BA_ONAPPLYDOWNGRADE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.hrRecommended = *phrStatus; + +// results.cbSize = sizeof(results); +// results.hrStatus = *phrStatus; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYDOWNGRADE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnApplyDowngrade failed."); + +// *phrStatus = results.hrStatus; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnBeginMsiTransactionBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in LPCWSTR wzTransactionId +// ) +// { +// HRESULT hr = S_OK; +// BA_ONBEGINMSITRANSACTIONBEGIN_ARGS args = { }; +// BA_ONBEGINMSITRANSACTIONBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzTransactionId = wzTransactionId; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONBEGINMSITRANSACTIONBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnBeginMsiTransactionBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnBeginMsiTransactionComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in LPCWSTR wzTransactionId, +// __in HRESULT hrStatus +// ) +// { +// HRESULT hr = S_OK; +// BA_ONBEGINMSITRANSACTIONCOMPLETE_ARGS args = { }; +// BA_ONBEGINMSITRANSACTIONCOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzTransactionId = wzTransactionId; +// args.hrStatus = hrStatus; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONBEGINMSITRANSACTIONCOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnBeginMsiTransactionComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCacheAcquireBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z_opt LPCWSTR wzPackageOrContainerId, +// __in_z_opt LPCWSTR wzPayloadId, +// __in_z LPWSTR* pwzSource, +// __in_z LPWSTR* pwzDownloadUrl, +// __in_z_opt LPCWSTR wzPayloadContainerId, +// __out BOOTSTRAPPER_CACHE_OPERATION* pCacheOperation +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHEACQUIREBEGIN_ARGS args = { }; +// BA_ONCACHEACQUIREBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// *pCacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE; + +// args.cbSize = sizeof(args); +// args.wzPackageOrContainerId = wzPackageOrContainerId; +// args.wzPayloadId = wzPayloadId; +// args.wzSource = *pwzSource; +// args.wzDownloadUrl = *pwzDownloadUrl; +// args.wzPayloadContainerId = wzPayloadContainerId; +// args.recommendation = *pCacheOperation; + +// results.cbSize = sizeof(results); +// results.action = *pCacheOperation; + +// hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCacheAcquireBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } +// else +// { +// // Verify the BA requested an action that is possible. +// if (BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD == results.action && *pwzDownloadUrl && **pwzDownloadUrl || +// BOOTSTRAPPER_CACHE_OPERATION_EXTRACT == results.action && wzPayloadContainerId || +// BOOTSTRAPPER_CACHE_OPERATION_COPY == results.action || +// BOOTSTRAPPER_CACHE_OPERATION_NONE == results.action) +// { +// *pCacheOperation = results.action; +// } +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCacheAcquireComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z_opt LPCWSTR wzPackageOrContainerId, +// __in_z_opt LPCWSTR wzPayloadId, +// __in HRESULT hrStatus, +// __inout BOOL* pfRetry +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHEACQUIRECOMPLETE_ARGS args = { }; +// BA_ONCACHEACQUIRECOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageOrContainerId = wzPackageOrContainerId; +// args.wzPayloadId = wzPayloadId; +// args.hrStatus = hrStatus; +// args.recommendation = *pfRetry ? BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION_RETRY : BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION_NONE; + +// results.cbSize = sizeof(results); +// results.action = args.recommendation; + +// hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRECOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCacheAcquireComplete failed."); + +// if (FAILED(hrStatus)) +// { +// *pfRetry = BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION_RETRY == results.action; +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCacheAcquireProgress( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z_opt LPCWSTR wzPackageOrContainerId, +// __in_z_opt LPCWSTR wzPayloadId, +// __in DWORD64 dw64Progress, +// __in DWORD64 dw64Total, +// __in DWORD dwOverallPercentage +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHEACQUIREPROGRESS_ARGS args = { }; +// BA_ONCACHEACQUIREPROGRESS_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageOrContainerId = wzPackageOrContainerId; +// args.wzPayloadId = wzPayloadId; +// args.dw64Progress = dw64Progress; +// args.dw64Total = dw64Total; +// args.dwOverallPercentage = dwOverallPercentage; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREPROGRESS, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCacheAcquireProgress failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCacheAcquireResolving( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z_opt LPCWSTR wzPackageOrContainerId, +// __in_z_opt LPCWSTR wzPayloadId, +// __in_z LPWSTR* rgSearchPaths, +// __in DWORD cSearchPaths, +// __in BOOL fFoundLocal, +// __in DWORD* pdwChosenSearchPath, +// __in_z_opt LPWSTR* pwzDownloadUrl, +// __in_z_opt LPCWSTR wzPayloadContainerId, +// __inout BOOTSTRAPPER_CACHE_RESOLVE_OPERATION* pCacheOperation +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHEACQUIRERESOLVING_ARGS args = { }; +// BA_ONCACHEACQUIRERESOLVING_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageOrContainerId = wzPackageOrContainerId; +// args.wzPayloadId = wzPayloadId; +// args.rgSearchPaths = const_cast(rgSearchPaths); +// args.cSearchPaths = cSearchPaths; +// args.fFoundLocal = fFoundLocal; +// args.dwRecommendedSearchPath = *pdwChosenSearchPath; +// args.wzDownloadUrl = *pwzDownloadUrl; +// args.recommendation = *pCacheOperation; + +// results.cbSize = sizeof(results); +// results.dwChosenSearchPath = *pdwChosenSearchPath; +// results.action = *pCacheOperation; + +// hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRERESOLVING, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCacheAcquireResolving failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } +// else +// { +// // Verify the BA requested an action that is possible. +// if (BOOTSTRAPPER_CACHE_RESOLVE_DOWNLOAD == results.action && *pwzDownloadUrl && **pwzDownloadUrl || +// BOOTSTRAPPER_CACHE_RESOLVE_CONTAINER == results.action && wzPayloadContainerId || +// BOOTSTRAPPER_CACHE_RESOLVE_RETRY == results.action || +// BOOTSTRAPPER_CACHE_RESOLVE_NONE == results.action) +// { +// *pCacheOperation = results.action; +// } +// else if (BOOTSTRAPPER_CACHE_RESOLVE_LOCAL == results.action && results.dwChosenSearchPath < cSearchPaths) +// { +// *pdwChosenSearchPath = results.dwChosenSearchPath; +// *pCacheOperation = results.action; +// } +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCacheBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHEBEGIN_ARGS args = { }; +// BA_ONCACHEBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCacheBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCacheComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in HRESULT hrStatus +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHECOMPLETE_ARGS args = { }; +// BA_ONCACHECOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.hrStatus = hrStatus; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCacheComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCacheContainerOrPayloadVerifyBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z_opt LPCWSTR wzPackageOrContainerId, +// __in_z_opt LPCWSTR wzPayloadId +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHECONTAINERORPAYLOADVERIFYBEGIN_ARGS args = { }; +// BA_ONCACHECONTAINERORPAYLOADVERIFYBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageOrContainerId = wzPackageOrContainerId; +// args.wzPayloadId = wzPayloadId; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCacheContainerOrPayloadVerifyBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCacheContainerOrPayloadVerifyComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z_opt LPCWSTR wzPackageOrContainerId, +// __in_z_opt LPCWSTR wzPayloadId, +// __in HRESULT hrStatus +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE_ARGS args = { }; +// BA_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageOrContainerId = wzPackageOrContainerId; +// args.wzPayloadId = wzPayloadId; +// args.hrStatus = hrStatus; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCacheContainerOrPayloadVerifyComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCacheContainerOrPayloadVerifyProgress( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z_opt LPCWSTR wzPackageOrContainerId, +// __in_z_opt LPCWSTR wzPayloadId, +// __in DWORD64 dw64Progress, +// __in DWORD64 dw64Total, +// __in DWORD dwOverallPercentage +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS_ARGS args = { }; +// BA_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageOrContainerId = wzPackageOrContainerId; +// args.wzPayloadId = wzPayloadId; +// args.dw64Progress = dw64Progress; +// args.dw64Total = dw64Total; +// args.dwOverallPercentage = dwOverallPercentage; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCacheContainerOrPayloadVerifyProgress failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCachePackageBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in DWORD cCachePayloads, +// __in DWORD64 dw64PackageCacheSize, +// __in BOOL fVital +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHEPACKAGEBEGIN_ARGS args = { }; +// BA_ONCACHEPACKAGEBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.cCachePayloads = cCachePayloads; +// args.dw64PackageCacheSize = dw64PackageCacheSize; +// args.fVital = fVital; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGEBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCachePackageBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCachePackageComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in HRESULT hrStatus, +// __inout BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION* pAction +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHEPACKAGECOMPLETE_ARGS args = { }; +// BA_ONCACHEPACKAGECOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.hrStatus = hrStatus; +// args.recommendation = *pAction; + +// results.cbSize = sizeof(results); +// results.action = *pAction; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGECOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCachePackageComplete failed."); + +// if (FAILED(hrStatus)) +// { +// *pAction = results.action; +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCachePackageNonVitalValidationFailure( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in HRESULT hrStatus, +// __inout BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION* pAction +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHEPACKAGENONVITALVALIDATIONFAILURE_ARGS args = { }; +// BA_ONCACHEPACKAGENONVITALVALIDATIONFAILURE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.hrStatus = hrStatus; +// args.recommendation = *pAction; + +// results.cbSize = sizeof(results); +// results.action = *pAction; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGENONVITALVALIDATIONFAILURE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCachePackageNonVitalValidationFailure failed."); + +// switch (results.action) +// { +// case BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION_NONE: __fallthrough; +// case BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION_ACQUIRE: +// *pAction = results.action; +// break; +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCachePayloadExtractBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z_opt LPCWSTR wzContainerId, +// __in_z_opt LPCWSTR wzPayloadId +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHEPAYLOADEXTRACTBEGIN_ARGS args = { }; +// BA_ONCACHEPAYLOADEXTRACTBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzContainerId = wzContainerId; +// args.wzPayloadId = wzPayloadId; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCachePayloadExtractBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCachePayloadExtractComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z_opt LPCWSTR wzContainerId, +// __in_z_opt LPCWSTR wzPayloadId, +// __in HRESULT hrStatus +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHEPAYLOADEXTRACTCOMPLETE_ARGS args = { }; +// BA_ONCACHEPAYLOADEXTRACTCOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzContainerId = wzContainerId; +// args.wzPayloadId = wzPayloadId; +// args.hrStatus = hrStatus; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTCOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCachePayloadExtractComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCachePayloadExtractProgress( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z_opt LPCWSTR wzContainerId, +// __in_z_opt LPCWSTR wzPayloadId, +// __in DWORD64 dw64Progress, +// __in DWORD64 dw64Total, +// __in DWORD dwOverallPercentage +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHEPAYLOADEXTRACTPROGRESS_ARGS args = { }; +// BA_ONCACHEPAYLOADEXTRACTPROGRESS_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzContainerId = wzContainerId; +// args.wzPayloadId = wzPayloadId; +// args.dw64Progress = dw64Progress; +// args.dw64Total = dw64Total; +// args.dwOverallPercentage = dwOverallPercentage; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTPROGRESS, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCachePayloadExtractProgress failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCacheVerifyBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z_opt LPCWSTR wzPackageOrContainerId, +// __in_z_opt LPCWSTR wzPayloadId +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHEVERIFYBEGIN_ARGS args = { }; +// BA_ONCACHEVERIFYBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageOrContainerId = wzPackageOrContainerId; +// args.wzPayloadId = wzPayloadId; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCacheVerifyBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCacheVerifyComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z_opt LPCWSTR wzPackageOrContainerId, +// __in_z_opt LPCWSTR wzPayloadId, +// __in HRESULT hrStatus, +// __inout BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION* pAction +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHEVERIFYCOMPLETE_ARGS args = { }; +// BA_ONCACHEVERIFYCOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageOrContainerId = wzPackageOrContainerId; +// args.wzPayloadId = wzPayloadId; +// args.hrStatus = hrStatus; +// args.recommendation = *pAction; + +// results.cbSize = sizeof(results); +// results.action = *pAction; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYCOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCacheVerifyComplete failed."); + +// if (FAILED(hrStatus)) +// { +// *pAction = results.action; +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCacheVerifyProgress( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z_opt LPCWSTR wzPackageOrContainerId, +// __in_z_opt LPCWSTR wzPayloadId, +// __in DWORD64 dw64Progress, +// __in DWORD64 dw64Total, +// __in DWORD dwOverallPercentage, +// __in BOOTSTRAPPER_CACHE_VERIFY_STEP verifyStep +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCACHEVERIFYPROGRESS_ARGS args = { }; +// BA_ONCACHEVERIFYPROGRESS_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageOrContainerId = wzPackageOrContainerId; +// args.wzPayloadId = wzPayloadId; +// args.dw64Progress = dw64Progress; +// args.dw64Total = dw64Total; +// args.dwOverallPercentage = dwOverallPercentage; +// args.verifyStep = verifyStep; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYPROGRESS, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCacheVerifyProgress failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCommitMsiTransactionBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in LPCWSTR wzTransactionId +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCOMMITMSITRANSACTIONBEGIN_ARGS args = { }; +// BA_ONCOMMITMSITRANSACTIONBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzTransactionId = wzTransactionId; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCOMMITMSITRANSACTIONBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCommitMsiTransactionBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnCommitMsiTransactionComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in LPCWSTR wzTransactionId, +// __in HRESULT hrStatus, +// __in BOOTSTRAPPER_APPLY_RESTART restart, +// __inout BOOTSTRAPPER_EXECUTEMSITRANSACTIONCOMPLETE_ACTION* pAction +// ) +// { +// HRESULT hr = S_OK; +// BA_ONCOMMITMSITRANSACTIONCOMPLETE_ARGS args = { }; +// BA_ONCOMMITMSITRANSACTIONCOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzTransactionId = wzTransactionId; +// args.hrStatus = hrStatus; +// args.restart = restart; +// args.recommendation = *pAction; + +// results.cbSize = sizeof(results); +// results.action = *pAction; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCOMMITMSITRANSACTIONCOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnCommitMsiTransactionComplete failed."); + +// *pAction = results.action; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnDetectBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in BOOL fCached, +// __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType, +// __in DWORD cPackages +// ) +// { +// HRESULT hr = S_OK; +// BA_ONDETECTBEGIN_ARGS args = { }; +// BA_ONDETECTBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.cPackages = cPackages; +// args.registrationType = registrationType; +// args.fCached = fCached; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnDetectBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnDetectCompatibleMsiPackage( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in_z LPCWSTR wzCompatiblePackageId, +// __in VERUTIL_VERSION* pCompatiblePackageVersion +// ) +// { +// HRESULT hr = S_OK; +// BA_ONDETECTCOMPATIBLEMSIPACKAGE_ARGS args = { }; +// BA_ONDETECTCOMPATIBLEMSIPACKAGE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.wzCompatiblePackageId = wzCompatiblePackageId; +// args.wzCompatiblePackageVersion = pCompatiblePackageVersion->sczVersion; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnDetectCompatibleMsiPackage failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnDetectComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in HRESULT hrStatus, +// __in BOOL fEligibleForCleanup +// ) +// { +// HRESULT hr = S_OK; +// BA_ONDETECTCOMPLETE_ARGS args = { }; +// BA_ONDETECTCOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.hrStatus = hrStatus; +// args.fEligibleForCleanup = fEligibleForCleanup; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnDetectComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnDetectForwardCompatibleBundle( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzBundleId, +// __in BOOTSTRAPPER_RELATION_TYPE relationType, +// __in_z LPCWSTR wzBundleTag, +// __in BOOL fPerMachine, +// __in VERUTIL_VERSION* pVersion, +// __in BOOL fMissingFromCache +// ) +// { +// HRESULT hr = S_OK; +// BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS args = { }; +// BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzBundleId = wzBundleId; +// args.relationType = relationType; +// args.wzBundleTag = wzBundleTag; +// args.fPerMachine = fPerMachine; +// args.wzVersion = pVersion->sczVersion; +// args.fMissingFromCache = fMissingFromCache; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnDetectForwardCompatibleBundle failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnDetectMsiFeature( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in_z LPCWSTR wzFeatureId, +// __in BOOTSTRAPPER_FEATURE_STATE state +// ) +// { +// HRESULT hr = S_OK; +// BA_ONDETECTMSIFEATURE_ARGS args = { }; +// BA_ONDETECTMSIFEATURE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.wzFeatureId = wzFeatureId; +// args.state = state; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTMSIFEATURE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnDetectMsiFeature failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnDetectPackageBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId +// ) +// { +// HRESULT hr = S_OK; +// BA_ONDETECTPACKAGEBEGIN_ARGS args = { }; +// BA_ONDETECTPACKAGEBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGEBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnDetectPackageBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnDetectPackageComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in HRESULT hrStatus, +// __in BOOTSTRAPPER_PACKAGE_STATE state, +// __in BOOL fCached +// ) +// { +// HRESULT hr = S_OK; +// BA_ONDETECTPACKAGECOMPLETE_ARGS args = { }; +// BA_ONDETECTPACKAGECOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.hrStatus = hrStatus; +// args.state = state; +// args.fCached = fCached; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGECOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnDetectPackageComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnDetectRelatedBundle( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzBundleId, +// __in BOOTSTRAPPER_RELATION_TYPE relationType, +// __in_z LPCWSTR wzBundleTag, +// __in BOOL fPerMachine, +// __in VERUTIL_VERSION* pVersion, +// __in BOOL fMissingFromCache +// ) +// { +// HRESULT hr = S_OK; +// BA_ONDETECTRELATEDBUNDLE_ARGS args = { }; +// BA_ONDETECTRELATEDBUNDLE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzBundleId = wzBundleId; +// args.relationType = relationType; +// args.wzBundleTag = wzBundleTag; +// args.fPerMachine = fPerMachine; +// args.wzVersion = pVersion->sczVersion; +// args.fMissingFromCache = fMissingFromCache; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDBUNDLE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnDetectRelatedBundle failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnDetectRelatedBundlePackage( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in_z LPCWSTR wzBundleId, +// __in BOOTSTRAPPER_RELATION_TYPE relationType, +// __in BOOL fPerMachine, +// __in VERUTIL_VERSION* pVersion +// ) +// { +// HRESULT hr = S_OK; +// BA_ONDETECTRELATEDBUNDLEPACKAGE_ARGS args = { }; +// BA_ONDETECTRELATEDBUNDLEPACKAGE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.wzBundleId = wzBundleId; +// args.relationType = relationType; +// args.fPerMachine = fPerMachine; +// args.wzVersion = pVersion->sczVersion; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDBUNDLEPACKAGE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnDetectRelatedBundlePackage failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnDetectRelatedMsiPackage( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in_z LPCWSTR wzUpgradeCode, +// __in_z LPCWSTR wzProductCode, +// __in BOOL fPerMachine, +// __in VERUTIL_VERSION* pVersion, +// __in BOOTSTRAPPER_RELATED_OPERATION operation +// ) +// { +// HRESULT hr = S_OK; +// BA_ONDETECTRELATEDMSIPACKAGE_ARGS args = { }; +// BA_ONDETECTRELATEDMSIPACKAGE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.wzUpgradeCode = wzUpgradeCode; +// args.wzProductCode = wzProductCode; +// args.fPerMachine = fPerMachine; +// args.wzVersion = pVersion->sczVersion; +// args.operation = operation; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDMSIPACKAGE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnDetectRelatedMsiPackage failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnDetectPatchTarget( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in_z LPCWSTR wzProductCode, +// __in BOOTSTRAPPER_PACKAGE_STATE patchState +// ) +// { +// HRESULT hr = S_OK; +// BA_ONDETECTPATCHTARGET_ARGS args = { }; +// BA_ONDETECTPATCHTARGET_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.wzProductCode = wzProductCode; +// args.patchState = patchState; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPATCHTARGET, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnDetectPatchTarget failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnDetectUpdate( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z_opt LPCWSTR wzUpdateLocation, +// __in DWORD64 dw64Size, +// __in_z_opt LPCWSTR wzHash, +// __in BOOTSTRAPPER_UPDATE_HASH_TYPE hashAlgorithm, +// __in VERUTIL_VERSION* pVersion, +// __in_z_opt LPCWSTR wzTitle, +// __in_z_opt LPCWSTR wzSummary, +// __in_z_opt LPCWSTR wzContentType, +// __in_z_opt LPCWSTR wzContent, +// __inout BOOL* pfStopProcessingUpdates +// ) +// { +// HRESULT hr = S_OK; +// BA_ONDETECTUPDATE_ARGS args = { }; +// BA_ONDETECTUPDATE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzUpdateLocation = wzUpdateLocation; +// args.dw64Size = dw64Size; +// args.wzHash = wzHash; +// args.hashAlgorithm = hashAlgorithm; +// args.wzVersion = pVersion->sczVersion; +// args.wzTitle = wzTitle; +// args.wzSummary = wzSummary; +// args.wzContentType = wzContentType; +// args.wzContent = wzContent; + +// results.cbSize = sizeof(results); +// results.fStopProcessingUpdates = *pfStopProcessingUpdates; + +// hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnDetectUpdate failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// *pfStopProcessingUpdates = results.fStopProcessingUpdates; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnDetectUpdateBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzUpdateLocation, +// __inout BOOL* pfSkip +// ) +// { +// HRESULT hr = S_OK; +// BA_ONDETECTUPDATEBEGIN_ARGS args = { }; +// BA_ONDETECTUPDATEBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzUpdateLocation = wzUpdateLocation; + +// results.cbSize = sizeof(results); +// results.fSkip = *pfSkip; + +// hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATEBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnDetectUpdateBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } +// *pfSkip = results.fSkip; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnDetectUpdateComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in HRESULT hrStatus, +// __inout BOOL* pfIgnoreError +// ) +// { +// HRESULT hr = S_OK; +// BA_ONDETECTUPDATECOMPLETE_ARGS args = { }; +// BA_ONDETECTUPDATECOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.hrStatus = hrStatus; + +// results.cbSize = sizeof(results); +// results.fIgnoreError = *pfIgnoreError; + +// hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATECOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnDetectUpdateComplete failed."); + +// if (FAILED(hrStatus)) +// { +// *pfIgnoreError = results.fIgnoreError; +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnElevateBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience +// ) +// { +// HRESULT hr = S_OK; +// BA_ONELEVATEBEGIN_ARGS args = { }; +// BA_ONELEVATEBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATEBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnElevateBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnElevateComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in HRESULT hrStatus +// ) +// { +// HRESULT hr = S_OK; +// BA_ONELEVATECOMPLETE_ARGS args = { }; +// BA_ONELEVATECOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.hrStatus = hrStatus; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATECOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnElevateComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnError( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in BOOTSTRAPPER_ERROR_TYPE errorType, +// __in_z_opt LPCWSTR wzPackageId, +// __in DWORD dwCode, +// __in_z_opt LPCWSTR wzError, +// __in DWORD dwUIHint, +// __in DWORD cData, +// __in_ecount_z_opt(cData) LPCWSTR* rgwzData, +// __inout int* pnResult +// ) +// { +// HRESULT hr = S_OK; +// BA_ONERROR_ARGS args = { }; +// BA_ONERROR_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.errorType = errorType; +// args.wzPackageId = wzPackageId; +// args.dwCode = dwCode; +// args.wzError = wzError; +// args.dwUIHint = dwUIHint; +// args.cData = cData; +// args.rgwzData = rgwzData; +// args.nRecommendation = *pnResult; + +// results.cbSize = sizeof(results); +// results.nResult = *pnResult; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONERROR, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnError failed."); + +// *pnResult = results.nResult; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnExecuteBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in DWORD cExecutingPackages +// ) +// { +// HRESULT hr = S_OK; +// BA_ONEXECUTEBEGIN_ARGS args = { }; +// BA_ONEXECUTEBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.cExecutingPackages = cExecutingPackages; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnExecuteBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnExecuteComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in HRESULT hrStatus +// ) +// { +// HRESULT hr = S_OK; +// BA_ONEXECUTECOMPLETE_ARGS args = { }; +// BA_ONEXECUTECOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.hrStatus = hrStatus; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTECOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnExecuteComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnExecuteFilesInUse( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in DWORD cFiles, +// __in_ecount_z_opt(cFiles) LPCWSTR* rgwzFiles, +// __in BOOTSTRAPPER_FILES_IN_USE_TYPE source, +// __inout int* pnResult +// ) +// { +// HRESULT hr = S_OK; +// BA_ONEXECUTEFILESINUSE_ARGS args = { }; +// BA_ONEXECUTEFILESINUSE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.cFiles = cFiles; +// args.rgwzFiles = rgwzFiles; +// args.nRecommendation = *pnResult; +// args.source = source; + +// results.cbSize = sizeof(results); +// results.nResult = *pnResult; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEFILESINUSE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnExecuteFilesInUse failed."); + +// *pnResult = results.nResult; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnExecuteMsiMessage( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in INSTALLMESSAGE messageType, +// __in DWORD dwUIHint, +// __in_z LPCWSTR wzMessage, +// __in DWORD cData, +// __in_ecount_z_opt(cData) LPCWSTR* rgwzData, +// __inout int* pnResult +// ) +// { +// HRESULT hr = S_OK; +// BA_ONEXECUTEMSIMESSAGE_ARGS args = { }; +// BA_ONEXECUTEMSIMESSAGE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.messageType = messageType; +// args.dwUIHint = dwUIHint; +// args.wzMessage = wzMessage; +// args.cData = cData; +// args.rgwzData = rgwzData; +// args.nRecommendation = *pnResult; + +// results.cbSize = sizeof(results); +// results.nResult = *pnResult; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEMSIMESSAGE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnExecuteMsiMessage failed."); + +// *pnResult = results.nResult; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnExecutePackageBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in BOOL fExecute, +// __in BOOTSTRAPPER_ACTION_STATE action, +// __in INSTALLUILEVEL uiLevel, +// __in BOOL fDisableExternalUiHandler +// ) +// { +// HRESULT hr = S_OK; +// BA_ONEXECUTEPACKAGEBEGIN_ARGS args = { }; +// BA_ONEXECUTEPACKAGEBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.fExecute = fExecute; +// args.action = action; +// args.uiLevel = uiLevel; +// args.fDisableExternalUiHandler = fDisableExternalUiHandler; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGEBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnExecutePackageBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnExecutePackageComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in HRESULT hrStatus, +// __in BOOTSTRAPPER_APPLY_RESTART restart, +// __inout BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION* pAction +// ) +// { +// HRESULT hr = S_OK; +// BA_ONEXECUTEPACKAGECOMPLETE_ARGS args = { }; +// BA_ONEXECUTEPACKAGECOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.hrStatus = hrStatus; +// args.restart = restart; +// args.recommendation = *pAction; + +// results.cbSize = sizeof(results); +// results.action = *pAction; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGECOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnExecutePackageComplete failed."); + +// *pAction = results.action; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnExecutePatchTarget( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in_z LPCWSTR wzTargetProductCode +// ) +// { +// HRESULT hr = S_OK; +// BA_ONEXECUTEPATCHTARGET_ARGS args = { }; +// BA_ONEXECUTEPATCHTARGET_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.wzTargetProductCode = wzTargetProductCode; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPATCHTARGET, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnExecutePatchTarget failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// BAAPI UserExperienceOnExecuteProcessCancel( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in DWORD dwProcessId, +// __inout BOOTSTRAPPER_EXECUTEPROCESSCANCEL_ACTION* pAction +// ) +// { +// HRESULT hr = S_OK; +// BA_ONEXECUTEPROCESSCANCEL_ARGS args = { }; +// BA_ONEXECUTEPROCESSCANCEL_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.dwProcessId = dwProcessId; +// args.recommendation = *pAction; + +// results.cbSize = sizeof(results); +// results.action = *pAction; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPROCESSCANCEL, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnExecuteProcessCancel failed."); + +// *pAction = results.action; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnExecuteProgress( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in DWORD dwProgressPercentage, +// __in DWORD dwOverallPercentage, +// __out int* pnResult +// ) +// { +// HRESULT hr = S_OK; +// BA_ONEXECUTEPROGRESS_ARGS args = { }; +// BA_ONEXECUTEPROGRESS_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.dwProgressPercentage = dwProgressPercentage; +// args.dwOverallPercentage = dwOverallPercentage; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPROGRESS, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnExecuteProgress failed."); + +// LExit: +// if (FAILED(hr)) +// { +// *pnResult = IDERROR; +// } +// else if (results.fCancel) +// { +// *pnResult = IDCANCEL; +// } +// else +// { +// *pnResult = IDNOACTION; +// } +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnLaunchApprovedExeBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience +// ) +// { +// HRESULT hr = S_OK; +// BA_ONLAUNCHAPPROVEDEXEBEGIN_ARGS args = { }; +// BA_ONLAUNCHAPPROVEDEXEBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnLaunchApprovedExeBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnLaunchApprovedExeComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in HRESULT hrStatus, +// __in DWORD dwProcessId +// ) +// { +// HRESULT hr = S_OK; +// BA_ONLAUNCHAPPROVEDEXECOMPLETE_ARGS args = { }; +// BA_ONLAUNCHAPPROVEDEXECOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.hrStatus = hrStatus; +// args.dwProcessId = dwProcessId; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnLaunchApprovedExeComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPauseAUBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPAUSEAUTOMATICUPDATESBEGIN_ARGS args = { }; +// BA_ONPAUSEAUTOMATICUPDATESBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPAUSEAUTOMATICUPDATESBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPauseAUBegin failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPauseAUComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in HRESULT hrStatus +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPAUSEAUTOMATICUPDATESCOMPLETE_ARGS args = { }; +// BA_ONPAUSEAUTOMATICUPDATESCOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.hrStatus = hrStatus; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPAUSEAUTOMATICUPDATESCOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPauseAUComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlanBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in DWORD cPackages +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANBEGIN_ARGS args = { }; +// BA_ONPLANBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.cPackages = cPackages; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlanBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlanCompatibleMsiPackageBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in_z LPCWSTR wzCompatiblePackageId, +// __in VERUTIL_VERSION* pCompatiblePackageVersion, +// __inout BOOL* pfRequested +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_ARGS args = { }; +// BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.wzCompatiblePackageId = wzCompatiblePackageId; +// args.wzCompatiblePackageVersion = pCompatiblePackageVersion->sczVersion; +// args.fRecommendedRemove = *pfRequested; + +// results.cbSize = sizeof(results); +// results.fRequestRemove = *pfRequested; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlanCompatibleMsiPackageBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } +// *pfRequested = results.fRequestRemove; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlanCompatibleMsiPackageComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in_z LPCWSTR wzCompatiblePackageId, +// __in HRESULT hrStatus, +// __in BOOL fRequested +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_ARGS args = { }; +// BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.wzCompatiblePackageId = wzCompatiblePackageId; +// args.hrStatus = hrStatus; +// args.fRequestedRemove = fRequested; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlanCompatibleMsiPackageComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlanMsiFeature( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in_z LPCWSTR wzFeatureId, +// __inout BOOTSTRAPPER_FEATURE_STATE* pRequestedState +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANMSIFEATURE_ARGS args = { }; +// BA_ONPLANMSIFEATURE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.wzFeatureId = wzFeatureId; +// args.recommendedState = *pRequestedState; + +// results.cbSize = sizeof(results); +// results.requestedState = *pRequestedState; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIFEATURE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlanMsiFeature failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } +// *pRequestedState = results.requestedState; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlanComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in HRESULT hrStatus +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANCOMPLETE_ARGS args = { }; +// BA_ONPLANCOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.hrStatus = hrStatus; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessageFromInactiveEngine(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlanComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlanForwardCompatibleBundle( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzBundleId, +// __in BOOTSTRAPPER_RELATION_TYPE relationType, +// __in_z LPCWSTR wzBundleTag, +// __in BOOL fPerMachine, +// __in VERUTIL_VERSION* pVersion, +// __inout BOOL* pfIgnoreBundle +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANFORWARDCOMPATIBLEBUNDLE_ARGS args = { }; +// BA_ONPLANFORWARDCOMPATIBLEBUNDLE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzBundleId = wzBundleId; +// args.relationType = relationType; +// args.wzBundleTag = wzBundleTag; +// args.fPerMachine = fPerMachine; +// args.wzVersion = pVersion->sczVersion; +// args.fRecommendedIgnoreBundle = *pfIgnoreBundle; + +// results.cbSize = sizeof(results); +// results.fIgnoreBundle = *pfIgnoreBundle; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANFORWARDCOMPATIBLEBUNDLE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlanForwardCompatibleBundle failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } +// *pfIgnoreBundle = results.fIgnoreBundle; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlanMsiPackage( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in BOOL fExecute, +// __in BOOTSTRAPPER_ACTION_STATE action, +// __inout BURN_MSI_PROPERTY* pActionMsiProperty, +// __inout INSTALLUILEVEL* pUiLevel, +// __inout BOOL* pfDisableExternalUiHandler, +// __inout BOOTSTRAPPER_MSI_FILE_VERSIONING* pFileVersioning +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANMSIPACKAGE_ARGS args = { }; +// BA_ONPLANMSIPACKAGE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.fExecute = fExecute; +// args.action = action; +// args.recommendedFileVersioning = *pFileVersioning; + +// results.cbSize = sizeof(results); +// results.actionMsiProperty = *pActionMsiProperty; +// results.uiLevel = *pUiLevel; +// results.fDisableExternalUiHandler = *pfDisableExternalUiHandler; +// results.fileVersioning = args.recommendedFileVersioning; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIPACKAGE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlanMsiPackage failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } +// *pActionMsiProperty = results.actionMsiProperty; +// *pUiLevel = results.uiLevel; +// *pfDisableExternalUiHandler = results.fDisableExternalUiHandler; +// *pFileVersioning = results.fileVersioning; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlannedCompatiblePackage( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in_z LPCWSTR wzCompatiblePackageId, +// __in BOOL fRemove +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANNEDCOMPATIBLEPACKAGE_ARGS args = { }; +// BA_ONPLANNEDCOMPATIBLEPACKAGE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.wzCompatiblePackageId = wzCompatiblePackageId; +// args.fRemove = fRemove; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlannedCompatiblePackage failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlannedPackage( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in BOOTSTRAPPER_ACTION_STATE execute, +// __in BOOTSTRAPPER_ACTION_STATE rollback, +// __in BOOL fPlannedCache, +// __in BOOL fPlannedUncache +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANNEDPACKAGE_ARGS args = { }; +// BA_ONPLANNEDPACKAGE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.execute = execute; +// args.rollback = rollback; +// args.fPlannedCache = fPlannedCache; +// args.fPlannedUncache = fPlannedUncache; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDPACKAGE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlannedPackage failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlanPackageBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in BOOTSTRAPPER_PACKAGE_STATE state, +// __in BOOL fCached, +// __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, +// __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition, +// __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState, +// __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANPACKAGEBEGIN_ARGS args = { }; +// BA_ONPLANPACKAGEBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.state = state; +// args.fCached = fCached; +// args.installCondition = installCondition; +// args.repairCondition = repairCondition; +// args.recommendedState = *pRequestedState; +// args.recommendedCacheType = *pRequestedCacheType; + +// results.cbSize = sizeof(results); +// results.requestedState = *pRequestedState; +// results.requestedCacheType = *pRequestedCacheType; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGEBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlanPackageBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } +// *pRequestedState = results.requestedState; + +// if (BOOTSTRAPPER_CACHE_TYPE_REMOVE <= results.requestedCacheType && BOOTSTRAPPER_CACHE_TYPE_FORCE >= results.requestedCacheType) +// { +// *pRequestedCacheType = results.requestedCacheType; +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlanPackageComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in HRESULT hrStatus, +// __in BOOTSTRAPPER_REQUEST_STATE requested +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANPACKAGECOMPLETE_ARGS args = { }; +// BA_ONPLANPACKAGECOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.hrStatus = hrStatus; +// args.requested = requested; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGECOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlanPackageComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlanRelatedBundle( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzBundleId, +// __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANRELATEDBUNDLE_ARGS args = { }; +// BA_ONPLANRELATEDBUNDLE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzBundleId = wzBundleId; +// args.recommendedState = *pRequestedState; + +// results.cbSize = sizeof(results); +// results.requestedState = *pRequestedState; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRELATEDBUNDLE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlanRelatedBundle failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } +// *pRequestedState = results.requestedState; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlanRelatedBundleType( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzBundleId, +// __inout BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE* pRequestedType +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANRELATEDBUNDLETYPE_ARGS args = { }; +// BA_ONPLANRELATEDBUNDLETYPE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzBundleId = wzBundleId; +// args.recommendedType = *pRequestedType; + +// results.cbSize = sizeof(results); +// results.requestedType = *pRequestedType; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRELATEDBUNDLETYPE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlanRelatedBundleType failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } +// *pRequestedType = results.requestedType; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlanRestoreRelatedBundle( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzBundleId, +// __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANRESTORERELATEDBUNDLE_ARGS args = { }; +// BA_ONPLANRESTORERELATEDBUNDLE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzBundleId = wzBundleId; +// args.recommendedState = *pRequestedState; + +// results.cbSize = sizeof(results); +// results.requestedState = *pRequestedState; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRESTORERELATEDBUNDLE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlanRestoreRelatedBundle failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } +// *pRequestedState = results.requestedState; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlanRollbackBoundary( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzRollbackBoundaryId, +// __inout BOOL* pfTransaction +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANROLLBACKBOUNDARY_ARGS args = { }; +// BA_ONPLANROLLBACKBOUNDARY_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzRollbackBoundaryId = wzRollbackBoundaryId; +// args.fRecommendedTransaction = *pfTransaction; + +// results.cbSize = sizeof(results); +// results.fTransaction = *pfTransaction; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANROLLBACKBOUNDARY, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlanRollbackBoundary failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } +// *pfTransaction = results.fTransaction; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnPlanPatchTarget( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in_z LPCWSTR wzPackageId, +// __in_z LPCWSTR wzProductCode, +// __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPLANPATCHTARGET_ARGS args = { }; +// BA_ONPLANPATCHTARGET_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzPackageId = wzPackageId; +// args.wzProductCode = wzProductCode; +// args.recommendedState = *pRequestedState; + +// results.cbSize = sizeof(results); +// results.requestedState = *pRequestedState; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPATCHTARGET, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnPlanPatchTarget failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } +// *pRequestedState = results.requestedState; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnProgress( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in BOOL fRollback, +// __in DWORD dwProgressPercentage, +// __in DWORD dwOverallPercentage +// ) +// { +// HRESULT hr = S_OK; +// BA_ONPROGRESS_ARGS args = { }; +// BA_ONPROGRESS_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.dwProgressPercentage = dwProgressPercentage; +// args.dwOverallPercentage = dwOverallPercentage; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPROGRESS, &args, args.cbSize, &result); +// hr = FilterExecuteResult(pUserExperience, hr, fRollback, results.fCancel, L"OnProgress"); + +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnRegisterBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType +// ) +// { +// HRESULT hr = S_OK; +// BA_ONREGISTERBEGIN_ARGS args = { }; +// BA_ONREGISTERBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.recommendedRegistrationType = *pRegistrationType; + +// results.cbSize = sizeof(results); +// results.registrationType = *pRegistrationType; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnRegisterBegin failed."); + +// if (results.fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } +// else if (BOOTSTRAPPER_REGISTRATION_TYPE_NONE < results.registrationType && BOOTSTRAPPER_REGISTRATION_TYPE_FULL >= results.registrationType) +// { +// *pRegistrationType = results.registrationType; +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnRegisterComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in HRESULT hrStatus +// ) +// { +// HRESULT hr = S_OK; +// BA_ONREGISTERCOMPLETE_ARGS args = { }; +// BA_ONREGISTERCOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.hrStatus = hrStatus; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERCOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnRegisterComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnRollbackMsiTransactionBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in LPCWSTR wzTransactionId +// ) +// { +// HRESULT hr = S_OK; +// BA_ONROLLBACKMSITRANSACTIONBEGIN_ARGS args = { }; +// BA_ONROLLBACKMSITRANSACTIONBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzTransactionId = wzTransactionId; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONROLLBACKMSITRANSACTIONBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnRollbackMsiTransactionBegin failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnRollbackMsiTransactionComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in LPCWSTR wzTransactionId, +// __in HRESULT hrStatus, +// __in BOOTSTRAPPER_APPLY_RESTART restart, +// __inout BOOTSTRAPPER_EXECUTEMSITRANSACTIONCOMPLETE_ACTION *pAction +// ) +// { +// HRESULT hr = S_OK; +// BA_ONROLLBACKMSITRANSACTIONCOMPLETE_ARGS args = { }; +// BA_ONROLLBACKMSITRANSACTIONCOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.wzTransactionId = wzTransactionId; +// args.hrStatus = hrStatus; +// args.restart = restart; +// args.recommendation = *pAction; + +// results.cbSize = sizeof(results); +// results.action = *pAction; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONROLLBACKMSITRANSACTIONCOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnRollbackMsiTransactionComplete failed."); + +// *pAction = results.action; + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnSetUpdateBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience +// ) +// { +// HRESULT hr = S_OK; +// BA_ONSETUPDATEBEGIN_ARGS args = { }; +// BA_ONSETUPDATEBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATEBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnSetUpdateBegin failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnSetUpdateComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in HRESULT hrStatus, +// __in_z_opt LPCWSTR wzPreviousPackageId, +// __in_z_opt LPCWSTR wzNewPackageId +// ) +// { +// HRESULT hr = S_OK; +// BA_ONSETUPDATECOMPLETE_ARGS args = { }; +// BA_ONSETUPDATECOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.hrStatus = hrStatus; +// args.wzPreviousPackageId = wzPreviousPackageId; +// args.wzNewPackageId = wzNewPackageId; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATECOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnSetUpdateComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnSystemRestorePointBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience +// ) +// { +// HRESULT hr = S_OK; +// BA_ONSYSTEMRESTOREPOINTBEGIN_ARGS args = { }; +// BA_ONSYSTEMRESTOREPOINTBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnSystemRestorePointBegin failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnSystemRestorePointComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in HRESULT hrStatus +// ) +// { +// HRESULT hr = S_OK; +// BA_ONSYSTEMRESTOREPOINTCOMPLETE_ARGS args = { }; +// BA_ONSYSTEMRESTOREPOINTCOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.hrStatus = hrStatus; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTCOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnSystemRestorePointComplete failed."); + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnUnregisterBegin( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType +// ) +// { +// HRESULT hr = S_OK; +// BA_ONUNREGISTERBEGIN_ARGS args = { }; +// BA_ONUNREGISTERBEGIN_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.recommendedRegistrationType = *pRegistrationType; + +// results.cbSize = sizeof(results); +// results.registrationType = *pRegistrationType; + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERBEGIN, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnUnregisterBegin failed."); + +// if (BOOTSTRAPPER_REGISTRATION_TYPE_NONE < results.registrationType && BOOTSTRAPPER_REGISTRATION_TYPE_FULL >= results.registrationType) +// { +// *pRegistrationType = results.registrationType; +// } + +// LExit: +// return hr; +// } + +// EXTERN_C BAAPI UserExperienceOnUnregisterComplete( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in HRESULT hrStatus +// ) +// { +// HRESULT hr = S_OK; +// BA_ONUNREGISTERCOMPLETE_ARGS args = { }; +// BA_ONUNREGISTERCOMPLETE_RESULTS results = { }; +// PIPE_RPC_RESULT result = { }; + +// args.cbSize = sizeof(args); +// args.hrStatus = hrStatus; + +// results.cbSize = sizeof(results); + +// hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERCOMPLETE, &args, args.cbSize, &result); +// ExitOnFailure(hr, "BA OnUnregisterComplete failed."); + +// LExit: +// return hr; +// } + +// extern "C" int UserExperienceCheckExecuteResult( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in BOOL fRollback, +// __in DWORD dwAllowedResults, +// __in int nResult +// ) +// { +// // Do not allow canceling while rolling back. +// if (fRollback && (IDCANCEL == nResult || IDABORT == nResult)) +// { +// nResult = IDNOACTION; +// } +// else if (FAILED(pUserExperience->hrApplyError) && !fRollback) // if we failed cancel except not during rollback. +// { +// nResult = IDCANCEL; +// } + +// nResult = FilterResult(dwAllowedResults, nResult); +// return nResult; +// } + +// extern "C" HRESULT UserExperienceInterpretExecuteResult( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in BOOL fRollback, +// __in DWORD dwAllowedResults, +// __in int nResult +// ) +// { +// HRESULT hr = S_OK; + +// // If we failed return that error unless this is rollback which should roll on. +// if (FAILED(pUserExperience->hrApplyError) && !fRollback) +// { +// hr = pUserExperience->hrApplyError; +// } +// else +// { +// int nCheckedResult = UserExperienceCheckExecuteResult(pUserExperience, fRollback, dwAllowedResults, nResult); +// hr = IDOK == nCheckedResult || IDNOACTION == nCheckedResult ? S_OK : IDCANCEL == nCheckedResult || IDABORT == nCheckedResult ? HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) : HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE); +// } + +// return hr; +// } + + +// // internal functions + +// static int FilterResult( +// __in DWORD dwAllowedResults, +// __in int nResult +// ) +// { +// if (IDNOACTION == nResult || IDERROR == nResult) // do nothing and errors pass through. +// { +// } +// else +// { +// switch (dwAllowedResults) +// { +// case MB_OK: +// nResult = IDOK; +// break; + +// case MB_OKCANCEL: +// if (IDOK == nResult || IDYES == nResult) +// { +// nResult = IDOK; +// } +// else if (IDCANCEL == nResult || IDABORT == nResult || IDNO == nResult) +// { +// nResult = IDCANCEL; +// } +// else +// { +// nResult = IDNOACTION; +// } +// break; + +// case MB_ABORTRETRYIGNORE: +// if (IDCANCEL == nResult || IDABORT == nResult) +// { +// nResult = IDABORT; +// } +// else if (IDRETRY == nResult || IDTRYAGAIN == nResult) +// { +// nResult = IDRETRY; +// } +// else if (IDIGNORE == nResult) +// { +// nResult = IDIGNORE; +// } +// else +// { +// nResult = IDNOACTION; +// } +// break; + +// case MB_YESNO: +// if (IDOK == nResult || IDYES == nResult) +// { +// nResult = IDYES; +// } +// else if (IDCANCEL == nResult || IDABORT == nResult || IDNO == nResult) +// { +// nResult = IDNO; +// } +// else +// { +// nResult = IDNOACTION; +// } +// break; + +// case MB_YESNOCANCEL: +// if (IDOK == nResult || IDYES == nResult) +// { +// nResult = IDYES; +// } +// else if (IDNO == nResult) +// { +// nResult = IDNO; +// } +// else if (IDCANCEL == nResult || IDABORT == nResult) +// { +// nResult = IDCANCEL; +// } +// else +// { +// nResult = IDNOACTION; +// } +// break; + +// case MB_RETRYCANCEL: +// if (IDRETRY == nResult || IDTRYAGAIN == nResult) +// { +// nResult = IDRETRY; +// } +// else if (IDCANCEL == nResult || IDABORT == nResult) +// { +// nResult = IDABORT; +// } +// else +// { +// nResult = IDNOACTION; +// } +// break; + +// case MB_CANCELTRYCONTINUE: +// if (IDCANCEL == nResult || IDABORT == nResult) +// { +// nResult = IDABORT; +// } +// else if (IDRETRY == nResult || IDTRYAGAIN == nResult) +// { +// nResult = IDRETRY; +// } +// else if (IDCONTINUE == nResult || IDIGNORE == nResult) +// { +// nResult = IDCONTINUE; +// } +// else +// { +// nResult = IDNOACTION; +// } +// break; + +// case BURN_MB_RETRYTRYAGAIN: // custom return code. +// if (IDRETRY != nResult && IDTRYAGAIN != nResult) +// { +// nResult = IDNOACTION; +// } +// break; + +// default: +// AssertSz(FALSE, "Unknown allowed results."); +// break; +// } +// } + +// return nResult; +// } + +// // This filters the BA's responses to events during apply. +// // If an apply thread failed, then return its error so this thread will bail out. +// // During rollback, the BA can't cancel. +// static HRESULT FilterExecuteResult( +// __in BURN_USER_EXPERIENCE* pUserExperience, +// __in HRESULT hrStatus, +// __in BOOL fRollback, +// __in BOOL fCancel, +// __in LPCWSTR sczEventName +// ) +// { +// HRESULT hr = hrStatus; +// HRESULT hrApplyError = pUserExperience->hrApplyError; // make sure to use the same value for the whole method, since it can be changed in other threads. + +// // If we failed return that error unless this is rollback which should roll on. +// if (FAILED(hrApplyError) && !fRollback) +// { +// hr = hrApplyError; +// } +// else if (fRollback) +// { +// if (fCancel) +// { +// LogId(REPORT_STANDARD, MSG_APPLY_CANCEL_IGNORED_DURING_ROLLBACK, sczEventName); +// } +// // TODO: since cancel isn't allowed, should the BA's HRESULT be ignored as well? +// // In the previous code, they could still alter rollback by returning IDERROR. +// } +// else +// { +// ExitOnFailure(hr, "BA %ls failed.", sczEventName); + +// if (fCancel) +// { +// hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); +// } +// } + +// LExit: +// return hr; +// } + +// static HRESULT SendBAMessage( +// __in BURN_USER_EXPERIENCE* /*pUserExperience*/, +// __in BOOTSTRAPPER_APPLICATION_MESSAGE /*message*/, +// __in_bcount(cbArgs) const LPVOID /*pvArgs*/, +// __in DWORD /*cbArgs*/, +// __in PIPE_RPC_RESULT* /*pResult*/ +// ) +// { +// // // HRESULT hr = S_OK; +// // // // DWORD rgResultAndSize[2] = { }; +// // // // DWORD cbSize = 0; +// // // // LPVOID pvData = NULL; +// // // // DWORD cbData = 0; + +// // // //if (!pUserExperience->hUXModule) +// // // if (!PipeRpcInitialized(&pUserExperience->hBARpcPipe)) +// // // { +// // // ExitFunction(); +// // // } + +// // // //hr = pUserExperience->pfnBAProc(message, pvArgs, pvResults, pUserExperience->pvBAProcContext); +// // // //if (hr == E_NOTIMPL) +// // // //{ +// // // // hr = S_OK; +// // // //} + +// // // // Send the message. +// // // // hr = PipeWriteMessage(hPipe, message, pvArgs, cbArgs); +// // // hr = PipeRpcRequest(&pUserExperience->hBARpcPipe, message, pvArgs, cbArgs, pResult); +// // // ExitOnFailure(hr, "Failed to write message to BA."); + +// // // #if TODO_DELETE +// // // // Read the result and size of response. +// // // hr = FileReadHandle(hPipe, reinterpret_cast(rgResultAndSize), sizeof(rgResultAndSize)); +// // // ExitOnFailure(hr, "Failed to read result and size of message."); + +// // // pResult->hr = rgResultAndSize[0]; +// // // cbSize = rgResultAndSize[1]; + +// // // // Ensure the message size isn't "too big". +// // // if (cbSize > MAX_SIZE_BA_RESPONSE) +// // // { +// // // hr = E_INVALIDDATA; +// // // ExitOnRootFailure(hr, "BA sent too much data in response."); +// // // } +// // // else if (cbSize > sizeof(DWORD)) // if there is data beyond the size of the response struct, read it. +// // // { +// // // cbData = cbSize - sizeof(DWORD); + +// // // pvData = MemAlloc(cbData, TRUE); +// // // ExitOnNull(pvData, hr, E_OUTOFMEMORY, "Failed to allocate memory for BA results."); + +// // // hr = FileReadHandle(hPipe, reinterpret_cast(pvData), cbData); +// // // ExitOnFailure(hr, "Failed to read result and size of message."); +// // // } + +// // // pResult->cbSize = cbSize; +// // // pResult->cbData = cbData; +// // // pResult->pvData = pvData; +// // // pvData = NULL; +// // // #endif + +// // // hr = pResult->hr; +// // // ExitOnFailure(hr, "BA reported failure."); + +// // // LExit: +// // // // ReleaseMem(pvData); + +// // // return hr; +// return E_NOTIMPL; +// } + +// static HRESULT SendBAMessageFromInactiveEngine( +// __in BURN_USER_EXPERIENCE* /*pUserExperience*/, +// __in BOOTSTRAPPER_APPLICATION_MESSAGE /*message*/, +// __in_bcount(cbArgs) const LPVOID /*pvArgs*/, +// __in DWORD /*cbArgs*/, +// __in PIPE_RPC_RESULT* /*pResult*/ +// ) +// { +// // // HRESULT hr = S_OK; + +// // // //if (!pUserExperience->hUXModule) +// // // if (!PipeRpcInitialized(&pUserExperience->hBARpcPipe)) +// // // { +// // // ExitFunction(); +// // // } + +// // // UserExperienceDeactivateEngine(pUserExperience); + +// // // hr = SendBAMessage(pUserExperience, message, pvArgs, cbArgs, pResult); + +// // // UserExperienceActivateEngine(pUserExperience); + +// // // LExit: +// // // return hr; +// return E_NOTIMPL; +// } diff --git a/src/burn/engine/userexperience.h b/src/burn/engine/userexperience.h index 4f15c5d7..23068e3e 100644 --- a/src/burn/engine/userexperience.h +++ b/src/burn/engine/userexperience.h @@ -1,8 +1,6 @@ #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. -#define BAAPI HRESULT __stdcall - #if defined(__cplusplus) extern "C" { #endif @@ -10,47 +8,13 @@ extern "C" { // constants -const DWORD BURN_MB_RETRYTRYAGAIN = 0x10; - // structs -typedef struct _BURN_USER_EXPERIENCE -{ - BURN_PAYLOADS payloads; - - HMODULE hUXModule; - PFN_BOOTSTRAPPER_APPLICATION_PROC pfnBAProc; - LPVOID pvBAProcContext; - LPWSTR sczTempDirectory; - - CRITICAL_SECTION csEngineActive; // Changing the engine active state in the user experience must be - // syncronized through this critical section. - // Note: The engine must never do a UX callback while in this critical section. - - BOOL fEngineActive; // Indicates that the engine is currently active with one of the execution - // steps (detect, plan, apply), and cannot accept requests from the UX. - // This flag should be cleared by the engine prior to UX callbacks that - // allows altering of the engine state. - - HRESULT hrApplyError; // Tracks is an error occurs during apply that requires the cache or - // execute threads to bail. - - HWND hwndApply; // The window handle provided at the beginning of Apply(). Only valid - // during apply. - - HWND hwndDetect; // The window handle provided at the beginning of Detect(). Only valid - // during Detect. - - DWORD dwExitCode; // Exit code returned by the user experience for the engine overall. -} BURN_USER_EXPERIENCE; // functions -HRESULT UserExperienceParseFromXml( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in IXMLDOMNode* pixnBundle - ); +#ifdef TODO_DELETE void UserExperienceUninitialize( __in BURN_USER_EXPERIENCE* pUserExperience ); @@ -63,43 +27,7 @@ HRESULT UserExperienceUnload( __in BURN_USER_EXPERIENCE* pUserExperience, __in BOOL fReload ); -HRESULT UserExperienceEnsureWorkingFolder( - __in BURN_CACHE* pCache, - __deref_out_z LPWSTR* psczUserExperienceWorkingFolder - ); -HRESULT UserExperienceRemove( - __in BURN_USER_EXPERIENCE* pUserExperience - ); -int UserExperienceSendError( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in BOOTSTRAPPER_ERROR_TYPE errorType, - __in_z_opt LPCWSTR wzPackageId, - __in HRESULT hrCode, - __in_z_opt LPCWSTR wzError, - __in DWORD uiFlags, - __in int nRecommendation - ); -void UserExperienceActivateEngine( - __in BURN_USER_EXPERIENCE* pUserExperience - ); -void UserExperienceDeactivateEngine( - __in BURN_USER_EXPERIENCE* pUserExperience - ); -/******************************************************************** - UserExperienceEnsureEngineInactive - Verifies the engine is inactive. - The caller MUST enter the csActive critical section before calling. -*********************************************************************/ -HRESULT UserExperienceEnsureEngineInactive( - __in BURN_USER_EXPERIENCE* pUserExperience - ); -void UserExperienceExecuteReset( - __in BURN_USER_EXPERIENCE* pUserExperience - ); -void UserExperienceExecutePhaseComplete( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in HRESULT hrResult - ); BAAPI UserExperienceOnApplyBegin( __in BURN_USER_EXPERIENCE* pUserExperience, __in DWORD dwPhaseCount @@ -604,18 +532,8 @@ BAAPI UserExperienceOnUnregisterComplete( __in BURN_USER_EXPERIENCE* pUserExperience, __in HRESULT hrStatus ); -int UserExperienceCheckExecuteResult( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in BOOL fRollback, - __in DWORD dwAllowedResults, - __in int nResult - ); -HRESULT UserExperienceInterpretExecuteResult( - __in BURN_USER_EXPERIENCE* pUserExperience, - __in BOOL fRollback, - __in DWORD dwAllowedResults, - __in int nResult - ); +#endif + #if defined(__cplusplus) } #endif diff --git a/src/burn/engine/variable.cpp b/src/burn/engine/variable.cpp index 36dc92e0..9d0aec52 100644 --- a/src/burn/engine/variable.cpp +++ b/src/burn/engine/variable.cpp @@ -302,8 +302,6 @@ extern "C" HRESULT VariableInitialize( {BURN_BUNDLE_ELEVATED, InitializeVariableNumeric, 0, FALSE, TRUE}, {BURN_BUNDLE_ACTIVE_PARENT, InitializeVariableString, NULL, FALSE, TRUE}, {BURN_BUNDLE_PROVIDER_KEY, InitializeVariableString, (DWORD_PTR)L"", FALSE, TRUE}, - {BURN_BUNDLE_SOURCE_PROCESS_PATH, InitializeVariableString, NULL, FALSE, TRUE}, - {BURN_BUNDLE_SOURCE_PROCESS_FOLDER, InitializeVariableString, NULL, FALSE, TRUE}, {BURN_BUNDLE_TAG, InitializeVariableString, (DWORD_PTR)L"", FALSE, TRUE}, {BURN_BUNDLE_UILEVEL, InitializeVariableNumeric, 0, FALSE, TRUE}, {BURN_BUNDLE_VERSION, InitializeVariableVersion, (DWORD_PTR)L"0", FALSE, TRUE}, @@ -1950,13 +1948,13 @@ static HRESULT InitializeVariableNativeMachine( ) { UNREFERENCED_PARAMETER(dwpData); - + HRESULT hr = S_OK; USHORT usNativeMachine = IMAGE_FILE_MACHINE_UNKNOWN; hr = ProcNativeMachine(::GetCurrentProcess(), &usNativeMachine); ExitOnFailure(hr, "Failed to get native machine value."); - + if (S_FALSE != hr) { hr = BVariantSetNumeric(pValue, usNativeMachine); diff --git a/src/burn/stub/stub.cpp b/src/burn/stub/stub.cpp index 9c9dfeef..d8cee9f1 100644 --- a/src/burn/stub/stub.cpp +++ b/src/burn/stub/stub.cpp @@ -41,20 +41,7 @@ int WINAPI wWinMain( hEngineFile = ::CreateFileW(sczPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } - // If the engine is in the clean room, we'll do the unsafe initialization - // because some systems in Windows (namely GDI+) will fail when run in - // a process that protects against DLL hijacking. Since we know the clean - // room is in a clean folder and not subject to DLL hijacking we won't - // make ourselves perfectly secure so that we can load BAs that still - // depend on those parts of Windows that are insecure to DLL hijacking. - if (EngineInCleanRoom(lpCmdLine)) - { - AppInitializeUnsafe(); - } - else - { - AppInitialize(rgsczSafelyLoadSystemDlls, countof(rgsczSafelyLoadSystemDlls)); - } + AppInitialize(rgsczSafelyLoadSystemDlls, countof(rgsczSafelyLoadSystemDlls)); AvoidLocalDllRedirection(sczPath); diff --git a/src/burn/stub/stub.manifest b/src/burn/stub/stub.manifest new file mode 100644 index 00000000..9718e9b1 --- /dev/null +++ b/src/burn/stub/stub.manifest @@ -0,0 +1,18 @@ + + + + WiX Toolset Bootstrapper Engine + + + + + + + + + true/pm + PerMonitorV2, PerMonitor, System + true + + + diff --git a/src/burn/stub/stub.vcxproj b/src/burn/stub/stub.vcxproj index 03f49209..d07b8da7 100644 --- a/src/burn/stub/stub.vcxproj +++ b/src/burn/stub/stub.vcxproj @@ -35,7 +35,6 @@ Windows burn Unicode - false Native component of WixToolset.Burn 1033 @@ -62,7 +61,7 @@ true true - cabinet.dll;crypt32.dll;msi.dll;shlwapi.dll;userenv.dll;version.dll;wininet.dll;wintrust.dll + cabinet.dll;crypt32.dll;msi.dll;rpcrt4.dll;shlwapi.dll;userenv.dll;version.dll;wininet.dll;wintrust.dll /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) @@ -81,6 +80,7 @@ + @@ -91,9 +91,8 @@ - - + diff --git a/src/burn/test/BurnUnitTest/ElevationTest.cpp b/src/burn/test/BurnUnitTest/ElevationTest.cpp index 77aac423..f9ae2579 100644 --- a/src/burn/test/BurnUnitTest/ElevationTest.cpp +++ b/src/burn/test/BurnUnitTest/ElevationTest.cpp @@ -2,7 +2,6 @@ #include "precomp.h" - const DWORD TEST_CHILD_SENT_MESSAGE_ID = 0xFFFE; const DWORD TEST_PARENT_SENT_MESSAGE_ID = 0xFFFF; const HRESULT S_TEST_SUCCEEDED = 0x3133; diff --git a/src/burn/test/BurnUnitTest/EmbeddedTest.cpp b/src/burn/test/BurnUnitTest/EmbeddedTest.cpp index 8d70cbab..a19790ad 100644 --- a/src/burn/test/BurnUnitTest/EmbeddedTest.cpp +++ b/src/burn/test/BurnUnitTest/EmbeddedTest.cpp @@ -2,7 +2,6 @@ #include "precomp.h" - const DWORD TEST_UNKNOWN_MESSAGE_ID = 0xFFFE; const HRESULT S_TEST_SUCCEEDED = 0x3133; const DWORD TEST_EXIT_CODE = 666; diff --git a/src/burn/test/BurnUnitTest/ExitCodeTest.cpp b/src/burn/test/BurnUnitTest/ExitCodeTest.cpp index 4ff78c5a..c742543b 100644 --- a/src/burn/test/BurnUnitTest/ExitCodeTest.cpp +++ b/src/burn/test/BurnUnitTest/ExitCodeTest.cpp @@ -2,7 +2,6 @@ #include "precomp.h" - namespace Microsoft { namespace Tools diff --git a/src/burn/test/BurnUnitTest/ManifestTest.cpp b/src/burn/test/BurnUnitTest/ManifestTest.cpp index 67e9c25f..87484472 100644 --- a/src/burn/test/BurnUnitTest/ManifestTest.cpp +++ b/src/burn/test/BurnUnitTest/ManifestTest.cpp @@ -37,8 +37,8 @@ namespace Bootstrapper "yes" #endif "'>" - " " - " " + " " + " " " " " " "