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); |