@joebigelow / wix / commits / d96ba426

Use hdt_get_function_pointer in dnchost when available.

Sean Hall committed Jul 22, 2020 at 19:55 UTC d96ba4263bf243dedb62e9090072fba53bfe1316
5 files changed +61 -8
src/WixToolset.Dnc.Host/BootstrapperApplicationFactory.cs
+2
@@ -7,6 +7,8 @@ namespace WixToolset.Dnc.Host
7 using System.Reflection;
8 using System.Runtime.InteropServices;
9
10 + delegate IBootstrapperApplicationFactory StaticEntryDelegate([MarshalAs(UnmanagedType.LPWStr)] string baFactoryAssemblyName, [MarshalAs(UnmanagedType.LPWStr)] string baFactoryAssemblyPath);
11 +
12 /// <summary>
13 /// Entry point for the .NET Core host to create and return the BA to the engine.
14 /// Reflection is used instead of referencing WixToolset.Mba.Core directly to avoid requiring it in the AssemblyLoadContext.
src/WixToolset.Dnc.Host/WixToolset.Dnc.Host.csproj
+3
@@ -24,7 +24,10 @@
24 <Line Include='#define DNC_ASSEMBLY_FILE_NAME L"$(AssemblyName).dll"' />
25 <Line Include='#define DNC_ASSEMBLY_FULL_NAME "%(AssemblyIdentity.Identity)"' />
26 <Line Include='#define DNC_ENTRY_TYPE "$(RootNamespace).BootstrapperApplicationFactory"' />
27 + <Line Include='#define DNC_ENTRY_TYPEW L"$(RootNamespace).BootstrapperApplicationFactory,$(AssemblyName)"' />
28 <Line Include='#define DNC_STATIC_ENTRY_METHOD "CreateBAFactory"' />
29 + <Line Include='#define DNC_STATIC_ENTRY_METHODW L"CreateBAFactory"' />
30 + <Line Include='#define DNC_STATIC_ENTRY_DELEGATEW L"$(RootNamespace).StaticEntryDelegate,$(AssemblyName)"' />
31 </ItemGroup>
32 <Message Importance="normal" Text="Generating identity definitions into @(HeaderPath->'%(FullPath)')" />
33 <WriteLinesToFile File="@(HeaderPath)" Lines="@(Line)" Overwrite="True" />
src/dnchost/dncutil.cpp
+53 -8
@@ -3,7 +3,9 @@
3 #include "precomp.h"
4
5 // https://github.com/dotnet/runtime/blob/master/src/installer/corehost/error_codes.h
6 +#define InvalidArgFailure 0x80008081
7 #define HostApiBufferTooSmall 0x80008098
8 +#define HostApiUnsupportedVersion 0x800080a2
9
10 // internal function declarations
11
@@ -24,6 +26,10 @@ static HRESULT InitializeCoreClr(
26 __in HOSTFXR_STATE* pState,
27 __in LPCWSTR wzNativeHostPath
28 );
29 +static HRESULT InitializeCoreClrPre5(
30 + __in HOSTFXR_STATE* pState,
31 + __in LPCWSTR wzNativeHostPath
32 + );
33 static HRESULT LoadCoreClr(
34 __in HOSTFXR_STATE* pState,
35 __in LPCWSTR wzCoreClrPath
@@ -75,14 +81,28 @@ HRESULT DnchostCreateFactory(
81 HRESULT hr = S_OK;
82 PFNCREATEBAFACTORY pfnCreateBAFactory = NULL;
83
78 - hr = pState->pfnCoreclrCreateDelegate(
79 - pState->pClrHandle,
80 - pState->dwDomainId,
81 - DNC_ASSEMBLY_FULL_NAME,
82 - DNC_ENTRY_TYPE,
83 - DNC_STATIC_ENTRY_METHOD,
84 - reinterpret_cast<void**>(&pfnCreateBAFactory));
85 - BalExitOnFailure(hr, "Failed to create delegate in app domain.");
84 + if (pState->pfnGetFunctionPointer)
85 + {
86 + hr = pState->pfnGetFunctionPointer(
87 + DNC_ENTRY_TYPEW,
88 + DNC_STATIC_ENTRY_METHODW,
89 + DNC_STATIC_ENTRY_DELEGATEW,
90 + NULL,
91 + NULL,
92 + reinterpret_cast<void**>(&pfnCreateBAFactory));
93 + BalExitOnFailure(hr, "Failed to create delegate through GetFunctionPointer.");
94 + }
95 + else
96 + {
97 + hr = pState->pfnCoreclrCreateDelegate(
98 + pState->pClrHandle,
99 + pState->dwDomainId,
100 + DNC_ASSEMBLY_FULL_NAME,
101 + DNC_ENTRY_TYPE,
102 + DNC_STATIC_ENTRY_METHOD,
103 + reinterpret_cast<void**>(&pfnCreateBAFactory));
104 + BalExitOnFailure(hr, "Failed to create delegate in app domain.");
105 + }
106
107 *ppAppFactory = pfnCreateBAFactory(wzBaFactoryAssemblyName, wzBaFactoryAssemblyPath);
108
@@ -149,6 +169,9 @@ static HRESULT LoadHostfxr(
169 pState->pfnHostfxrClose = reinterpret_cast<hostfxr_close_fn>(::GetProcAddress(hHostfxr, "hostfxr_close"));
170 BalExitOnNullWithLastError(pState->pfnHostfxrClose, hr, "Failed to get procedure address for hostfxr_close.");
171
172 + pState->pfnHostfxrGetRuntimeDelegate = reinterpret_cast<hostfxr_get_runtime_delegate_fn>(::GetProcAddress(hHostfxr, "hostfxr_get_runtime_delegate"));
173 + BalExitOnNullWithLastError(pState->pfnHostfxrGetRuntimeDelegate, hr, "Failed to get procedure address for hostfxr_get_runtime_delegate.");
174 +
175 LExit:
176 // Never unload the module since it isn't meant to be unloaded.
177
@@ -194,6 +217,28 @@ static HRESULT InitializeCoreClr(
217 )
218 {
219 HRESULT hr = S_OK;
220 +
221 + hr = pState->pfnHostfxrGetRuntimeDelegate(pState->hostContextHandle, hdt_get_function_pointer, reinterpret_cast<void**>(&pState->pfnGetFunctionPointer));
222 + if (InvalidArgFailure == hr || // old versions of hostfxr don't allow calling GetRuntimeDelegate from InitializeForApp.
223 + HostApiUnsupportedVersion == hr) // hdt_get_function_pointer was added in .NET 5.
224 + {
225 + hr = InitializeCoreClrPre5(pState, wzNativeHostPath);
226 + }
227 + else
228 + {
229 + ExitOnFailure(hr, "HostfxrGetRuntimeDelegate failed");
230 + }
231 +
232 +LExit:
233 + return hr;
234 +}
235 +
236 +static HRESULT InitializeCoreClrPre5(
237 + __in HOSTFXR_STATE* pState,
238 + __in LPCWSTR wzNativeHostPath
239 + )
240 +{
241 + HRESULT hr = S_OK;
242 int32_t rc = 0;
243 LPCWSTR* rgPropertyKeys = NULL;
244 LPCWSTR* rgPropertyValues = NULL;
src/dnchost/dncutil.h
+2
@@ -14,6 +14,8 @@ struct HOSTFXR_STATE
14 hostfxr_get_runtime_properties_fn pfnHostfxrGetRuntimeProperties;
15 hostfxr_set_error_writer_fn pfnHostfxrSetErrorWriter;
16 hostfxr_close_fn pfnHostfxrClose;
17 + hostfxr_get_runtime_delegate_fn pfnHostfxrGetRuntimeDelegate;
18 + get_function_pointer_fn pfnGetFunctionPointer;
19 coreclr_initialize_ptr pfnCoreclrInitialize;
20 coreclr_create_delegate_ptr pfnCoreclrCreateDelegate;
21 void* pClrHandle;
src/dnchost/precomp.h
+1
@@ -24,6 +24,7 @@
24 #define NETHOST_USE_AS_STATIC
25 #include <nethost.h>
26 #include <hostfxr.h>
27 +#include <coreclr_delegates.h>
28
29 #include "coreclrhost.h"
30 #include "dncutil.h"