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/be/detectnetcore.cpp | 2 +- src/ext/NetFx/be/detectnetcoresdk.cpp | 122 ++++++++++++++++++++++++++++++++++ src/ext/NetFx/be/detectnetcoresdk.h | 9 +++ src/ext/NetFx/be/netfxbe.vcxproj | 2 + src/ext/NetFx/be/netfxsearch.cpp | 25 +++++-- src/ext/NetFx/be/netfxsearch.h | 6 ++ src/ext/NetFx/be/precomp.h | 1 + 7 files changed, 162 insertions(+), 5 deletions(-) create mode 100644 src/ext/NetFx/be/detectnetcoresdk.cpp create mode 100644 src/ext/NetFx/be/detectnetcoresdk.h (limited to 'src/ext/NetFx/be') diff --git a/src/ext/NetFx/be/detectnetcore.cpp b/src/ext/NetFx/be/detectnetcore.cpp index 42156692..aeb04203 100644 --- a/src/ext/NetFx/be/detectnetcore.cpp +++ b/src/ext/NetFx/be/detectnetcore.cpp @@ -60,7 +60,7 @@ HRESULT DetectNetCore( hr = StrAllocFormatted(&sczExePath, L"%ls%ls\\netcoresearch.exe", wzBaseDirectory, wzPlatformName); BextExitOnFailure(hr, "Failed to build netcoresearch.exe path."); - hr = StrAllocFormatted(&sczCommandLine, L"\"%ls\" %ls %ls", sczExePath, wzMajorVersion, wzRuntimeType); + hr = StrAllocFormatted(&sczCommandLine, L"\"%ls\" runtime %ls %ls", sczExePath, wzMajorVersion, wzRuntimeType); BextExitOnFailure(hr, "Failed to build netcoresearch.exe command line."); hr = ProcExecute(sczExePath, sczCommandLine, &hProcess, NULL, &hStdOutErr); diff --git a/src/ext/NetFx/be/detectnetcoresdk.cpp b/src/ext/NetFx/be/detectnetcoresdk.cpp new file mode 100644 index 00000000..08b18334 --- /dev/null +++ b/src/ext/NetFx/be/detectnetcoresdk.cpp @@ -0,0 +1,122 @@ +// 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 "precomp.h" + +HRESULT DetectNetCoreSdk( + __in NETFX_NET_CORE_PLATFORM platform, + __in LPCWSTR wzVersion, + __in LPCWSTR wzBaseDirectory, + __inout LPWSTR* psczLatestVersion + ) +{ + HRESULT hr = S_OK; + LPCWSTR wzPlatformName = NULL; + LPWSTR sczExePath = NULL; + LPWSTR sczCommandLine = NULL; + HANDLE hProcess = NULL; + HANDLE hStdOutErr = INVALID_HANDLE_VALUE; + BYTE* rgbOutput = NULL; + DWORD cbOutput = 0; + DWORD cbTotalRead = 0; + DWORD cbRead = 0; + DWORD dwExitCode = 0; + + ReleaseNullStr(*psczLatestVersion); + + switch (platform) + { + case NETFX_NET_CORE_PLATFORM_ARM64: + wzPlatformName = L"arm64"; + break; + case NETFX_NET_CORE_PLATFORM_X64: + wzPlatformName = L"x64"; + break; + case NETFX_NET_CORE_PLATFORM_X86: + wzPlatformName = L"x86"; + break; + default: + BextExitWithRootFailure(hr, E_INVALIDARG, "Unknown platform: %u", platform); + break; + } + + hr = StrAllocFormatted(&sczExePath, L"%ls%ls\\netcoresearch.exe", wzBaseDirectory, wzPlatformName); + BextExitOnFailure(hr, "Failed to build netcoresearch.exe path."); + + hr = StrAllocFormatted(&sczCommandLine, L"\"%ls\" sdk %ls", sczExePath, wzVersion); + BextExitOnFailure(hr, "Failed to build netcoresearch.exe command line."); + + hr = ProcExecute(sczExePath, sczCommandLine, &hProcess, NULL, &hStdOutErr); + if (HRESULT_FROM_WIN32(ERROR_EXE_MACHINE_TYPE_MISMATCH) == hr) + { + ExitFunction1(hr = S_FALSE); + } + BextExitOnFailure(hr, "Failed to run: %ls", sczCommandLine); + + cbOutput = 64; + + rgbOutput = static_cast(MemAlloc(cbOutput, TRUE)); + BextExitOnNull(rgbOutput, hr, E_OUTOFMEMORY, "Failed to alloc output string."); + + while (::ReadFile(hStdOutErr, rgbOutput + cbTotalRead, cbOutput - cbTotalRead, &cbRead, NULL)) + { + cbTotalRead += cbRead; + + if (cbTotalRead == cbOutput) + { + cbOutput *= 2; + + const LPVOID pvNew = MemReAlloc(rgbOutput, cbOutput, TRUE); + BextExitOnNull(pvNew, hr, E_OUTOFMEMORY, "Failed to realloc output string."); + + rgbOutput = static_cast(pvNew); + } + } + + if (ERROR_BROKEN_PIPE != ::GetLastError()) + { + BextExitWithLastError(hr, "Failed to read netcoresearch.exe output."); + } + + hr = ProcWaitForCompletion(hProcess, INFINITE, &dwExitCode); + BextExitOnFailure(hr, "Failed to wait for netcoresearch.exe to exit."); + + if (0 != dwExitCode) + { + BextExitWithRootFailure(hr, E_UNEXPECTED, "netcoresearch.exe failed with exit code: 0x%x\r\nOutput:\r\n%hs", dwExitCode, rgbOutput); + } + + if (*rgbOutput) + { + hr = StrAllocStringAnsi(psczLatestVersion, reinterpret_cast(rgbOutput), 0, CP_UTF8); + BextExitOnFailure(hr, "Failed to widen output string: %hs", rgbOutput); + } + +LExit: + ReleaseFileHandle(hStdOutErr); + ReleaseHandle(hProcess); + ReleaseMem(rgbOutput); + ReleaseStr(sczCommandLine); + ReleaseStr(sczExePath); + + return hr; +} + +HRESULT NetfxPerformDetectNetCoreSdk( + __in LPCWSTR wzVariable, + __in NETFX_SEARCH* pSearch, + __in IBundleExtensionEngine* pEngine, + __in LPCWSTR wzBaseDirectory + ) +{ + HRESULT hr = S_OK; + LPWSTR sczLatestVersion = nullptr; + const auto& searchParams = pSearch->NetCoreSdkSearch; + hr = DetectNetCoreSdk(searchParams.platform, searchParams.sczVersion, wzBaseDirectory, &sczLatestVersion); + BextExitOnFailure(hr, "DetectNetCoreSdk failed."); + + hr = pEngine->SetVariableVersion(wzVariable, sczLatestVersion); + BextExitOnFailure(hr, "Failed to set variable '%ls' to '%ls'", wzVariable, sczLatestVersion); + +LExit: + return hr; +} diff --git a/src/ext/NetFx/be/detectnetcoresdk.h b/src/ext/NetFx/be/detectnetcoresdk.h new file mode 100644 index 00000000..025deaa2 --- /dev/null +++ b/src/ext/NetFx/be/detectnetcoresdk.h @@ -0,0 +1,9 @@ +#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. + +HRESULT NetfxPerformDetectNetCoreSdk( + __in LPCWSTR wzVariable, + __in NETFX_SEARCH* pSearch, + __in IBundleExtensionEngine* pEngine, + __in LPCWSTR wzBaseDirectory + ); diff --git a/src/ext/NetFx/be/netfxbe.vcxproj b/src/ext/NetFx/be/netfxbe.vcxproj index d1084dd1..0408da72 100644 --- a/src/ext/NetFx/be/netfxbe.vcxproj +++ b/src/ext/NetFx/be/netfxbe.vcxproj @@ -47,6 +47,7 @@ + @@ -57,6 +58,7 @@ + diff --git a/src/ext/NetFx/be/netfxsearch.cpp b/src/ext/NetFx/be/netfxsearch.cpp index 3c12161d..671e7546 100644 --- a/src/ext/NetFx/be/netfxsearch.cpp +++ b/src/ext/NetFx/be/netfxsearch.cpp @@ -15,7 +15,7 @@ STDMETHODIMP NetfxSearchParseFromXml( BSTR bstrNodeName = NULL; // Select Netfx search nodes. - hr = XmlSelectNodes(pixnBundleExtension, L"NetFxNetCoreSearch", &pixnNodes); + hr = XmlSelectNodes(pixnBundleExtension, L"NetFxNetCoreSearch|NetFxNetCoreSdkSearch", &pixnNodes); BextExitOnFailure(hr, "Failed to select Netfx search nodes."); // Get Netfx search node count. @@ -50,18 +50,32 @@ STDMETHODIMP NetfxSearchParseFromXml( { pSearch->Type = NETFX_SEARCH_TYPE_NET_CORE_SEARCH; + auto& netCoreSearch = pSearch->NetCoreSearch; // @RuntimeType - hr = XmlGetAttributeUInt32(pixnNode, L"RuntimeType", reinterpret_cast(&pSearch->NetCoreSearch.runtimeType)); + hr = XmlGetAttributeUInt32(pixnNode, L"RuntimeType", reinterpret_cast(&netCoreSearch.runtimeType)); BextExitOnFailure(hr, "Failed to get @RuntimeType."); // @Platform - hr = XmlGetAttributeUInt32(pixnNode, L"Platform", reinterpret_cast(&pSearch->NetCoreSearch.platform)); + hr = XmlGetAttributeUInt32(pixnNode, L"Platform", reinterpret_cast(&netCoreSearch.platform)); BextExitOnFailure(hr, "Failed to get @Platform."); // @MajorVersion - hr = XmlGetAttributeEx(pixnNode, L"MajorVersion", &pSearch->NetCoreSearch.sczMajorVersion); + hr = XmlGetAttributeEx(pixnNode, L"MajorVersion", &netCoreSearch.sczMajorVersion); BextExitOnFailure(hr, "Failed to get @MajorVersion."); } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrNodeName, -1, L"NetFxNetCoreSdkSearch", -1)) + { + pSearch->Type = NETFX_SEARCH_TYPE_NET_CORE_SDK_SEARCH; + + auto& netCoreSdkSearch = pSearch->NetCoreSdkSearch; + // @Platform + hr = XmlGetAttributeUInt32(pixnNode, L"Platform", reinterpret_cast(&netCoreSdkSearch.platform)); + BextExitOnFailure(hr, "Failed to get @Platform."); + + // @Version + hr = XmlGetAttributeEx(pixnNode, L"Version", &netCoreSdkSearch.sczVersion); + BextExitOnFailure(hr, "Failed to get @Version."); + } else { BextExitWithRootFailure(hr, E_UNEXPECTED, "Unexpected element name: %ls", bstrNodeName); @@ -115,6 +129,9 @@ STDMETHODIMP NetfxSearchExecute( case NETFX_SEARCH_TYPE_NET_CORE_SEARCH: hr = NetfxPerformDetectNetCore(wzVariable, pSearch, pEngine, wzBaseDirectory); break; + case NETFX_SEARCH_TYPE_NET_CORE_SDK_SEARCH: + hr = NetfxPerformDetectNetCoreSdk(wzVariable, pSearch, pEngine, wzBaseDirectory); + break; default: hr = E_UNEXPECTED; } diff --git a/src/ext/NetFx/be/netfxsearch.h b/src/ext/NetFx/be/netfxsearch.h index ae250690..f4e4db01 100644 --- a/src/ext/NetFx/be/netfxsearch.h +++ b/src/ext/NetFx/be/netfxsearch.h @@ -8,6 +8,7 @@ enum NETFX_SEARCH_TYPE { NETFX_SEARCH_TYPE_NONE, NETFX_SEARCH_TYPE_NET_CORE_SEARCH, + NETFX_SEARCH_TYPE_NET_CORE_SDK_SEARCH, }; enum NETFX_NET_CORE_RUNTIME_TYPE @@ -40,6 +41,11 @@ typedef struct _NETFX_SEARCH NETFX_NET_CORE_PLATFORM platform; LPWSTR sczMajorVersion; } NetCoreSearch; + struct + { + NETFX_NET_CORE_PLATFORM platform; + LPWSTR sczVersion; + } NetCoreSdkSearch; }; } NETFX_SEARCH; diff --git a/src/ext/NetFx/be/precomp.h b/src/ext/NetFx/be/precomp.h index 33aea9bc..4a774200 100644 --- a/src/ext/NetFx/be/precomp.h +++ b/src/ext/NetFx/be/precomp.h @@ -30,4 +30,5 @@ #include "..\..\beDecor.h" #include "netfxsearch.h" #include "detectnetcore.h" +#include "detectnetcoresdk.h" #include "NetfxBundleExtension.h" -- cgit v1.2.3-55-g6feb