int g_vhdboot_enable = 0;
+grub_uint64_t g_conf_replace_offset = 0;
+conf_replace *g_conf_replace_node = NULL;
+grub_uint8_t *g_conf_replace_new_buf = NULL;
+int g_conf_replace_new_len = 0;
+int g_conf_replace_new_len_align = 0;
+
ventoy_gpt_info *g_ventoy_part_info = NULL;
static char *g_tree_script_buf = NULL;
return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]);
}
+ g_conf_replace_node = NULL;
+ g_conf_replace_offset = 0;
+
if (g_img_chunk_list.chunk)
{
grub_free(g_img_chunk_list.chunk);
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
+static grub_err_t ventoy_select_conf_replace(grub_extcmd_context_t ctxt, int argc, char **args)
+{
+ grub_uint64_t offset = 0;
+ grub_uint32_t align = 0;
+ grub_file_t file = NULL;
+ conf_replace *node = NULL;
+
+ (void)ctxt;
+ (void)argc;
+ (void)args;
+
+ debug("select conf replace argc:%d\n", argc);
+
+ if (argc < 2)
+ {
+ return 0;
+ }
+
+ node = ventoy_plugin_find_conf_replace(args[1]);
+ if (!node)
+ {
+ debug("Conf replace not found for %s\n", args[1]);
+ goto end;
+ }
+
+ debug("Find conf replace for %s\n", args[1]);
+
+ file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(loop)%s", node->orgconf);
+ if (!file)
+ {
+ debug("<(loop)%s> NOT exist\n", node->orgconf);
+ goto end;
+ }
+
+ offset = grub_iso9660_get_last_file_dirent_pos(file);
+ grub_file_close(file);
+
+ file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[0], node->newconf);
+ if (!file)
+ {
+ debug("New config file <%s%s> NOT exist\n", args[0], node->newconf);
+ goto end;
+ }
+
+ align = ((int)file->size + 2047) / 2048 * 2048;
+
+ if (align > vtoy_max_replace_file_size)
+ {
+ debug("New config file <%s%s> too big\n", args[0], node->newconf);
+ goto end;
+ }
+
+ grub_file_read(file, g_conf_replace_new_buf, file->size);
+ g_conf_replace_new_len = (int)file->size;
+ g_conf_replace_new_len_align = align;
+
+ g_conf_replace_node = node;
+ g_conf_replace_offset = offset + 2;
+
+ debug("conf_replace OK: newlen: %d\n", g_conf_replace_new_len);
+
+end:
+ if (file)
+ {
+ grub_file_close(file);
+ }
+ VENTOY_CMD_RETURN(GRUB_ERR_NONE);
+}
+
static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int argc, char **args)
{
int i = 0;
g_part_list_buf = grub_malloc(VTOY_PART_BUF_LEN);
g_tree_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF);
g_list_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF);
+ g_conf_replace_new_buf = grub_malloc(vtoy_max_replace_file_size);
ventoy_filt_register(0, ventoy_wrapper_open);
{ "vt_dump_persistence", ventoy_cmd_dump_persistence, 0, NULL, "", "", NULL },
{ "vt_select_auto_install", ventoy_cmd_sel_auto_install, 0, NULL, "", "", NULL },
{ "vt_select_persistence", ventoy_cmd_sel_persistence, 0, NULL, "", "", NULL },
+ { "vt_select_conf_replace", ventoy_select_conf_replace, 0, NULL, "", "", NULL },
{ "vt_iso9660_nojoliet", ventoy_cmd_iso9660_nojoliet, 0, NULL, "", "", NULL },
{ "vt_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL },
cmd_para *cur = NULL;
ventoy_env_init();
-
+
for (i = 0; i < ARRAY_SIZE(ventoy_cmds); i++)
{
cur = ventoy_cmds + i;
struct menu_class *next;
}menu_class;
+#define vtoy_max_replace_file_size (2 * 1024 * 1024)
+typedef struct conf_replace
+{
+ int pathlen;
+ char isopath[256];
+ char orgconf[256];
+ char newconf[256];
+
+ struct conf_replace *next;
+}conf_replace;
+
typedef struct injection_config
{
int pathlen;
extern int g_vhdboot_enable;
extern int g_plugin_image_list;
extern ventoy_gpt_info *g_ventoy_part_info;
+extern grub_uint64_t g_conf_replace_offset;
+extern conf_replace *g_conf_replace_node;
+extern grub_uint8_t *g_conf_replace_new_buf;
+extern int g_conf_replace_new_len;
+extern int g_conf_replace_new_len_align;
#define ventoy_unix_fill_virt(new_data, new_len) \
{ \
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);
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);
static grub_err_t ventoy_grub_cfg_initrd_collect(const char *fileName)
{
int i = 0;
+ int dollar = 0;
grub_file_t file = NULL;
char *buf = NULL;
char *start = NULL;
{
break;
}
-
+
+ dollar = 0;
for (i = 0; i < 255 && (0 == ventoy_is_word_end(*start)); i++)
{
img->name[i] = *start++;
+ if (img->name[i] == '$')
+ {
+ dollar = 1;
+ }
}
- if (ventoy_find_initrd_by_name(g_initrd_img_list, img->name))
+ if (dollar == 1 || ventoy_find_initrd_by_name(g_initrd_img_list, img->name))
{
grub_free(img);
}
return headlen;
}
+static grub_uint32_t ventoy_linux_get_virt_chunk_count(void)
+{
+ grub_uint32_t count = g_valid_initrd_count;
+
+ if (g_conf_replace_offset > 0)
+ {
+ count++;
+ }
+
+ return count;
+}
+
static grub_uint32_t ventoy_linux_get_virt_chunk_size(void)
{
- return (sizeof(ventoy_virt_chunk) + g_ventoy_cpio_size) * g_valid_initrd_count;
+ grub_uint32_t size;
+
+ size = (sizeof(ventoy_virt_chunk) + g_ventoy_cpio_size) * g_valid_initrd_count;
+
+ if (g_conf_replace_offset > 0)
+ {
+ size += sizeof(ventoy_virt_chunk) + g_conf_replace_new_len_align;
+ }
+
+ return size;
}
static void ventoy_linux_fill_virt_data( grub_uint64_t isosize, ventoy_chain_head *chain)
sector = (isosize + 2047) / 2048;
cpio_secs = g_ventoy_cpio_size / 2048;
- offset = g_valid_initrd_count * sizeof(ventoy_virt_chunk);
+ offset = ventoy_linux_get_virt_chunk_count() * sizeof(ventoy_virt_chunk);
cur = (ventoy_virt_chunk *)override;
for (node = g_initrd_img_list; node; node = node->next)
cur++;
}
+ if (g_conf_replace_offset > 0)
+ {
+ cpio_secs = g_conf_replace_new_len_align / 2048;
+
+ cur->mem_sector_start = sector;
+ cur->mem_sector_end = cur->mem_sector_start + cpio_secs;
+ cur->mem_sector_offset = offset;
+ cur->remap_sector_start = 0;
+ cur->remap_sector_end = 0;
+ cur->org_sector_start = 0;
+
+ grub_memcpy(override + offset, g_conf_replace_new_buf, g_conf_replace_new_len);
+
+ chain->virt_img_size_in_bytes += g_conf_replace_new_len_align;
+
+ offset += g_conf_replace_new_len_align;
+ sector += cpio_secs;
+ cur++;
+ }
+
return;
}
+static grub_uint32_t ventoy_linux_get_override_chunk_count(void)
+{
+ grub_uint32_t count = g_valid_initrd_count;
+
+ if (g_conf_replace_offset > 0)
+ {
+ count++;
+ }
+
+ return count;
+}
+
static grub_uint32_t ventoy_linux_get_override_chunk_size(void)
{
- return sizeof(ventoy_override_chunk) * g_valid_initrd_count;
+ int count = g_valid_initrd_count;
+
+ if (g_conf_replace_offset > 0)
+ {
+ count++;
+ }
+
+ return sizeof(ventoy_override_chunk) * count;
}
static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *override)
grub_uint32_t newlen;
grub_uint64_t sector;
ventoy_override_chunk *cur;
+ ventoy_iso9660_override *dirent;
+ ventoy_udf_override *udf;
sector = (isosize + 2047) / 2048;
mod = newlen % 4;
if (mod > 0)
{
- newlen += 4 - mod;
+ newlen += 4 - mod; /* cpio must align with 4 */
}
if (node->iso_type == 0)
{
- ventoy_iso9660_override *dirent = (ventoy_iso9660_override *)node->override_data;
+ dirent = (ventoy_iso9660_override *)node->override_data;
node->override_length = sizeof(ventoy_iso9660_override);
dirent->first_sector = (grub_uint32_t)sector;
}
else
{
- ventoy_udf_override *udf = (ventoy_udf_override *)node->override_data;
+ udf = (ventoy_udf_override *)node->override_data;
node->override_length = sizeof(ventoy_udf_override);
udf->length = newlen;
cur++;
}
+ if (g_conf_replace_offset > 0)
+ {
+ cur->img_offset = g_conf_replace_offset;
+ cur->override_size = sizeof(ventoy_iso9660_override);
+
+ newlen = (grub_uint32_t)(g_conf_replace_new_len);
+
+ dirent = (ventoy_iso9660_override *)cur->override_data;
+ dirent->first_sector = (grub_uint32_t)sector;
+ dirent->size = newlen;
+ dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector);
+ dirent->size_be = grub_swap_bytes32(dirent->size);
+
+ sector += (dirent->size + 2047) / 2048;
+ cur++;
+ }
+
return;
}
grub_uint64_t isosize = 0;
grub_uint32_t boot_catlog = 0;
grub_uint32_t img_chunk_size = 0;
+ grub_uint32_t override_count = 0;
grub_uint32_t override_size = 0;
+ grub_uint32_t virt_chunk_count = 0;
grub_uint32_t virt_chunk_size = 0;
grub_file_t file;
grub_disk_t disk;
}
img_chunk_size = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk);
+
+ override_count = ventoy_linux_get_override_chunk_count();
+ virt_chunk_count = ventoy_linux_get_virt_chunk_count();
if (ventoy_compatible)
{
return 0;
}
- if (g_valid_initrd_count == 0)
+ /* part 4: override chunk */
+ if (override_count > 0)
{
- return 0;
+ chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size;
+ chain->override_chunk_num = override_count;
+ ventoy_linux_fill_override_data(isosize, (char *)chain + chain->override_chunk_offset);
}
- /* part 4: override chunk */
- chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size;
- chain->override_chunk_num = g_valid_initrd_count;
- ventoy_linux_fill_override_data(isosize, (char *)chain + chain->override_chunk_offset);
-
/* part 5: virt chunk */
- chain->virt_chunk_offset = chain->override_chunk_offset + override_size;
- chain->virt_chunk_num = g_valid_initrd_count;
- ventoy_linux_fill_virt_data(isosize, chain);
+ if (virt_chunk_count > 0)
+ {
+ chain->virt_chunk_offset = chain->override_chunk_offset + override_size;
+ chain->virt_chunk_num = virt_chunk_count;
+ ventoy_linux_fill_virt_data(isosize, chain);
+ }
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
static injection_config *g_injection_head = NULL;
static auto_memdisk *g_auto_memdisk_head = NULL;
static image_list *g_image_list_head = NULL;
+static conf_replace *g_conf_replace_head = NULL;
static int ventoy_plugin_control_check(VTOY_JSON *json, const char *isodisk)
{
return 0;
}
+static int ventoy_plugin_conf_replace_entry(VTOY_JSON *json, const char *isodisk)
+{
+ const char *isof = NULL;
+ const char *orgf = NULL;
+ const char *newf = NULL;
+ VTOY_JSON *pNode = NULL;
+ conf_replace *tail = NULL;
+ conf_replace *node = NULL;
+ conf_replace *next = NULL;
+
+ (void)isodisk;
+
+ if (json->enDataType != JSON_TYPE_ARRAY)
+ {
+ debug("Not array %d\n", json->enDataType);
+ return 0;
+ }
+
+ if (g_conf_replace_head)
+ {
+ for (node = g_conf_replace_head; node; node = next)
+ {
+ next = node->next;
+ grub_free(node);
+ }
+
+ g_conf_replace_head = NULL;
+ }
+
+ for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
+ {
+ isof = vtoy_json_get_string_ex(pNode->pstChild, "iso");
+ orgf = vtoy_json_get_string_ex(pNode->pstChild, "org");
+ newf = vtoy_json_get_string_ex(pNode->pstChild, "new");
+ if (isof && orgf && newf && isof[0] == '/' && orgf[0] == '/' && newf[0] == '/')
+ {
+ node = grub_zalloc(sizeof(conf_replace));
+ if (node)
+ {
+ node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", isof);
+ grub_snprintf(node->orgconf, sizeof(node->orgconf), "%s", orgf);
+ grub_snprintf(node->newconf, sizeof(node->newconf), "%s", newf);
+
+ if (g_conf_replace_head)
+ {
+ tail->next = node;
+ }
+ else
+ {
+ g_conf_replace_head = node;
+ }
+ tail = node;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int ventoy_plugin_conf_replace_check(VTOY_JSON *json, const char *isodisk)
+{
+ const char *isof = NULL;
+ const char *orgf = NULL;
+ const char *newf = NULL;
+ VTOY_JSON *pNode = NULL;
+ grub_file_t file = NULL;
+ char cmd[256];
+
+ (void)isodisk;
+
+ if (json->enDataType != JSON_TYPE_ARRAY)
+ {
+ grub_printf("Not array %d\n", json->enDataType);
+ return 1;
+ }
+
+ for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
+ {
+ isof = vtoy_json_get_string_ex(pNode->pstChild, "iso");
+ orgf = vtoy_json_get_string_ex(pNode->pstChild, "org");
+ newf = vtoy_json_get_string_ex(pNode->pstChild, "new");
+ if (isof && orgf && newf && isof[0] == '/' && orgf[0] == '/' && newf[0] == '/')
+ {
+ if (ventoy_check_file_exist("%s%s", isodisk, isof))
+ {
+ grub_printf("iso:<%s> [OK]\n", isof);
+
+ grub_snprintf(cmd, sizeof(cmd), "loopback vtisocheck %s%s", isodisk, isof);
+ grub_script_execute_sourcecode(cmd);
+
+ file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(vtisocheck)/%s", orgf);
+ if (file)
+ {
+ if (grub_strcmp(file->fs->name, "iso9660") == 0)
+ {
+ grub_printf("org:<%s> [OK]\n", orgf);
+ }
+ else
+ {
+ grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf);
+ }
+ grub_file_close(file);
+ }
+ else
+ {
+ grub_printf("org:<%s> [NOT Exist]\n", orgf);
+ }
+
+ grub_script_execute_sourcecode("loopback -d vtisocheck");
+ }
+ else
+ {
+ grub_printf("iso:<%s> [NOT Exist]\n", isof);
+ grub_printf("org:<%s>\n", orgf);
+ }
+
+ file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", isodisk, newf);
+ if (file)
+ {
+ if (file->size > vtoy_max_replace_file_size)
+ {
+ grub_printf("new:<%s> [Too Big %lu] \n", newf, (ulong)file->size);
+ }
+ else
+ {
+ grub_printf("new:<%s> [OK]\n", newf);
+ }
+ grub_file_close(file);
+ }
+ else
+ {
+ grub_printf("new:<%s> [NOT Exist]\n", newf);
+ }
+ grub_printf("\n");
+ }
+ }
+
+ return 0;
+}
+
static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON *json, const char *isodisk)
{
VTOY_JSON *pNode = NULL;
{ "injection", ventoy_plugin_injection_entry, ventoy_plugin_injection_check },
{ "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 },
};
static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk)
return 0;
}
+conf_replace * ventoy_plugin_find_conf_replace(const char *iso)
+{
+ int len;
+ conf_replace *node;
+
+ if (!g_conf_replace_head)
+ {
+ return NULL;
+ }
+
+ len = (int)grub_strlen(iso);
+
+ for (node = g_conf_replace_head; node; node = node->next)
+ {
+ if (node->pathlen == len && grub_strncmp(iso, node->isopath, len) == 0)
+ {
+ return node;
+ }
+ }
+
+ return NULL;
+}
+
grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args)
{
int i = 0;
unset pager
}
+ menuentry 'Check boot conf replace plugin configuration' --class=debug_bootconf_replace {
+ set pager=1
+ vt_check_plugin_json $vt_plugin_path conf_replace $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 ...'
}
done
}
-
+submenu "Screen Display Mode" --class=debug_screen_mode {
+ menuentry 'Force Text Mode' --class=debug_text_mode {
+ terminal_output console
+ }
+ menuentry 'Force Graphics Mode' --class=debug_gui_mode {
+ terminal_output gfxterm
+ }
+ menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET {
+ echo 'Return ...'
+ }
+}
if [ "$grub_platform" != "pc" ]; then
submenu 'Ventoy UEFI Utilities' --class=debug_util {
fi
elif [ -f (loop)/blackarch/boot/x86_64/archiso.img ]; then
vt_linux_specify_initrd_file /blackarch/boot/x86_64/archiso.img
+
+ elif [ -f (loop)/install.amd/initrd.gz ]; then
+ vt_linux_specify_initrd_file /live/initrd2.img
+ vt_linux_specify_initrd_file /install.amd/initrd.gz
+ vt_linux_specify_initrd_file /install.amd/gtk/initrd.gz
+
fi
}
vt_img_sector ${1}${chosen_path}
+ if [ "$ventoy_fs_probe" = "iso9660" ]; then
+ 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}
loopback loop ${1}${chosen_path}
get_os_type (loop)
-
+
if [ -n "$vtcompat" ]; then
set ventoy_compatible=YES
unset vtcompat
vt_img_sector ${1}${chosen_path}
+ if [ "$ventoy_fs_probe" = "iso9660" ]; then
+ 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}
#############################################################
#############################################################
-set VENTOY_VERSION="1.0.26"
+set VENTOY_VERSION="1.0.27"
#ACPI not compatible with Window7/8, so disable by default
set VTOY_PARAM_NO_ACPI=1
if search -n -s -f /Boot/BCD; then
for bt in bootmgr BOOTMGR Bootmgr BootMGR; do
if [ -f /$bt ]; then
- ntldr /$bt
+ if regexp '^hd0' $root; then
+ ntldr /$bt
+ else
+ drivemap -s hd0 $root
+ ntldr /$bt
+ fi
break
fi
done