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.
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;
#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, ...)
{
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;
return g_efi_os;
}
-static int ventoy_get_fs_type(const char *fs)
-{
- if (NULL == fs)
- {
- return ventoy_fs_max;
- }
- else if (grub_strncmp(fs, "exfat", 5) == 0)
- {
- return ventoy_fs_exfat;
- }
- else if (grub_strncmp(fs, "ntfs", 4) == 0)
- {
- return ventoy_fs_ntfs;
- }
- else if (grub_strncmp(fs, "ext", 3) == 0)
- {
- return ventoy_fs_ext;
- }
- else if (grub_strncmp(fs, "xfs", 3) == 0)
- {
- return ventoy_fs_xfs;
- }
- else if (grub_strncmp(fs, "udf", 3) == 0)
- {
- return ventoy_fs_udf;
- }
- else if (grub_strncmp(fs, "fat", 3) == 0)
- {
- return ventoy_fs_fat;
- }
-
- return ventoy_fs_max;
-}
-
-static int ventoy_string_check(const char *str, grub_char_check_func check)
-{
- if (!str)
- {
- return 0;
- }
-
- for ( ; *str; str++)
- {
- if (!check(*str))
- {
- return 0;
- }
- }
-
- return 1;
-}
-
-
-static grub_ssize_t ventoy_fs_read(grub_file_t file, char *buf, grub_size_t len)
-{
- grub_memcpy(buf, (char *)file->data + file->offset, len);
- return len;
-}
-
-static int ventoy_control_get_flag(const char *key)
-{
- const char *val = ventoy_get_env(key);
-
- if (val && val[0] == '1' && val[1] == 0)
- {
- return 1;
- }
- return 0;
-}
-
-static grub_err_t ventoy_fs_close(grub_file_t file)
-{
- grub_file_close(g_old_file);
- grub_free(file->data);
-
- file->device = 0;
- file->name = 0;
-
- return 0;
-}
-
-static int ventoy_video_hook(const struct grub_video_mode_info *info, void *hook_arg)
-{
- int i;
-
- (void)hook_arg;
-
- if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT)
- {
- return 0;
- }
-
- for (i = 0; i < g_video_mode_num; i++)
- {
- if (g_video_mode_list[i].width == info->width &&
- g_video_mode_list[i].height == info->height &&
- g_video_mode_list[i].bpp == info->bpp)
- {
- return 0;
- }
- }
-
- g_video_mode_list[g_video_mode_num].width = info->width;
- g_video_mode_list[g_video_mode_num].height = info->height;
- g_video_mode_list[g_video_mode_num].bpp = info->bpp;
- g_video_mode_num++;
-
- if (g_video_mode_num == g_video_mode_max)
- {
- g_video_mode_max *= 2;
- g_video_mode_list = grub_realloc(g_video_mode_list, g_video_mode_max * sizeof(ventoy_video_mode));
- }
-
- return 0;
-}
-
-static int ventoy_video_mode_cmp(ventoy_video_mode *v1, ventoy_video_mode *v2)
-{
- if (v1->bpp == v2->bpp)
- {
- if (v1->width == v2->width)
- {
- if (v1->height == v2->height)
- {
- return 0;
- }
- else
- {
- return (v1->height < v2->height) ? -1 : 1;
- }
- }
- else
- {
- return (v1->width < v2->width) ? -1 : 1;
- }
- }
- else
- {
- return (v1->bpp < v2->bpp) ? -1 : 1;
- }
-}
-
-static int ventoy_enum_video_mode(void)
-{
- int i, j;
- grub_video_adapter_t adapter;
- grub_video_driver_id_t id;
- ventoy_video_mode mode;
-
- g_video_mode_num = 0;
- g_video_mode_max = 1024;
- g_video_mode_list = grub_malloc(sizeof(ventoy_video_mode) * g_video_mode_max);
- if (!g_video_mode_list)
- {
- return 0;
- }
-
- #ifdef GRUB_MACHINE_PCBIOS
- grub_dl_load ("vbe");
- #endif
-
- id = grub_video_get_driver_id ();
-
- FOR_VIDEO_ADAPTERS (adapter)
- {
- if (!adapter->iterate ||
- (adapter->id != id && (id != GRUB_VIDEO_DRIVER_NONE ||
- adapter->init() != GRUB_ERR_NONE)))
- {
- continue;
- }
-
- adapter->iterate(ventoy_video_hook, NULL);
-
- if (adapter->id != id)
- {
- adapter->fini();
- }
- }
-
- /* sort video mode */
- for (i = 0; i < g_video_mode_num; i++)
- for (j = i + 1; j < g_video_mode_num; j++)
- {
- if (ventoy_video_mode_cmp(g_video_mode_list + i, g_video_mode_list + j) < 0)
- {
- grub_memcpy(&mode, g_video_mode_list + i, sizeof(ventoy_video_mode));
- grub_memcpy(g_video_mode_list + i, g_video_mode_list + j, sizeof(ventoy_video_mode));
- grub_memcpy(g_video_mode_list + j, &mode, sizeof(ventoy_video_mode));
- }
- }
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_file_t ventoy_wrapper_open(grub_file_t rawFile, enum grub_file_type type)
-{
- int len;
- grub_file_t file;
- static struct grub_fs vtoy_fs =
- {
- .name = "vtoy",
- .fs_dir = 0,
- .fs_open = 0,
- .fs_read = ventoy_fs_read,
- .fs_close = ventoy_fs_close,
- .fs_label = 0,
- .next = 0
- };
-
- if (type != 52)
- {
- return rawFile;
- }
-
- file = (grub_file_t)grub_zalloc(sizeof (*file));
- if (!file)
- {
- return 0;
- }
-
- file->data = grub_malloc(rawFile->size + 4096);
- if (!file->data)
- {
- return 0;
- }
-
- grub_file_read(rawFile, file->data, rawFile->size);
- len = ventoy_fill_data(4096, (char *)file->data + rawFile->size);
-
- g_old_file = rawFile;
-
- file->size = rawFile->size + len;
- file->device = rawFile->device;
- file->fs = &vtoy_fs;
- file->not_easily_seekable = 1;
-
- return file;
-}
-
-static int ventoy_check_decimal_var(const char *name, long *value)
+static int ventoy_arch_mode_init(void)
{
- const char *value_str = NULL;
-
- value_str = grub_env_get(name);
- if (NULL == value_str)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Variable %s not found", name);
- }
-
- if (!ventoy_is_decimal(value_str))
+ #ifdef GRUB_MACHINE_EFI
+ if (grub_strcmp(GRUB_TARGET_CPU, "i386") == 0)
{
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Variable %s value '%s' is not an integer", name, value_str);
+ g_ventoy_plat_data = VTOY_PLAT_I386_UEFI;
+ grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "ia32");
}
-
- *value = grub_strtol(value_str, NULL, 10);
-
- return GRUB_ERR_NONE;
-}
-
-static grub_err_t ventoy_cmd_debug(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- if (argc != 1)
+ else if (grub_strcmp(GRUB_TARGET_CPU, "arm64") == 0)
{
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {on|off}", cmd_raw_name);
+ g_ventoy_plat_data = VTOY_PLAT_ARM64_UEFI;
+ grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "aa64");
}
-
- if (0 == grub_strcmp(args[0], "on"))
+ else if (grub_strcmp(GRUB_TARGET_CPU, "mips64el") == 0)
{
- g_ventoy_debug = 1;
- grub_env_set("vtdebug_flag", "debug");
+ g_ventoy_plat_data = VTOY_PLAT_MIPS_UEFI;
+ grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "mips");
}
else
{
- g_ventoy_debug = 0;
- grub_env_set("vtdebug_flag", "");
- }
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_err_t ventoy_cmd_break(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- (void)ctxt;
-
- if (argc < 1 || (args[0][0] != '0' && args[0][0] != '1'))
- {
- grub_printf("Usage: %s {level} [debug]\r\n", cmd_raw_name);
- grub_printf(" level:\r\n");
- grub_printf(" 01/11: busybox / (+cat log)\r\n");
- grub_printf(" 02/12: initrd / (+cat log)\r\n");
- grub_printf(" 03/13: hook / (+cat log)\r\n");
- grub_printf("\r\n");
- grub_printf(" debug:\r\n");
- grub_printf(" 0: debug is off\r\n");
- grub_printf(" 1: debug is on\r\n");
- grub_printf("\r\n");
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
- }
-
- g_ventoy_break_level = (grub_uint8_t)grub_strtoul(args[0], NULL, 16);
-
- if (argc > 1 && grub_strtoul(args[1], NULL, 10) > 0)
- {
- g_ventoy_debug_level = 1;
- }
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_err_t ventoy_cmd_strstr(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- (void)ctxt;
-
- if (argc != 2)
- {
- return 1;
- }
-
- return (grub_strstr(args[0], args[1])) ? 0 : 1;
-}
-
-static grub_err_t ventoy_cmd_strbegin(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- char *c0, *c1;
-
- (void)ctxt;
-
- if (argc != 2)
- {
- return 1;
- }
-
- c0 = args[0];
- c1 = args[1];
-
- while (*c0 && *c1)
- {
- if (*c0 != *c1)
- {
- return 1;
- }
- c0++;
- c1++;
- }
-
- if (*c1)
- {
- return 1;
+ g_ventoy_plat_data = VTOY_PLAT_X86_64_UEFI;
+ grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "uefi");
}
+#else
+ g_ventoy_plat_data = VTOY_PLAT_X86_LEGACY;
+ grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "legacy");
+#endif
return 0;
}
-static grub_err_t ventoy_cmd_incr(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- long value_long = 0;
- char buf[32];
-
- if ((argc != 2) || (!ventoy_is_decimal(args[1])))
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Variable} {Int}", cmd_raw_name);
- }
-
- if (GRUB_ERR_NONE != ventoy_check_decimal_var(args[0], &value_long))
- {
- return grub_errno;
- }
-
- value_long += grub_strtol(args[1], NULL, 10);
-
- grub_snprintf(buf, sizeof(buf), "%ld", value_long);
- grub_env_set(args[0], buf);
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_err_t ventoy_cmd_mod(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- ulonglong value1 = 0;
- ulonglong value2 = 0;
- char buf[32];
-
- if (argc != 3)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int} {Int} {Variable}", cmd_raw_name);
- }
-
- value1 = grub_strtoull(args[0], NULL, 10);
- value2 = grub_strtoull(args[1], NULL, 10);
-
- grub_snprintf(buf, sizeof(buf), "%llu", (value1 & (value2 - 1)));
- grub_env_set(args[2], buf);
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_err_t ventoy_cmd_file_size(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int rc = 1;
- char buf[32];
- grub_file_t file;
-
- (void)ctxt;
- (void)argc;
- (void)args;
-
- if (argc != 2)
- {
- return rc;
- }
-
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
- if (file == NULL)
- {
- debug("failed to open file <%s> for udf check\n", args[0]);
- return 1;
- }
-
- grub_snprintf(buf, sizeof(buf), "%llu", (unsigned long long)file->size);
-
- grub_env_set(args[1], buf);
-
- grub_file_close(file);
- rc = 0;
-
- return rc;
-}
-
-static grub_err_t ventoy_cmd_load_wimboot(grub_extcmd_context_t ctxt, int argc, char **args)
+GRUB_MOD_INIT(ventoy)
{
- grub_file_t file;
-
- (void)ctxt;
- (void)argc;
- (void)args;
-
- g_wimboot_enable = 0;
- grub_check_free(g_wimiso_path);
- grub_check_free(g_wimiso_chunk_list.chunk);
-
- file = grub_file_open(args[0], VENTOY_FILE_TYPE);
- if (!file)
- {
- return 0;
- }
-
- grub_memset(&g_wimiso_chunk_list, 0, sizeof(g_wimiso_chunk_list));
- g_wimiso_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM);
- if (NULL == g_wimiso_chunk_list.chunk)
- {
- return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n");
- }
-
- g_wimiso_chunk_list.max_chunk = DEFAULT_CHUNK_NUM;
- g_wimiso_chunk_list.cur_chunk = 0;
-
- ventoy_get_block_list(file, &g_wimiso_chunk_list, file->device->disk->partition->start);
-
- g_wimboot_enable = 1;
- g_wimiso_path = grub_strdup(args[0]);
-
- grub_file_close(file);
-
- return 0;
+ ventoy_env_init();
+ ventoy_arch_mode_init();
+ ventoy_register_all_cmd();
}
-static int ventoy_load_efiboot_template(char **buf, int *datalen, int *direntoff)
+GRUB_MOD_FINI(ventoy)
{
- int len;
- grub_file_t file;
- char exec[128];
- char *data = NULL;
- grub_uint32_t offset;
-
- file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s/ventoy/ventoy_efiboot.img.xz", ventoy_get_env("vtoy_efi_part"));
- if (file == NULL)
- {
- debug("failed to open file <%s>\n", "ventoy_efiboot.img.xz");
- return 1;
- }
-
- len = (int)file->size;
-
- data = (char *)grub_malloc(file->size);
- if (!data)
- {
- return 1;
- }
-
- grub_file_read(file, data, file->size);
- grub_file_close(file);
-
- grub_snprintf(exec, sizeof(exec), "loopback efiboot mem:0x%llx:size:%d", (ulonglong)(ulong)data, len);
- grub_script_execute_sourcecode(exec);
-
- file = grub_file_open("(efiboot)/EFI/BOOT/BOOTX64.EFI", GRUB_FILE_TYPE_LINUX_INITRD);
- offset = (grub_uint32_t)grub_iso9660_get_last_file_dirent_pos(file);
- grub_file_close(file);
-
- grub_script_execute_sourcecode("loopback -d efiboot");
-
- *buf = data;
- *datalen = len;
- *direntoff = offset + 2;
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_concat_efi_iso(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int len = 0;
- int totlen = 0;
- int offset = 0;
- grub_file_t file;
- char name[32];
- char value[32];
- char *buf = NULL;
- char *data = NULL;
- ventoy_iso9660_override *dirent;
-
- (void)ctxt;
-
- if (argc != 2)
- {
- return 1;
- }
-
- totlen = sizeof(ventoy_chain_head);
-
- if (ventoy_load_efiboot_template(&buf, &len, &offset))
- {
- debug("failed to load efiboot template %d\n", len);
- return 1;
- }
-
- totlen += len;
-
- debug("efiboot template len:%d offset:%d\n", len, offset);
-
- file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s", args[0]);
- if (file == NULL)
- {
- debug("failed to open file <%s>\n", args[0]);
- return 1;
- }
-
- totlen += ventoy_align_2k(file->size);
-
- dirent = (ventoy_iso9660_override *)(buf + offset);
- dirent->first_sector = len / 2048;
- dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector);
- dirent->size = (grub_uint32_t)file->size;
- dirent->size_be = grub_swap_bytes32(dirent->size);
-
- debug("rawiso len:%d efilen:%d total:%d\n", len, (int)file->size, totlen);
-
-#ifdef GRUB_MACHINE_EFI
- data = (char *)grub_efi_allocate_iso_buf(totlen);
-#else
- data = (char *)grub_malloc(totlen);
-#endif
-
- ventoy_fill_os_param(file, (ventoy_os_param *)data);
-
- grub_memcpy(data + sizeof(ventoy_chain_head), buf, len);
- grub_check_free(buf);
-
- grub_file_read(file, data + sizeof(ventoy_chain_head) + len, file->size);
- grub_file_close(file);
-
- grub_snprintf(name, sizeof(name), "%s_addr", args[1]);
- grub_snprintf(value, sizeof(value), "0x%llx", (ulonglong)(ulong)data);
- grub_env_set(name, value);
-
- grub_snprintf(name, sizeof(name), "%s_size", args[1]);
- grub_snprintf(value, sizeof(value), "%d", (int)(totlen));
- grub_env_set(name, value);
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_load_file_to_mem(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int rc = 1;
- char name[32];
- char value[32];
- char *buf = NULL;
- grub_file_t file;
-
- (void)ctxt;
- (void)argc;
- (void)args;
-
- if (argc != 2)
- {
- return rc;
- }
-
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
- if (file == NULL)
- {
- debug("failed to open file <%s>\n", args[0]);
- return 1;
- }
-
-#ifdef GRUB_MACHINE_EFI
- buf = (char *)grub_efi_allocate_iso_buf(file->size);
-#else
- buf = (char *)grub_malloc(file->size);
-#endif
-
- grub_file_read(file, buf, file->size);
-
- grub_snprintf(name, sizeof(name), "%s_addr", args[1]);
- grub_snprintf(value, sizeof(value), "0x%llx", (unsigned long long)(unsigned long)buf);
- grub_env_set(name, value);
-
- grub_snprintf(name, sizeof(name), "%s_size", args[1]);
- grub_snprintf(value, sizeof(value), "%llu", (unsigned long long)file->size);
- grub_env_set(name, value);
-
- grub_file_close(file);
- rc = 0;
-
- return rc;
-}
-
-static grub_err_t ventoy_cmd_load_img_memdisk(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int rc = 1;
- int headlen;
- char name[32];
- char value[32];
- char *buf = NULL;
- grub_file_t file;
-
- (void)ctxt;
- (void)argc;
- (void)args;
-
- if (argc != 2)
- {
- return rc;
- }
-
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
- if (file == NULL)
- {
- debug("failed to open file <%s> for udf check\n", args[0]);
- return 1;
- }
-
- headlen = sizeof(ventoy_chain_head);
-
-#ifdef GRUB_MACHINE_EFI
- buf = (char *)grub_efi_allocate_iso_buf(headlen + file->size);
-#else
- buf = (char *)grub_malloc(headlen + file->size);
-#endif
-
- ventoy_fill_os_param(file, (ventoy_os_param *)buf);
-
- grub_file_read(file, buf + headlen, file->size);
-
- grub_snprintf(name, sizeof(name), "%s_addr", args[1]);
- grub_snprintf(value, sizeof(value), "0x%llx", (unsigned long long)(unsigned long)buf);
- grub_env_set(name, value);
-
- grub_snprintf(name, sizeof(name), "%s_size", args[1]);
- grub_snprintf(value, sizeof(value), "%llu", (unsigned long long)file->size);
- grub_env_set(name, value);
-
- grub_file_close(file);
- rc = 0;
-
- return rc;
-}
-
-static grub_err_t ventoy_cmd_iso9660_nojoliet(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- (void)ctxt;
-
- if (argc != 1)
- {
- return 1;
- }
-
- if (args[0][0] == '1')
- {
- grub_iso9660_set_nojoliet(1);
- }
- else
- {
- grub_iso9660_set_nojoliet(0);
- }
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_is_udf(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int i;
- int rc = 1;
- grub_file_t file;
- grub_uint8_t buf[32];
-
- (void)ctxt;
- (void)argc;
- (void)args;
-
- if (argc != 1)
- {
- return rc;
- }
-
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
- if (file == NULL)
- {
- debug("failed to open file <%s> for udf check\n", args[0]);
- return 1;
- }
-
- for (i = 16; i < 32; i++)
- {
- grub_file_seek(file, i * 2048);
- grub_file_read(file, buf, sizeof(buf));
- if (buf[0] == 255)
- {
- break;
- }
- }
-
- i++;
- grub_file_seek(file, i * 2048);
- grub_file_read(file, buf, sizeof(buf));
-
- if (grub_memcmp(buf + 1, "BEA01", 5) == 0)
- {
- i++;
- grub_file_seek(file, i * 2048);
- grub_file_read(file, buf, sizeof(buf));
-
- if (grub_memcmp(buf + 1, "NSR02", 5) == 0 ||
- grub_memcmp(buf + 1, "NSR03", 5) == 0)
- {
- rc = 0;
- }
- }
-
- grub_file_close(file);
-
- debug("ISO UDF: %s\n", rc ? "NO" : "YES");
-
- return rc;
-}
-
-static grub_err_t ventoy_cmd_cmp(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- long value_long1 = 0;
- long value_long2 = 0;
-
- if ((argc != 3) || (!ventoy_is_decimal(args[0])) || (!ventoy_is_decimal(args[2])))
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int1} { eq|ne|gt|lt|ge|le } {Int2}", cmd_raw_name);
- }
-
- value_long1 = grub_strtol(args[0], NULL, 10);
- value_long2 = grub_strtol(args[2], NULL, 10);
-
- if (0 == grub_strcmp(args[1], "eq"))
- {
- grub_errno = (value_long1 == value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE;
- }
- else if (0 == grub_strcmp(args[1], "ne"))
- {
- grub_errno = (value_long1 != value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE;
- }
- else if (0 == grub_strcmp(args[1], "gt"))
- {
- grub_errno = (value_long1 > value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE;
- }
- else if (0 == grub_strcmp(args[1], "lt"))
- {
- grub_errno = (value_long1 < value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE;
- }
- else if (0 == grub_strcmp(args[1], "ge"))
- {
- grub_errno = (value_long1 >= value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE;
- }
- else if (0 == grub_strcmp(args[1], "le"))
- {
- grub_errno = (value_long1 <= value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE;
- }
- else
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int1} { eq ne gt lt ge le } {Int2}", cmd_raw_name);
- }
-
- return grub_errno;
-}
-
-static grub_err_t ventoy_cmd_device(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- char *pos = NULL;
- char buf[128] = {0};
-
- if (argc != 2)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s path var", cmd_raw_name);
- }
-
- grub_strncpy(buf, (args[0][0] == '(') ? args[0] + 1 : args[0], sizeof(buf) - 1);
- pos = grub_strstr(buf, ",");
- if (pos)
- {
- *pos = 0;
- }
-
- grub_env_set(args[1], buf);
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_err_t ventoy_cmd_check_compatible(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int i;
- char buf[256];
- grub_disk_t disk;
- char *pos = NULL;
- const char *files[] = { "ventoy.dat", "VENTOY.DAT" };
-
- (void)ctxt;
-
- if (argc != 1)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s (loop)", cmd_raw_name);
- }
-
- for (i = 0; i < (int)ARRAY_SIZE(files); i++)
- {
- grub_snprintf(buf, sizeof(buf) - 1, "[ -e \"%s/%s\" ]", args[0], files[i]);
- if (0 == grub_script_execute_sourcecode(buf))
- {
- debug("file %s exist, ventoy_compatible YES\n", buf);
- grub_env_set("ventoy_compatible", "YES");
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
- }
- else
- {
- debug("file %s NOT exist\n", buf);
- }
- }
-
- grub_snprintf(buf, sizeof(buf) - 1, "%s", args[0][0] == '(' ? (args[0] + 1) : args[0]);
- pos = grub_strstr(buf, ")");
- if (pos)
- {
- *pos = 0;
- }
-
- disk = grub_disk_open(buf);
- if (disk)
- {
- grub_disk_read(disk, 16 << 2, 0, 1024, g_img_swap_tmp_buf);
- grub_disk_close(disk);
-
- g_img_swap_tmp_buf[703] = 0;
- for (i = 318; i < 703; i++)
- {
- if (g_img_swap_tmp_buf[i] == 'V' &&
- 0 == grub_strncmp(g_img_swap_tmp_buf + i, VENTOY_COMPATIBLE_STR, VENTOY_COMPATIBLE_STR_LEN))
- {
- debug("Ventoy compatible string exist at %d, ventoy_compatible YES\n", i);
- grub_env_set("ventoy_compatible", "YES");
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
- }
- }
- }
- else
- {
- debug("failed to open disk <%s>\n", buf);
- }
-
- grub_env_set("ventoy_compatible", "NO");
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-int ventoy_cmp_img(img_info *img1, img_info *img2)
-{
- char *s1, *s2;
- int c1 = 0;
- int c2 = 0;
-
- if (g_plugin_image_list == VENTOY_IMG_WHITE_LIST)
- {
- return (img1->plugin_list_index - img2->plugin_list_index);
- }
-
- for (s1 = img1->name, s2 = img2->name; *s1 && *s2; s1++, s2++)
- {
- c1 = *s1;
- c2 = *s2;
-
- if (0 == g_sort_case_sensitive)
- {
- if (grub_islower(c1))
- {
- c1 = c1 - 'a' + 'A';
- }
-
- if (grub_islower(c2))
- {
- c2 = c2 - 'a' + 'A';
- }
- }
-
- if (c1 != c2)
- {
- break;
- }
- }
-
- return (c1 - c2);
-}
-
-static int ventoy_cmp_subdir(img_iterator_node *node1, img_iterator_node *node2)
-{
- char *s1, *s2;
- int c1 = 0;
- int c2 = 0;
-
- if (g_plugin_image_list == VENTOY_IMG_WHITE_LIST)
- {
- return (node1->plugin_list_index - node2->plugin_list_index);
- }
-
- for (s1 = node1->dir, s2 = node2->dir; *s1 && *s2; s1++, s2++)
- {
- c1 = *s1;
- c2 = *s2;
-
- if (0 == g_sort_case_sensitive)
- {
- if (grub_islower(c1))
- {
- c1 = c1 - 'a' + 'A';
- }
-
- if (grub_islower(c2))
- {
- c2 = c2 - 'a' + 'A';
- }
- }
-
- if (c1 != c2)
- {
- break;
- }
- }
-
- return (c1 - c2);
-}
-
-void ventoy_swap_img(img_info *img1, img_info *img2)
-{
- grub_memcpy(&g_img_swap_tmp, img1, sizeof(img_info));
-
- grub_memcpy(img1, img2, sizeof(img_info));
- img1->next = g_img_swap_tmp.next;
- img1->prev = g_img_swap_tmp.prev;
-
- g_img_swap_tmp.next = img2->next;
- g_img_swap_tmp.prev = img2->prev;
- grub_memcpy(img2, &g_img_swap_tmp, sizeof(img_info));
-}
-
-static int ventoy_img_name_valid(const char *filename, grub_size_t namelen)
-{
- (void)namelen;
-
- if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_')
- {
- return 0;
- }
-
- return 1;
-}
-
-static int ventoy_check_ignore_flag(const char *filename, const struct grub_dirhook_info *info, void *data)
-{
- if (0 == info->dir)
- {
- if (filename && filename[0] == '.' && 0 == grub_strncmp(filename, ".ventoyignore", 13))
- {
- *((int *)data) = 1;
- return 0;
- }
- }
-
- return 0;
-}
-
-static int ventoy_collect_img_files(const char *filename, const struct grub_dirhook_info *info, void *data)
-{
- //int i = 0;
- int type = 0;
- int ignore = 0;
- int index = 0;
- grub_size_t len;
- img_info *img;
- img_info *tail;
- img_iterator_node *tmp;
- img_iterator_node *new_node;
- img_iterator_node *node = (img_iterator_node *)data;
-
- if (g_enumerate_time_checked == 0)
- {
- g_enumerate_finish_time_ms = grub_get_time_ms();
- if ((g_enumerate_finish_time_ms - g_enumerate_start_time_ms) >= 3000)
- {
- grub_cls();
- grub_printf("\n\n Ventoy scanning files, please wait...\n");
- grub_refresh();
- g_enumerate_time_checked = 1;
- }
- }
-
- len = grub_strlen(filename);
-
- if (info->dir)
- {
- if (node->level + 1 > g_img_max_search_level)
- {
- return 0;
- }
-
- if ((len == 1 && filename[0] == '.') ||
- (len == 2 && filename[0] == '.' && filename[1] == '.'))
- {
- return 0;
- }
-
- if (!ventoy_img_name_valid(filename, len))
- {
- return 0;
- }
-
- if (filename[0] == '$' && 0 == grub_strncmp(filename, "$RECYCLE.BIN", 12))
- {
- return 0;
- }
-
- if (g_plugin_image_list == VENTOY_IMG_WHITE_LIST)
- {
- grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s/", node->dir, filename);
- index = ventoy_plugin_get_image_list_index(vtoy_class_directory, g_img_swap_tmp_buf);
- if (index == 0)
- {
- debug("Directory %s not found in image_list plugin config...\n", g_img_swap_tmp_buf);
- return 0;
- }
- }
-
- new_node = grub_zalloc(sizeof(img_iterator_node));
- if (new_node)
- {
- new_node->level = node->level + 1;
- new_node->plugin_list_index = index;
- new_node->dirlen = grub_snprintf(new_node->dir, sizeof(new_node->dir), "%s%s/", node->dir, filename);
-
- g_enum_fs->fs_dir(g_enum_dev, new_node->dir, ventoy_check_ignore_flag, &ignore);
- if (ignore)
- {
- debug("Directory %s ignored...\n", new_node->dir);
- grub_free(new_node);
- return 0;
- }
-
- new_node->tail = node->tail;
-
- new_node->parent = node;
- if (!node->firstchild)
- {
- node->firstchild = new_node;
- }
-
- if (g_img_iterator_tail)
- {
- g_img_iterator_tail->next = new_node;
- g_img_iterator_tail = new_node;
- }
- else
- {
- g_img_iterator_head.next = new_node;
- g_img_iterator_tail = new_node;
- }
- }
- }
- else
- {
- debug("Find a file %s\n", filename);
- if (len < 4)
- {
- return 0;
- }
-
- if (FILE_FLT(ISO) && 0 == grub_strcasecmp(filename + len - 4, ".iso"))
- {
- type = img_type_iso;
- }
- else if (FILE_FLT(WIM) && g_wimboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".wim")))
- {
- type = img_type_wim;
- }
- else if (FILE_FLT(VHD) && g_vhdboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".vhd") ||
- (len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vhdx"))))
- {
- type = img_type_vhd;
- }
- #ifdef GRUB_MACHINE_EFI
- else if (FILE_FLT(EFI) && 0 == grub_strcasecmp(filename + len - 4, ".efi"))
- {
- type = img_type_efi;
- }
- #endif
- else if (FILE_FLT(IMG) && 0 == grub_strcasecmp(filename + len - 4, ".img"))
- {
- if (len == 18 && grub_strncmp(filename, "ventoy_", 7) == 0)
- {
- if (grub_strncmp(filename + 7, "wimboot", 7) == 0 ||
- grub_strncmp(filename + 7, "vhdboot", 7) == 0)
- {
- return 0;
- }
- }
- type = img_type_img;
- }
- else if (FILE_FLT(VTOY) && len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vtoy"))
- {
- type = img_type_vtoy;
- }
- else if (len >= 9 && 0 == grub_strcasecmp(filename + len - 5, ".vcfg"))
- {
- if (filename[len - 9] == '.' || (len >= 10 && filename[len - 10] == '.'))
- {
- grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s", node->dir, filename);
- ventoy_plugin_add_custom_boot(g_img_swap_tmp_buf);
- }
- return 0;
- }
- else
- {
- return 0;
- }
-
- if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_')
- {
- return 0;
- }
-
- if (g_plugin_image_list)
- {
- grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s", node->dir, filename);
- index = ventoy_plugin_get_image_list_index(vtoy_class_image_file, g_img_swap_tmp_buf);
- if (VENTOY_IMG_WHITE_LIST == g_plugin_image_list && index == 0)
- {
- debug("File %s not found in image_list plugin config...\n", g_img_swap_tmp_buf);
- return 0;
- }
- else if (VENTOY_IMG_BLACK_LIST == g_plugin_image_list && index > 0)
- {
- debug("File %s found in image_blacklist plugin config %d ...\n", g_img_swap_tmp_buf, index);
- return 0;
- }
- }
-
- img = grub_zalloc(sizeof(img_info));
- if (img)
- {
- img->type = type;
- img->plugin_list_index = index;
- grub_snprintf(img->name, sizeof(img->name), "%s", filename);
-
- img->pathlen = grub_snprintf(img->path, sizeof(img->path), "%s%s", node->dir, img->name);
-
- img->size = info->size;
- if (0 == img->size)
- {
- img->size = ventoy_grub_get_file_size("%s/%s%s", g_iso_path, node->dir, filename);
- }
-
- if (img->size < VTOY_FILT_MIN_FILE_SIZE)
- {
- debug("img <%s> size too small %llu\n", img->name, (ulonglong)img->size);
- grub_free(img);
- return 0;
- }
-
- if (g_ventoy_img_list)
- {
- tail = *(node->tail);
- img->prev = tail;
- tail->next = img;
- }
- else
- {
- g_ventoy_img_list = img;
- }
-
- img->id = g_ventoy_img_count;
- img->parent = node;
- if (node && NULL == node->firstiso)
- {
- node->firstiso = img;
- }
-
- node->isocnt++;
- tmp = node->parent;
- while (tmp)
- {
- tmp->isocnt++;
- tmp = tmp->parent;
- }
-
- *((img_info **)(node->tail)) = img;
- g_ventoy_img_count++;
-
- img->alias = ventoy_plugin_get_menu_alias(vtoy_alias_image_file, img->path);
- img->class = ventoy_plugin_get_menu_class(vtoy_class_image_file, img->name, img->path);
- if (!img->class)
- {
- img->class = g_menu_class[type];
- }
- img->menu_prefix = g_menu_prefix[type];
-
- if (img_type_iso == type)
- {
- if (ventoy_plugin_check_memdisk(img->path))
- {
- img->menu_prefix = "miso";
- }
- }
-
- debug("Add %s%s to list %d\n", node->dir, filename, g_ventoy_img_count);
- }
- }
-
- return 0;
-}
-
-static int ventoy_arch_mode_init(void)
-{
- #ifdef GRUB_MACHINE_EFI
- if (grub_strcmp(GRUB_TARGET_CPU, "i386") == 0)
- {
- g_ventoy_plat_data = VTOY_PLAT_I386_UEFI;
- grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "ia32");
- }
- else if (grub_strcmp(GRUB_TARGET_CPU, "arm64") == 0)
- {
- g_ventoy_plat_data = VTOY_PLAT_ARM64_UEFI;
- grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "aa64");
- }
- else if (grub_strcmp(GRUB_TARGET_CPU, "mips64el") == 0)
- {
- g_ventoy_plat_data = VTOY_PLAT_MIPS_UEFI;
- grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "mips");
- }
- else
- {
- g_ventoy_plat_data = VTOY_PLAT_X86_64_UEFI;
- grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "uefi");
- }
-#else
- g_ventoy_plat_data = VTOY_PLAT_X86_LEGACY;
- grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "legacy");
-#endif
-
- return 0;
-}
-
-int ventoy_fill_data(grub_uint32_t buflen, char *buffer)
-{
- int len = GRUB_UINT_MAX;
- const char *value = NULL;
- char name[32] = {0};
- char plat[32] = {0};
- char guidstr[32] = {0};
- ventoy_guid guid = VENTOY_GUID;
- const char *fmt1 = NULL;
- const char *fmt2 = NULL;
- const char *fmt3 = NULL;
- grub_uint32_t *puint = (grub_uint32_t *)name;
- grub_uint32_t *puint2 = (grub_uint32_t *)plat;
- const char fmtdata[]={ 0x39, 0x35, 0x25, 0x00, 0x35, 0x00, 0x23, 0x30, 0x30, 0x30, 0x30, 0x66, 0x66, 0x00 };
- const char fmtcode[]={
- 0x22, 0x0A, 0x2B, 0x20, 0x68, 0x62, 0x6F, 0x78, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x74, 0x6F, 0x70,
- 0x20, 0x3D, 0x20, 0x25, 0x73, 0x0A, 0x20, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x20, 0x3D, 0x20, 0x25,
- 0x73, 0x0A, 0x20, 0x20, 0x2B, 0x20, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x7B, 0x74, 0x65, 0x78,
- 0x74, 0x20, 0x3D, 0x20, 0x22, 0x25, 0x73, 0x20, 0x25, 0x73, 0x25, 0x73, 0x22, 0x20, 0x63, 0x6F,
- 0x6C, 0x6F, 0x72, 0x20, 0x3D, 0x20, 0x22, 0x25, 0x73, 0x22, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E,
- 0x20, 0x3D, 0x20, 0x22, 0x6C, 0x65, 0x66, 0x74, 0x22, 0x7D, 0x0A, 0x7D, 0x0A, 0x22, 0x00
- };
-
- grub_memset(name, 0, sizeof(name));
- puint[0] = grub_swap_bytes32(0x56454e54);
- puint[3] = grub_swap_bytes32(0x4f4e0000);
- puint[2] = grub_swap_bytes32(0x45525349);
- puint[1] = grub_swap_bytes32(0x4f595f56);
- value = ventoy_get_env(name);
-
- grub_memset(name, 0, sizeof(name));
- puint[1] = grub_swap_bytes32(0x5f544f50);
- puint[0] = grub_swap_bytes32(0x56544c45);
- fmt1 = ventoy_get_env(name);
- if (!fmt1)
- {
- fmt1 = fmtdata;
- }
-
- grub_memset(name, 0, sizeof(name));
- puint[1] = grub_swap_bytes32(0x5f4c4654);
- puint[0] = grub_swap_bytes32(0x56544c45);
- fmt2 = ventoy_get_env(name);
-
- grub_memset(name, 0, sizeof(name));
- puint[1] = grub_swap_bytes32(0x5f434c52);
- puint[0] = grub_swap_bytes32(0x56544c45);
- fmt3 = ventoy_get_env(name);
-
- grub_memcpy(guidstr, &guid, sizeof(guid));
-
- puint2[0] = grub_swap_bytes32(g_ventoy_plat_data);
-
- /* Easter egg :) It will be appreciated if you reserve it, but NOT mandatory. */
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wformat-nonliteral"
- len = grub_snprintf(buffer, buflen, fmtcode,
- fmt1 ? fmt1 : fmtdata,
- fmt2 ? fmt2 : fmtdata + 4,
- value ? value : "", plat, guidstr,
- fmt3 ? fmt3 : fmtdata + 6);
- #pragma GCC diagnostic pop
-
- grub_memset(name, 0, sizeof(name));
- puint[0] = grub_swap_bytes32(0x76746f79);
- puint[2] = grub_swap_bytes32(0x656e7365);
- puint[1] = grub_swap_bytes32(0x5f6c6963);
- ventoy_set_env(name, guidstr);
-
- return len;
-}
-
-int ventoy_check_password(const vtoy_password *pwd, int retry)
-{
- int offset;
- char input[256];
- grub_uint8_t md5[16];
-
- while (retry--)
- {
- grub_memset(input, 0, sizeof(input));
-
- grub_printf("Enter password: ");
- grub_refresh();
-
- if (pwd->type == VTOY_PASSWORD_TXT)
- {
- grub_password_get(input, 128);
- if (grub_strcmp(pwd->text, input) == 0)
- {
- return 0;
- }
- }
- else if (pwd->type == VTOY_PASSWORD_MD5)
- {
- grub_password_get(input, 128);
- grub_crypto_hash(GRUB_MD_MD5, md5, input, grub_strlen(input));
- if (grub_memcmp(pwd->md5, md5, 16) == 0)
- {
- return 0;
- }
- }
- else if (pwd->type == VTOY_PASSWORD_SALT_MD5)
- {
- offset = (int)grub_snprintf(input, 128, "%s", pwd->salt);
- grub_password_get(input + offset, 128);
-
- grub_crypto_hash(GRUB_MD_MD5, md5, input, grub_strlen(input));
- if (grub_memcmp(pwd->md5, md5, 16) == 0)
- {
- return 0;
- }
- }
-
- grub_printf("Invalid password!\n\n");
- grub_refresh();
- }
-
- return 1;
-}
-
-static img_info * ventoy_get_min_iso(img_iterator_node *node)
-{
- img_info *minimg = NULL;
- img_info *img = (img_info *)(node->firstiso);
-
- while (img && (img_iterator_node *)(img->parent) == node)
- {
- if (img->select == 0 && (NULL == minimg || ventoy_cmp_img(img, minimg) < 0))
- {
- minimg = img;
- }
- img = img->next;
- }
-
- if (minimg)
- {
- minimg->select = 1;
- }
-
- return minimg;
-}
-
-static img_iterator_node * ventoy_get_min_child(img_iterator_node *node)
-{
- img_iterator_node *Minchild = NULL;
- img_iterator_node *child = node->firstchild;
-
- while (child && child->parent == node)
- {
- if (child->select == 0 && (NULL == Minchild || ventoy_cmp_subdir(child, Minchild) < 0))
- {
- Minchild = child;
- }
- child = child->next;
- }
-
- if (Minchild)
- {
- Minchild->select = 1;
- }
-
- return Minchild;
-}
-
-static int ventoy_dynamic_tree_menu(img_iterator_node *node)
-{
- int offset = 1;
- img_info *img = NULL;
- const char *dir_class = NULL;
- const char *dir_alias = NULL;
- img_iterator_node *child = NULL;
-
- if (node->isocnt == 0 || node->done == 1)
- {
- return 0;
- }
-
- if (node->parent && node->parent->dirlen < node->dirlen)
- {
- offset = node->parent->dirlen;
- }
-
- if (node == &g_img_iterator_head)
- {
- if (g_default_menu_mode == 0)
- {
- if (g_tree_view_menu_style == 0)
- {
- vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
- "menuentry \"%-10s [Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n "
- " echo 'return ...' \n"
- "}\n", "<--");
- }
- else
- {
- vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
- "menuentry \"[Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n "
- " echo '%s ...' \n"
- "}\n", "return");
- }
- }
- }
- else
- {
- node->dir[node->dirlen - 1] = 0;
- dir_class = ventoy_plugin_get_menu_class(vtoy_class_directory, node->dir, node->dir);
- if (!dir_class)
- {
- dir_class = "vtoydir";
- }
-
- dir_alias = ventoy_plugin_get_menu_alias(vtoy_alias_directory, node->dir);
- if (dir_alias)
- {
- if (g_tree_view_menu_style == 0)
- {
- vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
- "submenu \"%-10s %s\" --class=\"%s\" --id=\"DIR_%s\" {\n",
- "DIR", dir_alias, dir_class, node->dir + offset);
- }
- else
- {
- vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
- "submenu \"%s\" --class=\"%s\" --id=\"DIR_%s\" {\n",
- dir_alias, dir_class, node->dir + offset);
- }
- }
- else
- {
- dir_alias = node->dir + offset;
-
- if (g_tree_view_menu_style == 0)
- {
- vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
- "submenu \"%-10s [%s]\" --class=\"%s\" --id=\"DIR_%s\" {\n",
- "DIR", dir_alias, dir_class, node->dir + offset);
- }
- else
- {
- vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
- "submenu \"[%s]\" --class=\"%s\" --id=\"DIR_%s\" {\n",
- dir_alias, dir_class, node->dir + offset);
- }
- }
-
- if (g_tree_view_menu_style == 0)
- {
- vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
- "menuentry \"%-10s [../]\" --class=\"vtoyret\" VTOY_RET {\n "
- " echo 'return ...' \n"
- "}\n", "<--");
- }
- else
- {
- vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
- "menuentry \"[../]\" --class=\"vtoyret\" VTOY_RET {\n "
- " echo '%s ...' \n"
- "}\n", "return");
- }
- }
-
- while ((child = ventoy_get_min_child(node)) != NULL)
- {
- ventoy_dynamic_tree_menu(child);
- }
-
- while ((img = ventoy_get_min_iso(node)) != NULL)
- {
- if (g_tree_view_menu_style == 0)
- {
- vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
- "menuentry \"%-10s %s%s\" --class=\"%s\" --id=\"VID_%d\" {\n"
- " %s_%s \n"
- "}\n",
- grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT),
- img->unsupport ? "[***********] " : "",
- img->alias ? img->alias : img->name, img->class, img->id,
- img->menu_prefix,
- img->unsupport ? "unsupport_menuentry" : "common_menuentry");
- }
- else
- {
- vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos,
- "menuentry \"%s%s\" --class=\"%s\" --id=\"VID_%d\" {\n"
- " %s_%s \n"
- "}\n",
- img->unsupport ? "[***********] " : "",
- img->alias ? img->alias : img->name, img->class, img->id,
- img->menu_prefix,
- img->unsupport ? "unsupport_menuentry" : "common_menuentry");
- }
- }
-
- if (node != &g_img_iterator_head)
- {
- vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "%s", "}\n");
- }
-
- node->done = 1;
- return 0;
-}
-
-int ventoy_check_device_result(int ret)
-{
- char buf[32];
-
- grub_snprintf(buf, sizeof(buf), "%d", (ret & 0x7FFF));
- grub_env_set("VTOY_CHKDEV_RESULT_STRING", buf);
- grub_env_export("VTOY_CHKDEV_RESULT_STRING");
-
- if (ret)
- {
- grub_printf(VTOY_WARNING"\n");
- grub_printf(VTOY_WARNING"\n");
- grub_printf(VTOY_WARNING"\n\n\n");
-
- grub_printf("This is NOT a standard Ventoy device and is NOT supported (0x%x).\n\n", ret);
- grub_printf("You should follow the instructions in https://www.ventoy.net to use Ventoy.\n");
-
- grub_printf("\n\nWill exit after 10 seconds ...... ");
- grub_refresh();
- grub_sleep(10);
- }
-
- return ret;
-}
-
-int ventoy_check_device(grub_device_t dev)
-{
- int workaround = 0;
- grub_file_t file;
- grub_uint64_t offset;
- char devname[64];
- grub_fs_t fs;
- grub_device_t dev2;
- char *label = NULL;
- struct grub_partition *partition;
-
- if (dev->disk == NULL || dev->disk->partition == NULL)
- {
- return ventoy_check_device_result(1 | 0x1000);
- }
-
- if (0 == ventoy_check_file_exist("(%s,2)/ventoy/ventoy.cpio", dev->disk->name) ||
- 0 == ventoy_check_file_exist("(%s,2)/grub/localboot.cfg", dev->disk->name) ||
- 0 == ventoy_check_file_exist("(%s,2)/tool/mount.exfat-fuse_aarch64", dev->disk->name))
- {
- #ifndef GRUB_MACHINE_EFI
- if (0 == ventoy_check_file_exist("(ventoydisk)/ventoy/ventoy.cpio", dev->disk->name) ||
- 0 == ventoy_check_file_exist("(ventoydisk)/grub/localboot.cfg", dev->disk->name) ||
- 0 == ventoy_check_file_exist("(ventoydisk)/tool/mount.exfat-fuse_aarch64", dev->disk->name))
- {
- return ventoy_check_device_result(2 | 0x1000);
- }
- else
- {
- workaround = 1;
- }
- #endif
- }
-
- /* We must have partition 2 */
- if (workaround)
- {
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", "(ventoydisk)/ventoy/ventoy.cpio");
- }
- else
- {
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(%s,2)/ventoy/ventoy.cpio", dev->disk->name);
- }
- if (!file)
- {
- return ventoy_check_device_result(3 | 0x1000);
- }
-
- if (NULL == grub_strstr(file->fs->name, "fat"))
- {
- grub_file_close(file);
- return ventoy_check_device_result(4 | 0x1000);
- }
-
- partition = dev->disk->partition;
- if (partition->number != 0 || partition->start != 2048)
- {
- return ventoy_check_device_result(5);
- }
-
- if (workaround)
- {
- if (grub_strncmp(g_ventoy_part_info->Head.Signature, "EFI PART", 8) == 0)
- {
- ventoy_gpt_part_tbl *PartTbl = g_ventoy_part_info->PartTbl;
- if (PartTbl[1].StartLBA != PartTbl[0].LastLBA + 1 ||
- (PartTbl[1].LastLBA + 1 - PartTbl[1].StartLBA) != 65536)
- {
- grub_file_close(file);
- return ventoy_check_device_result(6);
- }
- }
- else
- {
- ventoy_part_table *PartTbl = g_ventoy_part_info->MBR.PartTbl;
- if (PartTbl[1].StartSectorId != PartTbl[0].StartSectorId + PartTbl[0].SectorCount ||
- PartTbl[1].SectorCount != 65536)
- {
- grub_file_close(file);
- return ventoy_check_device_result(6);
- }
- }
- }
- else
- {
- offset = partition->start + partition->len;
- partition = file->device->disk->partition;
- if ((partition->number != 1) || (partition->len != 65536) || (offset != partition->start))
- {
- grub_file_close(file);
- return ventoy_check_device_result(7);
- }
- }
-
- grub_file_close(file);
-
- if (workaround == 0)
- {
- grub_snprintf(devname, sizeof(devname), "%s,2", dev->disk->name);
- dev2 = grub_device_open(devname);
- if (!dev2)
- {
- return ventoy_check_device_result(8);
- }
-
- fs = grub_fs_probe(dev2);
- if (!fs)
- {
- grub_device_close(dev2);
- return ventoy_check_device_result(9);
- }
-
- fs->fs_label(dev2, &label);
- if ((!label) || grub_strncmp("VTOYEFI", label, 7))
- {
- grub_device_close(dev2);
- return ventoy_check_device_result(10);
- }
-
- grub_device_close(dev2);
- }
-
- return ventoy_check_device_result(0);
-}
-
-static int ventoy_set_default_menu(void)
-{
- int img_len = 0;
- char *pos = NULL;
- char *end = NULL;
- char *def = NULL;
- const char *strdata = NULL;
- img_info *cur = NULL;
- img_info *default_node = NULL;
- const char *default_image = NULL;
-
- default_image = ventoy_get_env("VTOY_DEFAULT_IMAGE");
- if (default_image && default_image[0] == '/')
- {
- img_len = grub_strlen(default_image);
-
- for (cur = g_ventoy_img_list; cur; cur = cur->next)
- {
- if (img_len == cur->pathlen && grub_strcmp(default_image, cur->path) == 0)
- {
- default_node = cur;
- break;
- }
- }
-
- if (!default_node)
- {
- return 1;
- }
-
- if (0 == g_default_menu_mode)
- {
- vtoy_ssprintf(g_list_script_buf, g_list_script_pos, "set default='VID_%d'\n", default_node->id);
- }
- else
- {
- def = grub_strdup(default_image);
- if (!def)
- {
- return 1;
- }
-
- vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "set default=%c", '\'');
-
- strdata = ventoy_get_env("VTOY_DEFAULT_SEARCH_ROOT");
- if (strdata && strdata[0] == '/')
- {
- pos = def + grub_strlen(strdata);
- if (*pos == '/')
- {
- pos++;
- }
- }
- else
- {
- pos = def + 1;
- }
-
- while ((end = grub_strchr(pos, '/')) != NULL)
- {
- *end = 0;
- vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "DIR_%s>", pos);
- pos = end + 1;
- }
-
- vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "VID_%d'\n", default_node->id);
- grub_free(def);
- }
- }
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int len;
- grub_fs_t fs;
- grub_device_t dev = NULL;
- img_info *cur = NULL;
- img_info *tail = NULL;
- const char *strdata = NULL;
- char *device_name = NULL;
- char buf[32];
- img_iterator_node *node = NULL;
- img_iterator_node *tmp = NULL;
-
- (void)ctxt;
-
- if (argc != 2)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {device} {cntvar}", cmd_raw_name);
- }
-
- if (g_ventoy_img_list || g_ventoy_img_count)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Must clear image before list");
- }
-
- g_enumerate_time_checked = 0;
- g_enumerate_start_time_ms = grub_get_time_ms();
-
- strdata = ventoy_get_env("VTOY_FILT_DOT_UNDERSCORE_FILE");
- if (strdata && strdata[0] == '1' && strdata[1] == 0)
- {
- g_filt_dot_underscore_file = 1;
- }
-
- strdata = ventoy_get_env("VTOY_SORT_CASE_SENSITIVE");
- if (strdata && strdata[0] == '1' && strdata[1] == 0)
- {
- g_sort_case_sensitive = 1;
- }
-
- device_name = grub_file_get_device_name(args[0]);
- if (!device_name)
- {
- goto fail;
- }
-
- g_enum_dev = dev = grub_device_open(device_name);
- if (!dev)
- {
- goto fail;
- }
-
- g_enum_fs = fs = grub_fs_probe(dev);
- if (!fs)
- {
- goto fail;
- }
-
- if (ventoy_get_fs_type(fs->name) >= ventoy_fs_max)
- {
- debug("unsupported fs:<%s>\n", fs->name);
- ventoy_set_env("VTOY_NO_ISO_TIP", "unsupported file system");
- goto fail;
- }
-
- ventoy_set_env("vtoy_iso_fs", fs->name);
-
- strdata = ventoy_get_env("VTOY_DEFAULT_MENU_MODE");
- if (strdata && strdata[0] == '1')
- {
- g_default_menu_mode = 1;
- }
-
- grub_memset(&g_img_iterator_head, 0, sizeof(g_img_iterator_head));
-
- grub_snprintf(g_iso_path, sizeof(g_iso_path), "%s", args[0]);
-
- strdata = ventoy_get_env("VTOY_DEFAULT_SEARCH_ROOT");
- if (strdata && strdata[0] == '/')
- {
- len = grub_snprintf(g_img_iterator_head.dir, sizeof(g_img_iterator_head.dir) - 1, "%s", strdata);
- if (g_img_iterator_head.dir[len - 1] != '/')
- {
- g_img_iterator_head.dir[len++] = '/';
- }
- g_img_iterator_head.dirlen = len;
- }
- else
- {
- g_img_iterator_head.dirlen = 1;
- grub_strcpy(g_img_iterator_head.dir, "/");
- }
-
- g_img_iterator_head.tail = &tail;
-
- if (g_img_max_search_level < 0)
- {
- g_img_max_search_level = GRUB_INT_MAX;
- strdata = ventoy_get_env("VTOY_MAX_SEARCH_LEVEL");
- if (strdata && ventoy_is_decimal(strdata))
- {
- g_img_max_search_level = (int)grub_strtoul(strdata, NULL, 10);
- }
- }
-
- g_vtoy_file_flt[VTOY_FILE_FLT_ISO] = ventoy_control_get_flag("VTOY_FILE_FLT_ISO");
- g_vtoy_file_flt[VTOY_FILE_FLT_WIM] = ventoy_control_get_flag("VTOY_FILE_FLT_WIM");
- g_vtoy_file_flt[VTOY_FILE_FLT_EFI] = ventoy_control_get_flag("VTOY_FILE_FLT_EFI");
- g_vtoy_file_flt[VTOY_FILE_FLT_IMG] = ventoy_control_get_flag("VTOY_FILE_FLT_IMG");
- g_vtoy_file_flt[VTOY_FILE_FLT_VHD] = ventoy_control_get_flag("VTOY_FILE_FLT_VHD");
- g_vtoy_file_flt[VTOY_FILE_FLT_VTOY] = ventoy_control_get_flag("VTOY_FILE_FLT_VTOY");
-
- for (node = &g_img_iterator_head; node; node = node->next)
- {
- fs->fs_dir(dev, node->dir, ventoy_collect_img_files, node);
- }
-
- strdata = ventoy_get_env("VTOY_TREE_VIEW_MENU_STYLE");
- if (strdata && strdata[0] == '1' && strdata[1] == 0)
- {
- g_tree_view_menu_style = 1;
- }
-
- ventoy_set_default_menu();
-
- for (node = &g_img_iterator_head; node; node = node->next)
- {
- ventoy_dynamic_tree_menu(node);
- }
-
- /* free node */
- node = g_img_iterator_head.next;
- while (node)
- {
- tmp = node->next;
- grub_free(node);
- node = tmp;
- }
-
- /* sort image list by image name */
- for (cur = g_ventoy_img_list; cur; cur = cur->next)
- {
- for (tail = cur->next; tail; tail = tail->next)
- {
- if (ventoy_cmp_img(cur, tail) > 0)
- {
- ventoy_swap_img(cur, tail);
- }
- }
- }
-
- if (g_default_menu_mode == 1)
- {
- vtoy_ssprintf(g_list_script_buf, g_list_script_pos,
- "menuentry \"%s [Return to TreeView]\" --class=\"vtoyret\" VTOY_RET {\n "
- " echo 'return ...' \n"
- "}\n", "<--");
- }
-
- for (cur = g_ventoy_img_list; cur; cur = cur->next)
- {
- vtoy_ssprintf(g_list_script_buf, g_list_script_pos,
- "menuentry \"%s%s\" --class=\"%s\" --id=\"VID_%d\" {\n"
- " %s_%s \n"
- "}\n",
- cur->unsupport ? "[***********] " : "",
- cur->alias ? cur->alias : cur->name, cur->class, cur->id,
- cur->menu_prefix,
- cur->unsupport ? "unsupport_menuentry" : "common_menuentry");
- }
-
- g_tree_script_buf[g_tree_script_pos] = 0;
- g_list_script_buf[g_list_script_pos] = 0;
-
- grub_snprintf(buf, sizeof(buf), "%d", g_ventoy_img_count);
- grub_env_set(args[1], buf);
-
-fail:
-
- check_free(device_name, grub_free);
- check_free(dev, grub_device_close);
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-
-static grub_err_t ventoy_cmd_clear_img(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- img_info *next = NULL;
- img_info *cur = g_ventoy_img_list;
-
- (void)ctxt;
- (void)argc;
- (void)args;
-
- while (cur)
- {
- next = cur->next;
- grub_free(cur);
- cur = next;
- }
-
- g_ventoy_img_list = NULL;
- g_ventoy_img_count = 0;
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_err_t ventoy_cmd_img_name(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- long img_id = 0;
- img_info *cur = g_ventoy_img_list;
-
- (void)ctxt;
-
- if (argc != 2 || (!ventoy_is_decimal(args[0])))
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {imageID} {var}", cmd_raw_name);
- }
-
- img_id = grub_strtol(args[0], NULL, 10);
- if (img_id >= g_ventoy_img_count)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such many images %ld %ld", img_id, g_ventoy_img_count);
- }
-
- debug("Find image %ld name \n", img_id);
-
- while (cur && img_id > 0)
- {
- img_id--;
- cur = cur->next;
- }
-
- if (!cur)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such many images");
- }
-
- debug("image name is %s\n", cur->name);
-
- grub_env_set(args[1], cur->name);
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_err_t ventoy_cmd_ext_select_img_path(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int len = 0;
- char id[32] = {0};
- img_info *cur = g_ventoy_img_list;
-
- (void)ctxt;
-
- if (argc != 1)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {var}", cmd_raw_name);
- }
-
- len = (int)grub_strlen(args[0]);
-
- while (cur)
- {
- if (len == cur->pathlen && 0 == grub_strcmp(args[0], cur->path))
- {
- break;
- }
- cur = cur->next;
- }
-
- if (!cur)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such image");
- }
-
- grub_snprintf(id, sizeof(id), "VID_%d", cur->id);
- grub_env_set("chosen", id);
- grub_env_export("chosen");
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int img_id = 0;
- char value[32];
- char *pos = NULL;
- const char *id = NULL;
- img_info *cur = g_ventoy_img_list;
-
- (void)ctxt;
-
- if (argc < 1 || argc > 2)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {var}", cmd_raw_name);
- }
-
- id = grub_env_get("chosen");
-
- pos = grub_strstr(id, "VID_");
- if (pos)
- {
- img_id = (int)grub_strtoul(pos + 4, NULL, 10);
- }
- else
- {
- img_id = (int)grub_strtoul(id, NULL, 10);
- }
-
- while (cur)
- {
- if (img_id == cur->id)
- {
- break;
- }
- cur = cur->next;
- }
-
- if (!cur)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such image");
- }
-
- grub_env_set(args[0], cur->path);
-
- if (argc > 1)
- {
- grub_snprintf(value, sizeof(value), "%llu", (ulonglong)(cur->size));
- grub_env_set(args[1], value);
- }
-
- g_svd_replace_offset = 0;
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid, grub_uint8_t *signature)
-{
- grub_disk_t disk;
- char *device_name;
- char *pos;
- char *pos2;
-
- device_name = grub_file_get_device_name(filename);
- if (!device_name)
- {
- return 1;
- }
-
- pos = device_name;
- if (pos[0] == '(')
- {
- pos++;
- }
-
- pos2 = grub_strstr(pos, ",");
- if (!pos2)
- {
- pos2 = grub_strstr(pos, ")");
- }
-
- if (pos2)
- {
- *pos2 = 0;
- }
-
- disk = grub_disk_open(pos);
- if (disk)
- {
- grub_disk_read(disk, 0, 0x180, 16, guid);
- grub_disk_read(disk, 0, 0x1b8, 4, signature);
- grub_disk_close(disk);
- }
- else
- {
- return 1;
- }
-
- grub_free(device_name);
- return 0;
-}
-
-grub_uint32_t ventoy_get_iso_boot_catlog(grub_file_t file)
-{
- eltorito_descriptor desc;
-
- grub_memset(&desc, 0, sizeof(desc));
- grub_file_seek(file, 17 * 2048);
- grub_file_read(file, &desc, sizeof(desc));
-
- if (desc.type != 0 || desc.version != 1)
- {
- return 0;
- }
-
- if (grub_strncmp((char *)desc.id, "CD001", 5) != 0 ||
- grub_strncmp((char *)desc.system_id, "EL TORITO SPECIFICATION", 23) != 0)
- {
- return 0;
- }
-
- return desc.sector;
-}
-
-int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector)
-{
- int i;
- int x86count = 0;
- grub_uint8_t buf[512];
- grub_uint8_t parttype[] = { 0x04, 0x06, 0x0B, 0x0C };
-
- grub_file_seek(file, sector * 2048);
- grub_file_read(file, buf, sizeof(buf));
-
- if (buf[0] == 0x01 && buf[1] == 0xEF)
- {
- debug("%s efi eltorito in Validation Entry\n", file->name);
- return 1;
- }
-
- if (buf[0] == 0x01 && buf[1] == 0x00)
- {
- x86count++;
- }
-
- for (i = 64; i < (int)sizeof(buf); i += 32)
- {
- if ((buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0xEF)
- {
- debug("%s efi eltorito offset %d 0x%02x\n", file->name, i, buf[i]);
- return 1;
- }
-
- if ((buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0x00 && x86count == 1)
- {
- debug("0x9100 assume %s efi eltorito offset %d 0x%02x\n", file->name, i, buf[i]);
- return 1;
- }
- }
-
- if (x86count && buf[32] == 0x88 && buf[33] == 0x04)
- {
- for (i = 0; i < (int)(ARRAY_SIZE(parttype)); i++)
- {
- if (buf[36] == parttype[i])
- {
- debug("hard disk image assume %s efi eltorito, part type 0x%x\n", file->name, buf[36]);
- return 1;
- }
- }
- }
-
- debug("%s does not contain efi eltorito\n", file->name);
- return 0;
-}
-
-void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param)
-{
- char *pos;
- const char *fs = NULL;
- const char *cdprompt = NULL;
- grub_uint32_t i;
- grub_uint8_t chksum = 0;
- grub_disk_t disk;
-
- disk = file->device->disk;
- grub_memcpy(¶m->guid, &g_ventoy_guid, sizeof(ventoy_guid));
-
- param->vtoy_disk_size = disk->total_sectors * (1 << disk->log_sector_size);
- param->vtoy_disk_part_id = disk->partition->number + 1;
- param->vtoy_disk_part_type = ventoy_get_fs_type(file->fs->name);
-
- pos = grub_strstr(file->name, "/");
- if (!pos)
- {
- pos = file->name;
- }
-
- grub_snprintf(param->vtoy_img_path, sizeof(param->vtoy_img_path), "%s", pos);
-
- ventoy_get_disk_guid(file->name, param->vtoy_disk_guid, param->vtoy_disk_signature);
-
- param->vtoy_img_size = file->size;
-
- param->vtoy_reserved[0] = g_ventoy_break_level;
- param->vtoy_reserved[1] = g_ventoy_debug_level;
-
- param->vtoy_reserved[2] = g_ventoy_chain_type;
-
- /* Windows CD/DVD prompt 0:suppress 1:reserved */
- param->vtoy_reserved[4] = 0;
- if (g_ventoy_chain_type == 1) /* Windows */
- {
- cdprompt = ventoy_get_env("VTOY_WINDOWS_CD_PROMPT");
- if (cdprompt && cdprompt[0] == '1' && cdprompt[1] == 0)
- {
- param->vtoy_reserved[4] = 1;
- }
- }
-
- fs = ventoy_get_env("ventoy_fs_probe");
- if (fs && grub_strcmp(fs, "udf") == 0)
- {
- param->vtoy_reserved[3] = 1;
- }
-
- /* calculate checksum */
- for (i = 0; i < sizeof(ventoy_os_param); i++)
- {
- chksum += *((grub_uint8_t *)param + i);
- }
- param->chksum = (grub_uint8_t)(0x100 - chksum);
-
- return;
-}
-
-int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start)
-{
- grub_uint32_t i = 0;
- grub_uint64_t total = 0;
- grub_uint64_t fileblk = 0;
- ventoy_img_chunk *chunk = NULL;
-
- for (i = 0; i < chunklist->cur_chunk; i++)
- {
- chunk = chunklist->chunk + i;
-
- if (chunk->disk_start_sector <= start)
- {
- debug("%u disk start invalid %lu\n", i, (ulong)start);
- return 1;
- }
-
- total += chunk->disk_end_sector + 1 - chunk->disk_start_sector;
- }
-
- fileblk = (file->size + 511) / 512;
-
- if (total != fileblk)
- {
- debug("Invalid total: %llu %llu\n", (ulonglong)total, (ulonglong)fileblk);
- if ((file->size % 512) && (total + 1 == fileblk))
- {
- debug("maybe img file to be processed.\n");
- return 0;
- }
-
- return 1;
- }
-
- return 0;
-}
-
-int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start)
-{
- int fs_type;
- int len;
- grub_uint32_t i = 0;
- grub_uint32_t sector = 0;
- grub_uint32_t count = 0;
- grub_off_t size = 0;
- grub_off_t read = 0;
-
- fs_type = ventoy_get_fs_type(file->fs->name);
- if (fs_type == ventoy_fs_exfat)
- {
- grub_fat_get_file_chunk(start, file, chunklist);
- }
- else if (fs_type == ventoy_fs_ext)
- {
- grub_ext_get_file_chunk(start, file, chunklist);
- }
- else
- {
- file->read_hook = (grub_disk_read_hook_t)grub_disk_blocklist_read;
- file->read_hook_data = chunklist;
-
- for (size = file->size; size > 0; size -= read)
- {
- read = (size > VTOY_SIZE_1GB) ? VTOY_SIZE_1GB : size;
- grub_file_read(file, NULL, read);
- }
-
- for (i = 0; start > 0 && i < chunklist->cur_chunk; i++)
- {
- chunklist->chunk[i].disk_start_sector += start;
- chunklist->chunk[i].disk_end_sector += start;
- }
-
- if (ventoy_fs_udf == fs_type)
- {
- for (i = 0; i < chunklist->cur_chunk; i++)
- {
- count = (chunklist->chunk[i].disk_end_sector + 1 - chunklist->chunk[i].disk_start_sector) >> 2;
- chunklist->chunk[i].img_start_sector = sector;
- chunklist->chunk[i].img_end_sector = sector + count - 1;
- sector += count;
- }
- }
- }
-
- len = (int)grub_strlen(file->name);
- if ((len > 4 && grub_strncasecmp(file->name + len - 4, ".img", 4) == 0) ||
- (len > 4 && grub_strncasecmp(file->name + len - 4, ".vhd", 4) == 0) ||
- (len > 5 && grub_strncasecmp(file->name + len - 5, ".vhdx", 5) == 0) ||
- (len > 5 && grub_strncasecmp(file->name + len - 5, ".vtoy", 5) == 0))
- {
- for (i = 0; i < chunklist->cur_chunk; i++)
- {
- count = chunklist->chunk[i].disk_end_sector + 1 - chunklist->chunk[i].disk_start_sector;
- if (count < 4)
- {
- count = 1;
- }
- else
- {
- count >>= 2;
- }
-
- chunklist->chunk[i].img_start_sector = sector;
- chunklist->chunk[i].img_end_sector = sector + count - 1;
- sector += count;
- }
- }
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_img_sector(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int rc;
- grub_file_t file;
- grub_disk_addr_t start;
-
- (void)ctxt;
- (void)argc;
-
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
- if (!file)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]);
- }
-
- g_conf_replace_node = NULL;
- g_conf_replace_offset = 0;
-
- if (g_img_chunk_list.chunk)
- {
- grub_free(g_img_chunk_list.chunk);
- }
-
- if (ventoy_get_fs_type(file->fs->name) >= ventoy_fs_max)
- {
- grub_file_close(file);
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Unsupported filesystem %s\n", file->fs->name);
- }
-
- /* get image chunk data */
- grub_memset(&g_img_chunk_list, 0, sizeof(g_img_chunk_list));
- g_img_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM);
- if (NULL == g_img_chunk_list.chunk)
- {
- return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n");
- }
-
- g_img_chunk_list.max_chunk = DEFAULT_CHUNK_NUM;
- g_img_chunk_list.cur_chunk = 0;
-
- start = file->device->disk->partition->start;
-
- ventoy_get_block_list(file, &g_img_chunk_list, start);
-
- rc = ventoy_check_block_list(file, &g_img_chunk_list, start);
- grub_file_close(file);
-
- if (rc)
- {
- return grub_error(GRUB_ERR_NOT_IMPLEMENTED_YET, "Unsupported chunk list.\n");
- }
-
- grub_memset(&g_grub_param->file_replace, 0, sizeof(g_grub_param->file_replace));
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_err_t ventoy_select_conf_replace(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- grub_uint64_t offset = 0;
- grub_uint32_t align = 0;
- grub_file_t file = NULL;
- conf_replace *node = NULL;
-
- (void)ctxt;
- (void)argc;
- (void)args;
-
- debug("select conf replace argc:%d\n", argc);
-
- if (argc < 2)
- {
- return 0;
- }
-
- node = ventoy_plugin_find_conf_replace(args[1]);
- if (!node)
- {
- debug("Conf replace not found for %s\n", args[1]);
- goto end;
- }
-
- debug("Find conf replace for %s\n", args[1]);
-
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(loop)%s", node->orgconf);
- if (!file)
- {
- debug("<(loop)%s> NOT exist\n", node->orgconf);
- goto end;
- }
-
- offset = grub_iso9660_get_last_file_dirent_pos(file);
- grub_file_close(file);
-
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[0], node->newconf);
- if (!file)
- {
- debug("New config file <%s%s> NOT exist\n", args[0], node->newconf);
- goto end;
- }
-
- align = ((int)file->size + 2047) / 2048 * 2048;
-
- if (align > vtoy_max_replace_file_size)
- {
- debug("New config file <%s%s> too big\n", args[0], node->newconf);
- goto end;
- }
-
- grub_file_read(file, g_conf_replace_new_buf, file->size);
- g_conf_replace_new_len = (int)file->size;
- g_conf_replace_new_len_align = align;
-
- g_conf_replace_node = node;
- g_conf_replace_offset = offset + 2;
-
- debug("conf_replace OK: newlen: %d\n", g_conf_replace_new_len);
-
-end:
- if (file)
- {
- grub_file_close(file);
- }
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int i = 0;
- int pos = 0;
- char *buf = NULL;
- char configfile[128];
- install_template *node = NULL;
-
- (void)ctxt;
- (void)argc;
- (void)args;
-
- debug("select auto installation argc:%d\n", argc);
-
- if (argc < 1)
- {
- return 0;
- }
-
- node = ventoy_plugin_find_install_template(args[0]);
- if (!node)
- {
- debug("Auto install template not found for %s\n", args[0]);
- return 0;
- }
-
- if (node->autosel >= 0 && node->autosel <= node->templatenum)
- {
- node->cursel = node->autosel - 1;
- debug("Auto install template auto select %d\n", node->autosel);
- return 0;
- }
-
- buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF);
- if (!buf)
- {
- return 0;
- }
-
- vtoy_ssprintf(buf, pos, "menuentry \"Boot without auto installation template\" {\n"
- " echo %s\n}\n", "123");
-
- for (i = 0; i < node->templatenum; i++)
- {
- vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n"
- " echo 123\n}\n",
- node->templatepath[i].path);
- }
-
- g_ventoy_menu_esc = 1;
- g_ventoy_suppress_esc = 1;
-
- grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos);
- grub_script_execute_sourcecode(configfile);
-
- g_ventoy_menu_esc = 0;
- g_ventoy_suppress_esc = 0;
-
- grub_free(buf);
-
- node->cursel = g_ventoy_last_entry - 1;
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int i = 0;
- int pos = 0;
- char *buf = NULL;
- char configfile[128];
- persistence_config *node;
-
- (void)ctxt;
- (void)argc;
- (void)args;
-
- debug("select persistence argc:%d\n", argc);
-
- if (argc < 1)
- {
- return 0;
- }
-
- node = ventoy_plugin_find_persistent(args[0]);
- if (!node)
- {
- debug("Persistence image not found for %s\n", args[0]);
- return 0;
- }
-
- if (node->autosel >= 0 && node->autosel <= node->backendnum)
- {
- node->cursel = node->autosel - 1;
- debug("Persistence image auto select %d\n", node->autosel);
- return 0;
- }
-
- buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF);
- if (!buf)
- {
- return 0;
- }
-
- vtoy_ssprintf(buf, pos, "menuentry \"Boot without persistence\" {\n"
- " echo %s\n}\n", "123");
-
- for (i = 0; i < node->backendnum; i++)
- {
- vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n"
- " echo 123\n}\n",
- node->backendpath[i].path);
-
- }
-
- g_ventoy_menu_esc = 1;
- g_ventoy_suppress_esc = 1;
-
- grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos);
- grub_script_execute_sourcecode(configfile);
-
- g_ventoy_menu_esc = 0;
- g_ventoy_suppress_esc = 0;
-
- grub_free(buf);
-
- node->cursel = g_ventoy_last_entry - 1;
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_err_t ventoy_cmd_dump_img_sector(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- grub_uint32_t i;
- ventoy_img_chunk *cur;
-
- (void)ctxt;
- (void)argc;
- (void)args;
-
- for (i = 0; i < g_img_chunk_list.cur_chunk; i++)
- {
- cur = g_img_chunk_list.chunk + i;
- grub_printf("image:[%u - %u] <==> disk:[%llu - %llu]\n",
- cur->img_start_sector, cur->img_end_sector,
- (unsigned long long)cur->disk_start_sector, (unsigned long long)cur->disk_end_sector
- );
- }
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_err_t ventoy_cmd_test_block_list(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- grub_uint32_t i;
- grub_file_t file;
- ventoy_img_chunk_list chunklist;
-
- (void)ctxt;
- (void)argc;
-
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
- if (!file)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]);
- }
-
- /* get image chunk data */
- grub_memset(&chunklist, 0, sizeof(chunklist));
- chunklist.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM);
- if (NULL == chunklist.chunk)
- {
- return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n");
- }
-
- chunklist.max_chunk = DEFAULT_CHUNK_NUM;
- chunklist.cur_chunk = 0;
-
- ventoy_get_block_list(file, &chunklist, 0);
-
- if (0 != ventoy_check_block_list(file, &chunklist, 0))
- {
- grub_printf("########## UNSUPPORTED ###############\n");
- }
-
- grub_printf("filesystem: <%s> entry number:<%u>\n", file->fs->name, chunklist.cur_chunk);
-
- for (i = 0; i < chunklist.cur_chunk; i++)
- {
- grub_printf("%llu+%llu,", (ulonglong)chunklist.chunk[i].disk_start_sector,
- (ulonglong)(chunklist.chunk[i].disk_end_sector + 1 - chunklist.chunk[i].disk_start_sector));
- }
-
- grub_printf("\n==================================\n");
-
- for (i = 0; i < chunklist.cur_chunk; i++)
- {
- grub_printf("%2u: [%llu %llu] - [%llu %llu]\n", i,
- (ulonglong)chunklist.chunk[i].img_start_sector,
- (ulonglong)chunklist.chunk[i].img_end_sector,
- (ulonglong)chunklist.chunk[i].disk_start_sector,
- (ulonglong)chunklist.chunk[i].disk_end_sector
- );
- }
-
- grub_free(chunklist.chunk);
- grub_file_close(file);
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_err_t ventoy_cmd_add_replace_file(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int i;
- ventoy_grub_param_file_replace *replace = NULL;
-
- (void)ctxt;
- (void)argc;
- (void)args;
-
- if (argc >= 2)
- {
- replace = &(g_grub_param->file_replace);
- replace->magic = GRUB_FILE_REPLACE_MAGIC;
-
- replace->old_name_cnt = 0;
- for (i = 0; i < 4 && i + 1 < argc; i++)
- {
- replace->old_name_cnt++;
- grub_snprintf(replace->old_file_name[i], sizeof(replace->old_file_name[i]), "%s", args[i + 1]);
- }
-
- replace->new_file_virtual_id = (grub_uint32_t)grub_strtoul(args[0], NULL, 10);
- }
-
- VENTOY_CMD_RETURN(GRUB_ERR_NONE);
-}
-
-static grub_err_t ventoy_cmd_dump_menu(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- (void)ctxt;
- (void)argc;
- (void)args;
-
- if (argc == 0)
- {
- grub_printf("List Mode: CurLen:%d MaxLen:%u\n", g_list_script_pos, VTOY_MAX_SCRIPT_BUF);
- grub_printf("%s", g_list_script_buf);
- }
- else
- {
- grub_printf("Tree Mode: CurLen:%d MaxLen:%u\n", g_tree_script_pos, VTOY_MAX_SCRIPT_BUF);
- grub_printf("%s", g_tree_script_buf);
- }
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_dump_img_list(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- img_info *cur = g_ventoy_img_list;
-
- (void)ctxt;
- (void)argc;
- (void)args;
-
- while (cur)
- {
- grub_printf("path:<%s> id=%d list_index=%d\n", cur->path, cur->id, cur->plugin_list_index);
- grub_printf("name:<%s>\n\n", cur->name);
- cur = cur->next;
- }
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_dump_injection(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- (void)ctxt;
- (void)argc;
- (void)args;
-
- ventoy_plugin_dump_injection();
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_dump_auto_install(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- (void)ctxt;
- (void)argc;
- (void)args;
-
- ventoy_plugin_dump_auto_install();
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_dump_persistence(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- (void)ctxt;
- (void)argc;
- (void)args;
-
- ventoy_plugin_dump_persistence();
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_check_mode(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- (void)ctxt;
- (void)argc;
- (void)args;
-
- if (argc != 1)
- {
- return 1;
- }
-
- if (args[0][0] == '0')
- {
- return g_ventoy_memdisk_mode ? 0 : 1;
- }
- else if (args[0][0] == '1')
- {
- return g_ventoy_iso_raw ? 0 : 1;
- }
- else if (args[0][0] == '2')
- {
- return g_ventoy_iso_uefi_drv ? 0 : 1;
- }
- else if (args[0][0] == '3')
- {
- return g_ventoy_grub2_mode ? 0 : 1;
- }
-
- return 1;
-}
-
-static grub_err_t ventoy_cmd_dynamic_menu(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- static int configfile_mode = 0;
- char memfile[128] = {0};
-
- (void)ctxt;
- (void)argc;
- (void)args;
-
- /*
- * args[0]: 0:normal 1:configfile
- * args[1]: 0:list_buf 1:tree_buf
- */
-
- if (argc != 2)
- {
- debug("Invalid argc %d\n", argc);
- return 0;
- }
-
- if (args[0][0] == '0')
- {
- if (args[1][0] == '0')
- {
- grub_script_execute_sourcecode(g_list_script_buf);
- }
- else
- {
- grub_script_execute_sourcecode(g_tree_script_buf);
- }
- }
- else
- {
- if (configfile_mode)
- {
- debug("Now already in F3 mode %d\n", configfile_mode);
- return 0;
- }
-
- if (args[1][0] == '0')
- {
- grub_snprintf(memfile, sizeof(memfile), "configfile mem:0x%llx:size:%d",
- (ulonglong)(ulong)g_list_script_buf, g_list_script_pos);
- }
- else
- {
- g_ventoy_last_entry = -1;
- grub_snprintf(memfile, sizeof(memfile), "configfile mem:0x%llx:size:%d",
- (ulonglong)(ulong)g_tree_script_buf, g_tree_script_pos);
- }
-
- configfile_mode = 1;
- grub_script_execute_sourcecode(memfile);
- configfile_mode = 0;
- }
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_file_exist_nocase(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- grub_file_t file;
-
- (void)ctxt;
-
- if (argc != 1)
- {
- return 1;
- }
-
- g_ventoy_case_insensitive = 1;
- file = grub_file_open(args[0], VENTOY_FILE_TYPE);
- g_ventoy_case_insensitive = 0;
-
- grub_errno = 0;
-
- if (file)
- {
- grub_file_close(file);
- return 0;
- }
- return 1;
-}
-
-static grub_err_t ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int id = 0;
- int find = 0;
- grub_disk_t disk;
- const char *isopath = NULL;
- char hdname[32];
- ventoy_mbr_head mbr;
-
- (void)ctxt;
- (void)argc;
-
- if (argc != 1)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s variable\n", cmd_raw_name);
- }
-
- isopath = grub_env_get("vtoy_iso_part");
- if (!isopath)
- {
- debug("isopath is null %p\n", isopath);
- return 0;
- }
-
- debug("isopath is %s\n", isopath);
-
- for (id = 0; id < 30 && (find == 0); id++)
- {
- grub_snprintf(hdname, sizeof(hdname), "hd%d,", id);
- if (grub_strstr(isopath, hdname))
- {
- debug("skip %s ...\n", hdname);
- continue;
- }
-
- grub_snprintf(hdname, sizeof(hdname), "hd%d", id);
-
- disk = grub_disk_open(hdname);
- if (!disk)
- {
- debug("%s not exist\n", hdname);
- break;
- }
-
- grub_memset(&mbr, 0, sizeof(mbr));
- if (0 == grub_disk_read(disk, 0, 0, 512, &mbr))
- {
- if (mbr.Byte55 == 0x55 && mbr.ByteAA == 0xAA)
- {
- if (mbr.PartTbl[0].Active == 0x80 || mbr.PartTbl[1].Active == 0x80 ||
- mbr.PartTbl[2].Active == 0x80 || mbr.PartTbl[3].Active == 0x80)
- {
-
- grub_env_set(args[0], hdname);
- find = 1;
- }
- }
- debug("%s is %s\n", hdname, find ? "bootable" : "NOT bootable");
- }
- else
- {
- debug("read %s failed\n", hdname);
- }
-
- grub_disk_close(disk);
- }
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_read_1st_line(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int len = 1024;
- grub_file_t file;
- char *buf = NULL;
-
- (void)ctxt;
- (void)argc;
-
- if (argc != 2)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s file var \n", cmd_raw_name);
- }
-
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
- if (!file)
- {
- debug("failed to open file %s\n", args[0]);
- return 0;
- }
-
- buf = grub_malloc(len);
- if (!buf)
- {
- goto end;
- }
-
- buf[len - 1] = 0;
- grub_file_read(file, buf, len - 1);
-
- ventoy_get_line(buf);
- ventoy_set_env(args[1], buf);
-
-end:
-
- grub_check_free(buf);
- grub_file_close(file);
-
- return 0;
-}
-
-static int ventoy_img_partition_callback (struct grub_disk *disk, const grub_partition_t partition, void *data)
-{
- (void)disk;
- (void)data;
-
- g_part_list_pos += grub_snprintf(g_part_list_buf + g_part_list_pos, VTOY_MAX_SCRIPT_BUF - g_part_list_pos,
- "0 %llu linear /dev/ventoy %llu\n",
- (ulonglong)partition->len, (ulonglong)partition->start);
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_img_part_info(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- char *device_name = NULL;
- grub_device_t dev = NULL;
- char buf[64];
-
- (void)ctxt;
-
- g_part_list_pos = 0;
- grub_env_unset("vtoy_img_part_file");
-
- if (argc != 1)
- {
- return 1;
- }
-
- device_name = grub_file_get_device_name(args[0]);
- if (!device_name)
- {
- debug("ventoy_cmd_img_part_info failed, %s\n", args[0]);
- goto end;
- }
-
- dev = grub_device_open(device_name);
- if (!dev)
- {
- debug("grub_device_open failed, %s\n", device_name);
- goto end;
- }
-
- grub_partition_iterate(dev->disk, ventoy_img_partition_callback, NULL);
-
- grub_snprintf(buf, sizeof(buf), "newc:vtoy_dm_table:mem:0x%llx:size:%d", (ulonglong)(ulong)g_part_list_buf, g_part_list_pos);
- grub_env_set("vtoy_img_part_file", buf);
-
-end:
-
- check_free(device_name, grub_free);
- check_free(dev, grub_device_close);
-
- return 0;
-}
-
-
-static grub_err_t ventoy_cmd_file_strstr(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int rc = 1;
- grub_file_t file;
- char *buf = NULL;
-
- (void)ctxt;
- (void)argc;
-
- if (argc != 2)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s file str \n", cmd_raw_name);
- }
-
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
- if (!file)
- {
- debug("failed to open file %s\n", args[0]);
- return 1;
- }
-
- buf = grub_malloc(file->size + 1);
- if (!buf)
- {
- goto end;
- }
-
- buf[file->size] = 0;
- grub_file_read(file, buf, file->size);
-
- if (grub_strstr(buf, args[1]))
- {
- rc = 0;
- }
-
-end:
-
- grub_check_free(buf);
- grub_file_close(file);
-
- return rc;
-}
-
-static grub_err_t ventoy_cmd_parse_volume(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int len;
- grub_file_t file;
- char buf[64];
- grub_uint64_t size;
- ventoy_iso9660_vd pvd;
-
- (void)ctxt;
- (void)argc;
-
- if (argc != 4)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s sysid volid space \n", cmd_raw_name);
- }
-
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
- if (!file)
- {
- debug("failed to open file %s\n", args[0]);
- return 0;
- }
-
- grub_file_seek(file, 16 * 2048);
- len = (int)grub_file_read(file, &pvd, sizeof(pvd));
- if (len != sizeof(pvd))
- {
- debug("failed to read pvd %d\n", len);
- goto end;
- }
-
- grub_memset(buf, 0, sizeof(buf));
- grub_memcpy(buf, pvd.sys, sizeof(pvd.sys));
- ventoy_set_env(args[1], buf);
-
- grub_memset(buf, 0, sizeof(buf));
- grub_memcpy(buf, pvd.vol, sizeof(pvd.vol));
- ventoy_set_env(args[2], buf);
-
- size = pvd.space;
- size *= 2048;
- grub_snprintf(buf, sizeof(buf), "%llu", (ulonglong)size);
- ventoy_set_env(args[3], buf);
-
-end:
- grub_file_close(file);
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_parse_create_date(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int len;
- grub_file_t file;
- char buf[64];
-
- (void)ctxt;
- (void)argc;
-
- if (argc != 2)
- {
- return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s var \n", cmd_raw_name);
- }
-
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
- if (!file)
- {
- debug("failed to open file %s\n", args[0]);
- return 0;
- }
-
- grub_memset(buf, 0, sizeof(buf));
- grub_file_seek(file, 16 * 2048 + 813);
- len = (int)grub_file_read(file, buf, 17);
- if (len != 17)
- {
- debug("failed to read create date %d\n", len);
- goto end;
- }
-
- ventoy_set_env(args[1], buf);
-
-end:
- grub_file_close(file);
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_img_hook_root(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- (void)ctxt;
- (void)argc;
- (void)args;
-
- ventoy_env_hook_root(1);
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_img_unhook_root(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- (void)ctxt;
- (void)argc;
- (void)args;
-
- ventoy_env_hook_root(0);
-
- return 0;
-}
-
-#ifdef GRUB_MACHINE_EFI
-static grub_err_t ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int ret = 1;
- grub_uint8_t *var;
- grub_size_t size;
- grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
-
- (void)ctxt;
- (void)argc;
- (void)args;
-
- var = grub_efi_get_variable("SecureBoot", &global, &size);
- if (var && *var == 1)
- {
- return 0;
- }
-
- return ret;
-}
-#else
-static grub_err_t ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- (void)ctxt;
- (void)argc;
- (void)args;
- return 1;
-}
-#endif
-
-static grub_err_t ventoy_cmd_img_check_range(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int i;
- int ret = 1;
- grub_file_t file;
- grub_uint64_t FileSectors = 0;
- ventoy_gpt_info *gpt = NULL;
- ventoy_part_table *pt = NULL;
- grub_uint8_t zeroguid[16] = {0};
-
- (void)ctxt;
- (void)argc;
-
- file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
- if (!file)
- {
- debug("failed to open file %s\n", args[0]);
- return 1;
- }
-
- if (file->size % 512)
- {
- debug("unaligned file size: %llu\n", (ulonglong)file->size);
- goto out;
- }
-
- gpt = grub_zalloc(sizeof(ventoy_gpt_info));
- if (!gpt)
- {
- goto out;
- }
-
- FileSectors = file->size / 512;
-
- grub_file_read(file, gpt, sizeof(ventoy_gpt_info));
- if (grub_strncmp(gpt->Head.Signature, "EFI PART", 8) == 0)
- {
- debug("This is EFI partition table\n");
-
- for (i = 0; i < 128; i++)
- {
- if (grub_memcmp(gpt->PartTbl[i].PartGuid, zeroguid, 16))
- {
- if (FileSectors < gpt->PartTbl[i].LastLBA)
- {
- debug("out of range: part[%d] LastLBA:%llu FileSectors:%llu\n", i,
- (ulonglong)gpt->PartTbl[i].LastLBA, (ulonglong)FileSectors);
- goto out;
- }
- }
- }
- }
- else
- {
- debug("This is MBR partition table\n");
-
- for (i = 0; i < 4; i++)
- {
- pt = gpt->MBR.PartTbl + i;
- if (FileSectors < pt->StartSectorId + pt->SectorCount)
- {
- debug("out of range: part[%d] LastLBA:%llu FileSectors:%llu\n", i,
- (ulonglong)(pt->StartSectorId + pt->SectorCount),
- (ulonglong)FileSectors);
- goto out;
- }
- }
- }
-
- ret = 0;
-
-out:
- grub_file_close(file);
- grub_check_free(gpt);
- grub_errno = GRUB_ERR_NONE;
- return ret;
-}
-
-static grub_err_t ventoy_cmd_clear_key(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int i;
- int ret;
-
- (void)ctxt;
- (void)argc;
- (void)args;
-
- for (i = 0; i < 500; i++)
- {
- ret = grub_getkey_noblock();
- if (ret == GRUB_TERM_NO_KEY)
- {
- break;
- }
- }
-
- if (i >= 500)
- {
- grub_cls();
- grub_printf("\n\n Still have key input after clear.\n");
- grub_refresh();
- grub_sleep(5);
- }
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_acpi_param(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int i;
- int buflen;
- int datalen;
- int loclen;
- int img_chunk_num;
- int image_sector_size;
- char cmd[64];
- ventoy_chain_head *chain;
- ventoy_img_chunk *chunk;
- ventoy_os_param *osparam;
- ventoy_image_location *location;
- ventoy_image_disk_region *region;
- struct grub_acpi_table_header *acpi;
-
- (void)ctxt;
-
- if (argc != 2)
- {
- return 1;
- }
-
- debug("ventoy_cmd_acpi_param %s %s\n", args[0], args[1]);
-
- chain = (ventoy_chain_head *)(ulong)grub_strtoul(args[0], NULL, 16);
- if (!chain)
- {
- return 1;
- }
-
- image_sector_size = (int)grub_strtol(args[1], NULL, 10);
-
- if (grub_memcmp(&g_ventoy_guid, &(chain->os_param.guid), 16))
- {
- debug("Invalid ventoy guid 0x%x\n", chain->os_param.guid.data1);
- return 1;
- }
-
- img_chunk_num = chain->img_chunk_num;
-
- loclen = sizeof(ventoy_image_location) + (img_chunk_num - 1) * sizeof(ventoy_image_disk_region);
- datalen = sizeof(ventoy_os_param) + loclen;
-
- buflen = sizeof(struct grub_acpi_table_header) + datalen;
- acpi = grub_zalloc(buflen);
- if (!acpi)
- {
- return 1;
- }
-
- /* Step1: Fill acpi table header */
- grub_memcpy(acpi->signature, "VTOY", 4);
- acpi->length = buflen;
- acpi->revision = 1;
- grub_memcpy(acpi->oemid, "VENTOY", 6);
- grub_memcpy(acpi->oemtable, "OSPARAMS", 8);
- acpi->oemrev = 1;
- acpi->creator_id[0] = 1;
- acpi->creator_rev = 1;
-
- /* Step2: Fill data */
- osparam = (ventoy_os_param *)(acpi + 1);
- grub_memcpy(osparam, &chain->os_param, sizeof(ventoy_os_param));
- osparam->vtoy_img_location_addr = 0;
- osparam->vtoy_img_location_len = loclen;
- osparam->chksum = 0;
- osparam->chksum = 0x100 - grub_byte_checksum(osparam, sizeof(ventoy_os_param));
-
- location = (ventoy_image_location *)(osparam + 1);
- grub_memcpy(&location->guid, &osparam->guid, sizeof(ventoy_guid));
- location->image_sector_size = image_sector_size;
- location->disk_sector_size = chain->disk_sector_size;
- location->region_count = img_chunk_num;
-
- region = location->regions;
- chunk = (ventoy_img_chunk *)((char *)chain + chain->img_chunk_offset);
- if (512 == image_sector_size)
- {
- for (i = 0; i < img_chunk_num; i++)
- {
- region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1;
- region->image_start_sector = chunk->img_start_sector * 4;
- region->disk_start_sector = chunk->disk_start_sector;
- region++;
- chunk++;
- }
- }
- else
- {
- for (i = 0; i < img_chunk_num; i++)
- {
- region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1;
- region->image_start_sector = chunk->img_start_sector;
- region->disk_start_sector = chunk->disk_start_sector;
- region++;
- chunk++;
- }
- }
-
- /* Step3: Fill acpi checksum */
- acpi->checksum = 0;
- acpi->checksum = 0x100 - grub_byte_checksum(acpi, acpi->length);
-
- /* load acpi table */
- grub_snprintf(cmd, sizeof(cmd), "acpi mem:0x%lx:size:%d", (ulong)acpi, acpi->length);
- grub_script_execute_sourcecode(cmd);
-
- grub_free(acpi);
-
- VENTOY_CMD_RETURN(0);
-}
-
-static grub_err_t ventoy_cmd_push_last_entry(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- (void)ctxt;
- (void)argc;
- (void)args;
-
- g_ventoy_last_entry_back = g_ventoy_last_entry;
- g_ventoy_last_entry = -1;
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_pop_last_entry(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- (void)ctxt;
- (void)argc;
- (void)args;
-
- g_ventoy_last_entry = g_ventoy_last_entry_back;
-
- return 0;
-}
-
-grub_uint64_t ventoy_get_part1_size(ventoy_gpt_info *gpt)
-{
- grub_uint64_t sectors;
-
- if (grub_strncmp(gpt->Head.Signature, "EFI PART", 8) == 0)
- {
- sectors = gpt->PartTbl[0].LastLBA + 1 - gpt->PartTbl[0].StartLBA;
- }
- else
- {
- sectors = gpt->MBR.PartTbl[0].SectorCount;
- }
-
- return sectors * 512;
-}
-
-static int ventoy_lib_module_callback(const char *filename, const struct grub_dirhook_info *info, void *data)
-{
- const char *pos = filename + 1;
-
- if (info->dir)
- {
- while (*pos)
- {
- if (*pos == '.')
- {
- if ((*(pos - 1) >= '0' && *(pos - 1) <= '9') && (*(pos + 1) >= '0' && *(pos + 1) <= '9'))
- {
- grub_strncpy((char *)data, filename, 128);
- return 1;
- }
- }
- pos++;
- }
- }
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_lib_module_ver(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int rc = 1;
- char *device_name = NULL;
- grub_device_t dev = NULL;
- grub_fs_t fs = NULL;
- char buf[128] = {0};
-
- (void)ctxt;
-
- if (argc != 3)
- {
- debug("ventoy_cmd_lib_module_ver, invalid param num %d\n", argc);
- return 1;
- }
-
- debug("ventoy_cmd_lib_module_ver %s %s %s\n", args[0], args[1], args[2]);
-
- device_name = grub_file_get_device_name(args[0]);
- if (!device_name)
- {
- debug("grub_file_get_device_name failed, %s\n", args[0]);
- goto end;
- }
-
- dev = grub_device_open(device_name);
- if (!dev)
- {
- debug("grub_device_open failed, %s\n", device_name);
- goto end;
- }
-
- fs = grub_fs_probe(dev);
- if (!fs)
- {
- debug("grub_fs_probe failed, %s\n", device_name);
- goto end;
- }
-
- fs->fs_dir(dev, args[1], ventoy_lib_module_callback, buf);
-
- if (buf[0])
- {
- ventoy_set_env(args[2], buf);
- }
-
- rc = 0;
-
-end:
-
- check_free(device_name, grub_free);
- check_free(dev, grub_device_close);
-
- return rc;
-}
-
-static grub_err_t ventoy_cmd_load_part_table(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- char name[64];
- int ret;
- grub_disk_t disk;
- grub_device_t dev;
-
- (void)argc;
- (void)ctxt;
-
- g_ventoy_part_info = grub_zalloc(sizeof(ventoy_gpt_info));
- if (!g_ventoy_part_info)
- {
- return 1;
- }
-
- disk = grub_disk_open(args[0]);
- if (!disk)
- {
- debug("Failed to open disk %s\n", args[0]);
- return 1;
- }
-
- g_ventoy_disk_size = disk->total_sectors * (1U << disk->log_sector_size);
-
- grub_disk_read(disk, 0, 0, sizeof(ventoy_gpt_info), g_ventoy_part_info);
- grub_disk_close(disk);
-
- grub_snprintf(name, sizeof(name), "%s,1", args[0]);
- dev = grub_device_open(name);
- if (dev)
- {
- /* make sure that we are running in a correct Ventoy device */
- ret = ventoy_check_device(dev);
- grub_device_close(dev);
-
- if (ret)
- {
- grub_exit();
- }
- }
-
- return 0;
-}
-
-static grub_err_t ventoy_cmd_check_custom_boot(grub_extcmd_context_t ctxt, int argc, char **args)
-{
- int ret = 1;
- const char *vcfg = NULL;
-
- (void)argc;
- (void)ctxt;
-
- vcfg = ventoy_plugin_get_custom_boot(args[0]);
- if (vcfg)
- {
- debug("custom boot <%s>:<%s>\n", args[0], vcfg);
- grub_env_set(args[1], vcfg);
- ret = 0;
- }
- else
- {
- debug("custom boot <%s>:<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();
}
--- /dev/null
+/******************************************************************************
+ * 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(¶m->guid, &g_ventoy_guid, sizeof(ventoy_guid));
+
+ param->vtoy_disk_size = disk->total_sectors * (1 << disk->log_sector_size);
+ param->vtoy_disk_part_id = disk->partition->number + 1;
+ param->vtoy_disk_part_type = ventoy_get_fs_type(file->fs->name);
+
+ pos = grub_strstr(file->name, "/");
+ if (!pos)
+ {
+ pos = file->name;
+ }
+
+ grub_snprintf(param->vtoy_img_path, sizeof(param->vtoy_img_path), "%s", pos);
+
+ ventoy_get_disk_guid(file->name, param->vtoy_disk_guid, param->vtoy_disk_signature);
+
+ param->vtoy_img_size = file->size;
+
+ param->vtoy_reserved[0] = g_ventoy_break_level;
+ param->vtoy_reserved[1] = g_ventoy_debug_level;
+
+ param->vtoy_reserved[2] = g_ventoy_chain_type;
+
+ /* Windows CD/DVD prompt 0:suppress 1:reserved */
+ param->vtoy_reserved[4] = 0;
+ if (g_ventoy_chain_type == 1) /* Windows */
+ {
+ cdprompt = ventoy_get_env("VTOY_WINDOWS_CD_PROMPT");
+ if (cdprompt && cdprompt[0] == '1' && cdprompt[1] == 0)
+ {
+ param->vtoy_reserved[4] = 1;
+ }
+ }
+
+ fs = ventoy_get_env("ventoy_fs_probe");
+ if (fs && grub_strcmp(fs, "udf") == 0)
+ {
+ param->vtoy_reserved[3] = 1;
+ }
+
+ /* calculate checksum */
+ for (i = 0; i < sizeof(ventoy_os_param); i++)
+ {
+ chksum += *((grub_uint8_t *)param + i);
+ }
+ param->chksum = (grub_uint8_t)(0x100 - chksum);
+
+ return;
+}
+
+int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start)
+{
+ grub_uint32_t i = 0;
+ grub_uint64_t total = 0;
+ grub_uint64_t fileblk = 0;
+ ventoy_img_chunk *chunk = NULL;
+
+ for (i = 0; i < chunklist->cur_chunk; i++)
+ {
+ chunk = chunklist->chunk + i;
+
+ if (chunk->disk_start_sector <= start)
+ {
+ debug("%u disk start invalid %lu\n", i, (ulong)start);
+ return 1;
+ }
+
+ total += chunk->disk_end_sector + 1 - chunk->disk_start_sector;
+ }
+
+ fileblk = (file->size + 511) / 512;
+
+ if (total != fileblk)
+ {
+ debug("Invalid total: %llu %llu\n", (ulonglong)total, (ulonglong)fileblk);
+ if ((file->size % 512) && (total + 1 == fileblk))
+ {
+ debug("maybe img file to be processed.\n");
+ return 0;
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start)
+{
+ int fs_type;
+ int len;
+ grub_uint32_t i = 0;
+ grub_uint32_t sector = 0;
+ grub_uint32_t count = 0;
+ grub_off_t size = 0;
+ grub_off_t read = 0;
+
+ fs_type = ventoy_get_fs_type(file->fs->name);
+ if (fs_type == ventoy_fs_exfat)
+ {
+ grub_fat_get_file_chunk(start, file, chunklist);
+ }
+ else if (fs_type == ventoy_fs_ext)
+ {
+ grub_ext_get_file_chunk(start, file, chunklist);
+ }
+ else
+ {
+ file->read_hook = (grub_disk_read_hook_t)grub_disk_blocklist_read;
+ file->read_hook_data = chunklist;
+
+ for (size = file->size; size > 0; size -= read)
+ {
+ read = (size > VTOY_SIZE_1GB) ? VTOY_SIZE_1GB : size;
+ grub_file_read(file, NULL, read);
+ }
+
+ for (i = 0; start > 0 && i < chunklist->cur_chunk; i++)
+ {
+ chunklist->chunk[i].disk_start_sector += start;
+ chunklist->chunk[i].disk_end_sector += start;
+ }
+
+ if (ventoy_fs_udf == fs_type)
+ {
+ for (i = 0; i < chunklist->cur_chunk; i++)
+ {
+ count = (chunklist->chunk[i].disk_end_sector + 1 - chunklist->chunk[i].disk_start_sector) >> 2;
+ chunklist->chunk[i].img_start_sector = sector;
+ chunklist->chunk[i].img_end_sector = sector + count - 1;
+ sector += count;
+ }
+ }
+ }
+
+ len = (int)grub_strlen(file->name);
+ if ((len > 4 && grub_strncasecmp(file->name + len - 4, ".img", 4) == 0) ||
+ (len > 4 && grub_strncasecmp(file->name + len - 4, ".vhd", 4) == 0) ||
+ (len > 5 && grub_strncasecmp(file->name + len - 5, ".vhdx", 5) == 0) ||
+ (len > 5 && grub_strncasecmp(file->name + len - 5, ".vtoy", 5) == 0))
+ {
+ for (i = 0; i < chunklist->cur_chunk; i++)
+ {
+ count = chunklist->chunk[i].disk_end_sector + 1 - chunklist->chunk[i].disk_start_sector;
+ if (count < 4)
+ {
+ count = 1;
+ }
+ else
+ {
+ count >>= 2;
+ }
+
+ chunklist->chunk[i].img_start_sector = sector;
+ chunklist->chunk[i].img_end_sector = sector + count - 1;
+ sector += count;
+ }
+ }
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_img_sector(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int rc;
+ grub_file_t file;
+ grub_disk_addr_t start;
+
+ (void)ctxt;
+ (void)argc;
+
+ file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
+ if (!file)
+ {
+ return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]);
+ }
+
+ g_conf_replace_node = NULL;
+ g_conf_replace_offset = 0;
+
+ if (g_img_chunk_list.chunk)
+ {
+ grub_free(g_img_chunk_list.chunk);
+ }
+
+ if (ventoy_get_fs_type(file->fs->name) >= ventoy_fs_max)
+ {
+ grub_file_close(file);
+ return grub_error(GRUB_ERR_BAD_ARGUMENT, "Unsupported filesystem %s\n", file->fs->name);
+ }
+
+ /* get image chunk data */
+ grub_memset(&g_img_chunk_list, 0, sizeof(g_img_chunk_list));
+ g_img_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM);
+ if (NULL == g_img_chunk_list.chunk)
+ {
+ return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n");
+ }
+
+ g_img_chunk_list.max_chunk = DEFAULT_CHUNK_NUM;
+ g_img_chunk_list.cur_chunk = 0;
+
+ start = file->device->disk->partition->start;
+
+ ventoy_get_block_list(file, &g_img_chunk_list, start);
+
+ rc = ventoy_check_block_list(file, &g_img_chunk_list, start);
+ grub_file_close(file);
+
+ if (rc)
+ {
+ return grub_error(GRUB_ERR_NOT_IMPLEMENTED_YET, "Unsupported chunk list.\n");
+ }
+
+ grub_memset(&g_grub_param->file_replace, 0, sizeof(g_grub_param->file_replace));
+ VENTOY_CMD_RETURN(GRUB_ERR_NONE);
+}
+
+static grub_err_t ventoy_select_conf_replace(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ grub_uint64_t offset = 0;
+ grub_uint32_t align = 0;
+ grub_file_t file = NULL;
+ conf_replace *node = NULL;
+
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ debug("select conf replace argc:%d\n", argc);
+
+ if (argc < 2)
+ {
+ return 0;
+ }
+
+ node = ventoy_plugin_find_conf_replace(args[1]);
+ if (!node)
+ {
+ debug("Conf replace not found for %s\n", args[1]);
+ goto end;
+ }
+
+ debug("Find conf replace for %s\n", args[1]);
+
+ file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(loop)%s", node->orgconf);
+ if (!file)
+ {
+ debug("<(loop)%s> NOT exist\n", node->orgconf);
+ goto end;
+ }
+
+ offset = grub_iso9660_get_last_file_dirent_pos(file);
+ grub_file_close(file);
+
+ file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[0], node->newconf);
+ if (!file)
+ {
+ debug("New config file <%s%s> NOT exist\n", args[0], node->newconf);
+ goto end;
+ }
+
+ align = ((int)file->size + 2047) / 2048 * 2048;
+
+ if (align > vtoy_max_replace_file_size)
+ {
+ debug("New config file <%s%s> too big\n", args[0], node->newconf);
+ goto end;
+ }
+
+ grub_file_read(file, g_conf_replace_new_buf, file->size);
+ g_conf_replace_new_len = (int)file->size;
+ g_conf_replace_new_len_align = align;
+
+ g_conf_replace_node = node;
+ g_conf_replace_offset = offset + 2;
+
+ debug("conf_replace OK: newlen: %d\n", g_conf_replace_new_len);
+
+end:
+ if (file)
+ {
+ grub_file_close(file);
+ }
+ VENTOY_CMD_RETURN(GRUB_ERR_NONE);
+}
+
+static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int i = 0;
+ int pos = 0;
+ char *buf = NULL;
+ char configfile[128];
+ install_template *node = NULL;
+
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ debug("select auto installation argc:%d\n", argc);
+
+ if (argc < 1)
+ {
+ return 0;
+ }
+
+ node = ventoy_plugin_find_install_template(args[0]);
+ if (!node)
+ {
+ debug("Auto install template not found for %s\n", args[0]);
+ return 0;
+ }
+
+ if (node->autosel >= 0 && node->autosel <= node->templatenum)
+ {
+ node->cursel = node->autosel - 1;
+ debug("Auto install template auto select %d\n", node->autosel);
+ return 0;
+ }
+
+ buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF);
+ if (!buf)
+ {
+ return 0;
+ }
+
+ vtoy_ssprintf(buf, pos, "menuentry \"Boot without auto installation template\" {\n"
+ " echo %s\n}\n", "123");
+
+ for (i = 0; i < node->templatenum; i++)
+ {
+ vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n"
+ " echo 123\n}\n",
+ node->templatepath[i].path);
+ }
+
+ g_ventoy_menu_esc = 1;
+ g_ventoy_suppress_esc = 1;
+
+ grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos);
+ grub_script_execute_sourcecode(configfile);
+
+ g_ventoy_menu_esc = 0;
+ g_ventoy_suppress_esc = 0;
+
+ grub_free(buf);
+
+ node->cursel = g_ventoy_last_entry - 1;
+
+ VENTOY_CMD_RETURN(GRUB_ERR_NONE);
+}
+
+static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int i = 0;
+ int pos = 0;
+ char *buf = NULL;
+ char configfile[128];
+ persistence_config *node;
+
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ debug("select persistence argc:%d\n", argc);
+
+ if (argc < 1)
+ {
+ return 0;
+ }
+
+ node = ventoy_plugin_find_persistent(args[0]);
+ if (!node)
+ {
+ debug("Persistence image not found for %s\n", args[0]);
+ return 0;
+ }
+
+ if (node->autosel >= 0 && node->autosel <= node->backendnum)
+ {
+ node->cursel = node->autosel - 1;
+ debug("Persistence image auto select %d\n", node->autosel);
+ return 0;
+ }
+
+ buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF);
+ if (!buf)
+ {
+ return 0;
+ }
+
+ vtoy_ssprintf(buf, pos, "menuentry \"Boot without persistence\" {\n"
+ " echo %s\n}\n", "123");
+
+ for (i = 0; i < node->backendnum; i++)
+ {
+ vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n"
+ " echo 123\n}\n",
+ node->backendpath[i].path);
+
+ }
+
+ g_ventoy_menu_esc = 1;
+ g_ventoy_suppress_esc = 1;
+
+ grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos);
+ grub_script_execute_sourcecode(configfile);
+
+ g_ventoy_menu_esc = 0;
+ g_ventoy_suppress_esc = 0;
+
+ grub_free(buf);
+
+ node->cursel = g_ventoy_last_entry - 1;
+
+ VENTOY_CMD_RETURN(GRUB_ERR_NONE);
+}
+
+static grub_err_t ventoy_cmd_dump_img_sector(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ grub_uint32_t i;
+ ventoy_img_chunk *cur;
+
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ for (i = 0; i < g_img_chunk_list.cur_chunk; i++)
+ {
+ cur = g_img_chunk_list.chunk + i;
+ grub_printf("image:[%u - %u] <==> disk:[%llu - %llu]\n",
+ cur->img_start_sector, cur->img_end_sector,
+ (unsigned long long)cur->disk_start_sector, (unsigned long long)cur->disk_end_sector
+ );
+ }
+
+ VENTOY_CMD_RETURN(GRUB_ERR_NONE);
+}
+
+static grub_err_t ventoy_cmd_test_block_list(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ grub_uint32_t i;
+ grub_file_t file;
+ ventoy_img_chunk_list chunklist;
+
+ (void)ctxt;
+ (void)argc;
+
+ file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
+ if (!file)
+ {
+ return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]);
+ }
+
+ /* get image chunk data */
+ grub_memset(&chunklist, 0, sizeof(chunklist));
+ chunklist.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM);
+ if (NULL == chunklist.chunk)
+ {
+ return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n");
+ }
+
+ chunklist.max_chunk = DEFAULT_CHUNK_NUM;
+ chunklist.cur_chunk = 0;
+
+ ventoy_get_block_list(file, &chunklist, 0);
+
+ if (0 != ventoy_check_block_list(file, &chunklist, 0))
+ {
+ grub_printf("########## UNSUPPORTED ###############\n");
+ }
+
+ grub_printf("filesystem: <%s> entry number:<%u>\n", file->fs->name, chunklist.cur_chunk);
+
+ for (i = 0; i < chunklist.cur_chunk; i++)
+ {
+ grub_printf("%llu+%llu,", (ulonglong)chunklist.chunk[i].disk_start_sector,
+ (ulonglong)(chunklist.chunk[i].disk_end_sector + 1 - chunklist.chunk[i].disk_start_sector));
+ }
+
+ grub_printf("\n==================================\n");
+
+ for (i = 0; i < chunklist.cur_chunk; i++)
+ {
+ grub_printf("%2u: [%llu %llu] - [%llu %llu]\n", i,
+ (ulonglong)chunklist.chunk[i].img_start_sector,
+ (ulonglong)chunklist.chunk[i].img_end_sector,
+ (ulonglong)chunklist.chunk[i].disk_start_sector,
+ (ulonglong)chunklist.chunk[i].disk_end_sector
+ );
+ }
+
+ grub_free(chunklist.chunk);
+ grub_file_close(file);
+
+ VENTOY_CMD_RETURN(GRUB_ERR_NONE);
+}
+
+static grub_err_t ventoy_cmd_add_replace_file(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int i;
+ ventoy_grub_param_file_replace *replace = NULL;
+
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ if (argc >= 2)
+ {
+ replace = &(g_grub_param->file_replace);
+ replace->magic = GRUB_FILE_REPLACE_MAGIC;
+
+ replace->old_name_cnt = 0;
+ for (i = 0; i < 4 && i + 1 < argc; i++)
+ {
+ replace->old_name_cnt++;
+ grub_snprintf(replace->old_file_name[i], sizeof(replace->old_file_name[i]), "%s", args[i + 1]);
+ }
+
+ replace->new_file_virtual_id = (grub_uint32_t)grub_strtoul(args[0], NULL, 10);
+ }
+
+ VENTOY_CMD_RETURN(GRUB_ERR_NONE);
+}
+
+static grub_err_t ventoy_cmd_dump_menu(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ if (argc == 0)
+ {
+ grub_printf("List Mode: CurLen:%d MaxLen:%u\n", g_list_script_pos, VTOY_MAX_SCRIPT_BUF);
+ grub_printf("%s", g_list_script_buf);
+ }
+ else
+ {
+ grub_printf("Tree Mode: CurLen:%d MaxLen:%u\n", g_tree_script_pos, VTOY_MAX_SCRIPT_BUF);
+ grub_printf("%s", g_tree_script_buf);
+ }
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_dump_img_list(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ img_info *cur = g_ventoy_img_list;
+
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ while (cur)
+ {
+ grub_printf("path:<%s> id=%d list_index=%d\n", cur->path, cur->id, cur->plugin_list_index);
+ grub_printf("name:<%s>\n\n", cur->name);
+ cur = cur->next;
+ }
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_dump_injection(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ ventoy_plugin_dump_injection();
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_dump_auto_install(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ ventoy_plugin_dump_auto_install();
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_dump_persistence(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ ventoy_plugin_dump_persistence();
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_check_mode(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ if (argc != 1)
+ {
+ return 1;
+ }
+
+ if (args[0][0] == '0')
+ {
+ return g_ventoy_memdisk_mode ? 0 : 1;
+ }
+ else if (args[0][0] == '1')
+ {
+ return g_ventoy_iso_raw ? 0 : 1;
+ }
+ else if (args[0][0] == '2')
+ {
+ return g_ventoy_iso_uefi_drv ? 0 : 1;
+ }
+ else if (args[0][0] == '3')
+ {
+ return g_ventoy_grub2_mode ? 0 : 1;
+ }
+
+ return 1;
+}
+
+static grub_err_t ventoy_cmd_dynamic_menu(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ static int configfile_mode = 0;
+ char memfile[128] = {0};
+
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ /*
+ * args[0]: 0:normal 1:configfile
+ * args[1]: 0:list_buf 1:tree_buf
+ */
+
+ if (argc != 2)
+ {
+ debug("Invalid argc %d\n", argc);
+ return 0;
+ }
+
+ VTOY_CMD_CHECK(1);
+
+ if (args[0][0] == '0')
+ {
+ if (args[1][0] == '0')
+ {
+ grub_script_execute_sourcecode(g_list_script_buf);
+ }
+ else
+ {
+ grub_script_execute_sourcecode(g_tree_script_buf);
+ }
+ }
+ else
+ {
+ if (configfile_mode)
+ {
+ debug("Now already in F3 mode %d\n", configfile_mode);
+ return 0;
+ }
+
+ if (args[1][0] == '0')
+ {
+ grub_snprintf(memfile, sizeof(memfile), "configfile mem:0x%llx:size:%d",
+ (ulonglong)(ulong)g_list_script_buf, g_list_script_pos);
+ }
+ else
+ {
+ g_ventoy_last_entry = -1;
+ grub_snprintf(memfile, sizeof(memfile), "configfile mem:0x%llx:size:%d",
+ (ulonglong)(ulong)g_tree_script_buf, g_tree_script_pos);
+ }
+
+ configfile_mode = 1;
+ grub_script_execute_sourcecode(memfile);
+ configfile_mode = 0;
+ }
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_file_exist_nocase(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ grub_file_t file;
+
+ (void)ctxt;
+
+ if (argc != 1)
+ {
+ return 1;
+ }
+
+ g_ventoy_case_insensitive = 1;
+ file = grub_file_open(args[0], VENTOY_FILE_TYPE);
+ g_ventoy_case_insensitive = 0;
+
+ grub_errno = 0;
+
+ if (file)
+ {
+ grub_file_close(file);
+ return 0;
+ }
+ return 1;
+}
+
+static grub_err_t ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int id = 0;
+ int find = 0;
+ grub_disk_t disk;
+ const char *isopath = NULL;
+ char hdname[32];
+ ventoy_mbr_head mbr;
+
+ (void)ctxt;
+ (void)argc;
+
+ if (argc != 1)
+ {
+ return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s variable\n", cmd_raw_name);
+ }
+
+ isopath = grub_env_get("vtoy_iso_part");
+ if (!isopath)
+ {
+ debug("isopath is null %p\n", isopath);
+ return 0;
+ }
+
+ debug("isopath is %s\n", isopath);
+
+ for (id = 0; id < 30 && (find == 0); id++)
+ {
+ grub_snprintf(hdname, sizeof(hdname), "hd%d,", id);
+ if (grub_strstr(isopath, hdname))
+ {
+ debug("skip %s ...\n", hdname);
+ continue;
+ }
+
+ grub_snprintf(hdname, sizeof(hdname), "hd%d", id);
+
+ disk = grub_disk_open(hdname);
+ if (!disk)
+ {
+ debug("%s not exist\n", hdname);
+ break;
+ }
+
+ grub_memset(&mbr, 0, sizeof(mbr));
+ if (0 == grub_disk_read(disk, 0, 0, 512, &mbr))
+ {
+ if (mbr.Byte55 == 0x55 && mbr.ByteAA == 0xAA)
+ {
+ if (mbr.PartTbl[0].Active == 0x80 || mbr.PartTbl[1].Active == 0x80 ||
+ mbr.PartTbl[2].Active == 0x80 || mbr.PartTbl[3].Active == 0x80)
+ {
+
+ grub_env_set(args[0], hdname);
+ find = 1;
+ }
+ }
+ debug("%s is %s\n", hdname, find ? "bootable" : "NOT bootable");
+ }
+ else
+ {
+ debug("read %s failed\n", hdname);
+ }
+
+ grub_disk_close(disk);
+ }
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_read_1st_line(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int len = 1024;
+ grub_file_t file;
+ char *buf = NULL;
+
+ (void)ctxt;
+ (void)argc;
+
+ if (argc != 2)
+ {
+ return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s file var \n", cmd_raw_name);
+ }
+
+ file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
+ if (!file)
+ {
+ debug("failed to open file %s\n", args[0]);
+ return 0;
+ }
+
+ buf = grub_malloc(len);
+ if (!buf)
+ {
+ goto end;
+ }
+
+ buf[len - 1] = 0;
+ grub_file_read(file, buf, len - 1);
+
+ ventoy_get_line(buf);
+ ventoy_set_env(args[1], buf);
+
+end:
+
+ grub_check_free(buf);
+ grub_file_close(file);
+
+ return 0;
+}
+
+static int ventoy_img_partition_callback (struct grub_disk *disk, const grub_partition_t partition, void *data)
+{
+ (void)disk;
+ (void)data;
+
+ g_part_list_pos += grub_snprintf(g_part_list_buf + g_part_list_pos, VTOY_MAX_SCRIPT_BUF - g_part_list_pos,
+ "0 %llu linear /dev/ventoy %llu\n",
+ (ulonglong)partition->len, (ulonglong)partition->start);
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_img_part_info(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ char *device_name = NULL;
+ grub_device_t dev = NULL;
+ char buf[64];
+
+ (void)ctxt;
+
+ g_part_list_pos = 0;
+ grub_env_unset("vtoy_img_part_file");
+
+ if (argc != 1)
+ {
+ return 1;
+ }
+
+ device_name = grub_file_get_device_name(args[0]);
+ if (!device_name)
+ {
+ debug("ventoy_cmd_img_part_info failed, %s\n", args[0]);
+ goto end;
+ }
+
+ dev = grub_device_open(device_name);
+ if (!dev)
+ {
+ debug("grub_device_open failed, %s\n", device_name);
+ goto end;
+ }
+
+ grub_partition_iterate(dev->disk, ventoy_img_partition_callback, NULL);
+
+ grub_snprintf(buf, sizeof(buf), "newc:vtoy_dm_table:mem:0x%llx:size:%d", (ulonglong)(ulong)g_part_list_buf, g_part_list_pos);
+ grub_env_set("vtoy_img_part_file", buf);
+
+end:
+
+ check_free(device_name, grub_free);
+ check_free(dev, grub_device_close);
+
+ return 0;
+}
+
+
+static grub_err_t ventoy_cmd_file_strstr(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int rc = 1;
+ grub_file_t file;
+ char *buf = NULL;
+
+ (void)ctxt;
+ (void)argc;
+
+ if (argc != 2)
+ {
+ return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s file str \n", cmd_raw_name);
+ }
+
+ file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
+ if (!file)
+ {
+ debug("failed to open file %s\n", args[0]);
+ return 1;
+ }
+
+ buf = grub_malloc(file->size + 1);
+ if (!buf)
+ {
+ goto end;
+ }
+
+ buf[file->size] = 0;
+ grub_file_read(file, buf, file->size);
+
+ if (grub_strstr(buf, args[1]))
+ {
+ rc = 0;
+ }
+
+end:
+
+ grub_check_free(buf);
+ grub_file_close(file);
+
+ return rc;
+}
+
+static grub_err_t ventoy_cmd_parse_volume(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int len;
+ grub_file_t file;
+ char buf[64];
+ grub_uint64_t size;
+ ventoy_iso9660_vd pvd;
+
+ (void)ctxt;
+ (void)argc;
+
+ if (argc != 4)
+ {
+ return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s sysid volid space \n", cmd_raw_name);
+ }
+
+ file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
+ if (!file)
+ {
+ debug("failed to open file %s\n", args[0]);
+ return 0;
+ }
+
+ grub_file_seek(file, 16 * 2048);
+ len = (int)grub_file_read(file, &pvd, sizeof(pvd));
+ if (len != sizeof(pvd))
+ {
+ debug("failed to read pvd %d\n", len);
+ goto end;
+ }
+
+ grub_memset(buf, 0, sizeof(buf));
+ grub_memcpy(buf, pvd.sys, sizeof(pvd.sys));
+ ventoy_set_env(args[1], buf);
+
+ grub_memset(buf, 0, sizeof(buf));
+ grub_memcpy(buf, pvd.vol, sizeof(pvd.vol));
+ ventoy_set_env(args[2], buf);
+
+ size = pvd.space;
+ size *= 2048;
+ grub_snprintf(buf, sizeof(buf), "%llu", (ulonglong)size);
+ ventoy_set_env(args[3], buf);
+
+end:
+ grub_file_close(file);
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_parse_create_date(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int len;
+ grub_file_t file;
+ char buf[64];
+
+ (void)ctxt;
+ (void)argc;
+
+ if (argc != 2)
+ {
+ return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s var \n", cmd_raw_name);
+ }
+
+ file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
+ if (!file)
+ {
+ debug("failed to open file %s\n", args[0]);
+ return 0;
+ }
+
+ grub_memset(buf, 0, sizeof(buf));
+ grub_file_seek(file, 16 * 2048 + 813);
+ len = (int)grub_file_read(file, buf, 17);
+ if (len != 17)
+ {
+ debug("failed to read create date %d\n", len);
+ goto end;
+ }
+
+ ventoy_set_env(args[1], buf);
+
+end:
+ grub_file_close(file);
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_img_hook_root(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ ventoy_env_hook_root(1);
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_img_unhook_root(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ ventoy_env_hook_root(0);
+
+ return 0;
+}
+
+#ifdef GRUB_MACHINE_EFI
+static grub_err_t ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int ret = 1;
+ grub_uint8_t *var;
+ grub_size_t size;
+ grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
+
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ var = grub_efi_get_variable("SecureBoot", &global, &size);
+ if (var && *var == 1)
+ {
+ return 0;
+ }
+
+ return ret;
+}
+#else
+static grub_err_t ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+ return 1;
+}
+#endif
+
+static grub_err_t ventoy_cmd_img_check_range(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int i;
+ int ret = 1;
+ grub_file_t file;
+ grub_uint64_t FileSectors = 0;
+ ventoy_gpt_info *gpt = NULL;
+ ventoy_part_table *pt = NULL;
+ grub_uint8_t zeroguid[16] = {0};
+
+ (void)ctxt;
+ (void)argc;
+
+ file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
+ if (!file)
+ {
+ debug("failed to open file %s\n", args[0]);
+ return 1;
+ }
+
+ if (file->size % 512)
+ {
+ debug("unaligned file size: %llu\n", (ulonglong)file->size);
+ goto out;
+ }
+
+ gpt = grub_zalloc(sizeof(ventoy_gpt_info));
+ if (!gpt)
+ {
+ goto out;
+ }
+
+ FileSectors = file->size / 512;
+
+ grub_file_read(file, gpt, sizeof(ventoy_gpt_info));
+ if (grub_strncmp(gpt->Head.Signature, "EFI PART", 8) == 0)
+ {
+ debug("This is EFI partition table\n");
+
+ for (i = 0; i < 128; i++)
+ {
+ if (grub_memcmp(gpt->PartTbl[i].PartGuid, zeroguid, 16))
+ {
+ if (FileSectors < gpt->PartTbl[i].LastLBA)
+ {
+ debug("out of range: part[%d] LastLBA:%llu FileSectors:%llu\n", i,
+ (ulonglong)gpt->PartTbl[i].LastLBA, (ulonglong)FileSectors);
+ goto out;
+ }
+ }
+ }
+ }
+ else
+ {
+ debug("This is MBR partition table\n");
+
+ for (i = 0; i < 4; i++)
+ {
+ pt = gpt->MBR.PartTbl + i;
+ if (FileSectors < pt->StartSectorId + pt->SectorCount)
+ {
+ debug("out of range: part[%d] LastLBA:%llu FileSectors:%llu\n", i,
+ (ulonglong)(pt->StartSectorId + pt->SectorCount),
+ (ulonglong)FileSectors);
+ goto out;
+ }
+ }
+ }
+
+ ret = 0;
+
+out:
+ grub_file_close(file);
+ grub_check_free(gpt);
+ grub_errno = GRUB_ERR_NONE;
+ return ret;
+}
+
+static grub_err_t ventoy_cmd_clear_key(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int i;
+ int ret;
+
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ for (i = 0; i < 500; i++)
+ {
+ ret = grub_getkey_noblock();
+ if (ret == GRUB_TERM_NO_KEY)
+ {
+ break;
+ }
+ }
+
+ if (i >= 500)
+ {
+ grub_cls();
+ grub_printf("\n\n Still have key input after clear.\n");
+ grub_refresh();
+ grub_sleep(5);
+ }
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_acpi_param(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int i;
+ int buflen;
+ int datalen;
+ int loclen;
+ int img_chunk_num;
+ int image_sector_size;
+ char cmd[64];
+ ventoy_chain_head *chain;
+ ventoy_img_chunk *chunk;
+ ventoy_os_param *osparam;
+ ventoy_image_location *location;
+ ventoy_image_disk_region *region;
+ struct grub_acpi_table_header *acpi;
+
+ (void)ctxt;
+
+ if (argc != 2)
+ {
+ return 1;
+ }
+
+ debug("ventoy_cmd_acpi_param %s %s\n", args[0], args[1]);
+
+ chain = (ventoy_chain_head *)(ulong)grub_strtoul(args[0], NULL, 16);
+ if (!chain)
+ {
+ return 1;
+ }
+
+ image_sector_size = (int)grub_strtol(args[1], NULL, 10);
+
+ if (grub_memcmp(&g_ventoy_guid, &(chain->os_param.guid), 16))
+ {
+ debug("Invalid ventoy guid 0x%x\n", chain->os_param.guid.data1);
+ return 1;
+ }
+
+ img_chunk_num = chain->img_chunk_num;
+
+ loclen = sizeof(ventoy_image_location) + (img_chunk_num - 1) * sizeof(ventoy_image_disk_region);
+ datalen = sizeof(ventoy_os_param) + loclen;
+
+ buflen = sizeof(struct grub_acpi_table_header) + datalen;
+ acpi = grub_zalloc(buflen);
+ if (!acpi)
+ {
+ return 1;
+ }
+
+ /* Step1: Fill acpi table header */
+ grub_memcpy(acpi->signature, "VTOY", 4);
+ acpi->length = buflen;
+ acpi->revision = 1;
+ grub_memcpy(acpi->oemid, "VENTOY", 6);
+ grub_memcpy(acpi->oemtable, "OSPARAMS", 8);
+ acpi->oemrev = 1;
+ acpi->creator_id[0] = 1;
+ acpi->creator_rev = 1;
+
+ /* Step2: Fill data */
+ osparam = (ventoy_os_param *)(acpi + 1);
+ grub_memcpy(osparam, &chain->os_param, sizeof(ventoy_os_param));
+ osparam->vtoy_img_location_addr = 0;
+ osparam->vtoy_img_location_len = loclen;
+ osparam->chksum = 0;
+ osparam->chksum = 0x100 - grub_byte_checksum(osparam, sizeof(ventoy_os_param));
+
+ location = (ventoy_image_location *)(osparam + 1);
+ grub_memcpy(&location->guid, &osparam->guid, sizeof(ventoy_guid));
+ location->image_sector_size = image_sector_size;
+ location->disk_sector_size = chain->disk_sector_size;
+ location->region_count = img_chunk_num;
+
+ region = location->regions;
+ chunk = (ventoy_img_chunk *)((char *)chain + chain->img_chunk_offset);
+ if (512 == image_sector_size)
+ {
+ for (i = 0; i < img_chunk_num; i++)
+ {
+ region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1;
+ region->image_start_sector = chunk->img_start_sector * 4;
+ region->disk_start_sector = chunk->disk_start_sector;
+ region++;
+ chunk++;
+ }
+ }
+ else
+ {
+ for (i = 0; i < img_chunk_num; i++)
+ {
+ region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1;
+ region->image_start_sector = chunk->img_start_sector;
+ region->disk_start_sector = chunk->disk_start_sector;
+ region++;
+ chunk++;
+ }
+ }
+
+ /* Step3: Fill acpi checksum */
+ acpi->checksum = 0;
+ acpi->checksum = 0x100 - grub_byte_checksum(acpi, acpi->length);
+
+ /* load acpi table */
+ grub_snprintf(cmd, sizeof(cmd), "acpi mem:0x%lx:size:%d", (ulong)acpi, acpi->length);
+ grub_script_execute_sourcecode(cmd);
+
+ grub_free(acpi);
+
+ VENTOY_CMD_RETURN(0);
+}
+
+static grub_err_t ventoy_cmd_push_last_entry(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ g_ventoy_last_entry_back = g_ventoy_last_entry;
+ g_ventoy_last_entry = -1;
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_pop_last_entry(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ g_ventoy_last_entry = g_ventoy_last_entry_back;
+
+ return 0;
+}
+
+static int ventoy_lib_module_callback(const char *filename, const struct grub_dirhook_info *info, void *data)
+{
+ const char *pos = filename + 1;
+
+ if (info->dir)
+ {
+ while (*pos)
+ {
+ if (*pos == '.')
+ {
+ if ((*(pos - 1) >= '0' && *(pos - 1) <= '9') && (*(pos + 1) >= '0' && *(pos + 1) <= '9'))
+ {
+ grub_strncpy((char *)data, filename, 128);
+ return 1;
+ }
+ }
+ pos++;
+ }
+ }
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_lib_module_ver(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int rc = 1;
+ char *device_name = NULL;
+ grub_device_t dev = NULL;
+ grub_fs_t fs = NULL;
+ char buf[128] = {0};
+
+ (void)ctxt;
+
+ if (argc != 3)
+ {
+ debug("ventoy_cmd_lib_module_ver, invalid param num %d\n", argc);
+ return 1;
+ }
+
+ debug("ventoy_cmd_lib_module_ver %s %s %s\n", args[0], args[1], args[2]);
+
+ device_name = grub_file_get_device_name(args[0]);
+ if (!device_name)
+ {
+ debug("grub_file_get_device_name failed, %s\n", args[0]);
+ goto end;
+ }
+
+ dev = grub_device_open(device_name);
+ if (!dev)
+ {
+ debug("grub_device_open failed, %s\n", device_name);
+ goto end;
+ }
+
+ fs = grub_fs_probe(dev);
+ if (!fs)
+ {
+ debug("grub_fs_probe failed, %s\n", device_name);
+ goto end;
+ }
+
+ fs->fs_dir(dev, args[1], ventoy_lib_module_callback, buf);
+
+ if (buf[0])
+ {
+ ventoy_set_env(args[2], buf);
+ }
+
+ rc = 0;
+
+end:
+
+ check_free(device_name, grub_free);
+ check_free(dev, grub_device_close);
+
+ return rc;
+}
+
+int ventoy_load_part_table(const char *diskname)
+{
+ char name[64];
+ int ret;
+ grub_disk_t disk;
+ grub_device_t dev;
+
+ g_ventoy_part_info = grub_zalloc(sizeof(ventoy_gpt_info));
+ if (!g_ventoy_part_info)
+ {
+ return 1;
+ }
+
+ disk = grub_disk_open(diskname);
+ if (!disk)
+ {
+ debug("Failed to open disk %s\n", diskname);
+ return 1;
+ }
+
+ g_ventoy_disk_size = disk->total_sectors * (1U << disk->log_sector_size);
+
+ grub_disk_read(disk, 0, 0, sizeof(ventoy_gpt_info), g_ventoy_part_info);
+ grub_disk_close(disk);
+
+ grub_snprintf(name, sizeof(name), "%s,1", diskname);
+ dev = grub_device_open(name);
+ if (dev)
+ {
+ /* Check for official Ventoy device */
+ ret = ventoy_check_official_device(dev);
+ grub_device_close(dev);
+
+ if (ret)
+ {
+ return 1;
+ }
+ }
+
+ g_ventoy_disk_part_size[0] = ventoy_get_vtoy_partsize(0);
+ g_ventoy_disk_part_size[1] = ventoy_get_vtoy_partsize(1);
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_load_part_table(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int ret;
+
+ (void)argc;
+ (void)ctxt;
+
+ ret = ventoy_load_part_table(args[0]);
+ if (ret)
+ {
+ grub_exit();
+ }
+
+ g_ventoy_disk_part_size[0] = ventoy_get_vtoy_partsize(0);
+ g_ventoy_disk_part_size[1] = ventoy_get_vtoy_partsize(1);
+
+ return 0;
+}
+
+static grub_err_t ventoy_cmd_check_custom_boot(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ int ret = 1;
+ const char *vcfg = NULL;
+
+ (void)argc;
+ (void)ctxt;
+
+ vcfg = ventoy_plugin_get_custom_boot(args[0]);
+ if (vcfg)
+ {
+ debug("custom boot <%s>:<%s>\n", args[0], vcfg);
+ grub_env_set(args[1], vcfg);
+ ret = 0;
+ }
+ else
+ {
+ debug("custom boot <%s>:<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;
+}
+
+
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
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) \
{ \
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);
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__ */
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);
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;
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;
}
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[] =
{
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);
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)
debug("winload patch %d times\n", cnt);
}
- for (pos = vhdpath; *pos; pos++)
+ newpath = grub_strdup(vhdpath);
+ for (pos = newpath; *pos; pos++)
{
if (*pos == '/')
{
}
}
- 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;
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];
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
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)
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
}
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
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 {
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
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
--- /dev/null
+\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
--- /dev/null
+#!/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 ]
+
+
--- /dev/null
+[
+ {
+ "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
#!/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 =========="
#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
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
STORAGE_BUS_TYPE BusType;\r
\r
CHAR DriveLetters[64];\r
-\r
+ \r
CHAR VentoyVersion[32];\r
\r
BOOL SecureBootSupport;\r
<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" />
<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">
--- /dev/null
+/******************************************************************************\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
--- /dev/null
+/******************************************************************************\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
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)
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;
}