diff --git a/src/imports/avs.h b/src/imports/avs.h index ff48a33e..976e6c76 100644 --- a/src/imports/avs.h +++ b/src/imports/avs.h @@ -4,6 +4,7 @@ #include #include #include +#include enum property_create_flag { PROPERTY_FLAG_READ = 0x1, @@ -37,6 +38,7 @@ enum property_type { PROPERTY_TYPE_U64 = 9, PROPERTY_TYPE_BIN = 10, PROPERTY_TYPE_STR = 11, + PROPERTY_TYPE_ATTR = 46, PROPERTY_TYPE_BOOL = 52 }; @@ -160,6 +162,8 @@ void avs_boot( void avs_shutdown(void); +typedef uint32_t avs_desc; + void log_body_fatal(const char *module, const char *fmt, ...); void log_body_info(const char *module, const char *fmt, ...); void log_body_misc(const char *module, const char *fmt, ...); @@ -203,8 +207,8 @@ int property_psmap_export( const struct property_psmap *psmap); struct property_node *property_node_clone( - struct property *new_parent, - int unk0, + struct property *parent_prop, + struct property_node *parent_node, struct property_node *src, bool deep); struct property_node *property_node_create( @@ -228,10 +232,53 @@ struct property_node *property_node_traversal( struct property_node *node, enum property_node_traversal direction); void property_node_datasize(struct property_node *node); +static inline void property_remove(struct property *prop, struct property_node *node, const char *path) +{ + struct property_node *cur = property_search(prop, node, path); + while (cur) { + struct property_node *next = property_node_traversal(node, TRAVERSE_NEXT_SEARCH_RESULT); + property_node_remove(cur); + cur = next; + } +} + bool std_getenv(const char *key, char *val, uint32_t nbytes); void std_setenv(const char *key, const char *val); -void* avs_fs_open(const char* path, int mode, int flags); +struct avs_stat { + uint64_t st_atime; + uint64_t st_mtime; + uint64_t st_ctime; + uint32_t unk1; + uint32_t filesize; + struct stat padding; +}; + +enum avs_file_mode { + AVS_FILE_READ = 1, + AVS_FILE_WRITE = 2, + AVS_FILE_CREATE = 0x10, + AVS_FILE_TRUNCATE = 0x20, + AVS_FILE_EXCLUSIVE = 0x80, +}; + +enum avs_file_flag { + AVS_FILE_FLAG_SHARE_READ = 0x124, + AVS_FILE_FLAG_SHARE_WRITE = 0x92, +}; + +enum avs_seek_origin { + AVS_SEEK_SET = 0, + AVS_SEEK_CUR = 1, + AVS_SEEK_END = 2, +}; + +avs_desc avs_fs_open(const char *path, uint16_t mode, int flags); +int avs_fs_close(avs_desc desc); +size_t avs_fs_read(avs_desc desc, char *buf, uint32_t sz); +int avs_fs_lseek(avs_desc desc, long pos, int whence); +int avs_fs_lstat(const char *path, struct avs_stat *st); +int avs_fs_copy(const char *src, const char *dest); int avs_fs_addfs(void *filesys_struct); int avs_fs_mount( const char *mountpoint, const char *fsroot, const char *fstype, void *data); diff --git a/src/imports/import_32_0_avs.def b/src/imports/import_32_0_avs.def index cb2ea9d1..c808c1eb 100644 --- a/src/imports/import_32_0_avs.def +++ b/src/imports/import_32_0_avs.def @@ -2,6 +2,12 @@ LIBRARY libavs-win32 EXPORTS avs_boot + avs_fs_close + avs_fs_copy + avs_fs_lseek + avs_fs_lstat + avs_fs_open + avs_fs_read avs_net_ctrl avs_shutdown avs_thread_create diff --git a/src/imports/import_32_1002_avs.def b/src/imports/import_32_1002_avs.def index 6d1fd136..d421b1a3 100644 --- a/src/imports/import_32_1002_avs.def +++ b/src/imports/import_32_1002_avs.def @@ -2,6 +2,12 @@ LIBRARY libavs-win32 EXPORTS avs_boot + avs_fs_close + avs_fs_copy + avs_fs_lseek + avs_fs_lstat + avs_fs_open + avs_fs_read avs_net_ctrl avs_shutdown avs_thread_create diff --git a/src/imports/import_32_1101_avs.def b/src/imports/import_32_1101_avs.def index cfc6f9b5..a8bc4048 100644 --- a/src/imports/import_32_1101_avs.def +++ b/src/imports/import_32_1101_avs.def @@ -2,6 +2,12 @@ LIBRARY libavs-win32 EXPORTS avs_boot @22 NONAME + avs_fs_close @573 NONAME + avs_fs_copy @573 NONAME + avs_fs_lseek @573 NONAME + avs_fs_lstat @573 NONAME + avs_fs_open @573 NONAME + avs_fs_read @573 NONAME avs_net_ctrl @107 NONAME avs_shutdown @140 NONAME avs_thread_create @156 NONAME @@ -21,6 +27,8 @@ EXPORTS property_node_datasize @267 NONAME property_node_refer @278 NONAME property_node_remove @279 NONAME + property_node_clone @280 NONAME + property_node_traversal @282 NONAME property_psmap_import @288 NONAME property_psmap_export @287 NONAME property_read_query_memsize @291 NONAME diff --git a/src/imports/import_32_1304_avs.def b/src/imports/import_32_1304_avs.def index 489944a7..dd287422 100644 --- a/src/imports/import_32_1304_avs.def +++ b/src/imports/import_32_1304_avs.def @@ -2,7 +2,12 @@ LIBRARY libavs-win32 EXPORTS avs_boot @237 NONAME + avs_fs_close @573 NONAME + avs_fs_copy @573 NONAME + avs_fs_lseek @573 NONAME + avs_fs_lstat @573 NONAME avs_fs_open @178 NONAME + avs_fs_read @573 NONAME avs_net_ctrl @15 NONAME avs_shutdown @333 NONAME avs_thread_create @183 NONAME @@ -21,6 +26,8 @@ EXPORTS property_node_datasize @249 NONAME property_node_refer @268 NONAME property_node_remove @129 NONAME + property_node_clone @130 NONAME + property_node_traversal @132 NONAME property_psmap_import @102 NONAME property_psmap_export @110 NONAME property_read_query_memsize @100 NONAME diff --git a/src/imports/import_32_1403_avs.def b/src/imports/import_32_1403_avs.def index 32d68b11..61d2cd49 100644 --- a/src/imports/import_32_1403_avs.def +++ b/src/imports/import_32_1403_avs.def @@ -2,6 +2,12 @@ LIBRARY libavs-win32 EXPORTS avs_boot @298 NONAME + avs_fs_close @573 NONAME + avs_fs_copy @573 NONAME + avs_fs_lseek @573 NONAME + avs_fs_lstat @573 NONAME + avs_fs_open @573 NONAME + avs_fs_read @573 NONAME avs_net_ctrl @100 NONAME avs_shutdown @299 NONAME avs_thread_create @6 NONAME @@ -16,6 +22,8 @@ EXPORTS property_destroy @130 NONAME property_insert_read @133 NONAME property_node_remove @148 NONAME + property_node_clone @149 NONAME + property_node_traversal @151 NONAME property_psmap_import @163 NONAME property_psmap_export @164 NONAME property_read_query_memsize @161 NONAME diff --git a/src/imports/import_32_1508_avs.def b/src/imports/import_32_1508_avs.def index 05419ed7..88d6ce52 100644 --- a/src/imports/import_32_1508_avs.def +++ b/src/imports/import_32_1508_avs.def @@ -5,8 +5,10 @@ EXPORTS avs_fs_close @65 NONAME avs_fs_lseek @59 NONAME avs_fs_lseek64 @60 NONAME + avs_fs_lstat @79 NONAME avs_fs_open @58 NONAME avs_fs_read @61 NONAME + avs_fs_copy @81 NONAME avs_net_ctrl @98 NONAME avs_shutdown @286 NONAME avs_thread_create @6 NONAME @@ -24,6 +26,8 @@ EXPORTS property_node_create @145 NONAME property_node_refer @158 NONAME property_node_remove @146 NONAME + property_node_clone @147 NONAME + property_node_traversal @149 NONAME property_psmap_export @162 NONAME property_psmap_import @161 NONAME property_read_query_memsize @159 NONAME diff --git a/src/imports/import_32_1601_avs.def b/src/imports/import_32_1601_avs.def index e260a8c6..b6410ca6 100644 --- a/src/imports/import_32_1601_avs.def +++ b/src/imports/import_32_1601_avs.def @@ -1,6 +1,12 @@ LIBRARY libavs-win32 EXPORTS + avs_fs_close @573 NONAME + avs_fs_copy @573 NONAME + avs_fs_lseek @573 NONAME + avs_fs_lstat @573 NONAME + avs_fs_open @573 NONAME + avs_fs_read @573 NONAME avs_thread_create @5 NONAME avs_thread_destroy @7 NONAME avs_thread_exit @11 NONAME @@ -13,6 +19,8 @@ EXPORTS property_search @141 NONAME property_node_create @142 NONAME property_node_remove @143 NONAME + property_node_clone @144 NONAME + property_node_traversal @146 NONAME property_node_refer @155 NONAME property_read_query_memsize @156 NONAME property_psmap_export @159 NONAME diff --git a/src/imports/import_32_1603_avs.def b/src/imports/import_32_1603_avs.def index 98f5fe7a..f815822a 100644 --- a/src/imports/import_32_1603_avs.def +++ b/src/imports/import_32_1603_avs.def @@ -1,6 +1,12 @@ LIBRARY libavs-win32 EXPORTS + avs_fs_close @573 NONAME + avs_fs_copy @573 NONAME + avs_fs_lseek @573 NONAME + avs_fs_lstat @573 NONAME + avs_fs_open @573 NONAME + avs_fs_read @573 NONAME avs_thread_create @5 NONAME avs_thread_destroy @7 NONAME avs_thread_exit @11 NONAME @@ -13,6 +19,8 @@ EXPORTS property_search @162 NONAME property_node_create @163 NONAME property_node_remove @164 NONAME + property_node_clone @165 NONAME + property_node_traversal @167 NONAME property_node_refer @176 NONAME property_read_query_memsize @177 NONAME property_psmap_import @179 NONAME diff --git a/src/imports/import_32_1700_avs.def b/src/imports/import_32_1700_avs.def index d8944d9b..a4813abe 100644 --- a/src/imports/import_32_1700_avs.def +++ b/src/imports/import_32_1700_avs.def @@ -6,7 +6,13 @@ EXPORTS avs_thread_exit @11 NONAME avs_thread_join @12 NONAME avs_fs_addfs @73 NONAME + avs_fs_close @573 NONAME + avs_fs_copy @573 NONAME + avs_fs_lseek @573 NONAME + avs_fs_lstat @573 NONAME avs_fs_mount @76 NONAME + avs_fs_open @573 NONAME + avs_fs_read @573 NONAME avs_net_ctrl @119 NONAME property_create @145 NONAME property_destroy @146 NONAME @@ -15,6 +21,8 @@ EXPORTS property_search @162 NONAME property_node_create @163 NONAME property_node_remove @164 NONAME + property_node_clone @165 NONAME + property_node_traversal @167 NONAME property_node_refer @176 NONAME property_read_query_memsize @177 NONAME property_psmap_import @179 NONAME diff --git a/src/imports/import_32_803_avs.def b/src/imports/import_32_803_avs.def index a7f59b51..8c6b93e2 100644 --- a/src/imports/import_32_803_avs.def +++ b/src/imports/import_32_803_avs.def @@ -2,6 +2,12 @@ LIBRARY libavs-win32 EXPORTS avs_boot + avs_fs_close + avs_fs_copy + avs_fs_lseek + avs_fs_lstat + avs_fs_open + avs_fs_read avs_net_ctrl avs_shutdown avs_thread_create diff --git a/src/imports/import_64_1508_avs.def b/src/imports/import_64_1508_avs.def index bc9fbf06..210b7ad8 100644 --- a/src/imports/import_64_1508_avs.def +++ b/src/imports/import_64_1508_avs.def @@ -3,8 +3,10 @@ LIBRARY libavs-win64 EXPORTS avs_boot @285 NONAME avs_fs_close @65 NONAME + avs_fs_copy @81 NONAME avs_fs_lseek @59 NONAME avs_fs_lseek64 @60 NONAME + avs_fs_lstat @79 NONAME avs_fs_open @58 NONAME avs_fs_read @61 NONAME avs_net_ctrl @98 NONAME @@ -24,6 +26,8 @@ EXPORTS property_node_create @145 NONAME property_node_refer @158 NONAME property_node_remove @146 NONAME + property_node_clone @147 NONAME + property_node_traversal @149 NONAME property_psmap_export @162 NONAME property_psmap_import @161 NONAME property_read_query_memsize @159 NONAME diff --git a/src/imports/import_64_1509_avs.def b/src/imports/import_64_1509_avs.def index ae6110a2..9b6b945e 100644 --- a/src/imports/import_64_1509_avs.def +++ b/src/imports/import_64_1509_avs.def @@ -3,8 +3,10 @@ LIBRARY libavs-win64 EXPORTS avs_boot @285 NONAME avs_fs_close @65 NONAME + avs_fs_copy @81 NONAME avs_fs_lseek @59 NONAME avs_fs_lseek64 @60 NONAME + avs_fs_lstat @78 NONAME avs_fs_open @58 NONAME avs_fs_read @61 NONAME avs_net_ctrl @98 NONAME @@ -24,6 +26,8 @@ EXPORTS property_node_create @145 NONAME property_node_refer @158 NONAME property_node_remove @146 NONAME + property_node_clone @147 NONAME + property_node_traversal @149 NONAME property_psmap_export @162 NONAME property_psmap_import @161 NONAME property_read_query_memsize @159 NONAME diff --git a/src/imports/import_64_1601_avs.def b/src/imports/import_64_1601_avs.def index 5bbe4528..6dbb0f2f 100644 --- a/src/imports/import_64_1601_avs.def +++ b/src/imports/import_64_1601_avs.def @@ -1,6 +1,12 @@ LIBRARY libavs-win64 EXPORTS + avs_fs_close @573 NONAME + avs_fs_copy @573 NONAME + avs_fs_lseek @573 NONAME + avs_fs_lstat @573 NONAME + avs_fs_open @573 NONAME + avs_fs_read @573 NONAME avs_thread_create @5 NONAME avs_thread_destroy @7 NONAME avs_thread_exit @11 NONAME @@ -13,6 +19,8 @@ EXPORTS property_search @141 NONAME property_node_create @142 NONAME property_node_remove @143 NONAME + property_node_clone @144 NONAME + property_node_traversal @146 NONAME property_node_refer @155 NONAME property_read_query_memsize @156 NONAME property_psmap_export @159 NONAME diff --git a/src/imports/import_64_1603_avs.def b/src/imports/import_64_1603_avs.def index 0355922f..007bd5a8 100644 --- a/src/imports/import_64_1603_avs.def +++ b/src/imports/import_64_1603_avs.def @@ -1,6 +1,12 @@ LIBRARY libavs-win64 EXPORTS + avs_fs_close @573 NONAME + avs_fs_copy @573 NONAME + avs_fs_lseek @573 NONAME + avs_fs_lstat @573 NONAME + avs_fs_open @573 NONAME + avs_fs_read @573 NONAME avs_thread_create @5 NONAME avs_thread_destroy @7 NONAME avs_thread_exit @11 NONAME @@ -13,6 +19,8 @@ EXPORTS property_search @162 NONAME property_node_create @163 NONAME property_node_remove @164 NONAME + property_node_clone @165 NONAME + property_node_traversal @167 NONAME property_node_refer @176 NONAME property_read_query_memsize @177 NONAME property_psmap_import @179 NONAME diff --git a/src/imports/import_64_1700_avs.def b/src/imports/import_64_1700_avs.def index fe8cc6e6..1d1e0f00 100644 --- a/src/imports/import_64_1700_avs.def +++ b/src/imports/import_64_1700_avs.def @@ -6,7 +6,13 @@ EXPORTS avs_thread_exit @11 NONAME avs_thread_join @12 NONAME avs_fs_addfs @73 NONAME + avs_fs_close @573 NONAME + avs_fs_copy @573 NONAME + avs_fs_lseek @573 NONAME + avs_fs_lstat @573 NONAME avs_fs_mount @76 NONAME + avs_fs_open @573 NONAME + avs_fs_read @573 NONAME avs_net_ctrl @119 NONAME property_create @145 NONAME property_destroy @146 NONAME @@ -15,6 +21,8 @@ EXPORTS property_search @162 NONAME property_node_create @163 NONAME property_node_remove @164 NONAME + property_node_clone @165 NONAME + property_node_traversal @167 NONAME property_node_refer @176 NONAME property_read_query_memsize @177 NONAME property_psmap_import @179 NONAME diff --git a/src/main/launcher/Module.mk b/src/main/launcher/Module.mk index 96f735c8..e7b1fb5b 100644 --- a/src/main/launcher/Module.mk +++ b/src/main/launcher/Module.mk @@ -14,6 +14,7 @@ libs_launcher := \ src_launcher := \ avs-context.c \ + bs-config.c \ ea3-config.c \ main.c \ module.c \ diff --git a/src/main/launcher/bs-config.c b/src/main/launcher/bs-config.c new file mode 100644 index 00000000..2d380acf --- /dev/null +++ b/src/main/launcher/bs-config.c @@ -0,0 +1,346 @@ +#define LOG_MODULE "bootstrap" +#include + +#include "imports/avs.h" + +#include "launcher/bs-config.h" + +#include "util/defs.h" +#include "util/hex.h" +#include "util/log.h" +#include "util/str.h" + +// clang-format off +PSMAP_BEGIN(bootstrap_startup_psmap) +PSMAP_REQUIRED(PSMAP_TYPE_STR, struct bootstrap_startup_config, avs_config_file, + "boot/file") +PSMAP_REQUIRED(PSMAP_TYPE_U32, struct bootstrap_startup_config, avs_heap_size, + "boot/heap_avs") +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_startup_config, std_heap_size, + "boot/heap_std", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, mount_table_selector, + "boot/mounttable_selector", "boot") +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, watcher_enable, + "boot/watcher", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, timemachine_enable, + "boot/timemachine", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, launch_config_file, + "boot/launch_path", "/dev/raw/launch.xml") + +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, log_level, + "log/level", "all") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, log_name, + "log/name", "") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, log_file, + "log/file", "") +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_startup_config, log_bufsz, + "log/sz_buf", 4096) +PSMAP_OPTIONAL(PSMAP_TYPE_U16, struct bootstrap_startup_config, log_output_delay_ms, + "log/output_delay", 10) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, log_enable_console, + "log/enable_console", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, log_enable_sci, + "log/enable_netsci", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, log_enable_net, + "log/enable_netlog", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, log_enable_file, + "log/enable_file", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, log_rotate, + "log/rotate", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, log_append, + "log/append", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_U16, struct bootstrap_startup_config, log_count, + "log/gen", 10) + +PSMAP_OPTIONAL(PSMAP_TYPE_U8, struct bootstrap_startup_config, minidump_count, + "minidump/gen", 10) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, minidump_continue, + "minidump/cont_debug", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, minidump_log, + "minidump/echo_log", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_U8, struct bootstrap_startup_config, minidump_type, + "minidump/dump_type", 2) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, minidump_path, + "minidump/path", "/dev/raw/minidump") +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_startup_config, minidump_symbufsz, + "minidump/sz_symbuf", 32768) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, minidump_search_path, + "minidump/search", ".") + +PSMAP_REQUIRED(PSMAP_TYPE_STR, struct bootstrap_startup_config, module_file, + "component/file") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, module_load_type, + "component/load_type", "MEMORY") + +/* disabled until we implement PSMAP_TYPE_BIN + PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, ntdll_digest, + "dlml/ntdll/hash", "") + */ +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_startup_config, ntdll_size, + "dlml/ntdll/size", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_startup_config, ntdll_ift_table, + "dlml/ntdll/ift_table", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_startup_config, ntdll_ift_insert, + "dlml/ntdll/insert_ift", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_startup_config, ntdll_ift_remove, + "dlml/ntdll/remove_ift", 0) + +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, shield_enable, + "shield/enable", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, shield_verbose, + "shield/verbose", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, shield_use_loadlibrary, + "shield/use_loadlibrary", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, shield_logger, + "shield/logger", "") +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_startup_config, shield_sleep_min, + "shield/sleepmin", 10) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_startup_config, shield_sleep_blur, + "shield/sleepblur", 90) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, shield_whitelist_file, + "shield/whitelist", "prop/whitelist.csv") +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_startup_config, shield_tick_sleep, + "shield/ticksleep", 100) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_startup_config, shield_tick_error, + "shield/tickerror", 1000) +PSMAP_OPTIONAL(PSMAP_TYPE_U8, struct bootstrap_startup_config, shield_overwork_threshold, + "shield/overwork_threshold", 50) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_startup_config, shield_overwork_delay, + "shield/overwork_delay", 100) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_startup_config, shield_pause_delay, + "shield/pause_delay", 1000) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, shield_unlimited_key, + "shield/unlimited_key", "") +PSMAP_OPTIONAL(PSMAP_TYPE_U16, struct bootstrap_startup_config, shield_killer_port, + "shield_killer/port", 5001) + +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, dongle_license_cn, + "dongle/license", "") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, dongle_account_cn, + "dongle/account", "") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, dongle_driver_dll, + "dongle/pkcs11_driver", "eTPKCS11.dll") +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, dongle_disable_gc, + "dongle/disable_gc", 0) + +PSMAP_REQUIRED(PSMAP_TYPE_STR, struct bootstrap_startup_config, drm_dll, + "drm/dll") +PSMAP_REQUIRED(PSMAP_TYPE_STR, struct bootstrap_startup_config, drm_fstype, + "drm/fstype") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, drm_device, + "drm/device", "") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, drm_mount, + "drm/dst", "/") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, drm_options, + "drm/option", "") + +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, lte_enable, + "lte/enable", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, lte_config_file, + "lte/file", "/dev/nvram/lte-config.xml") +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, lte_unlimited_key, + "lte/unlimited_key", "") + +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, ssl_options, + "ssl/option", "") + +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, esign_enable, + "esign/enable", 0) + +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, eamuse_enable, + "eamuse/enable", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, eamuse_sync, + "eamuse/sync", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, eamuse_enable_model, + "eamuse/enable_model", 0) +PSMAP_OPTIONAL(PSMAP_TYPE_STR, struct bootstrap_startup_config, eamuse_config_file, + "eamuse/file", "/dev/nvram/ea3-config.xml") +PSMAP_OPTIONAL(PSMAP_TYPE_BOOL, struct bootstrap_startup_config, eamuse_updatecert_enable, + "eamuse/updatecert_enable", 1) +PSMAP_OPTIONAL(PSMAP_TYPE_U32, struct bootstrap_startup_config, eamuse_updatecert_interval, + "eamuse/updatecert_interval", 0) +PSMAP_END + +PSMAP_BEGIN(bootstrap_psmap) +PSMAP_REQUIRED(PSMAP_TYPE_STR, struct bootstrap_config, release_code, "/release_code") +PSMAP_END +// clang-format on + +#define ROOT_NODE "/config" +#define MODULE_PATH_PREFIX "modules/" + +const char *const inherited_nodes[] = { + "develop", + "default", + "log", + "minidump", + "boot", + "drm", + "ssl", + "eamuse", + "shield", + "esign", + "dongle", + "lte", +}; + +void bootstrap_config_init(struct bootstrap_config *config) +{ + memset(config, 0, sizeof(*config)); +} + +bool bootstrap_config_from_property( + struct bootstrap_config *config, + struct property *prop, + const char *selector) +{ + struct property_node *bootstrap_config = + property_search(prop, NULL, ROOT_NODE); + if (!bootstrap_config) { + log_warning(ROOT_NODE ": missing"); + return false; + } + log_misc(ROOT_NODE ": loading..."); + if (!property_psmap_import( + NULL, bootstrap_config, config, bootstrap_psmap)) { + log_warning(ROOT_NODE ": load failed"); + return false; + } + + /* Setup root startup node */ + struct property_node *startup_root = + property_search(NULL, bootstrap_config, "startup"); + if (!startup_root) { + log_warning(ROOT_NODE "/startup: missing"); + return false; + } + struct property_node *startup_config = + property_search(NULL, startup_root, selector); + if (!startup_config) { + log_warning(ROOT_NODE "/startup/%s: missing", selector); + return false; + } + + /* Resolve inheritance */ + struct property_node *startup_parent = startup_config; + for (;;) { + char inherit_name[64]; + int r = property_node_refer( + NULL, + startup_parent, + "inherit@", + PROPERTY_TYPE_ATTR, + inherit_name, + sizeof(inherit_name)); + if (r < 0) { + break; + } + + startup_parent = property_search(NULL, startup_root, inherit_name); + if (!startup_parent) { + log_warning(ROOT_NODE "/startup/%s: missing", inherit_name); + return false; + } + + for (int i = 0; i < _countof(inherited_nodes); i++) { + if (property_search(NULL, startup_config, inherited_nodes[i])) { + continue; + } + + struct property_node *node = + property_search(NULL, startup_parent, inherited_nodes[i]); + if (node) { + log_misc( + ROOT_NODE "/startup/%s: merging %s...", + inherit_name, + inherited_nodes[i]); + property_node_clone(NULL, startup_config, node, TRUE); + } + } + } + + /* Now parse the startup node */ + log_misc(ROOT_NODE "/startup/%s: loading merge result...", selector); + if (!property_psmap_import( + NULL, startup_config, &config->startup, bootstrap_startup_psmap)) { + log_warning(ROOT_NODE "/startup/%s: load failed", selector); + return false; + } + + config->module_params = + property_search(NULL, startup_config, "component/param"); + config->log_node = property_search(NULL, startup_config, "log"); + config->default_node = property_search(NULL, startup_config, "default"); + return true; +} + +void bootstrap_config_update_avs( + const struct bootstrap_config *config, struct property_node *avs_root) +{ + if (config->module_params) { + property_remove(NULL, avs_root, "mode/product"); + property_node_create( + NULL, avs_root, PROPERTY_TYPE_BOOL, "mode/product", 1); + property_remove(NULL, avs_root, "net/enable_raw"); + property_node_create( + NULL, avs_root, PROPERTY_TYPE_BOOL, "net/enable_raw", 1); + property_remove(NULL, avs_root, "net/eaudp/enable"); + property_node_create( + NULL, avs_root, PROPERTY_TYPE_BOOL, "net/eaudp/enable", 1); + property_remove(NULL, avs_root, "sntp/ea_on"); + property_node_create( + NULL, avs_root, PROPERTY_TYPE_BOOL, "sntp/ea_on", 1); + } + if (config->startup.drm_device[0]) { + property_remove(NULL, avs_root, "fs/root/device"); + property_node_create( + NULL, + avs_root, + PROPERTY_TYPE_STR, + "fs/root/device", + config->startup.drm_device); + } + if (config->log_node) { + property_remove(NULL, avs_root, "log"); + property_node_clone(NULL, avs_root, config->log_node, TRUE); + } +} + +bool bootstrap_config_iter_default_file( + struct bootstrap_config *config, + struct bootstrap_default_file *default_file) +{ + if (!config->default_file) { + config->default_file = + property_search(NULL, config->default_node, "file"); + } else { + config->default_file = property_node_traversal( + config->default_file, TRAVERSE_NEXT_SEARCH_RESULT); + } + if (!config->default_file) { + return false; + } + + int r; + r = property_node_refer( + NULL, + config->default_file, + "src@", + PROPERTY_TYPE_ATTR, + &default_file->src, + sizeof(default_file->src)); + if (r < 0) { + return false; + } + r = property_node_refer( + NULL, + config->default_file, + "dst@", + PROPERTY_TYPE_ATTR, + &default_file->dest, + sizeof(default_file->dest)); + if (r < 0) { + return false; + } + return true; +} diff --git a/src/main/launcher/bs-config.h b/src/main/launcher/bs-config.h new file mode 100644 index 00000000..8725fed0 --- /dev/null +++ b/src/main/launcher/bs-config.h @@ -0,0 +1,115 @@ +#ifndef LAUNCHER_BS_CONFIG_H +#define LAUNCHER_BS_CONFIG_H + +#include +#include + +#include "imports/avs.h" + +struct bootstrap_default_file { + char src[64]; + char dest[64]; +}; + +struct bootstrap_startup_config { + char avs_config_file[64]; + char launch_config_file[64]; + uint32_t avs_heap_size; + uint32_t std_heap_size; + char mount_table_selector[16]; + bool watcher_enable; + bool timemachine_enable; + + char log_level[8]; + char log_name[64]; + char log_file[64]; + uint32_t log_bufsz; + uint16_t log_output_delay_ms; + bool log_enable_console; + bool log_enable_sci; + bool log_enable_net; + bool log_enable_file; + bool log_rotate; + bool log_append; + uint16_t log_count; + + uint8_t minidump_count; + bool minidump_continue; + bool minidump_log; + uint8_t minidump_type; + char minidump_path[64]; + uint32_t minidump_symbufsz; + char minidump_search_path[64]; + + char module_file[64]; + char module_load_type[64]; + + char ntdll_digest[16]; + uint32_t ntdll_size; + uint32_t ntdll_ift_table; + uint32_t ntdll_ift_insert; + uint32_t ntdll_ift_remove; + + bool shield_enable; + bool shield_verbose; + bool shield_use_loadlibrary; + char shield_logger[64]; + uint32_t shield_sleep_min; + uint32_t shield_sleep_blur; + uint32_t shield_tick_sleep; + uint32_t shield_tick_error; + uint8_t shield_overwork_threshold; + uint32_t shield_overwork_delay; + uint32_t shield_pause_delay; + char shield_whitelist_file[64]; + char shield_unlimited_key[10]; + uint16_t shield_killer_port; + + char dongle_license_cn[32]; + char dongle_account_cn[32]; + char dongle_driver_dll[16]; + bool dongle_disable_gc; + + char drm_dll[64]; + char drm_device[64]; + char drm_mount[64]; + char drm_fstype[64]; + char drm_options[64]; + + bool lte_enable; + char lte_config_file[64]; + char lte_unlimited_key[10]; + + char ssl_options[64]; + + bool esign_enable; + + bool eamuse_enable; + bool eamuse_sync; + bool eamuse_enable_model; + char eamuse_config_file[64]; + bool eamuse_updatecert_enable; + uint32_t eamuse_updatecert_interval; +}; + +struct bootstrap_config { + char release_code[16]; + struct bootstrap_startup_config startup; + struct property_node *module_params; + struct property_node *log_node; + struct property_node *default_node; + struct property_node *default_file; +}; + +void bootstrap_config_init(struct bootstrap_config *config); +bool bootstrap_config_from_property( + struct bootstrap_config *config, + struct property *prop, + const char *profile); +void bootstrap_config_update_avs( + const struct bootstrap_config *config, struct property_node *avs_root); +bool bootstrap_config_iter_default_file( + struct bootstrap_config *config, + struct bootstrap_default_file *default_file); + +#endif /* LAUNCHER_BS_CONFIG_H */ diff --git a/src/main/launcher/main.c b/src/main/launcher/main.c index 4d935d78..d8ffcba7 100644 --- a/src/main/launcher/main.c +++ b/src/main/launcher/main.c @@ -9,6 +9,7 @@ #include "imports/avs.h" #include "launcher/avs-context.h" +#include "launcher/bs-config.h" #include "launcher/ea3-config.h" #include "launcher/module.h" #include "launcher/options.h" @@ -129,8 +130,10 @@ int main(int argc, const char **argv) struct ea3_ident ea3; struct module_context module; struct options options; + struct bootstrap_config bs; - struct property *app_config; + struct property *bootstrap_config = NULL; + struct property *app_config = NULL; struct property *avs_config; struct property *ea3_config; @@ -143,6 +146,22 @@ int main(int argc, const char **argv) /* Read command line */ options_init(&options); + options_read_early_cmdline(&options, argc, argv); + + bootstrap_config_init(&bs); + if (options.bootstrap_selector) { + bootstrap_config = boot_property_load(options.bootstrap_config_path); + log_info( + "Loading bootstrap selector '%s'...", options.bootstrap_selector); + if (!bootstrap_config_from_property( + &bs, bootstrap_config, options.bootstrap_selector)) { + log_fatal( + "%s: could not load configuration for '%s'", + options.bootstrap_config_path, + options.bootstrap_selector); + } + options_read_bootstrap(&options, &bs.startup); + } if (!options_read_cmdline(&options, argc, argv)) { options_print_usage(); @@ -195,6 +214,7 @@ int main(int argc, const char **argv) if (avs_config_root == NULL) { log_fatal("%s: /config missing", options.avs_config_path); } + bootstrap_config_update_avs(&bs, avs_config_root); load_hook_dlls(&options.before_hook_dlls); @@ -212,6 +232,23 @@ int main(int argc, const char **argv) os_version_log(); + /* Do late bootstrap initialisation */ + + struct bootstrap_default_file default_file; + while (bootstrap_config_iter_default_file(&bs, &default_file)) { + struct avs_stat st; + if (avs_fs_lstat(default_file.dest, &st)) { + continue; + } + log_misc("%s: copying from %s...", default_file.dest, default_file.src); + if (avs_fs_copy(default_file.src, default_file.dest) < 0) { + log_fatal( + "%s: could not copy from %s", + default_file.dest, + default_file.src); + } + } + /* Load game DLL */ if (options.iat_hook_dlls.nitems > 0) { @@ -231,13 +268,30 @@ int main(int argc, const char **argv) /* Prepare ea3 config */ - ea3_config = boot_property_load(options.ea3_config_path); + ea3_config = boot_property_load_avs(options.ea3_config_path); ea3_config_root = property_search(ea3_config, 0, "/ea3"); if (ea3_config_root == NULL) { log_fatal("%s: /ea3 missing", options.ea3_config_path); } + if (path_exists(options.ea3_ident_path)) { + log_info("%s: loading override", options.ea3_ident_path); + struct property *ea3_ident = boot_property_load(options.ea3_ident_path); + struct property_node *node = + property_search(ea3_ident, NULL, "/ea3_conf"); + if (node == NULL) { + log_fatal("%s: /ea3_conf missing", options.ea3_ident_path); + } + + for (node = property_node_traversal(node, TRAVERSE_FIRST_CHILD); node; + node = property_node_traversal(node, TRAVERSE_NEXT_SIBLING)) { + property_node_clone(NULL, ea3_config_root, node, TRUE); + } + + boot_property_free(ea3_ident); + } + ea3_ident_init(&ea3); if (!ea3_ident_from_property(&ea3, ea3_config)) { @@ -259,17 +313,19 @@ int main(int argc, const char **argv) /* Invoke dll_entry_init */ - if (path_exists(options.app_config_path)) { - app_config = boot_property_load(options.app_config_path); + if (bs.module_params) { + app_config_root = bs.module_params; + } else if (path_exists(options.app_config_path)) { + app_config = boot_property_load_avs(options.app_config_path); + app_config_root = property_search(app_config, 0, "/param"); } else { log_warning( "%s: app config file missing, using empty", options.app_config_path); app_config = boot_property_load_cstring("dummy"); + app_config_root = property_search(app_config, 0, "/param"); } - app_config_root = property_search(app_config, 0, "/param"); - if (app_config_root == NULL) { log_fatal("%s: /param missing", options.app_config_path); } @@ -285,7 +341,12 @@ int main(int argc, const char **argv) log_fatal("%s: dll_module_init() returned failure", options.module); } - boot_property_free(app_config); + if (app_config) { + boot_property_free(app_config); + } + if (bootstrap_config) { + boot_property_free(bootstrap_config); + } ea3_ident_to_property(&ea3, ea3_config); diff --git a/src/main/launcher/options.c b/src/main/launcher/options.c index 757555ec..d3d5165e 100644 --- a/src/main/launcher/options.c +++ b/src/main/launcher/options.c @@ -16,9 +16,12 @@ void options_init(struct options *options) { options->std_heap_size = DEFAULT_HEAP_SIZE; options->avs_heap_size = DEFAULT_HEAP_SIZE; + options->bootstrap_config_path = "prop/bootstrap.xml"; + options->bootstrap_selector = NULL; options->app_config_path = "prop/app-config.xml"; options->avs_config_path = "prop/avs-config.xml"; options->ea3_config_path = "prop/ea3-config.xml"; + options->ea3_ident_path = "prop/ea3-ident.xml"; options->softid = NULL; options->pcbid = NULL; options->module = NULL; @@ -33,11 +36,54 @@ void options_init(struct options *options) options->override_urlslash_value = false; } +void options_read_early_cmdline( + struct options *options, int argc, const char **argv) +{ + for (int i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + switch (argv[i][1]) { + case 'C': + if (i + 1 >= argc) { + return; + } + + options->bootstrap_config_path = argv[++i]; + + break; + + case 'Z': + if (i + 1 >= argc) { + return; + } + + options->bootstrap_selector = argv[++i]; + + break; + + default: + break; + } + } + } +} + bool options_read_cmdline(struct options *options, int argc, const char **argv) { + bool got_module = false; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { + case 'C': + case 'Z': + /* handled by options_read_early_cmdline() */ + if (i + 1 >= argc) { + return false; + } + + ++i; + + break; + case 'A': if (i + 1 >= argc) { return false; @@ -192,8 +238,10 @@ bool options_read_cmdline(struct options *options, int argc, const char **argv) break; } } else { - if (!options->module) { + /* override module from bootstrap config */ + if (!got_module) { options->module = argv[i]; + got_module = true; } } } @@ -205,6 +253,25 @@ bool options_read_cmdline(struct options *options, int argc, const char **argv) } } +void options_read_bootstrap( + struct options *options, const struct bootstrap_startup_config *bs_config) +{ + options->avs_config_path = bs_config->avs_config_file; + options->avs_heap_size = bs_config->avs_heap_size; + options->std_heap_size = bs_config->std_heap_size; + options->ea3_config_path = bs_config->eamuse_config_file; + + if (bs_config->log_enable_file) { + if (bs_config->log_file[0]) { + options->logfile = bs_config->log_file; + } else if (bs_config->log_name[0]) { + options->logfile = bs_config->log_name; + } + } + + options->module = bs_config->module_file; +} + void options_print_usage(void) { fprintf( @@ -215,6 +282,9 @@ void options_print_usage(void) " The following options can be specified before the app DLL " "path:\n" "\n" + " -C [filename] Bootstrap configuration file (default: " + "prop/bootstrap.xml)\n" + " -Z [selector] Bootstrap selector used in configuration\n" " -A [filename] App configuration file (default: " "prop/app-config.xml)\n" " -V [filename] AVS configuration file (default: " diff --git a/src/main/launcher/options.h b/src/main/launcher/options.h index 13f1c0fb..5ebba261 100644 --- a/src/main/launcher/options.h +++ b/src/main/launcher/options.h @@ -6,12 +6,17 @@ #include "util/array.h" +#include "launcher/bs-config.h" + struct options { size_t std_heap_size; size_t avs_heap_size; + const char *bootstrap_config_path; + const char *bootstrap_selector; const char *app_config_path; const char *avs_config_path; const char *ea3_config_path; + const char *ea3_ident_path; const char *softid; const char *pcbid; const char *module; @@ -26,7 +31,11 @@ struct options { }; void options_init(struct options *options); +void options_read_early_cmdline( + struct options *options, int argc, const char **argv); bool options_read_cmdline(struct options *options, int argc, const char **argv); +void options_read_bootstrap( + struct options *options, const struct bootstrap_startup_config *bs_config); void options_print_usage(void); void options_fini(struct options *options); diff --git a/src/main/launcher/property.c b/src/main/launcher/property.c index 2f5ded94..a6b1c836 100644 --- a/src/main/launcher/property.c +++ b/src/main/launcher/property.c @@ -11,6 +11,36 @@ #include "util/log.h" #include "util/mem.h" +typedef void (*rewinder)(uint32_t context); + +static struct property *do_property_load( + avs_reader_t reader, rewinder rewinder, uint32_t context, const char *name) +{ + struct property *prop; + void *buffer; + int nbytes; + + nbytes = property_read_query_memsize(reader, context, 0, 0); + + if (nbytes < 0) { + log_fatal("%s: Error querying configuration file", name); + } + + buffer = xmalloc(nbytes); + prop = property_create( + PROPERTY_FLAG_READ | PROPERTY_FLAG_WRITE | PROPERTY_FLAG_CREATE | + PROPERTY_FLAG_APPEND, + buffer, + nbytes); + rewinder(context); + + if (!property_insert_read(prop, 0, reader, context)) { + log_fatal("%s: Error reading configuration file", name); + } + + return prop; +} + static int boot_property_fread(uint32_t context, void *bytes, size_t nbytes) { FILE *f; @@ -20,33 +50,17 @@ static int boot_property_fread(uint32_t context, void *bytes, size_t nbytes) return fread(bytes, 1, nbytes, f); } -struct cstring_read_handle { - const char *buffer; - size_t buffer_len; - size_t offset; -}; - -static int -boot_property_cstring_read(uint32_t context, void *bytes, size_t nbytes) +static void boot_property_frewind(uint32_t context) { - int result = 0; - struct cstring_read_handle *h = TlsGetValue(context); - - if (h->offset < h->buffer_len) { - result = min(nbytes, h->buffer_len - h->offset); - memcpy(bytes, (const void *) (h->buffer + h->offset), result); - h->offset += result; - } - return result; + FILE *f = TlsGetValue(context); + rewind(f); } struct property *boot_property_load(const char *filename) { - struct property *prop; - void *buffer; - int nbytes; FILE *f; uint32_t f_keyhole; + struct property *prop; /* AVS callbacks are only given a 32-bit context parameter, even in 64-bit builds of AVS. We allocate a 32-bit TLS key and pass the context in this @@ -61,23 +75,8 @@ struct property *boot_property_load(const char *filename) log_fatal("%s: Error opening configuration file", filename); } - nbytes = property_read_query_memsize(boot_property_fread, f_keyhole, 0, 0); - - if (nbytes < 0) { - log_fatal("%s: Error querying configuration file", filename); - } - - buffer = xmalloc(nbytes); - prop = property_create( - PROPERTY_FLAG_READ | PROPERTY_FLAG_WRITE | PROPERTY_FLAG_CREATE | - PROPERTY_FLAG_APPEND, - buffer, - nbytes); - rewind(f); - - if (!property_insert_read(prop, 0, boot_property_fread, f_keyhole)) { - log_fatal("%s: Error reading configuration file", filename); - } + prop = do_property_load( + boot_property_fread, boot_property_frewind, f_keyhole, filename); TlsFree(f_keyhole); @@ -85,12 +84,37 @@ struct property *boot_property_load(const char *filename) return prop; } + +struct cstring_read_handle { + const char *buffer; + size_t buffer_len; + size_t offset; +}; + +static int +boot_property_cstring_read(uint32_t context, void *bytes, size_t nbytes) +{ + int result = 0; + struct cstring_read_handle *h = TlsGetValue(context); + + if (h->offset < h->buffer_len) { + result = min(nbytes, h->buffer_len - h->offset); + memcpy(bytes, (const void *) (h->buffer + h->offset), result); + h->offset += result; + } + return result; +} + +static void boot_property_cstring_rewind(uint32_t context) +{ + struct cstring_read_handle *h = TlsGetValue(context); + h->offset = 0; +} + struct property *boot_property_load_cstring(const char *cstring) { - struct property *prop; - void *buffer; - int nbytes; uint32_t s_keyhole; + struct property *prop; // see above struct cstring_read_handle read_handle; @@ -101,26 +125,43 @@ struct property *boot_property_load_cstring(const char *cstring) s_keyhole = TlsAlloc(); TlsSetValue(s_keyhole, &read_handle); - nbytes = property_read_query_memsize( - boot_property_cstring_read, s_keyhole, 0, 0); + prop = do_property_load( + boot_property_cstring_read, + boot_property_cstring_rewind, + s_keyhole, + ""); - if (nbytes < 0) { - log_fatal("Error querying configuration string"); - } + TlsFree(s_keyhole); - buffer = xmalloc(nbytes); - prop = property_create( - PROPERTY_FLAG_READ | PROPERTY_FLAG_WRITE | PROPERTY_FLAG_CREATE | - PROPERTY_FLAG_APPEND, - buffer, - nbytes); + return prop; +} - read_handle.offset = 0; - if (!property_insert_read(prop, 0, boot_property_cstring_read, s_keyhole)) { - log_fatal("Error inserting configuration string"); +static int boot_property_avs_read(uint32_t context, void *bytes, size_t nbytes) +{ + avs_desc desc = (avs_desc) context; + return avs_fs_read(desc, bytes, nbytes); +} + +static void boot_property_avs_rewind(uint32_t context) +{ + avs_desc desc = (avs_desc) context; + avs_fs_lseek(desc, 0, AVS_SEEK_SET); +} + +struct property *boot_property_load_avs(const char *filename) +{ + avs_desc desc; + struct property *prop; + + desc = avs_fs_open(filename, AVS_FILE_READ, AVS_FILE_FLAG_SHARE_READ); + if (!desc) { + log_fatal("%s: Error opening configuration file", filename); } - TlsFree(s_keyhole); + prop = do_property_load( + boot_property_avs_read, boot_property_avs_rewind, desc, filename); + + avs_fs_close(desc); return prop; } diff --git a/src/main/launcher/property.h b/src/main/launcher/property.h index c3f14d0e..e230b9cb 100644 --- a/src/main/launcher/property.h +++ b/src/main/launcher/property.h @@ -4,6 +4,7 @@ #include "imports/avs.h" struct property *boot_property_load(const char *filename); +struct property *boot_property_load_avs(const char *filename); struct property *boot_property_load_cstring(const char *cstring); void boot_property_free(struct property *prop);