1.0.29 release

This commit is contained in:
longpanda
2020-11-19 20:45:17 +08:00
parent 8c192a1807
commit d8fbd79dda
27 changed files with 2071 additions and 1330 deletions

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/device.h>
#include <grub/file.h>
#include <grub/env.h>
#include <grub/command.h>
#include <grub/search.h>
#include <grub/i18n.h>
#include <grub/disk.h>
#include <grub/partition.h>
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);
}

View File

@@ -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 },

View File

@@ -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);

View File

@@ -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);

View File

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

View File

@@ -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;