]> glassweightruler.freedombox.rocks Git - Ventoy.git/commitdiff
1. Change the UTF-16 languages.ini to UTF-8 languages.json
authorlongpanda <admin@ventoy.net>
Sat, 8 May 2021 06:22:37 +0000 (14:22 +0800)
committerlongpanda <admin@ventoy.net>
Sat, 8 May 2021 06:22:37 +0000 (14:22 +0800)
2. The update button is available even if data corrupted in VTOYEFI partition.
3. Set the default focus to No when you click Install button in Ventoy2Disk.exe.
4. Fix a BUG when booting Windows VHD(x) with the latest ventoy_vhdboot.img.
5. Support boot Windows VHD(x) files in local disk.

28 files changed:
GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c [new file with mode: 0644]
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_vhd.c
INSTALL/Ventoy2Disk.exe
INSTALL/grub/grub.cfg
INSTALL/tool/VentoyWorker.sh
INSTALL/ventoy_pack.sh
LANGUAGES/README [new file with mode: 0644]
LANGUAGES/check.sh [new file with mode: 0644]
LANGUAGES/languages.ini [deleted file]
LANGUAGES/languages.json [new file with mode: 0644]
LinuxGUI/language.sh
Ventoy2Disk/Ventoy2Disk/Language.h
Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c
Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.h
Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj
Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.vcxproj.filters
Ventoy2Disk/Ventoy2Disk/VentoyJson.c [new file with mode: 0644]
Ventoy2Disk/Ventoy2Disk/VentoyJson.h [new file with mode: 0644]
Ventoy2Disk/Ventoy2Disk/WinDialog.c
VtoyTool/vtoydump.c
VtoyTool/vtoytool/00/vtoytool_32
VtoyTool/vtoytool/00/vtoytool_64
VtoyTool/vtoytool/00/vtoytool_aa64
VtoyTool/vtoytool/00/vtoytool_m64e

index 9ffa5f81189195b11a1a01b416cb23ee880202bd..f73518911810f6581e0cd35a0c3569a20d09d14e 100644 (file)
@@ -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;
index e10985e80f5df6932b604881f46071cd8cd44162..14dae6e00e6965475326dcd30b4647cacd02a027 100644 (file)
 #include <grub/normal.h>
 #include <grub/extcmd.h>
 #include <grub/datetime.h>
-#include <grub/i18n.h>
 #include <grub/net.h>
 #include <grub/misc.h>
 #include <grub/kernel.h>
-#ifdef GRUB_MACHINE_EFI
-#include <grub/efi/api.h>
-#include <grub/efi/efi.h>
-#endif
 #include <grub/time.h>
-#include <grub/video.h>
-#include <grub/acpi.h>
-#include <grub/charset.h>
-#include <grub/crypto.h>
-#include <grub/lib/crc.h>
 #include <grub/ventoy.h>
 #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(&param->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>:<NOT FOUND>\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 (file)
index 0000000..9f0a8b8
--- /dev/null
@@ -0,0 +1,4497 @@
+/******************************************************************************
+ * ventoy_cmd.c 
+ *
+ * Copyright (c) 2021, longpanda <admin@ventoy.net>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/disk.h>
+#include <grub/device.h>
+#include <grub/term.h>
+#include <grub/partition.h>
+#include <grub/file.h>
+#include <grub/normal.h>
+#include <grub/extcmd.h>
+#include <grub/datetime.h>
+#include <grub/i18n.h>
+#include <grub/net.h>
+#include <grub/misc.h>
+#include <grub/kernel.h>
+#ifdef GRUB_MACHINE_EFI
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#endif
+#include <grub/time.h>
+#include <grub/video.h>
+#include <grub/acpi.h>
+#include <grub/charset.h>
+#include <grub/crypto.h>
+#include <grub/lib/crc.h>
+#include <grub/ventoy.h>
+#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(&param->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>:<NOT FOUND>\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;
+}
+
+
index 45f823f92131eada09411dbc97dd512a443142a0..5e7e11d2c6fea194512a0e1d28c61a67f5e0db97 100644 (file)
@@ -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__ */
 
index e74e73891027c51b7f8b09a41a602fcf63c51ccb..179739b2a41f53464fad8e7eb2043809472fe3ac 100644 (file)
@@ -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);
 
index 0b8b00f52dcf96797d8e475a4b797f40a9927474..a5203e2f8d97393eda0ffa7668b1483feca818aa 100644 (file)
 
 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)
index d5a1798d14e0d4f70bf02f54ead1b82f1a527a9e..da7243aed4ab1cc2b22f54c998c66b9d5e6aeaca 100644 (file)
Binary files a/INSTALL/Ventoy2Disk.exe and b/INSTALL/Ventoy2Disk.exe differ
index 8990ad5fe9a1a603cf7b2701ac937b454ebf7db0..9c4d6dfd354c60db6ac847d2f721ffe438e11aee 100644 (file)
@@ -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 {
index c820ffc46969d99b39cce47047d32cb855c2712a..543ac69717d3fce6defd8a9c17f57bcc415772ad 100644 (file)
@@ -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
index 577a23a0409af66353d1df221cc91f32762bb094..11b2a289861571e8553e135b75488602494d7f4a 100644 (file)
@@ -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 (file)
index 0000000..7a5b4f2
--- /dev/null
@@ -0,0 +1,17 @@
+\r
+File encoding: UTF-8\r
+\r
+language name must in the format: "Language-XXX (YYY)"\r
+    1. Language- fixed 9 characters\r
+    2. XXX: name in English\r
+    3. a space (ASCII: 0x20)\r
+    4. a left brace (ASCII: 0x28)\r
+    5. YYY: name in the specified language\r
+    6. a right brace (ASCII: 0x29)\r
+\r
+string translation:\r
+      all the String Define\r
+      #@ will be replaced with \r\n\r
+\r
+All the languages will be sorted by the name\r
+\r
diff --git a/LANGUAGES/check.sh b/LANGUAGES/check.sh
new file mode 100644 (file)
index 0000000..a18c1a8
--- /dev/null
@@ -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 (file)
index c40c752..0000000
Binary files a/LANGUAGES/languages.ini and /dev/null differ
diff --git a/LANGUAGES/languages.json b/LANGUAGES/languages.json
new file mode 100644 (file)
index 0000000..2abe6d8
--- /dev/null
@@ -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
index 2a0b6df840b9e10f0e4918b5498a9d39c70f196d..07d8fe2871211237131405d700e51bfdaec5e9b3 100644 (file)
@@ -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 =========="
index 144a9b23137c3a2c721fe72479d3e88d35a27ae3..aa1f4c0feede0a1097ce671339c37e3e2a208232 100644 (file)
@@ -101,13 +101,19 @@ typedef enum OPT_SUBMENU
 #define VTOY_MENU_LANGUAGE_BEGIN  0xB000\r
 \r
 \r
-#define VENTOY_LANGUAGE_INI  TEXT(".\\ventoy\\languages.ini")\r
+#define VENTOY_LANGUAGE_INI     TEXT(".\\ventoy\\languages.ini")\r
+#define VENTOY_LANGUAGE_JSON    TEXT(".\\ventoy\\languages.json")\r
+#define VENTOY_LANGUAGE_INI_A   ".\\ventoy\\languages.ini"\r
+#define VENTOY_LANGUAGE_JSON_A  ".\\ventoy\\languages.json"\r
+\r
 #define VENTOY_CFG_INI     TEXT(".\\Ventoy2Disk.ini")\r
 #define VENTOY_CFG_INI_A   ".\\Ventoy2Disk.ini"\r
 #define VENTOY_MAX_LANGUAGE     200\r
 \r
 #define GET_INI_STRING(Section, Key, Buf) GetPrivateProfileString(Section, Key, TEXT("#"), Buf, sizeof(Buf), VENTOY_LANGUAGE_INI)\r
 \r
+\r
+\r
 typedef struct VENTOY_LANGUAGE\r
 {\r
        WCHAR Name[128];\r
index 43c4ea0c2dff2448e09fdb6bb9d340d0a1c1b22f..4c9fdf4d1a32f7e7d3b663b377dff55a609497e4 100644 (file)
@@ -283,6 +283,12 @@ static int FilterPhysicalDrive(PHY_DRIVE_INFO *pDriveList, DWORD DriveCount)
             CurDrive->PartStyle = (MBR.PartTbl[0].FsFlag == 0xEE) ? 1 : 0;\r
             GetVentoyVerInPhyDrive(CurDrive, Part2StartSector, CurDrive->VentoyVersion, sizeof(CurDrive->VentoyVersion), &(CurDrive->SecureBootSupport));\r
             Log("PhyDrive %d is Ventoy Disk ver:%s SecureBoot:%u", CurDrive->PhyDrive, CurDrive->VentoyVersion, CurDrive->SecureBootSupport);\r
+\r
+            if (CurDrive->VentoyVersion[0] == 0)\r
+            {\r
+                CurDrive->VentoyVersion[0] = '?';\r
+                Log("Unknown Ventoy Version");\r
+            }\r
         }\r
     }\r
 \r
index b9a84db4fa90ed933e0c29d9c47125d44f61cb37..8ec38ab8b1cb34c6d60697224b457ba25279c784 100644 (file)
@@ -148,7 +148,7 @@ typedef struct PHY_DRIVE_INFO
     STORAGE_BUS_TYPE BusType;\r
 \r
     CHAR DriveLetters[64];\r
-\r
+   \r
     CHAR VentoyVersion[32];\r
 \r
     BOOL SecureBootSupport;\r
index 7824269f2662103d457618bae559eed11dfc6adf..e1276f2a9a520214b6ba2aebb136fce775eee970 100644 (file)
     <ClCompile Include="process.c" />
     <ClCompile Include="Utility.c" />
     <ClCompile Include="Ventoy2Disk.c" />
+    <ClCompile Include="VentoyJson.c" />
     <ClCompile Include="WinDialog.c" />
     <ClCompile Include="xz-embedded-20130513\linux\lib\decompress_unxz.c" />
   </ItemGroup>
     <ClInclude Include="process.h" />
     <ClInclude Include="resource.h" />
     <ClInclude Include="Ventoy2Disk.h" />
+    <ClInclude Include="VentoyJson.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="Ventoy2Disk.rc" />
index a4dede7c1b31104f456f99f8fac5d51e5b72d836..45f86ffe644eea4baaf0ef8f4e6f4021730f1f15 100644 (file)
@@ -78,6 +78,9 @@
     <ClCompile Include="crc32.c">
       <Filter>源文件</Filter>
     </ClCompile>
+    <ClCompile Include="VentoyJson.c">
+      <Filter>源文件</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Ventoy2Disk.h">
     <ClInclude Include="process.h">
       <Filter>头文件</Filter>
     </ClInclude>
+    <ClInclude Include="VentoyJson.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="Ventoy2Disk.rc">
diff --git a/Ventoy2Disk/Ventoy2Disk/VentoyJson.c b/Ventoy2Disk/Ventoy2Disk/VentoyJson.c
new file mode 100644 (file)
index 0000000..1bfca57
--- /dev/null
@@ -0,0 +1,771 @@
+/******************************************************************************\r
+ * VentoyJson.c\r
+ *\r
+ * Copyright (c) 2021, longpanda <admin@ventoy.net>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License as\r
+ * published by the Free Software Foundation; either version 3 of the\r
+ * License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful, but\r
+ * WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+#ifdef FOR_VTOY_JSON_CHECK\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#else\r
+#include <Windows.h>\r
+#include "Ventoy2Disk.h"\r
+#endif\r
+\r
+#include "VentoyJson.h"\r
+\r
+static void vtoy_json_free(VTOY_JSON *pstJsonHead)\r
+{\r
+    VTOY_JSON *pstNext = NULL;\r
+\r
+    while (NULL != pstJsonHead)\r
+    {\r
+        pstNext = pstJsonHead->pstNext;\r
+        if ((pstJsonHead->enDataType < JSON_TYPE_BUTT) && (NULL != pstJsonHead->pstChild))\r
+        {\r
+            vtoy_json_free(pstJsonHead->pstChild);\r
+        }\r
+\r
+        free(pstJsonHead);\r
+        pstJsonHead = pstNext;\r
+    }\r
+\r
+    return;\r
+}\r
+\r
+static char *vtoy_json_skip(const char *pcData)\r
+{\r
+    while ((NULL != pcData) && ('\0' != *pcData) && (*pcData <= 32))\r
+    {\r
+        pcData++;\r
+    }\r
+\r
+    return (char *)pcData;\r
+}\r
+\r
+VTOY_JSON *vtoy_json_find_item\r
+(\r
+    VTOY_JSON *pstJson,\r
+    JSON_TYPE  enDataType,\r
+    const char *szKey\r
+)\r
+{\r
+    while (NULL != pstJson)\r
+    {\r
+        if ((enDataType == pstJson->enDataType) && \r
+            (0 == strcmp(szKey, pstJson->pcName)))\r
+        {\r
+            return pstJson;\r
+        }\r
+        pstJson = pstJson->pstNext;\r
+    }\r
+    \r
+    return NULL;\r
+}\r
+\r
+static int vtoy_json_parse_number\r
+(\r
+    VTOY_JSON *pstJson, \r
+    const char *pcData,\r
+    const char **ppcEnd\r
+)\r
+{\r
+    unsigned long Value;\r
+\r
+    Value = strtoul(pcData, (char **)ppcEnd, 10);\r
+    if (*ppcEnd == pcData)\r
+    {\r
+        Log("Failed to parse json number %s.", pcData);\r
+        return JSON_FAILED;\r
+    }\r
+\r
+    pstJson->enDataType = JSON_TYPE_NUMBER;\r
+    pstJson->unData.lValue = Value;\r
+    \r
+    return JSON_SUCCESS;\r
+}\r
+\r
+static int vtoy_json_parse_string\r
+(\r
+    char *pcNewStart,\r
+    char *pcRawStart,\r
+    VTOY_JSON *pstJson, \r
+    const char *pcData,\r
+    const char **ppcEnd\r
+)\r
+{\r
+    UINT32 uiLen = 0;\r
+    const char *pcPos = NULL;\r
+    const char *pcTmp = pcData + 1;\r
+    \r
+    *ppcEnd = pcData;\r
+\r
+    if ('\"' != *pcData)\r
+    {\r
+        return JSON_FAILED;\r
+    }\r
+\r
+    pcPos = strchr(pcTmp, '\"');\r
+    if ((NULL == pcPos) || (pcPos < pcTmp))\r
+    {\r
+        Log("Invalid string %s.", pcData);\r
+        return JSON_FAILED;\r
+    }\r
+\r
+    *ppcEnd = pcPos + 1;\r
+    uiLen = (UINT32)(unsigned long)(pcPos - pcTmp);    \r
+    \r
+    pstJson->enDataType = JSON_TYPE_STRING;\r
+    pstJson->unData.pcStrVal = pcNewStart + (pcTmp - pcRawStart);\r
+    pstJson->unData.pcStrVal[uiLen] = '\0';\r
+    \r
+    return JSON_SUCCESS;\r
+}\r
+\r
+static int vtoy_json_parse_array\r
+(\r
+    char *pcNewStart,\r
+    char *pcRawStart,\r
+    VTOY_JSON *pstJson, \r
+    const char *pcData,\r
+    const char **ppcEnd\r
+)\r
+{\r
+    int Ret = JSON_SUCCESS;\r
+    VTOY_JSON *pstJsonChild = NULL;\r
+    VTOY_JSON *pstJsonItem = NULL;\r
+    const char *pcTmp = pcData + 1;\r
+\r
+    *ppcEnd = pcData;\r
+    pstJson->enDataType = JSON_TYPE_ARRAY;\r
+\r
+    if ('[' != *pcData)\r
+    {\r
+        return JSON_FAILED;\r
+    }\r
+\r
+    pcTmp = vtoy_json_skip(pcTmp);\r
+\r
+    if (']' == *pcTmp)\r
+    {\r
+        *ppcEnd = pcTmp + 1;\r
+        return JSON_SUCCESS;\r
+    }\r
+\r
+    JSON_NEW_ITEM(pstJson->pstChild, JSON_FAILED);\r
+\r
+    Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJson->pstChild, pcTmp, ppcEnd);\r
+    if (JSON_SUCCESS != Ret)\r
+    {\r
+        Log("Failed to parse array child.");\r
+        return JSON_FAILED;\r
+    }\r
+\r
+    pstJsonChild = pstJson->pstChild;\r
+    pcTmp = vtoy_json_skip(*ppcEnd);\r
+    while ((NULL != pcTmp) && (',' == *pcTmp))\r
+    {\r
+        JSON_NEW_ITEM(pstJsonItem, JSON_FAILED);\r
+        pstJsonChild->pstNext = pstJsonItem;\r
+        pstJsonItem->pstPrev = pstJsonChild;\r
+        pstJsonChild = pstJsonItem;\r
+\r
+        Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd);\r
+        if (JSON_SUCCESS != Ret)\r
+        {\r
+            Log("Failed to parse array child.");\r
+            return JSON_FAILED;\r
+        }\r
+        pcTmp = vtoy_json_skip(*ppcEnd);\r
+    }\r
+\r
+    if ((NULL != pcTmp) && (']' == *pcTmp))\r
+    {\r
+        *ppcEnd = pcTmp + 1;\r
+        return JSON_SUCCESS;\r
+    }\r
+    else\r
+    {\r
+        *ppcEnd = pcTmp;\r
+        return JSON_FAILED;\r
+    }\r
+}\r
+\r
+static int vtoy_json_parse_object\r
+(\r
+    char *pcNewStart,\r
+    char *pcRawStart,\r
+    VTOY_JSON *pstJson, \r
+    const char *pcData,\r
+    const char **ppcEnd\r
+)\r
+{\r
+    int Ret = JSON_SUCCESS;\r
+    VTOY_JSON *pstJsonChild = NULL;\r
+    VTOY_JSON *pstJsonItem = NULL;\r
+    const char *pcTmp = pcData + 1;\r
+\r
+    *ppcEnd = pcData;\r
+    pstJson->enDataType = JSON_TYPE_OBJECT;\r
+\r
+    if ('{' != *pcData)\r
+    {\r
+        return JSON_FAILED;\r
+    }\r
+\r
+    pcTmp = vtoy_json_skip(pcTmp);\r
+    if ('}' == *pcTmp)\r
+    {\r
+        *ppcEnd = pcTmp + 1;\r
+        return JSON_SUCCESS;\r
+    }\r
+\r
+    JSON_NEW_ITEM(pstJson->pstChild, JSON_FAILED);\r
+\r
+    Ret = vtoy_json_parse_string(pcNewStart, pcRawStart, pstJson->pstChild, pcTmp, ppcEnd);\r
+    if (JSON_SUCCESS != Ret)\r
+    {\r
+        Log("Failed to parse array child.");\r
+        return JSON_FAILED;\r
+    }\r
+\r
+    pstJsonChild = pstJson->pstChild;\r
+    pstJsonChild->pcName = pstJsonChild->unData.pcStrVal;\r
+    pstJsonChild->unData.pcStrVal = NULL;\r
+\r
+    pcTmp = vtoy_json_skip(*ppcEnd);\r
+    if ((NULL == pcTmp) || (':' != *pcTmp))\r
+    {\r
+        *ppcEnd = pcTmp;\r
+        return JSON_FAILED;\r
+    }\r
+\r
+    Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd);\r
+    if (JSON_SUCCESS != Ret)\r
+    {\r
+        Log("Failed to parse array child.");\r
+        return JSON_FAILED;\r
+    }\r
+\r
+    pcTmp = vtoy_json_skip(*ppcEnd);\r
+    while ((NULL != pcTmp) && (',' == *pcTmp))\r
+    {\r
+        JSON_NEW_ITEM(pstJsonItem, JSON_FAILED);\r
+        pstJsonChild->pstNext = pstJsonItem;\r
+        pstJsonItem->pstPrev = pstJsonChild;\r
+        pstJsonChild = pstJsonItem;\r
+\r
+        Ret = vtoy_json_parse_string(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd);\r
+        if (JSON_SUCCESS != Ret)\r
+        {\r
+            Log("Failed to parse array child.");\r
+            return JSON_FAILED;\r
+        }\r
+\r
+        pcTmp = vtoy_json_skip(*ppcEnd);\r
+        pstJsonChild->pcName = pstJsonChild->unData.pcStrVal;\r
+        pstJsonChild->unData.pcStrVal = NULL;\r
+        if ((NULL == pcTmp) || (':' != *pcTmp))\r
+        {\r
+            *ppcEnd = pcTmp;\r
+            return JSON_FAILED;\r
+        }\r
+\r
+        Ret = vtoy_json_parse_value(pcNewStart, pcRawStart, pstJsonChild, vtoy_json_skip(pcTmp + 1), ppcEnd);\r
+        if (JSON_SUCCESS != Ret)\r
+        {\r
+            Log("Failed to parse array child.");\r
+            return JSON_FAILED;\r
+        }\r
+\r
+        pcTmp = vtoy_json_skip(*ppcEnd);\r
+    }\r
+\r
+    if ((NULL != pcTmp) && ('}' == *pcTmp))\r
+    {\r
+        *ppcEnd = pcTmp + 1;\r
+        return JSON_SUCCESS;\r
+    }\r
+    else\r
+    {\r
+        *ppcEnd = pcTmp;\r
+        return JSON_FAILED;\r
+    }\r
+}\r
+\r
+int vtoy_json_parse_value\r
+(\r
+    char *pcNewStart,\r
+    char *pcRawStart,\r
+    VTOY_JSON *pstJson, \r
+    const char *pcData,\r
+    const char **ppcEnd\r
+)\r
+{\r
+    pcData = vtoy_json_skip(pcData);\r
+    \r
+    switch (*pcData)\r
+    {\r
+        case 'n':\r
+        {\r
+            if (0 == strncmp(pcData, "null", 4))\r
+            {\r
+                pstJson->enDataType = JSON_TYPE_NULL;\r
+                *ppcEnd = pcData + 4;\r
+                return JSON_SUCCESS;\r
+            }\r
+            break;\r
+        }\r
+        case 'f':\r
+        {\r
+            if (0 == strncmp(pcData, "false", 5))\r
+            {\r
+                pstJson->enDataType = JSON_TYPE_BOOL;\r
+                pstJson->unData.lValue = 0;\r
+                *ppcEnd = pcData + 5;\r
+                return JSON_SUCCESS;\r
+            }\r
+            break;\r
+        }\r
+        case 't':\r
+        {\r
+            if (0 == strncmp(pcData, "true", 4))\r
+            {\r
+                pstJson->enDataType = JSON_TYPE_BOOL;\r
+                pstJson->unData.lValue = 1;\r
+                *ppcEnd = pcData + 4;\r
+                return JSON_SUCCESS;\r
+            }\r
+            break;\r
+        }\r
+        case '\"':\r
+        {\r
+            return vtoy_json_parse_string(pcNewStart, pcRawStart, pstJson, pcData, ppcEnd);\r
+        }\r
+        case '[':\r
+        {\r
+            return vtoy_json_parse_array(pcNewStart, pcRawStart, pstJson, pcData, ppcEnd);\r
+        }\r
+        case '{':\r
+        {\r
+            return vtoy_json_parse_object(pcNewStart, pcRawStart, pstJson, pcData, ppcEnd);\r
+        }\r
+        case '-':\r
+        {\r
+            return vtoy_json_parse_number(pstJson, pcData, ppcEnd);\r
+        }\r
+        default :\r
+        {\r
+            if (*pcData >= '0' && *pcData <= '9')\r
+            {\r
+                return vtoy_json_parse_number(pstJson, pcData, ppcEnd);\r
+            }\r
+        }\r
+    }\r
+\r
+    *ppcEnd = pcData;\r
+    Log("Invalid json data %u.", (UINT8)(*pcData));\r
+    return JSON_FAILED;\r
+}\r
+\r
+VTOY_JSON * vtoy_json_create(void)\r
+{\r
+    VTOY_JSON *pstJson = NULL;\r
+\r
+    pstJson = (VTOY_JSON *)malloc(sizeof(VTOY_JSON));\r
+    if (NULL == pstJson)\r
+    {\r
+        return NULL;\r
+    }\r
+    memset(pstJson, 0, sizeof(VTOY_JSON));\r
+    return pstJson;\r
+}\r
+\r
+int vtoy_json_parse(VTOY_JSON *pstJson, const char *szJsonData)\r
+{\r
+    UINT32 uiMemSize = 0;\r
+    int Ret = JSON_SUCCESS;\r
+    char *pcNewBuf = NULL;\r
+    const char *pcEnd = NULL;\r
+\r
+    uiMemSize = strlen(szJsonData) + 1;\r
+    pcNewBuf = (char *)malloc(uiMemSize);\r
+    if (NULL == pcNewBuf)\r
+    {\r
+        Log("Failed to alloc new buf.");\r
+        return JSON_FAILED;\r
+    }\r
+    memcpy(pcNewBuf, szJsonData, uiMemSize);\r
+    pcNewBuf[uiMemSize - 1] = 0;\r
+\r
+    Ret = vtoy_json_parse_value(pcNewBuf, (char *)szJsonData, pstJson, szJsonData, &pcEnd);\r
+    if (JSON_SUCCESS != Ret)\r
+    {\r
+        Log("Failed to parse json data start=%p, end=%p", szJsonData, pcEnd);\r
+        return JSON_FAILED;\r
+    }\r
+\r
+    return JSON_SUCCESS;\r
+}\r
+\r
+int vtoy_json_scan_parse\r
+(\r
+    const VTOY_JSON    *pstJson,\r
+    UINT32       uiParseNum,\r
+    JSON_PARSE         *pstJsonParse\r
+)\r
+{   \r
+    UINT32 i = 0;\r
+    const VTOY_JSON *pstJsonCur = NULL;\r
+    JSON_PARSE *pstCurParse = NULL;\r
+\r
+    for (pstJsonCur = pstJson; NULL != pstJsonCur; pstJsonCur = pstJsonCur->pstNext)\r
+    {\r
+        if ((JSON_TYPE_OBJECT == pstJsonCur->enDataType) ||\r
+            (JSON_TYPE_ARRAY == pstJsonCur->enDataType))\r
+        {\r
+            continue;\r
+        }\r
+\r
+        for (i = 0, pstCurParse = NULL; i < uiParseNum; i++)\r
+        {\r
+            if (0 == strcmp(pstJsonParse[i].pcKey, pstJsonCur->pcName))\r
+            {   \r
+                pstCurParse = pstJsonParse + i;\r
+                break;\r
+            }\r
+        }\r
+\r
+        if (NULL == pstCurParse)\r
+        {\r
+            continue;\r
+        }\r
+    \r
+        switch (pstJsonCur->enDataType)\r
+        {\r
+            case JSON_TYPE_NUMBER:\r
+            {\r
+                if (sizeof(UINT32) == pstCurParse->uiBufSize)\r
+                {\r
+                    *(UINT32 *)(pstCurParse->pDataBuf) = (UINT32)pstJsonCur->unData.lValue;\r
+                }\r
+                else if (sizeof(UINT16) == pstCurParse->uiBufSize)\r
+                {\r
+                    *(UINT16 *)(pstCurParse->pDataBuf) = (UINT16)pstJsonCur->unData.lValue;\r
+                }\r
+                else if (sizeof(UINT8) == pstCurParse->uiBufSize)\r
+                {\r
+                    *(UINT8 *)(pstCurParse->pDataBuf) = (UINT8)pstJsonCur->unData.lValue;\r
+                }\r
+                else if ((pstCurParse->uiBufSize > sizeof(UINT64)))\r
+                {\r
+                    sprintf_s((char *)pstCurParse->pDataBuf, pstCurParse->uiBufSize, "%llu",\r
+                        (unsigned long long)(pstJsonCur->unData.lValue));\r
+                }\r
+                else\r
+                {\r
+                    Log("Invalid number data buf size %u.", pstCurParse->uiBufSize);\r
+                }\r
+                break;\r
+            }\r
+            case JSON_TYPE_STRING:\r
+            {\r
+                strcpy_s((char *)pstCurParse->pDataBuf, pstCurParse->uiBufSize, pstJsonCur->unData.pcStrVal);\r
+                break;\r
+            }\r
+            case JSON_TYPE_BOOL:\r
+            {\r
+                *(UINT8 *)(pstCurParse->pDataBuf) = (pstJsonCur->unData.lValue) > 0 ? 1 : 0;\r
+                break;\r
+            }\r
+            default :\r
+            {\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+    return JSON_SUCCESS;\r
+}\r
+\r
+int vtoy_json_scan_array\r
+(\r
+     VTOY_JSON *pstJson, \r
+     const char *szKey, \r
+     VTOY_JSON **ppstArrayItem\r
+)\r
+{\r
+    VTOY_JSON *pstJsonItem = NULL;\r
+    \r
+    pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_ARRAY, szKey);\r
+    if (NULL == pstJsonItem)\r
+    {\r
+        Log("Key %s is not found in json data.", szKey);\r
+        return JSON_NOT_FOUND;\r
+    }\r
+\r
+    *ppstArrayItem = pstJsonItem;\r
+\r
+    return JSON_SUCCESS;\r
+}\r
+\r
+int vtoy_json_scan_array_ex\r
+(\r
+     VTOY_JSON *pstJson, \r
+     const char *szKey, \r
+     VTOY_JSON **ppstArrayItem\r
+)\r
+{\r
+    VTOY_JSON *pstJsonItem = NULL;\r
+    \r
+    pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_ARRAY, szKey);\r
+    if (NULL == pstJsonItem)\r
+    {\r
+        Log("Key %s is not found in json data.", szKey);\r
+        return JSON_NOT_FOUND;\r
+    }\r
+    \r
+    *ppstArrayItem = pstJsonItem->pstChild;\r
+\r
+    return JSON_SUCCESS;\r
+}\r
+\r
+int vtoy_json_scan_object\r
+(\r
+     VTOY_JSON *pstJson, \r
+     const char *szKey, \r
+     VTOY_JSON **ppstObjectItem\r
+)\r
+{\r
+    VTOY_JSON *pstJsonItem = NULL;\r
+\r
+    pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_OBJECT, szKey);\r
+    if (NULL == pstJsonItem)\r
+    {\r
+        Log("Key %s is not found in json data.", szKey);\r
+        return JSON_NOT_FOUND;\r
+    }\r
+\r
+    *ppstObjectItem = pstJsonItem;\r
+\r
+    return JSON_SUCCESS;\r
+}\r
+\r
+int vtoy_json_get_int\r
+(\r
+    VTOY_JSON *pstJson, \r
+    const char *szKey, \r
+    int *piValue\r
+)\r
+{\r
+    VTOY_JSON *pstJsonItem = NULL;\r
+    \r
+    pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_NUMBER, szKey);\r
+    if (NULL == pstJsonItem)\r
+    {\r
+        Log("Key %s is not found in json data.", szKey);\r
+        return JSON_NOT_FOUND;\r
+    }\r
+\r
+    *piValue = (int)pstJsonItem->unData.lValue;\r
+\r
+    return JSON_SUCCESS;\r
+}\r
+\r
+int vtoy_json_get_uint\r
+(\r
+    VTOY_JSON *pstJson, \r
+    const char *szKey, \r
+    UINT32 *puiValue\r
+)\r
+{\r
+    VTOY_JSON *pstJsonItem = NULL;\r
+    \r
+    pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_NUMBER, szKey);\r
+    if (NULL == pstJsonItem)\r
+    {\r
+        Log("Key %s is not found in json data.", szKey);\r
+        return JSON_NOT_FOUND;\r
+    }\r
+\r
+    *puiValue = (UINT32)pstJsonItem->unData.lValue;\r
+\r
+    return JSON_SUCCESS;\r
+}\r
+\r
+int vtoy_json_get_uint64\r
+(\r
+    VTOY_JSON *pstJson, \r
+    const char *szKey, \r
+    UINT64 *pui64Value\r
+)\r
+{\r
+    VTOY_JSON *pstJsonItem = NULL;\r
+    \r
+    pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_NUMBER, szKey);\r
+    if (NULL == pstJsonItem)\r
+    {\r
+        Log("Key %s is not found in json data.", szKey);\r
+        return JSON_NOT_FOUND;\r
+    }\r
+\r
+    *pui64Value = (UINT64)pstJsonItem->unData.lValue;\r
+\r
+    return JSON_SUCCESS;\r
+}\r
+\r
+int vtoy_json_get_bool\r
+(\r
+    VTOY_JSON *pstJson,\r
+    const char *szKey, \r
+    UINT8 *pbValue\r
+)\r
+{\r
+    VTOY_JSON *pstJsonItem = NULL;\r
+    \r
+    pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_BOOL, szKey);\r
+    if (NULL == pstJsonItem)\r
+    {\r
+        Log("Key %s is not found in json data.", szKey);\r
+        return JSON_NOT_FOUND;\r
+    }\r
+\r
+    *pbValue = pstJsonItem->unData.lValue > 0 ? 1 : 0;\r
+\r
+    return JSON_SUCCESS;\r
+}\r
+\r
+int vtoy_json_get_string\r
+(\r
+     VTOY_JSON *pstJson, \r
+     const char *szKey, \r
+     UINT32  uiBufLen,\r
+     char *pcBuf\r
+)\r
+{\r
+    VTOY_JSON *pstJsonItem = NULL;\r
+    \r
+    pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_STRING, szKey);\r
+    if (NULL == pstJsonItem)\r
+    {\r
+        Log("Key %s is not found in json data.", szKey);\r
+        return JSON_NOT_FOUND;\r
+    }\r
+\r
+    strcpy_s(pcBuf, uiBufLen, pstJsonItem->unData.pcStrVal);\r
+\r
+    return JSON_SUCCESS;\r
+}\r
+\r
+const char * vtoy_json_get_string_ex(VTOY_JSON *pstJson,  const char *szKey)\r
+{\r
+    VTOY_JSON *pstJsonItem = NULL;\r
+\r
+    if ((NULL == pstJson) || (NULL == szKey))\r
+    {\r
+        return NULL;\r
+    }\r
+\r
+    pstJsonItem = vtoy_json_find_item(pstJson, JSON_TYPE_STRING, szKey);\r
+    if (NULL == pstJsonItem)\r
+    {\r
+        Log("Key %s is not found in json data.", szKey);\r
+        return NULL;\r
+    }\r
+\r
+    return pstJsonItem->unData.pcStrVal;\r
+}\r
+\r
+int vtoy_json_destroy(VTOY_JSON *pstJson)\r
+{\r
+    if (NULL == pstJson)\r
+    {   \r
+        return JSON_SUCCESS;\r
+    }\r
+\r
+    if (NULL != pstJson->pstChild)\r
+    {\r
+        vtoy_json_free(pstJson->pstChild);\r
+    }\r
+\r
+    if (NULL != pstJson->pstNext)\r
+    {\r
+        vtoy_json_free(pstJson->pstNext);\r
+    }\r
+\r
+    free(pstJson);\r
+    \r
+    return JSON_SUCCESS;\r
+}\r
+\r
+\r
+#ifdef FOR_VTOY_JSON_CHECK\r
+\r
+int main(int argc, char**argv)\r
+{\r
+    int ret = 1;\r
+    int FileSize;\r
+    FILE *fp;\r
+    void *Data = NULL;\r
+    VTOY_JSON *json = NULL;\r
+\r
+    fp = fopen(argv[1], "rb");\r
+    if (!fp)\r
+    {\r
+        Log("Failed to open %s\n", argv[1]);\r
+        goto out;\r
+    }\r
+\r
+    fseek(fp, 0, SEEK_END);\r
+    FileSize = (int)ftell(fp);\r
+    fseek(fp, 0, SEEK_SET);\r
+\r
+    Data = malloc(FileSize + 4);\r
+    if (!Data)\r
+    {\r
+        Log("Failed to malloc %d\n", FileSize + 4);\r
+        goto out;\r
+    }\r
+    *((char *)Data + FileSize) = 0;\r
+\r
+    fread(Data, 1, FileSize, fp);\r
+\r
+    json = vtoy_json_create();\r
+    if (!json)\r
+    {\r
+        Log("Failed vtoy_json_create\n");\r
+        goto out;\r
+    }\r
+\r
+    if (vtoy_json_parse(json, (char *)Data) != JSON_SUCCESS)\r
+    {\r
+        goto out;\r
+    }\r
+\r
+    ret = 0;\r
+\r
+out:\r
+    if (fp) fclose(fp);\r
+    if (Data) free(Data);\r
+    if (json) vtoy_json_destroy(json);\r
+\r
+    printf("\n");\r
+    return ret;\r
+}\r
+\r
+#endif\r
diff --git a/Ventoy2Disk/Ventoy2Disk/VentoyJson.h b/Ventoy2Disk/Ventoy2Disk/VentoyJson.h
new file mode 100644 (file)
index 0000000..6c2cf3b
--- /dev/null
@@ -0,0 +1,164 @@
+/******************************************************************************\r
+ * VentoyJson.h\r
+ *\r
+ * Copyright (c) 2021, longpanda <admin@ventoy.net>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License as\r
+ * published by the Free Software Foundation; either version 3 of the\r
+ * License, or (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful, but\r
+ * WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+#ifndef __VENTOY_JSON_H__\r
+#define __VENTOY_JSON_H__\r
+\r
+#ifdef FOR_VTOY_JSON_CHECK\r
+typedef unsigned char      UINT8;\r
+typedef unsigned short     UINT16;\r
+typedef unsigned int       UINT32;\r
+typedef unsigned long long UINT64;\r
+\r
+#define Log printf\r
+#define strcpy_s(a, b, c) strncpy(a, c, b)\r
+#define sprintf_s snprintf\r
+#endif\r
+\r
+#define JSON_SUCCESS    0\r
+#define JSON_FAILED     1\r
+#define JSON_NOT_FOUND  2\r
+\r
+typedef enum _JSON_TYPE\r
+{\r
+    JSON_TYPE_NUMBER = 0,\r
+    JSON_TYPE_STRING,\r
+    JSON_TYPE_BOOL,\r
+    JSON_TYPE_ARRAY,\r
+    JSON_TYPE_OBJECT,\r
+    JSON_TYPE_NULL,\r
+    JSON_TYPE_BUTT\r
+}JSON_TYPE;\r
+\r
+\r
+typedef struct _VTOY_JSON\r
+{\r
+    struct _VTOY_JSON *pstPrev;\r
+    struct _VTOY_JSON *pstNext;\r
+    struct _VTOY_JSON *pstChild;\r
+\r
+    JSON_TYPE enDataType;\r
+    union \r
+    {\r
+        char  *pcStrVal;\r
+        int   iNumVal;\r
+        UINT64 lValue;\r
+    }unData;\r
+\r
+    char *pcName;\r
+}VTOY_JSON;\r
+\r
+typedef struct _JSON_PARSE\r
+{\r
+    char *pcKey;\r
+    void *pDataBuf;\r
+    UINT32  uiBufSize;\r
+}JSON_PARSE;\r
+\r
+#define JSON_NEW_ITEM(pstJson, ret) \\r
+{ \\r
+    (pstJson) = (VTOY_JSON *)malloc(sizeof(VTOY_JSON)); \\r
+    if (NULL == (pstJson)) \\r
+    { \\r
+        Log("Failed to alloc memory for json.\n"); \\r
+        return (ret); \\r
+    } \\r
+    memset((pstJson), 0, sizeof(VTOY_JSON));\\r
+}\r
+\r
+VTOY_JSON *vtoy_json_find_item\r
+(\r
+    VTOY_JSON *pstJson,\r
+    JSON_TYPE  enDataType,\r
+    const char *szKey\r
+);\r
+int vtoy_json_parse_value\r
+(\r
+    char *pcNewStart,\r
+    char *pcRawStart,\r
+    VTOY_JSON *pstJson, \r
+    const char *pcData,\r
+    const char **ppcEnd\r
+);\r
+VTOY_JSON * vtoy_json_create(void);\r
+int vtoy_json_parse(VTOY_JSON *pstJson, const char *szJsonData);\r
+\r
+int vtoy_json_scan_parse\r
+(\r
+    const VTOY_JSON    *pstJson,\r
+    UINT32              uiParseNum,\r
+    JSON_PARSE         *pstJsonParse\r
+);\r
+\r
+int vtoy_json_scan_array\r
+(\r
+     VTOY_JSON *pstJson, \r
+     const char *szKey, \r
+     VTOY_JSON **ppstArrayItem\r
+);\r
+\r
+int vtoy_json_scan_array_ex\r
+(\r
+     VTOY_JSON *pstJson, \r
+     const char *szKey, \r
+     VTOY_JSON **ppstArrayItem\r
+);\r
+int vtoy_json_scan_object\r
+(\r
+     VTOY_JSON *pstJson, \r
+     const char *szKey, \r
+    VTOY_JSON **ppstObjectItem\r
+);\r
+int vtoy_json_get_int\r
+(\r
+    VTOY_JSON *pstJson, \r
+    const char *szKey, \r
+    int *piValue\r
+);\r
+int vtoy_json_get_uint\r
+(\r
+    VTOY_JSON *pstJson, \r
+    const char *szKey, \r
+    UINT32     *puiValue\r
+);\r
+int vtoy_json_get_uint64\r
+(\r
+    VTOY_JSON *pstJson, \r
+    const char *szKey, \r
+    UINT64 *pui64Value\r
+);\r
+int vtoy_json_get_bool\r
+(\r
+    VTOY_JSON *pstJson,\r
+    const char *szKey, \r
+    UINT8 *pbValue\r
+);\r
+int vtoy_json_get_string\r
+(\r
+     VTOY_JSON *pstJson, \r
+     const char *szKey, \r
+     UINT32  uiBufLen,\r
+     char *pcBuf\r
+);\r
+const char * vtoy_json_get_string_ex(VTOY_JSON *pstJson,  const char *szKey);\r
+int vtoy_json_destroy(VTOY_JSON *pstJson);\r
+\r
+#endif /* __VENTOY_JSON_H__ */\r
+\r
index bec810e8cc5bcea12f86cd4574367a229fe9a688..20f6f66c0473aa1f9286e86b5789348057646fcb 100644 (file)
Binary files a/Ventoy2Disk/Ventoy2Disk/WinDialog.c and b/Ventoy2Disk/Ventoy2Disk/WinDialog.c differ
index 34c1ee7e5e1b613357c2fa64a41417b7b937dadb..72b78151262fe3ab6b21fea17371f380edc84a22 100644 (file)
@@ -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;
     }
index 6cda86be93f1ce56ab9f7b42c1e1f80f1757bf88..97f553f4eae818f708f339b79ee919227a800089 100644 (file)
Binary files a/VtoyTool/vtoytool/00/vtoytool_32 and b/VtoyTool/vtoytool/00/vtoytool_32 differ
index 1acd940fbd504b3d96245cad850ed9324a800993..53a951e60fcac7ac6e8c1d4fca265c746cfeff26 100644 (file)
Binary files a/VtoyTool/vtoytool/00/vtoytool_64 and b/VtoyTool/vtoytool/00/vtoytool_64 differ
index 9a429bc5ffe74bcac6b965e0f08577041e62a41d..11833dce190e2f2dcea9a284f5a2d492aafe364b 100644 (file)
Binary files a/VtoyTool/vtoytool/00/vtoytool_aa64 and b/VtoyTool/vtoytool/00/vtoytool_aa64 differ
index 3fd69195dfbd4e489fa295081ca061da9f6c6ed5..249e1a0c33b90b0e71760feca61ff2ebbe6ca5e0 100644 (file)
Binary files a/VtoyTool/vtoytool/00/vtoytool_m64e and b/VtoyTool/vtoytool/00/vtoytool_m64e differ