diff --git a/GRUB2/grub-2.04/grub-core/fs/fat.c b/GRUB2/grub-2.04/grub-core/fs/fat.c index 6338d49e..6d4ce0d5 100644 --- a/GRUB2/grub-2.04/grub-core/fs/fat.c +++ b/GRUB2/grub-2.04/grub-core/fs/fat.c @@ -964,6 +964,12 @@ grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, info.dir = !! (ctxt.dir.attr & GRUB_FAT_ATTR_DIRECTORY); info.case_insensitive = 1; + + #ifdef MODE_EXFAT + if (!info.dir) + info.size = ctxt.dir.file_size; + #endif + #ifdef MODE_EXFAT if (!ctxt.dir.have_stream) continue; @@ -1445,4 +1451,3 @@ END: } #endif - diff --git a/GRUB2/grub-2.04/grub-core/normal/menu.c b/GRUB2/grub-2.04/grub-core/normal/menu.c index 4df03bfd..d39e19ac 100644 --- a/GRUB2/grub-2.04/grub-core/normal/menu.c +++ b/GRUB2/grub-2.04/grub-core/normal/menu.c @@ -34,6 +34,12 @@ #include #include +int g_ventoy_menu_refresh = 0; +int g_ventoy_memdisk_mode = 0; +int g_ventoy_iso_raw = 0; +int g_ventoy_iso_uefi_drv = 0; +int g_ventoy_last_entry = 0; + /* Time to delay after displaying an error message about a default/fallback entry failing to boot. */ #define DEFAULT_ENTRY_ERROR_DELAY_MS 2500 @@ -577,16 +583,20 @@ print_countdown (struct grub_term_coordinate *pos, int n) static int run_menu (grub_menu_t menu, int nested, int *auto_boot) { + const char *cmdstr; grub_uint64_t saved_time; - int default_entry, current_entry; + int default_entry,current_entry; int timeout; enum timeout_style timeout_style; default_entry = get_entry_number (menu, "default"); - + + if (g_ventoy_last_entry >= 0 && g_ventoy_last_entry < menu->size) { + default_entry = g_ventoy_last_entry; + } /* If DEFAULT_ENTRY is not within the menu entries, fall back to the first entry. */ - if (default_entry < 0 || default_entry >= menu->size) + else if (default_entry < 0 || default_entry >= menu->size) default_entry = 0; timeout = grub_menu_get_timeout (); @@ -787,34 +797,76 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) } goto refresh; + case GRUB_TERM_KEY_F2: + cmdstr = grub_env_get("VTOY_F2_CMD"); + if (cmdstr) + { + menu_fini (); + grub_script_execute_sourcecode(cmdstr); + goto refresh; + } + break; + case GRUB_TERM_KEY_F3: + cmdstr = grub_env_get("VTOY_F3_CMD"); + if (cmdstr) + { + menu_fini (); + grub_script_execute_sourcecode(cmdstr); + goto refresh; + } + break; + case GRUB_TERM_KEY_F4: + cmdstr = grub_env_get("VTOY_F4_CMD"); + if (cmdstr) + { + menu_fini (); + grub_script_execute_sourcecode(cmdstr); + goto refresh; + } + break; + case GRUB_TERM_KEY_F5: + cmdstr = grub_env_get("VTOY_F5_CMD"); + if (cmdstr) + { + menu_fini (); + grub_script_execute_sourcecode(cmdstr); + goto refresh; + } + break; + case GRUB_TERM_KEY_F6: + cmdstr = grub_env_get("VTOY_F6_CMD"); + if (cmdstr) + { + menu_fini (); + grub_script_execute_sourcecode(cmdstr); + goto refresh; + } + break; + case GRUB_TERM_KEY_F7: + cmdstr = grub_env_get("VTOY_F7_CMD"); + if (cmdstr) + { + menu_fini (); + grub_script_execute_sourcecode(cmdstr); + goto refresh; + } + break; case GRUB_TERM_KEY_F1: menu_fini (); - if (grub_env_get("VTOY_MEM_DISK")) { - grub_env_unset("VTOY_MEM_DISK"); - }else { - grub_env_set("VTOY_MEM_DISK", grub_env_get("VTOY_MEM_DISK_STR")); - } - grub_env_set("VTOY_MENU_REFRESH", "1"); + g_ventoy_memdisk_mode = 1 - g_ventoy_memdisk_mode; + g_ventoy_menu_refresh = 1; goto refresh; - case GRUB_TERM_KEY_F3: + case (GRUB_TERM_CTRL | 'i'): menu_fini (); - if (grub_env_get("VTOY_ISO_RAW")) { - grub_env_unset("VTOY_ISO_RAW"); - }else { - grub_env_set("VTOY_ISO_RAW", grub_env_get("VTOY_ISO_RAW_STR")); - } - grub_env_set("VTOY_MENU_REFRESH", "1"); + g_ventoy_iso_raw = 1 - g_ventoy_iso_raw; + g_ventoy_menu_refresh = 1; goto refresh; - case GRUB_TERM_KEY_F4: + case (GRUB_TERM_CTRL | 'u'): menu_fini (); - if (grub_env_get("VTOY_ISO_UEFI_DRV")) { - grub_env_unset("VTOY_ISO_UEFI_DRV"); - }else { - grub_env_set("VTOY_ISO_UEFI_DRV", grub_env_get("VTOY_ISO_UEFI_DRV_STR")); - } - grub_env_set("VTOY_MENU_REFRESH", "1"); + g_ventoy_iso_uefi_drv = 1 - g_ventoy_iso_uefi_drv; + g_ventoy_menu_refresh = 1; goto refresh; default: @@ -897,6 +949,8 @@ show_menu (grub_menu_t menu, int nested, int autobooted) if (boot_entry < 0) break; + g_ventoy_last_entry = boot_entry; + e = grub_menu_get_entry (menu, boot_entry); if (! e) continue; /* Menu is empty. */ diff --git a/GRUB2/grub-2.04/grub-core/ventoy/ventoy.c b/GRUB2/grub-2.04/grub-core/ventoy/ventoy.c index ba1ec345..97b34903 100644 --- a/GRUB2/grub-2.04/grub-core/ventoy/ventoy.c +++ b/GRUB2/grub-2.04/grub-core/ventoy/ventoy.c @@ -52,11 +52,14 @@ int g_valid_initrd_count = 0; static grub_file_t g_old_file; 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; 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; @@ -71,6 +74,13 @@ ventoy_guid g_ventoy_guid = VENTOY_GUID; ventoy_img_chunk_list g_img_chunk_list; +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; + + void ventoy_debug(const char *fmt, ...) { va_list args; @@ -530,7 +540,7 @@ static grub_err_t ventoy_cmd_check_compatible(grub_extcmd_context_t ctxt, int ar VENTOY_CMD_RETURN(GRUB_ERR_NONE); } -static int ventoy_cmp_img(img_info *img1, img_info *img2) +int ventoy_cmp_img(img_info *img1, img_info *img2) { char *s1, *s2; int c1 = 0; @@ -560,15 +570,17 @@ static int ventoy_cmp_img(img_info *img1, img_info *img2) return (c1 - c2); } -static void ventoy_swap_img(img_info *img1, img_info *img2) +void ventoy_swap_img(img_info *img1, img_info *img2) { - grub_memcpy(g_img_swap_tmp_buf, img1->name, sizeof(img1->name)); - grub_memcpy(img1->name, img2->name, sizeof(img1->name)); - grub_memcpy(img2->name, g_img_swap_tmp_buf, sizeof(img1->name)); + grub_memcpy(&g_img_swap_tmp, img1, sizeof(img_info)); - grub_memcpy(g_img_swap_tmp_buf, img1->path, sizeof(img1->path)); - grub_memcpy(img1->path, img2->path, sizeof(img1->path)); - grub_memcpy(img2->path, g_img_swap_tmp_buf, sizeof(img1->path)); + 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) @@ -591,11 +603,27 @@ static int ventoy_img_name_valid(const char *filename, grub_size_t namelen) 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_colect_img_files(const char *filename, const struct grub_dirhook_info *info, void *data) { + int ignore = 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; @@ -609,14 +637,47 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho return 0; } - new_node = grub_malloc(sizeof(img_iterator_node)); + if (!ventoy_img_name_valid(filename, len)) + { + return 0; + } + + if (filename[0] == '$' && 0 == grub_strncmp(filename, "$RECYCLE.BIN", 12)) + { + return 0; + } + + new_node = grub_zalloc(sizeof(img_iterator_node)); if (new_node) { - new_node->tail = node->tail; - grub_snprintf(new_node->dir, sizeof(new_node->dir), "%s%s/", node->dir, filename); + new_node->dirlen = grub_snprintf(new_node->dir, sizeof(new_node->dir), "%s%s/", node->dir, filename); - new_node->next = g_img_iterator_head.next; - g_img_iterator_head.next = new_node; + 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 @@ -646,6 +707,22 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho { g_ventoy_img_list = img; } + + img->size = info->size; + 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++; @@ -734,6 +811,96 @@ int ventoy_fill_data(grub_uint32_t buflen, char *buffer) return len; } +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 || grub_strcmp(img->name, minimg->name) < 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 || grub_strcmp(child->dir, Minchild->dir) < 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; + 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) + { + node->dir[node->dirlen - 1] = 0; + g_tree_script_pos += grub_snprintf(g_tree_script_buf + g_tree_script_pos, VTOY_MAX_SCRIPT_BUF - g_tree_script_pos, + "submenu \"%-10s [%s]\" {\n", "DIR", node->dir + offset); + } + + while ((child = ventoy_get_min_child(node)) != NULL) + { + ventoy_dynamic_tree_menu(child); + } + + while ((img = ventoy_get_min_iso(node)) != NULL) + { + g_tree_script_pos += grub_snprintf(g_tree_script_buf + g_tree_script_pos, VTOY_MAX_SCRIPT_BUF - g_tree_script_pos, + "menuentry \"%-10s %s\" --id=\"VID_%d\" {\n" + " common_menuentry \n" + "}\n", + grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT), img->name, img->id); + } + + if (node != &g_img_iterator_head) + { + g_tree_script_pos += grub_snprintf(g_tree_script_buf + g_tree_script_pos, VTOY_MAX_SCRIPT_BUF - g_tree_script_pos, "}\n"); + } + + node->done = 1; + return 0; +} + static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char **args) { grub_fs_t fs; @@ -743,6 +910,7 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char char *device_name = NULL; char buf[32]; img_iterator_node *node = NULL; + img_iterator_node *tmp = NULL; (void)ctxt; @@ -762,13 +930,13 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char goto fail; } - dev = grub_device_open(device_name); + g_enum_dev = dev = grub_device_open(device_name); if (!dev) { goto fail; } - fs = grub_fs_probe(dev); + g_enum_fs = fs = grub_fs_probe(dev); if (!fs) { goto fail; @@ -776,20 +944,29 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char grub_memset(&g_img_iterator_head, 0, sizeof(g_img_iterator_head)); + g_img_iterator_head.dirlen = 1; g_img_iterator_head.tail = &tail; - grub_strcpy(g_img_iterator_head.dir, "/"); + grub_strcpy(g_img_iterator_head.dir, "/"); - fs->fs_dir(dev, "/", ventoy_colect_img_files, &g_img_iterator_head); - - while (g_img_iterator_head.next) + for (node = &g_img_iterator_head; node; node = node->next) { - node = g_img_iterator_head.next; - g_img_iterator_head.next = node->next; - - fs->fs_dir(dev, node->dir, ventoy_colect_img_files, node); - grub_free(node); + fs->fs_dir(dev, node->dir, ventoy_colect_img_files, node); } + 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) { @@ -802,6 +979,16 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char } } + for (cur = g_ventoy_img_list; cur; cur = cur->next) + { + g_list_script_pos += grub_snprintf(g_list_script_buf + g_list_script_pos, VTOY_MAX_SCRIPT_BUF - g_list_script_pos, + "menuentry \"%s\" --id=\"VID_%d\" {\n" + " common_menuentry \n" + "}\n", + cur->name, cur->id); + } + 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); @@ -876,7 +1063,9 @@ static grub_err_t ventoy_cmd_img_name(grub_extcmd_context_t ctxt, int argc, char static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int argc, char **args) { - const char *name = NULL; + int img_id = 0; + char *pos = NULL; + const char *id = NULL; img_info *cur = g_ventoy_img_list; (void)ctxt; @@ -886,13 +1075,22 @@ 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); } - name = grub_env_get("chosen"); + 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 (0 == grub_strcmp(name, cur->name)) + if (img_id == cur->id) { - grub_env_set(args[0], cur->path); break; } cur = cur->next; @@ -903,6 +1101,8 @@ static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int arg return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such image"); } + grub_env_set(args[0], cur->path); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); } @@ -1138,6 +1338,146 @@ static grub_err_t ventoy_cmd_add_replace_file(grub_extcmd_context_t ctxt, int ar 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_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; + } + + return 1; +} + +static grub_err_t ventoy_cmd_dynamic_menu(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char memfile[128] = {0}; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc == 0) + { + grub_script_execute_sourcecode(g_list_script_buf); + } + 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); + grub_script_execute_sourcecode(memfile); + } + + return 0; +} + +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("iso_path"); + 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; +} + grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...) { va_list ap; @@ -1189,6 +1529,10 @@ static int ventoy_env_init(void) char buf[64]; grub_env_set("vtdebug_flag", ""); + grub_env_export("vtdebug_flag"); + + g_tree_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); + g_list_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); ventoy_filt_register(0, ventoy_wrapper_open); @@ -1219,6 +1563,10 @@ static cmd_para ventoy_cmds[] = { "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_cpio", ventoy_cmd_load_cpio, 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_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL }, { "vt_file_size", ventoy_cmd_file_size, 0, NULL, "", "", NULL }, diff --git a/GRUB2/grub-2.04/grub-core/ventoy/ventoy_def.h b/GRUB2/grub-2.04/grub-core/ventoy/ventoy_def.h index 8e261506..27a31513 100644 --- a/GRUB2/grub-2.04/grub-core/ventoy/ventoy_def.h +++ b/GRUB2/grub-2.04/grub-core/ventoy/ventoy_def.h @@ -21,10 +21,13 @@ #ifndef __VENTOY_DEF_H__ #define __VENTOY_DEF_H__ +#define VTOY_MAX_SCRIPT_BUF (4 * 1024 * 1024) + #define JSON_SUCCESS 0 #define JSON_FAILED 1 #define JSON_NOT_FOUND 2 +#define ulong unsigned long #define ulonglong unsigned long long #define vtoy_to_upper(c) (((char)(c) >= 'a' && (char)(c) <= 'z') ? ((char)(c) - 'a' + 'A') : (char)(c)) @@ -115,11 +118,15 @@ typedef struct ventoy_udf_override #pragma pack() - typedef struct img_info { char path[512]; char name[256]; + int id; + grub_uint64_t size; + int select; + + void *parent; struct img_info *next; struct img_info *prev; @@ -130,8 +137,19 @@ typedef struct img_iterator_node struct img_iterator_node *next; img_info **tail; char dir[400]; + int dirlen; + int isocnt; + int done; + int select; + + struct img_iterator_node *parent; + struct img_iterator_node *firstchild; + + void *firstiso; }img_iterator_node; + + typedef struct initrd_info { char name[256]; @@ -504,5 +522,41 @@ static inline int ventoy_is_word_end(int c) return (c == 0 || c == ',' || ventoy_isspace(c)); } +#pragma pack(1) +typedef struct ventoy_part_table +{ + grub_uint8_t Active; // 0x00 0x80 + + grub_uint8_t StartHead; + grub_uint16_t StartSector : 6; + grub_uint16_t StartCylinder : 10; + + grub_uint8_t FsFlag; + + grub_uint8_t EndHead; + grub_uint16_t EndSector : 6; + grub_uint16_t EndCylinder : 10; + + grub_uint32_t StartSectorId; + grub_uint32_t SectorCount; +}ventoy_part_table; + +typedef struct ventoy_mbr_head +{ + grub_uint8_t BootCode[446]; + ventoy_part_table PartTbl[4]; + grub_uint8_t Byte55; + grub_uint8_t ByteAA; +}ventoy_mbr_head; +#pragma pack() + +extern int g_ventoy_last_entry; +extern int g_ventoy_memdisk_mode; +extern int g_ventoy_iso_raw; +extern int g_ventoy_iso_uefi_drv; + +int ventoy_cmp_img(img_info *img1, img_info *img2); +void ventoy_swap_img(img_info *img1, img_info *img2); + #endif /* __VENTOY_DEF_H__ */ diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh index aa1f7fc6..705582bc 100644 --- a/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh @@ -22,10 +22,15 @@ #ventoy_systemd_udevd_work_around #ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace" -$SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE inst.stage2=hd:/dev/dm-0#" -i /lib/dracut-lib.sh +if $GREP -q 'root=live' /proc/cmdline; then + $SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE root=live:/dev/dm-0#" -i /lib/dracut-lib.sh +else + $SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE inst.stage2=hd:/dev/dm-0#" -i /lib/dracut-lib.sh +fi + ventoy_set_inotify_script rhel7/ventoy-inotifyd-hook.sh -$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/default/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/01-ventoy-inotifyd-start.sh +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel7/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/01-ventoy-inotifyd-start.sh # suppress write protected mount warning if [ -e /usr/sbin/anaconda-diskroot ]; then diff --git a/IMG/cpio/ventoy/ventoy.sh b/IMG/cpio/ventoy/ventoy.sh index 2517f0b1..543543d9 100644 --- a/IMG/cpio/ventoy/ventoy.sh +++ b/IMG/cpio/ventoy/ventoy.sh @@ -165,6 +165,12 @@ ventoy_get_os_type() { echo 'arch'; return fi + if $GREP -q 'berry ' /proc/version; then + echo 'berry'; return + fi + + + echo "default" } diff --git a/INSTALL/EFI/BOOT/grubx64_real.efi b/INSTALL/EFI/BOOT/grubx64_real.efi index 19c0ab09..f7179af2 100644 Binary files a/INSTALL/EFI/BOOT/grubx64_real.efi and b/INSTALL/EFI/BOOT/grubx64_real.efi differ diff --git a/INSTALL/Ventoy2Disk.sh b/INSTALL/Ventoy2Disk.sh index 1ebf05cc..8e05b586 100644 --- a/INSTALL/Ventoy2Disk.sh +++ b/INSTALL/Ventoy2Disk.sh @@ -56,6 +56,15 @@ fi vtdebug "MODE=$MODE FORCE=$FORCE" +if ! [ -f ./boot/boot.img ]; then + if [ -d ./grub ]; then + vterr "Don't run me here, please download the released install package, and run there." + else + vterr "Please run under the right directory!" + fi + exit 1 +fi + #decompress tool cd tool chmod +x ./xzcat diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg index 18b9b050..be1697a5 100644 --- a/INSTALL/grub/grub.cfg +++ b/INSTALL/grub/grub.cfg @@ -16,33 +16,26 @@ # #************************************************************************************ -function ventoy_boot_from_hdd { - if [ "$grub_platform" = "pc" ]; then - if [ "$iso_path" = "(hd0,1)" ]; then - if [ -b (hd1) ]; then - set root=(hd1) - drivemap -s hd0 hd1 - chainloader +1 - boot - else - echo "No local hdd found ..." - sleep 3 - fi - else - set root=(hd0) - chainloader +1 - boot - fi - else - exit +function ventoy_power { + echo '<1> Reboot' + echo '<2> Halt' + echo '<0> Return to menu' + echo -e '\nPlease enter your choice:' + + unset vtOpt + read vtOpt + + if [ "$vtOpt" = "1" ]; then + echo -e '\n\nSystem is rebooting ... \n' + sleep 1 + reboot + elif [ "$vtOpt" = "2" ]; then + echo -e '\n\nSystem is halting ... \n' + sleep 1 + halt fi } -function ventoy_reboot { - reboot -} - - function get_os_type { set vtoy_os=Linux for file in "efi/microsoft" "sources/boot.wim" "boot/bcd" "bootmgr.efi" "boot/etfsboot.com"; do @@ -115,6 +108,9 @@ function distro_specify_initrd_file { function distro_specify_initrd_file_phase2 { if [ -f (loop)/boot/initrd.img ]; then vt_linux_specify_initrd_file /boot/initrd.img + elif [ -f (loop)/Setup/initrd.gz ]; then + vt_linux_specify_initrd_file /Setup/initrd.gz + fi } @@ -211,7 +207,7 @@ function uefi_iso_menu_func { if [ -n "$vtisouefi" ]; then set LoadIsoEfiDriver=on unset vtisouefi - elif [ -n "$VTOY_ISO_UEFI_DRV" ]; then + elif vt_check_mode 2; then set LoadIsoEfiDriver=on else unset LoadIsoEfiDriver @@ -239,7 +235,7 @@ function uefi_iso_menu_func { if [ -n "$vtcompat" ]; then set ventoy_compatible=YES unset vtcompat - elif [ -n "$VTOY_ISO_RAW" ]; then + elif vt_check_mode 1; then set ventoy_compatible=YES else vt_check_compatible (loop) @@ -274,8 +270,6 @@ function uefi_iso_memdisk { } - - function legacy_windows_menu_func { vt_windows_reset @@ -383,7 +377,7 @@ function legacy_iso_menu_func { if [ -n "$vtcompat" ]; then set ventoy_compatible=YES unset vtcompat - elif [ -n "$VTOY_ISO_RAW" ]; then + elif vt_check_mode 1; then set ventoy_compatible=YES else vt_check_compatible (loop) @@ -413,6 +407,22 @@ function legacy_iso_memdisk { boot } +function common_menuentry { + if [ "$grub_platform" = "pc" ]; then + if vt_check_mode 0; then + legacy_iso_memdisk $iso_path + else + legacy_iso_menu_func $iso_path + fi + else + if vt_check_mode 0; then + uefi_iso_memdisk $iso_path + else + uefi_iso_menu_func $iso_path + fi + fi +} + ############################################################# ############################################################# @@ -422,7 +432,7 @@ function legacy_iso_memdisk { ############################################################# ############################################################# -set VENTOY_VERSION="1.0.08b2" +set VENTOY_VERSION="1.0.08" #disable timeout unset timeout @@ -431,8 +441,15 @@ set VTOY_MEM_DISK_STR="MEMDISK" set VTOY_ISO_RAW_STR="ISO RAW" set VTOY_ISO_UEFI_DRV_STR="UEFI FS" -set VTOY_F2_CMD="ventoy_boot_from_hdd" -set VTOY_F3_CMD="ventoy_reboot" +set VTOY_F2_CMD="ventoy_power" +set VTOY_F3_CMD="vt_dynamic_menu tree" + +set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:TreeView" +if [ "$grub_platform" = "pc" ]; then + set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION BIOS www.ventoy.net" +else + set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION UEFI www.ventoy.net" +fi vt_device $root vtoy_dev @@ -473,33 +490,12 @@ terminal_output gfxterm set ventoy_img_count=0 vt_list_img $iso_path ventoy_img_count -#Dynamic menu for every iso file -if vt_cmp $ventoy_img_count ne 0; then - set imgid=0 - while vt_cmp $imgid lt $ventoy_img_count; do - vt_img_name $imgid img_name - menuentry "$img_name" { - if [ "$grub_platform" = "pc" ]; then - if [ -n "$VTOY_MEM_DISK" ]; then - legacy_iso_memdisk $iso_path - else - legacy_iso_menu_func $iso_path - fi - else - if [ -n "$VTOY_MEM_DISK" ]; then - uefi_iso_memdisk $iso_path - else - uefi_iso_menu_func $iso_path - fi - fi - } - - vt_incr imgid 1 - done +#Main menu +if [ $ventoy_img_count -gt 0 ]; then + vt_dynamic_menu else menuentry "No ISO files found (Press enter to reboot ...)" { echo -e "\n Rebooting ... " reboot } fi - diff --git a/INSTALL/grub/i386-pc/core.img b/INSTALL/grub/i386-pc/core.img index 3e06b842..d8992331 100644 Binary files a/INSTALL/grub/i386-pc/core.img and b/INSTALL/grub/i386-pc/core.img differ diff --git a/INSTALL/grub/themes/ventoy/theme.txt b/INSTALL/grub/themes/ventoy/theme.txt index 86f5ec3d..a605b434 100644 --- a/INSTALL/grub/themes/ventoy/theme.txt +++ b/INSTALL/grub/themes/ventoy/theme.txt @@ -19,7 +19,7 @@ terminal-box: "terminal_box_*.png" item_font = "ascii" item_color = "#ffffff" item_height = 30 - item_icon_space = 1 + item_spacing = 1 item_padding = 1 @@ -27,8 +27,7 @@ terminal-box: "terminal_box_*.png" selected_item_color= "#f2f2f2" selected_item_pixmap_style = "select_*.png" - #icon_height = 30 - #icon_width = 30 + item_icon_space = 0 scrollbar = true scrollbar_width = 10 @@ -50,11 +49,11 @@ terminal-box: "terminal_box_*.png" } + hbox{ - left = 40% + left = 30% top = 95% width = 10% height = 25 - + label {text = "F1:Memdisk" color = "blue" align = "left"} + + label {text = "@VTOY_HOTKEY_TIP@" color = "blue" align = "left"} } diff --git a/INSTALL/grub/x86_64-efi/normal.mod b/INSTALL/grub/x86_64-efi/normal.mod index db224ddd..9487e610 100644 Binary files a/INSTALL/grub/x86_64-efi/normal.mod and b/INSTALL/grub/x86_64-efi/normal.mod differ diff --git a/INSTALL/ventoy/ventoy.cpio b/INSTALL/ventoy/ventoy.cpio index c181fcec..bbaa290e 100644 Binary files a/INSTALL/ventoy/ventoy.cpio and b/INSTALL/ventoy/ventoy.cpio differ