From f5d880cc70ad7350b0da1ea825141f95cbdb4c7b Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Sun, 16 Jan 2022 12:17:27 -0600 Subject: Update Burn to handle ExePackages that don't support uninstalling. Partial fix for #6459 --- src/burn/engine/exeengine.cpp | 44 ++++++++++++++++++++++------------------ src/burn/engine/package.cpp | 17 ++++++++++++++++ src/burn/engine/package.h | 1 + src/burn/engine/pseudobundle.cpp | 1 + 4 files changed, 43 insertions(+), 20 deletions(-) (limited to 'src/burn') diff --git a/src/burn/engine/exeengine.cpp b/src/burn/engine/exeengine.cpp index 7a36f882..cf10448f 100644 --- a/src/burn/engine/exeengine.cpp +++ b/src/burn/engine/exeengine.cpp @@ -11,36 +11,43 @@ extern "C" HRESULT ExeEngineParsePackageFromXml( ) { HRESULT hr = S_OK; + BOOL fFoundXml = FALSE; IXMLDOMNodeList* pixnNodes = NULL; IXMLDOMNode* pixnNode = NULL; LPWSTR scz = NULL; // @DetectCondition hr = XmlGetAttributeEx(pixnExePackage, L"DetectCondition", &pPackage->Exe.sczDetectCondition); - ExitOnFailure(hr, "Failed to get @DetectCondition."); + ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @DetectCondition."); // @InstallArguments hr = XmlGetAttributeEx(pixnExePackage, L"InstallArguments", &pPackage->Exe.sczInstallArguments); - ExitOnFailure(hr, "Failed to get @InstallArguments."); + ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallArguments."); // @UninstallArguments hr = XmlGetAttributeEx(pixnExePackage, L"UninstallArguments", &pPackage->Exe.sczUninstallArguments); - ExitOnFailure(hr, "Failed to get @UninstallArguments."); + ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @UninstallArguments."); // @RepairArguments hr = XmlGetAttributeEx(pixnExePackage, L"RepairArguments", &pPackage->Exe.sczRepairArguments); - ExitOnFailure(hr, "Failed to get @RepairArguments."); + ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RepairArguments."); // @Repairable hr = XmlGetYesNoAttribute(pixnExePackage, L"Repairable", &pPackage->Exe.fRepairable); - if (E_NOTFOUND != hr) - { - ExitOnFailure(hr, "Failed to get @Repairable."); - } + ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @Repairable."); + + // @Uninstallable + pPackage->Exe.fUninstallable = TRUE; // TODO: https://github.com/wixtoolset/issues/issues/6459 + /* + hr = XmlGetYesNoAttribute(pixnNode, L"Uninstallable", &pPackage->Exe.fUninstallable); + ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @Uninstallable."); + */ // @Protocol hr = XmlGetAttributeEx(pixnExePackage, L"Protocol", &scz); - if (SUCCEEDED(hr)) + ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @Protocol."); + + if (fFoundXml) { if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"burn", -1)) { @@ -60,10 +67,6 @@ extern "C" HRESULT ExeEngineParsePackageFromXml( ExitOnFailure(hr, "Invalid protocol type: %ls", scz); } } - else if (E_NOTFOUND != hr) - { - ExitOnFailure(hr, "Failed to get @Protocol."); - } hr = ExeEngineParseExitCodesFromXml(pixnExePackage, &pPackage->Exe.rgExitCodes, &pPackage->Exe.cExitCodes); ExitOnFailure(hr, "Failed to parse exit codes."); @@ -172,7 +175,7 @@ extern "C" HRESULT ExeEnginePlanCalculatePackage( execute = !pPackage->fPermanent ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; break; case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: - execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; + execute = pPackage->Exe.fUninstallable ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; break; default: execute = BOOTSTRAPPER_ACTION_STATE_NONE; @@ -552,11 +555,11 @@ extern "C" HRESULT ExeEngineParseExitCodesFromXml( // @Type hr = XmlGetAttributeNumber(pixnNode, L"Type", (DWORD*)&pExitCode->type); - ExitOnFailure(hr, "Failed to get @Type."); + ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Type."); // @Code hr = XmlGetAttributeEx(pixnNode, L"Code", &scz); - ExitOnFailure(hr, "Failed to get @Code."); + ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Code."); if (L'*' == scz[0]) { @@ -614,25 +617,26 @@ extern "C" HRESULT ExeEngineParseCommandLineArgumentsFromXml( for (DWORD i = 0; i < cNodes; ++i) { BURN_EXE_COMMAND_LINE_ARGUMENT* pCommandLineArgument = *prgCommandLineArguments + i; + BOOL fFoundXml = FALSE; hr = XmlNextElement(pixnNodes, &pixnNode, NULL); ExitOnFailure(hr, "Failed to get next command-line argument node."); // @InstallArgument hr = XmlGetAttributeEx(pixnNode, L"InstallArgument", &pCommandLineArgument->sczInstallArgument); - ExitOnFailure(hr, "Failed to get @InstallArgument."); + ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallArgument."); // @UninstallArgument hr = XmlGetAttributeEx(pixnNode, L"UninstallArgument", &pCommandLineArgument->sczUninstallArgument); - ExitOnFailure(hr, "Failed to get @UninstallArgument."); + ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @UninstallArgument."); // @RepairArgument hr = XmlGetAttributeEx(pixnNode, L"RepairArgument", &pCommandLineArgument->sczRepairArgument); - ExitOnFailure(hr, "Failed to get @RepairArgument."); + ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RepairArgument."); // @Condition hr = XmlGetAttributeEx(pixnNode, L"Condition", &pCommandLineArgument->sczCondition); - ExitOnFailure(hr, "Failed to get @Condition."); + ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Condition."); // Prepare next iteration. ReleaseNullObject(pixnNode); diff --git a/src/burn/engine/package.cpp b/src/burn/engine/package.cpp index 20b728f4..72da817f 100644 --- a/src/burn/engine/package.cpp +++ b/src/burn/engine/package.cpp @@ -235,6 +235,23 @@ extern "C" HRESULT PackagesParseFromXml( // ignore other package types for now } + if (!pPackage->fPermanent) + { + BOOL fUninstallable = TRUE; + + switch (pPackage->type) + { + case BURN_PACKAGE_TYPE_EXE: + fUninstallable = pPackage->Exe.fUninstallable; + break; + } + + if (!fUninstallable) + { + ExitWithRootFailure(hr, E_INVALIDDATA, "Non-permanent packages must be uninstallable."); + } + } + // parse payload references hr = ParsePayloadRefsFromXml(pPackage, pPayloads, pixnNode); ExitOnFailure(hr, "Failed to parse payload references."); diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h index 5a7aefa3..91bad1bc 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h @@ -323,6 +323,7 @@ typedef struct _BURN_PACKAGE BOOL fPseudoBundle; BOOL fFireAndForget; BOOL fRepairable; + BOOL fUninstallable; BURN_EXE_PROTOCOL_TYPE protocol; BURN_EXE_EXIT_CODE* rgExitCodes; diff --git a/src/burn/engine/pseudobundle.cpp b/src/burn/engine/pseudobundle.cpp index b343f810..153d76e6 100644 --- a/src/burn/engine/pseudobundle.cpp +++ b/src/burn/engine/pseudobundle.cpp @@ -115,6 +115,7 @@ extern "C" HRESULT PseudoBundleInitializePassthrough( pPassthroughPackage->fPermanent = TRUE; pPassthroughPackage->Exe.fPseudoBundle = TRUE; + pPassthroughPackage->Exe.fUninstallable = FALSE; pPassthroughPackage->Exe.protocol = pPackage->Bundle.fSupportsBurnProtocol ? BURN_EXE_PROTOCOL_TYPE_BURN : BURN_EXE_PROTOCOL_TYPE_NONE; hr = StrAllocString(&pPassthroughPackage->sczId, pPackage->sczId, 0); -- cgit v1.2.3-55-g6feb