mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-06-03 00:19:56 -04:00
1.0.13 release
This commit is contained in:
parent
785255b65f
commit
a5c706511b
55 changed files with 3501 additions and 1015 deletions
491
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/test.c
Normal file
491
GRUB2/MOD_SRC/grub-2.04/grub-core/commands/test.c
Normal file
|
@ -0,0 +1,491 @@
|
|||
/* test.c -- The test command.. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005,2007,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/dl.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/fs.h>
|
||||
#include <grub/device.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static int g_test_case_insensitive = 0;
|
||||
|
||||
/* A simple implementation for signed numbers. */
|
||||
static int
|
||||
grub_strtosl (char *arg, char **end, int base)
|
||||
{
|
||||
if (arg[0] == '-')
|
||||
return -grub_strtoul (arg + 1, end, base);
|
||||
return grub_strtoul (arg, end, base);
|
||||
}
|
||||
|
||||
/* Context for test_parse. */
|
||||
struct test_parse_ctx
|
||||
{
|
||||
int invert;
|
||||
int or, and;
|
||||
int file_exists;
|
||||
struct grub_dirhook_info file_info;
|
||||
char *filename;
|
||||
};
|
||||
|
||||
/* Take care of discarding and inverting. */
|
||||
static void
|
||||
update_val (int val, struct test_parse_ctx *ctx)
|
||||
{
|
||||
ctx->and = ctx->and && (ctx->invert ? ! val : val);
|
||||
ctx->invert = 0;
|
||||
}
|
||||
|
||||
/* A hook for iterating directories. */
|
||||
static int
|
||||
find_file (const char *cur_filename, const struct grub_dirhook_info *info,
|
||||
void *data)
|
||||
{
|
||||
int case_insensitive = 0;
|
||||
struct test_parse_ctx *ctx = data;
|
||||
|
||||
if (g_test_case_insensitive || info->case_insensitive)
|
||||
case_insensitive = 1;
|
||||
|
||||
if ((case_insensitive ? grub_strcasecmp (cur_filename, ctx->filename)
|
||||
: grub_strcmp (cur_filename, ctx->filename)) == 0)
|
||||
{
|
||||
ctx->file_info = *info;
|
||||
ctx->file_exists = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if file exists and fetch its information. */
|
||||
static void
|
||||
get_fileinfo (char *path, struct test_parse_ctx *ctx)
|
||||
{
|
||||
char *pathname;
|
||||
char *device_name;
|
||||
grub_fs_t fs;
|
||||
grub_device_t dev;
|
||||
|
||||
ctx->file_exists = 0;
|
||||
device_name = grub_file_get_device_name (path);
|
||||
dev = grub_device_open (device_name);
|
||||
if (! dev)
|
||||
{
|
||||
grub_free (device_name);
|
||||
return;
|
||||
}
|
||||
|
||||
fs = grub_fs_probe (dev);
|
||||
if (! fs)
|
||||
{
|
||||
grub_free (device_name);
|
||||
grub_device_close (dev);
|
||||
return;
|
||||
}
|
||||
|
||||
pathname = grub_strchr (path, ')');
|
||||
if (! pathname)
|
||||
pathname = path;
|
||||
else
|
||||
pathname++;
|
||||
|
||||
/* Remove trailing '/'. */
|
||||
while (*pathname && pathname[grub_strlen (pathname) - 1] == '/')
|
||||
pathname[grub_strlen (pathname) - 1] = 0;
|
||||
|
||||
/* Split into path and filename. */
|
||||
ctx->filename = grub_strrchr (pathname, '/');
|
||||
if (! ctx->filename)
|
||||
{
|
||||
path = grub_strdup ("/");
|
||||
ctx->filename = pathname;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->filename++;
|
||||
path = grub_strdup (pathname);
|
||||
path[ctx->filename - pathname] = 0;
|
||||
}
|
||||
|
||||
/* It's the whole device. */
|
||||
if (! *pathname)
|
||||
{
|
||||
ctx->file_exists = 1;
|
||||
grub_memset (&ctx->file_info, 0, sizeof (ctx->file_info));
|
||||
/* Root is always a directory. */
|
||||
ctx->file_info.dir = 1;
|
||||
|
||||
/* Fetch writing time. */
|
||||
ctx->file_info.mtimeset = 0;
|
||||
if (fs->fs_mtime)
|
||||
{
|
||||
if (! fs->fs_mtime (dev, &ctx->file_info.mtime))
|
||||
ctx->file_info.mtimeset = 1;
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
(fs->fs_dir) (dev, path, find_file, ctx);
|
||||
|
||||
grub_device_close (dev);
|
||||
grub_free (path);
|
||||
grub_free (device_name);
|
||||
}
|
||||
|
||||
/* Parse a test expression starting from *argn. */
|
||||
static int
|
||||
test_parse (char **args, int *argn, int argc)
|
||||
{
|
||||
struct test_parse_ctx ctx = {
|
||||
.and = 1,
|
||||
.or = 0,
|
||||
.invert = 0
|
||||
};
|
||||
|
||||
/* Here we have the real parsing. */
|
||||
while (*argn < argc)
|
||||
{
|
||||
/* First try 3 argument tests. */
|
||||
if (*argn + 2 < argc)
|
||||
{
|
||||
/* String tests. */
|
||||
if (grub_strcmp (args[*argn + 1], "=") == 0
|
||||
|| grub_strcmp (args[*argn + 1], "==") == 0)
|
||||
{
|
||||
update_val (grub_strcmp (args[*argn], args[*argn + 2]) == 0,
|
||||
&ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "!=") == 0)
|
||||
{
|
||||
update_val (grub_strcmp (args[*argn], args[*argn + 2]) != 0,
|
||||
&ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* GRUB extension: lexicographical sorting. */
|
||||
if (grub_strcmp (args[*argn + 1], "<") == 0)
|
||||
{
|
||||
update_val (grub_strcmp (args[*argn], args[*argn + 2]) < 0,
|
||||
&ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "<=") == 0)
|
||||
{
|
||||
update_val (grub_strcmp (args[*argn], args[*argn + 2]) <= 0,
|
||||
&ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], ">") == 0)
|
||||
{
|
||||
update_val (grub_strcmp (args[*argn], args[*argn + 2]) > 0,
|
||||
&ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], ">=") == 0)
|
||||
{
|
||||
update_val (grub_strcmp (args[*argn], args[*argn + 2]) >= 0,
|
||||
&ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Number tests. */
|
||||
if (grub_strcmp (args[*argn + 1], "-eq") == 0)
|
||||
{
|
||||
update_val (grub_strtosl (args[*argn], 0, 0)
|
||||
== grub_strtosl (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "-ge") == 0)
|
||||
{
|
||||
update_val (grub_strtosl (args[*argn], 0, 0)
|
||||
>= grub_strtosl (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "-gt") == 0)
|
||||
{
|
||||
update_val (grub_strtosl (args[*argn], 0, 0)
|
||||
> grub_strtosl (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "-le") == 0)
|
||||
{
|
||||
update_val (grub_strtosl (args[*argn], 0, 0)
|
||||
<= grub_strtosl (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "-lt") == 0)
|
||||
{
|
||||
update_val (grub_strtosl (args[*argn], 0, 0)
|
||||
< grub_strtosl (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "-ne") == 0)
|
||||
{
|
||||
update_val (grub_strtosl (args[*argn], 0, 0)
|
||||
!= grub_strtosl (args[*argn + 2], 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* GRUB extension: compare numbers skipping prefixes.
|
||||
Useful for comparing versions. E.g. vmlinuz-2 -plt vmlinuz-11. */
|
||||
if (grub_strcmp (args[*argn + 1], "-pgt") == 0
|
||||
|| grub_strcmp (args[*argn + 1], "-plt") == 0)
|
||||
{
|
||||
int i;
|
||||
/* Skip common prefix. */
|
||||
for (i = 0; args[*argn][i] == args[*argn + 2][i]
|
||||
&& args[*argn][i]; i++);
|
||||
|
||||
/* Go the digits back. */
|
||||
i--;
|
||||
while (grub_isdigit (args[*argn][i]) && i > 0)
|
||||
i--;
|
||||
i++;
|
||||
|
||||
if (grub_strcmp (args[*argn + 1], "-pgt") == 0)
|
||||
update_val (grub_strtoul (args[*argn] + i, 0, 0)
|
||||
> grub_strtoul (args[*argn + 2] + i, 0, 0), &ctx);
|
||||
else
|
||||
update_val (grub_strtoul (args[*argn] + i, 0, 0)
|
||||
< grub_strtoul (args[*argn + 2] + i, 0, 0), &ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* -nt and -ot tests. GRUB extension: when doing -?t<bias> bias
|
||||
will be added to the first mtime. */
|
||||
if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0
|
||||
|| grub_memcmp (args[*argn + 1], "-ot", 3) == 0)
|
||||
{
|
||||
struct grub_dirhook_info file1;
|
||||
int file1exists;
|
||||
int bias = 0;
|
||||
|
||||
/* Fetch fileinfo. */
|
||||
get_fileinfo (args[*argn], &ctx);
|
||||
file1 = ctx.file_info;
|
||||
file1exists = ctx.file_exists;
|
||||
get_fileinfo (args[*argn + 2], &ctx);
|
||||
|
||||
if (args[*argn + 1][3])
|
||||
bias = grub_strtosl (args[*argn + 1] + 3, 0, 0);
|
||||
|
||||
if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0)
|
||||
update_val ((file1exists && ! ctx.file_exists)
|
||||
|| (file1.mtimeset && ctx.file_info.mtimeset
|
||||
&& file1.mtime + bias > ctx.file_info.mtime),
|
||||
&ctx);
|
||||
else
|
||||
update_val ((! file1exists && ctx.file_exists)
|
||||
|| (file1.mtimeset && ctx.file_info.mtimeset
|
||||
&& file1.mtime + bias < ctx.file_info.mtime),
|
||||
&ctx);
|
||||
(*argn) += 3;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Two-argument tests. */
|
||||
if (*argn + 1 < argc)
|
||||
{
|
||||
/* File tests. */
|
||||
if (grub_strcmp (args[*argn], "-d") == 0)
|
||||
{
|
||||
get_fileinfo (args[*argn + 1], &ctx);
|
||||
update_val (ctx.file_exists && ctx.file_info.dir, &ctx);
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn], "-D") == 0)
|
||||
{
|
||||
g_test_case_insensitive = 1;
|
||||
get_fileinfo (args[*argn + 1], &ctx);
|
||||
g_test_case_insensitive = 0;
|
||||
update_val (ctx.file_exists && ctx.file_info.dir, &ctx);
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn], "-e") == 0)
|
||||
{
|
||||
get_fileinfo (args[*argn + 1], &ctx);
|
||||
update_val (ctx.file_exists, &ctx);
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn], "-E") == 0)
|
||||
{
|
||||
g_test_case_insensitive = 1;
|
||||
get_fileinfo (args[*argn + 1], &ctx);
|
||||
g_test_case_insensitive = 0;
|
||||
update_val (ctx.file_exists, &ctx);
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn], "-f") == 0)
|
||||
{
|
||||
get_fileinfo (args[*argn + 1], &ctx);
|
||||
/* FIXME: check for other types. */
|
||||
update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx);
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[*argn], "-F") == 0)
|
||||
{
|
||||
g_test_case_insensitive = 1;
|
||||
get_fileinfo (args[*argn + 1], &ctx);
|
||||
g_test_case_insensitive = 0;
|
||||
/* FIXME: check for other types. */
|
||||
update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx);
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn], "-s") == 0)
|
||||
{
|
||||
grub_file_t file;
|
||||
file = grub_file_open (args[*argn + 1], GRUB_FILE_TYPE_GET_SIZE
|
||||
| GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
update_val (file && (grub_file_size (file) != 0), &ctx);
|
||||
if (file)
|
||||
grub_file_close (file);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* String tests. */
|
||||
if (grub_strcmp (args[*argn], "-n") == 0)
|
||||
{
|
||||
update_val (args[*argn + 1][0], &ctx);
|
||||
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[*argn], "-z") == 0)
|
||||
{
|
||||
update_val (! args[*argn + 1][0], &ctx);
|
||||
(*argn) += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Special modifiers. */
|
||||
|
||||
/* End of expression. return to parent. */
|
||||
if (grub_strcmp (args[*argn], ")") == 0)
|
||||
{
|
||||
(*argn)++;
|
||||
return ctx.or || ctx.and;
|
||||
}
|
||||
/* Recursively invoke if parenthesis. */
|
||||
if (grub_strcmp (args[*argn], "(") == 0)
|
||||
{
|
||||
(*argn)++;
|
||||
update_val (test_parse (args, argn, argc), &ctx);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (args[*argn], "!") == 0)
|
||||
{
|
||||
ctx.invert = ! ctx.invert;
|
||||
(*argn)++;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[*argn], "-a") == 0)
|
||||
{
|
||||
(*argn)++;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[*argn], "-o") == 0)
|
||||
{
|
||||
ctx.or = ctx.or || ctx.and;
|
||||
ctx.and = 1;
|
||||
(*argn)++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* No test found. Interpret if as just a string. */
|
||||
update_val (args[*argn][0], &ctx);
|
||||
(*argn)++;
|
||||
}
|
||||
return ctx.or || ctx.and;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_test (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
int argn = 0;
|
||||
|
||||
if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0)
|
||||
argc--;
|
||||
|
||||
return test_parse (args, &argn, argc) ? GRUB_ERR_NONE
|
||||
: grub_error (GRUB_ERR_TEST_FAILURE, N_("false"));
|
||||
}
|
||||
|
||||
static grub_command_t cmd_1, cmd_2;
|
||||
|
||||
GRUB_MOD_INIT(test)
|
||||
{
|
||||
cmd_1 = grub_register_command ("[", grub_cmd_test,
|
||||
N_("EXPRESSION ]"), N_("Evaluate an expression."));
|
||||
cmd_1->flags |= GRUB_COMMAND_FLAG_EXTRACTOR;
|
||||
cmd_2 = grub_register_command ("test", grub_cmd_test,
|
||||
N_("EXPRESSION"), N_("Evaluate an expression."));
|
||||
cmd_2->flags |= GRUB_COMMAND_FLAG_EXTRACTOR;
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(test)
|
||||
{
|
||||
grub_unregister_command (cmd_1);
|
||||
grub_unregister_command (cmd_2);
|
||||
}
|
|
@ -117,6 +117,8 @@ struct grub_fshelp_find_file_iter_ctx
|
|||
enum grub_fshelp_filetype *foundtype;
|
||||
};
|
||||
|
||||
int g_ventoy_case_insensitive = 0;
|
||||
|
||||
/* Helper for grub_fshelp_find_file. */
|
||||
static int
|
||||
find_file_iter (const char *filename, enum grub_fshelp_filetype filetype,
|
||||
|
@ -124,6 +126,11 @@ find_file_iter (const char *filename, enum grub_fshelp_filetype filetype,
|
|||
{
|
||||
struct grub_fshelp_find_file_iter_ctx *ctx = data;
|
||||
|
||||
if (g_ventoy_case_insensitive)
|
||||
{
|
||||
filetype |= GRUB_FSHELP_CASE_INSENSITIVE;
|
||||
}
|
||||
|
||||
if (filetype == GRUB_FSHELP_UNKNOWN ||
|
||||
((filetype & GRUB_FSHELP_CASE_INSENSITIVE)
|
||||
? grub_strcasecmp (ctx->name, filename)
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static int g_ventoy_no_joliet = 0;
|
||||
static grub_uint64_t g_ventoy_last_read_pos = 0;
|
||||
static grub_uint64_t g_ventoy_last_read_offset = 0;
|
||||
static grub_uint64_t g_ventoy_last_read_dirent_pos = 0;
|
||||
|
@ -480,8 +481,10 @@ grub_iso9660_mount (grub_disk_t disk)
|
|||
(voldesc.escape[2] == 0x43) || /* UCS-2 Level 2. */
|
||||
(voldesc.escape[2] == 0x45))) /* UCS-2 Level 3. */
|
||||
{
|
||||
copy_voldesc = 1;
|
||||
data->joliet = 1;
|
||||
if (0 == g_ventoy_no_joliet) {
|
||||
copy_voldesc = 1;
|
||||
data->joliet = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (copy_voldesc)
|
||||
|
@ -1108,6 +1111,11 @@ grub_iso9660_mtime (grub_device_t device, grub_int32_t *timebuf)
|
|||
return err;
|
||||
}
|
||||
|
||||
void grub_iso9660_set_nojoliet(int nojoliet)
|
||||
{
|
||||
g_ventoy_no_joliet = nojoliet;
|
||||
}
|
||||
|
||||
grub_uint64_t grub_iso9660_get_last_read_pos(grub_file_t file)
|
||||
{
|
||||
(void)file;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <grub/i18n.h>
|
||||
#include <grub/ventoy.h>
|
||||
|
||||
#define GRUB_CACHE_TIMEOUT 2
|
||||
#define GRUB_CACHE_TIMEOUT 10
|
||||
|
||||
/* The last time the disk was used. */
|
||||
static grub_uint64_t grub_last_time = 0;
|
||||
|
|
|
@ -83,6 +83,29 @@ grub_file_t grub_memfile_open(const char *name)
|
|||
return file;
|
||||
}
|
||||
|
||||
int ventoy_check_file_exist(const char * fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
grub_file_t file;
|
||||
char fullpath[256] = {0};
|
||||
|
||||
va_start (ap, fmt);
|
||||
grub_vsnprintf(fullpath, 255, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
file = grub_file_open(fullpath, GRUB_FILE_TYPE_NONE);
|
||||
if (!file)
|
||||
{
|
||||
grub_errno = 0;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_file_close(file);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
grub_file_t
|
||||
grub_file_open (const char *name, enum grub_file_type type)
|
||||
{
|
||||
|
|
|
@ -260,6 +260,45 @@ reclaim_module_space (void)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifndef GRUB_MACHINE_EFI
|
||||
static int ventoy_legacy_limit_workaround(void)
|
||||
{
|
||||
grub_file_t file;
|
||||
char *pos, *root;
|
||||
char buf[128];
|
||||
|
||||
root = grub_strdup(grub_env_get("root"));
|
||||
if (!root)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
pos = grub_strchr(root, ',');
|
||||
if (pos) *pos = 0;
|
||||
|
||||
grub_snprintf(buf, sizeof(buf), "(%s,1)/ventoy/ventoy.disk.img.xz", root);
|
||||
file = grub_file_open(buf, GRUB_FILE_TYPE_NONE);
|
||||
if (file)
|
||||
{
|
||||
pos = grub_malloc(file->size);
|
||||
if (pos)
|
||||
{
|
||||
grub_file_read(file, pos, file->size);
|
||||
grub_snprintf(buf, sizeof(buf), "loopback ventoydisk mem:0x%lx:size:%lu",
|
||||
(unsigned long)pos, (unsigned long)file->size);
|
||||
|
||||
grub_parser_execute(buf);
|
||||
grub_env_set("prefix", "(ventoydisk)/grub");
|
||||
}
|
||||
|
||||
grub_file_close(file);
|
||||
}
|
||||
|
||||
grub_free(root);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The main routine. */
|
||||
void __attribute__ ((noreturn))
|
||||
grub_main (void)
|
||||
|
@ -293,6 +332,12 @@ grub_main (void)
|
|||
grub_env_export ("root");
|
||||
grub_env_export ("prefix");
|
||||
|
||||
#ifndef GRUB_MACHINE_EFI
|
||||
if (0 == ventoy_check_file_exist("%s/grub.cfg", grub_env_get("prefix"))) {
|
||||
ventoy_legacy_limit_workaround();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Reclaim space used for modules. */
|
||||
reclaim_module_space ();
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ int g_ventoy_iso_uefi_drv = 0;
|
|||
int g_ventoy_last_entry = 0;
|
||||
int g_ventoy_suppress_esc = 0;
|
||||
int g_ventoy_menu_esc = 0;
|
||||
int g_ventoy_fn_mutex = 0;
|
||||
|
||||
/* Time to delay after displaying an error message about a default/fallback
|
||||
entry failing to boot. */
|
||||
|
@ -802,39 +803,53 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
|
|||
goto refresh;
|
||||
|
||||
case GRUB_TERM_KEY_F2:
|
||||
cmdstr = grub_env_get("VTOY_F2_CMD");
|
||||
if (cmdstr)
|
||||
{
|
||||
menu_fini ();
|
||||
grub_script_execute_sourcecode(cmdstr);
|
||||
goto refresh;
|
||||
if (0 == g_ventoy_fn_mutex) {
|
||||
cmdstr = grub_env_get("VTOY_F2_CMD");
|
||||
if (cmdstr)
|
||||
{
|
||||
menu_fini ();
|
||||
g_ventoy_fn_mutex = 1;
|
||||
grub_script_execute_sourcecode(cmdstr);
|
||||
g_ventoy_fn_mutex = 0;
|
||||
goto refresh;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GRUB_TERM_KEY_F3:
|
||||
cmdstr = grub_env_get("VTOY_F3_CMD");
|
||||
if (cmdstr)
|
||||
{
|
||||
menu_fini ();
|
||||
grub_script_execute_sourcecode(cmdstr);
|
||||
goto refresh;
|
||||
if (0 == g_ventoy_fn_mutex) {
|
||||
cmdstr = grub_env_get("VTOY_F3_CMD");
|
||||
if (cmdstr)
|
||||
{
|
||||
menu_fini ();
|
||||
grub_script_execute_sourcecode(cmdstr);
|
||||
goto refresh;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GRUB_TERM_KEY_F4:
|
||||
cmdstr = grub_env_get("VTOY_F4_CMD");
|
||||
if (cmdstr)
|
||||
{
|
||||
menu_fini ();
|
||||
grub_script_execute_sourcecode(cmdstr);
|
||||
goto refresh;
|
||||
if (0 == g_ventoy_fn_mutex) {
|
||||
cmdstr = grub_env_get("VTOY_F4_CMD");
|
||||
if (cmdstr)
|
||||
{
|
||||
menu_fini ();
|
||||
g_ventoy_fn_mutex = 1;
|
||||
grub_script_execute_sourcecode(cmdstr);
|
||||
g_ventoy_fn_mutex = 0;
|
||||
goto refresh;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GRUB_TERM_KEY_F5:
|
||||
cmdstr = grub_env_get("VTOY_F5_CMD");
|
||||
if (cmdstr)
|
||||
{
|
||||
menu_fini ();
|
||||
grub_script_execute_sourcecode(cmdstr);
|
||||
goto refresh;
|
||||
if (0 == g_ventoy_fn_mutex) {
|
||||
cmdstr = grub_env_get("VTOY_F5_CMD");
|
||||
if (cmdstr)
|
||||
{
|
||||
menu_fini ();
|
||||
g_ventoy_fn_mutex = 1;
|
||||
grub_script_execute_sourcecode(cmdstr);
|
||||
g_ventoy_fn_mutex = 0;
|
||||
goto refresh;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GRUB_TERM_KEY_F6:
|
||||
|
|
|
@ -68,6 +68,7 @@ img_iterator_node *g_img_iterator_tail = NULL;
|
|||
|
||||
grub_uint8_t g_ventoy_break_level = 0;
|
||||
grub_uint8_t g_ventoy_debug_level = 0;
|
||||
grub_uint8_t g_ventoy_chain_type = 0;
|
||||
grub_uint8_t *g_ventoy_cpio_buf = NULL;
|
||||
grub_uint32_t g_ventoy_cpio_size = 0;
|
||||
cpio_newc_header *g_ventoy_initrd_head = NULL;
|
||||
|
@ -433,6 +434,27 @@ static grub_err_t ventoy_cmd_load_iso_to_mem(grub_extcmd_context_t ctxt, int arg
|
|||
return rc;
|
||||
}
|
||||
|
||||
static grub_err_t ventoy_cmd_iso9660_nojoliet(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
(void)ctxt;
|
||||
|
||||
if (argc != 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (args[0][0] == '1')
|
||||
{
|
||||
grub_iso9660_set_nojoliet(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_iso9660_set_nojoliet(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t ventoy_cmd_is_udf(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
int i;
|
||||
|
@ -853,6 +875,8 @@ static int ventoy_colect_img_files(const char *filename, const struct grub_dirho
|
|||
*((img_info **)(node->tail)) = img;
|
||||
g_ventoy_img_count++;
|
||||
|
||||
img->alias = ventoy_plugin_get_menu_alias(img->path);
|
||||
|
||||
debug("Add %s%s to list %d\n", node->dir, filename, g_ventoy_img_count);
|
||||
}
|
||||
}
|
||||
|
@ -1031,7 +1055,8 @@ static int ventoy_dynamic_tree_menu(img_iterator_node *node)
|
|||
" %s_%s \n"
|
||||
"}\n",
|
||||
grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT),
|
||||
img->unsupport ? "[unsupported] " : "", img->name, img->id,
|
||||
img->unsupport ? "[unsupported] " : "",
|
||||
img->alias ? img->alias : img->name, img->id,
|
||||
(img->type == img_type_iso) ? "iso" : "wim",
|
||||
img->unsupport ? "unsupport_menuentry" : "common_menuentry");
|
||||
}
|
||||
|
@ -1115,7 +1140,7 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
|
|||
if (strdata && strdata[0] == '/')
|
||||
{
|
||||
len = grub_snprintf(g_img_iterator_head.dir, sizeof(g_img_iterator_head.dir) - 1, "%s", strdata);
|
||||
if (g_img_iterator_head.dir[len] != '/')
|
||||
if (g_img_iterator_head.dir[len - 1] != '/')
|
||||
{
|
||||
g_img_iterator_head.dir[len++] = '/';
|
||||
}
|
||||
|
@ -1174,7 +1199,8 @@ static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char
|
|||
"menuentry \"%s%s\" --id=\"VID_%d\" {\n"
|
||||
" %s_%s \n"
|
||||
"}\n",
|
||||
cur->unsupport ? "[unsupported] " : "", cur->name, cur->id,
|
||||
cur->unsupport ? "[unsupported] " : "",
|
||||
cur->alias ? cur->alias : cur->name, cur->id,
|
||||
(cur->type == img_type_iso) ? "iso" : "wim",
|
||||
cur->unsupport ? "unsupport_menuentry" : "common_menuentry");
|
||||
}
|
||||
|
@ -1394,6 +1420,7 @@ int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector)
|
|||
void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param)
|
||||
{
|
||||
char *pos;
|
||||
const char *fs = NULL;
|
||||
grub_uint32_t i;
|
||||
grub_uint8_t chksum = 0;
|
||||
grub_disk_t disk;
|
||||
|
@ -1419,6 +1446,14 @@ void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param)
|
|||
|
||||
param->vtoy_reserved[0] = g_ventoy_break_level;
|
||||
param->vtoy_reserved[1] = g_ventoy_debug_level;
|
||||
|
||||
param->vtoy_reserved[2] = g_ventoy_chain_type;
|
||||
|
||||
fs = ventoy_get_env("ventoy_fs_probe");
|
||||
if (fs && grub_strcmp(fs, "udf") == 0)
|
||||
{
|
||||
param->vtoy_reserved[3] = 1;
|
||||
}
|
||||
|
||||
/* calculate checksum */
|
||||
for (i = 0; i < sizeof(ventoy_os_param); i++)
|
||||
|
@ -1567,6 +1602,8 @@ static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int ar
|
|||
(void)argc;
|
||||
(void)args;
|
||||
|
||||
debug("select auto installation %d\n", argc);
|
||||
|
||||
if (argc < 1)
|
||||
{
|
||||
return 0;
|
||||
|
@ -1575,6 +1612,7 @@ static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int ar
|
|||
node = ventoy_plugin_find_install_template(args[0]);
|
||||
if (!node)
|
||||
{
|
||||
debug("Install template not found for %s\n", args[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1622,6 +1660,8 @@ static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int arg
|
|||
(void)argc;
|
||||
(void)args;
|
||||
|
||||
debug("select persistece %d\n", argc);
|
||||
|
||||
if (argc < 1)
|
||||
{
|
||||
return 0;
|
||||
|
@ -1630,6 +1670,7 @@ static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int arg
|
|||
node = ventoy_plugin_find_persistent(args[0]);
|
||||
if (!node)
|
||||
{
|
||||
debug("Persistence image not found for %s\n", args[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1854,12 +1895,51 @@ static grub_err_t ventoy_cmd_dump_menu(grub_extcmd_context_t ctxt, int argc, cha
|
|||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t ventoy_cmd_dump_img_list(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
img_info *cur = g_ventoy_img_list;
|
||||
|
||||
(void)ctxt;
|
||||
(void)argc;
|
||||
(void)args;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
grub_printf("path:<%s>\n", cur->path);
|
||||
grub_printf("name:<%s>\n\n", cur->name);
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t ventoy_cmd_dump_auto_install(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
(void)ctxt;
|
||||
(void)argc;
|
||||
(void)args;
|
||||
|
||||
{
|
||||
grub_file_t file;
|
||||
char *buf;
|
||||
char name[128];
|
||||
|
||||
file = grub_file_open("(hd0,1)/ventoy/ventoy.disk.img.xz", GRUB_FILE_TYPE_NONE);
|
||||
if (file)
|
||||
{
|
||||
grub_printf("Open File OK (size:%llu)\n", (ulonglong)file->size);
|
||||
|
||||
buf = grub_malloc(file->size);
|
||||
grub_file_read(file, buf, file->size);
|
||||
|
||||
grub_file_close(file);
|
||||
|
||||
grub_snprintf(name, sizeof(name), "mem:0x%llx:size:%llu", (ulonglong)(ulong)buf, (ulonglong)file->size);
|
||||
grub_printf("<%s>\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ventoy_plugin_dump_auto_install();
|
||||
|
||||
return 0;
|
||||
|
@ -1962,6 +2042,31 @@ static grub_err_t ventoy_cmd_dynamic_menu(grub_extcmd_context_t ctxt, int argc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t ventoy_cmd_file_exist_nocase(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
grub_file_t file;
|
||||
|
||||
(void)ctxt;
|
||||
|
||||
if (argc != 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_ventoy_case_insensitive = 1;
|
||||
file = grub_file_open(args[0], VENTOY_FILE_TYPE);
|
||||
g_ventoy_case_insensitive = 0;
|
||||
|
||||
grub_errno = 0;
|
||||
|
||||
if (file)
|
||||
{
|
||||
grub_file_close(file);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static grub_err_t ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
int id = 0;
|
||||
|
@ -2109,6 +2214,8 @@ static int ventoy_env_init(void)
|
|||
grub_env_set("vtdebug_flag", "");
|
||||
grub_env_export("vtdebug_flag");
|
||||
|
||||
|
||||
|
||||
g_tree_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF);
|
||||
g_list_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF);
|
||||
|
||||
|
@ -2146,11 +2253,13 @@ static cmd_para ventoy_cmds[] =
|
|||
{ "vt_dump_menu", ventoy_cmd_dump_menu, 0, NULL, "", "", NULL },
|
||||
{ "vt_dynamic_menu", ventoy_cmd_dynamic_menu, 0, NULL, "", "", NULL },
|
||||
{ "vt_check_mode", ventoy_cmd_check_mode, 0, NULL, "", "", NULL },
|
||||
{ "vt_dump_img_list", ventoy_cmd_dump_img_list, 0, NULL, "", "", NULL },
|
||||
{ "vt_dump_auto_install", ventoy_cmd_dump_auto_install, 0, NULL, "", "", NULL },
|
||||
{ "vt_dump_persistence", ventoy_cmd_dump_persistence, 0, NULL, "", "", NULL },
|
||||
{ "vt_select_auto_install", ventoy_cmd_sel_auto_install, 0, NULL, "", "", NULL },
|
||||
{ "vt_select_persistence", ventoy_cmd_sel_persistence, 0, NULL, "", "", NULL },
|
||||
|
||||
{ "vt_iso9660_nojoliet", ventoy_cmd_iso9660_nojoliet, 0, NULL, "", "", NULL },
|
||||
{ "vt_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL },
|
||||
{ "vt_file_size", ventoy_cmd_file_size, 0, NULL, "", "", NULL },
|
||||
{ "vt_load_iso_to_mem", ventoy_cmd_load_iso_to_mem, 0, NULL, "", "", NULL },
|
||||
|
@ -2164,18 +2273,25 @@ static cmd_para ventoy_cmds[] =
|
|||
{ "vt_linux_valid_initrd_count", ventoy_cmd_valid_initrd_count, 0, NULL, "", "", NULL },
|
||||
{ "vt_linux_locate_initrd", ventoy_cmd_linux_locate_initrd, 0, NULL, "", "", NULL },
|
||||
{ "vt_linux_chain_data", ventoy_cmd_linux_chain_data, 0, NULL, "", "", NULL },
|
||||
{ "vt_linux_get_main_initrd_index", ventoy_cmd_linux_get_main_initrd_index, 0, NULL, "", "", NULL },
|
||||
|
||||
{ "vt_windows_reset", ventoy_cmd_wimdows_reset, 0, NULL, "", "", NULL },
|
||||
{ "vt_windows_locate_wim", ventoy_cmd_wimdows_locate_wim, 0, NULL, "", "", NULL },
|
||||
{ "vt_windows_chain_data", ventoy_cmd_windows_chain_data, 0, NULL, "", "", NULL },
|
||||
{ "vt_windows_collect_wim_patch", ventoy_cmd_collect_wim_patch, 0, NULL, "", "", NULL },
|
||||
{ "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_chain_data", ventoy_cmd_wim_chain_data, 0, NULL, "", "", NULL },
|
||||
|
||||
{ "vt_add_replace_file", ventoy_cmd_add_replace_file, 0, NULL, "", "", NULL },
|
||||
{ "vt_relocator_chaindata", ventoy_cmd_relocator_chaindata, 0, NULL, "", "", NULL },
|
||||
{ "vt_test_block_list", ventoy_cmd_test_block_list, 0, NULL, "", "", NULL },
|
||||
{ "vt_file_exist_nocase", ventoy_cmd_file_exist_nocase, 0, NULL, "", "", NULL },
|
||||
|
||||
|
||||
{ "vt_load_plugin", ventoy_cmd_load_plugin, 0, NULL, "", "", NULL },
|
||||
{ "vt_check_plugin_json", ventoy_cmd_plugin_check_json, 0, NULL, "", "", NULL },
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -132,6 +132,9 @@ typedef struct img_info
|
|||
{
|
||||
char path[512];
|
||||
char name[256];
|
||||
|
||||
const char *alias;
|
||||
|
||||
int id;
|
||||
int type;
|
||||
grub_uint64_t size;
|
||||
|
@ -363,6 +366,19 @@ typedef struct wim_tail
|
|||
grub_uint32_t new_lookup_align_len;
|
||||
}wim_tail;
|
||||
|
||||
typedef struct wim_patch
|
||||
{
|
||||
int pathlen;
|
||||
char path[256];
|
||||
|
||||
wim_hash old_hash;
|
||||
wim_tail wim_data;
|
||||
wim_lookup_entry *replace_look;
|
||||
|
||||
int valid;
|
||||
|
||||
struct wim_patch *next;
|
||||
}wim_patch;
|
||||
|
||||
|
||||
typedef enum _JSON_TYPE
|
||||
|
@ -412,11 +428,13 @@ typedef struct _JSON_PARSE
|
|||
}
|
||||
|
||||
typedef int (*ventoy_plugin_entry_pf)(VTOY_JSON *json, const char *isodisk);
|
||||
typedef int (*ventoy_plugin_check_pf)(VTOY_JSON *json, const char *isodisk);
|
||||
|
||||
typedef struct plugin_entry
|
||||
{
|
||||
const char *key;
|
||||
ventoy_plugin_entry_pf entryfunc;
|
||||
ventoy_plugin_check_pf checkfunc;
|
||||
}plugin_entry;
|
||||
|
||||
|
||||
|
@ -440,9 +458,9 @@ int ventoy_is_file_exist(const char *fmt, ...);
|
|||
int ventoy_fill_data(grub_uint32_t buflen, char *buffer);
|
||||
grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||
grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||
grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||
grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||
grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||
grub_err_t ventoy_cmd_dump_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||
|
||||
VTOY_JSON *vtoy_json_find_item
|
||||
(
|
||||
|
@ -596,12 +614,23 @@ typedef struct persistence_config
|
|||
struct persistence_config *next;
|
||||
}persistence_config;
|
||||
|
||||
typedef struct menu_alias
|
||||
{
|
||||
int pathlen;
|
||||
char isopath[256];
|
||||
char alias[256];
|
||||
|
||||
struct menu_alias *next;
|
||||
}menu_alias;
|
||||
|
||||
extern int g_ventoy_menu_esc;
|
||||
extern int g_ventoy_suppress_esc;
|
||||
extern int g_ventoy_last_entry;
|
||||
extern int g_ventoy_memdisk_mode;
|
||||
extern int g_ventoy_iso_raw;
|
||||
extern int g_ventoy_iso_uefi_drv;
|
||||
extern int g_ventoy_case_insensitive;
|
||||
extern grub_uint8_t g_ventoy_chain_type;
|
||||
|
||||
int ventoy_cmp_img(img_info *img1, img_info *img2);
|
||||
void ventoy_swap_img(img_info *img1, img_info *img2);
|
||||
|
@ -611,9 +640,15 @@ persistence_config * ventoy_plugin_find_persistent(const char *isopath);
|
|||
void ventoy_plugin_dump_auto_install(void);
|
||||
int ventoy_fill_windows_rtdata(void *buf, char *isopath);
|
||||
int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list);
|
||||
const char * ventoy_plugin_get_menu_alias(const char *isopath);
|
||||
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);
|
||||
grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||
grub_err_t ventoy_cmd_linux_get_main_initrd_index(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||
grub_err_t ventoy_cmd_collect_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||
grub_err_t ventoy_cmd_wim_patch_count(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||
grub_err_t ventoy_cmd_locate_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args);
|
||||
|
||||
#endif /* __VENTOY_DEF_H__ */
|
||||
|
||||
|
|
|
@ -42,6 +42,11 @@ static void json_debug(const char *fmt, ...)
|
|||
{
|
||||
va_list args;
|
||||
|
||||
if (g_ventoy_debug == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
va_start (args, fmt);
|
||||
grub_vprintf (fmt, args);
|
||||
va_end (args);
|
||||
|
|
|
@ -841,6 +841,50 @@ static grub_err_t ventoy_linux_locate_initrd(int filt, int *filtcnt)
|
|||
}
|
||||
|
||||
|
||||
grub_err_t ventoy_cmd_linux_get_main_initrd_index(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
int index = 0;
|
||||
char buf[32];
|
||||
initrd_info *node = NULL;
|
||||
|
||||
(void)ctxt;
|
||||
(void)argc;
|
||||
(void)args;
|
||||
|
||||
if (argc != 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (g_initrd_img_count == 1)
|
||||
{
|
||||
ventoy_set_env(args[0], "0");
|
||||
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
||||
}
|
||||
|
||||
for (node = g_initrd_img_list; node; node = node->next)
|
||||
{
|
||||
if (node->size <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strstr(node->name, "ucode") || grub_strstr(node->name, "-firmware"))
|
||||
{
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
grub_snprintf(buf, sizeof(buf), "%d", index);
|
||||
ventoy_set_env(args[0], buf);
|
||||
break;
|
||||
}
|
||||
|
||||
debug("main initrd index:%d\n", index);
|
||||
|
||||
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
||||
}
|
||||
|
||||
grub_err_t ventoy_cmd_linux_locate_initrd(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
int sizefilt = 0;
|
||||
|
@ -1100,6 +1144,7 @@ grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, cha
|
|||
grub_memset(chain, 0, sizeof(ventoy_chain_head));
|
||||
|
||||
/* part 1: os parameter */
|
||||
g_ventoy_chain_type = 0;
|
||||
ventoy_fill_os_param(file, &(chain->os_param));
|
||||
|
||||
/* part 2: chain head */
|
||||
|
|
|
@ -41,6 +41,46 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
|||
static char g_iso_disk_name[128];
|
||||
static install_template *g_install_template_head = NULL;
|
||||
static persistence_config *g_persistence_head = NULL;
|
||||
static menu_alias *g_menu_alias_head = NULL;
|
||||
|
||||
static int ventoy_plugin_control_check(VTOY_JSON *json, const char *isodisk)
|
||||
{
|
||||
int rc = 0;
|
||||
VTOY_JSON *pNode = NULL;
|
||||
VTOY_JSON *pChild = NULL;
|
||||
|
||||
(void)isodisk;
|
||||
|
||||
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)
|
||||
{
|
||||
pChild = pNode->pstChild;
|
||||
if (pChild->enDataType == JSON_TYPE_STRING)
|
||||
{
|
||||
grub_printf("%s: %s\n", pChild->pcName, pChild->unData.pcStrVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_printf("%s is NOT string type\n", pChild->pcName);
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_printf("%s is not an object\n", pNode->pcName);
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ventoy_plugin_control_entry(VTOY_JSON *json, const char *isodisk)
|
||||
{
|
||||
|
@ -70,6 +110,64 @@ static int ventoy_plugin_control_entry(VTOY_JSON *json, const char *isodisk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ventoy_plugin_theme_check(VTOY_JSON *json, const char *isodisk)
|
||||
{
|
||||
int exist = 0;
|
||||
const char *value;
|
||||
|
||||
value = vtoy_json_get_string_ex(json->pstChild, "file");
|
||||
if (value)
|
||||
{
|
||||
grub_printf("file: %s\n", value);
|
||||
if (value[0] == '/')
|
||||
{
|
||||
exist = ventoy_is_file_exist("%s%s", isodisk, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
exist = ventoy_is_file_exist("%s/ventoy/%s", isodisk, value);
|
||||
}
|
||||
|
||||
if (exist == 0)
|
||||
{
|
||||
grub_printf("Theme file %s does NOT exist\n", value);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
value = vtoy_json_get_string_ex(json->pstChild, "gfxmode");
|
||||
if (value)
|
||||
{
|
||||
grub_printf("gfxmode: %s\n", value);
|
||||
}
|
||||
|
||||
value = vtoy_json_get_string_ex(json->pstChild, "display_mode");
|
||||
if (value)
|
||||
{
|
||||
grub_printf("display_mode: %s\n", value);
|
||||
}
|
||||
|
||||
value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left");
|
||||
if (value)
|
||||
{
|
||||
grub_printf("ventoy_left: %s\n", value);
|
||||
}
|
||||
|
||||
value = vtoy_json_get_string_ex(json->pstChild, "ventoy_top");
|
||||
if (value)
|
||||
{
|
||||
grub_printf("ventoy_top: %s\n", value);
|
||||
}
|
||||
|
||||
value = vtoy_json_get_string_ex(json->pstChild, "ventoy_color");
|
||||
if (value)
|
||||
{
|
||||
grub_printf("ventoy_color: %s\n", value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk)
|
||||
{
|
||||
const char *value;
|
||||
|
@ -104,6 +202,13 @@ static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk)
|
|||
grub_env_set("vtoy_gfxmode", value);
|
||||
}
|
||||
|
||||
value = vtoy_json_get_string_ex(json->pstChild, "display_mode");
|
||||
if (value)
|
||||
{
|
||||
debug("display_mode %s\n", value);
|
||||
grub_env_set("vtoy_display_mode", value);
|
||||
}
|
||||
|
||||
value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left");
|
||||
if (value)
|
||||
{
|
||||
|
@ -125,6 +230,92 @@ static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ventoy_plugin_check_path(const char *path, const char *file)
|
||||
{
|
||||
if (file[0] != '/')
|
||||
{
|
||||
grub_printf("%s is NOT begin with '/' \n", file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (grub_strchr(file, '\\'))
|
||||
{
|
||||
grub_printf("%s contains invalid '\\' \n", file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (grub_strstr(file, "//"))
|
||||
{
|
||||
grub_printf("%s contains invalid double slash\n", file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (grub_strstr(file, "../"))
|
||||
{
|
||||
grub_printf("%s contains invalid '../' \n", file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!ventoy_is_file_exist("%s%s", path, file))
|
||||
{
|
||||
grub_printf("%s%s does NOT exist\n", path, file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ventoy_plugin_check_fullpath
|
||||
(
|
||||
VTOY_JSON *json,
|
||||
const char *isodisk,
|
||||
const char *key
|
||||
)
|
||||
{
|
||||
int rc = 0;
|
||||
int ret = 0;
|
||||
VTOY_JSON *node = json;
|
||||
VTOY_JSON *child = NULL;
|
||||
|
||||
while (node)
|
||||
{
|
||||
if (0 == grub_strcmp(key, node->pcName))
|
||||
{
|
||||
break;
|
||||
}
|
||||
node = node->pstNext;
|
||||
}
|
||||
|
||||
if (!node)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (JSON_TYPE_STRING == node->enDataType)
|
||||
{
|
||||
ret = ventoy_plugin_check_path(isodisk, node->unData.pcStrVal);
|
||||
grub_printf("%s: %s [%s]\n", key, node->unData.pcStrVal, ret ? "FAIL" : "OK");
|
||||
}
|
||||
else if (JSON_TYPE_ARRAY == node->enDataType)
|
||||
{
|
||||
for (child = node->pstChild; child; child = child->pstNext)
|
||||
{
|
||||
if (JSON_TYPE_STRING != child->enDataType)
|
||||
{
|
||||
grub_printf("Non string json type\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = ventoy_plugin_check_path(isodisk, child->unData.pcStrVal);
|
||||
grub_printf("%s: %s [%s]\n", key, child->unData.pcStrVal, rc ? "FAIL" : "OK");
|
||||
ret += rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ventoy_plugin_parse_fullpath
|
||||
(
|
||||
VTOY_JSON *json,
|
||||
|
@ -209,6 +400,46 @@ static int ventoy_plugin_parse_fullpath
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int ventoy_plugin_auto_install_check(VTOY_JSON *json, const char *isodisk)
|
||||
{
|
||||
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, "template");
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_printf("image: %s [FAIL]\n", iso);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_printf("image not found\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk)
|
||||
{
|
||||
int pathnum = 0;
|
||||
|
@ -264,6 +495,45 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk)
|
||||
{
|
||||
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, "backend");
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_printf("image: %s [FAIL]\n", iso);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_printf("image not found\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk)
|
||||
{
|
||||
|
@ -322,13 +592,93 @@ static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ventoy_plugin_menualias_check(VTOY_JSON *json, const char *isodisk)
|
||||
{
|
||||
const char *iso = NULL;
|
||||
const char *alias = NULL;
|
||||
VTOY_JSON *pNode = NULL;
|
||||
|
||||
(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)
|
||||
{
|
||||
iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
|
||||
alias = vtoy_json_get_string_ex(pNode->pstChild, "alias");
|
||||
if (iso && iso[0] == '/' && alias)
|
||||
{
|
||||
grub_printf("image: <%s>\n", iso);
|
||||
grub_printf("alias: <%s>\n\n", alias);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ventoy_plugin_menualias_entry(VTOY_JSON *json, const char *isodisk)
|
||||
{
|
||||
const char *iso = NULL;
|
||||
const char *alias = NULL;
|
||||
VTOY_JSON *pNode = NULL;
|
||||
menu_alias *node = NULL;
|
||||
menu_alias *next = NULL;
|
||||
|
||||
(void)isodisk;
|
||||
|
||||
if (json->enDataType != JSON_TYPE_ARRAY)
|
||||
{
|
||||
debug("Not array %d\n", json->enDataType);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (g_menu_alias_head)
|
||||
{
|
||||
for (node = g_menu_alias_head; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
grub_free(node);
|
||||
}
|
||||
|
||||
g_menu_alias_head = NULL;
|
||||
}
|
||||
|
||||
for (pNode = json->pstChild; pNode; pNode = pNode->pstNext)
|
||||
{
|
||||
iso = vtoy_json_get_string_ex(pNode->pstChild, "image");
|
||||
alias = vtoy_json_get_string_ex(pNode->pstChild, "alias");
|
||||
if (iso && iso[0] == '/' && alias)
|
||||
{
|
||||
node = grub_zalloc(sizeof(menu_alias));
|
||||
if (node)
|
||||
{
|
||||
node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso);
|
||||
grub_snprintf(node->alias, sizeof(node->alias), "%s", alias);
|
||||
|
||||
if (g_menu_alias_head)
|
||||
{
|
||||
node->next = g_menu_alias_head;
|
||||
}
|
||||
|
||||
g_menu_alias_head = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static plugin_entry g_plugin_entries[] =
|
||||
{
|
||||
{ "control", ventoy_plugin_control_entry },
|
||||
{ "theme", ventoy_plugin_theme_entry },
|
||||
{ "auto_install", ventoy_plugin_auto_install_entry },
|
||||
{ "persistence", ventoy_plugin_persistence_entry },
|
||||
{ "control", ventoy_plugin_control_entry, ventoy_plugin_control_check },
|
||||
{ "theme", ventoy_plugin_theme_entry, ventoy_plugin_theme_check },
|
||||
{ "auto_install", ventoy_plugin_auto_install_entry, ventoy_plugin_auto_install_check },
|
||||
{ "persistence", ventoy_plugin_persistence_entry, ventoy_plugin_persistence_check },
|
||||
{ "menu_alias", ventoy_plugin_menualias_entry, ventoy_plugin_menualias_check },
|
||||
};
|
||||
|
||||
static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk)
|
||||
|
@ -566,3 +916,100 @@ end:
|
|||
return rc;
|
||||
}
|
||||
|
||||
const char * ventoy_plugin_get_menu_alias(const char *isopath)
|
||||
{
|
||||
menu_alias *node = NULL;
|
||||
int len = (int)grub_strlen(isopath);
|
||||
|
||||
for (node = g_menu_alias_head; node; node = node->next)
|
||||
{
|
||||
if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0)
|
||||
{
|
||||
return node->alias;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
char *buf = NULL;
|
||||
grub_file_t file;
|
||||
VTOY_JSON *node = NULL;
|
||||
VTOY_JSON *json = NULL;
|
||||
|
||||
(void)ctxt;
|
||||
|
||||
if (argc != 3)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/ventoy/ventoy.json", args[0]);
|
||||
if (!file)
|
||||
{
|
||||
grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
buf = grub_malloc(file->size + 1);
|
||||
if (!buf)
|
||||
{
|
||||
grub_printf("Failed to malloc memory %lu.\n", (ulong)(file->size + 1));
|
||||
goto end;
|
||||
}
|
||||
|
||||
buf[file->size] = 0;
|
||||
grub_file_read(file, buf, file->size);
|
||||
|
||||
json = vtoy_json_create();
|
||||
if (!json)
|
||||
{
|
||||
grub_printf("Failed to create json\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = vtoy_json_parse(json, buf);
|
||||
if (ret)
|
||||
{
|
||||
grub_printf("Syntax error detected in ventoy.json, please check it.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (node = json->pstChild; node; node = node->pstNext)
|
||||
{
|
||||
if (grub_strcmp(node->pcName, args[1]) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!node)
|
||||
{
|
||||
grub_printf("%s is NOT found in ventoy.json\n", args[1]);
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++)
|
||||
{
|
||||
if (grub_strcmp(g_plugin_entries[i].key, args[1]) == 0)
|
||||
{
|
||||
if (g_plugin_entries[i].checkfunc)
|
||||
{
|
||||
ret = g_plugin_entries[i].checkfunc(node, args[2]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
check_free(file, grub_file_close);
|
||||
check_free(json, vtoy_json_destroy);
|
||||
grub_check_free(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,13 +40,229 @@
|
|||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
wim_hash g_old_hash;
|
||||
wim_tail g_wim_data;
|
||||
static int g_iso_fs_type = 0;
|
||||
static int g_wim_total_patch_count = 0;
|
||||
static int g_wim_valid_patch_count = 0;
|
||||
static wim_patch *g_wim_patch_head = NULL;
|
||||
|
||||
static wim_lookup_entry *g_replace_look = NULL;
|
||||
grub_uint8_t g_temp_buf[512];
|
||||
|
||||
grub_ssize_t lzx_decompress ( const void *data, grub_size_t len, void *buf );
|
||||
|
||||
static wim_patch *ventoy_find_wim_patch(const char *path)
|
||||
{
|
||||
int len = (int)grub_strlen(path);
|
||||
wim_patch *node = g_wim_patch_head;
|
||||
|
||||
while (node)
|
||||
{
|
||||
if (len == node->pathlen && 0 == grub_strcmp(path, node->path))
|
||||
{
|
||||
return node;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ventoy_collect_wim_patch(const char *bcdfile)
|
||||
{
|
||||
int i, j, k;
|
||||
int rc = 1;
|
||||
grub_uint64_t magic;
|
||||
grub_file_t file = NULL;
|
||||
char *buf = NULL;
|
||||
wim_patch *node = NULL;
|
||||
char c;
|
||||
grub_uint8_t byte;
|
||||
char valid;
|
||||
char path[256];
|
||||
|
||||
g_ventoy_case_insensitive = 1;
|
||||
file = grub_file_open(bcdfile, VENTOY_FILE_TYPE);
|
||||
g_ventoy_case_insensitive = 0;
|
||||
if (!file)
|
||||
{
|
||||
debug("Failed to open file %s\n", bcdfile);
|
||||
grub_errno = 0;
|
||||
goto end;
|
||||
}
|
||||
|
||||
buf = grub_malloc(file->size + 8);
|
||||
if (!buf)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
grub_file_read(file, buf, file->size);
|
||||
|
||||
for (i = 0; i < (int)file->size - 8; i++)
|
||||
{
|
||||
if (buf[i + 8] != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
magic = *(grub_uint64_t *)(buf + i);
|
||||
|
||||
/* .wim .WIM .Wim */
|
||||
if ((magic == 0x006D00690077002EULL) ||
|
||||
(magic == 0x004D00490057002EULL) ||
|
||||
(magic == 0x006D00690057002EULL))
|
||||
{
|
||||
for (j = i; j > 0; j-= 2)
|
||||
{
|
||||
if (*(grub_uint16_t *)(buf + j) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j > 0)
|
||||
{
|
||||
byte = (grub_uint8_t)(*(grub_uint16_t *)(buf + j + 2));
|
||||
if (byte != '/' && byte != '\\')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
valid = 1;
|
||||
for (k = 0, j += 2; k < (int)sizeof(path) - 1 && j < i + 8; j += 2)
|
||||
{
|
||||
byte = (grub_uint8_t)(*(grub_uint16_t *)(buf + j));
|
||||
c = (char)byte;
|
||||
if (byte > '~' || byte < ' ') /* not printable */
|
||||
{
|
||||
valid = 0;
|
||||
break;
|
||||
}
|
||||
else if (c == '\\')
|
||||
{
|
||||
c = '/';
|
||||
}
|
||||
|
||||
path[k++] = c;
|
||||
}
|
||||
path[k++] = 0;
|
||||
|
||||
debug("@@@@ Find wim flag:<%s>\n", path);
|
||||
|
||||
if (0 == valid)
|
||||
{
|
||||
debug("Invalid wim file %d\n", k);
|
||||
}
|
||||
else if (NULL == ventoy_find_wim_patch(path))
|
||||
{
|
||||
node = grub_zalloc(sizeof(wim_patch));
|
||||
if (node)
|
||||
{
|
||||
node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", path);
|
||||
|
||||
debug("add patch <%s>\n", path);
|
||||
|
||||
if (g_wim_patch_head)
|
||||
{
|
||||
node->next = g_wim_patch_head;
|
||||
}
|
||||
g_wim_patch_head = node;
|
||||
|
||||
g_wim_total_patch_count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug("wim <%s> already exist\n", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
check_free(file, grub_file_close);
|
||||
grub_check_free(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
grub_err_t ventoy_cmd_wim_patch_count(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
(void)ctxt;
|
||||
(void)argc;
|
||||
(void)args;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
grub_snprintf(buf, sizeof(buf), "%d", g_wim_total_patch_count);
|
||||
ventoy_set_env(args[0], buf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_err_t ventoy_cmd_collect_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
wim_patch *node = NULL;
|
||||
|
||||
(void)ctxt;
|
||||
(void)argc;
|
||||
(void)args;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
debug("ventoy_cmd_collect_wim_patch %s %s\n", args[0], args[1]);
|
||||
|
||||
if (grub_strcmp(args[0], "bcd") == 0)
|
||||
{
|
||||
ventoy_collect_wim_patch(args[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (NULL == ventoy_find_wim_patch(args[1]))
|
||||
{
|
||||
node = grub_zalloc(sizeof(wim_patch));
|
||||
if (node)
|
||||
{
|
||||
node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", args[1]);
|
||||
|
||||
debug("add patch <%s>\n", args[1]);
|
||||
|
||||
if (g_wim_patch_head)
|
||||
{
|
||||
node->next = g_wim_patch_head;
|
||||
}
|
||||
g_wim_patch_head = node;
|
||||
|
||||
g_wim_total_patch_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
grub_err_t ventoy_cmd_dump_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
int i = 0;
|
||||
wim_patch *node = NULL;
|
||||
|
||||
(void)ctxt;
|
||||
(void)argc;
|
||||
(void)args;
|
||||
|
||||
for (node = g_wim_patch_head; node; node = node->next)
|
||||
{
|
||||
grub_printf("%d %s [%s]\n", i++, node->path, node->valid ? "SUCCESS" : "FAIL");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int wim_name_cmp(const char *search, grub_uint16_t *name, grub_uint16_t namelen)
|
||||
{
|
||||
char c1 = vtoy_to_upper(*search);
|
||||
|
@ -96,16 +312,24 @@ static int ventoy_is_pe64(grub_uint8_t *buffer)
|
|||
|
||||
grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
wim_patch *next = NULL;
|
||||
wim_patch *node = g_wim_patch_head;
|
||||
|
||||
(void)ctxt;
|
||||
(void)argc;
|
||||
(void)args;
|
||||
|
||||
while (node)
|
||||
{
|
||||
next = node->next;
|
||||
grub_free(node);
|
||||
node = next;
|
||||
}
|
||||
|
||||
g_wim_patch_head = NULL;
|
||||
g_wim_total_patch_count = 0;
|
||||
g_wim_valid_patch_count = 0;
|
||||
|
||||
check_free(g_wim_data.jump_bin_data, grub_free);
|
||||
check_free(g_wim_data.new_meta_data, grub_free);
|
||||
check_free(g_wim_data.new_lookup_data, grub_free);
|
||||
|
||||
grub_memset(&g_wim_data, 0, sizeof(g_wim_data));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -159,7 +383,7 @@ end:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ventoy_get_override_info(grub_file_t file)
|
||||
static int ventoy_get_override_info(grub_file_t file, wim_tail *wim_data)
|
||||
{
|
||||
grub_uint32_t start_block;
|
||||
grub_uint64_t file_offset;
|
||||
|
@ -169,7 +393,7 @@ static int ventoy_get_override_info(grub_file_t file)
|
|||
|
||||
if (grub_strcmp(file->fs->name, "iso9660") == 0)
|
||||
{
|
||||
g_wim_data.iso_type = 0;
|
||||
g_iso_fs_type = wim_data->iso_type = 0;
|
||||
override_len = sizeof(ventoy_iso9660_override);
|
||||
override_offset = grub_iso9660_get_last_file_dirent_pos(file) + 2;
|
||||
|
||||
|
@ -181,7 +405,7 @@ static int ventoy_get_override_info(grub_file_t file)
|
|||
}
|
||||
else
|
||||
{
|
||||
g_wim_data.iso_type = 1;
|
||||
g_iso_fs_type = wim_data->iso_type = 1;
|
||||
override_len = sizeof(ventoy_udf_override);
|
||||
override_offset = grub_udf_get_last_file_attr_offset(file, &start_block, &fe_entry_size_offset);
|
||||
|
||||
|
@ -191,11 +415,11 @@ static int ventoy_get_override_info(grub_file_t file)
|
|||
(ulonglong)file->size, (ulonglong)override_offset, (ulonglong)file_offset, start_block);
|
||||
}
|
||||
|
||||
g_wim_data.file_offset = file_offset;
|
||||
g_wim_data.udf_start_block = start_block;
|
||||
g_wim_data.fe_entry_size_offset = fe_entry_size_offset;
|
||||
g_wim_data.override_offset = override_offset;
|
||||
g_wim_data.override_len = override_len;
|
||||
wim_data->file_offset = file_offset;
|
||||
wim_data->udf_start_block = start_block;
|
||||
wim_data->fe_entry_size_offset = fe_entry_size_offset;
|
||||
wim_data->override_offset = override_offset;
|
||||
wim_data->override_len = override_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -336,7 +560,7 @@ static wim_directory_entry * search_replace_wim_dirent(void *meta_data, wim_dire
|
|||
{
|
||||
wim_directory_entry *wim_dirent = NULL;
|
||||
const char *winpeshl_path[] = { "Windows", "System32", "winpeshl.exe", NULL };
|
||||
const char *pecmd_path[] = { "Windows", "System32", "PECMD.exe", NULL };
|
||||
//const char *pecmd_path[] = { "Windows", "System32", "PECMD.exe", NULL };
|
||||
|
||||
wim_dirent = search_full_wim_dirent(meta_data, dir, winpeshl_path);
|
||||
if (wim_dirent)
|
||||
|
@ -344,11 +568,13 @@ static wim_directory_entry * search_replace_wim_dirent(void *meta_data, wim_dire
|
|||
return wim_dirent;
|
||||
}
|
||||
|
||||
#if 0
|
||||
wim_dirent = search_full_wim_dirent(meta_data, dir, pecmd_path);
|
||||
if (wim_dirent)
|
||||
{
|
||||
return wim_dirent;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -394,7 +620,7 @@ static wim_lookup_entry * ventoy_find_meta_entry(wim_header *header, wim_lookup_
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int ventoy_update_all_hash(void *meta_data, wim_directory_entry *dir)
|
||||
static int ventoy_update_all_hash(wim_patch *patch, void *meta_data, wim_directory_entry *dir)
|
||||
{
|
||||
if ((meta_data == NULL) || (dir == NULL))
|
||||
{
|
||||
|
@ -408,15 +634,15 @@ static int ventoy_update_all_hash(void *meta_data, wim_directory_entry *dir)
|
|||
|
||||
do
|
||||
{
|
||||
if (dir->subdir == 0 && grub_memcmp(dir->hash.sha1, g_old_hash.sha1, sizeof(wim_hash)) == 0)
|
||||
if (dir->subdir == 0 && grub_memcmp(dir->hash.sha1, patch->old_hash.sha1, sizeof(wim_hash)) == 0)
|
||||
{
|
||||
debug("find target file, name_len:%u upadte hash\n", dir->name_len);
|
||||
grub_memcpy(dir->hash.sha1, &(g_wim_data.bin_hash), sizeof(wim_hash));
|
||||
grub_memcpy(dir->hash.sha1, &(patch->wim_data.bin_hash), sizeof(wim_hash));
|
||||
}
|
||||
|
||||
if (dir->subdir)
|
||||
{
|
||||
ventoy_update_all_hash(meta_data, (wim_directory_entry *)((char *)meta_data + dir->subdir));
|
||||
ventoy_update_all_hash(patch, meta_data, (wim_directory_entry *)((char *)meta_data + dir->subdir));
|
||||
}
|
||||
|
||||
dir = (wim_directory_entry *)((char *)dir + dir->len);
|
||||
|
@ -425,7 +651,7 @@ static int ventoy_update_all_hash(void *meta_data, wim_directory_entry *dir)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ventoy_cat_exe_file_data(grub_uint32_t exe_len, grub_uint8_t *exe_data)
|
||||
static int ventoy_cat_exe_file_data(wim_tail *wim_data, grub_uint32_t exe_len, grub_uint8_t *exe_data)
|
||||
{
|
||||
int pe64 = 0;
|
||||
char file[256];
|
||||
|
@ -439,19 +665,19 @@ static int ventoy_cat_exe_file_data(grub_uint32_t exe_len, grub_uint8_t *exe_dat
|
|||
ventoy_load_jump_exe(file, &jump_data, &jump_len, NULL);
|
||||
jump_align = ventoy_align(jump_len, 16);
|
||||
|
||||
g_wim_data.jump_exe_len = jump_len;
|
||||
g_wim_data.bin_raw_len = jump_align + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data) + exe_len;
|
||||
g_wim_data.bin_align_len = ventoy_align(g_wim_data.bin_raw_len, 2048);
|
||||
wim_data->jump_exe_len = jump_len;
|
||||
wim_data->bin_raw_len = jump_align + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data) + exe_len;
|
||||
wim_data->bin_align_len = ventoy_align(wim_data->bin_raw_len, 2048);
|
||||
|
||||
g_wim_data.jump_bin_data = grub_malloc(g_wim_data.bin_align_len);
|
||||
if (g_wim_data.jump_bin_data)
|
||||
wim_data->jump_bin_data = grub_malloc(wim_data->bin_align_len);
|
||||
if (wim_data->jump_bin_data)
|
||||
{
|
||||
grub_memcpy(g_wim_data.jump_bin_data, jump_data, jump_len);
|
||||
grub_memcpy(g_wim_data.jump_bin_data + jump_align + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data), exe_data, exe_len);
|
||||
grub_memcpy(wim_data->jump_bin_data, jump_data, jump_len);
|
||||
grub_memcpy(wim_data->jump_bin_data + jump_align + sizeof(ventoy_os_param) + sizeof(ventoy_windows_data), exe_data, exe_len);
|
||||
}
|
||||
|
||||
debug("jump_exe_len:%u bin_raw_len:%u bin_align_len:%u\n",
|
||||
g_wim_data.jump_exe_len, g_wim_data.bin_raw_len, g_wim_data.bin_align_len);
|
||||
wim_data->jump_exe_len, wim_data->bin_raw_len, wim_data->bin_align_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -490,49 +716,63 @@ static int ventoy_update_before_chain(ventoy_os_param *param, char *isopath)
|
|||
wim_lookup_entry *meta_look = NULL;
|
||||
wim_security_header *security = NULL;
|
||||
wim_directory_entry *rootdir = NULL;
|
||||
wim_header *head = &(g_wim_data.wim_header);
|
||||
wim_lookup_entry *lookup = (wim_lookup_entry *)g_wim_data.new_lookup_data;
|
||||
wim_header *head = NULL;
|
||||
wim_lookup_entry *lookup = NULL;
|
||||
wim_patch *node = NULL;
|
||||
wim_tail *wim_data = NULL;
|
||||
|
||||
jump_align = ventoy_align(g_wim_data.jump_exe_len, 16);
|
||||
if (g_wim_data.jump_bin_data)
|
||||
for (node = g_wim_patch_head; node; node = node->next)
|
||||
{
|
||||
grub_memcpy(g_wim_data.jump_bin_data + jump_align, param, sizeof(ventoy_os_param));
|
||||
ventoy_fill_windows_rtdata(g_wim_data.jump_bin_data + jump_align + sizeof(ventoy_os_param), isopath);
|
||||
}
|
||||
if (0 == node->valid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
grub_crypto_hash(GRUB_MD_SHA1, g_wim_data.bin_hash.sha1, g_wim_data.jump_bin_data, g_wim_data.bin_raw_len);
|
||||
wim_data = &node->wim_data;
|
||||
head = &wim_data->wim_header;
|
||||
lookup = (wim_lookup_entry *)wim_data->new_lookup_data;
|
||||
|
||||
security = (wim_security_header *)g_wim_data.new_meta_data;
|
||||
rootdir = (wim_directory_entry *)(g_wim_data.new_meta_data + ((security->len + 7) & 0xFFFFFFF8U));
|
||||
jump_align = ventoy_align(wim_data->jump_exe_len, 16);
|
||||
if (wim_data->jump_bin_data)
|
||||
{
|
||||
grub_memcpy(wim_data->jump_bin_data + jump_align, param, sizeof(ventoy_os_param));
|
||||
ventoy_fill_windows_rtdata(wim_data->jump_bin_data + jump_align + sizeof(ventoy_os_param), isopath);
|
||||
}
|
||||
|
||||
/* update all winpeshl.exe dirent entry's hash */
|
||||
ventoy_update_all_hash(g_wim_data.new_meta_data, rootdir);
|
||||
grub_crypto_hash(GRUB_MD_SHA1, wim_data->bin_hash.sha1, wim_data->jump_bin_data, wim_data->bin_raw_len);
|
||||
|
||||
/* update winpeshl.exe lookup entry data (hash/offset/length) */
|
||||
if (g_replace_look)
|
||||
{
|
||||
debug("update replace lookup entry_id:%ld\n", ((long)g_replace_look - (long)lookup) / sizeof(wim_lookup_entry));
|
||||
g_replace_look->resource.raw_size = g_wim_data.bin_raw_len;
|
||||
g_replace_look->resource.size_in_wim = g_wim_data.bin_raw_len;
|
||||
g_replace_look->resource.flags = 0;
|
||||
g_replace_look->resource.offset = g_wim_data.wim_align_size;
|
||||
security = (wim_security_header *)wim_data->new_meta_data;
|
||||
rootdir = (wim_directory_entry *)(wim_data->new_meta_data + ((security->len + 7) & 0xFFFFFFF8U));
|
||||
|
||||
grub_memcpy(g_replace_look->hash.sha1, g_wim_data.bin_hash.sha1, sizeof(wim_hash));
|
||||
}
|
||||
/* update all winpeshl.exe dirent entry's hash */
|
||||
ventoy_update_all_hash(node, wim_data->new_meta_data, rootdir);
|
||||
|
||||
/* update metadata's hash */
|
||||
meta_look = ventoy_find_meta_entry(head, lookup);
|
||||
if (meta_look)
|
||||
{
|
||||
debug("find meta lookup entry_id:%ld\n", ((long)meta_look - (long)lookup) / sizeof(wim_lookup_entry));
|
||||
grub_memcpy(&meta_look->resource, &head->metadata, sizeof(wim_resource_header));
|
||||
grub_crypto_hash(GRUB_MD_SHA1, meta_look->hash.sha1, g_wim_data.new_meta_data, g_wim_data.new_meta_len);
|
||||
/* update winpeshl.exe lookup entry data (hash/offset/length) */
|
||||
if (node->replace_look)
|
||||
{
|
||||
debug("update replace lookup entry_id:%ld\n", ((long)node->replace_look - (long)lookup) / sizeof(wim_lookup_entry));
|
||||
node->replace_look->resource.raw_size = wim_data->bin_raw_len;
|
||||
node->replace_look->resource.size_in_wim = wim_data->bin_raw_len;
|
||||
node->replace_look->resource.flags = 0;
|
||||
node->replace_look->resource.offset = wim_data->wim_align_size;
|
||||
|
||||
grub_memcpy(node->replace_look->hash.sha1, wim_data->bin_hash.sha1, sizeof(wim_hash));
|
||||
}
|
||||
|
||||
/* update metadata's hash */
|
||||
meta_look = ventoy_find_meta_entry(head, lookup);
|
||||
if (meta_look)
|
||||
{
|
||||
debug("find meta lookup entry_id:%ld\n", ((long)meta_look - (long)lookup) / sizeof(wim_lookup_entry));
|
||||
grub_memcpy(&meta_look->resource, &head->metadata, sizeof(wim_resource_header));
|
||||
grub_crypto_hash(GRUB_MD_SHA1, meta_look->hash.sha1, wim_data->new_meta_data, wim_data->new_meta_len);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch)
|
||||
{
|
||||
int rc;
|
||||
grub_file_t file;
|
||||
|
@ -543,20 +783,22 @@ grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, c
|
|||
wim_security_header *security = NULL;
|
||||
wim_directory_entry *rootdir = NULL;
|
||||
wim_directory_entry *search = NULL;
|
||||
wim_header *head = &(g_wim_data.wim_header);
|
||||
wim_header *head = &(patch->wim_data.wim_header);
|
||||
wim_tail *wim_data = &patch->wim_data;
|
||||
|
||||
(void)ctxt;
|
||||
(void)argc;
|
||||
debug("windows locate wim start %s\n", patch->path);
|
||||
|
||||
debug("windows locate wim start %s\n", args[0]);
|
||||
g_ventoy_case_insensitive = 1;
|
||||
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", disk, patch->path);
|
||||
g_ventoy_case_insensitive = 0;
|
||||
|
||||
file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]);
|
||||
if (!file)
|
||||
{
|
||||
return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]);
|
||||
debug("File %s%s NOT exist\n", disk, patch->path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ventoy_get_override_info(file);
|
||||
ventoy_get_override_info(file, &patch->wim_data);
|
||||
|
||||
grub_file_seek(file, 0);
|
||||
grub_file_read(file, head, sizeof(wim_header));
|
||||
|
@ -596,8 +838,8 @@ grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, c
|
|||
}
|
||||
|
||||
debug("find replace file at %p\n", search);
|
||||
|
||||
grub_memcpy(&g_old_hash, search->hash.sha1, sizeof(wim_hash));
|
||||
|
||||
grub_memcpy(&patch->old_hash, search->hash.sha1, sizeof(wim_hash));
|
||||
|
||||
debug("read lookup offset:%llu size:%llu\n", (ulonglong)head->lookup.offset, (ulonglong)head->lookup.raw_size);
|
||||
lookup = grub_malloc(head->lookup.raw_size);
|
||||
|
@ -605,16 +847,16 @@ grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, c
|
|||
grub_file_read(file, lookup, head->lookup.raw_size);
|
||||
|
||||
/* find and extact winpeshl.exe */
|
||||
g_replace_look = ventoy_find_look_entry(head, lookup, &g_old_hash);
|
||||
if (g_replace_look)
|
||||
patch->replace_look = ventoy_find_look_entry(head, lookup, &patch->old_hash);
|
||||
if (patch->replace_look)
|
||||
{
|
||||
exe_len = (grub_uint32_t)g_replace_look->resource.raw_size;
|
||||
exe_len = (grub_uint32_t)patch->replace_look->resource.raw_size;
|
||||
debug("find replace lookup entry_id:%ld raw_size:%u\n",
|
||||
((long)g_replace_look - (long)lookup) / sizeof(wim_lookup_entry), exe_len);
|
||||
((long)patch->replace_look - (long)lookup) / sizeof(wim_lookup_entry), exe_len);
|
||||
|
||||
if (0 == ventoy_read_resource(file, &(g_replace_look->resource), (void **)&(exe_data)))
|
||||
if (0 == ventoy_read_resource(file, &(patch->replace_look->resource), (void **)&(exe_data)))
|
||||
{
|
||||
ventoy_cat_exe_file_data(exe_len, exe_data);
|
||||
ventoy_cat_exe_file_data(wim_data, exe_len, exe_data);
|
||||
grub_free(exe_data);
|
||||
}
|
||||
else
|
||||
|
@ -624,106 +866,236 @@ grub_err_t ventoy_cmd_wimdows_locate_wim(grub_extcmd_context_t ctxt, int argc, c
|
|||
}
|
||||
else
|
||||
{
|
||||
debug("failed to find lookup entry for replace file 0x%02x 0x%02x\n", g_old_hash.sha1[0], g_old_hash.sha1[1]);
|
||||
debug("failed to find lookup entry for replace file 0x%02x 0x%02x\n",
|
||||
patch->old_hash.sha1[0], patch->old_hash.sha1[1]);
|
||||
}
|
||||
|
||||
g_wim_data.wim_raw_size = (grub_uint32_t)file->size;
|
||||
g_wim_data.wim_align_size = ventoy_align(g_wim_data.wim_raw_size, 2048);
|
||||
wim_data->wim_raw_size = (grub_uint32_t)file->size;
|
||||
wim_data->wim_align_size = ventoy_align(wim_data->wim_raw_size, 2048);
|
||||
|
||||
check_free(g_wim_data.new_meta_data, grub_free);
|
||||
g_wim_data.new_meta_data = decompress_data;
|
||||
g_wim_data.new_meta_len = head->metadata.raw_size;
|
||||
g_wim_data.new_meta_align_len = ventoy_align(g_wim_data.new_meta_len, 2048);
|
||||
grub_check_free(wim_data->new_meta_data);
|
||||
wim_data->new_meta_data = decompress_data;
|
||||
wim_data->new_meta_len = head->metadata.raw_size;
|
||||
wim_data->new_meta_align_len = ventoy_align(wim_data->new_meta_len, 2048);
|
||||
|
||||
check_free(g_wim_data.new_lookup_data, grub_free);
|
||||
g_wim_data.new_lookup_data = (grub_uint8_t *)lookup;
|
||||
g_wim_data.new_lookup_len = (grub_uint32_t)head->lookup.raw_size;
|
||||
g_wim_data.new_lookup_align_len = ventoy_align(g_wim_data.new_lookup_len, 2048);
|
||||
grub_check_free(wim_data->new_lookup_data);
|
||||
wim_data->new_lookup_data = (grub_uint8_t *)lookup;
|
||||
wim_data->new_lookup_len = (grub_uint32_t)head->lookup.raw_size;
|
||||
wim_data->new_lookup_align_len = ventoy_align(wim_data->new_lookup_len, 2048);
|
||||
|
||||
head->metadata.flags = RESHDR_FLAG_METADATA;
|
||||
head->metadata.offset = g_wim_data.wim_align_size + g_wim_data.bin_align_len;
|
||||
head->metadata.size_in_wim = g_wim_data.new_meta_len;
|
||||
head->metadata.raw_size = g_wim_data.new_meta_len;
|
||||
head->metadata.offset = wim_data->wim_align_size + wim_data->bin_align_len;
|
||||
head->metadata.size_in_wim = wim_data->new_meta_len;
|
||||
head->metadata.raw_size = wim_data->new_meta_len;
|
||||
|
||||
head->lookup.flags = 0;
|
||||
head->lookup.offset = head->metadata.offset + g_wim_data.new_meta_align_len;
|
||||
head->lookup.size_in_wim = g_wim_data.new_lookup_len;
|
||||
head->lookup.raw_size = g_wim_data.new_lookup_len;
|
||||
head->lookup.offset = head->metadata.offset + wim_data->new_meta_align_len;
|
||||
head->lookup.size_in_wim = wim_data->new_lookup_len;
|
||||
head->lookup.raw_size = wim_data->new_lookup_len;
|
||||
|
||||
grub_file_close(file);
|
||||
|
||||
debug("%s", "windows locate wim finish\n");
|
||||
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_err_t ventoy_cmd_locate_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
wim_patch *node = g_wim_patch_head;
|
||||
|
||||
(void)ctxt;
|
||||
(void)argc;
|
||||
(void)args;
|
||||
|
||||
while (node)
|
||||
{
|
||||
if (0 == ventoy_wimdows_locate_wim(args[0], node))
|
||||
{
|
||||
node->valid = 1;
|
||||
g_wim_valid_patch_count++;
|
||||
}
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_uint32_t ventoy_get_override_chunk_num(void)
|
||||
{
|
||||
/* 1: block count in Partition Descriptor */
|
||||
/* 2: file_size in file_entry or extend_file_entry */
|
||||
/* 3: data_size and position in extend data short ad */
|
||||
/* 4: new wim file header */
|
||||
return 4;
|
||||
if (g_iso_fs_type == 0)
|
||||
{
|
||||
/* ISO9660: */
|
||||
/* per wim */
|
||||
/* 1: file_size and file_offset */
|
||||
/* 2: new wim file header */
|
||||
return g_wim_valid_patch_count * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* UDF: */
|
||||
/* global: */
|
||||
/* 1: block count in Partition Descriptor */
|
||||
|
||||
/* per wim */
|
||||
/* 1: file_size in file_entry or extend_file_entry */
|
||||
/* 2: data_size and position in extend data short ad */
|
||||
/* 3: new wim file header */
|
||||
return g_wim_valid_patch_count * 3 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void ventoy_windows_fill_override_data( grub_uint64_t isosize, void *override)
|
||||
static void ventoy_windows_fill_override_data_iso9660( grub_uint64_t isosize, void *override)
|
||||
{
|
||||
grub_uint32_t data32;
|
||||
grub_uint64_t data64;
|
||||
grub_uint64_t sector;
|
||||
grub_uint32_t new_wim_size;
|
||||
ventoy_override_chunk *cur;
|
||||
wim_patch *node = NULL;
|
||||
wim_tail *wim_data = NULL;
|
||||
ventoy_iso9660_override *dirent = NULL;
|
||||
|
||||
sector = (isosize + 2047) / 2048;
|
||||
|
||||
cur = (ventoy_override_chunk *)override;
|
||||
|
||||
new_wim_size = g_wim_data.wim_align_size + g_wim_data.bin_align_len +
|
||||
g_wim_data.new_meta_align_len + g_wim_data.new_lookup_align_len;
|
||||
debug("ventoy_windows_fill_override_data_iso9660 %lu\n", (ulong)isosize);
|
||||
|
||||
if (g_wim_data.iso_type == 0)
|
||||
for (node = g_wim_patch_head; node; node = node->next)
|
||||
{
|
||||
ventoy_iso9660_override *dirent = (ventoy_iso9660_override *)g_wim_data.override_data;
|
||||
wim_data = &node->wim_data;
|
||||
if (0 == node->valid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
new_wim_size = wim_data->wim_align_size + wim_data->bin_align_len +
|
||||
wim_data->new_meta_align_len + wim_data->new_lookup_align_len;
|
||||
|
||||
dirent = (ventoy_iso9660_override *)wim_data->override_data;
|
||||
|
||||
dirent->first_sector = (grub_uint32_t)sector;
|
||||
dirent->size = new_wim_size;
|
||||
dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector);
|
||||
dirent->size_be = grub_swap_bytes32(dirent->size);
|
||||
|
||||
sector += (new_wim_size / 2048);
|
||||
|
||||
/* override 1: position and length in dirent */
|
||||
cur->img_offset = wim_data->override_offset;
|
||||
cur->override_size = wim_data->override_len;
|
||||
grub_memcpy(cur->override_data, wim_data->override_data, cur->override_size);
|
||||
cur++;
|
||||
|
||||
/* override 2: new wim file header */
|
||||
cur->img_offset = wim_data->file_offset;
|
||||
cur->override_size = sizeof(wim_header);
|
||||
grub_memcpy(cur->override_data, &(wim_data->wim_header), cur->override_size);
|
||||
cur++;
|
||||
}
|
||||
else
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void ventoy_windows_fill_override_data_udf( grub_uint64_t isosize, void *override)
|
||||
{
|
||||
grub_uint32_t data32;
|
||||
grub_uint64_t data64;
|
||||
grub_uint64_t sector;
|
||||
grub_uint32_t new_wim_size;
|
||||
grub_uint64_t total_wim_size = 0;
|
||||
grub_uint32_t udf_start_block = 0;
|
||||
ventoy_override_chunk *cur;
|
||||
wim_patch *node = NULL;
|
||||
wim_tail *wim_data = NULL;
|
||||
ventoy_udf_override *udf = NULL;
|
||||
|
||||
sector = (isosize + 2047) / 2048;
|
||||
|
||||
cur = (ventoy_override_chunk *)override;
|
||||
|
||||
debug("ventoy_windows_fill_override_data_udf %lu\n", (ulong)isosize);
|
||||
|
||||
for (node = g_wim_patch_head; node; node = node->next)
|
||||
{
|
||||
ventoy_udf_override *udf = (ventoy_udf_override *)g_wim_data.override_data;
|
||||
udf->length = new_wim_size;
|
||||
udf->position = (grub_uint32_t)sector - g_wim_data.udf_start_block;
|
||||
wim_data = &node->wim_data;
|
||||
if (node->valid)
|
||||
{
|
||||
if (udf_start_block == 0)
|
||||
{
|
||||
udf_start_block = wim_data->udf_start_block;
|
||||
}
|
||||
new_wim_size = wim_data->wim_align_size + wim_data->bin_align_len +
|
||||
wim_data->new_meta_align_len + wim_data->new_lookup_align_len;
|
||||
total_wim_size += new_wim_size;
|
||||
}
|
||||
}
|
||||
|
||||
//override 1: sector number in pd data
|
||||
cur->img_offset = grub_udf_get_last_pd_size_offset();
|
||||
cur->override_size = 4;
|
||||
data32 = sector - g_wim_data.udf_start_block + (new_wim_size / 2048);
|
||||
data32 = sector - udf_start_block + (total_wim_size / 2048);
|
||||
grub_memcpy(cur->override_data, &(data32), 4);
|
||||
|
||||
//override 2: filesize in file_entry
|
||||
cur++;
|
||||
cur->img_offset = g_wim_data.fe_entry_size_offset;
|
||||
cur->override_size = 8;
|
||||
data64 = new_wim_size;
|
||||
grub_memcpy(cur->override_data, &(data64), 8);
|
||||
for (node = g_wim_patch_head; node; node = node->next)
|
||||
{
|
||||
wim_data = &node->wim_data;
|
||||
if (0 == node->valid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
new_wim_size = wim_data->wim_align_size + wim_data->bin_align_len +
|
||||
wim_data->new_meta_align_len + wim_data->new_lookup_align_len;
|
||||
|
||||
/* override 3: position and length in extend data */
|
||||
cur++;
|
||||
cur->img_offset = g_wim_data.override_offset;
|
||||
cur->override_size = g_wim_data.override_len;
|
||||
grub_memcpy(cur->override_data, g_wim_data.override_data, cur->override_size);
|
||||
//override 2: filesize in file_entry
|
||||
cur++;
|
||||
cur->img_offset = wim_data->fe_entry_size_offset;
|
||||
cur->override_size = 8;
|
||||
data64 = new_wim_size;
|
||||
grub_memcpy(cur->override_data, &(data64), 8);
|
||||
|
||||
/* override 4: new wim file header */
|
||||
cur++;
|
||||
cur->img_offset = g_wim_data.file_offset;
|
||||
cur->override_size = sizeof(wim_header);
|
||||
grub_memcpy(cur->override_data, &(g_wim_data.wim_header), cur->override_size);
|
||||
udf = (ventoy_udf_override *)wim_data->override_data;
|
||||
udf->length = new_wim_size;
|
||||
udf->position = (grub_uint32_t)sector - udf_start_block;
|
||||
|
||||
sector += (new_wim_size / 2048);
|
||||
|
||||
/* override 3: position and length in extend data */
|
||||
cur++;
|
||||
cur->img_offset = wim_data->override_offset;
|
||||
cur->override_size = wim_data->override_len;
|
||||
grub_memcpy(cur->override_data, wim_data->override_data, cur->override_size);
|
||||
|
||||
/* override 4: new wim file header */
|
||||
cur++;
|
||||
cur->img_offset = wim_data->file_offset;
|
||||
cur->override_size = sizeof(wim_header);
|
||||
grub_memcpy(cur->override_data, &(wim_data->wim_header), cur->override_size);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static grub_uint32_t ventoy_windows_get_virt_data_size(void)
|
||||
{
|
||||
grub_uint32_t size = 0;
|
||||
wim_tail *wim_data = NULL;
|
||||
wim_patch *node = g_wim_patch_head;
|
||||
|
||||
while (node)
|
||||
{
|
||||
if (node->valid)
|
||||
{
|
||||
wim_data = &node->wim_data;
|
||||
size += sizeof(ventoy_virt_chunk) + wim_data->bin_align_len +
|
||||
wim_data->new_meta_align_len + wim_data->new_lookup_align_len;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static void ventoy_windows_fill_virt_data( grub_uint64_t isosize, ventoy_chain_head *chain)
|
||||
{
|
||||
grub_uint64_t sector;
|
||||
|
@ -732,37 +1104,53 @@ static void ventoy_windows_fill_virt_data( grub_uint64_t isosize, ventoy_chai
|
|||
grub_uint32_t mem_secs;
|
||||
char *override = NULL;
|
||||
ventoy_virt_chunk *cur = NULL;
|
||||
wim_tail *wim_data = NULL;
|
||||
wim_patch *node = NULL;
|
||||
|
||||
sector = (isosize + 2047) / 2048;
|
||||
offset = sizeof(ventoy_virt_chunk);
|
||||
|
||||
wim_secs = g_wim_data.wim_align_size / 2048;
|
||||
mem_secs = (g_wim_data.bin_align_len + g_wim_data.new_meta_align_len + g_wim_data.new_lookup_align_len) / 2048;
|
||||
offset = sizeof(ventoy_virt_chunk) * g_wim_valid_patch_count;
|
||||
|
||||
override = (char *)chain + chain->virt_chunk_offset;
|
||||
cur = (ventoy_virt_chunk *)override;
|
||||
|
||||
cur->remap_sector_start = sector;
|
||||
cur->remap_sector_end = cur->remap_sector_start + wim_secs;
|
||||
cur->org_sector_start = (grub_uint32_t)(g_wim_data.file_offset / 2048);
|
||||
|
||||
cur->mem_sector_start = cur->remap_sector_end;
|
||||
cur->mem_sector_end = cur->mem_sector_start + mem_secs;
|
||||
cur->mem_sector_offset = offset;
|
||||
for (node = g_wim_patch_head; node; node = node->next)
|
||||
{
|
||||
if (0 == node->valid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
grub_memcpy(override + offset, g_wim_data.jump_bin_data, g_wim_data.bin_raw_len);
|
||||
offset += g_wim_data.bin_align_len;
|
||||
wim_data = &node->wim_data;
|
||||
|
||||
grub_memcpy(override + offset, g_wim_data.new_meta_data, g_wim_data.new_meta_len);
|
||||
offset += g_wim_data.new_meta_align_len;
|
||||
|
||||
grub_memcpy(override + offset, g_wim_data.new_lookup_data, g_wim_data.new_lookup_len);
|
||||
offset += g_wim_data.new_lookup_align_len;
|
||||
wim_secs = wim_data->wim_align_size / 2048;
|
||||
mem_secs = (wim_data->bin_align_len + wim_data->new_meta_align_len + wim_data->new_lookup_align_len) / 2048;
|
||||
|
||||
cur->remap_sector_start = sector;
|
||||
cur->remap_sector_end = cur->remap_sector_start + wim_secs;
|
||||
cur->org_sector_start = (grub_uint32_t)(wim_data->file_offset / 2048);
|
||||
|
||||
cur->mem_sector_start = cur->remap_sector_end;
|
||||
cur->mem_sector_end = cur->mem_sector_start + mem_secs;
|
||||
cur->mem_sector_offset = offset;
|
||||
|
||||
sector += wim_secs + mem_secs;
|
||||
cur++;
|
||||
|
||||
grub_memcpy(override + offset, wim_data->jump_bin_data, wim_data->bin_raw_len);
|
||||
offset += wim_data->bin_align_len;
|
||||
|
||||
grub_memcpy(override + offset, wim_data->new_meta_data, wim_data->new_meta_len);
|
||||
offset += wim_data->new_meta_align_len;
|
||||
|
||||
grub_memcpy(override + offset, wim_data->new_lookup_data, wim_data->new_lookup_len);
|
||||
offset += wim_data->new_lookup_align_len;
|
||||
|
||||
chain->virt_img_size_in_bytes += wim_data->wim_align_size +
|
||||
wim_data->bin_align_len +
|
||||
wim_data->new_meta_align_len +
|
||||
wim_data->new_lookup_align_len;
|
||||
}
|
||||
|
||||
chain->virt_img_size_in_bytes += g_wim_data.wim_align_size +
|
||||
g_wim_data.bin_align_len +
|
||||
g_wim_data.new_meta_align_len +
|
||||
g_wim_data.new_lookup_align_len;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -828,7 +1216,7 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (0 == ventoy_compatible && g_wim_data.new_meta_data == NULL)
|
||||
if (0 == ventoy_compatible && g_wim_valid_patch_count == 0)
|
||||
{
|
||||
unknown_image = 1;
|
||||
debug("Warning: %s was not recognized by Ventoy\n", args[0]);
|
||||
|
@ -871,8 +1259,7 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c
|
|||
else
|
||||
{
|
||||
override_size = ventoy_get_override_chunk_num() * sizeof(ventoy_override_chunk);
|
||||
virt_chunk_size = sizeof(ventoy_virt_chunk) + g_wim_data.bin_align_len +
|
||||
g_wim_data.new_meta_align_len + g_wim_data.new_lookup_align_len;;
|
||||
virt_chunk_size = ventoy_windows_get_virt_data_size();
|
||||
size = sizeof(ventoy_chain_head) + img_chunk_size + override_size + virt_chunk_size;
|
||||
}
|
||||
|
||||
|
@ -903,9 +1290,10 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c
|
|||
grub_memset(chain, 0, sizeof(ventoy_chain_head));
|
||||
|
||||
/* part 1: os parameter */
|
||||
g_ventoy_chain_type = 1;
|
||||
ventoy_fill_os_param(file, &(chain->os_param));
|
||||
|
||||
if (g_wim_data.jump_bin_data && g_wim_data.new_meta_data)
|
||||
if (0 == unknown_image)
|
||||
{
|
||||
ventoy_update_before_chain(&(chain->os_param), args[0]);
|
||||
}
|
||||
|
@ -934,7 +1322,7 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (g_wim_data.new_meta_data == NULL)
|
||||
if (0 == g_wim_valid_patch_count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -942,11 +1330,19 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c
|
|||
/* part 4: override chunk */
|
||||
chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size;
|
||||
chain->override_chunk_num = ventoy_get_override_chunk_num();
|
||||
ventoy_windows_fill_override_data(isosize, (char *)chain + chain->override_chunk_offset);
|
||||
|
||||
if (g_iso_fs_type == 0)
|
||||
{
|
||||
ventoy_windows_fill_override_data_iso9660(isosize, (char *)chain + chain->override_chunk_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
ventoy_windows_fill_override_data_udf(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 = 1;
|
||||
chain->virt_chunk_num = g_wim_valid_patch_count;
|
||||
ventoy_windows_fill_virt_data(isosize, chain);
|
||||
|
||||
if (ventoy_is_efi_os() == 0)
|
||||
|
@ -1099,6 +1495,7 @@ grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char
|
|||
grub_memset(chain, 0, sizeof(ventoy_chain_head));
|
||||
|
||||
/* part 1: os parameter */
|
||||
g_ventoy_chain_type = 0;
|
||||
ventoy_fill_os_param(file, &(chain->os_param));
|
||||
|
||||
/* part 2: chain head */
|
||||
|
|
243
GRUB2/MOD_SRC/grub-2.04/include/grub/file.h
Normal file
243
GRUB2/MOD_SRC/grub-2.04/include/grub/file.h
Normal file
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2002,2007 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/>.
|
||||
*/
|
||||
|
||||
#ifndef GRUB_FILE_HEADER
|
||||
#define GRUB_FILE_HEADER 1
|
||||
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/device.h>
|
||||
#include <grub/fs.h>
|
||||
#include <grub/disk.h>
|
||||
|
||||
enum grub_file_type
|
||||
{
|
||||
GRUB_FILE_TYPE_NONE = 0,
|
||||
/* GRUB module to be loaded. */
|
||||
GRUB_FILE_TYPE_GRUB_MODULE,
|
||||
/* Loopback file to be represented as disk. */
|
||||
GRUB_FILE_TYPE_LOOPBACK,
|
||||
/* Linux kernel to be loaded. */
|
||||
GRUB_FILE_TYPE_LINUX_KERNEL,
|
||||
/* Linux initrd. */
|
||||
GRUB_FILE_TYPE_LINUX_INITRD,
|
||||
|
||||
/* Multiboot kernel. */
|
||||
GRUB_FILE_TYPE_MULTIBOOT_KERNEL,
|
||||
/* Multiboot module. */
|
||||
GRUB_FILE_TYPE_MULTIBOOT_MODULE,
|
||||
|
||||
/* Xen hypervisor - used on ARM only. */
|
||||
GRUB_FILE_TYPE_XEN_HYPERVISOR,
|
||||
/* Xen module - used on ARM only. */
|
||||
GRUB_FILE_TYPE_XEN_MODULE,
|
||||
|
||||
GRUB_FILE_TYPE_BSD_KERNEL,
|
||||
GRUB_FILE_TYPE_FREEBSD_ENV,
|
||||
GRUB_FILE_TYPE_FREEBSD_MODULE,
|
||||
GRUB_FILE_TYPE_FREEBSD_MODULE_ELF,
|
||||
GRUB_FILE_TYPE_NETBSD_MODULE,
|
||||
GRUB_FILE_TYPE_OPENBSD_RAMDISK,
|
||||
|
||||
GRUB_FILE_TYPE_XNU_INFO_PLIST,
|
||||
GRUB_FILE_TYPE_XNU_MKEXT,
|
||||
GRUB_FILE_TYPE_XNU_KEXT,
|
||||
GRUB_FILE_TYPE_XNU_KERNEL,
|
||||
GRUB_FILE_TYPE_XNU_RAMDISK,
|
||||
GRUB_FILE_TYPE_XNU_HIBERNATE_IMAGE,
|
||||
GRUB_FILE_XNU_DEVPROP,
|
||||
|
||||
GRUB_FILE_TYPE_PLAN9_KERNEL,
|
||||
|
||||
GRUB_FILE_TYPE_NTLDR,
|
||||
GRUB_FILE_TYPE_TRUECRYPT,
|
||||
GRUB_FILE_TYPE_FREEDOS,
|
||||
GRUB_FILE_TYPE_PXECHAINLOADER,
|
||||
GRUB_FILE_TYPE_PCCHAINLOADER,
|
||||
|
||||
GRUB_FILE_TYPE_COREBOOT_CHAINLOADER,
|
||||
|
||||
GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE,
|
||||
|
||||
/* File holding signature. */
|
||||
GRUB_FILE_TYPE_SIGNATURE,
|
||||
/* File holding public key to verify signature once. */
|
||||
GRUB_FILE_TYPE_PUBLIC_KEY,
|
||||
/* File holding public key to add to trused keys. */
|
||||
GRUB_FILE_TYPE_PUBLIC_KEY_TRUST,
|
||||
/* File of which we intend to print a blocklist to the user. */
|
||||
GRUB_FILE_TYPE_PRINT_BLOCKLIST,
|
||||
/* File we intend to use for test loading or testing speed. */
|
||||
GRUB_FILE_TYPE_TESTLOAD,
|
||||
/* File we open only to get its size. E.g. in ls output. */
|
||||
GRUB_FILE_TYPE_GET_SIZE,
|
||||
/* Font file. */
|
||||
GRUB_FILE_TYPE_FONT,
|
||||
/* File holding encryption key for encrypted ZFS. */
|
||||
GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY,
|
||||
/* File we open n grub-fstest. */
|
||||
GRUB_FILE_TYPE_FSTEST,
|
||||
/* File we open n grub-mount. */
|
||||
GRUB_FILE_TYPE_MOUNT,
|
||||
/* File which we attempt to identify the type of. */
|
||||
GRUB_FILE_TYPE_FILE_ID,
|
||||
/* File holding ACPI table. */
|
||||
GRUB_FILE_TYPE_ACPI_TABLE,
|
||||
/* File holding Device Tree. */
|
||||
GRUB_FILE_TYPE_DEVICE_TREE_IMAGE,
|
||||
/* File we intend show to user. */
|
||||
GRUB_FILE_TYPE_CAT,
|
||||
GRUB_FILE_TYPE_HEXCAT,
|
||||
/* One of pair of files we intend to compare. */
|
||||
GRUB_FILE_TYPE_CMP,
|
||||
/* List of hashes for hashsum. */
|
||||
GRUB_FILE_TYPE_HASHLIST,
|
||||
/* File hashed by hashsum. */
|
||||
GRUB_FILE_TYPE_TO_HASH,
|
||||
/* Keyboard layout. */
|
||||
GRUB_FILE_TYPE_KEYBOARD_LAYOUT,
|
||||
/* Picture file. */
|
||||
GRUB_FILE_TYPE_PIXMAP,
|
||||
/* *.lst shipped by GRUB. */
|
||||
GRUB_FILE_TYPE_GRUB_MODULE_LIST,
|
||||
/* config file. */
|
||||
GRUB_FILE_TYPE_CONFIG,
|
||||
GRUB_FILE_TYPE_THEME,
|
||||
GRUB_FILE_TYPE_GETTEXT_CATALOG,
|
||||
GRUB_FILE_TYPE_FS_SEARCH,
|
||||
GRUB_FILE_TYPE_AUDIO,
|
||||
GRUB_FILE_TYPE_VBE_DUMP,
|
||||
|
||||
GRUB_FILE_TYPE_LOADENV,
|
||||
GRUB_FILE_TYPE_SAVEENV,
|
||||
|
||||
GRUB_FILE_TYPE_VERIFY_SIGNATURE,
|
||||
|
||||
GRUB_FILE_TYPE_MASK = 0xffff,
|
||||
|
||||
/* --skip-sig is specified. */
|
||||
GRUB_FILE_TYPE_SKIP_SIGNATURE = 0x10000,
|
||||
GRUB_FILE_TYPE_NO_DECOMPRESS = 0x20000
|
||||
};
|
||||
|
||||
/* File description. */
|
||||
struct grub_file
|
||||
{
|
||||
/* File name. */
|
||||
char *name;
|
||||
|
||||
/* The underlying device. */
|
||||
grub_device_t device;
|
||||
|
||||
/* The underlying filesystem. */
|
||||
grub_fs_t fs;
|
||||
|
||||
/* The current offset. */
|
||||
grub_off_t offset;
|
||||
grub_off_t progress_offset;
|
||||
|
||||
/* Progress info. */
|
||||
grub_uint64_t last_progress_time;
|
||||
grub_off_t last_progress_offset;
|
||||
grub_uint64_t estimated_speed;
|
||||
|
||||
/* The file size. */
|
||||
grub_off_t size;
|
||||
|
||||
/* If file is not easily seekable. Should be set by underlying layer. */
|
||||
int not_easily_seekable;
|
||||
|
||||
/* Filesystem-specific data. */
|
||||
void *data;
|
||||
|
||||
/* This is called when a sector is read. Used only for a disk device. */
|
||||
grub_disk_read_hook_t read_hook;
|
||||
|
||||
/* Caller-specific data passed to the read hook. */
|
||||
void *read_hook_data;
|
||||
};
|
||||
typedef struct grub_file *grub_file_t;
|
||||
|
||||
extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook);
|
||||
|
||||
/* Filters with lower ID are executed first. */
|
||||
typedef enum grub_file_filter_id
|
||||
{
|
||||
GRUB_FILE_FILTER_VERIFY,
|
||||
GRUB_FILE_FILTER_GZIO,
|
||||
GRUB_FILE_FILTER_XZIO,
|
||||
GRUB_FILE_FILTER_LZOPIO,
|
||||
GRUB_FILE_FILTER_MAX,
|
||||
GRUB_FILE_FILTER_COMPRESSION_FIRST = GRUB_FILE_FILTER_GZIO,
|
||||
GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_LZOPIO,
|
||||
} grub_file_filter_id_t;
|
||||
|
||||
typedef grub_file_t (*grub_file_filter_t) (grub_file_t in, enum grub_file_type type);
|
||||
|
||||
extern grub_file_filter_t EXPORT_VAR(grub_file_filters)[GRUB_FILE_FILTER_MAX];
|
||||
|
||||
static inline void
|
||||
grub_file_filter_register (grub_file_filter_id_t id, grub_file_filter_t filter)
|
||||
{
|
||||
grub_file_filters[id] = filter;
|
||||
}
|
||||
|
||||
static inline void
|
||||
grub_file_filter_unregister (grub_file_filter_id_t id)
|
||||
{
|
||||
grub_file_filters[id] = 0;
|
||||
}
|
||||
|
||||
/* Get a device name from NAME. */
|
||||
char *EXPORT_FUNC(grub_file_get_device_name) (const char *name);
|
||||
|
||||
int EXPORT_FUNC(ventoy_check_file_exist) (const char * fmt, ...);
|
||||
grub_file_t EXPORT_FUNC(grub_file_open) (const char *name, enum grub_file_type type);
|
||||
grub_ssize_t EXPORT_FUNC(grub_file_read) (grub_file_t file, void *buf,
|
||||
grub_size_t len);
|
||||
grub_off_t EXPORT_FUNC(grub_file_seek) (grub_file_t file, grub_off_t offset);
|
||||
grub_err_t EXPORT_FUNC(grub_file_close) (grub_file_t file);
|
||||
|
||||
/* Return value of grub_file_size() in case file size is unknown. */
|
||||
#define GRUB_FILE_SIZE_UNKNOWN 0xffffffffffffffffULL
|
||||
|
||||
static inline grub_off_t
|
||||
grub_file_size (const grub_file_t file)
|
||||
{
|
||||
return file->size;
|
||||
}
|
||||
|
||||
static inline grub_off_t
|
||||
grub_file_tell (const grub_file_t file)
|
||||
{
|
||||
return file->offset;
|
||||
}
|
||||
|
||||
static inline int
|
||||
grub_file_seekable (const grub_file_t file)
|
||||
{
|
||||
return !file->not_easily_seekable;
|
||||
}
|
||||
|
||||
grub_file_t
|
||||
grub_file_offset_open (grub_file_t parent, enum grub_file_type type,
|
||||
grub_off_t start, grub_off_t size);
|
||||
void
|
||||
grub_file_offset_close (grub_file_t file);
|
||||
|
||||
#endif /* ! GRUB_FILE_HEADER */
|
|
@ -109,6 +109,8 @@ typedef struct ventoy_os_param
|
|||
*
|
||||
* vtoy_reserved[0]: vtoy_break_level
|
||||
* vtoy_reserved[1]: vtoy_debug_level
|
||||
* vtoy_reserved[2]: vtoy_chain_type 0:Linux 1:Windows
|
||||
* vtoy_reserved[3]: vtoy_iso_format 0:iso9660 1:udf
|
||||
*
|
||||
*/
|
||||
grub_uint8_t vtoy_reserved[32]; // Internal use by ventoy
|
||||
|
@ -227,6 +229,7 @@ typedef struct ventoy_grub_param
|
|||
|
||||
int grub_ext_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list);
|
||||
int grub_fat_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list);
|
||||
void grub_iso9660_set_nojoliet(int nojoliet);
|
||||
grub_uint64_t grub_iso9660_get_last_read_pos(grub_file_t file);
|
||||
grub_uint64_t grub_iso9660_get_last_file_dirent_pos(grub_file_t file);
|
||||
grub_uint64_t grub_udf_get_file_offset(grub_file_t file);
|
||||
|
|
|
@ -12,10 +12,10 @@ make install
|
|||
PATH=$PATH:$VT_DIR/GRUB2/INSTALL/bin/:$VT_DIR/GRUB2/INSTALL/sbin/
|
||||
|
||||
net_modules_legacy="net tftp http"
|
||||
all_modules_legacy="date drivemap blocklist lspci pci ext2 xfs ventoy chain read halt iso9660 linux16 test true sleep reboot echo videotest videoinfo videotest_checksum video_colors video_cirrus video_bochs vga vbe video_fb font video gettext extcmd terminal linux minicmd help configfile tr trig boot biosdisk disk ls tar squash4 password_pbkdf2 all_video png jpeg part_msdos fat exfat ntfs loopback gzio normal udf gfxmenu gfxterm gfxterm_background gfxterm_menu"
|
||||
all_modules_legacy="date drivemap blocklist ntldr search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio lspci pci ext2 xfs ventoy chain read halt iso9660 linux16 test true sleep reboot echo videotest videoinfo videotest_checksum video_colors video_cirrus video_bochs vga vbe video_fb font video gettext extcmd terminal linux minicmd help configfile tr trig boot biosdisk disk ls tar squash4 password_pbkdf2 all_video png jpeg part_msdos fat exfat ntfs loopback gzio normal udf gfxmenu gfxterm gfxterm_background gfxterm_menu"
|
||||
|
||||
net_modules_uefi="efinet net tftp http"
|
||||
all_modules_uefi="blocklist ventoy test ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux relocator jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop efi_uga video_bochs video_cirrus video video_fb gfxterm_background gfxterm_menu"
|
||||
all_modules_uefi="blocklist ventoy test search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux relocator jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop efi_uga video_bochs video_cirrus video video_fb gfxterm_background gfxterm_menu"
|
||||
|
||||
|
||||
if [ "$1" = "uefi" ]; then
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue