#include "core.h" #include #include #include #include #include "external/robin_hood.h" #include "launcher/logger.h" #include "util/detour.h" #include "util/fileutils.h" #include "util/libutils.h" #include "util/logging.h" #include "util/utils.h" namespace avs { namespace core { // functions AVS215_BOOT_T avs215_boot {}; AVS216_BOOT_T avs216_boot {}; AVS_SHUTDOWN_T avs_shutdown {}; PROPERTY_CREATE_T property_create {}; PROPERTY_DESC_TO_BUFFER_T property_desc_to_buffer {}; PROPERTY_DESTROY_T property_destroy {}; PROPERTY_INSERT_READ_T property_insert_read {}; PROPERTY_NODE_CREATE_T property_node_create {}; PROPERTY_NODE_REFER_T property_node_refer {}; PROPERTY_NODE_REMOVE_T property_node_remove {}; PROPERTY_READ_QUERY_MEMSIZE_T property_read_query_memsize {}; PROPERTY_SEARCH_T property_search {}; STD_SETENV_T avs_std_setenv {}; // optional functions AVS_FS_OPEN_T avs_fs_open {}; AVS_FS_CLOSE_T avs_fs_close {}; AVS_FS_DUMP_MOUNTPOINT_T avs_fs_dump_mountpoint {}; AVS_FS_MOUNT_T avs_fs_mount {}; AVS_FS_COPY_T avs_fs_copy {}; AVS_FS_FSTAT_T avs_fs_fstat {}; AVS_FS_LSTAT_T avs_fs_lstat {}; AVS_FS_LSEEK_T avs_fs_lseek {}; AVS_FS_READ_T avs_fs_read {}; AVS_FS_OPENDIR_T avs_fs_opendir {}; AVS_FS_READDIR_T avs_fs_readdir {}; AVS_FS_CLOSEDIR_T avs_fs_closedir {}; CSTREAM_CREATE_T cstream_create {}; CSTREAM_OPERATE_T cstream_operate {}; CSTREAM_FINISH_T cstream_finish {}; CSTREAM_DESTROY_T cstream_destroy {}; PROPERTY_NODE_READ_T property_node_read {}; PROPERTY_NODE_WRITE_T property_node_write {}; PROPERTY_FILE_WRITE_T property_file_write {}; PROPERTY_NODE_TRAVERSAL_T property_node_traversal {}; PROPERTY_PSMAP_EXPORT_T property_psmap_export {}; PROPERTY_PSMAP_IMPORT_T property_psmap_import {}; PROPERTY_NODE_NAME_T property_node_name {}; PROPERTY_NODE_GET_DESC_T property_node_get_desc {}; PROPERTY_GET_ERROR_T property_get_error {}; PROPERTY_NODE_CLONE_T property_node_clone {}; PROPERTY_QUERY_SIZE_T property_query_size {}; PROPERTY_NODE_QUERY_STAT_T property_node_query_stat {}; PROPERTY_NODE_DATASIZE_T property_node_datasize {}; PROPERTY_MEM_WRITE_T property_mem_write {}; PROPERTY_PART_WRITE_T property_part_write {}; PROPERTY_NODE_ABSOLUTE_PATH_T property_node_absolute_path {}; PROPERTY_NODE_HAS_T property_node_has {}; PROPERTY_NODE_IS_ARRAY_T property_node_is_array {}; PROPERTY_NODE_TYPE_T property_node_type {}; PROPERTY_GET_ATTRIBUTE_BOOL_T property_get_attribute_bool {}; PROPERTY_NODE_GET_ATTRIBUTE_BOOL_T property_node_get_attribute_bool {}; PROPERTY_NODE_GET_ATTRIBUTE_U32_T property_node_get_attribute_u32 {}; PROPERTY_NODE_GET_ATTRIBUTE_S32_T property_node_get_attribute_s32 {}; PROPERTY_NODE_RENAME_T property_node_rename {}; PROPERTY_QUERY_FREESIZE_T property_query_freesize {}; PROPERTY_CLEAR_ERROR_T property_clear_error {}; PROPERTY_LOOKUP_ENCODE_T property_lookup_encode {}; PROPERTY_UNLOCK_FLAG_T property_unlock_flag {}; PROPERTY_LOCK_FLAG_T property_lock_flag {}; PROPERTY_SET_FLAG_T property_set_flag {}; PROPERTY_PART_WRITE_META_T property_part_write_meta {}; PROPERTY_PART_WRITE_META2_T property_part_write_meta2 {}; PROPERTY_READ_DATA_T property_read_data {}; PROPERTY_READ_META_T property_read_meta {}; PROPERTY_GET_ATTRIBUTE_U32_T property_get_attribute_u32 {}; PROPERTY_GET_ATTRIBUTE_S32_T property_get_attribute_s32 {}; PROPERTY_GET_FINGERPRINT_T property_get_fingerprint {}; PROPERTY_NODE_REFDATA_T property_node_refdata {}; PROPERTY_INSERT_READ_WITH_FILENAME_T property_insert_read_with_filename {}; PROPERTY_MEM_READ_T property_mem_read {}; PROPERTY_READ_QUERY_MEMSIZE_LONG_T property_read_query_memsize_long {}; PROPERTY_CLEAR_T property_clear {}; AVS_NET_SOCKET_T avs_net_socket {}; AVS_NET_GETSOCKOPT_T avs_net_getsockopt {}; AVS_NET_SETSOCKOPT_T avs_net_setsockopt {}; AVS_NET_CONNECT_T avs_net_connect {}; AVS_NET_SEND_T avs_net_send {}; AVS_NET_RECV_T avs_net_recv {}; AVS_NET_POLL_T avs_net_poll {}; AVS_NET_POLLFDS_ADD_T avs_net_pollfds_add {}; AVS_NET_POLLFDS_GET_T avs_net_pollfds_get {}; AVS_NET_ADD_PROTOCOL_T avs_net_add_protocol {}; AVS_NET_ADD_PROTOCOL_LEGACY_T avs_net_add_protocol_legacy {}; AVS_NET_DEL_PROTOCOL_T avs_net_del_protocol {}; AVS_NET_ADDRINFOBYADDR_T avs_net_addrinfobyaddr {}; AVS_NET_BIND_T avs_net_bind {}; AVS_NET_CLOSE_T avs_net_close {}; AVS_NET_SHUTDOWN_T avs_net_shutdown {}; AVS_NET_GET_PEERNAME_T avs_net_get_peername {}; AVS_NET_GET_SOCKNAME_T avs_net_get_sockname {}; // state avs_core_import IMPORT_NAMES {}; // settings Version VERSION = AVS21580; std::string VERSION_STR = "unknown"; size_t HEAP_SIZE = 0x1000000; bool DEFAULT_HEAP_SIZE_SET = false; std::string LOG_PATH; std::string CFG_PATH; std::string LOG_LEVEL_CUSTOM; // handle HINSTANCE DLL_INSTANCE = nullptr; std::string DLL_NAME = ""; // static fields static void *AVS_HEAP1 = nullptr; static void *AVS_HEAP2 = nullptr; // constants static constexpr struct avs_core_import IMPORT_LEGACY { .version = "legacy", .property_search = "property_search", .boot = "avs_boot", .shutdown = "avs_shutdown", .property_desc_to_buffer = "property_desc_to_buffer", .property_destroy = "property_destroy", .property_read_query_memsize = "property_read_query_memsize", .property_create = "property_create", .property_insert_read = "property_insert_read", .property_node_create = "property_node_create", .property_node_remove = "property_node_remove", .property_node_refer = "property_node_refer", .std_setenv = "std_setenv", .avs_fs_open = "avs_fs_open", .avs_fs_copy = "avs_fs_copy", .avs_fs_close = "avs_fs_close", .avs_fs_dump_mountpoint = "avs_fs_dump_mountpoint", .avs_fs_mount = "avs_fs_mount", .avs_fs_fstat = "avs_fs_fstat", .avs_fs_lstat = "avs_fs_lstat", .avs_fs_lseek = "avs_fs_lseek", .avs_fs_read = "avs_fs_read", .avs_fs_opendir = "avs_fs_opendir", .avs_fs_readdir = "avs_fs_readdir", .avs_fs_closedir = "avs_fs_closedir", .cstream_create = "cstream_create", .cstream_operate = "cstream_operate", .cstream_finish = "cstream_finish", .cstream_destroy = "cstream_destroy", .property_node_read = "property_node_read", .property_node_write = "property_node_write", .property_file_write = "property_file_write", .property_node_traversal = "property_node_traversal", .property_psmap_export = "property_psmap_export", .property_psmap_import = "property_psmap_import", .property_node_name = "property_node_name", .property_node_get_desc = "property_node_get_desc", .property_get_error = "property_get_error", .property_node_clone = "property_node_clone", .property_query_size = "property_query_size", .property_node_query_stat = "property_node_query_stat", .property_node_datasize = "property_node_datasize", .property_mem_write = "property_mem_write", .property_part_write = "property_part_write", .property_node_absolute_path = "property_node_absolute_path", .property_node_has = "property_node_has", .property_node_is_array = "property_node_is_array", .property_node_type = "property_node_type", .property_get_attribute_bool = "property_get_attribute_bool", .property_node_get_attribute_bool = "property_node_get_attribute_bool", .property_node_get_attribute_u32 = "property_node_get_attribute_u32", .property_node_get_attribute_s32 = "property_node_get_attribute_s32", .property_node_rename = "property_node_rename", .property_query_freesize = "property_query_freesize", .property_clear_error = "property_clear_error", .property_lookup_encode = "property_lookup_encode", .property_unlock_flag = "property_unlock_flag", .property_lock_flag = "property_lock_flag", .property_set_flag = "property_set_flag", .property_part_write_meta = "property_part_write_meta", .property_part_write_meta2 = "property_part_write_meta2", .property_read_data = "property_read_data", .property_read_meta = "property_read_meta", .property_get_attribute_u32 = "property_get_attribute_u32", .property_get_attribute_s32 = "property_get_attribute_s32", .property_get_fingerprint = "property_get_fingerprint", .property_node_refdata = "property_node_refdata", .property_insert_read_with_filename = "property_insert_read_with_filename", .property_mem_read = "property_mem_read", .property_read_query_memsize_long = "property_read_query_memsize_long", .property_clear = "property_clear", .avs_net_add_protocol = "avs_net_add_protocol", .avs_net_del_protocol = "avs_net_del_protocol", .avs_net_addrinfobyaddr = "avs_net_addrinfobyaddr", .avs_net_socket = "avs_net_socket", .avs_net_setsockopt = "avs_net_setsockopt", .avs_net_getsockopt = "avs_net_getsockopt", .avs_net_connect = "avs_net_connect", .avs_net_send = "avs_net_send", .avs_net_recv = "avs_net_recv", .avs_net_poll = "avs_net_poll", .avs_net_pollfds_add = "avs_net_pollfds_add", .avs_net_pollfds_get = "avs_net_pollfds_get", .avs_net_bind = "avs_net_bind", .avs_net_close = "avs_net_close", .avs_net_shutdown = "avs_net_shutdown", .avs_net_get_peername = "avs_net_get_peername", .avs_net_get_sockname = "avs_net_get_sockname", }; static constexpr struct avs_core_import IMPORT_AVS21360 { .version = "2.13.6.0", .property_search = "XC058ba50000fb", .boot = "XC058ba50000f4", .shutdown = "XC058ba5000154", .property_desc_to_buffer = "XC058ba50000cd", .property_destroy = "XC058ba500010f", .property_read_query_memsize = "XC058ba5000066", .property_create = "XC058ba5000107", .property_insert_read = "XC058ba5000016", .property_node_create = "XC058ba5000143", .property_node_remove = "XC058ba5000085", .property_node_refer = "XC058ba5000113", .std_setenv = "XC058ba5000075", .avs_fs_open = "XC058ba50000b6", .avs_fs_copy = "XC058ba5000122", .avs_fs_close = "XC058ba500011b", .avs_fs_dump_mountpoint = "XC058ba50000c8", .avs_fs_mount = "XC058ba500009c", .avs_fs_fstat = "XC058ba50000d0", .avs_fs_lstat = "XC058ba5000063", .avs_fs_lseek = "XC058ba500000f", .avs_fs_read = "XC058ba5000139", .avs_fs_opendir = "XC058ba50000dd", .avs_fs_readdir = "XC058ba5000086", .avs_fs_closedir = "XC058ba5000087", .cstream_create = "XC058ba5000118", .cstream_operate = "XC058ba5000078", .cstream_finish = "XC058ba5000130", .cstream_destroy = "XC058ba500012b", .property_node_read = "XC058ba5000001", .property_node_write = "XC058ba5000146", .property_file_write = "XC058ba500009b", .property_node_traversal = "XC058ba500005f", .property_psmap_export = "XC058ba5000071", .property_psmap_import = "XC058ba5000068", .property_node_name = "XC058ba5000106", .property_node_get_desc = "XC058ba5000042", .property_get_error = "XC058ba500012e", .property_node_clone = "XC058ba5000103", .property_query_size = "XC058ba5000101", .property_node_query_stat = "XC058ba500015e", .property_node_datasize = "XC058ba5000100", .property_mem_write = "XC058ba5000162", .property_part_write = "XC058ba5000060", .property_node_absolute_path = "XC058ba500013b", .property_node_has = "XC058ba5000074", .property_node_is_array = "XC058ba5000116", .property_node_type = "XC058ba5000150", .property_get_attribute_bool = "XC058ba5000024", .property_node_get_attribute_bool = "XC058ba50000b4", .property_node_get_attribute_u32 = "XC058ba500000b", .property_node_get_attribute_s32 = "XC058ba500014b", .property_node_rename = "XC058ba50000ee", .property_query_freesize = "XC058ba500013a", .property_clear_error = "XC058ba50000a7", .property_lookup_encode = "XC058ba5000158", .property_unlock_flag = "XC058ba5000127", .property_lock_flag = "XC058ba500011e", .property_set_flag = "XC058ba500014d", .property_part_write_meta = "XC058ba50000d8", .property_part_write_meta2 = "XC058ba50000b5", .property_read_data = "property_read_data", // not found .property_read_meta = "property_read_meta", // not found .property_get_attribute_u32 = "XC058ba50000ab", .property_get_attribute_s32 = "XC058ba50000fe", .property_get_fingerprint = "XC058ba50000ce", .property_node_refdata = "XC058ba5000151", .property_insert_read_with_filename = "XC058ba500006c", .property_mem_read = "XC058ba5000132", .property_read_query_memsize_long = "XC058ba5000091", .property_clear = "XC058ba5000128", .avs_net_add_protocol = "XC058ba5000126", .avs_net_del_protocol = "XC058ba5000028", .avs_net_addrinfobyaddr = "XC058ba50000a8", .avs_net_socket = "XC058ba50000e3", .avs_net_setsockopt = "XC058ba5000009", .avs_net_getsockopt = "XC058ba50000a2", .avs_net_connect = "XC058ba5000000", .avs_net_send = "XC058ba50000ad", .avs_net_recv = "XC058ba5000163", .avs_net_poll = "XC058ba50000fa", .avs_net_pollfds_add = "XC058ba5000077", .avs_net_pollfds_get = "XC058ba500001e", .avs_net_bind = "XC058ba5000083", .avs_net_close = "XC058ba500010b", .avs_net_shutdown = "XC058ba500008d", .avs_net_get_peername = "XC058ba5000031", .avs_net_get_sockname = "XC058ba500005d", }; static constexpr struct avs_core_import IMPORT_AVS21430 { .version = "2.14.3.0", .property_search = "XC0bbe970000fa", .boot = "XC0bbe970000f2", .shutdown = "XC0bbe9700014d", .property_desc_to_buffer = "XC0bbe970000c9", .property_destroy = "XC0bbe9700010d", .property_read_query_memsize = "XC0bbe97000062", .property_create = "XC0bbe97000105", .property_insert_read = "XC0bbe97000017", .property_node_create = "XC0bbe9700013f", .property_node_remove = "XC0bbe97000080", .property_node_refer = "XC0bbe97000112", .std_setenv = "XC0bbe97000070", .avs_fs_open = "XC0bbe970000b3", .avs_fs_copy = "XC0bbe97000120", .avs_fs_close = "XC0bbe97000119", .avs_fs_dump_mountpoint = "XC0bbe970000c5", .avs_fs_mount = "XC0bbe97000099", .avs_fs_fstat = "XC0bbe970000ce", .avs_fs_lstat = "XC0bbe9700005f", .avs_fs_read = "XC0bbe97000134", .avs_fs_opendir = "XC0bbe970000db", .property_file_write = "property_file_write", // not found .property_get_error = "property_get_error", // not found .avs_net_add_protocol = "XC0bbe97000124", .avs_net_del_protocol = "XC0bbe97000026", .avs_net_addrinfobyaddr = "XC0bbe970000a4", .avs_net_socket = "XC0bbe970000e0", .avs_net_setsockopt = "XC0bbe9700000a", .avs_net_getsockopt = "XC0bbe9700009e", .avs_net_connect = "XC0bbe97000000", .avs_net_send = "XC0bbe970000a9", .avs_net_recv = "XC0bbe9700015d", .avs_net_poll = "XC0bbe970000f9", .avs_net_pollfds_add = "XC0bbe97000072", .avs_net_pollfds_get = "XC0bbe9700001d", .avs_net_bind = "XC0bbe9700007e", .avs_net_close = "XC0bbe97000109", .avs_net_shutdown = "XC0bbe9700008a", .avs_net_get_peername = "XC0bbe9700002e", .avs_net_get_sockname = "XC0bbe97000059", }; static constexpr struct avs_core_import IMPORT_AVS21580 { .version = "2.15.8.0", .property_search = "XCd229cc00012e", .boot = "XCd229cc0000aa", .shutdown = "XCd229cc00001d", .property_desc_to_buffer = "XCd229cc0000fd", .property_destroy = "XCd229cc00013c", .property_read_query_memsize = "XCd229cc0000ff", .property_create = "XCd229cc000126", .property_insert_read = "XCd229cc00009a", .property_node_create = "XCd229cc00002c", .property_node_remove = "XCd229cc000028", .property_node_refer = "XCd229cc000009", .std_setenv = "XCd229cc000094", .avs_fs_open = "XCd229cc000090", .avs_fs_copy = "XCd229cc0000eb", .avs_fs_close = "XCd229cc00011f", .avs_fs_dump_mountpoint = "XCd229cc0000e9", .avs_fs_mount = "XCd229cc0000ce", .avs_fs_fstat = "XCd229cc0000c3", .avs_fs_lstat = "XCd229cc0000c0", .avs_fs_lseek = "XCd229cc00004d", .avs_fs_read = "XCd229cc00010d", .avs_fs_opendir = "XCd229cc0000f0", .avs_fs_readdir = "XCd229cc0000bb", .avs_fs_closedir = "XCd229cc0000b8", .cstream_create = "XCd229cc000141", .cstream_operate = "XCd229cc00008c", .cstream_finish = "XCd229cc000025", .cstream_destroy = "XCd229cc0000e3", .property_node_read = "XCd229cc0000f3", .property_node_write = "XCd229cc00002d", .property_file_write = "XCd229cc000052", .property_node_traversal = "XCd229cc000046", .property_psmap_export = "XCd229cc000006", .property_psmap_import = "XCd229cc000005", .property_node_name = "XCd229cc000049", .property_node_get_desc = "XCd229cc000165", .property_get_error = "XCd229cc0000b5", .property_node_clone = "XCd229cc00010a", .property_query_size = "XCd229cc000032", .property_node_query_stat = "XCd229cc0000b1", .property_node_datasize = "XCd229cc000083", .property_mem_write = "XCd229cc000033", .property_part_write = "XCd229cc000024", .property_node_absolute_path = "XCd229cc00007c", .property_node_has = "XCd229cc00008a", .property_node_is_array = "XCd229cc000142", .property_node_type = "XCd229cc000071", .property_get_attribute_bool = "XCd229cc000043", .property_node_get_attribute_bool = "XCd229cc000110", .property_node_get_attribute_u32 = "XCd229cc0000db", .property_node_get_attribute_s32 = "XCd229cc00011a", .property_node_rename = "XCd229cc0000af", .property_query_freesize = "XCd229cc000144", .property_clear_error = "XCd229cc00014b", .property_lookup_encode = "XCd229cc0000fc", .property_unlock_flag = "XCd229cc000145", .property_lock_flag = "XCd229cc000121", .property_set_flag = "XCd229cc000035", .property_part_write_meta = "XCd229cc00004f", .property_part_write_meta2 = "XCd229cc000107", .property_read_data = "XCd229cc0000de", .property_read_meta = "XCd229cc00010e", .property_get_attribute_u32 = "XCd229cc000148", .property_get_attribute_s32 = "XCd229cc00005f", .property_get_fingerprint = "XCd229cc000057", .property_node_refdata = "XCd229cc00009f", .property_insert_read_with_filename = "XCd229cc0000cd", .property_mem_read = "XCd229cc000039", .property_read_query_memsize_long = "XCd229cc00002b", .property_clear = "XCd229cc0000c2", .avs_net_add_protocol = "XCd229cc000156", .avs_net_del_protocol = "XCd229cc00000f", .avs_net_addrinfobyaddr = "XCd229cc000040", .avs_net_socket = "XCd229cc000026", .avs_net_setsockopt = "XCd229cc000092", .avs_net_getsockopt = "XCd229cc000084", .avs_net_connect = "XCd229cc000038", .avs_net_send = "XCd229cc00011d", .avs_net_recv = "XCd229cc000131", .avs_net_poll = "XCd229cc00011c", .avs_net_pollfds_add = "XCd229cc00004b", .avs_net_pollfds_get = "XCd229cc000105", .avs_net_bind = "XCd229cc00007e", .avs_net_close = "XCd229cc00009c", .avs_net_shutdown = "XCd229cc0000ac", .avs_net_get_peername = "XCd229cc000085", .avs_net_get_sockname = "XCd229cc0000b0", }; static constexpr struct avs_core_import IMPORT_AVS21610 { .version = "2.16.1.0", .property_search = "XCnbrep700008c", .boot = "XCnbrep700011a", .shutdown = "XCnbrep700011b", .property_desc_to_buffer = "XCnbrep700007d", .property_destroy = "XCnbrep700007c", .property_read_query_memsize = "XCnbrep700009b", .property_create = "XCnbrep700007b", .property_insert_read = "XCnbrep700007f", .property_node_create = "XCnbrep700008d", .property_node_remove = "XCnbrep700008e", .property_node_refer = "XCnbrep700009a", .std_setenv = "XCnbrep70000cc", .avs_fs_open = "XCnbrep7000039", .avs_fs_copy = "XCnbrep7000050", .avs_fs_close = "XCnbrep7000040", .avs_fs_dump_mountpoint = "XCnbrep7000053", .avs_fs_mount = "XCnbrep7000036", .avs_fs_fstat = "XCnbrep700004d", .avs_fs_lstat = "XCnbrep700004e", .avs_fs_lseek = "XCnbrep700003a", .avs_fs_read = "XCnbrep700003c", .avs_fs_opendir = "XCnbrep7000047", .avs_fs_readdir = "XCnbrep7000048", .avs_fs_closedir = "XCnbrep7000049", .cstream_create = "XCnbrep7000124", .cstream_operate = "XCnbrep7000126", .cstream_finish = "XCnbrep7000127", .cstream_destroy = "XCnbrep7000128", .property_node_read = "XCnbrep7000096", .property_node_write = "XCnbrep7000097", .property_file_write = "XCnbrep70000a1", .property_node_traversal = "XCnbrep7000091", .property_psmap_export = "XCnbrep700009c", .property_psmap_import = "XCnbrep700009b", .property_node_name = "XCnbrep7000092", .property_node_get_desc = "XCnbrep7000099", .property_get_error = "XCnbrep7000089", .property_node_clone = "XCnbrep700008f", .property_query_size = "XCnbrep700008a", .property_node_query_stat = "XCnbrep70000b0", .property_node_datasize = "XCnbrep7000095", .property_mem_write = "XCnbrep70000a3", .property_part_write = "XCnbrep7000082", .property_node_absolute_path = "XCnbrep70000b1", .property_node_has = "XCnbrep7000098", .property_node_is_array = "XCnbrep7000094", .property_node_type = "XCnbrep7000093", .property_get_attribute_bool = "XCnbrep70000ab", .property_node_get_attribute_bool = "XCnbrep70000a8", .property_node_get_attribute_u32 = "XCnbrep70000a7", .property_node_get_attribute_s32 = "XCnbrep70000a6", .property_node_rename = "XCnbrep70000ae", .property_query_freesize = "XCnbrep700008b", .property_clear_error = "XCnbrep7000088", .property_lookup_encode = "XCnbrep70000a4", .property_unlock_flag = "XCnbrep7000087", .property_lock_flag = "XCnbrep7000086", .property_set_flag = "XCnbrep7000085", .property_part_write_meta = "XCnbrep7000084", .property_part_write_meta2 = "XCnbrep7000083", .property_read_data = "XCnbrep7000081", .property_read_meta = "XCnbrep7000080", .property_get_attribute_u32 = "XCnbrep70000aa", .property_get_attribute_s32 = "XCnbrep70000a9", .property_get_fingerprint = "XCnbrep70000af", .property_node_refdata = "XCnbrep7000090", .property_insert_read_with_filename = "XCnbrep70000a0", .property_mem_read = "XCnbrep70000a2", .property_read_query_memsize_long = "XCnbrep700009b", .property_clear = "XCnbrep700007e", .avs_net_add_protocol = "XCnbrep7000062", .avs_net_del_protocol = "XCnbrep7000063", .avs_net_addrinfobyaddr = "XCnbrep7000060", .avs_net_socket = "XCnbrep7000064", .avs_net_setsockopt = "XCnbrep7000065", .avs_net_getsockopt = "XCnbrep7000066", .avs_net_connect = "XCnbrep7000068", .avs_net_send = "XCnbrep700006d", .avs_net_recv = "XCnbrep7000071", .avs_net_poll = "XCnbrep7000075", .avs_net_pollfds_add = "XCnbrep7000077", .avs_net_pollfds_get = "XCnbrep7000078", .avs_net_bind = "XCnbrep7000067", .avs_net_close = "XCnbrep700006b", .avs_net_shutdown = "XCnbrep700006c", .avs_net_get_peername = "XCnbrep7000079", .avs_net_get_sockname = "XCnbrep700007a", }; static constexpr struct avs_core_import IMPORT_AVS21630 { .version = "2.16.3.0", .property_search = "XCnbrep70000a1", .boot = "XCnbrep7000129", .shutdown = "XCnbrep700012a", .property_desc_to_buffer = "XCnbrep7000092", .property_destroy = "XCnbrep7000091", .property_read_query_memsize = "XCnbrep70000b0", .property_create = "XCnbrep7000090", .property_insert_read = "XCnbrep7000094", .property_node_create = "XCnbrep70000a2", .property_node_remove = "XCnbrep70000a3", .property_node_refer = "XCnbrep70000af", .std_setenv = "XCnbrep70000d4", .avs_fs_open = "XCnbrep700004e", .avs_fs_copy = "XCnbrep7000065", .avs_fs_close = "XCnbrep7000055", .avs_fs_dump_mountpoint = "XCnbrep7000068", .avs_fs_mount = "XCnbrep700004b", .avs_fs_fstat = "XCnbrep7000062", .avs_fs_lstat = "XCnbrep7000063", .avs_fs_lseek = "XCnbrep700004f", .avs_fs_read = "XCnbrep7000051", .avs_fs_opendir = "XCnbrep700005c", .avs_fs_readdir = "XCnbrep700005d", .avs_fs_closedir = "XCnbrep700005e", .cstream_create = "XCnbrep7000130", .cstream_operate = "XCnbrep7000132", .cstream_finish = "XCnbrep7000133", .cstream_destroy = "XCnbrep7000134", .property_node_read = "XCnbrep70000ab", .property_node_write = "XCnbrep70000ac", .property_file_write = "XCnbrep70000b6", .property_node_traversal = "XCnbrep70000a6", .property_psmap_export = "XCnbrep70000b3", .property_psmap_import = "XCnbrep70000b2", .property_node_name = "XCnbrep70000a7", .property_node_get_desc = "XCnbrep70000ae", .property_get_error = "XCnbrep700009e", .property_node_clone = "XCnbrep70000a4", .property_query_size = "XCnbrep700009f", .property_node_query_stat = "XCnbrep70000c5", .property_node_datasize = "XCnbrep70000aa", .property_mem_write = "XCnbrep70000b8", .property_part_write = "XCnbrep7000097", .property_node_absolute_path = "XCnbrep70000c6", .property_node_has = "XCnbrep70000ad", .property_node_is_array = "XCnbrep70000a9", .property_node_type = "XCnbrep70000a8", .property_get_attribute_bool = "XCnbrep70000c0", .property_node_get_attribute_bool = "XCnbrep70000bd", .property_node_get_attribute_u32 = "XCnbrep70000bc", .property_node_get_attribute_s32 = "XCnbrep70000bb", .property_node_rename = "XCnbrep70000c3", .property_query_freesize = "XCnbrep70000a0", .property_clear_error = "XCnbrep700009d", .property_lookup_encode = "XCnbrep70000b9", .property_unlock_flag = "XCnbrep700009c", .property_lock_flag = "XCnbrep700009b", .property_set_flag = "XCnbrep700009a", .property_part_write_meta = "XCnbrep7000099", .property_part_write_meta2 = "XCnbrep7000098", .property_read_data = "XCnbrep7000096", .property_read_meta = "XCnbrep7000095", .property_get_attribute_u32 = "XCnbrep70000bf", .property_get_attribute_s32 = "XCnbrep70000be", .property_get_fingerprint = "XCnbrep70000c4", .property_node_refdata = "XCnbrep70000a5", .property_insert_read_with_filename = "XCnbrep70000b5", .property_mem_read = "XCnbrep70000b7", .property_read_query_memsize_long = "XCnbrep70000b1", .property_clear = "XCnbrep7000093", .avs_net_add_protocol = "XCnbrep7000077", .avs_net_del_protocol = "XCnbrep7000078", .avs_net_addrinfobyaddr = "XCnbrep7000075", .avs_net_socket = "XCnbrep7000079", .avs_net_setsockopt = "XCnbrep700007a", .avs_net_getsockopt = "XCnbrep700007b", .avs_net_connect = "XCnbrep700007d", .avs_net_send = "XCnbrep7000082", .avs_net_recv = "XCnbrep7000086", .avs_net_poll = "XCnbrep700008a", .avs_net_pollfds_add = "XCnbrep700008c", .avs_net_pollfds_get = "XCnbrep700008d", .avs_net_bind = "XCnbrep700007c", .avs_net_close = "XCnbrep7000080", .avs_net_shutdown = "XCnbrep7000081", .avs_net_get_peername = "XCnbrep700008f", .avs_net_get_sockname = "XCnbrep700008e", }; static constexpr struct avs_core_import IMPORT_AVS21651 { .version = "2.16.5.1", .property_search = "XCnbrep70000a1", .boot = "XCnbrep7000129", .shutdown = "XCnbrep700012a", .property_desc_to_buffer = "XCnbrep7000092", .property_destroy = "XCnbrep7000091", .property_read_query_memsize = "XCnbrep70000b0", .property_create = "XCnbrep7000090", .property_insert_read = "XCnbrep7000094", .property_node_create = "XCnbrep70000a2", .property_node_remove = "XCnbrep70000a3", .property_node_refer = "XCnbrep70000af", .std_setenv = "XCnbrep70000d4", .avs_fs_open = "XCnbrep700004e", .avs_fs_copy = "XCnbrep7000065", .avs_fs_close = "XCnbrep7000055", .avs_fs_dump_mountpoint = "XCnbrep7000068", .avs_fs_mount = "XCnbrep700004b", .avs_fs_fstat = "XCnbrep7000062", .avs_fs_lstat = "XCnbrep7000063", .avs_fs_lseek = "XCnbrep700004f", .avs_fs_read = "XCnbrep7000051", .avs_fs_opendir = "XCnbrep700005c", .avs_fs_readdir = "XCnbrep700005d", .avs_fs_closedir = "XCnbrep700005e", .cstream_create = "XCnbrep7000130", .cstream_operate = "XCnbrep7000132", .cstream_finish = "XCnbrep7000133", .cstream_destroy = "XCnbrep7000134", .property_node_read = "XCnbrep70000ab", .property_node_write = "XCnbrep70000ac", .property_file_write = "XCnbrep70000b6", .property_node_traversal = "XCnbrep70000a6", .property_psmap_export = "XCnbrep70000b3", .property_psmap_import = "XCnbrep70000b2", .property_node_name = "XCnbrep70000a7", .property_node_get_desc = "XCnbrep70000ae", .property_get_error = "XCnbrep700009e", .property_node_clone = "XCnbrep70000a4", .property_query_size = "XCnbrep700009f", .property_node_query_stat = "XCnbrep70000c5", .property_node_datasize = "XCnbrep70000aa", .property_mem_write = "XCnbrep70000b8", .property_part_write = "XCnbrep7000097", .property_node_absolute_path = "XCnbrep70000c6", .property_node_has = "XCnbrep70000ad", .property_node_is_array = "XCnbrep70000a9", .property_node_type = "XCnbrep70000a8", .property_get_attribute_bool = "XCnbrep70000c0", .property_node_get_attribute_bool = "XCnbrep70000bd", .property_node_get_attribute_u32 = "XCnbrep70000bc", .property_node_get_attribute_s32 = "XCnbrep70000bb", .property_node_rename = "XCnbrep70000c3", .property_query_freesize = "XCnbrep70000a0", .property_clear_error = "XCnbrep700009d", .property_lookup_encode = "XCnbrep70000b9", .property_unlock_flag = "XCnbrep700009c", .property_lock_flag = "XCnbrep700009b", .property_set_flag = "XCnbrep700009a", .property_part_write_meta = "XCnbrep7000099", .property_part_write_meta2 = "XCnbrep7000098", .property_read_data = "XCnbrep7000096", .property_read_meta = "XCnbrep7000095", .property_get_attribute_u32 = "XCnbrep70000bf", .property_get_attribute_s32 = "XCnbrep70000be", .property_get_fingerprint = "XCnbrep70000c4", .property_node_refdata = "XCnbrep70000a5", .property_insert_read_with_filename = "XCnbrep70000b5", .property_mem_read = "XCnbrep70000b7", .property_read_query_memsize_long = "XCnbrep70000b1", .property_clear = "XCnbrep7000093", .avs_net_add_protocol = "XCnbrep7000077", .avs_net_del_protocol = "XCnbrep7000078", .avs_net_addrinfobyaddr = "XCnbrep7000075", .avs_net_socket = "XCnbrep7000079", .avs_net_setsockopt = "XCnbrep700007a", .avs_net_getsockopt = "XCnbrep700007b", .avs_net_connect = "XCnbrep700007d", .avs_net_send = "XCnbrep7000082", .avs_net_recv = "XCnbrep7000086", .avs_net_poll = "XCnbrep700008a", .avs_net_pollfds_add = "XCnbrep700008c", .avs_net_pollfds_get = "XCnbrep700008d", .avs_net_bind = "XCnbrep700007c", .avs_net_close = "XCnbrep7000080", .avs_net_shutdown = "XCnbrep7000081", .avs_net_get_peername = "XCnbrep700008f", .avs_net_get_sockname = "XCnbrep700008e", }; static constexpr struct avs_core_import IMPORT_AVS21671 { .version = "2.16.7.1", .property_search = "XCnbrep70000a1", .boot = "XCnbrep7000129", .shutdown = "XCnbrep700012a", .property_desc_to_buffer = "XCnbrep7000092", .property_destroy = "XCnbrep7000091", .property_read_query_memsize = "XCnbrep70000b0", .property_create = "XCnbrep7000090", .property_insert_read = "XCnbrep7000094", .property_node_create = "XCnbrep70000a2", .property_node_remove = "XCnbrep70000a3", .property_node_refer = "XCnbrep70000af", .std_setenv = "XCnbrep70000d4", .avs_fs_open = "XCnbrep700004e", .avs_fs_copy = "XCnbrep7000065", .avs_fs_close = "XCnbrep7000055", .avs_fs_dump_mountpoint = "XCnbrep7000068", .avs_fs_mount = "XCnbrep700004b", .avs_fs_fstat = "XCnbrep7000062", .avs_fs_lstat = "XCnbrep7000063", .avs_fs_lseek = "XCnbrep700004f", .avs_fs_read = "XCnbrep7000051", .avs_fs_opendir = "XCnbrep700005c", .avs_fs_readdir = "XCnbrep700005d", .avs_fs_closedir = "XCnbrep700005e", .cstream_create = "XCnbrep7000130", .cstream_operate = "XCnbrep7000132", .cstream_finish = "XCnbrep7000133", .cstream_destroy = "XCnbrep7000134", .property_node_read = "XCnbrep70000ab", .property_node_write = "XCnbrep70000ac", .property_file_write = "XCnbrep70000b6", .property_node_traversal = "XCnbrep70000a6", .property_psmap_export = "XCnbrep70000b3", .property_psmap_import = "XCnbrep70000b2", .property_node_name = "XCnbrep70000a7", .property_node_get_desc = "XCnbrep70000ae", .property_get_error = "XCnbrep700009e", .property_node_clone = "XCnbrep70000a4", .property_query_size = "XCnbrep700009f", .property_node_query_stat = "XCnbrep70000c5", .property_node_datasize = "XCnbrep70000aa", .property_mem_write = "XCnbrep70000b8", .property_part_write = "XCnbrep7000097", .property_node_absolute_path = "XCnbrep70000c6", .property_node_has = "XCnbrep70000ad", .property_node_is_array = "XCnbrep70000a9", .property_node_type = "XCnbrep70000a8", .property_get_attribute_bool = "XCnbrep70000c0", .property_node_get_attribute_bool = "XCnbrep70000bd", .property_node_get_attribute_u32 = "XCnbrep70000bc", .property_node_get_attribute_s32 = "XCnbrep70000bb", .property_node_rename = "XCnbrep70000c3", .property_query_freesize = "XCnbrep70000a0", .property_clear_error = "XCnbrep700009d", .property_lookup_encode = "XCnbrep70000b9", .property_unlock_flag = "XCnbrep700009c", .property_lock_flag = "XCnbrep700009b", .property_set_flag = "XCnbrep700009a", .property_part_write_meta = "XCnbrep7000099", .property_part_write_meta2 = "XCnbrep7000098", .property_read_data = "XCnbrep7000096", .property_read_meta = "XCnbrep7000095", .property_get_attribute_u32 = "XCnbrep70000bf", .property_get_attribute_s32 = "XCnbrep70000be", .property_get_fingerprint = "XCnbrep70000c4", .property_node_refdata = "XCnbrep70000a5", .property_insert_read_with_filename = "XCnbrep70000b5", .property_mem_read = "XCnbrep70000b7", .property_read_query_memsize_long = "XCnbrep70000b1", .property_clear = "XCnbrep7000093", .avs_net_add_protocol = "XCnbrep7000077", .avs_net_del_protocol = "XCnbrep7000078", .avs_net_addrinfobyaddr = "XCnbrep7000075", .avs_net_socket = "XCnbrep7000079", .avs_net_setsockopt = "XCnbrep700007a", .avs_net_getsockopt = "XCnbrep700007b", .avs_net_connect = "XCnbrep700007d", .avs_net_send = "XCnbrep7000082", .avs_net_recv = "XCnbrep7000086", .avs_net_poll = "XCnbrep700008a", .avs_net_pollfds_add = "XCnbrep700008c", .avs_net_pollfds_get = "XCnbrep700008d", .avs_net_bind = "XCnbrep700007c", .avs_net_close = "XCnbrep7000080", .avs_net_shutdown = "XCnbrep7000081", .avs_net_get_peername = "XCnbrep700008f", .avs_net_get_sockname = "XCnbrep700008e", }; static constexpr struct avs_core_import IMPORT_AVS21681 { .version = "2.16.8.1", .property_search = "XCnbrep70000a1", .boot = "XCnbrep7000129", .shutdown = "XCnbrep700012a", .property_desc_to_buffer = "XCnbrep7000092", .property_destroy = "XCnbrep7000091", .property_read_query_memsize = "XCnbrep70000b0", .property_create = "XCnbrep7000090", .property_insert_read = "XCnbrep7000094", .property_node_create = "XCnbrep70000a2", .property_node_remove = "XCnbrep70000a3", .property_node_refer = "XCnbrep70000af", .std_setenv = "XCnbrep70000d4", .avs_fs_open = "XCnbrep700004e", .avs_fs_copy = "XCnbrep7000065", .avs_fs_close = "XCnbrep7000055", .avs_fs_dump_mountpoint = "XCnbrep7000068", .avs_fs_mount = "XCnbrep700004b", .avs_fs_fstat = "XCnbrep7000062", .avs_fs_lstat = "XCnbrep7000063", .avs_fs_lseek = "XCnbrep700004f", .avs_fs_read = "XCnbrep7000051", .avs_fs_opendir = "XCnbrep700005c", .avs_fs_readdir = "XCnbrep700005d", .avs_fs_closedir = "XCnbrep700005e", .cstream_create = "XCnbrep7000130", .cstream_operate = "XCnbrep7000132", .cstream_finish = "XCnbrep7000133", .cstream_destroy = "XCnbrep7000134", .property_node_read = "XCnbrep70000ab", .property_node_write = "XCnbrep70000ac", .property_file_write = "XCnbrep70000b6", .property_node_traversal = "XCnbrep70000a6", .property_psmap_export = "XCnbrep70000b3", .property_psmap_import = "XCnbrep70000b2", .property_node_name = "XCnbrep70000a7", .property_node_get_desc = "XCnbrep70000ae", .property_get_error = "XCnbrep700009e", .property_node_clone = "XCnbrep70000a4", .property_query_size = "XCnbrep700009f", .property_node_query_stat = "XCnbrep70000c5", .property_node_datasize = "XCnbrep70000aa", .property_mem_write = "XCnbrep70000b8", .property_part_write = "XCnbrep7000097", .property_node_absolute_path = "XCnbrep70000c6", .property_node_has = "XCnbrep70000ad", .property_node_is_array = "XCnbrep70000a9", .property_node_type = "XCnbrep70000a8", .property_get_attribute_bool = "XCnbrep70000c0", .property_node_get_attribute_bool = "XCnbrep70000bd", .property_node_get_attribute_u32 = "XCnbrep70000bc", .property_node_get_attribute_s32 = "XCnbrep70000bb", .property_node_rename = "XCnbrep70000c3", .property_query_freesize = "XCnbrep70000a0", .property_clear_error = "XCnbrep700009d", .property_lookup_encode = "XCnbrep70000b9", .property_unlock_flag = "XCnbrep700009c", .property_lock_flag = "XCnbrep700009b", .property_set_flag = "XCnbrep700009a", .property_part_write_meta = "XCnbrep7000099", .property_part_write_meta2 = "XCnbrep7000098", .property_read_data = "XCnbrep7000096", .property_read_meta = "XCnbrep7000095", .property_get_attribute_u32 = "XCnbrep70000bf", .property_get_attribute_s32 = "XCnbrep70000be", .property_get_fingerprint = "XCnbrep70000c4", .property_node_refdata = "XCnbrep70000a5", .property_insert_read_with_filename = "XCnbrep70000b5", .property_mem_read = "XCnbrep70000b7", .property_read_query_memsize_long = "XCnbrep70000b1", .property_clear = "XCnbrep7000093", .avs_net_add_protocol = "XCnbrep7000077", .avs_net_del_protocol = "XCnbrep7000078", .avs_net_addrinfobyaddr = "XCnbrep7000075", .avs_net_socket = "XCnbrep7000079", .avs_net_setsockopt = "XCnbrep700007a", .avs_net_getsockopt = "XCnbrep700007b", .avs_net_connect = "XCnbrep700007d", .avs_net_send = "XCnbrep7000082", .avs_net_recv = "XCnbrep7000086", .avs_net_poll = "XCnbrep700008a", .avs_net_pollfds_add = "XCnbrep700008c", .avs_net_pollfds_get = "XCnbrep700008d", .avs_net_bind = "XCnbrep700007c", .avs_net_close = "XCnbrep7000080", .avs_net_shutdown = "XCnbrep7000081", .avs_net_get_peername = "XCnbrep700008f", .avs_net_get_sockname = "XCnbrep700008e", }; static constexpr struct avs_core_import IMPORT_AVS21700 { .version = "2.17.0.0", .property_search = "XCgsqzn00000a1", .boot = "XCgsqzn0000129", .shutdown = "XCgsqzn000012a", .property_desc_to_buffer = "XCgsqzn0000092", .property_destroy = "XCgsqzn0000091", .property_read_query_memsize = "XCgsqzn00000b0", .property_create = "XCgsqzn0000090", .property_insert_read = "XCgsqzn0000094", .property_node_create = "XCgsqzn00000a2", .property_node_remove = "XCgsqzn00000a3", .property_node_refer = "XCgsqzn00000af", .std_setenv = "XCgsqzn00000d4", .avs_fs_open = "XCgsqzn000004e", .avs_fs_copy = "XCgsqzn0000065", .avs_fs_close = "XCgsqzn0000055", .avs_fs_dump_mountpoint = "XCgsqzn0000068", .avs_fs_mount = "XCgsqzn000004b", .avs_fs_fstat = "XCgsqzn0000062", .avs_fs_lstat = "XCgsqzn0000063", .avs_fs_lseek = "XCgsqzn000004f", .avs_fs_read = "XCgsqzn0000051", .avs_fs_opendir = "XCgsqzn000005c", .avs_fs_readdir = "XCgsqzn000005d", .avs_fs_closedir = "XCgsqzn000005e", .cstream_create = "XCgsqzn0000130", .cstream_operate = "XCgsqzn0000132", .cstream_finish = "XCgsqzn0000133", .cstream_destroy = "XCgsqzn0000134", .property_node_read = "XCgsqzn00000ab", .property_node_write = "XCgsqzn00000ac", .property_file_write = "XCgsqzn00000b6", .property_node_traversal = "XCgsqzn00000a6", .property_psmap_export = "XCgsqzn00000b3", .property_psmap_import = "XCgsqzn00000b2", .property_node_name = "XCgsqzn00000a7", .property_node_get_desc = "XCgsqzn00000ae", .property_get_error = "XCgsqzn000009e", .property_node_clone = "XCgsqzn00000a4", .property_query_size = "XCgsqzn000009f", .property_node_query_stat = "XCgsqzn00000c5", .property_node_datasize = "XCgsqzn00000aa", .property_mem_write = "XCgsqzn00000b8", .property_part_write = "XCgsqzn0000097", .property_node_absolute_path = "XCgsqzn00000c6", .property_node_has = "XCgsqzn00000ad", .property_node_is_array = "XCgsqzn00000a9", .property_node_type = "XCgsqzn00000a8", .property_get_attribute_bool = "XCgsqzn00000c0", .property_node_get_attribute_bool = "XCgsqzn00000bd", .property_node_get_attribute_u32 = "XCgsqzn00000bc", .property_node_get_attribute_s32 = "XCgsqzn00000bb", .property_node_rename = "XCgsqzn00000c3", .property_query_freesize = "XCgsqzn00000a0", .property_clear_error = "XCgsqzn000009d", .property_lookup_encode = "XCgsqzn00000b9", .property_unlock_flag = "XCgsqzn000009c", .property_lock_flag = "XCgsqzn000009b", .property_set_flag = "XCgsqzn000009a", .property_part_write_meta = "XCgsqzn0000099", .property_part_write_meta2 = "XCgsqzn0000098", .property_read_data = "XCgsqzn0000096", .property_read_meta = "XCgsqzn0000095", .property_get_attribute_u32 = "XCgsqzn00000bf", .property_get_attribute_s32 = "XCgsqzn00000be", .property_get_fingerprint = "XCgsqzn00000c4", .property_node_refdata = "XCgsqzn00000a5", .property_insert_read_with_filename = "XCgsqzn00000b5", .property_mem_read = "XCgsqzn00000b7", .property_read_query_memsize_long = "XCgsqzn00000b1", .property_clear = "XCgsqzn0000093", .avs_net_add_protocol = "XCgsqzn0000077", .avs_net_del_protocol = "XCgsqzn0000078", .avs_net_addrinfobyaddr = "XCgsqzn0000075", .avs_net_socket = "XCgsqzn0000079", .avs_net_setsockopt = "XCgsqzn000007a", .avs_net_getsockopt = "XCgsqzn000007b", .avs_net_connect = "XCgsqzn000007d", .avs_net_send = "XCgsqzn0000082", .avs_net_recv = "XCgsqzn0000086", .avs_net_poll = "XCgsqzn000008a", .avs_net_pollfds_add = "XCgsqzn000008c", .avs_net_pollfds_get = "XCgsqzn000008d", .avs_net_bind = "XCgsqzn000007c", .avs_net_close = "XCgsqzn0000080", .avs_net_shutdown = "XCgsqzn0000081", .avs_net_get_peername = "XCgsqzn000008f", .avs_net_get_sockname = "XCgsqzn000008e", }; static constexpr struct avs_core_import IMPORT_AVS21730 { .version = "2.17.3.0", .property_search = "XCgsqzn00000a1", .boot = "XCgsqzn0000129", .shutdown = "XCgsqzn000012a", .property_desc_to_buffer = "XCgsqzn0000092", .property_destroy = "XCgsqzn0000091", .property_read_query_memsize = "XCgsqzn00000b0", .property_create = "XCgsqzn0000090", .property_insert_read = "XCgsqzn0000094", .property_node_create = "XCgsqzn00000a2", .property_node_remove = "XCgsqzn00000a3", .property_node_refer = "XCgsqzn00000af", .std_setenv = "XCgsqzn00000d4", .avs_fs_open = "XCgsqzn000004e", .avs_fs_copy = "XCgsqzn0000065", .avs_fs_close = "XCgsqzn0000055", .avs_fs_dump_mountpoint = "XCgsqzn0000068", .avs_fs_mount = "XCgsqzn000004b", .avs_fs_fstat = "XCgsqzn0000062", .avs_fs_lstat = "XCgsqzn0000063", .avs_fs_lseek = "XCgsqzn000004f", .avs_fs_read = "XCgsqzn0000051", .avs_fs_opendir = "XCgsqzn000005c", .avs_fs_readdir = "XCgsqzn000005d", .avs_fs_closedir = "XCgsqzn000005e", .cstream_create = "XCgsqzn0000130", .cstream_operate = "XCgsqzn0000132", .cstream_finish = "XCgsqzn0000133", .cstream_destroy = "XCgsqzn0000134", .property_node_read = "XCgsqzn00000ab", .property_node_write = "XCgsqzn00000ac", .property_file_write = "XCgsqzn00000b6", .property_node_traversal = "XCgsqzn00000a6", .property_psmap_export = "XCgsqzn00000b3", .property_psmap_import = "XCgsqzn00000b2", .property_node_name = "XCgsqzn00000a7", .property_node_get_desc = "XCgsqzn00000ae", .property_get_error = "XCgsqzn000009e", .property_node_clone = "XCgsqzn00000a4", .property_query_size = "XCgsqzn000009f", .property_node_query_stat = "XCgsqzn00000c5", .property_node_datasize = "XCgsqzn00000aa", .property_mem_write = "XCgsqzn00000b8", .property_part_write = "XCgsqzn0000097", .property_node_absolute_path = "XCgsqzn00000c6", .property_node_has = "XCgsqzn00000ad", .property_node_is_array = "XCgsqzn00000a9", .property_node_type = "XCgsqzn00000a8", .property_get_attribute_bool = "XCgsqzn00000c0", .property_node_get_attribute_bool = "XCgsqzn00000bd", .property_node_get_attribute_u32 = "XCgsqzn00000bc", .property_node_get_attribute_s32 = "XCgsqzn00000bb", .property_node_rename = "XCgsqzn00000c3", .property_query_freesize = "XCgsqzn00000a0", .property_clear_error = "XCgsqzn000009d", .property_lookup_encode = "XCgsqzn00000b9", .property_unlock_flag = "XCgsqzn000009c", .property_lock_flag = "XCgsqzn000009b", .property_set_flag = "XCgsqzn000009a", .property_part_write_meta = "XCgsqzn0000099", .property_part_write_meta2 = "XCgsqzn0000098", .property_read_data = "XCgsqzn0000096", .property_read_meta = "XCgsqzn0000095", .property_get_attribute_u32 = "XCgsqzn00000bf", .property_get_attribute_s32 = "XCgsqzn00000be", .property_get_fingerprint = "XCgsqzn00000c4", .property_node_refdata = "XCgsqzn00000a5", .property_insert_read_with_filename = "XCgsqzn00000b5", .property_mem_read = "XCgsqzn00000b7", .property_read_query_memsize_long = "XCgsqzn00000b1", .property_clear = "XCgsqzn0000093", .avs_net_add_protocol = "XCgsqzn0000077", .avs_net_del_protocol = "XCgsqzn0000078", .avs_net_addrinfobyaddr = "XCgsqzn0000075", .avs_net_socket = "XCgsqzn0000079", .avs_net_setsockopt = "XCgsqzn000007a", .avs_net_getsockopt = "XCgsqzn000007b", .avs_net_connect = "XCgsqzn000007d", .avs_net_send = "XCgsqzn0000082", .avs_net_recv = "XCgsqzn0000086", .avs_net_poll = "XCgsqzn000008a", .avs_net_pollfds_add = "XCgsqzn000008c", .avs_net_pollfds_get = "XCgsqzn000008d", .avs_net_bind = "XCgsqzn000007c", .avs_net_close = "XCgsqzn0000080", .avs_net_shutdown = "XCgsqzn0000081", .avs_net_get_peername = "XCgsqzn000008f", .avs_net_get_sockname = "XCgsqzn000008e", }; static const struct avs_core_import IMPORTS[AVS_VERSION_COUNT] = { IMPORT_LEGACY, IMPORT_AVS21360, IMPORT_AVS21430, IMPORT_AVS21580, IMPORT_AVS21610, IMPORT_AVS21630, IMPORT_AVS21651, IMPORT_AVS21671, IMPORT_AVS21681, IMPORT_AVS21700, IMPORT_AVS21730, }; static const robin_hood::unordered_map HEAP_SIZE_DEFAULTS = { #ifdef SPICE64 // beatmania IIDX 25 {"bm2dx.dll", 0x8000000}, // SOUND VOLTEX {"soundvoltex.dll", 0x10000000}, #endif // jubeat {"jubeat.dll", 0x2000000}, // MUSECA {"museca.dll", 0xC000000}, // DDR ACE/A20 {"arkmdxbio2.dll", 0x2000000}, {"arkmdxp3.dll", 0x2000000}, {"arkmdxp4.dll", 0x2000000}, // Nostalgia {"nostalgia.dll", 0x8000000}, // Bishi Bashi Channel {"bsch.dll", 0xC000000}, // Quiz Magic Academy {"client.dll", 70000000}, // Mahjong Fight Club {"system.dll", 0x2000000}, // FutureTomTom {"arkmmd.dll", 0x22800000}, // HELLO! Pop'n Music {"popn.dll", 0x1E00000}, // Scotto {"scotto.dll", 160000000}, // TsumTsum {"arko26.dll", 0x1E00000}, // DANCERUSH {"superstep.dll", 0x18000000}, // Winning Eleven 2012 {"weac12_bootstrap_release.dll", 0x1E00000}, // Winning Eleven 2014 {"arknck.dll", 0x1E00000}, // Otoca D'or {"arkkep.dll", 0x8000000}, // Silent Scope: Bone Eater {"arkndd.dll", 0x1E00000}, // Metal Gear Arcade {"launch.dll", 0x800000}, // Ongaku Paradise {"arkjc9.dll", 0xA00000}, // KAMUNITY {"kamunity.dll", 33554432}, }; // apply a default heap size based on the game DLL name provided void set_default_heap_size(const std::string &dll_name) { // initialize the heap size with the default once if (DEFAULT_HEAP_SIZE_SET) { return; } if (HEAP_SIZE_DEFAULTS.find(dll_name) != HEAP_SIZE_DEFAULTS.end()) { auto old_size = HEAP_SIZE; HEAP_SIZE = HEAP_SIZE_DEFAULTS.at(dll_name); DEFAULT_HEAP_SIZE_SET = true; log_info("avs-core", "updated heap size: {} -> {}", old_size, avs::core::HEAP_SIZE); } } /* * Helpers */ static BOOL output_callback(const char *buf, DWORD size, HANDLE file) { // check size if (size == 0) { return TRUE; } // state machine for parsing style and converting to CRLF // this is needed because newer AVS buffers multiple lines unlike the old callback static logger::Style last_style = logger::Style::DEFAULT; static logger::Style new_style = last_style; static size_t position = 0; for (size_t i = 0; i < size; i++) { switch (position) { case 0: { if (buf[i] == ']') position++; else position = 0; break; } case 1: { if (buf[i] == ' ') position++; else position = 0; break; } case 2: { switch (buf[i]) { case 'M': new_style = logger::Style::GREY; break; case 'I': new_style = logger::Style::DEFAULT; break; case 'W': new_style = logger::Style::YELLOW; break; case 'F': new_style = logger::Style::RED; break; default: position = 0; break; } if (position > 0) position++; break; } case 3: { position = 0; if (buf[i] == ':') { last_style = new_style; // flush line for (size_t j = i + 1; j < size; j++) { if (buf[j] == '\n') { logger::push(std::string(buf, j), last_style, true); buf = &buf[j + 1]; size -= j + 1; i = 0; break; } } } break; } default: position = 0; break; } } // push rest to logger if (size > 1) { logger::push(std::string(buf, size - 1), last_style, true); } // success return TRUE; } static BOOL output_callback_old(HANDLE file, const char *buf, DWORD size) { // check size if (size == 0) { return TRUE; } std::string out; // prefix if (buf[0] != '[') { out += log_get_datetime(); out += " "; } // message out += std::string_view(buf, size - 1); // style logger::Style style = logger::Style::DEFAULT; switch (buf[0]) { case 'M': style = logger::Style::GREY; break; case 'F': style = logger::Style::RED; break; case 'W': style = logger::Style::YELLOW; break; } // push to logger logger::push(std::move(out), style); // success return TRUE; } static int avs_property_read_callback(uint32_t context, void *dst_buf, size_t count) { auto file = reinterpret_cast(TlsGetValue(context)); return fread(dst_buf, 1, count, file); } property_ptr config_read(const std::string &filename, const size_t extra_space, const bool allow_fail) { // open file FILE *file = fopen(filename.c_str(), "rb"); if (file == nullptr) { log_fatal("avs-core", "failed to open config file ({}): {}", filename, get_last_error_string()); } // store handle in tls uint32_t tls = TlsAlloc(); TlsSetValue(tls, file); // get file size int property_read_size = property_read_query_memsize(avs_property_read_callback, tls, 0, 0); if (property_read_size <= 0) { if (allow_fail) { return nullptr; } else { log_fatal("avs-core", "failed to read config file ({}): 0x{:x}", filename, static_cast(property_read_size)); } } // add extra size (to be able to create new nodes, AVS does not resize properties // after initial allocation) property_read_size += extra_space; // allocate memory auto buffer = malloc(property_read_size); auto property = property_create(23, buffer, property_read_size); if (property == nullptr) { log_fatal("avs-core", "cannot create property: {}", filename); } // rewind file rewind(file); // read file contents if (property_insert_read(property, 0, avs_property_read_callback, tls) == 0) { log_fatal("avs-core", "cannot read property: {}", filename); } // clean up TlsFree(tls); fclose(file); // error checking if (avs::core::property_get_error) { auto err = avs::core::property_get_error(property); if (err > 0) { log_fatal("avs-core", "failed to read config file ({}): {}", filename, error_str(err)); } } // return value return property; } static int avs_property_read_string_callback(uint32_t context, void *dst_buf, size_t count) { auto input = reinterpret_cast(TlsGetValue(context)); memcpy(dst_buf, input, count); return count; } property_ptr config_read_string(const char *input) { // open tls store to hold pointer to input uint32_t tls = TlsAlloc(); TlsSetValue(tls, const_cast(input)); // get input size int property_read_size = property_read_query_memsize( avs_property_read_string_callback, tls, 0, 0); // check file size if (property_read_size <= 0) { log_fatal("avs-core", "failed to reading config string: 0x{:x}", static_cast(property_read_size)); } // add extra size (to be able to create new nodes, AVS does not resize properties // after initial allocation) property_read_size += 1024; // allocate memory auto buffer = malloc(property_read_size); auto property = property_create(23, buffer, property_read_size); if (property == nullptr) { log_fatal("avs-core", "cannot create property"); } // read string if (property_insert_read(property, 0, avs_property_read_string_callback, tls) == 0) { log_fatal("avs-core", "cannot read property"); } // clean up TlsFree(tls); // return value return property; } node_ptr property_search_safe(property_ptr prop, node_ptr node, const char *name) { auto property = property_search(prop, node, name); if (property == nullptr) { log_fatal("avs-core", "node not found: {}", name); } return property; } void property_search_remove_safe(property_ptr prop, node_ptr node, const char *name) { auto prop_node = property_search(prop, node, name); if (prop_node == nullptr) { return; } property_node_remove(prop_node); } bool file_exists(const char *filename) { struct avs::core::avs_stat stat {}; return avs_fs_lstat(filename, &stat) != 0; } void config_destroy(property_ptr prop) { void *mem = property_desc_to_buffer(prop); property_destroy(prop); free(mem); } /* * Functions */ void create_log() { // set log path LOG_PATH = LOG_PATH.size() > 0 ? LOG_PATH : "log.txt"; // create log file LOG_FILE = CreateFileA( LOG_PATH.c_str(), GENERIC_WRITE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, 0, nullptr ); // remember actually used path if (LOG_FILE != INVALID_HANDLE_VALUE) { LOG_FILE_PATH = LOG_PATH; } } bool load_dll() { log_info("avs-core", "loading DLL"); // detect DLL name if (fileutils::file_exists(MODULE_PATH / "avs2-core.dll")) { DLL_NAME = "avs2-core.dll"; } else { #ifdef SPICE64 DLL_NAME = "libavs-win64.dll"; #else DLL_NAME = "libavs-win32.dll"; #endif } // load library DLL_INSTANCE = libutils::load_library(MODULE_PATH / DLL_NAME, false); if (!DLL_INSTANCE) { return false; } // check by version string if obtained char version[32] {}; intptr_t ver = -1; if (fileutils::version_pe(MODULE_PATH / DLL_NAME, version)) { log_misc("avs-core", "version string: {}", version); for (size_t i = 0; i < AVS_VERSION_COUNT; i++) { if (strcmp(IMPORTS[i].version, version) == 0) { ver = i; break; } } } // check version by brute force if (ver < 0) { for (size_t i = 0; i < AVS_VERSION_COUNT; i++) { if (GetProcAddress(DLL_INSTANCE, IMPORTS[i].property_search) != nullptr) { ver = i; break; } } } // check if version was found if (ver < 0) { log_fatal("avs-core", "Unknown {}", DLL_NAME); } // print version VERSION = (avs::core::Version) ver; VERSION_STR = IMPORTS[ver].version; log_info("avs-core", "Found AVS2 core {}", IMPORTS[ver].version); // load functions avs::core::IMPORT_NAMES = IMPORTS[ver]; avs215_boot = libutils::get_proc( DLL_INSTANCE, IMPORTS[ver].boot); avs216_boot = libutils::get_proc( DLL_INSTANCE, IMPORTS[ver].boot); avs_shutdown = libutils::get_proc( DLL_INSTANCE, IMPORTS[ver].shutdown); property_node_create = libutils::get_proc( DLL_INSTANCE, IMPORTS[ver].property_node_create); property_desc_to_buffer = libutils::get_proc( DLL_INSTANCE, IMPORTS[ver].property_desc_to_buffer); property_destroy = libutils::get_proc( DLL_INSTANCE, IMPORTS[ver].property_destroy); property_create = libutils::get_proc( DLL_INSTANCE, IMPORTS[ver].property_create); property_insert_read = libutils::get_proc( DLL_INSTANCE, IMPORTS[ver].property_insert_read); property_node_refer = libutils::get_proc( DLL_INSTANCE, IMPORTS[ver].property_node_refer); property_node_remove = libutils::get_proc( DLL_INSTANCE, IMPORTS[ver].property_node_remove); property_read_query_memsize = libutils::get_proc( DLL_INSTANCE, IMPORTS[ver].property_read_query_memsize); property_search = libutils::get_proc( DLL_INSTANCE, IMPORTS[ver].property_search); avs_std_setenv = libutils::get_proc( DLL_INSTANCE, IMPORTS[ver].std_setenv); avs_fs_open = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_fs_open); avs_fs_copy = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_fs_copy); avs_fs_close = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_fs_close); avs_fs_dump_mountpoint = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_fs_dump_mountpoint); avs_fs_mount = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_fs_mount); avs_fs_lstat = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_fs_lstat); // optional functions avs_fs_fstat = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_fs_fstat); avs_fs_lseek = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_fs_lseek); avs_fs_read = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_fs_read); avs_fs_opendir = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_fs_opendir); avs_fs_readdir = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_fs_readdir); avs_fs_closedir = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_fs_closedir); cstream_create = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].cstream_create); cstream_operate = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].cstream_operate); cstream_finish = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].cstream_finish); cstream_destroy = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].cstream_destroy); property_node_read = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_read); property_node_write = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_write); property_file_write = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_file_write); property_node_traversal = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_traversal); property_psmap_export = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_psmap_export); property_psmap_import = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_psmap_import); property_node_name = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_name); property_node_get_desc = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_get_desc); property_get_error = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_get_error); property_node_clone = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_clone); property_query_size = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_query_size); property_node_query_stat = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_query_stat); property_node_datasize = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_datasize); property_mem_write = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_mem_write); property_part_write = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_part_write); property_node_absolute_path = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_absolute_path); property_node_has = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_has); property_node_is_array = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_is_array); property_node_type = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_type); property_get_attribute_bool = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_get_attribute_bool); property_node_get_attribute_bool = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_get_attribute_bool); property_node_get_attribute_u32 = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_get_attribute_u32); property_node_get_attribute_s32 = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_get_attribute_s32); property_node_rename = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_rename); property_query_freesize = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_query_freesize); property_clear_error = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_clear_error); property_lookup_encode = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_lookup_encode); property_unlock_flag = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_unlock_flag); property_lock_flag = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_lock_flag); property_set_flag = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_set_flag); property_part_write_meta = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_part_write_meta); property_part_write_meta2 = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_part_write_meta2); property_read_data = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_read_data); property_read_meta = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_read_meta); property_get_attribute_u32 = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_get_attribute_u32); property_get_attribute_s32 = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_get_attribute_s32); property_get_fingerprint = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_get_fingerprint); property_node_refdata = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_node_refdata); property_insert_read_with_filename = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_insert_read_with_filename); property_mem_read = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_mem_read); property_read_query_memsize_long = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_read_query_memsize_long); property_clear = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].property_clear); avs_net_socket = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_socket); avs_net_setsockopt = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_setsockopt); avs_net_getsockopt = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_getsockopt); avs_net_connect = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_connect); avs_net_send = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_send); avs_net_recv = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_recv); avs_net_poll = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_poll); avs_net_pollfds_add = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_pollfds_add); avs_net_pollfds_get = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_pollfds_get); avs_net_add_protocol = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_add_protocol); avs_net_add_protocol_legacy = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_add_protocol); avs_net_del_protocol = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_del_protocol); avs_net_addrinfobyaddr = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_addrinfobyaddr); avs_net_bind = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_bind); avs_net_close = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_close); avs_net_shutdown = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_shutdown); avs_net_get_peername = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_get_peername); avs_net_get_sockname = libutils::try_proc( DLL_INSTANCE, IMPORTS[ver].avs_net_get_sockname); if (property_node_read) { log_misc("avs-core", "optional functions identified"); } // success return true; } static void create_dir( const std::string_view &avs_path, const std::string_view &src_path) { std::error_code err; auto real_path = std::filesystem::absolute(src_path, err); if (err) { log_warning("avs-core", "failed to resolve '{}' path: {}", avs_path, err.message()); return; } auto created = std::filesystem::create_directories(real_path, err); if (created) { log_info("avs-core", "created '{}' at '{}'", avs_path, real_path.string()); } if (err) { log_warning("avs-core", "failed to create '{}' folder at '{}': {}", avs_path, real_path.string(), err.message()); } } static void create_avs_config_fs_dir( struct property_info *prop, struct node_info *node, const char *folder_name) { char device_path[2048] { 0 }; char fs_type[255] { 0 }; auto avs_path = fmt::format("dev/{}", folder_name); auto base_node_path = fmt::format("/fs/{}", folder_name); auto fs_node = property_search(prop, node, base_node_path.c_str()); if (!fs_node) { return; } // check for `fstype` node, AVS defaults to the `nvram` fs if the `fstype` is unset auto fs_type_exists = property_search(prop, fs_node, "fstype") != nullptr; auto device_result = property_node_refer(prop, fs_node, "device", NODE_TYPE_str, device_path, sizeof(device_path)); auto fs_type_result = 0; if (device_result < 0) { log_warning("avs-core", "failed to get '{}/device' string value: 0x{:08x}", base_node_path, static_cast(device_result)); } if (fs_type_exists) { fs_type_result = property_node_refer(prop, fs_node, "fstype", NODE_TYPE_str, fs_type, sizeof(fs_type)); if (fs_type_result < 0) { log_warning("avs-core", "failed to get '{}/fstype' string value: 0x{:08x}", base_node_path, static_cast(fs_type_result)); } else { // only support 'fs' and 'nvram' fs types if (_stricmp(fs_type, "fs") != 0 && _stricmp(fs_type, "nvram") != 0) { log_misc("avs-core", "ignoring folder creation for '{}': unsupported fs type '{}'", avs_path, fs_type); return; } } } if (device_result < 0 || fs_type_result < 0) { return; } create_dir(avs_path, device_path); } static void create_avs_config_fs_table( struct property_info *prop, struct node_info *node) { char fs_type[255] { 0 }; char src_path[2048] { 0 }; char dst_path[2048] { 0 }; auto table_node = property_search(prop, node, "/fs/mounttable"); if (!table_node) { return; } auto vfs_node = property_search(prop, table_node, "vfs"); if (!vfs_node) { return; } do { auto fs_type_result = property_node_refer(prop, vfs_node, "fstype@", NODE_TYPE_attr, fs_type, sizeof(fs_type)); auto src_result = property_node_refer(prop, vfs_node, "src@", NODE_TYPE_attr, src_path, sizeof(src_path)); auto dst_result = property_node_refer(prop, vfs_node, "dst@", NODE_TYPE_attr, dst_path, sizeof(dst_path)); if (fs_type_result < 0) { log_warning("avs-core", "failed to get 'fs_type' string value: 0x{:08x}", static_cast(fs_type_result)); } if (src_result < 0) { log_warning("avs-core", "failed to get 'src' string value: 0x{:08x}", static_cast(src_result)); } if (dst_result < 0) { log_warning("avs-core", "failed to get 'dst' string value: 0x{:08x}", static_cast(dst_result)); } if (fs_type_result < 0 || src_result < 0 || dst_result < 0) { continue; } // only support 'fs' and 'nvram' fs types if (_stricmp(fs_type, "fs") != 0 && _stricmp(fs_type, "nvram") != 0) { log_misc("avs-core", "ignoring folder creation for '{}': unsupported fs type '{}'", dst_path, fs_type); continue; } create_dir(dst_path, src_path); } while ((vfs_node = property_node_traversal(vfs_node, TRAVERSE_NEXT_SEARCH_RESULT))); } void boot() { // default config path CFG_PATH = !CFG_PATH.empty() ? CFG_PATH : "prop/avs-config.xml"; log_info("avs-core", "booting (using {})", CFG_PATH); // read configuration auto config = config_read(CFG_PATH); auto config_node = property_search_safe(config, nullptr, "/config"); // create nvram and raw directories if possible for non-mounttable configurations create_avs_config_fs_dir(config, config_node, "nvram"); create_avs_config_fs_dir(config, config_node, "raw"); // create nvram and raw directories if possible for mounttable configurations create_avs_config_fs_table(config, config_node); // set log level if (!LOG_LEVEL_CUSTOM.empty()) { property_search_remove_safe(config, config_node, "/log/level"); if (VERSION == AVS21360 || VERSION == AVSLEGACY) { uint32_t log_level = 0; if (LOG_LEVEL_CUSTOM == "disable") { log_level = 0; } else if (LOG_LEVEL_CUSTOM == "fatal") { log_level = 1; } else if (LOG_LEVEL_CUSTOM == "warning") { log_level = 2; } else if (LOG_LEVEL_CUSTOM == "info") { log_level = 3; } else if (LOG_LEVEL_CUSTOM == "misc") { log_level = 4; } else if (LOG_LEVEL_CUSTOM == "all") { log_level = 5; } property_node_create(config, config_node, NODE_TYPE_u32, "/log/level", log_level); } else { property_node_create(config, config_node, NODE_TYPE_str, "/log/level", LOG_LEVEL_CUSTOM.c_str()); } } // print log level static const char *LOG_LEVELS[] = { "disable", "fatal", "warning", "info", "misc", "all" }; char current_log_level_buffer[32] { 0 }; uint32_t current_log_level = 0; if (VERSION == AVSLEGACY || VERSION == AVS21360) { auto level_node = property_search(config, config_node, "/log/level"); // set the log level to `misc` if one is not present if (!level_node) { level_node = property_node_create(config, config_node, NODE_TYPE_u32, "/log/level", 4); } // print the log level, if successfully retrieved if (property_node_refer(config, config_node, "/log/level", NODE_TYPE_u32, ¤t_log_level, sizeof(current_log_level)) > 0) { if (current_log_level < std::size(LOG_LEVELS)) { log_info("avs-core", "log level: {}", LOG_LEVELS[current_log_level]); } else { log_fatal("avs-core", "log level ({}) is invalid!", current_log_level); } } else { log_warning("avs-core", "log level: unknown"); } } else { auto level_node = property_search(config, config_node, "/log/level"); // convert old-style number log levels to new-style string log levels if (level_node && property_node_type && property_node_type(level_node) == NODE_TYPE_u32) { property_node_refer(config, config_node, "/log/level", NODE_TYPE_u32, ¤t_log_level, sizeof(current_log_level)); if (current_log_level < std::size(LOG_LEVELS)) { property_node_remove(level_node); level_node = property_node_create(config, config_node, NODE_TYPE_str, "/log/level", LOG_LEVELS[current_log_level]); } else { log_fatal("avs-core", "log level ({}) is invalid!", current_log_level); } } // set the log level to `misc` if one is not present if (!level_node) { level_node = property_node_create(config, config_node, NODE_TYPE_str, "/log/level", "misc"); } // print the log level, if successfully retrieved if (property_node_refer(config, config_node, "/log/level", NODE_TYPE_str, current_log_level_buffer, sizeof(current_log_level_buffer)) > 0) { log_info("avs-core", "log level: {}", current_log_level_buffer); } else { log_warning("avs-core", "log level: unknown"); } } // fix time offset auto t_now = std::time(nullptr); auto tm_now = *std::gmtime(&t_now); auto gmt = mktime(&tm_now); property_search_remove_safe(config, config_node, "/time/gmt_offset"); property_node_create(config, config_node, NODE_TYPE_s32, "/time/gmt_offset", t_now - gmt); // use system time server property_search_remove_safe(config, config_node, "/sntp/ea_on"); property_node_create(config, config_node, NODE_TYPE_bool, "/sntp/ea_on", 0); // check heap size if (HEAP_SIZE <= 0) { log_fatal("avs-core", "invalid heap size (<= 0)"); } log_misc("avs-core", "using heap size: {}", HEAP_SIZE); // initialize avs switch (VERSION) { case AVS21430: case AVS21580: { AVS_HEAP1 = malloc(HEAP_SIZE); if (!AVS_HEAP1) { log_warning("avs-core", "could not allocate heap 1"); } AVS_HEAP2 = malloc(HEAP_SIZE); if (!AVS_HEAP2) { log_warning("avs-core", "could not allocate heap 2"); } avs215_boot(config_node, AVS_HEAP1, HEAP_SIZE, AVS_HEAP2, HEAP_SIZE, (void *) &output_callback, LOG_FILE); break; } case AVS21610: case AVS21630: case AVS21651: case AVS21671: case AVS21681: case AVS21700: case AVS21730: { AVS_HEAP1 = malloc(HEAP_SIZE); if (!AVS_HEAP1) log_warning("avs-core", "could not allocate heap 1"); avs216_boot(config_node, AVS_HEAP1, HEAP_SIZE, nullptr, (void *) &output_callback, LOG_FILE); break; } case AVS21360: case AVSLEGACY: { AVS_HEAP1 = malloc(HEAP_SIZE); if (!AVS_HEAP1) { log_warning("avs-core", "could not allocate heap 1"); } AVS_HEAP2 = malloc(HEAP_SIZE); if (!AVS_HEAP2) { log_warning("avs-core", "could not allocate heap 2"); } avs215_boot(config_node, AVS_HEAP1, HEAP_SIZE, AVS_HEAP2, HEAP_SIZE, (void *) &output_callback_old, LOG_FILE); break; } default: log_fatal("avs-core", "unknown AVS boot procedure"); } // wait a bit for output Sleep(100); // destroy config config_destroy(config); } void copy_defaults() { static robin_hood::unordered_map> NVRAM_DEFAULTS { { "ea3-config.xml", std::nullopt }, { "eamuse-config.xml", "ea3-config.xml" }, { "ea3-cfg.xml", "ea3-config.xml" }, { "eacoin.xml", std::nullopt }, { "coin.xml", std::nullopt }, { "testmode-v.xml", std::nullopt }, }; for (auto &[prop_name, nvram_name] : NVRAM_DEFAULTS) { auto nvram = fmt::format("/dev/nvram/{}", nvram_name.has_value() ? nvram_name.value() : prop_name); // file not found in nvram if (!file_exists(nvram.c_str())) { auto prop = fmt::format("/prop/defaults/{}", prop_name); if (!file_exists(prop.c_str())) { prop = fmt::format("/prop/{}", prop_name); if (!file_exists(prop.c_str())) { continue; } } log_info("avs-core", "copying {} to {}", prop, nvram); avs_fs_copy(prop.c_str(), nvram.c_str()); } } } void shutdown() { log_info("avs-core", "shutdown"); // call shutdown avs_shutdown(); // clean heaps if (AVS_HEAP1) { free(AVS_HEAP1); AVS_HEAP1 = nullptr; } if (AVS_HEAP2) { free(AVS_HEAP2); AVS_HEAP2 = nullptr; } } const static struct { uint32_t error; const char* msg; } ERROR_LIST[] = { { 0x80092000, "invalid type" }, { 0x80092001, "type cannot use as array" }, { 0x80092002, "invalid" }, { 0x80092003, "too large data size" }, { 0x80092004, "too small buffer size" }, { 0x80092005, "passcode 0 is not allowed" }, { 0x80092040, "invalid node name" }, { 0x80092041, "invalid attribute name" }, { 0x80092042, "reserved attribute name" }, { 0x80092043, "cannot find node/attribute" }, { 0x80092080, "cannot allocate node" }, { 0x80092081, "cannot allocate node value" }, { 0x80092082, "cannot allocate mdigest for finger-print" }, { 0x80092083, "cannot allocate nodename" }, { 0x800920C0, "node type differs" }, { 0x800920C1, "node type is VOID" }, { 0x800920C2, "node is array" }, { 0x800920C3, "node is not array" }, { 0x80092100, "node is create-disabled" }, { 0x80092101, "node is read-disabled" }, { 0x80092102, "node is write-disabled" }, { 0x80092103, "flag is already locked" }, { 0x80092104, "passcode differs" }, { 0x80092105, "insert_read() is applied to attribute" }, { 0x80092106, "part_write() is applied to attribute" }, { 0x80092107, "MODE_EXTEND flag differs" }, { 0x80092140, "root node already exists" }, { 0x80092141, "attribute cannot have children" }, { 0x80092142, "node/attribute already exists" }, { 0x80092143, "number of nodes exceeds 65535" }, { 0x80092144, "cannot interpret as number" }, { 0x80092145, "property is empty" }, { 0x80092180, "I/O error" }, { 0x80092181, "unexpected EOF" }, { 0x80092182, "unknown format" }, { 0x800921C0, "broken magic" }, { 0x800921C1, "broken metadata" }, { 0x800921C2, "broken databody" }, { 0x800921C3, "invalid type" }, { 0x800921C4, "too large data size" }, { 0x800921C5, "too long node/attribute name" }, { 0x800921C6, "attribute name is too long" }, { 0x800921C7, "node/attribute already exists" }, { 0x80092200, "invalid encoding" }, { 0x80092201, "invalid XML token" }, { 0x80092202, "XML syntax error" }, { 0x80092203, "start tag / end tag mismatch" }, { 0x80092204, "too large node data (__size mismatch)" }, { 0x80092205, "too deep node tree" }, { 0x80092206, "invalid type" }, { 0x80092207, "invalid size" }, { 0x80092208, "invalid count" }, { 0x80092209, "invalid value" }, { 0x8009220A, "invalid node name" }, { 0x8009220B, "invalid attribute name" }, { 0x8009220C, "reserved attribute name" }, { 0x8009220D, "node/attribute already exists" }, { 0x8009220E, "too many elements in node data" }, { 0x80092240, "JSON syntax error" }, { 0x80092241, "invalid JSON literal" }, { 0x80092242, "invalid JSON number" }, { 0x80092243, "invalid JSON string" }, { 0x80092244, "invalid JSON object name" }, { 0x80092245, "object name already exists" }, { 0x80092246, "too long JSON object name" }, { 0x80092247, "too deep JSON object/array nesting" }, { 0x80092248, "cannot convert JSON array to property" }, { 0x80092249, "cannot convert empty JSON object to property" }, { 0x8009224A, "root node already exists" }, { 0x8009224B, "cannot convert root node to TYPE_ARRAY" }, { 0x8009224C, "name represents reserved attribute" }, { 0x80092280, "finger-print differs" }, { 0x800922C0, "operation is not supported" }, }; std::string error_str(int32_t error) { for (auto &e : ERROR_LIST) { if (e.error == (uint32_t) error) { return e.msg; } } return fmt::format("unknown ({})", error); } } }