diff options
Diffstat (limited to 'src/dutil/apuputil.cpp')
-rw-r--r-- | src/dutil/apuputil.cpp | 86 |
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( | |||
22 | static HRESULT FilterEntries( | 22 | static 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 | // |
129 | HRESULT DAPI ApupFilterChain( | 129 | HRESULT 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 | ||
406 | static __callback int __cdecl CompareEntries( | 401 | static __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( | |||
438 | static HRESULT FilterEntries( | 426 | static 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 | ||