aboutsummaryrefslogtreecommitdiff
path: root/src/ext/NetFx/be/detectnetcore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/NetFx/be/detectnetcore.cpp')
-rw-r--r--src/ext/NetFx/be/detectnetcore.cpp140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/ext/NetFx/be/detectnetcore.cpp b/src/ext/NetFx/be/detectnetcore.cpp
new file mode 100644
index 00000000..42156692
--- /dev/null
+++ b/src/ext/NetFx/be/detectnetcore.cpp
@@ -0,0 +1,140 @@
1// 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.
2
3#include "precomp.h"
4
5HRESULT DetectNetCore(
6 __in NETFX_NET_CORE_PLATFORM platform,
7 __in NETFX_NET_CORE_RUNTIME_TYPE runtimeType,
8 __in LPCWSTR wzMajorVersion,
9 __in LPCWSTR wzBaseDirectory,
10 __inout LPWSTR* psczLatestVersion
11 )
12{
13 HRESULT hr = S_OK;
14 LPCWSTR wzRuntimeType = NULL;
15 LPCWSTR wzPlatformName = NULL;
16 LPWSTR sczExePath = NULL;
17 LPWSTR sczCommandLine = NULL;
18 HANDLE hProcess = NULL;
19 HANDLE hStdOutErr = INVALID_HANDLE_VALUE;
20 BYTE* rgbOutput = NULL;
21 DWORD cbOutput = 0;
22 DWORD cbTotalRead = 0;
23 DWORD cbRead = 0;
24 DWORD dwExitCode = 0;
25
26 ReleaseNullStr(*psczLatestVersion);
27
28 switch (runtimeType)
29 {
30 case NETFX_NET_CORE_RUNTIME_TYPE_ASPNET:
31 wzRuntimeType = L"Microsoft.AspNetCore.App";
32 break;
33 case NETFX_NET_CORE_RUNTIME_TYPE_CORE:
34 wzRuntimeType = L"Microsoft.NETCore.App";
35 break;
36 case NETFX_NET_CORE_RUNTIME_TYPE_DESKTOP:
37 wzRuntimeType = L"Microsoft.WindowsDesktop.App";
38 break;
39 default:
40 BextExitWithRootFailure(hr, E_INVALIDARG, "Unknown runtime type: %u", runtimeType);
41 break;
42 }
43
44 switch (platform)
45 {
46 case NETFX_NET_CORE_PLATFORM_ARM64:
47 wzPlatformName = L"arm64";
48 break;
49 case NETFX_NET_CORE_PLATFORM_X64:
50 wzPlatformName = L"x64";
51 break;
52 case NETFX_NET_CORE_PLATFORM_X86:
53 wzPlatformName = L"x86";
54 break;
55 default:
56 BextExitWithRootFailure(hr, E_INVALIDARG, "Unknown platform: %u", platform);
57 break;
58 }
59
60 hr = StrAllocFormatted(&sczExePath, L"%ls%ls\\netcoresearch.exe", wzBaseDirectory, wzPlatformName);
61 BextExitOnFailure(hr, "Failed to build netcoresearch.exe path.");
62
63 hr = StrAllocFormatted(&sczCommandLine, L"\"%ls\" %ls %ls", sczExePath, wzMajorVersion, wzRuntimeType);
64 BextExitOnFailure(hr, "Failed to build netcoresearch.exe command line.");
65
66 hr = ProcExecute(sczExePath, sczCommandLine, &hProcess, NULL, &hStdOutErr);
67 if (HRESULT_FROM_WIN32(ERROR_EXE_MACHINE_TYPE_MISMATCH) == hr)
68 {
69 ExitFunction1(hr = S_FALSE);
70 }
71 BextExitOnFailure(hr, "Failed to run: %ls", sczCommandLine);
72
73 cbOutput = 64;
74
75 rgbOutput = reinterpret_cast<BYTE*>(MemAlloc(cbOutput, TRUE));
76 BextExitOnNull(rgbOutput, hr, E_OUTOFMEMORY, "Failed to alloc output string.");
77
78 while (::ReadFile(hStdOutErr, rgbOutput + cbTotalRead, cbOutput - cbTotalRead, &cbRead, NULL))
79 {
80 cbTotalRead += cbRead;
81
82 if (cbTotalRead == cbOutput)
83 {
84 cbOutput *= 2;
85
86 LPVOID pvNew = MemReAlloc(rgbOutput, cbOutput, TRUE);
87 BextExitOnNull(pvNew, hr, E_OUTOFMEMORY, "Failed to realloc output string.");
88
89 rgbOutput = reinterpret_cast<BYTE*>(pvNew);
90 }
91 }
92
93 if (ERROR_BROKEN_PIPE != ::GetLastError())
94 {
95 BextExitWithLastError(hr, "Failed to read netcoresearch.exe output.");
96 }
97
98 hr = ProcWaitForCompletion(hProcess, INFINITE, &dwExitCode);
99 BextExitOnFailure(hr, "Failed to wait for netcoresearch.exe to exit.");
100
101 if (0 != dwExitCode)
102 {
103 BextExitWithRootFailure(hr, E_UNEXPECTED, "netcoresearch.exe failed with exit code: 0x%x\r\nOutput:\r\n%hs", dwExitCode, rgbOutput);
104 }
105
106 if (*rgbOutput)
107 {
108 hr = StrAllocStringAnsi(psczLatestVersion, reinterpret_cast<LPSTR>(rgbOutput), 0, CP_UTF8);
109 BextExitOnFailure(hr, "Failed to widen output string: %hs", rgbOutput);
110 }
111
112LExit:
113 ReleaseFileHandle(hStdOutErr);
114 ReleaseHandle(hProcess);
115 ReleaseMem(rgbOutput);
116 ReleaseStr(sczCommandLine);
117 ReleaseStr(sczExePath);
118
119 return hr;
120}
121
122HRESULT NetfxPerformDetectNetCore(
123 __in LPCWSTR wzVariable,
124 __in NETFX_SEARCH* pSearch,
125 __in IBundleExtensionEngine* pEngine,
126 __in LPCWSTR wzBaseDirectory
127 )
128{
129 HRESULT hr = S_OK;
130 LPWSTR sczLatestVersion = FALSE;
131
132 hr = DetectNetCore(pSearch->NetCoreSearch.platform, pSearch->NetCoreSearch.runtimeType, pSearch->NetCoreSearch.sczMajorVersion, wzBaseDirectory, &sczLatestVersion);
133 BextExitOnFailure(hr, "DetectNetCore failed.");
134
135 hr = pEngine->SetVariableVersion(wzVariable, sczLatestVersion);
136 BextExitOnFailure(hr, "Failed to set variable '%ls' to '%ls'", wzVariable, sczLatestVersion);
137
138LExit:
139 return hr;
140}