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"