From c2b00d75493798d9f2452d5e5014b14afcb14889 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Wed, 5 Jan 2022 21:51:00 -0600 Subject: Always run upgrade related bundles last. #5128 --- src/burn/engine/relatedbundle.cpp | 55 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'src/burn/engine/relatedbundle.cpp') diff --git a/src/burn/engine/relatedbundle.cpp b/src/burn/engine/relatedbundle.cpp index e2380aab..1eafef07 100644 --- a/src/burn/engine/relatedbundle.cpp +++ b/src/burn/engine/relatedbundle.cpp @@ -4,6 +4,11 @@ // internal function declarations +static __callback int __cdecl CompareRelatedBundles( + __in void* pvContext, + __in const void* pvLeft, + __in const void* pvRight + ); static HRESULT LoadIfRelatedBundle( __in BOOL fPerMachine, __in HKEY hkUninstallKey, @@ -128,9 +133,59 @@ LExit: return hr; } +extern "C" void RelatedBundlesSort( + __in BURN_RELATED_BUNDLES* pRelatedBundles + ) +{ + qsort_s(pRelatedBundles->rgRelatedBundles, pRelatedBundles->cRelatedBundles, sizeof(BURN_RELATED_BUNDLE), CompareRelatedBundles, NULL); +} + // internal helper functions +static __callback int __cdecl CompareRelatedBundles( + __in void* /*pvContext*/, + __in const void* pvLeft, + __in const void* pvRight + ) +{ + int ret = 0; + const BURN_RELATED_BUNDLE* pBundleLeft = static_cast(pvLeft); + const BURN_RELATED_BUNDLE* pBundleRight = static_cast(pvRight); + + // Sort by relation type, then version, then bundle id. + if (pBundleLeft->relationType != pBundleRight->relationType) + { + // Upgrade bundles last, everything else according to the enum. + if (BOOTSTRAPPER_RELATION_UPGRADE == pBundleLeft->relationType) + { + ret = 1; + } + else if (BOOTSTRAPPER_RELATION_UPGRADE == pBundleRight->relationType) + { + ret = -1; + } + else if (pBundleLeft->relationType < pBundleRight->relationType) + { + ret = -1; + } + else + { + ret = 1; + } + } + else + { + VerCompareParsedVersions(pBundleLeft->pVersion, pBundleRight->pVersion, &ret); + if (0 == ret) + { + ret = ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pBundleLeft->package.sczId, -1, pBundleRight->package.sczId, -1) - 2; + } + } + + return ret; +} + static HRESULT LoadIfRelatedBundle( __in BOOL fPerMachine, __in HKEY hkUninstallKey, -- cgit v1.2.3-55-g6feb