aboutsummaryrefslogtreecommitdiff
path: root/src/burn/engine/relatedbundle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/burn/engine/relatedbundle.cpp')
-rw-r--r--src/burn/engine/relatedbundle.cpp105
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
13static __callback int __cdecl CompareRelatedBundles( 13static __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 );
18static __callback int __cdecl CompareRelatedBundlesPlan(
19 __in void* /*pvContext*/,
20 __in const void* pvLeft,
21 __in const void* pvRight
22 );
18static BUNDLE_QUERY_CALLBACK_RESULT CALLBACK QueryRelatedBundlesCallback( 23static 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
125extern "C" void RelatedBundlesSort( 132extern "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
139extern "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
135static __callback int __cdecl CompareRelatedBundles( 149static __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
192static __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
251static 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
194static HRESULT LoadIfRelatedBundle( 275static 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);