From eee408f4f52823038ca6da83693efd135c8511c8 Mon Sep 17 00:00:00 2001 From: Sean Hall <r.sean.hall@gmail.com> Date: Sun, 16 Jan 2022 14:08:45 -0600 Subject: Make Burn require a non-empty KB for MsuPackages to be uninstallable. --- src/burn/engine/msuengine.cpp | 21 ++++++++++++++------- src/burn/engine/package.cpp | 6 +++++- src/burn/engine/package.h | 1 + 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/burn/engine/msuengine.cpp b/src/burn/engine/msuengine.cpp index 4db425be..44386a6d 100644 --- a/src/burn/engine/msuengine.cpp +++ b/src/burn/engine/msuengine.cpp @@ -39,6 +39,17 @@ extern "C" HRESULT MsuEngineParsePackageFromXml( hr = XmlGetAttributeEx(pixnMsuPackage, L"DetectCondition", &pPackage->Msu.sczDetectCondition); ExitOnFailure(hr, "Failed to get @DetectCondition."); + // We can only uninstall MSU packages if they have a KB and we are on Win7 or newer. + if (pPackage->Msu.sczKB && *pPackage->Msu.sczKB && ::IsWindows7OrGreater()) + { + pPackage->Msu.fUninstallable = TRUE; + } + else + { + pPackage->fPermanent = TRUE; + pPackage->Msu.fUninstallable = FALSE; + } + LExit: return hr; } @@ -92,10 +103,6 @@ extern "C" HRESULT MsuEnginePlanCalculatePackage( HRESULT hr = S_OK; BOOTSTRAPPER_ACTION_STATE execute = BOOTSTRAPPER_ACTION_STATE_NONE; BOOTSTRAPPER_ACTION_STATE rollback = BOOTSTRAPPER_ACTION_STATE_NONE; - BOOL fAllowUninstall = FALSE; - - // We can only uninstall MSU packages if they have a KB and we are on Win7 or newer. - fAllowUninstall = pPackage->Msu.sczKB && *pPackage->Msu.sczKB && ::IsWindows7OrGreater(); // execute action switch (pPackage->currentState) @@ -110,11 +117,11 @@ extern "C" HRESULT MsuEnginePlanCalculatePackage( case BOOTSTRAPPER_REQUEST_STATE_ABSENT: __fallthrough; case BOOTSTRAPPER_REQUEST_STATE_CACHE: - execute = fAllowUninstall && !pPackage->fPermanent ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; + execute = !pPackage->fPermanent ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; break; case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: - execute = fAllowUninstall ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; + execute = pPackage->Msu.fUninstallable ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; break; default: @@ -166,7 +173,7 @@ extern "C" HRESULT MsuEnginePlanCalculatePackage( { case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: - rollback = fAllowUninstall ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; + rollback = !pPackage->fPermanent ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; break; default: diff --git a/src/burn/engine/package.cpp b/src/burn/engine/package.cpp index 72da817f..8a80194e 100644 --- a/src/burn/engine/package.cpp +++ b/src/burn/engine/package.cpp @@ -161,7 +161,6 @@ extern "C" HRESULT PackagesParseFromXml( // @Permanent hr = XmlGetYesNoAttribute(pixnNode, L"Permanent", &pPackage->fPermanent); ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Permanent."); - pPackage->fCanAffectRegistration = !pPackage->fPermanent; // @Vital hr = XmlGetYesNoAttribute(pixnNode, L"Vital", &pPackage->fVital); @@ -244,6 +243,9 @@ extern "C" HRESULT PackagesParseFromXml( case BURN_PACKAGE_TYPE_EXE: fUninstallable = pPackage->Exe.fUninstallable; break; + case BURN_PACKAGE_TYPE_MSU: + fUninstallable = pPackage->Msu.fUninstallable; + break; } if (!fUninstallable) @@ -252,6 +254,8 @@ extern "C" HRESULT PackagesParseFromXml( } } + pPackage->fCanAffectRegistration = !pPackage->fPermanent; + // 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 91bad1bc..bbd74ac9 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h @@ -371,6 +371,7 @@ typedef struct _BURN_PACKAGE { LPWSTR sczDetectCondition; LPWSTR sczKB; + BOOL fUninstallable; } Msu; }; } BURN_PACKAGE; -- cgit v1.2.3-55-g6feb