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;
+}