aboutsummaryrefslogtreecommitdiff
path: root/src/dutil/apuputil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dutil/apuputil.cpp')
-rw-r--r--src/dutil/apuputil.cpp86
1 files changed, 48 insertions, 38 deletions
diff --git a/src/dutil/apuputil.cpp b/src/dutil/apuputil.cpp
index 11aaf3f2..5bbdb8dd 100644
--- a/src/dutil/apuputil.cpp
+++ b/src/dutil/apuputil.cpp
@@ -22,7 +22,7 @@ static __callback int __cdecl CompareEntries(
22static HRESULT FilterEntries( 22static HRESULT FilterEntries(
23 __in APPLICATION_UPDATE_ENTRY* rgEntries, 23 __in APPLICATION_UPDATE_ENTRY* rgEntries,
24 __in DWORD cEntries, 24 __in DWORD cEntries,
25 __in DWORD64 dw64CurrentVersion, 25 __in VERUTIL_VERSION* pCurrentVersion,
26 __inout APPLICATION_UPDATE_ENTRY** prgFilteredEntries, 26 __inout APPLICATION_UPDATE_ENTRY** prgFilteredEntries,
27 __inout DWORD* pcFilteredEntries 27 __inout DWORD* pcFilteredEntries
28 ); 28 );
@@ -128,7 +128,7 @@ LExit:
128// 128//
129HRESULT DAPI ApupFilterChain( 129HRESULT DAPI ApupFilterChain(
130 __in APPLICATION_UPDATE_CHAIN* pChain, 130 __in APPLICATION_UPDATE_CHAIN* pChain,
131 __in DWORD64 dw64Version, 131 __in VERUTIL_VERSION* pVersion,
132 __out APPLICATION_UPDATE_CHAIN** ppFilteredChain 132 __out APPLICATION_UPDATE_CHAIN** ppFilteredChain
133 ) 133 )
134{ 134{
@@ -140,7 +140,7 @@ HRESULT DAPI ApupFilterChain(
140 pNewChain = static_cast<APPLICATION_UPDATE_CHAIN*>(MemAlloc(sizeof(APPLICATION_UPDATE_CHAIN), TRUE)); 140 pNewChain = static_cast<APPLICATION_UPDATE_CHAIN*>(MemAlloc(sizeof(APPLICATION_UPDATE_CHAIN), TRUE));
141 ExitOnNull(pNewChain, hr, E_OUTOFMEMORY, "Failed to allocate filtered chain."); 141 ExitOnNull(pNewChain, hr, E_OUTOFMEMORY, "Failed to allocate filtered chain.");
142 142
143 hr = FilterEntries(pChain->rgEntries, pChain->cEntries, dw64Version, &prgEntries, &cEntries); 143 hr = FilterEntries(pChain->rgEntries, pChain->cEntries, pVersion, &prgEntries, &cEntries);
144 ExitOnFailure(hr, "Failed to filter entries by version."); 144 ExitOnFailure(hr, "Failed to filter entries by version.");
145 145
146 if (pChain->wzDefaultApplicationId) 146 if (pChain->wzDefaultApplicationId)
@@ -197,6 +197,7 @@ static HRESULT ProcessEntry(
197{ 197{
198 HRESULT hr = S_OK; 198 HRESULT hr = S_OK;
199 BOOL fVersionFound = FALSE; 199 BOOL fVersionFound = FALSE;
200 int nCompareResult = 0;
200 201
201 // First search the ATOM entry's custom elements to try and find the application update information. 202 // First search the ATOM entry's custom elements to try and find the application update information.
202 for (ATOM_UNKNOWN_ELEMENT* pElement = pAtomEntry->pUnknownElements; pElement; pElement = pElement->pNext) 203 for (ATOM_UNKNOWN_ELEMENT* pElement = pAtomEntry->pUnknownElements; pElement; pElement = pElement->pNext)
@@ -226,13 +227,8 @@ static HRESULT ProcessEntry(
226 { 227 {
227 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pAttribute->wzAttribute, -1, L"version", -1)) 228 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pAttribute->wzAttribute, -1, L"version", -1))
228 { 229 {
229 DWORD dwMajor = 0; 230 hr = VerParseVersion(pAttribute->wzValue, 0, FALSE, &pApupEntry->pUpgradeVersion);
230 DWORD dwMinor = 0; 231 ExitOnFailure(hr, "Failed to parse upgrade version string '%ls' from ATOM entry.", pAttribute->wzValue);
231
232 hr = FileVersionFromString(pAttribute->wzValue, &dwMajor, &dwMinor);
233 ExitOnFailure(hr, "Failed to parse version string from ATOM entry.");
234
235 pApupEntry->dw64UpgradeVersion = static_cast<DWORD64>(dwMajor) << 32 | dwMinor;
236 } 232 }
237 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pAttribute->wzAttribute, -1, L"exclusive", -1)) 233 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pAttribute->wzAttribute, -1, L"exclusive", -1))
238 { 234 {
@@ -245,13 +241,9 @@ static HRESULT ProcessEntry(
245 } 241 }
246 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pElement->wzElement, -1, L"version", -1)) 242 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pElement->wzElement, -1, L"version", -1))
247 { 243 {
248 DWORD dwMajor = 0; 244 hr = VerParseVersion(pElement->wzValue, 0, FALSE, &pApupEntry->pVersion);
249 DWORD dwMinor = 0; 245 ExitOnFailure(hr, "Failed to parse version string '%ls' from ATOM entry.", pElement->wzValue);
250
251 hr = FileVersionFromString(pElement->wzValue, &dwMajor, &dwMinor);
252 ExitOnFailure(hr, "Failed to parse version string from ATOM entry.");
253 246
254 pApupEntry->dw64Version = static_cast<DWORD64>(dwMajor) << 32 | dwMinor;
255 fVersionFound = TRUE; 247 fVersionFound = TRUE;
256 } 248 }
257 } 249 }
@@ -263,7 +255,10 @@ static HRESULT ProcessEntry(
263 ExitFunction1(hr = S_FALSE); // skip this update since it has no application id or version. 255 ExitFunction1(hr = S_FALSE); // skip this update since it has no application id or version.
264 } 256 }
265 257
266 if (pApupEntry->dw64UpgradeVersion >= pApupEntry->dw64Version) 258 hr = VerCompareParsedVersions(pApupEntry->pUpgradeVersion, pApupEntry->pVersion, &nCompareResult);
259 ExitOnFailure(hr, "Failed to compare version to upgrade version.");
260
261 if (nCompareResult >= 0)
267 { 262 {
268 hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); 263 hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
269 ExitOnRootFailure(hr, "Upgrade version is greater than or equal to application version."); 264 ExitOnRootFailure(hr, "Upgrade version is greater than or equal to application version.");
@@ -404,31 +399,24 @@ LExit:
404 399
405 400
406static __callback int __cdecl CompareEntries( 401static __callback int __cdecl CompareEntries(
407 void* pvContext, 402 void* /*pvContext*/,
408 const void* pvLeft, 403 const void* pvLeft,
409 const void* pvRight 404 const void* pvRight
410 ) 405 )
411{ 406{
412 UNREFERENCED_PARAMETER(pvContext);
413
414 int ret = 0; 407 int ret = 0;
415 const APPLICATION_UPDATE_ENTRY* pEntryLeft = static_cast<const APPLICATION_UPDATE_ENTRY*>(pvLeft); 408 const APPLICATION_UPDATE_ENTRY* pEntryLeft = static_cast<const APPLICATION_UPDATE_ENTRY*>(pvLeft);
416 const APPLICATION_UPDATE_ENTRY* pEntryRight = static_cast<const APPLICATION_UPDATE_ENTRY*>(pvRight); 409 const APPLICATION_UPDATE_ENTRY* pEntryRight = static_cast<const APPLICATION_UPDATE_ENTRY*>(pvRight);
417 410
418 if (pEntryLeft->dw64Version == pEntryRight->dw64Version) 411 VerCompareParsedVersions(pEntryLeft->pVersion, pEntryRight->pVersion, &ret);
412 if (0 == ret)
419 { 413 {
420 if (pEntryLeft->dw64UpgradeVersion == pEntryRight->dw64UpgradeVersion) 414 VerCompareParsedVersions(pEntryLeft->pUpgradeVersion, pEntryRight->pUpgradeVersion, &ret);
415 if (0 == ret)
421 { 416 {
422 ret = (pEntryRight->dw64TotalSize < pEntryLeft->dw64TotalSize) ? -1 : 1; 417 ret = (pEntryRight->dw64TotalSize < pEntryLeft->dw64TotalSize) ? -1 :
418 (pEntryRight->dw64TotalSize > pEntryLeft->dw64TotalSize) ? 1 : 0;
423 } 419 }
424 else
425 {
426 ret = (pEntryLeft->dw64UpgradeVersion > pEntryRight->dw64UpgradeVersion) ? -1 : 1;
427 }
428 }
429 else
430 {
431 ret = (pEntryLeft->dw64Version > pEntryRight->dw64Version) ? -1 : 1;
432 } 420 }
433 421
434 return ret; 422 return ret;
@@ -438,12 +426,13 @@ static __callback int __cdecl CompareEntries(
438static HRESULT FilterEntries( 426static HRESULT FilterEntries(
439 __in APPLICATION_UPDATE_ENTRY* rgEntries, 427 __in APPLICATION_UPDATE_ENTRY* rgEntries,
440 __in DWORD cEntries, 428 __in DWORD cEntries,
441 __in DWORD64 dw64CurrentVersion, 429 __in VERUTIL_VERSION* pCurrentVersion,
442 __inout APPLICATION_UPDATE_ENTRY** prgFilteredEntries, 430 __inout APPLICATION_UPDATE_ENTRY** prgFilteredEntries,
443 __inout DWORD* pcFilteredEntries 431 __inout DWORD* pcFilteredEntries
444 ) 432 )
445{ 433{
446 HRESULT hr = S_OK; 434 HRESULT hr = S_OK;
435 int nCompareResult = 0;
447 size_t cbAllocSize = 0; 436 size_t cbAllocSize = 0;
448 const APPLICATION_UPDATE_ENTRY* pRequired = NULL;; 437 const APPLICATION_UPDATE_ENTRY* pRequired = NULL;;
449 LPVOID pv = NULL; 438 LPVOID pv = NULL;
@@ -453,8 +442,19 @@ static HRESULT FilterEntries(
453 for (DWORD i = 0; i < cEntries; ++i) 442 for (DWORD i = 0; i < cEntries; ++i)
454 { 443 {
455 const APPLICATION_UPDATE_ENTRY* pEntry = rgEntries + i; 444 const APPLICATION_UPDATE_ENTRY* pEntry = rgEntries + i;
456 if (((pEntry->fUpgradeExclusive && dw64CurrentVersion > pEntry->dw64UpgradeVersion) || (!pEntry->fUpgradeExclusive && dw64CurrentVersion >= pEntry->dw64UpgradeVersion)) && 445
457 dw64CurrentVersion < pEntry->dw64Version) 446 hr = VerCompareParsedVersions(pCurrentVersion, pEntry->pVersion, &nCompareResult);
447 ExitOnFailure(hr, "Failed to compare versions.");
448
449 if (nCompareResult >= 0)
450 {
451 continue;
452 }
453
454 hr = VerCompareParsedVersions(pCurrentVersion, pEntry->pUpgradeVersion, &nCompareResult);
455 ExitOnFailure(hr, "Failed to compare upgrade versions.");
456
457 if (nCompareResult > 0 || (!pEntry->fUpgradeExclusive && nCompareResult == 0))
458 { 458 {
459 pRequired = pEntry; 459 pRequired = pEntry;
460 break; 460 break;
@@ -486,9 +486,12 @@ static HRESULT FilterEntries(
486 hr = CopyEntry(pRequired, *prgFilteredEntries + *pcFilteredEntries - 1); 486 hr = CopyEntry(pRequired, *prgFilteredEntries + *pcFilteredEntries - 1);
487 ExitOnFailure(hr, "Failed to deep copy entry."); 487 ExitOnFailure(hr, "Failed to deep copy entry.");
488 488
489 if (pRequired->dw64Version < rgEntries[0].dw64Version) 489 hr = VerCompareParsedVersions(pRequired->pVersion, rgEntries[0].pVersion, &nCompareResult);
490 ExitOnFailure(hr, "Failed to compare required version.");
491
492 if (nCompareResult < 0)
490 { 493 {
491 FilterEntries(rgEntries, cEntries, pRequired->dw64Version, prgFilteredEntries, pcFilteredEntries); 494 FilterEntries(rgEntries, cEntries, pRequired->pVersion, prgFilteredEntries, pcFilteredEntries);
492 } 495 }
493 } 496 }
494 } 497 }
@@ -552,8 +555,13 @@ static HRESULT CopyEntry(
552 } 555 }
553 556
554 pDest->dw64TotalSize = pSrc->dw64TotalSize; 557 pDest->dw64TotalSize = pSrc->dw64TotalSize;
555 pDest->dw64UpgradeVersion = pSrc->dw64UpgradeVersion; 558
556 pDest->dw64Version = pSrc->dw64Version; 559 hr = VerCopyVersion(pSrc->pUpgradeVersion, &pDest->pUpgradeVersion);
560 ExitOnFailure(hr, "Failed to copy upgrade version.");
561
562 hr = VerCopyVersion(pSrc->pVersion, &pDest->pVersion);
563 ExitOnFailure(hr, "Failed to copy version.");
564
557 pDest->fUpgradeExclusive = pSrc->fUpgradeExclusive; 565 pDest->fUpgradeExclusive = pSrc->fUpgradeExclusive;
558 566
559 hr = ::SizeTMult(sizeof(APPLICATION_UPDATE_ENCLOSURE), pSrc->cEnclosures, &cbAllocSize); 567 hr = ::SizeTMult(sizeof(APPLICATION_UPDATE_ENCLOSURE), pSrc->cEnclosures, &cbAllocSize);
@@ -641,6 +649,8 @@ static void FreeEntry(
641 ReleaseStr(pEntry->wzSummary); 649 ReleaseStr(pEntry->wzSummary);
642 ReleaseStr(pEntry->wzContentType); 650 ReleaseStr(pEntry->wzContentType);
643 ReleaseStr(pEntry->wzContent); 651 ReleaseStr(pEntry->wzContent);
652 ReleaseVerutilVersion(pEntry->pVersion);
653 ReleaseVerutilVersion(pEntry->pUpgradeVersion);
644 } 654 }
645} 655}
646 656