From: longpanda Date: Fri, 29 May 2020 14:57:40 +0000 (+0800) Subject: 1. Add a new feature to directly boot wim files X-Git-Tag: v1.0.12~1 X-Git-Url: https://glassweightruler.freedombox.rocks/gitweb/Ventoy.git/commitdiff_plain/c8e86938feedfcdb089a26cc18d476ead303d50e?ds=sidebyside 1. Add a new feature to directly boot wim files 2. auto installation plugin update 1) Expand the configuration, now you can specify more than one auto installation scripts for one ISO file 2) Add a prompt for the iso with auto installation config, you can choose whether to use the auto installation script and which one to use for this time 3. persistence plugin update 1) Expand the configuration, now you can specify more than one persistence backend image files for one ISO file 2) Add a prompt for the iso with persistence config, you can choose whether to use the persistence image and which one to use for this time 4. Move the position of the red Memdisk tip to a more prominent position 5. Add a return parent directory item when in TreeView mode 6. Add a VTOY_DEFAULT_SEARCH_ROOT option in global control plugin to specify the root path of the iso files. 7. Change the style of F2 power menu 8. Fix a bug about Ventoy2Disk.exe can't start when there is a DataRAM Ramdisk in the system. 9. Files with size less than 32KB will be filted by default 10. Fix a bug about wrong file size in TreeView mode with NTFS/XFS 11. Files with space or Non Ascii charactors in name will be shown but with unsupported message when you boot it. 12. Optimization for Ventoy2Disk.sh 13. Optimization for arch linux boot 14. New iso support --- 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 857e741..3b83dd5 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 a5c8d93..96ffecb 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 e5c6f20..9cb3842 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 d39e19a..6c10f4a 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 883ca09..1ad4ebe 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 0202045..da6e688 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 403bf30..28133ce 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 16a31cc..4aad58d 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 529d308..6ca0563 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 3baf95f..45a28f0 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 7d842e2..e65fb5b 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 0000000..fec9cc0 --- /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 7981b1e..6be8155 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 2a2588b..ce5dbe5 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 5787f5e..d79bb2d 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 5fa98f8..a5db322 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 e0624c0..0323fce 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 38cbf07..ded8b10 100644 Binary files a/INSTALL/Ventoy2Disk.exe and b/INSTALL/Ventoy2Disk.exe differ diff --git a/INSTALL/Ventoy2Disk.sh b/INSTALL/Ventoy2Disk.sh index 257fee0..02a6906 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 0c51f5c..2a2175d 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 4874c6a..83dd216 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 0000000..daecd66 --- /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 a605b43..a73017b 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 9487e61..19e42a9 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 0000000..224ddf8 --- /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 0000000..04f5d22 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 7387ed1..dd9e095 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 d5ae13e..5b13a0e 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 4b2dd15..d8bac6a 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 1b18a87..8f94a70 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 fd02bb9..f113b36 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 814e259..75d12c8 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 ed25f96..535e1a9 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) {