From d3bd9187857fb42218925c4b9192b25f82e81db6 Mon Sep 17 00:00:00 2001
From: Sean Hall <r.sean.hall@gmail.com>
Date: Sat, 29 Aug 2020 21:30:21 -0500
Subject: Update apuputil and deputil to not use DWORD64 for versions.

---
 src/dutil/apuputil.cpp   | 86 +++++++++++++++++++++++++++---------------------
 src/dutil/deputil.cpp    |  6 ++--
 src/dutil/inc/apuputil.h |  6 ++--
 src/dutil/inc/deputil.h  |  2 +-
 src/dutil/precomp.h      |  2 +-
 5 files changed, 56 insertions(+), 46 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(
 static HRESULT FilterEntries(
     __in APPLICATION_UPDATE_ENTRY* rgEntries,
     __in DWORD cEntries,
-    __in DWORD64 dw64CurrentVersion,
+    __in VERUTIL_VERSION* pCurrentVersion,
     __inout APPLICATION_UPDATE_ENTRY** prgFilteredEntries,
     __inout DWORD* pcFilteredEntries
     );
@@ -128,7 +128,7 @@ LExit:
 //
 HRESULT DAPI ApupFilterChain(
     __in APPLICATION_UPDATE_CHAIN* pChain,
-    __in DWORD64 dw64Version,
+    __in VERUTIL_VERSION* pVersion,
     __out APPLICATION_UPDATE_CHAIN** ppFilteredChain
     )
 {
@@ -140,7 +140,7 @@ HRESULT DAPI ApupFilterChain(
     pNewChain = static_cast<APPLICATION_UPDATE_CHAIN*>(MemAlloc(sizeof(APPLICATION_UPDATE_CHAIN), TRUE));
     ExitOnNull(pNewChain, hr, E_OUTOFMEMORY, "Failed to allocate filtered chain.");
 
-    hr = FilterEntries(pChain->rgEntries, pChain->cEntries, dw64Version, &prgEntries, &cEntries);
+    hr = FilterEntries(pChain->rgEntries, pChain->cEntries, pVersion, &prgEntries, &cEntries);
     ExitOnFailure(hr, "Failed to filter entries by version.");
 
     if (pChain->wzDefaultApplicationId)
@@ -197,6 +197,7 @@ static HRESULT ProcessEntry(
 {
     HRESULT hr = S_OK;
     BOOL fVersionFound = FALSE;
+    int nCompareResult = 0;
 
     // First search the ATOM entry's custom elements to try and find the application update information.
     for (ATOM_UNKNOWN_ELEMENT* pElement = pAtomEntry->pUnknownElements; pElement; pElement = pElement->pNext)
@@ -226,13 +227,8 @@ static HRESULT ProcessEntry(
                 {
                     if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pAttribute->wzAttribute, -1, L"version", -1))
                     {
-                        DWORD dwMajor = 0;
-                        DWORD dwMinor = 0;
-
-                        hr = FileVersionFromString(pAttribute->wzValue, &dwMajor, &dwMinor);
-                        ExitOnFailure(hr, "Failed to parse version string from ATOM entry.");
-
-                        pApupEntry->dw64UpgradeVersion = static_cast<DWORD64>(dwMajor) << 32 | dwMinor;
+                        hr = VerParseVersion(pAttribute->wzValue, 0, FALSE, &pApupEntry->pUpgradeVersion);
+                        ExitOnFailure(hr, "Failed to parse upgrade version string '%ls' from ATOM entry.", pAttribute->wzValue);
                     }
                     else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pAttribute->wzAttribute, -1, L"exclusive", -1))
                     {
@@ -245,13 +241,9 @@ static HRESULT ProcessEntry(
             }
             else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, pElement->wzElement, -1, L"version", -1))
             {
-                DWORD dwMajor = 0;
-                DWORD dwMinor = 0;
-
-                hr = FileVersionFromString(pElement->wzValue, &dwMajor, &dwMinor);
-                ExitOnFailure(hr, "Failed to parse version string from ATOM entry.");
+                hr = VerParseVersion(pElement->wzValue, 0, FALSE, &pApupEntry->pVersion);
+                ExitOnFailure(hr, "Failed to parse version string '%ls' from ATOM entry.", pElement->wzValue);
 
-                pApupEntry->dw64Version = static_cast<DWORD64>(dwMajor) << 32 | dwMinor;
                 fVersionFound = TRUE;
             }
         }
@@ -263,7 +255,10 @@ static HRESULT ProcessEntry(
         ExitFunction1(hr = S_FALSE); // skip this update since it has no application id or version.
     }
 
-    if (pApupEntry->dw64UpgradeVersion >= pApupEntry->dw64Version)
+    hr = VerCompareParsedVersions(pApupEntry->pUpgradeVersion, pApupEntry->pVersion, &nCompareResult);
+    ExitOnFailure(hr, "Failed to compare version to upgrade version.");
+
+    if (nCompareResult >= 0)
     {
         hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
         ExitOnRootFailure(hr, "Upgrade version is greater than or equal to application version.");
@@ -404,31 +399,24 @@ LExit:
 
 
 static __callback int __cdecl CompareEntries(
-    void* pvContext,
+    void* /*pvContext*/,
     const void* pvLeft,
     const void* pvRight
     )
 {
-    UNREFERENCED_PARAMETER(pvContext);
-
     int ret = 0;
     const APPLICATION_UPDATE_ENTRY* pEntryLeft = static_cast<const APPLICATION_UPDATE_ENTRY*>(pvLeft);
     const APPLICATION_UPDATE_ENTRY* pEntryRight = static_cast<const APPLICATION_UPDATE_ENTRY*>(pvRight);
 
-    if (pEntryLeft->dw64Version == pEntryRight->dw64Version)
+    VerCompareParsedVersions(pEntryLeft->pVersion, pEntryRight->pVersion, &ret);
+    if (0 == ret)
     {
-        if (pEntryLeft->dw64UpgradeVersion == pEntryRight->dw64UpgradeVersion)
+        VerCompareParsedVersions(pEntryLeft->pUpgradeVersion, pEntryRight->pUpgradeVersion, &ret);
+        if (0 == ret)
         {
-            ret = (pEntryRight->dw64TotalSize < pEntryLeft->dw64TotalSize) ? -1 : 1;
+            ret = (pEntryRight->dw64TotalSize < pEntryLeft->dw64TotalSize) ? -1 :
+                  (pEntryRight->dw64TotalSize > pEntryLeft->dw64TotalSize) ?  1 : 0;
         }
-        else
-        {
-            ret = (pEntryLeft->dw64UpgradeVersion > pEntryRight->dw64UpgradeVersion) ? -1 : 1;
-        }
-    }
-    else
-    {
-        ret = (pEntryLeft->dw64Version > pEntryRight->dw64Version) ? -1 : 1;
     }
 
     return ret;
@@ -438,12 +426,13 @@ static __callback int __cdecl CompareEntries(
 static HRESULT FilterEntries(
     __in APPLICATION_UPDATE_ENTRY* rgEntries,
     __in DWORD cEntries,
-    __in DWORD64 dw64CurrentVersion,
+    __in VERUTIL_VERSION* pCurrentVersion,
     __inout APPLICATION_UPDATE_ENTRY** prgFilteredEntries,
     __inout DWORD* pcFilteredEntries
     )
 {
     HRESULT hr = S_OK;
+    int nCompareResult = 0;
     size_t cbAllocSize = 0;
     const APPLICATION_UPDATE_ENTRY* pRequired = NULL;;
     LPVOID pv = NULL;
@@ -453,8 +442,19 @@ static HRESULT FilterEntries(
         for (DWORD i = 0; i < cEntries; ++i)
         {
             const APPLICATION_UPDATE_ENTRY* pEntry = rgEntries + i;
-            if (((pEntry->fUpgradeExclusive && dw64CurrentVersion > pEntry->dw64UpgradeVersion) || (!pEntry->fUpgradeExclusive && dw64CurrentVersion >= pEntry->dw64UpgradeVersion)) && 
-                dw64CurrentVersion < pEntry->dw64Version)
+
+            hr = VerCompareParsedVersions(pCurrentVersion, pEntry->pVersion, &nCompareResult);
+            ExitOnFailure(hr, "Failed to compare versions.");
+
+            if (nCompareResult >= 0)
+            {
+                continue;
+            }
+
+            hr = VerCompareParsedVersions(pCurrentVersion, pEntry->pUpgradeVersion, &nCompareResult);
+            ExitOnFailure(hr, "Failed to compare upgrade versions.");
+
+            if (nCompareResult > 0 || (!pEntry->fUpgradeExclusive && nCompareResult == 0))
             {
                 pRequired = pEntry;
                 break;
@@ -486,9 +486,12 @@ static HRESULT FilterEntries(
             hr = CopyEntry(pRequired, *prgFilteredEntries + *pcFilteredEntries - 1);
             ExitOnFailure(hr, "Failed to deep copy entry.");
 
-            if (pRequired->dw64Version < rgEntries[0].dw64Version)
+            hr = VerCompareParsedVersions(pRequired->pVersion, rgEntries[0].pVersion, &nCompareResult);
+            ExitOnFailure(hr, "Failed to compare required version.");
+
+            if (nCompareResult < 0)
             {
-                FilterEntries(rgEntries, cEntries, pRequired->dw64Version, prgFilteredEntries, pcFilteredEntries);
+                FilterEntries(rgEntries, cEntries, pRequired->pVersion, prgFilteredEntries, pcFilteredEntries);
             }
         }
     }
@@ -552,8 +555,13 @@ static HRESULT CopyEntry(
     }
 
     pDest->dw64TotalSize = pSrc->dw64TotalSize;
-    pDest->dw64UpgradeVersion = pSrc->dw64UpgradeVersion;
-    pDest->dw64Version = pSrc->dw64Version;
+
+    hr = VerCopyVersion(pSrc->pUpgradeVersion, &pDest->pUpgradeVersion);
+    ExitOnFailure(hr, "Failed to copy upgrade version.");
+
+    hr = VerCopyVersion(pSrc->pVersion, &pDest->pVersion);
+    ExitOnFailure(hr, "Failed to copy version.");
+
     pDest->fUpgradeExclusive = pSrc->fUpgradeExclusive;
 
     hr = ::SizeTMult(sizeof(APPLICATION_UPDATE_ENCLOSURE), pSrc->cEnclosures, &cbAllocSize);
@@ -641,6 +649,8 @@ static void FreeEntry(
         ReleaseStr(pEntry->wzSummary);
         ReleaseStr(pEntry->wzContentType);
         ReleaseStr(pEntry->wzContent);
+        ReleaseVerutilVersion(pEntry->pVersion);
+        ReleaseVerutilVersion(pEntry->pUpgradeVersion);
     }
 }
 
diff --git a/src/dutil/deputil.cpp b/src/dutil/deputil.cpp
index b2db0dd6..d65c4348 100644
--- a/src/dutil/deputil.cpp
+++ b/src/dutil/deputil.cpp
@@ -33,7 +33,7 @@ DAPI_(HRESULT) DepGetProviderInformation(
     __in_z LPCWSTR wzProviderKey,
     __deref_out_z_opt LPWSTR* psczId,
     __deref_out_z_opt LPWSTR* psczName,
-    __out_opt DWORD64* pqwVersion
+    __deref_out_z_opt LPWSTR* psczVersion
     )
 {
     HRESULT hr = S_OK;
@@ -75,9 +75,9 @@ DAPI_(HRESULT) DepGetProviderInformation(
     }
 
     // Get the Version if requested and available.
-    if (pqwVersion)
+    if (psczVersion)
     {
-        hr = RegReadVersion(hkKey, vcszVersionValue, pqwVersion);
+        hr = RegReadString(hkKey, vcszVersionValue, psczVersion);
         if (E_FILENOTFOUND == hr)
         {
             hr = S_OK;
diff --git a/src/dutil/inc/apuputil.h b/src/dutil/inc/apuputil.h
index 6764bde8..15d42f5d 100644
--- a/src/dutil/inc/apuputil.h
+++ b/src/dutil/inc/apuputil.h
@@ -46,8 +46,8 @@ struct APPLICATION_UPDATE_ENTRY
 
     LPWSTR wzUpgradeId;
     BOOL fUpgradeExclusive;
-    DWORD64 dw64Version;
-    DWORD64 dw64UpgradeVersion;
+    VERUTIL_VERSION* pVersion;
+    VERUTIL_VERSION* pUpgradeVersion;
 
     DWORD64 dw64TotalSize;
 
@@ -73,7 +73,7 @@ HRESULT DAPI ApupAllocChainFromAtom(
 
 HRESULT DAPI ApupFilterChain(
     __in APPLICATION_UPDATE_CHAIN* pChain,
-    __in DWORD64 dw64Version,
+    __in VERUTIL_VERSION* pVersion,
     __out APPLICATION_UPDATE_CHAIN** ppFilteredChain
     );
 
diff --git a/src/dutil/inc/deputil.h b/src/dutil/inc/deputil.h
index a08d2eb5..8f5f0ae8 100644
--- a/src/dutil/inc/deputil.h
+++ b/src/dutil/inc/deputil.h
@@ -27,7 +27,7 @@ DAPI_(HRESULT) DepGetProviderInformation(
     __in_z LPCWSTR wzProviderKey,
     __deref_out_z_opt LPWSTR* psczId,
     __deref_out_z_opt LPWSTR* psczName,
-    __out_opt DWORD64* pqwVersion
+    __deref_out_z_opt LPWSTR* psczVersion
     );
 
 /***************************************************************************
diff --git a/src/dutil/precomp.h b/src/dutil/precomp.h
index be58860c..f8f3b944 100644
--- a/src/dutil/precomp.h
+++ b/src/dutil/precomp.h
@@ -43,6 +43,7 @@
 
 #include "dutilsources.h"
 #include "dutil.h"
+#include "verutil.h"
 #include "aclutil.h"
 #include "atomutil.h"
 #include "buffutil.h"
@@ -89,7 +90,6 @@
 #include "uncutil.h"
 #include "uriutil.h"
 #include "userutil.h"
-#include "verutil.h"
 #include "wiutil.h"
 #include "wuautil.h"
 #include <comutil.h>  // This header is needed for msxml2.h to compile correctly
-- 
cgit v1.2.3-55-g6feb