#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();
}