From 7ca91e5b04070620897d58377512775b77568689 Mon Sep 17 00:00:00 2001 From: Vitek Karas Date: Fri, 8 Mar 2019 13:49:23 -0800 Subject: [PATCH] Split libhost.h into multiple headers and cleanup (dotnet/core-setup#5391) Commit migrated from https://github.com/dotnet/core-setup/commit/3586f526ae50b9c1f7e31019a317a7358f1f2170 --- src/installer/corehost/cli/args.cpp | 1 - src/installer/corehost/cli/args.h | 2 +- src/installer/corehost/cli/deps_resolver.cpp | 1 - src/installer/corehost/cli/fxr/CMakeLists.txt | 1 - src/installer/corehost/cli/fxr/corehost_init.h | 173 ++++++++ src/installer/corehost/cli/fxr/framework_info.h | 3 +- src/installer/corehost/cli/fxr/fx_muxer.cpp | 73 +++- src/installer/corehost/cli/fxr/fx_muxer.h | 4 +- src/installer/corehost/cli/fxr/hostfxr.cpp | 1 - src/installer/corehost/cli/fxr/sdk_info.h | 3 +- src/installer/corehost/cli/host_interface.h | 97 +++++ src/installer/corehost/cli/hostpolicy.cpp | 1 - .../corehost/cli/hostpolicy/CMakeLists.txt | 1 - src/installer/corehost/cli/hostpolicy_init.h | 172 ++++++++ src/installer/corehost/cli/libhost.cpp | 148 ------- src/installer/corehost/cli/libhost.h | 436 --------------------- 16 files changed, 522 insertions(+), 595 deletions(-) create mode 100644 src/installer/corehost/cli/fxr/corehost_init.h create mode 100644 src/installer/corehost/cli/host_interface.h create mode 100644 src/installer/corehost/cli/hostpolicy_init.h delete mode 100644 src/installer/corehost/cli/libhost.cpp delete mode 100644 src/installer/corehost/cli/libhost.h diff --git a/src/installer/corehost/cli/args.cpp b/src/installer/corehost/cli/args.cpp index 01042ba..ac17e74 100644 --- a/src/installer/corehost/cli/args.cpp +++ b/src/installer/corehost/cli/args.cpp @@ -4,7 +4,6 @@ #include "args.h" #include "utils.h" #include "coreclr.h" -#include "libhost.h" arguments_t::arguments_t() : managed_application(_X("")) diff --git a/src/installer/corehost/cli/args.h b/src/installer/corehost/cli/args.h index fd56f65..44a5479 100644 --- a/src/installer/corehost/cli/args.h +++ b/src/installer/corehost/cli/args.h @@ -8,7 +8,7 @@ #include "pal.h" #include "trace.h" #include "deps_format.h" -#include "libhost.h" +#include "hostpolicy_init.h" struct probe_config_t { diff --git a/src/installer/corehost/cli/deps_resolver.cpp b/src/installer/corehost/cli/deps_resolver.cpp index 8651cb0..d8abbde 100644 --- a/src/installer/corehost/cli/deps_resolver.cpp +++ b/src/installer/corehost/cli/deps_resolver.cpp @@ -11,7 +11,6 @@ #include "deps_resolver.h" #include "utils.h" #include "fx_ver.h" -#include "libhost.h" const pal::string_t MissingAssemblyMessage = _X( "%s:\n" diff --git a/src/installer/corehost/cli/fxr/CMakeLists.txt b/src/installer/corehost/cli/fxr/CMakeLists.txt index 4b45037..b3909ea 100644 --- a/src/installer/corehost/cli/fxr/CMakeLists.txt +++ b/src/installer/corehost/cli/fxr/CMakeLists.txt @@ -13,7 +13,6 @@ include_directories(../json/casablanca/include) set(SOURCES ../../common/trace.cpp ../../common/utils.cpp - ../libhost.cpp ../deps_format.cpp ../deps_entry.cpp ../host_startup_info.cpp diff --git a/src/installer/corehost/cli/fxr/corehost_init.h b/src/installer/corehost/cli/fxr/corehost_init.h new file mode 100644 index 0000000..5aeb3bd --- /dev/null +++ b/src/installer/corehost/cli/fxr/corehost_init.h @@ -0,0 +1,173 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#ifndef __COREHOST_INIT_H__ +#define __COREHOST_INIT_H__ + +#include "pal.h" +#include "host_interface.h" +#include "fx_definition.h" + +class corehost_init_t +{ +private: + std::vector m_clr_keys; + std::vector m_clr_values; + std::vector m_clr_keys_cstr; + std::vector m_clr_values_cstr; + const pal::string_t m_tfm; + const pal::string_t m_deps_file; + const pal::string_t m_additional_deps_serialized; + bool m_is_framework_dependent; + std::vector m_probe_paths; + std::vector m_probe_paths_cstr; + host_mode_t m_host_mode; + host_interface_t m_host_interface; + std::vector m_fx_names; + std::vector m_fx_names_cstr; + std::vector m_fx_dirs; + std::vector m_fx_dirs_cstr; + std::vector m_fx_requested_versions; + std::vector m_fx_requested_versions_cstr; + std::vector m_fx_found_versions; + std::vector m_fx_found_versions_cstr; + const pal::string_t m_host_command; + const pal::string_t m_host_info_host_path; + const pal::string_t m_host_info_dotnet_root; + const pal::string_t m_host_info_app_path; +public: + corehost_init_t( + const pal::string_t& host_command, + const host_startup_info_t& host_info, + const pal::string_t& deps_file, + const pal::string_t& additional_deps_serialized, + const std::vector& probe_paths, + const host_mode_t mode, + const fx_definition_vector_t& fx_definitions) + : m_host_command(host_command) + , m_host_info_host_path(host_info.host_path) + , m_host_info_dotnet_root(host_info.dotnet_root) + , m_host_info_app_path(host_info.app_path) + , m_deps_file(deps_file) + , m_additional_deps_serialized(additional_deps_serialized) + , m_is_framework_dependent(get_app(fx_definitions).get_runtime_config().get_is_framework_dependent()) + , m_probe_paths(probe_paths) + , m_host_mode(mode) + , m_host_interface() + , m_tfm(get_app(fx_definitions).get_runtime_config().get_tfm()) + { + make_cstr_arr(m_probe_paths, &m_probe_paths_cstr); + + int fx_count = fx_definitions.size(); + m_fx_names.reserve(fx_count); + m_fx_dirs.reserve(fx_count); + m_fx_requested_versions.reserve(fx_count); + m_fx_found_versions.reserve(fx_count); + + std::unordered_map combined_properties; + for (auto& fx : fx_definitions) + { + fx->get_runtime_config().combine_properties(combined_properties); + + m_fx_names.push_back(fx->get_name()); + m_fx_dirs.push_back(fx->get_dir()); + m_fx_requested_versions.push_back(fx->get_requested_version()); + m_fx_found_versions.push_back(fx->get_found_version()); + } + + for (const auto& kv : combined_properties) + { + m_clr_keys.push_back(kv.first); + m_clr_values.push_back(kv.second); + } + + make_cstr_arr(m_fx_names, &m_fx_names_cstr); + make_cstr_arr(m_fx_dirs, &m_fx_dirs_cstr); + make_cstr_arr(m_fx_requested_versions, &m_fx_requested_versions_cstr); + make_cstr_arr(m_fx_found_versions, &m_fx_found_versions_cstr); + make_cstr_arr(m_clr_keys, &m_clr_keys_cstr); + make_cstr_arr(m_clr_values, &m_clr_values_cstr); + } + + const pal::string_t& tfm() const + { + return m_tfm; + } + + const host_interface_t& get_host_init_data() + { + host_interface_t& hi = m_host_interface; + + hi.version_lo = HOST_INTERFACE_LAYOUT_VERSION_LO; + hi.version_hi = HOST_INTERFACE_LAYOUT_VERSION_HI; + + hi.config_keys.len = m_clr_keys_cstr.size(); + hi.config_keys.arr = m_clr_keys_cstr.data(); + + hi.config_values.len = m_clr_values_cstr.size(); + hi.config_values.arr = m_clr_values_cstr.data(); + + // Keep these for backwards compat + if (m_fx_names_cstr.size() > 1) + { + hi.fx_name = m_fx_names_cstr[1]; + hi.fx_dir = m_fx_dirs_cstr[1]; + hi.fx_ver = m_fx_requested_versions_cstr[1]; + } + else + { + hi.fx_name = _X(""); + hi.fx_dir = _X(""); + hi.fx_ver = _X(""); + } + + hi.deps_file = m_deps_file.c_str(); + hi.additional_deps_serialized = m_additional_deps_serialized.c_str(); + hi.is_framework_dependent = m_is_framework_dependent; + + hi.probe_paths.len = m_probe_paths_cstr.size(); + hi.probe_paths.arr = m_probe_paths_cstr.data(); + + // These are not used anymore, but we have to keep them for backward compat reasons. + // Set default values. + hi.patch_roll_forward = true; + hi.prerelease_roll_forward = false; + + hi.host_mode = m_host_mode; + + hi.tfm = m_tfm.c_str(); + + hi.fx_names.len = m_fx_names_cstr.size(); + hi.fx_names.arr = m_fx_names_cstr.data(); + + hi.fx_dirs.len = m_fx_dirs_cstr.size(); + hi.fx_dirs.arr = m_fx_dirs_cstr.data(); + + hi.fx_requested_versions.len = m_fx_requested_versions_cstr.size(); + hi.fx_requested_versions.arr = m_fx_requested_versions_cstr.data(); + + hi.fx_found_versions.len = m_fx_found_versions_cstr.size(); + hi.fx_found_versions.arr = m_fx_found_versions_cstr.data(); + + hi.host_command = m_host_command.c_str(); + + hi.host_info_host_path = m_host_info_host_path.c_str(); + hi.host_info_dotnet_root = m_host_info_dotnet_root.c_str(); + hi.host_info_app_path = m_host_info_app_path.c_str(); + + return hi; + } + +private: + + static void make_cstr_arr(const std::vector& arr, std::vector* out) + { + out->reserve(arr.size()); + for (const auto& str : arr) + { + out->push_back(str.c_str()); + } + } +}; + +#endif // __COREHOST_INIT_H__ \ No newline at end of file diff --git a/src/installer/corehost/cli/fxr/framework_info.h b/src/installer/corehost/cli/fxr/framework_info.h index d502f95..4953882 100644 --- a/src/installer/corehost/cli/fxr/framework_info.h +++ b/src/installer/corehost/cli/fxr/framework_info.h @@ -4,7 +4,8 @@ #ifndef __FRAMEWORK_INFO_H_ #define __FRAMEWORK_INFO_H_ -#include "libhost.h" +#include "pal.h" +#include "fx_ver.h" struct framework_info { diff --git a/src/installer/corehost/cli/fxr/fx_muxer.cpp b/src/installer/corehost/cli/fxr/fx_muxer.cpp index 8438147..863f489 100644 --- a/src/installer/corehost/cli/fxr/fx_muxer.cpp +++ b/src/installer/corehost/cli/fxr/fx_muxer.cpp @@ -5,6 +5,7 @@ #include #include "args.h" #include "cpprest/json.h" +#include "corehost_init.h" #include "deps_format.h" #include "error_codes.h" #include "framework_info.h" @@ -13,7 +14,6 @@ #include "fx_reference.h" #include "fx_ver.h" #include "host_startup_info.h" -#include "libhost.h" #include "pal.h" #include "runtime_config.h" #include "sdk_info.h" @@ -402,6 +402,48 @@ bool resolve_hostpolicy_dir_from_probe_paths(const pal::string_t& version, const return false; } +void get_runtime_config_paths_from_arg(const pal::string_t& arg, pal::string_t* cfg, pal::string_t* dev_cfg) +{ + auto name = get_filename_without_ext(arg); + + auto json_name = name + _X(".json"); + auto dev_json_name = name + _X(".dev.json"); + + auto json_path = get_directory(arg); + auto dev_json_path = json_path; + + append_path(&json_path, json_name.c_str()); + append_path(&dev_json_path, dev_json_name.c_str()); + + trace::verbose(_X("Runtime config is cfg=%s dev=%s"), json_path.c_str(), dev_json_path.c_str()); + + dev_cfg->assign(dev_json_path); + cfg->assign(json_path); +} + +void get_runtime_config_paths(const pal::string_t& path, const pal::string_t& name, pal::string_t* cfg, pal::string_t* dev_cfg) +{ + auto json_path = path; + auto json_name = name + _X(".runtimeconfig.json"); + append_path(&json_path, json_name.c_str()); + cfg->assign(json_path); + + auto dev_json_path = path; + auto dev_json_name = name + _X(".runtimeconfig.dev.json"); + append_path(&dev_json_path, dev_json_name.c_str()); + dev_cfg->assign(dev_json_path); + + trace::verbose(_X("Runtime config is cfg=%s dev=%s"), json_path.c_str(), dev_json_path.c_str()); +} + +void get_runtime_config_paths_from_app(const pal::string_t& app, pal::string_t* cfg, pal::string_t* dev_cfg) +{ + auto name = get_filename_without_ext(app); + auto path = get_directory(app); + + get_runtime_config_paths(path, name, cfg, dev_cfg); +} + /** * Return name of deps file for app. */ @@ -1010,6 +1052,35 @@ int read_config( return StatusCode::Success; } +host_mode_t detect_operating_mode(const host_startup_info_t& host_info) +{ + if (coreclr_exists_in_dir(host_info.dotnet_root)) + { + // Detect between standalone apphost or legacy split mode (specifying --depsfile and --runtimeconfig) + + pal::string_t deps_in_dotnet_root = host_info.dotnet_root; + pal::string_t deps_filename = host_info.get_app_name() + _X(".deps.json"); + append_path(&deps_in_dotnet_root, deps_filename.c_str()); + bool deps_exists = pal::file_exists(deps_in_dotnet_root); + + trace::info(_X("Detecting mode... CoreCLR present in dotnet root [%s] and checking if [%s] file present=[%d]"), + host_info.dotnet_root.c_str(), deps_filename.c_str(), deps_exists); + + // Name of runtimeconfig file; since no path is included here the check is in the current working directory + pal::string_t config_in_cwd = host_info.get_app_name() + _X(".runtimeconfig.json"); + + return (deps_exists || !pal::file_exists(config_in_cwd)) && pal::file_exists(host_info.app_path) ? host_mode_t::apphost : host_mode_t::split_fx; + } + + if (pal::file_exists(host_info.app_path)) + { + // Framework-dependent apphost + return host_mode_t::apphost; + } + + return host_mode_t::muxer; +} + int fx_muxer_t::soft_roll_forward_helper( const fx_reference_t& newer, const fx_reference_t& older, diff --git a/src/installer/corehost/cli/fxr/fx_muxer.h b/src/installer/corehost/cli/fxr/fx_muxer.h index cdf00bd..4ed98c0 100644 --- a/src/installer/corehost/cli/fxr/fx_muxer.h +++ b/src/installer/corehost/cli/fxr/fx_muxer.h @@ -8,7 +8,9 @@ struct fx_ver_t; struct host_startup_info_t; #include -#include "libhost.h" +#include "fx_definition.h" +#include "host_interface.h" +#include "host_startup_info.h" const int Max_Framework_Resolve_Retries = 100; diff --git a/src/installer/corehost/cli/fxr/hostfxr.cpp b/src/installer/corehost/cli/fxr/hostfxr.cpp index 09638f1..a430f5f 100644 --- a/src/installer/corehost/cli/fxr/hostfxr.cpp +++ b/src/installer/corehost/cli/fxr/hostfxr.cpp @@ -8,7 +8,6 @@ #include "fx_ver.h" #include "fx_muxer.h" #include "error_codes.h" -#include "libhost.h" #include "corehost.h" #include "runtime_config.h" #include "sdk_info.h" diff --git a/src/installer/corehost/cli/fxr/sdk_info.h b/src/installer/corehost/cli/fxr/sdk_info.h index 1c296fc..399b94e 100644 --- a/src/installer/corehost/cli/fxr/sdk_info.h +++ b/src/installer/corehost/cli/fxr/sdk_info.h @@ -4,7 +4,8 @@ #ifndef __SDK_INFO_H_ #define __SDK_INFO_H_ -#include "libhost.h" +#include "pal.h" +#include "fx_ver.h" struct sdk_info { diff --git a/src/installer/corehost/cli/host_interface.h b/src/installer/corehost/cli/host_interface.h new file mode 100644 index 0000000..d0bd2f0 --- /dev/null +++ b/src/installer/corehost/cli/host_interface.h @@ -0,0 +1,97 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#ifndef __HOST_INTERFACE_H__ +#define __HOST_INTERFACE_H__ + +#include "pal.h" + +enum host_mode_t +{ + invalid = 0, + + muxer, // Invoked as "dotnet.exe". + + apphost, // Invoked as .exe from the application base; this is the renamed "apphost.exe". + + split_fx, // Invoked as "corehost.exe" for xunit scenarios. Supported for backwards compat for 1.x apps. + // Split FX means, the host is operating like "corerun.exe" in a split location from the application base (CORE_ROOT equivalent), + // but it has its "hostfxr.dll" next to it. + + libhost, // Invoked from a non-exe scenario (e.g. COM Activation or self-hosting native application) +}; + +#define _HOST_INTERFACE_PACK 1 +#pragma pack(push, _HOST_INTERFACE_PACK) +struct strarr_t +{ + // DO NOT modify this struct. It is used in a layout + // dependent manner. Create another for your use. + size_t len; + const pal::char_t** arr; +}; + +struct host_interface_t +{ + size_t version_lo; // Just assign sizeof() to this field. + size_t version_hi; // Breaking changes to the layout -- increment HOST_INTERFACE_LAYOUT_VERSION + strarr_t config_keys; + strarr_t config_values; + const pal::char_t* fx_dir; + const pal::char_t* fx_name; + const pal::char_t* deps_file; + size_t is_framework_dependent; + strarr_t probe_paths; + size_t patch_roll_forward; + size_t prerelease_roll_forward; + size_t host_mode; + const pal::char_t* tfm; + const pal::char_t* additional_deps_serialized; + const pal::char_t* fx_ver; + strarr_t fx_names; + strarr_t fx_dirs; + strarr_t fx_requested_versions; + strarr_t fx_found_versions; + const pal::char_t* host_command; + const pal::char_t* host_info_host_path; + const pal::char_t* host_info_dotnet_root; + const pal::char_t* host_info_app_path; + // !! WARNING / WARNING / WARNING / WARNING / WARNING / WARNING / WARNING / WARNING / WARNING + // !! 1. Only append to this structure to maintain compat. + // !! 2. Any nested structs should not use compiler specific padding (pack with _HOST_INTERFACE_PACK) + // !! 3. Do not take address of the fields of this struct or be prepared to deal with unaligned accesses. + // !! 4. Must be POD types; only use non-const size_t and pointer types; no access modifiers. + // !! 5. Do not reorder fields or change any existing field types. + // !! 6. Add static asserts for fields you add. +}; +#pragma pack(pop) +static_assert(_HOST_INTERFACE_PACK == 1, "Packing size should not be modified for back compat"); +static_assert(offsetof(host_interface_t, version_lo) == 0 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, version_hi) == 1 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, config_keys) == 2 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, config_values) == 4 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, fx_dir) == 6 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, fx_name) == 7 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, deps_file) == 8 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, is_framework_dependent) == 9 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, probe_paths) == 10 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, patch_roll_forward) == 12 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, prerelease_roll_forward) == 13 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, host_mode) == 14 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, tfm) == 15 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, additional_deps_serialized) == 16 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, fx_ver) == 17 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, fx_names) == 18 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, fx_dirs) == 20 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, fx_requested_versions) == 22 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, fx_found_versions) == 24 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, host_command) == 26 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, host_info_host_path) == 27 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, host_info_dotnet_root) == 28 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(offsetof(host_interface_t, host_info_app_path) == 29 * sizeof(size_t), "Struct offset breaks backwards compatibility"); +static_assert(sizeof(host_interface_t) == 30 * sizeof(size_t), "Did you add static asserts for the newly added fields?"); + +#define HOST_INTERFACE_LAYOUT_VERSION_HI 0x16041101 // YYMMDD:nn always increases when layout breaks compat. +#define HOST_INTERFACE_LAYOUT_VERSION_LO sizeof(host_interface_t) + +#endif // __HOST_INTERFACE_H__ diff --git a/src/installer/corehost/cli/hostpolicy.cpp b/src/installer/corehost/cli/hostpolicy.cpp index d1c0365..5f2b455 100644 --- a/src/installer/corehost/cli/hostpolicy.cpp +++ b/src/installer/corehost/cli/hostpolicy.cpp @@ -11,7 +11,6 @@ #include "coreclr.h" #include "corehost.h" #include "cpprest/json.h" -#include "libhost.h" #include "error_codes.h" #include "breadcrumbs.h" #include "host_startup_info.h" diff --git a/src/installer/corehost/cli/hostpolicy/CMakeLists.txt b/src/installer/corehost/cli/hostpolicy/CMakeLists.txt index 203b652..483c6c6 100644 --- a/src/installer/corehost/cli/hostpolicy/CMakeLists.txt +++ b/src/installer/corehost/cli/hostpolicy/CMakeLists.txt @@ -14,7 +14,6 @@ include_directories(../json/casablanca/include) set(SOURCES ../../common/trace.cpp ../../common/utils.cpp - ../libhost.cpp ../runtime_config.cpp ../json/casablanca/src/json/json.cpp ../json/casablanca/src/json/json_parsing.cpp diff --git a/src/installer/corehost/cli/hostpolicy_init.h b/src/installer/corehost/cli/hostpolicy_init.h new file mode 100644 index 0000000..6ede732 --- /dev/null +++ b/src/installer/corehost/cli/hostpolicy_init.h @@ -0,0 +1,172 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#ifndef __HOSTPOLICY_INIT_H__ +#define __HOSTPOLICY_INIT_H__ +#include "trace.h" +#include "host_interface.h" +#include "host_startup_info.h" +#include "fx_definition.h" +#include "fx_ver.h" + +struct hostpolicy_init_t +{ + std::vector> cfg_keys; + std::vector> cfg_values; + pal::string_t deps_file; + pal::string_t additional_deps_serialized; + std::vector probe_paths; + fx_definition_vector_t fx_definitions; + pal::string_t tfm; + host_mode_t host_mode; + bool patch_roll_forward; + bool prerelease_roll_forward; + bool is_framework_dependent; + pal::string_t host_command; + host_startup_info_t host_info; + + static bool init(host_interface_t* input, hostpolicy_init_t* init) + { + // Check if there are any breaking changes. + if (input->version_hi != HOST_INTERFACE_LAYOUT_VERSION_HI) + { + trace::error(_X("The version of the data layout used to initialize %s is [0x%04x]; expected version [0x%04x]"), LIBHOSTPOLICY_NAME, input->version_hi, HOST_INTERFACE_LAYOUT_VERSION_HI); + return false; + } + + trace::verbose(_X("Reading from host interface version: [0x%04x:%d] to initialize policy version: [0x%04x:%d]"), input->version_hi, input->version_lo, HOST_INTERFACE_LAYOUT_VERSION_HI, HOST_INTERFACE_LAYOUT_VERSION_LO); + + //This check is to ensure is an old hostfxr can still load new hostpolicy. + //We should not read garbage due to potentially shorter struct size + + pal::string_t fx_requested_ver; + + if (input->version_lo >= offsetof(host_interface_t, host_mode) + sizeof(input->host_mode)) + { + make_clrstr_arr(input->config_keys.len, input->config_keys.arr, &init->cfg_keys); + make_clrstr_arr(input->config_values.len, input->config_values.arr, &init->cfg_values); + + init->deps_file = input->deps_file; + init->is_framework_dependent = input->is_framework_dependent; + + make_palstr_arr(input->probe_paths.len, input->probe_paths.arr, &init->probe_paths); + + init->patch_roll_forward = input->patch_roll_forward; + init->prerelease_roll_forward = input->prerelease_roll_forward; + init->host_mode = (host_mode_t)input->host_mode; + } + else + { + trace::error(_X("The size of the data layout used to initialize %s is %d; expected at least %d"), LIBHOSTPOLICY_NAME, input->version_lo, + offsetof(host_interface_t, host_mode) + sizeof(input->host_mode)); + } + + //An old hostfxr may not provide these fields. + //The version_lo (sizeof) the old hostfxr saw at build time will be + //smaller and we should not attempt to read the fields in that case. + if (input->version_lo >= offsetof(host_interface_t, tfm) + sizeof(input->tfm)) + { + init->tfm = input->tfm; + } + + if (input->version_lo >= offsetof(host_interface_t, fx_ver) + sizeof(input->fx_ver)) + { + init->additional_deps_serialized = input->additional_deps_serialized; + fx_requested_ver = input->fx_ver; + } + + int fx_count = 0; + if (input->version_lo >= offsetof(host_interface_t, fx_names) + sizeof(input->fx_names)) + { + int fx_count = input->fx_names.len; + assert(fx_count > 0); + assert(fx_count == input->fx_dirs.len); + assert(fx_count == input->fx_requested_versions.len); + assert(fx_count == input->fx_found_versions.len); + + std::vector fx_names; + std::vector fx_dirs; + std::vector fx_requested_versions; + std::vector fx_found_versions; + + make_palstr_arr(input->fx_names.len, input->fx_names.arr, &fx_names); + make_palstr_arr(input->fx_dirs.len, input->fx_dirs.arr, &fx_dirs); + make_palstr_arr(input->fx_requested_versions.len, input->fx_requested_versions.arr, &fx_requested_versions); + make_palstr_arr(input->fx_found_versions.len, input->fx_found_versions.arr, &fx_found_versions); + + init->fx_definitions.reserve(fx_count); + for (int i = 0; i < fx_count; ++i) + { + auto fx = new fx_definition_t(fx_names[i], fx_dirs[i], fx_requested_versions[i], fx_found_versions[i]); + init->fx_definitions.push_back(std::unique_ptr(fx)); + } + } + else + { + // Backward compat; create the fx_definitions[0] and [1] from the previous information + init->fx_definitions.reserve(2); + + auto fx = new fx_definition_t(); + init->fx_definitions.push_back(std::unique_ptr(fx)); + + if (init->is_framework_dependent) + { + pal::string_t fx_dir = input->fx_dir; + pal::string_t fx_name = input->fx_name; + + // The found_ver was not passed previously, so obtain that from fx_dir + pal::string_t fx_found_ver; + size_t index = fx_dir.rfind(DIR_SEPARATOR); + if (index != pal::string_t::npos) + { + fx_found_ver = fx_dir.substr(index + 1); + } + + fx = new fx_definition_t(fx_name, fx_dir, fx_requested_ver, fx_found_ver); + init->fx_definitions.push_back(std::unique_ptr(fx)); + } + } + + // Initialize the host command + init_host_command(input, init); + + if (input->version_lo >= offsetof(host_interface_t, host_info_host_path) + sizeof(input->host_info_host_path)) + { + init->host_info.host_path = input->host_info_host_path; + init->host_info.dotnet_root = input->host_info_dotnet_root; + init->host_info.app_path = input->host_info_app_path; + // For the backwards compat case, this will be later initialized with argv[0] + } + + return true; + } + + static void init_host_command(host_interface_t* input, hostpolicy_init_t* init) + { + if (input->version_lo >= offsetof(host_interface_t, host_command) + sizeof(input->host_command)) + { + init->host_command = input->host_command; + } + } + +private: + static void make_palstr_arr(int argc, const pal::char_t** argv, std::vector* out) + { + out->reserve(argc); + for (int i = 0; i < argc; ++i) + { + out->push_back(argv[i]); + } + } + + static void make_clrstr_arr(int argc, const pal::char_t** argv, std::vector>* out) + { + out->resize(argc); + for (int i = 0; i < argc; ++i) + { + pal::pal_clrstring(pal::string_t(argv[i]), &(*out)[i]); + } + } +}; + +#endif // __HOSTPOLICY_INIT_H__ diff --git a/src/installer/corehost/cli/libhost.cpp b/src/installer/corehost/cli/libhost.cpp deleted file mode 100644 index 81b5277..0000000 --- a/src/installer/corehost/cli/libhost.cpp +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#include "pal.h" -#include "utils.h" -#include "trace.h" -#include "libhost.h" -#include "host_startup_info.h" - -void get_runtime_config_paths_from_app(const pal::string_t& app, pal::string_t* cfg, pal::string_t* dev_cfg) -{ - auto name = get_filename_without_ext(app); - auto path = get_directory(app); - - get_runtime_config_paths(path, name, cfg, dev_cfg); -} - -void get_runtime_config_paths_from_arg(const pal::string_t& arg, pal::string_t* cfg, pal::string_t* dev_cfg) -{ - auto name = get_filename_without_ext(arg); - - auto json_name = name + _X(".json"); - auto dev_json_name = name + _X(".dev.json"); - - auto json_path = get_directory(arg); - auto dev_json_path = json_path; - - append_path(&json_path, json_name.c_str()); - append_path(&dev_json_path, dev_json_name.c_str()); - - trace::verbose(_X("Runtime config is cfg=%s dev=%s"), json_path.c_str(), dev_json_path.c_str()); - - dev_cfg->assign(dev_json_path); - cfg->assign(json_path); -} - -void get_runtime_config_paths(const pal::string_t& path, const pal::string_t& name, pal::string_t* cfg, pal::string_t* dev_cfg) -{ - auto json_path = path; - auto json_name = name + _X(".runtimeconfig.json"); - append_path(&json_path, json_name.c_str()); - cfg->assign(json_path); - - auto dev_json_path = path; - auto dev_json_name = name + _X(".runtimeconfig.dev.json"); - append_path(&dev_json_path, dev_json_name.c_str()); - dev_cfg->assign(dev_json_path); - - trace::verbose(_X("Runtime config is cfg=%s dev=%s"), json_path.c_str(), dev_json_path.c_str()); -} - -host_mode_t detect_operating_mode(const host_startup_info_t& host_info) -{ - if (coreclr_exists_in_dir(host_info.dotnet_root)) - { - // Detect between standalone apphost or legacy split mode (specifying --depsfile and --runtimeconfig) - - pal::string_t deps_in_dotnet_root = host_info.dotnet_root; - pal::string_t deps_filename = host_info.get_app_name() + _X(".deps.json"); - append_path(&deps_in_dotnet_root, deps_filename.c_str()); - bool deps_exists = pal::file_exists(deps_in_dotnet_root); - - trace::info(_X("Detecting mode... CoreCLR present in dotnet root [%s] and checking if [%s] file present=[%d]"), - host_info.dotnet_root.c_str(), deps_filename.c_str(), deps_exists); - - // Name of runtimeconfig file; since no path is included here the check is in the current working directory - pal::string_t config_in_cwd = host_info.get_app_name() + _X(".runtimeconfig.json"); - - return (deps_exists || !pal::file_exists(config_in_cwd)) && pal::file_exists(host_info.app_path) ? host_mode_t::apphost : host_mode_t::split_fx; - } - - if (pal::file_exists(host_info.app_path)) - { - // Framework-dependent apphost - return host_mode_t::apphost; - } - - return host_mode_t::muxer; -} - -void try_patch_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t& start_ver, pal::string_t* max_str) -{ - pal::string_t path = cur_dir; - - if (trace::is_enabled()) - { - pal::string_t start_str = start_ver.as_str(); - trace::verbose(_X("Reading patch roll forward candidates in dir [%s] for version [%s]"), path.c_str(), start_str.c_str()); - } - - pal::string_t maj_min_star = start_ver.patch_glob(); - - std::vector list; - pal::readdir_onlydirectories(path, maj_min_star, &list); - - fx_ver_t max_ver = start_ver; - fx_ver_t ver; - for (const auto& str : list) - { - trace::verbose(_X("Considering patch roll forward candidate version [%s]"), str.c_str()); - if (fx_ver_t::parse(str, &ver, true)) - { - max_ver = std::max(ver, max_ver); - } - } - max_str->assign(max_ver.as_str()); - - if (trace::is_enabled()) - { - pal::string_t start_str = start_ver.as_str(); - trace::verbose(_X("Patch roll forwarded [%s] -> [%s] in [%s]"), start_str.c_str(), max_str->c_str(), path.c_str()); - } -} - -void try_prerelease_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t& start_ver, pal::string_t* max_str) -{ - pal::string_t path = cur_dir; - - if (trace::is_enabled()) - { - pal::string_t start_str = start_ver.as_str(); - trace::verbose(_X("Reading prerelease roll forward candidates in dir [%s] for version [%s]"), path.c_str(), start_str.c_str()); - } - - pal::string_t maj_min_pat_star = start_ver.prerelease_glob(); - - std::vector list; - pal::readdir_onlydirectories(path, maj_min_pat_star, &list); - - fx_ver_t max_ver = start_ver; - fx_ver_t ver; - for (const auto& str : list) - { - trace::verbose(_X("Considering prerelease roll forward candidate version [%s]"), str.c_str()); - if (fx_ver_t::parse(str, &ver, false) - && ver.is_prerelease()) // Pre-release can roll forward to only pre-release - { - max_ver = std::max(ver, max_ver); - } - } - max_str->assign(max_ver.as_str()); - - if (trace::is_enabled()) - { - pal::string_t start_str = start_ver.as_str(); - trace::verbose(_X("Prerelease roll forwarded [%s] -> [%s] in [%s]"), start_str.c_str(), max_str->c_str(), path.c_str()); - } -} diff --git a/src/installer/corehost/cli/libhost.h b/src/installer/corehost/cli/libhost.h deleted file mode 100644 index 913e4fe..0000000 --- a/src/installer/corehost/cli/libhost.h +++ /dev/null @@ -1,436 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#ifndef __LIBHOST_H__ -#define __LIBHOST_H__ -#include -#include "trace.h" -#include "host_startup_info.h" -#include "runtime_config.h" -#include "fx_definition.h" -#include "fx_ver.h" - -enum host_mode_t -{ - invalid = 0, - - muxer, // Invoked as "dotnet.exe". - - apphost, // Invoked as .exe from the application base; this is the renamed "apphost.exe". - - split_fx, // Invoked as "corehost.exe" for xunit scenarios. Supported for backwards compat for 1.x apps. - // Split FX means, the host is operating like "corerun.exe" in a split location from the application base (CORE_ROOT equivalent), - // but it has its "hostfxr.dll" next to it. - - libhost, // Invoked from a non-exe scenario (e.g. COM Activation or self-hosting native application) -}; - -class fx_ver_t; -class runtime_config_t; - -#define _HOST_INTERFACE_PACK 1 -#pragma pack(push, _HOST_INTERFACE_PACK) -struct strarr_t -{ - // DO NOT modify this struct. It is used in a layout - // dependent manner. Create another for your use. - size_t len; - const pal::char_t** arr; -}; - -struct host_interface_t -{ - size_t version_lo; // Just assign sizeof() to this field. - size_t version_hi; // Breaking changes to the layout -- increment HOST_INTERFACE_LAYOUT_VERSION - strarr_t config_keys; - strarr_t config_values; - const pal::char_t* fx_dir; - const pal::char_t* fx_name; - const pal::char_t* deps_file; - size_t is_framework_dependent; - strarr_t probe_paths; - size_t patch_roll_forward; - size_t prerelease_roll_forward; - size_t host_mode; - const pal::char_t* tfm; - const pal::char_t* additional_deps_serialized; - const pal::char_t* fx_ver; - strarr_t fx_names; - strarr_t fx_dirs; - strarr_t fx_requested_versions; - strarr_t fx_found_versions; - const pal::char_t* host_command; - const pal::char_t* host_info_host_path; - const pal::char_t* host_info_dotnet_root; - const pal::char_t* host_info_app_path; - // !! WARNING / WARNING / WARNING / WARNING / WARNING / WARNING / WARNING / WARNING / WARNING - // !! 1. Only append to this structure to maintain compat. - // !! 2. Any nested structs should not use compiler specific padding (pack with _HOST_INTERFACE_PACK) - // !! 3. Do not take address of the fields of this struct or be prepared to deal with unaligned accesses. - // !! 4. Must be POD types; only use non-const size_t and pointer types; no access modifiers. - // !! 5. Do not reorder fields or change any existing field types. - // !! 6. Add static asserts for fields you add. -}; -#pragma pack(pop) -static_assert(_HOST_INTERFACE_PACK == 1, "Packing size should not be modified for back compat"); -static_assert(offsetof(host_interface_t, version_lo) == 0 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, version_hi) == 1 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, config_keys) == 2 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, config_values) == 4 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, fx_dir) == 6 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, fx_name) == 7 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, deps_file) == 8 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, is_framework_dependent) == 9 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, probe_paths) == 10 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, patch_roll_forward) == 12 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, prerelease_roll_forward) == 13 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, host_mode) == 14 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, tfm) == 15 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, additional_deps_serialized) == 16 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, fx_ver) == 17 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, fx_names) == 18 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, fx_dirs) == 20 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, fx_requested_versions) == 22 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, fx_found_versions) == 24 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, host_command) == 26 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, host_info_host_path) == 27 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, host_info_dotnet_root) == 28 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(offsetof(host_interface_t, host_info_app_path) == 29 * sizeof(size_t), "Struct offset breaks backwards compatibility"); -static_assert(sizeof(host_interface_t) == 30 * sizeof(size_t), "Did you add static asserts for the newly added fields?"); - -#define HOST_INTERFACE_LAYOUT_VERSION_HI 0x16041101 // YYMMDD:nn always increases when layout breaks compat. -#define HOST_INTERFACE_LAYOUT_VERSION_LO sizeof(host_interface_t) - -class corehost_init_t -{ -private: - std::vector m_clr_keys; - std::vector m_clr_values; - std::vector m_clr_keys_cstr; - std::vector m_clr_values_cstr; - const pal::string_t m_tfm; - const pal::string_t m_deps_file; - const pal::string_t m_additional_deps_serialized; - bool m_is_framework_dependent; - std::vector m_probe_paths; - std::vector m_probe_paths_cstr; - host_mode_t m_host_mode; - host_interface_t m_host_interface; - std::vector m_fx_names; - std::vector m_fx_names_cstr; - std::vector m_fx_dirs; - std::vector m_fx_dirs_cstr; - std::vector m_fx_requested_versions; - std::vector m_fx_requested_versions_cstr; - std::vector m_fx_found_versions; - std::vector m_fx_found_versions_cstr; - const pal::string_t m_host_command; - const pal::string_t m_host_info_host_path; - const pal::string_t m_host_info_dotnet_root; - const pal::string_t m_host_info_app_path; -public: - corehost_init_t( - const pal::string_t& host_command, - const host_startup_info_t& host_info, - const pal::string_t& deps_file, - const pal::string_t& additional_deps_serialized, - const std::vector& probe_paths, - const host_mode_t mode, - const fx_definition_vector_t& fx_definitions) - : m_host_command(host_command) - , m_host_info_host_path(host_info.host_path) - , m_host_info_dotnet_root(host_info.dotnet_root) - , m_host_info_app_path(host_info.app_path) - , m_deps_file(deps_file) - , m_additional_deps_serialized(additional_deps_serialized) - , m_is_framework_dependent(get_app(fx_definitions).get_runtime_config().get_is_framework_dependent()) - , m_probe_paths(probe_paths) - , m_host_mode(mode) - , m_host_interface() - , m_tfm(get_app(fx_definitions).get_runtime_config().get_tfm()) - { - make_cstr_arr(m_probe_paths, &m_probe_paths_cstr); - - int fx_count = fx_definitions.size(); - m_fx_names.reserve(fx_count); - m_fx_dirs.reserve(fx_count); - m_fx_requested_versions.reserve(fx_count); - m_fx_found_versions.reserve(fx_count); - - std::unordered_map combined_properties; - for (auto& fx : fx_definitions) - { - fx->get_runtime_config().combine_properties(combined_properties); - - m_fx_names.push_back(fx->get_name()); - m_fx_dirs.push_back(fx->get_dir()); - m_fx_requested_versions.push_back(fx->get_requested_version()); - m_fx_found_versions.push_back(fx->get_found_version()); - } - - for (const auto& kv : combined_properties) - { - m_clr_keys.push_back(kv.first); - m_clr_values.push_back(kv.second); - } - - make_cstr_arr(m_fx_names, &m_fx_names_cstr); - make_cstr_arr(m_fx_dirs, &m_fx_dirs_cstr); - make_cstr_arr(m_fx_requested_versions, &m_fx_requested_versions_cstr); - make_cstr_arr(m_fx_found_versions, &m_fx_found_versions_cstr); - make_cstr_arr(m_clr_keys, &m_clr_keys_cstr); - make_cstr_arr(m_clr_values, &m_clr_values_cstr); - } - - const pal::string_t& tfm() const - { - return m_tfm; - } - - const host_interface_t& get_host_init_data() - { - host_interface_t& hi = m_host_interface; - - hi.version_lo = HOST_INTERFACE_LAYOUT_VERSION_LO; - hi.version_hi = HOST_INTERFACE_LAYOUT_VERSION_HI; - - hi.config_keys.len = m_clr_keys_cstr.size(); - hi.config_keys.arr = m_clr_keys_cstr.data(); - - hi.config_values.len = m_clr_values_cstr.size(); - hi.config_values.arr = m_clr_values_cstr.data(); - - // Keep these for backwards compat - if (m_fx_names_cstr.size() > 1) - { - hi.fx_name = m_fx_names_cstr[1]; - hi.fx_dir = m_fx_dirs_cstr[1]; - hi.fx_ver = m_fx_requested_versions_cstr[1]; - } - else - { - hi.fx_name = _X(""); - hi.fx_dir = _X(""); - hi.fx_ver = _X(""); - } - - hi.deps_file = m_deps_file.c_str(); - hi.additional_deps_serialized = m_additional_deps_serialized.c_str(); - hi.is_framework_dependent = m_is_framework_dependent; - - hi.probe_paths.len = m_probe_paths_cstr.size(); - hi.probe_paths.arr = m_probe_paths_cstr.data(); - - // These are not used anymore, but we have to keep them for backward compat reasons. - // Set default values. - hi.patch_roll_forward = true; - hi.prerelease_roll_forward = false; - - hi.host_mode = m_host_mode; - - hi.tfm = m_tfm.c_str(); - - hi.fx_names.len = m_fx_names_cstr.size(); - hi.fx_names.arr = m_fx_names_cstr.data(); - - hi.fx_dirs.len = m_fx_dirs_cstr.size(); - hi.fx_dirs.arr = m_fx_dirs_cstr.data(); - - hi.fx_requested_versions.len = m_fx_requested_versions_cstr.size(); - hi.fx_requested_versions.arr = m_fx_requested_versions_cstr.data(); - - hi.fx_found_versions.len = m_fx_found_versions_cstr.size(); - hi.fx_found_versions.arr = m_fx_found_versions_cstr.data(); - - hi.host_command = m_host_command.c_str(); - - hi.host_info_host_path = m_host_info_host_path.c_str(); - hi.host_info_dotnet_root = m_host_info_dotnet_root.c_str(); - hi.host_info_app_path = m_host_info_app_path.c_str(); - - return hi; - } - -private: - - static void make_cstr_arr(const std::vector& arr, std::vector* out) - { - out->reserve(arr.size()); - for (const auto& str : arr) - { - out->push_back(str.c_str()); - } - } -}; - -struct hostpolicy_init_t -{ - std::vector> cfg_keys; - std::vector> cfg_values; - pal::string_t deps_file; - pal::string_t additional_deps_serialized; - std::vector probe_paths; - fx_definition_vector_t fx_definitions; - pal::string_t tfm; - host_mode_t host_mode; - bool patch_roll_forward; - bool prerelease_roll_forward; - bool is_framework_dependent; - pal::string_t host_command; - host_startup_info_t host_info; - - static bool init(host_interface_t* input, hostpolicy_init_t* init) - { - // Check if there are any breaking changes. - if (input->version_hi != HOST_INTERFACE_LAYOUT_VERSION_HI) - { - trace::error(_X("The version of the data layout used to initialize %s is [0x%04x]; expected version [0x%04x]"), LIBHOSTPOLICY_NAME, input->version_hi, HOST_INTERFACE_LAYOUT_VERSION_HI); - return false; - } - - trace::verbose(_X("Reading from host interface version: [0x%04x:%d] to initialize policy version: [0x%04x:%d]"), input->version_hi, input->version_lo, HOST_INTERFACE_LAYOUT_VERSION_HI, HOST_INTERFACE_LAYOUT_VERSION_LO); - - //This check is to ensure is an old hostfxr can still load new hostpolicy. - //We should not read garbage due to potentially shorter struct size - - pal::string_t fx_requested_ver; - - if (input->version_lo >= offsetof(host_interface_t, host_mode) + sizeof(input->host_mode)) - { - make_clrstr_arr(input->config_keys.len, input->config_keys.arr, &init->cfg_keys); - make_clrstr_arr(input->config_values.len, input->config_values.arr, &init->cfg_values); - - init->deps_file = input->deps_file; - init->is_framework_dependent = input->is_framework_dependent; - - make_palstr_arr(input->probe_paths.len, input->probe_paths.arr, &init->probe_paths); - - init->patch_roll_forward = input->patch_roll_forward; - init->prerelease_roll_forward = input->prerelease_roll_forward; - init->host_mode = (host_mode_t)input->host_mode; - } - else - { - trace::error(_X("The size of the data layout used to initialize %s is %d; expected at least %d"), LIBHOSTPOLICY_NAME, input->version_lo, - offsetof(host_interface_t, host_mode) + sizeof(input->host_mode)); - } - - //An old hostfxr may not provide these fields. - //The version_lo (sizeof) the old hostfxr saw at build time will be - //smaller and we should not attempt to read the fields in that case. - if (input->version_lo >= offsetof(host_interface_t, tfm) + sizeof(input->tfm)) - { - init->tfm = input->tfm; - } - - if (input->version_lo >= offsetof(host_interface_t, fx_ver) + sizeof(input->fx_ver)) - { - init->additional_deps_serialized = input->additional_deps_serialized; - fx_requested_ver = input->fx_ver; - } - - int fx_count = 0; - if (input->version_lo >= offsetof(host_interface_t, fx_names) + sizeof(input->fx_names)) - { - int fx_count = input->fx_names.len; - assert(fx_count > 0); - assert(fx_count == input->fx_dirs.len); - assert(fx_count == input->fx_requested_versions.len); - assert(fx_count == input->fx_found_versions.len); - - std::vector fx_names; - std::vector fx_dirs; - std::vector fx_requested_versions; - std::vector fx_found_versions; - - make_palstr_arr(input->fx_names.len, input->fx_names.arr, &fx_names); - make_palstr_arr(input->fx_dirs.len, input->fx_dirs.arr, &fx_dirs); - make_palstr_arr(input->fx_requested_versions.len, input->fx_requested_versions.arr, &fx_requested_versions); - make_palstr_arr(input->fx_found_versions.len, input->fx_found_versions.arr, &fx_found_versions); - - init->fx_definitions.reserve(fx_count); - for (int i = 0; i < fx_count; ++i) - { - auto fx = new fx_definition_t(fx_names[i], fx_dirs[i], fx_requested_versions[i], fx_found_versions[i]); - init->fx_definitions.push_back(std::unique_ptr(fx)); - } - } - else - { - // Backward compat; create the fx_definitions[0] and [1] from the previous information - init->fx_definitions.reserve(2); - - auto fx = new fx_definition_t(); - init->fx_definitions.push_back(std::unique_ptr(fx)); - - if (init->is_framework_dependent) - { - pal::string_t fx_dir = input->fx_dir; - pal::string_t fx_name = input->fx_name; - - // The found_ver was not passed previously, so obtain that from fx_dir - pal::string_t fx_found_ver; - size_t index = fx_dir.rfind(DIR_SEPARATOR); - if (index != pal::string_t::npos) - { - fx_found_ver = fx_dir.substr(index + 1); - } - - fx = new fx_definition_t(fx_name, fx_dir, fx_requested_ver, fx_found_ver); - init->fx_definitions.push_back(std::unique_ptr(fx)); - } - } - - // Initialize the host command - init_host_command(input, init); - - if (input->version_lo >= offsetof(host_interface_t, host_info_host_path) + sizeof(input->host_info_host_path)) - { - init->host_info.host_path = input->host_info_host_path; - init->host_info.dotnet_root = input->host_info_dotnet_root; - init->host_info.app_path = input->host_info_app_path; - // For the backwards compat case, this will be later initialized with argv[0] - } - - return true; - } - - static void init_host_command(host_interface_t* input, hostpolicy_init_t* init) - { - if (input->version_lo >= offsetof(host_interface_t, host_command) + sizeof(input->host_command)) - { - init->host_command = input->host_command; - } - } - -private: - static void make_palstr_arr(int argc, const pal::char_t** argv, std::vector* out) - { - out->reserve(argc); - for (int i = 0; i < argc; ++i) - { - out->push_back(argv[i]); - } - } - - static void make_clrstr_arr(int argc, const pal::char_t** argv, std::vector>* out) - { - out->resize(argc); - for (int i = 0; i < argc; ++i) - { - pal::pal_clrstring(pal::string_t(argv[i]), &(*out)[i]); - } - } -}; - -void get_runtime_config_paths_from_app(const pal::string_t& file, pal::string_t* config_file, pal::string_t* dev_config_file); -void get_runtime_config_paths_from_arg(const pal::string_t& file, pal::string_t* config_file, pal::string_t* dev_config_file); -void get_runtime_config_paths(const pal::string_t& path, const pal::string_t& name, pal::string_t* config_file, pal::string_t* dev_config_file); - -host_mode_t detect_operating_mode(const host_startup_info_t& host_info); -bool hostpolicy_exists_in_svc(pal::string_t* resolved_dir); - -void try_patch_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t& start_ver, pal::string_t* max_str); -void try_prerelease_roll_forward_in_dir(const pal::string_t& cur_dir, const fx_ver_t& start_ver, pal::string_t* max_str); - -#endif // __LIBHOST_H__ -- 2.7.4