diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/search.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/search.c new file mode 100644 index 00000000..3852c0c7 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/search.c @@ -0,0 +1,353 @@ +/* search.c - search devices based on a file or a filesystem label */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static int g_no_vtoyefi_part = 0; +static char g_vtoyefi_dosname[64]; +static char g_vtoyefi_gptname[64]; + +struct cache_entry +{ + struct cache_entry *next; + char *key; + char *value; +}; + +static struct cache_entry *cache; + +/* Context for FUNC_NAME. */ +struct search_ctx +{ + const char *key; + const char *var; + int no_floppy; + char **hints; + unsigned nhints; + int count; + int is_cache; +}; + +/* Helper for FUNC_NAME. */ +static int +iterate_device (const char *name, void *data) +{ + struct search_ctx *ctx = data; + int found = 0; + + /* Skip floppy drives when requested. */ + if (ctx->no_floppy && + name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') + return 1; + + if (g_no_vtoyefi_part && (grub_strcmp(name, g_vtoyefi_dosname) == 0 || grub_strcmp(name, g_vtoyefi_gptname) == 0)) { + return 0; + } + +#ifdef DO_SEARCH_FS_UUID +#define compare_fn grub_strcasecmp +#else +#define compare_fn grub_strcmp +#endif + +#ifdef DO_SEARCH_FILE + { + char *buf; + grub_file_t file; + + buf = grub_xasprintf ("(%s)%s", name, ctx->key); + if (! buf) + return 1; + + file = grub_file_open (buf, GRUB_FILE_TYPE_FS_SEARCH + | GRUB_FILE_TYPE_NO_DECOMPRESS); + if (file) + { + found = 1; + grub_file_close (file); + } + grub_free (buf); + } +#else + { + /* SEARCH_FS_UUID or SEARCH_LABEL */ + grub_device_t dev; + grub_fs_t fs; + char *quid; + + dev = grub_device_open (name); + if (dev) + { + fs = grub_fs_probe (dev); + +#ifdef DO_SEARCH_FS_UUID +#define read_fn fs_uuid +#else +#define read_fn fs_label +#endif + + if (fs && fs->read_fn) + { + fs->read_fn (dev, &quid); + + if (grub_errno == GRUB_ERR_NONE && quid) + { + if (compare_fn (quid, ctx->key) == 0) + found = 1; + + grub_free (quid); + } + } + + grub_device_close (dev); + } + } +#endif + + if (!ctx->is_cache && found && ctx->count == 0) + { + struct cache_entry *cache_ent; + cache_ent = grub_malloc (sizeof (*cache_ent)); + if (cache_ent) + { + cache_ent->key = grub_strdup (ctx->key); + cache_ent->value = grub_strdup (name); + if (cache_ent->value && cache_ent->key) + { + cache_ent->next = cache; + cache = cache_ent; + } + else + { + grub_free (cache_ent->value); + grub_free (cache_ent->key); + grub_free (cache_ent); + grub_errno = GRUB_ERR_NONE; + } + } + else + grub_errno = GRUB_ERR_NONE; + } + + if (found) + { + ctx->count++; + if (ctx->var) + grub_env_set (ctx->var, name); + else + grub_printf (" %s", name); + } + + grub_errno = GRUB_ERR_NONE; + return (found && ctx->var); +} + +/* Helper for FUNC_NAME. */ +static int +part_hook (grub_disk_t disk, const grub_partition_t partition, void *data) +{ + struct search_ctx *ctx = data; + char *partition_name, *devname; + int ret; + + partition_name = grub_partition_get_name (partition); + if (! partition_name) + return 1; + + devname = grub_xasprintf ("%s,%s", disk->name, partition_name); + grub_free (partition_name); + if (!devname) + return 1; + ret = iterate_device (devname, ctx); + grub_free (devname); + + return ret; +} + +/* Helper for FUNC_NAME. */ +static void +try (struct search_ctx *ctx) +{ + unsigned i; + struct cache_entry **prev; + struct cache_entry *cache_ent; + + for (prev = &cache, cache_ent = *prev; cache_ent; + prev = &cache_ent->next, cache_ent = *prev) + if (compare_fn (cache_ent->key, ctx->key) == 0) + break; + if (cache_ent) + { + ctx->is_cache = 1; + if (iterate_device (cache_ent->value, ctx)) + { + ctx->is_cache = 0; + return; + } + ctx->is_cache = 0; + /* Cache entry was outdated. Remove it. */ + if (!ctx->count) + { + *prev = cache_ent->next; + grub_free (cache_ent->key); + grub_free (cache_ent->value); + grub_free (cache_ent); + } + } + + for (i = 0; i < ctx->nhints; i++) + { + char *end; + if (!ctx->hints[i][0]) + continue; + end = ctx->hints[i] + grub_strlen (ctx->hints[i]) - 1; + if (*end == ',') + *end = 0; + if (iterate_device (ctx->hints[i], ctx)) + { + if (!*end) + *end = ','; + return; + } + if (!*end) + { + grub_device_t dev; + int ret; + dev = grub_device_open (ctx->hints[i]); + if (!dev) + { + if (!*end) + *end = ','; + continue; + } + if (!dev->disk) + { + grub_device_close (dev); + if (!*end) + *end = ','; + continue; + } + ret = grub_partition_iterate (dev->disk, part_hook, ctx); + if (!*end) + *end = ','; + grub_device_close (dev); + if (ret) + return; + } + } + grub_device_iterate (iterate_device, ctx); +} + +void +FUNC_NAME (const char *key, const char *var, int no_floppy, + char **hints, unsigned nhints) +{ + struct search_ctx ctx = { + .key = key, + .var = var, + .no_floppy = no_floppy, + .hints = hints, + .nhints = nhints, + .count = 0, + .is_cache = 0 + }; + grub_fs_autoload_hook_t saved_autoload; + + g_no_vtoyefi_part = 0; + if (grub_env_get("VTOY_SEARCH_NO_VTOYEFI")) + { + grub_snprintf(g_vtoyefi_dosname, sizeof(g_vtoyefi_dosname), "%s,msdos2", grub_env_get("vtoydev")); + grub_snprintf(g_vtoyefi_gptname, sizeof(g_vtoyefi_gptname), "%s,gpt2", grub_env_get("vtoydev")); + g_no_vtoyefi_part = 1; + } + + /* First try without autoloading if we're setting variable. */ + if (var) + { + saved_autoload = grub_fs_autoload_hook; + grub_fs_autoload_hook = 0; + try (&ctx); + + /* Restore autoload hook. */ + grub_fs_autoload_hook = saved_autoload; + + /* Retry with autoload if nothing found. */ + if (grub_errno == GRUB_ERR_NONE && ctx.count == 0) + try (&ctx); + } + else + try (&ctx); + + if (grub_errno == GRUB_ERR_NONE && ctx.count == 0) + grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key); +} + +static grub_err_t +grub_cmd_do_search (grub_command_t cmd __attribute__ ((unused)), int argc, + char **args) +{ + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + FUNC_NAME (args[0], argc == 1 ? 0 : args[1], 0, (args + 2), + argc > 2 ? argc - 2 : 0); + + return grub_errno; +} + +static grub_command_t cmd; + +#ifdef DO_SEARCH_FILE +GRUB_MOD_INIT(search_fs_file) +#elif defined (DO_SEARCH_FS_UUID) +GRUB_MOD_INIT(search_fs_uuid) +#else +GRUB_MOD_INIT(search_label) +#endif +{ + cmd = + grub_register_command (COMMAND_NAME, grub_cmd_do_search, + N_("NAME [VARIABLE] [HINTS]"), + HELP_MESSAGE); +} + +#ifdef DO_SEARCH_FILE +GRUB_MOD_FINI(search_fs_file) +#elif defined (DO_SEARCH_FS_UUID) +GRUB_MOD_FINI(search_fs_uuid) +#else +GRUB_MOD_FINI(search_label) +#endif +{ + grub_unregister_command (cmd); +} 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 8be06582..e21bd63b 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 @@ -1111,26 +1111,13 @@ void ventoy_swap_img(img_info *img1, img_info *img2) static int ventoy_img_name_valid(const char *filename, grub_size_t namelen) { - grub_size_t i; - + (void)namelen; + if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_') { return 0; } - for (i = 0; i < namelen; i++) - { - if (filename[i] == ' ' || filename[i] == '\t') - { - return 0; - } - - if ((grub_uint8_t)(filename[i]) >= 127) - { - return 0; - } - } - return 1; } @@ -1150,7 +1137,7 @@ 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 i = 0; int type = 0; int ignore = 0; int index = 0; @@ -1297,15 +1284,6 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho img->plugin_list_index = index; grub_snprintf(img->name, sizeof(img->name), "%s", filename); - for (i = 0; i < (int)len; i++) - { - if (filename[i] == ' ' || filename[i] == '\t' || (0 == grub_isprint(filename[i]))) - { - img->name[i] = '*'; - img->unsupport = 1; - } - } - img->pathlen = grub_snprintf(img->path, sizeof(img->path), "%s%s", node->dir, img->name); img->size = info->size; @@ -4001,6 +3979,7 @@ static cmd_para ventoy_cmds[] = { "vt_windows_locate_wim_patch", ventoy_cmd_locate_wim_patch, 0, NULL, "", "", NULL }, { "vt_windows_count_wim_patch", ventoy_cmd_wim_patch_count, 0, NULL, "", "", NULL }, { "vt_dump_wim_patch", ventoy_cmd_dump_wim_patch, 0, NULL, "", "", NULL }, + { "vt_wim_check_bootable", ventoy_cmd_wim_check_bootable, 0, NULL, "", "", NULL }, { "vt_wim_chain_data", ventoy_cmd_wim_chain_data, 0, NULL, "", "", NULL }, { "vt_add_replace_file", ventoy_cmd_add_replace_file, 0, NULL, "", "", NULL }, 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 207aee96..ae0f6f00 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 @@ -508,6 +508,7 @@ grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **a grub_err_t ventoy_cmd_wimdows_reset(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); +grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_dump_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args); VTOY_JSON *vtoy_json_find_item @@ -731,6 +732,24 @@ typedef struct install_template struct install_template *next; }install_template; +typedef struct dudfile +{ + int size; + char *buf; +}dudfile; + +typedef struct dud +{ + int pathlen; + char isopath[256]; + + int dudnum; + file_fullpath *dudpath; + dudfile *files; + + struct dud *next; +}dud; + typedef struct persistence_config { int pathlen; @@ -855,6 +874,8 @@ const char * ventoy_plugin_get_menu_class(int type, const char *name); int ventoy_plugin_check_memdisk(const char *isopath); int ventoy_plugin_get_image_list_index(int type, const char *name); conf_replace * ventoy_plugin_find_conf_replace(const char *iso); +dud * ventoy_plugin_find_dud(const char *iso); +int ventoy_plugin_load_dud(dud *node, const char *isopart); 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 1718e19d..21ac4f5f 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 @@ -1044,11 +1044,15 @@ grub_err_t ventoy_cmd_cpio_busybox_64(grub_extcmd_context_t ctxt, int argc, char grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **args) { + int i; int rc; + char *pos = NULL; char *template_file = NULL; char *template_buf = NULL; char *persistent_buf = NULL; char *injection_buf = NULL; + dud *dudnode = NULL; + char tmpname[128]; const char *injection_file = NULL; grub_uint8_t *buf = NULL; grub_uint32_t mod; @@ -1059,6 +1063,7 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg grub_uint32_t template_size = 0; grub_uint32_t persistent_size = 0; grub_uint32_t injection_size = 0; + grub_uint32_t dud_size = 0; grub_file_t file; grub_file_t tmpfile; ventoy_img_chunk_list chunk_list; @@ -1152,11 +1157,30 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg debug("injection not configed %s\n", args[1]); } - g_ventoy_cpio_buf = grub_malloc(file->size + 4096 + template_size + persistent_size + injection_size + img_chunk_size); + dudnode = ventoy_plugin_find_dud(args[1]); + if (dudnode) + { + debug("dud file: <%d>\n", dudnode->dudnum); + ventoy_plugin_load_dud(dudnode, args[2]); + for (i = 0; i < dudnode->dudnum; i++) + { + if (dudnode->files[i].size > 0) + { + dud_size += dudnode->files[i].size + sizeof(cpio_newc_header); + } + } + } + else + { + debug("dud not configed %s\n", args[1]); + } + + g_ventoy_cpio_buf = grub_malloc(file->size + 40960 + template_size + + persistent_size + injection_size + dud_size + img_chunk_size); if (NULL == g_ventoy_cpio_buf) { grub_file_close(file); - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't alloc memory %llu\n", file->size + 4096 + img_chunk_size); + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't alloc memory %llu\n", file->size); } grub_file_read(file, g_ventoy_cpio_buf, file->size); @@ -1198,6 +1222,18 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg injection_buf = NULL; } + if (dud_size > 0) + { + for (i = 0; i < dudnode->dudnum; i++) + { + pos = grub_strrchr(dudnode->dudpath[i].path, '.'); + grub_snprintf(tmpname, sizeof(tmpname), "ventoy/ventoy_dud%d%s", i, (pos ? pos : ".iso")); + dud_size = dudnode->files[i].size; + headlen = ventoy_cpio_newc_fill_head(buf, dud_size, dudnode->files[i].buf, tmpname); + buf += headlen + ventoy_align(dud_size, 4); + } + } + /* step2: insert os param to cpio */ headlen = ventoy_cpio_newc_fill_head(buf, 0, NULL, "ventoy/ventoy_os_param"); padlen = sizeof(ventoy_os_param); 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 a5c2c030..0f92a008 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 @@ -41,6 +41,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); static char g_iso_disk_name[128]; static install_template *g_install_template_head = NULL; +static dud *g_dud_head = NULL; static persistence_config *g_persistence_head = NULL; static menu_alias *g_menu_alias_head = NULL; static menu_class *g_menu_class_head = NULL; @@ -590,6 +591,110 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk return 0; } +static int ventoy_plugin_dud_check(VTOY_JSON *json, const char *isodisk) +{ + int pathnum = 0; + const char *iso = NULL; + VTOY_JSON *pNode = NULL; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array type %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->enDataType != JSON_TYPE_OBJECT) + { + grub_printf("NOT object type\n"); + } + + iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (iso) + { + if (0 == ventoy_plugin_check_path(isodisk, iso)) + { + grub_printf("image: %s [OK]\n", iso); + ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "dud", &pathnum); + } + else + { + grub_printf("image: %s [FAIL]\n", iso); + } + } + else + { + grub_printf("image not found\n"); + } + } + + return 0; +} + +static int ventoy_plugin_dud_entry(VTOY_JSON *json, const char *isodisk) +{ + int pathnum = 0; + const char *iso = NULL; + VTOY_JSON *pNode = NULL; + dud *node = NULL; + dud *next = NULL; + file_fullpath *dudpath = NULL; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_dud_head) + { + for (node = g_dud_head; node; node = next) + { + next = node->next; + grub_check_free(node->dudpath); + grub_free(node); + } + + g_dud_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (iso && iso[0] == '/') + { + if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "dud", &dudpath, &pathnum)) + { + node = grub_zalloc(sizeof(dud)); + if (node) + { + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); + node->dudpath = dudpath; + node->dudnum = pathnum; + node->files = grub_zalloc(sizeof(dudfile) * pathnum); + + if (node->files) + { + if (g_dud_head) + { + node->next = g_dud_head; + } + + g_dud_head = node; + } + else + { + grub_free(node); + } + } + } + } + } + + return 0; +} + static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk) { int autosel = 0; @@ -1333,6 +1438,7 @@ static plugin_entry g_plugin_entries[] = { "auto_memdisk", ventoy_plugin_auto_memdisk_entry, ventoy_plugin_auto_memdisk_check }, { "image_list", ventoy_plugin_image_list_entry, ventoy_plugin_image_list_check }, { "conf_replace", ventoy_plugin_conf_replace_entry, ventoy_plugin_conf_replace_check }, + { "dud", ventoy_plugin_dud_entry, ventoy_plugin_dud_check }, }; static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk) @@ -1761,6 +1867,59 @@ conf_replace * ventoy_plugin_find_conf_replace(const char *iso) return NULL; } +dud * ventoy_plugin_find_dud(const char *iso) +{ + int len; + dud *node; + + if (!g_dud_head) + { + return NULL; + } + + len = (int)grub_strlen(iso); + for (node = g_dud_head; node; node = node->next) + { + if (node->pathlen == len && grub_strncmp(iso, node->isopath, len) == 0) + { + return node; + } + } + + return NULL; +} + +int ventoy_plugin_load_dud(dud *node, const char *isopart) +{ + int i; + char *buf; + grub_file_t file; + + for (i = 0; i < node->dudnum; i++) + { + if (node->files[i].size > 0) + { + debug("file %d has been loaded\n", i); + continue; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", isopart, node->dudpath[i].path); + if (file) + { + buf = grub_malloc(file->size); + if (buf) + { + grub_file_read(file, buf, file->size); + node->files[i].size = (int)file->size; + node->files[i].buf = buf; + } + grub_file_close(file); + } + } + + return 0; +} + grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args) { int i = 0; @@ -1782,6 +1941,7 @@ grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, ch if (!file) { grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n"); + grub_printf("Attention: directory name and filename are both case-sensitive.\n"); 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 a9d3c81f..3f7612be 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 @@ -1542,6 +1542,41 @@ static int ventoy_get_wim_chunklist(const char *filename, ventoy_img_chunk_list return 0; } +grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t boot_index; + grub_file_t file = NULL; + wim_header *wimhdr = NULL; + + (void)ctxt; + (void)argc; + + wimhdr = grub_zalloc(sizeof(wim_header)); + if (!wimhdr) + { + return 1; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + grub_free(wimhdr); + return 1; + } + + grub_file_read(file, wimhdr, sizeof(wim_header)); + grub_file_close(file); + boot_index = wimhdr->boot_index; + grub_free(wimhdr); + + if (boot_index == 0) + { + return 1; + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args) { grub_uint32_t i = 0; diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh index ed53f4ca..cff0f107 100644 --- a/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh @@ -42,10 +42,17 @@ fi echo "VTKS=$VTKS" >> $VTLOG +if ls $VTOY_PATH | $GREP -q 'ventoy_dud[0-9]'; then + for vtDud in $(ls $VTOY_PATH/ventoy_dud*); do + vtInstDD="$vtInstDD inst.dd=file:$vtDud" + done +fi +echo "vtInstDD=$vtInstDD" >> $VTLOG + if $GREP -q 'root=live' /proc/cmdline; then - $SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE root=live:/dev/dm-0 $VTKS#" -i /lib/dracut-lib.sh + $SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE root=live:/dev/dm-0 $VTKS $vtInstDD#" -i /lib/dracut-lib.sh else - $SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE inst.stage2=hd:/dev/dm-0 $VTKS#" -i /lib/dracut-lib.sh + $SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE inst.stage2=hd:/dev/dm-0 $VTKS $vtInstDD#" -i /lib/dracut-lib.sh fi ventoy_set_inotify_script rhel7/ventoy-inotifyd-hook.sh diff --git a/IMG/cpio/ventoy/hook/suse/ventoy-hook.sh b/IMG/cpio/ventoy/hook/suse/ventoy-hook.sh index 9574efe5..47aa0504 100644 --- a/IMG/cpio/ventoy/hook/suse/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/suse/ventoy-hook.sh @@ -26,6 +26,32 @@ if [ -f $VTOY_PATH/autoinstall ]; then fi fi +if $BUSYBOX_PATH/ls $VTOY_PATH | $GREP -q 'ventoy_dud[0-9]'; then + if [ -f /linuxrc.config ]; then + vtKerVer=$($BUSYBOX_PATH/uname -r) + ventoy_check_insmod /modules/loop.ko + ventoy_check_insmod /modules/squashfs.ko + + ventoy_check_mount /parts/00_lib /modules + ventoy_check_insmod /modules/lib/modules/$vtKerVer/initrd/isofs.ko + $BUSYBOX_PATH/umount /modules + + for vtDud in $($BUSYBOX_PATH/ls $VTOY_PATH/ventoy_dud*); do + $BUSYBOX_PATH/mkdir -p ${vtDud%.*}_mnt + if $BUSYBOX_PATH/mount $vtDud ${vtDud%.*}_mnt > /dev/null 2>&1; then + $BUSYBOX_PATH/cp -a ${vtDud%.*}_mnt ${vtDud%.*}_data + $BUSYBOX_PATH/umount ${vtDud%.*}_mnt + echo "dud: file://${vtDud%.*}_data" >> /linuxrc.config + else + echo "mount $vtDud failed" >> $VTLOG + fi + done + + $BUSYBOX_PATH/rmmod isofs >> $VTLOG 2>&1 + $BUSYBOX_PATH/rmmod squashfs >> $VTLOG 2>&1 + $BUSYBOX_PATH/rmmod loop >> $VTLOG 2>&1 + fi +fi #echo "Exec: /bin/sh $VTOY_PATH/hook/suse/cdrom-hook.sh" >> /info-ventoy #echo "install: hd:/?device=/dev/mapper/ventoy" >> /info-ventoy diff --git a/IMG/cpio/ventoy/hook/ventoy-os-lib.sh b/IMG/cpio/ventoy/hook/ventoy-os-lib.sh index fb36ac25..dbd015f8 100644 --- a/IMG/cpio/ventoy/hook/ventoy-os-lib.sh +++ b/IMG/cpio/ventoy/hook/ventoy-os-lib.sh @@ -110,4 +110,14 @@ ventoy_set_loop_inotify_script() { echo $VTOY_PATH/loop/$1 > $VTOY_PATH/inotifyd-loop-script.txt } +ventoy_check_insmod() { + if [ -e $1 ]; then + $BUSYBOX_PATH/insmod $1 + fi +} +ventoy_check_mount() { + if [ -e $1 ]; then + $BUSYBOX_PATH/mount $1 $2 + fi +} diff --git a/INSTALL/EFI/BOOT/grubx64_real.efi b/INSTALL/EFI/BOOT/grubx64_real.efi index 21649902..f6bf038f 100644 Binary files a/INSTALL/EFI/BOOT/grubx64_real.efi and b/INSTALL/EFI/BOOT/grubx64_real.efi differ diff --git a/INSTALL/grub/debug.cfg b/INSTALL/grub/debug.cfg index d62d26be..9be152db 100644 --- a/INSTALL/grub/debug.cfg +++ b/INSTALL/grub/debug.cfg @@ -94,6 +94,15 @@ submenu 'Check plugin json configuration (ventoy.json)' --class=debug_json { unset pager } + menuentry 'Check dud plugin configuration' --class=debug_dud { + set pager=1 + vt_check_plugin_json $vt_plugin_path dud $vtoy_iso_part + + echo -e "\npress ENTER to exit ..." + read vtInputKey + unset pager + } + menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET { echo 'Return ...' } diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg index ac0ccde9..82fdbbbe 100644 --- a/INSTALL/grub/grub.cfg +++ b/INSTALL/grub/grub.cfg @@ -46,7 +46,7 @@ function ventoy_gui_console { function ventoy_acpi_param { if [ "$VTOY_PARAM_NO_ACPI" != "1" ]; then - vt_acpi_param $1 $2 + vt_acpi_param "$1" "$2" fi } @@ -283,7 +283,7 @@ function distro_specify_initrd_file_phase2 { function ventoy_get_ghostbsd_ver { - # vt_parse_iso_create_date $1/${chosen_path} vt_create_date + # vt_parse_iso_create_date "$1/${chosen_path}" vt_create_date # if regexp "^202005" "$vt_create_date"; then # set vt_freebsd_ver=12.x # fi @@ -322,11 +322,11 @@ function ventoy_freebsd_proc { set vtFreeBsdDistro=FreeBSD if vt_strstr "$vt_volume_id" "GHOSTBSD"; then - ventoy_get_ghostbsd_ver $1 ${chosen_path} + ventoy_get_ghostbsd_ver "$1" "${chosen_path}" elif vt_strstr "$vt_volume_id" "FREENAS"; then - ventoy_get_freenas_ver $1 ${chosen_path} + ventoy_get_freenas_ver "$1" "${chosen_path}" elif vt_strstr "$vt_volume_id" "FURYBSD"; then - ventoy_get_furybsd_ver $1 ${chosen_path} + ventoy_get_furybsd_ver "$1" "${chosen_path}" elif regexp "^13_[0-9]" "$vt_volume_id"; then set vt_freebsd_ver=13.x elif regexp "^12_[0-9]" "$vt_volume_id"; then @@ -338,7 +338,7 @@ function ventoy_freebsd_proc { elif regexp "^9_[0-9]" "$vt_volume_id"; then set vt_freebsd_ver=9.x elif [ -d (loop)/usr/midnightbsd-dist ]; then - ventoy_get_midnightbsd_ver $1 ${chosen_path} + ventoy_get_midnightbsd_ver "$1" "${chosen_path}" set vtFreeBsdDistro=MidnightBSD elif [ -e (loop)/bin/freebsd-version ]; then vt_unix_parse_freebsd_ver (loop)/bin/freebsd-version vt_userland_ver @@ -399,7 +399,7 @@ function ventoy_freebsd_proc { fi vt_unix_replace_ko $vt_unix_mod_path (vtunix)/ventoy_unix/$vtFreeBsdDistro/geom_ventoy_ko/$vt_freebsd_ver/$vt_freebsd_bit/geom_ventoy.ko.xz - vt_unix_replace_conf FreeBSD ${1}${chosen_path} + vt_unix_replace_conf FreeBSD "${1}${chosen_path}" } function ventoy_unix_comm_proc { @@ -409,7 +409,7 @@ function ventoy_unix_comm_proc { loopback vtunix $vtoy_efi_part/ventoy/ventoy_unix.cpio if [ "$vt_unix_type" = "FreeBSD" ]; then - ventoy_freebsd_proc $1 ${chosen_path} + ventoy_freebsd_proc "$1" "${chosen_path}" elif [ "$vt_unix_type" = "NetBSD" ]; then echo "NetBSD not supported" @@ -422,7 +422,7 @@ function ventoy_unix_comm_proc { fi fi - vt_unix_chain_data ${1}${chosen_path} + vt_unix_chain_data "${1}${chosen_path}" ventoy_debug_pause } @@ -435,7 +435,7 @@ function uefi_windows_menu_func { if [ "$ventoy_fs_probe" = "iso9660" ]; then loopback -d loop vt_iso9660_nojoliet 1 - loopback loop $1$2 + loopback loop "$1$2" fi for file in "efi/microsoft/boot/bcd"; do @@ -451,7 +451,7 @@ function uefi_windows_menu_func { locate_wim fi - vt_windows_chain_data ${1}${chosen_path} + vt_windows_chain_data "${1}${chosen_path}" ventoy_debug_pause if [ -n "$vtoy_chain_mem_addr" ]; then @@ -472,10 +472,10 @@ function uefi_linux_menu_func { if [ "$ventoy_fs_probe" = "udf" ]; then loopback -d loop set ventoy_fs_probe=iso9660 - loopback loop $1$2 + loopback loop "$1$2" fi - vt_load_cpio ${vtoy_path}/ventoy.cpio $2 $1 "busybox=$ventoy_busybox_ver" + vt_load_cpio ${vtoy_path}/ventoy.cpio "$2" "$1" "busybox=$ventoy_busybox_ver" vt_linux_clear_initrd @@ -561,7 +561,7 @@ function uefi_linux_menu_func { fi - vt_linux_chain_data ${1}${chosen_path} + vt_linux_chain_data "${1}${chosen_path}" if [ -n "$vtoy_chain_mem_addr" ]; then ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 @@ -575,7 +575,7 @@ function uefi_linux_menu_func { } function uefi_unix_menu_func { - ventoy_unix_comm_proc $1 ${chosen_path} + ventoy_unix_comm_proc $1 "${chosen_path}" if [ -n "$vtoy_chain_mem_addr" ]; then ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 @@ -603,18 +603,18 @@ function uefi_iso_menu_func { unset LoadIsoEfiDriver fi - set chosen_path=$2 - vt_select_auto_install ${chosen_path} - vt_select_persistence ${chosen_path} + set chosen_path="$2" + vt_select_auto_install "${chosen_path}" + vt_select_persistence "${chosen_path}" - if vt_is_udf ${1}${chosen_path}; then + if vt_is_udf "${1}${chosen_path}"; then set ventoy_fs_probe=udf else set ventoy_fs_probe=iso9660 vt_iso9660_nojoliet 0 fi - loopback loop ${1}${chosen_path} + loopback loop "${1}${chosen_path}" get_os_type (loop) if [ -d (loop)/EFI ]; then @@ -634,19 +634,19 @@ function uefi_iso_menu_func { vt_check_compatible (loop) fi - vt_img_sector ${1}${chosen_path} + vt_img_sector "${1}${chosen_path}" if [ "$ventoy_fs_probe" = "iso9660" ]; then - vt_select_conf_replace ${1} ${chosen_path} + vt_select_conf_replace "${1}" "${chosen_path}" fi if [ "$vtoy_os" = "Windows" ]; then vt_check_compatible_pe (loop) - uefi_windows_menu_func $1 ${chosen_path} + uefi_windows_menu_func "$1" "${chosen_path}" elif [ "$vtoy_os" = "Unix" ]; then - uefi_unix_menu_func $1 ${chosen_path} + uefi_unix_menu_func "$1" "${chosen_path}" else - uefi_linux_menu_func $1 ${chosen_path} + uefi_linux_menu_func "$1" "${chosen_path}" fi ventoy_gui_console @@ -654,7 +654,7 @@ function uefi_iso_menu_func { function uefi_iso_memdisk { echo 'Loading ISO file to memory ...' - vt_load_img_memdisk ${1}${2} vtoy_iso_buf + vt_load_img_memdisk "${1}${2}" vtoy_iso_buf ventoy_cli_console chainloader ${vtoy_path}/ventoy_x64.efi memdisk env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_iso_buf_addr}:size:${vtoy_iso_buf_size} @@ -672,7 +672,7 @@ function legacy_windows_menu_func { if [ "$ventoy_fs_probe" = "iso9660" ]; then loopback -d loop vt_iso9660_nojoliet 1 - loopback loop $1$2 + loopback loop "$1$2" fi for file in "boot/bcd" "/efi/microsoft/boot/bcd" "SSTR/BCD"; do @@ -690,7 +690,7 @@ function legacy_windows_menu_func { locate_wim fi - vt_windows_chain_data ${1}${chosen_path} + vt_windows_chain_data "${1}${chosen_path}" ventoy_debug_pause if [ -n "$vtoy_chain_mem_addr" ]; then @@ -709,10 +709,10 @@ function legacy_linux_menu_func { if [ "$ventoy_fs_probe" = "udf" ]; then loopback -d loop set ventoy_fs_probe=iso9660 - loopback loop $1$2 + loopback loop "$1$2" fi - vt_load_cpio $vtoy_path/ventoy.cpio $2 $1 "busybox=$ventoy_busybox_ver" + vt_load_cpio $vtoy_path/ventoy.cpio "$2" "$1" "busybox=$ventoy_busybox_ver" vt_linux_clear_initrd @@ -755,7 +755,7 @@ function legacy_linux_menu_func { locate_initrd fi - vt_linux_chain_data ${1}${chosen_path} + vt_linux_chain_data "${1}${chosen_path}" ventoy_debug_pause if [ -n "$vtoy_chain_mem_addr" ]; then @@ -770,7 +770,7 @@ function legacy_linux_menu_func { function legacy_unix_menu_func { - ventoy_unix_comm_proc $1 ${chosen_path} + ventoy_unix_comm_proc $1 "${chosen_path}" if [ -n "$vtoy_chain_mem_addr" ]; then #ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 @@ -789,18 +789,19 @@ function legacy_iso_menu_func { loopback -d loop fi - set chosen_path=$2 - vt_select_auto_install ${chosen_path} - vt_select_persistence ${chosen_path} + set chosen_path="$2" + + vt_select_auto_install "${chosen_path}" + vt_select_persistence "${chosen_path}" - if vt_is_udf ${1}${chosen_path}; then + if vt_is_udf "${1}${chosen_path}"; then set ventoy_fs_probe=udf else set ventoy_fs_probe=iso9660 vt_iso9660_nojoliet 0 fi - loopback loop ${1}${chosen_path} + loopback loop "${1}${chosen_path}" get_os_type (loop) @@ -813,19 +814,19 @@ function legacy_iso_menu_func { vt_check_compatible (loop) fi - vt_img_sector ${1}${chosen_path} + vt_img_sector "${1}${chosen_path}" if [ "$ventoy_fs_probe" = "iso9660" ]; then - vt_select_conf_replace ${1} ${chosen_path} + vt_select_conf_replace "${1}" "${chosen_path}" fi if [ "$vtoy_os" = "Windows" ]; then vt_check_compatible_pe (loop) - legacy_windows_menu_func $1 ${chosen_path} + legacy_windows_menu_func "$1" "${chosen_path}" elif [ "$vtoy_os" = "Unix" ]; then - legacy_unix_menu_func $1 ${chosen_path} + legacy_unix_menu_func "$1" "${chosen_path}" else - legacy_linux_menu_func $1 ${chosen_path} + legacy_linux_menu_func "$1" "${chosen_path}" fi } @@ -833,7 +834,7 @@ function legacy_iso_memdisk { linux16 $vtoy_path/memdisk iso raw echo "Loading ISO file to memory ..." - initrd16 ${1}${2} + initrd16 "${1}${2}" boot } @@ -843,11 +844,11 @@ function iso_endless_os_proc { loopback -d loop fi - loopback loop ${1}${2} - vt_img_sector ${1}${2} + loopback loop "${1}${2}" + vt_img_sector "${1}${2}" - vt_load_cpio $vtoy_path/ventoy.cpio $2 $1 "busybox=$ventoy_busybox_ver" - vt_trailer_cpio $1 $2 noinit + vt_load_cpio $vtoy_path/ventoy.cpio "$2" "$1" "busybox=$ventoy_busybox_ver" + vt_trailer_cpio "$1" "$2" noinit ventoy_debug_pause @@ -873,7 +874,7 @@ function ventoy_iso_busybox_ver { #special process for deepin-live iso if [ "$vt_chosen_size" = "403701760" ]; then - if vt_str_str $vt_chosen_path "/deepin-live"; then + if vt_str_str "$vt_chosen_path" "/deepin-live"; then set ventoy_busybox_ver=64 fi elif vt_str_begin $vt_volume_id "PHOTON_"; then @@ -889,28 +890,28 @@ function iso_common_menuentry { unset vt_volume_id vt_chosen_img_path vt_chosen_path vt_chosen_size - vt_parse_iso_volume ${vtoy_iso_part}${vt_chosen_path} vt_system_id vt_volume_id + vt_parse_iso_volume "${vtoy_iso_part}${vt_chosen_path}" vt_system_id vt_volume_id ventoy_iso_busybox_ver #special process for Endless OS if vt_str_begin $vt_volume_id "Endless-OS"; then - iso_endless_os_proc $vtoy_iso_part $vt_chosen_path + iso_endless_os_proc $vtoy_iso_part "$vt_chosen_path" elif vt_str_begin $vt_volume_id "TENS-Public"; then set vtcompat=1 fi if [ "$grub_platform" = "pc" ]; then if vt_check_mode 0; then - legacy_iso_memdisk $vtoy_iso_part $vt_chosen_path + legacy_iso_memdisk $vtoy_iso_part "$vt_chosen_path" else - legacy_iso_menu_func $vtoy_iso_part $vt_chosen_path + legacy_iso_menu_func $vtoy_iso_part "$vt_chosen_path" fi else if vt_check_mode 0; then - uefi_iso_memdisk $vtoy_iso_part $vt_chosen_path + uefi_iso_memdisk $vtoy_iso_part "$vt_chosen_path" else - uefi_iso_menu_func $vtoy_iso_part $vt_chosen_path + uefi_iso_menu_func $vtoy_iso_part "$vt_chosen_path" fi fi } @@ -923,9 +924,9 @@ function miso_common_menuentry { ventoy_debug_pause if [ "$grub_platform" = "pc" ]; then - legacy_iso_memdisk $vtoy_iso_part $vt_chosen_path + legacy_iso_memdisk $vtoy_iso_part "$vt_chosen_path" else - uefi_iso_memdisk $vtoy_iso_part $vt_chosen_path + uefi_iso_memdisk $vtoy_iso_part "$vt_chosen_path" fi } @@ -947,7 +948,12 @@ function iso_unsupport_menuentry { function wim_common_menuentry { vt_chosen_img_path vt_chosen_path vt_chosen_size - vt_wim_chain_data ${vtoy_iso_part}${vt_chosen_path} + if vt_wim_check_bootable "${vtoy_iso_part}${vt_chosen_path}"; then + vt_wim_chain_data "${vtoy_iso_part}${vt_chosen_path}" + else + echo -e "\n This is NOT a bootable WIM file. \n" + echo -e " 这不是一个可启动的 WIM 文件。\n" + fi ventoy_debug_pause @@ -973,7 +979,7 @@ function wim_unsupport_menuentry { function efi_common_menuentry { vt_chosen_img_path vt_chosen_path vt_chosen_size - vt_concat_efi_iso ${vtoy_iso_part}${vt_chosen_path} vtoy_iso_buf + vt_concat_efi_iso "${vtoy_iso_part}${vt_chosen_path}" vtoy_iso_buf ventoy_debug_pause @@ -985,7 +991,7 @@ function efi_common_menuentry { if [ -n "$vtoy_dotefi_retry" ]; then unset vtoy_dotefi_retry - chainloader ${vtoy_iso_part}${vt_chosen_path} + chainloader "${vtoy_iso_part}${vt_chosen_path}" boot fi @@ -1009,7 +1015,7 @@ function vhd_common_menuentry { fi vt_chosen_img_path vt_chosen_path vt_chosen_size - vt_patch_vhdboot $vt_chosen_path + vt_patch_vhdboot "$vt_chosen_path" ventoy_debug_pause @@ -1038,7 +1044,7 @@ function vtoyboot_common_func { set AltBootPart=0 set vtoysupport=0 - vt_get_vtoy_type ${1} vtoytype parttype AltBootPart + vt_get_vtoy_type "${1}" vtoytype parttype AltBootPart if vt_str_begin $vtoytype vhd; then set vtoysupport=1 @@ -1063,8 +1069,8 @@ function vtoyboot_common_func { fi fi - vt_img_sector ${1} - vt_raw_chain_data ${1} + vt_img_sector "${1}" + vt_raw_chain_data "${1}" ventoy_debug_pause @@ -1092,7 +1098,7 @@ function vtoyboot_common_func { function vtoy_common_menuentry { vt_chosen_img_path vt_chosen_path vt_chosen_size - vtoyboot_common_func ${vtoy_iso_part}${vt_chosen_path} + vtoyboot_common_func "${vtoy_iso_part}${vt_chosen_path}" } function vtoy_unsupport_menuentry { @@ -1107,8 +1113,8 @@ function vtoy_unsupport_menuentry { function ventoy_img_easyos { - vt_load_cpio $vtoy_path/ventoy.cpio ${vt_chosen_path} ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" - vt_trailer_cpio ${vtoy_iso_part} ${vt_chosen_path} noinit + vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit loopback easysfs (vtimghd,1)/easy.sfs vt_get_lib_module_ver (easysfs) /lib/modules/ vt_module_ver @@ -1133,8 +1139,8 @@ function ventoy_img_easyos { } function ventoy_img_volumio { - vt_load_cpio $vtoy_path/ventoy.cpio ${vt_chosen_path} ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" - vt_trailer_cpio ${vtoy_iso_part} ${vt_chosen_path} noinit + vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit ventoy_debug_pause @@ -1151,8 +1157,8 @@ function ventoy_img_volumio { function ventoy_img_openelec { elec_ver=$1 - vt_load_cpio $vtoy_path/ventoy.cpio ${vt_chosen_path} ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" - vt_trailer_cpio ${vtoy_iso_part} ${vt_chosen_path} noinit + vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit loopback vtloopex $vtoy_efi_part/ventoy/vtloopex.cpio vt_img_extra_initrd_append (vtloopex)/$elec_ver/vtloopex.tar.xz @@ -1173,8 +1179,8 @@ function ventoy_img_openelec { function ventoy_img_freedombox { - vt_load_cpio $vtoy_path/ventoy.cpio ${vt_chosen_path} ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" - vt_trailer_cpio ${vtoy_iso_part} ${vt_chosen_path} noinit + vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit vt_get_lib_module_ver (vtimghd,1) /lib/modules/ vt_module_ver if [ -n "$vt_module_ver" ]; then @@ -1194,8 +1200,8 @@ function ventoy_img_freedombox { } function ventoy_img_paldo { - vt_load_cpio $vtoy_path/ventoy.cpio ${vt_chosen_path} ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" - vt_trailer_cpio ${vtoy_iso_part} ${vt_chosen_path} noinit + vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit ventoy_debug_pause @@ -1216,8 +1222,8 @@ function ventoy_img_paldo { } function ventoy_img_ubos { - vt_load_cpio $vtoy_path/ventoy.cpio ${vt_chosen_path} ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" - vt_trailer_cpio ${vtoy_iso_part} ${vt_chosen_path} noinit + vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit vt_get_lib_module_ver (vtimghd,3) /lib/modules/ vt_module_ver if [ -n "$vt_module_ver" ]; then @@ -1240,8 +1246,8 @@ function ventoy_img_ubos { } function ventoy_img_recalbox { - vt_load_cpio $vtoy_path/ventoy.cpio ${vt_chosen_path} ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" - vt_trailer_cpio ${vtoy_iso_part} ${vt_chosen_path} noinit + vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit ventoy_debug_pause @@ -1257,8 +1263,8 @@ function ventoy_img_recalbox { } function ventoy_img_batocera { - vt_load_cpio $vtoy_path/ventoy.cpio ${vt_chosen_path} ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" - vt_trailer_cpio ${vtoy_iso_part} ${vt_chosen_path} noinit + vt_load_cpio $vtoy_path/ventoy.cpio "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit ventoy_debug_pause @@ -1295,8 +1301,8 @@ function img_common_menuentry { loopback -d vtimghd fi - loopback vtimghd ${vtoy_iso_part}${vt_chosen_path} - vt_img_sector ${vtoy_iso_part}${vt_chosen_path} + loopback vtimghd "${vtoy_iso_part}${vt_chosen_path}" + vt_img_sector "${vtoy_iso_part}${vt_chosen_path}" vt_img_part_info (vtimghd) @@ -1340,7 +1346,7 @@ function img_common_menuentry { ventoy_img_memtest86 fi else - vt_linux_chain_data ${vtoy_iso_part}${vt_chosen_path} + vt_linux_chain_data "${vtoy_iso_part}${vt_chosen_path}" ventoy_acpi_param ${vtoy_chain_mem_addr} 512 if [ "$grub_platform" = "pc" ]; then linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} sector512 mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} @@ -1369,7 +1375,7 @@ function img_unsupport_menuentry { ############################################################# ############################################################# -set VENTOY_VERSION="1.0.28" +set VENTOY_VERSION="1.0.29" #ACPI not compatible with Window7/8, so disable by default set VTOY_PARAM_NO_ACPI=1 diff --git a/INSTALL/grub/i386-pc/core.img b/INSTALL/grub/i386-pc/core.img index 04828f12..627411b7 100644 Binary files a/INSTALL/grub/i386-pc/core.img and b/INSTALL/grub/i386-pc/core.img differ diff --git a/INSTALL/grub/i386-pc/search_fs_file.mod b/INSTALL/grub/i386-pc/search_fs_file.mod index 2ec78500..65489245 100644 Binary files a/INSTALL/grub/i386-pc/search_fs_file.mod and b/INSTALL/grub/i386-pc/search_fs_file.mod differ diff --git a/INSTALL/grub/i386-pc/search_fs_uuid.mod b/INSTALL/grub/i386-pc/search_fs_uuid.mod index 218adc71..1612551a 100644 Binary files a/INSTALL/grub/i386-pc/search_fs_uuid.mod and b/INSTALL/grub/i386-pc/search_fs_uuid.mod differ diff --git a/INSTALL/grub/i386-pc/search_label.mod b/INSTALL/grub/i386-pc/search_label.mod index 71f941a2..73ec8182 100644 Binary files a/INSTALL/grub/i386-pc/search_label.mod and b/INSTALL/grub/i386-pc/search_label.mod differ diff --git a/INSTALL/grub/localboot.cfg b/INSTALL/grub/localboot.cfg index 84008865..e82677ee 100644 --- a/INSTALL/grub/localboot.cfg +++ b/INSTALL/grub/localboot.cfg @@ -92,12 +92,15 @@ else fi } - menuentry 'Search and boot BOOTX64.EFI' --class=boot_uefi { + menuentry 'Search and boot BOOTX64.EFI' --class=boot_uefi { + set VTOY_SEARCH_NO_VTOYEFI=1 if search -n -s -f /efi/boot/bootx64.efi; then + unset VTOY_SEARCH_NO_VTOYEFI terminal_output console chainloader /efi/boot/bootx64.efi boot else + unset VTOY_SEARCH_NO_VTOYEFI echo "BOOTX64.EFI NOT found ..." fi } diff --git a/INSTALL/grub/x86_64-efi/search_fs_file.mod b/INSTALL/grub/x86_64-efi/search_fs_file.mod index 83720396..d02316d5 100644 Binary files a/INSTALL/grub/x86_64-efi/search_fs_file.mod and b/INSTALL/grub/x86_64-efi/search_fs_file.mod differ diff --git a/INSTALL/grub/x86_64-efi/search_fs_uuid.mod b/INSTALL/grub/x86_64-efi/search_fs_uuid.mod index 63701d19..bd5f5558 100644 Binary files a/INSTALL/grub/x86_64-efi/search_fs_uuid.mod and b/INSTALL/grub/x86_64-efi/search_fs_uuid.mod differ diff --git a/INSTALL/grub/x86_64-efi/search_label.mod b/INSTALL/grub/x86_64-efi/search_label.mod index f1b82658..68ce50dd 100644 Binary files a/INSTALL/grub/x86_64-efi/search_label.mod and b/INSTALL/grub/x86_64-efi/search_label.mod differ diff --git a/INSTALL/tool/VentoyWorker.sh b/INSTALL/tool/VentoyWorker.sh index c74d3c9c..f12fbb7e 100644 --- a/INSTALL/tool/VentoyWorker.sh +++ b/INSTALL/tool/VentoyWorker.sh @@ -9,6 +9,7 @@ print_usage() { echo ' -i install ventoy to sdX (fail if disk already installed with ventoy)' echo ' -I force install ventoy to sdX (no matter installed or not)' echo ' -u update ventoy in sdX' + echo ' -l list Ventoy information in sdX' echo '' echo ' OPTION: (optional)' echo ' -r SIZE_MB preserve some space at the bottom of the disk (only for install)' @@ -29,6 +30,8 @@ while [ -n "$1" ]; do FORCE="Y" elif [ "$1" = "-u" ]; then MODE="update" + elif [ "$1" = "-l" ]; then + MODE="list" elif [ "$1" = "-s" ]; then SECUREBOOT="YES" elif [ "$1" = "-g" ]; then @@ -42,7 +45,7 @@ while [ -n "$1" ]; do RESERVE_SIZE_MB=$1 elif [ "$1" = "-V" ] || [ "$1" = "--version" ]; then exit 0 - elif [ "$1" == "-h" ] || [ "$1" = "--help" ]; then + elif [ "$1" = "-h" ] || [ "$1" = "--help" ]; then print_usage exit 0 else @@ -76,7 +79,7 @@ if [ -e /sys/class/block/${DISK#/dev/}/start ]; then exit 1 fi -if [ -n "$RESERVE_SPACE" ]; then +if [ -n "$RESERVE_SPACE" -a "$MODE" = "install" ]; then if echo $RESERVE_SIZE_MB | grep -q '^[0-9][0-9]*$'; then vtdebug "User will reserve $RESERVE_SIZE_MB MB disk space" else @@ -104,6 +107,36 @@ else exit 1 fi +if [ "$MODE" = "list" ]; then + version=$(get_disk_ventoy_version $DISK) + if [ $? -eq 0 ]; then + echo "Ventoy Version in Disk: $version" + + vtPart1Type=$(dd if=$DISK bs=1 count=1 skip=450 status=none | hexdump -n1 -e '1/1 "%02X"') + if [ "$vtPart1Type" = "EE" ]; then + echo "Disk Partition Style : GPT" + else + echo "Disk Partition Style : MBR" + fi + + vtPART2=$(get_disk_part_name $DISK 2) + rm -rf ./tmpmntp2 && mkdir ./tmpmntp2 + mount $vtPART2 ./tmpmntp2 > /dev/null 2>&1 + + if [ -e ./tmpmntp2/EFI/BOOT/MokManager.efi ]; then + echo "Secure Boot Support : YES" + else + echo "Secure Boot Support : NO" + fi + umount ./tmpmntp2 > /dev/null 2>&1 + rm -rf ./tmpmntp2 + else + echo "Ventoy Version: NA" + fi + echo "" + exit 0 +fi + #check mountpoint grep "^$DISK" /proc/mounts | while read mtline; do mtpnt=$(echo $mtline | awk '{print $2}') @@ -345,7 +378,7 @@ else SHORT_PART2=${PART2#/dev/} part2_start=$(cat /sys/class/block/$SHORT_PART2/start) - PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') + PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | hexdump -n1 -e '1/1 "%02X"') if [ "$PART1_TYPE" = "EE" ]; then vtdebug "This is GPT partition style ..." @@ -355,8 +388,8 @@ else vtdebug "This is MBR partition style ..." dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=440 - PART1_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=446 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') - PART2_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=462 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') + PART1_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=446 status=none | hexdump -n1 -e '1/1 "%02X"') + PART2_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=462 status=none | hexdump -n1 -e '1/1 "%02X"') vtdebug "PART1_ACTIVE=$PART1_ACTIVE PART2_ACTIVE=$PART2_ACTIVE" if [ "$PART1_ACTIVE" = "00" ] && [ "$PART2_ACTIVE" = "80" ]; then diff --git a/INSTALL/tool/ventoy_lib.sh b/INSTALL/tool/ventoy_lib.sh index b4bf1db3..7fe771a0 100644 --- a/INSTALL/tool/ventoy_lib.sh +++ b/INSTALL/tool/ventoy_lib.sh @@ -128,8 +128,8 @@ is_disk_contains_ventoy() { return fi - PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') - PART2_TYPE=$(dd if=$DISK bs=1 count=1 skip=466 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') + PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | hexdump -n1 -e '1/1 "%02X"') + PART2_TYPE=$(dd if=$DISK bs=1 count=1 skip=466 status=none | hexdump -n1 -e '1/1 "%02X"') # if [ "$PART1_TYPE" != "EE" ]; then # if [ "$PART2_TYPE" != "EF" ]; then @@ -139,7 +139,7 @@ is_disk_contains_ventoy() { # fi # fi - # PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') + # PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | hexdump -n1 -e '1/1 "%02X"') # if [ "$PART1_TYPE" != "07" ]; then # vtdebug "part1 type is $PART2_TYPE not 07" # ventoy_false diff --git a/INSTALL/ventoy/ventoy.cpio b/INSTALL/ventoy/ventoy.cpio index 88fec99c..be35a228 100644 Binary files a/INSTALL/ventoy/ventoy.cpio and b/INSTALL/ventoy/ventoy.cpio differ diff --git a/INSTALL/ventoy/vtoyjump32.exe b/INSTALL/ventoy/vtoyjump32.exe index a2610ef0..bcff9240 100644 Binary files a/INSTALL/ventoy/vtoyjump32.exe and b/INSTALL/ventoy/vtoyjump32.exe differ diff --git a/INSTALL/ventoy/vtoyjump64.exe b/INSTALL/ventoy/vtoyjump64.exe index 7881e63a..4edb6de3 100644 Binary files a/INSTALL/ventoy/vtoyjump64.exe and b/INSTALL/ventoy/vtoyjump64.exe differ diff --git a/LANGUAGES/languages.ini b/LANGUAGES/languages.ini index 41ec7803..f74709bc 100644 Binary files a/LANGUAGES/languages.ini and b/LANGUAGES/languages.ini differ diff --git a/vtoyjump/vtoyjump/vtoyjump.c b/vtoyjump/vtoyjump/vtoyjump.c index ec671f59..f5e40416 100644 --- a/vtoyjump/vtoyjump/vtoyjump.c +++ b/vtoyjump/vtoyjump/vtoyjump.c @@ -1,1208 +1,1271 @@ -/****************************************************************************** -* vtoyjump.c -* -* 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 . -* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include "vtoyjump.h" -#include "fat_filelib.h" - -static ventoy_os_param g_os_param; -static ventoy_windows_data g_windows_data; -static UINT8 g_os_param_reserved[32]; -static BOOL g_64bit_system = FALSE; -static ventoy_guid g_ventoy_guid = VENTOY_GUID; - -void Log(const char *Fmt, ...) -{ - va_list Arg; - int Len = 0; - FILE *File = NULL; - SYSTEMTIME Sys; - char szBuf[1024]; - - GetLocalTime(&Sys); - Len += sprintf_s(szBuf, sizeof(szBuf), - "[%4d/%02d/%02d %02d:%02d:%02d.%03d] ", - Sys.wYear, Sys.wMonth, Sys.wDay, - Sys.wHour, Sys.wMinute, Sys.wSecond, - Sys.wMilliseconds); - - va_start(Arg, Fmt); - Len += vsnprintf_s(szBuf + Len, sizeof(szBuf)-Len, sizeof(szBuf)-Len, Fmt, Arg); - va_end(Arg); - - fopen_s(&File, "ventoy.log", "a+"); - if (File) - { - fwrite(szBuf, 1, Len, File); - fwrite("\n", 1, 1, File); - fclose(File); - } -} - - -static int LoadNtDriver(const char *DrvBinPath) -{ - int i; - int rc = 0; - BOOL Ret; - DWORD Status; - SC_HANDLE hServiceMgr; - SC_HANDLE hService; - char name[256] = { 0 }; - - for (i = (int)strlen(DrvBinPath) - 1; i >= 0; i--) - { - if (DrvBinPath[i] == '\\' || DrvBinPath[i] == '/') - { - sprintf_s(name, sizeof(name), "%s", DrvBinPath + i + 1); - break; - } - } - - Log("Load NT driver: %s %s", DrvBinPath, name); - - hServiceMgr = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS); - if (hServiceMgr == NULL) - { - Log("OpenSCManager failed Error:%u", GetLastError()); - return 1; - } - - Log("OpenSCManager OK"); - - hService = CreateServiceA(hServiceMgr, - name, - name, - SERVICE_ALL_ACCESS, - SERVICE_KERNEL_DRIVER, - SERVICE_DEMAND_START, - SERVICE_ERROR_NORMAL, - DrvBinPath, - NULL, NULL, NULL, NULL, NULL); - if (hService == NULL) - { - Status = GetLastError(); - if (Status != ERROR_IO_PENDING && Status != ERROR_SERVICE_EXISTS) - { - Log("CreateService failed v %u", Status); - CloseServiceHandle(hServiceMgr); - return 1; - } - - hService = OpenServiceA(hServiceMgr, name, SERVICE_ALL_ACCESS); - if (hService == NULL) - { - Log("OpenService failed %u", Status); - CloseServiceHandle(hServiceMgr); - return 1; - } - } - - Log("CreateService imdisk OK"); - - Ret = StartServiceA(hService, 0, NULL); - if (Ret) - { - Log("StartService OK"); - } - else - { - Status = GetLastError(); - if (Status == ERROR_SERVICE_ALREADY_RUNNING) - { - rc = 0; - } - else - { - Log("StartService error %u", Status); - rc = 1; - } - } - - CloseServiceHandle(hService); - CloseServiceHandle(hServiceMgr); - - Log("Load NT driver %s", rc ? "failed" : "success"); - - return rc; -} - -static int ReadWholeFile2Buf(const char *Fullpath, void **Data, DWORD *Size) -{ - int rc = 1; - DWORD FileSize; - DWORD dwSize; - HANDLE Handle; - BYTE *Buffer = NULL; - - Log("ReadWholeFile2Buf <%s>", Fullpath); - - Handle = CreateFileA(Fullpath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); - if (Handle == INVALID_HANDLE_VALUE) - { - Log("Could not open the file<%s>, error:%u", Fullpath, GetLastError()); - goto End; - } - - FileSize = SetFilePointer(Handle, 0, NULL, FILE_END); - - Buffer = malloc(FileSize); - if (!Buffer) - { - Log("Failed to alloc memory size:%u", FileSize); - goto End; - } - - SetFilePointer(Handle, 0, NULL, FILE_BEGIN); - if (!ReadFile(Handle, Buffer, FileSize, &dwSize, NULL)) - { - Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError()); - goto End; - } - - *Data = Buffer; - *Size = FileSize; - - Log("Success read file size:%u", FileSize); - - rc = 0; - -End: - SAFE_CLOSE_HANDLE(Handle); - - return rc; -} - -static BOOL CheckPeHead(BYTE *Head) -{ - UINT32 PeOffset; - - if (Head[0] != 'M' || Head[1] != 'Z') - { - return FALSE; - } - - PeOffset = *(UINT32 *)(Head + 60); - if (*(UINT32 *)(Head + PeOffset) != 0x00004550) - { - return FALSE; - } - - return TRUE; -} - -static BOOL IsPe64(BYTE *buffer) -{ - DWORD pe_off; - - if (!CheckPeHead(buffer)) - { - return FALSE; - } - - pe_off = *(UINT32 *)(buffer + 60); - if (*(UINT16 *)(buffer + pe_off + 24) == 0x020b) - { - return TRUE; - } - - return FALSE; -} - - -static BOOL CheckOsParam(ventoy_os_param *param) -{ - UINT32 i; - BYTE Sum = 0; - - if (memcmp(¶m->guid, &g_ventoy_guid, sizeof(ventoy_guid))) - { - return FALSE; - } - - for (i = 0; i < sizeof(ventoy_os_param); i++) - { - Sum += *((BYTE *)param + i); - } - - if (Sum) - { - return FALSE; - } - - if (param->vtoy_img_location_addr % 4096) - { - return FALSE; - } - - return TRUE; -} - -static int SaveBuffer2File(const char *Fullpath, void *Buffer, DWORD Length) -{ - int rc = 1; - DWORD dwSize; - HANDLE Handle; - - Log("SaveBuffer2File <%s> len:%u", Fullpath, Length); - - Handle = CreateFileA(Fullpath, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, 0, 0); - if (Handle == INVALID_HANDLE_VALUE) - { - Log("Could not create new file, error:%u", GetLastError()); - goto End; - } - - WriteFile(Handle, Buffer, Length, &dwSize, NULL); - - rc = 0; - -End: - SAFE_CLOSE_HANDLE(Handle); - - return rc; -} - -static BOOL IsPathExist(BOOL Dir, const char *Fmt, ...) -{ - va_list Arg; - HANDLE hFile; - DWORD Attr; - CHAR FilePath[MAX_PATH]; - - va_start(Arg, Fmt); - vsnprintf_s(FilePath, sizeof(FilePath), sizeof(FilePath), Fmt, Arg); - va_end(Arg); - - hFile = CreateFileA(FilePath, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); - if (INVALID_HANDLE_VALUE == hFile) - { - return FALSE; - } - - CloseHandle(hFile); - - Attr = GetFileAttributesA(FilePath); - - if (Dir) - { - if ((Attr & FILE_ATTRIBUTE_DIRECTORY) == 0) - { - return FALSE; - } - } - else - { - if (Attr & FILE_ATTRIBUTE_DIRECTORY) - { - return FALSE; - } - } - - return TRUE; -} - -static int GetPhyDiskUUID(const char LogicalDrive, UINT8 *UUID, DISK_EXTENT *DiskExtent) -{ - BOOL Ret; - DWORD dwSize; - HANDLE Handle; - VOLUME_DISK_EXTENTS DiskExtents; - CHAR PhyPath[128]; - UINT8 SectorBuf[512]; - - Log("GetPhyDiskUUID %C", LogicalDrive); - - sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\%C:", LogicalDrive); - Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); - if (Handle == INVALID_HANDLE_VALUE) - { - Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError()); - return 1; - } - - Ret = DeviceIoControl(Handle, - IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, - NULL, - 0, - &DiskExtents, - (DWORD)(sizeof(DiskExtents)), - (LPDWORD)&dwSize, - NULL); - if (!Ret || DiskExtents.NumberOfDiskExtents == 0) - { - Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed, error:%u", GetLastError()); - CloseHandle(Handle); - return 1; - } - CloseHandle(Handle); - - memcpy(DiskExtent, DiskExtents.Extents, sizeof(DiskExtent)); - Log("%C: is in PhysicalDrive%d ", LogicalDrive, DiskExtents.Extents[0].DiskNumber); - - sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", DiskExtents.Extents[0].DiskNumber); - Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); - if (Handle == INVALID_HANDLE_VALUE) - { - Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError()); - return 1; - } - - if (!ReadFile(Handle, SectorBuf, sizeof(SectorBuf), &dwSize, NULL)) - { - Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError()); - CloseHandle(Handle); - return 1; - } - - memcpy(UUID, SectorBuf + 0x180, 16); - CloseHandle(Handle); - return 0; -} - -int VentoyMountISOByAPI(const char *IsoPath) -{ - HANDLE Handle; - DWORD Status; - WCHAR wFilePath[512] = { 0 }; - VIRTUAL_STORAGE_TYPE StorageType; - OPEN_VIRTUAL_DISK_PARAMETERS OpenParameters; - ATTACH_VIRTUAL_DISK_PARAMETERS AttachParameters; - - Log("VentoyMountISOByAPI <%s>", IsoPath); - - MultiByteToWideChar(CP_ACP, 0, IsoPath, (int)strlen(IsoPath), wFilePath, (int)(sizeof(wFilePath) / sizeof(WCHAR))); - - memset(&StorageType, 0, sizeof(StorageType)); - memset(&OpenParameters, 0, sizeof(OpenParameters)); - memset(&AttachParameters, 0, sizeof(AttachParameters)); - - OpenParameters.Version = OPEN_VIRTUAL_DISK_VERSION_1; - AttachParameters.Version = ATTACH_VIRTUAL_DISK_VERSION_1; - - Status = OpenVirtualDisk(&StorageType, wFilePath, VIRTUAL_DISK_ACCESS_READ, 0, &OpenParameters, &Handle); - if (Status != ERROR_SUCCESS) - { - if (ERROR_VIRTDISK_PROVIDER_NOT_FOUND == Status) - { - Log("VirtualDisk for ISO file is not supported in current system"); - } - else - { - Log("Failed to open virtual disk ErrorCode:%u", Status); - } - return 1; - } - - Log("OpenVirtualDisk success"); - - Status = AttachVirtualDisk(Handle, NULL, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY | ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME, 0, &AttachParameters, NULL); - if (Status != ERROR_SUCCESS) - { - Log("Failed to attach virtual disk ErrorCode:%u", Status); - CloseHandle(Handle); - return 1; - } - - CloseHandle(Handle); - return 0; -} - - -static HANDLE g_FatPhyDrive; -static UINT64 g_Part2StartSec; - -static int CopyFileFromFatDisk(const CHAR* SrcFile, const CHAR *DstFile) -{ - int rc = 1; - int size = 0; - char *buf = NULL; - void *flfile = NULL; - - Log("CopyFileFromFatDisk (%s)==>(%s)", SrcFile, DstFile); - - flfile = fl_fopen(SrcFile, "rb"); - if (flfile) - { - fl_fseek(flfile, 0, SEEK_END); - size = (int)fl_ftell(flfile); - fl_fseek(flfile, 0, SEEK_SET); - - buf = (char *)malloc(size); - if (buf) - { - fl_fread(buf, 1, size, flfile); - - rc = 0; - SaveBuffer2File(DstFile, buf, size); - free(buf); - } - - fl_fclose(flfile); - } - - return rc; -} - -static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount) -{ - DWORD dwSize; - BOOL bRet; - DWORD ReadSize; - LARGE_INTEGER liCurrentPosition; - - liCurrentPosition.QuadPart = Sector + g_Part2StartSec; - liCurrentPosition.QuadPart *= 512; - SetFilePointerEx(g_FatPhyDrive, liCurrentPosition, &liCurrentPosition, FILE_BEGIN); - - ReadSize = (DWORD)(SectorCount * 512); - - bRet = ReadFile(g_FatPhyDrive, Buffer, ReadSize, &dwSize, NULL); - if (bRet == FALSE || dwSize != ReadSize) - { - Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u\n", bRet, ReadSize, dwSize, GetLastError()); - } - - return 1; -} - -static CHAR GetMountLogicalDrive(void) -{ - CHAR Letter = 'Y'; - DWORD Drives; - DWORD Mask = 0x1000000; - - Drives = GetLogicalDrives(); - Log("Drives=0x%x", Drives); - - while (Mask) - { - if ((Drives & Mask) == 0) - { - break; - } - - Letter--; - Mask >>= 1; - } - - return Letter; -} - -UINT64 GetVentoyEfiPartStartSector(HANDLE hDrive) -{ - BOOL bRet; - DWORD dwSize; - MBR_HEAD MBR; - VTOY_GPT_INFO *pGpt = NULL; - UINT64 StartSector = 0; - - SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); - - bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL); - Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR); - - if ((!bRet) || (dwSize != sizeof(MBR))) - { - 0; - } - - if (MBR.PartTbl[0].FsFlag == 0xEE) - { - Log("GPT partition style"); - - pGpt = malloc(sizeof(VTOY_GPT_INFO)); - if (!pGpt) - { - return 0; - } - - SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); - bRet = ReadFile(hDrive, pGpt, sizeof(VTOY_GPT_INFO), &dwSize, NULL); - if ((!bRet) || (dwSize != sizeof(VTOY_GPT_INFO))) - { - Log("Failed to read gpt info %d %u %d", bRet, dwSize, LASTERR); - return 0; - } - - StartSector = pGpt->PartTbl[1].StartLBA; - free(pGpt); - } - else - { - Log("MBR partition style"); - StartSector = MBR.PartTbl[1].StartSectorId; - } - - Log("GetVentoyEfiPart StartSector: %llu", StartSector); - return StartSector; -} - -int VentoyMountISOByImdisk(const char *IsoPath, DWORD PhyDrive) -{ - int rc = 1; - BOOL bRet; - CHAR Letter; - DWORD dwBytes; - HANDLE hDrive; - CHAR PhyPath[MAX_PATH]; - STARTUPINFOA Si; - PROCESS_INFORMATION Pi; - GET_LENGTH_INFORMATION LengthInfo; - - Log("VentoyMountISOByImdisk %s", IsoPath); - - sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", PhyDrive); - hDrive = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); - if (hDrive == INVALID_HANDLE_VALUE) - { - Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError()); - goto End; - } - - bRet = DeviceIoControl(hDrive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &LengthInfo, sizeof(LengthInfo), &dwBytes, NULL); - if (!bRet) - { - Log("Could not get phy disk %s size, error:%u", PhyPath, GetLastError()); - goto End; - } - - g_FatPhyDrive = hDrive; - g_Part2StartSec = GetVentoyEfiPartStartSector(hDrive); - - Log("Parse FAT fs..."); - - fl_init(); - - if (0 == fl_attach_media(VentoyFatDiskRead, NULL)) - { - if (g_64bit_system) - { - CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.sys", "ventoy\\imdisk.sys"); - CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.exe", "ventoy\\imdisk.exe"); - CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.cpl", "ventoy\\imdisk.cpl"); - } - else - { - CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.sys", "ventoy\\imdisk.sys"); - CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.exe", "ventoy\\imdisk.exe"); - CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.cpl", "ventoy\\imdisk.cpl"); - } - - GetCurrentDirectoryA(sizeof(PhyPath), PhyPath); - strcat_s(PhyPath, sizeof(PhyPath), "\\ventoy\\imdisk.sys"); - - if (LoadNtDriver(PhyPath) == 0) - { - rc = 0; - - Letter = GetMountLogicalDrive(); - sprintf_s(PhyPath, sizeof(PhyPath), "ventoy\\imdisk.exe -a -o ro -f %s -m %C:", IsoPath, Letter); - - Log("mount iso to %C: use imdisk cmd <%s>", Letter, PhyPath); - - GetStartupInfoA(&Si); - - Si.dwFlags |= STARTF_USESHOWWINDOW; - Si.wShowWindow = SW_HIDE; - - CreateProcessA(NULL, PhyPath, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi); - WaitForSingleObject(Pi.hProcess, INFINITE); - } - } - fl_shutdown(); - -End: - - SAFE_CLOSE_HANDLE(hDrive); - - return rc; -} - -static int MountIsoFile(CONST CHAR *IsoPath, DWORD PhyDrive) -{ - if (IsWindows8OrGreater()) - { - Log("This is Windows 8 or latter..."); - if (VentoyMountISOByAPI(IsoPath) == 0) - { - Log("Mount iso by API success"); - return 0; - } - else - { - Log("Mount iso by API failed, maybe not supported, try imdisk"); - return VentoyMountISOByImdisk(IsoPath, PhyDrive); - } - } - else - { - Log("This is before Windows 8 ..."); - if (VentoyMountISOByImdisk(IsoPath, PhyDrive) == 0) - { - Log("Mount iso by imdisk success"); - return 0; - } - else - { - return VentoyMountISOByAPI(IsoPath); - } - } -} - -static int GetPhyDriveByLogicalDrive(int DriveLetter) -{ - BOOL Ret; - DWORD dwSize; - HANDLE Handle; - VOLUME_DISK_EXTENTS DiskExtents; - CHAR PhyPath[128]; - - sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\%C:", (CHAR)DriveLetter); - - Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); - if (Handle == INVALID_HANDLE_VALUE) - { - Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError()); - return -1; - } - - Ret = DeviceIoControl(Handle, - IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, - NULL, - 0, - &DiskExtents, - (DWORD)(sizeof(DiskExtents)), - (LPDWORD)&dwSize, - NULL); - - if (!Ret || DiskExtents.NumberOfDiskExtents == 0) - { - Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed %s, error:%u", PhyPath, GetLastError()); - SAFE_CLOSE_HANDLE(Handle); - return -1; - } - SAFE_CLOSE_HANDLE(Handle); - - Log("LogicalDrive:%s PhyDrive:%d Offset:%llu ExtentLength:%llu", - PhyPath, - DiskExtents.Extents[0].DiskNumber, - DiskExtents.Extents[0].StartingOffset.QuadPart, - DiskExtents.Extents[0].ExtentLength.QuadPart - ); - - return (int)DiskExtents.Extents[0].DiskNumber; -} - - -static int DeleteVentoyPart2MountPoint(DWORD PhyDrive) -{ - CHAR Letter = 'A'; - DWORD Drives; - DWORD PhyDisk; - CHAR DriveName[] = "?:\\"; - - Log("DeleteVentoyPart2MountPoint Phy%u ...", PhyDrive); - - Drives = GetLogicalDrives(); - while (Drives) - { - if ((Drives & 0x01) && IsPathExist(FALSE, "%C:\\ventoy\\ventoy.cpio", Letter)) - { - Log("File %C:\\ventoy\\ventoy.cpio exist", Letter); - - PhyDisk = GetPhyDriveByLogicalDrive(Letter); - Log("PhyDisk=%u for %C", PhyDisk, Letter); - - if (PhyDisk == PhyDrive) - { - DriveName[0] = Letter; - DeleteVolumeMountPointA(DriveName); - return 0; - } - } - - Letter++; - Drives >>= 1; - } - - return 1; -} - -static BOOL check_tar_archive(const char *archive, CHAR *tarName) -{ - int len; - int nameLen; - const char *pos = archive; - const char *slash = archive; - - while (*pos) - { - if (*pos == '\\' || *pos == '/') - { - slash = pos; - } - pos++; - } - - len = (int)strlen(slash); - - if (len > 7 && (strncmp(slash + len - 7, ".tar.gz", 7) == 0 || strncmp(slash + len - 7, ".tar.xz", 7) == 0)) - { - nameLen = (int)sprintf_s(tarName, MAX_PATH, "X:%s", slash); - tarName[nameLen - 3] = 0; - return TRUE; - } - else if (len > 8 && strncmp(slash + len - 8, ".tar.bz2", 8) == 0) - { - nameLen = (int)sprintf_s(tarName, MAX_PATH, "X:%s", slash); - tarName[nameLen - 4] = 0; - return TRUE; - } - else if (len > 9 && strncmp(slash + len - 9, ".tar.lzma", 9) == 0) - { - nameLen = (int)sprintf_s(tarName, MAX_PATH, "X:%s", slash); - tarName[nameLen - 5] = 0; - return TRUE; - } - - return FALSE; -} - -static int DecompressInjectionArchive(const char *archive, DWORD PhyDrive) -{ - int rc = 1; - BOOL bRet; - DWORD dwBytes; - HANDLE hDrive; - HANDLE hOut; - DWORD flags = CREATE_NO_WINDOW; - CHAR StrBuf[MAX_PATH]; - CHAR tarName[MAX_PATH]; - STARTUPINFOA Si; - PROCESS_INFORMATION Pi; - PROCESS_INFORMATION NewPi; - GET_LENGTH_INFORMATION LengthInfo; - SECURITY_ATTRIBUTES Sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; - - Log("DecompressInjectionArchive %s", archive); - - sprintf_s(StrBuf, sizeof(StrBuf), "\\\\.\\PhysicalDrive%d", PhyDrive); - hDrive = CreateFileA(StrBuf, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); - if (hDrive == INVALID_HANDLE_VALUE) - { - Log("Could not open the disk<%s>, error:%u", StrBuf, GetLastError()); - goto End; - } - - bRet = DeviceIoControl(hDrive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &LengthInfo, sizeof(LengthInfo), &dwBytes, NULL); - if (!bRet) - { - Log("Could not get phy disk %s size, error:%u", StrBuf, GetLastError()); - goto End; - } - - g_FatPhyDrive = hDrive; - g_Part2StartSec = GetVentoyEfiPartStartSector(hDrive); - - Log("Parse FAT fs..."); - - fl_init(); - - if (0 == fl_attach_media(VentoyFatDiskRead, NULL)) - { - if (g_64bit_system) - { - CopyFileFromFatDisk("/ventoy/7z/64/7za.exe", "ventoy\\7za.exe"); - } - else - { - CopyFileFromFatDisk("/ventoy/7z/32/7za.exe", "ventoy\\7za.exe"); - } - - sprintf_s(StrBuf, sizeof(StrBuf), "ventoy\\7za.exe x -y -aoa -oX:\\ %s", archive); - - Log("extract inject to X:"); - Log("cmdline:<%s>", StrBuf); - - GetStartupInfoA(&Si); - - hOut = CreateFileA("ventoy\\7z.log", - FILE_APPEND_DATA, - FILE_SHARE_WRITE | FILE_SHARE_READ, - &Sa, - OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); - - Si.dwFlags |= STARTF_USESTDHANDLES; - - if (hOut != INVALID_HANDLE_VALUE) - { - Si.hStdError = hOut; - Si.hStdOutput = hOut; - } - - CreateProcessA(NULL, StrBuf, NULL, NULL, TRUE, flags, NULL, NULL, &Si, &Pi); - WaitForSingleObject(Pi.hProcess, INFINITE); - - // - // decompress tar archive, for tar.gz/tar.xz/tar.bz2 - // - if (check_tar_archive(archive, tarName)) - { - Log("Decompress tar archive...<%s>", tarName); - - sprintf_s(StrBuf, sizeof(StrBuf), "ventoy\\7za.exe x -y -aoa -oX:\\ %s", tarName); - - CreateProcessA(NULL, StrBuf, NULL, NULL, TRUE, flags, NULL, NULL, &Si, &NewPi); - WaitForSingleObject(NewPi.hProcess, INFINITE); - - Log("Now delete %s", tarName); - DeleteFileA(tarName); - } - - SAFE_CLOSE_HANDLE(hOut); - } - fl_shutdown(); - -End: - - SAFE_CLOSE_HANDLE(hDrive); - - return rc; -} - -static int ProcessUnattendedInstallation(const char *script) -{ - DWORD dw; - HKEY hKey; - LSTATUS Ret; - CHAR Letter; - CHAR CurDir[MAX_PATH]; - - Log("Copy unattended XML ..."); - - GetCurrentDirectory(sizeof(CurDir), CurDir); - Letter = CurDir[0]; - if ((Letter >= 'A' && Letter <= 'Z') || (Letter >= 'a' && Letter <= 'z')) - { - Log("Current Drive Letter: %C", Letter); - } - else - { - Letter = 'X'; - } - - sprintf_s(CurDir, sizeof(CurDir), "%C:\\Autounattend.xml", Letter); - Log("Copy file <%s> --> <%s>", script, CurDir); - CopyFile(script, CurDir, FALSE); - - Ret = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "System\\Setup", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dw); - if (ERROR_SUCCESS == Ret) - { - Ret = RegSetValueEx(hKey, "UnattendFile", 0, REG_SZ, CurDir, (DWORD)(strlen(CurDir) + 1)); - } - - return 0; -} - -static int VentoyHook(ventoy_os_param *param) -{ - int rc; - CHAR Letter = 'A'; - DISK_EXTENT DiskExtent; - DWORD Drives = GetLogicalDrives(); - UINT8 UUID[16]; - CHAR IsoPath[MAX_PATH]; - - Log("Logical Drives=0x%x Path:<%s>", Drives, param->vtoy_img_path); - - while (Drives) - { - if (Drives & 0x01) - { - sprintf_s(IsoPath, sizeof(IsoPath), "%C:\\%s", Letter, param->vtoy_img_path); - if (IsPathExist(FALSE, "%s", IsoPath)) - { - Log("File exist under %C:", Letter); - if (GetPhyDiskUUID(Letter, UUID, &DiskExtent) == 0) - { - if (memcmp(UUID, param->vtoy_disk_guid, 16) == 0) - { - Log("Disk UUID match"); - break; - } - } - } - else - { - Log("File NOT exist under %C:", Letter); - } - } - - Drives >>= 1; - Letter++; - } - - if (Drives == 0) - { - Log("Failed to find ISO file"); - return 1; - } - - Log("Find ISO file <%s>", IsoPath); - - rc = MountIsoFile(IsoPath, DiskExtent.DiskNumber); - Log("Mount ISO FILE: %s", rc == 0 ? "SUCCESS" : "FAILED"); - - // for protect - rc = DeleteVentoyPart2MountPoint(DiskExtent.DiskNumber); - Log("Delete ventoy mountpoint: %s", rc == 0 ? "SUCCESS" : "NO NEED"); - - if (g_windows_data.auto_install_script[0]) - { - sprintf_s(IsoPath, sizeof(IsoPath), "%C:%s", Letter, g_windows_data.auto_install_script); - if (IsPathExist(FALSE, "%s", IsoPath)) - { - Log("use auto install script %s...", IsoPath); - ProcessUnattendedInstallation(IsoPath); - } - else - { - Log("auto install script %s not exist", IsoPath); - } - } - else - { - Log("auto install no need"); - } - - if (g_windows_data.injection_archive[0]) - { - sprintf_s(IsoPath, sizeof(IsoPath), "%C:%s", Letter, g_windows_data.injection_archive); - if (IsPathExist(FALSE, "%s", IsoPath)) - { - Log("decompress injection archive %s...", IsoPath); - DecompressInjectionArchive(IsoPath, DiskExtent.DiskNumber); - } - else - { - Log("injection archive %s not exist", IsoPath); - } - } - else - { - Log("no injection archive found"); - } - - return 0; -} - -const char * GetFileNameInPath(const char *fullpath) -{ - int i; - const char *pos = NULL; - - if (strstr(fullpath, ":")) - { - for (i = (int)strlen(fullpath); i > 0; i--) - { - if (fullpath[i - 1] == '/' || fullpath[i - 1] == '\\') - { - return fullpath + i; - } - } - } - - return fullpath; -} - -int VentoyJump(INT argc, CHAR **argv, CHAR *LunchFile) -{ - int rc = 1; - DWORD Pos; - DWORD PeStart; - DWORD FileSize; - BYTE *Buffer = NULL; - CHAR ExeFileName[MAX_PATH]; - - sprintf_s(ExeFileName, sizeof(ExeFileName), "%s", argv[0]); - if (!IsPathExist(FALSE, "%s", ExeFileName)) - { - Log("File %s NOT exist, now try %s.exe", ExeFileName, ExeFileName); - sprintf_s(ExeFileName, sizeof(ExeFileName), "%s.exe", argv[0]); - - Log("File %s exist ? %s", ExeFileName, IsPathExist(FALSE, "%s", ExeFileName) ? "YES" : "NO"); - } - - if (ReadWholeFile2Buf(ExeFileName, (void **)&Buffer, &FileSize)) - { - goto End; - } - - g_64bit_system = IsPe64(Buffer); - - if (!IsPathExist(TRUE, "ventoy")) - { - if (!CreateDirectoryA("ventoy", NULL)) - { - Log("Failed to create ventoy directory err:%u", GetLastError()); - goto End; - } - } - - for (PeStart = 0; PeStart < FileSize; PeStart += 16) - { - if (CheckOsParam((ventoy_os_param *)(Buffer + PeStart)) && - CheckPeHead(Buffer + PeStart + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data))) - { - Log("Find os pararm at %u", PeStart); - - memcpy(&g_os_param, Buffer + PeStart, sizeof(ventoy_os_param)); - memcpy(&g_windows_data, Buffer + PeStart + sizeof(ventoy_os_param), sizeof(ventoy_windows_data)); - memcpy(g_os_param_reserved, g_os_param.vtoy_reserved, sizeof(g_os_param_reserved)); - - if (g_os_param_reserved[0] == 1) - { - Log("break here for debug ....."); - goto End; - } - - // convert / to \\ - for (Pos = 0; Pos < sizeof(g_os_param.vtoy_img_path) && g_os_param.vtoy_img_path[Pos]; Pos++) - { - if (g_os_param.vtoy_img_path[Pos] == '/') - { - g_os_param.vtoy_img_path[Pos] = '\\'; - } - } - - PeStart += sizeof(ventoy_os_param) + sizeof(ventoy_windows_data); - sprintf_s(LunchFile, MAX_PATH, "ventoy\\%s", GetFileNameInPath(ExeFileName)); - SaveBuffer2File(LunchFile, Buffer + PeStart, FileSize - PeStart); - break; - } - } - - if (PeStart >= FileSize) - { - Log("OS param not found"); - goto End; - } - - if (g_os_param_reserved[0] == 2) - { - Log("skip hook for debug ....."); - rc = 0; - goto End; - } - - rc = VentoyHook(&g_os_param); - -End: - - if (Buffer) - { - free(Buffer); - } - - return rc; -} - -int main(int argc, char **argv) -{ - int i = 0; - int rc = 0; - CHAR *Pos = NULL; - CHAR CurDir[MAX_PATH]; - CHAR LunchFile[MAX_PATH]; - STARTUPINFOA Si; - PROCESS_INFORMATION Pi; - - if (argv[0] && argv[0][0] && argv[0][1] == ':') - { - GetCurrentDirectoryA(sizeof(CurDir), CurDir); - - strcpy_s(LunchFile, sizeof(LunchFile), argv[0]); - Pos = (char *)GetFileNameInPath(LunchFile); - - strcat_s(CurDir, sizeof(CurDir), "\\"); - strcat_s(CurDir, sizeof(CurDir), Pos); - - if (_stricmp(argv[0], CurDir) != 0) - { - *Pos = 0; - SetCurrentDirectoryA(LunchFile); - } - } - - Log("######## VentoyJump ##########"); - Log("argc = %d argv[0] = <%s>", argc, argv[0]); - - if (Pos && *Pos == 0) - { - Log("Old current directory = <%s>", CurDir); - Log("New current directory = <%s>", LunchFile); - } - else - { - GetCurrentDirectoryA(sizeof(CurDir), CurDir); - Log("Current directory = <%s>", CurDir); - } - - GetStartupInfoA(&Si); - - memset(LunchFile, 0, sizeof(LunchFile)); - rc = VentoyJump(argc, argv, LunchFile); - - if (g_os_param_reserved[0] == 3) - { - Log("Open log for debug ..."); - sprintf_s(LunchFile, sizeof(LunchFile), "%s", "notepad.exe ventoy.log"); - } - else - { - Si.dwFlags |= STARTF_USESHOWWINDOW; - Si.wShowWindow = SW_HIDE; - Log("Ventoy jump %s ...", rc == 0 ? "success" : "failed"); - } - - CreateProcessA(NULL, LunchFile, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi); - - while (rc) - { - Log("Ventoy hook failed, now wait and retry ..."); - Sleep(1000); - - rc = VentoyHook(&g_os_param); - } - - WaitForSingleObject(Pi.hProcess, INFINITE); - - return 0; -} +/****************************************************************************** +* vtoyjump.c +* +* 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 . +* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include "vtoyjump.h" +#include "fat_filelib.h" + +static ventoy_os_param g_os_param; +static ventoy_windows_data g_windows_data; +static UINT8 g_os_param_reserved[32]; +static BOOL g_64bit_system = FALSE; +static ventoy_guid g_ventoy_guid = VENTOY_GUID; + +void Log(const char *Fmt, ...) +{ + va_list Arg; + int Len = 0; + FILE *File = NULL; + SYSTEMTIME Sys; + char szBuf[1024]; + + GetLocalTime(&Sys); + Len += sprintf_s(szBuf, sizeof(szBuf), + "[%4d/%02d/%02d %02d:%02d:%02d.%03d] ", + Sys.wYear, Sys.wMonth, Sys.wDay, + Sys.wHour, Sys.wMinute, Sys.wSecond, + Sys.wMilliseconds); + + va_start(Arg, Fmt); + Len += vsnprintf_s(szBuf + Len, sizeof(szBuf)-Len, sizeof(szBuf)-Len, Fmt, Arg); + va_end(Arg); + + fopen_s(&File, "ventoy.log", "a+"); + if (File) + { + fwrite(szBuf, 1, Len, File); + fwrite("\n", 1, 1, File); + fclose(File); + } +} + + +static int LoadNtDriver(const char *DrvBinPath) +{ + int i; + int rc = 0; + BOOL Ret; + DWORD Status; + SC_HANDLE hServiceMgr; + SC_HANDLE hService; + char name[256] = { 0 }; + + for (i = (int)strlen(DrvBinPath) - 1; i >= 0; i--) + { + if (DrvBinPath[i] == '\\' || DrvBinPath[i] == '/') + { + sprintf_s(name, sizeof(name), "%s", DrvBinPath + i + 1); + break; + } + } + + Log("Load NT driver: %s %s", DrvBinPath, name); + + hServiceMgr = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (hServiceMgr == NULL) + { + Log("OpenSCManager failed Error:%u", GetLastError()); + return 1; + } + + Log("OpenSCManager OK"); + + hService = CreateServiceA(hServiceMgr, + name, + name, + SERVICE_ALL_ACCESS, + SERVICE_KERNEL_DRIVER, + SERVICE_DEMAND_START, + SERVICE_ERROR_NORMAL, + DrvBinPath, + NULL, NULL, NULL, NULL, NULL); + if (hService == NULL) + { + Status = GetLastError(); + if (Status != ERROR_IO_PENDING && Status != ERROR_SERVICE_EXISTS) + { + Log("CreateService failed v %u", Status); + CloseServiceHandle(hServiceMgr); + return 1; + } + + hService = OpenServiceA(hServiceMgr, name, SERVICE_ALL_ACCESS); + if (hService == NULL) + { + Log("OpenService failed %u", Status); + CloseServiceHandle(hServiceMgr); + return 1; + } + } + + Log("CreateService imdisk OK"); + + Ret = StartServiceA(hService, 0, NULL); + if (Ret) + { + Log("StartService OK"); + } + else + { + Status = GetLastError(); + if (Status == ERROR_SERVICE_ALREADY_RUNNING) + { + rc = 0; + } + else + { + Log("StartService error %u", Status); + rc = 1; + } + } + + CloseServiceHandle(hService); + CloseServiceHandle(hServiceMgr); + + Log("Load NT driver %s", rc ? "failed" : "success"); + + return rc; +} + +static int ReadWholeFile2Buf(const char *Fullpath, void **Data, DWORD *Size) +{ + int rc = 1; + DWORD FileSize; + DWORD dwSize; + HANDLE Handle; + BYTE *Buffer = NULL; + + Log("ReadWholeFile2Buf <%s>", Fullpath); + + Handle = CreateFileA(Fullpath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + if (Handle == INVALID_HANDLE_VALUE) + { + Log("Could not open the file<%s>, error:%u", Fullpath, GetLastError()); + goto End; + } + + FileSize = SetFilePointer(Handle, 0, NULL, FILE_END); + + Buffer = malloc(FileSize); + if (!Buffer) + { + Log("Failed to alloc memory size:%u", FileSize); + goto End; + } + + SetFilePointer(Handle, 0, NULL, FILE_BEGIN); + if (!ReadFile(Handle, Buffer, FileSize, &dwSize, NULL)) + { + Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError()); + goto End; + } + + *Data = Buffer; + *Size = FileSize; + + Log("Success read file size:%u", FileSize); + + rc = 0; + +End: + SAFE_CLOSE_HANDLE(Handle); + + return rc; +} + +static BOOL CheckPeHead(BYTE *Head) +{ + UINT32 PeOffset; + + if (Head[0] != 'M' || Head[1] != 'Z') + { + return FALSE; + } + + PeOffset = *(UINT32 *)(Head + 60); + if (*(UINT32 *)(Head + PeOffset) != 0x00004550) + { + return FALSE; + } + + return TRUE; +} + +static BOOL IsPe64(BYTE *buffer) +{ + DWORD pe_off; + + if (!CheckPeHead(buffer)) + { + return FALSE; + } + + pe_off = *(UINT32 *)(buffer + 60); + if (*(UINT16 *)(buffer + pe_off + 24) == 0x020b) + { + return TRUE; + } + + return FALSE; +} + + +static BOOL CheckOsParam(ventoy_os_param *param) +{ + UINT32 i; + BYTE Sum = 0; + + if (memcmp(¶m->guid, &g_ventoy_guid, sizeof(ventoy_guid))) + { + return FALSE; + } + + for (i = 0; i < sizeof(ventoy_os_param); i++) + { + Sum += *((BYTE *)param + i); + } + + if (Sum) + { + return FALSE; + } + + if (param->vtoy_img_location_addr % 4096) + { + return FALSE; + } + + return TRUE; +} + +static int SaveBuffer2File(const char *Fullpath, void *Buffer, DWORD Length) +{ + int rc = 1; + DWORD dwSize; + HANDLE Handle; + + Log("SaveBuffer2File <%s> len:%u", Fullpath, Length); + + Handle = CreateFileA(Fullpath, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, 0, 0); + if (Handle == INVALID_HANDLE_VALUE) + { + Log("Could not create new file, error:%u", GetLastError()); + goto End; + } + + WriteFile(Handle, Buffer, Length, &dwSize, NULL); + + rc = 0; + +End: + SAFE_CLOSE_HANDLE(Handle); + + return rc; +} + +static int IsUTF8Encode(const char *src) +{ + int i; + const UCHAR *Byte = (const UCHAR *)src; + + for (i = 0; i < MAX_PATH && Byte[i]; i++) + { + if (Byte[i] > 127) + { + return 1; + } + } + + return 0; +} + +static int Utf8ToUtf16(const char* src, WCHAR * dst) +{ + int size = MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, 0); + return MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, size + 1); +} + +static BOOL IsPathExist(BOOL Dir, const char *Fmt, ...) +{ + va_list Arg; + HANDLE hFile; + DWORD Attr; + int UTF8 = 0; + CHAR FilePathA[MAX_PATH]; + WCHAR FilePathW[MAX_PATH]; + + va_start(Arg, Fmt); + vsnprintf_s(FilePathA, sizeof(FilePathA), sizeof(FilePathA), Fmt, Arg); + va_end(Arg); + + UTF8 = IsUTF8Encode(FilePathA); + + if (UTF8) + { + Utf8ToUtf16(FilePathA, FilePathW); + hFile = CreateFileW(FilePathW, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + } + else + { + hFile = CreateFileA(FilePathA, FILE_READ_EA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + } + if (INVALID_HANDLE_VALUE == hFile) + { + return FALSE; + } + + CloseHandle(hFile); + + if (UTF8) + { + Attr = GetFileAttributesW(FilePathW); + } + else + { + Attr = GetFileAttributesA(FilePathA); + } + + if (Dir) + { + if ((Attr & FILE_ATTRIBUTE_DIRECTORY) == 0) + { + return FALSE; + } + } + else + { + if (Attr & FILE_ATTRIBUTE_DIRECTORY) + { + return FALSE; + } + } + + return TRUE; +} + +static int GetPhyDiskUUID(const char LogicalDrive, UINT8 *UUID, DISK_EXTENT *DiskExtent) +{ + BOOL Ret; + DWORD dwSize; + HANDLE Handle; + VOLUME_DISK_EXTENTS DiskExtents; + CHAR PhyPath[128]; + UINT8 SectorBuf[512]; + + Log("GetPhyDiskUUID %C", LogicalDrive); + + sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\%C:", LogicalDrive); + Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + if (Handle == INVALID_HANDLE_VALUE) + { + Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError()); + return 1; + } + + Ret = DeviceIoControl(Handle, + IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, + NULL, + 0, + &DiskExtents, + (DWORD)(sizeof(DiskExtents)), + (LPDWORD)&dwSize, + NULL); + if (!Ret || DiskExtents.NumberOfDiskExtents == 0) + { + Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed, error:%u", GetLastError()); + CloseHandle(Handle); + return 1; + } + CloseHandle(Handle); + + memcpy(DiskExtent, DiskExtents.Extents, sizeof(DiskExtent)); + Log("%C: is in PhysicalDrive%d ", LogicalDrive, DiskExtents.Extents[0].DiskNumber); + + sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", DiskExtents.Extents[0].DiskNumber); + Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + if (Handle == INVALID_HANDLE_VALUE) + { + Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError()); + return 1; + } + + if (!ReadFile(Handle, SectorBuf, sizeof(SectorBuf), &dwSize, NULL)) + { + Log("ReadFile failed, dwSize:%u error:%u", dwSize, GetLastError()); + CloseHandle(Handle); + return 1; + } + + memcpy(UUID, SectorBuf + 0x180, 16); + CloseHandle(Handle); + return 0; +} + +int VentoyMountISOByAPI(const char *IsoPath) +{ + HANDLE Handle; + DWORD Status; + WCHAR wFilePath[512] = { 0 }; + VIRTUAL_STORAGE_TYPE StorageType; + OPEN_VIRTUAL_DISK_PARAMETERS OpenParameters; + ATTACH_VIRTUAL_DISK_PARAMETERS AttachParameters; + + Log("VentoyMountISOByAPI <%s>", IsoPath); + + if (IsUTF8Encode(IsoPath)) + { + MultiByteToWideChar(CP_UTF8, 0, IsoPath, (int)strlen(IsoPath), wFilePath, (int)(sizeof(wFilePath) / sizeof(WCHAR))); + } + else + { + MultiByteToWideChar(CP_ACP, 0, IsoPath, (int)strlen(IsoPath), wFilePath, (int)(sizeof(wFilePath) / sizeof(WCHAR))); + } + + memset(&StorageType, 0, sizeof(StorageType)); + memset(&OpenParameters, 0, sizeof(OpenParameters)); + memset(&AttachParameters, 0, sizeof(AttachParameters)); + + OpenParameters.Version = OPEN_VIRTUAL_DISK_VERSION_1; + AttachParameters.Version = ATTACH_VIRTUAL_DISK_VERSION_1; + + Status = OpenVirtualDisk(&StorageType, wFilePath, VIRTUAL_DISK_ACCESS_READ, 0, &OpenParameters, &Handle); + if (Status != ERROR_SUCCESS) + { + if (ERROR_VIRTDISK_PROVIDER_NOT_FOUND == Status) + { + Log("VirtualDisk for ISO file is not supported in current system"); + } + else + { + Log("Failed to open virtual disk ErrorCode:%u", Status); + } + return 1; + } + + Log("OpenVirtualDisk success"); + + Status = AttachVirtualDisk(Handle, NULL, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY | ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME, 0, &AttachParameters, NULL); + if (Status != ERROR_SUCCESS) + { + Log("Failed to attach virtual disk ErrorCode:%u", Status); + CloseHandle(Handle); + return 1; + } + + CloseHandle(Handle); + return 0; +} + + +static HANDLE g_FatPhyDrive; +static UINT64 g_Part2StartSec; + +static int CopyFileFromFatDisk(const CHAR* SrcFile, const CHAR *DstFile) +{ + int rc = 1; + int size = 0; + char *buf = NULL; + void *flfile = NULL; + + Log("CopyFileFromFatDisk (%s)==>(%s)", SrcFile, DstFile); + + flfile = fl_fopen(SrcFile, "rb"); + if (flfile) + { + fl_fseek(flfile, 0, SEEK_END); + size = (int)fl_ftell(flfile); + fl_fseek(flfile, 0, SEEK_SET); + + buf = (char *)malloc(size); + if (buf) + { + fl_fread(buf, 1, size, flfile); + + rc = 0; + SaveBuffer2File(DstFile, buf, size); + free(buf); + } + + fl_fclose(flfile); + } + + return rc; +} + +static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount) +{ + DWORD dwSize; + BOOL bRet; + DWORD ReadSize; + LARGE_INTEGER liCurrentPosition; + + liCurrentPosition.QuadPart = Sector + g_Part2StartSec; + liCurrentPosition.QuadPart *= 512; + SetFilePointerEx(g_FatPhyDrive, liCurrentPosition, &liCurrentPosition, FILE_BEGIN); + + ReadSize = (DWORD)(SectorCount * 512); + + bRet = ReadFile(g_FatPhyDrive, Buffer, ReadSize, &dwSize, NULL); + if (bRet == FALSE || dwSize != ReadSize) + { + Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u\n", bRet, ReadSize, dwSize, GetLastError()); + } + + return 1; +} + +static CHAR GetMountLogicalDrive(void) +{ + CHAR Letter = 'Y'; + DWORD Drives; + DWORD Mask = 0x1000000; + + Drives = GetLogicalDrives(); + Log("Drives=0x%x", Drives); + + while (Mask) + { + if ((Drives & Mask) == 0) + { + break; + } + + Letter--; + Mask >>= 1; + } + + return Letter; +} + +UINT64 GetVentoyEfiPartStartSector(HANDLE hDrive) +{ + BOOL bRet; + DWORD dwSize; + MBR_HEAD MBR; + VTOY_GPT_INFO *pGpt = NULL; + UINT64 StartSector = 0; + + SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); + + bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL); + Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR); + + if ((!bRet) || (dwSize != sizeof(MBR))) + { + 0; + } + + if (MBR.PartTbl[0].FsFlag == 0xEE) + { + Log("GPT partition style"); + + pGpt = malloc(sizeof(VTOY_GPT_INFO)); + if (!pGpt) + { + return 0; + } + + SetFilePointer(hDrive, 0, NULL, FILE_BEGIN); + bRet = ReadFile(hDrive, pGpt, sizeof(VTOY_GPT_INFO), &dwSize, NULL); + if ((!bRet) || (dwSize != sizeof(VTOY_GPT_INFO))) + { + Log("Failed to read gpt info %d %u %d", bRet, dwSize, LASTERR); + return 0; + } + + StartSector = pGpt->PartTbl[1].StartLBA; + free(pGpt); + } + else + { + Log("MBR partition style"); + StartSector = MBR.PartTbl[1].StartSectorId; + } + + Log("GetVentoyEfiPart StartSector: %llu", StartSector); + return StartSector; +} + +int VentoyMountISOByImdisk(const char *IsoPath, DWORD PhyDrive) +{ + int rc = 1; + BOOL bRet; + CHAR Letter; + DWORD dwBytes; + HANDLE hDrive; + CHAR PhyPath[MAX_PATH]; + WCHAR PhyPathW[MAX_PATH]; + STARTUPINFOA Si; + PROCESS_INFORMATION Pi; + GET_LENGTH_INFORMATION LengthInfo; + + Log("VentoyMountISOByImdisk %s", IsoPath); + + sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", PhyDrive); + if (IsUTF8Encode(PhyPath)) + { + Utf8ToUtf16(PhyPath, PhyPathW); + hDrive = CreateFileW(PhyPathW, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + } + else + { + hDrive = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + } + + if (hDrive == INVALID_HANDLE_VALUE) + { + Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError()); + goto End; + } + + bRet = DeviceIoControl(hDrive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &LengthInfo, sizeof(LengthInfo), &dwBytes, NULL); + if (!bRet) + { + Log("Could not get phy disk %s size, error:%u", PhyPath, GetLastError()); + goto End; + } + + g_FatPhyDrive = hDrive; + g_Part2StartSec = GetVentoyEfiPartStartSector(hDrive); + + Log("Parse FAT fs..."); + + fl_init(); + + if (0 == fl_attach_media(VentoyFatDiskRead, NULL)) + { + if (g_64bit_system) + { + CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.sys", "ventoy\\imdisk.sys"); + CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.exe", "ventoy\\imdisk.exe"); + CopyFileFromFatDisk("/ventoy/imdisk/64/imdisk.cpl", "ventoy\\imdisk.cpl"); + } + else + { + CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.sys", "ventoy\\imdisk.sys"); + CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.exe", "ventoy\\imdisk.exe"); + CopyFileFromFatDisk("/ventoy/imdisk/32/imdisk.cpl", "ventoy\\imdisk.cpl"); + } + + GetCurrentDirectoryA(sizeof(PhyPath), PhyPath); + strcat_s(PhyPath, sizeof(PhyPath), "\\ventoy\\imdisk.sys"); + + if (LoadNtDriver(PhyPath) == 0) + { + rc = 0; + + Letter = GetMountLogicalDrive(); + sprintf_s(PhyPath, sizeof(PhyPath), "ventoy\\imdisk.exe -a -o ro -f %s -m %C:", IsoPath, Letter); + + Log("mount iso to %C: use imdisk cmd <%s>", Letter, PhyPath); + + GetStartupInfoA(&Si); + + Si.dwFlags |= STARTF_USESHOWWINDOW; + Si.wShowWindow = SW_HIDE; + + CreateProcessA(NULL, PhyPath, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi); + WaitForSingleObject(Pi.hProcess, INFINITE); + } + } + fl_shutdown(); + +End: + + SAFE_CLOSE_HANDLE(hDrive); + + return rc; +} + +static int MountIsoFile(CONST CHAR *IsoPath, DWORD PhyDrive) +{ + if (IsWindows8OrGreater()) + { + Log("This is Windows 8 or latter..."); + if (VentoyMountISOByAPI(IsoPath) == 0) + { + Log("Mount iso by API success"); + return 0; + } + else + { + Log("Mount iso by API failed, maybe not supported, try imdisk"); + return VentoyMountISOByImdisk(IsoPath, PhyDrive); + } + } + else + { + Log("This is before Windows 8 ..."); + if (VentoyMountISOByImdisk(IsoPath, PhyDrive) == 0) + { + Log("Mount iso by imdisk success"); + return 0; + } + else + { + return VentoyMountISOByAPI(IsoPath); + } + } +} + +static int GetPhyDriveByLogicalDrive(int DriveLetter) +{ + BOOL Ret; + DWORD dwSize; + HANDLE Handle; + VOLUME_DISK_EXTENTS DiskExtents; + CHAR PhyPath[128]; + + sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\%C:", (CHAR)DriveLetter); + + Handle = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + if (Handle == INVALID_HANDLE_VALUE) + { + Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError()); + return -1; + } + + Ret = DeviceIoControl(Handle, + IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, + NULL, + 0, + &DiskExtents, + (DWORD)(sizeof(DiskExtents)), + (LPDWORD)&dwSize, + NULL); + + if (!Ret || DiskExtents.NumberOfDiskExtents == 0) + { + Log("DeviceIoControl IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed %s, error:%u", PhyPath, GetLastError()); + SAFE_CLOSE_HANDLE(Handle); + return -1; + } + SAFE_CLOSE_HANDLE(Handle); + + Log("LogicalDrive:%s PhyDrive:%d Offset:%llu ExtentLength:%llu", + PhyPath, + DiskExtents.Extents[0].DiskNumber, + DiskExtents.Extents[0].StartingOffset.QuadPart, + DiskExtents.Extents[0].ExtentLength.QuadPart + ); + + return (int)DiskExtents.Extents[0].DiskNumber; +} + + +static int DeleteVentoyPart2MountPoint(DWORD PhyDrive) +{ + CHAR Letter = 'A'; + DWORD Drives; + DWORD PhyDisk; + CHAR DriveName[] = "?:\\"; + + Log("DeleteVentoyPart2MountPoint Phy%u ...", PhyDrive); + + Drives = GetLogicalDrives(); + while (Drives) + { + if ((Drives & 0x01) && IsPathExist(FALSE, "%C:\\ventoy\\ventoy.cpio", Letter)) + { + Log("File %C:\\ventoy\\ventoy.cpio exist", Letter); + + PhyDisk = GetPhyDriveByLogicalDrive(Letter); + Log("PhyDisk=%u for %C", PhyDisk, Letter); + + if (PhyDisk == PhyDrive) + { + DriveName[0] = Letter; + DeleteVolumeMountPointA(DriveName); + return 0; + } + } + + Letter++; + Drives >>= 1; + } + + return 1; +} + +static BOOL check_tar_archive(const char *archive, CHAR *tarName) +{ + int len; + int nameLen; + const char *pos = archive; + const char *slash = archive; + + while (*pos) + { + if (*pos == '\\' || *pos == '/') + { + slash = pos; + } + pos++; + } + + len = (int)strlen(slash); + + if (len > 7 && (strncmp(slash + len - 7, ".tar.gz", 7) == 0 || strncmp(slash + len - 7, ".tar.xz", 7) == 0)) + { + nameLen = (int)sprintf_s(tarName, MAX_PATH, "X:%s", slash); + tarName[nameLen - 3] = 0; + return TRUE; + } + else if (len > 8 && strncmp(slash + len - 8, ".tar.bz2", 8) == 0) + { + nameLen = (int)sprintf_s(tarName, MAX_PATH, "X:%s", slash); + tarName[nameLen - 4] = 0; + return TRUE; + } + else if (len > 9 && strncmp(slash + len - 9, ".tar.lzma", 9) == 0) + { + nameLen = (int)sprintf_s(tarName, MAX_PATH, "X:%s", slash); + tarName[nameLen - 5] = 0; + return TRUE; + } + + return FALSE; +} + +static int DecompressInjectionArchive(const char *archive, DWORD PhyDrive) +{ + int rc = 1; + BOOL bRet; + DWORD dwBytes; + HANDLE hDrive; + HANDLE hOut; + DWORD flags = CREATE_NO_WINDOW; + CHAR StrBuf[MAX_PATH]; + CHAR tarName[MAX_PATH]; + STARTUPINFOA Si; + PROCESS_INFORMATION Pi; + PROCESS_INFORMATION NewPi; + GET_LENGTH_INFORMATION LengthInfo; + SECURITY_ATTRIBUTES Sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + + Log("DecompressInjectionArchive %s", archive); + + sprintf_s(StrBuf, sizeof(StrBuf), "\\\\.\\PhysicalDrive%d", PhyDrive); + hDrive = CreateFileA(StrBuf, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + if (hDrive == INVALID_HANDLE_VALUE) + { + Log("Could not open the disk<%s>, error:%u", StrBuf, GetLastError()); + goto End; + } + + bRet = DeviceIoControl(hDrive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &LengthInfo, sizeof(LengthInfo), &dwBytes, NULL); + if (!bRet) + { + Log("Could not get phy disk %s size, error:%u", StrBuf, GetLastError()); + goto End; + } + + g_FatPhyDrive = hDrive; + g_Part2StartSec = GetVentoyEfiPartStartSector(hDrive); + + Log("Parse FAT fs..."); + + fl_init(); + + if (0 == fl_attach_media(VentoyFatDiskRead, NULL)) + { + if (g_64bit_system) + { + CopyFileFromFatDisk("/ventoy/7z/64/7za.exe", "ventoy\\7za.exe"); + } + else + { + CopyFileFromFatDisk("/ventoy/7z/32/7za.exe", "ventoy\\7za.exe"); + } + + sprintf_s(StrBuf, sizeof(StrBuf), "ventoy\\7za.exe x -y -aoa -oX:\\ %s", archive); + + Log("extract inject to X:"); + Log("cmdline:<%s>", StrBuf); + + GetStartupInfoA(&Si); + + hOut = CreateFileA("ventoy\\7z.log", + FILE_APPEND_DATA, + FILE_SHARE_WRITE | FILE_SHARE_READ, + &Sa, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + Si.dwFlags |= STARTF_USESTDHANDLES; + + if (hOut != INVALID_HANDLE_VALUE) + { + Si.hStdError = hOut; + Si.hStdOutput = hOut; + } + + CreateProcessA(NULL, StrBuf, NULL, NULL, TRUE, flags, NULL, NULL, &Si, &Pi); + WaitForSingleObject(Pi.hProcess, INFINITE); + + // + // decompress tar archive, for tar.gz/tar.xz/tar.bz2 + // + if (check_tar_archive(archive, tarName)) + { + Log("Decompress tar archive...<%s>", tarName); + + sprintf_s(StrBuf, sizeof(StrBuf), "ventoy\\7za.exe x -y -aoa -oX:\\ %s", tarName); + + CreateProcessA(NULL, StrBuf, NULL, NULL, TRUE, flags, NULL, NULL, &Si, &NewPi); + WaitForSingleObject(NewPi.hProcess, INFINITE); + + Log("Now delete %s", tarName); + DeleteFileA(tarName); + } + + SAFE_CLOSE_HANDLE(hOut); + } + fl_shutdown(); + +End: + + SAFE_CLOSE_HANDLE(hDrive); + + return rc; +} + +static int ProcessUnattendedInstallation(const char *script) +{ + DWORD dw; + HKEY hKey; + LSTATUS Ret; + CHAR Letter; + CHAR CurDir[MAX_PATH]; + + Log("Copy unattended XML ..."); + + GetCurrentDirectory(sizeof(CurDir), CurDir); + Letter = CurDir[0]; + if ((Letter >= 'A' && Letter <= 'Z') || (Letter >= 'a' && Letter <= 'z')) + { + Log("Current Drive Letter: %C", Letter); + } + else + { + Letter = 'X'; + } + + sprintf_s(CurDir, sizeof(CurDir), "%C:\\Autounattend.xml", Letter); + Log("Copy file <%s> --> <%s>", script, CurDir); + CopyFile(script, CurDir, FALSE); + + Ret = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "System\\Setup", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dw); + if (ERROR_SUCCESS == Ret) + { + Ret = RegSetValueEx(hKey, "UnattendFile", 0, REG_SZ, CurDir, (DWORD)(strlen(CurDir) + 1)); + } + + return 0; +} + +static int VentoyHook(ventoy_os_param *param) +{ + int rc; + CHAR Letter = 'A'; + DISK_EXTENT DiskExtent; + DWORD Drives = GetLogicalDrives(); + UINT8 UUID[16]; + CHAR IsoPath[MAX_PATH]; + + Log("Logical Drives=0x%x Path:<%s>", Drives, param->vtoy_img_path); + + if (IsUTF8Encode(param->vtoy_img_path)) + { + Log("This file is UTF8 encoding\n"); + } + + while (Drives) + { + if (Drives & 0x01) + { + sprintf_s(IsoPath, sizeof(IsoPath), "%C:\\%s", Letter, param->vtoy_img_path); + if (IsPathExist(FALSE, "%s", IsoPath)) + { + Log("File exist under %C:", Letter); + if (GetPhyDiskUUID(Letter, UUID, &DiskExtent) == 0) + { + if (memcmp(UUID, param->vtoy_disk_guid, 16) == 0) + { + Log("Disk UUID match"); + break; + } + } + } + else + { + Log("File NOT exist under %C:", Letter); + } + } + + Drives >>= 1; + Letter++; + } + + if (Drives == 0) + { + Log("Failed to find ISO file"); + return 1; + } + + Log("Find ISO file <%s>", IsoPath); + + rc = MountIsoFile(IsoPath, DiskExtent.DiskNumber); + Log("Mount ISO FILE: %s", rc == 0 ? "SUCCESS" : "FAILED"); + + // for protect + rc = DeleteVentoyPart2MountPoint(DiskExtent.DiskNumber); + Log("Delete ventoy mountpoint: %s", rc == 0 ? "SUCCESS" : "NO NEED"); + + if (g_windows_data.auto_install_script[0]) + { + sprintf_s(IsoPath, sizeof(IsoPath), "%C:%s", Letter, g_windows_data.auto_install_script); + if (IsPathExist(FALSE, "%s", IsoPath)) + { + Log("use auto install script %s...", IsoPath); + ProcessUnattendedInstallation(IsoPath); + } + else + { + Log("auto install script %s not exist", IsoPath); + } + } + else + { + Log("auto install no need"); + } + + if (g_windows_data.injection_archive[0]) + { + sprintf_s(IsoPath, sizeof(IsoPath), "%C:%s", Letter, g_windows_data.injection_archive); + if (IsPathExist(FALSE, "%s", IsoPath)) + { + Log("decompress injection archive %s...", IsoPath); + DecompressInjectionArchive(IsoPath, DiskExtent.DiskNumber); + } + else + { + Log("injection archive %s not exist", IsoPath); + } + } + else + { + Log("no injection archive found"); + } + + return 0; +} + +const char * GetFileNameInPath(const char *fullpath) +{ + int i; + const char *pos = NULL; + + if (strstr(fullpath, ":")) + { + for (i = (int)strlen(fullpath); i > 0; i--) + { + if (fullpath[i - 1] == '/' || fullpath[i - 1] == '\\') + { + return fullpath + i; + } + } + } + + return fullpath; +} + +int VentoyJump(INT argc, CHAR **argv, CHAR *LunchFile) +{ + int rc = 1; + DWORD Pos; + DWORD PeStart; + DWORD FileSize; + BYTE *Buffer = NULL; + CHAR ExeFileName[MAX_PATH]; + + sprintf_s(ExeFileName, sizeof(ExeFileName), "%s", argv[0]); + if (!IsPathExist(FALSE, "%s", ExeFileName)) + { + Log("File %s NOT exist, now try %s.exe", ExeFileName, ExeFileName); + sprintf_s(ExeFileName, sizeof(ExeFileName), "%s.exe", argv[0]); + + Log("File %s exist ? %s", ExeFileName, IsPathExist(FALSE, "%s", ExeFileName) ? "YES" : "NO"); + } + + if (ReadWholeFile2Buf(ExeFileName, (void **)&Buffer, &FileSize)) + { + goto End; + } + + g_64bit_system = IsPe64(Buffer); + + if (!IsPathExist(TRUE, "ventoy")) + { + if (!CreateDirectoryA("ventoy", NULL)) + { + Log("Failed to create ventoy directory err:%u", GetLastError()); + goto End; + } + } + + for (PeStart = 0; PeStart < FileSize; PeStart += 16) + { + if (CheckOsParam((ventoy_os_param *)(Buffer + PeStart)) && + CheckPeHead(Buffer + PeStart + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data))) + { + Log("Find os pararm at %u", PeStart); + + memcpy(&g_os_param, Buffer + PeStart, sizeof(ventoy_os_param)); + memcpy(&g_windows_data, Buffer + PeStart + sizeof(ventoy_os_param), sizeof(ventoy_windows_data)); + memcpy(g_os_param_reserved, g_os_param.vtoy_reserved, sizeof(g_os_param_reserved)); + + if (g_os_param_reserved[0] == 1) + { + Log("break here for debug ....."); + goto End; + } + + // convert / to \\ + for (Pos = 0; Pos < sizeof(g_os_param.vtoy_img_path) && g_os_param.vtoy_img_path[Pos]; Pos++) + { + if (g_os_param.vtoy_img_path[Pos] == '/') + { + g_os_param.vtoy_img_path[Pos] = '\\'; + } + } + + PeStart += sizeof(ventoy_os_param) + sizeof(ventoy_windows_data); + sprintf_s(LunchFile, MAX_PATH, "ventoy\\%s", GetFileNameInPath(ExeFileName)); + SaveBuffer2File(LunchFile, Buffer + PeStart, FileSize - PeStart); + break; + } + } + + if (PeStart >= FileSize) + { + Log("OS param not found"); + goto End; + } + + if (g_os_param_reserved[0] == 2) + { + Log("skip hook for debug ....."); + rc = 0; + goto End; + } + + rc = VentoyHook(&g_os_param); + +End: + + if (Buffer) + { + free(Buffer); + } + + return rc; +} + +int main(int argc, char **argv) +{ + int i = 0; + int rc = 0; + CHAR *Pos = NULL; + CHAR CurDir[MAX_PATH]; + CHAR LunchFile[MAX_PATH]; + STARTUPINFOA Si; + PROCESS_INFORMATION Pi; + + if (argv[0] && argv[0][0] && argv[0][1] == ':') + { + GetCurrentDirectoryA(sizeof(CurDir), CurDir); + + strcpy_s(LunchFile, sizeof(LunchFile), argv[0]); + Pos = (char *)GetFileNameInPath(LunchFile); + + strcat_s(CurDir, sizeof(CurDir), "\\"); + strcat_s(CurDir, sizeof(CurDir), Pos); + + if (_stricmp(argv[0], CurDir) != 0) + { + *Pos = 0; + SetCurrentDirectoryA(LunchFile); + } + } + + Log("######## VentoyJump ##########"); + Log("argc = %d argv[0] = <%s>", argc, argv[0]); + + if (Pos && *Pos == 0) + { + Log("Old current directory = <%s>", CurDir); + Log("New current directory = <%s>", LunchFile); + } + else + { + GetCurrentDirectoryA(sizeof(CurDir), CurDir); + Log("Current directory = <%s>", CurDir); + } + + GetStartupInfoA(&Si); + + memset(LunchFile, 0, sizeof(LunchFile)); + rc = VentoyJump(argc, argv, LunchFile); + + if (g_os_param_reserved[0] == 3) + { + Log("Open log for debug ..."); + sprintf_s(LunchFile, sizeof(LunchFile), "%s", "notepad.exe ventoy.log"); + } + else + { + Si.dwFlags |= STARTF_USESHOWWINDOW; + Si.wShowWindow = SW_HIDE; + Log("Ventoy jump %s ...", rc == 0 ? "success" : "failed"); + } + + CreateProcessA(NULL, LunchFile, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi); + + while (rc) + { + Log("Ventoy hook failed, now wait and retry ..."); + Sleep(1000); + + rc = VentoyHook(&g_os_param); + } + + WaitForSingleObject(Pi.hProcess, INFINITE); + + return 0; +}