1.0.44 release

This commit is contained in:
longpanda 2021-05-15 19:44:20 +08:00
parent 1c5aeb35dc
commit 99fbd14f08
4 changed files with 394 additions and 4 deletions

View File

@ -0,0 +1,316 @@
#include <grub/types.h>
#include <grub/err.h>
#include <grub/linux.h>
#include <grub/misc.h>
#include <grub/file.h>
#include <grub/mm.h>
#include <grub/env.h>
#include <grub/term.h>
struct newc_head
{
char magic[6];
char ino[8];
char mode[8];
char uid[8];
char gid[8];
char nlink[8];
char mtime[8];
char filesize[8];
char devmajor[8];
char devminor[8];
char rdevmajor[8];
char rdevminor[8];
char namesize[8];
char check[8];
} GRUB_PACKED;
struct grub_linux_initrd_component
{
grub_file_t file;
char *newc_name;
grub_off_t size;
};
struct dir
{
char *name;
struct dir *next;
struct dir *child;
};
static char
hex (grub_uint8_t val)
{
if (val < 10)
return '0' + val;
return 'a' + val - 10;
}
static void
set_field (char *var, grub_uint32_t val)
{
int i;
char *ptr = var;
for (i = 28; i >= 0; i -= 4)
*ptr++ = hex((val >> i) & 0xf);
}
static grub_uint8_t *
make_header (grub_uint8_t *ptr,
const char *name, grub_size_t len,
grub_uint32_t mode,
grub_off_t fsize)
{
struct newc_head *head = (struct newc_head *) ptr;
grub_uint8_t *optr;
grub_size_t oh = 0;
grub_memcpy (head->magic, "070701", 6);
set_field (head->ino, 0);
set_field (head->mode, mode);
set_field (head->uid, 0);
set_field (head->gid, 0);
set_field (head->nlink, 1);
set_field (head->mtime, 0);
set_field (head->filesize, fsize);
set_field (head->devmajor, 0);
set_field (head->devminor, 0);
set_field (head->rdevmajor, 0);
set_field (head->rdevminor, 0);
set_field (head->namesize, len);
set_field (head->check, 0);
optr = ptr;
ptr += sizeof (struct newc_head);
grub_memcpy (ptr, name, len);
ptr += len;
oh = ALIGN_UP_OVERHEAD (ptr - optr, 4);
grub_memset (ptr, 0, oh);
ptr += oh;
return ptr;
}
static void
free_dir (struct dir *root)
{
if (!root)
return;
free_dir (root->next);
free_dir (root->child);
grub_free (root->name);
grub_free (root);
}
static grub_size_t
insert_dir (const char *name, struct dir **root,
grub_uint8_t *ptr)
{
struct dir *cur, **head = root;
const char *cb, *ce = name;
grub_size_t size = 0;
while (1)
{
for (cb = ce; *cb == '/'; cb++);
for (ce = cb; *ce && *ce != '/'; ce++);
if (!*ce)
break;
for (cur = *root; cur; cur = cur->next)
if (grub_memcmp (cur->name, cb, ce - cb)
&& cur->name[ce - cb] == 0)
break;
if (!cur)
{
struct dir *n;
n = grub_zalloc (sizeof (*n));
if (!n)
return 0;
n->next = *head;
n->name = grub_strndup (cb, ce - cb);
if (ptr)
{
grub_dprintf ("linux", "Creating directory %s, %s\n", name, ce);
ptr = make_header (ptr, name, ce - name,
040777, 0);
}
size += ALIGN_UP ((ce - (char *) name)
+ sizeof (struct newc_head), 4);
*head = n;
cur = n;
}
root = &cur->next;
}
return size;
}
grub_err_t
grub_initrd_init (int argc, char *argv[],
struct grub_linux_initrd_context *initrd_ctx)
{
int i;
int newc = 0;
struct dir *root = 0;
initrd_ctx->nfiles = 0;
initrd_ctx->components = 0;
initrd_ctx->components = grub_zalloc (argc
* sizeof (initrd_ctx->components[0]));
if (!initrd_ctx->components)
return grub_errno;
initrd_ctx->size = 0;
for (i = 0; i < argc; i++)
{
const char *fname = argv[i];
initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4);
if (grub_memcmp (argv[i], "newc:", 5) == 0)
{
const char *ptr, *eptr;
ptr = argv[i] + 5;
while (*ptr == '/')
ptr++;
eptr = grub_strchr (ptr, ':');
if (eptr)
{
initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr);
if (!initrd_ctx->components[i].newc_name)
{
grub_initrd_close (initrd_ctx);
return grub_errno;
}
initrd_ctx->size
+= ALIGN_UP (sizeof (struct newc_head)
+ grub_strlen (initrd_ctx->components[i].newc_name),
4);
initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name,
&root, 0);
newc = 1;
fname = eptr + 1;
}
}
else if (newc)
{
initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
+ sizeof ("TRAILER!!!") - 1, 4);
free_dir (root);
root = 0;
newc = 0;
}
initrd_ctx->components[i].file = grub_file_open (fname,
GRUB_FILE_TYPE_LINUX_INITRD
| GRUB_FILE_TYPE_NO_DECOMPRESS);
if (!initrd_ctx->components[i].file)
{
grub_initrd_close (initrd_ctx);
return grub_errno;
}
initrd_ctx->nfiles++;
initrd_ctx->components[i].size
= grub_file_size (initrd_ctx->components[i].file);
initrd_ctx->size += initrd_ctx->components[i].size;
}
if (newc)
{
initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4);
initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
+ sizeof ("TRAILER!!!") - 1, 4);
free_dir (root);
root = 0;
}
return GRUB_ERR_NONE;
}
grub_size_t
grub_get_initrd_size (struct grub_linux_initrd_context *initrd_ctx)
{
return initrd_ctx->size;
}
void
grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx)
{
int i;
if (!initrd_ctx->components)
return;
for (i = 0; i < initrd_ctx->nfiles; i++)
{
grub_free (initrd_ctx->components[i].newc_name);
grub_file_close (initrd_ctx->components[i].file);
}
grub_free (initrd_ctx->components);
initrd_ctx->components = 0;
}
extern int ventoy_need_prompt_load_file(void);
extern grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size);
grub_err_t
grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
char *argv[], void *target)
{
grub_uint8_t *ptr = target;
int i;
int newc = 0;
struct dir *root = 0;
grub_ssize_t cursize = 0;
grub_ssize_t readsize = 0;
for (i = 0; i < initrd_ctx->nfiles; i++)
{
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
if (initrd_ctx->components[i].newc_name)
{
ptr += insert_dir (initrd_ctx->components[i].newc_name,
&root, ptr);
ptr = make_header (ptr, initrd_ctx->components[i].newc_name,
grub_strlen (initrd_ctx->components[i].newc_name),
0100777,
initrd_ctx->components[i].size);
newc = 1;
}
else if (newc)
{
ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1,
0, 0);
free_dir (root);
root = 0;
newc = 0;
}
cursize = initrd_ctx->components[i].size;
if (ventoy_need_prompt_load_file() && initrd_ctx->components[i].newc_name &&
grub_strcmp(initrd_ctx->components[i].newc_name, "boot.wim") == 0)
{
readsize = ventoy_load_file_with_prompt(initrd_ctx->components[i].file, ptr, cursize);
}
else
{
readsize = grub_file_read (initrd_ctx->components[i].file, ptr, cursize);
}
if (readsize != cursize)
{
if (!grub_errno)
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
argv[i]);
grub_initrd_close (initrd_ctx);
return grub_errno;
}
ptr += cursize;
}
if (newc)
{
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, 0, 0);
}
free_dir (root);
root = 0;
return GRUB_ERR_NONE;
}

View File

@ -139,6 +139,9 @@ const char *g_menu_prefix[img_type_max] =
"iso", "wim", "efi", "img", "vhd", "vtoy"
};
static int g_vtoy_load_prompt = 0;
static char g_vtoy_prompt_msg[64];
static int ventoy_get_fs_type(const char *fs)
{
if (NULL == fs)
@ -1043,6 +1046,61 @@ static grub_err_t ventoy_cmd_concat_efi_iso(grub_extcmd_context_t ctxt, int argc
return 0;
}
grub_err_t ventoy_cmd_set_wim_prompt(grub_extcmd_context_t ctxt, int argc, char **args)
{
(void)ctxt;
(void)argc;
(void)args;
g_vtoy_load_prompt = 0;
grub_memset(g_vtoy_prompt_msg, 0, sizeof(g_vtoy_prompt_msg));
if (argc == 2 && args[0][0] == '1')
{
g_vtoy_load_prompt = 1;
grub_snprintf(g_vtoy_prompt_msg, sizeof(g_vtoy_prompt_msg), "%s", args[1]);
}
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}
int ventoy_need_prompt_load_file(void)
{
return g_vtoy_load_prompt;
}
grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size)
{
grub_uint64_t ro = 0;
grub_uint64_t div = 0;
grub_ssize_t left = size;
char *cur = (char *)buf;
grub_printf("\r%s 1%% ", g_vtoy_prompt_msg);
grub_refresh();
while (left >= VTOY_SIZE_2MB)
{
grub_file_read(file, cur, VTOY_SIZE_2MB);
cur += VTOY_SIZE_2MB;
left -= VTOY_SIZE_2MB;
div = grub_divmod64((grub_uint64_t)((size - left) * 100), (grub_uint64_t)size, &ro);
grub_printf("\r%s %d%% ", g_vtoy_prompt_msg, (int)div);
grub_refresh();
}
if (left > 0)
{
grub_file_read(file, cur, left);
}
grub_printf("\r%s 100%% \n", g_vtoy_prompt_msg);
grub_refresh();
return size;
}
static grub_err_t ventoy_cmd_load_file_to_mem(grub_extcmd_context_t ctxt, int argc, char **args)
{
int rc = 1;
@ -1089,7 +1147,14 @@ static grub_err_t ventoy_cmd_load_file_to_mem(grub_extcmd_context_t ctxt, int ar
return 1;
}
grub_file_read(file, buf, file->size);
if (g_vtoy_load_prompt)
{
ventoy_load_file_with_prompt(file, buf, file->size);
}
else
{
grub_file_read(file, buf, file->size);
}
grub_snprintf(name, sizeof(name), "%s_addr", args[2]);
grub_snprintf(value, sizeof(value), "0x%llx", (unsigned long long)(unsigned long)buf);
@ -4507,6 +4572,7 @@ static cmd_para ventoy_cmds[] =
{ "vt_img_check_range", ventoy_cmd_img_check_range, 0, NULL, "", "", NULL },
{ "vt_is_pe64", ventoy_cmd_is_pe64, 0, NULL, "", "", NULL },
{ "vt_sel_wimboot", ventoy_cmd_sel_wimboot, 0, NULL, "", "", NULL },
{ "vt_set_wim_load_prompt", ventoy_cmd_set_wim_prompt, 0, NULL, "", "", NULL },
};

View File

@ -29,6 +29,8 @@
#define VTOY_SIZE_1GB 1073741824
#define VTOY_SIZE_1MB (1024 * 1024)
#define VTOY_SIZE_2MB (2 * 1024 * 1024)
#define VTOY_SIZE_4MB (4 * 1024 * 1024)
#define VTOY_SIZE_512KB (512 * 1024)
#define VTOY_SIZE_1KB 1024
@ -564,6 +566,9 @@ grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char
grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_dump_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_sel_wimboot(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_set_wim_prompt(grub_extcmd_context_t ctxt, int argc, char **args);
grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size);
int ventoy_need_prompt_load_file(void);
VTOY_JSON *vtoy_json_find_item
(

View File

@ -848,13 +848,14 @@ function vtoy_windows_wimboot_func {
linux16 "$vtoy_path/$vt_wimkernel" quiet
ventoy_debug_pause
echo Loading files...... (This may take a few minutes, please wait)
vt_set_wim_load_prompt 1 "Loading files......"
initrd16 newc:vtoyjump.exe:$vtoy_path/vtoyjump${vtoy_wimboot_bit}.exe \
newc:wimboot.data:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size} \
newc:winpeshl.ini:mem:${vtoy_winpeshl_ini_addr}:size:${vtoy_winpeshl_ini_size} \
newc:bcd:$vtoy_wimboot_prefix/boot/bcd \
newc:boot.sdi:$vtoy_wimboot_prefix/boot/boot.sdi \
newc:boot.wim:$vtoy_wimboot_prefix/sources/boot.wim
vt_set_wim_load_prompt 0
boot
else
if [ "$grub_cpu" = "i386" ]; then
@ -863,8 +864,10 @@ function vtoy_windows_wimboot_func {
set vt_wimkernel=wimboot.x86_64.xz
fi
echo Loading files...... (This may take a few minutes, please wait)
vt_set_wim_load_prompt 1 "Loading files......"
vt_load_file_to_mem "nodecompress" $vtoy_wimboot_prefix/sources/boot.wim vtoy_wimfile_mem
vt_set_wim_load_prompt 0
if [ $? -eq 0 ]; then
set vtoy_wimfile_path=mem:${vtoy_wimfile_mem_addr}:size:${vtoy_wimfile_mem_size}
else
@ -1793,7 +1796,7 @@ function img_unsupport_menuentry {
#############################################################
#############################################################
set VENTOY_VERSION="1.0.43"
set VENTOY_VERSION="1.0.44"
#ACPI not compatible with Window7/8, so disable by default
set VTOY_PARAM_NO_ACPI=1