From 02e682881979cd87592ee1e8e39b7744b575829c Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Mon, 9 May 2022 22:21:16 -0700 Subject: Add support for semver in bundles and dependencies Take advantage of WixVersion/verutil functionality to support wider range of version numbers were possible in the WiX Toolset Completes 4666 --- src/libs/dutil/WixToolset.DUtil/deputil.cpp | 32 +++++++++++----- src/libs/dutil/WixToolset.DUtil/inc/regutil.h | 11 ++++++ src/libs/dutil/WixToolset.DUtil/regutil.cpp | 53 +++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 10 deletions(-) (limited to 'src/libs/dutil') diff --git a/src/libs/dutil/WixToolset.DUtil/deputil.cpp b/src/libs/dutil/WixToolset.DUtil/deputil.cpp index 1a480263..4de85199 100644 --- a/src/libs/dutil/WixToolset.DUtil/deputil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/deputil.cpp @@ -121,9 +121,10 @@ DAPI_(HRESULT) DepCheckDependency( HRESULT hr = S_OK; LPWSTR sczKey = NULL; HKEY hkKey = NULL; - DWORD64 dw64Version = 0; - DWORD64 dw64MinVersion = 0; - DWORD64 dw64MaxVersion = 0; + VERUTIL_VERSION* pVersion = NULL; + VERUTIL_VERSION* pMinVersion = NULL; + VERUTIL_VERSION* pMaxVersion = NULL; + int nResult = 0; BOOL fAllowEqual = FALSE; LPWSTR sczName = NULL; @@ -138,7 +139,7 @@ DAPI_(HRESULT) DepCheckDependency( DepExitOnFailure(hr, "Failed to open the registry key for dependency \"%ls\".", wzProviderKey); // If there are no registry values, consider the key orphaned and treat it as missing. - hr = RegReadVersion(hkKey, vcszVersionValue, &dw64Version); + hr = RegReadWixVersion(hkKey, vcszVersionValue, &pVersion); if (E_FILENOTFOUND != hr) { DepExitOnFailure(hr, "Failed to read the %ls registry value for dependency \"%ls\".", vcszVersionValue, wzProviderKey); @@ -171,11 +172,15 @@ DAPI_(HRESULT) DepCheckDependency( { if (*wzMinVersion) { - hr = FileVersionFromStringEx(wzMinVersion, 0, &dw64MinVersion); - DepExitOnFailure(hr, "Failed to get the 64-bit version number from \"%ls\".", wzMinVersion); + hr = VerParseVersion(wzMinVersion, 0, FALSE, &pMinVersion); + DepExitOnFailure(hr, "Failed to get the min version number from \"%ls\".", wzMinVersion); + + hr = VerCompareParsedVersions(pVersion, pMinVersion, &nResult); + DepExitOnFailure(hr, "Failed to compare dependency with min version \"%ls\".", wzMinVersion); fAllowEqual = iAttributes & RequiresAttributesMinVersionInclusive; - if (!(fAllowEqual && dw64MinVersion <= dw64Version || dw64MinVersion < dw64Version)) + // !(fAllowEqual && pMinVersion <= pVersion || pMinVersion < pVersion)) + if (!(fAllowEqual && 0 <= nResult || 0 < nResult)) { hr = DictKeyExists(sdDependencies, wzProviderKey); if (E_NOTFOUND != hr) @@ -205,11 +210,15 @@ DAPI_(HRESULT) DepCheckDependency( { if (*wzMaxVersion) { - hr = FileVersionFromStringEx(wzMaxVersion, 0, &dw64MaxVersion); - DepExitOnFailure(hr, "Failed to get the 64-bit version number from \"%ls\".", wzMaxVersion); + hr = VerParseVersion(wzMaxVersion, 0, FALSE, &pMaxVersion); + DepExitOnFailure(hr, "Failed to get the max version number from \"%ls\".", wzMaxVersion); + + hr = VerCompareParsedVersions(pMaxVersion, pVersion, &nResult); + DepExitOnFailure(hr, "Failed to compare dependency with max version \"%ls\".", wzMaxVersion); fAllowEqual = iAttributes & RequiresAttributesMaxVersionInclusive; - if (!(fAllowEqual && dw64Version <= dw64MaxVersion || dw64Version < dw64MaxVersion)) + // !(fAllowEqual && pVersion <= pMaxVersion || pVersion < pMaxVersion) + if (!(fAllowEqual && 0 <= nResult || 0 < nResult)) { hr = DictKeyExists(sdDependencies, wzProviderKey); if (E_NOTFOUND != hr) @@ -235,6 +244,9 @@ DAPI_(HRESULT) DepCheckDependency( } LExit: + ReleaseVerutilVersion(pMaxVersion); + ReleaseVerutilVersion(pMinVersion); + ReleaseVerutilVersion(pVersion); ReleaseStr(sczName); ReleaseRegKey(hkKey); ReleaseStr(sczKey); diff --git a/src/libs/dutil/WixToolset.DUtil/inc/regutil.h b/src/libs/dutil/WixToolset.DUtil/inc/regutil.h index 3cbb53b0..76d2d7cb 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/regutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/regutil.h @@ -1,6 +1,7 @@ #pragma once // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. +#include "verutil.h" #ifdef __cplusplus extern "C" { @@ -260,6 +261,16 @@ HRESULT DAPI RegReadVersion( __out DWORD64* pdw64Version ); +/******************************************************************** + RegReadWixVersion - reads a registry key value as a WiX version. + +*********************************************************************/ +HRESULT DAPI RegReadWixVersion( + __in HKEY hk, + __in_z_opt LPCWSTR wzName, + __out VERUTIL_VERSION** ppVersion + ); + /******************************************************************** RegReadNone - reads a NONE registry key value. diff --git a/src/libs/dutil/WixToolset.DUtil/regutil.cpp b/src/libs/dutil/WixToolset.DUtil/regutil.cpp index 78507ade..64224d42 100644 --- a/src/libs/dutil/WixToolset.DUtil/regutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/regutil.cpp @@ -590,6 +590,7 @@ DAPI_(HRESULT) RegReadVersion( { ExitFunction1(hr = E_FILENOTFOUND); } + if (REG_SZ == dwType || REG_EXPAND_SZ == dwType) { hr = RegReadString(hk, wzName, &sczVersion); @@ -614,6 +615,58 @@ LExit: return hr; } + +DAPI_(HRESULT) RegReadWixVersion( + __in HKEY hk, + __in_z_opt LPCWSTR wzName, + __out VERUTIL_VERSION** ppVersion + ) +{ + HRESULT hr = S_OK; + DWORD er = ERROR_SUCCESS; + DWORD dwType = 0; + DWORD cb = 0; + DWORD64 dw64Version = 0; + LPWSTR sczVersion = NULL; + VERUTIL_VERSION* pVersion = NULL; + + cb = sizeof(DWORD64); + er = vpfnRegQueryValueExW(hk, wzName, NULL, &dwType, reinterpret_cast(&dw64Version), &cb); + if (E_FILENOTFOUND == HRESULT_FROM_WIN32(er)) + { + ExitFunction1(hr = E_FILENOTFOUND); + } + + if (REG_SZ == dwType || REG_EXPAND_SZ == dwType) + { + hr = RegReadString(hk, wzName, &sczVersion); + RegExitOnFailure(hr, "Failed to read registry version as string."); + + hr = VerParseVersion(sczVersion, 0, FALSE, &pVersion); + RegExitOnFailure(hr, "Failed to convert registry string to version."); + } + else if (REG_QWORD == dwType) + { + hr = VerVersionFromQword(dw64Version, &pVersion); + RegExitOnFailure(hr, "Failed to convert registry string to version."); + } + else // unexpected data type + { + hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE); + RegExitOnRootFailure(hr, "Error reading version registry value due to unexpected data type: %u", dwType); + } + + *ppVersion = pVersion; + pVersion = NULL; + +LExit: + ReleaseVerutilVersion(pVersion); + ReleaseStr(sczVersion); + + return hr; +} + + DAPI_(HRESULT) RegReadNone( __in HKEY hk, __in_z_opt LPCWSTR wzName -- cgit v1.2.3-55-g6feb