2016-01-09 23:33:22 -08:00
// 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.
2016-02-22 01:41:25 -08:00
# ifndef __LIBHOST_H__
# define __LIBHOST_H__
2016-04-07 20:50:44 -07:00
# include <stdint.h>
# include "trace.h"
# include "runtime_config.h"
2016-03-28 02:59:57 -07:00
# include "fx_ver.h"
2016-02-22 01:41:25 -08:00
enum host_mode_t
{
invalid = 0 ,
muxer ,
standalone ,
split_fx
} ;
2016-03-28 02:59:57 -07:00
class fx_ver_t ;
2016-02-22 01:41:25 -08:00
class runtime_config_t ;
2016-04-07 20:50:44 -07:00
# define _HOST_INTERFACE_PACK 1
# pragma pack(push, _HOST_INTERFACE_PACK)
struct strarr_t
2016-02-22 01:41:25 -08:00
{
2016-04-07 20:50:44 -07:00
// 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 ;
} ;
2016-03-28 02:59:57 -07:00
2016-04-07 20:50:44 -07:00
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_portable ;
strarr_t probe_paths ;
size_t patch_roll_forward ;
size_t prerelease_roll_forward ;
size_t host_mode ;
// !! 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_portable ) = = 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 ( sizeof ( host_interface_t ) = = 15 * 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
{
2016-03-28 02:59:57 -07:00
private :
2016-04-07 20:50:44 -07:00
std : : vector < pal : : string_t > m_clr_keys ;
std : : vector < pal : : string_t > m_clr_values ;
std : : vector < const pal : : char_t * > m_clr_keys_cstr ;
std : : vector < const pal : : char_t * > m_clr_values_cstr ;
2016-02-22 01:41:25 -08:00
const pal : : string_t m_fx_dir ;
2016-04-07 20:50:44 -07:00
const pal : : string_t m_fx_name ;
const pal : : string_t m_deps_file ;
bool m_portable ;
std : : vector < pal : : string_t > m_probe_paths ;
std : : vector < const pal : : char_t * > m_probe_paths_cstr ;
bool m_patch_roll_forward ;
bool m_prerelease_roll_forward ;
2016-02-22 01:41:25 -08:00
host_mode_t m_host_mode ;
2016-04-07 20:50:44 -07:00
host_interface_t m_host_interface ;
const pal : : string_t m_fx_ver ;
2016-02-22 01:41:25 -08:00
public :
corehost_init_t (
const pal : : string_t & deps_file ,
2016-03-28 02:59:57 -07:00
const std : : vector < pal : : string_t > & probe_paths ,
2016-02-22 01:41:25 -08:00
const pal : : string_t & fx_dir ,
const host_mode_t mode ,
2016-04-07 20:50:44 -07:00
const runtime_config_t & runtime_config )
2016-02-22 01:41:25 -08:00
: m_fx_dir ( fx_dir )
2016-04-07 20:50:44 -07:00
, m_fx_name ( runtime_config . get_fx_name ( ) )
2016-02-22 01:41:25 -08:00
, m_deps_file ( deps_file )
2016-04-07 20:50:44 -07:00
, m_portable ( runtime_config . get_portable ( ) )
2016-03-28 02:59:57 -07:00
, m_probe_paths ( probe_paths )
2016-04-07 20:50:44 -07:00
, m_patch_roll_forward ( runtime_config . get_patch_roll_fwd ( ) )
, m_prerelease_roll_forward ( runtime_config . get_prerelease_roll_fwd ( ) )
2016-02-22 01:41:25 -08:00
, m_host_mode ( mode )
2016-04-07 20:50:44 -07:00
, m_host_interface ( )
, m_fx_ver ( runtime_config . get_fx_version ( ) )
2016-02-22 01:41:25 -08:00
{
2016-04-07 20:50:44 -07:00
runtime_config . config_kv ( & m_clr_keys , & m_clr_values ) ;
make_cstr_arr ( m_clr_keys , & m_clr_keys_cstr ) ;
make_cstr_arr ( m_clr_values , & m_clr_values_cstr ) ;
make_cstr_arr ( m_probe_paths , & m_probe_paths_cstr ) ;
2016-02-22 01:41:25 -08:00
}
2016-04-07 20:50:44 -07:00
const pal : : string_t & fx_dir ( ) const
2016-02-22 01:41:25 -08:00
{
2016-04-07 20:50:44 -07:00
return m_fx_dir ;
2016-02-22 01:41:25 -08:00
}
2016-04-07 20:50:44 -07:00
const pal : : string_t & fx_name ( ) const
2016-02-22 01:41:25 -08:00
{
2016-04-07 20:50:44 -07:00
return m_fx_name ;
2016-02-22 01:41:25 -08:00
}
2016-04-07 20:50:44 -07:00
const pal : : string_t & fx_version ( ) const
2016-02-22 01:41:25 -08:00
{
2016-04-07 20:50:44 -07:00
return m_fx_ver ;
2016-02-22 01:41:25 -08:00
}
2016-04-07 20:50:44 -07:00
const host_interface_t & get_host_init_data ( )
2016-02-22 01:41:25 -08:00
{
2016-04-07 20:50:44 -07:00
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 ( ) ;
hi . fx_dir = m_fx_dir . c_str ( ) ;
hi . fx_name = m_fx_name . c_str ( ) ;
hi . deps_file = m_deps_file . c_str ( ) ;
hi . is_portable = m_portable ;
hi . probe_paths . len = m_probe_paths_cstr . size ( ) ;
hi . probe_paths . arr = m_probe_paths_cstr . data ( ) ;
hi . patch_roll_forward = m_patch_roll_forward ;
hi . prerelease_roll_forward = m_prerelease_roll_forward ;
hi . host_mode = m_host_mode ;
return hi ;
2016-02-22 01:41:25 -08:00
}
2016-04-07 20:50:44 -07:00
private :
static void make_cstr_arr ( const std : : vector < pal : : string_t > & arr , std : : vector < const pal : : char_t * > * out )
{
out - > reserve ( arr . size ( ) ) ;
for ( const auto & str : arr )
{
out - > push_back ( str . c_str ( ) ) ;
}
}
} ;
struct hostpolicy_init_t
{
2016-04-22 19:10:32 -07:00
std : : vector < std : : vector < char > > cfg_keys ;
std : : vector < std : : vector < char > > cfg_values ;
2016-04-07 20:50:44 -07:00
pal : : string_t deps_file ;
std : : vector < pal : : string_t > probe_paths ;
pal : : string_t fx_dir ;
pal : : string_t fx_name ;
host_mode_t host_mode ;
bool patch_roll_forward ;
bool prerelease_roll_forward ;
bool is_portable ;
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 ;
}
// Check if the size is at least what we expect to contain.
if ( input - > version_lo < HOST_INTERFACE_LAYOUT_VERSION_LO )
{
trace : : error ( _X ( " The size of the data layout used to initialize %s is %d; expected at least %d " ) , LIBHOSTPOLICY_NAME , input - > version_lo , HOST_INTERFACE_LAYOUT_VERSION_LO ) ;
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 ) ;
2016-04-22 19:10:32 -07:00
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 ) ;
2016-04-07 20:50:44 -07:00
init - > fx_dir = input - > fx_dir ;
init - > fx_name = input - > fx_name ;
init - > deps_file = input - > deps_file ;
init - > is_portable = input - > is_portable ;
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 ;
return true ;
}
private :
static void make_palstr_arr ( int argc , const pal : : char_t * * argv , std : : vector < pal : : string_t > * out )
2016-02-22 01:41:25 -08:00
{
2016-04-07 20:50:44 -07:00
out - > reserve ( argc ) ;
for ( int i = 0 ; i < argc ; + + i )
{
out - > push_back ( argv [ i ] ) ;
}
2016-02-22 01:41:25 -08:00
}
2016-03-28 02:59:57 -07:00
2016-04-22 19:10:32 -07:00
static void make_clrstr_arr ( int argc , const pal : : char_t * * argv , std : : vector < std : : vector < char > > * out )
2016-03-28 02:59:57 -07:00
{
2016-04-22 19:10:32 -07:00
out - > resize ( argc ) ;
2016-04-07 20:50:44 -07:00
for ( int i = 0 ; i < argc ; + + i )
{
2016-04-26 17:54:49 -07:00
pal : : pal_clrstring ( pal : : string_t ( argv [ i ] ) , & ( * out ) [ i ] ) ;
2016-04-07 20:50:44 -07:00
}
2016-03-28 02:59:57 -07:00
}
2016-02-22 01:41:25 -08:00
} ;
2016-04-07 18:07:51 -07:00
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 ) ;
2016-04-07 20:50:44 -07:00
host_mode_t detect_operating_mode ( const pal : : string_t & own_dir , const pal : : string_t & own_dll , const pal : : string_t & own_name ) ;
bool hostpolicy_exists_in_svc ( pal : : string_t * resolved_dir ) ;
2016-02-22 01:41:25 -08:00
2016-04-06 04:24:23 -07:00
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 ) ;
2016-03-28 02:59:57 -07:00
2016-04-06 04:24:23 -07:00
# endif // __LIBHOST_H__