diff --git a/.github/ISSUE_TEMPLATE/issue_template.yml b/.github/ISSUE_TEMPLATE/issue_template.yml index 396c69d7..91029fcd 100644 --- a/.github/ISSUE_TEMPLATE/issue_template.yml +++ b/.github/ISSUE_TEMPLATE/issue_template.yml @@ -21,7 +21,7 @@ body: attributes: label: Ventoy Version description: What version of ventoy are you running? - placeholder: 1.0.66 + placeholder: 1.0.67 validations: required: true - type: dropdown diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def index f7351891..987400db 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def @@ -1610,6 +1610,7 @@ module = { common = ventoy/ventoy_vhd.c; common = ventoy/ventoy_plugin.c; common = ventoy/ventoy_json.c; + common = ventoy/ventoy_browser.c; common = ventoy/lzx.c; common = ventoy/xpress.c; common = ventoy/huffman.c; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/file.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/file.c index 61e02614..22a74414 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/file.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/file.c @@ -114,6 +114,7 @@ typedef struct grub_vlnk struct grub_vlnk *next; }grub_vlnk; +static grub_vlnk g_vtoy_vlnk; static grub_vlnk *g_vlnk_list; int grub_file_is_vlnk_suffix(const char *name, int len) @@ -146,6 +147,23 @@ int grub_file_is_vlnk_suffix(const char *name, int len) return 0; } +int grub_file_vtoy_vlnk(const char *src, const char *dst) +{ + if (src) + { + g_vtoy_vlnk.srclen = (int)grub_strlen(src); + grub_strncpy(g_vtoy_vlnk.src, src, sizeof(g_vtoy_vlnk.src) - 1); + grub_strncpy(g_vtoy_vlnk.dst, dst, sizeof(g_vtoy_vlnk.dst) - 1); + } + else + { + g_vtoy_vlnk.srclen = 0; + g_vtoy_vlnk.src[0] = 0; + g_vtoy_vlnk.dst[0] = 0; + } + return 0; +} + int grub_file_add_vlnk(const char *src, const char *dst) { grub_vlnk *node = NULL; @@ -174,10 +192,17 @@ const char *grub_file_get_vlnk(const char *name, int *vlnk) grub_vlnk *node = g_vlnk_list; len = grub_strlen(name); + if (!grub_file_is_vlnk_suffix(name, len)) { return name; } + + if (len == g_vtoy_vlnk.srclen && grub_strcmp(name, g_vtoy_vlnk.src) == 0) + { + *vlnk = 1; + return g_vtoy_vlnk.dst; + } while (node) { @@ -207,7 +232,7 @@ grub_file_open (const char *name, enum grub_file_type type) return grub_memfile_open(name); } - if (g_vlnk_list && (type & GRUB_FILE_TYPE_NO_VLNK) == 0) + if ((g_vlnk_list || g_vtoy_vlnk.srclen) && (type & GRUB_FILE_TYPE_NO_VLNK) == 0) name = grub_file_get_vlnk(name, &vlnk); device_name = grub_file_get_device_name (name); diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_browser.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_browser.c new file mode 100644 index 00000000..831795bc --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_browser.c @@ -0,0 +1,500 @@ +/****************************************************************************** + * ventoy_browser.c + * + * Copyright (c) 2022, longpanda + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ventoy_def.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define BROWSER_MENU_BUF 65536 + +static grub_fs_t g_menu_fs = NULL; +static char *g_menu_device = NULL; +static char g_menu_path_buf[1024]; +static int g_menu_path_len = 0; +static browser_node *g_browser_list = NULL; + +static int ventoy_browser_strcmp(char *str1, char *str2) +{ + char *s1, *s2; + int c1 = 0; + int c2 = 0; + + for (s1 = str1, s2 = str2; *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_browser_mbuf_alloc(browser_mbuf *mbuf) +{ + grub_memset(mbuf, 0, sizeof(browser_mbuf)); + mbuf->buf = grub_malloc(BROWSER_MENU_BUF); + if (!mbuf->buf) + { + return 0; + } + + mbuf->pos = 0; + mbuf->max = BROWSER_MENU_BUF; + return 1; +} + +static void ventoy_browser_mbuf_free(browser_mbuf *mbuf) +{ + if (mbuf) + grub_check_free(mbuf->buf) +} + +static int ventoy_browser_mbuf_extend(browser_mbuf *mbuf) +{ + if (mbuf->max - mbuf->pos <= VTOY_SIZE_1KB) + { + mbuf->max += BROWSER_MENU_BUF; + mbuf->buf = grub_realloc(mbuf->buf, mbuf->max); + } + + return 0; +} + +static browser_node * ventoy_browser_find_top_node(int dir) +{ + browser_node *node = NULL; + browser_node *sel = NULL; + + for (node = g_browser_list; node; node = node->next) + { + if (node->dir == dir) + { + if (sel) + { + if (ventoy_browser_strcmp(sel->filename, node->filename) > 0) + { + sel = node; + } + } + else + { + sel = node; + } + } + } + + return sel; +} + +static int ventoy_browser_check_filename(const char *filename, int len, int *type) +{ + 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 + { + return 0; + } + + if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_') + { + return 0; + } + + return 1; +} + + +static int ventoy_browser_iterate_partition(struct grub_disk *disk, const grub_partition_t partition, void *data) +{ + char partname[64]; + char title[256]; + grub_device_t dev; + grub_fs_t fs; + char *Label = NULL; + browser_mbuf *mbuf = (browser_mbuf *)data; + + (void)data; + + grub_snprintf(partname, sizeof(partname) - 1, "%s,%d", disk->name, partition->number + 1); + + dev = grub_device_open(partname); + if (!dev) + { + return 0; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + grub_device_close(dev); + return 0; + } + + fs->fs_label(dev, &Label); + + grub_snprintf(title, sizeof(title), "%-10s (%s,%s%d) [%s] %s %s", + "DISK", disk->name, partition->msdostype == 0xee ? "gpt" : "msdos", + partition->number + 1, (Label ? Label : ""), fs->name, + grub_get_human_size(partition->len << disk->log_sector_size, GRUB_HUMAN_SIZE_SHORT)); + + if (ventoy_get_fs_type(fs->name) >= ventoy_fs_max) + { + browser_ssprintf(mbuf, "menuentry \"%s\" --class=vtoydisk {\n" + " echo \"unsupported file system type!\" \n" + " ventoy_pause\n" + "}\n", + title); + } + else + { + browser_ssprintf(mbuf, "menuentry \"%s\" --class=vtoydisk {\n" + " vt_browser_dir %s,%d 0x%lx /\n" + "}\n", + title, disk->name, partition->number + 1, (ulong)fs); + } + + ventoy_browser_mbuf_extend(mbuf); + + return 0; +} + + +static int ventoy_browser_iterate_disk(const char *name, void *data) +{ + grub_disk_t disk; + grub_uint32_t sig; + grub_uint32_t selfsig; + + grub_memcpy(&selfsig, g_ventoy_part_info->MBR.BootCode + 0x1b8, 4); + + if (name[0] != 'h') + { + return 0; + } + + disk = grub_disk_open(name); + if (disk) + { + grub_disk_read(disk, 0, 0x1b8, 4, &sig); + + /* skip ventoy device self */ + if (sig != selfsig) + { + grub_partition_iterate(disk, ventoy_browser_iterate_partition, data); + } + + grub_disk_close(disk); + } + + return 0; +} + +static int ventoy_browser_iterate_dir(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + int type; + int len; + browser_node *node; + + (void)data; + + len = grub_strlen(filename); + + if (info->dir) + { + 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] == '$') + { + if (0 == grub_strncmp(filename, "$RECYCLE.BIN", 12) || + 0 == grub_strncasecmp(filename, "$Extend", 7)) + { + return 0; + } + } + + node = grub_zalloc(sizeof(browser_node)); + if (!node) + { + return 0; + } + + node->dir = 1; + grub_strncpy(node->filename, filename, sizeof(node->filename)); + grub_snprintf(node->menuentry, sizeof(node->menuentry), + "menuentry \"%-10s [%s]\" --class=vtoydir {\n" + " vt_browser_dir %s 0x%lx \"%s/%s\"\n" + "}\n", + "DIR", filename, g_menu_device, (ulong)g_menu_fs, g_menu_path_buf, filename); + } + else + { + grub_uint64_t fsize; + grub_file_t file = NULL; + + if (ventoy_browser_check_filename(filename, len, &type) == 0) + { + return 0; + } + + fsize = info->size; + if (fsize == 0) + { + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(%s)%s/%s", g_menu_device, g_menu_path_buf, filename); + if (!file) + { + return 0; + } + + fsize = file->size; + grub_file_close(file); + } + + if (fsize < VTOY_FILT_MIN_FILE_SIZE) + { + return 0; + } + + node = grub_zalloc(sizeof(browser_node)); + if (!node) + { + return 0; + } + + node->dir = 0; + grub_strncpy(node->filename, filename, sizeof(node->filename)); + grub_snprintf(node->menuentry, sizeof(node->menuentry), + "menuentry \"%-10s %s\" --class=%s {\n" + " vt_set_fake_vlnk \"(%s)%s/%s\" %s %llu\n" + " %s_common_menuentry\n" + " vt_reset_fake_vlnk\n" + "}\n", + grub_get_human_size(fsize, GRUB_HUMAN_SIZE_SHORT), filename, g_menu_class[type], + g_menu_device, g_menu_path_buf, filename, g_menu_prefix[type], (ulonglong)fsize, + g_menu_prefix[type]); + + } + + node->prev = NULL; + node->next = g_browser_list; + if (g_browser_list) + { + g_browser_list->prev = node; + } + g_browser_list = node; + + return 0; +} + +grub_err_t ventoy_cmd_browser_dir(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + grub_fs_t fs; + grub_device_t dev; + char cfgfile[64]; + browser_node *node; + browser_mbuf mbuf; + + (void)ctxt; + (void)argc; + + if (!ventoy_browser_mbuf_alloc(&mbuf)) + { + return 1; + } + + fs = (grub_fs_t)grub_strtoul(args[1], NULL, 16); + if (!fs) + { + debug("Invalid fs %s\n", args[1]); + return 1; + } + + dev = grub_device_open(args[0]); + if (!dev) + { + debug("Failed to open device %s\n", args[0]); + return 1; + } + + g_menu_fs = fs; + g_menu_device = args[0]; + g_browser_list = NULL; + + if (args[2][0] == '/' && args[2][1] == 0) + { + g_menu_path_len = 0; + g_menu_path_buf[0] = 0; + fs->fs_dir(dev, "/", ventoy_browser_iterate_dir, NULL); + } + else + { + g_menu_path_len = grub_snprintf(g_menu_path_buf, sizeof(g_menu_path_buf), "%s", args[2]); + fs->fs_dir(dev, g_menu_path_buf, ventoy_browser_iterate_dir, NULL); + } + grub_device_close(dev); + + browser_ssprintf(&mbuf, "menuentry \"%-10s [../]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n}\n", "<--"); + + for (i = 1; i >= 0; i--) + { + while (1) + { + node = ventoy_browser_find_top_node(i); + if (node) + { + grub_printf("Find Node <%s>\n", node->filename); + browser_ssprintf(&mbuf, "%s", node->menuentry); + if (node->prev) + { + node->prev->next = node->next; + } + if (node->next) + { + node->next->prev = node->prev; + } + + if (node == g_browser_list) + { + g_browser_list = node->next; + } + grub_free(node); + } + else + { + break; + } + } + } + g_browser_list = NULL; + + grub_snprintf(cfgfile, sizeof(cfgfile), "configfile mem:0x%lx:size:%d", (ulong)mbuf.buf, mbuf.pos); + grub_script_execute_sourcecode(cfgfile); + + ventoy_browser_mbuf_free(&mbuf); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_browser_disk(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char cfgfile[64]; + browser_mbuf mbuf; + + (void)ctxt; + (void)argc; + (void)args; + + if (!ventoy_browser_mbuf_alloc(&mbuf)) + { + return 1; + } + + browser_ssprintf(&mbuf, "menuentry \"%-10s [Return]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n}\n", "<--"); + + grub_disk_dev_iterate(ventoy_browser_iterate_disk, &mbuf); + + grub_snprintf(cfgfile, sizeof(cfgfile), "configfile mem:0x%lx:size:%d", (ulong)mbuf.buf, mbuf.pos); + grub_script_execute_sourcecode(cfgfile); + + ventoy_browser_mbuf_free(&mbuf); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c index 2fb78c30..161ad7c8 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c @@ -134,14 +134,14 @@ 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}; +int g_vtoy_file_flt[VTOY_FILE_FLT_BUTT] = {0}; static int g_pager_flag = 0; static char g_old_pager[32]; static const char *g_vtoy_winpeshl_ini = "[LaunchApps]\r\nvtoyjump.exe"; -static const char *g_menu_class[] = +const char *g_menu_class[img_type_max] = { "vtoyiso", "vtoywim", "vtoyefi", "vtoyimg", "vtoyvhd", "vtoyvtoy" }; @@ -158,7 +158,7 @@ static char g_json_case_mis_path[32]; static ventoy_vlnk_part *g_vlnk_part_list = NULL; -static int ventoy_get_fs_type(const char *fs) +int ventoy_get_fs_type(const char *fs) { if (NULL == fs) { @@ -686,10 +686,10 @@ 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}; + char fullpath[512] = {0}; va_start (ap, fmt); - grub_vsnprintf(fullpath, 255, fmt, ap); + grub_vsnprintf(fullpath, 511, fmt, ap); va_end (ap); file = grub_file_open(fullpath, type); @@ -707,13 +707,13 @@ int ventoy_is_dir_exist(const char *fmt, ...) va_list ap; int len; char *pos = NULL; - char buf[256] = {0}; + char buf[512] = {0}; grub_snprintf(buf, sizeof(buf), "%s", "[ -d \""); pos = buf + 6; va_start (ap, fmt); - len = grub_vsnprintf(pos, 255, fmt, ap); + len = grub_vsnprintf(pos, 511, fmt, ap); va_end (ap); grub_strncpy(pos + len, "\" ]", 3); @@ -1582,7 +1582,7 @@ void ventoy_swap_img(img_info *img1, img_info *img2) grub_memcpy(img2, &g_img_swap_tmp, sizeof(img_info)); } -static int ventoy_img_name_valid(const char *filename, grub_size_t namelen) +int ventoy_img_name_valid(const char *filename, grub_size_t namelen) { (void)namelen; @@ -2564,6 +2564,40 @@ static grub_err_t ventoy_cmd_ext_select_img_path(grub_extcmd_context_t ctxt, int VENTOY_CMD_RETURN(GRUB_ERR_NONE); } +static char g_fake_vlnk_src[512]; +static char g_fake_vlnk_dst[512]; +static grub_uint64_t g_fake_vlnk_size; +static grub_err_t ventoy_cmd_set_fake_vlnk(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_fake_vlnk_size = (grub_uint64_t)grub_strtoull(args[2], NULL, 10); + + grub_strncpy(g_fake_vlnk_dst, args[0], sizeof(g_fake_vlnk_dst)); + grub_snprintf(g_fake_vlnk_src, sizeof(g_fake_vlnk_src), "%s/________VENTOYVLNK.vlnk.%s", g_iso_path, args[1]); + + grub_file_vtoy_vlnk(g_fake_vlnk_src, g_fake_vlnk_dst); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_reset_fake_vlnk(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_fake_vlnk_src[0] = 0; + g_fake_vlnk_dst[0] = 0; + g_fake_vlnk_size = 0; + grub_file_vtoy_vlnk(NULL, NULL); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + + static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int argc, char **args) { char value[32]; @@ -2578,6 +2612,18 @@ static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int arg return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {var}", cmd_raw_name); } + if (g_fake_vlnk_src[0] && g_fake_vlnk_dst[0]) + { + grub_env_set(args[0], grub_strchr(g_fake_vlnk_src, '/')); + if (argc > 1) + { + grub_snprintf(value, sizeof(value), "%llu", (ulonglong)(g_fake_vlnk_size)); + grub_env_set(args[1], value); + } + + goto end; + } + id = grub_env_get("chosen"); pos = grub_strstr(id, "VID_"); @@ -2603,6 +2649,7 @@ static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int arg grub_env_set(args[1], value); } +end: g_svd_replace_offset = 0; VENTOY_CMD_RETURN(GRUB_ERR_NONE); @@ -5468,6 +5515,8 @@ int ventoy_env_init(void) static cmd_para ventoy_cmds[] = { + { "vt_browser_disk", ventoy_cmd_browser_disk, 0, NULL, "", "", NULL }, + { "vt_browser_dir", ventoy_cmd_browser_dir, 0, NULL, "", "", NULL }, { "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 }, @@ -5608,6 +5657,8 @@ static cmd_para ventoy_cmds[] = { "vt_vlnk_dump_part", grub_cmd_vlnk_dump_part, 0, NULL, "", "", NULL }, { "vt_is_vlnk_name", grub_cmd_is_vlnk_name, 0, NULL, "", "", NULL }, { "vt_get_vlnk_dst", grub_cmd_get_vlnk_dst, 0, NULL, "", "", NULL }, + { "vt_set_fake_vlnk", ventoy_cmd_set_fake_vlnk, 0, NULL, "", "", NULL }, + { "vt_reset_fake_vlnk", ventoy_cmd_reset_fake_vlnk, 0, NULL, "", "", NULL }, }; int ventoy_register_all_cmd(void) diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h index 69d34400..f00ce37e 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h @@ -35,6 +35,7 @@ #define VTOY_SIZE_4MB (4 * 1024 * 1024) #define VTOY_SIZE_512KB (512 * 1024) #define VTOY_SIZE_1KB 1024 +#define VTOY_SIZE_32KB (32 * 1024) #define JSON_SUCCESS 0 #define JSON_FAILED 1 @@ -315,6 +316,9 @@ void ventoy_debug(const char *fmt, ...); #define vtoy_ssprintf(buf, pos, fmt, ...) \ pos += grub_snprintf(buf + pos, VTOY_MAX_SCRIPT_BUF - pos, fmt, __VA_ARGS__) +#define browser_ssprintf(mbuf, fmt, args...) \ + (mbuf)->pos += grub_snprintf((mbuf)->buf + (mbuf)->pos, (mbuf)->max - (mbuf)->pos, fmt, ##args) + #define FLAG_HEADER_RESERVED 0x00000001 #define FLAG_HEADER_COMPRESSION 0x00000002 #define FLAG_HEADER_READONLY 0x00000004 @@ -1166,8 +1170,34 @@ typedef struct ventoy_vlnk_part struct ventoy_vlnk_part *next; }ventoy_vlnk_part; + +typedef struct browser_mbuf +{ + int max; + int pos; + char *buf; +}browser_mbuf; + +typedef struct browser_node +{ + int dir; + char menuentry[1024]; + char filename[512]; + struct browser_node *prev; + struct browser_node *next; +}browser_node; + +extern int g_sort_case_sensitive; +extern int g_wimboot_enable; +extern int g_filt_dot_underscore_file; +extern int g_vtoy_file_flt[VTOY_FILE_FLT_BUTT]; +extern const char *g_menu_class[img_type_max]; extern char g_iso_path[256]; int ventoy_add_vlnk_file(char *dir, const char *name); +grub_err_t ventoy_cmd_browser_dir(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_browser_disk(grub_extcmd_context_t ctxt, int argc, char **args); +int ventoy_get_fs_type(const char *fs); +int ventoy_img_name_valid(const char *filename, grub_size_t namelen); #endif /* __VENTOY_DEF_H__ */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/file.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/file.h index 2d64b590..21af4e04 100644 --- a/GRUB2/MOD_SRC/grub-2.04/include/grub/file.h +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/file.h @@ -218,6 +218,7 @@ grub_err_t EXPORT_FUNC(grub_file_close) (grub_file_t file); int EXPORT_FUNC(grub_file_is_vlnk_suffix)(const char *name, int len); int EXPORT_FUNC(grub_file_add_vlnk)(const char *src, const char *dst); +int EXPORT_FUNC(grub_file_vtoy_vlnk)(const char *src, const char *dst); const char * EXPORT_FUNC(grub_file_get_vlnk)(const char *name, int *vlnk); /* Return value of grub_file_size() in case file size is unknown. */ diff --git a/INSTALL/grub/debug.cfg b/INSTALL/grub/debug.cfg index 9ccf3387..6b8f8c2b 100644 --- a/INSTALL/grub/debug.cfg +++ b/INSTALL/grub/debug.cfg @@ -1,4 +1,5 @@ +source $prefix/power.cfg source $prefix/keyboard.cfg submenu "Resolution Configuration" --class=debug_resolution --class=F5tool { diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg index 1059f846..1107c78e 100644 --- a/INSTALL/grub/grub.cfg +++ b/INSTALL/grub/grub.cfg @@ -65,10 +65,6 @@ function ventoy_vcfg_proc { fi } -function ventoy_power { - configfile $prefix/power.cfg -} - function ventoy_diagnosis { vt_enum_video_mode configfile $prefix/debug.cfg @@ -2073,7 +2069,7 @@ function img_unsupport_menuentry { ############################################################# ############################################################# -set VENTOY_VERSION="1.0.66" +set VENTOY_VERSION="1.0.67" #ACPI not compatible with Window7/8, so disable by default set VTOY_PARAM_NO_ACPI=1 @@ -2081,7 +2077,7 @@ set VTOY_PARAM_NO_ACPI=1 # Default menu display mode, you can change it as you want. # 0: List mode # 1: TreeView mode -set VTOY_DEFAULT_MENU_MODE=1 +set VTOY_DEFAULT_MENU_MODE=0 set VTOY_MEM_DISK_STR="[Memdisk]" set VTOY_ISO_RAW_STR="Compatible Mode" @@ -2089,7 +2085,7 @@ set VTOY_GRUB2_MODE_STR="GRUB2 Mode" set VTOY_WIMBOOT_MODE_STR="WIMBOOT Mode" set VTOY_ISO_UEFI_DRV_STR="UEFI FS" -set VTOY_F2_CMD="ventoy_power" +set VTOY_F2_CMD="vt_browser_disk" set VTOY_F4_CMD="ventoy_localboot" set VTOY_F5_CMD="ventoy_diagnosis" set VTOY_F6_CMD="ventoy_ext_menu" @@ -2187,10 +2183,10 @@ fi if [ $VTOY_DEFAULT_MENU_MODE -eq 0 ]; then set VTOY_F3_CMD="vt_dynamic_menu 1 1" - set VTOY_HOTKEY_TIP="h:Help F1:Memdisk F2:Power F3:TreeView F4:Localboot F5:Tools F6:ExMenu" + set VTOY_HOTKEY_TIP="h:Help F1:Memdisk F2:Browser F3:TreeView F4:Localboot F5:Tools F6:ExMenu" else set VTOY_F3_CMD="vt_dynamic_menu 1 0" - set VTOY_HOTKEY_TIP="h:Help F1:Memdisk F2:Power F3:ListView F4:Localboot F5:Tools F6:ExMenu" + set VTOY_HOTKEY_TIP="h:Help F1:Memdisk F2:Browser F3:ListView F4:Localboot F5:Tools F6:ExMenu" fi terminal_output console @@ -2310,9 +2306,7 @@ if [ -n "$VTOY_DEFAULT_IMAGE" ]; then export timeout export default - if [ "$vtHotkey" = "F2" ]; then - ventoy_power - elif [ "$vtHotkey" = "F4" ]; then + if [ "$vtHotkey" = "F4" ]; then ventoy_localboot elif [ "$vtHotkey" = "F5" ]; then ventoy_diagnosis diff --git a/INSTALL/grub/help/de_DE.txt b/INSTALL/grub/help/de_DE.txt index a04d1034..e36f1143 100644 --- a/INSTALL/grub/help/de_DE.txt +++ b/INSTALL/grub/help/de_DE.txt @@ -1,6 +1,6 @@ h - Zeigt dieses Hilfe Menu F1 - Memdisk Modus (Nur für kleine WinPE/LiveCD ISO/IMG) -F2 - Neustarten/Herunterfahren +F2 - Browse and boot files in local disk F3 - Menu wechsel zwischen Baum <-> Listen Ansicht F4 - Windows/Linux vom lokalem Datenträger starten F5 - Dienstprogramme diff --git a/INSTALL/grub/help/en_US.txt b/INSTALL/grub/help/en_US.txt index f75c8109..e9fd7438 100644 --- a/INSTALL/grub/help/en_US.txt +++ b/INSTALL/grub/help/en_US.txt @@ -1,6 +1,6 @@ h - Display this help information F1 - Memdisk Mode (Only for small WinPE/LiveCD ISO/IMG) -F2 - Reboot/Power off +F2 - Browse and boot files in local disk F3 - Switch menu mode between Treeview <-> ListView F4 - Boot Windows/Linux in local disk F5 - Utilities diff --git a/INSTALL/grub/help/fr_FR.txt b/INSTALL/grub/help/fr_FR.txt index ece0d282..ac61e1fc 100644 --- a/INSTALL/grub/help/fr_FR.txt +++ b/INSTALL/grub/help/fr_FR.txt @@ -1,6 +1,6 @@ h - Afficher cette aide F1 - Mode Memdisk (Seulement pour WinPE/LiveCD ISO/IMG) -F2 - Redémarrer/arrêter +F2 - Browse and boot files in local disk F3 - Basculer l'affichage 'Vue en arbre' <-> 'Vue en liste' F4 - Démarrer le système Windows/Linux local F5 - Utilitaires diff --git a/INSTALL/grub/help/hr_HR.txt b/INSTALL/grub/help/hr_HR.txt index 04bd1ada..33eb810d 100644 --- a/INSTALL/grub/help/hr_HR.txt +++ b/INSTALL/grub/help/hr_HR.txt @@ -1,6 +1,6 @@ h - Prikazuje ove informacije F1 - Memdisk način rada (samo za male WinPE/LiveCD imidž fajlove) -F2 - Ponovno pokretanje/isključivanje +F2 - Browse and boot files in local disk F3 - Mijenja meni između TreeView <-> ListView F4 - Pokreće Windows/Linux na lokalnom disku F5 - Postavke diff --git a/INSTALL/grub/help/id_ID.txt b/INSTALL/grub/help/id_ID.txt index 879e0e90..34962959 100644 --- a/INSTALL/grub/help/id_ID.txt +++ b/INSTALL/grub/help/id_ID.txt @@ -1,6 +1,6 @@ h - Tampilkan bantuan informasi ini F1 - Mode Memdisk (Hanya untuk ukuran WinPE/LiveCD ISO/IMG yang kecil) -F2 - Mulai ulang/Matikan +F2 - Browse and boot files in local disk F3 - Beralih mode menu antara Treeview <-> ListView F4 - Jalankan (boot) Windows/Linux pada disk lokal F5 - Alat Utilitas diff --git a/INSTALL/grub/help/ja_JP.txt b/INSTALL/grub/help/ja_JP.txt index c7febd52..4f78dc4d 100644 --- a/INSTALL/grub/help/ja_JP.txt +++ b/INSTALL/grub/help/ja_JP.txt @@ -1,6 +1,6 @@ h - この画面を表示する F1 - 主記憶装置上に記憶域を作成する(容量の小さなWinPE・LiveCD専用) -F2 - 再起動・電源断 +F2 - Browse and boot files in local disk F3 - 表示形式を切り替える(一覧 ↔ 階層) F4 - 手元の記憶装置にあるOSを起動する F5 - 諸機能 diff --git a/INSTALL/grub/help/pt_PT.txt b/INSTALL/grub/help/pt_PT.txt index ee8f8f9e..93edece3 100644 --- a/INSTALL/grub/help/pt_PT.txt +++ b/INSTALL/grub/help/pt_PT.txt @@ -1,6 +1,6 @@ h - Mostra esta informação de ajuda F1 - Modo Memdisk (Apenas para pequenos WinPE/LiveCD ISO/IMG) -F2 - Reiniciar/Desligar +F2 - Browse and boot files in local disk F3 - Alternar o modo menu entre Vista de árvore <-> Vista de lista F4 - Arrancar o Windows/Linux em disco local F5 - Utilitários diff --git a/INSTALL/grub/help/sr_CY.txt b/INSTALL/grub/help/sr_CY.txt index b9fde242..73d2acf1 100644 --- a/INSTALL/grub/help/sr_CY.txt +++ b/INSTALL/grub/help/sr_CY.txt @@ -1,6 +1,6 @@ h - Приказује ове информације F1 - Memdisk начин рада (само за мале WinPE/LiveCD имиџ фајлове) -F2 - Поновно покретање/искључивање +F2 - Browse and boot files in local disk F3 - Мијења мени између TreeView <-> ListView F4 - Покреће Windows/Linux на локалном диску F5 - Поставке diff --git a/INSTALL/grub/help/sr_SR.txt b/INSTALL/grub/help/sr_SR.txt index faf445e0..8eeeef4f 100644 --- a/INSTALL/grub/help/sr_SR.txt +++ b/INSTALL/grub/help/sr_SR.txt @@ -1,6 +1,6 @@ h - Prikazuje ove informacije F1 - Memdisk način rada (samo za male WinPE/LiveCD imidž fajlove) -F2 - Ponovno pokretanje/isključivanje +F2 - Browse and boot files in local disk F3 - Mijenja meni između TreeView <-> ListView F4 - Pokreće Windows/Linux na lokalnom disku F5 - Postavke diff --git a/INSTALL/grub/help/tr_TR.txt b/INSTALL/grub/help/tr_TR.txt index d57d709e..8e5e4068 100644 --- a/INSTALL/grub/help/tr_TR.txt +++ b/INSTALL/grub/help/tr_TR.txt @@ -1,6 +1,6 @@ h - Yardım bilgilerini göster F1 - Memdisk Modu başlatır(Yalnızca küçük WinPE/LiveCD ISO/IMG ler için bu modu kullanabilirsiniz) -F2 - Bilgisayarı Yeniden Başlat/Kapat +F2 - Browse and boot files in local disk F3 - Ventoy Menü modu olarak,Klasör görünümü(Treeview) ile Liste görünümü(ListView) arasında geçiş yapmayı sağlar. F4 - Bilgisayarınızda yüklü olan Windows yada Linux işletim sistemini, sabit diskten başlatır. F5 - Ventoy Araçlar menüsü diff --git a/INSTALL/grub/help/zh_CN.txt b/INSTALL/grub/help/zh_CN.txt index 49a2ec14..e580e16c 100644 --- a/INSTALL/grub/help/zh_CN.txt +++ b/INSTALL/grub/help/zh_CN.txt @@ -1,6 +1,6 @@ h - 显示本帮助信息 F1 - 把文件加载到内存启动(只适用于文件很小的 WinPE/LiveCD等) -F2 - 电源操作 (重启、关机) +F2 - 浏览并启动本地硬盘中的镜像文件 F3 - 菜单显示模式切换。可在列表模式和目录模式之间自由切换。 F4 - 启动本地硬盘上的 Windows/Linux 等系统。 F5 - 各类工具 diff --git a/INSTALL/grub/power.cfg b/INSTALL/grub/power.cfg index ede844c2..2b3bb358 100644 --- a/INSTALL/grub/power.cfg +++ b/INSTALL/grub/power.cfg @@ -1,15 +1,17 @@ -menuentry Reboot --class=power_reboot { - echo -e '\n\nSystem is rebooting ... \n' - sleep 1 - reboot -} +submenu "Power" --class=debug_power --class=F5tool { + menuentry Reboot --class=debug_reboot --class=debug_power --class=F5tool { + echo -e '\n\nSystem is rebooting ... \n' + sleep 1 + reboot + } -menuentry Halt --class=power_halt { - echo -e '\n\nSystem is halting ... \n' - sleep 1 - halt -} + menuentry Halt --class=debug_halt --class=debug_power --class=F5tool { + echo -e '\n\nSystem is halting ... \n' + sleep 1 + halt + } -menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET { - echo 'Return ...' + menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET { + echo 'Return ...' + } } diff --git a/INSTALL/ventoy/vtoyjump32.exe b/INSTALL/ventoy/vtoyjump32.exe index 960c0253..d1dd1004 100644 Binary files a/INSTALL/ventoy/vtoyjump32.exe and b/INSTALL/ventoy/vtoyjump32.exe differ diff --git a/INSTALL/ventoy/vtoyjump64.exe b/INSTALL/ventoy/vtoyjump64.exe index 82a42ae9..95cf823c 100644 Binary files a/INSTALL/ventoy/vtoyjump64.exe and b/INSTALL/ventoy/vtoyjump64.exe differ diff --git a/Plugson/src/Web/ventoy_http.c b/Plugson/src/Web/ventoy_http.c index c24096d2..be24e375 100644 --- a/Plugson/src/Web/ventoy_http.c +++ b/Plugson/src/Web/ventoy_http.c @@ -485,9 +485,7 @@ void ventoy_data_default_control(data_control *data) { memset(data, 0, sizeof(data_control)); - data->default_menu_mode = 1; data->filter_dot_underscore = 1; - data->treeview_style = 1; data->max_search_level = -1; data->menu_timeout = 0; diff --git a/Plugson/vs/VentoyPlugson/Release/VentoyPlugson.exe b/Plugson/vs/VentoyPlugson/Release/VentoyPlugson.exe index 2ef8e217..930dd290 100644 Binary files a/Plugson/vs/VentoyPlugson/Release/VentoyPlugson.exe and b/Plugson/vs/VentoyPlugson/Release/VentoyPlugson.exe differ diff --git a/vtoyjump/vtoyjump/vtoyjump.c b/vtoyjump/vtoyjump/vtoyjump.c index c2ab0a12..07c5307f 100644 --- a/vtoyjump/vtoyjump/vtoyjump.c +++ b/vtoyjump/vtoyjump/vtoyjump.c @@ -1418,6 +1418,40 @@ End: return Ret; } +static BOOL CheckVentoyDisk(DWORD DiskNum) +{ + DWORD dwSize = 0; + CHAR PhyPath[128]; + UINT8 SectorBuf[512]; + HANDLE Handle; + UINT8 check[8] = { 0x56, 0x54, 0x00, 0x47, 0x65, 0x00, 0x48, 0x44 }; + + sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", DiskNum); + Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + if (Handle == INVALID_HANDLE_VALUE) + { + Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError()); + return FALSE; + } + + if (!ReadFile(Handle, SectorBuf, sizeof(SectorBuf), &dwSize, NULL)) + { + Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError()); + CloseHandle(Handle); + return FALSE; + } + + CloseHandle(Handle); + + if (memcmp(SectorBuf + 0x190, check, 8) == 0) + { + return TRUE; + } + + return FALSE; +} + + static int VentoyHook(ventoy_os_param *param) { int i; @@ -1429,6 +1463,7 @@ static int VentoyHook(ventoy_os_param *param) CHAR VtoyLetter; DWORD Drives; DWORD NewDrives; + DWORD VtoyDiskNum; UINT32 DiskSig; UINT32 VtoySig; DISK_EXTENT DiskExtent; @@ -1457,6 +1492,8 @@ static int VentoyHook(ventoy_os_param *param) if (IsFileExist("%s", IsoPath)) { Log("File exist under %C:", Letter); + memset(UUID, 0, sizeof(UUID)); + memset(&DiskExtent, 0, sizeof(DiskExtent)); if (GetPhyDiskUUID(Letter, UUID, NULL, &DiskExtent) == 0) { if (memcmp(UUID, param->vtoy_disk_guid, 16) == 0) @@ -1510,6 +1547,9 @@ static int VentoyHook(ventoy_os_param *param) { if (Drives & 0x01) { + memset(UUID, 0, sizeof(UUID)); + memset(&VtoyDiskExtent, 0, sizeof(VtoyDiskExtent)); + DiskSig = 0; if (GetPhyDiskUUID(VtoyLetter, UUID, &DiskSig, &VtoyDiskExtent) == 0) { Log("DiskSig=%08X PartStart=%lld", DiskSig, VtoyDiskExtent.StartingOffset.QuadPart); @@ -1543,11 +1583,25 @@ static int VentoyHook(ventoy_os_param *param) Log("Failed to find ventoy disk"); return 1; } + + VtoyDiskNum = VtoyDiskExtent.DiskNumber; } else { VtoyLetter = Letter; Log("No vlnk mode %C", Letter); + + VtoyDiskNum = DiskExtent.DiskNumber; + } + + if (CheckVentoyDisk(VtoyDiskNum)) + { + Log("Disk check OK %C: %u", VtoyLetter, VtoyDiskNum); + } + else + { + Log("Failed to check ventoy disk %u", VtoyDiskNum); + return 1; } Drives = GetLogicalDrives(); @@ -1588,7 +1642,7 @@ static int VentoyHook(ventoy_os_param *param) } // for protect - rc = DeleteVentoyPart2MountPoint(VtoyDiskExtent.DiskNumber); + rc = DeleteVentoyPart2MountPoint(VtoyDiskNum); Log("Delete ventoy mountpoint: %s", rc == 0 ? "SUCCESS" : "NO NEED"); if (g_windows_data.auto_install_script[0]) @@ -1615,7 +1669,7 @@ static int VentoyHook(ventoy_os_param *param) if (IsFileExist("%s", IsoPath)) { Log("decompress injection archive %s...", IsoPath); - DecompressInjectionArchive(IsoPath, VtoyDiskExtent.DiskNumber); + DecompressInjectionArchive(IsoPath, VtoyDiskNum); if (IsFileExist("%s", AUTO_RUN_BAT)) { diff --git a/vtoyjump/vtoyjump/vtoyjump.h b/vtoyjump/vtoyjump/vtoyjump.h index ef0d2153..3a8fcb61 100644 --- a/vtoyjump/vtoyjump/vtoyjump.h +++ b/vtoyjump/vtoyjump/vtoyjump.h @@ -62,7 +62,9 @@ typedef struct ventoy_os_param UINT64 vtoy_reserved[4]; // Internal use by ventoy - UINT8 reserved[31]; + UINT8 vtoy_disk_signature[4]; + + UINT8 reserved[27]; }ventoy_os_param; typedef struct ventoy_windows_data