diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2022-03-13 23:45:32 -0500 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2022-03-14 14:53:29 -0500 |
| commit | 4cd1c4e06145434ca940ac828772dc47b9d9738e (patch) | |
| tree | a754d685039173c63303dc6d0d8b1a2bf3ab506b /src/burn/engine/relatedbundle.cpp | |
| parent | 89adb2e3cc232b11b28e5bdeccb0c522c8124a29 (diff) | |
| download | wix-4cd1c4e06145434ca940ac828772dc47b9d9738e.tar.gz wix-4cd1c4e06145434ca940ac828772dc47b9d9738e.tar.bz2 wix-4cd1c4e06145434ca940ac828772dc47b9d9738e.zip | |
Allow the BA to override the bundle relation type during plan.
Diffstat (limited to 'src/burn/engine/relatedbundle.cpp')
| -rw-r--r-- | src/burn/engine/relatedbundle.cpp | 105 |
1 files changed, 93 insertions, 12 deletions
diff --git a/src/burn/engine/relatedbundle.cpp b/src/burn/engine/relatedbundle.cpp index e6633131..58911711 100644 --- a/src/burn/engine/relatedbundle.cpp +++ b/src/burn/engine/relatedbundle.cpp | |||
| @@ -10,11 +10,16 @@ typedef struct _BUNDLE_QUERY_CONTEXT | |||
| 10 | 10 | ||
| 11 | // internal function declarations | 11 | // internal function declarations |
| 12 | 12 | ||
| 13 | static __callback int __cdecl CompareRelatedBundles( | 13 | static __callback int __cdecl CompareRelatedBundlesDetect( |
| 14 | __in void* pvContext, | 14 | __in void* pvContext, |
| 15 | __in const void* pvLeft, | 15 | __in const void* pvLeft, |
| 16 | __in const void* pvRight | 16 | __in const void* pvRight |
| 17 | ); | 17 | ); |
| 18 | static __callback int __cdecl CompareRelatedBundlesPlan( | ||
| 19 | __in void* /*pvContext*/, | ||
| 20 | __in const void* pvLeft, | ||
| 21 | __in const void* pvRight | ||
| 22 | ); | ||
| 18 | static BUNDLE_QUERY_CALLBACK_RESULT CALLBACK QueryRelatedBundlesCallback( | 23 | static BUNDLE_QUERY_CALLBACK_RESULT CALLBACK QueryRelatedBundlesCallback( |
| 19 | __in const BUNDLE_QUERY_RELATED_BUNDLE_RESULT* pBundle, | 24 | __in const BUNDLE_QUERY_RELATED_BUNDLE_RESULT* pBundle, |
| 20 | __in_opt LPVOID pvContext | 25 | __in_opt LPVOID pvContext |
| @@ -88,6 +93,8 @@ extern "C" void RelatedBundlesUninitialize( | |||
| 88 | MemFree(pRelatedBundles->rgRelatedBundles); | 93 | MemFree(pRelatedBundles->rgRelatedBundles); |
| 89 | } | 94 | } |
| 90 | 95 | ||
| 96 | ReleaseMem(pRelatedBundles->rgpPlanSortedRelatedBundles); | ||
| 97 | |||
| 91 | memset(pRelatedBundles, 0, sizeof(BURN_RELATED_BUNDLES)); | 98 | memset(pRelatedBundles, 0, sizeof(BURN_RELATED_BUNDLES)); |
| 92 | } | 99 | } |
| 93 | 100 | ||
| @@ -122,17 +129,24 @@ LExit: | |||
| 122 | return hr; | 129 | return hr; |
| 123 | } | 130 | } |
| 124 | 131 | ||
| 125 | extern "C" void RelatedBundlesSort( | 132 | extern "C" void RelatedBundlesSortDetect( |
| 133 | __in BURN_RELATED_BUNDLES* pRelatedBundles | ||
| 134 | ) | ||
| 135 | { | ||
| 136 | qsort_s(pRelatedBundles->rgRelatedBundles, pRelatedBundles->cRelatedBundles, sizeof(BURN_RELATED_BUNDLE), CompareRelatedBundlesDetect, NULL); | ||
| 137 | } | ||
| 138 | |||
| 139 | extern "C" void RelatedBundlesSortPlan( | ||
| 126 | __in BURN_RELATED_BUNDLES* pRelatedBundles | 140 | __in BURN_RELATED_BUNDLES* pRelatedBundles |
| 127 | ) | 141 | ) |
| 128 | { | 142 | { |
| 129 | qsort_s(pRelatedBundles->rgRelatedBundles, pRelatedBundles->cRelatedBundles, sizeof(BURN_RELATED_BUNDLE), CompareRelatedBundles, NULL); | 143 | qsort_s(pRelatedBundles->rgpPlanSortedRelatedBundles, pRelatedBundles->cRelatedBundles, sizeof(BURN_RELATED_BUNDLE*), CompareRelatedBundlesPlan, NULL); |
| 130 | } | 144 | } |
| 131 | 145 | ||
| 132 | 146 | ||
| 133 | // internal helper functions | 147 | // internal helper functions |
| 134 | 148 | ||
| 135 | static __callback int __cdecl CompareRelatedBundles( | 149 | static __callback int __cdecl CompareRelatedBundlesDetect( |
| 136 | __in void* /*pvContext*/, | 150 | __in void* /*pvContext*/, |
| 137 | __in const void* pvLeft, | 151 | __in const void* pvLeft, |
| 138 | __in const void* pvRight | 152 | __in const void* pvRight |
| @@ -143,18 +157,61 @@ static __callback int __cdecl CompareRelatedBundles( | |||
| 143 | const BURN_RELATED_BUNDLE* pBundleRight = static_cast<const BURN_RELATED_BUNDLE*>(pvRight); | 157 | const BURN_RELATED_BUNDLE* pBundleRight = static_cast<const BURN_RELATED_BUNDLE*>(pvRight); |
| 144 | 158 | ||
| 145 | // Sort by relation type, then version, then bundle id. | 159 | // Sort by relation type, then version, then bundle id. |
| 146 | if (pBundleLeft->relationType != pBundleRight->relationType) | 160 | if (pBundleLeft->detectRelationType != pBundleRight->detectRelationType) |
| 147 | { | 161 | { |
| 148 | // Upgrade bundles last, everything else according to the enum. | 162 | // Upgrade bundles last, everything else according to the enum. |
| 149 | if (BOOTSTRAPPER_RELATION_UPGRADE == pBundleLeft->relationType) | 163 | if (BOOTSTRAPPER_RELATION_UPGRADE == pBundleLeft->detectRelationType) |
| 150 | { | 164 | { |
| 151 | ret = 1; | 165 | ret = 1; |
| 152 | } | 166 | } |
| 153 | else if (BOOTSTRAPPER_RELATION_UPGRADE == pBundleRight->relationType) | 167 | else if (BOOTSTRAPPER_RELATION_UPGRADE == pBundleRight->detectRelationType) |
| 154 | { | 168 | { |
| 155 | ret = -1; | 169 | ret = -1; |
| 156 | } | 170 | } |
| 157 | else if (pBundleLeft->relationType < pBundleRight->relationType) | 171 | else if (pBundleLeft->detectRelationType < pBundleRight->detectRelationType) |
| 172 | { | ||
| 173 | ret = -1; | ||
| 174 | } | ||
| 175 | else | ||
| 176 | { | ||
| 177 | ret = 1; | ||
| 178 | } | ||
| 179 | } | ||
| 180 | else | ||
| 181 | { | ||
| 182 | VerCompareParsedVersions(pBundleLeft->pVersion, pBundleRight->pVersion, &ret); | ||
| 183 | if (0 == ret) | ||
| 184 | { | ||
| 185 | ret = ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pBundleLeft->package.sczId, -1, pBundleRight->package.sczId, -1) - 2; | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 189 | return ret; | ||
| 190 | } | ||
| 191 | |||
| 192 | static __callback int __cdecl CompareRelatedBundlesPlan( | ||
| 193 | __in void* /*pvContext*/, | ||
| 194 | __in const void* pvLeft, | ||
| 195 | __in const void* pvRight | ||
| 196 | ) | ||
| 197 | { | ||
| 198 | int ret = 0; | ||
| 199 | const BURN_RELATED_BUNDLE* pBundleLeft = *reinterpret_cast<BURN_RELATED_BUNDLE**>(const_cast<void*>(pvLeft)); | ||
| 200 | const BURN_RELATED_BUNDLE* pBundleRight = *reinterpret_cast<BURN_RELATED_BUNDLE**>(const_cast<void*>(pvRight)); | ||
| 201 | |||
| 202 | // Sort by relation type, then version, then bundle id. | ||
| 203 | if (pBundleLeft->planRelationType != pBundleRight->planRelationType) | ||
| 204 | { | ||
| 205 | // Upgrade bundles last, everything else according to the enum. | ||
| 206 | if (BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_UPGRADE == pBundleLeft->planRelationType) | ||
| 207 | { | ||
| 208 | ret = 1; | ||
| 209 | } | ||
| 210 | else if (BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_UPGRADE == pBundleRight->planRelationType) | ||
| 211 | { | ||
| 212 | ret = -1; | ||
| 213 | } | ||
| 214 | else if (pBundleLeft->planRelationType < pBundleRight->planRelationType) | ||
| 158 | { | 215 | { |
| 159 | ret = -1; | 216 | ret = -1; |
| 160 | } | 217 | } |
| @@ -191,6 +248,30 @@ LExit: | |||
| 191 | return result; | 248 | return result; |
| 192 | } | 249 | } |
| 193 | 250 | ||
| 251 | static BOOTSTRAPPER_RELATION_TYPE ConvertRelationType( | ||
| 252 | __in BUNDLE_RELATION_TYPE relationType | ||
| 253 | ) | ||
| 254 | { | ||
| 255 | switch (relationType) | ||
| 256 | { | ||
| 257 | case BUNDLE_RELATION_DETECT: | ||
| 258 | return BOOTSTRAPPER_RELATION_DETECT; | ||
| 259 | case BUNDLE_RELATION_UPGRADE: | ||
| 260 | return BOOTSTRAPPER_RELATION_UPGRADE; | ||
| 261 | case BUNDLE_RELATION_ADDON: | ||
| 262 | return BOOTSTRAPPER_RELATION_ADDON; | ||
| 263 | case BUNDLE_RELATION_PATCH: | ||
| 264 | return BOOTSTRAPPER_RELATION_PATCH; | ||
| 265 | case BUNDLE_RELATION_DEPENDENT_ADDON: | ||
| 266 | return BOOTSTRAPPER_RELATION_DEPENDENT_ADDON; | ||
| 267 | case BUNDLE_RELATION_DEPENDENT_PATCH: | ||
| 268 | return BOOTSTRAPPER_RELATION_DEPENDENT_PATCH; | ||
| 269 | default: | ||
| 270 | AssertSz(BUNDLE_RELATION_NONE == relationType, "Unknown BUNDLE_RELATION_TYPE"); | ||
| 271 | return BOOTSTRAPPER_RELATION_NONE; | ||
| 272 | } | ||
| 273 | } | ||
| 274 | |||
| 194 | static HRESULT LoadIfRelatedBundle( | 275 | static HRESULT LoadIfRelatedBundle( |
| 195 | __in const BUNDLE_QUERY_RELATED_BUNDLE_RESULT* pBundle, | 276 | __in const BUNDLE_QUERY_RELATED_BUNDLE_RESULT* pBundle, |
| 196 | __in BURN_REGISTRATION* pRegistration, | 277 | __in BURN_REGISTRATION* pRegistration, |
| @@ -199,7 +280,7 @@ static HRESULT LoadIfRelatedBundle( | |||
| 199 | { | 280 | { |
| 200 | HRESULT hr = S_OK; | 281 | HRESULT hr = S_OK; |
| 201 | BOOL fPerMachine = BUNDLE_INSTALL_CONTEXT_MACHINE == pBundle->installContext; | 282 | BOOL fPerMachine = BUNDLE_INSTALL_CONTEXT_MACHINE == pBundle->installContext; |
| 202 | BOOTSTRAPPER_RELATION_TYPE relationType = (BOOTSTRAPPER_RELATION_TYPE)pBundle->relationType; | 283 | BOOTSTRAPPER_RELATION_TYPE relationType = ConvertRelationType(pBundle->relationType); |
| 203 | BURN_RELATED_BUNDLE* pRelatedBundle = NULL; | 284 | BURN_RELATED_BUNDLE* pRelatedBundle = NULL; |
| 204 | 285 | ||
| 205 | // If we found our bundle id, it's not a related bundle. | 286 | // If we found our bundle id, it's not a related bundle. |
| @@ -316,11 +397,11 @@ static HRESULT LoadRelatedBundleFromKey( | |||
| 316 | } | 397 | } |
| 317 | ExitOnFailure(hr, "Failed to read tag from registry for bundle: %ls", wzRelatedBundleId); | 398 | ExitOnFailure(hr, "Failed to read tag from registry for bundle: %ls", wzRelatedBundleId); |
| 318 | 399 | ||
| 319 | pRelatedBundle->relationType = relationType; | 400 | pRelatedBundle->detectRelationType = relationType; |
| 320 | 401 | ||
| 321 | hr = PseudoBundleInitializeRelated(&pRelatedBundle->package, fSupportsBurnProtocol, fPerMachine, wzRelatedBundleId, | 402 | hr = PseudoBundleInitializeRelated(&pRelatedBundle->package, fSupportsBurnProtocol, fPerMachine, wzRelatedBundleId, |
| 322 | #ifdef DEBUG | 403 | #ifdef DEBUG |
| 323 | pRelatedBundle->relationType, | 404 | pRelatedBundle->detectRelationType, |
| 324 | #endif | 405 | #endif |
| 325 | fCached, sczCachePath, qwFileSize, pBundleDependencyProvider); | 406 | fCached, sczCachePath, qwFileSize, pBundleDependencyProvider); |
| 326 | ExitOnFailure(hr, "Failed to initialize related bundle to represent bundle: %ls", wzRelatedBundleId); | 407 | ExitOnFailure(hr, "Failed to initialize related bundle to represent bundle: %ls", wzRelatedBundleId); |
