diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c index 857e7415..3b83dd5a 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c @@ -413,7 +413,7 @@ EFI_STATUS EFIAPI ventoy_block_io_read secNum = BufferSize / 2048; offset = Lba * 2048; - if (offset + BufferSize < g_chain->real_img_size_in_bytes) + if (offset + BufferSize <= g_chain->real_img_size_in_bytes) { return ventoy_read_iso_sector(Lba, secNum, Buffer); } diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/xfs.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/xfs.c index a5c8d938..96ffecbf 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/xfs.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/xfs.c @@ -970,8 +970,6 @@ grub_xfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, info.mtime = grub_be_to_cpu32 (node->inode.mtime.sec); } info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); - if (!info.dir) - info.size = node->inode.size; grub_free (node); return ctx->hook (filename, &info, ctx->hook_data); } diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c index e5c6f208..9cb38425 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c @@ -412,16 +412,23 @@ grub_disk_read_small (grub_disk_t disk, grub_disk_addr_t sector, grub_err_t grub_disk_blocklist_read(void *chunklist, grub_uint64_t sector, grub_uint64_t size, grub_uint32_t log_sector_size) { + grub_uint64_t sizeshift; ventoy_img_chunk *last_chunk = NULL; ventoy_img_chunk *new_chunk = NULL; ventoy_img_chunk_list *chunk_list = (ventoy_img_chunk_list *)chunklist; + sizeshift = (size >> log_sector_size); + if (sizeshift == 0) + { + sizeshift = 1; + } + if (chunk_list->cur_chunk == 0) { chunk_list->chunk[0].img_start_sector = 0; chunk_list->chunk[0].img_end_sector = (size >> 11) - 1; chunk_list->chunk[0].disk_start_sector = sector; - chunk_list->chunk[0].disk_end_sector = sector + (size >> log_sector_size) - 1; + chunk_list->chunk[0].disk_end_sector = sector + sizeshift - 1; chunk_list->cur_chunk = 1; return 0; } @@ -430,7 +437,7 @@ grub_err_t grub_disk_blocklist_read(void *chunklist, grub_uint64_t sector, if (last_chunk->disk_end_sector + 1 == sector) { last_chunk->img_end_sector += (size >> 11); - last_chunk->disk_end_sector += (size >> log_sector_size); + last_chunk->disk_end_sector += sizeshift; return 0; } @@ -452,7 +459,7 @@ grub_err_t grub_disk_blocklist_read(void *chunklist, grub_uint64_t sector, new_chunk->img_start_sector = last_chunk->img_end_sector + 1; new_chunk->img_end_sector = new_chunk->img_start_sector + (size >> 11) - 1; new_chunk->disk_start_sector = sector; - new_chunk->disk_end_sector = sector + (size >> log_sector_size) - 1; + new_chunk->disk_end_sector = sector + sizeshift - 1; chunk_list->cur_chunk++; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c index d39e19ac..6c10f4ab 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c @@ -39,6 +39,8 @@ 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; +int g_ventoy_suppress_esc = 0; +int g_ventoy_menu_esc = 0; /* Time to delay after displaying an error message about a default/fallback entry failing to boot. */ @@ -590,8 +592,10 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) enum timeout_style timeout_style; default_entry = get_entry_number (menu, "default"); - - if (g_ventoy_last_entry >= 0 && g_ventoy_last_entry < menu->size) { + + if (g_ventoy_suppress_esc) + default_entry = 1; + else 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 @@ -771,12 +775,12 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) case '\r': // case GRUB_TERM_KEY_RIGHT: case GRUB_TERM_CTRL | 'f': - menu_fini (); + menu_fini (); *auto_boot = 0; - return current_entry; + return current_entry; case GRUB_TERM_ESC: - if (nested) + if (nested && 0 == g_ventoy_suppress_esc) { menu_fini (); return -1; @@ -950,11 +954,16 @@ show_menu (grub_menu_t menu, int nested, int autobooted) break; g_ventoy_last_entry = boot_entry; + if (g_ventoy_menu_esc) + break; e = grub_menu_get_entry (menu, boot_entry); if (! e) continue; /* Menu is empty. */ + if (2 == e->argc && e->args && e->args[1] && grub_strncmp(e->args[1], "VTOY_RET", 8) == 0) + break; + grub_cls (); if (auto_boot) diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c index 883ca097..1ad4ebe8 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef GRUB_MACHINE_EFI #include #endif @@ -49,12 +50,15 @@ 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; static grub_file_t g_old_file; +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; @@ -75,6 +79,10 @@ 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; + static char *g_tree_script_buf = NULL; static int g_tree_script_pos = 0; @@ -341,6 +349,44 @@ static grub_err_t ventoy_cmd_file_size(grub_extcmd_context_t ctxt, int argc, cha return rc; } +static grub_err_t ventoy_cmd_load_wimboot(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_file_t file; + + (void)ctxt; + (void)argc; + (void)args; + + g_wimboot_enable = 0; + grub_check_free(g_wimiso_path); + grub_check_free(g_wimiso_chunk_list.chunk); + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!file) + { + return 0; + } + + grub_memset(&g_wimiso_chunk_list, 0, sizeof(g_wimiso_chunk_list)); + g_wimiso_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); + if (NULL == g_wimiso_chunk_list.chunk) + { + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); + } + + g_wimiso_chunk_list.max_chunk = DEFAULT_CHUNK_NUM; + g_wimiso_chunk_list.cur_chunk = 0; + + ventoy_get_block_list(file, &g_wimiso_chunk_list, file->device->disk->partition->start); + + g_wimboot_enable = 1; + g_wimiso_path = grub_strdup(args[0]); + + grub_file_close(file); + + return 0; +} + static grub_err_t ventoy_cmd_load_iso_to_mem(grub_extcmd_context_t ctxt, int argc, char **args) { int rc = 1; @@ -659,6 +705,8 @@ static int ventoy_check_ignore_flag(const char *filename, const struct grub_dirh static int ventoy_colect_img_files(const char *filename, const struct grub_dirhook_info *info, void *data) { + int i = 0; + int type = 0; int ignore = 0; grub_size_t len; img_info *img; @@ -723,52 +771,89 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho else { debug("Find a file %s\n", filename); + if (len <= 4) + { + return 0; + } - if ((len > 4) && (0 == grub_strcasecmp(filename + len - 4, ".iso"))) + if (0 == grub_strcasecmp(filename + len - 4, ".iso")) { - if (!ventoy_img_name_valid(filename, len)) - { - return 0; - } - - img = grub_zalloc(sizeof(img_info)); - if (img) + type = img_type_iso; + } + else if (g_wimboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".wim"))) + { + type = img_type_wim; + } + else + { + return 0; + } + + if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_') + { + return 0; + } + + img = grub_zalloc(sizeof(img_info)); + if (img) + { + img->type = type; + grub_snprintf(img->name, sizeof(img->name), "%s", filename); + + for (i = 0; i < (int)len; i++) { - grub_snprintf(img->name, sizeof(img->name), "%s", filename); - grub_snprintf(img->path, sizeof(img->path), "%s%s", node->dir, filename); - - if (g_ventoy_img_list) - { - tail = *(node->tail); - img->prev = tail; - tail->next = img; - } - else + if (filename[i] == ' ' || filename[i] == '\t' || (0 == grub_isprint(filename[i]))) { - g_ventoy_img_list = img; + img->name[i] = '*'; + img->unsupport = 1; } + } + + grub_snprintf(img->path, sizeof(img->path), "%s%s", node->dir, img->name); - img->size = info->size; - img->id = g_ventoy_img_count; - img->parent = node; - if (node && NULL == node->firstiso) - { - node->firstiso = img; - } + img->size = info->size; + if (0 == img->size) + { + img->size = ventoy_grub_get_file_size("%s/%s", g_iso_path, img->path); + } - node->isocnt++; - tmp = node->parent; - while (tmp) - { - tmp->isocnt++; - tmp = tmp->parent; - } - - *((img_info **)(node->tail)) = img; - g_ventoy_img_count++; + 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; + } - debug("Add %s%s to list %d\n", node->dir, filename, g_ventoy_img_count); + node->isocnt++; + tmp = node->parent; + while (tmp) + { + tmp->isocnt++; + tmp = tmp->parent; } + + *((img_info **)(node->tail)) = img; + g_ventoy_img_count++; + + debug("Add %s%s to list %d\n", node->dir, filename, g_ventoy_img_count); } } @@ -911,11 +996,27 @@ static int ventoy_dynamic_tree_menu(img_iterator_node *node) offset = node->parent->dirlen; } - if (node != &g_img_iterator_head) + if (node == &g_img_iterator_head) + { + if (g_default_menu_mode == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"%-10s [Return to ListView]\" VTOY_RET {\n " + " echo 'return ...' \n" + "}\n", "<--"); + } + } + else { 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); + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "submenu \"%-10s [%s]\" {\n", + "DIR", node->dir + offset); + + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"%-10s [../]\" VTOY_RET {\n " + " echo 'return ...' \n" + "}\n", "<--"); } while ((child = ventoy_get_min_child(node)) != NULL) @@ -925,16 +1026,19 @@ static int ventoy_dynamic_tree_menu(img_iterator_node *node) 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); + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"%-10s %s%s\" --id=\"VID_%d\" {\n" + " %s_%s \n" + "}\n", + grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT), + img->unsupport ? "[unsupported] " : "", img->name, img->id, + (img->type == img_type_iso) ? "iso" : "wim", + img->unsupport ? "unsupport_menuentry" : "common_menuentry"); } 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"); + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "%s", "}\n"); } node->done = 1; @@ -943,6 +1047,7 @@ static int ventoy_dynamic_tree_menu(img_iterator_node *node) 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; @@ -992,14 +1097,37 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char 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; } + 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)); - g_img_iterator_head.dirlen = 1; + 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] != '/') + { + 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; - grub_strcpy(g_img_iterator_head.dir, "/"); for (node = &g_img_iterator_head; node; node = node->next) { @@ -1032,13 +1160,23 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char } } + if (g_default_menu_mode == 1) + { + vtoy_ssprintf(g_list_script_buf, g_list_script_pos, + "menuentry \"%s [Return to TreeView]\" VTOY_RET {\n " + " echo 'return ...' \n" + "}\n", "<--"); + } + 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" + vtoy_ssprintf(g_list_script_buf, g_list_script_pos, + "menuentry \"%s%s\" --id=\"VID_%d\" {\n" + " %s_%s \n" "}\n", - cur->name, cur->id); + cur->unsupport ? "[unsupported] " : "", cur->name, cur->id, + (cur->type == img_type_iso) ? "iso" : "wim", + cur->unsupport ? "unsupport_menuentry" : "common_menuentry"); } g_list_script_buf[g_list_script_pos] = 0; @@ -1311,9 +1449,9 @@ int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, total += chunk->disk_end_sector + 1 - chunk->disk_start_sector; } - if (total != (file->size / 512)) + if (total != ((file->size + 511) / 512)) { - debug("Invalid total: %llu %llu\n", (ulonglong)total, (ulonglong)(file->size / 512)); + debug("Invalid total: %llu %llu\n", (ulonglong)total, (ulonglong)((file->size + 511) / 512)); return 1; } @@ -1417,6 +1555,117 @@ static grub_err_t ventoy_cmd_img_sector(grub_extcmd_context_t ctxt, int argc, ch 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; + + if (argc < 1) + { + return 0; + } + + node = ventoy_plugin_find_install_template(args[0]); + if (!node) + { + 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; + + if (argc < 1) + { + return 0; + } + + node = ventoy_plugin_find_persistent(args[0]); + if (!node) + { + 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; @@ -1783,6 +2032,30 @@ static grub_err_t ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt, int a 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; @@ -1867,6 +2140,7 @@ static cmd_para ventoy_cmds[] = { "vt_chosen_img_path", ventoy_cmd_chosen_img_path, 0, NULL, "{var}", "get 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_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 }, @@ -1874,6 +2148,8 @@ static cmd_para ventoy_cmds[] = { "vt_check_mode", ventoy_cmd_check_mode, 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_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL }, { "vt_file_size", ventoy_cmd_file_size, 0, NULL, "", "", NULL }, @@ -1892,6 +2168,7 @@ static cmd_para ventoy_cmds[] = { "vt_windows_reset", ventoy_cmd_wimdows_reset, 0, NULL, "", "", NULL }, { "vt_windows_locate_wim", ventoy_cmd_wimdows_locate_wim, 0, NULL, "", "", NULL }, { "vt_windows_chain_data", ventoy_cmd_windows_chain_data, 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_relocator_chaindata", ventoy_cmd_relocator_chaindata, 0, NULL, "", "", NULL }, 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 0202045f..da6e6889 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 @@ -23,7 +23,10 @@ #define VTOY_MAX_SCRIPT_BUF (4 * 1024 * 1024) -#define VTOY_SIZE_1GB 1073741824 +#define VTOY_FILT_MIN_FILE_SIZE 32768 + +#define VTOY_SIZE_1GB 1073741824 +#define VTOY_SIZE_512KB (512 * 1024) #define JSON_SUCCESS 0 #define JSON_FAILED 1 @@ -62,6 +65,7 @@ typedef struct cmd_para grub_extcmd_t cmd; }cmd_para; +#define ventoy_align_2k(value) ((value + 2047) / 2048 * 2048) #define ventoy_align(value, align) (((value) + ((align) - 1)) & (~((align) - 1))) #pragma pack(1) @@ -87,6 +91,7 @@ typedef struct cpio_newc_header #define cmd_raw_name ctxt->extcmd->cmd->name #define check_free(p, func) if (p) { func(p); p = NULL; } +#define grub_check_free(p) if (p) { grub_free(p); p = NULL; } typedef int (*grub_char_check_func)(int c); #define ventoy_is_decimal(str) ventoy_string_check(str, grub_isdigit) @@ -120,13 +125,18 @@ typedef struct ventoy_udf_override #pragma pack() +#define img_type_iso 0 +#define img_type_wim 1 + typedef struct img_info { char path[512]; char name[256]; int id; + int type; grub_uint64_t size; int select; + int unsupport; void *parent; @@ -186,12 +196,15 @@ extern grub_uint8_t *g_ventoy_runtime_buf; extern ventoy_guid g_ventoy_guid; extern ventoy_img_chunk_list g_img_chunk_list; +extern ventoy_img_chunk_list g_wimiso_chunk_list; +extern char *g_wimiso_path; extern int g_ventoy_debug; void ventoy_debug(const char *fmt, ...); #define debug(fmt, ...) if (g_ventoy_debug) ventoy_debug("[VTOY]: "fmt, __VA_ARGS__) - +#define vtoy_ssprintf(buf, pos, fmt, ...) \ + pos += grub_snprintf(buf + pos, VTOY_MAX_SCRIPT_BUF - pos, fmt, __VA_ARGS__) #define FLAG_HEADER_RESERVED 0x00000001 #define FLAG_HEADER_COMPRESSION 0x00000002 @@ -422,12 +435,14 @@ grub_err_t ventoy_cmd_valid_initrd_count(grub_extcmd_context_t ctxt, int argc, c grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **args); int ventoy_cpio_newc_fill_head(void *buf, int filesize, const void *filedata, const char *name); grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...); +grub_uint64_t ventoy_grub_get_file_size(const char *fmt, ...); int ventoy_is_file_exist(const char *fmt, ...); int ventoy_fill_data(grub_uint32_t buflen, char *buffer); grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); VTOY_JSON *vtoy_json_find_item ( @@ -552,23 +567,37 @@ typedef struct ventoy_mbr_head }ventoy_mbr_head; #pragma pack() +typedef struct file_fullpath +{ + char path[256]; +}file_fullpath; typedef struct install_template { + int pathlen; char isopath[256]; - char templatepath[256]; + + int cursel; + int templatenum; + file_fullpath *templatepath; struct install_template *next; }install_template; typedef struct persistence_config { + int pathlen; char isopath[256]; - char filepath[256]; + int cursel; + int backendnum; + file_fullpath *backendpath; + struct persistence_config *next; }persistence_config; +extern int g_ventoy_menu_esc; +extern int g_ventoy_suppress_esc; extern int g_ventoy_last_entry; extern int g_ventoy_memdisk_mode; extern int g_ventoy_iso_raw; @@ -576,10 +605,12 @@ 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); -char * ventoy_plugin_get_install_template(const char *isopath); +char * ventoy_plugin_get_cur_install_template(const char *isopath); +install_template * ventoy_plugin_find_install_template(const char *isopath); +persistence_config * ventoy_plugin_find_persistent(const char *isopath); void ventoy_plugin_dump_auto_install(void); int ventoy_fill_windows_rtdata(void *buf, char *isopath); -int ventoy_plugin_get_persistent_chunklist(const char *isopath, ventoy_img_chunk_list *chunk_list); +int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list); int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start); int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start); void ventoy_plugin_dump_persistence(void); diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c index 403bf30b..28133ce2 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c @@ -896,14 +896,14 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg g_ventoy_cpio_size = 0; } - rc = ventoy_plugin_get_persistent_chunklist(args[1], &chunk_list); + rc = ventoy_plugin_get_persistent_chunklist(args[1], -1, &chunk_list); if (rc == 0 && chunk_list.cur_chunk > 0 && chunk_list.chunk) { persistent_size = chunk_list.cur_chunk * sizeof(ventoy_img_chunk); persistent_buf = (char *)(chunk_list.chunk); } - template_file = ventoy_plugin_get_install_template(args[1]); + template_file = ventoy_plugin_get_cur_install_template(args[1]); if (template_file) { debug("auto install template: <%s>\n", template_file); @@ -925,6 +925,10 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg debug("Failed to open install script %s%s\n", args[2], template_file); } } + else + { + debug("auto install script skipped or not configed %s\n", args[1]); + } g_ventoy_cpio_buf = grub_malloc(file->size + 4096 + template_size + persistent_size + img_chunk_size); if (NULL == g_ventoy_cpio_buf) diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c index 16a31cc3..4aad58d8 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c @@ -125,16 +125,98 @@ static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk) return 0; } +static int ventoy_plugin_parse_fullpath +( + VTOY_JSON *json, + const char *isodisk, + const char *key, + file_fullpath **fullpath, + int *pathnum +) +{ + int rc = 1; + int count = 0; + VTOY_JSON *node = json; + VTOY_JSON *child = NULL; + file_fullpath *path = NULL; + + while (node) + { + if (0 == grub_strcmp(key, node->pcName)) + { + break; + } + node = node->pstNext; + } + + if (!node) + { + return 1; + } + + if (JSON_TYPE_STRING == node->enDataType) + { + debug("%s is string type data\n", node->pcName); + + if ((node->unData.pcStrVal[0] != '/') || (!ventoy_is_file_exist("%s%s", isodisk, node->unData.pcStrVal))) + { + debug("%s%s file not found\n", isodisk, node->unData.pcStrVal); + return 1; + } + + path = (file_fullpath *)grub_zalloc(sizeof(file_fullpath)); + if (path) + { + grub_snprintf(path->path, sizeof(path->path), "%s", node->unData.pcStrVal); + *fullpath = path; + *pathnum = 1; + rc = 0; + } + } + else if (JSON_TYPE_ARRAY == node->enDataType) + { + for (child = node->pstChild; child; child = child->pstNext) + { + if ((JSON_TYPE_STRING != child->enDataType) || (child->unData.pcStrVal[0] != '/')) + { + debug("Invalid data type:%d\n", child->enDataType); + return 1; + } + count++; + } + debug("%s is array type data, count=%d\n", node->pcName, count); + + path = (file_fullpath *)grub_zalloc(sizeof(file_fullpath) * count); + if (path) + { + *fullpath = path; + + for (count = 0, child = node->pstChild; child; child = child->pstNext) + { + if (ventoy_is_file_exist("%s%s", isodisk, child->unData.pcStrVal)) + { + grub_snprintf(path->path, sizeof(path->path), "%s", child->unData.pcStrVal); + path++; + count++; + } + } + + *pathnum = count; + rc = 0; + } + } + + return rc; +} static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk) { + int pathnum = 0; const char *iso = NULL; - const char *script = NULL; VTOY_JSON *pNode = NULL; install_template *node = NULL; install_template *next = NULL; - - (void)isodisk; + file_fullpath *templatepath = NULL; if (json->enDataType != JSON_TYPE_ARRAY) { @@ -147,6 +229,7 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk for (node = g_install_template_head; node; node = next) { next = node->next; + grub_check_free(node->templatepath); grub_free(node); } @@ -158,14 +241,14 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); if (iso && iso[0] == '/') { - script = vtoy_json_get_string_ex(pNode->pstChild, "template"); - if (script && script[0] == '/') + if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "template", &templatepath, &pathnum)) { node = grub_zalloc(sizeof(install_template)); if (node) { - grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); - grub_snprintf(node->templatepath, sizeof(node->templatepath), "%s", script); + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); + node->templatepath = templatepath; + node->templatenum = pathnum; if (g_install_template_head) { @@ -184,11 +267,12 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk) { + int pathnum = 0; const char *iso = NULL; - const char *persist = NULL; VTOY_JSON *pNode = NULL; persistence_config *node = NULL; persistence_config *next = NULL; + file_fullpath *backendpath = NULL; (void)isodisk; @@ -203,6 +287,7 @@ static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk) for (node = g_persistence_head; node; node = next) { next = node->next; + grub_check_free(node->backendpath); grub_free(node); } @@ -214,14 +299,14 @@ static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk) iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); if (iso && iso[0] == '/') { - persist = vtoy_json_get_string_ex(pNode->pstChild, "backend"); - if (persist && persist[0] == '/') + if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "backend", &backendpath, &pathnum)) { node = grub_zalloc(sizeof(persistence_config)); if (node) { - grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); - grub_snprintf(node->filepath, sizeof(node->filepath), "%s", persist); + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); + node->backendpath = backendpath; + node->backendnum = pathnum; if (g_persistence_head) { @@ -325,15 +410,18 @@ grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **a VENTOY_CMD_RETURN(GRUB_ERR_NONE); } - void ventoy_plugin_dump_auto_install(void) { + int i; install_template *node = NULL; for (node = g_install_template_head; node; node = node->next) { - grub_printf("IMAGE:<%s>\n", node->isopath); - grub_printf("SCRIPT:<%s>\n\n", node->templatepath); + grub_printf("\nIMAGE:<%s>\n", node->isopath); + for (i = 0; i < node->templatenum; i++) + { + grub_printf("SCRIPT %d:<%s>\n", i, node->templatepath[i].path); + } } return; @@ -342,69 +430,110 @@ void ventoy_plugin_dump_auto_install(void) void ventoy_plugin_dump_persistence(void) { int rc; + int i = 0; persistence_config *node = NULL; ventoy_img_chunk_list chunk_list; - + for (node = g_persistence_head; node; node = node->next) { - grub_printf("IMAGE:<%s>\n", node->isopath); - grub_printf("PERSIST:<%s>", node->filepath); + grub_printf("\nIMAGE:<%s>\n", node->isopath); - rc = ventoy_plugin_get_persistent_chunklist(node->isopath, &chunk_list); - if (rc == 0) - { - grub_printf(" [ SUCCESS ]\n\n"); - grub_free(chunk_list.chunk); - } - else + for (i = 0; i < node->backendnum; i++) { - grub_printf(" [ FAILED ]\n\n"); + grub_printf("PERSIST %d:<%s>", i, node->backendpath[i].path); + rc = ventoy_plugin_get_persistent_chunklist(node->isopath, i, &chunk_list); + if (rc == 0) + { + grub_printf(" [ SUCCESS ]\n"); + grub_free(chunk_list.chunk); + } + else + { + grub_printf(" [ FAILED ]\n"); + } } } return; } +install_template * ventoy_plugin_find_install_template(const char *isopath) +{ + install_template *node = NULL; + int len = (int)grub_strlen(isopath); + + for (node = g_install_template_head; node; node = node->next) + { + if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0) + { + return node; + } + } + + return NULL; +} -char * ventoy_plugin_get_install_template(const char *isopath) +char * ventoy_plugin_get_cur_install_template(const char *isopath) { install_template *node = NULL; - for (node = g_install_template_head; node; node = node->next) + node = ventoy_plugin_find_install_template(isopath); + if ((!node) || (!node->templatepath)) { - if (grub_strcmp(node->isopath, isopath) == 0) + return NULL; + } + + if (node->cursel < 0 || node->cursel >= node->templatenum) + { + return NULL; + } + + return node->templatepath[node->cursel].path; +} + +persistence_config * ventoy_plugin_find_persistent(const char *isopath) +{ + persistence_config *node = NULL; + int len = (int)grub_strlen(isopath); + + for (node = g_persistence_head; node; node = node->next) + { + if ((len == node->pathlen) && (grub_strcmp(node->isopath, isopath) == 0)) { - return node->templatepath; + return node; } } return NULL; } -int ventoy_plugin_get_persistent_chunklist(const char *isopath, ventoy_img_chunk_list *chunk_list) +int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list) { int rc = 1; grub_uint64_t start = 0; grub_file_t file = NULL; persistence_config *node = NULL; - for (node = g_persistence_head; node; node = node->next) + node = ventoy_plugin_find_persistent(isopath); + if ((!node) || (!node->backendpath)) { - if (grub_strcmp(node->isopath, isopath) == 0) - { - break; - } + return 1; } - if (NULL == node) + if (index < 0) { - goto end; + index = node->cursel; + } + + if (index < 0 || index >= node->backendnum) + { + return 1; } - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", g_iso_disk_name, node->filepath); + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", g_iso_disk_name, node->backendpath[index].path); if (!file) { - debug("Failed to open file %s%s\n", g_iso_disk_name, node->filepath); + debug("Failed to open file %s%s\n", g_iso_disk_name, node->backendpath[index].path); goto end; } diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c index 529d3086..6ca05632 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c @@ -470,7 +470,7 @@ int ventoy_fill_windows_rtdata(void *buf, char *isopath) return 1; } - script = ventoy_plugin_get_install_template(pos); + script = ventoy_plugin_get_cur_install_template(pos); if (script) { debug("auto install script <%s>\n", script); @@ -478,7 +478,7 @@ int ventoy_fill_windows_rtdata(void *buf, char *isopath) } else { - debug("auto install script not found %p\n", pos); + debug("auto install script skipped or not configed %s\n", pos); } return 0; @@ -957,3 +957,214 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c VENTOY_CMD_RETURN(GRUB_ERR_NONE); } +static grub_uint32_t ventoy_get_wim_iso_offset(const char *filepath) +{ + grub_uint32_t imgoffset; + grub_file_t file; + char cmdbuf[128]; + + grub_snprintf(cmdbuf, sizeof(cmdbuf), "loopback wimiso %s", filepath); + grub_script_execute_sourcecode(cmdbuf); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", "(wimiso)/boot/boot.wim"); + if (!file) + { + grub_printf("Failed to open boot.wim file in the image file\n"); + return 0; + } + + imgoffset = (grub_uint32_t)grub_iso9660_get_last_file_dirent_pos(file) + 2; + + debug("wimiso wim direct offset: %u\n", imgoffset); + + grub_file_close(file); + + grub_script_execute_sourcecode("loopback -d wimiso"); + + return imgoffset; +} + +static int ventoy_get_wim_chunklist(const char *filename, ventoy_img_chunk_list *wimchunk, grub_uint64_t *wimsize) +{ + grub_file_t wimfile; + + wimfile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", filename); + if (!wimfile) + { + return 1; + } + + grub_memset(wimchunk, 0, sizeof(ventoy_img_chunk_list)); + wimchunk->chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); + if (NULL == wimchunk->chunk) + { + grub_file_close(wimfile); + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); + } + + wimchunk->max_chunk = DEFAULT_CHUNK_NUM; + wimchunk->cur_chunk = 0; + + ventoy_get_block_list(wimfile, wimchunk, wimfile->device->disk->partition->start); + + *wimsize = wimfile->size; + grub_file_close(wimfile); + + return 0; +} + +grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t i = 0; + grub_uint32_t imgoffset = 0; + grub_uint32_t size = 0; + grub_uint32_t isosector = 0; + grub_uint64_t wimsize = 0; + grub_uint32_t boot_catlog = 0; + grub_uint32_t img_chunk1_size = 0; + grub_uint32_t img_chunk2_size = 0; + grub_uint32_t override_size = 0; + grub_file_t file; + grub_disk_t disk; + const char *pLastChain = NULL; + ventoy_chain_head *chain; + ventoy_iso9660_override *dirent; + ventoy_img_chunk *chunknode; + ventoy_override_chunk *override; + ventoy_img_chunk_list wimchunk; + char envbuf[128]; + + (void)ctxt; + (void)argc; + + debug("wim chain data begin <%s> ...\n", args[0]); + + if (NULL == g_wimiso_chunk_list.chunk || NULL == g_wimiso_path) + { + grub_printf("ventoy not ready\n"); + return 1; + } + + imgoffset = ventoy_get_wim_iso_offset(g_wimiso_path); + if (imgoffset == 0) + { + grub_printf("image offset not found\n"); + return 1; + } + + if (0 != ventoy_get_wim_chunklist(args[0], &wimchunk, &wimsize)) + { + grub_printf("Failed to get wim chunklist\n"); + return 1; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", g_wimiso_path); + if (!file) + { + return 1; + } + + boot_catlog = ventoy_get_iso_boot_catlog(file); + + img_chunk1_size = g_wimiso_chunk_list.cur_chunk * sizeof(ventoy_img_chunk); + img_chunk2_size = wimchunk.cur_chunk * sizeof(ventoy_img_chunk); + override_size = sizeof(ventoy_override_chunk); + + size = sizeof(ventoy_chain_head) + img_chunk1_size + img_chunk2_size + override_size; + + pLastChain = grub_env_get("vtoy_chain_mem_addr"); + if (pLastChain) + { + chain = (ventoy_chain_head *)grub_strtoul(pLastChain, NULL, 16); + if (chain) + { + debug("free last chain memory %p\n", chain); + grub_free(chain); + } + } + + chain = grub_malloc(size); + if (!chain) + { + grub_printf("Failed to alloc chain memory size %u\n", size); + grub_file_close(file); + return 1; + } + + grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (unsigned long)chain); + grub_env_set("vtoy_chain_mem_addr", envbuf); + grub_snprintf(envbuf, sizeof(envbuf), "%u", size); + grub_env_set("vtoy_chain_mem_size", envbuf); + + grub_memset(chain, 0, sizeof(ventoy_chain_head)); + + /* part 1: os parameter */ + ventoy_fill_os_param(file, &(chain->os_param)); + + /* part 2: chain head */ + disk = file->device->disk; + chain->disk_drive = disk->id; + chain->disk_sector_size = (1 << disk->log_sector_size); + chain->real_img_size_in_bytes = ventoy_align_2k(file->size) + ventoy_align_2k(wimsize); + chain->virt_img_size_in_bytes = chain->real_img_size_in_bytes; + chain->boot_catalog = boot_catlog; + + if (!ventoy_is_efi_os()) + { + grub_file_seek(file, boot_catlog * 2048); + grub_file_read(file, chain->boot_catalog_sector, sizeof(chain->boot_catalog_sector)); + } + + /* part 3: image chunk */ + chain->img_chunk_offset = sizeof(ventoy_chain_head); + chain->img_chunk_num = g_wimiso_chunk_list.cur_chunk + wimchunk.cur_chunk; + grub_memcpy((char *)chain + chain->img_chunk_offset, g_wimiso_chunk_list.chunk, img_chunk1_size); + + /* fs cluster size >= 2048, so don't need to proc align */ + + /* align by 2048 */ + chunknode = wimchunk.chunk + wimchunk.cur_chunk - 1; + i = (chunknode->disk_end_sector + 1 - chunknode->disk_start_sector) % 4; + if (i) + { + chunknode->disk_end_sector += 4 - i; + } + + isosector = (grub_uint32_t)((file->size + 2047) / 2048); + for (i = 0; i < wimchunk.cur_chunk; i++) + { + chunknode = wimchunk.chunk + i; + chunknode->img_start_sector = isosector; + chunknode->img_end_sector = chunknode->img_start_sector + + ((chunknode->disk_end_sector + 1 - chunknode->disk_start_sector) / 4) - 1; + isosector = chunknode->img_end_sector + 1; + } + + grub_memcpy((char *)chain + chain->img_chunk_offset + img_chunk1_size, wimchunk.chunk, img_chunk2_size); + + /* part 4: override chunk */ + chain->override_chunk_offset = chain->img_chunk_offset + img_chunk1_size + img_chunk2_size; + chain->override_chunk_num = 1; + + override = (ventoy_override_chunk *)((char *)chain + chain->override_chunk_offset); + override->img_offset = imgoffset; + override->override_size = sizeof(ventoy_iso9660_override); + + dirent = (ventoy_iso9660_override *)(override->override_data); + dirent->first_sector = (grub_uint32_t)((file->size + 2047) / 2048); + dirent->size = (grub_uint32_t)(wimsize); + dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); + dirent->size_be = grub_swap_bytes32(dirent->size); + + debug("imgoffset=%u first_sector=0x%x size=0x%x\n", imgoffset, dirent->first_sector, dirent->size); + + if (ventoy_is_efi_os() == 0) + { + ventoy_windows_drive_map(chain); + } + + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/install.sh b/GRUB2/MOD_SRC/grub-2.04/install.sh index 3baf95f4..45a28f0d 100644 --- a/GRUB2/MOD_SRC/grub-2.04/install.sh +++ b/GRUB2/MOD_SRC/grub-2.04/install.sh @@ -12,7 +12,7 @@ make install PATH=$PATH:$VT_DIR/GRUB2/INSTALL/bin/:$VT_DIR/GRUB2/INSTALL/sbin/ net_modules_legacy="net tftp http" -all_modules_legacy="date drivemap blocklist ext2 xfs ventoy chain read halt iso9660 linux16 test true sleep reboot echo video_colors video_cirrus video_bochs vga vbe video_fb font video gettext extcmd terminal linux minicmd help configfile tr trig boot biosdisk disk ls tar squash4 password_pbkdf2 all_video png jpeg part_msdos fat exfat ntfs loopback gzio normal udf gfxmenu gfxterm gfxterm_background gfxterm_menu" +all_modules_legacy="date drivemap blocklist lspci pci ext2 xfs ventoy chain read halt iso9660 linux16 test true sleep reboot echo videotest videoinfo videotest_checksum video_colors video_cirrus video_bochs vga vbe video_fb font video gettext extcmd terminal linux minicmd help configfile tr trig boot biosdisk disk ls tar squash4 password_pbkdf2 all_video png jpeg part_msdos fat exfat ntfs loopback gzio normal udf gfxmenu gfxterm gfxterm_background gfxterm_menu" net_modules_uefi="efinet net tftp http" all_modules_uefi="blocklist ventoy test ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux relocator jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop efi_uga video_bochs video_cirrus video video_fb gfxterm_background gfxterm_menu" diff --git a/IMG/cpio/ventoy/hook/arch/ventoy-hook.sh b/IMG/cpio/ventoy/hook/arch/ventoy-hook.sh index 7d842e2f..e65fb5bf 100644 --- a/IMG/cpio/ventoy/hook/arch/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/arch/ventoy-hook.sh @@ -22,6 +22,10 @@ if $GREP -q '^"$mount_handler"' /init; then echo 'use mount_handler ...' >> $VTLOG $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ventoy-disk.sh \"\$archisodevice\"" -i /init + + if [ -f /hooks/archiso ]; then + $SED '/while ! poll_device "${dev}"/a\ if /ventoy/busybox/sh /ventoy/hook/arch/ventoy-timeout.sh ${dev}; then break; fi' -i /hooks/archiso + fi else # some archlinux initramfs doesn't contain device-mapper udev rules file ARCH_UDEV_DIR=$(ventoy_get_udev_conf_dir) diff --git a/IMG/cpio/ventoy/hook/arch/ventoy-timeout.sh b/IMG/cpio/ventoy/hook/arch/ventoy-timeout.sh new file mode 100644 index 00000000..fec9cc07 --- /dev/null +++ b/IMG/cpio/ventoy/hook/arch/ventoy-timeout.sh @@ -0,0 +1,36 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +if [ -b /dev/$vtDM ]; then + vtlog "ln -s /dev/$vtDM $1" + ln -s /dev/$vtDM "$1" + exit 0 +else + vtlog "Device-mapper not found" + exit 1 +fi + + diff --git a/IMG/cpio/ventoy/hook/default/ventoy-inotifyd-start.sh b/IMG/cpio/ventoy/hook/default/ventoy-inotifyd-start.sh index 7981b1e6..6be81555 100644 --- a/IMG/cpio/ventoy/hook/default/ventoy-inotifyd-start.sh +++ b/IMG/cpio/ventoy/hook/default/ventoy-inotifyd-start.sh @@ -21,5 +21,11 @@ vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) -vtlog "... start inotifyd listen $vtHook ..." -$BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +vtdisk=$(get_ventoy_disk_name) +if [ "$vtdisk" = "unknown" ]; then + vtlog "... start inotifyd listen $vtHook ..." + $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +else + vtlog "... $vtdisk already exist ..." + $BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" +fi diff --git a/IMG/cpio/ventoy/hook/gentoo/ventoy-hook.sh b/IMG/cpio/ventoy/hook/gentoo/ventoy-hook.sh index 2a2588bd..ce5dbe5e 100644 --- a/IMG/cpio/ventoy/hook/gentoo/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/gentoo/ventoy-hook.sh @@ -19,7 +19,7 @@ . $VTOY_PATH/hook/ventoy-os-lib.sh -if [ -d /etc/udev/rules.d ]; then +if [ -d /etc/udev/rules.d ] || [ -d /lib/udev/rules.d ]; then ventoy_systemd_udevd_work_around ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace" else diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh index 5787f5e4..d79bb2df 100644 --- a/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh @@ -42,7 +42,8 @@ if is_inotify_ventoy_part $3; then fi vtlog "set anaconda-diskroot ..." - /sbin/initqueue --settled --onetime --name anaconda-diskroot anaconda-diskroot /dev/dm-0 + /sbin/anaconda-diskroot /dev/dm-0 + #/sbin/initqueue --settled --onetime --name anaconda-diskroot anaconda-diskroot /dev/dm-0 set_ventoy_hook_finish fi diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-timeout.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-timeout.sh index 5fa98f8b..a5db322c 100644 --- a/IMG/cpio/ventoy/hook/rhel7/ventoy-timeout.sh +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-timeout.sh @@ -27,6 +27,7 @@ blkdev_num=$(dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9] vtDM=$(ventoy_find_dm_id ${blkdev_num}) vtlog "diskroot $vtDM ..." -/sbin/initqueue --settled --onetime --name anaconda-diskroot anaconda-diskroot /dev/$vtDM +/sbin/anaconda-diskroot /dev/dm-0 +#/sbin/initqueue --settled --onetime --name anaconda-diskroot anaconda-diskroot /dev/$vtDM PATH=$VTPATH_OLD diff --git a/INSTALL/EFI/BOOT/grubx64_real.efi b/INSTALL/EFI/BOOT/grubx64_real.efi index e0624c0c..0323fce7 100644 Binary files a/INSTALL/EFI/BOOT/grubx64_real.efi and b/INSTALL/EFI/BOOT/grubx64_real.efi differ diff --git a/INSTALL/Ventoy2Disk.exe b/INSTALL/Ventoy2Disk.exe index 38cbf07e..ded8b109 100644 Binary files a/INSTALL/Ventoy2Disk.exe and b/INSTALL/Ventoy2Disk.exe differ diff --git a/INSTALL/Ventoy2Disk.sh b/INSTALL/Ventoy2Disk.sh index 257fee0a..02a69060 100644 --- a/INSTALL/Ventoy2Disk.sh +++ b/INSTALL/Ventoy2Disk.sh @@ -1,25 +1,5 @@ #!/bin/sh -OLDDIR=$PWD - -if ! [ -f ./tool/ventoy_lib.sh ]; then - cd ${0%Ventoy2Disk.sh} -fi - -. ./tool/ventoy_lib.sh - -print_usage() { - echo 'Usage: Ventoy2Disk.sh CMD [ OPTION ] /dev/sdX' - echo ' CMD:' - echo ' -i install ventoy to sdX (fail if disk already installed with ventoy)' - echo ' -u update ventoy in sdX' - echo ' -I force install ventoy to sdX (no matter installed or not)' - echo '' - echo ' OPTION: (optional)' - echo ' -s enable secure boot support (default is disabled)' - echo '' - -} echo '' echo '***********************************************************' @@ -28,334 +8,43 @@ echo '* longpanda admin@ventoy.net *' echo '***********************************************************' echo '' -vtdebug "############# Ventoy2Disk $0 ################" +OLDDIR=$PWD -while [ -n "$1" ]; do - if [ "$1" = "-i" ]; then - MODE="install" - elif [ "$1" = "-I" ]; then - MODE="install" - FORCE="Y" - elif [ "$1" = "-u" ]; then - MODE="update" - elif [ "$1" = "-s" ]; then - SECUREBOOT="YES" - else - if ! [ -b "$1" ]; then - vterr "$1 is NOT a valid device" - print_usage - cd $OLDDIR - exit 1 - fi - DISK=$1 +if ! [ -f ./tool/xzcat ]; then + if [ -f ${0%Ventoy2Disk.sh}/tool/xzcat ]; then + cd ${0%Ventoy2Disk.sh} fi - - shift -done - -if [ -z "$MODE" ]; then - print_usage - cd $OLDDIR - exit 1 -fi - -if ! [ -b "$DISK" ]; then - vterr "Disk $DISK does not exist" - cd $OLDDIR - exit 1 -fi - -if [ -e /sys/class/block/${DISK#/dev/}/start ]; then - vterr "$DISK is a partition, please use the whole disk" - cd $OLDDIR - exit 1 fi -if dd if="$DISK" of=/dev/null bs=1 count=1 >/dev/null 2>&1; then - vtdebug "root permission check ok ..." -else - vterr "Failed to access $DISK, maybe root privilege is needed!" - echo '' - cd $OLDDIR - exit 1 -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." + echo "Don't run Ventoy2Disk.sh here, please download the released install package, and run the script in it." else - vterr "Please run under the right directory!" - fi - exit 1 -fi - -#decompress tool -cd tool -chmod +x ./xzcat -for file in $(ls); do - if [ "$file" != "xzcat" ]; then - if [ "$file" != "ventoy_lib.sh" ]; then - ./xzcat $file > ${file%.xz} - chmod +x ${file%.xz} - fi + echo "Please run under the correct directory!" fi -done -cd ../ - -if ! check_tool_work_ok; then - vterr "Some tools can not run in current system. Please check log.txt for detail." - cd $OLDDIR - exit 1 -fi - -testEF=$(echo -en '\xEF' | ./tool/hexdump -n 1 -e '1/1 "%02X"') -if [ "$testEF" != "EF" ]; then - vtdebug "testEF=##${testEF}##" - vterr "There is something wrong with the interpreter !" exit 1 fi -grep "^$DISK" /proc/mounts | while read mtline; do - mtpnt=$(echo $mtline | awk '{print $2}') - vtdebug "Trying to umount $mtpnt ..." - umount $mtpnt >/dev/null 2>&1 -done +echo "############# Ventoy2Disk $* ################" >> ./log.txt -if swapon -s | grep -q "^${DISK}[0-9]"; then - swapon -s | grep "^${DISK}[0-9]" | awk '{print $1}' | while read line; do - vtdebug "Trying to swapoff $line ..." - swapoff $line +#decompress tool +if ! [ -f ./tool/ash ]; then + cd tool + chmod +x ./xzcat + for file in $(ls *.xz); do + ./xzcat $file > ${file%.xz} + chmod +x ${file%.xz} done -fi - - -if grep "$DISK" /proc/mounts; then - vterr "$DISK is already mounted, please umount it first!" - cd $OLDDIR - exit 1 -fi - -if swapon -s | grep -q "^${DISK}[0-9]"; then - vterr "$DISK is used as swap, please swapoff it first!" - cd $OLDDIR - exit 1 -fi - - -if [ "$MODE" = "install" ]; then - vtdebug "install ventoy ..." - - if parted -v > /dev/null 2>&1; then - PARTTOOL='parted' - elif fdisk -v >/dev/null 2>&1; then - PARTTOOL='fdisk' - else - vterr "Both parted and fdisk are not found in the sysstem, Ventoy can't create new partition." - cd $OLDDIR - exit 1 - fi - - version=$(get_disk_ventoy_version $DISK) - if [ $? -eq 0 ]; then - if [ -z "$FORCE" ]; then - vtwarn "$DISK already contains a Ventoy with version $version" - vtwarn "Use -u option to do a safe upgrade operation." - vtwarn "OR if you really want to reinstall ventoy to $DISK, please use -I option." - vtwarn "" - cd $OLDDIR - exit 1 - fi - fi - - disk_sector_num=$(cat /sys/block/${DISK#/dev/}/size) - disk_size_gb=$(expr $disk_sector_num / 2097152) - - if [ $disk_sector_num -gt 4294967296 ]; then - vterr "$DISK is over 2TB size, MBR will not work on it." - cd $OLDDIR - exit 1 - fi - - #Print disk info - echo "Disk : $DISK" - parted -s $DISK p 2>&1 | grep Model - echo "Size : $disk_size_gb GB" - echo '' - - vtwarn "Attention:" - vtwarn "You will install Ventoy to $DISK." - vtwarn "All the data on the disk $DISK will be lost!!!" - echo "" - - read -p 'Continue? (y/n)' Answer - if [ "$Answer" != "y" ]; then - if [ "$Answer" != "Y" ]; then - exit 0 - fi - fi - - echo "" - vtwarn "All the data on the disk $DISK will be lost!!!" - read -p 'Double-check. Continue? (y/n)' Answer - if [ "$Answer" != "y" ]; then - if [ "$Answer" != "Y" ]; then - exit 0 - fi - fi - - - if [ $disk_sector_num -le $VENTOY_SECTOR_NUM ]; then - vterr "No enough space in disk $DISK" - exit 1 - fi - - if ! dd if=/dev/zero of=$DISK bs=1 count=512 status=none conv=fsync; then - vterr "Write data to $DISK failed, please check whether it's in use." - exit 1 - fi - - format_ventoy_disk $DISK $PARTTOOL - - # format part1 - if ventoy_is_linux64; then - cmd=./tool/mkexfatfs_64 - else - cmd=./tool/mkexfatfs_32 - fi + cd ../ - chmod +x ./tool/* - - # DiskSize > 32GB Cluster Size use 128KB - # DiskSize < 32GB Cluster Size use 32KB - if [ $disk_size_gb -gt 32 ]; then - cluster_sectors=256 - else - cluster_sectors=64 - fi - - $cmd -n ventoy -s $cluster_sectors ${DISK}1 - - chmod +x ./tool/vtoy_gen_uuid - - vtinfo "writing data to disk ..." - dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=446 - ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 - ./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start_sector - - #disk uuid - ./tool/vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} seek=384 bs=1 count=16 - - #disk signature - ./tool/vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} skip=12 seek=440 bs=1 count=4 - - vtinfo "sync data ..." - sync - - vtinfo "esp partition processing ..." - - sleep 1 - mtpnt=$(grep "^${DISK}2" /proc/mounts | awk '{print $2}') - if [ -n "$mtpnt" ]; then - umount $mtpnt >/dev/null 2>&1 - fi - - if [ "$SECUREBOOT" != "YES" ]; then - mkdir ./tmp_mnt - - vtdebug "mounting part2 ...." - for tt in 1 2 3; do - if mount ${DISK}2 ./tmp_mnt; then - vtdebug "mounting part2 success" - break - fi - - mtpnt=$(grep "^${DISK}2" /proc/mounts | awk '{print $2}') - if [ -n "$mtpnt" ]; then - umount $mtpnt >/dev/null 2>&1 - fi - sleep 2 - done - - rm -f ./tmp_mnt/EFI/BOOT/BOOTX64.EFI - rm -f ./tmp_mnt/EFI/BOOT/grubx64.efi - rm -f ./tmp_mnt/EFI/BOOT/MokManager.efi - rm -f ./tmp_mnt/ENROLL_THIS_KEY_IN_MOKMANAGER.cer - mv ./tmp_mnt/EFI/BOOT/grubx64_real.efi ./tmp_mnt/EFI/BOOT/BOOTX64.EFI - - umount ./tmp_mnt - rm -rf ./tmp_mnt - fi - - echo "" - vtinfo "Install Ventoy to $DISK successfully finished." - echo "" - -else - vtdebug "update ventoy ..." - - oldver=$(get_disk_ventoy_version $DISK) - if [ $? -ne 0 ]; then - vtwarn "$DISK does not contain ventoy or data corupted" - echo "" - vtwarn "Please use -i option if you want to install ventoy to $DISK" - echo "" + if ! [ -f ./tool/ash ]; then + echo 'Failed to decompress tools ...' cd $OLDDIR exit 1 fi - - curver=$(cat ./ventoy/version) - - vtinfo "Upgrade operation is safe, all the data in the 1st partition (iso files and other) will be unchanged!" - echo "" - - read -p "Update Ventoy $oldver ===> $curver Continue? (y/n)" Answer - if [ "$Answer" != "y" ]; then - if [ "$Answer" != "Y" ]; then - cd $OLDDIR - exit 0 - fi - fi - - PART2=$(get_disk_part_name $DISK 2) - - dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=440 - - ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 - - disk_sector_num=$(cat /sys/block/${DISK#/dev/}/size) - part2_start=$(expr $disk_sector_num - $VENTOY_SECTOR_NUM) - ./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start - - sync - - if [ "$SECUREBOOT" != "YES" ]; then - mkdir ./tmp_mnt - - vtdebug "mounting part2 ...." - for tt in 1 2 3; do - if mount ${DISK}2 ./tmp_mnt; then - vtdebug "mounting part2 success" - break - fi - sleep 2 - done - - rm -f ./tmp_mnt/EFI/BOOT/BOOTX64.EFI - rm -f ./tmp_mnt/EFI/BOOT/grubx64.efi - rm -f ./tmp_mnt/EFI/BOOT/MokManager.efi - rm -f ./tmp_mnt/ENROLL_THIS_KEY_IN_MOKMANAGER.cer - mv ./tmp_mnt/EFI/BOOT/grubx64_real.efi ./tmp_mnt/EFI/BOOT/BOOTX64.EFI - - umount ./tmp_mnt - rm -rf ./tmp_mnt - fi - - echo "" - vtinfo "Update Ventoy to $DISK successfully finished." - echo "" - fi +./tool/ash ./tool/VentoyWorker.sh $* + cd $OLDDIR + diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg index 0c51f5c1..2a2175d3 100644 --- a/INSTALL/grub/grub.cfg +++ b/INSTALL/grub/grub.cfg @@ -17,23 +17,7 @@ #************************************************************************************ 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 + configfile ${vtoy_path}/grub/power.cfg } function get_os_type { @@ -239,6 +223,8 @@ function uefi_iso_menu_func { fi vt_chosen_img_path chosen_path + vt_select_auto_install ${chosen_path} + vt_select_persistence ${chosen_path} if vt_is_udf ${1}${chosen_path}; then set ventoy_fs_probe=udf @@ -386,6 +372,8 @@ function legacy_iso_menu_func { fi vt_chosen_img_path chosen_path + vt_select_auto_install ${chosen_path} + vt_select_persistence ${chosen_path} if vt_is_udf ${1}${chosen_path}; then set ventoy_fs_probe=udf @@ -431,7 +419,7 @@ function legacy_iso_memdisk { boot } -function common_menuentry { +function iso_common_menuentry { if [ "$grub_platform" = "pc" ]; then if vt_check_mode 0; then legacy_iso_memdisk $iso_path @@ -447,6 +435,39 @@ function common_menuentry { fi } +function iso_unsupport_menuentry { + echo -e "\n The name of the iso file could NOT contain space or non-ascii characters. \n" + echo -e "\n Will return to main menu after 10 seconds ...\n" + sleep 10 +} + + +function wim_common_menuentry { + vt_chosen_img_path chosen_path + vt_wim_chain_data ${iso_path}${chosen_path} + if [ -n "${vtdebug_flag}" ]; then + sleep 5 + fi + + if [ -n "$vtoy_chain_mem_addr" ]; then + if [ "$grub_platform" = "pc" ]; then + linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + else + terminal_output console + chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + fi + boot + else + echo "chain empty failed" + sleep 5 + fi +} + +function wim_unsupport_menuentry { + echo -e "\n The name of the wim file could NOT contain space or non-ascii characters. \n" + echo -e "\n Will return to main menu after 10 seconds ...\n" + sleep 10 +} ############################################################# ############################################################# @@ -456,7 +477,7 @@ function common_menuentry { ############################################################# ############################################################# -set VENTOY_VERSION="1.0.11" +set VENTOY_VERSION="1.0.12" # Default menu display mode, you can change it as you want. # 0: List mode @@ -466,7 +487,7 @@ set VTOY_DEFAULT_MENU_MODE=0 #disable timeout unset timeout -set VTOY_MEM_DISK_STR="MEMDISK" +set VTOY_MEM_DISK_STR="[Memdisk]" set VTOY_ISO_RAW_STR="ISO RAW" set VTOY_ISO_UEFI_DRV_STR="UEFI FS" @@ -485,12 +506,14 @@ if [ "$vtoy_dev" = "tftp" ]; then for vtid in 0 1 2 3; do if [ -d (hd$vtid,2)/ventoy ]; then set iso_path=(hd$vtid,1) + set vtoy_efi_part=(hd$vtid,2) break fi done else set vtoy_path=($root)/ventoy set iso_path=($vtoy_dev,1) + set vtoy_efi_part=($vtoy_dev,2) fi loadfont ascii @@ -500,6 +523,12 @@ if [ -f $iso_path/ventoy/ventoy.json ]; then vt_load_plugin $iso_path fi +if [ -f $iso_path/ventoy/ventoy_wimboot.img ]; then + vt_load_wimboot $iso_path/ventoy/ventoy_wimboot.img +elif [ -f $vtoy_efi_part/ventoy/ventoy_wimboot.img ]; then + vt_load_wimboot $vtoy_efi_part/ventoy/ventoy_wimboot.img +fi + if [ $VTOY_DEFAULT_MENU_MODE -eq 0 ]; then set VTOY_F3_CMD="vt_dynamic_menu 1 1" @@ -536,7 +565,14 @@ if [ $ventoy_img_count -gt 0 ]; then vt_dynamic_menu 0 1 fi else - menuentry "No ISO files found (Press enter to reboot ...)" { + if [ -n "$VTOY_NO_ISO_TIP" ]; then + NO_ISO_MENU="No ISO files found, $VTOY_NO_ISO_TIP" + elif [ -n "$VTOY_DEFAULT_SEARCH_ROOT" ]; then + NO_ISO_MENU="No ISO files found, please check VTOY_DEFAULT_SEARCH_ROOT" + else + NO_ISO_MENU="No ISO files found" + fi + menuentry "$NO_ISO_MENU (Press enter to reboot ...)" { echo -e "\n Rebooting ... " reboot } diff --git a/INSTALL/grub/i386-pc/core.img b/INSTALL/grub/i386-pc/core.img index 4874c6a0..83dd2167 100644 Binary files a/INSTALL/grub/i386-pc/core.img and b/INSTALL/grub/i386-pc/core.img differ diff --git a/INSTALL/grub/power.cfg b/INSTALL/grub/power.cfg new file mode 100644 index 00000000..daecd666 --- /dev/null +++ b/INSTALL/grub/power.cfg @@ -0,0 +1,15 @@ +menuentry Reboot { + echo -e '\n\nSystem is rebooting ... \n' + sleep 1 + reboot +} + +menuentry Halt { + echo -e '\n\nSystem is halting ... \n' + sleep 1 + reboot +} + +menuentry 'Return to menu [Esc]' VTOY_RET { + echo 'Return ...' +} diff --git a/INSTALL/grub/themes/ventoy/theme.txt b/INSTALL/grub/themes/ventoy/theme.txt index a605b434..a73017b7 100644 --- a/INSTALL/grub/themes/ventoy/theme.txt +++ b/INSTALL/grub/themes/ventoy/theme.txt @@ -58,8 +58,8 @@ terminal-box: "terminal_box_*.png" + hbox{ - left = 90% - top = 5 + left = 30% + top = 95%-25 width = 10% height = 25 + label {text = "@VTOY_MEM_DISK@" color = "red" align = "left"} diff --git a/INSTALL/grub/x86_64-efi/normal.mod b/INSTALL/grub/x86_64-efi/normal.mod index 9487e610..19e42a99 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/tool/VentoyWorker.sh b/INSTALL/tool/VentoyWorker.sh new file mode 100644 index 00000000..224ddf8c --- /dev/null +++ b/INSTALL/tool/VentoyWorker.sh @@ -0,0 +1,305 @@ +#!/bin/sh + +. ./tool/ventoy_lib.sh + +print_usage() { + echo 'Usage: Ventoy2Disk.sh CMD [ OPTION ] /dev/sdX' + echo ' CMD:' + echo ' -i install ventoy to sdX (fail if disk already installed with ventoy)' + echo ' -u update ventoy in sdX' + echo ' -I force install ventoy to sdX (no matter installed or not)' + echo '' + echo ' OPTION: (optional)' + echo ' -s enable secure boot support (default is disabled)' + echo '' + +} + + +while [ -n "$1" ]; do + if [ "$1" = "-i" ]; then + MODE="install" + elif [ "$1" = "-I" ]; then + MODE="install" + FORCE="Y" + elif [ "$1" = "-u" ]; then + MODE="update" + elif [ "$1" = "-s" ]; then + SECUREBOOT="YES" + else + if ! [ -b "$1" ]; then + vterr "$1 is NOT a valid device" + print_usage + exit 1 + fi + DISK=$1 + fi + + shift +done + +if [ -z "$MODE" ]; then + print_usage + exit 1 +fi + +if ! [ -b "$DISK" ]; then + vterr "Disk $DISK does not exist" + exit 1 +fi + +if [ -e /sys/class/block/${DISK#/dev/}/start ]; then + vterr "$DISK is a partition, please use the whole disk" + exit 1 +fi + +if dd if="$DISK" of=/dev/null bs=1 count=1 >/dev/null 2>&1; then + vtdebug "root permission check ok ..." +else + vterr "Failed to access $DISK, maybe root privilege is needed!" + echo '' + exit 1 +fi + +vtdebug "MODE=$MODE FORCE=$FORCE" + +if ! check_tool_work_ok; then + vterr "Some tools can not run in current system. Please check log.txt for detail." + exit 1 +fi + +grep "^$DISK" /proc/mounts | while read mtline; do + mtpnt=$(echo $mtline | awk '{print $2}') + vtdebug "Trying to umount $mtpnt ..." + umount $mtpnt >/dev/null 2>&1 +done + +if swapon -s | grep -q "^${DISK}[0-9]"; then + swapon -s | grep "^${DISK}[0-9]" | awk '{print $1}' | while read line; do + vtdebug "Trying to swapoff $line ..." + swapoff $line + done +fi + + +if grep "$DISK" /proc/mounts; then + vterr "$DISK is already mounted, please umount it first!" + exit 1 +fi + +if swapon -s | grep -q "^${DISK}[0-9]"; then + vterr "$DISK is used as swap, please swapoff it first!" + exit 1 +fi + + +if [ "$MODE" = "install" ]; then + vtdebug "install ventoy ..." + + if parted -v > /dev/null 2>&1; then + PARTTOOL='parted' + elif fdisk -v >/dev/null 2>&1; then + PARTTOOL='fdisk' + else + vterr "Both parted and fdisk are not found in the sysstem, Ventoy can't create new partition." + exit 1 + fi + + version=$(get_disk_ventoy_version $DISK) + if [ $? -eq 0 ]; then + if [ -z "$FORCE" ]; then + vtwarn "$DISK already contains a Ventoy with version $version" + vtwarn "Use -u option to do a safe upgrade operation." + vtwarn "OR if you really want to reinstall ventoy to $DISK, please use -I option." + vtwarn "" + exit 1 + fi + fi + + disk_sector_num=$(cat /sys/block/${DISK#/dev/}/size) + disk_size_gb=$(expr $disk_sector_num / 2097152) + + if [ $disk_sector_num -gt 4294967296 ]; then + vterr "$DISK is over 2TB size, MBR will not work on it." + exit 1 + fi + + #Print disk info + echo "Disk : $DISK" + parted -s $DISK p 2>&1 | grep Model + echo "Size : $disk_size_gb GB" + echo '' + + vtwarn "Attention:" + vtwarn "You will install Ventoy to $DISK." + vtwarn "All the data on the disk $DISK will be lost!!!" + echo "" + + read -p 'Continue? (y/n)' Answer + if [ "$Answer" != "y" ]; then + if [ "$Answer" != "Y" ]; then + exit 0 + fi + fi + + echo "" + vtwarn "All the data on the disk $DISK will be lost!!!" + read -p 'Double-check. Continue? (y/n)' Answer + if [ "$Answer" != "y" ]; then + if [ "$Answer" != "Y" ]; then + exit 0 + fi + fi + + + if [ $disk_sector_num -le $VENTOY_SECTOR_NUM ]; then + vterr "No enough space in disk $DISK" + exit 1 + fi + + if ! dd if=/dev/zero of=$DISK bs=1 count=512 status=none conv=fsync; then + vterr "Write data to $DISK failed, please check whether it's in use." + exit 1 + fi + + format_ventoy_disk $DISK $PARTTOOL + + # format part1 + if ventoy_is_linux64; then + cmd=./tool/mkexfatfs_64 + else + cmd=./tool/mkexfatfs_32 + fi + + chmod +x ./tool/* + + # DiskSize > 32GB Cluster Size use 128KB + # DiskSize < 32GB Cluster Size use 32KB + if [ $disk_size_gb -gt 32 ]; then + cluster_sectors=256 + else + cluster_sectors=64 + fi + + $cmd -n ventoy -s $cluster_sectors ${DISK}1 + + chmod +x ./tool/vtoy_gen_uuid + + vtinfo "writing data to disk ..." + dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=446 + ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 + ./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start_sector + + #disk uuid + ./tool/vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} seek=384 bs=1 count=16 + + #disk signature + ./tool/vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} skip=12 seek=440 bs=1 count=4 + + vtinfo "sync data ..." + sync + + vtinfo "esp partition processing ..." + + sleep 1 + mtpnt=$(grep "^${DISK}2" /proc/mounts | awk '{print $2}') + if [ -n "$mtpnt" ]; then + umount $mtpnt >/dev/null 2>&1 + fi + + if [ "$SECUREBOOT" != "YES" ]; then + mkdir ./tmp_mnt + + vtdebug "mounting part2 ...." + for tt in 1 2 3; do + if mount ${DISK}2 ./tmp_mnt; then + vtdebug "mounting part2 success" + break + fi + + mtpnt=$(grep "^${DISK}2" /proc/mounts | awk '{print $2}') + if [ -n "$mtpnt" ]; then + umount $mtpnt >/dev/null 2>&1 + fi + sleep 2 + done + + rm -f ./tmp_mnt/EFI/BOOT/BOOTX64.EFI + rm -f ./tmp_mnt/EFI/BOOT/grubx64.efi + rm -f ./tmp_mnt/EFI/BOOT/MokManager.efi + rm -f ./tmp_mnt/ENROLL_THIS_KEY_IN_MOKMANAGER.cer + mv ./tmp_mnt/EFI/BOOT/grubx64_real.efi ./tmp_mnt/EFI/BOOT/BOOTX64.EFI + + umount ./tmp_mnt + rm -rf ./tmp_mnt + fi + + echo "" + vtinfo "Install Ventoy to $DISK successfully finished." + echo "" + +else + vtdebug "update ventoy ..." + + oldver=$(get_disk_ventoy_version $DISK) + if [ $? -ne 0 ]; then + vtwarn "$DISK does not contain ventoy or data corupted" + echo "" + vtwarn "Please use -i option if you want to install ventoy to $DISK" + echo "" + exit 1 + fi + + curver=$(cat ./ventoy/version) + + vtinfo "Upgrade operation is safe, all the data in the 1st partition (iso files and other) will be unchanged!" + echo "" + + read -p "Update Ventoy $oldver ===> $curver Continue? (y/n)" Answer + if [ "$Answer" != "y" ]; then + if [ "$Answer" != "Y" ]; then + exit 0 + fi + fi + + PART2=$(get_disk_part_name $DISK 2) + + dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=440 + + ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 + + disk_sector_num=$(cat /sys/block/${DISK#/dev/}/size) + part2_start=$(expr $disk_sector_num - $VENTOY_SECTOR_NUM) + ./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start + + sync + + if [ "$SECUREBOOT" != "YES" ]; then + mkdir ./tmp_mnt + + vtdebug "mounting part2 ...." + for tt in 1 2 3; do + if mount ${DISK}2 ./tmp_mnt; then + vtdebug "mounting part2 success" + break + fi + sleep 2 + done + + rm -f ./tmp_mnt/EFI/BOOT/BOOTX64.EFI + rm -f ./tmp_mnt/EFI/BOOT/grubx64.efi + rm -f ./tmp_mnt/EFI/BOOT/MokManager.efi + rm -f ./tmp_mnt/ENROLL_THIS_KEY_IN_MOKMANAGER.cer + mv ./tmp_mnt/EFI/BOOT/grubx64_real.efi ./tmp_mnt/EFI/BOOT/BOOTX64.EFI + + umount ./tmp_mnt + rm -rf ./tmp_mnt + fi + + echo "" + vtinfo "Update Ventoy to $DISK successfully finished." + echo "" + +fi + + diff --git a/INSTALL/tool/ash b/INSTALL/tool/ash new file mode 100644 index 00000000..04f5d228 Binary files /dev/null and b/INSTALL/tool/ash differ diff --git a/INSTALL/tool/ventoy_lib.sh b/INSTALL/tool/ventoy_lib.sh index 7387ed15..dd9e0959 100644 --- a/INSTALL/tool/ventoy_lib.sh +++ b/INSTALL/tool/ventoy_lib.sh @@ -186,6 +186,8 @@ get_disk_ventoy_version() { format_ventoy_disk() { DISK=$1 + PARTTOOL=$2 + PART1=$(get_disk_part_name $DISK 1) PART2=$(get_disk_part_name $DISK 2) @@ -205,9 +207,9 @@ format_ventoy_disk() { fi echo "" - echo "Create partitions on $DISK by $2 ..." + echo "Create partitions on $DISK by $PARTTOOL ..." - if [ "$2" = "parted" ]; then + if [ "$PARTTOOL" = "parted" ]; then vtdebug "format disk by parted ..." parted -a none --script $DISK \ mklabel msdos \ @@ -216,6 +218,9 @@ format_ventoy_disk() { mkpart primary fat16 $part2_start_sector $part2_end_sector \ set 2 boot on \ quit + + sync + echo -en '\xEF' | dd of=$DISK conv=fsync bs=1 count=1 seek=466 > /dev/null 2>&1 else vtdebug "format disk by fdisk ..." @@ -243,10 +248,10 @@ w EOF fi - echo "Done" udevadm trigger >/dev/null 2>&1 partprobe >/dev/null 2>&1 sleep 3 + echo "Done" echo 'mkfs on disk partitions ...' for i in 1 2 3 4 5 6 7; do @@ -258,9 +263,6 @@ EOF fi done - if [ "$2" = "parted" ]; then - echo -en '\xEF' | dd of=$DISK conv=fsync bs=1 count=1 seek=466 - fi if ! [ -b $PART2 ]; then MajorMinor=$(sed "s/:/ /" /sys/class/block/${PART2#/dev/}/dev) @@ -274,7 +276,7 @@ EOF fi fi - echo "create efi fat fs ..." + echo "create efi fat fs $PART2 ..." for i in 0 1 2 3 4 5 6 7 8 9; do if mkfs.vfat -F 16 -n EFI $PART2; then echo 'success' @@ -285,3 +287,7 @@ EOF fi done } + + + + diff --git a/INSTALL/ventoy/ipxe.krn b/INSTALL/ventoy/ipxe.krn index d5ae13ed..5b13a0e1 100644 Binary files a/INSTALL/ventoy/ipxe.krn and b/INSTALL/ventoy/ipxe.krn differ diff --git a/INSTALL/ventoy/ventoy.cpio b/INSTALL/ventoy/ventoy.cpio index 4b2dd150..d8bac6aa 100644 Binary files a/INSTALL/ventoy/ventoy.cpio and b/INSTALL/ventoy/ventoy.cpio differ diff --git a/INSTALL/ventoy/ventoy_x64.efi b/INSTALL/ventoy/ventoy_x64.efi index 1b18a87b..8f94a70d 100644 Binary files a/INSTALL/ventoy/ventoy_x64.efi and b/INSTALL/ventoy/ventoy_x64.efi differ diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c index fd02bb91..f113b363 100644 --- a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c @@ -224,7 +224,7 @@ int ventoy_vdisk_read(struct san_device *sandev, uint64_t lba, unsigned int coun ix86 = (struct i386_all_regs *)sandev->x86_regptr; readend = (lba + count) * 2048; - if (readend < g_chain->real_img_size_in_bytes) + if (readend <= g_chain->real_img_size_in_bytes) { ventoy_vdisk_read_real(lba, count, buffer); ix86->regs.dl = sandev->drive; diff --git a/LANGUAGES/languages.ini b/LANGUAGES/languages.ini index 814e2594..75d12c88 100644 Binary files a/LANGUAGES/languages.ini and b/LANGUAGES/languages.ini differ diff --git a/Ventoy2Disk/Ventoy2Disk/PhyDrive.c b/Ventoy2Disk/Ventoy2Disk/PhyDrive.c index ed25f967..535e1a91 100644 --- a/Ventoy2Disk/Ventoy2Disk/PhyDrive.c +++ b/Ventoy2Disk/Ventoy2Disk/PhyDrive.c @@ -661,6 +661,12 @@ int GetAllPhysicalDriveInfo(PHY_DRIVE_INFO *pDriveList, DWORD *pDriveCount) continue; } + if (DevDescHeader.Size < sizeof(STORAGE_DEVICE_DESCRIPTOR)) + { + Log("Invalid DevDescHeader.Size:%u", DevDescHeader.Size); + continue; + } + pDevDesc = (STORAGE_DEVICE_DESCRIPTOR *)malloc(DevDescHeader.Size); if (!pDevDesc) {