diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def index 9ffa5f81..f7351891 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def @@ -1603,6 +1603,7 @@ module = { module = { name = ventoy; common = ventoy/ventoy.c; + common = ventoy/ventoy_cmd.c; common = ventoy/ventoy_linux.c; common = ventoy/ventoy_unix.c; common = ventoy/ventoy_windows.c; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c index e10985e8..14dae6e0 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c @@ -31,113 +31,18 @@ #include #include #include -#include #include #include #include -#ifdef GRUB_MACHINE_EFI -#include -#include -#endif #include -#include -#include -#include -#include -#include #include #include "ventoy_def.h" -#include "miniz.h" GRUB_MOD_LICENSE ("GPLv3+"); int g_ventoy_debug = 0; static int g_efi_os = 0xFF; -initrd_info *g_initrd_img_list = NULL; -initrd_info *g_initrd_img_tail = NULL; -int g_initrd_img_count = 0; -int g_valid_initrd_count = 0; -int g_default_menu_mode = 0; -int g_filt_dot_underscore_file = 0; -int g_sort_case_sensitive = 0; -int g_tree_view_menu_style = 0; -static grub_file_t g_old_file; -static int g_ventoy_last_entry_back; -static grub_uint32_t g_ventoy_plat_data; - -char g_iso_path[256]; -char g_img_swap_tmp_buf[1024]; -img_info g_img_swap_tmp; -img_info *g_ventoy_img_list = NULL; - -int g_ventoy_img_count = 0; - -grub_device_t g_enum_dev = NULL; -grub_fs_t g_enum_fs = NULL; -int g_img_max_search_level = -1; -img_iterator_node g_img_iterator_head; -img_iterator_node *g_img_iterator_tail = NULL; - -grub_uint8_t g_ventoy_break_level = 0; -grub_uint8_t g_ventoy_debug_level = 0; -grub_uint8_t g_ventoy_chain_type = 0; - -grub_uint8_t *g_ventoy_cpio_buf = NULL; -grub_uint32_t g_ventoy_cpio_size = 0; -cpio_newc_header *g_ventoy_initrd_head = NULL; -grub_uint8_t *g_ventoy_runtime_buf = NULL; - -int g_plugin_image_list = 0; - -ventoy_grub_param *g_grub_param = NULL; - -ventoy_guid g_ventoy_guid = VENTOY_GUID; - -ventoy_img_chunk_list g_img_chunk_list; - -int g_wimboot_enable = 0; -ventoy_img_chunk_list g_wimiso_chunk_list; -char *g_wimiso_path = NULL; - -int g_vhdboot_enable = 0; - -grub_uint64_t g_conf_replace_offset = 0; -grub_uint64_t g_svd_replace_offset = 0; -conf_replace *g_conf_replace_node = NULL; -grub_uint8_t *g_conf_replace_new_buf = NULL; -int g_conf_replace_new_len = 0; -int g_conf_replace_new_len_align = 0; - -ventoy_gpt_info *g_ventoy_part_info = NULL; -grub_uint64_t g_ventoy_disk_size = 0; - -static char *g_tree_script_buf = NULL; -static int g_tree_script_pos = 0; - -static char *g_list_script_buf = NULL; -static int g_list_script_pos = 0; - -static char *g_part_list_buf = NULL; -static int g_part_list_pos = 0; - -static int g_video_mode_max = 0; -static int g_video_mode_num = 0; -static ventoy_video_mode *g_video_mode_list = NULL; - -static int g_enumerate_time_checked = 0; -static grub_uint64_t g_enumerate_start_time_ms; -static grub_uint64_t g_enumerate_finish_time_ms; -static int g_vtoy_file_flt[VTOY_FILE_FLT_BUTT] = {0}; - -static const char *g_menu_class[] = -{ - "vtoyiso", "vtoywim", "vtoyefi", "vtoyimg", "vtoyvhd", "vtoyvtoy" -}; - -static const char *g_menu_prefix[] = -{ - "iso", "wim", "efi", "img", "vhd", "vtoy" -}; +grub_uint32_t g_ventoy_plat_data; void ventoy_debug(const char *fmt, ...) { @@ -179,7 +84,6 @@ int ventoy_strncmp (const char *pattern, const char *str, grub_size_t n) return (int)(grub_uint8_t)*pattern - (int)(grub_uint8_t)*str; } - void ventoy_debug_dump_guid(const char *prefix, grub_uint8_t *guid) { int i; @@ -207,4366 +111,46 @@ int ventoy_is_efi_os(void) return g_efi_os; } -static int ventoy_get_fs_type(const char *fs) -{ - if (NULL == fs) - { - return ventoy_fs_max; - } - else if (grub_strncmp(fs, "exfat", 5) == 0) - { - return ventoy_fs_exfat; - } - else if (grub_strncmp(fs, "ntfs", 4) == 0) - { - return ventoy_fs_ntfs; - } - else if (grub_strncmp(fs, "ext", 3) == 0) - { - return ventoy_fs_ext; - } - else if (grub_strncmp(fs, "xfs", 3) == 0) - { - return ventoy_fs_xfs; - } - else if (grub_strncmp(fs, "udf", 3) == 0) - { - return ventoy_fs_udf; - } - else if (grub_strncmp(fs, "fat", 3) == 0) - { - return ventoy_fs_fat; - } - - return ventoy_fs_max; -} - -static int ventoy_string_check(const char *str, grub_char_check_func check) -{ - if (!str) - { - return 0; - } - - for ( ; *str; str++) - { - if (!check(*str)) - { - return 0; - } - } - - return 1; -} - - -static grub_ssize_t ventoy_fs_read(grub_file_t file, char *buf, grub_size_t len) -{ - grub_memcpy(buf, (char *)file->data + file->offset, len); - return len; -} - -static int ventoy_control_get_flag(const char *key) -{ - const char *val = ventoy_get_env(key); - - if (val && val[0] == '1' && val[1] == 0) - { - return 1; - } - return 0; -} - -static grub_err_t ventoy_fs_close(grub_file_t file) -{ - grub_file_close(g_old_file); - grub_free(file->data); - - file->device = 0; - file->name = 0; - - return 0; -} - -static int ventoy_video_hook(const struct grub_video_mode_info *info, void *hook_arg) -{ - int i; - - (void)hook_arg; - - if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT) - { - return 0; - } - - for (i = 0; i < g_video_mode_num; i++) - { - if (g_video_mode_list[i].width == info->width && - g_video_mode_list[i].height == info->height && - g_video_mode_list[i].bpp == info->bpp) - { - return 0; - } - } - - g_video_mode_list[g_video_mode_num].width = info->width; - g_video_mode_list[g_video_mode_num].height = info->height; - g_video_mode_list[g_video_mode_num].bpp = info->bpp; - g_video_mode_num++; - - if (g_video_mode_num == g_video_mode_max) - { - g_video_mode_max *= 2; - g_video_mode_list = grub_realloc(g_video_mode_list, g_video_mode_max * sizeof(ventoy_video_mode)); - } - - return 0; -} - -static int ventoy_video_mode_cmp(ventoy_video_mode *v1, ventoy_video_mode *v2) -{ - if (v1->bpp == v2->bpp) - { - if (v1->width == v2->width) - { - if (v1->height == v2->height) - { - return 0; - } - else - { - return (v1->height < v2->height) ? -1 : 1; - } - } - else - { - return (v1->width < v2->width) ? -1 : 1; - } - } - else - { - return (v1->bpp < v2->bpp) ? -1 : 1; - } -} - -static int ventoy_enum_video_mode(void) -{ - int i, j; - grub_video_adapter_t adapter; - grub_video_driver_id_t id; - ventoy_video_mode mode; - - g_video_mode_num = 0; - g_video_mode_max = 1024; - g_video_mode_list = grub_malloc(sizeof(ventoy_video_mode) * g_video_mode_max); - if (!g_video_mode_list) - { - return 0; - } - - #ifdef GRUB_MACHINE_PCBIOS - grub_dl_load ("vbe"); - #endif - - id = grub_video_get_driver_id (); - - FOR_VIDEO_ADAPTERS (adapter) - { - if (!adapter->iterate || - (adapter->id != id && (id != GRUB_VIDEO_DRIVER_NONE || - adapter->init() != GRUB_ERR_NONE))) - { - continue; - } - - adapter->iterate(ventoy_video_hook, NULL); - - if (adapter->id != id) - { - adapter->fini(); - } - } - - /* sort video mode */ - for (i = 0; i < g_video_mode_num; i++) - for (j = i + 1; j < g_video_mode_num; j++) - { - if (ventoy_video_mode_cmp(g_video_mode_list + i, g_video_mode_list + j) < 0) - { - grub_memcpy(&mode, g_video_mode_list + i, sizeof(ventoy_video_mode)); - grub_memcpy(g_video_mode_list + i, g_video_mode_list + j, sizeof(ventoy_video_mode)); - grub_memcpy(g_video_mode_list + j, &mode, sizeof(ventoy_video_mode)); - } - } - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_file_t ventoy_wrapper_open(grub_file_t rawFile, enum grub_file_type type) -{ - int len; - grub_file_t file; - static struct grub_fs vtoy_fs = - { - .name = "vtoy", - .fs_dir = 0, - .fs_open = 0, - .fs_read = ventoy_fs_read, - .fs_close = ventoy_fs_close, - .fs_label = 0, - .next = 0 - }; - - if (type != 52) - { - return rawFile; - } - - file = (grub_file_t)grub_zalloc(sizeof (*file)); - if (!file) - { - return 0; - } - - file->data = grub_malloc(rawFile->size + 4096); - if (!file->data) - { - return 0; - } - - grub_file_read(rawFile, file->data, rawFile->size); - len = ventoy_fill_data(4096, (char *)file->data + rawFile->size); - - g_old_file = rawFile; - - file->size = rawFile->size + len; - file->device = rawFile->device; - file->fs = &vtoy_fs; - file->not_easily_seekable = 1; - - return file; -} - -static int ventoy_check_decimal_var(const char *name, long *value) +static int ventoy_arch_mode_init(void) { - const char *value_str = NULL; - - value_str = grub_env_get(name); - if (NULL == value_str) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Variable %s not found", name); - } - - if (!ventoy_is_decimal(value_str)) + #ifdef GRUB_MACHINE_EFI + if (grub_strcmp(GRUB_TARGET_CPU, "i386") == 0) { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Variable %s value '%s' is not an integer", name, value_str); + g_ventoy_plat_data = VTOY_PLAT_I386_UEFI; + grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "ia32"); } - - *value = grub_strtol(value_str, NULL, 10); - - return GRUB_ERR_NONE; -} - -static grub_err_t ventoy_cmd_debug(grub_extcmd_context_t ctxt, int argc, char **args) -{ - if (argc != 1) + else if (grub_strcmp(GRUB_TARGET_CPU, "arm64") == 0) { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {on|off}", cmd_raw_name); + g_ventoy_plat_data = VTOY_PLAT_ARM64_UEFI; + grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "aa64"); } - - if (0 == grub_strcmp(args[0], "on")) + else if (grub_strcmp(GRUB_TARGET_CPU, "mips64el") == 0) { - g_ventoy_debug = 1; - grub_env_set("vtdebug_flag", "debug"); + g_ventoy_plat_data = VTOY_PLAT_MIPS_UEFI; + grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "mips"); } else { - g_ventoy_debug = 0; - grub_env_set("vtdebug_flag", ""); - } - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_break(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - - if (argc < 1 || (args[0][0] != '0' && args[0][0] != '1')) - { - grub_printf("Usage: %s {level} [debug]\r\n", cmd_raw_name); - grub_printf(" level:\r\n"); - grub_printf(" 01/11: busybox / (+cat log)\r\n"); - grub_printf(" 02/12: initrd / (+cat log)\r\n"); - grub_printf(" 03/13: hook / (+cat log)\r\n"); - grub_printf("\r\n"); - grub_printf(" debug:\r\n"); - grub_printf(" 0: debug is off\r\n"); - grub_printf(" 1: debug is on\r\n"); - grub_printf("\r\n"); - VENTOY_CMD_RETURN(GRUB_ERR_NONE); - } - - g_ventoy_break_level = (grub_uint8_t)grub_strtoul(args[0], NULL, 16); - - if (argc > 1 && grub_strtoul(args[1], NULL, 10) > 0) - { - g_ventoy_debug_level = 1; - } - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_strstr(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - - if (argc != 2) - { - return 1; - } - - return (grub_strstr(args[0], args[1])) ? 0 : 1; -} - -static grub_err_t ventoy_cmd_strbegin(grub_extcmd_context_t ctxt, int argc, char **args) -{ - char *c0, *c1; - - (void)ctxt; - - if (argc != 2) - { - return 1; - } - - c0 = args[0]; - c1 = args[1]; - - while (*c0 && *c1) - { - if (*c0 != *c1) - { - return 1; - } - c0++; - c1++; - } - - if (*c1) - { - return 1; + g_ventoy_plat_data = VTOY_PLAT_X86_64_UEFI; + grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "uefi"); } +#else + g_ventoy_plat_data = VTOY_PLAT_X86_LEGACY; + grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "legacy"); +#endif return 0; } -static grub_err_t ventoy_cmd_incr(grub_extcmd_context_t ctxt, int argc, char **args) -{ - long value_long = 0; - char buf[32]; - - if ((argc != 2) || (!ventoy_is_decimal(args[1]))) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Variable} {Int}", cmd_raw_name); - } - - if (GRUB_ERR_NONE != ventoy_check_decimal_var(args[0], &value_long)) - { - return grub_errno; - } - - value_long += grub_strtol(args[1], NULL, 10); - - grub_snprintf(buf, sizeof(buf), "%ld", value_long); - grub_env_set(args[0], buf); - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_mod(grub_extcmd_context_t ctxt, int argc, char **args) -{ - ulonglong value1 = 0; - ulonglong value2 = 0; - char buf[32]; - - if (argc != 3) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int} {Int} {Variable}", cmd_raw_name); - } - - value1 = grub_strtoull(args[0], NULL, 10); - value2 = grub_strtoull(args[1], NULL, 10); - - grub_snprintf(buf, sizeof(buf), "%llu", (value1 & (value2 - 1))); - grub_env_set(args[2], buf); - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_file_size(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int rc = 1; - char buf[32]; - grub_file_t file; - - (void)ctxt; - (void)argc; - (void)args; - - if (argc != 2) - { - return rc; - } - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (file == NULL) - { - debug("failed to open file <%s> for udf check\n", args[0]); - return 1; - } - - grub_snprintf(buf, sizeof(buf), "%llu", (unsigned long long)file->size); - - grub_env_set(args[1], buf); - - grub_file_close(file); - rc = 0; - - return rc; -} - -static grub_err_t ventoy_cmd_load_wimboot(grub_extcmd_context_t ctxt, int argc, char **args) +GRUB_MOD_INIT(ventoy) { - grub_file_t file; - - (void)ctxt; - (void)argc; - (void)args; - - g_wimboot_enable = 0; - grub_check_free(g_wimiso_path); - grub_check_free(g_wimiso_chunk_list.chunk); - - file = grub_file_open(args[0], VENTOY_FILE_TYPE); - if (!file) - { - return 0; - } - - grub_memset(&g_wimiso_chunk_list, 0, sizeof(g_wimiso_chunk_list)); - g_wimiso_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); - if (NULL == g_wimiso_chunk_list.chunk) - { - return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); - } - - g_wimiso_chunk_list.max_chunk = DEFAULT_CHUNK_NUM; - g_wimiso_chunk_list.cur_chunk = 0; - - ventoy_get_block_list(file, &g_wimiso_chunk_list, file->device->disk->partition->start); - - g_wimboot_enable = 1; - g_wimiso_path = grub_strdup(args[0]); - - grub_file_close(file); - - return 0; + ventoy_env_init(); + ventoy_arch_mode_init(); + ventoy_register_all_cmd(); } -static int ventoy_load_efiboot_template(char **buf, int *datalen, int *direntoff) +GRUB_MOD_FINI(ventoy) { - int len; - grub_file_t file; - char exec[128]; - char *data = NULL; - grub_uint32_t offset; - - file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s/ventoy/ventoy_efiboot.img.xz", ventoy_get_env("vtoy_efi_part")); - if (file == NULL) - { - debug("failed to open file <%s>\n", "ventoy_efiboot.img.xz"); - return 1; - } - - len = (int)file->size; - - data = (char *)grub_malloc(file->size); - if (!data) - { - return 1; - } - - grub_file_read(file, data, file->size); - grub_file_close(file); - - grub_snprintf(exec, sizeof(exec), "loopback efiboot mem:0x%llx:size:%d", (ulonglong)(ulong)data, len); - grub_script_execute_sourcecode(exec); - - file = grub_file_open("(efiboot)/EFI/BOOT/BOOTX64.EFI", GRUB_FILE_TYPE_LINUX_INITRD); - offset = (grub_uint32_t)grub_iso9660_get_last_file_dirent_pos(file); - grub_file_close(file); - - grub_script_execute_sourcecode("loopback -d efiboot"); - - *buf = data; - *datalen = len; - *direntoff = offset + 2; - - return 0; -} - -static grub_err_t ventoy_cmd_concat_efi_iso(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int len = 0; - int totlen = 0; - int offset = 0; - grub_file_t file; - char name[32]; - char value[32]; - char *buf = NULL; - char *data = NULL; - ventoy_iso9660_override *dirent; - - (void)ctxt; - - if (argc != 2) - { - return 1; - } - - totlen = sizeof(ventoy_chain_head); - - if (ventoy_load_efiboot_template(&buf, &len, &offset)) - { - debug("failed to load efiboot template %d\n", len); - return 1; - } - - totlen += len; - - debug("efiboot template len:%d offset:%d\n", len, offset); - - file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s", args[0]); - if (file == NULL) - { - debug("failed to open file <%s>\n", args[0]); - return 1; - } - - totlen += ventoy_align_2k(file->size); - - dirent = (ventoy_iso9660_override *)(buf + offset); - dirent->first_sector = len / 2048; - dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); - dirent->size = (grub_uint32_t)file->size; - dirent->size_be = grub_swap_bytes32(dirent->size); - - debug("rawiso len:%d efilen:%d total:%d\n", len, (int)file->size, totlen); - -#ifdef GRUB_MACHINE_EFI - data = (char *)grub_efi_allocate_iso_buf(totlen); -#else - data = (char *)grub_malloc(totlen); -#endif - - ventoy_fill_os_param(file, (ventoy_os_param *)data); - - grub_memcpy(data + sizeof(ventoy_chain_head), buf, len); - grub_check_free(buf); - - grub_file_read(file, data + sizeof(ventoy_chain_head) + len, file->size); - grub_file_close(file); - - grub_snprintf(name, sizeof(name), "%s_addr", args[1]); - grub_snprintf(value, sizeof(value), "0x%llx", (ulonglong)(ulong)data); - grub_env_set(name, value); - - grub_snprintf(name, sizeof(name), "%s_size", args[1]); - grub_snprintf(value, sizeof(value), "%d", (int)(totlen)); - grub_env_set(name, value); - - return 0; -} - -static grub_err_t ventoy_cmd_load_file_to_mem(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int rc = 1; - char name[32]; - char value[32]; - char *buf = NULL; - grub_file_t file; - - (void)ctxt; - (void)argc; - (void)args; - - if (argc != 2) - { - return rc; - } - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (file == NULL) - { - debug("failed to open file <%s>\n", args[0]); - return 1; - } - -#ifdef GRUB_MACHINE_EFI - buf = (char *)grub_efi_allocate_iso_buf(file->size); -#else - buf = (char *)grub_malloc(file->size); -#endif - - grub_file_read(file, buf, file->size); - - grub_snprintf(name, sizeof(name), "%s_addr", args[1]); - grub_snprintf(value, sizeof(value), "0x%llx", (unsigned long long)(unsigned long)buf); - grub_env_set(name, value); - - grub_snprintf(name, sizeof(name), "%s_size", args[1]); - grub_snprintf(value, sizeof(value), "%llu", (unsigned long long)file->size); - grub_env_set(name, value); - - grub_file_close(file); - rc = 0; - - return rc; -} - -static grub_err_t ventoy_cmd_load_img_memdisk(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int rc = 1; - int headlen; - char name[32]; - char value[32]; - char *buf = NULL; - grub_file_t file; - - (void)ctxt; - (void)argc; - (void)args; - - if (argc != 2) - { - return rc; - } - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (file == NULL) - { - debug("failed to open file <%s> for udf check\n", args[0]); - return 1; - } - - headlen = sizeof(ventoy_chain_head); - -#ifdef GRUB_MACHINE_EFI - buf = (char *)grub_efi_allocate_iso_buf(headlen + file->size); -#else - buf = (char *)grub_malloc(headlen + file->size); -#endif - - ventoy_fill_os_param(file, (ventoy_os_param *)buf); - - grub_file_read(file, buf + headlen, file->size); - - grub_snprintf(name, sizeof(name), "%s_addr", args[1]); - grub_snprintf(value, sizeof(value), "0x%llx", (unsigned long long)(unsigned long)buf); - grub_env_set(name, value); - - grub_snprintf(name, sizeof(name), "%s_size", args[1]); - grub_snprintf(value, sizeof(value), "%llu", (unsigned long long)file->size); - grub_env_set(name, value); - - grub_file_close(file); - rc = 0; - - return rc; -} - -static grub_err_t ventoy_cmd_iso9660_nojoliet(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - - if (argc != 1) - { - return 1; - } - - if (args[0][0] == '1') - { - grub_iso9660_set_nojoliet(1); - } - else - { - grub_iso9660_set_nojoliet(0); - } - - return 0; -} - -static grub_err_t ventoy_cmd_is_udf(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int i; - int rc = 1; - grub_file_t file; - grub_uint8_t buf[32]; - - (void)ctxt; - (void)argc; - (void)args; - - if (argc != 1) - { - return rc; - } - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (file == NULL) - { - debug("failed to open file <%s> for udf check\n", args[0]); - return 1; - } - - for (i = 16; i < 32; i++) - { - grub_file_seek(file, i * 2048); - grub_file_read(file, buf, sizeof(buf)); - if (buf[0] == 255) - { - break; - } - } - - i++; - grub_file_seek(file, i * 2048); - grub_file_read(file, buf, sizeof(buf)); - - if (grub_memcmp(buf + 1, "BEA01", 5) == 0) - { - i++; - grub_file_seek(file, i * 2048); - grub_file_read(file, buf, sizeof(buf)); - - if (grub_memcmp(buf + 1, "NSR02", 5) == 0 || - grub_memcmp(buf + 1, "NSR03", 5) == 0) - { - rc = 0; - } - } - - grub_file_close(file); - - debug("ISO UDF: %s\n", rc ? "NO" : "YES"); - - return rc; -} - -static grub_err_t ventoy_cmd_cmp(grub_extcmd_context_t ctxt, int argc, char **args) -{ - long value_long1 = 0; - long value_long2 = 0; - - if ((argc != 3) || (!ventoy_is_decimal(args[0])) || (!ventoy_is_decimal(args[2]))) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int1} { eq|ne|gt|lt|ge|le } {Int2}", cmd_raw_name); - } - - value_long1 = grub_strtol(args[0], NULL, 10); - value_long2 = grub_strtol(args[2], NULL, 10); - - if (0 == grub_strcmp(args[1], "eq")) - { - grub_errno = (value_long1 == value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; - } - else if (0 == grub_strcmp(args[1], "ne")) - { - grub_errno = (value_long1 != value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; - } - else if (0 == grub_strcmp(args[1], "gt")) - { - grub_errno = (value_long1 > value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; - } - else if (0 == grub_strcmp(args[1], "lt")) - { - grub_errno = (value_long1 < value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; - } - else if (0 == grub_strcmp(args[1], "ge")) - { - grub_errno = (value_long1 >= value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; - } - else if (0 == grub_strcmp(args[1], "le")) - { - grub_errno = (value_long1 <= value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; - } - else - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int1} { eq ne gt lt ge le } {Int2}", cmd_raw_name); - } - - return grub_errno; -} - -static grub_err_t ventoy_cmd_device(grub_extcmd_context_t ctxt, int argc, char **args) -{ - char *pos = NULL; - char buf[128] = {0}; - - if (argc != 2) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s path var", cmd_raw_name); - } - - grub_strncpy(buf, (args[0][0] == '(') ? args[0] + 1 : args[0], sizeof(buf) - 1); - pos = grub_strstr(buf, ","); - if (pos) - { - *pos = 0; - } - - grub_env_set(args[1], buf); - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_check_compatible(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int i; - char buf[256]; - grub_disk_t disk; - char *pos = NULL; - const char *files[] = { "ventoy.dat", "VENTOY.DAT" }; - - (void)ctxt; - - if (argc != 1) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s (loop)", cmd_raw_name); - } - - for (i = 0; i < (int)ARRAY_SIZE(files); i++) - { - grub_snprintf(buf, sizeof(buf) - 1, "[ -e \"%s/%s\" ]", args[0], files[i]); - if (0 == grub_script_execute_sourcecode(buf)) - { - debug("file %s exist, ventoy_compatible YES\n", buf); - grub_env_set("ventoy_compatible", "YES"); - VENTOY_CMD_RETURN(GRUB_ERR_NONE); - } - else - { - debug("file %s NOT exist\n", buf); - } - } - - grub_snprintf(buf, sizeof(buf) - 1, "%s", args[0][0] == '(' ? (args[0] + 1) : args[0]); - pos = grub_strstr(buf, ")"); - if (pos) - { - *pos = 0; - } - - disk = grub_disk_open(buf); - if (disk) - { - grub_disk_read(disk, 16 << 2, 0, 1024, g_img_swap_tmp_buf); - grub_disk_close(disk); - - g_img_swap_tmp_buf[703] = 0; - for (i = 318; i < 703; i++) - { - if (g_img_swap_tmp_buf[i] == 'V' && - 0 == grub_strncmp(g_img_swap_tmp_buf + i, VENTOY_COMPATIBLE_STR, VENTOY_COMPATIBLE_STR_LEN)) - { - debug("Ventoy compatible string exist at %d, ventoy_compatible YES\n", i); - grub_env_set("ventoy_compatible", "YES"); - VENTOY_CMD_RETURN(GRUB_ERR_NONE); - } - } - } - else - { - debug("failed to open disk <%s>\n", buf); - } - - grub_env_set("ventoy_compatible", "NO"); - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -int ventoy_cmp_img(img_info *img1, img_info *img2) -{ - char *s1, *s2; - int c1 = 0; - int c2 = 0; - - if (g_plugin_image_list == VENTOY_IMG_WHITE_LIST) - { - return (img1->plugin_list_index - img2->plugin_list_index); - } - - for (s1 = img1->name, s2 = img2->name; *s1 && *s2; s1++, s2++) - { - c1 = *s1; - c2 = *s2; - - if (0 == g_sort_case_sensitive) - { - if (grub_islower(c1)) - { - c1 = c1 - 'a' + 'A'; - } - - if (grub_islower(c2)) - { - c2 = c2 - 'a' + 'A'; - } - } - - if (c1 != c2) - { - break; - } - } - - return (c1 - c2); -} - -static int ventoy_cmp_subdir(img_iterator_node *node1, img_iterator_node *node2) -{ - char *s1, *s2; - int c1 = 0; - int c2 = 0; - - if (g_plugin_image_list == VENTOY_IMG_WHITE_LIST) - { - return (node1->plugin_list_index - node2->plugin_list_index); - } - - for (s1 = node1->dir, s2 = node2->dir; *s1 && *s2; s1++, s2++) - { - c1 = *s1; - c2 = *s2; - - if (0 == g_sort_case_sensitive) - { - if (grub_islower(c1)) - { - c1 = c1 - 'a' + 'A'; - } - - if (grub_islower(c2)) - { - c2 = c2 - 'a' + 'A'; - } - } - - if (c1 != c2) - { - break; - } - } - - return (c1 - c2); -} - -void ventoy_swap_img(img_info *img1, img_info *img2) -{ - grub_memcpy(&g_img_swap_tmp, img1, sizeof(img_info)); - - grub_memcpy(img1, img2, sizeof(img_info)); - img1->next = g_img_swap_tmp.next; - img1->prev = g_img_swap_tmp.prev; - - g_img_swap_tmp.next = img2->next; - g_img_swap_tmp.prev = img2->prev; - grub_memcpy(img2, &g_img_swap_tmp, sizeof(img_info)); -} - -static int ventoy_img_name_valid(const char *filename, grub_size_t namelen) -{ - (void)namelen; - - if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_') - { - return 0; - } - - return 1; -} - -static int ventoy_check_ignore_flag(const char *filename, const struct grub_dirhook_info *info, void *data) -{ - if (0 == info->dir) - { - if (filename && filename[0] == '.' && 0 == grub_strncmp(filename, ".ventoyignore", 13)) - { - *((int *)data) = 1; - return 0; - } - } - - return 0; -} - -static int ventoy_collect_img_files(const char *filename, const struct grub_dirhook_info *info, void *data) -{ - //int i = 0; - int type = 0; - int ignore = 0; - int index = 0; - grub_size_t len; - img_info *img; - img_info *tail; - img_iterator_node *tmp; - img_iterator_node *new_node; - img_iterator_node *node = (img_iterator_node *)data; - - if (g_enumerate_time_checked == 0) - { - g_enumerate_finish_time_ms = grub_get_time_ms(); - if ((g_enumerate_finish_time_ms - g_enumerate_start_time_ms) >= 3000) - { - grub_cls(); - grub_printf("\n\n Ventoy scanning files, please wait...\n"); - grub_refresh(); - g_enumerate_time_checked = 1; - } - } - - len = grub_strlen(filename); - - if (info->dir) - { - if (node->level + 1 > g_img_max_search_level) - { - return 0; - } - - if ((len == 1 && filename[0] == '.') || - (len == 2 && filename[0] == '.' && filename[1] == '.')) - { - return 0; - } - - if (!ventoy_img_name_valid(filename, len)) - { - return 0; - } - - if (filename[0] == '$' && 0 == grub_strncmp(filename, "$RECYCLE.BIN", 12)) - { - return 0; - } - - if (g_plugin_image_list == VENTOY_IMG_WHITE_LIST) - { - grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s/", node->dir, filename); - index = ventoy_plugin_get_image_list_index(vtoy_class_directory, g_img_swap_tmp_buf); - if (index == 0) - { - debug("Directory %s not found in image_list plugin config...\n", g_img_swap_tmp_buf); - return 0; - } - } - - new_node = grub_zalloc(sizeof(img_iterator_node)); - if (new_node) - { - new_node->level = node->level + 1; - new_node->plugin_list_index = index; - new_node->dirlen = grub_snprintf(new_node->dir, sizeof(new_node->dir), "%s%s/", node->dir, filename); - - g_enum_fs->fs_dir(g_enum_dev, new_node->dir, ventoy_check_ignore_flag, &ignore); - if (ignore) - { - debug("Directory %s ignored...\n", new_node->dir); - grub_free(new_node); - return 0; - } - - new_node->tail = node->tail; - - new_node->parent = node; - if (!node->firstchild) - { - node->firstchild = new_node; - } - - if (g_img_iterator_tail) - { - g_img_iterator_tail->next = new_node; - g_img_iterator_tail = new_node; - } - else - { - g_img_iterator_head.next = new_node; - g_img_iterator_tail = new_node; - } - } - } - else - { - debug("Find a file %s\n", filename); - if (len < 4) - { - return 0; - } - - if (FILE_FLT(ISO) && 0 == grub_strcasecmp(filename + len - 4, ".iso")) - { - type = img_type_iso; - } - else if (FILE_FLT(WIM) && g_wimboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".wim"))) - { - type = img_type_wim; - } - else if (FILE_FLT(VHD) && g_vhdboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".vhd") || - (len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vhdx")))) - { - type = img_type_vhd; - } - #ifdef GRUB_MACHINE_EFI - else if (FILE_FLT(EFI) && 0 == grub_strcasecmp(filename + len - 4, ".efi")) - { - type = img_type_efi; - } - #endif - else if (FILE_FLT(IMG) && 0 == grub_strcasecmp(filename + len - 4, ".img")) - { - if (len == 18 && grub_strncmp(filename, "ventoy_", 7) == 0) - { - if (grub_strncmp(filename + 7, "wimboot", 7) == 0 || - grub_strncmp(filename + 7, "vhdboot", 7) == 0) - { - return 0; - } - } - type = img_type_img; - } - else if (FILE_FLT(VTOY) && len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vtoy")) - { - type = img_type_vtoy; - } - else if (len >= 9 && 0 == grub_strcasecmp(filename + len - 5, ".vcfg")) - { - if (filename[len - 9] == '.' || (len >= 10 && filename[len - 10] == '.')) - { - grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s", node->dir, filename); - ventoy_plugin_add_custom_boot(g_img_swap_tmp_buf); - } - return 0; - } - else - { - return 0; - } - - if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_') - { - return 0; - } - - if (g_plugin_image_list) - { - grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s", node->dir, filename); - index = ventoy_plugin_get_image_list_index(vtoy_class_image_file, g_img_swap_tmp_buf); - if (VENTOY_IMG_WHITE_LIST == g_plugin_image_list && index == 0) - { - debug("File %s not found in image_list plugin config...\n", g_img_swap_tmp_buf); - return 0; - } - else if (VENTOY_IMG_BLACK_LIST == g_plugin_image_list && index > 0) - { - debug("File %s found in image_blacklist plugin config %d ...\n", g_img_swap_tmp_buf, index); - return 0; - } - } - - img = grub_zalloc(sizeof(img_info)); - if (img) - { - img->type = type; - img->plugin_list_index = index; - grub_snprintf(img->name, sizeof(img->name), "%s", filename); - - img->pathlen = grub_snprintf(img->path, sizeof(img->path), "%s%s", node->dir, img->name); - - img->size = info->size; - if (0 == img->size) - { - img->size = ventoy_grub_get_file_size("%s/%s%s", g_iso_path, node->dir, filename); - } - - if (img->size < VTOY_FILT_MIN_FILE_SIZE) - { - debug("img <%s> size too small %llu\n", img->name, (ulonglong)img->size); - grub_free(img); - return 0; - } - - if (g_ventoy_img_list) - { - tail = *(node->tail); - img->prev = tail; - tail->next = img; - } - else - { - g_ventoy_img_list = img; - } - - img->id = g_ventoy_img_count; - img->parent = node; - if (node && NULL == node->firstiso) - { - node->firstiso = img; - } - - node->isocnt++; - tmp = node->parent; - while (tmp) - { - tmp->isocnt++; - tmp = tmp->parent; - } - - *((img_info **)(node->tail)) = img; - g_ventoy_img_count++; - - img->alias = ventoy_plugin_get_menu_alias(vtoy_alias_image_file, img->path); - img->class = ventoy_plugin_get_menu_class(vtoy_class_image_file, img->name, img->path); - if (!img->class) - { - img->class = g_menu_class[type]; - } - img->menu_prefix = g_menu_prefix[type]; - - if (img_type_iso == type) - { - if (ventoy_plugin_check_memdisk(img->path)) - { - img->menu_prefix = "miso"; - } - } - - debug("Add %s%s to list %d\n", node->dir, filename, g_ventoy_img_count); - } - } - - return 0; -} - -static int ventoy_arch_mode_init(void) -{ - #ifdef GRUB_MACHINE_EFI - if (grub_strcmp(GRUB_TARGET_CPU, "i386") == 0) - { - g_ventoy_plat_data = VTOY_PLAT_I386_UEFI; - grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "ia32"); - } - else if (grub_strcmp(GRUB_TARGET_CPU, "arm64") == 0) - { - g_ventoy_plat_data = VTOY_PLAT_ARM64_UEFI; - grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "aa64"); - } - else if (grub_strcmp(GRUB_TARGET_CPU, "mips64el") == 0) - { - g_ventoy_plat_data = VTOY_PLAT_MIPS_UEFI; - grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "mips"); - } - else - { - g_ventoy_plat_data = VTOY_PLAT_X86_64_UEFI; - grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "uefi"); - } -#else - g_ventoy_plat_data = VTOY_PLAT_X86_LEGACY; - grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "legacy"); -#endif - - return 0; -} - -int ventoy_fill_data(grub_uint32_t buflen, char *buffer) -{ - int len = GRUB_UINT_MAX; - const char *value = NULL; - char name[32] = {0}; - char plat[32] = {0}; - char guidstr[32] = {0}; - ventoy_guid guid = VENTOY_GUID; - const char *fmt1 = NULL; - const char *fmt2 = NULL; - const char *fmt3 = NULL; - grub_uint32_t *puint = (grub_uint32_t *)name; - grub_uint32_t *puint2 = (grub_uint32_t *)plat; - const char fmtdata[]={ 0x39, 0x35, 0x25, 0x00, 0x35, 0x00, 0x23, 0x30, 0x30, 0x30, 0x30, 0x66, 0x66, 0x00 }; - const char fmtcode[]={ - 0x22, 0x0A, 0x2B, 0x20, 0x68, 0x62, 0x6F, 0x78, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x74, 0x6F, 0x70, - 0x20, 0x3D, 0x20, 0x25, 0x73, 0x0A, 0x20, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x20, 0x3D, 0x20, 0x25, - 0x73, 0x0A, 0x20, 0x20, 0x2B, 0x20, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x7B, 0x74, 0x65, 0x78, - 0x74, 0x20, 0x3D, 0x20, 0x22, 0x25, 0x73, 0x20, 0x25, 0x73, 0x25, 0x73, 0x22, 0x20, 0x63, 0x6F, - 0x6C, 0x6F, 0x72, 0x20, 0x3D, 0x20, 0x22, 0x25, 0x73, 0x22, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, - 0x20, 0x3D, 0x20, 0x22, 0x6C, 0x65, 0x66, 0x74, 0x22, 0x7D, 0x0A, 0x7D, 0x0A, 0x22, 0x00 - }; - - grub_memset(name, 0, sizeof(name)); - puint[0] = grub_swap_bytes32(0x56454e54); - puint[3] = grub_swap_bytes32(0x4f4e0000); - puint[2] = grub_swap_bytes32(0x45525349); - puint[1] = grub_swap_bytes32(0x4f595f56); - value = ventoy_get_env(name); - - grub_memset(name, 0, sizeof(name)); - puint[1] = grub_swap_bytes32(0x5f544f50); - puint[0] = grub_swap_bytes32(0x56544c45); - fmt1 = ventoy_get_env(name); - if (!fmt1) - { - fmt1 = fmtdata; - } - - grub_memset(name, 0, sizeof(name)); - puint[1] = grub_swap_bytes32(0x5f4c4654); - puint[0] = grub_swap_bytes32(0x56544c45); - fmt2 = ventoy_get_env(name); - - grub_memset(name, 0, sizeof(name)); - puint[1] = grub_swap_bytes32(0x5f434c52); - puint[0] = grub_swap_bytes32(0x56544c45); - fmt3 = ventoy_get_env(name); - - grub_memcpy(guidstr, &guid, sizeof(guid)); - - puint2[0] = grub_swap_bytes32(g_ventoy_plat_data); - - /* Easter egg :) It will be appreciated if you reserve it, but NOT mandatory. */ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wformat-nonliteral" - len = grub_snprintf(buffer, buflen, fmtcode, - fmt1 ? fmt1 : fmtdata, - fmt2 ? fmt2 : fmtdata + 4, - value ? value : "", plat, guidstr, - fmt3 ? fmt3 : fmtdata + 6); - #pragma GCC diagnostic pop - - grub_memset(name, 0, sizeof(name)); - puint[0] = grub_swap_bytes32(0x76746f79); - puint[2] = grub_swap_bytes32(0x656e7365); - puint[1] = grub_swap_bytes32(0x5f6c6963); - ventoy_set_env(name, guidstr); - - return len; -} - -int ventoy_check_password(const vtoy_password *pwd, int retry) -{ - int offset; - char input[256]; - grub_uint8_t md5[16]; - - while (retry--) - { - grub_memset(input, 0, sizeof(input)); - - grub_printf("Enter password: "); - grub_refresh(); - - if (pwd->type == VTOY_PASSWORD_TXT) - { - grub_password_get(input, 128); - if (grub_strcmp(pwd->text, input) == 0) - { - return 0; - } - } - else if (pwd->type == VTOY_PASSWORD_MD5) - { - grub_password_get(input, 128); - grub_crypto_hash(GRUB_MD_MD5, md5, input, grub_strlen(input)); - if (grub_memcmp(pwd->md5, md5, 16) == 0) - { - return 0; - } - } - else if (pwd->type == VTOY_PASSWORD_SALT_MD5) - { - offset = (int)grub_snprintf(input, 128, "%s", pwd->salt); - grub_password_get(input + offset, 128); - - grub_crypto_hash(GRUB_MD_MD5, md5, input, grub_strlen(input)); - if (grub_memcmp(pwd->md5, md5, 16) == 0) - { - return 0; - } - } - - grub_printf("Invalid password!\n\n"); - grub_refresh(); - } - - return 1; -} - -static img_info * ventoy_get_min_iso(img_iterator_node *node) -{ - img_info *minimg = NULL; - img_info *img = (img_info *)(node->firstiso); - - while (img && (img_iterator_node *)(img->parent) == node) - { - if (img->select == 0 && (NULL == minimg || ventoy_cmp_img(img, minimg) < 0)) - { - minimg = img; - } - img = img->next; - } - - if (minimg) - { - minimg->select = 1; - } - - return minimg; -} - -static img_iterator_node * ventoy_get_min_child(img_iterator_node *node) -{ - img_iterator_node *Minchild = NULL; - img_iterator_node *child = node->firstchild; - - while (child && child->parent == node) - { - if (child->select == 0 && (NULL == Minchild || ventoy_cmp_subdir(child, Minchild) < 0)) - { - Minchild = child; - } - child = child->next; - } - - if (Minchild) - { - Minchild->select = 1; - } - - return Minchild; -} - -static int ventoy_dynamic_tree_menu(img_iterator_node *node) -{ - int offset = 1; - img_info *img = NULL; - const char *dir_class = NULL; - const char *dir_alias = NULL; - img_iterator_node *child = NULL; - - if (node->isocnt == 0 || node->done == 1) - { - return 0; - } - - if (node->parent && node->parent->dirlen < node->dirlen) - { - offset = node->parent->dirlen; - } - - if (node == &g_img_iterator_head) - { - if (g_default_menu_mode == 0) - { - if (g_tree_view_menu_style == 0) - { - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, - "menuentry \"%-10s [Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n " - " echo 'return ...' \n" - "}\n", "<--"); - } - else - { - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, - "menuentry \"[Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n " - " echo '%s ...' \n" - "}\n", "return"); - } - } - } - else - { - node->dir[node->dirlen - 1] = 0; - dir_class = ventoy_plugin_get_menu_class(vtoy_class_directory, node->dir, node->dir); - if (!dir_class) - { - dir_class = "vtoydir"; - } - - dir_alias = ventoy_plugin_get_menu_alias(vtoy_alias_directory, node->dir); - if (dir_alias) - { - if (g_tree_view_menu_style == 0) - { - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, - "submenu \"%-10s %s\" --class=\"%s\" --id=\"DIR_%s\" {\n", - "DIR", dir_alias, dir_class, node->dir + offset); - } - else - { - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, - "submenu \"%s\" --class=\"%s\" --id=\"DIR_%s\" {\n", - dir_alias, dir_class, node->dir + offset); - } - } - else - { - dir_alias = node->dir + offset; - - if (g_tree_view_menu_style == 0) - { - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, - "submenu \"%-10s [%s]\" --class=\"%s\" --id=\"DIR_%s\" {\n", - "DIR", dir_alias, dir_class, node->dir + offset); - } - else - { - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, - "submenu \"[%s]\" --class=\"%s\" --id=\"DIR_%s\" {\n", - dir_alias, dir_class, node->dir + offset); - } - } - - if (g_tree_view_menu_style == 0) - { - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, - "menuentry \"%-10s [../]\" --class=\"vtoyret\" VTOY_RET {\n " - " echo 'return ...' \n" - "}\n", "<--"); - } - else - { - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, - "menuentry \"[../]\" --class=\"vtoyret\" VTOY_RET {\n " - " echo '%s ...' \n" - "}\n", "return"); - } - } - - while ((child = ventoy_get_min_child(node)) != NULL) - { - ventoy_dynamic_tree_menu(child); - } - - while ((img = ventoy_get_min_iso(node)) != NULL) - { - if (g_tree_view_menu_style == 0) - { - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, - "menuentry \"%-10s %s%s\" --class=\"%s\" --id=\"VID_%d\" {\n" - " %s_%s \n" - "}\n", - grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT), - img->unsupport ? "[***********] " : "", - img->alias ? img->alias : img->name, img->class, img->id, - img->menu_prefix, - img->unsupport ? "unsupport_menuentry" : "common_menuentry"); - } - else - { - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, - "menuentry \"%s%s\" --class=\"%s\" --id=\"VID_%d\" {\n" - " %s_%s \n" - "}\n", - img->unsupport ? "[***********] " : "", - img->alias ? img->alias : img->name, img->class, img->id, - img->menu_prefix, - img->unsupport ? "unsupport_menuentry" : "common_menuentry"); - } - } - - if (node != &g_img_iterator_head) - { - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "%s", "}\n"); - } - - node->done = 1; - return 0; -} - -int ventoy_check_device_result(int ret) -{ - char buf[32]; - - grub_snprintf(buf, sizeof(buf), "%d", (ret & 0x7FFF)); - grub_env_set("VTOY_CHKDEV_RESULT_STRING", buf); - grub_env_export("VTOY_CHKDEV_RESULT_STRING"); - - if (ret) - { - grub_printf(VTOY_WARNING"\n"); - grub_printf(VTOY_WARNING"\n"); - grub_printf(VTOY_WARNING"\n\n\n"); - - grub_printf("This is NOT a standard Ventoy device and is NOT supported (0x%x).\n\n", ret); - grub_printf("You should follow the instructions in https://www.ventoy.net to use Ventoy.\n"); - - grub_printf("\n\nWill exit after 10 seconds ...... "); - grub_refresh(); - grub_sleep(10); - } - - return ret; -} - -int ventoy_check_device(grub_device_t dev) -{ - int workaround = 0; - grub_file_t file; - grub_uint64_t offset; - char devname[64]; - grub_fs_t fs; - grub_device_t dev2; - char *label = NULL; - struct grub_partition *partition; - - if (dev->disk == NULL || dev->disk->partition == NULL) - { - return ventoy_check_device_result(1 | 0x1000); - } - - if (0 == ventoy_check_file_exist("(%s,2)/ventoy/ventoy.cpio", dev->disk->name) || - 0 == ventoy_check_file_exist("(%s,2)/grub/localboot.cfg", dev->disk->name) || - 0 == ventoy_check_file_exist("(%s,2)/tool/mount.exfat-fuse_aarch64", dev->disk->name)) - { - #ifndef GRUB_MACHINE_EFI - if (0 == ventoy_check_file_exist("(ventoydisk)/ventoy/ventoy.cpio", dev->disk->name) || - 0 == ventoy_check_file_exist("(ventoydisk)/grub/localboot.cfg", dev->disk->name) || - 0 == ventoy_check_file_exist("(ventoydisk)/tool/mount.exfat-fuse_aarch64", dev->disk->name)) - { - return ventoy_check_device_result(2 | 0x1000); - } - else - { - workaround = 1; - } - #endif - } - - /* We must have partition 2 */ - if (workaround) - { - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", "(ventoydisk)/ventoy/ventoy.cpio"); - } - else - { - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(%s,2)/ventoy/ventoy.cpio", dev->disk->name); - } - if (!file) - { - return ventoy_check_device_result(3 | 0x1000); - } - - if (NULL == grub_strstr(file->fs->name, "fat")) - { - grub_file_close(file); - return ventoy_check_device_result(4 | 0x1000); - } - - partition = dev->disk->partition; - if (partition->number != 0 || partition->start != 2048) - { - return ventoy_check_device_result(5); - } - - if (workaround) - { - if (grub_strncmp(g_ventoy_part_info->Head.Signature, "EFI PART", 8) == 0) - { - ventoy_gpt_part_tbl *PartTbl = g_ventoy_part_info->PartTbl; - if (PartTbl[1].StartLBA != PartTbl[0].LastLBA + 1 || - (PartTbl[1].LastLBA + 1 - PartTbl[1].StartLBA) != 65536) - { - grub_file_close(file); - return ventoy_check_device_result(6); - } - } - else - { - ventoy_part_table *PartTbl = g_ventoy_part_info->MBR.PartTbl; - if (PartTbl[1].StartSectorId != PartTbl[0].StartSectorId + PartTbl[0].SectorCount || - PartTbl[1].SectorCount != 65536) - { - grub_file_close(file); - return ventoy_check_device_result(6); - } - } - } - else - { - offset = partition->start + partition->len; - partition = file->device->disk->partition; - if ((partition->number != 1) || (partition->len != 65536) || (offset != partition->start)) - { - grub_file_close(file); - return ventoy_check_device_result(7); - } - } - - grub_file_close(file); - - if (workaround == 0) - { - grub_snprintf(devname, sizeof(devname), "%s,2", dev->disk->name); - dev2 = grub_device_open(devname); - if (!dev2) - { - return ventoy_check_device_result(8); - } - - fs = grub_fs_probe(dev2); - if (!fs) - { - grub_device_close(dev2); - return ventoy_check_device_result(9); - } - - fs->fs_label(dev2, &label); - if ((!label) || grub_strncmp("VTOYEFI", label, 7)) - { - grub_device_close(dev2); - return ventoy_check_device_result(10); - } - - grub_device_close(dev2); - } - - return ventoy_check_device_result(0); -} - -static int ventoy_set_default_menu(void) -{ - int img_len = 0; - char *pos = NULL; - char *end = NULL; - char *def = NULL; - const char *strdata = NULL; - img_info *cur = NULL; - img_info *default_node = NULL; - const char *default_image = NULL; - - default_image = ventoy_get_env("VTOY_DEFAULT_IMAGE"); - if (default_image && default_image[0] == '/') - { - img_len = grub_strlen(default_image); - - for (cur = g_ventoy_img_list; cur; cur = cur->next) - { - if (img_len == cur->pathlen && grub_strcmp(default_image, cur->path) == 0) - { - default_node = cur; - break; - } - } - - if (!default_node) - { - return 1; - } - - if (0 == g_default_menu_mode) - { - vtoy_ssprintf(g_list_script_buf, g_list_script_pos, "set default='VID_%d'\n", default_node->id); - } - else - { - def = grub_strdup(default_image); - if (!def) - { - return 1; - } - - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "set default=%c", '\''); - - strdata = ventoy_get_env("VTOY_DEFAULT_SEARCH_ROOT"); - if (strdata && strdata[0] == '/') - { - pos = def + grub_strlen(strdata); - if (*pos == '/') - { - pos++; - } - } - else - { - pos = def + 1; - } - - while ((end = grub_strchr(pos, '/')) != NULL) - { - *end = 0; - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "DIR_%s>", pos); - pos = end + 1; - } - - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "VID_%d'\n", default_node->id); - grub_free(def); - } - } - - return 0; -} - -static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int len; - grub_fs_t fs; - grub_device_t dev = NULL; - img_info *cur = NULL; - img_info *tail = NULL; - const char *strdata = NULL; - char *device_name = NULL; - char buf[32]; - img_iterator_node *node = NULL; - img_iterator_node *tmp = NULL; - - (void)ctxt; - - if (argc != 2) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {device} {cntvar}", cmd_raw_name); - } - - if (g_ventoy_img_list || g_ventoy_img_count) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Must clear image before list"); - } - - g_enumerate_time_checked = 0; - g_enumerate_start_time_ms = grub_get_time_ms(); - - strdata = ventoy_get_env("VTOY_FILT_DOT_UNDERSCORE_FILE"); - if (strdata && strdata[0] == '1' && strdata[1] == 0) - { - g_filt_dot_underscore_file = 1; - } - - strdata = ventoy_get_env("VTOY_SORT_CASE_SENSITIVE"); - if (strdata && strdata[0] == '1' && strdata[1] == 0) - { - g_sort_case_sensitive = 1; - } - - device_name = grub_file_get_device_name(args[0]); - if (!device_name) - { - goto fail; - } - - g_enum_dev = dev = grub_device_open(device_name); - if (!dev) - { - goto fail; - } - - g_enum_fs = fs = grub_fs_probe(dev); - if (!fs) - { - goto fail; - } - - if (ventoy_get_fs_type(fs->name) >= ventoy_fs_max) - { - debug("unsupported fs:<%s>\n", fs->name); - ventoy_set_env("VTOY_NO_ISO_TIP", "unsupported file system"); - goto fail; - } - - ventoy_set_env("vtoy_iso_fs", fs->name); - - strdata = ventoy_get_env("VTOY_DEFAULT_MENU_MODE"); - if (strdata && strdata[0] == '1') - { - g_default_menu_mode = 1; - } - - grub_memset(&g_img_iterator_head, 0, sizeof(g_img_iterator_head)); - - grub_snprintf(g_iso_path, sizeof(g_iso_path), "%s", args[0]); - - strdata = ventoy_get_env("VTOY_DEFAULT_SEARCH_ROOT"); - if (strdata && strdata[0] == '/') - { - len = grub_snprintf(g_img_iterator_head.dir, sizeof(g_img_iterator_head.dir) - 1, "%s", strdata); - if (g_img_iterator_head.dir[len - 1] != '/') - { - g_img_iterator_head.dir[len++] = '/'; - } - g_img_iterator_head.dirlen = len; - } - else - { - g_img_iterator_head.dirlen = 1; - grub_strcpy(g_img_iterator_head.dir, "/"); - } - - g_img_iterator_head.tail = &tail; - - if (g_img_max_search_level < 0) - { - g_img_max_search_level = GRUB_INT_MAX; - strdata = ventoy_get_env("VTOY_MAX_SEARCH_LEVEL"); - if (strdata && ventoy_is_decimal(strdata)) - { - g_img_max_search_level = (int)grub_strtoul(strdata, NULL, 10); - } - } - - g_vtoy_file_flt[VTOY_FILE_FLT_ISO] = ventoy_control_get_flag("VTOY_FILE_FLT_ISO"); - g_vtoy_file_flt[VTOY_FILE_FLT_WIM] = ventoy_control_get_flag("VTOY_FILE_FLT_WIM"); - g_vtoy_file_flt[VTOY_FILE_FLT_EFI] = ventoy_control_get_flag("VTOY_FILE_FLT_EFI"); - g_vtoy_file_flt[VTOY_FILE_FLT_IMG] = ventoy_control_get_flag("VTOY_FILE_FLT_IMG"); - g_vtoy_file_flt[VTOY_FILE_FLT_VHD] = ventoy_control_get_flag("VTOY_FILE_FLT_VHD"); - g_vtoy_file_flt[VTOY_FILE_FLT_VTOY] = ventoy_control_get_flag("VTOY_FILE_FLT_VTOY"); - - for (node = &g_img_iterator_head; node; node = node->next) - { - fs->fs_dir(dev, node->dir, ventoy_collect_img_files, node); - } - - strdata = ventoy_get_env("VTOY_TREE_VIEW_MENU_STYLE"); - if (strdata && strdata[0] == '1' && strdata[1] == 0) - { - g_tree_view_menu_style = 1; - } - - ventoy_set_default_menu(); - - for (node = &g_img_iterator_head; node; node = node->next) - { - ventoy_dynamic_tree_menu(node); - } - - /* free node */ - node = g_img_iterator_head.next; - while (node) - { - tmp = node->next; - grub_free(node); - node = tmp; - } - - /* sort image list by image name */ - for (cur = g_ventoy_img_list; cur; cur = cur->next) - { - for (tail = cur->next; tail; tail = tail->next) - { - if (ventoy_cmp_img(cur, tail) > 0) - { - ventoy_swap_img(cur, tail); - } - } - } - - if (g_default_menu_mode == 1) - { - vtoy_ssprintf(g_list_script_buf, g_list_script_pos, - "menuentry \"%s [Return to TreeView]\" --class=\"vtoyret\" VTOY_RET {\n " - " echo 'return ...' \n" - "}\n", "<--"); - } - - for (cur = g_ventoy_img_list; cur; cur = cur->next) - { - vtoy_ssprintf(g_list_script_buf, g_list_script_pos, - "menuentry \"%s%s\" --class=\"%s\" --id=\"VID_%d\" {\n" - " %s_%s \n" - "}\n", - cur->unsupport ? "[***********] " : "", - cur->alias ? cur->alias : cur->name, cur->class, cur->id, - cur->menu_prefix, - cur->unsupport ? "unsupport_menuentry" : "common_menuentry"); - } - - g_tree_script_buf[g_tree_script_pos] = 0; - g_list_script_buf[g_list_script_pos] = 0; - - grub_snprintf(buf, sizeof(buf), "%d", g_ventoy_img_count); - grub_env_set(args[1], buf); - -fail: - - check_free(device_name, grub_free); - check_free(dev, grub_device_close); - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - - -static grub_err_t ventoy_cmd_clear_img(grub_extcmd_context_t ctxt, int argc, char **args) -{ - img_info *next = NULL; - img_info *cur = g_ventoy_img_list; - - (void)ctxt; - (void)argc; - (void)args; - - while (cur) - { - next = cur->next; - grub_free(cur); - cur = next; - } - - g_ventoy_img_list = NULL; - g_ventoy_img_count = 0; - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_img_name(grub_extcmd_context_t ctxt, int argc, char **args) -{ - long img_id = 0; - img_info *cur = g_ventoy_img_list; - - (void)ctxt; - - if (argc != 2 || (!ventoy_is_decimal(args[0]))) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {imageID} {var}", cmd_raw_name); - } - - img_id = grub_strtol(args[0], NULL, 10); - if (img_id >= g_ventoy_img_count) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such many images %ld %ld", img_id, g_ventoy_img_count); - } - - debug("Find image %ld name \n", img_id); - - while (cur && img_id > 0) - { - img_id--; - cur = cur->next; - } - - if (!cur) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such many images"); - } - - debug("image name is %s\n", cur->name); - - grub_env_set(args[1], cur->name); - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_ext_select_img_path(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int len = 0; - char id[32] = {0}; - img_info *cur = g_ventoy_img_list; - - (void)ctxt; - - if (argc != 1) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {var}", cmd_raw_name); - } - - len = (int)grub_strlen(args[0]); - - while (cur) - { - if (len == cur->pathlen && 0 == grub_strcmp(args[0], cur->path)) - { - break; - } - cur = cur->next; - } - - if (!cur) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such image"); - } - - grub_snprintf(id, sizeof(id), "VID_%d", cur->id); - grub_env_set("chosen", id); - grub_env_export("chosen"); - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int img_id = 0; - char value[32]; - char *pos = NULL; - const char *id = NULL; - img_info *cur = g_ventoy_img_list; - - (void)ctxt; - - if (argc < 1 || argc > 2) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {var}", cmd_raw_name); - } - - id = grub_env_get("chosen"); - - pos = grub_strstr(id, "VID_"); - if (pos) - { - img_id = (int)grub_strtoul(pos + 4, NULL, 10); - } - else - { - img_id = (int)grub_strtoul(id, NULL, 10); - } - - while (cur) - { - if (img_id == cur->id) - { - break; - } - cur = cur->next; - } - - if (!cur) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such image"); - } - - grub_env_set(args[0], cur->path); - - if (argc > 1) - { - grub_snprintf(value, sizeof(value), "%llu", (ulonglong)(cur->size)); - grub_env_set(args[1], value); - } - - g_svd_replace_offset = 0; - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid, grub_uint8_t *signature) -{ - grub_disk_t disk; - char *device_name; - char *pos; - char *pos2; - - device_name = grub_file_get_device_name(filename); - if (!device_name) - { - return 1; - } - - pos = device_name; - if (pos[0] == '(') - { - pos++; - } - - pos2 = grub_strstr(pos, ","); - if (!pos2) - { - pos2 = grub_strstr(pos, ")"); - } - - if (pos2) - { - *pos2 = 0; - } - - disk = grub_disk_open(pos); - if (disk) - { - grub_disk_read(disk, 0, 0x180, 16, guid); - grub_disk_read(disk, 0, 0x1b8, 4, signature); - grub_disk_close(disk); - } - else - { - return 1; - } - - grub_free(device_name); - return 0; -} - -grub_uint32_t ventoy_get_iso_boot_catlog(grub_file_t file) -{ - eltorito_descriptor desc; - - grub_memset(&desc, 0, sizeof(desc)); - grub_file_seek(file, 17 * 2048); - grub_file_read(file, &desc, sizeof(desc)); - - if (desc.type != 0 || desc.version != 1) - { - return 0; - } - - if (grub_strncmp((char *)desc.id, "CD001", 5) != 0 || - grub_strncmp((char *)desc.system_id, "EL TORITO SPECIFICATION", 23) != 0) - { - return 0; - } - - return desc.sector; -} - -int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector) -{ - int i; - int x86count = 0; - grub_uint8_t buf[512]; - grub_uint8_t parttype[] = { 0x04, 0x06, 0x0B, 0x0C }; - - grub_file_seek(file, sector * 2048); - grub_file_read(file, buf, sizeof(buf)); - - if (buf[0] == 0x01 && buf[1] == 0xEF) - { - debug("%s efi eltorito in Validation Entry\n", file->name); - return 1; - } - - if (buf[0] == 0x01 && buf[1] == 0x00) - { - x86count++; - } - - for (i = 64; i < (int)sizeof(buf); i += 32) - { - if ((buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0xEF) - { - debug("%s efi eltorito offset %d 0x%02x\n", file->name, i, buf[i]); - return 1; - } - - if ((buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0x00 && x86count == 1) - { - debug("0x9100 assume %s efi eltorito offset %d 0x%02x\n", file->name, i, buf[i]); - return 1; - } - } - - if (x86count && buf[32] == 0x88 && buf[33] == 0x04) - { - for (i = 0; i < (int)(ARRAY_SIZE(parttype)); i++) - { - if (buf[36] == parttype[i]) - { - debug("hard disk image assume %s efi eltorito, part type 0x%x\n", file->name, buf[36]); - return 1; - } - } - } - - debug("%s does not contain efi eltorito\n", file->name); - return 0; -} - -void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param) -{ - char *pos; - const char *fs = NULL; - const char *cdprompt = NULL; - grub_uint32_t i; - grub_uint8_t chksum = 0; - grub_disk_t disk; - - disk = file->device->disk; - grub_memcpy(¶m->guid, &g_ventoy_guid, sizeof(ventoy_guid)); - - param->vtoy_disk_size = disk->total_sectors * (1 << disk->log_sector_size); - param->vtoy_disk_part_id = disk->partition->number + 1; - param->vtoy_disk_part_type = ventoy_get_fs_type(file->fs->name); - - pos = grub_strstr(file->name, "/"); - if (!pos) - { - pos = file->name; - } - - grub_snprintf(param->vtoy_img_path, sizeof(param->vtoy_img_path), "%s", pos); - - ventoy_get_disk_guid(file->name, param->vtoy_disk_guid, param->vtoy_disk_signature); - - param->vtoy_img_size = file->size; - - param->vtoy_reserved[0] = g_ventoy_break_level; - param->vtoy_reserved[1] = g_ventoy_debug_level; - - param->vtoy_reserved[2] = g_ventoy_chain_type; - - /* Windows CD/DVD prompt 0:suppress 1:reserved */ - param->vtoy_reserved[4] = 0; - if (g_ventoy_chain_type == 1) /* Windows */ - { - cdprompt = ventoy_get_env("VTOY_WINDOWS_CD_PROMPT"); - if (cdprompt && cdprompt[0] == '1' && cdprompt[1] == 0) - { - param->vtoy_reserved[4] = 1; - } - } - - fs = ventoy_get_env("ventoy_fs_probe"); - if (fs && grub_strcmp(fs, "udf") == 0) - { - param->vtoy_reserved[3] = 1; - } - - /* calculate checksum */ - for (i = 0; i < sizeof(ventoy_os_param); i++) - { - chksum += *((grub_uint8_t *)param + i); - } - param->chksum = (grub_uint8_t)(0x100 - chksum); - - return; -} - -int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start) -{ - grub_uint32_t i = 0; - grub_uint64_t total = 0; - grub_uint64_t fileblk = 0; - ventoy_img_chunk *chunk = NULL; - - for (i = 0; i < chunklist->cur_chunk; i++) - { - chunk = chunklist->chunk + i; - - if (chunk->disk_start_sector <= start) - { - debug("%u disk start invalid %lu\n", i, (ulong)start); - return 1; - } - - total += chunk->disk_end_sector + 1 - chunk->disk_start_sector; - } - - fileblk = (file->size + 511) / 512; - - if (total != fileblk) - { - debug("Invalid total: %llu %llu\n", (ulonglong)total, (ulonglong)fileblk); - if ((file->size % 512) && (total + 1 == fileblk)) - { - debug("maybe img file to be processed.\n"); - return 0; - } - - return 1; - } - - return 0; -} - -int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start) -{ - int fs_type; - int len; - grub_uint32_t i = 0; - grub_uint32_t sector = 0; - grub_uint32_t count = 0; - grub_off_t size = 0; - grub_off_t read = 0; - - fs_type = ventoy_get_fs_type(file->fs->name); - if (fs_type == ventoy_fs_exfat) - { - grub_fat_get_file_chunk(start, file, chunklist); - } - else if (fs_type == ventoy_fs_ext) - { - grub_ext_get_file_chunk(start, file, chunklist); - } - else - { - file->read_hook = (grub_disk_read_hook_t)grub_disk_blocklist_read; - file->read_hook_data = chunklist; - - for (size = file->size; size > 0; size -= read) - { - read = (size > VTOY_SIZE_1GB) ? VTOY_SIZE_1GB : size; - grub_file_read(file, NULL, read); - } - - for (i = 0; start > 0 && i < chunklist->cur_chunk; i++) - { - chunklist->chunk[i].disk_start_sector += start; - chunklist->chunk[i].disk_end_sector += start; - } - - if (ventoy_fs_udf == fs_type) - { - for (i = 0; i < chunklist->cur_chunk; i++) - { - count = (chunklist->chunk[i].disk_end_sector + 1 - chunklist->chunk[i].disk_start_sector) >> 2; - chunklist->chunk[i].img_start_sector = sector; - chunklist->chunk[i].img_end_sector = sector + count - 1; - sector += count; - } - } - } - - len = (int)grub_strlen(file->name); - if ((len > 4 && grub_strncasecmp(file->name + len - 4, ".img", 4) == 0) || - (len > 4 && grub_strncasecmp(file->name + len - 4, ".vhd", 4) == 0) || - (len > 5 && grub_strncasecmp(file->name + len - 5, ".vhdx", 5) == 0) || - (len > 5 && grub_strncasecmp(file->name + len - 5, ".vtoy", 5) == 0)) - { - for (i = 0; i < chunklist->cur_chunk; i++) - { - count = chunklist->chunk[i].disk_end_sector + 1 - chunklist->chunk[i].disk_start_sector; - if (count < 4) - { - count = 1; - } - else - { - count >>= 2; - } - - chunklist->chunk[i].img_start_sector = sector; - chunklist->chunk[i].img_end_sector = sector + count - 1; - sector += count; - } - } - - return 0; -} - -static grub_err_t ventoy_cmd_img_sector(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int rc; - grub_file_t file; - grub_disk_addr_t start; - - (void)ctxt; - (void)argc; - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (!file) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]); - } - - g_conf_replace_node = NULL; - g_conf_replace_offset = 0; - - if (g_img_chunk_list.chunk) - { - grub_free(g_img_chunk_list.chunk); - } - - if (ventoy_get_fs_type(file->fs->name) >= ventoy_fs_max) - { - grub_file_close(file); - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Unsupported filesystem %s\n", file->fs->name); - } - - /* get image chunk data */ - grub_memset(&g_img_chunk_list, 0, sizeof(g_img_chunk_list)); - g_img_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); - if (NULL == g_img_chunk_list.chunk) - { - return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); - } - - g_img_chunk_list.max_chunk = DEFAULT_CHUNK_NUM; - g_img_chunk_list.cur_chunk = 0; - - start = file->device->disk->partition->start; - - ventoy_get_block_list(file, &g_img_chunk_list, start); - - rc = ventoy_check_block_list(file, &g_img_chunk_list, start); - grub_file_close(file); - - if (rc) - { - return grub_error(GRUB_ERR_NOT_IMPLEMENTED_YET, "Unsupported chunk list.\n"); - } - - grub_memset(&g_grub_param->file_replace, 0, sizeof(g_grub_param->file_replace)); - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_select_conf_replace(grub_extcmd_context_t ctxt, int argc, char **args) -{ - grub_uint64_t offset = 0; - grub_uint32_t align = 0; - grub_file_t file = NULL; - conf_replace *node = NULL; - - (void)ctxt; - (void)argc; - (void)args; - - debug("select conf replace argc:%d\n", argc); - - if (argc < 2) - { - return 0; - } - - node = ventoy_plugin_find_conf_replace(args[1]); - if (!node) - { - debug("Conf replace not found for %s\n", args[1]); - goto end; - } - - debug("Find conf replace for %s\n", args[1]); - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(loop)%s", node->orgconf); - if (!file) - { - debug("<(loop)%s> NOT exist\n", node->orgconf); - goto end; - } - - offset = grub_iso9660_get_last_file_dirent_pos(file); - grub_file_close(file); - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[0], node->newconf); - if (!file) - { - debug("New config file <%s%s> NOT exist\n", args[0], node->newconf); - goto end; - } - - align = ((int)file->size + 2047) / 2048 * 2048; - - if (align > vtoy_max_replace_file_size) - { - debug("New config file <%s%s> too big\n", args[0], node->newconf); - goto end; - } - - grub_file_read(file, g_conf_replace_new_buf, file->size); - g_conf_replace_new_len = (int)file->size; - g_conf_replace_new_len_align = align; - - g_conf_replace_node = node; - g_conf_replace_offset = offset + 2; - - debug("conf_replace OK: newlen: %d\n", g_conf_replace_new_len); - -end: - if (file) - { - grub_file_close(file); - } - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int i = 0; - int pos = 0; - char *buf = NULL; - char configfile[128]; - install_template *node = NULL; - - (void)ctxt; - (void)argc; - (void)args; - - debug("select auto installation argc:%d\n", argc); - - if (argc < 1) - { - return 0; - } - - node = ventoy_plugin_find_install_template(args[0]); - if (!node) - { - debug("Auto install template not found for %s\n", args[0]); - return 0; - } - - if (node->autosel >= 0 && node->autosel <= node->templatenum) - { - node->cursel = node->autosel - 1; - debug("Auto install template auto select %d\n", node->autosel); - return 0; - } - - buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF); - if (!buf) - { - return 0; - } - - vtoy_ssprintf(buf, pos, "menuentry \"Boot without auto installation template\" {\n" - " echo %s\n}\n", "123"); - - for (i = 0; i < node->templatenum; i++) - { - vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n" - " echo 123\n}\n", - node->templatepath[i].path); - } - - g_ventoy_menu_esc = 1; - g_ventoy_suppress_esc = 1; - - grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos); - grub_script_execute_sourcecode(configfile); - - g_ventoy_menu_esc = 0; - g_ventoy_suppress_esc = 0; - - grub_free(buf); - - node->cursel = g_ventoy_last_entry - 1; - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int i = 0; - int pos = 0; - char *buf = NULL; - char configfile[128]; - persistence_config *node; - - (void)ctxt; - (void)argc; - (void)args; - - debug("select persistence argc:%d\n", argc); - - if (argc < 1) - { - return 0; - } - - node = ventoy_plugin_find_persistent(args[0]); - if (!node) - { - debug("Persistence image not found for %s\n", args[0]); - return 0; - } - - if (node->autosel >= 0 && node->autosel <= node->backendnum) - { - node->cursel = node->autosel - 1; - debug("Persistence image auto select %d\n", node->autosel); - return 0; - } - - buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF); - if (!buf) - { - return 0; - } - - vtoy_ssprintf(buf, pos, "menuentry \"Boot without persistence\" {\n" - " echo %s\n}\n", "123"); - - for (i = 0; i < node->backendnum; i++) - { - vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n" - " echo 123\n}\n", - node->backendpath[i].path); - - } - - g_ventoy_menu_esc = 1; - g_ventoy_suppress_esc = 1; - - grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos); - grub_script_execute_sourcecode(configfile); - - g_ventoy_menu_esc = 0; - g_ventoy_suppress_esc = 0; - - grub_free(buf); - - node->cursel = g_ventoy_last_entry - 1; - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_dump_img_sector(grub_extcmd_context_t ctxt, int argc, char **args) -{ - grub_uint32_t i; - ventoy_img_chunk *cur; - - (void)ctxt; - (void)argc; - (void)args; - - for (i = 0; i < g_img_chunk_list.cur_chunk; i++) - { - cur = g_img_chunk_list.chunk + i; - grub_printf("image:[%u - %u] <==> disk:[%llu - %llu]\n", - cur->img_start_sector, cur->img_end_sector, - (unsigned long long)cur->disk_start_sector, (unsigned long long)cur->disk_end_sector - ); - } - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_test_block_list(grub_extcmd_context_t ctxt, int argc, char **args) -{ - grub_uint32_t i; - grub_file_t file; - ventoy_img_chunk_list chunklist; - - (void)ctxt; - (void)argc; - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (!file) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]); - } - - /* get image chunk data */ - grub_memset(&chunklist, 0, sizeof(chunklist)); - chunklist.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); - if (NULL == chunklist.chunk) - { - return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); - } - - chunklist.max_chunk = DEFAULT_CHUNK_NUM; - chunklist.cur_chunk = 0; - - ventoy_get_block_list(file, &chunklist, 0); - - if (0 != ventoy_check_block_list(file, &chunklist, 0)) - { - grub_printf("########## UNSUPPORTED ###############\n"); - } - - grub_printf("filesystem: <%s> entry number:<%u>\n", file->fs->name, chunklist.cur_chunk); - - for (i = 0; i < chunklist.cur_chunk; i++) - { - grub_printf("%llu+%llu,", (ulonglong)chunklist.chunk[i].disk_start_sector, - (ulonglong)(chunklist.chunk[i].disk_end_sector + 1 - chunklist.chunk[i].disk_start_sector)); - } - - grub_printf("\n==================================\n"); - - for (i = 0; i < chunklist.cur_chunk; i++) - { - grub_printf("%2u: [%llu %llu] - [%llu %llu]\n", i, - (ulonglong)chunklist.chunk[i].img_start_sector, - (ulonglong)chunklist.chunk[i].img_end_sector, - (ulonglong)chunklist.chunk[i].disk_start_sector, - (ulonglong)chunklist.chunk[i].disk_end_sector - ); - } - - grub_free(chunklist.chunk); - grub_file_close(file); - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_add_replace_file(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int i; - ventoy_grub_param_file_replace *replace = NULL; - - (void)ctxt; - (void)argc; - (void)args; - - if (argc >= 2) - { - replace = &(g_grub_param->file_replace); - replace->magic = GRUB_FILE_REPLACE_MAGIC; - - replace->old_name_cnt = 0; - for (i = 0; i < 4 && i + 1 < argc; i++) - { - replace->old_name_cnt++; - grub_snprintf(replace->old_file_name[i], sizeof(replace->old_file_name[i]), "%s", args[i + 1]); - } - - replace->new_file_virtual_id = (grub_uint32_t)grub_strtoul(args[0], NULL, 10); - } - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_dump_menu(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - (void)argc; - (void)args; - - if (argc == 0) - { - grub_printf("List Mode: CurLen:%d MaxLen:%u\n", g_list_script_pos, VTOY_MAX_SCRIPT_BUF); - grub_printf("%s", g_list_script_buf); - } - else - { - grub_printf("Tree Mode: CurLen:%d MaxLen:%u\n", g_tree_script_pos, VTOY_MAX_SCRIPT_BUF); - grub_printf("%s", g_tree_script_buf); - } - - return 0; -} - -static grub_err_t ventoy_cmd_dump_img_list(grub_extcmd_context_t ctxt, int argc, char **args) -{ - img_info *cur = g_ventoy_img_list; - - (void)ctxt; - (void)argc; - (void)args; - - while (cur) - { - grub_printf("path:<%s> id=%d list_index=%d\n", cur->path, cur->id, cur->plugin_list_index); - grub_printf("name:<%s>\n\n", cur->name); - cur = cur->next; - } - - return 0; -} - -static grub_err_t ventoy_cmd_dump_injection(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - (void)argc; - (void)args; - - ventoy_plugin_dump_injection(); - - return 0; -} - -static grub_err_t ventoy_cmd_dump_auto_install(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - (void)argc; - (void)args; - - ventoy_plugin_dump_auto_install(); - - return 0; -} - -static grub_err_t ventoy_cmd_dump_persistence(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - (void)argc; - (void)args; - - ventoy_plugin_dump_persistence(); - - return 0; -} - -static grub_err_t ventoy_cmd_check_mode(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - (void)argc; - (void)args; - - if (argc != 1) - { - return 1; - } - - if (args[0][0] == '0') - { - return g_ventoy_memdisk_mode ? 0 : 1; - } - else if (args[0][0] == '1') - { - return g_ventoy_iso_raw ? 0 : 1; - } - else if (args[0][0] == '2') - { - return g_ventoy_iso_uefi_drv ? 0 : 1; - } - else if (args[0][0] == '3') - { - return g_ventoy_grub2_mode ? 0 : 1; - } - - return 1; -} - -static grub_err_t ventoy_cmd_dynamic_menu(grub_extcmd_context_t ctxt, int argc, char **args) -{ - static int configfile_mode = 0; - char memfile[128] = {0}; - - (void)ctxt; - (void)argc; - (void)args; - - /* - * args[0]: 0:normal 1:configfile - * args[1]: 0:list_buf 1:tree_buf - */ - - if (argc != 2) - { - debug("Invalid argc %d\n", argc); - return 0; - } - - if (args[0][0] == '0') - { - if (args[1][0] == '0') - { - grub_script_execute_sourcecode(g_list_script_buf); - } - else - { - grub_script_execute_sourcecode(g_tree_script_buf); - } - } - else - { - if (configfile_mode) - { - debug("Now already in F3 mode %d\n", configfile_mode); - return 0; - } - - if (args[1][0] == '0') - { - grub_snprintf(memfile, sizeof(memfile), "configfile mem:0x%llx:size:%d", - (ulonglong)(ulong)g_list_script_buf, g_list_script_pos); - } - else - { - g_ventoy_last_entry = -1; - grub_snprintf(memfile, sizeof(memfile), "configfile mem:0x%llx:size:%d", - (ulonglong)(ulong)g_tree_script_buf, g_tree_script_pos); - } - - configfile_mode = 1; - grub_script_execute_sourcecode(memfile); - configfile_mode = 0; - } - - return 0; -} - -static grub_err_t ventoy_cmd_file_exist_nocase(grub_extcmd_context_t ctxt, int argc, char **args) -{ - grub_file_t file; - - (void)ctxt; - - if (argc != 1) - { - return 1; - } - - g_ventoy_case_insensitive = 1; - file = grub_file_open(args[0], VENTOY_FILE_TYPE); - g_ventoy_case_insensitive = 0; - - grub_errno = 0; - - if (file) - { - grub_file_close(file); - return 0; - } - return 1; -} - -static grub_err_t ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int id = 0; - int find = 0; - grub_disk_t disk; - const char *isopath = NULL; - char hdname[32]; - ventoy_mbr_head mbr; - - (void)ctxt; - (void)argc; - - if (argc != 1) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s variable\n", cmd_raw_name); - } - - isopath = grub_env_get("vtoy_iso_part"); - if (!isopath) - { - debug("isopath is null %p\n", isopath); - return 0; - } - - debug("isopath is %s\n", isopath); - - for (id = 0; id < 30 && (find == 0); id++) - { - grub_snprintf(hdname, sizeof(hdname), "hd%d,", id); - if (grub_strstr(isopath, hdname)) - { - debug("skip %s ...\n", hdname); - continue; - } - - grub_snprintf(hdname, sizeof(hdname), "hd%d", id); - - disk = grub_disk_open(hdname); - if (!disk) - { - debug("%s not exist\n", hdname); - break; - } - - grub_memset(&mbr, 0, sizeof(mbr)); - if (0 == grub_disk_read(disk, 0, 0, 512, &mbr)) - { - if (mbr.Byte55 == 0x55 && mbr.ByteAA == 0xAA) - { - if (mbr.PartTbl[0].Active == 0x80 || mbr.PartTbl[1].Active == 0x80 || - mbr.PartTbl[2].Active == 0x80 || mbr.PartTbl[3].Active == 0x80) - { - - grub_env_set(args[0], hdname); - find = 1; - } - } - debug("%s is %s\n", hdname, find ? "bootable" : "NOT bootable"); - } - else - { - debug("read %s failed\n", hdname); - } - - grub_disk_close(disk); - } - - return 0; -} - -static grub_err_t ventoy_cmd_read_1st_line(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int len = 1024; - grub_file_t file; - char *buf = NULL; - - (void)ctxt; - (void)argc; - - if (argc != 2) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s file var \n", cmd_raw_name); - } - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (!file) - { - debug("failed to open file %s\n", args[0]); - return 0; - } - - buf = grub_malloc(len); - if (!buf) - { - goto end; - } - - buf[len - 1] = 0; - grub_file_read(file, buf, len - 1); - - ventoy_get_line(buf); - ventoy_set_env(args[1], buf); - -end: - - grub_check_free(buf); - grub_file_close(file); - - return 0; -} - -static int ventoy_img_partition_callback (struct grub_disk *disk, const grub_partition_t partition, void *data) -{ - (void)disk; - (void)data; - - g_part_list_pos += grub_snprintf(g_part_list_buf + g_part_list_pos, VTOY_MAX_SCRIPT_BUF - g_part_list_pos, - "0 %llu linear /dev/ventoy %llu\n", - (ulonglong)partition->len, (ulonglong)partition->start); - - return 0; -} - -static grub_err_t ventoy_cmd_img_part_info(grub_extcmd_context_t ctxt, int argc, char **args) -{ - char *device_name = NULL; - grub_device_t dev = NULL; - char buf[64]; - - (void)ctxt; - - g_part_list_pos = 0; - grub_env_unset("vtoy_img_part_file"); - - if (argc != 1) - { - return 1; - } - - device_name = grub_file_get_device_name(args[0]); - if (!device_name) - { - debug("ventoy_cmd_img_part_info failed, %s\n", args[0]); - goto end; - } - - dev = grub_device_open(device_name); - if (!dev) - { - debug("grub_device_open failed, %s\n", device_name); - goto end; - } - - grub_partition_iterate(dev->disk, ventoy_img_partition_callback, NULL); - - grub_snprintf(buf, sizeof(buf), "newc:vtoy_dm_table:mem:0x%llx:size:%d", (ulonglong)(ulong)g_part_list_buf, g_part_list_pos); - grub_env_set("vtoy_img_part_file", buf); - -end: - - check_free(device_name, grub_free); - check_free(dev, grub_device_close); - - return 0; -} - - -static grub_err_t ventoy_cmd_file_strstr(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int rc = 1; - grub_file_t file; - char *buf = NULL; - - (void)ctxt; - (void)argc; - - if (argc != 2) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s file str \n", cmd_raw_name); - } - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (!file) - { - debug("failed to open file %s\n", args[0]); - return 1; - } - - buf = grub_malloc(file->size + 1); - if (!buf) - { - goto end; - } - - buf[file->size] = 0; - grub_file_read(file, buf, file->size); - - if (grub_strstr(buf, args[1])) - { - rc = 0; - } - -end: - - grub_check_free(buf); - grub_file_close(file); - - return rc; -} - -static grub_err_t ventoy_cmd_parse_volume(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int len; - grub_file_t file; - char buf[64]; - grub_uint64_t size; - ventoy_iso9660_vd pvd; - - (void)ctxt; - (void)argc; - - if (argc != 4) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s sysid volid space \n", cmd_raw_name); - } - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (!file) - { - debug("failed to open file %s\n", args[0]); - return 0; - } - - grub_file_seek(file, 16 * 2048); - len = (int)grub_file_read(file, &pvd, sizeof(pvd)); - if (len != sizeof(pvd)) - { - debug("failed to read pvd %d\n", len); - goto end; - } - - grub_memset(buf, 0, sizeof(buf)); - grub_memcpy(buf, pvd.sys, sizeof(pvd.sys)); - ventoy_set_env(args[1], buf); - - grub_memset(buf, 0, sizeof(buf)); - grub_memcpy(buf, pvd.vol, sizeof(pvd.vol)); - ventoy_set_env(args[2], buf); - - size = pvd.space; - size *= 2048; - grub_snprintf(buf, sizeof(buf), "%llu", (ulonglong)size); - ventoy_set_env(args[3], buf); - -end: - grub_file_close(file); - - return 0; -} - -static grub_err_t ventoy_cmd_parse_create_date(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int len; - grub_file_t file; - char buf[64]; - - (void)ctxt; - (void)argc; - - if (argc != 2) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s var \n", cmd_raw_name); - } - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (!file) - { - debug("failed to open file %s\n", args[0]); - return 0; - } - - grub_memset(buf, 0, sizeof(buf)); - grub_file_seek(file, 16 * 2048 + 813); - len = (int)grub_file_read(file, buf, 17); - if (len != 17) - { - debug("failed to read create date %d\n", len); - goto end; - } - - ventoy_set_env(args[1], buf); - -end: - grub_file_close(file); - - return 0; -} - -static grub_err_t ventoy_cmd_img_hook_root(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - (void)argc; - (void)args; - - ventoy_env_hook_root(1); - - return 0; -} - -static grub_err_t ventoy_cmd_img_unhook_root(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - (void)argc; - (void)args; - - ventoy_env_hook_root(0); - - return 0; -} - -#ifdef GRUB_MACHINE_EFI -static grub_err_t ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int ret = 1; - grub_uint8_t *var; - grub_size_t size; - grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; - - (void)ctxt; - (void)argc; - (void)args; - - var = grub_efi_get_variable("SecureBoot", &global, &size); - if (var && *var == 1) - { - return 0; - } - - return ret; -} -#else -static grub_err_t ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - (void)argc; - (void)args; - return 1; -} -#endif - -static grub_err_t ventoy_cmd_img_check_range(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int i; - int ret = 1; - grub_file_t file; - grub_uint64_t FileSectors = 0; - ventoy_gpt_info *gpt = NULL; - ventoy_part_table *pt = NULL; - grub_uint8_t zeroguid[16] = {0}; - - (void)ctxt; - (void)argc; - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (!file) - { - debug("failed to open file %s\n", args[0]); - return 1; - } - - if (file->size % 512) - { - debug("unaligned file size: %llu\n", (ulonglong)file->size); - goto out; - } - - gpt = grub_zalloc(sizeof(ventoy_gpt_info)); - if (!gpt) - { - goto out; - } - - FileSectors = file->size / 512; - - grub_file_read(file, gpt, sizeof(ventoy_gpt_info)); - if (grub_strncmp(gpt->Head.Signature, "EFI PART", 8) == 0) - { - debug("This is EFI partition table\n"); - - for (i = 0; i < 128; i++) - { - if (grub_memcmp(gpt->PartTbl[i].PartGuid, zeroguid, 16)) - { - if (FileSectors < gpt->PartTbl[i].LastLBA) - { - debug("out of range: part[%d] LastLBA:%llu FileSectors:%llu\n", i, - (ulonglong)gpt->PartTbl[i].LastLBA, (ulonglong)FileSectors); - goto out; - } - } - } - } - else - { - debug("This is MBR partition table\n"); - - for (i = 0; i < 4; i++) - { - pt = gpt->MBR.PartTbl + i; - if (FileSectors < pt->StartSectorId + pt->SectorCount) - { - debug("out of range: part[%d] LastLBA:%llu FileSectors:%llu\n", i, - (ulonglong)(pt->StartSectorId + pt->SectorCount), - (ulonglong)FileSectors); - goto out; - } - } - } - - ret = 0; - -out: - grub_file_close(file); - grub_check_free(gpt); - grub_errno = GRUB_ERR_NONE; - return ret; -} - -static grub_err_t ventoy_cmd_clear_key(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int i; - int ret; - - (void)ctxt; - (void)argc; - (void)args; - - for (i = 0; i < 500; i++) - { - ret = grub_getkey_noblock(); - if (ret == GRUB_TERM_NO_KEY) - { - break; - } - } - - if (i >= 500) - { - grub_cls(); - grub_printf("\n\n Still have key input after clear.\n"); - grub_refresh(); - grub_sleep(5); - } - - return 0; -} - -static grub_err_t ventoy_cmd_acpi_param(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int i; - int buflen; - int datalen; - int loclen; - int img_chunk_num; - int image_sector_size; - char cmd[64]; - ventoy_chain_head *chain; - ventoy_img_chunk *chunk; - ventoy_os_param *osparam; - ventoy_image_location *location; - ventoy_image_disk_region *region; - struct grub_acpi_table_header *acpi; - - (void)ctxt; - - if (argc != 2) - { - return 1; - } - - debug("ventoy_cmd_acpi_param %s %s\n", args[0], args[1]); - - chain = (ventoy_chain_head *)(ulong)grub_strtoul(args[0], NULL, 16); - if (!chain) - { - return 1; - } - - image_sector_size = (int)grub_strtol(args[1], NULL, 10); - - if (grub_memcmp(&g_ventoy_guid, &(chain->os_param.guid), 16)) - { - debug("Invalid ventoy guid 0x%x\n", chain->os_param.guid.data1); - return 1; - } - - img_chunk_num = chain->img_chunk_num; - - loclen = sizeof(ventoy_image_location) + (img_chunk_num - 1) * sizeof(ventoy_image_disk_region); - datalen = sizeof(ventoy_os_param) + loclen; - - buflen = sizeof(struct grub_acpi_table_header) + datalen; - acpi = grub_zalloc(buflen); - if (!acpi) - { - return 1; - } - - /* Step1: Fill acpi table header */ - grub_memcpy(acpi->signature, "VTOY", 4); - acpi->length = buflen; - acpi->revision = 1; - grub_memcpy(acpi->oemid, "VENTOY", 6); - grub_memcpy(acpi->oemtable, "OSPARAMS", 8); - acpi->oemrev = 1; - acpi->creator_id[0] = 1; - acpi->creator_rev = 1; - - /* Step2: Fill data */ - osparam = (ventoy_os_param *)(acpi + 1); - grub_memcpy(osparam, &chain->os_param, sizeof(ventoy_os_param)); - osparam->vtoy_img_location_addr = 0; - osparam->vtoy_img_location_len = loclen; - osparam->chksum = 0; - osparam->chksum = 0x100 - grub_byte_checksum(osparam, sizeof(ventoy_os_param)); - - location = (ventoy_image_location *)(osparam + 1); - grub_memcpy(&location->guid, &osparam->guid, sizeof(ventoy_guid)); - location->image_sector_size = image_sector_size; - location->disk_sector_size = chain->disk_sector_size; - location->region_count = img_chunk_num; - - region = location->regions; - chunk = (ventoy_img_chunk *)((char *)chain + chain->img_chunk_offset); - if (512 == image_sector_size) - { - for (i = 0; i < img_chunk_num; i++) - { - region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1; - region->image_start_sector = chunk->img_start_sector * 4; - region->disk_start_sector = chunk->disk_start_sector; - region++; - chunk++; - } - } - else - { - for (i = 0; i < img_chunk_num; i++) - { - region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1; - region->image_start_sector = chunk->img_start_sector; - region->disk_start_sector = chunk->disk_start_sector; - region++; - chunk++; - } - } - - /* Step3: Fill acpi checksum */ - acpi->checksum = 0; - acpi->checksum = 0x100 - grub_byte_checksum(acpi, acpi->length); - - /* load acpi table */ - grub_snprintf(cmd, sizeof(cmd), "acpi mem:0x%lx:size:%d", (ulong)acpi, acpi->length); - grub_script_execute_sourcecode(cmd); - - grub_free(acpi); - - VENTOY_CMD_RETURN(0); -} - -static grub_err_t ventoy_cmd_push_last_entry(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - (void)argc; - (void)args; - - g_ventoy_last_entry_back = g_ventoy_last_entry; - g_ventoy_last_entry = -1; - - return 0; -} - -static grub_err_t ventoy_cmd_pop_last_entry(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - (void)argc; - (void)args; - - g_ventoy_last_entry = g_ventoy_last_entry_back; - - return 0; -} - -grub_uint64_t ventoy_get_part1_size(ventoy_gpt_info *gpt) -{ - grub_uint64_t sectors; - - if (grub_strncmp(gpt->Head.Signature, "EFI PART", 8) == 0) - { - sectors = gpt->PartTbl[0].LastLBA + 1 - gpt->PartTbl[0].StartLBA; - } - else - { - sectors = gpt->MBR.PartTbl[0].SectorCount; - } - - return sectors * 512; -} - -static int ventoy_lib_module_callback(const char *filename, const struct grub_dirhook_info *info, void *data) -{ - const char *pos = filename + 1; - - if (info->dir) - { - while (*pos) - { - if (*pos == '.') - { - if ((*(pos - 1) >= '0' && *(pos - 1) <= '9') && (*(pos + 1) >= '0' && *(pos + 1) <= '9')) - { - grub_strncpy((char *)data, filename, 128); - return 1; - } - } - pos++; - } - } - - return 0; -} - -static grub_err_t ventoy_cmd_lib_module_ver(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int rc = 1; - char *device_name = NULL; - grub_device_t dev = NULL; - grub_fs_t fs = NULL; - char buf[128] = {0}; - - (void)ctxt; - - if (argc != 3) - { - debug("ventoy_cmd_lib_module_ver, invalid param num %d\n", argc); - return 1; - } - - debug("ventoy_cmd_lib_module_ver %s %s %s\n", args[0], args[1], args[2]); - - device_name = grub_file_get_device_name(args[0]); - if (!device_name) - { - debug("grub_file_get_device_name failed, %s\n", args[0]); - goto end; - } - - dev = grub_device_open(device_name); - if (!dev) - { - debug("grub_device_open failed, %s\n", device_name); - goto end; - } - - fs = grub_fs_probe(dev); - if (!fs) - { - debug("grub_fs_probe failed, %s\n", device_name); - goto end; - } - - fs->fs_dir(dev, args[1], ventoy_lib_module_callback, buf); - - if (buf[0]) - { - ventoy_set_env(args[2], buf); - } - - rc = 0; - -end: - - check_free(device_name, grub_free); - check_free(dev, grub_device_close); - - return rc; -} - -static grub_err_t ventoy_cmd_load_part_table(grub_extcmd_context_t ctxt, int argc, char **args) -{ - char name[64]; - int ret; - grub_disk_t disk; - grub_device_t dev; - - (void)argc; - (void)ctxt; - - g_ventoy_part_info = grub_zalloc(sizeof(ventoy_gpt_info)); - if (!g_ventoy_part_info) - { - return 1; - } - - disk = grub_disk_open(args[0]); - if (!disk) - { - debug("Failed to open disk %s\n", args[0]); - return 1; - } - - g_ventoy_disk_size = disk->total_sectors * (1U << disk->log_sector_size); - - grub_disk_read(disk, 0, 0, sizeof(ventoy_gpt_info), g_ventoy_part_info); - grub_disk_close(disk); - - grub_snprintf(name, sizeof(name), "%s,1", args[0]); - dev = grub_device_open(name); - if (dev) - { - /* make sure that we are running in a correct Ventoy device */ - ret = ventoy_check_device(dev); - grub_device_close(dev); - - if (ret) - { - grub_exit(); - } - } - - return 0; -} - -static grub_err_t ventoy_cmd_check_custom_boot(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int ret = 1; - const char *vcfg = NULL; - - (void)argc; - (void)ctxt; - - vcfg = ventoy_plugin_get_custom_boot(args[0]); - if (vcfg) - { - debug("custom boot <%s>:<%s>\n", args[0], vcfg); - grub_env_set(args[1], vcfg); - ret = 0; - } - else - { - debug("custom boot <%s>:\n", args[0]); - } - - grub_errno = 0; - return ret; -} - - -static grub_err_t ventoy_cmd_part_exist(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int id; - grub_uint8_t zeroguid[16] = {0}; - - (void)argc; - (void)ctxt; - - id = (int)grub_strtoul(args[0], NULL, 10); - grub_errno = 0; - - if (grub_memcmp(g_ventoy_part_info->Head.Signature, "EFI PART", 8) == 0) - { - if (id >= 1 && id <= 128) - { - if (grub_memcmp(g_ventoy_part_info->PartTbl[id - 1].PartGuid, zeroguid, 16)) - { - return 0; - } - } - } - else - { - if (id >= 1 && id <= 4) - { - if (g_ventoy_part_info->MBR.PartTbl[id - 1].FsFlag) - { - return 0; - } - } - } - - return 1; -} - -static grub_err_t ventoy_cmd_get_fs_label(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int rc = 1; - char *device_name = NULL; - grub_device_t dev = NULL; - grub_fs_t fs = NULL; - char *label = NULL; - - (void)ctxt; - - debug("get fs label for %s\n", args[0]); - - if (argc != 2) - { - debug("ventoy_cmd_get_fs_label, invalid param num %d\n", argc); - return 1; - } - - device_name = grub_file_get_device_name(args[0]); - if (!device_name) - { - debug("grub_file_get_device_name failed, %s\n", args[0]); - goto end; - } - - dev = grub_device_open(device_name); - if (!dev) - { - debug("grub_device_open failed, %s\n", device_name); - goto end; - } - - fs = grub_fs_probe(dev); - if (NULL == fs || NULL == fs->fs_label) - { - debug("grub_fs_probe failed, %s %p %p\n", device_name, fs, fs->fs_label); - goto end; - } - - fs->fs_label(dev, &label); - if (label) - { - debug("label=<%s>\n", label); - ventoy_set_env(args[1], label); - grub_free(label); - } - - rc = 0; - -end: - - check_free(device_name, grub_free); - check_free(dev, grub_device_close); - - return rc; -} - -static int ventoy_fs_enum_1st_file(const char *filename, const struct grub_dirhook_info *info, void *data) -{ - if (!info->dir) - { - grub_snprintf((char *)data, 256, "%s", filename); - return 1; - } - - return 0; -} - - -static grub_err_t ventoy_cmd_fs_enum_1st_file(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int rc = 1; - char *device_name = NULL; - grub_device_t dev = NULL; - grub_fs_t fs = NULL; - char name[256] ={0}; - - (void)ctxt; - - if (argc != 3) - { - debug("ventoy_cmd_fs_enum_1st_file, invalid param num %d\n", argc); - return 1; - } - - device_name = grub_file_get_device_name(args[0]); - if (!device_name) - { - debug("grub_file_get_device_name failed, %s\n", args[0]); - goto end; - } - - dev = grub_device_open(device_name); - if (!dev) - { - debug("grub_device_open failed, %s\n", device_name); - goto end; - } - - fs = grub_fs_probe(dev); - if (!fs) - { - debug("grub_fs_probe failed, %s\n", device_name); - goto end; - } - - fs->fs_dir(dev, args[1], ventoy_fs_enum_1st_file, name); - if (name[0]) - { - ventoy_set_env(args[2], name); - } - - rc = 0; - -end: - - check_free(device_name, grub_free); - check_free(dev, grub_device_close); - - return rc; -} - -static grub_err_t ventoy_cmd_basename(grub_extcmd_context_t ctxt, int argc, char **args) -{ - char c; - char *pos = NULL; - char *end = NULL; - - (void)ctxt; - - if (argc != 2) - { - debug("ventoy_cmd_basename, invalid param num %d\n", argc); - return 1; - } - - for (pos = args[0]; *pos; pos++) - { - if (*pos == '.') - { - end = pos; - } - } - - if (end) - { - c = *end; - *end = 0; - } - - grub_env_set(args[1], args[0]); - - if (end) - { - *end = c; - } - - return 0; -} - -static grub_err_t ventoy_cmd_basefile(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int i; - int len; - const char *buf; - - (void)ctxt; - - if (argc != 2) - { - debug("ventoy_cmd_basefile, invalid param num %d\n", argc); - return 1; - } - - buf = args[0]; - len = (int)grub_strlen(buf); - for (i = len; i > 0; i--) - { - if (buf[i - 1] == '/') - { - grub_env_set(args[1], buf + i); - return 0; - } - } - - grub_env_set(args[1], buf); - - return 0; -} - -static grub_err_t ventoy_cmd_enum_video_mode(grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_video_mode_info info; - char buf[32]; - - (void)ctxt; - (void)argc; - (void)args; - - if (!g_video_mode_list) - { - ventoy_enum_video_mode(); - } - - if (grub_video_get_info(&info) == GRUB_ERR_NONE) - { - grub_snprintf(buf, sizeof(buf), "Resolution (%ux%u)", info.width, info.height); - } - else - { - grub_snprintf(buf, sizeof(buf), "Resolution (0x0)"); - } - - grub_env_set("VTOY_CUR_VIDEO_MODE", buf); - - grub_snprintf(buf, sizeof(buf), "%d", g_video_mode_num); - grub_env_set("VTOY_VIDEO_MODE_NUM", buf); - - VENTOY_CMD_RETURN(0); -} - -static grub_err_t vt_cmd_update_cur_video_mode(grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_video_mode_info info; - char buf[32]; - - (void)ctxt; - (void)argc; - (void)args; - - if (grub_video_get_info(&info) == GRUB_ERR_NONE) - { - grub_snprintf(buf, sizeof(buf), "%ux%ux%u", info.width, info.height, info.bpp); - } - else - { - grub_snprintf(buf, sizeof(buf), "0x0x0"); - } - - grub_env_set(args[0], buf); - - VENTOY_CMD_RETURN(0); -} - -static grub_err_t ventoy_cmd_get_video_mode(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int id; - char buf[32]; - - (void)ctxt; - (void)argc; - - if (!g_video_mode_list) - { - return 0; - } - - id = (int)grub_strtoul(args[0], NULL, 10); - if (id < g_video_mode_num) - { - grub_snprintf(buf, sizeof(buf), "%ux%ux%u", - g_video_mode_list[id].width, g_video_mode_list[id].height, g_video_mode_list[id].bpp); - } - - grub_env_set(args[1], buf); - - VENTOY_CMD_RETURN(0); -} - -grub_uint64_t ventoy_grub_get_file_size(const char *fmt, ...) -{ - grub_uint64_t size = 0; - grub_file_t file; - va_list ap; - char fullpath[256] = {0}; - - va_start (ap, fmt); - grub_vsnprintf(fullpath, 255, fmt, ap); - va_end (ap); - - file = grub_file_open(fullpath, VENTOY_FILE_TYPE); - if (!file) - { - debug("grub_file_open failed <%s>\n", fullpath); - grub_errno = 0; - return 0; - } - - size = file->size; - grub_file_close(file); - return size; -} - -grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...) -{ - va_list ap; - grub_file_t file; - char fullpath[256] = {0}; - - va_start (ap, fmt); - grub_vsnprintf(fullpath, 255, fmt, ap); - va_end (ap); - - file = grub_file_open(fullpath, type); - if (!file) - { - debug("grub_file_open failed <%s> %d\n", fullpath, grub_errno); - grub_errno = 0; - } - - return file; -} - -int ventoy_is_file_exist(const char *fmt, ...) -{ - va_list ap; - int len; - char *pos = NULL; - char buf[256] = {0}; - - grub_snprintf(buf, sizeof(buf), "%s", "[ -f \""); - pos = buf + 6; - - va_start (ap, fmt); - len = grub_vsnprintf(pos, 255, fmt, ap); - va_end (ap); - - grub_strncpy(pos + len, "\" ]", 3); - - debug("script exec %s\n", buf); - - if (0 == grub_script_execute_sourcecode(buf)) - { - return 1; - } - - return 0; -} - -int ventoy_is_dir_exist(const char *fmt, ...) -{ - va_list ap; - int len; - char *pos = NULL; - char buf[256] = {0}; - - grub_snprintf(buf, sizeof(buf), "%s", "[ -d \""); - pos = buf + 6; - - va_start (ap, fmt); - len = grub_vsnprintf(pos, 255, fmt, ap); - va_end (ap); - - grub_strncpy(pos + len, "\" ]", 3); - - debug("script exec %s\n", buf); - - if (0 == grub_script_execute_sourcecode(buf)) - { - return 1; - } - - return 0; -} - -int ventoy_gzip_compress(void *mem_in, int mem_in_len, void *mem_out, int mem_out_len) -{ - mz_stream s; - grub_uint8_t *outbuf; - grub_uint8_t gzHdr[10] = - { - 0x1F, 0x8B, /* magic */ - 8, /* z method */ - 0, /* flags */ - 0,0,0,0, /* mtime */ - 4, /* xfl */ - 3, /* OS */ - }; - - grub_memset(&s, 0, sizeof(mz_stream)); - - mz_deflateInit2(&s, 1, MZ_DEFLATED, -MZ_DEFAULT_WINDOW_BITS, 6, MZ_DEFAULT_STRATEGY); - - outbuf = (grub_uint8_t *)mem_out; - - mem_out_len -= sizeof(gzHdr) + 8; - grub_memcpy(outbuf, gzHdr, sizeof(gzHdr)); - outbuf += sizeof(gzHdr); - - s.avail_in = mem_in_len; - s.next_in = mem_in; - - s.avail_out = mem_out_len; - s.next_out = outbuf; - - mz_deflate(&s, MZ_FINISH); - - mz_deflateEnd(&s); - - outbuf += s.total_out; - *(grub_uint32_t *)outbuf = grub_getcrc32c(0, outbuf, s.total_out); - *(grub_uint32_t *)(outbuf + 4) = (grub_uint32_t)(s.total_out); - - return s.total_out + sizeof(gzHdr) + 8; -} - -static int ventoy_env_init(void) -{ - char buf[64]; - - grub_env_set("vtdebug_flag", ""); - - g_part_list_buf = grub_malloc(VTOY_PART_BUF_LEN); - g_tree_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); - g_list_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); - g_conf_replace_new_buf = grub_malloc(vtoy_max_replace_file_size); - - ventoy_filt_register(0, ventoy_wrapper_open); - - g_grub_param = (ventoy_grub_param *)grub_zalloc(sizeof(ventoy_grub_param)); - if (g_grub_param) - { - g_grub_param->grub_env_get = grub_env_get; - g_grub_param->grub_env_set = (grub_env_set_pf)grub_env_set; - g_grub_param->grub_env_printf = (grub_env_printf_pf)grub_printf; - grub_snprintf(buf, sizeof(buf), "%p", g_grub_param); - grub_env_set("env_param", buf); - grub_env_set("ventoy_env_param", buf); - - grub_env_export("env_param"); - grub_env_export("ventoy_env_param"); - } - - return 0; -} - -static cmd_para ventoy_cmds[] = -{ - { "vt_incr", ventoy_cmd_incr, 0, NULL, "{Var} {INT}", "Increase integer variable", NULL }, - { "vt_mod", ventoy_cmd_mod, 0, NULL, "{Int} {Int} {Var}", "mod integer variable", NULL }, - { "vt_strstr", ventoy_cmd_strstr, 0, NULL, "", "", NULL }, - { "vt_str_begin", ventoy_cmd_strbegin, 0, NULL, "", "", NULL }, - { "vt_debug", ventoy_cmd_debug, 0, NULL, "{on|off}", "turn debug on/off", NULL }, - { "vtdebug", ventoy_cmd_debug, 0, NULL, "{on|off}", "turn debug on/off", NULL }, - { "vtbreak", ventoy_cmd_break, 0, NULL, "{level}", "set debug break", NULL }, - { "vt_cmp", ventoy_cmd_cmp, 0, NULL, "{Int1} { eq|ne|gt|lt|ge|le } {Int2}", "Comare two integers", NULL }, - { "vt_device", ventoy_cmd_device, 0, NULL, "path var", "", NULL }, - { "vt_check_compatible", ventoy_cmd_check_compatible, 0, NULL, "", "", NULL }, - { "vt_list_img", ventoy_cmd_list_img, 0, NULL, "{device} {cntvar}", "find all iso file in device", NULL }, - { "vt_clear_img", ventoy_cmd_clear_img, 0, NULL, "", "clear image list", NULL }, - { "vt_img_name", ventoy_cmd_img_name, 0, NULL, "{imageID} {var}", "get image name", NULL }, - { "vt_chosen_img_path", ventoy_cmd_chosen_img_path, 0, NULL, "{var}", "get chosen img path", NULL }, - { "vt_ext_select_img_path", ventoy_cmd_ext_select_img_path, 0, NULL, "{var}", "select chosen img path", NULL }, - { "vt_img_sector", ventoy_cmd_img_sector, 0, NULL, "{imageName}", "", NULL }, - { "vt_dump_img_sector", ventoy_cmd_dump_img_sector, 0, NULL, "", "", NULL }, - { "vt_load_wimboot", ventoy_cmd_load_wimboot, 0, NULL, "", "", NULL }, - { "vt_load_vhdboot", ventoy_cmd_load_vhdboot, 0, NULL, "", "", NULL }, - { "vt_patch_vhdboot", ventoy_cmd_patch_vhdboot, 0, NULL, "", "", NULL }, - { "vt_raw_chain_data", ventoy_cmd_raw_chain_data, 0, NULL, "", "", NULL }, - { "vt_get_vtoy_type", ventoy_cmd_get_vtoy_type, 0, NULL, "", "", NULL }, - { "vt_check_custom_boot", ventoy_cmd_check_custom_boot, 0, NULL, "", "", NULL }, - { "vt_dump_custom_boot", ventoy_cmd_dump_custom_boot, 0, NULL, "", "", NULL }, - - { "vt_skip_svd", ventoy_cmd_skip_svd, 0, NULL, "", "", NULL }, - { "vt_cpio_busybox64", ventoy_cmd_cpio_busybox_64, 0, NULL, "", "", NULL }, - { "vt_load_cpio", ventoy_cmd_load_cpio, 0, NULL, "", "", NULL }, - { "vt_trailer_cpio", ventoy_cmd_trailer_cpio, 0, NULL, "", "", NULL }, - { "vt_push_last_entry", ventoy_cmd_push_last_entry, 0, NULL, "", "", NULL }, - { "vt_pop_last_entry", ventoy_cmd_pop_last_entry, 0, NULL, "", "", NULL }, - { "vt_get_lib_module_ver", ventoy_cmd_lib_module_ver, 0, NULL, "", "", NULL }, - - { "vt_load_part_table", ventoy_cmd_load_part_table, 0, NULL, "", "", NULL }, - { "vt_check_part_exist", ventoy_cmd_part_exist, 0, NULL, "", "", NULL }, - { "vt_get_fs_label", ventoy_cmd_get_fs_label, 0, NULL, "", "", NULL }, - { "vt_fs_enum_1st_file", ventoy_cmd_fs_enum_1st_file, 0, NULL, "", "", NULL }, - { "vt_file_basename", ventoy_cmd_basename, 0, NULL, "", "", NULL }, - { "vt_file_basefile", ventoy_cmd_basefile, 0, NULL, "", "", NULL }, - { "vt_enum_video_mode", ventoy_cmd_enum_video_mode, 0, NULL, "", "", NULL }, - { "vt_get_video_mode", ventoy_cmd_get_video_mode, 0, NULL, "", "", NULL }, - { "vt_update_cur_video_mode", vt_cmd_update_cur_video_mode, 0, NULL, "", "", NULL }, - - - { "vt_find_first_bootable_hd", ventoy_cmd_find_bootable_hdd, 0, NULL, "", "", NULL }, - { "vt_dump_menu", ventoy_cmd_dump_menu, 0, NULL, "", "", NULL }, - { "vt_dynamic_menu", ventoy_cmd_dynamic_menu, 0, NULL, "", "", NULL }, - { "vt_check_mode", ventoy_cmd_check_mode, 0, NULL, "", "", NULL }, - { "vt_dump_img_list", ventoy_cmd_dump_img_list, 0, NULL, "", "", NULL }, - { "vt_dump_injection", ventoy_cmd_dump_injection, 0, NULL, "", "", NULL }, - { "vt_dump_auto_install", ventoy_cmd_dump_auto_install, 0, NULL, "", "", NULL }, - { "vt_dump_persistence", ventoy_cmd_dump_persistence, 0, NULL, "", "", NULL }, - { "vt_select_auto_install", ventoy_cmd_sel_auto_install, 0, NULL, "", "", NULL }, - { "vt_select_persistence", ventoy_cmd_sel_persistence, 0, NULL, "", "", NULL }, - { "vt_select_conf_replace", ventoy_select_conf_replace, 0, NULL, "", "", NULL }, - - { "vt_iso9660_nojoliet", ventoy_cmd_iso9660_nojoliet, 0, NULL, "", "", NULL }, - { "vt_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL }, - { "vt_file_size", ventoy_cmd_file_size, 0, NULL, "", "", NULL }, - { "vt_load_file_to_mem", ventoy_cmd_load_file_to_mem, 0, NULL, "", "", NULL }, - { "vt_load_img_memdisk", ventoy_cmd_load_img_memdisk, 0, NULL, "", "", NULL }, - { "vt_concat_efi_iso", ventoy_cmd_concat_efi_iso, 0, NULL, "", "", NULL }, - - { "vt_linux_parse_initrd_isolinux", ventoy_cmd_isolinux_initrd_collect, 0, NULL, "{cfgfile}", "", NULL }, - { "vt_linux_parse_initrd_grub", ventoy_cmd_grub_initrd_collect, 0, NULL, "{cfgfile}", "", NULL }, - { "vt_linux_specify_initrd_file", ventoy_cmd_specify_initrd_file, 0, NULL, "", "", NULL }, - { "vt_linux_clear_initrd", ventoy_cmd_clear_initrd_list, 0, NULL, "", "", NULL }, - { "vt_linux_dump_initrd", ventoy_cmd_dump_initrd_list, 0, NULL, "", "", NULL }, - { "vt_linux_initrd_count", ventoy_cmd_initrd_count, 0, NULL, "", "", NULL }, - { "vt_linux_valid_initrd_count", ventoy_cmd_valid_initrd_count, 0, NULL, "", "", NULL }, - { "vt_linux_locate_initrd", ventoy_cmd_linux_locate_initrd, 0, NULL, "", "", NULL }, - { "vt_linux_chain_data", ventoy_cmd_linux_chain_data, 0, NULL, "", "", NULL }, - { "vt_linux_get_main_initrd_index", ventoy_cmd_linux_get_main_initrd_index, 0, NULL, "", "", NULL }, - - { "vt_windows_reset", ventoy_cmd_wimdows_reset, 0, NULL, "", "", NULL }, - { "vt_windows_chain_data", ventoy_cmd_windows_chain_data, 0, NULL, "", "", NULL }, - { "vt_windows_collect_wim_patch", ventoy_cmd_collect_wim_patch, 0, NULL, "", "", NULL }, - { "vt_windows_locate_wim_patch", ventoy_cmd_locate_wim_patch, 0, NULL, "", "", NULL }, - { "vt_windows_count_wim_patch", ventoy_cmd_wim_patch_count, 0, NULL, "", "", NULL }, - { "vt_dump_wim_patch", ventoy_cmd_dump_wim_patch, 0, NULL, "", "", NULL }, - { "vt_wim_check_bootable", ventoy_cmd_wim_check_bootable, 0, NULL, "", "", NULL }, - { "vt_wim_chain_data", ventoy_cmd_wim_chain_data, 0, NULL, "", "", NULL }, - - { "vt_add_replace_file", ventoy_cmd_add_replace_file, 0, NULL, "", "", NULL }, - { "vt_test_block_list", ventoy_cmd_test_block_list, 0, NULL, "", "", NULL }, - { "vt_file_exist_nocase", ventoy_cmd_file_exist_nocase, 0, NULL, "", "", NULL }, - - - { "vt_load_plugin", ventoy_cmd_load_plugin, 0, NULL, "", "", NULL }, - { "vt_check_plugin_json", ventoy_cmd_plugin_check_json, 0, NULL, "", "", NULL }, - { "vt_check_password", ventoy_cmd_check_password, 0, NULL, "", "", NULL }, - - { "vt_1st_line", ventoy_cmd_read_1st_line, 0, NULL, "", "", NULL }, - { "vt_file_strstr", ventoy_cmd_file_strstr, 0, NULL, "", "", NULL }, - { "vt_img_part_info", ventoy_cmd_img_part_info, 0, NULL, "", "", NULL }, - - - { "vt_parse_iso_volume", ventoy_cmd_parse_volume, 0, NULL, "", "", NULL }, - { "vt_parse_iso_create_date", ventoy_cmd_parse_create_date, 0, NULL, "", "", NULL }, - { "vt_parse_freenas_ver", ventoy_cmd_parse_freenas_ver, 0, NULL, "", "", NULL }, - { "vt_unix_parse_freebsd_ver", ventoy_cmd_unix_freebsd_ver, 0, NULL, "", "", NULL }, - { "vt_unix_parse_freebsd_ver_elf", ventoy_cmd_unix_freebsd_ver_elf, 0, NULL, "", "", NULL }, - { "vt_unix_reset", ventoy_cmd_unix_reset, 0, NULL, "", "", NULL }, - { "vt_unix_replace_conf", ventoy_cmd_unix_replace_conf, 0, NULL, "", "", NULL }, - { "vt_unix_replace_ko", ventoy_cmd_unix_replace_ko, 0, NULL, "", "", NULL }, - { "vt_unix_fill_image_desc", ventoy_cmd_unix_fill_image_desc, 0, NULL, "", "", NULL }, - { "vt_unix_gzip_new_ko", ventoy_cmd_unix_gzip_newko, 0, NULL, "", "", NULL }, - { "vt_unix_chain_data", ventoy_cmd_unix_chain_data, 0, NULL, "", "", NULL }, - - { "vt_img_hook_root", ventoy_cmd_img_hook_root, 0, NULL, "", "", NULL }, - { "vt_img_unhook_root", ventoy_cmd_img_unhook_root, 0, NULL, "", "", NULL }, - { "vt_acpi_param", ventoy_cmd_acpi_param, 0, NULL, "", "", NULL }, - { "vt_check_secureboot_var", ventoy_cmd_check_secureboot_var, 0, NULL, "", "", NULL }, - { "vt_clear_key", ventoy_cmd_clear_key, 0, NULL, "", "", NULL }, - { "vt_img_check_range", ventoy_cmd_img_check_range, 0, NULL, "", "", NULL }, - -}; - - - -GRUB_MOD_INIT(ventoy) -{ - grub_uint32_t i; - cmd_para *cur = NULL; - - ventoy_env_init(); - - ventoy_arch_mode_init(); - - for (i = 0; i < ARRAY_SIZE(ventoy_cmds); i++) - { - cur = ventoy_cmds + i; - cur->cmd = grub_register_extcmd(cur->name, cur->func, cur->flags, - cur->summary, cur->description, cur->parser); - } -} - -GRUB_MOD_FINI(ventoy) -{ - grub_uint32_t i; - - for (i = 0; i < ARRAY_SIZE(ventoy_cmds); i++) - { - grub_unregister_extcmd(ventoy_cmds[i].cmd); - } + ventoy_unregister_all_cmd(); } diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c new file mode 100644 index 00000000..9f0a8b8f --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c @@ -0,0 +1,4497 @@ +/****************************************************************************** + * ventoy_cmd.c + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef GRUB_MACHINE_EFI +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include "ventoy_def.h" +#include "miniz.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +initrd_info *g_initrd_img_list = NULL; +initrd_info *g_initrd_img_tail = NULL; +int g_initrd_img_count = 0; +int g_valid_initrd_count = 0; +int g_default_menu_mode = 0; +int g_filt_dot_underscore_file = 0; +int g_sort_case_sensitive = 0; +int g_tree_view_menu_style = 0; +static grub_file_t g_old_file; +static int g_ventoy_last_entry_back; + +char g_iso_path[256]; +char g_img_swap_tmp_buf[1024]; +img_info g_img_swap_tmp; +img_info *g_ventoy_img_list = NULL; + +int g_ventoy_img_count = 0; + +grub_device_t g_enum_dev = NULL; +grub_fs_t g_enum_fs = NULL; +int g_img_max_search_level = -1; +img_iterator_node g_img_iterator_head; +img_iterator_node *g_img_iterator_tail = NULL; + +grub_uint8_t g_ventoy_break_level = 0; +grub_uint8_t g_ventoy_debug_level = 0; +grub_uint8_t g_ventoy_chain_type = 0; + +grub_uint8_t *g_ventoy_cpio_buf = NULL; +grub_uint32_t g_ventoy_cpio_size = 0; +cpio_newc_header *g_ventoy_initrd_head = NULL; +grub_uint8_t *g_ventoy_runtime_buf = NULL; + +int g_plugin_image_list = 0; + +ventoy_grub_param *g_grub_param = NULL; + +ventoy_guid g_ventoy_guid = VENTOY_GUID; + +ventoy_img_chunk_list g_img_chunk_list; + +int g_wimboot_enable = 0; +ventoy_img_chunk_list g_wimiso_chunk_list; +char *g_wimiso_path = NULL; + +int g_vhdboot_enable = 0; + +grub_uint64_t g_conf_replace_offset = 0; +grub_uint64_t g_svd_replace_offset = 0; +conf_replace *g_conf_replace_node = NULL; +grub_uint8_t *g_conf_replace_new_buf = NULL; +int g_conf_replace_new_len = 0; +int g_conf_replace_new_len_align = 0; + +ventoy_gpt_info *g_ventoy_part_info = NULL; +grub_uint64_t g_ventoy_disk_size = 0; +grub_uint64_t g_ventoy_disk_part_size[2]; + +static char *g_tree_script_buf = NULL; +static int g_tree_script_pos = 0; + +static char *g_list_script_buf = NULL; +static int g_list_script_pos = 0; + +static char *g_part_list_buf = NULL; +static int g_part_list_pos = 0; + +static int g_video_mode_max = 0; +static int g_video_mode_num = 0; +static ventoy_video_mode *g_video_mode_list = NULL; + +static int g_enumerate_time_checked = 0; +static grub_uint64_t g_enumerate_start_time_ms; +static grub_uint64_t g_enumerate_finish_time_ms; +static int g_vtoy_file_flt[VTOY_FILE_FLT_BUTT] = {0}; + +static const char *g_menu_class[] = +{ + "vtoyiso", "vtoywim", "vtoyefi", "vtoyimg", "vtoyvhd", "vtoyvtoy" +}; + +static const char *g_menu_prefix[] = +{ + "iso", "wim", "efi", "img", "vhd", "vtoy" +}; + +static int ventoy_get_fs_type(const char *fs) +{ + if (NULL == fs) + { + return ventoy_fs_max; + } + else if (grub_strncmp(fs, "exfat", 5) == 0) + { + return ventoy_fs_exfat; + } + else if (grub_strncmp(fs, "ntfs", 4) == 0) + { + return ventoy_fs_ntfs; + } + else if (grub_strncmp(fs, "ext", 3) == 0) + { + return ventoy_fs_ext; + } + else if (grub_strncmp(fs, "xfs", 3) == 0) + { + return ventoy_fs_xfs; + } + else if (grub_strncmp(fs, "udf", 3) == 0) + { + return ventoy_fs_udf; + } + else if (grub_strncmp(fs, "fat", 3) == 0) + { + return ventoy_fs_fat; + } + + return ventoy_fs_max; +} + +static int ventoy_string_check(const char *str, grub_char_check_func check) +{ + if (!str) + { + return 0; + } + + for ( ; *str; str++) + { + if (!check(*str)) + { + return 0; + } + } + + return 1; +} + + +static grub_ssize_t ventoy_fs_read(grub_file_t file, char *buf, grub_size_t len) +{ + grub_memcpy(buf, (char *)file->data + file->offset, len); + return len; +} + +static int ventoy_control_get_flag(const char *key) +{ + const char *val = ventoy_get_env(key); + + if (val && val[0] == '1' && val[1] == 0) + { + return 1; + } + return 0; +} + +static grub_err_t ventoy_fs_close(grub_file_t file) +{ + grub_file_close(g_old_file); + grub_free(file->data); + + file->device = 0; + file->name = 0; + + return 0; +} + +static int ventoy_video_hook(const struct grub_video_mode_info *info, void *hook_arg) +{ + int i; + + (void)hook_arg; + + if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT) + { + return 0; + } + + for (i = 0; i < g_video_mode_num; i++) + { + if (g_video_mode_list[i].width == info->width && + g_video_mode_list[i].height == info->height && + g_video_mode_list[i].bpp == info->bpp) + { + return 0; + } + } + + g_video_mode_list[g_video_mode_num].width = info->width; + g_video_mode_list[g_video_mode_num].height = info->height; + g_video_mode_list[g_video_mode_num].bpp = info->bpp; + g_video_mode_num++; + + if (g_video_mode_num == g_video_mode_max) + { + g_video_mode_max *= 2; + g_video_mode_list = grub_realloc(g_video_mode_list, g_video_mode_max * sizeof(ventoy_video_mode)); + } + + return 0; +} + +static int ventoy_video_mode_cmp(ventoy_video_mode *v1, ventoy_video_mode *v2) +{ + if (v1->bpp == v2->bpp) + { + if (v1->width == v2->width) + { + if (v1->height == v2->height) + { + return 0; + } + else + { + return (v1->height < v2->height) ? -1 : 1; + } + } + else + { + return (v1->width < v2->width) ? -1 : 1; + } + } + else + { + return (v1->bpp < v2->bpp) ? -1 : 1; + } +} + +static int ventoy_enum_video_mode(void) +{ + int i, j; + grub_video_adapter_t adapter; + grub_video_driver_id_t id; + ventoy_video_mode mode; + + g_video_mode_num = 0; + g_video_mode_max = 1024; + g_video_mode_list = grub_malloc(sizeof(ventoy_video_mode) * g_video_mode_max); + if (!g_video_mode_list) + { + return 0; + } + + #ifdef GRUB_MACHINE_PCBIOS + grub_dl_load ("vbe"); + #endif + + id = grub_video_get_driver_id (); + + FOR_VIDEO_ADAPTERS (adapter) + { + if (!adapter->iterate || + (adapter->id != id && (id != GRUB_VIDEO_DRIVER_NONE || + adapter->init() != GRUB_ERR_NONE))) + { + continue; + } + + adapter->iterate(ventoy_video_hook, NULL); + + if (adapter->id != id) + { + adapter->fini(); + } + } + + /* sort video mode */ + for (i = 0; i < g_video_mode_num; i++) + for (j = i + 1; j < g_video_mode_num; j++) + { + if (ventoy_video_mode_cmp(g_video_mode_list + i, g_video_mode_list + j) < 0) + { + grub_memcpy(&mode, g_video_mode_list + i, sizeof(ventoy_video_mode)); + grub_memcpy(g_video_mode_list + i, g_video_mode_list + j, sizeof(ventoy_video_mode)); + grub_memcpy(g_video_mode_list + j, &mode, sizeof(ventoy_video_mode)); + } + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_file_t ventoy_wrapper_open(grub_file_t rawFile, enum grub_file_type type) +{ + int len; + grub_file_t file; + static struct grub_fs vtoy_fs = + { + .name = "vtoy", + .fs_dir = 0, + .fs_open = 0, + .fs_read = ventoy_fs_read, + .fs_close = ventoy_fs_close, + .fs_label = 0, + .next = 0 + }; + + if (type != 52) + { + return rawFile; + } + + file = (grub_file_t)grub_zalloc(sizeof (*file)); + if (!file) + { + return 0; + } + + file->data = grub_malloc(rawFile->size + 4096); + if (!file->data) + { + return 0; + } + + grub_file_read(rawFile, file->data, rawFile->size); + len = ventoy_fill_data(4096, (char *)file->data + rawFile->size); + + g_old_file = rawFile; + + file->size = rawFile->size + len; + file->device = rawFile->device; + file->fs = &vtoy_fs; + file->not_easily_seekable = 1; + + return file; +} + +static int ventoy_check_decimal_var(const char *name, long *value) +{ + const char *value_str = NULL; + + value_str = grub_env_get(name); + if (NULL == value_str) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Variable %s not found", name); + } + + if (!ventoy_is_decimal(value_str)) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Variable %s value '%s' is not an integer", name, value_str); + } + + *value = grub_strtol(value_str, NULL, 10); + + return GRUB_ERR_NONE; +} + +grub_uint64_t ventoy_get_vtoy_partsize(int part) +{ + grub_uint64_t sectors; + + if (grub_strncmp(g_ventoy_part_info->Head.Signature, "EFI PART", 8) == 0) + { + sectors = g_ventoy_part_info->PartTbl[part].LastLBA + 1 - g_ventoy_part_info->PartTbl[part].StartLBA; + } + else + { + sectors = g_ventoy_part_info->MBR.PartTbl[part].SectorCount; + } + + return sectors * 512; +} + +static int ventoy_load_efiboot_template(char **buf, int *datalen, int *direntoff) +{ + int len; + grub_file_t file; + char exec[128]; + char *data = NULL; + grub_uint32_t offset; + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s/ventoy/ventoy_efiboot.img.xz", ventoy_get_env("vtoy_efi_part")); + if (file == NULL) + { + debug("failed to open file <%s>\n", "ventoy_efiboot.img.xz"); + return 1; + } + + len = (int)file->size; + + data = (char *)grub_malloc(file->size); + if (!data) + { + return 1; + } + + grub_file_read(file, data, file->size); + grub_file_close(file); + + grub_snprintf(exec, sizeof(exec), "loopback efiboot mem:0x%llx:size:%d", (ulonglong)(ulong)data, len); + grub_script_execute_sourcecode(exec); + + file = grub_file_open("(efiboot)/EFI/BOOT/BOOTX64.EFI", GRUB_FILE_TYPE_LINUX_INITRD); + offset = (grub_uint32_t)grub_iso9660_get_last_file_dirent_pos(file); + grub_file_close(file); + + grub_script_execute_sourcecode("loopback -d efiboot"); + + *buf = data; + *datalen = len; + *direntoff = offset + 2; + + return 0; +} + +static int ventoy_set_check_result(int ret) +{ + char buf[32]; + + grub_snprintf(buf, sizeof(buf), "%d", (ret & 0x7FFF)); + grub_env_set("VTOY_CHKDEV_RESULT_STRING", buf); + grub_env_export("VTOY_CHKDEV_RESULT_STRING"); + + if (ret) + { + grub_printf(VTOY_WARNING"\n"); + grub_printf(VTOY_WARNING"\n"); + grub_printf(VTOY_WARNING"\n\n\n"); + + grub_printf("This is NOT a standard Ventoy device and is NOT supported (0x%x).\n\n", ret); + grub_printf("You should follow the instructions in https://www.ventoy.net to use Ventoy.\n"); + + grub_printf("\n\nWill exit after 10 seconds ...... "); + grub_refresh(); + grub_sleep(10); + } + + return ret; +} + +static int ventoy_check_official_device(grub_device_t dev) +{ + int workaround = 0; + grub_file_t file; + grub_uint64_t offset; + char devname[64]; + grub_fs_t fs; + grub_device_t dev2; + char *label = NULL; + struct grub_partition *partition; + + if (dev->disk == NULL || dev->disk->partition == NULL) + { + return ventoy_set_check_result(1 | 0x1000); + } + + if (0 == ventoy_check_file_exist("(%s,2)/ventoy/ventoy.cpio", dev->disk->name) || + 0 == ventoy_check_file_exist("(%s,2)/grub/localboot.cfg", dev->disk->name) || + 0 == ventoy_check_file_exist("(%s,2)/tool/mount.exfat-fuse_aarch64", dev->disk->name)) + { + #ifndef GRUB_MACHINE_EFI + if (0 == ventoy_check_file_exist("(ventoydisk)/ventoy/ventoy.cpio", dev->disk->name) || + 0 == ventoy_check_file_exist("(ventoydisk)/grub/localboot.cfg", dev->disk->name) || + 0 == ventoy_check_file_exist("(ventoydisk)/tool/mount.exfat-fuse_aarch64", dev->disk->name)) + { + return ventoy_set_check_result(2 | 0x1000); + } + else + { + workaround = 1; + } + #endif + } + + /* We must have partition 2 */ + if (workaround) + { + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", "(ventoydisk)/ventoy/ventoy.cpio"); + } + else + { + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(%s,2)/ventoy/ventoy.cpio", dev->disk->name); + } + if (!file) + { + return ventoy_set_check_result(3 | 0x1000); + } + + if (NULL == grub_strstr(file->fs->name, "fat")) + { + grub_file_close(file); + return ventoy_set_check_result(4 | 0x1000); + } + + partition = dev->disk->partition; + if (partition->number != 0 || partition->start != 2048) + { + return ventoy_set_check_result(5); + } + + if (workaround) + { + if (grub_strncmp(g_ventoy_part_info->Head.Signature, "EFI PART", 8) == 0) + { + ventoy_gpt_part_tbl *PartTbl = g_ventoy_part_info->PartTbl; + if (PartTbl[1].StartLBA != PartTbl[0].LastLBA + 1 || + (PartTbl[1].LastLBA + 1 - PartTbl[1].StartLBA) != 65536) + { + grub_file_close(file); + return ventoy_set_check_result(6); + } + } + else + { + ventoy_part_table *PartTbl = g_ventoy_part_info->MBR.PartTbl; + if (PartTbl[1].StartSectorId != PartTbl[0].StartSectorId + PartTbl[0].SectorCount || + PartTbl[1].SectorCount != 65536) + { + grub_file_close(file); + return ventoy_set_check_result(6); + } + } + } + else + { + offset = partition->start + partition->len; + partition = file->device->disk->partition; + if ((partition->number != 1) || (partition->len != 65536) || (offset != partition->start)) + { + grub_file_close(file); + return ventoy_set_check_result(7); + } + } + + grub_file_close(file); + + if (workaround == 0) + { + grub_snprintf(devname, sizeof(devname), "%s,2", dev->disk->name); + dev2 = grub_device_open(devname); + if (!dev2) + { + return ventoy_set_check_result(8); + } + + fs = grub_fs_probe(dev2); + if (!fs) + { + grub_device_close(dev2); + return ventoy_set_check_result(9); + } + + fs->fs_label(dev2, &label); + if ((!label) || grub_strncmp("VTOYEFI", label, 7)) + { + grub_device_close(dev2); + return ventoy_set_check_result(10); + } + + grub_device_close(dev2); + } + + return ventoy_set_check_result(0); +} + +static int ventoy_check_ignore_flag(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + if (0 == info->dir) + { + if (filename && filename[0] == '.' && 0 == grub_strncmp(filename, ".ventoyignore", 13)) + { + *((int *)data) = 1; + return 0; + } + } + + return 0; +} + +grub_uint64_t ventoy_grub_get_file_size(const char *fmt, ...) +{ + grub_uint64_t size = 0; + grub_file_t file; + va_list ap; + char fullpath[256] = {0}; + + va_start (ap, fmt); + grub_vsnprintf(fullpath, 255, fmt, ap); + va_end (ap); + + file = grub_file_open(fullpath, VENTOY_FILE_TYPE); + if (!file) + { + debug("grub_file_open failed <%s>\n", fullpath); + grub_errno = 0; + return 0; + } + + size = file->size; + grub_file_close(file); + return size; +} + +grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...) +{ + va_list ap; + grub_file_t file; + char fullpath[256] = {0}; + + va_start (ap, fmt); + grub_vsnprintf(fullpath, 255, fmt, ap); + va_end (ap); + + file = grub_file_open(fullpath, type); + if (!file) + { + debug("grub_file_open failed <%s> %d\n", fullpath, grub_errno); + grub_errno = 0; + } + + return file; +} + +int ventoy_is_file_exist(const char *fmt, ...) +{ + va_list ap; + int len; + char *pos = NULL; + char buf[256] = {0}; + + grub_snprintf(buf, sizeof(buf), "%s", "[ -f \""); + pos = buf + 6; + + va_start (ap, fmt); + len = grub_vsnprintf(pos, 255, fmt, ap); + va_end (ap); + + grub_strncpy(pos + len, "\" ]", 3); + + debug("script exec %s\n", buf); + + if (0 == grub_script_execute_sourcecode(buf)) + { + return 1; + } + + return 0; +} + +int ventoy_is_dir_exist(const char *fmt, ...) +{ + va_list ap; + int len; + char *pos = NULL; + char buf[256] = {0}; + + grub_snprintf(buf, sizeof(buf), "%s", "[ -d \""); + pos = buf + 6; + + va_start (ap, fmt); + len = grub_vsnprintf(pos, 255, fmt, ap); + va_end (ap); + + grub_strncpy(pos + len, "\" ]", 3); + + debug("script exec %s\n", buf); + + if (0 == grub_script_execute_sourcecode(buf)) + { + return 1; + } + + return 0; +} + +int ventoy_gzip_compress(void *mem_in, int mem_in_len, void *mem_out, int mem_out_len) +{ + mz_stream s; + grub_uint8_t *outbuf; + grub_uint8_t gzHdr[10] = + { + 0x1F, 0x8B, /* magic */ + 8, /* z method */ + 0, /* flags */ + 0,0,0,0, /* mtime */ + 4, /* xfl */ + 3, /* OS */ + }; + + grub_memset(&s, 0, sizeof(mz_stream)); + + mz_deflateInit2(&s, 1, MZ_DEFLATED, -MZ_DEFAULT_WINDOW_BITS, 6, MZ_DEFAULT_STRATEGY); + + outbuf = (grub_uint8_t *)mem_out; + + mem_out_len -= sizeof(gzHdr) + 8; + grub_memcpy(outbuf, gzHdr, sizeof(gzHdr)); + outbuf += sizeof(gzHdr); + + s.avail_in = mem_in_len; + s.next_in = mem_in; + + s.avail_out = mem_out_len; + s.next_out = outbuf; + + mz_deflate(&s, MZ_FINISH); + + mz_deflateEnd(&s); + + outbuf += s.total_out; + *(grub_uint32_t *)outbuf = grub_getcrc32c(0, outbuf, s.total_out); + *(grub_uint32_t *)(outbuf + 4) = (grub_uint32_t)(s.total_out); + + return s.total_out + sizeof(gzHdr) + 8; +} + + +#if 0 +ventoy grub cmds +#endif + +static grub_err_t ventoy_cmd_debug(grub_extcmd_context_t ctxt, int argc, char **args) +{ + if (argc != 1) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {on|off}", cmd_raw_name); + } + + if (0 == grub_strcmp(args[0], "on")) + { + g_ventoy_debug = 1; + grub_env_set("vtdebug_flag", "debug"); + } + else + { + g_ventoy_debug = 0; + grub_env_set("vtdebug_flag", ""); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_break(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + + if (argc < 1 || (args[0][0] != '0' && args[0][0] != '1')) + { + grub_printf("Usage: %s {level} [debug]\r\n", cmd_raw_name); + grub_printf(" level:\r\n"); + grub_printf(" 01/11: busybox / (+cat log)\r\n"); + grub_printf(" 02/12: initrd / (+cat log)\r\n"); + grub_printf(" 03/13: hook / (+cat log)\r\n"); + grub_printf("\r\n"); + grub_printf(" debug:\r\n"); + grub_printf(" 0: debug is off\r\n"); + grub_printf(" 1: debug is on\r\n"); + grub_printf("\r\n"); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); + } + + g_ventoy_break_level = (grub_uint8_t)grub_strtoul(args[0], NULL, 16); + + if (argc > 1 && grub_strtoul(args[1], NULL, 10) > 0) + { + g_ventoy_debug_level = 1; + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_strstr(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + + if (argc != 2) + { + return 1; + } + + return (grub_strstr(args[0], args[1])) ? 0 : 1; +} + +static grub_err_t ventoy_cmd_strbegin(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char *c0, *c1; + + (void)ctxt; + + if (argc != 2) + { + return 1; + } + + c0 = args[0]; + c1 = args[1]; + + while (*c0 && *c1) + { + if (*c0 != *c1) + { + return 1; + } + c0++; + c1++; + } + + if (*c1) + { + return 1; + } + + return 0; +} + +static grub_err_t ventoy_cmd_incr(grub_extcmd_context_t ctxt, int argc, char **args) +{ + long value_long = 0; + char buf[32]; + + if ((argc != 2) || (!ventoy_is_decimal(args[1]))) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Variable} {Int}", cmd_raw_name); + } + + if (GRUB_ERR_NONE != ventoy_check_decimal_var(args[0], &value_long)) + { + return grub_errno; + } + + value_long += grub_strtol(args[1], NULL, 10); + + grub_snprintf(buf, sizeof(buf), "%ld", value_long); + grub_env_set(args[0], buf); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_mod(grub_extcmd_context_t ctxt, int argc, char **args) +{ + ulonglong value1 = 0; + ulonglong value2 = 0; + char buf[32]; + + if (argc != 3) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int} {Int} {Variable}", cmd_raw_name); + } + + value1 = grub_strtoull(args[0], NULL, 10); + value2 = grub_strtoull(args[1], NULL, 10); + + grub_snprintf(buf, sizeof(buf), "%llu", (value1 & (value2 - 1))); + grub_env_set(args[2], buf); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_file_size(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + char buf[32]; + grub_file_t file; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 2) + { + return rc; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (file == NULL) + { + debug("failed to open file <%s> for udf check\n", args[0]); + return 1; + } + + grub_snprintf(buf, sizeof(buf), "%llu", (unsigned long long)file->size); + + grub_env_set(args[1], buf); + + grub_file_close(file); + rc = 0; + + return rc; +} + +static grub_err_t ventoy_cmd_load_wimboot(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_file_t file; + + (void)ctxt; + (void)argc; + (void)args; + + g_wimboot_enable = 0; + grub_check_free(g_wimiso_path); + grub_check_free(g_wimiso_chunk_list.chunk); + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!file) + { + return 0; + } + + grub_memset(&g_wimiso_chunk_list, 0, sizeof(g_wimiso_chunk_list)); + g_wimiso_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); + if (NULL == g_wimiso_chunk_list.chunk) + { + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); + } + + g_wimiso_chunk_list.max_chunk = DEFAULT_CHUNK_NUM; + g_wimiso_chunk_list.cur_chunk = 0; + + ventoy_get_block_list(file, &g_wimiso_chunk_list, file->device->disk->partition->start); + + g_wimboot_enable = 1; + g_wimiso_path = grub_strdup(args[0]); + + grub_file_close(file); + + return 0; +} + +static grub_err_t ventoy_cmd_concat_efi_iso(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len = 0; + int totlen = 0; + int offset = 0; + grub_file_t file; + char name[32]; + char value[32]; + char *buf = NULL; + char *data = NULL; + ventoy_iso9660_override *dirent; + + (void)ctxt; + + if (argc != 2) + { + return 1; + } + + totlen = sizeof(ventoy_chain_head); + + if (ventoy_load_efiboot_template(&buf, &len, &offset)) + { + debug("failed to load efiboot template %d\n", len); + return 1; + } + + totlen += len; + + debug("efiboot template len:%d offset:%d\n", len, offset); + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s", args[0]); + if (file == NULL) + { + debug("failed to open file <%s>\n", args[0]); + return 1; + } + + totlen += ventoy_align_2k(file->size); + + dirent = (ventoy_iso9660_override *)(buf + offset); + dirent->first_sector = len / 2048; + dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); + dirent->size = (grub_uint32_t)file->size; + dirent->size_be = grub_swap_bytes32(dirent->size); + + debug("rawiso len:%d efilen:%d total:%d\n", len, (int)file->size, totlen); + +#ifdef GRUB_MACHINE_EFI + data = (char *)grub_efi_allocate_iso_buf(totlen); +#else + data = (char *)grub_malloc(totlen); +#endif + + ventoy_fill_os_param(file, (ventoy_os_param *)data); + + grub_memcpy(data + sizeof(ventoy_chain_head), buf, len); + grub_check_free(buf); + + grub_file_read(file, data + sizeof(ventoy_chain_head) + len, file->size); + grub_file_close(file); + + grub_snprintf(name, sizeof(name), "%s_addr", args[1]); + grub_snprintf(value, sizeof(value), "0x%llx", (ulonglong)(ulong)data); + grub_env_set(name, value); + + grub_snprintf(name, sizeof(name), "%s_size", args[1]); + grub_snprintf(value, sizeof(value), "%d", (int)(totlen)); + grub_env_set(name, value); + + return 0; +} + +static grub_err_t ventoy_cmd_load_file_to_mem(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + char name[32]; + char value[32]; + char *buf = NULL; + grub_file_t file; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 2) + { + return rc; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (file == NULL) + { + debug("failed to open file <%s>\n", args[0]); + return 1; + } + +#ifdef GRUB_MACHINE_EFI + buf = (char *)grub_efi_allocate_iso_buf(file->size); +#else + buf = (char *)grub_malloc(file->size); +#endif + + grub_file_read(file, buf, file->size); + + grub_snprintf(name, sizeof(name), "%s_addr", args[1]); + grub_snprintf(value, sizeof(value), "0x%llx", (unsigned long long)(unsigned long)buf); + grub_env_set(name, value); + + grub_snprintf(name, sizeof(name), "%s_size", args[1]); + grub_snprintf(value, sizeof(value), "%llu", (unsigned long long)file->size); + grub_env_set(name, value); + + grub_file_close(file); + rc = 0; + + return rc; +} + +static grub_err_t ventoy_cmd_load_img_memdisk(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + int headlen; + char name[32]; + char value[32]; + char *buf = NULL; + grub_file_t file; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 2) + { + return rc; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (file == NULL) + { + debug("failed to open file <%s> for udf check\n", args[0]); + return 1; + } + + headlen = sizeof(ventoy_chain_head); + +#ifdef GRUB_MACHINE_EFI + buf = (char *)grub_efi_allocate_iso_buf(headlen + file->size); +#else + buf = (char *)grub_malloc(headlen + file->size); +#endif + + ventoy_fill_os_param(file, (ventoy_os_param *)buf); + + grub_file_read(file, buf + headlen, file->size); + + grub_snprintf(name, sizeof(name), "%s_addr", args[1]); + grub_snprintf(value, sizeof(value), "0x%llx", (unsigned long long)(unsigned long)buf); + grub_env_set(name, value); + + grub_snprintf(name, sizeof(name), "%s_size", args[1]); + grub_snprintf(value, sizeof(value), "%llu", (unsigned long long)file->size); + grub_env_set(name, value); + + grub_file_close(file); + rc = 0; + + return rc; +} + +static grub_err_t ventoy_cmd_iso9660_nojoliet(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + + if (argc != 1) + { + return 1; + } + + if (args[0][0] == '1') + { + grub_iso9660_set_nojoliet(1); + } + else + { + grub_iso9660_set_nojoliet(0); + } + + return 0; +} + +static grub_err_t ventoy_cmd_is_udf(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int rc = 1; + grub_file_t file; + grub_uint8_t buf[32]; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 1) + { + return rc; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (file == NULL) + { + debug("failed to open file <%s> for udf check\n", args[0]); + return 1; + } + + for (i = 16; i < 32; i++) + { + grub_file_seek(file, i * 2048); + grub_file_read(file, buf, sizeof(buf)); + if (buf[0] == 255) + { + break; + } + } + + i++; + grub_file_seek(file, i * 2048); + grub_file_read(file, buf, sizeof(buf)); + + if (grub_memcmp(buf + 1, "BEA01", 5) == 0) + { + i++; + grub_file_seek(file, i * 2048); + grub_file_read(file, buf, sizeof(buf)); + + if (grub_memcmp(buf + 1, "NSR02", 5) == 0 || + grub_memcmp(buf + 1, "NSR03", 5) == 0) + { + rc = 0; + } + } + + grub_file_close(file); + + debug("ISO UDF: %s\n", rc ? "NO" : "YES"); + + return rc; +} + +static grub_err_t ventoy_cmd_cmp(grub_extcmd_context_t ctxt, int argc, char **args) +{ + long value_long1 = 0; + long value_long2 = 0; + + if ((argc != 3) || (!ventoy_is_decimal(args[0])) || (!ventoy_is_decimal(args[2]))) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int1} { eq|ne|gt|lt|ge|le } {Int2}", cmd_raw_name); + } + + value_long1 = grub_strtol(args[0], NULL, 10); + value_long2 = grub_strtol(args[2], NULL, 10); + + if (0 == grub_strcmp(args[1], "eq")) + { + grub_errno = (value_long1 == value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else if (0 == grub_strcmp(args[1], "ne")) + { + grub_errno = (value_long1 != value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else if (0 == grub_strcmp(args[1], "gt")) + { + grub_errno = (value_long1 > value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else if (0 == grub_strcmp(args[1], "lt")) + { + grub_errno = (value_long1 < value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else if (0 == grub_strcmp(args[1], "ge")) + { + grub_errno = (value_long1 >= value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else if (0 == grub_strcmp(args[1], "le")) + { + grub_errno = (value_long1 <= value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int1} { eq ne gt lt ge le } {Int2}", cmd_raw_name); + } + + return grub_errno; +} + +static grub_err_t ventoy_cmd_device(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char *pos = NULL; + char buf[128] = {0}; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s path var", cmd_raw_name); + } + + grub_strncpy(buf, (args[0][0] == '(') ? args[0] + 1 : args[0], sizeof(buf) - 1); + pos = grub_strstr(buf, ","); + if (pos) + { + *pos = 0; + } + + grub_env_set(args[1], buf); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_check_compatible(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + char buf[256]; + grub_disk_t disk; + char *pos = NULL; + const char *files[] = { "ventoy.dat", "VENTOY.DAT" }; + + (void)ctxt; + + if (argc != 1) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s (loop)", cmd_raw_name); + } + + for (i = 0; i < (int)ARRAY_SIZE(files); i++) + { + grub_snprintf(buf, sizeof(buf) - 1, "[ -e \"%s/%s\" ]", args[0], files[i]); + if (0 == grub_script_execute_sourcecode(buf)) + { + debug("file %s exist, ventoy_compatible YES\n", buf); + grub_env_set("ventoy_compatible", "YES"); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); + } + else + { + debug("file %s NOT exist\n", buf); + } + } + + grub_snprintf(buf, sizeof(buf) - 1, "%s", args[0][0] == '(' ? (args[0] + 1) : args[0]); + pos = grub_strstr(buf, ")"); + if (pos) + { + *pos = 0; + } + + disk = grub_disk_open(buf); + if (disk) + { + grub_disk_read(disk, 16 << 2, 0, 1024, g_img_swap_tmp_buf); + grub_disk_close(disk); + + g_img_swap_tmp_buf[703] = 0; + for (i = 318; i < 703; i++) + { + if (g_img_swap_tmp_buf[i] == 'V' && + 0 == grub_strncmp(g_img_swap_tmp_buf + i, VENTOY_COMPATIBLE_STR, VENTOY_COMPATIBLE_STR_LEN)) + { + debug("Ventoy compatible string exist at %d, ventoy_compatible YES\n", i); + grub_env_set("ventoy_compatible", "YES"); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); + } + } + } + else + { + debug("failed to open disk <%s>\n", buf); + } + + grub_env_set("ventoy_compatible", "NO"); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +int ventoy_cmp_img(img_info *img1, img_info *img2) +{ + char *s1, *s2; + int c1 = 0; + int c2 = 0; + + if (g_plugin_image_list == VENTOY_IMG_WHITE_LIST) + { + return (img1->plugin_list_index - img2->plugin_list_index); + } + + for (s1 = img1->name, s2 = img2->name; *s1 && *s2; s1++, s2++) + { + c1 = *s1; + c2 = *s2; + + if (0 == g_sort_case_sensitive) + { + if (grub_islower(c1)) + { + c1 = c1 - 'a' + 'A'; + } + + if (grub_islower(c2)) + { + c2 = c2 - 'a' + 'A'; + } + } + + if (c1 != c2) + { + break; + } + } + + return (c1 - c2); +} + +static int ventoy_cmp_subdir(img_iterator_node *node1, img_iterator_node *node2) +{ + char *s1, *s2; + int c1 = 0; + int c2 = 0; + + if (g_plugin_image_list == VENTOY_IMG_WHITE_LIST) + { + return (node1->plugin_list_index - node2->plugin_list_index); + } + + for (s1 = node1->dir, s2 = node2->dir; *s1 && *s2; s1++, s2++) + { + c1 = *s1; + c2 = *s2; + + if (0 == g_sort_case_sensitive) + { + if (grub_islower(c1)) + { + c1 = c1 - 'a' + 'A'; + } + + if (grub_islower(c2)) + { + c2 = c2 - 'a' + 'A'; + } + } + + if (c1 != c2) + { + break; + } + } + + return (c1 - c2); +} + +void ventoy_swap_img(img_info *img1, img_info *img2) +{ + grub_memcpy(&g_img_swap_tmp, img1, sizeof(img_info)); + + grub_memcpy(img1, img2, sizeof(img_info)); + img1->next = g_img_swap_tmp.next; + img1->prev = g_img_swap_tmp.prev; + + g_img_swap_tmp.next = img2->next; + g_img_swap_tmp.prev = img2->prev; + grub_memcpy(img2, &g_img_swap_tmp, sizeof(img_info)); +} + +static int ventoy_img_name_valid(const char *filename, grub_size_t namelen) +{ + (void)namelen; + + if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_') + { + return 0; + } + + return 1; +} + +static int ventoy_collect_img_files(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + //int i = 0; + int type = 0; + int ignore = 0; + int index = 0; + grub_size_t len; + img_info *img; + img_info *tail; + img_iterator_node *tmp; + img_iterator_node *new_node; + img_iterator_node *node = (img_iterator_node *)data; + + if (g_enumerate_time_checked == 0) + { + g_enumerate_finish_time_ms = grub_get_time_ms(); + if ((g_enumerate_finish_time_ms - g_enumerate_start_time_ms) >= 3000) + { + grub_cls(); + grub_printf("\n\n Ventoy scanning files, please wait...\n"); + grub_refresh(); + g_enumerate_time_checked = 1; + } + } + + len = grub_strlen(filename); + + if (info->dir) + { + if (node->level + 1 > g_img_max_search_level) + { + return 0; + } + + if ((len == 1 && filename[0] == '.') || + (len == 2 && filename[0] == '.' && filename[1] == '.')) + { + return 0; + } + + if (!ventoy_img_name_valid(filename, len)) + { + return 0; + } + + if (filename[0] == '$' && 0 == grub_strncmp(filename, "$RECYCLE.BIN", 12)) + { + return 0; + } + + if (g_plugin_image_list == VENTOY_IMG_WHITE_LIST) + { + grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s/", node->dir, filename); + index = ventoy_plugin_get_image_list_index(vtoy_class_directory, g_img_swap_tmp_buf); + if (index == 0) + { + debug("Directory %s not found in image_list plugin config...\n", g_img_swap_tmp_buf); + return 0; + } + } + + new_node = grub_zalloc(sizeof(img_iterator_node)); + if (new_node) + { + new_node->level = node->level + 1; + new_node->plugin_list_index = index; + new_node->dirlen = grub_snprintf(new_node->dir, sizeof(new_node->dir), "%s%s/", node->dir, filename); + + g_enum_fs->fs_dir(g_enum_dev, new_node->dir, ventoy_check_ignore_flag, &ignore); + if (ignore) + { + debug("Directory %s ignored...\n", new_node->dir); + grub_free(new_node); + return 0; + } + + new_node->tail = node->tail; + + new_node->parent = node; + if (!node->firstchild) + { + node->firstchild = new_node; + } + + if (g_img_iterator_tail) + { + g_img_iterator_tail->next = new_node; + g_img_iterator_tail = new_node; + } + else + { + g_img_iterator_head.next = new_node; + g_img_iterator_tail = new_node; + } + } + } + else + { + debug("Find a file %s\n", filename); + if (len < 4) + { + return 0; + } + + if (FILE_FLT(ISO) && 0 == grub_strcasecmp(filename + len - 4, ".iso")) + { + type = img_type_iso; + } + else if (FILE_FLT(WIM) && g_wimboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".wim"))) + { + type = img_type_wim; + } + else if (FILE_FLT(VHD) && g_vhdboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".vhd") || + (len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vhdx")))) + { + type = img_type_vhd; + } + #ifdef GRUB_MACHINE_EFI + else if (FILE_FLT(EFI) && 0 == grub_strcasecmp(filename + len - 4, ".efi")) + { + type = img_type_efi; + } + #endif + else if (FILE_FLT(IMG) && 0 == grub_strcasecmp(filename + len - 4, ".img")) + { + if (len == 18 && grub_strncmp(filename, "ventoy_", 7) == 0) + { + if (grub_strncmp(filename + 7, "wimboot", 7) == 0 || + grub_strncmp(filename + 7, "vhdboot", 7) == 0) + { + return 0; + } + } + type = img_type_img; + } + else if (FILE_FLT(VTOY) && len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vtoy")) + { + type = img_type_vtoy; + } + else if (len >= 9 && 0 == grub_strcasecmp(filename + len - 5, ".vcfg")) + { + if (filename[len - 9] == '.' || (len >= 10 && filename[len - 10] == '.')) + { + grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s", node->dir, filename); + ventoy_plugin_add_custom_boot(g_img_swap_tmp_buf); + } + return 0; + } + else + { + return 0; + } + + if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_') + { + return 0; + } + + if (g_plugin_image_list) + { + grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s", node->dir, filename); + index = ventoy_plugin_get_image_list_index(vtoy_class_image_file, g_img_swap_tmp_buf); + if (VENTOY_IMG_WHITE_LIST == g_plugin_image_list && index == 0) + { + debug("File %s not found in image_list plugin config...\n", g_img_swap_tmp_buf); + return 0; + } + else if (VENTOY_IMG_BLACK_LIST == g_plugin_image_list && index > 0) + { + debug("File %s found in image_blacklist plugin config %d ...\n", g_img_swap_tmp_buf, index); + return 0; + } + } + + img = grub_zalloc(sizeof(img_info)); + if (img) + { + img->type = type; + img->plugin_list_index = index; + grub_snprintf(img->name, sizeof(img->name), "%s", filename); + + img->pathlen = grub_snprintf(img->path, sizeof(img->path), "%s%s", node->dir, img->name); + + img->size = info->size; + if (0 == img->size) + { + img->size = ventoy_grub_get_file_size("%s/%s%s", g_iso_path, node->dir, filename); + } + + if (img->size < VTOY_FILT_MIN_FILE_SIZE) + { + debug("img <%s> size too small %llu\n", img->name, (ulonglong)img->size); + grub_free(img); + return 0; + } + + if (g_ventoy_img_list) + { + tail = *(node->tail); + img->prev = tail; + tail->next = img; + } + else + { + g_ventoy_img_list = img; + } + + img->id = g_ventoy_img_count; + img->parent = node; + if (node && NULL == node->firstiso) + { + node->firstiso = img; + } + + node->isocnt++; + tmp = node->parent; + while (tmp) + { + tmp->isocnt++; + tmp = tmp->parent; + } + + *((img_info **)(node->tail)) = img; + g_ventoy_img_count++; + + img->alias = ventoy_plugin_get_menu_alias(vtoy_alias_image_file, img->path); + img->class = ventoy_plugin_get_menu_class(vtoy_class_image_file, img->name, img->path); + if (!img->class) + { + img->class = g_menu_class[type]; + } + img->menu_prefix = g_menu_prefix[type]; + + if (img_type_iso == type) + { + if (ventoy_plugin_check_memdisk(img->path)) + { + img->menu_prefix = "miso"; + } + } + + debug("Add %s%s to list %d\n", node->dir, filename, g_ventoy_img_count); + } + } + + return 0; +} + +int ventoy_fill_data(grub_uint32_t buflen, char *buffer) +{ + int len = GRUB_UINT_MAX; + const char *value = NULL; + char name[32] = {0}; + char plat[32] = {0}; + char guidstr[32] = {0}; + ventoy_guid guid = VENTOY_GUID; + const char *fmt1 = NULL; + const char *fmt2 = NULL; + const char *fmt3 = NULL; + grub_uint32_t *puint = (grub_uint32_t *)name; + grub_uint32_t *puint2 = (grub_uint32_t *)plat; + const char fmtdata[]={ 0x39, 0x35, 0x25, 0x00, 0x35, 0x00, 0x23, 0x30, 0x30, 0x30, 0x30, 0x66, 0x66, 0x00 }; + const char fmtcode[]={ + 0x22, 0x0A, 0x2B, 0x20, 0x68, 0x62, 0x6F, 0x78, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x74, 0x6F, 0x70, + 0x20, 0x3D, 0x20, 0x25, 0x73, 0x0A, 0x20, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x20, 0x3D, 0x20, 0x25, + 0x73, 0x0A, 0x20, 0x20, 0x2B, 0x20, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x7B, 0x74, 0x65, 0x78, + 0x74, 0x20, 0x3D, 0x20, 0x22, 0x25, 0x73, 0x20, 0x25, 0x73, 0x25, 0x73, 0x22, 0x20, 0x63, 0x6F, + 0x6C, 0x6F, 0x72, 0x20, 0x3D, 0x20, 0x22, 0x25, 0x73, 0x22, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, + 0x20, 0x3D, 0x20, 0x22, 0x6C, 0x65, 0x66, 0x74, 0x22, 0x7D, 0x0A, 0x7D, 0x0A, 0x22, 0x00 + }; + + grub_memset(name, 0, sizeof(name)); + puint[0] = grub_swap_bytes32(0x56454e54); + puint[3] = grub_swap_bytes32(0x4f4e0000); + puint[2] = grub_swap_bytes32(0x45525349); + puint[1] = grub_swap_bytes32(0x4f595f56); + value = ventoy_get_env(name); + + grub_memset(name, 0, sizeof(name)); + puint[1] = grub_swap_bytes32(0x5f544f50); + puint[0] = grub_swap_bytes32(0x56544c45); + fmt1 = ventoy_get_env(name); + if (!fmt1) + { + fmt1 = fmtdata; + } + + grub_memset(name, 0, sizeof(name)); + puint[1] = grub_swap_bytes32(0x5f4c4654); + puint[0] = grub_swap_bytes32(0x56544c45); + fmt2 = ventoy_get_env(name); + + grub_memset(name, 0, sizeof(name)); + puint[1] = grub_swap_bytes32(0x5f434c52); + puint[0] = grub_swap_bytes32(0x56544c45); + fmt3 = ventoy_get_env(name); + + grub_memcpy(guidstr, &guid, sizeof(guid)); + + puint2[0] = grub_swap_bytes32(g_ventoy_plat_data); + + /* Easter egg :) It will be appreciated if you reserve it, but NOT mandatory. */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-nonliteral" + len = grub_snprintf(buffer, buflen, fmtcode, + fmt1 ? fmt1 : fmtdata, + fmt2 ? fmt2 : fmtdata + 4, + value ? value : "", plat, guidstr, + fmt3 ? fmt3 : fmtdata + 6); + #pragma GCC diagnostic pop + + grub_memset(name, 0, sizeof(name)); + puint[0] = grub_swap_bytes32(0x76746f79); + puint[2] = grub_swap_bytes32(0x656e7365); + puint[1] = grub_swap_bytes32(0x5f6c6963); + ventoy_set_env(name, guidstr); + + return len; +} + +int ventoy_check_password(const vtoy_password *pwd, int retry) +{ + int offset; + char input[256]; + grub_uint8_t md5[16]; + + while (retry--) + { + grub_memset(input, 0, sizeof(input)); + + grub_printf("Enter password: "); + grub_refresh(); + + if (pwd->type == VTOY_PASSWORD_TXT) + { + grub_password_get(input, 128); + if (grub_strcmp(pwd->text, input) == 0) + { + return 0; + } + } + else if (pwd->type == VTOY_PASSWORD_MD5) + { + grub_password_get(input, 128); + grub_crypto_hash(GRUB_MD_MD5, md5, input, grub_strlen(input)); + if (grub_memcmp(pwd->md5, md5, 16) == 0) + { + return 0; + } + } + else if (pwd->type == VTOY_PASSWORD_SALT_MD5) + { + offset = (int)grub_snprintf(input, 128, "%s", pwd->salt); + grub_password_get(input + offset, 128); + + grub_crypto_hash(GRUB_MD_MD5, md5, input, grub_strlen(input)); + if (grub_memcmp(pwd->md5, md5, 16) == 0) + { + return 0; + } + } + + grub_printf("Invalid password!\n\n"); + grub_refresh(); + } + + return 1; +} + +static img_info * ventoy_get_min_iso(img_iterator_node *node) +{ + img_info *minimg = NULL; + img_info *img = (img_info *)(node->firstiso); + + while (img && (img_iterator_node *)(img->parent) == node) + { + if (img->select == 0 && (NULL == minimg || ventoy_cmp_img(img, minimg) < 0)) + { + minimg = img; + } + img = img->next; + } + + if (minimg) + { + minimg->select = 1; + } + + return minimg; +} + +static img_iterator_node * ventoy_get_min_child(img_iterator_node *node) +{ + img_iterator_node *Minchild = NULL; + img_iterator_node *child = node->firstchild; + + while (child && child->parent == node) + { + if (child->select == 0 && (NULL == Minchild || ventoy_cmp_subdir(child, Minchild) < 0)) + { + Minchild = child; + } + child = child->next; + } + + if (Minchild) + { + Minchild->select = 1; + } + + return Minchild; +} + +static int ventoy_dynamic_tree_menu(img_iterator_node *node) +{ + int offset = 1; + img_info *img = NULL; + const char *dir_class = NULL; + const char *dir_alias = NULL; + img_iterator_node *child = NULL; + + if (node->isocnt == 0 || node->done == 1) + { + return 0; + } + + if (node->parent && node->parent->dirlen < node->dirlen) + { + offset = node->parent->dirlen; + } + + if (node == &g_img_iterator_head) + { + if (g_default_menu_mode == 0) + { + if (g_tree_view_menu_style == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"%-10s [Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n" + "}\n", "<--"); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"[Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo '%s ...' \n" + "}\n", "return"); + } + } + } + else + { + node->dir[node->dirlen - 1] = 0; + dir_class = ventoy_plugin_get_menu_class(vtoy_class_directory, node->dir, node->dir); + if (!dir_class) + { + dir_class = "vtoydir"; + } + + dir_alias = ventoy_plugin_get_menu_alias(vtoy_alias_directory, node->dir); + if (dir_alias) + { + if (g_tree_view_menu_style == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "submenu \"%-10s %s\" --class=\"%s\" --id=\"DIR_%s\" {\n", + "DIR", dir_alias, dir_class, node->dir + offset); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "submenu \"%s\" --class=\"%s\" --id=\"DIR_%s\" {\n", + dir_alias, dir_class, node->dir + offset); + } + } + else + { + dir_alias = node->dir + offset; + + if (g_tree_view_menu_style == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "submenu \"%-10s [%s]\" --class=\"%s\" --id=\"DIR_%s\" {\n", + "DIR", dir_alias, dir_class, node->dir + offset); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "submenu \"[%s]\" --class=\"%s\" --id=\"DIR_%s\" {\n", + dir_alias, dir_class, node->dir + offset); + } + } + + if (g_tree_view_menu_style == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"%-10s [../]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n" + "}\n", "<--"); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"[../]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo '%s ...' \n" + "}\n", "return"); + } + } + + while ((child = ventoy_get_min_child(node)) != NULL) + { + ventoy_dynamic_tree_menu(child); + } + + while ((img = ventoy_get_min_iso(node)) != NULL) + { + if (g_tree_view_menu_style == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"%-10s %s%s\" --class=\"%s\" --id=\"VID_%d\" {\n" + " %s_%s \n" + "}\n", + grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT), + img->unsupport ? "[***********] " : "", + img->alias ? img->alias : img->name, img->class, img->id, + img->menu_prefix, + img->unsupport ? "unsupport_menuentry" : "common_menuentry"); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"%s%s\" --class=\"%s\" --id=\"VID_%d\" {\n" + " %s_%s \n" + "}\n", + img->unsupport ? "[***********] " : "", + img->alias ? img->alias : img->name, img->class, img->id, + img->menu_prefix, + img->unsupport ? "unsupport_menuentry" : "common_menuentry"); + } + } + + if (node != &g_img_iterator_head) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "%s", "}\n"); + } + + node->done = 1; + return 0; +} + +static int ventoy_set_default_menu(void) +{ + int img_len = 0; + char *pos = NULL; + char *end = NULL; + char *def = NULL; + const char *strdata = NULL; + img_info *cur = NULL; + img_info *default_node = NULL; + const char *default_image = NULL; + + default_image = ventoy_get_env("VTOY_DEFAULT_IMAGE"); + if (default_image && default_image[0] == '/') + { + img_len = grub_strlen(default_image); + + for (cur = g_ventoy_img_list; cur; cur = cur->next) + { + if (img_len == cur->pathlen && grub_strcmp(default_image, cur->path) == 0) + { + default_node = cur; + break; + } + } + + if (!default_node) + { + return 1; + } + + if (0 == g_default_menu_mode) + { + vtoy_ssprintf(g_list_script_buf, g_list_script_pos, "set default='VID_%d'\n", default_node->id); + } + else + { + def = grub_strdup(default_image); + if (!def) + { + return 1; + } + + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "set default=%c", '\''); + + strdata = ventoy_get_env("VTOY_DEFAULT_SEARCH_ROOT"); + if (strdata && strdata[0] == '/') + { + pos = def + grub_strlen(strdata); + if (*pos == '/') + { + pos++; + } + } + else + { + pos = def + 1; + } + + while ((end = grub_strchr(pos, '/')) != NULL) + { + *end = 0; + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "DIR_%s>", pos); + pos = end + 1; + } + + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "VID_%d'\n", default_node->id); + grub_free(def); + } + } + + return 0; +} + +static grub_err_t ventoy_cmd_clear_img(grub_extcmd_context_t ctxt, int argc, char **args) +{ + img_info *next = NULL; + img_info *cur = g_ventoy_img_list; + + (void)ctxt; + (void)argc; + (void)args; + + while (cur) + { + next = cur->next; + grub_free(cur); + cur = next; + } + + g_ventoy_img_list = NULL; + g_ventoy_img_count = 0; + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_img_name(grub_extcmd_context_t ctxt, int argc, char **args) +{ + long img_id = 0; + img_info *cur = g_ventoy_img_list; + + (void)ctxt; + + if (argc != 2 || (!ventoy_is_decimal(args[0]))) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {imageID} {var}", cmd_raw_name); + } + + img_id = grub_strtol(args[0], NULL, 10); + if (img_id >= g_ventoy_img_count) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such many images %ld %ld", img_id, g_ventoy_img_count); + } + + debug("Find image %ld name \n", img_id); + + while (cur && img_id > 0) + { + img_id--; + cur = cur->next; + } + + if (!cur) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such many images"); + } + + debug("image name is %s\n", cur->name); + + grub_env_set(args[1], cur->name); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_ext_select_img_path(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len = 0; + char id[32] = {0}; + img_info *cur = g_ventoy_img_list; + + (void)ctxt; + + if (argc != 1) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {var}", cmd_raw_name); + } + + len = (int)grub_strlen(args[0]); + + while (cur) + { + if (len == cur->pathlen && 0 == grub_strcmp(args[0], cur->path)) + { + break; + } + cur = cur->next; + } + + if (!cur) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such image"); + } + + grub_snprintf(id, sizeof(id), "VID_%d", cur->id); + grub_env_set("chosen", id); + grub_env_export("chosen"); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int img_id = 0; + char value[32]; + char *pos = NULL; + const char *id = NULL; + img_info *cur = g_ventoy_img_list; + + (void)ctxt; + + if (argc < 1 || argc > 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {var}", cmd_raw_name); + } + + id = grub_env_get("chosen"); + + pos = grub_strstr(id, "VID_"); + if (pos) + { + img_id = (int)grub_strtoul(pos + 4, NULL, 10); + } + else + { + img_id = (int)grub_strtoul(id, NULL, 10); + } + + while (cur) + { + if (img_id == cur->id) + { + break; + } + cur = cur->next; + } + + if (!cur) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such image"); + } + + grub_env_set(args[0], cur->path); + + if (argc > 1) + { + grub_snprintf(value, sizeof(value), "%llu", (ulonglong)(cur->size)); + grub_env_set(args[1], value); + } + + g_svd_replace_offset = 0; + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + + +static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len; + grub_fs_t fs; + grub_device_t dev = NULL; + img_info *cur = NULL; + img_info *tail = NULL; + const char *strdata = NULL; + char *device_name = NULL; + char buf[32]; + img_iterator_node *node = NULL; + img_iterator_node *tmp = NULL; + + (void)ctxt; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {device} {cntvar}", cmd_raw_name); + } + + if (g_ventoy_img_list || g_ventoy_img_count) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Must clear image before list"); + } + + VTOY_CMD_CHECK(1); + + g_enumerate_time_checked = 0; + g_enumerate_start_time_ms = grub_get_time_ms(); + + strdata = ventoy_get_env("VTOY_FILT_DOT_UNDERSCORE_FILE"); + if (strdata && strdata[0] == '1' && strdata[1] == 0) + { + g_filt_dot_underscore_file = 1; + } + + strdata = ventoy_get_env("VTOY_SORT_CASE_SENSITIVE"); + if (strdata && strdata[0] == '1' && strdata[1] == 0) + { + g_sort_case_sensitive = 1; + } + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + goto fail; + } + + g_enum_dev = dev = grub_device_open(device_name); + if (!dev) + { + goto fail; + } + + g_enum_fs = fs = grub_fs_probe(dev); + if (!fs) + { + goto fail; + } + + if (ventoy_get_fs_type(fs->name) >= ventoy_fs_max) + { + debug("unsupported fs:<%s>\n", fs->name); + ventoy_set_env("VTOY_NO_ISO_TIP", "unsupported file system"); + goto fail; + } + + ventoy_set_env("vtoy_iso_fs", fs->name); + + strdata = ventoy_get_env("VTOY_DEFAULT_MENU_MODE"); + if (strdata && strdata[0] == '1') + { + g_default_menu_mode = 1; + } + + grub_memset(&g_img_iterator_head, 0, sizeof(g_img_iterator_head)); + + grub_snprintf(g_iso_path, sizeof(g_iso_path), "%s", args[0]); + + strdata = ventoy_get_env("VTOY_DEFAULT_SEARCH_ROOT"); + if (strdata && strdata[0] == '/') + { + len = grub_snprintf(g_img_iterator_head.dir, sizeof(g_img_iterator_head.dir) - 1, "%s", strdata); + if (g_img_iterator_head.dir[len - 1] != '/') + { + g_img_iterator_head.dir[len++] = '/'; + } + g_img_iterator_head.dirlen = len; + } + else + { + g_img_iterator_head.dirlen = 1; + grub_strcpy(g_img_iterator_head.dir, "/"); + } + + g_img_iterator_head.tail = &tail; + + if (g_img_max_search_level < 0) + { + g_img_max_search_level = GRUB_INT_MAX; + strdata = ventoy_get_env("VTOY_MAX_SEARCH_LEVEL"); + if (strdata && ventoy_is_decimal(strdata)) + { + g_img_max_search_level = (int)grub_strtoul(strdata, NULL, 10); + } + } + + g_vtoy_file_flt[VTOY_FILE_FLT_ISO] = ventoy_control_get_flag("VTOY_FILE_FLT_ISO"); + g_vtoy_file_flt[VTOY_FILE_FLT_WIM] = ventoy_control_get_flag("VTOY_FILE_FLT_WIM"); + g_vtoy_file_flt[VTOY_FILE_FLT_EFI] = ventoy_control_get_flag("VTOY_FILE_FLT_EFI"); + g_vtoy_file_flt[VTOY_FILE_FLT_IMG] = ventoy_control_get_flag("VTOY_FILE_FLT_IMG"); + g_vtoy_file_flt[VTOY_FILE_FLT_VHD] = ventoy_control_get_flag("VTOY_FILE_FLT_VHD"); + g_vtoy_file_flt[VTOY_FILE_FLT_VTOY] = ventoy_control_get_flag("VTOY_FILE_FLT_VTOY"); + + for (node = &g_img_iterator_head; node; node = node->next) + { + fs->fs_dir(dev, node->dir, ventoy_collect_img_files, node); + } + + strdata = ventoy_get_env("VTOY_TREE_VIEW_MENU_STYLE"); + if (strdata && strdata[0] == '1' && strdata[1] == 0) + { + g_tree_view_menu_style = 1; + } + + ventoy_set_default_menu(); + + for (node = &g_img_iterator_head; node; node = node->next) + { + ventoy_dynamic_tree_menu(node); + } + + /* free node */ + node = g_img_iterator_head.next; + while (node) + { + tmp = node->next; + grub_free(node); + node = tmp; + } + + /* sort image list by image name */ + for (cur = g_ventoy_img_list; cur; cur = cur->next) + { + for (tail = cur->next; tail; tail = tail->next) + { + if (ventoy_cmp_img(cur, tail) > 0) + { + ventoy_swap_img(cur, tail); + } + } + } + + if (g_default_menu_mode == 1) + { + vtoy_ssprintf(g_list_script_buf, g_list_script_pos, + "menuentry \"%s [Return to TreeView]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n" + "}\n", "<--"); + } + + for (cur = g_ventoy_img_list; cur; cur = cur->next) + { + vtoy_ssprintf(g_list_script_buf, g_list_script_pos, + "menuentry \"%s%s\" --class=\"%s\" --id=\"VID_%d\" {\n" + " %s_%s \n" + "}\n", + cur->unsupport ? "[***********] " : "", + cur->alias ? cur->alias : cur->name, cur->class, cur->id, + cur->menu_prefix, + cur->unsupport ? "unsupport_menuentry" : "common_menuentry"); + } + + g_tree_script_buf[g_tree_script_pos] = 0; + g_list_script_buf[g_list_script_pos] = 0; + + grub_snprintf(buf, sizeof(buf), "%d", g_ventoy_img_count); + grub_env_set(args[1], buf); + +fail: + + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid, grub_uint8_t *signature) +{ + grub_disk_t disk; + char *device_name; + char *pos; + char *pos2; + + device_name = grub_file_get_device_name(filename); + if (!device_name) + { + return 1; + } + + pos = device_name; + if (pos[0] == '(') + { + pos++; + } + + pos2 = grub_strstr(pos, ","); + if (!pos2) + { + pos2 = grub_strstr(pos, ")"); + } + + if (pos2) + { + *pos2 = 0; + } + + disk = grub_disk_open(pos); + if (disk) + { + grub_disk_read(disk, 0, 0x180, 16, guid); + grub_disk_read(disk, 0, 0x1b8, 4, signature); + grub_disk_close(disk); + } + else + { + return 1; + } + + grub_free(device_name); + return 0; +} + +grub_uint32_t ventoy_get_iso_boot_catlog(grub_file_t file) +{ + eltorito_descriptor desc; + + grub_memset(&desc, 0, sizeof(desc)); + grub_file_seek(file, 17 * 2048); + grub_file_read(file, &desc, sizeof(desc)); + + if (desc.type != 0 || desc.version != 1) + { + return 0; + } + + if (grub_strncmp((char *)desc.id, "CD001", 5) != 0 || + grub_strncmp((char *)desc.system_id, "EL TORITO SPECIFICATION", 23) != 0) + { + return 0; + } + + return desc.sector; +} + +int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector) +{ + int i; + int x86count = 0; + grub_uint8_t buf[512]; + grub_uint8_t parttype[] = { 0x04, 0x06, 0x0B, 0x0C }; + + grub_file_seek(file, sector * 2048); + grub_file_read(file, buf, sizeof(buf)); + + if (buf[0] == 0x01 && buf[1] == 0xEF) + { + debug("%s efi eltorito in Validation Entry\n", file->name); + return 1; + } + + if (buf[0] == 0x01 && buf[1] == 0x00) + { + x86count++; + } + + for (i = 64; i < (int)sizeof(buf); i += 32) + { + if ((buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0xEF) + { + debug("%s efi eltorito offset %d 0x%02x\n", file->name, i, buf[i]); + return 1; + } + + if ((buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0x00 && x86count == 1) + { + debug("0x9100 assume %s efi eltorito offset %d 0x%02x\n", file->name, i, buf[i]); + return 1; + } + } + + if (x86count && buf[32] == 0x88 && buf[33] == 0x04) + { + for (i = 0; i < (int)(ARRAY_SIZE(parttype)); i++) + { + if (buf[36] == parttype[i]) + { + debug("hard disk image assume %s efi eltorito, part type 0x%x\n", file->name, buf[36]); + return 1; + } + } + } + + debug("%s does not contain efi eltorito\n", file->name); + return 0; +} + +void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param) +{ + char *pos; + const char *fs = NULL; + const char *cdprompt = NULL; + grub_uint32_t i; + grub_uint8_t chksum = 0; + grub_disk_t disk; + + disk = file->device->disk; + grub_memcpy(¶m->guid, &g_ventoy_guid, sizeof(ventoy_guid)); + + param->vtoy_disk_size = disk->total_sectors * (1 << disk->log_sector_size); + param->vtoy_disk_part_id = disk->partition->number + 1; + param->vtoy_disk_part_type = ventoy_get_fs_type(file->fs->name); + + pos = grub_strstr(file->name, "/"); + if (!pos) + { + pos = file->name; + } + + grub_snprintf(param->vtoy_img_path, sizeof(param->vtoy_img_path), "%s", pos); + + ventoy_get_disk_guid(file->name, param->vtoy_disk_guid, param->vtoy_disk_signature); + + param->vtoy_img_size = file->size; + + param->vtoy_reserved[0] = g_ventoy_break_level; + param->vtoy_reserved[1] = g_ventoy_debug_level; + + param->vtoy_reserved[2] = g_ventoy_chain_type; + + /* Windows CD/DVD prompt 0:suppress 1:reserved */ + param->vtoy_reserved[4] = 0; + if (g_ventoy_chain_type == 1) /* Windows */ + { + cdprompt = ventoy_get_env("VTOY_WINDOWS_CD_PROMPT"); + if (cdprompt && cdprompt[0] == '1' && cdprompt[1] == 0) + { + param->vtoy_reserved[4] = 1; + } + } + + fs = ventoy_get_env("ventoy_fs_probe"); + if (fs && grub_strcmp(fs, "udf") == 0) + { + param->vtoy_reserved[3] = 1; + } + + /* calculate checksum */ + for (i = 0; i < sizeof(ventoy_os_param); i++) + { + chksum += *((grub_uint8_t *)param + i); + } + param->chksum = (grub_uint8_t)(0x100 - chksum); + + return; +} + +int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start) +{ + grub_uint32_t i = 0; + grub_uint64_t total = 0; + grub_uint64_t fileblk = 0; + ventoy_img_chunk *chunk = NULL; + + for (i = 0; i < chunklist->cur_chunk; i++) + { + chunk = chunklist->chunk + i; + + if (chunk->disk_start_sector <= start) + { + debug("%u disk start invalid %lu\n", i, (ulong)start); + return 1; + } + + total += chunk->disk_end_sector + 1 - chunk->disk_start_sector; + } + + fileblk = (file->size + 511) / 512; + + if (total != fileblk) + { + debug("Invalid total: %llu %llu\n", (ulonglong)total, (ulonglong)fileblk); + if ((file->size % 512) && (total + 1 == fileblk)) + { + debug("maybe img file to be processed.\n"); + return 0; + } + + return 1; + } + + return 0; +} + +int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start) +{ + int fs_type; + int len; + grub_uint32_t i = 0; + grub_uint32_t sector = 0; + grub_uint32_t count = 0; + grub_off_t size = 0; + grub_off_t read = 0; + + fs_type = ventoy_get_fs_type(file->fs->name); + if (fs_type == ventoy_fs_exfat) + { + grub_fat_get_file_chunk(start, file, chunklist); + } + else if (fs_type == ventoy_fs_ext) + { + grub_ext_get_file_chunk(start, file, chunklist); + } + else + { + file->read_hook = (grub_disk_read_hook_t)grub_disk_blocklist_read; + file->read_hook_data = chunklist; + + for (size = file->size; size > 0; size -= read) + { + read = (size > VTOY_SIZE_1GB) ? VTOY_SIZE_1GB : size; + grub_file_read(file, NULL, read); + } + + for (i = 0; start > 0 && i < chunklist->cur_chunk; i++) + { + chunklist->chunk[i].disk_start_sector += start; + chunklist->chunk[i].disk_end_sector += start; + } + + if (ventoy_fs_udf == fs_type) + { + for (i = 0; i < chunklist->cur_chunk; i++) + { + count = (chunklist->chunk[i].disk_end_sector + 1 - chunklist->chunk[i].disk_start_sector) >> 2; + chunklist->chunk[i].img_start_sector = sector; + chunklist->chunk[i].img_end_sector = sector + count - 1; + sector += count; + } + } + } + + len = (int)grub_strlen(file->name); + if ((len > 4 && grub_strncasecmp(file->name + len - 4, ".img", 4) == 0) || + (len > 4 && grub_strncasecmp(file->name + len - 4, ".vhd", 4) == 0) || + (len > 5 && grub_strncasecmp(file->name + len - 5, ".vhdx", 5) == 0) || + (len > 5 && grub_strncasecmp(file->name + len - 5, ".vtoy", 5) == 0)) + { + for (i = 0; i < chunklist->cur_chunk; i++) + { + count = chunklist->chunk[i].disk_end_sector + 1 - chunklist->chunk[i].disk_start_sector; + if (count < 4) + { + count = 1; + } + else + { + count >>= 2; + } + + chunklist->chunk[i].img_start_sector = sector; + chunklist->chunk[i].img_end_sector = sector + count - 1; + sector += count; + } + } + + return 0; +} + +static grub_err_t ventoy_cmd_img_sector(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc; + grub_file_t file; + grub_disk_addr_t start; + + (void)ctxt; + (void)argc; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]); + } + + g_conf_replace_node = NULL; + g_conf_replace_offset = 0; + + if (g_img_chunk_list.chunk) + { + grub_free(g_img_chunk_list.chunk); + } + + if (ventoy_get_fs_type(file->fs->name) >= ventoy_fs_max) + { + grub_file_close(file); + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Unsupported filesystem %s\n", file->fs->name); + } + + /* get image chunk data */ + grub_memset(&g_img_chunk_list, 0, sizeof(g_img_chunk_list)); + g_img_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); + if (NULL == g_img_chunk_list.chunk) + { + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); + } + + g_img_chunk_list.max_chunk = DEFAULT_CHUNK_NUM; + g_img_chunk_list.cur_chunk = 0; + + start = file->device->disk->partition->start; + + ventoy_get_block_list(file, &g_img_chunk_list, start); + + rc = ventoy_check_block_list(file, &g_img_chunk_list, start); + grub_file_close(file); + + if (rc) + { + return grub_error(GRUB_ERR_NOT_IMPLEMENTED_YET, "Unsupported chunk list.\n"); + } + + grub_memset(&g_grub_param->file_replace, 0, sizeof(g_grub_param->file_replace)); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_select_conf_replace(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint64_t offset = 0; + grub_uint32_t align = 0; + grub_file_t file = NULL; + conf_replace *node = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + debug("select conf replace argc:%d\n", argc); + + if (argc < 2) + { + return 0; + } + + node = ventoy_plugin_find_conf_replace(args[1]); + if (!node) + { + debug("Conf replace not found for %s\n", args[1]); + goto end; + } + + debug("Find conf replace for %s\n", args[1]); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(loop)%s", node->orgconf); + if (!file) + { + debug("<(loop)%s> NOT exist\n", node->orgconf); + goto end; + } + + offset = grub_iso9660_get_last_file_dirent_pos(file); + grub_file_close(file); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[0], node->newconf); + if (!file) + { + debug("New config file <%s%s> NOT exist\n", args[0], node->newconf); + goto end; + } + + align = ((int)file->size + 2047) / 2048 * 2048; + + if (align > vtoy_max_replace_file_size) + { + debug("New config file <%s%s> too big\n", args[0], node->newconf); + goto end; + } + + grub_file_read(file, g_conf_replace_new_buf, file->size); + g_conf_replace_new_len = (int)file->size; + g_conf_replace_new_len_align = align; + + g_conf_replace_node = node; + g_conf_replace_offset = offset + 2; + + debug("conf_replace OK: newlen: %d\n", g_conf_replace_new_len); + +end: + if (file) + { + grub_file_close(file); + } + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i = 0; + int pos = 0; + char *buf = NULL; + char configfile[128]; + install_template *node = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + debug("select auto installation argc:%d\n", argc); + + if (argc < 1) + { + return 0; + } + + node = ventoy_plugin_find_install_template(args[0]); + if (!node) + { + debug("Auto install template not found for %s\n", args[0]); + return 0; + } + + if (node->autosel >= 0 && node->autosel <= node->templatenum) + { + node->cursel = node->autosel - 1; + debug("Auto install template auto select %d\n", node->autosel); + return 0; + } + + buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF); + if (!buf) + { + return 0; + } + + vtoy_ssprintf(buf, pos, "menuentry \"Boot without auto installation template\" {\n" + " echo %s\n}\n", "123"); + + for (i = 0; i < node->templatenum; i++) + { + vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n" + " echo 123\n}\n", + node->templatepath[i].path); + } + + g_ventoy_menu_esc = 1; + g_ventoy_suppress_esc = 1; + + grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos); + grub_script_execute_sourcecode(configfile); + + g_ventoy_menu_esc = 0; + g_ventoy_suppress_esc = 0; + + grub_free(buf); + + node->cursel = g_ventoy_last_entry - 1; + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i = 0; + int pos = 0; + char *buf = NULL; + char configfile[128]; + persistence_config *node; + + (void)ctxt; + (void)argc; + (void)args; + + debug("select persistence argc:%d\n", argc); + + if (argc < 1) + { + return 0; + } + + node = ventoy_plugin_find_persistent(args[0]); + if (!node) + { + debug("Persistence image not found for %s\n", args[0]); + return 0; + } + + if (node->autosel >= 0 && node->autosel <= node->backendnum) + { + node->cursel = node->autosel - 1; + debug("Persistence image auto select %d\n", node->autosel); + return 0; + } + + buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF); + if (!buf) + { + return 0; + } + + vtoy_ssprintf(buf, pos, "menuentry \"Boot without persistence\" {\n" + " echo %s\n}\n", "123"); + + for (i = 0; i < node->backendnum; i++) + { + vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n" + " echo 123\n}\n", + node->backendpath[i].path); + + } + + g_ventoy_menu_esc = 1; + g_ventoy_suppress_esc = 1; + + grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos); + grub_script_execute_sourcecode(configfile); + + g_ventoy_menu_esc = 0; + g_ventoy_suppress_esc = 0; + + grub_free(buf); + + node->cursel = g_ventoy_last_entry - 1; + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_dump_img_sector(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t i; + ventoy_img_chunk *cur; + + (void)ctxt; + (void)argc; + (void)args; + + for (i = 0; i < g_img_chunk_list.cur_chunk; i++) + { + cur = g_img_chunk_list.chunk + i; + grub_printf("image:[%u - %u] <==> disk:[%llu - %llu]\n", + cur->img_start_sector, cur->img_end_sector, + (unsigned long long)cur->disk_start_sector, (unsigned long long)cur->disk_end_sector + ); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_test_block_list(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t i; + grub_file_t file; + ventoy_img_chunk_list chunklist; + + (void)ctxt; + (void)argc; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]); + } + + /* get image chunk data */ + grub_memset(&chunklist, 0, sizeof(chunklist)); + chunklist.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); + if (NULL == chunklist.chunk) + { + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); + } + + chunklist.max_chunk = DEFAULT_CHUNK_NUM; + chunklist.cur_chunk = 0; + + ventoy_get_block_list(file, &chunklist, 0); + + if (0 != ventoy_check_block_list(file, &chunklist, 0)) + { + grub_printf("########## UNSUPPORTED ###############\n"); + } + + grub_printf("filesystem: <%s> entry number:<%u>\n", file->fs->name, chunklist.cur_chunk); + + for (i = 0; i < chunklist.cur_chunk; i++) + { + grub_printf("%llu+%llu,", (ulonglong)chunklist.chunk[i].disk_start_sector, + (ulonglong)(chunklist.chunk[i].disk_end_sector + 1 - chunklist.chunk[i].disk_start_sector)); + } + + grub_printf("\n==================================\n"); + + for (i = 0; i < chunklist.cur_chunk; i++) + { + grub_printf("%2u: [%llu %llu] - [%llu %llu]\n", i, + (ulonglong)chunklist.chunk[i].img_start_sector, + (ulonglong)chunklist.chunk[i].img_end_sector, + (ulonglong)chunklist.chunk[i].disk_start_sector, + (ulonglong)chunklist.chunk[i].disk_end_sector + ); + } + + grub_free(chunklist.chunk); + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_add_replace_file(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + ventoy_grub_param_file_replace *replace = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc >= 2) + { + replace = &(g_grub_param->file_replace); + replace->magic = GRUB_FILE_REPLACE_MAGIC; + + replace->old_name_cnt = 0; + for (i = 0; i < 4 && i + 1 < argc; i++) + { + replace->old_name_cnt++; + grub_snprintf(replace->old_file_name[i], sizeof(replace->old_file_name[i]), "%s", args[i + 1]); + } + + replace->new_file_virtual_id = (grub_uint32_t)grub_strtoul(args[0], NULL, 10); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_dump_menu(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + if (argc == 0) + { + grub_printf("List Mode: CurLen:%d MaxLen:%u\n", g_list_script_pos, VTOY_MAX_SCRIPT_BUF); + grub_printf("%s", g_list_script_buf); + } + else + { + grub_printf("Tree Mode: CurLen:%d MaxLen:%u\n", g_tree_script_pos, VTOY_MAX_SCRIPT_BUF); + grub_printf("%s", g_tree_script_buf); + } + + return 0; +} + +static grub_err_t ventoy_cmd_dump_img_list(grub_extcmd_context_t ctxt, int argc, char **args) +{ + img_info *cur = g_ventoy_img_list; + + (void)ctxt; + (void)argc; + (void)args; + + while (cur) + { + grub_printf("path:<%s> id=%d list_index=%d\n", cur->path, cur->id, cur->plugin_list_index); + grub_printf("name:<%s>\n\n", cur->name); + cur = cur->next; + } + + return 0; +} + +static grub_err_t ventoy_cmd_dump_injection(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_plugin_dump_injection(); + + return 0; +} + +static grub_err_t ventoy_cmd_dump_auto_install(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_plugin_dump_auto_install(); + + return 0; +} + +static grub_err_t ventoy_cmd_dump_persistence(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_plugin_dump_persistence(); + + return 0; +} + +static grub_err_t ventoy_cmd_check_mode(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 1) + { + return 1; + } + + if (args[0][0] == '0') + { + return g_ventoy_memdisk_mode ? 0 : 1; + } + else if (args[0][0] == '1') + { + return g_ventoy_iso_raw ? 0 : 1; + } + else if (args[0][0] == '2') + { + return g_ventoy_iso_uefi_drv ? 0 : 1; + } + else if (args[0][0] == '3') + { + return g_ventoy_grub2_mode ? 0 : 1; + } + + return 1; +} + +static grub_err_t ventoy_cmd_dynamic_menu(grub_extcmd_context_t ctxt, int argc, char **args) +{ + static int configfile_mode = 0; + char memfile[128] = {0}; + + (void)ctxt; + (void)argc; + (void)args; + + /* + * args[0]: 0:normal 1:configfile + * args[1]: 0:list_buf 1:tree_buf + */ + + if (argc != 2) + { + debug("Invalid argc %d\n", argc); + return 0; + } + + VTOY_CMD_CHECK(1); + + if (args[0][0] == '0') + { + if (args[1][0] == '0') + { + grub_script_execute_sourcecode(g_list_script_buf); + } + else + { + grub_script_execute_sourcecode(g_tree_script_buf); + } + } + else + { + if (configfile_mode) + { + debug("Now already in F3 mode %d\n", configfile_mode); + return 0; + } + + if (args[1][0] == '0') + { + grub_snprintf(memfile, sizeof(memfile), "configfile mem:0x%llx:size:%d", + (ulonglong)(ulong)g_list_script_buf, g_list_script_pos); + } + else + { + g_ventoy_last_entry = -1; + grub_snprintf(memfile, sizeof(memfile), "configfile mem:0x%llx:size:%d", + (ulonglong)(ulong)g_tree_script_buf, g_tree_script_pos); + } + + configfile_mode = 1; + grub_script_execute_sourcecode(memfile); + configfile_mode = 0; + } + + return 0; +} + +static grub_err_t ventoy_cmd_file_exist_nocase(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_file_t file; + + (void)ctxt; + + if (argc != 1) + { + return 1; + } + + g_ventoy_case_insensitive = 1; + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + g_ventoy_case_insensitive = 0; + + grub_errno = 0; + + if (file) + { + grub_file_close(file); + return 0; + } + return 1; +} + +static grub_err_t ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int id = 0; + int find = 0; + grub_disk_t disk; + const char *isopath = NULL; + char hdname[32]; + ventoy_mbr_head mbr; + + (void)ctxt; + (void)argc; + + if (argc != 1) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s variable\n", cmd_raw_name); + } + + isopath = grub_env_get("vtoy_iso_part"); + if (!isopath) + { + debug("isopath is null %p\n", isopath); + return 0; + } + + debug("isopath is %s\n", isopath); + + for (id = 0; id < 30 && (find == 0); id++) + { + grub_snprintf(hdname, sizeof(hdname), "hd%d,", id); + if (grub_strstr(isopath, hdname)) + { + debug("skip %s ...\n", hdname); + continue; + } + + grub_snprintf(hdname, sizeof(hdname), "hd%d", id); + + disk = grub_disk_open(hdname); + if (!disk) + { + debug("%s not exist\n", hdname); + break; + } + + grub_memset(&mbr, 0, sizeof(mbr)); + if (0 == grub_disk_read(disk, 0, 0, 512, &mbr)) + { + if (mbr.Byte55 == 0x55 && mbr.ByteAA == 0xAA) + { + if (mbr.PartTbl[0].Active == 0x80 || mbr.PartTbl[1].Active == 0x80 || + mbr.PartTbl[2].Active == 0x80 || mbr.PartTbl[3].Active == 0x80) + { + + grub_env_set(args[0], hdname); + find = 1; + } + } + debug("%s is %s\n", hdname, find ? "bootable" : "NOT bootable"); + } + else + { + debug("read %s failed\n", hdname); + } + + grub_disk_close(disk); + } + + return 0; +} + +static grub_err_t ventoy_cmd_read_1st_line(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len = 1024; + grub_file_t file; + char *buf = NULL; + + (void)ctxt; + (void)argc; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s file var \n", cmd_raw_name); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 0; + } + + buf = grub_malloc(len); + if (!buf) + { + goto end; + } + + buf[len - 1] = 0; + grub_file_read(file, buf, len - 1); + + ventoy_get_line(buf); + ventoy_set_env(args[1], buf); + +end: + + grub_check_free(buf); + grub_file_close(file); + + return 0; +} + +static int ventoy_img_partition_callback (struct grub_disk *disk, const grub_partition_t partition, void *data) +{ + (void)disk; + (void)data; + + g_part_list_pos += grub_snprintf(g_part_list_buf + g_part_list_pos, VTOY_MAX_SCRIPT_BUF - g_part_list_pos, + "0 %llu linear /dev/ventoy %llu\n", + (ulonglong)partition->len, (ulonglong)partition->start); + + return 0; +} + +static grub_err_t ventoy_cmd_img_part_info(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char *device_name = NULL; + grub_device_t dev = NULL; + char buf[64]; + + (void)ctxt; + + g_part_list_pos = 0; + grub_env_unset("vtoy_img_part_file"); + + if (argc != 1) + { + return 1; + } + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + debug("ventoy_cmd_img_part_info failed, %s\n", args[0]); + goto end; + } + + dev = grub_device_open(device_name); + if (!dev) + { + debug("grub_device_open failed, %s\n", device_name); + goto end; + } + + grub_partition_iterate(dev->disk, ventoy_img_partition_callback, NULL); + + grub_snprintf(buf, sizeof(buf), "newc:vtoy_dm_table:mem:0x%llx:size:%d", (ulonglong)(ulong)g_part_list_buf, g_part_list_pos); + grub_env_set("vtoy_img_part_file", buf); + +end: + + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + return 0; +} + + +static grub_err_t ventoy_cmd_file_strstr(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + grub_file_t file; + char *buf = NULL; + + (void)ctxt; + (void)argc; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s file str \n", cmd_raw_name); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 1; + } + + buf = grub_malloc(file->size + 1); + if (!buf) + { + goto end; + } + + buf[file->size] = 0; + grub_file_read(file, buf, file->size); + + if (grub_strstr(buf, args[1])) + { + rc = 0; + } + +end: + + grub_check_free(buf); + grub_file_close(file); + + return rc; +} + +static grub_err_t ventoy_cmd_parse_volume(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len; + grub_file_t file; + char buf[64]; + grub_uint64_t size; + ventoy_iso9660_vd pvd; + + (void)ctxt; + (void)argc; + + if (argc != 4) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s sysid volid space \n", cmd_raw_name); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 0; + } + + grub_file_seek(file, 16 * 2048); + len = (int)grub_file_read(file, &pvd, sizeof(pvd)); + if (len != sizeof(pvd)) + { + debug("failed to read pvd %d\n", len); + goto end; + } + + grub_memset(buf, 0, sizeof(buf)); + grub_memcpy(buf, pvd.sys, sizeof(pvd.sys)); + ventoy_set_env(args[1], buf); + + grub_memset(buf, 0, sizeof(buf)); + grub_memcpy(buf, pvd.vol, sizeof(pvd.vol)); + ventoy_set_env(args[2], buf); + + size = pvd.space; + size *= 2048; + grub_snprintf(buf, sizeof(buf), "%llu", (ulonglong)size); + ventoy_set_env(args[3], buf); + +end: + grub_file_close(file); + + return 0; +} + +static grub_err_t ventoy_cmd_parse_create_date(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len; + grub_file_t file; + char buf[64]; + + (void)ctxt; + (void)argc; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s var \n", cmd_raw_name); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 0; + } + + grub_memset(buf, 0, sizeof(buf)); + grub_file_seek(file, 16 * 2048 + 813); + len = (int)grub_file_read(file, buf, 17); + if (len != 17) + { + debug("failed to read create date %d\n", len); + goto end; + } + + ventoy_set_env(args[1], buf); + +end: + grub_file_close(file); + + return 0; +} + +static grub_err_t ventoy_cmd_img_hook_root(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_env_hook_root(1); + + return 0; +} + +static grub_err_t ventoy_cmd_img_unhook_root(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_env_hook_root(0); + + return 0; +} + +#ifdef GRUB_MACHINE_EFI +static grub_err_t ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret = 1; + grub_uint8_t *var; + grub_size_t size; + grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; + + (void)ctxt; + (void)argc; + (void)args; + + var = grub_efi_get_variable("SecureBoot", &global, &size); + if (var && *var == 1) + { + return 0; + } + + return ret; +} +#else +static grub_err_t ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + return 1; +} +#endif + +static grub_err_t ventoy_cmd_img_check_range(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int ret = 1; + grub_file_t file; + grub_uint64_t FileSectors = 0; + ventoy_gpt_info *gpt = NULL; + ventoy_part_table *pt = NULL; + grub_uint8_t zeroguid[16] = {0}; + + (void)ctxt; + (void)argc; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 1; + } + + if (file->size % 512) + { + debug("unaligned file size: %llu\n", (ulonglong)file->size); + goto out; + } + + gpt = grub_zalloc(sizeof(ventoy_gpt_info)); + if (!gpt) + { + goto out; + } + + FileSectors = file->size / 512; + + grub_file_read(file, gpt, sizeof(ventoy_gpt_info)); + if (grub_strncmp(gpt->Head.Signature, "EFI PART", 8) == 0) + { + debug("This is EFI partition table\n"); + + for (i = 0; i < 128; i++) + { + if (grub_memcmp(gpt->PartTbl[i].PartGuid, zeroguid, 16)) + { + if (FileSectors < gpt->PartTbl[i].LastLBA) + { + debug("out of range: part[%d] LastLBA:%llu FileSectors:%llu\n", i, + (ulonglong)gpt->PartTbl[i].LastLBA, (ulonglong)FileSectors); + goto out; + } + } + } + } + else + { + debug("This is MBR partition table\n"); + + for (i = 0; i < 4; i++) + { + pt = gpt->MBR.PartTbl + i; + if (FileSectors < pt->StartSectorId + pt->SectorCount) + { + debug("out of range: part[%d] LastLBA:%llu FileSectors:%llu\n", i, + (ulonglong)(pt->StartSectorId + pt->SectorCount), + (ulonglong)FileSectors); + goto out; + } + } + } + + ret = 0; + +out: + grub_file_close(file); + grub_check_free(gpt); + grub_errno = GRUB_ERR_NONE; + return ret; +} + +static grub_err_t ventoy_cmd_clear_key(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int ret; + + (void)ctxt; + (void)argc; + (void)args; + + for (i = 0; i < 500; i++) + { + ret = grub_getkey_noblock(); + if (ret == GRUB_TERM_NO_KEY) + { + break; + } + } + + if (i >= 500) + { + grub_cls(); + grub_printf("\n\n Still have key input after clear.\n"); + grub_refresh(); + grub_sleep(5); + } + + return 0; +} + +static grub_err_t ventoy_cmd_acpi_param(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int buflen; + int datalen; + int loclen; + int img_chunk_num; + int image_sector_size; + char cmd[64]; + ventoy_chain_head *chain; + ventoy_img_chunk *chunk; + ventoy_os_param *osparam; + ventoy_image_location *location; + ventoy_image_disk_region *region; + struct grub_acpi_table_header *acpi; + + (void)ctxt; + + if (argc != 2) + { + return 1; + } + + debug("ventoy_cmd_acpi_param %s %s\n", args[0], args[1]); + + chain = (ventoy_chain_head *)(ulong)grub_strtoul(args[0], NULL, 16); + if (!chain) + { + return 1; + } + + image_sector_size = (int)grub_strtol(args[1], NULL, 10); + + if (grub_memcmp(&g_ventoy_guid, &(chain->os_param.guid), 16)) + { + debug("Invalid ventoy guid 0x%x\n", chain->os_param.guid.data1); + return 1; + } + + img_chunk_num = chain->img_chunk_num; + + loclen = sizeof(ventoy_image_location) + (img_chunk_num - 1) * sizeof(ventoy_image_disk_region); + datalen = sizeof(ventoy_os_param) + loclen; + + buflen = sizeof(struct grub_acpi_table_header) + datalen; + acpi = grub_zalloc(buflen); + if (!acpi) + { + return 1; + } + + /* Step1: Fill acpi table header */ + grub_memcpy(acpi->signature, "VTOY", 4); + acpi->length = buflen; + acpi->revision = 1; + grub_memcpy(acpi->oemid, "VENTOY", 6); + grub_memcpy(acpi->oemtable, "OSPARAMS", 8); + acpi->oemrev = 1; + acpi->creator_id[0] = 1; + acpi->creator_rev = 1; + + /* Step2: Fill data */ + osparam = (ventoy_os_param *)(acpi + 1); + grub_memcpy(osparam, &chain->os_param, sizeof(ventoy_os_param)); + osparam->vtoy_img_location_addr = 0; + osparam->vtoy_img_location_len = loclen; + osparam->chksum = 0; + osparam->chksum = 0x100 - grub_byte_checksum(osparam, sizeof(ventoy_os_param)); + + location = (ventoy_image_location *)(osparam + 1); + grub_memcpy(&location->guid, &osparam->guid, sizeof(ventoy_guid)); + location->image_sector_size = image_sector_size; + location->disk_sector_size = chain->disk_sector_size; + location->region_count = img_chunk_num; + + region = location->regions; + chunk = (ventoy_img_chunk *)((char *)chain + chain->img_chunk_offset); + if (512 == image_sector_size) + { + for (i = 0; i < img_chunk_num; i++) + { + region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1; + region->image_start_sector = chunk->img_start_sector * 4; + region->disk_start_sector = chunk->disk_start_sector; + region++; + chunk++; + } + } + else + { + for (i = 0; i < img_chunk_num; i++) + { + region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1; + region->image_start_sector = chunk->img_start_sector; + region->disk_start_sector = chunk->disk_start_sector; + region++; + chunk++; + } + } + + /* Step3: Fill acpi checksum */ + acpi->checksum = 0; + acpi->checksum = 0x100 - grub_byte_checksum(acpi, acpi->length); + + /* load acpi table */ + grub_snprintf(cmd, sizeof(cmd), "acpi mem:0x%lx:size:%d", (ulong)acpi, acpi->length); + grub_script_execute_sourcecode(cmd); + + grub_free(acpi); + + VENTOY_CMD_RETURN(0); +} + +static grub_err_t ventoy_cmd_push_last_entry(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_ventoy_last_entry_back = g_ventoy_last_entry; + g_ventoy_last_entry = -1; + + return 0; +} + +static grub_err_t ventoy_cmd_pop_last_entry(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_ventoy_last_entry = g_ventoy_last_entry_back; + + return 0; +} + +static int ventoy_lib_module_callback(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + const char *pos = filename + 1; + + if (info->dir) + { + while (*pos) + { + if (*pos == '.') + { + if ((*(pos - 1) >= '0' && *(pos - 1) <= '9') && (*(pos + 1) >= '0' && *(pos + 1) <= '9')) + { + grub_strncpy((char *)data, filename, 128); + return 1; + } + } + pos++; + } + } + + return 0; +} + +static grub_err_t ventoy_cmd_lib_module_ver(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + char *device_name = NULL; + grub_device_t dev = NULL; + grub_fs_t fs = NULL; + char buf[128] = {0}; + + (void)ctxt; + + if (argc != 3) + { + debug("ventoy_cmd_lib_module_ver, invalid param num %d\n", argc); + return 1; + } + + debug("ventoy_cmd_lib_module_ver %s %s %s\n", args[0], args[1], args[2]); + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + debug("grub_file_get_device_name failed, %s\n", args[0]); + goto end; + } + + dev = grub_device_open(device_name); + if (!dev) + { + debug("grub_device_open failed, %s\n", device_name); + goto end; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + debug("grub_fs_probe failed, %s\n", device_name); + goto end; + } + + fs->fs_dir(dev, args[1], ventoy_lib_module_callback, buf); + + if (buf[0]) + { + ventoy_set_env(args[2], buf); + } + + rc = 0; + +end: + + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + return rc; +} + +int ventoy_load_part_table(const char *diskname) +{ + char name[64]; + int ret; + grub_disk_t disk; + grub_device_t dev; + + g_ventoy_part_info = grub_zalloc(sizeof(ventoy_gpt_info)); + if (!g_ventoy_part_info) + { + return 1; + } + + disk = grub_disk_open(diskname); + if (!disk) + { + debug("Failed to open disk %s\n", diskname); + return 1; + } + + g_ventoy_disk_size = disk->total_sectors * (1U << disk->log_sector_size); + + grub_disk_read(disk, 0, 0, sizeof(ventoy_gpt_info), g_ventoy_part_info); + grub_disk_close(disk); + + grub_snprintf(name, sizeof(name), "%s,1", diskname); + dev = grub_device_open(name); + if (dev) + { + /* Check for official Ventoy device */ + ret = ventoy_check_official_device(dev); + grub_device_close(dev); + + if (ret) + { + return 1; + } + } + + g_ventoy_disk_part_size[0] = ventoy_get_vtoy_partsize(0); + g_ventoy_disk_part_size[1] = ventoy_get_vtoy_partsize(1); + + return 0; +} + +static grub_err_t ventoy_cmd_load_part_table(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret; + + (void)argc; + (void)ctxt; + + ret = ventoy_load_part_table(args[0]); + if (ret) + { + grub_exit(); + } + + g_ventoy_disk_part_size[0] = ventoy_get_vtoy_partsize(0); + g_ventoy_disk_part_size[1] = ventoy_get_vtoy_partsize(1); + + return 0; +} + +static grub_err_t ventoy_cmd_check_custom_boot(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret = 1; + const char *vcfg = NULL; + + (void)argc; + (void)ctxt; + + vcfg = ventoy_plugin_get_custom_boot(args[0]); + if (vcfg) + { + debug("custom boot <%s>:<%s>\n", args[0], vcfg); + grub_env_set(args[1], vcfg); + ret = 0; + } + else + { + debug("custom boot <%s>:\n", args[0]); + } + + grub_errno = 0; + return ret; +} + + +static grub_err_t ventoy_cmd_part_exist(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int id; + grub_uint8_t zeroguid[16] = {0}; + + (void)argc; + (void)ctxt; + + id = (int)grub_strtoul(args[0], NULL, 10); + grub_errno = 0; + + if (grub_memcmp(g_ventoy_part_info->Head.Signature, "EFI PART", 8) == 0) + { + if (id >= 1 && id <= 128) + { + if (grub_memcmp(g_ventoy_part_info->PartTbl[id - 1].PartGuid, zeroguid, 16)) + { + return 0; + } + } + } + else + { + if (id >= 1 && id <= 4) + { + if (g_ventoy_part_info->MBR.PartTbl[id - 1].FsFlag) + { + return 0; + } + } + } + + return 1; +} + +static grub_err_t ventoy_cmd_get_fs_label(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + char *device_name = NULL; + grub_device_t dev = NULL; + grub_fs_t fs = NULL; + char *label = NULL; + + (void)ctxt; + + debug("get fs label for %s\n", args[0]); + + if (argc != 2) + { + debug("ventoy_cmd_get_fs_label, invalid param num %d\n", argc); + return 1; + } + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + debug("grub_file_get_device_name failed, %s\n", args[0]); + goto end; + } + + dev = grub_device_open(device_name); + if (!dev) + { + debug("grub_device_open failed, %s\n", device_name); + goto end; + } + + fs = grub_fs_probe(dev); + if (NULL == fs || NULL == fs->fs_label) + { + debug("grub_fs_probe failed, %s %p %p\n", device_name, fs, fs->fs_label); + goto end; + } + + fs->fs_label(dev, &label); + if (label) + { + debug("label=<%s>\n", label); + ventoy_set_env(args[1], label); + grub_free(label); + } + + rc = 0; + +end: + + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + return rc; +} + +static int ventoy_fs_enum_1st_file(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + if (!info->dir) + { + grub_snprintf((char *)data, 256, "%s", filename); + return 1; + } + + return 0; +} + + +static grub_err_t ventoy_cmd_fs_enum_1st_file(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + char *device_name = NULL; + grub_device_t dev = NULL; + grub_fs_t fs = NULL; + char name[256] ={0}; + + (void)ctxt; + + if (argc != 3) + { + debug("ventoy_cmd_fs_enum_1st_file, invalid param num %d\n", argc); + return 1; + } + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + debug("grub_file_get_device_name failed, %s\n", args[0]); + goto end; + } + + dev = grub_device_open(device_name); + if (!dev) + { + debug("grub_device_open failed, %s\n", device_name); + goto end; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + debug("grub_fs_probe failed, %s\n", device_name); + goto end; + } + + fs->fs_dir(dev, args[1], ventoy_fs_enum_1st_file, name); + if (name[0]) + { + ventoy_set_env(args[2], name); + } + + rc = 0; + +end: + + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + return rc; +} + +static grub_err_t ventoy_cmd_basename(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char c; + char *pos = NULL; + char *end = NULL; + + (void)ctxt; + + if (argc != 2) + { + debug("ventoy_cmd_basename, invalid param num %d\n", argc); + return 1; + } + + for (pos = args[0]; *pos; pos++) + { + if (*pos == '.') + { + end = pos; + } + } + + if (end) + { + c = *end; + *end = 0; + } + + grub_env_set(args[1], args[0]); + + if (end) + { + *end = c; + } + + return 0; +} + +static grub_err_t ventoy_cmd_basefile(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int len; + const char *buf; + + (void)ctxt; + + if (argc != 2) + { + debug("ventoy_cmd_basefile, invalid param num %d\n", argc); + return 1; + } + + buf = args[0]; + len = (int)grub_strlen(buf); + for (i = len; i > 0; i--) + { + if (buf[i - 1] == '/') + { + grub_env_set(args[1], buf + i); + return 0; + } + } + + grub_env_set(args[1], buf); + + return 0; +} + +static grub_err_t ventoy_cmd_enum_video_mode(grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_video_mode_info info; + char buf[32]; + + (void)ctxt; + (void)argc; + (void)args; + + if (!g_video_mode_list) + { + ventoy_enum_video_mode(); + } + + if (grub_video_get_info(&info) == GRUB_ERR_NONE) + { + grub_snprintf(buf, sizeof(buf), "Resolution (%ux%u)", info.width, info.height); + } + else + { + grub_snprintf(buf, sizeof(buf), "Resolution (0x0)"); + } + + grub_env_set("VTOY_CUR_VIDEO_MODE", buf); + + grub_snprintf(buf, sizeof(buf), "%d", g_video_mode_num); + grub_env_set("VTOY_VIDEO_MODE_NUM", buf); + + VENTOY_CMD_RETURN(0); +} + +static grub_err_t vt_cmd_update_cur_video_mode(grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_video_mode_info info; + char buf[32]; + + (void)ctxt; + (void)argc; + (void)args; + + if (grub_video_get_info(&info) == GRUB_ERR_NONE) + { + grub_snprintf(buf, sizeof(buf), "%ux%ux%u", info.width, info.height, info.bpp); + } + else + { + grub_snprintf(buf, sizeof(buf), "0x0x0"); + } + + grub_env_set(args[0], buf); + + VENTOY_CMD_RETURN(0); +} + +static grub_err_t ventoy_cmd_get_video_mode(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int id; + char buf[32]; + + (void)ctxt; + (void)argc; + + if (!g_video_mode_list) + { + return 0; + } + + id = (int)grub_strtoul(args[0], NULL, 10); + if (id < g_video_mode_num) + { + grub_snprintf(buf, sizeof(buf), "%ux%ux%u", + g_video_mode_list[id].width, g_video_mode_list[id].height, g_video_mode_list[id].bpp); + } + + grub_env_set(args[1], buf); + + VENTOY_CMD_RETURN(0); +} + +int ventoy_env_init(void) +{ + char buf[64]; + + grub_env_set("vtdebug_flag", ""); + + g_part_list_buf = grub_malloc(VTOY_PART_BUF_LEN); + g_tree_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); + g_list_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); + g_conf_replace_new_buf = grub_malloc(vtoy_max_replace_file_size); + + ventoy_filt_register(0, ventoy_wrapper_open); + + g_grub_param = (ventoy_grub_param *)grub_zalloc(sizeof(ventoy_grub_param)); + if (g_grub_param) + { + g_grub_param->grub_env_get = grub_env_get; + g_grub_param->grub_env_set = (grub_env_set_pf)grub_env_set; + g_grub_param->grub_env_printf = (grub_env_printf_pf)grub_printf; + grub_snprintf(buf, sizeof(buf), "%p", g_grub_param); + grub_env_set("env_param", buf); + grub_env_set("ventoy_env_param", buf); + + grub_env_export("env_param"); + grub_env_export("ventoy_env_param"); + } + + return 0; +} + +static cmd_para ventoy_cmds[] = +{ + { "vt_incr", ventoy_cmd_incr, 0, NULL, "{Var} {INT}", "Increase integer variable", NULL }, + { "vt_mod", ventoy_cmd_mod, 0, NULL, "{Int} {Int} {Var}", "mod integer variable", NULL }, + { "vt_strstr", ventoy_cmd_strstr, 0, NULL, "", "", NULL }, + { "vt_str_begin", ventoy_cmd_strbegin, 0, NULL, "", "", NULL }, + { "vt_debug", ventoy_cmd_debug, 0, NULL, "{on|off}", "turn debug on/off", NULL }, + { "vtdebug", ventoy_cmd_debug, 0, NULL, "{on|off}", "turn debug on/off", NULL }, + { "vtbreak", ventoy_cmd_break, 0, NULL, "{level}", "set debug break", NULL }, + { "vt_cmp", ventoy_cmd_cmp, 0, NULL, "{Int1} { eq|ne|gt|lt|ge|le } {Int2}", "Comare two integers", NULL }, + { "vt_device", ventoy_cmd_device, 0, NULL, "path var", "", NULL }, + { "vt_check_compatible", ventoy_cmd_check_compatible, 0, NULL, "", "", NULL }, + { "vt_list_img", ventoy_cmd_list_img, 0, NULL, "{device} {cntvar}", "find all iso file in device", NULL }, + { "vt_clear_img", ventoy_cmd_clear_img, 0, NULL, "", "clear image list", NULL }, + { "vt_img_name", ventoy_cmd_img_name, 0, NULL, "{imageID} {var}", "get image name", NULL }, + { "vt_chosen_img_path", ventoy_cmd_chosen_img_path, 0, NULL, "{var}", "get chosen img path", NULL }, + { "vt_ext_select_img_path", ventoy_cmd_ext_select_img_path, 0, NULL, "{var}", "select chosen img path", NULL }, + { "vt_img_sector", ventoy_cmd_img_sector, 0, NULL, "{imageName}", "", NULL }, + { "vt_dump_img_sector", ventoy_cmd_dump_img_sector, 0, NULL, "", "", NULL }, + { "vt_load_wimboot", ventoy_cmd_load_wimboot, 0, NULL, "", "", NULL }, + { "vt_load_vhdboot", ventoy_cmd_load_vhdboot, 0, NULL, "", "", NULL }, + { "vt_patch_vhdboot", ventoy_cmd_patch_vhdboot, 0, NULL, "", "", NULL }, + { "vt_raw_chain_data", ventoy_cmd_raw_chain_data, 0, NULL, "", "", NULL }, + { "vt_get_vtoy_type", ventoy_cmd_get_vtoy_type, 0, NULL, "", "", NULL }, + { "vt_check_custom_boot", ventoy_cmd_check_custom_boot, 0, NULL, "", "", NULL }, + { "vt_dump_custom_boot", ventoy_cmd_dump_custom_boot, 0, NULL, "", "", NULL }, + + { "vt_skip_svd", ventoy_cmd_skip_svd, 0, NULL, "", "", NULL }, + { "vt_cpio_busybox64", ventoy_cmd_cpio_busybox_64, 0, NULL, "", "", NULL }, + { "vt_load_cpio", ventoy_cmd_load_cpio, 0, NULL, "", "", NULL }, + { "vt_trailer_cpio", ventoy_cmd_trailer_cpio, 0, NULL, "", "", NULL }, + { "vt_push_last_entry", ventoy_cmd_push_last_entry, 0, NULL, "", "", NULL }, + { "vt_pop_last_entry", ventoy_cmd_pop_last_entry, 0, NULL, "", "", NULL }, + { "vt_get_lib_module_ver", ventoy_cmd_lib_module_ver, 0, NULL, "", "", NULL }, + + { "vt_load_part_table", ventoy_cmd_load_part_table, 0, NULL, "", "", NULL }, + { "vt_check_part_exist", ventoy_cmd_part_exist, 0, NULL, "", "", NULL }, + { "vt_get_fs_label", ventoy_cmd_get_fs_label, 0, NULL, "", "", NULL }, + { "vt_fs_enum_1st_file", ventoy_cmd_fs_enum_1st_file, 0, NULL, "", "", NULL }, + { "vt_file_basename", ventoy_cmd_basename, 0, NULL, "", "", NULL }, + { "vt_file_basefile", ventoy_cmd_basefile, 0, NULL, "", "", NULL }, + { "vt_enum_video_mode", ventoy_cmd_enum_video_mode, 0, NULL, "", "", NULL }, + { "vt_get_video_mode", ventoy_cmd_get_video_mode, 0, NULL, "", "", NULL }, + { "vt_update_cur_video_mode", vt_cmd_update_cur_video_mode, 0, NULL, "", "", NULL }, + + + { "vt_find_first_bootable_hd", ventoy_cmd_find_bootable_hdd, 0, NULL, "", "", NULL }, + { "vt_dump_menu", ventoy_cmd_dump_menu, 0, NULL, "", "", NULL }, + { "vt_dynamic_menu", ventoy_cmd_dynamic_menu, 0, NULL, "", "", NULL }, + { "vt_check_mode", ventoy_cmd_check_mode, 0, NULL, "", "", NULL }, + { "vt_dump_img_list", ventoy_cmd_dump_img_list, 0, NULL, "", "", NULL }, + { "vt_dump_injection", ventoy_cmd_dump_injection, 0, NULL, "", "", NULL }, + { "vt_dump_auto_install", ventoy_cmd_dump_auto_install, 0, NULL, "", "", NULL }, + { "vt_dump_persistence", ventoy_cmd_dump_persistence, 0, NULL, "", "", NULL }, + { "vt_select_auto_install", ventoy_cmd_sel_auto_install, 0, NULL, "", "", NULL }, + { "vt_select_persistence", ventoy_cmd_sel_persistence, 0, NULL, "", "", NULL }, + { "vt_select_conf_replace", ventoy_select_conf_replace, 0, NULL, "", "", NULL }, + + { "vt_iso9660_nojoliet", ventoy_cmd_iso9660_nojoliet, 0, NULL, "", "", NULL }, + { "vt_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL }, + { "vt_file_size", ventoy_cmd_file_size, 0, NULL, "", "", NULL }, + { "vt_load_file_to_mem", ventoy_cmd_load_file_to_mem, 0, NULL, "", "", NULL }, + { "vt_load_img_memdisk", ventoy_cmd_load_img_memdisk, 0, NULL, "", "", NULL }, + { "vt_concat_efi_iso", ventoy_cmd_concat_efi_iso, 0, NULL, "", "", NULL }, + + { "vt_linux_parse_initrd_isolinux", ventoy_cmd_isolinux_initrd_collect, 0, NULL, "{cfgfile}", "", NULL }, + { "vt_linux_parse_initrd_grub", ventoy_cmd_grub_initrd_collect, 0, NULL, "{cfgfile}", "", NULL }, + { "vt_linux_specify_initrd_file", ventoy_cmd_specify_initrd_file, 0, NULL, "", "", NULL }, + { "vt_linux_clear_initrd", ventoy_cmd_clear_initrd_list, 0, NULL, "", "", NULL }, + { "vt_linux_dump_initrd", ventoy_cmd_dump_initrd_list, 0, NULL, "", "", NULL }, + { "vt_linux_initrd_count", ventoy_cmd_initrd_count, 0, NULL, "", "", NULL }, + { "vt_linux_valid_initrd_count", ventoy_cmd_valid_initrd_count, 0, NULL, "", "", NULL }, + { "vt_linux_locate_initrd", ventoy_cmd_linux_locate_initrd, 0, NULL, "", "", NULL }, + { "vt_linux_chain_data", ventoy_cmd_linux_chain_data, 0, NULL, "", "", NULL }, + { "vt_linux_get_main_initrd_index", ventoy_cmd_linux_get_main_initrd_index, 0, NULL, "", "", NULL }, + + { "vt_windows_reset", ventoy_cmd_wimdows_reset, 0, NULL, "", "", NULL }, + { "vt_windows_chain_data", ventoy_cmd_windows_chain_data, 0, NULL, "", "", NULL }, + { "vt_windows_collect_wim_patch", ventoy_cmd_collect_wim_patch, 0, NULL, "", "", NULL }, + { "vt_windows_locate_wim_patch", ventoy_cmd_locate_wim_patch, 0, NULL, "", "", NULL }, + { "vt_windows_count_wim_patch", ventoy_cmd_wim_patch_count, 0, NULL, "", "", NULL }, + { "vt_dump_wim_patch", ventoy_cmd_dump_wim_patch, 0, NULL, "", "", NULL }, + { "vt_wim_check_bootable", ventoy_cmd_wim_check_bootable, 0, NULL, "", "", NULL }, + { "vt_wim_chain_data", ventoy_cmd_wim_chain_data, 0, NULL, "", "", NULL }, + + { "vt_add_replace_file", ventoy_cmd_add_replace_file, 0, NULL, "", "", NULL }, + { "vt_test_block_list", ventoy_cmd_test_block_list, 0, NULL, "", "", NULL }, + { "vt_file_exist_nocase", ventoy_cmd_file_exist_nocase, 0, NULL, "", "", NULL }, + + + { "vt_load_plugin", ventoy_cmd_load_plugin, 0, NULL, "", "", NULL }, + { "vt_check_plugin_json", ventoy_cmd_plugin_check_json, 0, NULL, "", "", NULL }, + { "vt_check_password", ventoy_cmd_check_password, 0, NULL, "", "", NULL }, + + { "vt_1st_line", ventoy_cmd_read_1st_line, 0, NULL, "", "", NULL }, + { "vt_file_strstr", ventoy_cmd_file_strstr, 0, NULL, "", "", NULL }, + { "vt_img_part_info", ventoy_cmd_img_part_info, 0, NULL, "", "", NULL }, + + + { "vt_parse_iso_volume", ventoy_cmd_parse_volume, 0, NULL, "", "", NULL }, + { "vt_parse_iso_create_date", ventoy_cmd_parse_create_date, 0, NULL, "", "", NULL }, + { "vt_parse_freenas_ver", ventoy_cmd_parse_freenas_ver, 0, NULL, "", "", NULL }, + { "vt_unix_parse_freebsd_ver", ventoy_cmd_unix_freebsd_ver, 0, NULL, "", "", NULL }, + { "vt_unix_parse_freebsd_ver_elf", ventoy_cmd_unix_freebsd_ver_elf, 0, NULL, "", "", NULL }, + { "vt_unix_reset", ventoy_cmd_unix_reset, 0, NULL, "", "", NULL }, + { "vt_unix_replace_conf", ventoy_cmd_unix_replace_conf, 0, NULL, "", "", NULL }, + { "vt_unix_replace_ko", ventoy_cmd_unix_replace_ko, 0, NULL, "", "", NULL }, + { "vt_unix_fill_image_desc", ventoy_cmd_unix_fill_image_desc, 0, NULL, "", "", NULL }, + { "vt_unix_gzip_new_ko", ventoy_cmd_unix_gzip_newko, 0, NULL, "", "", NULL }, + { "vt_unix_chain_data", ventoy_cmd_unix_chain_data, 0, NULL, "", "", NULL }, + + { "vt_img_hook_root", ventoy_cmd_img_hook_root, 0, NULL, "", "", NULL }, + { "vt_img_unhook_root", ventoy_cmd_img_unhook_root, 0, NULL, "", "", NULL }, + { "vt_acpi_param", ventoy_cmd_acpi_param, 0, NULL, "", "", NULL }, + { "vt_check_secureboot_var", ventoy_cmd_check_secureboot_var, 0, NULL, "", "", NULL }, + { "vt_clear_key", ventoy_cmd_clear_key, 0, NULL, "", "", NULL }, + { "vt_img_check_range", ventoy_cmd_img_check_range, 0, NULL, "", "", NULL }, + +}; + +int ventoy_register_all_cmd(void) +{ + grub_uint32_t i; + cmd_para *cur = NULL; + + for (i = 0; i < ARRAY_SIZE(ventoy_cmds); i++) + { + cur = ventoy_cmds + i; + cur->cmd = grub_register_extcmd(cur->name, cur->func, cur->flags, + cur->summary, cur->description, cur->parser); + } + return 0; +} + +int ventoy_unregister_all_cmd(void) +{ + grub_uint32_t i; + + for (i = 0; i < ARRAY_SIZE(ventoy_cmds); i++) + { + grub_unregister_extcmd(ventoy_cmds[i].cmd); + } + + return 0; +} + + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h index 45f823f9..5e7e11d2 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h @@ -140,6 +140,7 @@ typedef struct cpio_newc_header typedef int (*grub_char_check_func)(int c); #define ventoy_is_decimal(str) ventoy_string_check(str, grub_isdigit) +#define OFFSET_OF(TYPE, MEMBER) ((grub_size_t) &((TYPE *)0)->MEMBER) #pragma pack(1) typedef struct ventoy_patch_vhd @@ -932,6 +933,8 @@ extern grub_uint8_t *g_conf_replace_new_buf; extern int g_conf_replace_new_len; extern int g_conf_replace_new_len_align; extern grub_uint64_t g_ventoy_disk_size; +extern grub_uint64_t g_ventoy_disk_part_size[2]; +extern grub_uint32_t g_ventoy_plat_data; #define ventoy_unix_fill_virt(new_data, new_len) \ { \ @@ -949,12 +952,16 @@ extern grub_uint64_t g_ventoy_disk_size; chain->virt_img_size_in_bytes += data_secs * 2048; \ } +#define ventoy_syscall0(name) grub_##name() +#define ventoy_syscall1(name, a) grub_##name(a) + char * ventoy_get_line(char *start); int ventoy_cmp_img(img_info *img1, img_info *img2); void ventoy_swap_img(img_info *img1, img_info *img2); char * ventoy_plugin_get_cur_install_template(const char *isopath); install_template * ventoy_plugin_find_install_template(const char *isopath); persistence_config * ventoy_plugin_find_persistent(const char *isopath); +grub_uint64_t ventoy_get_vtoy_partsize(int part); void ventoy_plugin_dump_injection(void); void ventoy_plugin_dump_auto_install(void); int ventoy_fill_windows_rtdata(void *buf, char *isopath); @@ -994,11 +1001,16 @@ grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char * grub_err_t ventoy_cmd_raw_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_get_vtoy_type(grub_extcmd_context_t ctxt, int argc, char **args); int ventoy_check_password(const vtoy_password *pwd, int retry); -int ventoy_gzip_compress(void *mem_in, int mem_in_len, void *mem_out, int mem_out_len); -grub_uint64_t ventoy_get_part1_size(ventoy_gpt_info *gpt); int ventoy_plugin_add_custom_boot(const char *vcfgpath); const char * ventoy_plugin_get_custom_boot(const char *isopath); grub_err_t ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt, int argc, char **args); +int ventoy_gzip_compress(void *mem_in, int mem_in_len, void *mem_out, int mem_out_len); +int ventoy_load_part_table(const char *diskname); +int ventoy_env_init(void); +int ventoy_register_all_cmd(void); +int ventoy_unregister_all_cmd(void); + +#define VTOY_CMD_CHECK(a) if (33554432 != g_ventoy_disk_part_size[a]) ventoy_syscall0(exit) #endif /* __VENTOY_DEF_H__ */ diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c index e74e7389..179739b2 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c @@ -720,7 +720,7 @@ grub_err_t ventoy_cmd_unix_fill_image_desc(grub_extcmd_context_t ctxt, int argc, desc = (ventoy_image_desc *)(byte + i); desc->disk_size = g_ventoy_disk_size; - desc->part1_size = ventoy_get_part1_size(g_ventoy_part_info); + desc->part1_size = g_ventoy_disk_part_size[0]; grub_memcpy(desc->disk_uuid, g_ventoy_part_info->MBR.BootCode + 0x180, 16); grub_memcpy(desc->disk_signature, g_ventoy_part_info->MBR.BootCode + 0x1B8, 4); diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_vhd.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_vhd.c index 0b8b00f5..a5203e2f 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_vhd.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_vhd.c @@ -44,14 +44,12 @@ GRUB_MOD_LICENSE ("GPLv3+"); -static int g_vhdboot_bcd_offset = 0; -static int g_vhdboot_bcd_len = 0; static int g_vhdboot_isolen = 0; static char *g_vhdboot_totbuf = NULL; static char *g_vhdboot_isobuf = NULL; static grub_uint64_t g_img_trim_head_secnum = 0; -static int ventoy_vhd_find_bcd(int *bcdoffset, int *bcdlen) +static int ventoy_vhd_find_bcd(int *bcdoffset, int *bcdlen, const char *path) { grub_uint32_t offset; grub_file_t file; @@ -61,10 +59,9 @@ static int ventoy_vhd_find_bcd(int *bcdoffset, int *bcdlen) grub_script_execute_sourcecode(cmdbuf); - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", "(vhdiso)/boot/bcd"); + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(vhdiso)%s", path); if (!file) { - grub_printf("Failed to open bcd file in the image file\n"); return 1; } @@ -83,13 +80,15 @@ static int ventoy_vhd_find_bcd(int *bcdoffset, int *bcdlen) return 0; } -static int ventoy_vhd_patch_path(char *vhdpath, ventoy_patch_vhd *patch1, ventoy_patch_vhd *patch2) +static int ventoy_vhd_patch_path(char *vhdpath, ventoy_patch_vhd *patch1, ventoy_patch_vhd *patch2, + int bcdoffset, int bcdlen) { int i; int cnt = 0; char *pos; grub_size_t pathlen; const char *plat; + char *newpath = NULL; grub_uint16_t *unicode_path; const grub_uint8_t winloadexe[] = { @@ -97,6 +96,11 @@ static int ventoy_vhd_patch_path(char *vhdpath, ventoy_patch_vhd *patch1, ventoy 0x65, 0x00, 0x78, 0x00, 0x65, 0x00 }; + while ((*vhdpath) != '/') + { + vhdpath++; + } + pathlen = sizeof(grub_uint16_t) * (grub_strlen(vhdpath) + 1); debug("unicode path for <%s> len:%d\n", vhdpath, (int)pathlen); @@ -110,10 +114,10 @@ static int ventoy_vhd_patch_path(char *vhdpath, ventoy_patch_vhd *patch1, ventoy if (plat && (plat[0] == 'e')) /* UEFI */ { - pos = g_vhdboot_isobuf + g_vhdboot_bcd_offset; + pos = g_vhdboot_isobuf + bcdoffset; /* winload.exe ==> winload.efi */ - for (i = 0; i + (int)sizeof(winloadexe) < g_vhdboot_bcd_len; i++) + for (i = 0; i + (int)sizeof(winloadexe) < bcdlen; i++) { if (*((grub_uint32_t *)(pos + i)) == 0x00690077 && grub_memcmp(pos + i, winloadexe, sizeof(winloadexe)) == 0) @@ -127,7 +131,8 @@ static int ventoy_vhd_patch_path(char *vhdpath, ventoy_patch_vhd *patch1, ventoy debug("winload patch %d times\n", cnt); } - for (pos = vhdpath; *pos; pos++) + newpath = grub_strdup(vhdpath); + for (pos = newpath; *pos; pos++) { if (*pos == '/') { @@ -135,40 +140,127 @@ static int ventoy_vhd_patch_path(char *vhdpath, ventoy_patch_vhd *patch1, ventoy } } - grub_utf8_to_utf16(unicode_path, pathlen, (grub_uint8_t *)vhdpath, -1, NULL); + grub_utf8_to_utf16(unicode_path, pathlen, (grub_uint8_t *)newpath, -1, NULL); grub_memcpy(patch1->vhd_file_path, unicode_path, pathlen); grub_memcpy(patch2->vhd_file_path, unicode_path, pathlen); + grub_free(newpath); return 0; } -static int ventoy_vhd_patch_disk(ventoy_patch_vhd *patch1, ventoy_patch_vhd *patch2) +static int ventoy_vhd_read_parttbl(const char *filename, ventoy_gpt_info *gpt, int *index) { + int ret = 1; + grub_file_t file = NULL; + grub_disk_t disk = NULL; + + file = grub_file_open(filename, VENTOY_FILE_TYPE); + if (!file) + { + goto end; + } + + disk = grub_disk_open(file->device->disk->name); + if (!disk) + { + goto end; + } + + *index = file->device->disk->partition->index; + grub_disk_read(disk, 0, 0, sizeof(ventoy_gpt_info), gpt); + + ret = 0; + +end: + check_free(file, grub_file_close); + check_free(disk, grub_disk_close); + + return ret; +} + +static int ventoy_vhd_patch_disk(const char *vhdpath, ventoy_patch_vhd *patch1, ventoy_patch_vhd *patch2) +{ + int partIndex = 0; + grub_uint64_t offset = 0; char efipart[16] = {0}; + ventoy_gpt_info *gpt = NULL; - grub_memcpy(efipart, g_ventoy_part_info->Head.Signature, sizeof(g_ventoy_part_info->Head.Signature)); + if (vhdpath[0] == '/') + { + gpt = g_ventoy_part_info; + partIndex = 0; + debug("This is Ventoy ISO partIndex %d %s\n", partIndex, vhdpath); + } + else + { + gpt = grub_zalloc(sizeof(ventoy_gpt_info)); + ventoy_vhd_read_parttbl(vhdpath, gpt, &partIndex); + debug("This is HDD partIndex %d %s\n", partIndex, vhdpath); + } - debug("part1 type: 0x%x <%s>\n", g_ventoy_part_info->MBR.PartTbl[0].FsFlag, efipart); + grub_memcpy(efipart, gpt->Head.Signature, sizeof(gpt->Head.Signature)); + + grub_memset(patch1, 0, OFFSET_OF(ventoy_patch_vhd, vhd_file_path)); + grub_memset(patch2, 0, OFFSET_OF(ventoy_patch_vhd, vhd_file_path)); if (grub_strncmp(efipart, "EFI PART", 8) == 0) { - ventoy_debug_dump_guid("GPT disk GUID: ", g_ventoy_part_info->Head.DiskGuid); - ventoy_debug_dump_guid("GPT part GUID: ", g_ventoy_part_info->PartTbl[0].PartGuid); + ventoy_debug_dump_guid("GPT disk GUID: ", gpt->Head.DiskGuid); + ventoy_debug_dump_guid("GPT partIndex GUID: ", gpt->PartTbl[partIndex].PartGuid); - grub_memcpy(patch1->disk_signature_or_guid, g_ventoy_part_info->Head.DiskGuid, 16); - grub_memcpy(patch1->part_offset_or_guid, g_ventoy_part_info->PartTbl[0].PartGuid, 16); - grub_memcpy(patch2->disk_signature_or_guid, g_ventoy_part_info->Head.DiskGuid, 16); - grub_memcpy(patch2->part_offset_or_guid, g_ventoy_part_info->PartTbl[0].PartGuid, 16); + grub_memcpy(patch1->disk_signature_or_guid, gpt->Head.DiskGuid, 16); + grub_memcpy(patch1->part_offset_or_guid, gpt->PartTbl[partIndex].PartGuid, 16); + grub_memcpy(patch2->disk_signature_or_guid, gpt->Head.DiskGuid, 16); + grub_memcpy(patch2->part_offset_or_guid, gpt->PartTbl[partIndex].PartGuid, 16); patch1->part_type = patch2->part_type = 0; } else { - debug("MBR disk signature: %02x%02x%02x%02x\n", - g_ventoy_part_info->MBR.BootCode[0x1b8 + 0], g_ventoy_part_info->MBR.BootCode[0x1b8 + 1], - g_ventoy_part_info->MBR.BootCode[0x1b8 + 2], g_ventoy_part_info->MBR.BootCode[0x1b8 + 3]); - grub_memcpy(patch1->disk_signature_or_guid, g_ventoy_part_info->MBR.BootCode + 0x1b8, 4); - grub_memcpy(patch2->disk_signature_or_guid, g_ventoy_part_info->MBR.BootCode + 0x1b8, 4); + offset = gpt->MBR.PartTbl[partIndex].StartSectorId; + offset *= 512; + + debug("MBR disk signature: %02x%02x%02x%02x Part(%d) offset:%llu\n", + gpt->MBR.BootCode[0x1b8 + 0], gpt->MBR.BootCode[0x1b8 + 1], + gpt->MBR.BootCode[0x1b8 + 2], gpt->MBR.BootCode[0x1b8 + 3], + partIndex + 1, offset); + + grub_memcpy(patch1->part_offset_or_guid, &offset, 8); + grub_memcpy(patch2->part_offset_or_guid, &offset, 8); + + grub_memcpy(patch1->disk_signature_or_guid, gpt->MBR.BootCode + 0x1b8, 4); + grub_memcpy(patch2->disk_signature_or_guid, gpt->MBR.BootCode + 0x1b8, 4); + + patch1->part_type = patch2->part_type = 1; + } + + if (gpt != g_ventoy_part_info) + { + grub_free(gpt); + } + + return 0; +} + +static int ventoy_find_vhdpatch_offset(int bcdoffset, int bcdlen, int *offset) +{ + int i; + int cnt = 0; + grub_uint8_t *buf = (grub_uint8_t *)(g_vhdboot_isobuf + bcdoffset); + grub_uint8_t magic[16] = { + 0x5C, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00 + }; + + for (i = 0; i < bcdlen - 16 && cnt < 2; i++) + { + if (*(grub_uint32_t *)(buf + i) == 0x0058005C) + { + if (grub_memcmp(magic, buf + i, 16) == 0) + { + *offset++ = i - (int)OFFSET_OF(ventoy_patch_vhd, vhd_file_path); + cnt++; + } + } } return 0; @@ -177,6 +269,8 @@ static int ventoy_vhd_patch_disk(ventoy_patch_vhd *patch1, ventoy_patch_vhd *pat grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args) { int rc; + int bcdoffset, bcdlen; + int patchoffset[2]; ventoy_patch_vhd *patch1; ventoy_patch_vhd *patch2; char envbuf[64]; @@ -194,18 +288,39 @@ grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char * return 0; } - rc = ventoy_vhd_find_bcd(&g_vhdboot_bcd_offset, &g_vhdboot_bcd_len); + rc = ventoy_vhd_find_bcd(&bcdoffset, &bcdlen, "/boot/bcd"); if (rc) { debug("failed to get bcd location %d\n", rc); - return 0; + } + else + { + ventoy_find_vhdpatch_offset(bcdoffset, bcdlen, patchoffset); + patch1 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + bcdoffset + patchoffset[0]); + patch2 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + bcdoffset + patchoffset[1]); + + debug("Find /boot/bcd (%d %d) now patch it (offset: 0x%x 0x%x) ...\n", + bcdoffset, bcdlen, patchoffset[0], patchoffset[1]); + ventoy_vhd_patch_disk(args[0], patch1, patch2); + ventoy_vhd_patch_path(args[0], patch1, patch2, bcdoffset, bcdlen); } - patch1 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + g_vhdboot_bcd_offset + 0x495a); - patch2 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + g_vhdboot_bcd_offset + 0x50aa); - - ventoy_vhd_patch_disk(patch1, patch2); - ventoy_vhd_patch_path(args[0], patch1, patch2); + rc = ventoy_vhd_find_bcd(&bcdoffset, &bcdlen, "/boot/BCD"); + if (rc) + { + debug("No file /boot/BCD \n"); + } + else + { + ventoy_find_vhdpatch_offset(bcdoffset, bcdlen, patchoffset); + patch1 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + bcdoffset + patchoffset[0]); + patch2 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + bcdoffset + patchoffset[1]); + + debug("Find /boot/BCD (%d %d) now patch it (offset: 0x%x 0x%x) ...\n", + bcdoffset, bcdlen, patchoffset[0], patchoffset[1]); + ventoy_vhd_patch_disk(args[0], patch1, patch2); + ventoy_vhd_patch_path(args[0], patch1, patch2, bcdoffset, bcdlen); + } /* set buffer and size */ #ifdef GRUB_MACHINE_EFI @@ -220,7 +335,7 @@ grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char * grub_env_set("vtoy_vhd_buf_size", envbuf); #endif - return 0; + VENTOY_CMD_RETURN(GRUB_ERR_NONE); } grub_err_t ventoy_cmd_load_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args) diff --git a/INSTALL/Ventoy2Disk.exe b/INSTALL/Ventoy2Disk.exe index d5a1798d..da7243ae 100644 Binary files a/INSTALL/Ventoy2Disk.exe and b/INSTALL/Ventoy2Disk.exe differ diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg index 8990ad5f..9c4d6dfd 100644 --- a/INSTALL/grub/grub.cfg +++ b/INSTALL/grub/grub.cfg @@ -131,7 +131,7 @@ function get_os_type { function vt_check_compatible_pe { #Check for PE without external tools if [ -f "$1/HBCD_PE.ini" ]; then - set ventoy_compatible=YES + set ventoy_compatible=YES fi } @@ -1230,6 +1230,30 @@ function efi_unsupport_menuentry { common_unsupport_menuentry } +function vhdboot_common_func { + vt_patch_vhdboot "$1" + + ventoy_debug_pause + + if [ -n "$vtoy_vhd_buf_addr" ]; then + if [ "$grub_platform" = "pc" ]; then + ventoy_cli_console + linux16 $vtoy_path/memdisk iso raw + initrd16 mem:${vtoy_vhd_buf_addr}:size:${vtoy_vhd_buf_size} + boot + ventoy_gui_console + else + ventoy_cli_console + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi memdisk env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_vhd_buf_addr}:size:${vtoy_vhd_buf_size} + boot + ventoy_gui_console + fi + else + echo "Please put the right ventoy_vhdboot.img file to the 1st partition" + ventoy_pause + fi +} + function vhd_common_menuentry { if [ "$VTOY_VHD_NO_WARNING" != "1" ]; then @@ -1252,25 +1276,7 @@ function vhd_common_menuentry { return fi - vt_patch_vhdboot "$vt_chosen_path" - - ventoy_debug_pause - - if [ -n "$vtoy_vhd_buf_addr" ]; then - if [ "$grub_platform" = "pc" ]; then - linux16 $vtoy_path/memdisk iso raw - initrd16 mem:${vtoy_vhd_buf_addr}:size:${vtoy_vhd_buf_size} - boot - else - ventoy_cli_console - chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi memdisk env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_vhd_buf_addr}:size:${vtoy_vhd_buf_size} - boot - ventoy_gui_console - fi - else - echo "Please put the right ventoy_vhdboot.img file to the 1st partition" - ventoy_pause - fi + vhdboot_common_func "${vt_chosen_path}" } function vhd_unsupport_menuentry { diff --git a/INSTALL/tool/VentoyWorker.sh b/INSTALL/tool/VentoyWorker.sh index c820ffc4..543ac697 100644 --- a/INSTALL/tool/VentoyWorker.sh +++ b/INSTALL/tool/VentoyWorker.sh @@ -365,11 +365,15 @@ else oldver=$(get_disk_ventoy_version $DISK) if [ $? -ne 0 ]; then - vtwarn "$DISK does not contain Ventoy or data corrupted" - echo "" - vtwarn "Please use -i option if you want to install ventoy to $DISK" - echo "" - exit 1 + if is_disk_contains_ventoy $DISK; then + oldver="Unknown" + else + vtwarn "$DISK does not contain Ventoy or data corrupted" + echo "" + vtwarn "Please use -i option if you want to install ventoy to $DISK" + echo "" + exit 1 + fi fi #reserve secure boot option diff --git a/INSTALL/ventoy_pack.sh b/INSTALL/ventoy_pack.sh index 577a23a0..11b2a289 100644 --- a/INSTALL/ventoy_pack.sh +++ b/INSTALL/ventoy_pack.sh @@ -151,7 +151,7 @@ tar -czvf ventoy-${curver}-linux.tar.gz $tmpdir rm -f ventoy-${curver}-windows.zip cp $OPT Ventoy2Disk*.exe $tmpdir/ -cp $OPT $LANG_DIR/languages.ini $tmpdir/ventoy/ +cp $OPT $LANG_DIR/languages.json $tmpdir/ventoy/ rm -rf $tmpdir/tool rm -f $tmpdir/*.sh rm -rf $tmpdir/WebUI diff --git a/LANGUAGES/README b/LANGUAGES/README new file mode 100644 index 00000000..7a5b4f25 --- /dev/null +++ b/LANGUAGES/README @@ -0,0 +1,17 @@ + +File encoding: UTF-8 + +language name must in the format: "Language-XXX (YYY)" + 1. Language- fixed 9 characters + 2. XXX: name in English + 3. a space (ASCII: 0x20) + 4. a left brace (ASCII: 0x28) + 5. YYY: name in the specified language + 6. a right brace (ASCII: 0x29) + +string translation: + all the String Define + #@ will be replaced with \r\n + +All the languages will be sorted by the name + diff --git a/LANGUAGES/check.sh b/LANGUAGES/check.sh new file mode 100644 index 00000000..a18c1a8d --- /dev/null +++ b/LANGUAGES/check.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +VTOY_PATH=$1 + +if [ ! -f $VTOY_PATH/LANGUAGES/languages.json ]; then + exit 1 +fi + +gcc -DFOR_VTOY_JSON_CHECK $VTOY_PATH/Ventoy2Disk/Ventoy2Disk/VentoyJson.c -I $VTOY_PATH/Ventoy2Disk/Ventoy2Disk/ -o checkjson + +./checkjson $VTOY_PATH/LANGUAGES/languages.json +ret=$? + +rm -f ./checkjson +[ $ret -eq 0 ] + + diff --git a/LANGUAGES/languages.ini b/LANGUAGES/languages.ini deleted file mode 100644 index c40c7521..00000000 Binary files a/LANGUAGES/languages.ini and /dev/null differ diff --git a/LANGUAGES/languages.json b/LANGUAGES/languages.json new file mode 100644 index 00000000..2abe6d82 --- /dev/null +++ b/LANGUAGES/languages.json @@ -0,0 +1,1741 @@ +[ + { + "name":"Arabic (العربية)", + "FontFamily":"Courier New", + "FontSize":20, + "Author":"Omar Namis Mostafa", + + "STR_ERROR":"خطأ", + "STR_WARNING":"تحذير", + "STR_INFO":"معلومات", + "STR_INCORRECT_DIR":"يرجى التشغيل من المسار الصحيح!", + "STR_INCORRECT_TREE_DIR":"لا تقم بالتشغيل من هنا، يرجى تحميل حزمة التثبيت، وتشغيلها من هناك.", + "STR_DEVICE":"الجهاز", + "STR_LOCAL_VER":"في الحزمة Ventoy", + "STR_DISK_VER":"في الجهاز Ventoy", + "STR_STATUS":"الحالة - جاهز", + "STR_INSTALL":"تثبيت", + "STR_UPDATE":"تحديث", + "STR_UPDATE_TIP":"عملية التحديث آمنة, لن يتم عمل تغييرات على ملفات الـISO.#@استمرار؟", + "STR_INSTALL_TIP":"سوف يتم تهيئة القرص وسيتم حذف جميع البيانات.#@المواصلة؟", + "STR_INSTALL_TIP2":"سوف يتم تهيئة القرص وسيتم حذف جميع البيانات.#@المواصلة؟ (التحقق مرة أخرى)", + "STR_INSTALL_SUCCESS":"مبروك!#@تم تثبيت Ventoy بنجاح على الجهاز.", + "STR_INSTALL_FAILED":"حدث خطأ أثناء التثبيت. يمكنك إعادة توصيل الـUSB والمحاولة مرة أخرى. تفقّد log.txt للتفاصيل.", + "STR_UPDATE_SUCCESS":"مبروك!#@تم تحديث Ventoy بنجاح على الجهاز.", + "STR_UPDATE_FAILED":"حدث خطأ أثناء التحديث. يمكنك إعادة توصيل الـUSB والمحاولة مرة أخرى. تفقّد log.txt للتفاصيل.", + "STR_WAIT_PROCESS":"هناك عملية نشطة، يرجى الانتظار...", + "STR_MENU_OPTION":"خيارات", + "STR_MENU_SECURE_BOOT":"تمهيد آمن", + "STR_MENU_PART_CFG":"تكوين التقسيم", + "STR_BTN_OK":"موافق", + "STR_BTN_CANCEL":"إلغاء", + "STR_PRESERVE_SPACE":"الحفاظ على بعض المساحة في الجزء السفلي من القرص", + "STR_SPACE_VAL_INVALID":"قيمة غير صالحة للمساحة المحجوزة", + "STR_MENU_CLEAR":"إزالة Ventoy", + "STR_CLEAR_SUCCESS":"تمت إزالة Ventoy من الجهاز بنجاح.", + "STR_CLEAR_FAILED":"حدث خطأ عند إزالة Ventoy من القرص. يمكنك إعادة توصيل الـUSB والمحاولة مرة أخرى. تفقد log.txt للتفاصيل.", + "STR_MENU_PART_STYLE":"أسلوب التقسيم", + "STR_DISK_2TB_MBR_ERROR":"يرجى اختيار GPT للأقراص الأكبر من 2 تيرابايت", + "STR_SHOW_ALL_DEV":"عرض كافة الأجهزة", + "STR_PART_ALIGN_4KB":"محاذاة الأقسام مع 4KB", + "STR_WEB_COMMUNICATION_ERR":"خطأ في الاتصال:", + "STR_WEB_REMOTE_ABNORMAL":"خطأ في الاتصال: بعيد غير طبيعي", + "STR_WEB_REQUEST_TIMEOUT":"خطأ في الاتصال: انتهت مهلة الطلب", + "STR_WEB_SERVICE_UNAVAILABLE":"خطأ في الاتصال: الخدمة غير متوفرة", + "STR_WEB_TOKEN_MISMATCH":"تم تحديث حالة البرنامج الخفي ، يرجى إعادة المحاولة لاحقًا.", + "STR_WEB_SERVICE_BUSY":"الخدمة مشغولة ، يرجى إعادة المحاولة لاحقًا.", + "STRXXX":"" + }, + { + "name":"Korean (한국어)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Remiz,VenusGirl", + + "STR_ERROR":"오류", + "STR_WARNING":"경고", + "STR_INFO":"정보", + "STR_INCORRECT_DIR":"올바른 디렉토리에서 실행하십시오!", + "STR_INCORRECT_TREE_DIR":"여기서 저를 실행하지 말고, 출시된 설치 패키지를 다운로드한 다음 거기서 실행하십시오.", + "STR_DEVICE":"장치", + "STR_LOCAL_VER":"패키지의 Ventoy 버전", + "STR_DISK_VER":"장치 내부의 Ventoy 버전", + "STR_STATUS":"상태 - 준비 완료", + "STR_INSTALL":"설치", + "STR_UPDATE":"업데이트", + "STR_UPDATE_TIP":"업그레이드 작업은 안전하며 ISO 파일은 변경되지 않습니다.#@계속하시겠습니까?", + "STR_INSTALL_TIP":"디스크가 포맷되고 모든 데이터가 손실됩니다.#@계속하시겠습니까?", + "STR_INSTALL_TIP2":"디스크가 포맷되고 모든 데이터가 손실됩니다.#@계속하시겠습니까? (다시 확인)", + "STR_INSTALL_SUCCESS":"축하합니다!#@Ventoy가 장치에 성공적으로 설치되었습니다.", + "STR_INSTALL_FAILED":"설치 중 오류가 발생했습니다. USB를 다시 연결하고 다시 시도할 수 있습니다. 자세한 내용은 log.txt를 확인하십시오.", + "STR_UPDATE_SUCCESS":"축하합니다!#@Ventoy가 장치에 성공적으로 업데이트되었습니다.", + "STR_UPDATE_FAILED":"업데이트 중에 오류가 발생했습니다. USB를 다시 연결하고 다시 시도할 수 있습니다. 자세한 내용은 log.txt를 확인하십시오.", + "STR_WAIT_PROCESS":"현재 작업이 실행 중입니다. 기다려 주십시오...", + "STR_MENU_OPTION":"옵션", + "STR_MENU_SECURE_BOOT":"보안 부트 (Secure Boot) 지원", + "STR_MENU_PART_CFG":"파티션 구성", + "STR_BTN_OK":"확인", + "STR_BTN_CANCEL":"취소", + "STR_PRESERVE_SPACE":"디스크의 끝에 예약된 공간 확보", + "STR_SPACE_VAL_INVALID":"예약된 공간의 값이 잘못되었습니다", + "STR_MENU_CLEAR":"Ventoy 제거", + "STR_CLEAR_SUCCESS":"Ventoy가 장치에서 성공적으로 제거되었습니다.", + "STR_CLEAR_FAILED":"디스크에서 Ventoy를 지울 때 오류가 발생했습니다. USB를 다시 연결하고 다시 시도할 수 있습니다. 자세한 내용은 log.txt를 확인하십시오.", + "STR_MENU_PART_STYLE":"파티션 유형", + "STR_DISK_2TB_MBR_ERROR":"2TB 이상의 디스크는 GPT를 선택하십시오", + "STR_SHOW_ALL_DEV":"모든 장치 표시", + "STR_PART_ALIGN_4KB":"파티션을 4KB로 정렬", + "STR_WEB_COMMUNICATION_ERR":"통신 오류:", + "STR_WEB_REMOTE_ABNORMAL":"통신 오류: 원격 이상", + "STR_WEB_REQUEST_TIMEOUT":"통신 오류: 요청이 시간 초과됨", + "STR_WEB_SERVICE_UNAVAILABLE":"통신 오류: 서비스를 사용할 수 없음", + "STR_WEB_TOKEN_MISMATCH":"데몬 상태가 업데이트되었습니다. 나중에 다시 시도하십시오.", + "STR_WEB_SERVICE_BUSY":"서비스가 사용 중입니다. 나중에 다시 시도하십시오.", + "STRXXX":"" + }, + { + "name":"Chinese Simplified (简体中文)", + "FontFamily":"宋体", + "FontSize":14, + "Author":"longpanda", + + "STR_ERROR":"错误", + "STR_WARNING":"警告", + "STR_INFO":"提醒", + "STR_INCORRECT_DIR":"请在正确的目录下运行!", + "STR_INCORRECT_TREE_DIR":"请不要在代码树下运行此程序(INSTALL目录),请下载安装包,解压后在那里运行。", + "STR_DEVICE":"设备", + "STR_LOCAL_VER":"安装包内 Ventoy 版本", + "STR_DISK_VER":"设备内部 Ventoy 版本", + "STR_STATUS":"状态 - 准备就绪", + "STR_INSTALL":"安装", + "STR_UPDATE":"升级", + "STR_UPDATE_TIP":"升级操作是安全的, ISO文件不会丢失#@是否继续?", + "STR_INSTALL_TIP":"磁盘会被格式化, 所有数据都会丢失!#@是否继续?", + "STR_INSTALL_TIP2":"磁盘会被格式化, 所有数据都会丢失!#@再次确认是否继续?", + "STR_INSTALL_SUCCESS":"恭喜你! Ventoy 已经成功安装到此设备中.", + "STR_INSTALL_FAILED":"安装 Ventoy 过程中发生错误. 你可以重新拔插一下U盘然后重试一次, 详细信息请查阅 log.txt 文件.", + "STR_UPDATE_SUCCESS":"恭喜你! 新版本的 Ventoy 已经成功更新到此设备中.", + "STR_UPDATE_FAILED":"更新 Ventoy 过程中遇到错误. 你可以重新拔插一下U盘然后重试一次, 详细信息请查阅 log.txt 文件.", + "STR_WAIT_PROCESS":"当前有任务正在运行, 请等待...", + "STR_MENU_OPTION":"配置选项", + "STR_MENU_SECURE_BOOT":"安全启动支持", + "STR_MENU_PART_CFG":"分区设置", + "STR_BTN_OK":"确定", + "STR_BTN_CANCEL":"取消", + "STR_PRESERVE_SPACE":"在磁盘最后保留一段空间", + "STR_SPACE_VAL_INVALID":"保留空间的数值非法", + "STR_MENU_CLEAR":"清除 Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy已经成功从此设备中清除.", + "STR_CLEAR_FAILED":"清除 Ventoy 过程中遇到错误. 你可以重新拔插一下U盘然后重试一次, 详细信息请查阅 log.txt 文件.", + "STR_MENU_PART_STYLE":"分区类型", + "STR_DISK_2TB_MBR_ERROR":"磁盘容量超过2TB,请选择GPT分区格式", + "STR_SHOW_ALL_DEV":"显示所有设备", + "STR_PART_ALIGN_4KB":"分区按照 4KB 对齐", + "STR_WEB_COMMUNICATION_ERR":"通信失败:", + "STR_WEB_REMOTE_ABNORMAL":"通信失败:服务端异常", + "STR_WEB_REQUEST_TIMEOUT":"通信失败:请求超时", + "STR_WEB_SERVICE_UNAVAILABLE":"通信失败:服务不可用", + "STR_WEB_TOKEN_MISMATCH":"后台服务状态更新,请稍后重试", + "STR_WEB_SERVICE_BUSY":"后台服务正忙,请稍后重试", + "STRXXX":"" + }, + { + "name":"English (English)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"longpanda", + + "STR_ERROR":"Error", + "STR_WARNING":"Warning", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Please run under the correct directory!", + "STR_INCORRECT_TREE_DIR":"Don't run me here, please download the released install package, and run there.", + "STR_DEVICE":"Device", + "STR_LOCAL_VER":"Ventoy In Package", + "STR_DISK_VER":"Ventoy In Device", + "STR_STATUS":"Status - READY", + "STR_INSTALL":"Install", + "STR_UPDATE":"Update", + "STR_UPDATE_TIP":"Upgrade operation is safe, ISO files will be unchanged.#@Continue?", + "STR_INSTALL_TIP":"The disk will be formatted and all the data will be lost.#@Continue?", + "STR_INSTALL_TIP2":"The disk will be formatted and all the data will be lost.#@Continue? (Double Check)", + "STR_INSTALL_SUCCESS":"Congratulations!#@Ventoy has been successfully installed to the device.", + "STR_INSTALL_FAILED":"An error occurred during the installation. You can replug the USB and try again. Check log.txt for detail.", + "STR_UPDATE_SUCCESS":"Congratulations!#@Ventoy has been successfully updated to the device.", + "STR_UPDATE_FAILED":"An error occurred during the update. You can replug the USB and try again. Check log.txt for detail.", + "STR_WAIT_PROCESS":"A thread is running, please wait...", + "STR_MENU_OPTION":"Option", + "STR_MENU_SECURE_BOOT":"Secure Boot Support", + "STR_MENU_PART_CFG":"Partition Configuration", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Cancel", + "STR_PRESERVE_SPACE":"Preserve some space at the end of the disk", + "STR_SPACE_VAL_INVALID":"Invalid value for reserved space", + "STR_MENU_CLEAR":"Clear Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy has been successfully removed from the device.", + "STR_CLEAR_FAILED":"An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.", + "STR_MENU_PART_STYLE":"Partition Style", + "STR_DISK_2TB_MBR_ERROR":"Please select GPT for disk over 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Persian (فارسی)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"ivadham", + + "STR_ERROR":"خطا", + "STR_WARNING":"هشدار", + "STR_INFO":"توضیحات", + "STR_INCORRECT_DIR":".لطفاً در پوشه‌دان صحیح اجرا کنید", + "STR_INCORRECT_TREE_DIR":".این‌جا اجرا نکنید، لطفاً بستهٔ نصب را دانلود و آن‌جا اجرا کنید", + "STR_DEVICE":"حافظهٔ قابل حمل", + "STR_LOCAL_VER":"آمادهٔ نصب Ventoy", + "STR_DISK_VER":"نصب‌شده روی حافظه Ventoy", + "STR_STATUS":"وضعیت - آماده", + "STR_INSTALL":"فرمت و نصب", + "STR_UPDATE":"به‌روزرسانی", + "STR_UPDATE_TIP":"عملیات به‌روزرسانی بی‌خطر است و داده‌های روی حافظهٔ قابل حمل سالم باقی خواهند ماند. ادامه؟", + "STR_INSTALL_TIP":"حافظهٔ قابل حمل فرمت و تمامی داده‌های آن پاک خواهد شد. ادامه؟", + "STR_INSTALL_TIP2":"توجه: این عملیات غیرقابل بازگشت است. ادامه؟", + "STR_INSTALL_SUCCESS":".تبریک! عملیات نصب بر روی حافظهٔ قابل حمل با موفقیت پایان یافت", + "STR_INSTALL_FAILED":".خطا در عملیات نصب! یو‌اس‌بی را از نو متصل و دوباره تلاش کنید", + "STR_UPDATE_SUCCESS":".تبریک! نرم‌افزار با موفقیت بر روی حافظهٔ قابل حمل به‌روزرسانی شد", + "STR_UPDATE_FAILED":".خطا در به‌روزرسانی! یو‌اس‌بی را از نو متصل و دوباره تلاش کنید", + "STR_WAIT_PROCESS":"...پروسه‌ای در حال اجرا است، لطفاً صبر کنید", + "STR_MENU_OPTION":"تنظیمات", + "STR_MENU_SECURE_BOOT":"(Secure Boot) بوت امن", + "STR_MENU_PART_CFG":"پیکربندی پارتیشن", + "STR_BTN_OK":"تأیید", + "STR_BTN_CANCEL":"انصراف", + "STR_PRESERVE_SPACE":"اختصاص مقداری فضا به انتهای حافظهٔ قابل حمل", + "STR_SPACE_VAL_INVALID":".این مقدار فضا برای اختصاص‌یافتن نامعتبر است", + "STR_MENU_CLEAR":"Ventoy را پاک کنید", + "STR_CLEAR_SUCCESS":"Ventoy با موفقیت از دستگاه برداشته شد.", + "STR_CLEAR_FAILED":"هنگام پاک کردن Ventoy از روی دیسک خطایی روی داد. می توانید USB را دوباره از برق جدا کنید و دوباره امتحان کنید. log.txt را برای جزئیات بررسی کنید.", + "STR_MENU_PART_STYLE":"سبک پارتیشن بندی", + "STR_DISK_2TB_MBR_ERROR":"لطفاً GPT را برای دیسک بیش از 2 ترابایت انتخاب کنید", + "STR_SHOW_ALL_DEV":"نمایش همه دستگاه ها", + "STR_PART_ALIGN_4KB":"پارتیشن ها را با 4KB تراز کنید", + "STR_WEB_COMMUNICATION_ERR":"خطای ارتباطی:", + "STR_WEB_REMOTE_ABNORMAL":"خطای ارتباطی: از راه دور غیر طبیعی است", + "STR_WEB_REQUEST_TIMEOUT":"خطای ارتباطی: زمان درخواست به پایان رسیده است", + "STR_WEB_SERVICE_UNAVAILABLE":"خطای ارتباطی: سرویس موجود نیست", + "STR_WEB_TOKEN_MISMATCH":"وضعیت Daemon به روز شد ، لطفاً بعداً دوباره امتحان کنید.", + "STR_WEB_SERVICE_BUSY":"سرویس شلوغ است ، لطفاً بعداً دوباره امتحان کنید.", + "STRXXX":"" + }, + { + "name":"Polish (Polski)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"B.O.S.S", + + "STR_ERROR":"Błąd", + "STR_WARNING":"Ostrzeżenie", + "STR_INFO":"Informacja", + "STR_INCORRECT_DIR":"Proszę uruchom w odpowiednim katalogu!", + "STR_INCORRECT_TREE_DIR":"Nie uruchamiaj mnie tutaj, pobierz pakiet instalacyjny i uruchom go.", + "STR_DEVICE":"Urządzenie", + "STR_LOCAL_VER":"Ventoy w programie", + "STR_DISK_VER":"Ventoy na urządzeniu", + "STR_STATUS":"Status - GOTOWY", + "STR_INSTALL":"Zainstaluj", + "STR_UPDATE":"Zaktualizuj", + "STR_UPDATE_TIP":"Operacja aktualizacji jest bezpieczna, pliki ISO pozostaną niezmienione.#@Kontynuować?", + "STR_INSTALL_TIP":"Dysk zostanie sformatowany, a wszystkie dane zostaną utracone.#@Kontynuować?", + "STR_INSTALL_TIP2":"Dysk zostanie sformatowany, a wszystkie dane zostaną utracone.#@Kontynuować? (Podwójne sprawdzenie)", + "STR_INSTALL_SUCCESS":"Gratulacje!#@Ventoy został pomyślnie zainstalowany na urządzeniu.", + "STR_INSTALL_FAILED":"Wystąpił błąd podczas instalacji. Możesz ponownie podłączyć USB i spróbować jeszcze raz. Szczegóły w log.txt.", + "STR_UPDATE_SUCCESS":"Gratulacje!#@Ventoy zostało pomyślnie zaktualizowane na urządzeniu.", + "STR_UPDATE_FAILED":"Wystąpił błąd podczas aktualizacji. Możesz ponownie podłączyć USB i spróbować jeszcze raz. Szczegóły w log.txt.", + "STR_WAIT_PROCESS":"Wątek jest uruchomiony, proszę czekać...", + "STR_MENU_OPTION":"Opcje", + "STR_MENU_SECURE_BOOT":"Bezpieczny rozruch/Secure Boot", + "STR_MENU_PART_CFG":"Konfiguracja partycji", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Anuluj", + "STR_PRESERVE_SPACE":"Zachowaj trochę miejsca na dole dysku", + "STR_SPACE_VAL_INVALID":"Nieprawidłowa wartość zarezerwowanego miejsca", + "STR_MENU_CLEAR":"Wyczyść Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy został pomyślnie usunięty z urządzenia.", + "STR_CLEAR_FAILED":"Wystąpił błąd podczas usuwania Ventoy z dysku. Możesz podłączyć USB i spróbować jeszcze raz. Szczegóły w log.txt.", + "STR_MENU_PART_STYLE":"Schemat partycji", + "STR_DISK_2TB_MBR_ERROR":"Wybierz GPT dla dysku powyżej 2TB", + "STR_SHOW_ALL_DEV":"Pokaż wszystkie urządzenia", + "STR_PART_ALIGN_4KB":"Wyrównaj partycje z 4KB", + "STR_WEB_COMMUNICATION_ERR":"Błąd komunikacji:", + "STR_WEB_REMOTE_ABNORMAL":"Błąd komunikacji: nieprawidłowy serwer", + "STR_WEB_REQUEST_TIMEOUT":"Błąd komunikacji: przekroczono limit czasu żądania", + "STR_WEB_SERVICE_UNAVAILABLE":"Błąd komunikacji: usługa niedostępna", + "STR_WEB_TOKEN_MISMATCH":"Stan daemona został zaktualizowany, spróbuj ponownie później.", + "STR_WEB_SERVICE_BUSY":"Usługa jest zajęta, spróbuj ponownie później.", + "STRXXX":"" + }, + { + "name":"Portuguese Brazilian (Português do Brasil)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"EstevaoCostaG3, David BrazSan", + + "STR_ERROR":"Erro", + "STR_WARNING":"Atenção", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Por favor, execute no diretório correto!", + "STR_INCORRECT_TREE_DIR":"Não me execute aqui, por favor baixe o pacote de instalação lançado, e me execute lá.", + "STR_DEVICE":"Dispositivo", + "STR_LOCAL_VER":"Ventoy em pacote", + "STR_DISK_VER":"Ventoy em dispositivo", + "STR_STATUS":"Status - PRONTO", + "STR_INSTALL":"Instalar", + "STR_UPDATE":"Atualizar", + "STR_UPDATE_TIP":"A operação de atualização é segura, os arquivos ISO não serão alterados.#@Continuar?", + "STR_INSTALL_TIP":"O disco será formatado e todos os dados serão perdidos.#@Continuar?", + "STR_INSTALL_TIP2":"O disco será formatado e todos os dados serão perdidos.#@Continuar? (Verificação dupla)", + "STR_INSTALL_SUCCESS":"Parabéns!#@Ventoy foi instalado com sucesso no dispositivo.", + "STR_INSTALL_FAILED":"Um erro ocorreu durante a instalação. Você pode reconectar o dispositivo USB e tentar novamente. Verifique o arquivo log.txt para mais detalhes.", + "STR_UPDATE_SUCCESS":"Parabéns!#@Ventoy foi atualizado com sucesso no dispositivo.", + "STR_UPDATE_FAILED":"Um erro ocorreu durante a atualização. Você pode reconectar o dispositivo USB e tentar novamente. Verifique o arquivo log.txt para mais detalhes.", + "STR_WAIT_PROCESS":"Uma thread está em execução, por favor espere...", + "STR_MENU_OPTION":"Opção", + "STR_MENU_SECURE_BOOT":"Boot seguro", + "STR_MENU_PART_CFG":"Configuração de Partição", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Cancelar", + "STR_PRESERVE_SPACE":"Preservar algum espaço no final do disco", + "STR_SPACE_VAL_INVALID":"Valor invalido para o espaço reservado", + "STR_MENU_CLEAR":"Remover o Ventoy", + "STR_CLEAR_SUCCESS":"O Ventoy foi removido deste dispositivo com sucesso.", + "STR_CLEAR_FAILED":"Um erro ocorreu ao remover o Ventoy do disco. Você pode reconectar o dispositivo USB e tentar novamente. Verifique o Arquivo log.txt para mais detalhes.", + "STR_MENU_PART_STYLE":"Estilo de Partição", + "STR_DISK_2TB_MBR_ERROR":"Por favor selecione GPT para discos maiores que 2TB", + "STR_SHOW_ALL_DEV":"Mostrar Todos os Dispositivos", + "STR_PART_ALIGN_4KB":"Alinhar partições com 4KB", + "STR_WEB_COMMUNICATION_ERR":"Erro de comunicação:", + "STR_WEB_REMOTE_ABNORMAL":"Erro de comunicação: remoto anormal", + "STR_WEB_REQUEST_TIMEOUT":"Erro de comunicação: Solicitação cronometrado", + "STR_WEB_SERVICE_UNAVAILABLE":"Erro de comunicação: Serviço indisponível", + "STR_WEB_TOKEN_MISMATCH":"Status daemon atualizado, por favor, tente novamente mais tarde.", + "STR_WEB_SERVICE_BUSY":"O serviço está ocupado, por favor, tente novamente mais tarde.", + "STRXXX":"" + }, + { + "name":"Turkish (Türkçe)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Erhan Kültür/crasadure", + + "STR_ERROR":"Hata", + "STR_WARNING":"Uyarı", + "STR_INFO":"Bilgi", + "STR_INCORRECT_DIR":"Lütfen doğru dizin altında çalıştırın!", + "STR_INCORRECT_TREE_DIR":"Dosyayı burada çalıştırma, lütfen yayınlanan en son kurulum paketini indirin ve oradan çalıştırın.", + "STR_DEVICE":"Aygıt", + "STR_LOCAL_VER":"Ventoy GÜNCEL Sürüm", + "STR_DISK_VER":"Cihazdaki Ventoy Sürümü", + "STR_STATUS":"Durum - HAZIR", + "STR_INSTALL":"Kur", + "STR_UPDATE":"Güncelle", + "STR_UPDATE_TIP":"Ventoyun versiyon bilgisi güncellenecek, ISO dosyalarınız bundan etkilenmiyecek.#@Devam edilsinmi?", + "STR_INSTALL_TIP":"Disk biçimlendirilecek ve tüm veriler kaybolacak.#@Devam edilsinmi?", + "STR_INSTALL_TIP2":"Disk biçimlendirilecek ve tüm veriler kaybolacak.#@Devam edilsinmi? (Son UYARI!)", + "STR_INSTALL_SUCCESS":"Tebrikler!#@ventoy cihaza başarıyla kuruldu.", + "STR_INSTALL_FAILED":"Yükleme sırasında bir hata oluştu. USB'yi yeniden takıp tekrar deneyebilirsiniz. Ayrıntılar için log.txt dosyasına bakın.", + "STR_UPDATE_SUCCESS":"Tebrikler!#@ventoy cihazda başarıyla güncellendi.", + "STR_UPDATE_FAILED":"Güncelleme sırasında bir hata oluştu. USB'yi yeniden takıp tekrar deneyebilirsiniz. Ayrıntılar için log.txt dosyasına bakın.", + "STR_WAIT_PROCESS":"Mevcut işlem çalışıyor, lütfen bekleyiniz ...", + "STR_MENU_OPTION":"Seçenek", + "STR_MENU_SECURE_BOOT":"Güvenli Önyükleme", + "STR_MENU_PART_CFG":"Partisyon Yapılandırması", + "STR_BTN_OK":"Tamam", + "STR_BTN_CANCEL":"İptal et", + "STR_PRESERVE_SPACE":"Diskin sonunda ayrılmış disk partisyonu oluştur", + "STR_SPACE_VAL_INVALID":"Ayrılmış alan için geçersiz değer girdiniz", + "STR_MENU_CLEAR":"Ventoyu USB Diskten Sil", + "STR_CLEAR_SUCCESS":"Ventoy başarılı bir şekilde diskten silindi", + "STR_CLEAR_FAILED":"Ventoy USB diskten temizlenirken bir hata oluştu.Lütfen USB Diski tekrar takın ve tekrar deneyin.Hatanın detayları için Log.txt dosyasını okuyun", + "STR_MENU_PART_STYLE":"Partisyon Yapısı", + "STR_DISK_2TB_MBR_ERROR":"2TB üstündeki diskler için lütfen GPT disk yapısını seçiniz.", + "STR_SHOW_ALL_DEV":"Tüm Cihazları Göster", + "STR_PART_ALIGN_4KB":"Tüm Partisyonları 4KB düzeninde hizala", + "STR_WEB_COMMUNICATION_ERR":"Iletişim Hatası:", + "STR_WEB_REMOTE_ABNORMAL":"Iletişim Hatası:Uzaktan erişim hizmeti anormal durumda", + "STR_WEB_REQUEST_TIMEOUT":"Iletişim hatası: Uzaktan erişim isteği zaman aşımına uğradı", + "STR_WEB_SERVICE_UNAVAILABLE":"Iletişim hatası: Uzaktan web erişim hizmeti erişilemez durumda", + "STR_WEB_TOKEN_MISMATCH":"Daemon durumu güncellendi,lütfen daha sonra tekrar deneyiniz.", + "STR_WEB_SERVICE_BUSY":"Hizmet meşgul, lütfen daha sonra tekrar deneyin.", + "STRXXX":"" + }, + { + "name":"German (Deutsch)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"luzea & u!^DEV", + + "STR_ERROR":"Fehler", + "STR_WARNING":"Warnung", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Bitte im richtigen Verzeichnis ausführen!", + "STR_INCORRECT_TREE_DIR":"Bitte nicht hier ausführen. Laden Sie das Installationspaket herunter und von dort aus ausführen.", + "STR_DEVICE":"Gerät", + "STR_LOCAL_VER":"Ventoy (lokal)", + "STR_DISK_VER":"Ventoy (Gerät)", + "STR_STATUS":"Status - BEREIT", + "STR_INSTALL":"Installieren", + "STR_UPDATE":"Aktualisieren", + "STR_UPDATE_TIP":"Die Durchführung der Aktualisierung ist sicher, ISO-Dateien bleiben unverändert.#@Fortfahren?", + "STR_INSTALL_TIP":"Das Gerät wird formatiert und alle Daten gehen verloren.#@Fortfahren?", + "STR_INSTALL_TIP2":"Das Gerät wird formatiert und alle Daten gehen verloren.#@Fortfahren? (erneute Überprüfung)", + "STR_INSTALL_SUCCESS":"Herzlichen Glückwunsch!#@Ventoy wurde erfolgreich auf dem Gerät installiert.", + "STR_INSTALL_FAILED":"Während der Installation ist ein Fehler aufgetreten. Stecken Sie das Gerät neu ein und versuchen Sie es erneut. Überprüfen Sie die log.txt auf Details.", + "STR_UPDATE_SUCCESS":"Herzlichen Glückwunsch!#@Ventoy wurde erfolgreich auf dem Gerät aktualisiert.", + "STR_UPDATE_FAILED":"Während der Aktualisierung ist ein Fehler aufgetreten. Stecken Sie das Gerät neu ein und versuchen Sie es erneut. Überprüfen Sie die log.txt auf Details.", + "STR_WAIT_PROCESS":"Ein anderer Thread läuft, bitte warten...", + "STR_MENU_OPTION":"Optionen", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"Partitionskonfiguration", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Abbrechen", + "STR_PRESERVE_SPACE":"Etwas Speicher am Ende des Datenträgers reservieren.", + "STR_SPACE_VAL_INVALID":"Ungültiger Wert für reservierten Speicherplatz!", + "STR_MENU_CLEAR":"Ventoy entfernen", + "STR_CLEAR_SUCCESS":"Ventoy wurde erfolgreich vom Gerät entfernt.", + "STR_CLEAR_FAILED":"Beim Versuch, Ventoy zu entfernen, ist ein Fehler aufgetreten. Stecken Sie das Gerät neu ein und versuchen Sie es erneut. Überprüfen Sie die log.txt auf Details.", + "STR_MENU_PART_STYLE":"Partitionsstil", + "STR_DISK_2TB_MBR_ERROR":"Wählen Sie GPT für Geräte > 2TB aus.", + "STR_SHOW_ALL_DEV":"Alle Geräte anzeigen", + "STR_PART_ALIGN_4KB":"Richten Sie Partitionen mit 4KB aus", + "STR_WEB_COMMUNICATION_ERR":"Kommunikationsfehler:", + "STR_WEB_REMOTE_ABNORMAL":"Kommunikationsfehler: unnormales Verhalten", + "STR_WEB_REQUEST_TIMEOUT":"Kommunikationsfehler: Zeitüberschreitung der Anforderung", + "STR_WEB_SERVICE_UNAVAILABLE":"Kommunikationsfehler: Dienst nicht verfügbar", + "STR_WEB_TOKEN_MISMATCH":"Daemon-Status aktualisiert, bitte später erneut versuchen.", + "STR_WEB_SERVICE_BUSY":"Dienst ist ausgelastet, bitte später erneut versuchen.", + "STRXXX":"" + }, + { + "name":"Occitan (Occitan)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"quentin", + + "STR_ERROR":"Error", + "STR_WARNING":"Avertiment", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Aqueste programa deu s’executar dins lo bon repertòri!", + "STR_INCORRECT_TREE_DIR":"Lancetz pas aquò, mercés de telecargar lo programa d’installacion e relançatz-lo.", + "STR_DEVICE":"Periferic", + "STR_LOCAL_VER":"Ventoy en local", + "STR_DISK_VER":"Ventoy sul periferic", + "STR_STATUS":"Estat - prèst", + "STR_INSTALL":"Installacion", + "STR_UPDATE":"Mesa a jorn", + "STR_UPDATE_TIP":"La mesa a jorn es segura, los fichièrs ISO seràn pas modificats.#@Continhar ?", + "STR_INSTALL_TIP":"Lo disc serà formatat e totas sas donadas seràn perdudas.#@Contunhar ?", + "STR_INSTALL_TIP2":"Lo disc serà formatat e totas sas donadas seràn perdudas.#@Contunhar ? (confirmacion)", + "STR_INSTALL_SUCCESS":"Felicitacions !#@Ventoy es estat corrèctament installat sul periferic.", + "STR_INSTALL_FAILED":"Una error s’es producha pendent l’installacion. Podètz tornar brancar lo periferic USB e tornar ensajar. Agachatz lo fichièr log.txt per ne saber mai.", + "STR_UPDATE_SUCCESS":"Felicitacions !#@Ventoy es estat corrèctament mes a jorn sul periferic.", + "STR_UPDATE_FAILED":"Una error s’es producha pendent la mesa a jorn. Podètz tornar brancar lo periferic USB e tornar ensajar. Agachatz lo fichièr log.txt per ne saber mai.", + "STR_WAIT_PROCESS":"Una operacion es en cors, esperatz...", + "STR_MENU_OPTION":"Opcion", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"Configuracion de particion", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Anullar", + "STR_PRESERVE_SPACE":"Preserve some space at the end of the disk", + "STR_SPACE_VAL_INVALID":"Valor invalida per l’espaci reservat", + "STR_MENU_CLEAR":"Escafar Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy es estat corrèctament tirat del periferic.", + "STR_CLEAR_FAILED":"Una error s’es producha pendent l’esfaçament de Ventoy del disc. Podètz tornar brancar l’USB e tornar ensajar. Vejatz log.txt pels detalhs.", + "STR_MENU_PART_STYLE":"Estil de particion", + "STR_DISK_2TB_MBR_ERROR":"Pels disques de mai de 2To seleccionatz GPT", + "STR_SHOW_ALL_DEV":"Mostrar totes los periferics", + "STR_PART_ALIGN_4KB":"Alinhar las particions sus 4Ko", + "STR_WEB_COMMUNICATION_ERR":"Error de comunicacion :", + "STR_WEB_REMOTE_ABNORMAL":"Error de comunicacion : remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Error de comunicacion: requèsta tardièra", + "STR_WEB_SERVICE_UNAVAILABLE":"Error de comunicacion : servici pas disponible", + "STR_WEB_TOKEN_MISMATCH":"Estat del Daemon actualizat, tornatz ensajar mai tard.", + "STR_WEB_SERVICE_BUSY":"Lo servici es ocupat, tornatz ensajar mai tard.", + "STRXXX":"" + }, + { + "name":"French (Français)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"vboucard", + + "STR_ERROR":"Erreur", + "STR_WARNING":"Avertissement", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Ce programme doit s'exécuter dans le bon répertoire !", + "STR_INCORRECT_TREE_DIR":"Ne me lancez pas d'ici, veuillez télécharger le programme d'installation et relancez-le.", + "STR_DEVICE":"Périphérique", + "STR_LOCAL_VER":"Ventoy en local", + "STR_DISK_VER":"Ventoy sur le périphérique", + "STR_STATUS":"Etat - prêt", + "STR_INSTALL":"Installation", + "STR_UPDATE":"Mise à jour", + "STR_UPDATE_TIP":"La mise à jour est sûre, les fichiers ISO ne seront pas modifiés.#@Continuer?", + "STR_INSTALL_TIP":"Le disque va être formaté et toutes ses données seront perdues.#@Continuer?", + "STR_INSTALL_TIP2":"Le disque va être formaté et toutes ses données seront perdues.#@Continuer? (confirmation)", + "STR_INSTALL_SUCCESS":"Félicitations !#@Ventoy a été correctement installé sur le périphérique.", + "STR_INSTALL_FAILED":"Une erreur est survenue durant l'installation. Vous pouvez rebrancher le périphérique USB et réessayer. Vérifiez le fichier log.txt pour plus de détails.", + "STR_UPDATE_SUCCESS":"Félicitations !#@Ventoy a été correctement mis à jour sur le périphérique.", + "STR_UPDATE_FAILED":"Une erreur est survenue durant la mise à jour. Vous pouvez rebrancher le périphérique USB et réessayer. Vérifiez le fichier log.txt pour plus de détails.", + "STR_WAIT_PROCESS":"Une opération est en cours, veuillez patienter...", + "STR_MENU_OPTION":"Option", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"Configuration de partition", + "STR_BTN_OK":"D'accord", + "STR_BTN_CANCEL":"Annuler", + "STR_PRESERVE_SPACE":"Préservez de l'espace au bas du disque", + "STR_SPACE_VAL_INVALID":"Valeur non valide pour l'espace réservé", + "STR_MENU_CLEAR":"Effacer Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy a été enlevé du périphérique avec succès.", + "STR_CLEAR_FAILED":"Une erreur est survenue pendant la suppression de Ventoy. Vous pouvez rebrancher le périphérique USB. Vérifiez le fichier log.txt pour plus de détails.", + "STR_MENU_PART_STYLE":"Type de partition", + "STR_DISK_2TB_MBR_ERROR":"Sélectionnez le type GPT pour les disques de plus de 2TO", + "STR_SHOW_ALL_DEV":"Afficher tous les appareils", + "STR_PART_ALIGN_4KB":"Alignez les partitions avec 4 KO", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Czech (Čeština)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"vavanade", + + "STR_ERROR":"Chyba", + "STR_WARNING":"Varování", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Spusťte prosím ve správném adresáři!", + "STR_INCORRECT_TREE_DIR":"Nespouštějte mě zde, stáhněte si prosím vydaný instalační balík a spusťte v něm.", + "STR_DEVICE":"Zařízení", + "STR_LOCAL_VER":"Ventoy v balíčku", + "STR_DISK_VER":"Ventoy v zařízení", + "STR_STATUS":"Status - PŘIPRAVENO", + "STR_INSTALL":"Instalovat", + "STR_UPDATE":"Aktualizovat", + "STR_UPDATE_TIP":"Operace aktualizace je bezpečná, ISO soubory nebudou změněny.#@Pokračovat?", + "STR_INSTALL_TIP":"Disk bude zformátován a všechna data budou ztracena!#@Pokračovat?", + "STR_INSTALL_TIP2":"Disk bude zformátován a všechna data budou ztracena!#@Pokračovat? (druhá kontrola)", + "STR_INSTALL_SUCCESS":"Gratulujeme!#@Ventoy byla na zařízení úspěšně nainstalována.", + "STR_INSTALL_FAILED":"V průběhu instalace se vyskytla chyba. Můžete vyjmout a znovu zastrčit USB zařízení a zkusit to znovu. Pro podrobnosti se podívejte do souboru log.txt.", + "STR_UPDATE_SUCCESS":"Gratulujeme!#@Ventoy byla na zařízení úspěšně aktualizována.", + "STR_UPDATE_FAILED":"V průběhu aktualizace se vyskytla chyba. Můžete vyjmout a znovu zastrčit USB zařízení a zkusit to znovu. Pro podrobnosti se podívejte do souboru log.txt.", + "STR_WAIT_PROCESS":"Vlákno běží, prosíme vyčkejte...", + "STR_MENU_OPTION":"Možnosti", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"Konfigurace oddílu", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"zrušení", + "STR_PRESERVE_SPACE":"Zachovejte místo na spodní straně disku", + "STR_SPACE_VAL_INVALID":"Neplatná hodnota pro vyhrazený prostor", + "STR_MENU_CLEAR":"Vymazat Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy has been successfully removed from the device.", + "STR_CLEAR_FAILED":"An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.", + "STR_MENU_PART_STYLE":"Styl oddílu", + "STR_DISK_2TB_MBR_ERROR":"Vyberte GPT pro disk přes 2TB", + "STR_SHOW_ALL_DEV":"Zobrazit všechna zařízení", + "STR_PART_ALIGN_4KB":"Zarovnejte oddíly s 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Spanish (Español)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Carlos Sánchez, MELERIX", + + "STR_ERROR":"Error", + "STR_WARNING":"Advertencia", + "STR_INFO":"Información", + "STR_INCORRECT_DIR":"¡Por favor, ejecuta bajo el directorio correcto!", + "STR_INCORRECT_TREE_DIR":"No me ejecute aquí, por favor descarga el paquete de instalacion lanzado, y ejecutalo allí.", + "STR_DEVICE":"Dispositivo", + "STR_LOCAL_VER":"Ventoy En Paquete", + "STR_DISK_VER":"Ventoy En Dispositivo", + "STR_STATUS":"Estado - LISTO", + "STR_INSTALL":"Instalar", + "STR_UPDATE":"Actualizar", + "STR_UPDATE_TIP":"La operación de actualización es segura, Los archivo ISO no se modificarán.#@¿Continuar?", + "STR_INSTALL_TIP":"El dispositivo será formateado y todos los datos se perderán.#@¿Continuar?", + "STR_INSTALL_TIP2":"El dispositivo será formateado y todos los datos se perderán.#@¿Continuar? (Doble Comprobación)", + "STR_INSTALL_SUCCESS":"¡Felicitaciones!#@Ventoy ha sido instalado exitosamente en el dispositivo.", + "STR_INSTALL_FAILED":"Ocurrío un error durante la instalación. Puedes reconectar el USB e intentar de nuevo. Comprueba log.txt para detalles.", + "STR_UPDATE_SUCCESS":"¡Felicitaciones!#@Ventoy ha sido actualizado exitosamente en el dispositivo.", + "STR_UPDATE_FAILED":"Ocurrío un error durante la actualización. Puedes reconectar el USB e intentar de nuevo. Comprueba log.txt para detalles.", + "STR_WAIT_PROCESS":"Un hilo está ejecutandose, por favor espera...", + "STR_MENU_OPTION":"Opción", + "STR_MENU_SECURE_BOOT":"Soporte de Arranque Seguro", + "STR_MENU_PART_CFG":"Confirguración de Partición", + "STR_BTN_OK":"ACEPTAR", + "STR_BTN_CANCEL":"Cancelar", + "STR_PRESERVE_SPACE":"Preservar algo de espacio en la parte inferior del dispositivo", + "STR_SPACE_VAL_INVALID":"Valor inválido para espacio preservado", + "STR_MENU_CLEAR":"Limpiar Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy ha sido removido exotosamente desde el dispositivo.", + "STR_CLEAR_FAILED":"Ocurrío un error al limpiar Ventoy desde el dispositivo. Puedes reconectar el USB e intentar de nuevo. Comprueba log.txt para detalle.", + "STR_MENU_PART_STYLE":"Estilo de Partición", + "STR_DISK_2TB_MBR_ERROR":"Por favor selecciona GPT para dispositivos sobre 2TB", + "STR_SHOW_ALL_DEV":"Mostrar todos los dispositivos", + "STR_PART_ALIGN_4KB":"Alinear particiones con 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Russian (Pусский)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"BL4CKH47H4CK3R", + + "STR_ERROR":"Ошибка", + "STR_WARNING":"Предупреждение", + "STR_INFO":"Информация", + "STR_INCORRECT_DIR":"Пожалуйста, запустите в другом каталоге!", + "STR_INCORRECT_TREE_DIR":"Не запускайте меня здесь, пожалуйста, загрузите выпущенный установочный пакет и запустите его в другом месте.", + "STR_DEVICE":"Устройство", + "STR_LOCAL_VER":"Ventoy в пакете", + "STR_DISK_VER":"Ventoy на устройстве", + "STR_STATUS":"Статус - ГОТОВ", + "STR_INSTALL":"Установить", + "STR_UPDATE":"Обновить", + "STR_UPDATE_TIP":"Обновление безопасно, ISO-файлы останутся без изменений.#@Продолжить?", + "STR_INSTALL_TIP":"Диск будет отформатирован и все данные будут потеряны.#@Продолжить?", + "STR_INSTALL_TIP2":"Диск будет отформатирован и все данные будут потеряны.#@Вы ДЕЙСТВИТЕЛЬНО хотите продолжить?", + "STR_INSTALL_SUCCESS":"Поздравляем!#@Ventoy был успешно установлен на устройство.", + "STR_INSTALL_FAILED":"Во время установки Ventoy произошла ошибка. Переподключите устройство и попробуйте снова. Проверьте log.txt на ошибки.", + "STR_UPDATE_SUCCESS":"Поздравляем!#@Ventoy был успешно обновлен на устройстве.", + "STR_UPDATE_FAILED":"Во время обновления Ventoy произошла ошибка. Переподключите устройство и попробуйте снова. Проверьте log.txt на ошибки.", + "STR_WAIT_PROCESS":"Процесс запущен, пожалуйста подождите...", + "STR_MENU_OPTION":"Опции", + "STR_MENU_SECURE_BOOT":"Поддержка Secure Boot", + "STR_MENU_PART_CFG":"Дополнительный раздел", + "STR_BTN_OK":"ОК", + "STR_BTN_CANCEL":"Отмена", + "STR_PRESERVE_SPACE":"Создать дополнительный раздел в конце диска", + "STR_SPACE_VAL_INVALID":"Неверное значение размера раздела", + "STR_MENU_CLEAR":"Удалить Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy был успешно удалён с устройства.", + "STR_CLEAR_FAILED":"Во время удаления Ventoy произошла ошибка. Переподключите устройство и попробуйте снова. Проверьте log.txt на ошибки.", + "STR_MENU_PART_STYLE":"Стиль разметки разделов", + "STR_DISK_2TB_MBR_ERROR":"Пожалуйста, выберите GPT для дисков более 2ТБ", + "STR_SHOW_ALL_DEV":"Показать все устройства", + "STR_PART_ALIGN_4KB":"Выровнять разделы с размером 4КБ", + "STR_WEB_COMMUNICATION_ERR":"Ошибка связи:", + "STR_WEB_REMOTE_ABNORMAL":"Ошибка связи: Удаленное соединение недействительно", + "STR_WEB_REQUEST_TIMEOUT":"Ошибка связи: Истекло время ожидания запроса", + "STR_WEB_SERVICE_UNAVAILABLE":"Ошибка связи: Служба недоступна", + "STR_WEB_TOKEN_MISMATCH":"Статус демона обновлен. Повторите попытку позже.", + "STR_WEB_SERVICE_BUSY":"Служба занята, повторите попытку позже.", + "STRXXX":"" + }, + { + "name":"Bengali (বাংলা)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"BL4CKH47H4CK3R", + + "STR_ERROR":"ত্রুটি", + "STR_WARNING":"সতর্কতা", + "STR_INFO":"তথ্য", + "STR_INCORRECT_DIR":"দয়া করে সঠিক ডিরেক্টরিতে চালান!", + "STR_INCORRECT_TREE_DIR":"আমাকে এখানে চালাবেন না, দয়া করে প্রকাশিত ইনস্টল প্যাকেজটি ডাউনলোড করুন এবং সেখানে চালান।", + "STR_DEVICE":"ডিভাইস", + "STR_LOCAL_VER":"Ventoy প্যাকেজে আছে", + "STR_DISK_VER":"Ventoy ডিভাইসে আছে", + "STR_STATUS":"স্থিতি - প্রস্তুত", + "STR_INSTALL":"ইনস্টল করুন", + "STR_UPDATE":"আপডেট করুন", + "STR_UPDATE_TIP":"আপগ্রেড অপারেশন নিরাপদ, ISO ফাইলগুলি অপরিবর্তিত থাকবে।#@চালিয়ে যাবেন?", + "STR_INSTALL_TIP":"ডিস্কটি ফর্ম্যাট করা হবে এবং সমস্ত ডেটা হারিয়ে যাবে।#@চালিয়ে যাবেন?", + "STR_INSTALL_TIP2":"ডিস্কটি ফর্ম্যাট করা হবে এবং সমস্ত ডেটা হারিয়ে যাবে।#@চালিয়ে যাবেন? (পুনঃনিরীক্ষণ)", + "STR_INSTALL_SUCCESS":"অভিনন্দন! #@Ventoy সফলভাবে ডিভাইসে ইনস্টল করা হয়েছে।", + "STR_INSTALL_FAILED":"ইনস্টলেশন চলাকালীন একটি ত্রুটি ঘটেছে। আপনি USB পুনরায় প্লাগ করতে পারেন এবং আবার চেষ্টা করতে পারেন। বিস্তারিত জানার জন্য log.txt পরীক্ষা করুন।", + "STR_UPDATE_SUCCESS":"অভিনন্দন! #@Ventoy সফলভাবে ডিভাইসে আপডেট করা হয়েছে।", + "STR_UPDATE_FAILED":"আপডেটের সময় একটি ত্রুটি ঘটেছে। আপনি USB পুনরায় প্লাগ করতে পারেন এবং আবার চেষ্টা করতে পারেন। বিস্তারিত জানার জন্য log.txt পরীক্ষা করুন।", + "STR_WAIT_PROCESS":"একটি থ্রেড চলছে, দয়া করে অপেক্ষা করুন ...", + "STR_MENU_OPTION":"অপসন", + "STR_MENU_SECURE_BOOT":"নিরাপদ বুট", + "STR_MENU_PART_CFG":"পার্টিশন কনফিগারেশন", + "STR_BTN_OK":"ঠিক আছে", + "STR_BTN_CANCEL":"বাতিল", + "STR_PRESERVE_SPACE":"ডিস্কের নীচে কিছু স্থান সংরক্ষণ করুন", + "STR_SPACE_VAL_INVALID":"সংরক্ষিত জায়গার জন্য অবৈধ মান", + "STR_MENU_CLEAR":"Ventoy সাফ", + "STR_CLEAR_SUCCESS":"Ventoy সফলভাবে ডিভাইস থেকে সরানো হয়েছে।", + "STR_CLEAR_FAILED":"ডিস্ক থেকে Ventoy সাফ করার সময় একটি ত্রুটি ঘটেছে। আপনি USB পুনরায় প্লাগ করতে পারেন এবং আবার চেষ্টা করতে পারেন। বিস্তারিত জানার জন্য log.txt পরীক্ষা করুন।", + "STR_MENU_PART_STYLE":"পার্টিশন স্টাইল", + "STR_DISK_2TB_MBR_ERROR":"2TB এর বেশি ডিস্কের জন্য দয়া করে GPT নির্বাচন করুন", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Hindi (हिन्दी)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"BL4CKH47H4CK3R", + + "STR_ERROR":"त्रुटि", + "STR_WARNING":"चेतावनी", + "STR_INFO":"जानकारी", + "STR_INCORRECT_DIR":"कृपया सही निर्देशिका के तहत चलाएं!", + "STR_INCORRECT_TREE_DIR":"मुझे यहां न चलाएं, कृपया जारी किए गए इंस्टॉल पैकेज को डाउनलोड करें, और वहां चलाएं।", + "STR_DEVICE":"डिवाइस", + "STR_LOCAL_VER":"पैकेज में Ventoy", + "STR_DISK_VER":"डिवाइस में Ventoy", + "STR_STATUS":"स्थिति - तैयार", + "STR_INSTALL":"इंस्टॉल", + "STR_UPDATE":"अपडेट करें", + "STR_UPDATE_TIP":"नवीनीकरण ऑपरेशन सुरक्षित है, ISO फाइल अपरिवर्तित रहेंगी।#@जारी रखें?", + "STR_INSTALL_TIP":"डिस्क को स्वरूपित किया जाएगा और सभी डेटा खो जाएगा।#@जारी रखें?", + "STR_INSTALL_TIP2":"डिस्क को स्वरूपित किया जाएगा और सभी डेटा खो जाएगा।#@जारी रखें? (दोहरी जाँच)", + "STR_INSTALL_SUCCESS":"बधाई! #@Ventoy डिवाइस में सफलतापूर्वक स्थापित किया गया है।", + "STR_INSTALL_FAILED":"स्थापना के दौरान एक त्रुटि हुई। आप USB को पुन: स्थापित कर सकते हैं और पुनः प्रयास कर सकते हैं। विस्तार के लिए log.txt की जाँच करें।", + "STR_UPDATE_SUCCESS":"बधाई! #@Ventoy डिवाइस में सफलतापूर्वक अपडेट हो गई है।", + "STR_UPDATE_FAILED":"अपडेट के दौरान एक त्रुटि हुई। आप USB को पुन: भर सकते हैं और पुनः प्रयास कर सकते हैं। विस्तार के लिए log.txt की जाँच करें।", + "STR_WAIT_PROCESS":"एक धागा चल रहा है, कृपया प्रतीक्षा करें ...", + "STR_MENU_OPTION":"विकल्प", + "STR_MENU_SECURE_BOOT":"सुरक्षित बूट", + "STR_MENU_PART_CFG":"विभाजन विन्यास", + "STR_BTN_OK":"ठीक है", + "STR_BTN_CANCEL":"रद्द करना", + "STR_PRESERVE_SPACE":"डिस्क के निचले भाग में कुछ स्थान सुरक्षित रखें", + "STR_SPACE_VAL_INVALID":"आरक्षित स्थान के लिए अमान्य मान", + "STR_MENU_CLEAR":"Ventoy को हटा दें", + "STR_CLEAR_SUCCESS":"डिवाइस से Ventoy को सफलतापूर्वक हटा दिया गया है।", + "STR_CLEAR_FAILED":"डिस्क से Ventoy को साफ़ करते समय एक त्रुटि हुई। आप USB को पुन: भर सकते हैं और पुनः प्रयास कर सकते हैं। विस्तार के लिए log.txt की जाँच करें।", + "STR_MENU_PART_STYLE":"विभाजन शैली", + "STR_DISK_2TB_MBR_ERROR":"कृपया 2TB से अधिक डिस्क के लिए GPT का चयन करें", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Dutch (Nederlands)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"UmitCanbolat", + + "STR_ERROR":"Fout", + "STR_WARNING":"Waarschuwing", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Voer Ventoy uit in de juiste directory!", + "STR_INCORRECT_TREE_DIR":"Ventoy kan hier niet worden uitgevoerd. Download het installatiepakket en probeer Ventoy daarmee te starten.", + "STR_DEVICE":"Apparaat", + "STR_LOCAL_VER":"Ventoy in pakket", + "STR_DISK_VER":"Ventoy op apparaat", + "STR_STATUS":"Status - GEREED", + "STR_INSTALL":"Installeren", + "STR_UPDATE":"Bijwerken", + "STR_UPDATE_TIP":"Upgraden is veilig: ISO-bestanden blijven ongewijzigd.#@Doorgaan?", + "STR_INSTALL_TIP":"De schijf wordt geformatteerd en alle gegevens gaan verloren.#@Doorgaan?", + "STR_INSTALL_TIP2":"De schijf wordt geformatteerd en alle gegevens gaan verloren.#@Doorgaan? (Dubbelcheck)", + "STR_INSTALL_SUCCESS":"Gefeliciteerd!#@Ventoy is met succes op het apparaat geïnstalleerd.", + "STR_INSTALL_FAILED":"Er is een fout opgetreden tijdens de installatie. U kunt het apparaat opnieuw aansluiten en het nogmaals proberen. Controleer log.txt voor details.", + "STR_UPDATE_SUCCESS":"Gefeliciteerd!#@Ventoy is succesvol bijgewerkt op het apparaat.", + "STR_UPDATE_FAILED":"Er is een fout opgetreden tijdens de update. U kunt het apparaat opnieuw aansluiten en het nogmaals proberen. Controleer log.txt voor details.", + "STR_WAIT_PROCESS":"Ventoy is nog bezig, even geduld...", + "STR_MENU_OPTION":"Opties", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"Partitieconfiguratie", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Annuleren", + "STR_PRESERVE_SPACE":"Ruimte aan het einde van de schijf reserveren", + "STR_SPACE_VAL_INVALID":"Ongeldige waarde voor gereserveerde ruimte", + "STR_MENU_CLEAR":"Ventoy verwijderen", + "STR_CLEAR_SUCCESS":"Ventoy is succesvol verwijderd van het apparaat.", + "STR_CLEAR_FAILED":"Er is een fout opgetreden bij het verwijderen van Ventoy. U kunt het apparaat opnieuw aansluiten en het nogmaals proberen. Controleer log.txt voor details.", + "STR_MENU_PART_STYLE":"Partitietabel", + "STR_DISK_2TB_MBR_ERROR":"Selecteer GPT als partitietabel voor schijven groter dan 2TB", + "STR_SHOW_ALL_DEV":"Toon alle apparaten", + "STR_PART_ALIGN_4KB":"Lijn partities uit met 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communicatie fout:", + "STR_WEB_REMOTE_ABNORMAL":"Communicatiefout: abnormaal op afstand", + "STR_WEB_REQUEST_TIMEOUT":"Communicatiefout: time-out van verzoek", + "STR_WEB_SERVICE_UNAVAILABLE":"Communicatiefout: service niet beschikbaar", + "STR_WEB_TOKEN_MISMATCH":"Daemon-status bijgewerkt, probeer het later opnieuw.", + "STR_WEB_SERVICE_BUSY":"Service is bezet, probeer het later opnieuw.", + "STRXXX":"" + }, + { + "name":"Romanian (Română)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"DorinMol", + + "STR_ERROR":"Eroare", + "STR_WARNING":"Avertisment", + "STR_INFO":"Informare", + "STR_INCORRECT_DIR":"Vă rugăm executați în directorul corect!", + "STR_INCORRECT_TREE_DIR":"Nu rulați aici, vă rugăm să descărcați pachetul de instalare și executati acolo.", + "STR_DEVICE":"Dispozitiv", + "STR_LOCAL_VER":"Ventoy În Pachet", + "STR_DISK_VER":"Ventoy În Dispozitiv", + "STR_STATUS":"Stare - PREGĂTIT", + "STR_INSTALL":"Instalare", + "STR_UPDATE":"Actualizare", + "STR_UPDATE_TIP":"Operația de actualizare este sigură, fișierele ISO nu vor fi alterate / modificate.#@Continuați?", + "STR_INSTALL_TIP":"Unitatea disc va fi formatată și toate datele vor fi pierdute.#@Continuați?", + "STR_INSTALL_TIP2":"Unitatea disc va fi formatată și toate datele vor fi pierdute.#@Continuați? (Verificare Dublă)", + "STR_INSTALL_SUCCESS":"Felicitări!#@Ventoy a fost instalat cu succes pe dispozitiv.", + "STR_INSTALL_FAILED":"A apărut o eroare în timpul instalării. Reintroduceți dispozitivul USB și încercați din nou. Verificați log.txt pentru detalii.", + "STR_UPDATE_SUCCESS":"Felicitări!#@Ventoy a fost actualizat cu succes pe dispozitiv.", + "STR_UPDATE_FAILED":"A apărut o eroare în timpul actualizării. Reintroduceți dispozitivul USB și încercați din nou. Verificați log.txt pentru detalii.", + "STR_WAIT_PROCESS":"Rulează un fir de execuție, vă rugăm așteptați...", + "STR_MENU_OPTION":"Opțiune", + "STR_MENU_SECURE_BOOT":"Încărcare Sigură", + "STR_MENU_PART_CFG":"Configurare partiție", + "STR_BTN_OK":"O.K", + "STR_BTN_CANCEL":"Anulare", + "STR_PRESERVE_SPACE":"Păstrați puțin spațiu în partea de jos a discului", + "STR_SPACE_VAL_INVALID":"Valoare nevalidă pentru spațiul rezervat", + "STR_MENU_CLEAR":"Clear Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy has been successfully removed from the device.", + "STR_CLEAR_FAILED":"An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.", + "STR_MENU_PART_STYLE":"Partition Style", + "STR_DISK_2TB_MBR_ERROR":"Please select GPT for disk over 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Japanese (日本語)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"taichi eto,Bentnand", + + "STR_ERROR":"エラー", + "STR_WARNING":"警告", + "STR_INFO":"情報", + "STR_INCORRECT_DIR":"正しいディレクトリーで実行してください", + "STR_INCORRECT_TREE_DIR":"ここで実行するには、パッケージをインストールしてください。.", + "STR_DEVICE":"デバイス", + "STR_LOCAL_VER":"Ventoy In Package", + "STR_DISK_VER":"Ventoy In Device", + "STR_STATUS":"Status - 準備完了", + "STR_INSTALL":"インストール", + "STR_UPDATE":"更新", + "STR_UPDATE_TIP":"アップグレード可能です、ISOファイルは改変されません。.#@続行?", + "STR_INSTALL_TIP":"選択されたディスクは完全に初期化され、保存されたデータは二度と復元できません。#@続行?", + "STR_INSTALL_TIP2":"選択されたディスクは完全に初期化され、保存されたデータは二度と復元できません。#@続行? (再確認)", + "STR_INSTALL_SUCCESS":"Congratulations!#@Ventoy は正常にインストールされました", + "STR_INSTALL_FAILED":"インストール中にエラーが発生しました。デバイスを再接続してもう一度やり直してください。 詳細ログ log.txt ", + "STR_UPDATE_SUCCESS":"Congratulations!#@Ventoy は正常にアップデートされました.", + "STR_UPDATE_FAILED":"更新中にエラーが発生しました。デバイスを再接続してもう一度やり直してください。. 詳細ログ log.txt", + "STR_WAIT_PROCESS":"処理中...", + "STR_MENU_OPTION":"設定", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"パーティション構成", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"キャンセル", + "STR_PRESERVE_SPACE":"ディスクの下部にある程度のスペースを確保する", + "STR_SPACE_VAL_INVALID":"予約スペースの無効な値", + "STR_MENU_CLEAR":"Ventoyを削除", + "STR_CLEAR_SUCCESS":"Ventoyがディスクから削除されました。", + "STR_CLEAR_FAILED":"Ventoyをディスクから削除できませんでした。USBを再挿入してみてください。 詳細ログ log.txt", + "STR_MENU_PART_STYLE":"パーティションスタイル", + "STR_DISK_2TB_MBR_ERROR":"2TB以上のディスクにはGPTを使用してください。", + "STR_SHOW_ALL_DEV":"すべてのデバイスを表示", + "STR_PART_ALIGN_4KB":"パーティションを4KBに揃える", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"デーモンのステータスが更新されました。しばらくしてから再試行してください。", + "STR_WEB_SERVICE_BUSY":"サービスがビジーです。後で再試行してください。", + "STRXXX":"" + }, + { + "name":"Italian (Italiano)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"AverageUser2", + + "STR_ERROR":"Errore", + "STR_WARNING":"Attenzione", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Si prega di eseguire nella cartella corretta", + "STR_INCORRECT_TREE_DIR":"Non eseguire qui, scarica il pacchetto di installazione ed avvialo", + "STR_DEVICE":"Dispositivo", + "STR_LOCAL_VER":"Versione Ventoy locale", + "STR_DISK_VER":"Ventoy nel dispositivo", + "STR_STATUS":"Stato - PRONTO", + "STR_INSTALL":"Installa", + "STR_UPDATE":"Aggiorna", + "STR_UPDATE_TIP":"L'aggiornamento è sicuro, i file presenti nel dispositivo rimarranno invariati.#@Continue?", + "STR_INSTALL_TIP":"Il disco verrà formattato e tutti i dati saranno persi.#@Continue?", + "STR_INSTALL_TIP2":"Il disco verrà formattato e tutti i dati saranno persi.#@Continue?' (Seconda Verifica)", + "STR_INSTALL_SUCCESS":"Congratulazioni!#@Ventoy è stato installato con successo nel dispositivo", + "STR_INSTALL_FAILED":"Si è verificato un errore durante l'installazione. Reinserisci il dispostivo e riprova. Controlla il file log.txt per i dettagli.", + "STR_UPDATE_SUCCESS":"Congratulazioni!#@Ventoy è stato aggiornato con successo nel dispositivo", + "STR_UPDATE_FAILED":"Si è verificato un errore durante l'aggiornamento. Reinserisci il dispostivo e riprova. Controlla il file log.txt per i dettagli.", + "STR_WAIT_PROCESS":"Un processo è in esecuzione, attendere prego...", + "STR_MENU_OPTION":"Opzioni", + "STR_MENU_SECURE_BOOT":"Avvio protetto (secure boot)", + "STR_MENU_PART_CFG":"Configurazione della partizione", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Annulla", + "STR_PRESERVE_SPACE":"Conserva spazio nella parte finale del disco", + "STR_SPACE_VAL_INVALID":"Quantità di spazio da riservare non valida", + "STR_MENU_CLEAR":"Rimuovi Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy è stato rimosso con successo dal dispositivo.", + "STR_CLEAR_FAILED":"Si è verificato un errore durante la rimozione di Ventoy dal dispositivo. Reinserisci il dispositivo e riprova. Controlla il file log.txt per maggiori dettagli", + "STR_MENU_PART_STYLE":"Stile Tabella delle partizioni", + "STR_DISK_2TB_MBR_ERROR":"Seleziona GPT per dischi con dimensioni maggiori di 2TB", + "STR_SHOW_ALL_DEV":"Mostra tutti i dispositivi", + "STR_PART_ALIGN_4KB":"Allinea le partizioni con 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Croatian (Hrvatski)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Valnjes", + + "STR_ERROR":"Pogreška", + "STR_WARNING":"Upozorenje", + "STR_INFO":"Informacija", + "STR_INCORRECT_DIR":"Molim vas pokrenite unutar pravog direktorija!", + "STR_INCORRECT_TREE_DIR":"Ne pokrećite me ovdje, molim vas downloadajte poslijednju verziju, te ponovno pokrenite!", + "STR_DEVICE":"Uređaj", + "STR_LOCAL_VER":"Ventoy (lokalni)", + "STR_DISK_VER":"Ventoy (na uređaju)", + "STR_STATUS":"Status - SPREMAN", + "STR_INSTALL":"Instaliraj", + "STR_UPDATE":"Ažuriraj", + "STR_UPDATE_TIP":"Nadogradnja je sigurna, ISO datoteke neće biti promjenjene.#@Nastaviti?", + "STR_INSTALL_TIP":"USB disk će biti formatiran i svi podatci će biti izgubljeni!#@Nastaviti?", + "STR_INSTALL_TIP2":"USB disk će biti formatiran i svi podatci će biti izgubljeni!#@Nastaviti? (Dodatna provjera)", + "STR_INSTALL_SUCCESS":"Čestitam!#@Ventoy je uspješno instaliran na vaš uređaj.", + "STR_INSTALL_FAILED":"Dogodila se pogreška tokom instalacije. Pokušajte ponovno spojiti USB i pokušati ponovno. Provjerite log.txt za više detalja o nastaloj pogrešci.", + "STR_UPDATE_SUCCESS":"Čestitam!#@Ventoy je uspješno ažuriran na vašem uređaju.", + "STR_UPDATE_FAILED":"Dogodila se pogreška tokom ažuriranja. Pokušajte ponovno spojiti USB i pokušati ponovno. Provjerite log.txt za više detalja o nastaloj pogrešci.", + "STR_WAIT_PROCESS":"Instanca je vec pokrenuta, molimo vas pričekajte...", + "STR_MENU_OPTION":"Opcije", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"Konfiguracija particije", + "STR_BTN_OK":"u redu", + "STR_BTN_CANCEL":"Otkazati", + "STR_PRESERVE_SPACE":"Sačuvajte malo prostora na dnu diska", + "STR_SPACE_VAL_INVALID":"Nevažeća vrijednost rezerviranog prostora", + "STR_MENU_CLEAR":"Obriši Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy je uspesno obrisan sa uređaja", + "STR_CLEAR_FAILED":"Dogodila se greška tokom brisanja Ventoy sa diska. Možeš ponovo ubacit USB i pokušati opet. Pogledaj log.txt za još detalja.", + "STR_MENU_PART_STYLE":"Stil particija", + "STR_DISK_2TB_MBR_ERROR":"Molim te, koristi GPT za diskove preko 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Hungarian (Magyar)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Bitfarago", + + "STR_ERROR":"Hiba", + "STR_WARNING":"Figyelem", + "STR_INFO":"Infó", + "STR_INCORRECT_DIR":"Kérjük, futtasd a megfelelő könyvtárból!", + "STR_INCORRECT_TREE_DIR":"Ne futtasd innen. Töltsd le a kiadott telepítőcsomagot és onnan futtasd.", + "STR_DEVICE":"Eszköz", + "STR_LOCAL_VER":"Ventoy a csomagban", + "STR_DISK_VER":"Ventoy az eszközön", + "STR_STATUS":"Állapot - KÉSZ", + "STR_INSTALL":"Telepítés", + "STR_UPDATE":"Frissítés", + "STR_UPDATE_TIP":"A frissítés biztonságos, az ISO fájlok nem változnak.#@Folytatod?", + "STR_INSTALL_TIP":"A meghajtó formázva lesz és minden rajta lévő adat elveszik.#@Folytatod?", + "STR_INSTALL_TIP2":"A meghajtó formázva lesz és minden rajta lévő adat elveszik.#@Folytatod? (Második jóváhagyás)", + "STR_INSTALL_SUCCESS":"Gratulálunk!#@A Ventoy sikeresen telepítve lett az eszközön.", + "STR_INSTALL_FAILED":"Hiba történt a telepítés során. Csatlakoztasd újra az USB eszközt, és próbáld újra.#@A részleteket lásd a log.txt fájlban.", + "STR_UPDATE_SUCCESS":"Gratulálunk!#@A Ventoy sikeresen frissítve lett az eszközön.", + "STR_UPDATE_FAILED":"Hiba történt a frissítés során. Csatlakoztasd újra az USB eszközt, és próbáld újra.#@A részleteket lásd a log.txt fájlban.", + "STR_WAIT_PROCESS":"A feldolgozás még folyamatban van, kérlek várj...", + "STR_MENU_OPTION":"Opció", + "STR_MENU_SECURE_BOOT":"Biztonsági mód (Secure Boot)", + "STR_MENU_PART_CFG":"Partíciókonfiguráció", + "STR_BTN_OK":"rendben", + "STR_BTN_CANCEL":"Megszünteti", + "STR_PRESERVE_SPACE":"Tartson szabad helyet a lemez alján", + "STR_SPACE_VAL_INVALID":"A fenntartott hely érvénytelen értéke", + "STR_MENU_CLEAR":"Clear Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy has been successfully removed from the device.", + "STR_CLEAR_FAILED":"An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.", + "STR_MENU_PART_STYLE":"Partition Style", + "STR_DISK_2TB_MBR_ERROR":"Please select GPT for disk over 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Chinese Traditional (繁體中文)", + "FontFamily":"新細明體", + "FontSize":14, + "Author":"penut85420", + + "STR_ERROR":"錯誤", + "STR_WARNING":"警告", + "STR_INFO":"提醒", + "STR_INCORRECT_DIR":"請在正確的資料夾下開啟!", + "STR_INCORRECT_TREE_DIR":"請下載並使用發行版本的安裝包", + "STR_DEVICE":"裝置", + "STR_LOCAL_VER":"當前 Ventoy 版本", + "STR_DISK_VER":"裝置內部的 Ventoy 版本", + "STR_STATUS":"狀態 - 準備就緒", + "STR_INSTALL":"安裝", + "STR_UPDATE":"升級", + "STR_UPDATE_TIP":"升級操作是安全的,磁碟內的 ISO 文件不會被清除#@是否繼續?", + "STR_INSTALL_TIP":"磁碟將會被格式化,所有內容將會被清除!#@是否繼續?", + "STR_INSTALL_TIP2":"磁碟將會被格式化,所有內容將會被清除!#@再次確認是否繼續?", + "STR_INSTALL_SUCCESS":"恭喜,Ventoy 已經成功安裝到此裝置中!", + "STR_INSTALL_FAILED":"安裝 Ventoy 的過程中發生錯誤,請重新插入磁碟並重試一次,詳細訊息請調閱 log.txt 文件。", + "STR_UPDATE_SUCCESS":"恭喜,新版本的 Ventoy 已經成功更新到此裝置中!", + "STR_UPDATE_FAILED":"更新 Ventoy 的過程中發生錯誤,請重新插入磁碟並重試一次,詳細訊息請調閱 log.txt 文件。", + "STR_WAIT_PROCESS":"目前有執行緒正在運作中,請稍候", + "STR_MENU_OPTION":"選項", + "STR_MENU_SECURE_BOOT":"支援 Secure Boot", + "STR_MENU_PART_CFG":"分區配置", + "STR_BTN_OK":"確定", + "STR_BTN_CANCEL":"取消", + "STR_PRESERVE_SPACE":"在磁盤最後保留一部分空間", + "STR_SPACE_VAL_INVALID":"保留空間的大小不合法", + "STR_MENU_CLEAR":"清除Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy已成功從設備中清除", + "STR_CLEAR_FAILED":"清除 Ventoy 的過程中發生錯誤,請重新插入磁碟並重試一次,詳細訊息請調閱 log.txt 文件。", + "STR_MENU_PART_STYLE":"分區格式", + "STR_DISK_2TB_MBR_ERROR":"對於超過2TB的磁片請選擇GPT分區格式", + "STR_SHOW_ALL_DEV":"顯示所有設備", + "STR_PART_ALIGN_4KB":"分區按照4KB對齊", + "STR_WEB_COMMUNICATION_ERR":"通信錯誤:", + "STR_WEB_REMOTE_ABNORMAL":"通信錯誤: 服務端異常", + "STR_WEB_REQUEST_TIMEOUT":"通信錯誤: 請求超時", + "STR_WEB_SERVICE_UNAVAILABLE":"通信錯誤: 服務不可用", + "STR_WEB_TOKEN_MISMATCH":"服務狀態已更新", + "STR_WEB_SERVICE_BUSY":"服務正忙,請稍後重試", + "STRXXX":"" + }, + { + "name":"Serbian Latin (Srpski)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Bojan Maksimović, panickingkernel, Zoran Jankov", + + "STR_ERROR":"Greška", + "STR_WARNING":"Upozorenje", + "STR_INFO":"Informacija", + "STR_INCORRECT_DIR":"Molim Vas, pokrenite ме u pravom direktorijumu!", + "STR_INCORRECT_TREE_DIR":"Nemojте me pokretati ovde, molim Vas preuzmite objavljeni instalacioni paket i pokrenite me tamo.", + "STR_DEVICE":"Uređaj", + "STR_LOCAL_VER":"Ventoy u paketu", + "STR_DISK_VER":"Ventoy u uređaju", + "STR_STATUS":"Status - SPREMAN", + "STR_INSTALL":"Instaliraj", + "STR_UPDATE":"Nadogradi", + "STR_UPDATE_TIP":"Nadogradnja je sigurna, ISO fajlovi neće biti promenjeni.#@Nastavi?", + "STR_INSTALL_TIP":"Disk će biti formatiran i svi podaci će biti izgubljeni.#@Nastavi?", + "STR_INSTALL_TIP2":"Disk će biti formatiran i svi podaci će biti izgubljeni.#@Nastavi? (Dvostruka provera)", + "STR_INSTALL_SUCCESS":"Čestitam!#@Ventoy je uspešno instaliran na ovom uređaju.", + "STR_INSTALL_FAILED":"Dogodila se greška tokom instalacije. Možete izvaditi i ponovo ubaciti USB, pa pokušati opet. Pogledajte log.txt za još detalja.", + "STR_UPDATE_SUCCESS":"Čestitam!#@Ventoy je uspešno nadograđen na ovom uređaju.", + "STR_UPDATE_FAILED":"Dogodila se greška prilikom nadogradnje. Možeте izvaditi i ponovo ubaciti USB, pa pokušati opet. Pogledajte log.txt za još detalja.", + "STR_WAIT_PROCESS":"Odvija se operacija, molim Vas sačekajte...", + "STR_MENU_OPTION":"Opcije", + "STR_MENU_SECURE_BOOT":"Sigurno uključivanje je podržano", + "STR_MENU_PART_CFG":"Konfiguracija particija", + "STR_BTN_OK":"U redu", + "STR_BTN_CANCEL":"Otkaži", + "STR_PRESERVE_SPACE":"Sačuvaj nešto prostora na kraju diska", + "STR_SPACE_VAL_INVALID":"Neispravna vrednost za prezervirani prostor", + "STR_MENU_CLEAR":"Obriši Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy je uspešno obrisan sa uređaja", + "STR_CLEAR_FAILED":"Dogodila se greška tokom brisanja Ventoy sa diska. Možete ponovo ubaciti USB i pokušati opet. Pogledajte log.txt za još detalja.", + "STR_MENU_PART_STYLE":"Stil particija", + "STR_DISK_2TB_MBR_ERROR":"Molim Vas, izaberite GPT za diskove preko 2TB", + "STR_SHOW_ALL_DEV":"Pokaži sve uređaje", + "STR_PART_ALIGN_4KB":"Poravnajte sve particije sa 4KB", + "STR_WEB_COMMUNICATION_ERR":"Greška u komunikaciji:", + "STR_WEB_REMOTE_ABNORMAL":"Greška u komunikaciji: nenormalno daljinsko upravljanje", + "STR_WEB_REQUEST_TIMEOUT":"Greška u komunikaciji: Zahtev je istekao", + "STR_WEB_SERVICE_UNAVAILABLE":"Greška u komunikaciji: Servis nije dostupan", + "STR_WEB_TOKEN_MISMATCH":"Status demona ažuriran, pokušajte ponovo kasnije.", + "STR_WEB_SERVICE_BUSY":"Servis je zauzet, pokušajte ponovo kasnije.", + "STRXXX":"" + }, + { + "name":"Serbian Cyrillic (Српски)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Bojan Maksimović, panickingkernel, Zoran Jankov", + + "STR_ERROR":"Грешка", + "STR_WARNING":"Упозорење", + "STR_INFO":"Информација", + "STR_INCORRECT_DIR":"Молим Вас, покрените ме у правом директоријуму!", + "STR_INCORRECT_TREE_DIR":"Немојте ме покретати овде, молим Вас преузмите објављени инсталациони пакет и покрените ме тамо.", + "STR_DEVICE":"Уређај", + "STR_LOCAL_VER":"Ventoy у пакету", + "STR_DISK_VER":"Ventoy у уређају", + "STR_STATUS":"Статус - СПРЕМАН", + "STR_INSTALL":"Инсталирај", + "STR_UPDATE":"Надогради", + "STR_UPDATE_TIP":"Надоградња је сигурна, ISO фајлови неће бити промењени.#@Настави?", + "STR_INSTALL_TIP":"Диск ће бити форматиран и сви подаци ће бити изгубљени.#@Настави?", + "STR_INSTALL_TIP2":"Диск ће бити форматиран и сви подаци ће бити изгубљени.#@Настави? (Двострука провера)", + "STR_INSTALL_SUCCESS":"Честитам!#@Ventoy је успешно инсталиран на овом уређају.", + "STR_INSTALL_FAILED":"Догодила се грешка током инсталације. Можете извадити и поново убацити USB, па покушати опет. Погледајте log.txt за још детаља.", + "STR_UPDATE_SUCCESS":"Честитам!#@Ventoy је био успешно надограђен на овом уређају.", + "STR_UPDATE_FAILED":"Догодила се грешка током надоградње. Можете извадити и поново убацити USB, па покушати опет. Погледајте log.txt за још детаља.", + "STR_WAIT_PROCESS":"Одвија се операција, молим Вас сачекајте...", + "STR_MENU_OPTION":"Опције", + "STR_MENU_SECURE_BOOT":"Сигурно уклјучиванје је подржано", + "STR_MENU_PART_CFG":"Конфигурација партиција", + "STR_BTN_OK":"У реду", + "STR_BTN_CANCEL":"Откажи", + "STR_PRESERVE_SPACE":"Саћувај нешто простора на крају диска", + "STR_SPACE_VAL_INVALID":"Неисправна вредност за презервирани простор", + "STR_MENU_CLEAR":"Обриши Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy је успешно обрисан са уређаја", + "STR_CLEAR_FAILED":"Можете поново убацити USB и покушати опет. Погледајте log.txt за још детаља.", + "STR_MENU_PART_STYLE":"Стил партиција", + "STR_DISK_2TB_MBR_ERROR":"Молим Вас, изаберите GPT за дискове преко 2ТB", + "STR_SHOW_ALL_DEV":"Прикажи све уређаје", + "STR_PART_ALIGN_4KB":"Поравнајте партиције са 4KB", + "STR_WEB_COMMUNICATION_ERR":"Комуникациона грешка:", + "STR_WEB_REMOTE_ABNORMAL":"Комуникациона грешка: ненормално даљинско управљање", + "STR_WEB_REQUEST_TIMEOUT":"Комуникациона грешка: Захтев је истекао", + "STR_WEB_SERVICE_UNAVAILABLE":"Комуникациона грешка: Сервис је недоступан", + "STR_WEB_TOKEN_MISMATCH":"Статус демона ажуриран, покушајте поново касније.", + "STR_WEB_SERVICE_BUSY":"Севис је заузет, покушајте поново касније.", + "STRXXX":"" + }, + { + "name":"Thai (ไทย)", + "FontFamily":"Courier New", + "FontSize":17, + "Author":"longpanda", + + "STR_ERROR":"ผิดพลาด", + "STR_WARNING":"คำเตือน", + "STR_INFO":"ข้อมูล", + "STR_INCORRECT_DIR":"กรุณาเรียกใช้ในอุปกรณ์ที่ถูกต้อง!", + "STR_INCORRECT_TREE_DIR":"อย่าติดตั้งในนี้, โปรดดาวน์โหลดและใช้แพ็คเกจการติดตั้งของรุ่นที่วางจำหน่าย", + "STR_DEVICE":"อุปกรณ์", + "STR_LOCAL_VER":"เวอร์ชั่น Ventoy ", + "STR_DISK_VER":"ลง Ventoy ในอุปกรณ์", + "STR_STATUS":"สถานะ - พร้อม", + "STR_INSTALL":"ติดตั้ง", + "STR_UPDATE":"ปรับปรุง", + "STR_UPDATE_TIP":"การดำเนินการอัปเกรดปลอดภัย, ไฟล์ ISO จะไม่มีการเปลี่ยนแปลง.#@ต่อเนื่อง?", + "STR_INSTALL_TIP":"ดิสก์จะถูกฟอร์แมตและข้อมูลทั้งหมดจะสูญหาย.#@ต่อเนื่อง?", + "STR_INSTALL_TIP2":"ดิสก์จะถูกฟอร์แมตและข้อมูลทั้งหมดจะสูญหาย#@ต่อเนื่อง? (ตรวจสอบอีกครั้ง)", + "STR_INSTALL_SUCCESS":"ขอแสดงความยินดี!#@Ventoy ติดตั้งไปยังอุปกรณ์สำเร็จแล้ว", + "STR_INSTALL_FAILED":"เกิดข้อผิดพลาดระหว่างการติดตั้ง. คุณสามารถถอด USB และลองอีกครั้ง. ตรวจสอบรายละเอียดได้ที่ log.txt.", + "STR_UPDATE_SUCCESS":"ขอแสดงความยินดี!#@Ventoy อัปเดตไปยังอุปกรณ์สำเร็จแล้ว.", + "STR_UPDATE_FAILED":"เกิดข้อผิดพลาดระหว่างการอัพเดต. คุณสามารถถอด USB และลองอีกครั้ง. ตรวจสอบรายละเอียดได้ที่ log.txt.", + "STR_WAIT_PROCESS":"CPU กำลังทำงานอยู่,ได้โปรดรอ...", + "STR_MENU_OPTION":"ตัวเลือก", + "STR_MENU_SECURE_BOOT":"สนับสนุนการบูตที่ปลอดภัย", + "STR_MENU_PART_CFG":"กำหนดค่าพาร์ติชัน", + "STR_BTN_OK":"ตกลง", + "STR_BTN_CANCEL":"ยกเลิก", + "STR_PRESERVE_SPACE":"เก็บพื้นที่บางส่วนของอุปกรณ์ไว้", + "STR_SPACE_VAL_INVALID":"มีปัญหาสำหรับพื้นที่ที่สงวนไว้(กรุณา ฟอร์แมต และติดตั้งใหม่)", + "STR_MENU_CLEAR":"Clear Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy has been successfully removed from the device.", + "STR_CLEAR_FAILED":"An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.", + "STR_MENU_PART_STYLE":"Partition Style", + "STR_DISK_2TB_MBR_ERROR":"Please select GPT for disk over 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Norwegian (Norsk)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Stein-Ove Bøthun", + + "STR_ERROR":"Feil", + "STR_WARNING":"Advarsel", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Vennligst kjør fra den riktige mappen!", + "STR_INCORRECT_TREE_DIR":"Ikke kjør meg her, vennligst last ned den utgitte installasjonspakken og kjør den der.", + "STR_DEVICE":"Enhet", + "STR_LOCAL_VER":"Ventoy i Pakken", + "STR_DISK_VER":"Ventoy på Enheten", + "STR_STATUS":"Status - KLAR", + "STR_INSTALL":"Installer", + "STR_UPDATE":"Oppdater", + "STR_UPDATE_TIP":"Oppgraderingen er trygg, ISO-filene vil være uendret.#@Fortsette?", + "STR_INSTALL_TIP":"Disken blir formatert og alle dataene vil gå tapt.#@Fortsette?", + "STR_INSTALL_TIP2":"Disken blir formatert og alle dataene vil gå tapt.#@Fortsette? (Dobbelsjekk)", + "STR_INSTALL_SUCCESS":"Gratulerer!#@Ventoy er blitt installert på enheten.", + "STR_INSTALL_FAILED":"Det oppstod en feil under installasjonen. Du kan koble til USB-en på nytt og prøve igjen. Check log.txt for flere detaljer.", + "STR_UPDATE_SUCCESS":"Gratulerer!#@Ventoy har blitt oppdatert på enheten.", + "STR_UPDATE_FAILED":"Det oppstod en feil under oppdateringen. Du kan koble til USB-en på nytt og prøve igjen. Se log.txt for flere detaljer.", + "STR_WAIT_PROCESS":"En prosess kjører, vennligst vent...", + "STR_MENU_OPTION":"Alternativ", + "STR_MENU_SECURE_BOOT":"Støtte for sikker oppstart", + "STR_MENU_PART_CFG":"Partisjonskonfigirasjon", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Avbryt", + "STR_PRESERVE_SPACE":"Bevar litt plass på bunnen av disken", + "STR_SPACE_VAL_INVALID":"Ugyldig verdi for reservert plass", + "STR_MENU_CLEAR":"Fjern Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy er blitt fjernet fra enheten.", + "STR_CLEAR_FAILED":"Det oppstod en feil da Ventoy bler fjernet fra disken. Du kan koble til USB-en på nytt og prøve igjen. Sjekk log.txt for flere detaljer.", + "STR_MENU_PART_STYLE":"Partisjonsstil", + "STR_DISK_2TB_MBR_ERROR":"Velg GPT for disker over 2 TB", + "STR_SHOW_ALL_DEV":"Vis alle enheter", + "STR_PART_ALIGN_4KB":"Juster partisjoner med 4KB", + "STR_WEB_COMMUNICATION_ERR":"Kommunikasjonsfeil:", + "STR_WEB_REMOTE_ABNORMAL":"Kommunokasjonsfeil: unormalt fjerntliggende", + "STR_WEB_REQUEST_TIMEOUT":"Kommunikasjonsfeil: Forespørselen ble tidsavbrutt", + "STR_WEB_SERVICE_UNAVAILABLE":"Kommunikasjonsfeil: Tjeneste utilgjengelig", + "STR_WEB_TOKEN_MISMATCH":"Daemon status er oppdatert, vennligst prøv igjen senere.", + "STR_WEB_SERVICE_BUSY":"Tjenesten er opptatt, vennligst prøv igjen senere.", + "STRXXX":"" + }, + { + "name":"Vietnamese (Tiếng Việt)", + "FontFamily":"Tahoma", + "FontSize":14, + "Author":"Nguyen Quoc Hoang - cuumay.com", + + "STR_ERROR":"Lỗi", + "STR_WARNING":"Cảnh báo", + "STR_INFO":"Thông tin", + "STR_INCORRECT_DIR":"Vui lòng chạy Ventoy2Disk tại đúng thư mục của nó !", + "STR_INCORRECT_TREE_DIR":"Không được chạy Ventoy2Disk ở đây, vui lòng tải gói cài đặt đã phát hành và chạy ở đó.", + "STR_DEVICE":"Thiết bị", + "STR_LOCAL_VER":"Phiên bản Ventoy", + "STR_DISK_VER":"Phiên bản Ventoy ở thiết bị", + "STR_STATUS":"Trạng thái - SẴN SÀNG", + "STR_INSTALL":"Cài đặt", + "STR_UPDATE":"Cập nhật", + "STR_UPDATE_TIP":"Việc cập nhật Ventoy là an toàn, các tập tin ISO của bạn sẽ được giữ nguyên trạng.#@ Bạn thật sự muốn tiếp tục ?.", + "STR_INSTALL_TIP":"Thiết bị sẽ được định dạng và do đó TẤT CẢ DỮ LIỆU trên thiết bị sẽ bị mất.#@ Bạn thật sự muốn tiếp tục ?.", + "STR_INSTALL_TIP2":"Thiết bị sẽ được định dạng và do đó TẤT CẢ DỮ LIỆU trên thiết bị sẽ bị mất.#@ Bạn thật sự muốn tiếp tục ?. (Xác nhận lần hai)", + "STR_INSTALL_SUCCESS":"Chúc mừng bạn !.#@ Thiết bị đã được cài Ventoy thành công.", + "STR_INSTALL_FAILED":"Đã xảy ra lỗi trong quá trình cài đặt Ventoy. Bạn có thể rút thiết bị ra và thử lại. Xem chi tiết ở tệp log.txt.", + "STR_UPDATE_SUCCESS":"Chúc mừng bạn !.#@ Thiết bị đã được cập nhật Ventoy thành công.", + "STR_UPDATE_FAILED":"Đã xảy ra lỗi trong quá trình cập nhật Ventoy. Bạn có thể rút thiết bị ra và thử lại. Xem chi tiết ở tệp log.txt.", + "STR_WAIT_PROCESS":"Một luồng xử lý đang chạy, vui lòng chờ...", + "STR_MENU_OPTION":"Tùy chọn", + "STR_MENU_SECURE_BOOT":"Bật hỗ trợ Secure Boot", + "STR_MENU_PART_CFG":"Cấu hình phân vùng", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Hủy", + "STR_PRESERVE_SPACE":"Giữ lại phần dung lượng ở cuối thiết bị", + "STR_SPACE_VAL_INVALID":"Giá trị dung lượng giữ lại không hợp lệ.", + "STR_MENU_CLEAR":"Gỡ bỏ Ventoy", + "STR_CLEAR_SUCCESS":"Chúc mừng bạn !.#@ Thiết bị đã được gỡ bỏ Ventoy thành công.", + "STR_CLEAR_FAILED":"Đã xảy ra lỗi trong quá trình gỡ bỏ Ventoy. Bạn có thể rút thiết bị ra và thử lại. Xem chi tiết ở tệp log.txt.", + "STR_MENU_PART_STYLE":"Kiểu phân vùng", + "STR_DISK_2TB_MBR_ERROR":"Thiết bị có dung lượng lớn hơn 2TB. Vui lòng chọn Kiểu phân vùng là GPT.", + "STR_SHOW_ALL_DEV":"Hiện tất cả Thiết bị", + "STR_PART_ALIGN_4KB":"Căn chỉnh phân vùng với 4KB", + "STR_WEB_COMMUNICATION_ERR":"Lỗi giao tiếp:", + "STR_WEB_REMOTE_ABNORMAL":"Lỗi giao tiếp: Remote bất thường", + "STR_WEB_REQUEST_TIMEOUT":"Lỗi giao tiếp: Yêu cầu đã hết thời gian chờ", + "STR_WEB_SERVICE_UNAVAILABLE":"Lỗi giao tiếp: Dịch vụ không sẵn có", + "STR_WEB_TOKEN_MISMATCH":"Đã cập nhật trạng thái Daemon, vui lòng thử lại sau.", + "STR_WEB_SERVICE_BUSY":"Dịch vụ bận, vui lòng thử lại sau.", + "STRXXX":"" + }, + { + "name":"Lithuanian (Lietuvių)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"r0manas", + + "STR_ERROR ":"Klaida", + "STR_WARNING ":"Įspėjimas", + "STR_INFO ":"Informacija", + "STR_INCORRECT_DIR ":"Prašome paleisti teisingame kataloge!", + "STR_INCORRECT_TREE_DIR ":"Nepaleiskite manęs čia, atsisiųskite išleistą diegimo paketą ir paleiskite ten.", + "STR_DEVICE ":"Įrenginys", + "STR_LOCAL_VER ":"„Ventoy“ versija pakuotėje", + "STR_DISK_VER ":"„Ventoy“ versija įrenginyje", + "STR_STATUS ":"Būsena - PASIRENGĘS", + "STR_INSTALL ":"Įdiegti", + "STR_UPDATE ":"Atnaujinti", + "STR_UPDATE_TIP ":"Atnaujinti - saugu, ISO failai liks nepažeisti.#@Tęsti?", + "STR_INSTALL_TIP ":"Įrenginys bus suformatuotas ir visi duomenys bus prarasti.#@Tęsti?", + "STR_INSTALL_TIP2 ":"Įrenginys bus suformatuotas ir visi duomenys bus prarasti.#@Tęsti? (TIKRAI TĘSTI?)", + "STR_INSTALL_SUCCESS ":"Sveikinu!#@Ventoy sėkmingai įdiegtas įrenginyje.", + "STR_INSTALL_FAILED ":"Diegimo metu įvyko klaida. Galite iš naujo prijungti USB ir bandyti dar kartą. Patikrinkite log.txt, jei norite sužinoti daugiau.", + "STR_UPDATE_SUCCESS ":"Sveikinu!#@Ventoy sėkmingai atnaujintas įrenginyje.", + "STR_UPDATE_FAILED ":"Atnaujinant įvyko klaida. Galite iš naujo prijungti USB ir bandyti dar kartą. Patikrinkite log.txt, jei norite sužinoti daugiau.", + "STR_WAIT_PROCESS ":"Pradėtas procesas, palaukite ...", + "STR_MENU_OPTION ":"Nustatymai", + "STR_MENU_SECURE_BOOT ":"Secure Boot palaikymas", + "STR_MENU_PART_CFG ":"Skirsnio konfigūracija", + "STR_BTN_OK ":"Gerai", + "STR_BTN_CANCEL ":"Atšaukti", + "STR_PRESERVE_SPACE ":"Rezervuoti vietos įrenginyje", + "STR_SPACE_VAL_INVALID ":"Neteisinga rezervuotos vietos vertė", + "STR_MENU_CLEAR ":"Pašalinti „Ventoy“", + "STR_CLEAR_SUCCESS ":"„Ventoy“ sėkmingai pašalintas iš įrenginio.", + "STR_CLEAR_FAILED ":"Įvyko klaida pašalinant „Ventoy“ iš įrenginio. USB ir bandyti dar kartą. Patikrinkite log.txt, jei norite sužinoti daugiau.", + "STR_MENU_PART_STYLE ":"Skirsnio formatas", + "STR_DISK_2TB_MBR_ERROR ":"Prašome pasirinkti GPT, jei įrenginys didesnis nei 2 TB.", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Macedonian (Македонски)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Влатко Стојанов", + + "STR_ERROR":"Грешка", + "STR_WARNING":"Предупредување", + "STR_INFO":"Инфо", + "STR_INCORRECT_DIR":"Ве молам покренете ме коректниот фолдер!", + "STR_INCORRECT_TREE_DIR":"Не покренувајте ме овде, ве молам превземете ја последната верзија и покренете ме таму.", + "STR_DEVICE":"Уред", + "STR_LOCAL_VER":"Ventoy Во Пакетот", + "STR_DISK_VER":"Ventoy Во Уредот", + "STR_STATUS":"Статус - Спремен", + "STR_INSTALL":"Инсталирај", + "STR_UPDATE":"Ажурирај", + "STR_UPDATE_TIP":"Операцијата ажурирање е безбедна, ISO датотеките нема да бидат променети.#@Продолжи?", + "STR_INSTALL_TIP":"УСБ дискот ќе биде форматиран и сите податоци ќе бидат уништени.#@Продолжи?", + "STR_INSTALL_TIP2":"УСБ дискот ќе биде форматиран и сите податоци ќе бидат уништени.#@Продолжи? (Двојна проверка)", + "STR_INSTALL_SUCCESS":"Честитки!#@Ventoy е успешно инсталиран на уредот.", + "STR_INSTALL_FAILED":"Се појави грешка при инсталацијата. Отстранете го УСБ драјвот и пробајте повторно. Проверете го log.txt за детали.", + "STR_UPDATE_SUCCESS":"Честитки!#@Ventoy е успешно ажуриран на уредот.", + "STR_UPDATE_FAILED":"Се појави грешка при ажурирањето. Отстранете го УСБ драјвот и пробајте повторно. Проверете го log.txt за детали.", + "STR_WAIT_PROCESS":"Процесот е вклучен, ве молиме почекајте...", + "STR_MENU_OPTION":"Опции", + "STR_MENU_SECURE_BOOT":"Secure Boot Поддршка", + "STR_MENU_PART_CFG":"Конфигурирање на партиции", + "STR_BTN_OK":"ОК", + "STR_BTN_CANCEL":"Излез", + "STR_PRESERVE_SPACE":"Резервирај место на крајот на дискот", + "STR_SPACE_VAL_INVALID":"Невалидна вредност за резервираното место", + "STR_MENU_CLEAR":"Отстрани го Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy е успешно отстранет од уредот.", + "STR_CLEAR_FAILED":"Се појави грешка при отстранувањето на Ventoy од уредот. Отстранете го УСБ драјвот и пробајте повторно. Проверете го log.txt за детали.", + "STR_MENU_PART_STYLE":"Тип на партиција", + "STR_DISK_2TB_MBR_ERROR":"Ве молиме изберете GPT за дискови поголеми од 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Hebrew (עברית)", + "FontFamily":"tahoma", + "FontSize":16, + "Author":"chaim-chv", + + "STR_ERROR":"תקלה", + "STR_WARNING":"אזהרה", + "STR_INFO":"מידע", + "STR_INCORRECT_DIR":"הרץ בבקשה בתיקייה הנכונה!", + "STR_INCORRECT_TREE_DIR":"אל תריץ אותי כאן. בבקשה הורד את חבילת ההתקנה ששוחררה, ותריץ אותי שם.", + "STR_DEVICE":"התקן", + "STR_LOCAL_VER":"גרסת Ventoy מקומית", + "STR_DISK_VER":"גרסת Ventoy בהתקן", + "STR_STATUS":"סטטוס - מוכן", + "STR_INSTALL":"התקנה", + "STR_UPDATE":"עדכון", + "STR_UPDATE_TIP":"אופציית העדכון היא בטוחה לשימוש. קבצי ה-ISO לא ייפגעו.#@להמשיך?", + "STR_INSTALL_TIP":"הדיסק יפורמט וכל המידע שבו ייעלם.#@להמשיך?", + "STR_INSTALL_TIP2":"הדיסק יפורמט וכל המידע שבו ייעלפ ויימחק לחלוטין.#@להמשיך? (בדיקה לווידוא)", + "STR_INSTALL_SUCCESS":"הצלחה!#@Ventoy הותקנה בהצלחה על הדיסק הנבחר", + "STR_INSTALL_FAILED":"אירעה תקלה בניסיון ההתקנה. אפשר לנסות לחבר את הדיסק מחדש ולבצע ניסיון התקנה נוסף. עיין בקובץ ה-log.txt לפרטים נוספים.", + "STR_UPDATE_SUCCESS":"הצלחה!#@Ventoy הותקנה בהצלחה על הדיסק הנבחר", + "STR_UPDATE_FAILED":"אירעה תקלה בניסיון העדכון. אפשר לנסות לחבר את הדיסק מחדש ולבצע ניסיון נוסף לעדכון. עיין בקובץ ה-log.txt לפרטים נוספים.", + "STR_WAIT_PROCESS":"עובד... נא המתן", + "STR_MENU_OPTION":"אפשרויות", + "STR_MENU_SECURE_BOOT":"תמיכה ב-Secure Boot", + "STR_MENU_PART_CFG":"הגדרת מחיצות", + "STR_BTN_OK":"אישור", + "STR_BTN_CANCEL":"ביטול", + "STR_PRESERVE_SPACE":"הגדר מקום לשמירה בדיסק", + "STR_SPACE_VAL_INVALID":"ערך לא חוקי עבור שטח לשמירה", + "STR_MENU_CLEAR":"נקה את Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy נמחקה בהצלחה מהדיסק הנבחר.", + "STR_CLEAR_FAILED":"אירעה תקלה בניסיון למחוק את Ventoy מהדיסק הנבחר. אפשר לנסות לחבר את הדיסק מחדש ולבצע שוב מחיקה. עיין בקובץ ה-log.txt לפרטים נוספים.", + "STR_MENU_PART_STYLE":"סוג מחיצה", + "STR_DISK_2TB_MBR_ERROR":"בחר ב-GPT עבור דיסק שגדול מ-2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Portuguese (Português de Portugal)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Eskiso", + + "STR_ERROR":"Erro", + "STR_WARNING":"Aviso", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Por favor, execute na pasta correta!", + "STR_INCORRECT_TREE_DIR":"Não me execute aqui, por favor transfira o pacote de instalação, e execute lá.", + "STR_DEVICE":"Dispositivo", + "STR_LOCAL_VER":"Ventoy em pacote", + "STR_DISK_VER":"Ventoy no dispositivo", + "STR_STATUS":"Estado - PRONTO", + "STR_INSTALL":"Instalar", + "STR_UPDATE":"Atualizar", + "STR_UPDATE_TIP":"A operação de atualização é segura, os ficheiros ISO não serão alterados.#@Continuar?", + "STR_INSTALL_TIP":"O disco será formatado e todos os dados serão perdidos.#@Continuar?", + "STR_INSTALL_TIP2":"O disco será formatado e todos os dados serão perdidos.#@Continuar? (Confirmação)", + "STR_INSTALL_SUCCESS":"Parabéns!#@Ventoy foi instalado com sucesso no dispositivo.", + "STR_INSTALL_FAILED":"Um erro ocorreu durante a instalação. Pode reconectar o dispositivo USB e tentar novamente. Verifique o ficheiro log.txt para mais detalhes.", + "STR_UPDATE_SUCCESS":"Parabéns!#@Ventoy foi atualizado com sucesso no dispositivo.", + "STR_UPDATE_FAILED":"Um erro ocorreu durante a atualização. Pode reconectar o dispositivo USB e tentar novamente. Verifique o ficheiro log.txt para mais detalhes.", + "STR_WAIT_PROCESS":"Uma thread está em execução, por favor espere...", + "STR_MENU_OPTION":"Opção", + "STR_MENU_SECURE_BOOT":"Boot seguro", + "STR_MENU_PART_CFG":"Configuração da Partição", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Cancelar", + "STR_PRESERVE_SPACE":"Preservar algum espaço no final do disco", + "STR_SPACE_VAL_INVALID":"Valor invalido para o espaço reservado", + "STR_MENU_CLEAR":"Remover o Ventoy", + "STR_CLEAR_SUCCESS":"O Ventoy foi removido deste dispositivo com sucesso.", + "STR_CLEAR_FAILED":"Um erro ocorreu ao remover o Ventoy do disco. Pode reconectar o dispositivo USB e tentar novamente. Verifique o ficheiro log.txt para mais detalhes.", + "STR_MENU_PART_STYLE":"Estilo de Partição", + "STR_DISK_2TB_MBR_ERROR":"Por favor selecione GPT para discos maiores que 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Indonesian (Bahasa Indonesia)", + "FontFamily":"Comic Sans MS", + "FontSize":16, + "Author":"Ida Bagus Anom Sanjaya", + + "STR_ERROR":"Kesalahan", + "STR_WARNING":"Peringatan", + "STR_INFO":"Informasi", + "STR_INCORRECT_DIR":"Silakan jalankan pada direktori yang benar!", + "STR_INCORRECT_TREE_DIR":"Jangan jalankan di sini, silakan unduh paket pemasangan yang diliris, dan jalankan di sana.", + "STR_DEVICE":"Perangkat", + "STR_LOCAL_VER":"Ventoy pada Paket", + "STR_DISK_VER":"Ventoy pada Perangkat", + "STR_STATUS":"Status - SIAP", + "STR_INSTALL":"Pasang", + "STR_UPDATE":"Perbarui", + "STR_UPDATE_TIP":"Operasi pembaruan ini aman, Tidak akan ada perubahan berkas ISO.#@Lanjutkan?", + "STR_INSTALL_TIP":"Disk akan di-format dan semua data akan hilang.#@Lanjutkan?", + "STR_INSTALL_TIP2":"Disk akan di-format dan semua data akan hilang.#@Lanjutkan? (YAKIN)", + "STR_INSTALL_SUCCESS":"Selamat!#@Ventoy telah berhasil terpasang di perangkat ini.", + "STR_INSTALL_FAILED":"Terjadi kesalahan ketika pemasangan berlangsung. Anda perlu mencabut-pasang ulang USB dan coba lagi. Cek log.txt untuk detil.", + "STR_UPDATE_SUCCESS":"Selamat!#@Ventoy telah berhasil diperbarui di perangkat ini.", + "STR_UPDATE_FAILED":"Terjadi kesalahan ketika pembaruan berlangsung. Anda perlu mencabut-pasang ulang USB dan coba lagi. Cek log.txt untuk detil.", + "STR_WAIT_PROCESS":"Tugas sedang berjalan, silakan tunggu...", + "STR_MENU_OPTION":"Pilihan", + "STR_MENU_SECURE_BOOT":"Dukungan Secure Boot", + "STR_MENU_PART_CFG":"Konfigurasi Partisi", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Batal", + "STR_PRESERVE_SPACE":"Mempertahankan sejumlah ruang penyimpanan pada disk di bawah ini", + "STR_SPACE_VAL_INVALID":"Nilai menpertahankan ruang tidak valid", + "STR_MENU_CLEAR":"Bersihkan Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy telah berhasil dihapus pada perangkat ini.", + "STR_CLEAR_FAILED":"Terjadi kesalahan ketika penghapusan berlangsung. Anda perlu mencabut-pasang ulang USB dan coba lagi. Cek log.txt untuk detil.", + "STR_MENU_PART_STYLE":"Gaya Partisi", + "STR_DISK_2TB_MBR_ERROR":"Silakan pilih GPT untuk disk yang lebih dari 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STRXXX":"" + }, + { + "name":"Ukrainian (Українська)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Teraskull", + + "STR_ERROR":"Помилка", + "STR_WARNING":"Попередження", + "STR_INFO":"Інформація", + "STR_INCORRECT_DIR":"Будь ласка, запустіть у правильному каталозі!", + "STR_INCORRECT_TREE_DIR":"Не запускайте мене тут, завантажте реліз інсталяційного пакету і запустіть там.", + "STR_DEVICE":"Пристрій", + "STR_LOCAL_VER":"Ventoy в пакеті", + "STR_DISK_VER":"Ventoy на пристрої", + "STR_STATUS":"Стан - ГОТОВИЙ", + "STR_INSTALL":"Встановити", + "STR_UPDATE":"Оновити", + "STR_UPDATE_TIP":"Процес оновлення безпечний, файли ISO залишаться незмінними.#@Продовжити?", + "STR_INSTALL_TIP":"Диск буде відформатовано, і всі дані будуть втрачені.#@Продовжити?", + "STR_INSTALL_TIP2":"Диск буде відформатовано, і всі дані будуть втрачені.#@Продовжити? (Подвійна перевірка)", + "STR_INSTALL_SUCCESS":"Вітаємо!#@Ventoy успішно встановлено на пристрій.", + "STR_INSTALL_FAILED":"Під час встановлення сталася помилка. Ви можете ще раз підключити USB і повторити спробу. Перевірте log.txt для деталей.", + "STR_UPDATE_SUCCESS":"Вітаємо!#@Ventoy на пристрої успішно оновлено.", + "STR_UPDATE_FAILED":"Під час оновлення сталася помилка. Ви можете ще раз підключити USB і повторити спробу. Перевірте log.txt для деталей.", + "STR_WAIT_PROCESS":"Потік запущено, зачекайте...", + "STR_MENU_OPTION":"Опції", + "STR_MENU_SECURE_BOOT":"Підтримка Secure Boot", + "STR_MENU_PART_CFG":"Конфігурація розділів", + "STR_BTN_OK":"ОК", + "STR_BTN_CANCEL":"Скасувати", + "STR_PRESERVE_SPACE":"Зарезервувати простір в кінці диска", + "STR_SPACE_VAL_INVALID":"Недійсне значення для зарезервованого простору", + "STR_MENU_CLEAR":"Видалити Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy успішно видалено з пристрою.", + "STR_CLEAR_FAILED":"Під час видалення Ventoy сталася помилка. Ви можете ще раз підключити USB і повторити спробу. Перевірте log.txt для деталей.", + "STR_MENU_PART_STYLE":"Стиль розмітки розділів", + "STR_DISK_2TB_MBR_ERROR":"Будь ласка, виберіть GPT для дисків понад 2TB", + "STR_SHOW_ALL_DEV":"Показати всі пристрої", + "STR_PART_ALIGN_4KB":"Вирівняти розділи з розміром 4КБ", + "STR_WEB_COMMUNICATION_ERR":"Помилка зв'язку: ", + "STR_WEB_REMOTE_ABNORMAL":"Помилка зв'язку: віддалене з'єднання недійсне", + "STR_WEB_REQUEST_TIMEOUT":"Помилка зв'язку: Час очікування запиту минув", + "STR_WEB_SERVICE_UNAVAILABLE":"Помилка зв'язку: Служба недоступна", + "STR_WEB_TOKEN_MISMATCH":"Статус демона оновлено. Повторіть спробу пізніше.", + "STR_WEB_SERVICE_BUSY":"Служба зайнята, повторіть спробу пізніше.", + "STRXXX":"" + }, + { + "name":"Greek (Ελληνικά)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"grmasa, Vasilis Kosmidis", + + "STR_ERROR":"Σφάλμα", + "STR_WARNING":"Προειδοποίηση", + "STR_INFO":"Πληροφορίες", + "STR_INCORRECT_DIR":"Παρακαλώ εκτελέστε στον σωστό κατάλογο!", + "STR_INCORRECT_TREE_DIR":"Μην με εκτελείτε εδώ, κατεβάστε το πακέτο εγκατάστασης και εκτελέστε εκεί.", + "STR_DEVICE":"Συσκευή", + "STR_LOCAL_VER":"Ventoy στο πρόγραμμα", + "STR_DISK_VER":"Ventoy στη συσκευή", + "STR_STATUS":"Κατάσταση - ΕΤΟΙΜΟ", + "STR_INSTALL":"Εγκατάσταση", + "STR_UPDATE":"Αναβάθμιση", + "STR_UPDATE_TIP":"Η λειτουργία αναβάθμισης είναι ασφαλής, τα αρχεία ISO δεν θα αλλάξουν.#@Συνέχεια;", + "STR_INSTALL_TIP":"Ο δίσκος θα μορφοποιηθεί και όλα τα δεδομένα θα χαθούν.#@Συνέχεια;", + "STR_INSTALL_TIP2":"Ο δίσκος θα μορφοποιηθεί και όλα τα δεδομένα θα χαθούν.#@Συνέχεια; (Επανελέγξτε)", + "STR_INSTALL_SUCCESS":"Συγχαρητήρια!#Το @Ventoy έχει εγκατασταθεί με επιτυχία στη συσκευή.", + "STR_INSTALL_FAILED":"Παρουσιάστηκε σφάλμα κατά την εγκατάσταση. Μπορείτε να επανασυνδέσετε το USB και να δοκιμάσετε ξανά. Ελέγξτε το αρχείο log.txt για λεπτομέρειες.", + "STR_UPDATE_SUCCESS":"Συγχαρητήρια!#Το @Ventoy ενημερώθηκε με επιτυχία στη συσκευή.", + "STR_UPDATE_FAILED":"Παρουσιάστηκε σφάλμα κατά την ενημέρωση. Μπορείτε να επανασυνδέσετε το USB και να δοκιμάσετε ξανά. Ελέγξτε το αρχείο log.txt για λεπτομέρειες.", + "STR_WAIT_PROCESS":"Ένα νήμα εκτελείται, παρακαλώ περιμένετε...", + "STR_MENU_OPTION":"Επιλογές", + "STR_MENU_SECURE_BOOT":"Υποστήριξη ασφαλούς εκκίνησης (Secure Boot)", + "STR_MENU_PART_CFG":"Διαμόρφωση κατατμήσεων", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Ακύρωση", + "STR_PRESERVE_SPACE":"Διατηρήστε λίγο χώρο στο κάτω μέρος του δίσκου", + "STR_SPACE_VAL_INVALID":"Μη έγκυρη τιμή για τον δεσμευμένο χώρο", + "STR_MENU_CLEAR":"Απεγκατάσταση του Ventoy", + "STR_CLEAR_SUCCESS":"Το Ventoy καταργήθηκε με επιτυχία από τη συσκευή.", + "STR_CLEAR_FAILED":"Παρουσιάστηκε σφάλμα κατά την εκκαθάριση του Ventoy από το δίσκο. Μπορείτε να επανασυνδέσετε το USB και να δοκιμάσετε ξανά. Ελέγξτε το αρχείο log.txt για λεπτομέρειες.", + "STR_MENU_PART_STYLE":"Στυλ κατατμήσεων", + "STR_DISK_2TB_MBR_ERROR":"Παρακαλώ επιλέξτε GPT για δίσκο άνω των 2 TB", + "STR_SHOW_ALL_DEV":"Προβολή όλων των συσκευών", + "STR_PART_ALIGN_4KB":"Ευθυγράμμιση κατατμήσεων με 4KB", + "STR_WEB_COMMUNICATION_ERR":"Σφάλμα επικοινωνίας:", + "STR_WEB_REMOTE_ABNORMAL":"Σφάλμα επικοινωνίας: απομακρυσμένη ανωμαλία", + "STR_WEB_REQUEST_TIMEOUT":"Σφάλμα επικοινωνίας: χρονική λήξη αιτήματος", + "STR_WEB_SERVICE_UNAVAILABLE":"Σφάλμα επικοινωνίας: υπηρεσία μη διαθέσιμη", + "STR_WEB_TOKEN_MISMATCH":"Η κατάσταση του δαίμονα επικαιροποιήθηκε. Παρακαλώ δοκιμάστε αργότερα.", + "STR_WEB_SERVICE_BUSY":"Η υπηρεσία είναι απασχολημένη. Παρακαλώ δοκιμάστε αργότερα.", + "STRXXX":"" + }, + { + "name":"Swedish (Svenska)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Sopor", + + "STR_ERROR":"Fel", + "STR_WARNING":"Varning", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Kör programmet från korrekt katalog!", + "STR_INCORRECT_TREE_DIR":"Kör inte programmet här. Ladda ner installationspaketet och kör programmet där.", + "STR_DEVICE":"Enhet", + "STR_LOCAL_VER":"Ventoy i paketet", + "STR_DISK_VER":"Ventoy på enheten", + "STR_STATUS":"Status - REDO", + "STR_INSTALL":"Installera", + "STR_UPDATE":"Uppdatera", + "STR_UPDATE_TIP":"Uppdateringen är säker, ISO-filerna kommer att vara oförändrade.#@Fortsätta?", + "STR_INSTALL_TIP":"Enheten kommer att formateras och all data kommer att gå förlorad.#@Fortsätta?", + "STR_INSTALL_TIP2":"Enheten kommer att formateras och all data kommer att gå förlorad.#@Fortsätta? (Sista varningen!)", + "STR_INSTALL_SUCCESS":"Gratulerar!#@Ventoy har installerats på enheten.", + "STR_INSTALL_FAILED":"Ett fel inträffade under installationen. Prova att återansluta USB-enheten och försök igen. Läs i log.txt för mer information.", + "STR_UPDATE_SUCCESS":"Gratulerar!#@Ventoy har uppdaterats på enheten.", + "STR_UPDATE_FAILED":"Ett fel inträffade under uppdateringen. Prova att återansluta USB-enheten och försök igen. Läs i log.txt för mer information.", + "STR_WAIT_PROCESS":"En tråd körs redan, vänta...", + "STR_MENU_OPTION":"Alternativ", + "STR_MENU_SECURE_BOOT":"Stöd för säker start", + "STR_MENU_PART_CFG":"Partitionskonfiguration", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Avbryt", + "STR_PRESERVE_SPACE":"Spara lite utrymme i slutet av enheten", + "STR_SPACE_VAL_INVALID":"Ogiltigt värde för reserverat utrymme", + "STR_MENU_CLEAR":"Ta bort Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy har tagits bort från enheten.", + "STR_CLEAR_FAILED":"Ett fel inträffade när Ventoy skulle tas bort från enheten. Prova att återansluta USB-enheten och försök igen. Läs i log.txt för mer information.", + "STR_MENU_PART_STYLE":"Partitionsstil", + "STR_DISK_2TB_MBR_ERROR":"Välj GPT för enhet över 2 TB", + "STR_SHOW_ALL_DEV":"Visa alla enheter", + "STR_PART_ALIGN_4KB":"Justera partitioner med 4KB", + "STR_WEB_COMMUNICATION_ERR":"Kommunikationsfel:", + "STR_WEB_REMOTE_ABNORMAL":"Kommunikationsfel: onormal fjärr", + "STR_WEB_REQUEST_TIMEOUT":"Kommunikationsfel: Begäran tog för lång tid", + "STR_WEB_SERVICE_UNAVAILABLE":"Kommunikationsfel: Tjänsten är inte tillgänglig", + "STR_WEB_TOKEN_MISMATCH":"Daemon-status uppdaterad. Försök igen senare.", + "STR_WEB_SERVICE_BUSY":"Tjänster är upptagen. Försök igen senare.", + "STRXXX":"" + }, + { + "name":"Slovenian (Slovenski)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Urajmal", + + "STR_ERROR":"Napaka", + "STR_WARNING":"Opozorilo", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Prosim izberite pravilno pot!", + "STR_INCORRECT_TREE_DIR":"Ne zaganjajte tukaj. Prosim prenesite posodobljeno verzijo in jo zaženite.", + "STR_DEVICE":"Naprava", + "STR_LOCAL_VER":"Ventoy verzija", + "STR_DISK_VER":"Ventoy na napravi", + "STR_STATUS":"Status - PRIPRAVLJEN", + "STR_INSTALL":"Namesti", + "STR_UPDATE":"Nadgradi", + "STR_UPDATE_TIP":"Varna nadgradnja. ISO datoteke ne bodo spremenjene.#@Nadaljujem?", + "STR_INSTALL_TIP":"Ta disk bo formatiran in vsi podatki bodo izbrisani.#@Nadaljujem?", + "STR_INSTALL_TIP2":"Ta disk bo formatiran in vsi podatki bodo izbrisani.#@Nadaljujem? (Druga potrditev)", + "STR_INSTALL_SUCCESS":"Čestitamo!#@ventoy je bil uspešno nameščen na napravo.", + "STR_INSTALL_FAILED":"Med namestitvijo je prišlo do napake. Iztaknite in ponovno priklopite USB. Preverite log.txt za podrobnosti.", + "STR_UPDATE_SUCCESS":"Čestitamo!#@ventoy na napravi je bil uspešno posodobljen.", + "STR_UPDATE_FAILED":"Prišlo je do napake med nadgradnjo. Iztaknite in ponovno priklopite USB. Preverite log.txt za podrobnosti.", + "STR_WAIT_PROCESS":"Proces teče, prosimo počakajte, ...", + "STR_MENU_OPTION":"Nastavitve", + "STR_MENU_SECURE_BOOT":"Podpora Secure Boot", + "STR_MENU_PART_CFG":"Konfiguracija particij", + "STR_BTN_OK":"V redu", + "STR_BTN_CANCEL":"Prekliči", + "STR_PRESERVE_SPACE":"Ohrani nekaj prostora na koncu particije", + "STR_SPACE_VAL_INVALID":"Nepravilna vrednost za rezerviran prostor", + "STR_MENU_CLEAR":"Odstrani Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy je bil uspešno odstranjen.", + "STR_CLEAR_FAILED":"Prišlo je do napake pri odstranjevanju Ventoy-a iz diska. Iztaknite in ponovno priklopite USB. Preverite log.txt za podrobnosti.", + "STR_MENU_PART_STYLE":"Vrsta particije", + "STR_DISK_2TB_MBR_ERROR":"Prosim izberite GPT za particije nad 2TB", + "STR_SHOW_ALL_DEV":"Pokaži vse naprave", + "STR_PART_ALIGN_4KB":"Poravnaj particije na 4KB", + "STR_WEB_COMMUNICATION_ERR":"Napaka v komunikaciji:", + "STR_WEB_REMOTE_ABNORMAL":"Napaka v komunikaciji: oddaljena težava", + "STR_WEB_REQUEST_TIMEOUT":"Napaka v komunikaciji: čas je potekel", + "STR_WEB_SERVICE_UNAVAILABLE":"Napaka v komunikaciji: storitev ni na voljo", + "STR_WEB_TOKEN_MISMATCH":"Zahteva storitve je potekla, prosim poskusite kasneje.", + "STR_WEB_SERVICE_BUSY":"Storitev je zasedena, prosim poskusite kasneje.", + "STRXXX":"" + } +] \ No newline at end of file diff --git a/LinuxGUI/language.sh b/LinuxGUI/language.sh index 2a0b6df8..07d8fe28 100644 --- a/LinuxGUI/language.sh +++ b/LinuxGUI/language.sh @@ -1,37 +1,19 @@ #!/bin/bash -echo "generating languages.js ..." +VTOY_PATH=$PWD/../ -iconv -f utf-16 -t utf-8 ../LANGUAGES/languages.ini | egrep -v '=STR|^;' | egrep 'Language-|STR_' > languages.js +echo "checking languages.json ..." +sh $VTOY_PATH/LANGUAGES/check.sh $VTOY_PATH || exit 1 -dos2unix languages.js - -sed 's/\(STR_.*\)=/"\1":/g' -i languages.js - -sed "s/: *'/:\"/g" -i languages.js - -sed "s/'\s*$/\",/g" -i languages.js - -sed 's/\[Language-\(.*\)\].*/"STR_XXX":""},{"name":"\1",/g' -i languages.js +echo "generating languages.json ..." -sed "1s/.*\},/var vtoy_language_data = \[/" -i languages.js +echo "var vtoy_language_data = " > languages.js +cat $VTOY_PATH/LANGUAGES/languages.json >> languages.js +echo ";" >> languages.js -sed 's/\("STR_WEB_COMMUNICATION_ERR"[^,]*\)/\1,/g' -i languages.js -sed 's/,,/,/g' -i languages.js - -CNT=$(grep -v -c ',$' languages.js) - -if [ $CNT -gt 0 ]; then - echo "====== FAILED =========" - grep -v -n ',$' languages.js - exit 1 -fi - - -echo '"STR_XXX":""}' >> languages.js -echo '];' >> languages.js +dos2unix languages.js rm -f WebUI/static/js/languages.js mv languages.js WebUI/static/js/ -echo "====== SUCCESS ==========" \ No newline at end of file +echo "====== SUCCESS ==========" diff --git a/Ventoy2Disk/Ventoy2Disk/Language.h b/Ventoy2Disk/Ventoy2Disk/Language.h index 144a9b23..aa1f4c0f 100644 --- a/Ventoy2Disk/Ventoy2Disk/Language.h +++ b/Ventoy2Disk/Ventoy2Disk/Language.h @@ -101,13 +101,19 @@ typedef enum OPT_SUBMENU #define VTOY_MENU_LANGUAGE_BEGIN 0xB000 -#define VENTOY_LANGUAGE_INI TEXT(".\\ventoy\\languages.ini") +#define VENTOY_LANGUAGE_INI TEXT(".\\ventoy\\languages.ini") +#define VENTOY_LANGUAGE_JSON TEXT(".\\ventoy\\languages.json") +#define VENTOY_LANGUAGE_INI_A ".\\ventoy\\languages.ini" +#define VENTOY_LANGUAGE_JSON_A ".\\ventoy\\languages.json" + #define VENTOY_CFG_INI TEXT(".\\Ventoy2Disk.ini") #define VENTOY_CFG_INI_A ".\\Ventoy2Disk.ini" #define VENTOY_MAX_LANGUAGE 200 #define GET_INI_STRING(Section, Key, Buf) GetPrivateProfileString(Section, Key, TEXT("#"), Buf, sizeof(Buf), VENTOY_LANGUAGE_INI) + + typedef struct VENTOY_LANGUAGE { WCHAR Name[128]; diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c index 43c4ea0c..4c9fdf4d 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c @@ -283,6 +283,12 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount) CurDrive->PartStyle = (MBR.PartTbl[0].FsFlag == 0xEE) ? 1 : 0; GetVentoyVerInPhyDrive(CurDrive, Part2StartSector, CurDrive->VentoyVersion, sizeof(CurDrive->VentoyVersion), &(CurDrive->SecureBootSupport)); Log("PhyDrive %d is Ventoy Disk ver:%s SecureBoot:%u", CurDrive->PhyDrive, CurDrive->VentoyVersion, CurDrive->SecureBootSupport); + + if (CurDrive->VentoyVersion[0] == 0) + { + CurDrive->VentoyVersion[0] = '?'; + Log("Unknown Ventoy Version"); + } } } diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h index b9a84db4..8ec38ab8 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h @@ -148,7 +148,7 @@ typedef struct PHY_DRIVE_INFO STORAGE_BUS_TYPE BusType; CHAR DriveLetters[64]; - + CHAR VentoyVersion[32]; BOOL SecureBootSupport; diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj index 7824269f..e1276f2a 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj @@ -110,6 +110,7 @@ + @@ -133,6 +134,7 @@ + diff --git a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters index a4dede7c..45f86ffe 100644 --- a/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters +++ b/Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters @@ -78,6 +78,9 @@ 源文件 + + 源文件 + @@ -137,6 +140,9 @@ 头文件 + + 头文件 + diff --git a/Ventoy2Disk/Ventoy2Disk/VentoyJson.c b/Ventoy2Disk/Ventoy2Disk/VentoyJson.c new file mode 100644 index 00000000..1bfca570 --- /dev/null +++ b/Ventoy2Disk/Ventoy2Disk/VentoyJson.c @@ -0,0 +1,771 @@ +/****************************************************************************** + * VentoyJson.c + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#ifdef FOR_VTOY_JSON_CHECK +#include +#include +#include +#else +#include +#include "Ventoy2Disk.h" +#endif + +#include "VentoyJson.h" + +static void vtoy_json_free(VTOY_JSON *pstJsonHead) +{ + VTOY_JSON *pstNext = NULL; + + while (NULL != pstJsonHead) + { + pstNext = pstJsonHead->pstNext; + if ((pstJsonHead->enDataType < JSON_TYPE_BUTT) && (NULL != pstJsonHead->pstChild)) + { + vtoy_json_free(pstJsonHead->pstChild); + } + + free(pstJsonHead); + pstJsonHead = pstNext; + } + + return; +} + +static char *vtoy_json_skip(const char *pcData) +{ + while ((NULL != pcData) && ('\0' != *pcData) && (*pcData <= 32)) + { + pcData++; + } + + return (char *)pcData; +} + +VTOY_JSON *vtoy_json_find_item +( + VTOY_JSON *pstJson, + JSON_TYPE enDataType, + const char *szKey +) +{ + while (NULL != pstJson) + { + if ((enDataType == pstJson->enDataType) && + (0 == strcmp(szKey, pstJson->pcName))) + { + return pstJson; + } + pstJson = pstJson->pstNext; + } + + return NULL; +} + +static int vtoy_json_parse_number +( + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +) +{ + unsigned long Value; + + Value = strtoul(pcData, (char **)ppcEnd, 10); + if (*ppcEnd == pcData) + { + Log("Failed to parse json number %s.", pcData); + return JSON_FAILED; + } + + pstJson->enDataType = JSON_TYPE_NUMBER; + pstJson->unData.lValue = Value; + + return JSON_SUCCESS; +} + +static int vtoy_json_parse_string +( + char *pcNewStart, + char *pcRawStart, + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +) +{ + UINT32 uiLen = 0; + const char *pcPos = NULL; + const char *pcTmp = pcData + 1; + + *ppcEnd = pcData; + + if ('\"' != *pcData) + { + return JSON_FAILED; + } + + pcPos = strchr(pcTmp, '\"'); + if ((NULL == pcPos) || (pcPos < pcTmp)) + { + Log("Invalid string %s.", pcData); + return JSON_FAILED; + } + + *ppcEnd = pcPos + 1; + uiLen = (UINT32)(unsigned long)(pcPos - pcTmp); + + pstJson->enDataType = JSON_TYPE_STRING; + pstJson->unData.pcStrVal = pcNewStart + (pcTmp - pcRawStart); + pstJson->unData.pcStrVal[uiLen] = '\0'; + + return JSON_SUCCESS; +} + +static int vtoy_json_parse_array +( + char *pcNewStart, + char *pcRawStart, + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +) +{ + int Ret = JSON_SUCCESS; + VTOY_JSON *pstJsonChild = NULL; + VTOY_JSON *pstJsonItem = NULL; + const char *pcTmp = pcData + 1; + + *ppcEnd = pcData; + pstJson->enDataType = JSON_TYPE_ARRAY; + + if ('[' != *pcData) + { + return JSON_FAILED; + } + + pcTmp = vtoy_json_skip(pcTmp); + + if (']' == *pcTmp) + { + *ppcEnd = pcTmp + 1; + return JSON_SUCCESS; + } + + JSON_NEW_ITEM(pstJson->pstChild, JSON_FAILED); + + Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJson->pstChild, pcTmp, ppcEnd); + if (JSON_SUCCESS != Ret) + { + Log("Failed to parse array child."); + return JSON_FAILED; + } + + pstJsonChild = pstJson->pstChild; + pcTmp = vtoy_json_skip(*ppcEnd); + while ((NULL != pcTmp) && (',' == *pcTmp)) + { + JSON_NEW_ITEM(pstJsonItem, JSON_FAILED); + pstJsonChild->pstNext = pstJsonItem; + pstJsonItem->pstPrev = pstJsonChild; + pstJsonChild = pstJsonItem; + + Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd); + if (JSON_SUCCESS != Ret) + { + Log("Failed to parse array child."); + return JSON_FAILED; + } + pcTmp = vtoy_json_skip(*ppcEnd); + } + + if ((NULL != pcTmp) && (']' == *pcTmp)) + { + *ppcEnd = pcTmp + 1; + return JSON_SUCCESS; + } + else + { + *ppcEnd = pcTmp; + return JSON_FAILED; + } +} + +static int vtoy_json_parse_object +( + char *pcNewStart, + char *pcRawStart, + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +) +{ + int Ret = JSON_SUCCESS; + VTOY_JSON *pstJsonChild = NULL; + VTOY_JSON *pstJsonItem = NULL; + const char *pcTmp = pcData + 1; + + *ppcEnd = pcData; + pstJson->enDataType = JSON_TYPE_OBJECT; + + if ('{' != *pcData) + { + return JSON_FAILED; + } + + pcTmp = vtoy_json_skip(pcTmp); + if ('}' == *pcTmp) + { + *ppcEnd = pcTmp + 1; + return JSON_SUCCESS; + } + + JSON_NEW_ITEM(pstJson->pstChild, JSON_FAILED); + + Ret = vtoy_json_parse_string(pcNewStart, pcRawStart, pstJson->pstChild, pcTmp, ppcEnd); + if (JSON_SUCCESS != Ret) + { + Log("Failed to parse array child."); + return JSON_FAILED; + } + + pstJsonChild = pstJson->pstChild; + pstJsonChild->pcName = pstJsonChild->unData.pcStrVal; + pstJsonChild->unData.pcStrVal = NULL; + + pcTmp = vtoy_json_skip(*ppcEnd); + if ((NULL == pcTmp) || (':' != *pcTmp)) + { + *ppcEnd = pcTmp; + return JSON_FAILED; + } + + Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd); + if (JSON_SUCCESS != Ret) + { + Log("Failed to parse array child."); + return JSON_FAILED; + } + + pcTmp = vtoy_json_skip(*ppcEnd); + while ((NULL != pcTmp) && (',' == *pcTmp)) + { + JSON_NEW_ITEM(pstJsonItem, JSON_FAILED); + pstJsonChild->pstNext = pstJsonItem; + pstJsonItem->pstPrev = pstJsonChild; + pstJsonChild = pstJsonItem; + + Ret = vtoy_json_parse_string(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd); + if (JSON_SUCCESS != Ret) + { + Log("Failed to parse array child."); + return JSON_FAILED; + } + + pcTmp = vtoy_json_skip(*ppcEnd); + pstJsonChild->pcName = pstJsonChild->unData.pcStrVal; + pstJsonChild->unData.pcStrVal = NULL; + if ((NULL == pcTmp) || (':' != *pcTmp)) + { + *ppcEnd = pcTmp; + return JSON_FAILED; + } + + Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd); + if (JSON_SUCCESS != Ret) + { + Log("Failed to parse array child."); + return JSON_FAILED; + } + + pcTmp = vtoy_json_skip(*ppcEnd); + } + + if ((NULL != pcTmp) && ('}' == *pcTmp)) + { + *ppcEnd = pcTmp + 1; + return JSON_SUCCESS; + } + else + { + *ppcEnd = pcTmp; + return JSON_FAILED; + } +} + +int vtoy_json_parse_value +( + char *pcNewStart, + char *pcRawStart, + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +) +{ + pcData = vtoy_json_skip(pcData); + + switch (*pcData) + { + case 'n': + { + if (0 == strncmp(pcData, "null", 4)) + { + pstJson->enDataType = JSON_TYPE_NULL; + *ppcEnd = pcData + 4; + return JSON_SUCCESS; + } + break; + } + case 'f': + { + if (0 == strncmp(pcData, "false", 5)) + { + pstJson->enDataType = JSON_TYPE_BOOL; + pstJson->unData.lValue = 0; + *ppcEnd = pcData + 5; + return JSON_SUCCESS; + } + break; + } + case 't': + { + if (0 == strncmp(pcData, "true", 4)) + { + pstJson->enDataType = JSON_TYPE_BOOL; + pstJson->unData.lValue = 1; + *ppcEnd = pcData + 4; + return JSON_SUCCESS; + } + break; + } + case '\"': + { + return vtoy_json_parse_string(pcNewStart, pcRawStart, pstJson, pcData, ppcEnd); + } + case '[': + { + return vtoy_json_parse_array(pcNewStart, pcRawStart, pstJson, pcData, ppcEnd); + } + case '{': + { + return vtoy_json_parse_object(pcNewStart, pcRawStart, pstJson, pcData, ppcEnd); + } + case '-': + { + return vtoy_json_parse_number(pstJson, pcData, ppcEnd); + } + default : + { + if (*pcData >= '0' && *pcData <= '9') + { + return vtoy_json_parse_number(pstJson, pcData, ppcEnd); + } + } + } + + *ppcEnd = pcData; + Log("Invalid json data %u.", (UINT8)(*pcData)); + return JSON_FAILED; +} + +VTOY_JSON * vtoy_json_create(void) +{ + VTOY_JSON *pstJson = NULL; + + pstJson = (VTOY_JSON *)malloc(sizeof(VTOY_JSON)); + if (NULL == pstJson) + { + return NULL; + } + memset(pstJson, 0, sizeof(VTOY_JSON)); + return pstJson; +} + +int vtoy_json_parse(VTOY_JSON *pstJson, const char *szJsonData) +{ + UINT32 uiMemSize = 0; + int Ret = JSON_SUCCESS; + char *pcNewBuf = NULL; + const char *pcEnd = NULL; + + uiMemSize = strlen(szJsonData) + 1; + pcNewBuf = (char *)malloc(uiMemSize); + if (NULL == pcNewBuf) + { + Log("Failed to alloc new buf."); + return JSON_FAILED; + } + memcpy(pcNewBuf, szJsonData, uiMemSize); + pcNewBuf[uiMemSize - 1] = 0; + + Ret = vtoy_json_parse_value(pcNewBuf, (char *)szJsonData, pstJson, szJsonData, &pcEnd); + if (JSON_SUCCESS != Ret) + { + Log("Failed to parse json data start=%p, end=%p", szJsonData, pcEnd); + return JSON_FAILED; + } + + return JSON_SUCCESS; +} + +int vtoy_json_scan_parse +( + const VTOY_JSON *pstJson, + UINT32 uiParseNum, + JSON_PARSE *pstJsonParse +) +{ + UINT32 i = 0; + const VTOY_JSON *pstJsonCur = NULL; + JSON_PARSE *pstCurParse = NULL; + + for (pstJsonCur = pstJson; NULL != pstJsonCur; pstJsonCur = pstJsonCur->pstNext) + { + if ((JSON_TYPE_OBJECT == pstJsonCur->enDataType) || + (JSON_TYPE_ARRAY == pstJsonCur->enDataType)) + { + continue; + } + + for (i = 0, pstCurParse = NULL; i < uiParseNum; i++) + { + if (0 == strcmp(pstJsonParse[i].pcKey, pstJsonCur->pcName)) + { + pstCurParse = pstJsonParse + i; + break; + } + } + + if (NULL == pstCurParse) + { + continue; + } + + switch (pstJsonCur->enDataType) + { + case JSON_TYPE_NUMBER: + { + if (sizeof(UINT32) == pstCurParse->uiBufSize) + { + *(UINT32 *)(pstCurParse->pDataBuf) = (UINT32)pstJsonCur->unData.lValue; + } + else if (sizeof(UINT16) == pstCurParse->uiBufSize) + { + *(UINT16 *)(pstCurParse->pDataBuf) = (UINT16)pstJsonCur->unData.lValue; + } + else if (sizeof(UINT8) == pstCurParse->uiBufSize) + { + *(UINT8 *)(pstCurParse->pDataBuf) = (UINT8)pstJsonCur->unData.lValue; + } + else if ((pstCurParse->uiBufSize > sizeof(UINT64))) + { + sprintf_s((char *)pstCurParse->pDataBuf, pstCurParse->uiBufSize, "%llu", + (unsigned long long)(pstJsonCur->unData.lValue)); + } + else + { + Log("Invalid number data buf size %u.", pstCurParse->uiBufSize); + } + break; + } + case JSON_TYPE_STRING: + { + strcpy_s((char *)pstCurParse->pDataBuf, pstCurParse->uiBufSize, pstJsonCur->unData.pcStrVal); + break; + } + case JSON_TYPE_BOOL: + { + *(UINT8 *)(pstCurParse->pDataBuf) = (pstJsonCur->unData.lValue) > 0 ? 1 : 0; + break; + } + default : + { + break; + } + } + } + + return JSON_SUCCESS; +} + +int vtoy_json_scan_array +( + VTOY_JSON *pstJson, + const char *szKey, + VTOY_JSON **ppstArrayItem +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_ARRAY, szKey); + if (NULL == pstJsonItem) + { + Log("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + *ppstArrayItem = pstJsonItem; + + return JSON_SUCCESS; +} + +int vtoy_json_scan_array_ex +( + VTOY_JSON *pstJson, + const char *szKey, + VTOY_JSON **ppstArrayItem +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_ARRAY, szKey); + if (NULL == pstJsonItem) + { + Log("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + *ppstArrayItem = pstJsonItem->pstChild; + + return JSON_SUCCESS; +} + +int vtoy_json_scan_object +( + VTOY_JSON *pstJson, + const char *szKey, + VTOY_JSON **ppstObjectItem +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_OBJECT, szKey); + if (NULL == pstJsonItem) + { + Log("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + *ppstObjectItem = pstJsonItem; + + return JSON_SUCCESS; +} + +int vtoy_json_get_int +( + VTOY_JSON *pstJson, + const char *szKey, + int *piValue +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_NUMBER, szKey); + if (NULL == pstJsonItem) + { + Log("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + *piValue = (int)pstJsonItem->unData.lValue; + + return JSON_SUCCESS; +} + +int vtoy_json_get_uint +( + VTOY_JSON *pstJson, + const char *szKey, + UINT32 *puiValue +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_NUMBER, szKey); + if (NULL == pstJsonItem) + { + Log("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + *puiValue = (UINT32)pstJsonItem->unData.lValue; + + return JSON_SUCCESS; +} + +int vtoy_json_get_uint64 +( + VTOY_JSON *pstJson, + const char *szKey, + UINT64 *pui64Value +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_NUMBER, szKey); + if (NULL == pstJsonItem) + { + Log("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + *pui64Value = (UINT64)pstJsonItem->unData.lValue; + + return JSON_SUCCESS; +} + +int vtoy_json_get_bool +( + VTOY_JSON *pstJson, + const char *szKey, + UINT8 *pbValue +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_BOOL, szKey); + if (NULL == pstJsonItem) + { + Log("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + *pbValue = pstJsonItem->unData.lValue > 0 ? 1 : 0; + + return JSON_SUCCESS; +} + +int vtoy_json_get_string +( + VTOY_JSON *pstJson, + const char *szKey, + UINT32 uiBufLen, + char *pcBuf +) +{ + VTOY_JSON *pstJsonItem = NULL; + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_STRING, szKey); + if (NULL == pstJsonItem) + { + Log("Key %s is not found in json data.", szKey); + return JSON_NOT_FOUND; + } + + strcpy_s(pcBuf, uiBufLen, pstJsonItem->unData.pcStrVal); + + return JSON_SUCCESS; +} + +const char * vtoy_json_get_string_ex(VTOY_JSON *pstJson, const char *szKey) +{ + VTOY_JSON *pstJsonItem = NULL; + + if ((NULL == pstJson) || (NULL == szKey)) + { + return NULL; + } + + pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_STRING, szKey); + if (NULL == pstJsonItem) + { + Log("Key %s is not found in json data.", szKey); + return NULL; + } + + return pstJsonItem->unData.pcStrVal; +} + +int vtoy_json_destroy(VTOY_JSON *pstJson) +{ + if (NULL == pstJson) + { + return JSON_SUCCESS; + } + + if (NULL != pstJson->pstChild) + { + vtoy_json_free(pstJson->pstChild); + } + + if (NULL != pstJson->pstNext) + { + vtoy_json_free(pstJson->pstNext); + } + + free(pstJson); + + return JSON_SUCCESS; +} + + +#ifdef FOR_VTOY_JSON_CHECK + +int main(int argc, char**argv) +{ + int ret = 1; + int FileSize; + FILE *fp; + void *Data = NULL; + VTOY_JSON *json = NULL; + + fp = fopen(argv[1], "rb"); + if (!fp) + { + Log("Failed to open %s\n", argv[1]); + goto out; + } + + fseek(fp, 0, SEEK_END); + FileSize = (int)ftell(fp); + fseek(fp, 0, SEEK_SET); + + Data = malloc(FileSize + 4); + if (!Data) + { + Log("Failed to malloc %d\n", FileSize + 4); + goto out; + } + *((char *)Data + FileSize) = 0; + + fread(Data, 1, FileSize, fp); + + json = vtoy_json_create(); + if (!json) + { + Log("Failed vtoy_json_create\n"); + goto out; + } + + if (vtoy_json_parse(json, (char *)Data) != JSON_SUCCESS) + { + goto out; + } + + ret = 0; + +out: + if (fp) fclose(fp); + if (Data) free(Data); + if (json) vtoy_json_destroy(json); + + printf("\n"); + return ret; +} + +#endif diff --git a/Ventoy2Disk/Ventoy2Disk/VentoyJson.h b/Ventoy2Disk/Ventoy2Disk/VentoyJson.h new file mode 100644 index 00000000..6c2cf3b3 --- /dev/null +++ b/Ventoy2Disk/Ventoy2Disk/VentoyJson.h @@ -0,0 +1,164 @@ +/****************************************************************************** + * VentoyJson.h + * + * Copyright (c) 2021, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#ifndef __VENTOY_JSON_H__ +#define __VENTOY_JSON_H__ + +#ifdef FOR_VTOY_JSON_CHECK +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned int UINT32; +typedef unsigned long long UINT64; + +#define Log printf +#define strcpy_s(a, b, c) strncpy(a, c, b) +#define sprintf_s snprintf +#endif + +#define JSON_SUCCESS 0 +#define JSON_FAILED 1 +#define JSON_NOT_FOUND 2 + +typedef enum _JSON_TYPE +{ + JSON_TYPE_NUMBER = 0, + JSON_TYPE_STRING, + JSON_TYPE_BOOL, + JSON_TYPE_ARRAY, + JSON_TYPE_OBJECT, + JSON_TYPE_NULL, + JSON_TYPE_BUTT +}JSON_TYPE; + + +typedef struct _VTOY_JSON +{ + struct _VTOY_JSON *pstPrev; + struct _VTOY_JSON *pstNext; + struct _VTOY_JSON *pstChild; + + JSON_TYPE enDataType; + union + { + char *pcStrVal; + int iNumVal; + UINT64 lValue; + }unData; + + char *pcName; +}VTOY_JSON; + +typedef struct _JSON_PARSE +{ + char *pcKey; + void *pDataBuf; + UINT32 uiBufSize; +}JSON_PARSE; + +#define JSON_NEW_ITEM(pstJson, ret) \ +{ \ + (pstJson) = (VTOY_JSON *)malloc(sizeof(VTOY_JSON)); \ + if (NULL == (pstJson)) \ + { \ + Log("Failed to alloc memory for json.\n"); \ + return (ret); \ + } \ + memset((pstJson), 0, sizeof(VTOY_JSON));\ +} + +VTOY_JSON *vtoy_json_find_item +( + VTOY_JSON *pstJson, + JSON_TYPE enDataType, + const char *szKey +); +int vtoy_json_parse_value +( + char *pcNewStart, + char *pcRawStart, + VTOY_JSON *pstJson, + const char *pcData, + const char **ppcEnd +); +VTOY_JSON * vtoy_json_create(void); +int vtoy_json_parse(VTOY_JSON *pstJson, const char *szJsonData); + +int vtoy_json_scan_parse +( + const VTOY_JSON *pstJson, + UINT32 uiParseNum, + JSON_PARSE *pstJsonParse +); + +int vtoy_json_scan_array +( + VTOY_JSON *pstJson, + const char *szKey, + VTOY_JSON **ppstArrayItem +); + +int vtoy_json_scan_array_ex +( + VTOY_JSON *pstJson, + const char *szKey, + VTOY_JSON **ppstArrayItem +); +int vtoy_json_scan_object +( + VTOY_JSON *pstJson, + const char *szKey, + VTOY_JSON **ppstObjectItem +); +int vtoy_json_get_int +( + VTOY_JSON *pstJson, + const char *szKey, + int *piValue +); +int vtoy_json_get_uint +( + VTOY_JSON *pstJson, + const char *szKey, + UINT32 *puiValue +); +int vtoy_json_get_uint64 +( + VTOY_JSON *pstJson, + const char *szKey, + UINT64 *pui64Value +); +int vtoy_json_get_bool +( + VTOY_JSON *pstJson, + const char *szKey, + UINT8 *pbValue +); +int vtoy_json_get_string +( + VTOY_JSON *pstJson, + const char *szKey, + UINT32 uiBufLen, + char *pcBuf +); +const char * vtoy_json_get_string_ex(VTOY_JSON *pstJson, const char *szKey); +int vtoy_json_destroy(VTOY_JSON *pstJson); + +#endif /* __VENTOY_JSON_H__ */ + diff --git a/Ventoy2Disk/Ventoy2Disk/WinDialog.c b/Ventoy2Disk/Ventoy2Disk/WinDialog.c index bec810e8..20f6f66c 100644 Binary files a/Ventoy2Disk/Ventoy2Disk/WinDialog.c and b/Ventoy2Disk/Ventoy2Disk/WinDialog.c differ diff --git a/VtoyTool/vtoydump.c b/VtoyTool/vtoydump.c index 34c1ee7e..72b78151 100644 --- a/VtoyTool/vtoydump.c +++ b/VtoyTool/vtoydump.c @@ -464,10 +464,13 @@ static int vtoy_check_device(ventoy_os_param *param, const char *device) static int vtoy_print_os_param(ventoy_os_param *param, char *diskname) { - int cnt = 0; + int fd, size; + int cnt = 0; char *path = param->vtoy_img_path; const char *fs; - + char diskpath[256] = {0}; + char sizebuf[64] = {0}; + cnt = vtoy_find_disk_by_size(param->vtoy_disk_size, diskname); debug("find disk by size %llu, cnt=%d...\n", (unsigned long long)param->vtoy_disk_size, cnt); if (1 == cnt) @@ -494,6 +497,37 @@ static int vtoy_print_os_param(ventoy_os_param *param, char *diskname) if (1 == cnt) { + if (strstr(diskname, "nvme") || strstr(diskname, "mmc") || strstr(diskname, "nbd")) + { + snprintf(diskpath, sizeof(diskpath) - 1, "/sys/class/block/%sp2/size", diskname); + } + else + { + snprintf(diskpath, sizeof(diskpath) - 1, "/sys/class/block/%s2/size", diskname); + } + + if (access(diskpath, F_OK) >= 0) + { + debug("get part size from sysfs for %s\n", diskpath); + + fd = open(diskpath, O_RDONLY | O_BINARY); + if (fd >= 0) + { + read(fd, sizebuf, sizeof(sizebuf)); + size = (int)strtoull(sizebuf, NULL, 10); + close(fd); + if ((size != (64 * 1024)) && (size != (8 * 1024))) + { + debug("sizebuf=<%s> size=%d\n", sizebuf, size); + return 1; + } + } + } + else + { + debug("%s not exist \n", diskpath); + } + printf("/dev/%s#%s#%s\n", diskname, fs, path); return 0; } diff --git a/VtoyTool/vtoytool/00/vtoytool_32 b/VtoyTool/vtoytool/00/vtoytool_32 index 6cda86be..97f553f4 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_32 and b/VtoyTool/vtoytool/00/vtoytool_32 differ diff --git a/VtoyTool/vtoytool/00/vtoytool_64 b/VtoyTool/vtoytool/00/vtoytool_64 index 1acd940f..53a951e6 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_64 and b/VtoyTool/vtoytool/00/vtoytool_64 differ diff --git a/VtoyTool/vtoytool/00/vtoytool_aa64 b/VtoyTool/vtoytool/00/vtoytool_aa64 index 9a429bc5..11833dce 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_aa64 and b/VtoyTool/vtoytool/00/vtoytool_aa64 differ diff --git a/VtoyTool/vtoytool/00/vtoytool_m64e b/VtoyTool/vtoytool/00/vtoytool_m64e index 3fd69195..249e1a0c 100644 Binary files a/VtoyTool/vtoytool/00/vtoytool_m64e and b/VtoyTool/vtoytool/00/vtoytool_m64e differ