Start using runtime properties to set StartupHook and EntrypointFilter (#10121)
This commit is contained in:
parent
5af8e170bc
commit
214ca07b6c
|
|
@ -30,7 +30,6 @@ void HostFxrErrorRedirector::HostFxrErrorRedirectorCallback(const WCHAR* message
|
|||
m_writeFunction->Append(std::wstring(message) + L"\r\n");
|
||||
}
|
||||
|
||||
|
||||
void HostFxr::Load()
|
||||
{
|
||||
HMODULE hModule;
|
||||
|
|
@ -43,9 +42,12 @@ void HostFxr::Load(HMODULE moduleHandle)
|
|||
m_hHostFxrDll = moduleHandle;
|
||||
try
|
||||
{
|
||||
m_hostfxr_main_fn = ModuleHelpers::GetKnownProcAddress<hostfxr_main_fn>(moduleHandle, "hostfxr_main");
|
||||
m_hostfxr_get_native_search_directories_fn = ModuleHelpers::GetKnownProcAddress<hostfxr_get_native_search_directories_fn>(moduleHandle, "hostfxr_get_native_search_directories");
|
||||
m_corehost_set_error_writer_fn = ModuleHelpers::GetKnownProcAddress<corehost_set_error_writer_fn>(moduleHandle, "hostfxr_set_error_writer", /* optional */ true);
|
||||
m_hostfxr_initialize_for_dotnet_commandline_fn = ModuleHelpers::GetKnownProcAddress<hostfxr_initialize_for_dotnet_runtime_fn>(moduleHandle, "hostfxr_initialize_for_dotnet_command_line", /* optional */ true);
|
||||
m_hostfxr_set_runtime_property_value_fn = ModuleHelpers::GetKnownProcAddress<hostfxr_set_runtime_property_value_fn>(moduleHandle, "hostfxr_set_runtime_property_value", /* optional */ true);
|
||||
m_hostfxr_run_app_fn = ModuleHelpers::GetKnownProcAddress<hostfxr_run_app_fn>(moduleHandle, "hostfxr_run_app", /* optional */ true);
|
||||
m_hostfxr_close_fn = ModuleHelpers::GetKnownProcAddress<hostfxr_close_fn>(moduleHandle, "hostfxr_close", /* optional */ true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
|
@ -59,7 +61,6 @@ void HostFxr::Load(HMODULE moduleHandle)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void HostFxr::Load(const std::wstring& location)
|
||||
{
|
||||
try
|
||||
|
|
@ -87,7 +88,14 @@ void HostFxr::SetMain(hostfxr_main_fn hostfxr_main_fn)
|
|||
|
||||
int HostFxr::Main(DWORD argc, const PCWSTR* argv) const noexcept(false)
|
||||
{
|
||||
return m_hostfxr_main_fn(argc, argv);
|
||||
if (m_host_context_handle != nullptr && m_hostfxr_run_app_fn != nullptr)
|
||||
{
|
||||
return m_hostfxr_run_app_fn(m_host_context_handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_hostfxr_main_fn(argc, argv);
|
||||
}
|
||||
}
|
||||
|
||||
int HostFxr::GetNativeSearchDirectories(INT argc, const PCWSTR* argv, PWSTR buffer, DWORD buffer_size, DWORD* required_buffer_size) const noexcept
|
||||
|
|
@ -99,3 +107,62 @@ HostFxrErrorRedirector HostFxr::RedirectOutput(RedirectionOutput* writer) const
|
|||
{
|
||||
return HostFxrErrorRedirector(m_corehost_set_error_writer_fn, writer);
|
||||
}
|
||||
|
||||
int HostFxr::InitializeForApp(int argc, PCWSTR* argv, const std::wstring& dotnetExe) const noexcept
|
||||
{
|
||||
if (m_hostfxr_initialize_for_dotnet_commandline_fn == nullptr || m_hostfxr_main_fn != nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
hostfxr_initialize_parameters params;
|
||||
params.size = sizeof(hostfxr_initialize_parameters);
|
||||
params.host_path = L"";
|
||||
|
||||
// Transformation occurs here rather than hostfxr arguments as hostfxr_get_native_directories still needs
|
||||
// exe as the first argument.
|
||||
if (!dotnetExe.empty())
|
||||
{
|
||||
// Portable application
|
||||
// argv[0] = dotnet.exe
|
||||
// argv[1] = app.dll
|
||||
// argv[2] = rest of the args
|
||||
|
||||
std::filesystem::path dotnetExePath(dotnetExe);
|
||||
auto dotnetFolderPath = dotnetExePath.parent_path();
|
||||
params.dotnet_root = dotnetFolderPath.c_str();
|
||||
|
||||
RETURN_INT_IF_NOT_ZERO(m_hostfxr_initialize_for_dotnet_commandline_fn(argc - 1, &argv[1], ¶ms, &m_host_context_handle));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Standalone application
|
||||
// argv[0] = app.exe
|
||||
// argv[1] = rest of the args
|
||||
params.dotnet_root = L"";
|
||||
std::filesystem::path applicationPath(argv[0]);
|
||||
applicationPath.replace_extension(".dll");
|
||||
argv[0] = applicationPath.c_str();
|
||||
|
||||
RETURN_INT_IF_NOT_ZERO(m_hostfxr_initialize_for_dotnet_commandline_fn(argc, argv, ¶ms, &m_host_context_handle));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HostFxr::SetRuntimePropertyValue(PCWSTR name, PCWSTR value) const noexcept
|
||||
{
|
||||
if (m_host_context_handle != nullptr && m_hostfxr_set_runtime_property_value_fn != nullptr)
|
||||
{
|
||||
return m_hostfxr_set_runtime_property_value_fn(m_host_context_handle, name, value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HostFxr::Close() const noexcept
|
||||
{
|
||||
if (m_host_context_handle != nullptr && m_hostfxr_close_fn != nullptr)
|
||||
{
|
||||
m_hostfxr_close_fn(m_host_context_handle);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,26 @@
|
|||
#include "exceptions.h"
|
||||
#include "RedirectionOutput.h"
|
||||
|
||||
struct hostfxr_initialize_parameters
|
||||
{
|
||||
size_t size;
|
||||
PCWSTR host_path;
|
||||
PCWSTR dotnet_root;
|
||||
};
|
||||
|
||||
#define DOTNETCORE_STARTUP_HOOK L"STARTUP_HOOKS"
|
||||
#define DOTNETCORE_USE_ENTRYPOINT_FILTER L"USE_ENTRYPOINT_FILTER"
|
||||
#define DOTNETCORE_STACK_SIZE L"DEFAULT_STACK_SIZE"
|
||||
#define ASPNETCORE_STARTUP_ASSEMBLY L"Microsoft.AspNetCore.Server.IIS"
|
||||
|
||||
typedef INT(*hostfxr_get_native_search_directories_fn) (INT argc, CONST PCWSTR* argv, PWSTR buffer, DWORD buffer_size, DWORD* required_buffer_size);
|
||||
typedef INT(*hostfxr_main_fn) (DWORD argc, CONST PCWSTR argv[]);
|
||||
typedef void(*corehost_error_writer_fn) (const WCHAR* message);
|
||||
typedef corehost_error_writer_fn(*corehost_set_error_writer_fn) (corehost_error_writer_fn error_writer);
|
||||
typedef int(*hostfxr_initialize_for_dotnet_runtime_fn)(int argc, const PCWSTR* argv, hostfxr_initialize_parameters* parameters, void* const* host_context_handle);
|
||||
typedef int(*hostfxr_set_runtime_property_value_fn)(void* host_context_handle, PCWSTR name, PCWSTR value);
|
||||
typedef int(*hostfxr_run_app_fn)(void* host_context_handle);
|
||||
typedef int(*hostfxr_close_fn)(void* hostfxr_context_handle);
|
||||
|
||||
struct ErrorContext
|
||||
{
|
||||
|
|
@ -49,7 +65,8 @@ public:
|
|||
corehost_set_error_writer_fn corehost_set_error_writer_fn) noexcept
|
||||
: m_hostfxr_main_fn(hostfxr_main_fn),
|
||||
m_hostfxr_get_native_search_directories_fn(hostfxr_get_native_search_directories_fn),
|
||||
m_corehost_set_error_writer_fn(corehost_set_error_writer_fn)
|
||||
m_corehost_set_error_writer_fn(corehost_set_error_writer_fn),
|
||||
m_host_context_handle(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -66,10 +83,18 @@ public:
|
|||
int GetNativeSearchDirectories(INT argc, CONST PCWSTR* argv, PWSTR buffer, DWORD buffer_size, DWORD* required_buffer_size) const noexcept;
|
||||
|
||||
HostFxrErrorRedirector RedirectOutput(RedirectionOutput* writer) const noexcept;
|
||||
int SetRuntimePropertyValue(PCWSTR name, PCWSTR value) const noexcept;
|
||||
int InitializeForApp(int argc, PCWSTR* argv, const std::wstring& m_dotnetExeKnownLocation) const noexcept;
|
||||
void Close() const noexcept;
|
||||
|
||||
private:
|
||||
HandleWrapper<ModuleHandleTraits> m_hHostFxrDll;
|
||||
hostfxr_main_fn m_hostfxr_main_fn;
|
||||
hostfxr_get_native_search_directories_fn m_hostfxr_get_native_search_directories_fn;
|
||||
hostfxr_initialize_for_dotnet_runtime_fn m_hostfxr_initialize_for_dotnet_commandline_fn;
|
||||
hostfxr_set_runtime_property_value_fn m_hostfxr_set_runtime_property_value_fn;
|
||||
hostfxr_run_app_fn m_hostfxr_run_app_fn;
|
||||
corehost_set_error_writer_fn m_corehost_set_error_writer_fn;
|
||||
hostfxr_close_fn m_hostfxr_close_fn;
|
||||
void* m_host_context_handle;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -89,6 +89,9 @@
|
|||
#define SUCCEEDED_LOG(hr) SUCCEEDED(LOG_IF_FAILED(hr))
|
||||
#define FAILED_LOG(hr) FAILED(LOG_IF_FAILED(hr))
|
||||
|
||||
#define RETURN_INT_IF_NOT_ZERO(val) do { if ((val) != 0) { return val; }} while (0, 0)
|
||||
#define RETURN_IF_NOT_ZERO(val) do { if ((val) != 0) { return; }} while (0, 0)
|
||||
|
||||
inline thread_local IHttpTraceContext* g_traceContext;
|
||||
|
||||
__declspec(noinline) inline VOID TraceHRESULT(LOCATION_ARGUMENTS HRESULT hr)
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ IN_PROCESS_APPLICATION::StopInternal(bool fServerInitiated)
|
|||
VOID
|
||||
IN_PROCESS_APPLICATION::StopClr()
|
||||
{
|
||||
// This has the state lock around it.
|
||||
// This has the state lock around it.
|
||||
LOG_INFO(L"Stopping CLR");
|
||||
|
||||
if (!m_blockManagedCallbacks)
|
||||
|
|
@ -241,25 +241,19 @@ IN_PROCESS_APPLICATION::ExecuteApplication()
|
|||
LOG_INFOF(L"Setting current directory to %s", this->QueryApplicationPhysicalPath().c_str());
|
||||
}
|
||||
|
||||
if (m_pConfig->QueryCallStartupHook())
|
||||
auto startupReturnCode = context->m_hostFxr.InitializeForApp(context->m_argc, context->m_argv.get(), m_dotnetExeKnownLocation);
|
||||
if (startupReturnCode != 0)
|
||||
{
|
||||
// Used to display developer exception page when there is an exception in main.
|
||||
auto currentStartupHookEnv = Environment::GetEnvironmentVariableValue(DOTNETCORE_STARTUP_HOOK);
|
||||
|
||||
if (currentStartupHookEnv.has_value())
|
||||
{
|
||||
currentStartupHookEnv = currentStartupHookEnv.value() + L";" + ASPNETCORE_STARTUP_ASSEMBLY;
|
||||
LOG_LAST_ERROR_IF(!SetEnvironmentVariable(DOTNETCORE_STARTUP_HOOK, currentStartupHookEnv.value().c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_LAST_ERROR_IF(!SetEnvironmentVariable(DOTNETCORE_STARTUP_HOOK, ASPNETCORE_STARTUP_ASSEMBLY));
|
||||
}
|
||||
throw InvalidOperationException(format(L"Error occured when initializing inprocess application, Return code: 0x%x", startupReturnCode));
|
||||
}
|
||||
|
||||
// Used to make .NET Runtime always log to event log when there is an unhandled exception.
|
||||
LOG_LAST_ERROR_IF(!SetEnvironmentVariable(L"COMPlus_UseEntryPointFilter", L"1"));
|
||||
LOG_LAST_ERROR_IF(!SetEnvironmentVariable(L"COMPlus_DefaultStackSize", m_pConfig->QueryStackSize().c_str()));
|
||||
if (m_pConfig->QueryCallStartupHook())
|
||||
{
|
||||
RETURN_IF_NOT_ZERO(context->m_hostFxr.SetRuntimePropertyValue(DOTNETCORE_STARTUP_HOOK, ASPNETCORE_STARTUP_ASSEMBLY));
|
||||
}
|
||||
|
||||
RETURN_IF_NOT_ZERO(context->m_hostFxr.SetRuntimePropertyValue(DOTNETCORE_USE_ENTRYPOINT_FILTER, L"1"));
|
||||
RETURN_IF_NOT_ZERO(context->m_hostFxr.SetRuntimePropertyValue(DOTNETCORE_STACK_SIZE, m_pConfig->QueryStackSize().c_str()));
|
||||
|
||||
bool clrThreadExited;
|
||||
{
|
||||
|
|
@ -434,6 +428,7 @@ IN_PROCESS_APPLICATION::ExecuteClr(const std::shared_ptr<ExecuteClrContext>& con
|
|||
LOG_INFOF(L"Managed application exited with code %d", exitCode);
|
||||
|
||||
context->m_exitCode = exitCode;
|
||||
context->m_hostFxr.Close();
|
||||
}
|
||||
__except(GetExceptionCode() != 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ typedef BOOL(WINAPI * PFN_SHUTDOWN_HANDLER) (void* pvShutdownHandlerContext);
|
|||
typedef REQUEST_NOTIFICATION_STATUS(WINAPI * PFN_ASYNC_COMPLETION_HANDLER)(void *pvManagedHttpContext, HRESULT hrCompletionStatus, DWORD cbCompletion);
|
||||
typedef void(WINAPI * PFN_REQUESTS_DRAINED_HANDLER) (void* pvShutdownHandlerContext);
|
||||
|
||||
#define DOTNETCORE_STARTUP_HOOK L"DOTNET_STARTUP_HOOKS"
|
||||
#define ASPNETCORE_STARTUP_ASSEMBLY L"Microsoft.AspNetCore.Server.IIS"
|
||||
class IN_PROCESS_APPLICATION : public InProcessApplicationBase
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
Loading…
Reference in New Issue