From d96ba4263bf243dedb62e9090072fba53bfe1316 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Wed, 22 Jul 2020 19:55:20 +1000 Subject: Use hdt_get_function_pointer in dnchost when available. --- .../BootstrapperApplicationFactory.cs | 2 + src/WixToolset.Dnc.Host/WixToolset.Dnc.Host.csproj | 3 ++ src/dnchost/dncutil.cpp | 61 +++++++++++++++++++--- src/dnchost/dncutil.h | 2 + src/dnchost/precomp.h | 1 + 5 files changed, 61 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/WixToolset.Dnc.Host/BootstrapperApplicationFactory.cs b/src/WixToolset.Dnc.Host/BootstrapperApplicationFactory.cs index 0c6ea367..d38fd1a9 100644 --- a/src/WixToolset.Dnc.Host/BootstrapperApplicationFactory.cs +++ b/src/WixToolset.Dnc.Host/BootstrapperApplicationFactory.cs @@ -7,6 +7,8 @@ namespace WixToolset.Dnc.Host using System.Reflection; using System.Runtime.InteropServices; + delegate IBootstrapperApplicationFactory StaticEntryDelegate([MarshalAs(UnmanagedType.LPWStr)] string baFactoryAssemblyName, [MarshalAs(UnmanagedType.LPWStr)] string baFactoryAssemblyPath); + /// /// Entry point for the .NET Core host to create and return the BA to the engine. /// Reflection is used instead of referencing WixToolset.Mba.Core directly to avoid requiring it in the AssemblyLoadContext. diff --git a/src/WixToolset.Dnc.Host/WixToolset.Dnc.Host.csproj b/src/WixToolset.Dnc.Host/WixToolset.Dnc.Host.csproj index 495b13a2..707edd1b 100644 --- a/src/WixToolset.Dnc.Host/WixToolset.Dnc.Host.csproj +++ b/src/WixToolset.Dnc.Host/WixToolset.Dnc.Host.csproj @@ -24,7 +24,10 @@ + + + diff --git a/src/dnchost/dncutil.cpp b/src/dnchost/dncutil.cpp index 996bf086..4a82d961 100644 --- a/src/dnchost/dncutil.cpp +++ b/src/dnchost/dncutil.cpp @@ -3,7 +3,9 @@ #include "precomp.h" // https://github.com/dotnet/runtime/blob/master/src/installer/corehost/error_codes.h +#define InvalidArgFailure 0x80008081 #define HostApiBufferTooSmall 0x80008098 +#define HostApiUnsupportedVersion 0x800080a2 // internal function declarations @@ -24,6 +26,10 @@ static HRESULT InitializeCoreClr( __in HOSTFXR_STATE* pState, __in LPCWSTR wzNativeHostPath ); +static HRESULT InitializeCoreClrPre5( + __in HOSTFXR_STATE* pState, + __in LPCWSTR wzNativeHostPath + ); static HRESULT LoadCoreClr( __in HOSTFXR_STATE* pState, __in LPCWSTR wzCoreClrPath @@ -75,14 +81,28 @@ HRESULT DnchostCreateFactory( HRESULT hr = S_OK; PFNCREATEBAFACTORY pfnCreateBAFactory = NULL; - hr = pState->pfnCoreclrCreateDelegate( - pState->pClrHandle, - pState->dwDomainId, - DNC_ASSEMBLY_FULL_NAME, - DNC_ENTRY_TYPE, - DNC_STATIC_ENTRY_METHOD, - reinterpret_cast(&pfnCreateBAFactory)); - BalExitOnFailure(hr, "Failed to create delegate in app domain."); + if (pState->pfnGetFunctionPointer) + { + hr = pState->pfnGetFunctionPointer( + DNC_ENTRY_TYPEW, + DNC_STATIC_ENTRY_METHODW, + DNC_STATIC_ENTRY_DELEGATEW, + NULL, + NULL, + reinterpret_cast(&pfnCreateBAFactory)); + BalExitOnFailure(hr, "Failed to create delegate through GetFunctionPointer."); + } + else + { + hr = pState->pfnCoreclrCreateDelegate( + pState->pClrHandle, + pState->dwDomainId, + DNC_ASSEMBLY_FULL_NAME, + DNC_ENTRY_TYPE, + DNC_STATIC_ENTRY_METHOD, + reinterpret_cast(&pfnCreateBAFactory)); + BalExitOnFailure(hr, "Failed to create delegate in app domain."); + } *ppAppFactory = pfnCreateBAFactory(wzBaFactoryAssemblyName, wzBaFactoryAssemblyPath); @@ -149,6 +169,9 @@ static HRESULT LoadHostfxr( pState->pfnHostfxrClose = reinterpret_cast(::GetProcAddress(hHostfxr, "hostfxr_close")); BalExitOnNullWithLastError(pState->pfnHostfxrClose, hr, "Failed to get procedure address for hostfxr_close."); + pState->pfnHostfxrGetRuntimeDelegate = reinterpret_cast(::GetProcAddress(hHostfxr, "hostfxr_get_runtime_delegate")); + BalExitOnNullWithLastError(pState->pfnHostfxrGetRuntimeDelegate, hr, "Failed to get procedure address for hostfxr_get_runtime_delegate."); + LExit: // Never unload the module since it isn't meant to be unloaded. @@ -194,6 +217,28 @@ static HRESULT InitializeCoreClr( ) { HRESULT hr = S_OK; + + hr = pState->pfnHostfxrGetRuntimeDelegate(pState->hostContextHandle, hdt_get_function_pointer, reinterpret_cast(&pState->pfnGetFunctionPointer)); + if (InvalidArgFailure == hr || // old versions of hostfxr don't allow calling GetRuntimeDelegate from InitializeForApp. + HostApiUnsupportedVersion == hr) // hdt_get_function_pointer was added in .NET 5. + { + hr = InitializeCoreClrPre5(pState, wzNativeHostPath); + } + else + { + ExitOnFailure(hr, "HostfxrGetRuntimeDelegate failed"); + } + +LExit: + return hr; +} + +static HRESULT InitializeCoreClrPre5( + __in HOSTFXR_STATE* pState, + __in LPCWSTR wzNativeHostPath + ) +{ + HRESULT hr = S_OK; int32_t rc = 0; LPCWSTR* rgPropertyKeys = NULL; LPCWSTR* rgPropertyValues = NULL; diff --git a/src/dnchost/dncutil.h b/src/dnchost/dncutil.h index 1a7c16e3..85eda3b2 100644 --- a/src/dnchost/dncutil.h +++ b/src/dnchost/dncutil.h @@ -14,6 +14,8 @@ struct HOSTFXR_STATE hostfxr_get_runtime_properties_fn pfnHostfxrGetRuntimeProperties; hostfxr_set_error_writer_fn pfnHostfxrSetErrorWriter; hostfxr_close_fn pfnHostfxrClose; + hostfxr_get_runtime_delegate_fn pfnHostfxrGetRuntimeDelegate; + get_function_pointer_fn pfnGetFunctionPointer; coreclr_initialize_ptr pfnCoreclrInitialize; coreclr_create_delegate_ptr pfnCoreclrCreateDelegate; void* pClrHandle; diff --git a/src/dnchost/precomp.h b/src/dnchost/precomp.h index d19a0780..84ff6424 100644 --- a/src/dnchost/precomp.h +++ b/src/dnchost/precomp.h @@ -24,6 +24,7 @@ #define NETHOST_USE_AS_STATIC #include #include +#include #include "coreclrhost.h" #include "dncutil.h" -- cgit v1.2.3-55-g6feb