From 853887b4e84df1965794802b7683f3a9aca3e930 Mon Sep 17 00:00:00 2001 From: Staffan Gustafsson Date: Wed, 30 Nov 2022 17:15:12 +0100 Subject: Adding support for DotNetCoreSdkSearch and DotNetCoreSdkCompatibilityCheck --- src/ext/NetFx/netcoresearch/netcoresearch.cpp | 216 +++++++++++++++++++++----- 1 file changed, 175 insertions(+), 41 deletions(-) (limited to 'src/ext/NetFx/netcoresearch') diff --git a/src/ext/NetFx/netcoresearch/netcoresearch.cpp b/src/ext/NetFx/netcoresearch/netcoresearch.cpp index 517f6ac4..5cf6d10b 100644 --- a/src/ext/NetFx/netcoresearch/netcoresearch.cpp +++ b/src/ext/NetFx/netcoresearch/netcoresearch.cpp @@ -2,16 +2,36 @@ #include "precomp.h" +enum class NETCORESEARCHKIND +{ + None, + Runtime, + Sdk, +}; + struct NETCORESEARCH_STATE { - LPCWSTR wzTargetName; - DWORD dwMajorVersion; + NETCORESEARCHKIND Kind = NETCORESEARCHKIND::None; + union + { + struct + { + LPCWSTR wzTargetName; + DWORD dwMajorVersion; + } Runtime; + struct + { + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwFeatureBand; + } + Sdk; + } Data; VERUTIL_VERSION* pVersion; }; static HRESULT GetDotnetEnvironmentInfo( - __in DWORD dwMajorVersion, - __in_z LPCWSTR wzTargetName, + __in NETCORESEARCH_STATE& pSearchState, __inout VERUTIL_VERSION** ppVersion ); static void HOSTFXR_CALLTYPE GetDotnetEnvironmentInfoResult( @@ -19,24 +39,28 @@ static void HOSTFXR_CALLTYPE GetDotnetEnvironmentInfoResult( __in LPVOID pvContext ); +bool string_equal_invariant(__in PCWSTR const x,__in PCWSTR const y) { return CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, x, -1, y, -1); } + +HRESULT get_search_state_from_arguments(__in int argc, __in LPWSTR argv[], __out NETCORESEARCH_STATE& searchState); + int __cdecl wmain(int argc, LPWSTR argv[]) { HRESULT hr = S_OK; - DWORD dwMajorVersion = 0; VERUTIL_VERSION* pVersion = NULL; + NETCORESEARCH_STATE searchState = {}; + + ::SetConsoleCP(CP_UTF8); ConsoleInitialize(); - if (argc != 3) + hr = get_search_state_from_arguments(argc, argv, OUT searchState); + if (FAILED(hr)) { - ExitFunction1(hr = E_INVALIDARG); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to parse arguments."); } - hr = StrStringToUInt32(argv[1], 0, reinterpret_cast(&dwMajorVersion)); - ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to get target version from: %ls", argv[1]); + hr = GetDotnetEnvironmentInfo(searchState, &pVersion); - hr = GetDotnetEnvironmentInfo(dwMajorVersion, argv[2], &pVersion); - ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to search for .NET Core."); if (pVersion) { @@ -49,9 +73,65 @@ LExit: return hr; } +HRESULT get_search_state_from_arguments(int argc, LPWSTR argv[], __out NETCORESEARCH_STATE& searchState) +{ + HRESULT hr = S_OK; + searchState = {}; + const auto searchKind = argv[1]; + + if (argc < 3) + { + ExitFunction1(hr = E_INVALIDARG); + } + + + if (string_equal_invariant(searchKind, L"runtime")) + { + if (argc != 4) + { + ExitFunction1(hr = E_INVALIDARG); + } + searchState.Kind = NETCORESEARCHKIND::Runtime; + + const PCWSTR majorVersion = argv[2]; + const PCWSTR targetName = argv[3]; + + auto& data = searchState.Data.Runtime; + + data.wzTargetName = targetName; + hr = StrStringToUInt32(majorVersion, 0, reinterpret_cast(&data.dwMajorVersion)); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to get target version from: %ls", majorVersion); + } + else if(string_equal_invariant(searchKind, L"sdk")) + { + searchState.Kind = NETCORESEARCHKIND::Sdk; + + const PCWSTR version = argv[2]; + + VERUTIL_VERSION* sdkVersion = nullptr; + hr = VerParseVersion(version, 0, FALSE, &sdkVersion); + if (FAILED(hr)) + { + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to parse version from: %ls", version); + } + + auto& data = searchState.Data.Sdk; + + data.dwMajorVersion = sdkVersion->dwMajor; + data.dwMinorVersion = sdkVersion->dwMinor; + data.dwFeatureBand = sdkVersion->dwPatch; + + VerFreeVersion(sdkVersion); + } + +LExit: + return hr; +} + + + static HRESULT GetDotnetEnvironmentInfo( - __in DWORD dwMajorVersion, - __in_z LPCWSTR wzTargetName, + __in NETCORESEARCH_STATE& state, __inout VERUTIL_VERSION** ppVersion ) { @@ -60,10 +140,6 @@ static HRESULT GetDotnetEnvironmentInfo( LPWSTR sczHostfxrPath = NULL; HMODULE hModule = NULL; hostfxr_get_dotnet_environment_info_fn pfnGetDotnetEnvironmentInfo = NULL; - NETCORESEARCH_STATE state = { }; - - state.dwMajorVersion = dwMajorVersion; - state.wzTargetName = wzTargetName; hr = PathForCurrentProcess(&sczProcessPath, NULL); ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to get process path."); @@ -102,50 +178,108 @@ LExit: return hr; } +bool matches_feature_band(const int requested, const int actual) +{ + // we have not requested a match on feature band, so skip the check + if (requested == 0) return true; + + const int requestedBand = requested / 100; + const int actualBand = actual / 100; + + if (actualBand != requestedBand) return false; + + return actual >= requested; +} + static void HOSTFXR_CALLTYPE GetDotnetEnvironmentInfoResult( __in const hostfxr_dotnet_environment_info* pInfo, __in LPVOID pvContext ) { - NETCORESEARCH_STATE* pState = reinterpret_cast(pvContext); + NETCORESEARCH_STATE* pState = static_cast(pvContext); HRESULT hr = S_OK; - VERUTIL_VERSION* pFrameworkVersion = NULL; + VERUTIL_VERSION* pDotnetVersion = nullptr; int nCompare = 0; - for (size_t i = 0; i < pInfo->framework_count; ++i) - { - const hostfxr_dotnet_environment_framework_info* pFrameworkInfo = pInfo->frameworks + i; - ReleaseVerutilVersion(pFrameworkVersion); - if (CSTR_EQUAL != ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pState->wzTargetName, -1, pFrameworkInfo->name, -1)) + if (pState->Kind == NETCORESEARCHKIND::Sdk) + { + auto& sdkData = pState->Data.Sdk; + for (size_t i = 0; i < pInfo->sdk_count; ++i) { - continue; - } + const hostfxr_dotnet_environment_sdk_info* pSdkInfo = pInfo->sdks + i; + ReleaseVerutilVersion(pDotnetVersion); - hr = VerParseVersion(pFrameworkInfo->version, 0, FALSE, &pFrameworkVersion); - ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to parse framework version: %ls", pFrameworkInfo->version); + hr = VerParseVersion(pSdkInfo->version, 0, FALSE, &pDotnetVersion); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to parse sdk version: %ls", pSdkInfo->version); - if (pFrameworkVersion->dwMajor != pState->dwMajorVersion) - { - continue; - } + if (pDotnetVersion->dwMajor != sdkData.dwMajorVersion) + { + continue; + } + if (!matches_feature_band(sdkData.dwFeatureBand, pDotnetVersion->dwPatch)) + { + continue; + } - if (pState->pVersion) + if (pState->pVersion) + { + hr = VerCompareParsedVersions(pState->pVersion, pDotnetVersion, &nCompare); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to compare versions."); + + if (nCompare > -1) + { + continue; + } + } + + ReleaseVerutilVersion(pState->pVersion); + pState->pVersion = pDotnetVersion; + pDotnetVersion = nullptr; + } + } + else if(pState->Kind == NETCORESEARCHKIND::Runtime) + { + auto& runtimeData = pState->Data.Runtime; + for (size_t i = 0; i < pInfo->framework_count; ++i) { - hr = VerCompareParsedVersions(pState->pVersion, pFrameworkVersion, &nCompare); - ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to compare versions."); + const hostfxr_dotnet_environment_framework_info* pFrameworkInfo = pInfo->frameworks + i; + ReleaseVerutilVersion(pDotnetVersion); - if (nCompare > -1) + if (string_equal_invariant(runtimeData.wzTargetName, pFrameworkInfo->name)) { continue; } - } - ReleaseVerutilVersion(pState->pVersion); - pState->pVersion = pFrameworkVersion; - pFrameworkVersion = NULL; + hr = VerParseVersion(pFrameworkInfo->version, 0, FALSE, &pDotnetVersion); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to parse framework version: %ls", pFrameworkInfo->version); + + if (pDotnetVersion->dwMajor != runtimeData.dwMajorVersion) + { + continue; + } + + if (pState->pVersion) + { + hr = VerCompareParsedVersions(pState->pVersion, pDotnetVersion, &nCompare); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to compare versions."); + + if (nCompare > -1) + { + continue; + } + } + + ReleaseVerutilVersion(pState->pVersion); + pState->pVersion = pDotnetVersion; + pDotnetVersion = nullptr; + } + } + else + { + ConsoleWriteError(E_INVALIDARG, CONSOLE_COLOR_RED, "Invalid NETCORESEARCHKIND."); } LExit: - ReleaseVerutilVersion(pFrameworkVersion); + ReleaseVerutilVersion(pDotnetVersion); } -- cgit v1.2.3-55-g6feb